hostvars templating fix, override serialization (#83509) (#83515)

fixes #82872
nicer implementation courtesy of nitzmahone

(cherry picked from commit 6c0f4c8a2d)
pull/83545/head
Brian Coca 5 months ago committed by GitHub
parent ddadca052f
commit e90cfa4ed9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,2 @@
bugfixes:
- templating hostvars under native jinja will not cause serialization errors anymore.

@ -18,6 +18,7 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Mapping from collections.abc import Mapping
from functools import cached_property
from ansible import constants as C from ansible import constants as C
from ansible.template import Templar, AnsibleUndefined from ansible.template import Templar, AnsibleUndefined
@ -114,9 +115,12 @@ class HostVarsVars(Mapping):
def __init__(self, variables, loader): def __init__(self, variables, loader):
self._vars = variables self._vars = variables
self._loader = loader self._loader = loader
@cached_property
def _templar(self):
# NOTE: this only has access to the host's own vars, # NOTE: this only has access to the host's own vars,
# so templates that depend on vars in other scopes will not work. # so templates that depend on vars in other scopes will not work.
self._templar = Templar(variables=self._vars, loader=self._loader) return Templar(variables=self._vars, loader=self._loader)
def __getitem__(self, var): def __getitem__(self, var):
return self._templar.template(self._vars[var], fail_on_undefined=False, static_vars=C.INTERNAL_STATIC_VARS) return self._templar.template(self._vars[var], fail_on_undefined=False, static_vars=C.INTERNAL_STATIC_VARS)
@ -132,3 +136,10 @@ class HostVarsVars(Mapping):
def __repr__(self): def __repr__(self):
return repr(self._templar.template(self._vars, fail_on_undefined=False, static_vars=C.INTERNAL_STATIC_VARS)) return repr(self._templar.template(self._vars, fail_on_undefined=False, static_vars=C.INTERNAL_STATIC_VARS))
def __getstate__(self):
''' override serialization here to avoid
pickle issues with templar and Jinja native'''
state = self.__dict__.copy()
state.pop('_templar', None)
return state

@ -55,3 +55,5 @@ do
ANSIBLE_CONFIG="./${badcfg}.cfg" ansible-config dump --only-changed ANSIBLE_CONFIG="./${badcfg}.cfg" ansible-config dump --only-changed
done done
# ensure we picle hostvarscorrectly with native https://github.com/ansible/ansible/issues/83503
ANSIBLE_JINJA2_NATIVE=1 ansible -m debug -a "msg={{ groups.all | map('extract', hostvars) }}" -i testhost, all -c local -v "$@"

Loading…
Cancel
Save