#!/usr/bin/env python3 """ Plugins management for RiotKit's container for Taiga.io application =================================================================== Pre-installs all available plugins on container build, then lets *ops to decide which plugin to enable on container startup License: MIT Author: RiotKit Collective (https://github.com/riotkit-org) """ import os import sys import json import importlib.util class PluginManager: _front_path: str _plugins_path: str _plugins: dict def __init__(self): self._front_path = self._detect_front_path() self._plugins_path = self._detect_plugins_path() self._load_all() def install(self): """ Command: Iterate over all AVAILABLE plugins and pre-install them. They can be enabled later. :return: """ print(' >> Installing plugins...') print(list(self._plugins.items())) for plugin_name, module in self._plugins.items(): print(' >> Instaling plugin "%s"' % plugin_name) os.chdir(self._front_path) print(' .. installing frontend') module.frontend_setup() os.chdir('/usr/src/taiga-back/') print(' .. installing backend') module.backend_setup() def after_application_migrations(self): """ Command: Execute code/commands after Taiga migration finishes (eg. execute plugin migrations) :return: """ plugins_to_migrate = self._get_enabled_plugins() valid_plugins_list = str(list(self._plugins.keys())).replace('.py', '') print(' >> Updating/migrating plugins...') print(plugins_to_migrate) for plugin_name in plugins_to_migrate: if not plugin_name: continue if plugin_name not in self._plugins: raise Exception('Plugin name "%s" is invalid, valid options: %s' % (plugin_name, valid_plugins_list)) module = self._plugins[plugin_name] print(' >> Executing after_application_migration for plugin "%s"' % plugin_name) os.chdir('/usr/src/taiga-back/') if hasattr(module, 'after_application_migration'): module.after_application_migration() def export_plugin_variables_to_environment(self): """ Command: Enable SELECTED plugins :return: """ enabled_plugins = self._get_enabled_plugins() valid_plugins_list = str(list(self._plugins.keys())).replace('.py', '') frontend_contrib_plugins_list = [] backend_installed_apps = [] for enabled_plugin in enabled_plugins: if not enabled_plugin: continue if enabled_plugin not in self._plugins: raise Exception('Plugin name "%s" is invalid, valid options: %s' % (enabled_plugin, valid_plugins_list)) module = self._plugins[enabled_plugin] frontend_contrib_plugins_list += module.FRONTEND_CONTRIB_PLUGINS backend_installed_apps += module.BACKEND_INSTALLED_APPS print(''' export FRONTEND_CONTRIB_PLUGINS_LIST="%s"; export BACKEND_INSTALLED_APPS="%s"; ''' % ( json.dumps(frontend_contrib_plugins_list).strip('[]').replace('"', '\\"'), json.dumps(backend_installed_apps).replace('"', '\\"') ) ) @staticmethod def _get_enabled_plugins() -> list: return os.getenv('TAIGA_PLUGINS', '').replace(' ', '').replace('"', '').strip().split(',') def _load_all(self): self._plugins = {} for filename in os.scandir(self._plugins_path): if not filename.name.endswith('.py'): continue plugin_name = os.path.basename(filename.name).replace('.py', '') self._plugins[plugin_name] = self._load(plugin_name, filename.path) @staticmethod def _load(plugin_name: str, path: str): spec = importlib.util.spec_from_file_location("dockertaiga.%s" % plugin_name, path) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) return mod @staticmethod def _detect_plugins_path(): if os.path.isdir('/usr/src/taiga-plugins'): return '/usr/src/taiga-plugins' return os.path.abspath(os.path.dirname(__file__) + '/../../plugins/') @staticmethod def _detect_front_path(): if os.path.isdir('/usr/src/taiga-front-dist/dist/plugins'): return '/usr/src/taiga-front-dist/dist/plugins' return '/tmp' if __name__ == '__main__': action = sys.argv[1] if len(sys.argv) > 1 else '' app = PluginManager() if action == 'install-all-plugins': app.install() elif action == 'export': app.export_plugin_variables_to_environment() elif action == 'after-migrations': app.after_application_migrations() else: print('Tasks: install-all-plugins, export') sys.exit(1)