diff options
Diffstat (limited to 'src/mailman/core')
| -rw-r--r-- | src/mailman/core/chains.py | 5 | ||||
| -rw-r--r-- | src/mailman/core/initialize.py | 50 | ||||
| -rw-r--r-- | src/mailman/core/pipelines.py | 6 | ||||
| -rw-r--r-- | src/mailman/core/plugins.py | 41 | ||||
| -rw-r--r-- | src/mailman/core/rules.py | 4 | ||||
| -rw-r--r-- | src/mailman/core/workflows.py | 4 |
6 files changed, 94 insertions, 16 deletions
diff --git a/src/mailman/core/chains.py b/src/mailman/core/chains.py index c251d38bc..48ed82d63 100644 --- a/src/mailman/core/chains.py +++ b/src/mailman/core/chains.py @@ -19,7 +19,7 @@ from mailman.config import config from mailman.interfaces.chain import IChain, LinkAction -from mailman.utilities.modules import add_components +from mailman.utilities.plugins import add_pluggable_components from public import public @@ -89,5 +89,4 @@ def process(mlist, msg, msgdata, start_chain='default-posting-chain'): @public def initialize(): """Set up chains, both built-in and from the database.""" - add_components('mailman.chains', IChain, config.chains) - # XXX Read chains from the database and initialize them. + add_pluggable_components('chains', IChain, config.chains) diff --git a/src/mailman/core/initialize.py b/src/mailman/core/initialize.py index dfa365448..ae9ff623e 100644 --- a/src/mailman/core/initialize.py +++ b/src/mailman/core/initialize.py @@ -26,9 +26,12 @@ by the command line arguments. import os import sys +import warnings +import traceback import mailman.config.config import mailman.core.logging +from mailman.core.i18n import _ from mailman.interfaces.database import IDatabaseFactory from mailman.utilities.modules import call_name from pkg_resources import resource_string as resource_bytes @@ -133,7 +136,7 @@ def initialize_2(debug=False, propagate_logs=None, testing=False): * Database * Logging - * Pre-hook + * Plugin's pre_hook * Rules * Chains * Pipelines @@ -146,10 +149,34 @@ def initialize_2(debug=False, propagate_logs=None, testing=False): """ # Create the queue and log directories if they don't already exist. mailman.core.logging.initialize(propagate_logs) - # Run the pre-hook if there is one. + # Initialize plugins + from mailman.core.plugins import initialize as initialize_plugins + initialize_plugins() + # Check for deprecated features in config. config = mailman.config.config - if config.mailman.pre_hook: + if config.mailman.pre_hook: # pragma: nocover + warnings.warn( + _('The pre_hook configuration value has been replaced by the ' + 'plugins infrastructure.'), UserWarning) call_name(config.mailman.pre_hook) + # Run the plugin pre_hooks, if one fails, disable the offending plugin. + for name in list(config.plugins.keys()): + plugin = config.plugins[name] + try: + plugin.pre_hook() + except: # pragma: nocover + traceback.print_exc() + warnings.warn(_('Plugin $name failed to run its pre_hook,' + 'it will be disabled and its components' + 'wont be loaded.'), RuntimeWarning) + # It failed, push disabling overlay to config. This will stop + # components from being loaded. + config.push(name + '_error', """\ +[plugin.{}] +enable: no + """.format(name)) + # And forget about it. This will stop running its post_hook. + del config.plugins[name] # Instantiate the database class, ensure that it's of the right type, and # initialize it. Then stash the object on our configuration object. utility_name = ('testing' if testing else 'production') @@ -173,12 +200,23 @@ def initialize_2(debug=False, propagate_logs=None, testing=False): def initialize_3(): """Third initialization step. - * Post-hook + * Plugin's post_hook """ - # Run the post-hook if there is one. + # Run the plugin post_hooks config = mailman.config.config - if config.mailman.post_hook: + if config.mailman.post_hook: # pragma: nocover + warnings.warn( + _('The post_hook configuration value has been replaced by the ' + 'plugins infrastructure.'), UserWarning) call_name(config.mailman.post_hook) + for plugin in config.plugins.values(): + try: + plugin.post_hook() + except: # pragma: nocover + # A post_hook may fail, here we just hope for the best that the + # plugin can work even if it post_hook failed as it's components + # are already loaded. + pass @public diff --git a/src/mailman/core/pipelines.py b/src/mailman/core/pipelines.py index 4265d24d1..6e2ad4a27 100644 --- a/src/mailman/core/pipelines.py +++ b/src/mailman/core/pipelines.py @@ -24,7 +24,7 @@ from mailman.config import config from mailman.interfaces.handler import IHandler from mailman.interfaces.pipeline import ( DiscardMessage, IPipeline, RejectMessage) -from mailman.utilities.modules import add_components +from mailman.utilities.plugins import add_pluggable_components from public import public @@ -63,6 +63,6 @@ def process(mlist, msg, msgdata, pipeline_name='built-in'): def initialize(): """Initialize the pipelines.""" # Find all handlers in the registered plugins. - add_components('mailman.handlers', IHandler, config.handlers) + add_pluggable_components('handlers', IHandler, config.handlers) # Set up some pipelines. - add_components('mailman.pipelines', IPipeline, config.pipelines) + add_pluggable_components('pipelines', IPipeline, config.pipelines) diff --git a/src/mailman/core/plugins.py b/src/mailman/core/plugins.py new file mode 100644 index 000000000..e891f380d --- /dev/null +++ b/src/mailman/core/plugins.py @@ -0,0 +1,41 @@ +# Copyright (C) 2008-2017 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. + +"""Various plugin helpers.""" + +from lazr.config import as_boolean +from mailman.config import config +from mailman.interfaces.plugin import IPlugin +from mailman.utilities.modules import find_name +from public import public +from zope.interface.verify import verifyObject + + +@public +def initialize(): + """Initialize all enabled plugins.""" + for name, plugin_config in config.plugin_configs: + plugin_class_path = plugin_config['class'] + if as_boolean(plugin_config.enable) and plugin_class_path: + plugin_class = find_name(plugin_class_path) + plugin = plugin_class() + verifyObject(IPlugin, plugin) + plugin.name = name + assert plugin.name not in config.plugins, ( + 'Duplicate plugin "{}" found in {}'.format( + plugin.name, plugin_class)) + config.plugins[plugin.name] = plugin diff --git a/src/mailman/core/rules.py b/src/mailman/core/rules.py index 8e0d9197c..74934eb99 100644 --- a/src/mailman/core/rules.py +++ b/src/mailman/core/rules.py @@ -19,7 +19,7 @@ from mailman.config import config from mailman.interfaces.rules import IRule -from mailman.utilities.modules import add_components +from mailman.utilities.plugins import add_pluggable_components from public import public @@ -27,4 +27,4 @@ from public import public def initialize(): """Find and register all rules in all plugins.""" # Find rules in plugins. - add_components('mailman.rules', IRule, config.rules) + add_pluggable_components('rules', IRule, config.rules) diff --git a/src/mailman/core/workflows.py b/src/mailman/core/workflows.py index b16da7df9..4581956d2 100644 --- a/src/mailman/core/workflows.py +++ b/src/mailman/core/workflows.py @@ -19,14 +19,14 @@ from mailman.config import config from mailman.interfaces.workflows import IWorkflow -from mailman.utilities.modules import find_components +from mailman.utilities.plugins import find_pluggable_components from public import public @public def initialize(): """Find and register all workflows in all plugins.""" - for workflow in find_components('mailman.workflows', IWorkflow): + for workflow in find_pluggable_components('workflows', IWorkflow): assert workflow.name not in config.workflows, ( 'Duplicate key "{}" found in {}: "{}"'.format( workflow.name, config.workflows, |
