diff --git a/opt/ahenk/ahenkd.py b/opt/ahenk/ahenkd.py index 355048a..9988aae 100755 --- a/opt/ahenk/ahenkd.py +++ b/opt/ahenk/ahenkd.py @@ -21,10 +21,11 @@ from base.logger.AhenkLogger import Logger from base.messaging.MessageResponseQueue import MessageResponseQueue from base.messaging.Messager import Messager from base.messaging.Messaging import Messaging -from base.plugin.PluginManager import PluginManager +from base.plugin.plugin_manager import PluginManager from base.registration.Registration import Registration from base.task.TaskManager import TaskManager from base.scheduler.scheduler_factory import SchedulerFactory +from base.plugin.plugin_manager_factory import PluginManagerFactory pidfilePath = '/var/run/ahenk.pid' @@ -75,7 +76,7 @@ class AhenkDeamon(BaseDaemon): return messageManager def init_plugin_manager(self): - pluginManager = PluginManager() + pluginManager = PluginManagerFactory.get_instance() pluginManager.loadPlugins() Scope.getInstance().setPluginManager(pluginManager) return pluginManager @@ -122,6 +123,29 @@ class AhenkDeamon(BaseDaemon): Scope.getInstance().getLogger().debug('[AhenkDeamon] Attempting to register') Scope.getInstance().getRegistration().registration_request() + + def reload_plugins(self): + Scope.getInstance().getPluginManager().reloadPlugins() + + def reload_configuration(self): + # Not implemented yet + pass + + def reload_messaging(self): + #Not implemented yet + pass + + def reload_logger(self): + #Not implemented yet + pass + + + def update_plugin_manager(self): + #TODO destroy plugin manager here + self.init_plugin_manager() + + + def run(self): print('Ahenk running...') diff --git a/opt/ahenk/base/plugin/plugin_manager.py b/opt/ahenk/base/plugin/plugin_manager.py new file mode 100644 index 0000000..194860c --- /dev/null +++ b/opt/ahenk/base/plugin/plugin_manager.py @@ -0,0 +1,143 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +# Author: İsmail BAŞARAN +import imp +import os + +from base.Scope import Scope +from base.plugin.Plugin import Plugin +from base.plugin.PluginQueue import PluginQueue +from base.model.PluginKillSignal import PluginKillSignal + +# TODO create base abstract class +class PluginManager(object): + """docstring for PluginManager""" + + # implement logger + def __init__(self): + super(PluginManager, self).__init__() + self.scope = Scope.getInstance() + self.configManager = self.scope.getConfigurationManager() + self.db_service = self.scope.getDbService() + self.plugins = [] + self.pluginQueueDict = dict() + self.logger = self.scope.getLogger() + + #TODO version? + def loadPlugins(self): + """ + This method loads plugins + """ + self.logger.info('[PluginManager] Loading plugins...') + self.plugins = [] + self.logger.debug('[PluginManager] Lookup for possible plugins...') + possibleplugins = os.listdir(self.configManager.get("PLUGIN", "pluginFolderPath")) + self.logger.debug('[PluginManager] Possible plugins.. ' + str(possibleplugins)) + for pname in possibleplugins: + location = os.path.join(self.configManager.get("PLUGIN", "pluginFolderPath"), pname) + if not os.path.isdir(location) or not self.configManager.get("PLUGIN", "mainModuleName") + ".py" in os.listdir(location): + self.logger.debug('It is not a plugin location ! There is no main module - ' + str(location)) + continue + try: + self.loadSinglePlugin(pname) + except Exception as e: + self.logger.error('Exception occured when loading plugin ! Plugin name : ' + str(pname) + ' Exception : ' + str(e)) + self.logger.info('[PluginManager] Loaded plugins successfully.') + + def loadSinglePlugin(self, pluginName): + # TODO check already loaded plugin + self.pluginQueueDict[pluginName] = PluginQueue() + plugin = Plugin(pluginName, self.pluginQueueDict[pluginName]) + plugin.setDaemon(True) + plugin.start() + self.plugins.append(plugin) + + def findCommand(self, pluginName, commandId): + location = os.path.join(self.configManager.get("PLUGIN", "pluginFolderPath"), pluginName) + if os.path.isdir(location) and commandId + ".py" in os.listdir(location): + info = imp.find_module(commandId, [location]) + return imp.load_module(commandId, *info) + else: + self.logger.warning('Command id -' + commandId + ' - not found') + return None + + def processTask(self, task): + try: + if task.plugin.name.lower() in self.pluginQueueDict: + self.pluginQueueDict[task.plugin.name.lower()].put(task, 1) + except Exception as e: + # TODO update task - status to not found command + self.logger.error("[PluginManager] Exception occurred when processing task " + str(e)) + + def reloadPlugins(self): + #TODO + try: + self.logger.info('[PluginManager] Reloading plugins... ') + kill_sgnl = PluginKillSignal() + for p_queue in self.pluginQueueDict: + p_queue.put(kill_sgnl) + self.plugins = [] + self.loadPlugins() + self.logger.info('[PluginManager] Plugin reloaded successfully.') + except Exception as e: + self.logger.error('[PluginManager] Exception occurred when reloading plugins ' + str(e)) + + def findPolicyModule(self, plugin_name): + location = os.path.join(self.configManager.get("PLUGIN", "pluginFolderPath"), plugin_name) + if os.path.isdir(location) and "policy.py" in os.listdir(location): + info = imp.find_module("policy", [location]) + return imp.load_module("policy", *info) + else: + self.logger.warning('[PluginManager] policy.py not found Plugin Name : ' + str(plugin_name)) + return None + + def processPolicy(self, policy): + #TODO do you need username in profile? + + username = policy.username + ahenk_profiles = policy.ahenk_profiles + user_profiles = policy.user_profiles + + if ahenk_profiles is not None: + for profile in ahenk_profiles: + self.process_profile(profile) + + if user_profiles is not None: + for profile in user_profiles: + profile.set_username(username) + self.process_profile(profile) + + def process_profile(self, profile): + try: + plugin = profile.get_plugin() + plugin_name = plugin.name + if plugin_name in self.pluginQueueDict: + self.pluginQueueDict[plugin_name].put(profile, 1) + except Exception as e: + print("Exception occured..") + self.logger.error("Policy profile not processed " + str(profile.plugin.name)) + + def checkPluginExists(self, plugin_name, version=None): + + criteria = ' name=\''+plugin_name+'\'' + if version is not None: + criteria += ' and version=\'' + str(version) + '\'' + result = self.db_service.select('plugin', 'name', criteria) + + if result is None: + return False + else: + return True + + def reloadSinglePlugin(self, pluginName): + # Not implemented yet + + pass + + def checkCommandExist(self, pluginName, commandId): + # Not implemented yet + pass + + def printQueueSize(self): + print("size " + str(len(self.pluginQueueDict))) + diff --git a/opt/ahenk/base/plugin/plugin_manager_factory.py b/opt/ahenk/base/plugin/plugin_manager_factory.py new file mode 100644 index 0000000..9e12aa3 --- /dev/null +++ b/opt/ahenk/base/plugin/plugin_manager_factory.py @@ -0,0 +1,11 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +# Author: İsmail BAŞARAN + +from base.plugin.plugin_manager import PluginManager + +class PluginManagerFactory(object): + + def get_instance(): + return PluginManager() + get_instance = staticmethod(get_instance) \ No newline at end of file