Reworking retry/until logic to fix bugs

Prior to this patch, the retry/until logic would fail any task that
succeeded if it took all of the alloted retries to succeed. This patch
reworks the retry/until logic to make things more simple and clear.

Fixes #15697
pull/15134/head
James Cammarata 9 years ago
parent 6d4ba4a161
commit 4f0be29d65

@ -419,10 +419,10 @@ class TaskExecutor:
self._task.args = dict((i[0], i[1]) for i in iteritems(self._task.args) if i[1] != omit_token) self._task.args = dict((i[0], i[1]) for i in iteritems(self._task.args) if i[1] != omit_token)
# Read some values from the task, so that we can modify them if need be # Read some values from the task, so that we can modify them if need be
if self._task.until is not None: if self._task.until:
retries = self._task.retries retries = self._task.retries
if retries <= 0: if retries is None:
retries = 1 retries = 3
else: else:
retries = 1 retries = 1
@ -436,7 +436,7 @@ class TaskExecutor:
display.debug("starting attempt loop") display.debug("starting attempt loop")
result = None result = None
for attempt in range(retries): for attempt in range(1, retries + 1):
display.debug("running the handler") display.debug("running the handler")
try: try:
result = self._handler.run(task_vars=variables) result = self._handler.run(task_vars=variables)
@ -499,23 +499,23 @@ class TaskExecutor:
_evaluate_changed_when_result(result) _evaluate_changed_when_result(result)
_evaluate_failed_when_result(result) _evaluate_failed_when_result(result)
if attempt < retries - 1: if retries > 1:
cond = Conditional(loader=self._loader) cond = Conditional(loader=self._loader)
cond.when = self._task.until cond.when = self._task.until
if cond.evaluate_conditional(templar, vars_copy): if cond.evaluate_conditional(templar, vars_copy):
break break
else: else:
# no conditional check, or it failed, so sleep for the specified time # no conditional check, or it failed, so sleep for the specified time
result['attempts'] = attempt + 1 if attempt < retries:
result['retries'] = retries result['attempts'] = attempt
result['_ansible_retry'] = True result['_ansible_retry'] = True
display.debug('Retrying task, attempt %d of %d' % (attempt + 1, retries)) result['retries'] = retries
self._rslt_q.put(TaskResult(self._host, self._task, result), block=False) display.debug('Retrying task, attempt %d of %d' % (attempt, retries))
time.sleep(delay) self._rslt_q.put(TaskResult(self._host, self._task, result), block=False)
time.sleep(delay)
else: else:
if retries > 1: if retries > 1:
# we ran out of attempts, so mark the result as failed # we ran out of attempts, so mark the result as failed
result['attempts'] = retries
result['failed'] = True result['failed'] = True
# do the final update of the local variables here, for both registered # do the final update of the local variables here, for both registered

@ -84,7 +84,7 @@ class Task(Base, Conditional, Taggable, Become):
_notify = FieldAttribute(isa='list') _notify = FieldAttribute(isa='list')
_poll = FieldAttribute(isa='int') _poll = FieldAttribute(isa='int')
_register = FieldAttribute(isa='string') _register = FieldAttribute(isa='string')
_retries = FieldAttribute(isa='int', default=3) _retries = FieldAttribute(isa='int')
_until = FieldAttribute(isa='list', default=[]) _until = FieldAttribute(isa='list', default=[])
def __init__(self, block=None, role=None, task_include=None): def __init__(self, block=None, role=None, task_include=None):

Loading…
Cancel
Save