From 4a285808b068c3ec8cfece842d24a8ad690f3bd9 Mon Sep 17 00:00:00 2001 From: Thomas Wang Date: Wed, 5 Jun 2024 00:04:10 +1000 Subject: [PATCH 1/7] quick fix for 83292 > > Co-authored-by: Martin Krizek --- lib/ansible/plugins/strategy/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/plugins/strategy/__init__.py b/lib/ansible/plugins/strategy/__init__.py index efd69efe9b4..7665c8f6ff2 100644 --- a/lib/ansible/plugins/strategy/__init__.py +++ b/lib/ansible/plugins/strategy/__init__.py @@ -600,7 +600,7 @@ class StrategyBase: # 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 original_task.run_once and not original_task.any_errors_fatal: # if we're using run_once, we have to fail every host here for h in self._inventory.get_hosts(iterator._play.hosts): if h.name not in self._tqm._unreachable_hosts: From 6ab80968cc6b6214d5c0a7155648a55e488f3314 Mon Sep 17 00:00:00 2001 From: Thomas Wang Date: Wed, 5 Jun 2024 00:08:04 +1000 Subject: [PATCH 2/7] added some test --- .../targets/any_errors_fatal/83292.yml | 20 +++++++++++++++++++ .../targets/any_errors_fatal/runme.sh | 5 +++++ 2 files changed, 25 insertions(+) create mode 100644 test/integration/targets/any_errors_fatal/83292.yml diff --git a/test/integration/targets/any_errors_fatal/83292.yml b/test/integration/targets/any_errors_fatal/83292.yml new file mode 100644 index 00000000000..027344e0f87 --- /dev/null +++ b/test/integration/targets/any_errors_fatal/83292.yml @@ -0,0 +1,20 @@ + +- hosts: testhost,testhost2 + gather_facts: false + any_errors_fatal: true + tasks: + - block: + - debug: + msg: Some task running for all hosts + - fail: + run_once: true + - name: any_errors_fatal fails all hosts when any of them fails + debug: + msg: SHOULD NOT HAPPEN + rescue: + - name: Rescues both hosts + debug: + msg: rescuedd + - name: You can recover from fatal errors by adding a rescue section to the block. + debug: + msg: recovered diff --git a/test/integration/targets/any_errors_fatal/runme.sh b/test/integration/targets/any_errors_fatal/runme.sh index 55381a73679..2277b9124c1 100755 --- a/test/integration/targets/any_errors_fatal/runme.sh +++ b/test/integration/targets/any_errors_fatal/runme.sh @@ -47,3 +47,8 @@ ansible-playbook -i inventory "$@" 80981.yml | tee out.txt [ "$(grep -c 'SHOULD NOT HAPPEN' out.txt)" -eq 0 ] [ "$(grep -c 'rescuedd' out.txt)" -eq 2 ] [ "$(grep -c 'recovered' out.txt)" -eq 2 ] + +ansible-playbook -i inventory "$@" 83292.yml | tee out.txt +[ "$(grep -c 'SHOULD NOT HAPPEN' out.txt)" -eq 0 ] +[ "$(grep -c 'rescuedd' out.txt)" -eq 2 ] +[ "$(grep -c 'recovered' out.txt)" -eq 2 ] From df047f96df126c455d651c550a5daa6af8601a52 Mon Sep 17 00:00:00 2001 From: Thomas Wang Date: Wed, 5 Jun 2024 00:10:24 +1000 Subject: [PATCH 3/7] added change log --- changelogs/fragments/83292.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelogs/fragments/83292.yml diff --git a/changelogs/fragments/83292.yml b/changelogs/fragments/83292.yml new file mode 100644 index 00000000000..6720247aaea --- /dev/null +++ b/changelogs/fragments/83292.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - Fix the issue of playbook with any_errors_fatal as true, the rescue section only executes on the host where a fail task with run_once as true is triggered, not affecting other hosts as expected.(https://github.com/ansible/ansible/issues/83292) \ No newline at end of file From ddbbb7c6fb8c688b31e25eec3ae9bd6f25683700 Mon Sep 17 00:00:00 2001 From: Thomas Wang Date: Wed, 5 Jun 2024 00:18:40 +1000 Subject: [PATCH 4/7] fix yaml lint --- test/integration/targets/any_errors_fatal/83292.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/targets/any_errors_fatal/83292.yml b/test/integration/targets/any_errors_fatal/83292.yml index 027344e0f87..1f1a83ef842 100644 --- a/test/integration/targets/any_errors_fatal/83292.yml +++ b/test/integration/targets/any_errors_fatal/83292.yml @@ -17,4 +17,4 @@ msg: rescuedd - name: You can recover from fatal errors by adding a rescue section to the block. debug: - msg: recovered + msg: recovered \ No newline at end of file From 0b3de5e03eb61ac8dfd75d6f1ba7b47dbc2ed6e2 Mon Sep 17 00:00:00 2001 From: Thomas Wang Date: Wed, 5 Jun 2024 00:22:39 +1000 Subject: [PATCH 5/7] fix yaml lint --- test/integration/targets/any_errors_fatal/83292.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/integration/targets/any_errors_fatal/83292.yml b/test/integration/targets/any_errors_fatal/83292.yml index 1f1a83ef842..498cbf0941f 100644 --- a/test/integration/targets/any_errors_fatal/83292.yml +++ b/test/integration/targets/any_errors_fatal/83292.yml @@ -1,4 +1,3 @@ - - hosts: testhost,testhost2 gather_facts: false any_errors_fatal: true @@ -17,4 +16,4 @@ msg: rescuedd - name: You can recover from fatal errors by adding a rescue section to the block. debug: - msg: recovered \ No newline at end of file + msg: recovered From 41a84cc1cf7d55274fc16401656cfdab8a900fb6 Mon Sep 17 00:00:00 2001 From: s-hertel <19572925+s-hertel@users.noreply.github.com> Date: Thu, 6 Jun 2024 10:20:53 -0400 Subject: [PATCH 6/7] Update linear to only check any_errors_fatal instead of conflating it with run_once, any_errors_fatal takes precedence --- lib/ansible/plugins/strategy/linear.py | 4 ++-- .../targets/any_errors_fatal/83292.yml | 4 ++-- .../targets/any_errors_fatal/runme.sh | 18 ++++++++++++++---- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/lib/ansible/plugins/strategy/linear.py b/lib/ansible/plugins/strategy/linear.py index 29f94c4699b..ac3a54dfd70 100644 --- a/lib/ansible/plugins/strategy/linear.py +++ b/lib/ansible/plugins/strategy/linear.py @@ -200,7 +200,7 @@ class StrategyModule(StrategyBase): results.extend(self._execute_meta(task, play_context, iterator, host)) if task.args.get('_raw_params', None) not in ('noop', 'reset_connection', 'end_host', 'role_complete', 'flush_handlers'): run_once = True - if (task.any_errors_fatal or run_once) and not task.ignore_errors: + if task.any_errors_fatal and not task.ignore_errors: any_errors_fatal = True else: # handle step if needed, skip meta actions as they are used internally @@ -213,7 +213,7 @@ class StrategyModule(StrategyBase): run_once = templar.template(task.run_once) or action and getattr(action, 'BYPASS_HOST_LOOP', False) - if (task.any_errors_fatal or run_once) and not task.ignore_errors: + if task.any_errors_fatal and not task.ignore_errors: any_errors_fatal = True if not callback_sent: diff --git a/test/integration/targets/any_errors_fatal/83292.yml b/test/integration/targets/any_errors_fatal/83292.yml index 498cbf0941f..179cbeef5b7 100644 --- a/test/integration/targets/any_errors_fatal/83292.yml +++ b/test/integration/targets/any_errors_fatal/83292.yml @@ -1,12 +1,12 @@ - hosts: testhost,testhost2 gather_facts: false - any_errors_fatal: true + any_errors_fatal: "{{ any_errors_fatal | default(omit) }}" tasks: - block: - debug: msg: Some task running for all hosts - fail: - run_once: true + run_once: "{{ run_once | default(omit) }}" - name: any_errors_fatal fails all hosts when any of them fails debug: msg: SHOULD NOT HAPPEN diff --git a/test/integration/targets/any_errors_fatal/runme.sh b/test/integration/targets/any_errors_fatal/runme.sh index 2277b9124c1..c17fc5cb3da 100755 --- a/test/integration/targets/any_errors_fatal/runme.sh +++ b/test/integration/targets/any_errors_fatal/runme.sh @@ -48,7 +48,17 @@ ansible-playbook -i inventory "$@" 80981.yml | tee out.txt [ "$(grep -c 'rescuedd' out.txt)" -eq 2 ] [ "$(grep -c 'recovered' out.txt)" -eq 2 ] -ansible-playbook -i inventory "$@" 83292.yml | tee out.txt -[ "$(grep -c 'SHOULD NOT HAPPEN' out.txt)" -eq 0 ] -[ "$(grep -c 'rescuedd' out.txt)" -eq 2 ] -[ "$(grep -c 'recovered' out.txt)" -eq 2 ] +args=( + "-e any_errors_fatal=true" + "-e run_once=true" + "-e any_errors_fatal=true run_once=true" + "" +) + +for arg in "${args[@]}"; do + ansible-playbook -i inventory "$@" 83292.yml "$arg" | tee out.txt + + [ "$(grep -c 'SHOULD NOT HAPPEN' out.txt)" -eq 0 ] + [ "$(grep -c 'rescuedd' out.txt)" -eq 2 ] + [ "$(grep -c 'recovered' out.txt)" -eq 2 ] +done From dd7dc00e8c6d07cce96a5c7de6a24eef3810a7dc Mon Sep 17 00:00:00 2001 From: s-hertel <19572925+s-hertel@users.noreply.github.com> Date: Thu, 6 Jun 2024 11:03:29 -0400 Subject: [PATCH 7/7] fix syntax for no extra vars --- test/integration/targets/any_errors_fatal/runme.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/integration/targets/any_errors_fatal/runme.sh b/test/integration/targets/any_errors_fatal/runme.sh index c17fc5cb3da..12d487f7679 100755 --- a/test/integration/targets/any_errors_fatal/runme.sh +++ b/test/integration/targets/any_errors_fatal/runme.sh @@ -54,9 +54,12 @@ args=( "-e any_errors_fatal=true run_once=true" "" ) - for arg in "${args[@]}"; do - ansible-playbook -i inventory "$@" 83292.yml "$arg" | tee out.txt + if [ -z "$arg" ]; then + ansible-playbook -i inventory "$@" 83292.yml | tee out.txt + else + ansible-playbook -i inventory "$@" 83292.yml "$arg" | tee out.txt + fi [ "$(grep -c 'SHOULD NOT HAPPEN' out.txt)" -eq 0 ] [ "$(grep -c 'rescuedd' out.txt)" -eq 2 ]