linear: fix included handlers executing in lockstep (#83209) (#83528)

Fixes #83019

(cherry picked from commit 775bc1110e)
pull/83720/head
Martin Krizek 4 months ago committed by GitHub
parent 1f9dead60f
commit d33bb8ebfd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,2 @@
bugfixes:
- "linear strategy: fix handlers included via ``include_tasks`` handler to be executed in lockstep (https://github.com/ansible/ansible/issues/83019)"

@ -31,7 +31,6 @@ DOCUMENTATION = '''
from ansible import constants as C from ansible import constants as C
from ansible.errors import AnsibleError, AnsibleAssertionError, AnsibleParserError from ansible.errors import AnsibleError, AnsibleAssertionError, AnsibleParserError
from ansible.executor.play_iterator import IteratingStates
from ansible.module_utils.common.text.converters import to_text from ansible.module_utils.common.text.converters import to_text
from ansible.playbook.handler import Handler from ansible.playbook.handler import Handler
from ansible.playbook.included_file import IncludedFile from ansible.playbook.included_file import IncludedFile
@ -46,12 +45,6 @@ display = Display()
class StrategyModule(StrategyBase): class StrategyModule(StrategyBase):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# used for the lockstep to indicate to run handlers
self._in_handlers = False
def _get_next_task_lockstep(self, hosts, iterator): def _get_next_task_lockstep(self, hosts, iterator):
''' '''
Returns a list of (host, task) tuples, where the task may Returns a list of (host, task) tuples, where the task may
@ -73,19 +66,7 @@ class StrategyModule(StrategyBase):
if not state_task_per_host: if not state_task_per_host:
return [(h, None) for h in hosts] return [(h, None) for h in hosts]
if self._in_handlers and not any(filter( task_uuids = {t._uuid for s, t in state_task_per_host.values()}
lambda rs: rs == IteratingStates.HANDLERS,
(s.run_state for s, dummy in state_task_per_host.values()))
):
self._in_handlers = False
if self._in_handlers:
lowest_cur_handler = min(
s.cur_handlers_task for s, t in state_task_per_host.values()
if s.run_state == IteratingStates.HANDLERS
)
else:
task_uuids = [t._uuid for s, t in state_task_per_host.values()]
_loop_cnt = 0 _loop_cnt = 0
while _loop_cnt <= 1: while _loop_cnt <= 1:
try: try:
@ -106,19 +87,14 @@ class StrategyModule(StrategyBase):
host_tasks = [] host_tasks = []
for host, (state, task) in state_task_per_host.items(): for host, (state, task) in state_task_per_host.items():
if ((self._in_handlers and lowest_cur_handler == state.cur_handlers_task) or if cur_task._uuid == task._uuid:
(not self._in_handlers and cur_task._uuid == task._uuid)):
iterator.set_state_for_host(host.name, state) iterator.set_state_for_host(host.name, state)
host_tasks.append((host, task)) host_tasks.append((host, task))
else: else:
host_tasks.append((host, noop_task)) host_tasks.append((host, noop_task))
# once hosts synchronize on 'flush_handlers' lockstep enters if cur_task.action in C._ACTION_META and cur_task.args.get('_raw_params') == 'flush_handlers':
# '_in_handlers' phase where handlers are run instead of tasks iterator.all_tasks[iterator.cur_task:iterator.cur_task] = [h for b in iterator._play.handlers for h in b.block]
# until at least one host is in IteratingStates.HANDLERS
if (not self._in_handlers and cur_task.action in C._ACTION_META and
cur_task.args.get('_raw_params') == 'flush_handlers'):
self._in_handlers = True
return host_tasks return host_tasks

@ -0,0 +1,6 @@
- include_tasks: handlers_lockstep_83019-include-nested.yml
when: inventory_hostname == "A"
- name: handler2
debug:
msg: handler2

@ -0,0 +1,8 @@
- hosts: A,B
gather_facts: false
tasks:
- command: echo
notify: handler
handlers:
- name: handler
include_tasks: handlers_lockstep_83019-include.yml

@ -219,3 +219,6 @@ ansible-playbook 82241.yml -i inventory.handlers "$@" 2>&1 | tee out.txt
ansible-playbook handlers_lockstep_82307.yml -i inventory.handlers "$@" 2>&1 | tee out.txt ansible-playbook handlers_lockstep_82307.yml -i inventory.handlers "$@" 2>&1 | tee out.txt
[ "$(grep out.txt -ce 'TASK \[handler2\]')" = "0" ] [ "$(grep out.txt -ce 'TASK \[handler2\]')" = "0" ]
ansible-playbook handlers_lockstep_83019.yml -i inventory.handlers "$@" 2>&1 | tee out.txt
[ "$(grep out.txt -ce 'TASK \[handler1\]')" = "0" ]

Loading…
Cancel
Save