summaryrefslogtreecommitdiffstats
path: root/openstack/common/plugin/pluginmanager.py
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-07-11 21:02:48 +0000
committerGerrit Code Review <review@openstack.org>2012-07-11 21:02:48 +0000
commit289a0b328b96693944faf69b43124d4449cdbded (patch)
treee83bb1a51d6f0a94d9f151336db38a16209e3442 /openstack/common/plugin/pluginmanager.py
parent92650ab9e9c3ed74029d06cfd8fd26e10a1ef940 (diff)
parent856503b064e79bc0daf1d27bf2ce1fa4ecd62160 (diff)
downloadoslo-289a0b328b96693944faf69b43124d4449cdbded.tar.gz
oslo-289a0b328b96693944faf69b43124d4449cdbded.tar.xz
oslo-289a0b328b96693944faf69b43124d4449cdbded.zip
Merge "Add common plugin framework."
Diffstat (limited to 'openstack/common/plugin/pluginmanager.py')
-rw-r--r--openstack/common/plugin/pluginmanager.py86
1 files changed, 86 insertions, 0 deletions
diff --git a/openstack/common/plugin/pluginmanager.py b/openstack/common/plugin/pluginmanager.py
new file mode 100644
index 0000000..0095135
--- /dev/null
+++ b/openstack/common/plugin/pluginmanager.py
@@ -0,0 +1,86 @@
+# Copyright 2012 OpenStack LLC.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import imp
+import os
+import pkg_resources
+
+from openstack.common import cfg
+from openstack.common import log as logging
+from openstack.common.notifier import list_notifier
+
+
+CONF = cfg.CONF
+LOG = logging.getLogger(__name__)
+
+
+class PluginManager(object):
+ """Manages plugin entrypoints and loading.
+
+ For a service to implement this plugin interface for callback purposes:
+
+ - Make use of the openstack-common notifier system
+ - Instantiate this manager in each process (passing in
+ project and service name)
+
+ For an API service to extend itself using this plugin interface,
+ it needs to query the plugin_extension_factory provided by
+ the already-instantiated PluginManager.
+ """
+
+ def __init__(self, project_name, service_name):
+ """ Construct Plugin Manager; load and initialize plugins.
+
+ project_name (e.g. 'nova' or 'glance') is used
+ to construct the entry point that identifies plugins.
+
+ The service_name (e.g. 'compute') is passed on to
+ each plugin as a raw string for it to do what it will.
+ """
+ self._project_name = project_name
+ self._service_name = service_name
+ self.plugins = []
+
+ # Make sure we're using the list_notifier.
+ if not hasattr(CONF, "list_notifier_drivers"):
+ CONF.list_notifier_drivers = []
+ old_notifier = CONF.notification_driver
+ CONF.notification_driver = 'openstack.common.notifier.list_notifier'
+ if (old_notifier and
+ old_notifier != 'openstack.common.notifier.list_notifier'):
+ list_notifier.add_driver(old_notifier)
+
+ def load_plugins(self):
+ self.plugins = []
+
+ for entrypoint in pkg_resources.iter_entry_points('%s.plugin' %
+ self._project_name):
+ try:
+ pluginclass = entrypoint.load()
+ plugin = pluginclass(self._service_name)
+ self.plugins.append(plugin)
+ except Exception, exc:
+ LOG.error(_("Failed to load plugin %(plug)s: %(exc)s") %
+ {'plug': entrypoint, 'exc': exc})
+
+ for plugin in self.plugins:
+ for notifier in plugin.notifiers:
+ list_notifier.add_driver(notifier)
+
+ def plugin_extension_factory(self, ext_mgr):
+ for plugin in self.plugins:
+ descriptors = plugin.api_extension_descriptors
+ for descriptor in descriptors:
+ ext_mgr.load_extension(descriptor)