Fixing role dependency chain creation
The dep chain for roles created during the compile step had bugs, in which the dep chain was overwriten and the original tasks in the role were not assigned a dep chain. This lead to problems in determining whether roles had already run when in a "diamond" structure, and in some cases roles were not correctly getting variables from parents. Fixes #14046
This commit is contained in:
parent
abecb520ad
commit
fb797a9e77
3 changed files with 22 additions and 9 deletions
|
@ -49,6 +49,7 @@ class HostState:
|
|||
self.cur_rescue_task = 0
|
||||
self.cur_always_task = 0
|
||||
self.cur_role = None
|
||||
self.cur_dep_chain = None
|
||||
self.run_state = PlayIterator.ITERATING_SETUP
|
||||
self.fail_state = PlayIterator.FAILED_NONE
|
||||
self.pending_setup = False
|
||||
|
@ -102,6 +103,8 @@ class HostState:
|
|||
new_state.run_state = self.run_state
|
||||
new_state.fail_state = self.fail_state
|
||||
new_state.pending_setup = self.pending_setup
|
||||
if self.cur_dep_chain is not None:
|
||||
new_state.cur_dep_chain = self.cur_dep_chain[:]
|
||||
if self.tasks_child_state is not None:
|
||||
new_state.tasks_child_state = self.tasks_child_state.copy()
|
||||
if self.rescue_child_state is not None:
|
||||
|
@ -212,13 +215,21 @@ class PlayIterator:
|
|||
s.pending_setup = False
|
||||
|
||||
if not task:
|
||||
old_s = s
|
||||
(s, task) = self._get_next_task_from_state(s, peek=peek)
|
||||
|
||||
def _roles_are_different(ra, rb):
|
||||
if ra != rb:
|
||||
return True
|
||||
else:
|
||||
return old_s.cur_dep_chain != task._block._dep_chain
|
||||
|
||||
if task and task._role:
|
||||
# if we had a current role, mark that role as completed
|
||||
if s.cur_role and task._role != s.cur_role and host.name in s.cur_role._had_task_run and not peek:
|
||||
if s.cur_role and _roles_are_different(task._role, s.cur_role) and host.name in s.cur_role._had_task_run and not peek:
|
||||
s.cur_role._completed[host.name] = True
|
||||
s.cur_role = task._role
|
||||
s.cur_dep_chain = task._block._dep_chain
|
||||
|
||||
if not peek:
|
||||
self._host_states[host.name] = s
|
||||
|
|
|
@ -323,7 +323,7 @@ class Role(Base, Become, Conditional, Taggable):
|
|||
|
||||
return host.name in self._completed and not self._metadata.allow_duplicates
|
||||
|
||||
def compile(self, play, dep_chain=[]):
|
||||
def compile(self, play, dep_chain=None):
|
||||
'''
|
||||
Returns the task list for this role, which is created by first
|
||||
recursively compiling the tasks for all direct dependencies, and
|
||||
|
@ -337,18 +337,20 @@ class Role(Base, Become, Conditional, Taggable):
|
|||
block_list = []
|
||||
|
||||
# update the dependency chain here
|
||||
if dep_chain is None:
|
||||
dep_chain = []
|
||||
new_dep_chain = dep_chain + [self]
|
||||
|
||||
deps = self.get_direct_dependencies()
|
||||
for dep in deps:
|
||||
dep_blocks = dep.compile(play=play, dep_chain=new_dep_chain)
|
||||
for dep_block in dep_blocks:
|
||||
new_dep_block = dep_block.copy()
|
||||
new_dep_block._dep_chain = new_dep_chain
|
||||
new_dep_block._play = play
|
||||
block_list.append(new_dep_block)
|
||||
block_list.extend(dep_blocks)
|
||||
|
||||
block_list.extend(self._task_blocks)
|
||||
for task_block in self._task_blocks:
|
||||
new_task_block = task_block.copy()
|
||||
new_task_block._dep_chain = new_dep_chain
|
||||
new_task_block._play = play
|
||||
block_list.append(new_task_block)
|
||||
|
||||
return block_list
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
- assert:
|
||||
that:
|
||||
- 'extra_var == "extra_var"'
|
||||
- 'param_var == "param_var"'
|
||||
- 'param_var == "param_var_role1"'
|
||||
- 'vars_var == "vars_var"'
|
||||
- 'vars_files_var == "vars_files_var"'
|
||||
- 'vars_files_var_role == "vars_files_var_dep"'
|
||||
|
|
Loading…
Reference in a new issue