Skip to content

Commit

Permalink
Allow any_errors_fatal to be dynamic
Browse files Browse the repository at this point in the history
This change updates the linear and free strategies to ensure that the
value of any_errors_fatal is properly evaulated if it contains a dynamic
value. Previously if it was not set to a boolean false, it would be
true.

Fixes #61025
  • Loading branch information
mwhahaha committed Jul 16, 2020
1 parent 8c213c9 commit 5e8f049
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 6 deletions.
7 changes: 6 additions & 1 deletion lib/ansible/plugins/strategy/free.py
Expand Up @@ -195,7 +195,12 @@ def run(self, iterator, play_context):
else:
# handle step if needed, skip meta actions as they are used internally
if not self._step or self._take_step(task, host_name):
if task.any_errors_fatal:
task_any_errors_fatal = task.get_validated_value('any_errors_fatal',
task._valid_attrs['any_errors_fatal'],
templar.template(task.any_errors_fatal),
None)

if task_any_errors_fatal:
display.warning("Using any_errors_fatal with the free strategy is not supported, "
"as tasks are executed independently on each host")
self._tqm.send_callback('v2_playbook_on_task_start', task, is_conditional=False)
Expand Down
9 changes: 7 additions & 2 deletions lib/ansible/plugins/strategy/linear.py
Expand Up @@ -269,13 +269,18 @@ def run(self, iterator, play_context):
# corresponding action plugin
action = None

task_any_errors_fatal = task.get_validated_value('any_errors_fatal',
task._valid_attrs['any_errors_fatal'],
templar.template(task.any_errors_fatal),
None)

if task.action == 'meta':
# for the linear strategy, we run meta tasks just once and for
# all hosts currently being iterated over rather than one host
results.extend(self._execute_meta(task, play_context, iterator, host))
if task.args.get('_raw_params', None) not in ('noop', 'reset_connection', 'end_host'):
run_once = True
if (task.any_errors_fatal or run_once) and not task.ignore_errors:
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
Expand All @@ -288,7 +293,7 @@ def run(self, iterator, play_context):

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 or run_once) and not task.ignore_errors:
any_errors_fatal = True

if not callback_sent:
Expand Down
@@ -0,0 +1,12 @@
- hosts: all
gather_facts: false
any_errors_fatal: false
ignore_unreachable: true
vars:
skip_errors: "silliness"
tasks:
- block:
- shell: '{{ "/bin/false" if inventory_hostname == "testhost" else "/bin/true" }}'
- debug:
msg: "any_errors_fatal_dynamic_value_continues"
any_errors_fatal: "{{ skip_errors }}"
12 changes: 12 additions & 0 deletions test/integration/targets/any_errors_fatal/61025-dynamic_block.yml
@@ -0,0 +1,12 @@
- hosts: all
gather_facts: false
any_errors_fatal: false
ignore_unreachable: true
vars:
skip_errors: true
tasks:
- block:
- shell: '{{ "/bin/false" if inventory_hostname == "testhost" else "/bin/true" }}'
- debug:
msg: "any_errors_fatal_dynamic_value_continues"
any_errors_fatal: "{{ not skip_errors }}"
@@ -0,0 +1,3 @@
- import_playbook: dynamic_playbook.yml
vars:
skip_errors: true
@@ -0,0 +1,7 @@
- hosts: all
gather_facts: false
any_errors_fatal: "{{ not skip_errors }}"
tasks:
- shell: '{{ "/bin/false" if inventory_hostname == "testhost" else "/bin/true" }}'
- debug:
msg: "any_errors_fatal_dynamic_value_import_playbook_continues"
27 changes: 24 additions & 3 deletions test/integration/targets/any_errors_fatal/runme.sh
Expand Up @@ -15,9 +15,30 @@ if [ "${res}" -eq 0 ] ; then
exit 1
fi

set -ux

ansible-playbook -i inventory "$@" always_block.yml | tee out.txt | grep 'any_errors_fatal_always_block_start'
res=$?
cat out.txt
exit $res
if [ "${res}" -ne 0 ] ; then
exit 1
fi

ansible-playbook -i inventory "$@" 61025-dynamic_block.yml | tee out.txt | grep 'any_errors_fatal_dynamic_value_continues'
res=$?
cat out.txt
if [ "${res}" -ne 0 ] ; then
exit 1
fi

ansible-playbook -i inventory "$@" 61025-import_playbook.yml | tee out.txt | grep 'any_errors_fatal_dynamic_value_import_playbook_continues'
res=$?
cat out.txt
if [ "${res}" -ne 0 ] ; then
exit 1
fi

ansible-playbook -i inventory "$@" 61025-bad_dynamic_value.yml 2>&1 | tee out.txt | grep 'not a valid boolean.'
res=$?
cat out.txt
if [ "${res}" -ne 0 ] ; then
exit 1
fi

0 comments on commit 5e8f049

Please sign in to comment.