diff --git a/lib/ansible/plugins/strategy/linear.py b/lib/ansible/plugins/strategy/linear.py index 29721983cc7..6c27a13787a 100644 --- a/lib/ansible/plugins/strategy/linear.py +++ b/lib/ansible/plugins/strategy/linear.py @@ -265,6 +265,8 @@ 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'): run_once = True + if (task.any_errors_fatal or run_once) and not task.ignore_errors: + any_errors_fatal = True else: # handle step if needed, skip meta actions as they are used internally if self._step and choose_step: @@ -402,7 +404,9 @@ class StrategyModule(StrategyBase): failed_hosts = [] unreachable_hosts = [] for res in results: - if res.is_failed() and iterator.is_failed(res._host): + # execute_meta() does not set 'failed' in the TaskResult + # so we skip checking it with the meta tasks and look just at the iterator + if (res.is_failed() or res._task.action == 'meta') and iterator.is_failed(res._host): failed_hosts.append(res._host.name) elif res.is_unreachable(): unreachable_hosts.append(res._host.name) diff --git a/test/integration/targets/handlers/runme.sh b/test/integration/targets/handlers/runme.sh index 726d8094c7e..fdeb8682750 100755 --- a/test/integration/targets/handlers/runme.sh +++ b/test/integration/targets/handlers/runme.sh @@ -57,3 +57,9 @@ grep -q "ERROR! The requested handler 'notify_inexistent_handler' was not found # Notify inexistent handlers without errors when ANSIBLE_ERROR_ON_MISSING_HANDLER=false ANSIBLE_ERROR_ON_MISSING_HANDLER=false ansible-playbook test_handlers_inexistent_notify.yml -i inventory.handlers -v "$@" +# https://github.com/ansible/ansible/issues/36649 +output_dir=/tmp +set +e +result="$(ansible-playbook test_handlers_any_errors_fatal.yml -e output_dir=$output_dir -i inventory.handlers -v "$@" 2>&1)" +set -e +[ ! -f $output_dir/should_not_exist_B ] || (rm -f $output_dir/should_not_exist_B && exit 1) diff --git a/test/integration/targets/handlers/test_handlers_any_errors_fatal.yml b/test/integration/targets/handlers/test_handlers_any_errors_fatal.yml new file mode 100644 index 00000000000..9029443a6fe --- /dev/null +++ b/test/integration/targets/handlers/test_handlers_any_errors_fatal.yml @@ -0,0 +1,25 @@ +- hosts: + - A + - B + gather_facts: no + any_errors_fatal: yes + connection: local + vars: + output_dir: /tmp + tasks: + - name: Task one + debug: + msg: 'task 1' + changed_when: yes + notify: EXPECTED FAILURE failed_handler + + - meta: flush_handlers + + - name: This task should never happen + file: + path: "{{ output_dir }}/should_not_exist_{{ inventory_hostname }}" + state: touch + handlers: + - name: EXPECTED FAILURE failed_handler + fail: + when: 'inventory_hostname == "A"'