From b38f746604e3705ccebd51b79458b7f2b0a15ead Mon Sep 17 00:00:00 2001 From: James Cammarata Date: Wed, 13 Sep 2017 11:33:43 -0500 Subject: [PATCH] Fix conditional inheritance on dynamic includes (tasks and roles) (#30178) Per the new style of execution, for dynamic tasks conditionals are expected to only affect the include task itself and should not be inherited by child tasks. This patch brings the behavior inline with this expectation. Fixes #27845 --- lib/ansible/playbook/block.py | 19 ++++++++++++++----- lib/ansible/playbook/helpers.py | 4 ++++ lib/ansible/playbook/task.py | 19 ++++++++++++++----- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/lib/ansible/playbook/block.py b/lib/ansible/playbook/block.py index 85c5f8b96e..a97e7f8fbf 100644 --- a/lib/ansible/playbook/block.py +++ b/lib/ansible/playbook/block.py @@ -294,11 +294,12 @@ class Block(Base, Become, Conditional, Taggable): if self._parent and (value is None or extend): try: - parent_value = getattr(self._parent, attr, None) - if extend: - value = self._extend_value(value, parent_value, prepend) - else: - value = parent_value + if attr != 'when' or getattr(self._parent, 'statically_loaded', True): + parent_value = getattr(self._parent, attr, None) + if extend: + value = self._extend_value(value, parent_value, prepend) + else: + value = parent_value except AttributeError: pass if self._role and (value is None or extend): @@ -386,3 +387,11 @@ class Block(Base, Become, Conditional, Taggable): return self._parent.all_parents_static() return True + + def get_first_parent_include(self): + from ansible.playbook.task_include import TaskInclude + if self._parent: + if isinstance(self._parent, TaskInclude): + return self._parent + return self._parent.get_first_parent_include() + return None diff --git a/lib/ansible/playbook/helpers.py b/lib/ansible/playbook/helpers.py index 44f12eecef..bb84d2cb77 100644 --- a/lib/ansible/playbook/helpers.py +++ b/lib/ansible/playbook/helpers.py @@ -279,6 +279,7 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h else: task_list.extend(included_blocks) else: + t.is_static = False task_list.append(t) elif 'include_role' in task_ds or 'import_role' in task_ds: @@ -319,6 +320,9 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h display.debug('Determined that if include_role static is %s' % str(is_static)) if is_static: + # we set a flag to indicate this include was static + ir.statically_loaded = True + # uses compiled list from object blocks, _ = ir.get_block_list(variable_manager=variable_manager, loader=loader) t = task_list.extend(blocks) diff --git a/lib/ansible/playbook/task.py b/lib/ansible/playbook/task.py index d9253ab9c0..34de600de9 100644 --- a/lib/ansible/playbook/task.py +++ b/lib/ansible/playbook/task.py @@ -411,11 +411,12 @@ class Task(Base, Conditional, Taggable, Become): try: value = self._attributes[attr] if self._parent and (value is None or extend): - parent_value = getattr(self._parent, attr, None) - if extend: - value = self._extend_value(value, parent_value, prepend) - else: - value = parent_value + if attr != 'when' or getattr(self._parent, 'statically_loaded', True): + parent_value = getattr(self._parent, attr, None) + if extend: + value = self._extend_value(value, parent_value, prepend) + else: + value = parent_value except KeyError: pass @@ -456,3 +457,11 @@ class Task(Base, Conditional, Taggable, Become): if self._parent: return self._parent.all_parents_static() return True + + def get_first_parent_include(self): + from ansible.playbook.task_include import TaskInclude + if self._parent: + if isinstance(self._parent, TaskInclude): + return self._parent + return self._parent.get_first_parent_include() + return None