Don't use the task for a cache, return a special cache var (#47243)

* Don't use task to cache loop results, use hostvars. Fixes #47207

* Avoid a race condition, supply _ansible_loop_cache through get_vars directly

* Add tests

* Add changelog fragment

* Remove unnecessary copy

* Remove unnecessary host from _get_delegated_vars signature
This commit is contained in:
Matt Martz 2018-10-18 15:25:43 -05:00 committed by GitHub
parent 9e2c02455a
commit 77d32b8f57
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 10 deletions

View file

@ -430,7 +430,7 @@ class VariableManager:
# if we have a task and we're delegating to another host, figure out the
# variables for that host now so we don't have to rely on hostvars later
if task and task.delegate_to is not None and include_delegate_to:
all_vars['ansible_delegated_vars'] = self._get_delegated_vars(play, task, all_vars)
all_vars['ansible_delegated_vars'], all_vars['_ansible_loop_cache'] = self._get_delegated_vars(play, task, all_vars)
# 'vars' magic var
if task or play:
@ -594,16 +594,15 @@ class VariableManager:
include_hostvars=False,
)
_ansible_loop_cache = None
if has_loop and cache_items:
# delegate_to templating produced a change, update task.loop with templated items,
# delegate_to templating produced a change, so we will cache the templated items
# in a special private hostvar
# this ensures that delegate_to+loop doesn't produce different results than TaskExecutor
# which may reprocess the loop
# Set loop_with to None, so we don't do extra unexpected processing on the cached items later
# in TaskExecutor
task.loop_with = None
task.loop = items
_ansible_loop_cache = items
return delegated_host_vars
return delegated_host_vars, _ansible_loop_cache
def clear_facts(self, hostname):
'''