summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Krizek <martin.krizek@gmail.com>2018-05-15 21:04:28 +0200
committeransibot <ansibot@users.noreply.github.com>2018-05-15 15:04:28 -0400
commit274fea3f5f386313ce1169017603ee7192870c56 (patch)
tree2d43769b0e7cf98d85486f9a2199b5654e62aaa2
parentbc73fba58f755d0fb82548c289ad4901f4fcf698 (diff)
downloadansible-274fea3f5f386313ce1169017603ee7192870c56.tar.gz
Backport: Fix nested noop block padding in dynamic includes (#40182)
* Fix nested noop block padding in dynamic includes (#38814) * Fix nested noop block padding in dynamic includes * Address issues from the review * Fix typo (cherry picked from commit 5dd8977cfafd6f6e0a946c92b173b79e56d8687b) * Add changelog/fragment for 38814
-rw-r--r--changelogs/fragments/nested-noop-block-padding-dynamic-includes.yaml2
-rw-r--r--lib/ansible/plugins/strategy/linear.py43
-rw-r--r--test/integration/targets/strategy_linear/aliases1
-rw-r--r--test/integration/targets/strategy_linear/roles/role1/tasks/main.yml6
-rw-r--r--test/integration/targets/strategy_linear/roles/role1/tasks/tasks.yml7
-rw-r--r--test/integration/targets/strategy_linear/roles/role2/tasks/main.yml7
-rwxr-xr-xtest/integration/targets/strategy_linear/runme.sh5
-rw-r--r--test/integration/targets/strategy_linear/test_include_file_noop.yml16
8 files changed, 76 insertions, 11 deletions
diff --git a/changelogs/fragments/nested-noop-block-padding-dynamic-includes.yaml b/changelogs/fragments/nested-noop-block-padding-dynamic-includes.yaml
new file mode 100644
index 0000000000..1a6c085b7f
--- /dev/null
+++ b/changelogs/fragments/nested-noop-block-padding-dynamic-includes.yaml
@@ -0,0 +1,2 @@
+bugfixes:
+- Fix nested noop block padding in dynamic includes (https://github.com/ansible/ansible/pull/38814)
diff --git a/lib/ansible/plugins/strategy/linear.py b/lib/ansible/plugins/strategy/linear.py
index d9a0c185e8..ff51b7d35c 100644
--- a/lib/ansible/plugins/strategy/linear.py
+++ b/lib/ansible/plugins/strategy/linear.py
@@ -31,7 +31,7 @@ DOCUMENTATION = '''
author: Ansible Core Team
'''
-from ansible.errors import AnsibleError
+from ansible.errors import AnsibleError, AnsibleAssertionError
from ansible.executor.play_iterator import PlayIterator
from ansible.module_utils.six import iteritems
from ansible.module_utils._text import to_text
@@ -52,6 +52,36 @@ except ImportError:
class StrategyModule(StrategyBase):
+ noop_task = None
+
+ def _replace_with_noop(self, target):
+ if self.noop_task is None:
+ raise AnsibleAssertionError('strategy.linear.StrategyModule.noop_task is None, need Task()')
+
+ result = []
+ for el in target:
+ if isinstance(el, Task):
+ result.append(self.noop_task)
+ elif isinstance(el, Block):
+ result.append(self._create_noop_block_from(el, el._parent))
+ return result
+
+ def _create_noop_block_from(self, original_block, parent):
+ noop_block = Block(parent_block=parent)
+ noop_block.block = self._replace_with_noop(original_block.block)
+ noop_block.always = self._replace_with_noop(original_block.always)
+ noop_block.rescue = self._replace_with_noop(original_block.rescue)
+
+ return noop_block
+
+ def _prepare_and_create_noop_block_from(self, original_block, parent, iterator):
+ self.noop_task = Task()
+ self.noop_task.action = 'meta'
+ self.noop_task.args['_raw_params'] = 'noop'
+ self.noop_task.set_loader(iterator._play._loader)
+
+ return self._create_noop_block_from(original_block, parent)
+
def _get_next_task_lockstep(self, hosts, iterator):
'''
Returns a list of (host, task) tuples, where the task may
@@ -309,12 +339,6 @@ class StrategyModule(StrategyBase):
if len(included_files) > 0:
display.debug("we have included files to process")
- # A noop task for use in padding dynamic includes
- noop_task = Task()
- noop_task.action = 'meta'
- noop_task.args['_raw_params'] = 'noop'
- noop_task.set_loader(iterator._play._loader)
-
display.debug("generating all_blocks data")
all_blocks = dict((host, []) for host in hosts_left)
display.debug("done generating all_blocks data")
@@ -345,10 +369,7 @@ class StrategyModule(StrategyBase):
final_block = new_block.filter_tagged_tasks(play_context, task_vars)
display.debug("done filtering new block on tags")
- noop_block = Block(parent_block=task._parent)
- noop_block.block = [noop_task for t in new_block.block]
- noop_block.always = [noop_task for t in new_block.always]
- noop_block.rescue = [noop_task for t in new_block.rescue]
+ noop_block = self._prepare_and_create_noop_block_from(final_block, task._parent, iterator)
for host in hosts_left:
if host in included_file._hosts:
diff --git a/test/integration/targets/strategy_linear/aliases b/test/integration/targets/strategy_linear/aliases
new file mode 100644
index 0000000000..79d8b9285e
--- /dev/null
+++ b/test/integration/targets/strategy_linear/aliases
@@ -0,0 +1 @@
+posix/ci/group3
diff --git a/test/integration/targets/strategy_linear/roles/role1/tasks/main.yml b/test/integration/targets/strategy_linear/roles/role1/tasks/main.yml
new file mode 100644
index 0000000000..51efd43ea6
--- /dev/null
+++ b/test/integration/targets/strategy_linear/roles/role1/tasks/main.yml
@@ -0,0 +1,6 @@
+- name: Include tasks
+ include_tasks: "tasks.yml"
+
+- name: Mark role as finished
+ set_fact:
+ role1_complete: True
diff --git a/test/integration/targets/strategy_linear/roles/role1/tasks/tasks.yml b/test/integration/targets/strategy_linear/roles/role1/tasks/tasks.yml
new file mode 100644
index 0000000000..b7a46aa098
--- /dev/null
+++ b/test/integration/targets/strategy_linear/roles/role1/tasks/tasks.yml
@@ -0,0 +1,7 @@
+- name: Call role2
+ include_role:
+ name: role2
+
+- name: Call role2 again
+ include_role:
+ name: role2
diff --git a/test/integration/targets/strategy_linear/roles/role2/tasks/main.yml b/test/integration/targets/strategy_linear/roles/role2/tasks/main.yml
new file mode 100644
index 0000000000..81e041e1ac
--- /dev/null
+++ b/test/integration/targets/strategy_linear/roles/role2/tasks/main.yml
@@ -0,0 +1,7 @@
+- block:
+ - block:
+ - name: Nested task 1
+ debug: msg="Nested task 1"
+
+ - name: Nested task 2
+ debug: msg="Nested task 2"
diff --git a/test/integration/targets/strategy_linear/runme.sh b/test/integration/targets/strategy_linear/runme.sh
new file mode 100755
index 0000000000..3f95dd7613
--- /dev/null
+++ b/test/integration/targets/strategy_linear/runme.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+set -eux
+
+ansible-playbook test_include_file_noop.yml -i ../../inventory "$@"
diff --git a/test/integration/targets/strategy_linear/test_include_file_noop.yml b/test/integration/targets/strategy_linear/test_include_file_noop.yml
new file mode 100644
index 0000000000..9dbf83dad0
--- /dev/null
+++ b/test/integration/targets/strategy_linear/test_include_file_noop.yml
@@ -0,0 +1,16 @@
+- hosts:
+ - testhost
+ - testhost2
+ gather_facts: no
+ vars:
+ secondhost: testhost2
+ tasks:
+ - name: Call the first role only on one host
+ include_role:
+ name: role1
+ when: inventory_hostname is match(secondhost)
+
+ - name: Make sure nothing else runs until role1 finishes
+ assert:
+ that:
+ - "'role1_complete' in hostvars[secondhost]"