Fail conductor startup if invalid defaults exist
This causes the conductor to fail to start up if a default interface implementation cannot be found for any dynamic driver. This avoids problems later where building a task object to operate on a node could fail for the same reason. This also removes a RAID interface test that turned out to be an invalid test, but we couldn't tell it was invalid until we had changed the start up behavior of the conductor. Note that this release note doesn't actually note a change between releases, but rather is mostly for my use when I come back to combine many of the release notes for this feature later. Change-Id: I39d3c30a6beda2e496ff85119281fdf4de191560 Partial-Bug: #1524745
This commit is contained in:
parent
0071c7e1ec
commit
6206c47720
@ -171,7 +171,8 @@ class BaseConductorManager(object):
|
||||
self._register_and_validate_hardware_interfaces(hardware_types)
|
||||
except (exception.DriverLoadError, exception.DriverNotFound,
|
||||
exception.ConductorHardwareInterfacesAlreadyRegistered,
|
||||
exception.InterfaceNotFoundInEntrypoint) as e:
|
||||
exception.InterfaceNotFoundInEntrypoint,
|
||||
exception.NoValidDefaultForInterface) as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_LE('Failed to register hardware types. %s'), e)
|
||||
self.del_host()
|
||||
@ -263,6 +264,8 @@ class BaseConductorManager(object):
|
||||
hardware type object.
|
||||
:raises: ConductorHardwareInterfacesAlreadyRegistered
|
||||
:raises: InterfaceNotFoundInEntrypoint
|
||||
:raises: NoValidDefaultForInterface if the default value cannot be
|
||||
calculated and is not provided in the configuration
|
||||
"""
|
||||
# first unregister, in case we have cruft laying around
|
||||
self.conductor.unregister_all_hardware_interfaces()
|
||||
@ -272,6 +275,9 @@ class BaseConductorManager(object):
|
||||
for interface_type, interface_names in interface_map.items():
|
||||
default_interface = driver_factory.default_interface(
|
||||
ht, interface_type)
|
||||
if default_interface is None:
|
||||
raise exception.NoValidDefaultForInterface(
|
||||
interface_type=interface_type, node=None, driver=ht)
|
||||
self.conductor.register_hardware_interfaces(ht_name,
|
||||
interface_type,
|
||||
interface_names,
|
||||
|
@ -338,6 +338,31 @@ class RegisterInterfacesTestCase(mgr_utils.ServiceSetUpMixin,
|
||||
# we're iterating over dicts, don't worry about order
|
||||
reg_mock.assert_has_calls(expected_calls)
|
||||
|
||||
def test__register_and_validate_no_valid_default(self,
|
||||
esi_mock,
|
||||
default_mock,
|
||||
reg_mock,
|
||||
unreg_mock):
|
||||
# these must be same order as esi_mock side effect
|
||||
hardware_types = collections.OrderedDict((
|
||||
('fake-hardware', fake_hardware.FakeHardware()),
|
||||
))
|
||||
esi_mock.side_effect = [
|
||||
collections.OrderedDict((
|
||||
('management', ['fake', 'noop']),
|
||||
('deploy', ['agent', 'iscsi']),
|
||||
)),
|
||||
]
|
||||
default_mock.return_value = None
|
||||
|
||||
self.assertRaises(
|
||||
exception.NoValidDefaultForInterface,
|
||||
self.service._register_and_validate_hardware_interfaces,
|
||||
hardware_types)
|
||||
|
||||
unreg_mock.assert_called_once_with(mock.ANY)
|
||||
self.assertFalse(reg_mock.called)
|
||||
|
||||
|
||||
class StartConsolesTestCase(mgr_utils.ServiceSetUpMixin,
|
||||
tests_db_base.DbTestCase):
|
||||
|
@ -637,7 +637,6 @@ class VendorPassthruTestCase(mgr_utils.ServiceSetUpMixin,
|
||||
self._test_vendor_passthru_async('fake', None)
|
||||
|
||||
def test_vendor_passthru_async_hw_type(self):
|
||||
self.config(enabled_vendor_interfaces=['fake'])
|
||||
self._test_vendor_passthru_async('fake-hardware', 'fake')
|
||||
|
||||
@mock.patch.object(task_manager.TaskManager, 'upgrade_lock')
|
||||
@ -3845,12 +3844,10 @@ class RaidHardwareTypeTestCases(RaidTestCases):
|
||||
raid_interface = 'fake'
|
||||
|
||||
def test_get_raid_logical_disk_properties_iface_not_supported(self):
|
||||
self.config(enabled_raid_interfaces=[])
|
||||
self._start_service()
|
||||
exc = self.assertRaises(messaging.rpc.ExpectedException,
|
||||
self.service.get_raid_logical_disk_properties,
|
||||
self.context, self.driver_name)
|
||||
self.assertEqual(exception.UnsupportedDriverExtension, exc.exc_info[0])
|
||||
# NOTE(jroll) we don't run this test as get_logical_disk_properties
|
||||
# is supported on all RAID implementations, and we cannot have a
|
||||
# null interface for a hardware type
|
||||
pass
|
||||
|
||||
def test_set_target_raid_config_iface_not_supported(self):
|
||||
# NOTE(jroll): it's impossible for a dynamic driver to have a null
|
||||
@ -4624,7 +4621,8 @@ class ManagerCheckDeployTimeoutsTestCase(mgr_utils.CommonMixIn,
|
||||
|
||||
|
||||
@mgr_utils.mock_record_keepalive
|
||||
class ManagerTestProperties(tests_db_base.DbTestCase):
|
||||
class ManagerTestProperties(mgr_utils.ServiceSetUpMixin,
|
||||
tests_db_base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ManagerTestProperties, self).setUp()
|
||||
@ -4633,7 +4631,7 @@ class ManagerTestProperties(tests_db_base.DbTestCase):
|
||||
def _check_driver_properties(self, driver, expected):
|
||||
mgr_utils.mock_the_extension_manager(driver=driver)
|
||||
self.driver = driver_factory.get_driver(driver)
|
||||
self.service.init_host()
|
||||
self._start_service()
|
||||
properties = self.service.get_driver_properties(self.context, driver)
|
||||
self.assertEqual(sorted(expected), sorted(properties.keys()))
|
||||
|
||||
@ -4753,16 +4751,13 @@ class ManagerTestProperties(tests_db_base.DbTestCase):
|
||||
|
||||
|
||||
@mgr_utils.mock_record_keepalive
|
||||
class ManagerTestHardwareTypeProperties(tests_db_base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ManagerTestHardwareTypeProperties, self).setUp()
|
||||
self.service = manager.ConductorManager('test-host', 'test-topic')
|
||||
class ManagerTestHardwareTypeProperties(mgr_utils.ServiceSetUpMixin,
|
||||
tests_db_base.DbTestCase):
|
||||
|
||||
def _check_hardware_type_properties(self, hardware_type, expected):
|
||||
self.config(enabled_hardware_types=[hardware_type])
|
||||
self.hardware_type = driver_factory.get_hardware_type(hardware_type)
|
||||
self.service.init_host()
|
||||
self._start_service()
|
||||
properties = self.service.get_driver_properties(self.context,
|
||||
hardware_type)
|
||||
self.assertEqual(sorted(expected), sorted(properties.keys()))
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
upgrade:
|
||||
- The conductor will now fail to start up if invalid configuration is
|
||||
provided, such that a default interface implementation for any enabled
|
||||
hardware type cannot be found.
|
Loading…
x
Reference in New Issue
Block a user