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:
Matt Martz 2020-04-06 15:09:00 -05:00 committed by GitHub
parent 318d5606c1
commit 123c624b28
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 1 deletions

View file

@ -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)

View file

@ -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':