Fixing bugs related to nested blocks inside roles

* Make sure dep chains are checked recursively for nested blocks
* Fixing iterator is_failed() check to make sure we're not in a
  rescue block before returning True
* Use is_failed() to test whether a host should be added to the TQM
  failed_hosts list
* Use is_failed() when compiling the list of hosts left to iterate
  over in both the linear and free strategies

Fixes #14222
This commit is contained in:
James Cammarata 2016-02-10 21:27:14 -05:00
commit 275728e0f6
6 changed files with 46 additions and 28 deletions

View file

@ -46,6 +46,7 @@ class Block(Base, Become, Conditional, Taggable):
self._role = role
self._task_include = None
self._parent_block = None
self._dep_chain = None
self._use_handlers = use_handlers
self._implicit = implicit
@ -54,11 +55,6 @@ class Block(Base, Become, Conditional, Taggable):
elif parent_block:
self._parent_block = parent_block
if parent_block:
self._dep_chain = parent_block._dep_chain[:]
else:
self._dep_chain = []
super(Block, self).__init__()
def get_vars(self):
@ -153,6 +149,15 @@ class Block(Base, Become, Conditional, Taggable):
except AssertionError:
raise AnsibleParserError("A malformed block was encountered.", obj=self._ds)
def get_dep_chain(self):
if self._dep_chain is None:
if self._parent_block:
return self._parent_block.get_dep_chain()
else:
return None
else:
return self._dep_chain[:]
def copy(self, exclude_parent=False, exclude_tasks=False):
def _dupe_task_list(task_list, new_block):
new_task_list = []
@ -169,7 +174,9 @@ class Block(Base, Become, Conditional, Taggable):
new_me = super(Block, self).copy()
new_me._play = self._play
new_me._use_handlers = self._use_handlers
new_me._dep_chain = self._dep_chain[:]
if self._dep_chain:
new_me._dep_chain = self._dep_chain[:]
if not exclude_tasks:
new_me.block = _dupe_task_list(self.block or [], new_me)
@ -201,7 +208,7 @@ class Block(Base, Become, Conditional, Taggable):
if attr not in ('block', 'rescue', 'always'):
data[attr] = getattr(self, attr)
data['dep_chain'] = self._dep_chain
data['dep_chain'] = self.get_dep_chain()
if self._role is not None:
data['role'] = self._role.serialize()
@ -226,7 +233,7 @@ class Block(Base, Become, Conditional, Taggable):
if attr in data and attr not in ('block', 'rescue', 'always'):
setattr(self, attr, data.get(attr))
self._dep_chain = data.get('dep_chain', [])
self._dep_chain = data.get('dep_chain', None)
# if there was a serialized role, unpack it too
role_data = data.get('role')
@ -247,10 +254,12 @@ class Block(Base, Become, Conditional, Taggable):
pb = Block()
pb.deserialize(pb_data)
self._parent_block = pb
self._dep_chain = self._parent_block.get_dep_chain()
def evaluate_conditional(self, templar, all_vars):
if len(self._dep_chain):
for dep in self._dep_chain:
dep_chain = self.get_dep_chain()
if dep_chain:
for dep in dep_chain:
if not dep.evaluate_conditional(templar, all_vars):
return False
if self._task_include is not None:
@ -274,8 +283,10 @@ class Block(Base, Become, Conditional, Taggable):
if self._task_include:
self._task_include.set_loader(loader)
for dep in self._dep_chain:
dep.set_loader(loader)
dep_chain = self.get_dep_chain()
if dep_chain:
for dep in dep_chain:
dep.set_loader(loader)
def _get_parent_attribute(self, attr, extend=False):
'''
@ -305,10 +316,10 @@ class Block(Base, Become, Conditional, Taggable):
else:
value = parent_value
if len(self._dep_chain) and (value is None or extend):
reverse_dep_chain = self._dep_chain[:]
reverse_dep_chain.reverse()
for dep in reverse_dep_chain:
dep_chain = self.get_dep_chain()
if dep_chain and (value is None or extend):
dep_chain.reverse()
for dep in dep_chain:
dep_value = getattr(dep, attr, None)
if extend:
value = self._extend_value(value, dep_value)

View file

@ -262,10 +262,11 @@ class Role(Base, Become, Conditional, Taggable):
def get_inherited_vars(self, dep_chain=[], include_params=True):
inherited_vars = dict()
for parent in dep_chain:
inherited_vars = combine_vars(inherited_vars, parent._role_vars)
if include_params:
inherited_vars = combine_vars(inherited_vars, parent._role_params)
if dep_chain:
for parent in dep_chain:
inherited_vars = combine_vars(inherited_vars, parent._role_vars)
if include_params:
inherited_vars = combine_vars(inherited_vars, parent._role_params)
return inherited_vars
def get_role_params(self):