Log a warning for unsupported drivers and interfaces

This iterates over all loaded drivers/interfaces at factory
initialization time, and looks at an attribute 'supported'. If supported
is not True, a message will be logged that the driver is unsupported,
deprecated, and may be removed in a future release.

This patch marks all drivers as supported, and subsequent patches will
mark specific drivers as unsupported, based on their testing status.

This also changes the NetworkInterface class to inherit from
BaseInterface (to make this work right). That looks like a programming
error when that interface was created.

Change-Id: I6f9fa4f367bd2e14e5992d2e601bfdcf852ef3a4
Partial-Bug: #1526410
This commit is contained in:
Jim Rollenhagen 2016-09-06 22:10:48 +00:00
parent 047fc52a99
commit 0f07436861
3 changed files with 63 additions and 4 deletions

View File

@ -184,7 +184,8 @@ class BaseDriverFactory(object):
cls._entrypoint_name,
_check_func,
invoke_on_load=True,
on_load_failure_callback=_catch_driver_not_found))
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.
@ -197,6 +198,10 @@ class BaseDriverFactory(object):
raise exception.DriverNotFoundInEntrypoint(
driver_name=names, entrypoint=cls._entrypoint_name)
# warn for any untested/unsupported/deprecated drivers or interfaces
cls._extension_manager.map(cls._extension_manager.names(),
_warn_if_unsupported)
LOG.info(_LI("Loaded the following drivers: %s"),
cls._extension_manager.names())
@ -206,6 +211,12 @@ class BaseDriverFactory(object):
return self._extension_manager.names()
def _warn_if_unsupported(ext):
if not ext.obj.supported:
LOG.warning(_LW('Driver "%s" is UNSUPPORTED. It has been deprecated '
'and may be removed in a future release.'), ext.name)
class DriverFactory(BaseDriverFactory):
_entrypoint_name = 'ironic.drivers'
_enabled_driver_list_config_option = 'enabled_drivers'

View File

@ -48,6 +48,13 @@ class BaseDriver(object):
the interfaces are appropriate.
"""
supported = True
"""Indicates if a driver is supported.
This will be set to False for drivers which are untested in first- or
third-party CI, or in the proces of being deprecated.
"""
core_interfaces = []
standard_interfaces = []
@ -166,6 +173,14 @@ class BareDriver(BaseDriver):
class BaseInterface(object):
"""A base interface implementing common functions for Driver Interfaces."""
supported = True
"""Indicates if an interface is supported.
This will be set to False for interfaces which are untested in first- or
third-party CI, or in the proces of being deprecated.
"""
interface_type = 'base'
def __new__(cls, *args, **kwargs):
@ -1021,9 +1036,11 @@ class RAIDInterface(BaseInterface):
@six.add_metaclass(abc.ABCMeta)
class NetworkInterface(object):
class NetworkInterface(BaseInterface):
"""Base class for network interfaces."""
interface_type = 'network'
def get_properties(self):
"""Return the properties of the interface.

View File

@ -65,7 +65,7 @@ class DriverLoadTestCase(base.TestCase):
with mock.patch.object(dispatch.NameDispatchExtensionManager,
'__init__', self._fake_init_driver_err):
driver_factory.DriverFactory._init_extension_manager()
self.assertEqual(2, mock_em.call_count)
self.assertEqual(3, mock_em.call_count)
@mock.patch.object(driver_factory.LOG, 'warning', autospec=True)
def test_driver_duplicated_entry(self, mock_log):
@ -75,6 +75,33 @@ class DriverLoadTestCase(base.TestCase):
['fake'], driver_factory.DriverFactory._extension_manager.names())
self.assertTrue(mock_log.called)
@mock.patch.object(driver_factory, '_warn_if_unsupported')
def test_driver_init_checks_unsupported(self, mock_warn):
self.config(enabled_drivers=['fake'])
driver_factory.DriverFactory._init_extension_manager()
self.assertEqual(
['fake'], driver_factory.DriverFactory._extension_manager.names())
self.assertTrue(mock_warn.called)
class WarnUnsupportedDriversTestCase(base.TestCase):
@mock.patch.object(driver_factory.LOG, 'warning', autospec=True)
def _test__warn_if_unsupported(self, supported, mock_log):
ext = mock.Mock()
ext.obj = mock.Mock()
ext.obj.supported = supported
driver_factory._warn_if_unsupported(ext)
if supported:
self.assertFalse(mock_log.called)
else:
self.assertTrue(mock_log.called)
def test__warn_if_unsupported_with_supported(self):
self._test__warn_if_unsupported(True)
def test__warn_if_unsupported_with_unsupported(self):
self._test__warn_if_unsupported(False)
class GetDriverTestCase(base.TestCase):
def setUp(self):
@ -98,7 +125,8 @@ class NetworkInterfaceFactoryTestCase(db_base.DbTestCase):
driver_factory.NetworkInterfaceFactory._extension_manager = None
self.config(enabled_drivers=['fake'])
def test_build_driver_for_task(self):
@mock.patch.object(driver_factory, '_warn_if_unsupported')
def test_build_driver_for_task(self, mock_warn):
# flat and noop network interfaces are enabled in base test case
factory = driver_factory.NetworkInterfaceFactory
node = obj_utils.create_test_node(self.context, driver='fake',
@ -112,6 +140,9 @@ class NetworkInterfaceFactoryTestCase(db_base.DbTestCase):
factory._entrypoint_name)
self.assertEqual(['flat', 'neutron', 'noop'],
sorted(factory._enabled_driver_list))
# NOTE(jroll) 4 checks, one for the driver we're building and
# one for each of the 3 network interfaces
self.assertEqual(4, mock_warn.call_count)
def test_build_driver_for_task_default_is_none(self):
# flat and noop network interfaces are enabled in base test case