any_errors_fatal: do not fail unreachable hosts

Fixes #82834

ci_complete
pull/82852/head
Martin Krizek 8 months ago
parent 2bb09bfd12
commit 29cf8b599e

@ -0,0 +1,2 @@
bugfixes:
- any_errors_fatal - fix an issue where errors caused by hosts being unreachable did not always result in a fatal error (https://github.com/ansible/ansible/issues/82834)

@ -371,8 +371,15 @@ class StrategyModule(StrategyBase):
unreachable_hosts.append(res._host.name) unreachable_hosts.append(res._host.name)
if any_errors_fatal and (failed_hosts or unreachable_hosts): if any_errors_fatal and (failed_hosts or unreachable_hosts):
# After processing the task results hosts_left are now outdated,
# use updated failed and unreachable hosts for filtering.
# Note that `failed_hosts` contains hosts that were already
# failed in `_process_pending_results` but are not necessarily
# in `_tqm._failed_hosts` as they may still have to execute
# rescue/always section, so we can't fail them again now.
ignore_hosts = set(failed_hosts).union(self._tqm._failed_hosts, self._tqm._unreachable_hosts)
for host in hosts_left: for host in hosts_left:
if host.name not in failed_hosts: if host.name not in ignore_hosts:
self._tqm._failed_hosts[host.name] = True self._tqm._failed_hosts[host.name] = True
iterator.mark_host_failed(host) iterator.mark_host_failed(host)
display.debug("done checking for any_errors_fatal") display.debug("done checking for any_errors_fatal")
@ -382,6 +389,8 @@ class StrategyModule(StrategyBase):
percentage = iterator._play.max_fail_percentage / 100.0 percentage = iterator._play.max_fail_percentage / 100.0
if (len(self._tqm._failed_hosts) / iterator.batch_size) > percentage: if (len(self._tqm._failed_hosts) / iterator.batch_size) > percentage:
# FIXME hosts_left should also be filtered further on updated
# host statuses as with any_errors_fatal above
for host in hosts_left: for host in hosts_left:
# don't double-mark hosts, or the iterator will potentially # don't double-mark hosts, or the iterator will potentially
# fail them out of the rescue/always states # fail them out of the rescue/always states

@ -0,0 +1,13 @@
- hosts: localhost
gather_facts: false
tasks:
- add_host:
hostname: unreachable_host
- hosts: unreachable_host, localhost
gather_facts: false
any_errors_fatal: true
serial:
- 1
tasks:
- command: echo "SHOULD NOT HAPPEN"

@ -49,3 +49,7 @@ ansible-playbook -i inventory "$@" 80981.yml | tee out.txt
[ "$(grep -c 'SHOULD NOT HAPPEN' out.txt)" -eq 0 ] [ "$(grep -c 'SHOULD NOT HAPPEN' out.txt)" -eq 0 ]
[ "$(grep -c 'rescue' out.txt)" -eq 2 ] [ "$(grep -c 'rescue' out.txt)" -eq 2 ]
[ "$(grep -c 'recovered' out.txt)" -eq 2 ] [ "$(grep -c 'recovered' out.txt)" -eq 2 ]
# -v here is intentional as we rely on the output of the command module that is by default not printed
ansible-playbook -i inventory -v "$@" 82834.yml | tee out.txt
[ "$(grep -c 'SHOULD NOT HAPPEN' out.txt)" -eq 0 ]

Loading…
Cancel
Save