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']
|
||||
|
||||
# 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:
|
||||
pass
|
||||
|
@ -389,6 +395,34 @@ class StrategyBase:
|
|||
host_name = result.get('_ansible_delegated_vars', {}).get('ansible_delegated_host', None)
|
||||
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
|
||||
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)
|
||||
|
||||
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:
|
||||
host_list = self.get_delegated_hosts(result_item, original_task)
|
||||
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)
|
||||
|
||||
if original_task.action == 'include_vars':
|
||||
|
|
Loading…
Reference in a new issue