Conductor errors if enabled_drivers are not found
The conductor service should fail during startup if a configured driver, eg. one that is specified in "enabled_drivers", is not found. At the moment, it merely ignores missing drivers. In addition to adding a check that all configured drivers are loaded, this patch re-arranges some of the initialization of ConductorManager such that an exception during init_host() does not result in secondary exceptions being logged and obfuscating the cause, namely, that no drivers were loaded. Closes-bug: #1417954 Change-Id: I6a96f4b49891c92859479656fe36d2bbd38fe602
This commit is contained in:
parent
e4d2622c86
commit
a53a003030
@ -124,6 +124,17 @@ class DriverFactory(object):
|
|||||||
_check_func,
|
_check_func,
|
||||||
invoke_on_load=True,
|
invoke_on_load=True,
|
||||||
on_load_failure_callback=_catch_driver_not_found))
|
on_load_failure_callback=_catch_driver_not_found))
|
||||||
|
|
||||||
|
# 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) !=
|
||||||
|
sorted(cls._extension_manager.names())):
|
||||||
|
found = cls._extension_manager.names()
|
||||||
|
names = [n for n in CONF.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)
|
||||||
|
|
||||||
LOG.info(_LI("Loaded the following drivers: %s"),
|
LOG.info(_LI("Loaded the following drivers: %s"),
|
||||||
cls._extension_manager.names())
|
cls._extension_manager.names())
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ class DHCPNotFound(NotFound):
|
|||||||
|
|
||||||
|
|
||||||
class DriverNotFound(NotFound):
|
class DriverNotFound(NotFound):
|
||||||
message = _("Failed to load driver %(driver_name)s.")
|
message = _("Could not find the following driver(s): %(driver_name)s.")
|
||||||
|
|
||||||
|
|
||||||
class ImageNotFound(NotFound):
|
class ImageNotFound(NotFound):
|
||||||
|
@ -64,17 +64,19 @@ class RPCService(service.Service):
|
|||||||
def start(self):
|
def start(self):
|
||||||
super(RPCService, self).start()
|
super(RPCService, self).start()
|
||||||
admin_context = context.RequestContext('admin', 'admin', is_admin=True)
|
admin_context = context.RequestContext('admin', 'admin', is_admin=True)
|
||||||
self.manager.init_host()
|
|
||||||
self.tg.add_dynamic_timer(
|
|
||||||
self.manager.periodic_tasks,
|
|
||||||
periodic_interval_max=cfg.CONF.periodic_interval,
|
|
||||||
context=admin_context)
|
|
||||||
|
|
||||||
target = messaging.Target(topic=self.topic, server=self.host)
|
target = messaging.Target(topic=self.topic, server=self.host)
|
||||||
endpoints = [self.manager]
|
endpoints = [self.manager]
|
||||||
serializer = objects_base.IronicObjectSerializer()
|
serializer = objects_base.IronicObjectSerializer()
|
||||||
self.rpcserver = rpc.get_server(target, endpoints, serializer)
|
self.rpcserver = rpc.get_server(target, endpoints, serializer)
|
||||||
self.rpcserver.start()
|
self.rpcserver.start()
|
||||||
|
|
||||||
|
self.manager.init_host()
|
||||||
|
self.tg.add_dynamic_timer(
|
||||||
|
self.manager.periodic_tasks,
|
||||||
|
periodic_interval_max=cfg.CONF.periodic_interval,
|
||||||
|
context=admin_context)
|
||||||
|
|
||||||
LOG.info(_LI('Created RPC server for service %(service)s on host '
|
LOG.info(_LI('Created RPC server for service %(service)s on host '
|
||||||
'%(host)s.'),
|
'%(host)s.'),
|
||||||
{'service': self.topic, 'host': self.host})
|
{'service': self.topic, 'host': self.host})
|
||||||
|
@ -202,7 +202,20 @@ class ConductorManager(periodic_task.PeriodicTasks):
|
|||||||
def init_host(self):
|
def init_host(self):
|
||||||
self.dbapi = dbapi.get_instance()
|
self.dbapi = dbapi.get_instance()
|
||||||
|
|
||||||
|
self._keepalive_evt = threading.Event()
|
||||||
|
"""Event for the keepalive thread."""
|
||||||
|
|
||||||
|
self._worker_pool = greenpool.GreenPool(
|
||||||
|
size=CONF.conductor.workers_pool_size)
|
||||||
|
"""GreenPool of background workers for performing tasks async."""
|
||||||
|
|
||||||
|
self.ring_manager = hash.HashRingManager()
|
||||||
|
"""Consistent hash ring which maps drivers to conductors."""
|
||||||
|
|
||||||
|
# NOTE(deva): instantiating DriverFactory may raise DriverLoadError
|
||||||
|
# or DriverNotFound
|
||||||
self._driver_factory = driver_factory.DriverFactory()
|
self._driver_factory = driver_factory.DriverFactory()
|
||||||
|
"""Driver factory loads all enabled drivers."""
|
||||||
|
|
||||||
self.drivers = self._driver_factory.names
|
self.drivers = self._driver_factory.names
|
||||||
"""List of driver names which this conductor supports."""
|
"""List of driver names which this conductor supports."""
|
||||||
@ -241,16 +254,8 @@ class ConductorManager(periodic_task.PeriodicTasks):
|
|||||||
update_existing=True)
|
update_existing=True)
|
||||||
self.conductor = cdr
|
self.conductor = cdr
|
||||||
|
|
||||||
self.ring_manager = hash.HashRingManager()
|
|
||||||
"""Consistent hash ring which maps drivers to conductors."""
|
|
||||||
|
|
||||||
self._worker_pool = greenpool.GreenPool(
|
|
||||||
size=CONF.conductor.workers_pool_size)
|
|
||||||
"""GreenPool of background workers for performing tasks async."""
|
|
||||||
|
|
||||||
# Spawn a dedicated greenthread for the keepalive
|
# Spawn a dedicated greenthread for the keepalive
|
||||||
try:
|
try:
|
||||||
self._keepalive_evt = threading.Event()
|
|
||||||
self._spawn_worker(self._conductor_service_record_keepalive)
|
self._spawn_worker(self._conductor_service_record_keepalive)
|
||||||
LOG.info(_LI('Successfuly started conductor with hostname '
|
LOG.info(_LI('Successfuly started conductor with hostname '
|
||||||
'%(hostname)s.'),
|
'%(hostname)s.'),
|
||||||
|
@ -58,4 +58,4 @@ class DriverLoadTestCase(base.TestCase):
|
|||||||
with mock.patch.object(dispatch.NameDispatchExtensionManager,
|
with mock.patch.object(dispatch.NameDispatchExtensionManager,
|
||||||
'__init__', self._fake_init_driver_err):
|
'__init__', self._fake_init_driver_err):
|
||||||
driver_factory.DriverFactory._init_extension_manager()
|
driver_factory.DriverFactory._init_extension_manager()
|
||||||
mock_em.assert_called_once_with()
|
self.assertEqual(2, mock_em.call_count)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user