parent
24593f2ffb
commit
907ff2f26c
8 changed files with 69 additions and 2 deletions
2
changelogs/fragments/end-host-meta-task.yaml
Normal file
2
changelogs/fragments/end-host-meta-task.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- Add new meta task end_host - https://github.com/ansible/ansible/issues/40904
|
|
@ -39,7 +39,8 @@ options:
|
||||||
- "C(clear_host_errors) (added in 2.1) clears the failed state (if any) from hosts specified in the play's list of hosts."
|
- "C(clear_host_errors) (added in 2.1) clears the failed state (if any) from hosts specified in the play's list of hosts."
|
||||||
- "C(end_play) (added in 2.2) causes the play to end without failing the host(s). Note that this affects all hosts."
|
- "C(end_play) (added in 2.2) causes the play to end without failing the host(s). Note that this affects all hosts."
|
||||||
- "C(reset_connection) (added in 2.3) interrupts a persistent connection (i.e. ssh + control persist)"
|
- "C(reset_connection) (added in 2.3) interrupts a persistent connection (i.e. ssh + control persist)"
|
||||||
choices: ['flush_handlers', 'refresh_inventory', 'noop', 'clear_facts', 'clear_host_errors', 'end_play', 'reset_connection']
|
- "C(end_host) (added in 2.8) is a per-host variation of C(end_play). Causes the play to end for the current host without failing it."
|
||||||
|
choices: ['flush_handlers', 'refresh_inventory', 'noop', 'clear_facts', 'clear_host_errors', 'end_play', 'reset_connection', 'end_host']
|
||||||
required: true
|
required: true
|
||||||
notes:
|
notes:
|
||||||
- C(meta) is not really a module nor action_plugin as such it cannot be overwritten.
|
- C(meta) is not really a module nor action_plugin as such it cannot be overwritten.
|
||||||
|
@ -77,4 +78,10 @@ EXAMPLES = '''
|
||||||
- user: name={{ansible_user}} groups=input
|
- user: name={{ansible_user}} groups=input
|
||||||
- name: reset ssh connection to allow user changes to affect 'current login user'
|
- name: reset ssh connection to allow user changes to affect 'current login user'
|
||||||
meta: reset_connection
|
meta: reset_connection
|
||||||
|
|
||||||
|
- name: End the play for hosts that run CentOS 6
|
||||||
|
meta: end_host
|
||||||
|
when:
|
||||||
|
- ansible_distribution == 'CentOS'
|
||||||
|
- ansible_distribution_major_version == '6'
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -1067,6 +1067,13 @@ class StrategyBase:
|
||||||
if host.name not in self._tqm._unreachable_hosts:
|
if host.name not in self._tqm._unreachable_hosts:
|
||||||
iterator._host_states[host.name].run_state = iterator.ITERATING_COMPLETE
|
iterator._host_states[host.name].run_state = iterator.ITERATING_COMPLETE
|
||||||
msg = "ending play"
|
msg = "ending play"
|
||||||
|
elif meta_action == 'end_host':
|
||||||
|
if _evaluate_conditional(target_host):
|
||||||
|
iterator._host_states[target_host.name].run_state = iterator.ITERATING_COMPLETE
|
||||||
|
msg = "ending play for %s" % target_host.name
|
||||||
|
else:
|
||||||
|
skipped = True
|
||||||
|
msg = "end_host conditional evaluated to false, continuing execution for %s" % target_host.name
|
||||||
elif meta_action == 'reset_connection':
|
elif meta_action == 'reset_connection':
|
||||||
all_vars = self._variable_manager.get_vars(play=iterator._play, host=target_host, task=task)
|
all_vars = self._variable_manager.get_vars(play=iterator._play, host=target_host, task=task)
|
||||||
templar = Templar(loader=self._loader, variables=all_vars)
|
templar = Templar(loader=self._loader, variables=all_vars)
|
||||||
|
|
|
@ -265,7 +265,7 @@ class StrategyModule(StrategyBase):
|
||||||
# for the linear strategy, we run meta tasks just once and for
|
# for the linear strategy, we run meta tasks just once and for
|
||||||
# all hosts currently being iterated over rather than one host
|
# all hosts currently being iterated over rather than one host
|
||||||
results.extend(self._execute_meta(task, play_context, iterator, host))
|
results.extend(self._execute_meta(task, play_context, iterator, host))
|
||||||
if task.args.get('_raw_params', None) not in ('noop', 'reset_connection'):
|
if task.args.get('_raw_params', None) not in ('noop', 'reset_connection', 'end_host'):
|
||||||
run_once = True
|
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
|
any_errors_fatal = True
|
||||||
|
|
1
test/integration/targets/meta_tasks/aliases
Normal file
1
test/integration/targets/meta_tasks/aliases
Normal file
|
@ -0,0 +1 @@
|
||||||
|
shippable/posix/group3
|
23
test/integration/targets/meta_tasks/runme.sh
Executable file
23
test/integration/targets/meta_tasks/runme.sh
Executable file
|
@ -0,0 +1,23 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
# test end_host meta task, with when conditional
|
||||||
|
for test_strategy in linear free; do
|
||||||
|
out="$(ansible-playbook test_end_host.yml -i ../../inventory -e test_strategy=$test_strategy -vv "$@")"
|
||||||
|
|
||||||
|
grep -q "META: end_host conditional evaluated to false, continuing execution for testhost" <<< "$out"
|
||||||
|
grep -q "META: ending play for testhost2" <<< "$out"
|
||||||
|
grep -q "play not ended for testhost" <<< "$out"
|
||||||
|
grep -qv "play not ended for testhost2" <<< "$out"
|
||||||
|
done
|
||||||
|
|
||||||
|
# test end_host meta task, on all hosts
|
||||||
|
for test_strategy in linear free; do
|
||||||
|
out="$(ansible-playbook test_end_host_all.yml -i ../../inventory -e test_strategy=$test_strategy -vv "$@")"
|
||||||
|
|
||||||
|
grep -q "META: ending play for testhost" <<< "$out"
|
||||||
|
grep -q "META: ending play for testhost2" <<< "$out"
|
||||||
|
grep -qv "play not ended for testhost" <<< "$out"
|
||||||
|
grep -qv "play not ended for testhost2" <<< "$out"
|
||||||
|
done
|
14
test/integration/targets/meta_tasks/test_end_host.yml
Normal file
14
test/integration/targets/meta_tasks/test_end_host.yml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
- name: "Testing end_host with strategy={{ test_strategy | default('linear') }}"
|
||||||
|
hosts:
|
||||||
|
- testhost
|
||||||
|
- testhost2
|
||||||
|
gather_facts: no
|
||||||
|
strategy: "{{ test_strategy | default('linear') }}"
|
||||||
|
tasks:
|
||||||
|
- debug:
|
||||||
|
|
||||||
|
- meta: end_host
|
||||||
|
when: "host_var_role_name == 'role2'" # end play for testhost2, see test/integration/inventory
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: "play not ended for {{ inventory_hostname }}"
|
13
test/integration/targets/meta_tasks/test_end_host_all.yml
Normal file
13
test/integration/targets/meta_tasks/test_end_host_all.yml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
- name: "Testing end_host all hosts with strategy={{ test_strategy | default('linear') }}"
|
||||||
|
hosts:
|
||||||
|
- testhost
|
||||||
|
- testhost2
|
||||||
|
gather_facts: no
|
||||||
|
strategy: "{{ test_strategy | default('linear') }}"
|
||||||
|
tasks:
|
||||||
|
- debug:
|
||||||
|
|
||||||
|
- meta: end_host
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
msg: "play not ended {{ inventory_hostname }}"
|
Loading…
Reference in a new issue