From 8e6ebae8bda737b2e8115c548d69fb15cdc48b11 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Thu, 30 Nov 2017 17:16:10 -0500 Subject: [PATCH] Make include_x inheritance more congruent with docs (#32769) * draft making tags congruent with include_x * remove ability to 'inline tags' for new inc keys * generic inheritance * fix typo * pepe --- lib/ansible/playbook/base.py | 2 ++ lib/ansible/playbook/helpers.py | 3 +++ lib/ansible/playbook/role_include.py | 2 ++ lib/ansible/playbook/taggable.py | 6 ++---- lib/ansible/playbook/task.py | 7 ++++++- lib/ansible/playbook/task_include.py | 2 ++ 6 files changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/ansible/playbook/base.py b/lib/ansible/playbook/base.py index 4beb56f55cb..26c92157431 100644 --- a/lib/ansible/playbook/base.py +++ b/lib/ansible/playbook/base.py @@ -165,6 +165,8 @@ class Base(with_metaclass(BaseMeta, object)): 'su', 'su_user', 'su_pass', 'su_exe', 'su_flags', ] + _inheritable = True + def __init__(self): # initialize the data loader and variable manager, which will be provided diff --git a/lib/ansible/playbook/helpers.py b/lib/ansible/playbook/helpers.py index 06d73154887..e72668050a2 100644 --- a/lib/ansible/playbook/helpers.py +++ b/lib/ansible/playbook/helpers.py @@ -249,6 +249,7 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h variable_manager=variable_manager, ) + # FIXME: remove once 'include' is removed # pop tags out of the include args, if they were specified there, and assign # them to the include. If the include already had tags specified, we raise an # error so that users know not to specify them both ways @@ -257,6 +258,8 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h tags = tags.split(',') if len(tags) > 0: + if 'include_tasks' in task_ds or 'import_tasks' in task_ds: + raise AnsibleParserError('You cannot specify "tags" inline to the task, it is a task keyword') if len(ti_copy.tags) > 0: raise AnsibleParserError( "Include tasks should not specify tags in more than one way (both via args and directly on the task). " diff --git a/lib/ansible/playbook/role_include.py b/lib/ansible/playbook/role_include.py index 488790aee74..9d32f432138 100644 --- a/lib/ansible/playbook/role_include.py +++ b/lib/ansible/playbook/role_include.py @@ -48,6 +48,8 @@ class IncludeRole(TaskInclude): OTHER_ARGS = ('private', 'allow_duplicates') # assigned to matching property VALID_ARGS = tuple(frozenset(BASE + FROM_ARGS + OTHER_ARGS)) # all valid args + _inheritable = False + # ================================================================================= # ATTRIBUTES diff --git a/lib/ansible/playbook/taggable.py b/lib/ansible/playbook/taggable.py index 511dda85cfd..86f4cab177e 100644 --- a/lib/ansible/playbook/taggable.py +++ b/lib/ansible/playbook/taggable.py @@ -49,11 +49,9 @@ class Taggable: def _get_attr_tags(self): ''' - Override for the 'tags' getattr fetcher, used from Base. + Override for the 'tags' getattr fetcher, used from Base, allow some classes to not give their tags to their 'children' ''' - tags = self._attributes['tags'] - if tags is None: - tags = [] + tags = self._attributes.get('tags', []) if hasattr(self, '_get_parent_attribute'): tags = self._get_parent_attribute('tags', extend=True) return tags diff --git a/lib/ansible/playbook/task.py b/lib/ansible/playbook/task.py index cbedc2b4fea..b00c638b32b 100644 --- a/lib/ansible/playbook/task.py +++ b/lib/ansible/playbook/task.py @@ -420,7 +420,12 @@ class Task(Base, Conditional, Taggable, Become): value = self._attributes[attr] if self._parent and (value is None or extend): if attr != 'when' or getattr(self._parent, 'statically_loaded', True): - parent_value = getattr(self._parent, attr, None) + # vars are always inheritable, other attributes might not be for the partent but still should be for other ancestors + if attr != 'vars' and not getattr(self._parent, '_inheritable', True) and hasattr(self._parent, '_get_parent_attribute'): + parent_value = self._parent._get_parent_attribute(attr, extend=extend, prepend=prepend) + else: + parent_value = getattr(self._parent, attr, None) + if extend: value = self._extend_value(value, parent_value, prepend) else: diff --git a/lib/ansible/playbook/task_include.py b/lib/ansible/playbook/task_include.py index f8612a02d30..55da790b670 100644 --- a/lib/ansible/playbook/task_include.py +++ b/lib/ansible/playbook/task_include.py @@ -50,6 +50,8 @@ class TaskInclude(Task): @staticmethod def load(data, block=None, role=None, task_include=None, variable_manager=None, loader=None): t = TaskInclude(block=block, role=role, task_include=task_include) + if t.action == 'include_task': + t._inheritable = False return t.load_data(data, variable_manager=variable_manager, loader=loader) def copy(self, exclude_parent=False, exclude_tasks=False):