From c297ee9b5da91a0054feb2ea6fd971e21e22d4f5 Mon Sep 17 00:00:00 2001 From: Martin Krizek Date: Wed, 18 Jan 2023 23:22:34 +0100 Subject: [PATCH] Correctly count rescued tasks in play stats (#79724) (#79728) Fixes #79711 ci_complete (cherry picked from commit e38b3e64fd5f9bb6c5ca9462150c89f0932fd2c4) --- .../fragments/79711-fix-play-stats-rescued.yml | 2 ++ lib/ansible/executor/play_iterator.py | 2 +- lib/ansible/plugins/strategy/__init__.py | 4 +++- test/integration/targets/blocks/79711.yml | 17 +++++++++++++++++ test/integration/targets/blocks/runme.sh | 9 +++++++++ 5 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/79711-fix-play-stats-rescued.yml create mode 100644 test/integration/targets/blocks/79711.yml diff --git a/changelogs/fragments/79711-fix-play-stats-rescued.yml b/changelogs/fragments/79711-fix-play-stats-rescued.yml new file mode 100644 index 00000000000..db77f5cc492 --- /dev/null +++ b/changelogs/fragments/79711-fix-play-stats-rescued.yml @@ -0,0 +1,2 @@ +bugfixes: + - Correctly count rescued tasks in play recap (https://github.com/ansible/ansible/issues/79711) diff --git a/lib/ansible/executor/play_iterator.py b/lib/ansible/executor/play_iterator.py index 6049b236f14..24497821656 100644 --- a/lib/ansible/executor/play_iterator.py +++ b/lib/ansible/executor/play_iterator.py @@ -571,7 +571,7 @@ class PlayIterator: Given the current HostState state, determines if the current block, or any child blocks, are in rescue mode. ''' - if state.get_current_block().rescue: + if state.run_state == IteratingStates.TASKS and state.get_current_block().rescue: return True if state.tasks_child_state is not None: return self.is_any_block_rescuing(state.tasks_child_state) diff --git a/lib/ansible/plugins/strategy/__init__.py b/lib/ansible/plugins/strategy/__init__.py index 2f04a3f73ff..e3c4b02da67 100644 --- a/lib/ansible/plugins/strategy/__init__.py +++ b/lib/ansible/plugins/strategy/__init__.py @@ -551,6 +551,8 @@ class StrategyBase: role_ran = True ignore_errors = original_task.ignore_errors if not ignore_errors: + # save the current state before failing it for later inspection + state_when_failed = iterator.get_state_for_host(original_host.name) display.debug("marking %s as failed" % original_host.name) if original_task.run_once: # if we're using run_once, we have to fail every host here @@ -568,7 +570,7 @@ class StrategyBase: # if we're iterating on the rescue portion of a block then # we save the failed task in a special var for use # within the rescue/always - if iterator.is_any_block_rescuing(state): + if iterator.is_any_block_rescuing(state_when_failed): self._tqm._stats.increment('rescued', original_host.name) iterator._play._removed_hosts.remove(original_host.name) self._variable_manager.set_nonpersistent_facts( diff --git a/test/integration/targets/blocks/79711.yml b/test/integration/targets/blocks/79711.yml new file mode 100644 index 00000000000..ca9bfbb4986 --- /dev/null +++ b/test/integration/targets/blocks/79711.yml @@ -0,0 +1,17 @@ +- hosts: localhost + gather_facts: false + tasks: + - block: + - block: + - debug: + - name: EXPECTED FAILURE + fail: + rescue: + - debug: + - debug: + - name: EXPECTED FAILURE + fail: + always: + - debug: + always: + - debug: diff --git a/test/integration/targets/blocks/runme.sh b/test/integration/targets/blocks/runme.sh index 06e3ddee830..820107bbe1f 100755 --- a/test/integration/targets/blocks/runme.sh +++ b/test/integration/targets/blocks/runme.sh @@ -127,3 +127,12 @@ rm -f 78612.out ansible-playbook -vv 43191.yml ansible-playbook -vv 43191-2.yml + +# https://github.com/ansible/ansible/issues/79711 +set +e +ANSIBLE_FORCE_HANDLERS=0 ansible-playbook -vv 79711.yml | tee 79711.out +set -e +[ "$(grep -c 'ok=5' 79711.out)" -eq 1 ] +[ "$(grep -c 'failed=1' 79711.out)" -eq 1 ] +[ "$(grep -c 'rescued=1' 79711.out)" -eq 1 ] +rm -f 79711.out