From b3abab1bd58b2bbdd797bac4d18022388d5bc604 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Mon, 27 Feb 2017 16:22:30 -0500 Subject: [PATCH] Fact proccessing fixes (#22003) * clarify facts assignment for several corner cases run_once/delegate_facts: now delegate_facts > run_once, previously run_once always published facts to all hosts in play include_vars/delegate_to: now include_vars allows to delegate to a specific host also fix task_vars exception in delegate_facts/loop as var was removed fixes #15365 * removed unused loop_var --- lib/ansible/plugins/strategy/__init__.py | 33 ++++++++++++++---------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/lib/ansible/plugins/strategy/__init__.py b/lib/ansible/plugins/strategy/__init__.py index d580342dd80..3dbe5505146 100644 --- a/lib/ansible/plugins/strategy/__init__.py +++ b/lib/ansible/plugins/strategy/__init__.py @@ -236,6 +236,15 @@ class StrategyBase: host_list = [task_host] return host_list + def get_delegated_hosts(self, result, task): + + host_name = task.delegate_to + actual_host = self._inventory.get_host(host_name) + if actual_host is None: + actual_host = Host(name=host_name) + + return [actual_host] + def _process_pending_results(self, iterator, one_pass=False, max_passes=None): ''' Reads results off the final queue and takes appropriate action @@ -476,27 +485,25 @@ class StrategyBase: if 'ansible_facts' in result_item: - # if delegated fact and we are delegating facts, we need to change target host for them - if original_task.delegate_to is not None and original_task.delegate_facts: - item = result_item.get(loop_var, None) - if item is not None: - task_vars[loop_var] = item - host_name = original_task.delegate_to - actual_host = self._inventory.get_host(host_name) - if actual_host is None: - actual_host = Host(name=host_name) - else: - actual_host = original_host - - host_list = self.get_task_hosts(iterator, actual_host, original_task) if original_task.action == 'include_vars': + if original_task.delegate_to is not None: + host_list = self.get_delegated_hosts(result_item, original_task) + else: + host_list = self.get_task_hosts(iterator, original_host, original_task) + for (var_name, var_value) in iteritems(result_item['ansible_facts']): # find the host we're actually referring too here, which may # be a host that is not really in inventory at all for target_host in host_list: self._variable_manager.set_host_variable(target_host, var_name, var_value) else: + # if delegated fact and we are delegating facts, we need to change target host for them + if original_task.delegate_to is not None and original_task.delegate_facts: + host_list = self.get_delegated_hosts(result_item, original_task) + else: + host_list = self.get_task_hosts(iterator, original_host, original_task) + for target_host in host_list: if original_task.action == 'set_fact': self._variable_manager.set_nonpersistent_facts(target_host, result_item['ansible_facts'].copy())