Add callback function to manage missing hooks

Before https://review.openstack.org/#/c/337043/,
stevedore.NamedExtensionManager returned KeyError
when calling with non-existing names and name_order=True.

After the mentioned change this is not longer true,
so we used the just added on_missing_entrypoints_callback option
to customize the behavior in this cases and make it raise
a custom exception MissingHookError.

Change-Id: I1f1edc0b7a82a16bf9be4113db61ee1cd0080db4
Closes-Bug: #1600141
This commit is contained in:
Alfredo Moralejo 2016-07-08 11:11:13 +02:00
parent 5ea04f5002
commit 522113da43
3 changed files with 14 additions and 3 deletions

View File

@ -411,8 +411,9 @@ class Service(object):
hooks = [ext.name for ext in
plugins_base.processing_hooks_manager()]
except KeyError as exc:
# stevedore raises KeyError on missing hook
LOG.critical(_LC('Hook %s failed to load or was not found'),
# callback function raises MissingHookError derived from KeyError
# on missing hook
LOG.critical(_LC('Hook(s) %s failed to load or was not found'),
str(exc))
sys.exit(1)

View File

@ -149,6 +149,12 @@ _CONDITIONS_MGR = None
_ACTIONS_MGR = None
def missing_entrypoints_callback(names):
"""Raise MissingHookError with comma-separated list of missing hooks"""
missing_names = ', '.join(names)
raise MissingHookError(missing_names)
def processing_hooks_manager(*args):
"""Create a Stevedore extension manager for processing hooks.
@ -164,6 +170,7 @@ def processing_hooks_manager(*args):
names=names,
invoke_on_load=True,
invoke_args=args,
on_missing_entrypoints_callback=missing_entrypoints_callback,
name_order=True)
return _HOOKS_MGR
@ -204,3 +211,7 @@ def rule_actions_manager():
'actions is deprecated (action "%s")'),
act.name)
return _ACTIONS_MGR
class MissingHookError(KeyError):
"""Exception when hook is not found when processing it."""

View File

@ -626,7 +626,6 @@ class TestInit(test_base.BaseTest):
self.service.init()
self.assertFalse(mock_firewall.called)
@unittest.skip('skipped until stevedore > 1.15.0 is released')
@mock.patch.object(main.LOG, 'critical')
def test_init_failed_processing_hook(self, mock_log, mock_node_cache,
mock_get_client, mock_auth,