Add support for defining index var for task loops

pull/35758/merge
Andrew Gaffney 7 years ago committed by Brian Coca
parent 7be8079bad
commit e9b0a4ccb4

@ -287,6 +287,19 @@ Another option to loop control is ``pause``, which allows you to control the tim
loop_control: loop_control:
pause: 3 pause: 3
.. versionadded:: 2.7
If you need to keep track of where you are in a loop, you can use the ``index_var`` option to loop control to specify a variable name to contain the current loop index.::
- name: count our fruit
debug:
msg: "{{ item }} with index {{ my_idx }}"
loop:
- apple
- banana
- pear
loop_control:
index_var: my_idx
.. _loops_and_includes_2.0: .. _loops_and_includes_2.0:

@ -269,10 +269,12 @@ class TaskExecutor:
task_vars = self._job_vars task_vars = self._job_vars
loop_var = 'item' loop_var = 'item'
index_var = None
label = None label = None
loop_pause = 0 loop_pause = 0
if self._task.loop_control: if self._task.loop_control:
loop_var = self._task.loop_control.loop_var loop_var = self._task.loop_control.loop_var
index_var = self._task.loop_control.index_var
loop_pause = self._task.loop_control.pause loop_pause = self._task.loop_control.pause
# the these may be 'None', so we still need to default to something useful # the these may be 'None', so we still need to default to something useful
label = self._task.loop_control.label or ('{{' + loop_var + '}}') label = self._task.loop_control.label or ('{{' + loop_var + '}}')
@ -287,8 +289,10 @@ class TaskExecutor:
# Only squash with 'with_:' not with the 'loop:', 'magic' squashing can be removed once with_ loops are # Only squash with 'with_:' not with the 'loop:', 'magic' squashing can be removed once with_ loops are
items = self._squash_items(items, loop_var, task_vars) items = self._squash_items(items, loop_var, task_vars)
for item in items: for item_index, item in enumerate(items):
task_vars[loop_var] = item task_vars[loop_var] = item
if index_var:
task_vars[index_var] = item_index
# pause between loop iterations # pause between loop iterations
if loop_pause and ran_once: if loop_pause and ran_once:
@ -316,6 +320,8 @@ class TaskExecutor:
# now update the result with the item info, and append the result # now update the result with the item info, and append the result
# to the list of results # to the list of results
res[loop_var] = item res[loop_var] = item
if index_var:
res[index_var] = item_index
res['_ansible_item_result'] = True res['_ansible_item_result'] = True
res['_ansible_ignore_errors'] = task_fields.get('ignore_errors') res['_ansible_ignore_errors'] = task_fields.get('ignore_errors')

@ -78,10 +78,14 @@ class IncludedFile:
include_variables = include_result.get('include_variables', dict()) include_variables = include_result.get('include_variables', dict())
loop_var = 'item' loop_var = 'item'
index_var = None
if original_task.loop_control: if original_task.loop_control:
loop_var = original_task.loop_control.loop_var loop_var = original_task.loop_control.loop_var
index_var = original_task.loop_control.index_var
if loop_var in include_result: if loop_var in include_result:
task_vars[loop_var] = include_variables[loop_var] = include_result[loop_var] task_vars[loop_var] = include_variables[loop_var] = include_result[loop_var]
if index_var and index_var in include_result:
task_vars[index_var] = include_variables[index_var] = include_result[index_var]
if original_task.action in ('include', 'include_tasks'): if original_task.action in ('include', 'include_tasks'):
include_file = None include_file = None

@ -26,6 +26,7 @@ from ansible.playbook.base import Base
class LoopControl(Base): class LoopControl(Base):
_loop_var = FieldAttribute(isa='str', default='item') _loop_var = FieldAttribute(isa='str', default='item')
_index_var = FieldAttribute(isa='str')
_label = FieldAttribute(isa='str') _label = FieldAttribute(isa='str')
_pause = FieldAttribute(isa='int', default=0) _pause = FieldAttribute(isa='int', default=0)

@ -0,0 +1,3 @@
- name: check that index var exists inside included tasks file
assert:
that: my_idx == item|int

@ -1,3 +1,7 @@
#
# loop_control/pause
#
- name: Measure time before - name: Measure time before
shell: date +%s shell: date +%s
register: before register: before
@ -146,3 +150,29 @@
that: that:
- 'results10["results"][0]["ping"] == "Hello World"' - 'results10["results"][0]["ping"] == "Hello World"'
- 'results10["results"][1]["ping"] == "Olá Mundo"' - 'results10["results"][1]["ping"] == "Olá Mundo"'
#
# loop_control/index_var
#
- name: check that the index var is created and increments as expected
assert:
that: my_idx == item|int
with_sequence: start=0 count=3
loop_control:
index_var: my_idx
- name: check that value of index var matches position of current item in source list
assert:
that: 'test_var.index(item) == my_idx'
vars:
test_var: ['a', 'b', 'c']
with_items: "{{ test_var }}"
loop_control:
index_var: my_idx
- name: check index var with included tasks file
include_tasks: index_var_tasks.yml
with_sequence: start=0 count=3
loop_control:
index_var: my_idx

Loading…
Cancel
Save