Merge "added option to skip hooks"
This commit is contained in:
commit
1440acd60e
@ -213,6 +213,24 @@ you could do the following::
|
|||||||
|
|
||||||
The sequence number for the ``foo.yml`` playbook is ``10``.
|
The sequence number for the ``foo.yml`` playbook is ``10``.
|
||||||
|
|
||||||
|
Hook execution can be disabled with ``--skip-hooks``. ``--skip-hooks all`` will halt hook execution altogether.
|
||||||
|
``--skip-hooks <pattern>`` will skip playbooks matching the ``<pattern>``.
|
||||||
|
|
||||||
|
For example, if the following playbooks exist:
|
||||||
|
|
||||||
|
- ``$KAYOBE_CONFIG_PATH/hooks/control-host-bootstrap/pre.d/example1.yml``
|
||||||
|
- ``$KAYOBE_CONFIG_PATH/hooks/control-host-bootstrap/pre.d/example2.yml``
|
||||||
|
- ``$KAYOBE_CONFIG_PATH/hooks/control-host-bootstrap/post.d/example1.yml``
|
||||||
|
|
||||||
|
And the following command is used::
|
||||||
|
|
||||||
|
(kayobe) $ kayobe control host bootstrap --skip-hooks example1
|
||||||
|
|
||||||
|
Only ``$KAYOBE_CONFIG_PATH/hooks/control-host-bootstrap/pre.d/example2.yml`` will be executed.
|
||||||
|
|
||||||
|
This example assumes that the term ``example1`` does not appear in
|
||||||
|
``$KAYOBE_CONFIG_PATH``. If it did, all hooks would be skipped.
|
||||||
|
|
||||||
Failure handling
|
Failure handling
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
@ -77,6 +77,9 @@ def add_args(parser):
|
|||||||
action="store_true",
|
action="store_true",
|
||||||
help="only print names of tasks, don't run them, "
|
help="only print names of tasks, don't run them, "
|
||||||
"note this has no affect on kolla-ansible.")
|
"note this has no affect on kolla-ansible.")
|
||||||
|
parser.add_argument("-sh", "--skip-hooks", action="store", default=None,
|
||||||
|
help="disables hooks. Specify a pattern to skip"
|
||||||
|
"specific playbooks. \"all\" skips all playbooks")
|
||||||
|
|
||||||
|
|
||||||
def _get_kayobe_environment_path(parsed_args):
|
def _get_kayobe_environment_path(parsed_args):
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
import glob
|
import glob
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from cliff.command import Command
|
from cliff.command import Command
|
||||||
@ -190,18 +191,27 @@ class HookDispatcher(CommandHook):
|
|||||||
self.logger.debug("Discovered the following hooks: %s" % hooks)
|
self.logger.debug("Discovered the following hooks: %s" % hooks)
|
||||||
return hooks
|
return hooks
|
||||||
|
|
||||||
def hooks(self, config_path, target):
|
def hooks(self, config_path, target, filter):
|
||||||
hooks = self._find_hooks(config_path, target)
|
hooks_out = []
|
||||||
|
if filter == "all":
|
||||||
|
self.logger.debug("Skipping all hooks")
|
||||||
|
return hooks_out
|
||||||
|
hooks_in = self._find_hooks(config_path, target)
|
||||||
# Hooks can be prefixed with a sequence number to adjust running order,
|
# Hooks can be prefixed with a sequence number to adjust running order,
|
||||||
# e.g 10-my-custom-playbook.yml. Sort by sequence number.
|
# e.g 10-my-custom-playbook.yml. Sort by sequence number.
|
||||||
hooks = sorted(hooks, key=_split_hook_sequence_number)
|
hooks_in = sorted(hooks_in, key=_split_hook_sequence_number)
|
||||||
|
for hook in hooks_in:
|
||||||
# Resolve symlinks so that we can reference roles.
|
# Resolve symlinks so that we can reference roles.
|
||||||
hooks = [os.path.realpath(hook) for hook in hooks]
|
hook = os.path.realpath(hook)
|
||||||
return hooks
|
if filter and re.search(filter, hook):
|
||||||
|
self.logger.debug("Skipping hook: %s", hook)
|
||||||
|
else:
|
||||||
|
hooks_out.append(hook)
|
||||||
|
return hooks_out
|
||||||
|
|
||||||
def run_hooks(self, parsed_args, target):
|
def run_hooks(self, parsed_args, target):
|
||||||
config_path = parsed_args.config_path
|
config_path = parsed_args.config_path
|
||||||
hooks = self.hooks(config_path, target)
|
hooks = self.hooks(config_path, target, parsed_args.skip_hooks)
|
||||||
if hooks:
|
if hooks:
|
||||||
self.logger.debug("Running hooks: %s" % hooks)
|
self.logger.debug("Running hooks: %s" % hooks)
|
||||||
self.command.run_kayobe_playbooks(parsed_args, hooks)
|
self.command.run_kayobe_playbooks(parsed_args, hooks)
|
||||||
|
@ -2506,5 +2506,47 @@ class TestHookDispatcher(unittest.TestCase):
|
|||||||
"z-test-alphabetical.yml",
|
"z-test-alphabetical.yml",
|
||||||
]
|
]
|
||||||
mock_path.realpath.side_effect = lambda x: x
|
mock_path.realpath.side_effect = lambda x: x
|
||||||
actual = dispatcher.hooks("config/path", "pre")
|
actual = dispatcher.hooks("config/path", "pre", None)
|
||||||
|
self.assertListEqual(actual, expected_result)
|
||||||
|
|
||||||
|
@mock.patch('kayobe.cli.commands.os.path')
|
||||||
|
def test_hook_filter_all(self, mock_path):
|
||||||
|
mock_command = mock.MagicMock()
|
||||||
|
dispatcher = commands.HookDispatcher(command=mock_command)
|
||||||
|
dispatcher._find_hooks = mock.MagicMock()
|
||||||
|
dispatcher._find_hooks.return_value = [
|
||||||
|
"5-hook.yml",
|
||||||
|
"5-multiple-dashes-in-name.yml",
|
||||||
|
"10-before-hook.yml",
|
||||||
|
"10-hook.yml",
|
||||||
|
"no-prefix.yml",
|
||||||
|
"z-test-alphabetical.yml",
|
||||||
|
]
|
||||||
|
mock_path.realpath.side_effect = lambda x: x
|
||||||
|
actual = dispatcher.hooks("config/path", "pre", "all")
|
||||||
|
self.assertListEqual(actual, [])
|
||||||
|
|
||||||
|
@mock.patch('kayobe.cli.commands.os.path')
|
||||||
|
def test_hook_filter_one(self, mock_path):
|
||||||
|
mock_command = mock.MagicMock()
|
||||||
|
dispatcher = commands.HookDispatcher(command=mock_command)
|
||||||
|
dispatcher._find_hooks = mock.MagicMock()
|
||||||
|
dispatcher._find_hooks.return_value = [
|
||||||
|
"5-hook.yml",
|
||||||
|
"5-multiple-dashes-in-name.yml",
|
||||||
|
"10-before-hook.yml",
|
||||||
|
"10-hook.yml",
|
||||||
|
"no-prefix.yml",
|
||||||
|
"z-test-alphabetical.yml",
|
||||||
|
]
|
||||||
|
expected_result = [
|
||||||
|
"5-hook.yml",
|
||||||
|
"10-before-hook.yml",
|
||||||
|
"10-hook.yml",
|
||||||
|
"no-prefix.yml",
|
||||||
|
"z-test-alphabetical.yml",
|
||||||
|
]
|
||||||
|
mock_path.realpath.side_effect = lambda x: x
|
||||||
|
actual = dispatcher.hooks("config/path", "pre",
|
||||||
|
"5-multiple-dashes-in-name.yml")
|
||||||
self.assertListEqual(actual, expected_result)
|
self.assertListEqual(actual, expected_result)
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds the --skip-hooks argument to ignore hooks for the execution of a
|
||||||
|
command. See `story 2009241
|
||||||
|
<https://storyboard.openstack.org/#!/story/2009241>`_ for details.
|
Loading…
Reference in New Issue
Block a user