Skip to content

Commit

Permalink
Don't immediately return failed for any_errors_fatal tasks
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jimi-c committed Aug 5, 2016
1 parent 1714279 commit 9c99172
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 7 deletions.
4 changes: 2 additions & 2 deletions lib/ansible/executor/task_queue_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ class TaskQueueManager:
RUN_OK = 0
RUN_ERROR = 1
RUN_FAILED_HOSTS = 2
RUN_UNREACHABLE_HOSTS = 3
RUN_FAILED_BREAK_PLAY = 4
RUN_UNREACHABLE_HOSTS = 4
RUN_FAILED_BREAK_PLAY = 8
RUN_UNKNOWN_ERROR = 255

def __init__(self, inventory, variable_manager, loader, options, passwords, stdout_callback=None, run_additional_callbacks=True, run_tree=False):
Expand Down
8 changes: 6 additions & 2 deletions lib/ansible/plugins/strategy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,18 @@ def __init__(self, tqm):
# 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, int):
result |= handler_result
else:
result &= handler_result

# now update with the hosts (if any) that failed or were
# unreachable during the handler execution phase
Expand Down
8 changes: 5 additions & 3 deletions lib/ansible/plugins/strategy/linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def run(self, iterator, play_context):
'''

# iteratate over each task, while there is one left to run
result = True
result = self._tqm.RUN_OK
work_to_do = True
while work_to_do and not self._tqm._terminated:

Expand Down Expand Up @@ -284,6 +284,7 @@ def run(self, iterator, play_context):
variable_manager=self._variable_manager
)
except AnsibleError as e:
# this is a fatal error, so we abort here regardless of block state
return self._tqm.RUN_ERROR

include_failure = False
Expand Down Expand Up @@ -364,8 +365,9 @@ def run(self, iterator, play_context):
if host.name not in failed_hosts:
self._tqm._failed_hosts[host.name] = True
iterator.mark_host_failed(host)

self._tqm.send_callback('v2_playbook_on_no_hosts_remaining')
return self._tqm.RUN_FAILED_BREAK_PLAY
result |= self._tqm.RUN_FAILED_BREAK_PLAY
display.debug("done checking for any_errors_fatal")

display.debug("checking for max_fail_percentage")
Expand All @@ -380,7 +382,7 @@ def run(self, iterator, play_context):
self._tqm._failed_hosts[host.name] = True
iterator.mark_host_failed(host)
self._tqm.send_callback('v2_playbook_on_no_hosts_remaining')
return self._tqm.RUN_FAILED_BREAK_PLAY
result |= self._tqm.RUN_FAILED_BREAK_PLAY
display.debug("done checking for max_fail_percentage")

except (IOError, EOFError) as e:
Expand Down

0 comments on commit 9c99172

Please sign in to comment.