mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-05-07 22:02:50 +00:00
Don't immediately return failed for any_errors_fatal tasks
Instead of immediately returning a failed code (indicating a break in the play execution), we internally 'or' that failure code with the result (now an integer flag instead of a boolean) so that we can properly handle the rescue/always portions of blocks and still remember that the break condition was hit. Fixes #16937
This commit is contained in:
@@ -119,14 +119,18 @@ class StrategyBase:
|
||||
# outstanding tasks still in queue
|
||||
self._blocked_hosts = dict()
|
||||
|
||||
def run(self, iterator, play_context, result=True):
|
||||
def run(self, iterator, play_context, result=0):
|
||||
# save the failed/unreachable hosts, as the run_handlers()
|
||||
# method will clear that information during its execution
|
||||
failed_hosts = iterator.get_failed_hosts()
|
||||
unreachable_hosts = self._tqm._unreachable_hosts.keys()
|
||||
|
||||
display.debug("running handlers")
|
||||
result &= self.run_handlers(iterator, play_context)
|
||||
handler_result = self.run_handlers(iterator, play_context)
|
||||
if isinstance(handler_result, bool) and not handler_result:
|
||||
result |= self._tqm.RUN_ERROR
|
||||
elif not handler_result:
|
||||
result |= handler_result
|
||||
|
||||
# now update with the hosts (if any) that failed or were
|
||||
# unreachable during the handler execution phase
|
||||
@@ -140,8 +144,6 @@ class StrategyBase:
|
||||
return self._tqm.RUN_UNREACHABLE_HOSTS
|
||||
elif len(failed_hosts) > 0:
|
||||
return self._tqm.RUN_FAILED_HOSTS
|
||||
elif isinstance(result, bool) and not result:
|
||||
return self._tqm.RUN_ERROR
|
||||
else:
|
||||
return self._tqm.RUN_OK
|
||||
|
||||
@@ -296,7 +298,11 @@ class StrategyBase:
|
||||
display.debug("marking %s as failed" % original_host.name)
|
||||
if original_task.run_once:
|
||||
# if we're using run_once, we have to fail every host here
|
||||
[iterator.mark_host_failed(h) for h in self._inventory.get_hosts(iterator._play.hosts) if h.name not in self._tqm._unreachable_hosts]
|
||||
for h in self._inventory.get_hosts(iterator._play.hosts):
|
||||
if h.name not in self._tqm._unreachable_hosts:
|
||||
state, _ = iterator.get_next_task_for_host(h, peek=True)
|
||||
iterator.mark_host_failed(h)
|
||||
state, new_task = iterator.get_next_task_for_host(h, peek=True)
|
||||
else:
|
||||
iterator.mark_host_failed(original_host)
|
||||
|
||||
@@ -631,7 +637,7 @@ class StrategyBase:
|
||||
Runs handlers on those hosts which have been notified.
|
||||
'''
|
||||
|
||||
result = True
|
||||
result = self._tqm.RUN_OK
|
||||
|
||||
for handler_block in iterator._play.handlers:
|
||||
# FIXME: handlers need to support the rescue/always portions of blocks too,
|
||||
@@ -671,7 +677,7 @@ class StrategyBase:
|
||||
|
||||
host_results = []
|
||||
for host in notified_hosts:
|
||||
if not handler.has_triggered(host) and (host.name not in self._tqm._failed_hosts or play_context.force_handlers):
|
||||
if not handler.has_triggered(host) and (not iterator.is_failed(host) or play_context.force_handlers):
|
||||
task_vars = self._variable_manager.get_vars(loader=self._loader, play=iterator._play, host=host, task=handler)
|
||||
self.add_tqm_variables(task_vars, play=iterator._play)
|
||||
self._queue_task(host, handler, task_vars, play_context)
|
||||
|
||||
Reference in New Issue
Block a user