Fix: Duplicated driver causes conductor to fail
This patch is fixing a problem which causes the conductor to get confused and error out on startup in case there's a duplicated entry in the enabled_drivers configuration option. Closes-Bug: #1561564 Change-Id: Ib72bcde9b32d3c0b4b237068aa53146f58ea10a2
This commit is contained in:
parent
62123f1db3
commit
420fe0c5ab
@ -23,6 +23,7 @@ from stevedore import dispatch
|
||||
from ironic.common import exception
|
||||
from ironic.common.i18n import _
|
||||
from ironic.common.i18n import _LI
|
||||
from ironic.common.i18n import _LW
|
||||
from ironic.drivers import base as driver_base
|
||||
|
||||
|
||||
@ -136,6 +137,18 @@ class DriverFactory(object):
|
||||
if cls._extension_manager:
|
||||
return
|
||||
|
||||
# Check for duplicated driver entries and warn the operator
|
||||
# about them
|
||||
counter = collections.Counter(CONF.enabled_drivers).items()
|
||||
duplicated_drivers = list(dup for (dup, i) in counter if i > 1)
|
||||
if duplicated_drivers:
|
||||
LOG.warning(_LW('The driver(s) "%s" is/are duplicated in the '
|
||||
'list of enabled_drivers. Please check your '
|
||||
'configuration file.'),
|
||||
', '.join(duplicated_drivers))
|
||||
|
||||
enabled_drivers = set(CONF.enabled_drivers)
|
||||
|
||||
# NOTE(deva): Drivers raise "DriverLoadError" if they are unable to be
|
||||
# loaded, eg. due to missing external dependencies.
|
||||
# We capture that exception, and, only if it is for an
|
||||
@ -147,13 +160,13 @@ class DriverFactory(object):
|
||||
def _catch_driver_not_found(mgr, ep, exc):
|
||||
# NOTE(deva): stevedore loads plugins *before* evaluating
|
||||
# _check_func, so we need to check here, too.
|
||||
if ep.name in CONF.enabled_drivers:
|
||||
if ep.name in enabled_drivers:
|
||||
if not isinstance(exc, exception.DriverLoadError):
|
||||
raise exception.DriverLoadError(driver=ep.name, reason=exc)
|
||||
raise exc
|
||||
|
||||
def _check_func(ext):
|
||||
return ext.name in CONF.enabled_drivers
|
||||
return ext.name in enabled_drivers
|
||||
|
||||
cls._extension_manager = (
|
||||
dispatch.NameDispatchExtensionManager(
|
||||
@ -164,10 +177,10 @@ class DriverFactory(object):
|
||||
|
||||
# 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(CONF.enabled_drivers) !=
|
||||
if (sorted(enabled_drivers) !=
|
||||
sorted(cls._extension_manager.names())):
|
||||
found = cls._extension_manager.names()
|
||||
names = [n for n in CONF.enabled_drivers if n not in found]
|
||||
names = [n for n in enabled_drivers if n not in found]
|
||||
# just in case more than one could not be found ...
|
||||
names = ', '.join(names)
|
||||
raise exception.DriverNotFound(driver_name=names)
|
||||
|
@ -64,6 +64,14 @@ class DriverLoadTestCase(base.TestCase):
|
||||
driver_factory.DriverFactory._init_extension_manager()
|
||||
self.assertEqual(2, mock_em.call_count)
|
||||
|
||||
@mock.patch.object(driver_factory.LOG, 'warning', autospec=True)
|
||||
def test_driver_duplicated_entry(self, mock_log):
|
||||
self.config(enabled_drivers=['fake', 'fake'])
|
||||
driver_factory.DriverFactory._init_extension_manager()
|
||||
self.assertEqual(
|
||||
['fake'], driver_factory.DriverFactory._extension_manager.names())
|
||||
self.assertTrue(mock_log.called)
|
||||
|
||||
|
||||
class GetDriverTestCase(base.TestCase):
|
||||
def setUp(self):
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
fixes:
|
||||
- Fixes a problem which causes the conductor to error out on startup
|
||||
in case there's a duplicated entry in the enabled_drivers configuration
|
||||
option.
|
Loading…
Reference in New Issue
Block a user