Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 42 additions & 9 deletions agent360/plugins/plugins-installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import certifi
import logging
import json
import time
import threading
import subprocess
from pprint import pprint

if sys.version_info >= (3,):
Expand All @@ -30,13 +33,42 @@
class Plugin(plugins.BasePlugin):
__name__ = 'plugins-installer'

# guard flags to prevent multiple updater threads
_updater_started = False
_lock = threading.Lock()

def run(self, config):
self.config = config
updated = self._update_plugins_from_backend()
if updated:
self._restart_agent()
results = self._get_plugins(config)
return results

# ensure only one background updater thread
with Plugin._lock:
if not Plugin._updater_started:
Plugin._updater_started = True
t = threading.Thread(
target=self._periodic_updater,
name="PluginUpdaterThread",
daemon=True
)
t.start()

return self._get_plugins(config)

def _periodic_updater(self):
while True:
try:
updated = self._update_plugins_from_backend()
if updated:
logging.info("Plugins updated, restarting agent")
self._restart_agent()
except Exception as e:
logging.error("Error in periodic plugin update: %s", e)

try:
interval = self.config.getint('agent', 'plugin_update_interval')
except Exception:
interval = 1800 # default 30 minutes
time.sleep(interval)


def _restart_agent(self):
pid = os.fork()
Expand All @@ -45,7 +77,7 @@ def _restart_agent(self):
try:
subprocess.run(['systemctl', 'restart', 'agent360'], check=True)
except Exception as e:
logging.error('Failed to restart agent360: %s' % e)
logging.error('Failed to restart agent360: %s', e)
os._exit(0)

def _update_plugins_from_backend(self, proto='https'):
Expand All @@ -71,7 +103,8 @@ def _update_plugins_from_backend(self, proto='https'):
updated = True
self._set_plugin_configuration(plugin['id'], c, plugin['config'][c])
except Exception as e:
logging.error('Failed to get plugins state: %s' % e)
logging.error('Failed to get plugins state: %s', e)
return False
return updated

def _get_connection(self, proto='https'):
Expand Down Expand Up @@ -120,8 +153,8 @@ def _config_section_create(self, section):
def _get_config_section_properties(self, config, section_name):
# Exclude parent configuration
excluded_keys = ['api_host', 'api_path', 'interval', 'log_file', 'log_file_mode',
'logging_level','max_cached_collections', 'max_data_age', 'max_data_span',
'plugins', 'server', 'subprocess', 'threads', 'ttl', 'user']
'logging_level', 'max_cached_collections', 'max_data_age', 'max_data_span',
'plugins', 'server', 'subprocess', 'threads', 'ttl', 'user']
if section_name in config:
properties = {
key: config[section_name][key]
Expand Down