提交 eb639434 编写于 作者: A Amador Pahim 提交者: GitHub

Merge pull request #1495 from clebergnu/plugins_disable

Plugins: add mechanism to disable installed plugins
......@@ -16,10 +16,12 @@
import sys
from stevedore import ExtensionManager
from stevedore import EnabledExtensionManager
from .settings import settings
class Dispatcher(ExtensionManager):
class Dispatcher(EnabledExtensionManager):
"""
Base dispatcher for various extension types
......@@ -28,10 +30,21 @@ class Dispatcher(ExtensionManager):
def __init__(self, namespace):
self.load_failures = []
super(Dispatcher, self).__init__(namespace=namespace,
check_func=self.enabled,
invoke_on_load=True,
on_load_failure_callback=self.store_load_failure,
propagate_map_exceptions=True)
def enabled(self, extension):
namespace_prefix = 'avocado.plugins.'
if self.namespace.startswith(namespace_prefix):
namespace = self.namespace[len(namespace_prefix):]
else:
namespace = self.namespace
disabled = settings.get_value('plugins', 'disable', key_type=list)
fqn = "%s.%s" % (namespace, extension.entry_point.name)
return fqn not in disabled
@staticmethod
def store_load_failure(manager, entrypoint, exception):
manager.load_failures.append((entrypoint, exception))
......
......@@ -42,13 +42,13 @@ class Plugins(CLICmd):
log = logging.getLogger("avocado.app")
plugin_types = [
(dispatcher.CLICmdDispatcher(),
'Plugins that add new commands (avocado.plugins.cli.cmd):'),
'Plugins that add new commands (cli.cmd):'),
(dispatcher.CLIDispatcher(),
'Plugins that add new options to commands (avocado.plugins.cli):'),
'Plugins that add new options to commands (cli):'),
(dispatcher.JobPrePostDispatcher(),
'Plugins that run before/after the execution of jobs (avocado.plugins.job.prepost):'),
'Plugins that run before/after the execution of jobs (job.prepost):'),
(dispatcher.ResultDispatcher(),
'Plugins that generate job result in different formats (avocado.plugins.result):')
'Plugins that generate job result in different formats (result):')
]
for plugins_active, msg in plugin_types:
log.info(msg)
......
......@@ -81,6 +81,54 @@ to add to your setuptools based `setup.py` file something like::
Then, by running either ``$ python setup.py install`` or ``$ python setup.py
develop`` your plugin should be visible to Avocado.
Fully qualified named for a plugin
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The plugin registry mentioned earlier, (`setuptools`_ and its `entry
points`_) is global to a given Python installation. Avocado uses the
namespace prefix ``avocado.plugins.`` to avoid name clashes with other
software. Now, inside Avocado itself, there's no need keep using the
``avocado.plugins.`` prefix.
Take for instance, the Job Pre/Post plugins are defined on
``setup.py``::
'avocado.plugins.job.prepost': [
'jobscripts = avocado.plugins.jobscripts:JobScripts'
]
The setuptools entry point namespace is composed of the mentioned
prefix ``avocado.plugins.``, which is is then followed by the Avocado
plugin type, in this case, ``job.prepost``.
Inside avocado itself, the fully qualified name for a plugin is the
plugin type, such as ``job.prepost`` concatenated to the name used in
the entry point definition itself, in this case, ``jobscripts``.
To summarize, still using the same example, the fully qualified
Avocado plugin name is going to be ``job.prepost.jobscripts``.
Disabling a plugin
~~~~~~~~~~~~~~~~~~
Even though a plugin can be installed and registered under
`setuptools`_ `entry points`_, it can be explicitly disabled in
Avocado.
The mechanism available to do so is to add entries to the ``disable``
key under the ``plugins`` section of the Avocado configuration file.
Example::
[plugins]
disable = ['cli.hello', 'job.prepost.jobscripts']
The exact effect on Avocado when a plugin is disabled depends on the
plugin type. For instance, by disabling plugins of type ``cli.cmd``,
the command implemented by the plugin should no longer be available on
the Avocado command line application. Now, by disabling a
``job.prepost`` plugin, those won't be executed before/after the
execution of the jobs.
Wrap Up
~~~~~~~
......
......@@ -69,6 +69,9 @@ username =
password =
[plugins]
# Disable listed plugins completely. Use the fully qualified plugin
# name, as described in the Avocado documentation "Plugins" section.
disable = []
# Suppress notification about broken plugins in the app standard error.
# Add the name of each broken plugin you want to suppress the notification
# in the list. The names can be easily seen from the stderr messages. Example:
......
......@@ -877,6 +877,28 @@ class PluginsTest(AbsPluginsTest, unittest.TestCase):
(expected_rc, result))
self.assertNotIn('Disabled', output)
def test_disable_plugin(self):
os.chdir(basedir)
cmd_line = './scripts/avocado plugins'
result = process.run(cmd_line, ignore_status=True)
expected_rc = exit_codes.AVOCADO_ALL_OK
self.assertEqual(result.exit_status, expected_rc,
"Avocado did not return rc %d:\n%s" %
(expected_rc, result))
self.assertIn("Collect system information", result.stdout)
config_content = "[plugins]\ndisable=['cli.cmd.sysinfo',]"
config = script.TemporaryScript("disable_sysinfo_cmd.conf",
config_content)
with config:
cmd_line = './scripts/avocado --config %s plugins' % config
result = process.run(cmd_line, ignore_status=True)
expected_rc = exit_codes.AVOCADO_ALL_OK
self.assertEqual(result.exit_status, expected_rc,
"Avocado did not return rc %d:\n%s" %
(expected_rc, result))
self.assertNotIn("Collect system information", result.stdout)
def test_Namespace_object_has_no_attribute(self):
os.chdir(basedir)
cmd_line = './scripts/avocado plugins'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册