From adb9d7e4611a98d84e553988e1425e744377e95c Mon Sep 17 00:00:00 2001 From: James Cammarata Date: Tue, 11 Aug 2015 16:34:58 -0400 Subject: [PATCH] Track role execution per-host, not overall in the role Fixes #11863 Fixes #11878 --- lib/ansible/executor/play_iterator.py | 4 ++-- lib/ansible/playbook/role/__init__.py | 16 ++++++++-------- lib/ansible/plugins/strategies/__init__.py | 10 ++-------- lib/ansible/plugins/strategies/free.py | 2 +- lib/ansible/plugins/strategies/linear.py | 2 +- 5 files changed, 14 insertions(+), 20 deletions(-) diff --git a/lib/ansible/executor/play_iterator.py b/lib/ansible/executor/play_iterator.py index 45089d19d20..1c5909122bd 100644 --- a/lib/ansible/executor/play_iterator.py +++ b/lib/ansible/executor/play_iterator.py @@ -162,8 +162,8 @@ class PlayIterator: 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 s.cur_role._had_task_run and not peek: - s.cur_role._completed = True + if s.cur_role and 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 if not peek: diff --git a/lib/ansible/playbook/role/__init__.py b/lib/ansible/playbook/role/__init__.py index f46014f60bc..1a6f99540c5 100644 --- a/lib/ansible/playbook/role/__init__.py +++ b/lib/ansible/playbook/role/__init__.py @@ -80,8 +80,8 @@ class Role(Base, Become, Conditional, Taggable): self._handler_blocks = [] self._default_vars = dict() self._role_vars = dict() - self._had_task_run = False - self._completed = False + self._had_task_run = dict() + self._completed = dict() super(Role, self).__init__() @@ -303,13 +303,13 @@ class Role(Base, Become, Conditional, Taggable): block_list.extend(self._handler_blocks) return block_list - def has_run(self): + def has_run(self, host): ''' Returns true if this role has been iterated over completely and at least one task was run ''' - return self._had_task_run and self._completed and not self._metadata.allow_duplicates + return host.name in self._completed and not self._metadata.allow_duplicates def compile(self, play, dep_chain=[]): ''' @@ -348,8 +348,8 @@ class Role(Base, Become, Conditional, Taggable): res['_role_vars'] = self._role_vars res['_role_params'] = self._role_params res['_default_vars'] = self._default_vars - res['_had_task_run'] = self._had_task_run - res['_completed'] = self._completed + res['_had_task_run'] = self._had_task_run.copy() + res['_completed'] = self._completed.copy() if self._metadata: res['_metadata'] = self._metadata.serialize() @@ -373,8 +373,8 @@ class Role(Base, Become, Conditional, Taggable): self._role_vars = data.get('_role_vars', dict()) self._role_params = data.get('_role_params', dict()) self._default_vars = data.get('_default_vars', dict()) - self._had_task_run = data.get('_had_task_run', False) - self._completed = data.get('_completed', False) + self._had_task_run = data.get('_had_task_run', dict()) + self._completed = data.get('_completed', dict()) if include_deps: deps = [] diff --git a/lib/ansible/plugins/strategies/__init__.py b/lib/ansible/plugins/strategies/__init__.py index 92cca11b451..0728750bdec 100644 --- a/lib/ansible/plugins/strategies/__init__.py +++ b/lib/ansible/plugins/strategies/__init__.py @@ -205,14 +205,8 @@ class StrategyBase: # lookup the role in the ROLE_CACHE to make sure we're dealing # with the correct object and mark it as executed for (entry, role_obj) in iterator._play.ROLE_CACHE[task_result._task._role._role_name].iteritems(): - params = task_result._task._role._role_params - if task_result._task._role.tags is not None: - params['tags'] = task_result._task._role.tags - if task_result._task._role.when is not None: - params['when'] = task_result._task._role.when - hashed_entry = hash_params(params) - if entry == hashed_entry: - role_obj._had_task_run = True + if role_obj._uuid == task_result._task._role._uuid: + role_obj._had_task_run[host.name] = True ret_results.append(task_result) diff --git a/lib/ansible/plugins/strategies/free.py b/lib/ansible/plugins/strategies/free.py index 43b62964737..5bc0d8db36e 100644 --- a/lib/ansible/plugins/strategies/free.py +++ b/lib/ansible/plugins/strategies/free.py @@ -97,7 +97,7 @@ class StrategyModule(StrategyBase): # check to see if this task should be skipped, due to it being a member of a # role which has already run (and whether that role allows duplicate execution) - if task._role and task._role.has_run(): + if task._role and task._role.has_run(host): # If there is no metadata, the default behavior is to not allow duplicates, # if there is metadata, check to see if the allow_duplicates flag was set to true if task._role._metadata is None or task._role._metadata and not task._role._metadata.allow_duplicates: diff --git a/lib/ansible/plugins/strategies/linear.py b/lib/ansible/plugins/strategies/linear.py index feac0917664..1a05d184301 100644 --- a/lib/ansible/plugins/strategies/linear.py +++ b/lib/ansible/plugins/strategies/linear.py @@ -170,7 +170,7 @@ class StrategyModule(StrategyBase): # check to see if this task should be skipped, due to it being a member of a # role which has already run (and whether that role allows duplicate execution) - if task._role and task._role.has_run(): + if task._role and task._role.has_run(host): # If there is no metadata, the default behavior is to not allow duplicates, # if there is metadata, check to see if the allow_duplicates flag was set to true if task._role._metadata is None or task._role._metadata and not task._role._metadata.allow_duplicates: