Merge "added option to skip hooks"

This commit is contained in:
Zuul 2022-10-12 09:13:46 +00:00 committed by Gerrit Code Review
commit 1440acd60e
5 changed files with 87 additions and 8 deletions

View File

@ -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
---------------- ----------------

View File

@ -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):

View File

@ -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)
# Resolve symlinks so that we can reference roles. for hook in hooks_in:
hooks = [os.path.realpath(hook) for hook in hooks] # Resolve symlinks so that we can reference roles.
return hooks hook = os.path.realpath(hook)
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)

View File

@ -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)

View File

@ -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.