mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Merge branch 'failed_when' of https://github.com/hnakamur/ansible into hnakamur-failed_when
This commit is contained in:
commit
3b801dec72
6 changed files with 61 additions and 8 deletions
|
@ -189,7 +189,7 @@ class AggregateStats(object):
|
||||||
|
|
||||||
for (host, value) in runner_results.get('contacted', {}).iteritems():
|
for (host, value) in runner_results.get('contacted', {}).iteritems():
|
||||||
if not ignore_errors and (('failed' in value and bool(value['failed'])) or
|
if not ignore_errors and (('failed' in value and bool(value['failed'])) or
|
||||||
('rc' in value and value['rc'] != 0)):
|
('failed_when_result' in value and [value['failed_when_result']] or ['rc' in value and value['rc'] != 0])[0]):
|
||||||
self._increment('failures', host)
|
self._increment('failures', host)
|
||||||
elif 'skipped' in value and bool(value['skipped']):
|
elif 'skipped' in value and bool(value['skipped']):
|
||||||
self._increment('skipped', host)
|
self._increment('skipped', host)
|
||||||
|
|
|
@ -29,7 +29,7 @@ class Task(object):
|
||||||
'delegate_to', 'first_available_file', 'ignore_errors',
|
'delegate_to', 'first_available_file', 'ignore_errors',
|
||||||
'local_action', 'transport', 'sudo', 'sudo_user', 'sudo_pass',
|
'local_action', 'transport', 'sudo', 'sudo_user', 'sudo_pass',
|
||||||
'items_lookup_plugin', 'items_lookup_terms', 'environment', 'args',
|
'items_lookup_plugin', 'items_lookup_terms', 'environment', 'args',
|
||||||
'any_errors_fatal', 'changed_when', 'always_run'
|
'any_errors_fatal', 'changed_when', 'failed_when', 'always_run'
|
||||||
]
|
]
|
||||||
|
|
||||||
# to prevent typos and such
|
# to prevent typos and such
|
||||||
|
@ -38,7 +38,7 @@ class Task(object):
|
||||||
'first_available_file', 'include', 'tags', 'register', 'ignore_errors',
|
'first_available_file', 'include', 'tags', 'register', 'ignore_errors',
|
||||||
'delegate_to', 'local_action', 'transport', 'sudo', 'sudo_user',
|
'delegate_to', 'local_action', 'transport', 'sudo', 'sudo_user',
|
||||||
'sudo_pass', 'when', 'connection', 'environment', 'args',
|
'sudo_pass', 'when', 'connection', 'environment', 'args',
|
||||||
'any_errors_fatal', 'changed_when', 'always_run'
|
'any_errors_fatal', 'changed_when', 'failed_when', 'always_run'
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, play, ds, module_vars=None, default_vars=None, additional_conditions=None):
|
def __init__(self, play, ds, module_vars=None, default_vars=None, additional_conditions=None):
|
||||||
|
@ -88,7 +88,7 @@ class Task(object):
|
||||||
else:
|
else:
|
||||||
raise errors.AnsibleError("cannot find lookup plugin named %s for usage in with_%s" % (plugin_name, plugin_name))
|
raise errors.AnsibleError("cannot find lookup plugin named %s for usage in with_%s" % (plugin_name, plugin_name))
|
||||||
|
|
||||||
elif x in [ 'changed_when', 'when']:
|
elif x in [ 'changed_when', 'failed_when', 'when']:
|
||||||
ds[x] = "jinja2_compare %s" % (ds[x])
|
ds[x] = "jinja2_compare %s" % (ds[x])
|
||||||
elif x.startswith("when_"):
|
elif x.startswith("when_"):
|
||||||
if 'when' in ds:
|
if 'when' in ds:
|
||||||
|
@ -167,6 +167,11 @@ class Task(object):
|
||||||
if self.changed_when is not None:
|
if self.changed_when is not None:
|
||||||
self.changed_when = utils.compile_when_to_only_if(self.changed_when)
|
self.changed_when = utils.compile_when_to_only_if(self.changed_when)
|
||||||
|
|
||||||
|
self.failed_when = ds.get('failed_when', None)
|
||||||
|
|
||||||
|
if self.failed_when is not None:
|
||||||
|
self.failed_when = utils.compile_when_to_only_if(self.failed_when)
|
||||||
|
|
||||||
self.async_seconds = int(ds.get('async', 0)) # not async by default
|
self.async_seconds = int(ds.get('async', 0)) # not async by default
|
||||||
self.async_poll_interval = int(ds.get('poll', 10)) # default poll = 10 seconds
|
self.async_poll_interval = int(ds.get('poll', 10)) # default poll = 10 seconds
|
||||||
self.notify = ds.get('notify', [])
|
self.notify = ds.get('notify', [])
|
||||||
|
@ -223,6 +228,7 @@ class Task(object):
|
||||||
self.module_vars['ignore_errors'] = self.ignore_errors
|
self.module_vars['ignore_errors'] = self.ignore_errors
|
||||||
self.module_vars['register'] = self.register
|
self.module_vars['register'] = self.register
|
||||||
self.module_vars['changed_when'] = self.changed_when
|
self.module_vars['changed_when'] = self.changed_when
|
||||||
|
self.module_vars['failed_when'] = self.failed_when
|
||||||
self.module_vars['always_run'] = self.always_run
|
self.module_vars['always_run'] = self.always_run
|
||||||
|
|
||||||
# tags allow certain parts of a playbook to be run without running the whole playbook
|
# tags allow certain parts of a playbook to be run without running the whole playbook
|
||||||
|
|
|
@ -508,7 +508,7 @@ class Runner(object):
|
||||||
for x in results:
|
for x in results:
|
||||||
if x.get('changed') == True:
|
if x.get('changed') == True:
|
||||||
all_changed = True
|
all_changed = True
|
||||||
if (x.get('failed') == True) or (('rc' in x) and (x['rc'] != 0)):
|
if (x.get('failed') == True) or ('failed_when_result' in x and [x['failed_when_result']] or [('rc' in x) and (x['rc'] != 0)])[0]:
|
||||||
all_failed = True
|
all_failed = True
|
||||||
break
|
break
|
||||||
msg = 'All items completed'
|
msg = 'All items completed'
|
||||||
|
@ -670,13 +670,17 @@ class Runner(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
changed_when = self.module_vars.get('changed_when')
|
changed_when = self.module_vars.get('changed_when')
|
||||||
if changed_when is not None:
|
failed_when = self.module_vars.get('failed_when')
|
||||||
|
if changed_when is not None or failed_when is not None:
|
||||||
register = self.module_vars.get('register')
|
register = self.module_vars.get('register')
|
||||||
if register is not None:
|
if register is not None:
|
||||||
if 'stdout' in data:
|
if 'stdout' in data:
|
||||||
data['stdout_lines'] = data['stdout'].splitlines()
|
data['stdout_lines'] = data['stdout'].splitlines()
|
||||||
inject[register] = data
|
inject[register] = data
|
||||||
data['changed'] = utils.check_conditional(changed_when, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars)
|
if changed_when is not None:
|
||||||
|
data['changed'] = utils.check_conditional(changed_when, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars)
|
||||||
|
if failed_when is not None:
|
||||||
|
data['failed_when_result'] = data['failed'] = utils.check_conditional(failed_when, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars)
|
||||||
|
|
||||||
if is_chained:
|
if is_chained:
|
||||||
# no callbacks
|
# no callbacks
|
||||||
|
|
|
@ -59,5 +59,5 @@ class ReturnData(object):
|
||||||
return self.comm_ok
|
return self.comm_ok
|
||||||
|
|
||||||
def is_successful(self):
|
def is_successful(self):
|
||||||
return self.comm_ok and (self.result.get('failed', False) == False) and (self.result.get('rc',0) == 0)
|
return self.comm_ok and (self.result.get('failed', False) == False) and ('failed_when_result' in self.result and [not self.result['failed_when_result']] or [self.result.get('rc',0) == 0])[0]
|
||||||
|
|
||||||
|
|
|
@ -474,6 +474,34 @@ class TestPlaybook(unittest.TestCase):
|
||||||
|
|
||||||
assert utils.jsonify(expected, format=True) == utils.jsonify(actual,format=True)
|
assert utils.jsonify(expected, format=True) == utils.jsonify(actual,format=True)
|
||||||
|
|
||||||
|
def test_playbook_failed_when(self):
|
||||||
|
test_callbacks = TestCallbacks()
|
||||||
|
playbook = ansible.playbook.PlayBook(
|
||||||
|
playbook=os.path.join(self.test_dir, 'playbook-failed_when.yml'),
|
||||||
|
host_list='test/ansible_hosts',
|
||||||
|
stats=ans_callbacks.AggregateStats(),
|
||||||
|
callbacks=test_callbacks,
|
||||||
|
runner_callbacks=test_callbacks
|
||||||
|
)
|
||||||
|
actual = playbook.run()
|
||||||
|
|
||||||
|
# if different, this will output to screen
|
||||||
|
print "**ACTUAL**"
|
||||||
|
print utils.jsonify(actual, format=True)
|
||||||
|
expected = {
|
||||||
|
"localhost": {
|
||||||
|
"changed": 2,
|
||||||
|
"failures": 1,
|
||||||
|
"ok": 2,
|
||||||
|
"skipped": 0,
|
||||||
|
"unreachable": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print "**EXPECTED**"
|
||||||
|
print utils.jsonify(expected, format=True)
|
||||||
|
|
||||||
|
assert utils.jsonify(expected, format=True) == utils.jsonify(actual,format=True)
|
||||||
|
|
||||||
|
|
||||||
def test_playbook_always_run(self):
|
def test_playbook_always_run(self):
|
||||||
test_callbacks = TestCallbacks()
|
test_callbacks = TestCallbacks()
|
||||||
|
|
15
test/playbook-failed_when.yml
Normal file
15
test/playbook-failed_when.yml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
- hosts: all
|
||||||
|
connection: local
|
||||||
|
gather_facts: False
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- action: shell exit 0
|
||||||
|
register: exit
|
||||||
|
failed_when: not exit.rc in [0, 1]
|
||||||
|
- action: shell exit 1
|
||||||
|
register: exit
|
||||||
|
failed_when: exit.rc not in [0, 1]
|
||||||
|
- action: shell exit 2
|
||||||
|
register: exit
|
||||||
|
failed_when: exit.rc not in [0, 1]
|
Loading…
Reference in a new issue