mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Merge branch 'do_until_14' of https://github.com/bennojoy/ansible into bennojoy-do_until_14
This commit is contained in:
commit
202c4f5294
3 changed files with 70 additions and 4 deletions
|
@ -461,6 +461,39 @@ from turning into arbitrary code with ugly nested ifs, conditionals, and so on -
|
||||||
in more streamlined & auditable configuration rules -- especially because there are a
|
in more streamlined & auditable configuration rules -- especially because there are a
|
||||||
minimum of decision points to track.
|
minimum of decision points to track.
|
||||||
|
|
||||||
|
Do-Until
|
||||||
|
````````
|
||||||
|
|
||||||
|
Sometimes you would want to retry a task till a certain condition is met, In such conditions the Do/Until feature will help.
|
||||||
|
Here's an example which show's the syntax to be applied for the task.::
|
||||||
|
|
||||||
|
- action: shell /usr/bin/foo
|
||||||
|
register: result
|
||||||
|
until: register.stdout.find("all systems go") != -1
|
||||||
|
retries: 5
|
||||||
|
delay: 10
|
||||||
|
|
||||||
|
The above example run the shell module recursively till the module's result has "all systems go" in it's stdout or the task has
|
||||||
|
been retried for 5 times with a delay of 10 seconds. The default value for "retries" is 3 and "delay" is 5.
|
||||||
|
|
||||||
|
The task returns the results returned by the last task run. The results of individual retries can be viewed by -vv option.
|
||||||
|
The results will have a new key "attempts" which will have the number of the retries for the task.
|
||||||
|
|
||||||
|
.. Note::
|
||||||
|
|
||||||
|
The Do/Until does not take decision on whether to fail or pass the play when the maximum retries are completed, the user can
|
||||||
|
can do that in the next task as follows.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
- action: shell /usr/bin/foo
|
||||||
|
register: result
|
||||||
|
until: register.stdout.find("all systems go") != -1
|
||||||
|
retries: 5
|
||||||
|
delay: 10
|
||||||
|
failed_when: result.attempts == 5
|
||||||
|
|
||||||
|
|
||||||
Loops
|
Loops
|
||||||
`````
|
`````
|
||||||
|
|
||||||
|
|
|
@ -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', 'failed_when', 'always_run'
|
'any_errors_fatal', 'changed_when', 'failed_when', 'always_run', 'delay', 'retries', 'until'
|
||||||
]
|
]
|
||||||
|
|
||||||
# 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', 'failed_when', 'always_run'
|
'any_errors_fatal', 'changed_when', 'failed_when', 'always_run', 'delay', 'retries', 'until'
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, play, ds, module_vars=None, default_vars=None, additional_conditions=None, role_name=None):
|
def __init__(self, play, ds, module_vars=None, default_vars=None, additional_conditions=None, role_name=None):
|
||||||
|
@ -112,6 +112,16 @@ class Task(object):
|
||||||
self.environment = ds.get('environment', {})
|
self.environment = ds.get('environment', {})
|
||||||
self.role_name = role_name
|
self.role_name = role_name
|
||||||
|
|
||||||
|
#Code to allow do until feature in a Task
|
||||||
|
if 'until' in ds:
|
||||||
|
if not ds.get('register'):
|
||||||
|
raise errors.AnsibleError("register keyword is mandatory when using do until feature")
|
||||||
|
self.module_vars['delay'] = ds.get('delay', 5)
|
||||||
|
self.module_vars['retries'] = ds.get('retries', 3)
|
||||||
|
self.module_vars['register'] = ds.get('register', None)
|
||||||
|
self.until = "jinja2_compare %s" % (ds.get('until'))
|
||||||
|
self.module_vars['until'] = utils.compile_when_to_only_if(self.until)
|
||||||
|
|
||||||
# rather than simple key=value args on the options line, these represent structured data and the values
|
# rather than simple key=value args on the options line, these represent structured data and the values
|
||||||
# can be hashes and lists, not just scalars
|
# can be hashes and lists, not just scalars
|
||||||
self.args = ds.get('args', {})
|
self.args = ds.get('args', {})
|
||||||
|
|
|
@ -658,7 +658,30 @@ class Runner(object):
|
||||||
|
|
||||||
|
|
||||||
result = handler.run(conn, tmp, module_name, module_args, inject, complex_args)
|
result = handler.run(conn, tmp, module_name, module_args, inject, complex_args)
|
||||||
|
# Code for do until feature
|
||||||
|
until = self.module_vars.get('until', None)
|
||||||
|
if until is not None and result.comm_ok:
|
||||||
|
inject[self.module_vars.get('register')] = result.result
|
||||||
|
cond = template.template(self.basedir, until, inject, expand_lists=False)
|
||||||
|
if not utils.check_conditional(cond, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars):
|
||||||
|
retries = self.module_vars.get('retries')
|
||||||
|
delay = self.module_vars.get('delay')
|
||||||
|
for x in range(1, retries + 1):
|
||||||
|
time.sleep(delay)
|
||||||
|
tmp = ''
|
||||||
|
if getattr(handler, 'NEEDS_TMPPATH', True):
|
||||||
|
tmp = self._make_tmp_path(conn)
|
||||||
|
result = handler.run(conn, tmp, module_name, module_args, inject, complex_args)
|
||||||
|
result.result['attempts'] = x
|
||||||
|
vv("Result from run %i is: %s" % (x, result.result))
|
||||||
|
if not result.comm_ok:
|
||||||
|
break;
|
||||||
|
inject[self.module_vars.get('register')] = result.result
|
||||||
|
cond = template.template(self.basedir, until, inject, expand_lists=False)
|
||||||
|
if utils.check_conditional(cond, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars):
|
||||||
|
break;
|
||||||
|
else:
|
||||||
|
result.result['attempts'] = 0
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
if not result.comm_ok:
|
if not result.comm_ok:
|
||||||
|
|
Loading…
Reference in a new issue