Always set the discovered interpreter on the delegated host (#64906)
* Always set the discovered interpreter on the delegated host. Fixes #63180 * Make code a little more generic * Move code into a function * Implement some changes based on reviews * Add changelog fragment
This commit is contained in:
parent
318d5606c1
commit
123c624b28
2 changed files with 41 additions and 1 deletions
|
@ -0,0 +1,4 @@
|
||||||
|
bugfixes:
|
||||||
|
- Fact Delegation - Add ability to indicate which facts must always be delegated. Primarily
|
||||||
|
for ``discovered_interpreter_python`` right now, but extensible later.
|
||||||
|
(https://github.com/ansible/ansible/issues/61002)
|
|
@ -55,6 +55,12 @@ display = Display()
|
||||||
|
|
||||||
__all__ = ['StrategyBase']
|
__all__ = ['StrategyBase']
|
||||||
|
|
||||||
|
# This list can be an exact match, or start of string bound
|
||||||
|
# does not accept regex
|
||||||
|
ALWAYS_DELEGATE_FACT_PREFIXES = frozenset((
|
||||||
|
'discovered_interpreter_',
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
class StrategySentinel:
|
class StrategySentinel:
|
||||||
pass
|
pass
|
||||||
|
@ -389,6 +395,34 @@ class StrategyBase:
|
||||||
host_name = result.get('_ansible_delegated_vars', {}).get('ansible_delegated_host', None)
|
host_name = result.get('_ansible_delegated_vars', {}).get('ansible_delegated_host', None)
|
||||||
return [host_name or task.delegate_to]
|
return [host_name or task.delegate_to]
|
||||||
|
|
||||||
|
def _set_always_delegated_facts(self, result, task):
|
||||||
|
"""Sets host facts for ``delegate_to`` hosts for facts that should
|
||||||
|
always be delegated
|
||||||
|
|
||||||
|
This operation mutates ``result`` to remove the always delegated facts
|
||||||
|
|
||||||
|
See ``ALWAYS_DELEGATE_FACT_PREFIXES``
|
||||||
|
"""
|
||||||
|
if task.delegate_to is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
facts = result['ansible_facts']
|
||||||
|
always_keys = set()
|
||||||
|
_add = always_keys.add
|
||||||
|
for fact_key in facts:
|
||||||
|
for always_key in ALWAYS_DELEGATE_FACT_PREFIXES:
|
||||||
|
if fact_key.startswith(always_key):
|
||||||
|
_add(fact_key)
|
||||||
|
if always_keys:
|
||||||
|
_pop = facts.pop
|
||||||
|
always_facts = {
|
||||||
|
'ansible_facts': dict((k, _pop(k)) for k in list(facts) if k in always_keys)
|
||||||
|
}
|
||||||
|
host_list = self.get_delegated_hosts(result, task)
|
||||||
|
_set_host_facts = self._variable_manager.set_host_facts
|
||||||
|
for target_host in host_list:
|
||||||
|
_set_host_facts(target_host, always_facts)
|
||||||
|
|
||||||
@debug_closure
|
@debug_closure
|
||||||
def _process_pending_results(self, iterator, one_pass=False, max_passes=None):
|
def _process_pending_results(self, iterator, one_pass=False, max_passes=None):
|
||||||
'''
|
'''
|
||||||
|
@ -606,11 +640,13 @@ class StrategyBase:
|
||||||
self._add_group(original_host, result_item)
|
self._add_group(original_host, result_item)
|
||||||
|
|
||||||
if 'ansible_facts' in result_item:
|
if 'ansible_facts' in result_item:
|
||||||
|
|
||||||
# if delegated fact and we are delegating facts, we need to change target host for them
|
# 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:
|
if original_task.delegate_to is not None and original_task.delegate_facts:
|
||||||
host_list = self.get_delegated_hosts(result_item, original_task)
|
host_list = self.get_delegated_hosts(result_item, original_task)
|
||||||
else:
|
else:
|
||||||
|
# Set facts that should always be on the delegated hosts
|
||||||
|
self._set_always_delegated_facts(result_item, original_task)
|
||||||
|
|
||||||
host_list = self.get_task_hosts(iterator, original_host, original_task)
|
host_list = self.get_task_hosts(iterator, original_host, original_task)
|
||||||
|
|
||||||
if original_task.action == 'include_vars':
|
if original_task.action == 'include_vars':
|
||||||
|
|
Loading…
Reference in a new issue