diff --git a/CHANGELOG.md b/CHANGELOG.md index a5b2fa25e8ff9e..e62c75e67f403e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,6 +79,8 @@ Ansible Changes By Release ###Minor Changes: * now -vvv shows exact path from which 'currently executing module' was picked up from. +* loop_control now has a label option to allow fine grained control what gets displayed per item +* loop_control now has a pause option to allow pausing for N seconds between loop iterations of a task. ## 2.1 "The Song Remains the Same" diff --git a/docsite/rst/playbooks_loops.rst b/docsite/rst/playbooks_loops.rst index 69cecc45d4af9a..383bc481a3840c 100644 --- a/docsite/rst/playbooks_loops.rst +++ b/docsite/rst/playbooks_loops.rst @@ -573,6 +573,36 @@ As of Ansible 2.1, the `loop_control` option can be used to specify the name of .. note:: If Ansible detects that the current loop is using a variable which has already been defined, it will raise an error to fail the task. +.. versionadded: 2.2 +When using complex data structures for looping the display might get a bit too "busy", this is where the c(label) directive comes to help:: + + - name: create servers + digital_ocean: name={{item.name}} state=present .... + with_items: + - name: server1 + disks: 3gb + ram: 15Gb + netowrk: + nic01: 100Gb + nic02: 10Gb + ... + loop_control: + label: "{{item.name}}" + +This will now display just the 'label' field instead of the whole structure per 'item', it defaults to '"{{item}}"' to display things as usual. + +.. versionadded: 2.2 +Another option to loop control is c(pause), which allows you to control the time (in seconds) between execution of items in a task loop.:: + + # main.yml + - name: create servers, pause 3s before creating next + digital_ocean: name={{item}} state=present .... + with_items: + - server1 + - server2 + loop_control: + pause: 3 + .. _loops_and_includes_2.0: diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index d66ab25103382a..436f0381d34379 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -237,18 +237,27 @@ def _run_loop(self, items): loop_var = 'item' label = None + loop_pause = 0 if self._task.loop_control: # the value may be 'None', so we still need to default it back to 'item' loop_var = self._task.loop_control.loop_var or 'item' label = self._task.loop_control.label or ('{{' + loop_var + '}}') + loop_pause = self._task.loop_control.pause or 0 if loop_var in task_vars: display.warning("The loop variable '%s' is already in use. You should set the `loop_var` value in the `loop_control` option for the task to something else to avoid variable collisions and unexpected behavior." % loop_var) + ran_once = False items = self._squash_items(items, loop_var, task_vars) for item in items: task_vars[loop_var] = item + # pause between loop iterations + if loop_pause and ran_once: + time.sleep(loop_pause) + else: + ran_once = True + try: tmp_task = self._task.copy(exclude_parent=True, exclude_tasks=True) tmp_task._parent = self._task._parent diff --git a/lib/ansible/playbook/loop_control.py b/lib/ansible/playbook/loop_control.py index 6a7d9f9b39b001..78501a982fb927 100644 --- a/lib/ansible/playbook/loop_control.py +++ b/lib/ansible/playbook/loop_control.py @@ -30,6 +30,7 @@ class LoopControl(Base): _loop_var = FieldAttribute(isa='str') _label = FieldAttribute(isa='str') + _pause = FieldAttribute(isa='int') def __init__(self): super(LoopControl, self).__init__()