From 7eccab7dc0b8643486b4fad1b857bd20221b838a Mon Sep 17 00:00:00 2001 From: Thomas Herve Date: Fri, 15 Dec 2017 15:01:10 +0100 Subject: [PATCH] Use NamedExtensionManager for drivers Instead of using stevedore NameDispatchExtensionManager and filter the enabled drivers, use NamedExtensionManager with the list of enabled names. That has the benefit of not loading the drivers we don't want. Change-Id: I492a140f22f52a3ddc52b83a774efc8c17e68c20 Closes-Bug: #1738411 --- ironic/common/driver_factory.py | 34 +++++++------------ .../tests/unit/common/test_driver_factory.py | 12 +++---- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/ironic/common/driver_factory.py b/ironic/common/driver_factory.py index 4e9e4fadc2..531e23a296 100644 --- a/ironic/common/driver_factory.py +++ b/ironic/common/driver_factory.py @@ -17,7 +17,7 @@ import collections from oslo_concurrency import lockutils from oslo_log import log -from stevedore import dispatch +from stevedore import named from ironic.common import exception from ironic.common.i18n import _ @@ -495,31 +495,23 @@ class BaseDriverFactory(object): raise exception.DriverLoadError(driver=ep.name, reason=exc) raise exc - def _check_func(ext): - return ext.name in cls._enabled_driver_list - - cls._extension_manager = ( - dispatch.NameDispatchExtensionManager( - cls._entrypoint_name, - _check_func, - invoke_on_load=True, - on_load_failure_callback=_catch_driver_not_found, - propagate_map_exceptions=True)) - - # NOTE(deva): if we were unable to load any configured driver, perhaps - # because it is not present on the system, raise an error. - if (sorted(cls._enabled_driver_list) != - sorted(cls._extension_manager.names())): - found = cls._extension_manager.names() - names = [n for n in cls._enabled_driver_list if n not in found] - # just in case more than one could not be found ... + def missing_callback(names): names = ', '.join(names) raise exception.DriverNotFoundInEntrypoint( names=names, entrypoint=cls._entrypoint_name) + cls._extension_manager = ( + named.NamedExtensionManager( + cls._entrypoint_name, + cls._enabled_driver_list, + invoke_on_load=True, + on_load_failure_callback=_catch_driver_not_found, + propagate_map_exceptions=True, + on_missing_entrypoints_callback=missing_callback)) + # warn for any untested/unsupported/deprecated drivers or interfaces - cls._extension_manager.map(cls._extension_manager.names(), - _warn_if_unsupported) + if cls._enabled_driver_list: + cls._extension_manager.map(_warn_if_unsupported) LOG.info(cls._logging_template, cls._extension_manager.names()) diff --git a/ironic/tests/unit/common/test_driver_factory.py b/ironic/tests/unit/common/test_driver_factory.py index b2aee2279f..daaf7193f9 100644 --- a/ironic/tests/unit/common/test_driver_factory.py +++ b/ironic/tests/unit/common/test_driver_factory.py @@ -14,7 +14,7 @@ import mock from oslo_utils import uuidutils -from stevedore import dispatch +from stevedore import named from ironic.common import driver_factory from ironic.common import exception @@ -45,7 +45,7 @@ class DriverLoadTestCase(db_base.DbTestCase): def test_driver_load_error_if_driver_enabled(self): self.config(enabled_drivers=['fake']) - with mock.patch.object(dispatch.NameDispatchExtensionManager, + with mock.patch.object(named.NamedExtensionManager, '__init__', self._fake_init_driver_err): self.assertRaises( exception.DriverLoadError, @@ -53,20 +53,20 @@ class DriverLoadTestCase(db_base.DbTestCase): def test_wrap_in_driver_load_error_if_driver_enabled(self): self.config(enabled_drivers=['fake']) - with mock.patch.object(dispatch.NameDispatchExtensionManager, + with mock.patch.object(named.NamedExtensionManager, '__init__', self._fake_init_name_err): self.assertRaises( exception.DriverLoadError, driver_factory.DriverFactory._init_extension_manager) - @mock.patch.object(dispatch.NameDispatchExtensionManager, 'names', + @mock.patch.object(named.NamedExtensionManager, 'names', autospec=True) def test_no_driver_load_error_if_driver_disabled(self, mock_em): self.config(enabled_drivers=[]) - with mock.patch.object(dispatch.NameDispatchExtensionManager, + with mock.patch.object(named.NamedExtensionManager, '__init__', self._fake_init_driver_err): driver_factory.DriverFactory._init_extension_manager() - self.assertEqual(3, mock_em.call_count) + self.assertEqual(1, mock_em.call_count) @mock.patch.object(driver_factory.LOG, 'warning', autospec=True) def test_driver_duplicated_entry(self, mock_log):