def load(self, name, reload_module=False): """ Load a plugin into memory, this is effectively the Python equivalent of importing it. A reference to the plugin class is kept in :py:attr:`.loaded_plugins`. If the plugin is already loaded, no changes are made. :param str name: The name of the plugin to load. :param bool reload_module: Reload the module to allow changes to take affect. :return: The plugin class. """ self._lock.acquire() if not reload_module and name in self.loaded_plugins: self._lock.release() return module = self.load_module(name, reload_module=reload_module) klass = getattr(module, 'Plugin', None) if klass is None: self._lock.release() self.logger.warning("failed to load plugin '{0}', Plugin class not found".format(name)) raise errors.KingPhisherPluginError(name, 'the Plugin class is missing') if not issubclass(klass, self._plugin_klass): self._lock.release() self.logger.warning("failed to load plugin '{0}', Plugin class is invalid".format(name)) raise errors.KingPhisherPluginError(name, 'the Plugin class is invalid') self.loaded_plugins[name] = klass self.logger.debug("plugin '{0}' has been {1}loaded".format(name, 're' if reload_module else '')) self._lock.release() return klass
def __init__(self, config): self.config = config path = self._get_path() self._server = None super(ServerPluginManager, self).__init__(path, (config,)) for plugin in config.get_if_exists('server.plugins', {}).keys(): # load the plugin try: self.load(plugin) except Exception: self.logger.critical('failed to load plugin: ' + plugin, exc_info=True) raise errors.KingPhisherPluginError(plugin, 'failed to load') # check compatibility klass = self[plugin] for req_type, req_value, req_met in klass.compatibility: req_type = req_type.lower() if req_met: self.logger.debug("plugin '{0}' requirement {1} ({2}) met".format(plugin, req_type, req_value)) continue self.logger.warning("plugin '{0}' unmet requirement {1} ({2})".format(plugin, req_type, req_value)) raise errors.KingPhisherPluginError(plugin, 'failed to meet requirement: ' + req_type) # enable the plugin try: self.enable(plugin) except errors.KingPhisherPluginError as error: raise error except Exception: self.logger.critical('failed to enable plugin: ' + plugin) raise errors.KingPhisherPluginError(plugin, 'failed to enable') signals.db_initialized.connect(self._sig_db_initialized)
def __init__(self, config): self.config = config path = self._get_path() self._server = None super(ServerPluginManager, self).__init__( path, (config, ), config.get_if_exists('server.plugin_library_path')) for plugin in config.get_if_exists('server.plugins', {}).keys(): # load the plugin self._load_plugin(plugin) # check compatibility klass = self[plugin] for req_type, req_value, req_met in klass.compatibility: req_type = req_type.lower() if req_met: self.logger.debug( "plugin '{0}' requirement {1} ({2}) met".format( plugin, req_type, req_value)) continue if req_type == 'required package' and not req_met: self.logger.warning( "plugin '{0}' unmet requirement {1} ({2})".format( plugin, req_type, req_value)) if config.get_if_exists( 'server.plugin_library_path' ) and config.get_if_exists( 'server.plugin_install_requirements'): pip_results = self.install_packages([req_value]) if pip_results is None: self.logger.warning('pip install failed') elif pip_results.status: self.logger.warning( 'pip install failed, exit status: ' + str(pip_results.status)) self.logger.debug('pip error: {}'.format( pip_results.stderr)) else: self._load_plugin(plugin, reload_module=True) else: raise errors.KingPhisherPluginError( plugin, 'failed to meet requirement: ' + req_type) else: self.logger.warning( "plugin '{0}' unmet requirement {1} ({2})".format( plugin, req_type, req_value)) raise errors.KingPhisherPluginError( plugin, 'failed to meet requirement: ' + req_type) try: self.enable(plugin) except errors.KingPhisherPluginError as error: raise error except Exception: self.logger.critical('failed to enable plugin: ' + plugin) raise errors.KingPhisherPluginError(plugin, 'failed to enable') signals.db_initialized.connect(self._sig_db_initialized)
def enable(self, name): """ Enable a plugin by it's name. This will create a new instance of the plugin modules "Plugin" class, passing it the arguments defined in :py:attr:`.plugin_init_args`. A reference to the plugin instance is kept in :py:attr:`.enabled_plugins`. After the instance is created, the plugins :py:meth:`~.PluginBase.initialize` method is called. :param str name: The name of the plugin to enable. :return: The newly created instance. :rtype: :py:class:`.PluginBase` """ self._lock.acquire() klass = self.loaded_plugins[name] if not klass.is_compatible: raise errors.KingPhisherPluginError(name, 'the plugin is incompatible') inst = klass(*self.plugin_init_args) if not inst.initialize(): self.logger.warning( "failed to enable plugin '{0}', initialize check failed". format(name)) self._lock.release() return self.enabled_plugins[name] = inst self._lock.release() return inst
def __init__(self, root_config): self.root_config = root_config """A reference to the main server instance :py:attr:`~king_phisher.server.server.KingPhisherServer.config`.""" self.server = None """A reference to the :py:class:`~king_phisher.server.server.KingPhisherServer` instance. Only available if the instance has been created.""" super(ServerPlugin, self).__init__() for option in self.options: if self.config[option.name] is None: raise errors.KingPhisherPluginError( self.name, 'missing required option: ' + option.name)