From e5e4068231ce867b661821b8b6fb28e754c38e8c Mon Sep 17 00:00:00 2001 From: Christoph Zimmermann Date: Sun, 29 Oct 2023 14:53:15 +0100 Subject: [PATCH 1/3] Added functionality in curses i/f --- glances/outputs/glances_curses.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py index e078e9b1..7cbc5b8a 100644 --- a/glances/outputs/glances_curses.py +++ b/glances/outputs/glances_curses.py @@ -89,6 +89,7 @@ class _GlancesCurses(object): # 'w' > Delete finished warning logs 'W': {'switch': 'disable_wifi'}, # 'x' > Delete finished warning and critical logs + 'Y': {'switch': 'enable_systemd'}, # 'z' > Enable or disable processes # '+' > Increase the process nice level # '-' > Decrease the process nice level @@ -117,6 +118,7 @@ class _GlancesCurses(object): 'raid', 'smart', 'sensors', + 'systemd', 'now', ] _left_sidebar_min_width = 23 From 0ce4092df755748622d05d1104efe7c8fcbaf3f2 Mon Sep 17 00:00:00 2001 From: Christoph Zimmermann Date: Sun, 29 Oct 2023 15:07:30 +0100 Subject: [PATCH 2/3] Added check for already loaded module in sys.modules --- glances/stats.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/glances/stats.py b/glances/stats.py index 803914f3..67688127 100644 --- a/glances/stats.py +++ b/glances/stats.py @@ -164,19 +164,22 @@ class GlancesStats(object): # Ensure that plugins can be found in plugin_dir sys.path.insert(0, path) for plugin in get_addl_plugins(self, path): - start_duration.reset() - try: - _mod_loaded = import_module(plugin+'.model') - self._plugins[plugin] = _mod_loaded.PluginModel(args=args, config=config) - logger.debug("Plugin {} started in {} seconds".format(plugin, start_duration.get())) - except Exception as e: - # If a plugin can not be loaded, display a critical message - # on the console but do not crash - logger.critical("Error while initializing the {} plugin ({})".format(plugin, e)) - logger.error(traceback.format_exc()) - # An error occurred, disable the plugin - if args: - setattr(args, 'disable_' + plugin, False) + if plugin in sys.modules: + logger.warn(f"Pugin {plugin} already in sys.modules, skipping (workaround: rename plugin)") + else: + start_duration.reset() + try: + _mod_loaded = import_module(plugin+'.model') + self._plugins[plugin] = _mod_loaded.PluginModel(args=args, config=config) + logger.debug("Plugin {} started in {} seconds".format(plugin, start_duration.get())) + except Exception as e: + # If a plugin can not be loaded, display a critical message + # on the console but do not crash + logger.critical("Error while initializing the {} plugin ({})".format(plugin, e)) + logger.error(traceback.format_exc()) + # An error occurred, disable the plugin + if args: + setattr(args, 'disable_' + plugin, False) sys.path = _sys_path # Log plugins list From 037d3f7c895a5ac7d231e0b158a243ee2c22935d Mon Sep 17 00:00:00 2001 From: Christoph Zimmermann Date: Tue, 31 Oct 2023 16:19:11 +0100 Subject: [PATCH 3/3] Fixed plugin name handling in GlancesPluginModel and optimized package handling in load_additional_plugins --- glances/plugins/plugin/model.py | 12 ++++++++++-- glances/stats.py | 18 ++++++++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/glances/plugins/plugin/model.py b/glances/plugins/plugin/model.py index d36ddbfb..2ebcf046 100644 --- a/glances/plugins/plugin/model.py +++ b/glances/plugins/plugin/model.py @@ -70,8 +70,16 @@ class GlancesPluginModel(object): :stats_init_value: Default value for a stats item """ # Build the plugin name - # Get second-last entry as the last one will always be 'model' - self.plugin_name = self.__class__.__module__.split('.')[-2] + _mod = self.__class__.__module__ + _comp = _mod.split('.') + # Internal or external module (former prefixed by 'glances.plugins') + if 'glances.plugins' in _mod: + _ndx = 2 + else: + _ndx = -2 + + self.plugin_name = _comp[_ndx] + if self.plugin_name.startswith('glances_'): self.plugin_name = self.plugin_name.split('glances_')[1] logger.debug("Init {} plugin".format(self.plugin_name)) diff --git a/glances/stats.py b/glances/stats.py index 67688127..e8c89a8c 100644 --- a/glances/stats.py +++ b/glances/stats.py @@ -15,7 +15,7 @@ import sys import threading import traceback from importlib import import_module -import pkgutil +import pathlib from glances.logger import logger from glances.globals import exports_path, plugins_path, sys_path @@ -142,10 +142,16 @@ class GlancesStats(object): def get_addl_plugins(self, plugin_path): """ Get list of additonal plugins """ _plugin_list = [] - for plugin in pkgutil.walk_packages([plugin_path]): - # Make sure we only include top-level packages in that directory - if plugin.ispkg and not plugin.name.startswith('__') and plugin.module_finder.path == plugin_path: - _plugin_list.append(plugin.name) + for plugin in os.listdir(plugin_path): + path = os.path.join(plugin_path, plugin) + if os.path.isdir(path) and not path.startswith('__'): + # Poor man's walk_pkgs - can't use pkgutil as the module would be already imported here! + for fil in pathlib.Path(path).glob('*.py'): + if fil.is_file(): + with open(fil) as fd: + if 'PluginModel' in fd.read(): + _plugin_list.append(plugin) + break return _plugin_list @@ -154,7 +160,7 @@ class GlancesStats(object): if config and config.parser.has_option('global', 'plugin_dir'): path = config.parser['global']['plugin_dir'] - if args and 'plugin_dir' in args: + if args and 'plugin_dir' in args and args.plugin_dir: path = args.plugin_dir if path: