summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Krizek <martin.krizek@gmail.com>2020-07-22 23:00:27 +0200
committerGitHub <noreply@github.com>2020-07-22 14:00:27 -0700
commit4170786cd9ef7c91e10cd02245f0ba65c353d978 (patch)
tree176864721a4e97212ef1bf33a9c1f48406ed7680
parent32c818a1c8cc593b712ee4e2eccb3c03a3c1cc54 (diff)
downloadansible-4170786cd9ef7c91e10cd02245f0ba65c353d978.tar.gz
2.10: Detect failure in always block after rescue (#70094) (#70204)
* Detect failure in always block after rescue (#70094) * Detect failure in always block after rescue Fixes #70000 ci_complete * Add more tests (cherry picked from commit 0ed5b7737708127899762ba768af93cae11e116a) * add changelog Co-authored-by: Matt Davis <mrd@redhat.com>
-rw-r--r--changelogs/fragments/70000-playbook-detect-failure-in-always.yml2
-rw-r--r--lib/ansible/executor/play_iterator.py2
-rw-r--r--test/integration/targets/blocks/always_failure_no_rescue_rc.yml13
-rw-r--r--test/integration/targets/blocks/always_failure_with_rescue_rc.yml16
-rw-r--r--test/integration/targets/blocks/always_no_rescue_rc.yml12
-rwxr-xr-xtest/integration/targets/blocks/runme.sh35
6 files changed, 79 insertions, 1 deletions
diff --git a/changelogs/fragments/70000-playbook-detect-failure-in-always.yml b/changelogs/fragments/70000-playbook-detect-failure-in-always.yml
new file mode 100644
index 0000000000..1637e47ffb
--- /dev/null
+++ b/changelogs/fragments/70000-playbook-detect-failure-in-always.yml
@@ -0,0 +1,2 @@
+bugfixes:
+ - playbooks - detect and propagate failures in ``always`` blocks after ``rescue`` (https://github.com/ansible/ansible/issues/70000)
diff --git a/lib/ansible/executor/play_iterator.py b/lib/ansible/executor/play_iterator.py
index c06b232d2b..dccc2a23e4 100644
--- a/lib/ansible/executor/play_iterator.py
+++ b/lib/ansible/executor/play_iterator.py
@@ -489,7 +489,7 @@ class PlayIterator:
elif state.run_state == self.ITERATING_ALWAYS and state.fail_state & self.FAILED_ALWAYS == 0:
return False
else:
- return not state.did_rescue
+ return not (state.did_rescue and state.fail_state & self.FAILED_ALWAYS == 0)
elif state.run_state == self.ITERATING_TASKS and self._check_failed_state(state.tasks_child_state):
cur_block = self._blocks[state.cur_block]
if len(cur_block.rescue) > 0 and state.fail_state & self.FAILED_RESCUE == 0:
diff --git a/test/integration/targets/blocks/always_failure_no_rescue_rc.yml b/test/integration/targets/blocks/always_failure_no_rescue_rc.yml
new file mode 100644
index 0000000000..924643ce0f
--- /dev/null
+++ b/test/integration/targets/blocks/always_failure_no_rescue_rc.yml
@@ -0,0 +1,13 @@
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - block:
+ - name: EXPECTED FAILURE
+ fail:
+ msg: Failure in block
+ always:
+ - name: EXPECTED FAILURE
+ fail:
+ msg: Failure in always
+ - debug:
+ msg: DID NOT RUN
diff --git a/test/integration/targets/blocks/always_failure_with_rescue_rc.yml b/test/integration/targets/blocks/always_failure_with_rescue_rc.yml
new file mode 100644
index 0000000000..f3029cbcc8
--- /dev/null
+++ b/test/integration/targets/blocks/always_failure_with_rescue_rc.yml
@@ -0,0 +1,16 @@
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - block:
+ - name: EXPECTED FAILURE
+ fail:
+ msg: Failure in block
+ rescue:
+ - debug:
+ msg: Rescue
+ always:
+ - name: EXPECTED FAILURE
+ fail:
+ msg: Failure in always
+ - debug:
+ msg: DID NOT RUN
diff --git a/test/integration/targets/blocks/always_no_rescue_rc.yml b/test/integration/targets/blocks/always_no_rescue_rc.yml
new file mode 100644
index 0000000000..a4e864160a
--- /dev/null
+++ b/test/integration/targets/blocks/always_no_rescue_rc.yml
@@ -0,0 +1,12 @@
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - block:
+ - name: EXPECTED FAILURE
+ fail:
+ msg: Failure in block
+ always:
+ - debug:
+ msg: Always
+ - debug:
+ msg: DID NOT RUN
diff --git a/test/integration/targets/blocks/runme.sh b/test/integration/targets/blocks/runme.sh
index f158735611..69f8d04aa1 100755
--- a/test/integration/targets/blocks/runme.sh
+++ b/test/integration/targets/blocks/runme.sh
@@ -39,3 +39,38 @@ env python -c \
[ "$(grep -c 'TEST COMPLETE' block_test.out)" = "$(grep -E '^[0-9]+ plays in' block_test_wo_colors.out | cut -f1 -d' ')" ]
ansible-playbook -vv block_rescue_vars.yml
+
+# https://github.com/ansible/ansible/issues/70000
+set +e
+exit_code=0
+ansible-playbook -vv always_failure_with_rescue_rc.yml > rc_test.out || exit_code=$?
+set -e
+cat rc_test.out
+[ $exit_code -eq 2 ]
+[ "$(grep -c 'Failure in block' rc_test.out )" -eq 1 ]
+[ "$(grep -c 'Rescue' rc_test.out )" -eq 1 ]
+[ "$(grep -c 'Failure in always' rc_test.out )" -eq 1 ]
+[ "$(grep -c 'DID NOT RUN' rc_test.out )" -eq 0 ]
+rm -f rc_test_out
+
+set +e
+exit_code=0
+ansible-playbook -vv always_no_rescue_rc.yml > rc_test.out || exit_code=$?
+set -e
+cat rc_test.out
+[ $exit_code -eq 2 ]
+[ "$(grep -c 'Failure in block' rc_test.out )" -eq 1 ]
+[ "$(grep -c 'Always' rc_test.out )" -eq 1 ]
+[ "$(grep -c 'DID NOT RUN' rc_test.out )" -eq 0 ]
+rm -f rc_test.out
+
+set +e
+exit_code=0
+ansible-playbook -vv always_failure_no_rescue_rc.yml > rc_test.out || exit_code=$?
+set -e
+cat rc_test.out
+[ $exit_code -eq 2 ]
+[ "$(grep -c 'Failure in block' rc_test.out )" -eq 1 ]
+[ "$(grep -c 'Failure in always' rc_test.out )" -eq 1 ]
+[ "$(grep -c 'DID NOT RUN' rc_test.out )" -eq 0 ]
+rm -f rc_test.out