diff --git a/changelogs/fragments/74625-fix-ansible_play_batch-between-plays.yml b/changelogs/fragments/74625-fix-ansible_play_batch-between-plays.yml new file mode 100644 index 00000000000..845bca7117d --- /dev/null +++ b/changelogs/fragments/74625-fix-ansible_play_batch-between-plays.yml @@ -0,0 +1,2 @@ +bugfixes: + - Save unreachable hosts between plays by adding them to the PlayIterator's _play._removed_hosts (https://github.com/ansible/ansible/issues/66945). diff --git a/lib/ansible/executor/task_queue_manager.py b/lib/ansible/executor/task_queue_manager.py index 5647e4e6da5..eaa262d87ae 100644 --- a/lib/ansible/executor/task_queue_manager.py +++ b/lib/ansible/executor/task_queue_manager.py @@ -301,6 +301,8 @@ class TaskQueueManager: for host_name in self._failed_hosts.keys(): host = self._inventory.get_host(host_name) iterator.mark_host_failed(host) + for host_name in self._unreachable_hosts.keys(): + iterator._play._removed_hosts.append(host_name) self.clear_failed_hosts() diff --git a/test/integration/targets/special_vars_hosts/aliases b/test/integration/targets/special_vars_hosts/aliases new file mode 100644 index 00000000000..70a7b7a9f32 --- /dev/null +++ b/test/integration/targets/special_vars_hosts/aliases @@ -0,0 +1 @@ +shippable/posix/group5 diff --git a/test/integration/targets/special_vars_hosts/inventory b/test/integration/targets/special_vars_hosts/inventory new file mode 100644 index 00000000000..8d69e574eb4 --- /dev/null +++ b/test/integration/targets/special_vars_hosts/inventory @@ -0,0 +1,3 @@ +successful ansible_connection=local ansible_host=127.0.0.1 ansible_python_interpreter="{{ ansible_playbook_python }}" +failed ansible_connection=local ansible_host=127.0.0.1 ansible_python_interpreter="{{ ansible_playbook_python }}" +unreachable ansible_connection=ssh ansible_host=127.0.0.1 ansible_port=1011 # IANA Reserved port diff --git a/test/integration/targets/special_vars_hosts/playbook.yml b/test/integration/targets/special_vars_hosts/playbook.yml new file mode 100644 index 00000000000..e3d9e435419 --- /dev/null +++ b/test/integration/targets/special_vars_hosts/playbook.yml @@ -0,0 +1,53 @@ +--- +- hosts: all + gather_facts: no + tasks: + - name: test magic vars for hosts without any failed/unreachable (no serial) + assert: + that: + - ansible_play_batch | length == 3 + - ansible_play_hosts | length == 3 + - ansible_play_hosts_all | length == 3 + run_once: True + + - ping: + failed_when: "inventory_hostname == 'failed'" + + - meta: clear_host_errors + +- hosts: all + gather_facts: no + tasks: + - name: test host errors were cleared + assert: + that: + - ansible_play_batch | length == 3 + - ansible_play_hosts | length == 3 + - ansible_play_hosts_all | length == 3 + run_once: True + + - ping: + failed_when: "inventory_hostname == 'failed'" + + - name: test magic vars exclude failed/unreachable hosts + assert: + that: + - ansible_play_batch | length == 1 + - ansible_play_hosts | length == 1 + - "ansible_play_batch == ['successful']" + - "ansible_play_hosts == ['successful']" + - ansible_play_hosts_all | length == 3 + run_once: True + +- hosts: all + gather_facts: no + tasks: + - name: test failed/unreachable persists between plays + assert: + that: + - ansible_play_batch | length == 1 + - ansible_play_hosts | length == 1 + - "ansible_play_batch == ['successful']" + - "ansible_play_hosts == ['successful']" + - ansible_play_hosts_all | length == 3 + run_once: True diff --git a/test/integration/targets/special_vars_hosts/runme.sh b/test/integration/targets/special_vars_hosts/runme.sh new file mode 100755 index 00000000000..81c1d9be651 --- /dev/null +++ b/test/integration/targets/special_vars_hosts/runme.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -eux + +ansible-playbook -i ./inventory playbook.yml "$@" | tee out.txt +grep 'unreachable=2' out.txt +grep 'failed=2' out.txt