Fix returning unreachable for looped tasks (#84049)

* Fix returning unreachable for looped tasks

Add tests for ignore_unreachable and loop
pull/84210/head
Sloane Hertel 1 year ago committed by GitHub
parent a3b58fb67c
commit 03acb22f99
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,2 @@
bugfixes:
- Fix returning 'unreachable' for the overall task result. This prevents false positives when a looped task has unignored unreachable items (https://github.com/ansible/ansible/issues/84019).

@ -150,6 +150,7 @@ class TaskExecutor:
if 'unreachable' in item and item['unreachable']:
item_ignore_unreachable = item.pop('_ansible_ignore_unreachable')
if not res.get('unreachable'):
res['unreachable'] = True
self._task.ignore_unreachable = item_ignore_unreachable
elif self._task.ignore_unreachable and not item_ignore_unreachable:
self._task.ignore_unreachable = item_ignore_unreachable

@ -1,6 +1,8 @@
#!/usr/bin/env bash
set -eux
export ANSIBLE_TIMEOUT=1
export ANSIBLE_CONNECTION_PLUGINS=./fake_connectors
# use fake connectors that raise errors at different stages
ansible-playbook test_with_bad_plugins.yml -i inventory -v "$@"
@ -14,3 +16,9 @@ if ansible-playbook test_base_cannot_connect.yml -i inventory -v "$@"; then
else
echo "Connection to nonexistent hosts failed without using ignore_unreachable. Success!"
fi
if ansible-playbook test_base_loop_cannot_connect.yml -i inventory -v "$@" > out.txt; then
echo "Playbook intended to fail succeeded. Connection succeeded to nonexistent host"
exit 1
fi
grep out.txt -e 'ignored=1' | grep 'unreachable=2' | grep 'ok=1'

@ -0,0 +1,41 @@
- hosts: localhost,nonexistent
gather_facts: false
tasks:
- name: Test ignore_unreachable for all items (pass)
ping:
ignore_unreachable: "{{ item.ignore_unreachable }}"
loop:
- ignore_unreachable: true
- ignore_unreachable: true
register: unreachable_ignored
- name: Test ignore_unreachable for second item (fail)
ping:
ignore_unreachable: "{{ item.ignore_unreachable }}"
loop:
- ignore_unreachable: false
- ignore_unreachable: true
register: unreachable_first
- meta: clear_host_errors
- name: Test ignore_unreachable for first item (fail)
ping:
ignore_unreachable: "{{ item.ignore_unreachable }}"
loop:
- ignore_unreachable: true
- ignore_unreachable: false
register: unreachable_last
- meta: clear_host_errors
- assert:
that:
- unreachable_ignored is not unreachable
- unreachable_first["results"][0] is unreachable
- unreachable_first["results"][-1] is not unreachable
- unreachable_first is unreachable
- unreachable_last["results"][-1] is unreachable
- unreachable_last["results"][0] is not unreachable
- unreachable_last is unreachable
when: inventory_hostname == 'nonexistent'
Loading…
Cancel
Save