mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-25 03:41:25 -07:00
Several fixes for includes
* when including statically, make sure that all parents were also included statically (issue #16990) * properly resolve nested static include paths * print a message when a file is statically included Fixes #16990
This commit is contained in:
parent
854d47826c
commit
1c7e0c73c9
5 changed files with 69 additions and 31 deletions
|
@ -374,3 +374,19 @@ class Block(Base, Become, Conditional, Taggable):
|
||||||
return self._parent.get_include_params()
|
return self._parent.get_include_params()
|
||||||
else:
|
else:
|
||||||
return dict()
|
return dict()
|
||||||
|
|
||||||
|
def all_parents_static(self):
|
||||||
|
'''
|
||||||
|
Determine if all of the parents of this block were statically loaded
|
||||||
|
or not. Since Task/TaskInclude objects may be in the chain, they simply
|
||||||
|
call their parents all_parents_static() method. Only Block objects in
|
||||||
|
the chain check the statically_loaded value of the parent.
|
||||||
|
'''
|
||||||
|
from ansible.playbook.task_include import TaskInclude
|
||||||
|
if self._parent:
|
||||||
|
if isinstance(self._parent, TaskInclude) and not self._parent.statically_loaded:
|
||||||
|
return False
|
||||||
|
return self._parent.all_parents_static()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
|
@ -129,20 +129,21 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
||||||
else:
|
else:
|
||||||
is_static = C.DEFAULT_TASK_INCLUDES_STATIC or \
|
is_static = C.DEFAULT_TASK_INCLUDES_STATIC or \
|
||||||
(use_handlers and C.DEFAULT_HANDLER_INCLUDES_STATIC) or \
|
(use_handlers and C.DEFAULT_HANDLER_INCLUDES_STATIC) or \
|
||||||
(not templar._contains_vars(t.args['_raw_params']) and not t.loop)
|
(not templar._contains_vars(t.args['_raw_params']) and t.all_parents_static() and not t.loop)
|
||||||
|
|
||||||
if is_static:
|
if is_static:
|
||||||
if t.loop is not None:
|
if t.loop is not None:
|
||||||
raise AnsibleParserError("You cannot use 'static' on an include with a loop", obj=task_ds)
|
raise AnsibleParserError("You cannot use 'static' on an include with a loop", obj=task_ds)
|
||||||
|
|
||||||
# FIXME: all of this code is very similar (if not identical) to that in
|
# we set a flag to indicate this include was static
|
||||||
# plugins/strategy/__init__.py, and should be unified to avoid
|
t.statically_loaded = True
|
||||||
# patches only being applied to one or the other location
|
|
||||||
if task_include:
|
|
||||||
# handle relative includes by walking up the list of parent include
|
# handle relative includes by walking up the list of parent include
|
||||||
# tasks and checking the relative result to see if it exists
|
# tasks and checking the relative result to see if it exists
|
||||||
parent_include = task_include
|
parent_include = block
|
||||||
cumulative_path = None
|
cumulative_path = None
|
||||||
|
|
||||||
|
found = False
|
||||||
while parent_include is not None:
|
while parent_include is not None:
|
||||||
if not isinstance(parent_include, TaskInclude):
|
if not isinstance(parent_include, TaskInclude):
|
||||||
parent_include = parent_include._parent
|
parent_include = parent_include._parent
|
||||||
|
@ -160,10 +161,12 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
||||||
include_file = loader.path_dwim_relative(loader.get_basedir(), cumulative_path, include_target)
|
include_file = loader.path_dwim_relative(loader.get_basedir(), cumulative_path, include_target)
|
||||||
|
|
||||||
if os.path.exists(include_file):
|
if os.path.exists(include_file):
|
||||||
|
found = True
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
parent_include = parent_include._parent
|
parent_include = parent_include._parent
|
||||||
else:
|
|
||||||
|
if not found:
|
||||||
try:
|
try:
|
||||||
include_target = templar.template(t.args['_raw_params'])
|
include_target = templar.template(t.args['_raw_params'])
|
||||||
except AnsibleUndefinedVariable as e:
|
except AnsibleUndefinedVariable as e:
|
||||||
|
@ -189,6 +192,12 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
||||||
return []
|
return []
|
||||||
elif not isinstance(data, list):
|
elif not isinstance(data, list):
|
||||||
raise AnsibleError("included task files must contain a list of tasks", obj=data)
|
raise AnsibleError("included task files must contain a list of tasks", obj=data)
|
||||||
|
|
||||||
|
# since we can't send callbacks here, we display a message directly in
|
||||||
|
# the same fashion used by the on_include callback. We also do it here,
|
||||||
|
# because the recursive nature of helper methods means we may be loading
|
||||||
|
# nested includes, and we want the include order printed correctly
|
||||||
|
display.display("statically included: %s" % include_file, color=C.COLOR_SKIP)
|
||||||
except AnsibleFileNotFound as e:
|
except AnsibleFileNotFound as e:
|
||||||
if t.static or \
|
if t.static or \
|
||||||
C.DEFAULT_TASK_INCLUDES_STATIC or \
|
C.DEFAULT_TASK_INCLUDES_STATIC or \
|
||||||
|
@ -240,7 +249,6 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
|
||||||
b.tags = list(set(b.tags).union(tags))
|
b.tags = list(set(b.tags).union(tags))
|
||||||
# END FIXME
|
# END FIXME
|
||||||
|
|
||||||
# FIXME: send callback here somehow...
|
|
||||||
# FIXME: handlers shouldn't need this special handling, but do
|
# FIXME: handlers shouldn't need this special handling, but do
|
||||||
# right now because they don't iterate blocks correctly
|
# right now because they don't iterate blocks correctly
|
||||||
if use_handlers:
|
if use_handlers:
|
||||||
|
|
|
@ -463,3 +463,8 @@ class Task(Base, Conditional, Taggable, Become):
|
||||||
|
|
||||||
return path_stack
|
return path_stack
|
||||||
|
|
||||||
|
def all_parents_static(self):
|
||||||
|
if self._parent:
|
||||||
|
return self._parent.all_parents_static()
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
|
@ -43,11 +43,20 @@ class TaskInclude(Task):
|
||||||
|
|
||||||
_static = FieldAttribute(isa='bool', default=None)
|
_static = FieldAttribute(isa='bool', default=None)
|
||||||
|
|
||||||
|
def __init__(self, block=None, role=None, task_include=None):
|
||||||
|
super(TaskInclude, self).__init__(block=block, role=role, task_include=task_include)
|
||||||
|
self.statically_loaded = False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def load(data, block=None, role=None, task_include=None, variable_manager=None, loader=None):
|
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)
|
t = TaskInclude(block=block, role=role, task_include=task_include)
|
||||||
return t.load_data(data, variable_manager=variable_manager, loader=loader)
|
return t.load_data(data, variable_manager=variable_manager, loader=loader)
|
||||||
|
|
||||||
|
def copy(self, exclude_parent=False, exclude_tasks=False):
|
||||||
|
new_me = super(TaskInclude, self).copy(exclude_parent=exclude_parent, exclude_tasks=exclude_tasks)
|
||||||
|
new_me.statically_loaded = self.statically_loaded
|
||||||
|
return new_me
|
||||||
|
|
||||||
def get_vars(self):
|
def get_vars(self):
|
||||||
'''
|
'''
|
||||||
We override the parent Task() classes get_vars here because
|
We override the parent Task() classes get_vars here because
|
||||||
|
|
|
@ -578,7 +578,7 @@ class StrategyBase:
|
||||||
data,
|
data,
|
||||||
play=iterator._play,
|
play=iterator._play,
|
||||||
parent_block=None,
|
parent_block=None,
|
||||||
task_include=None,
|
task_include=included_file._task,
|
||||||
role=included_file._task._role,
|
role=included_file._task._role,
|
||||||
use_handlers=is_handler,
|
use_handlers=is_handler,
|
||||||
loader=self._loader,
|
loader=self._loader,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue