Skip to content

Instantly share code, notes, and snippets.

@mkrizek
Last active December 4, 2019 14:58
Show Gist options
  • Save mkrizek/2fcd1b1e4d29fb56b450ceabc5a19552 to your computer and use it in GitHub Desktop.
Save mkrizek/2fcd1b1e4d29fb56b450ceabc5a19552 to your computer and use it in GitHub Desktop.
65365
commit 960e971b01a8493d40245a9cdb018b4d1ad13c33 (HEAD -> issue-65365)
Author: Martin Krizek <martin.krizek@gmail.com>
Date: Wed Dec 4 15:55:52 2019 +0100
Set HostVars._variable_manager's attrs
When HostVars are part of the data that goes through (de)serialization
when being passed from a worker process to the main process, its
variable manager reference loses some of its attributes due to the
implementation of __getstate__ and __setstate__ (perf utilization).
Since HostVars already has those attributes, use __setstate__ to assign
them.
Fixes #65365
diff --git a/changelogs/fragments/65365-fix-tb-printing-hostvars.yml b/changelogs/fragments/65365-fix-tb-printing-hostvars.yml
new file mode 100644
index 0000000000..dcf753c791
--- /dev/null
+++ b/changelogs/fragments/65365-fix-tb-printing-hostvars.yml
@@ -0,0 +1,2 @@
+bugfixes:
+ - Fix traceback when printing ``HostVars`` on native Jinja2 (https://github.com/ansible/ansible/issues/65365)
diff --git a/lib/ansible/vars/hostvars.py b/lib/ansible/vars/hostvars.py
index 3159b920ce..b47ec1975c 100644
--- a/lib/ansible/vars/hostvars.py
+++ b/lib/ansible/vars/hostvars.py
@@ -49,7 +49,6 @@ class HostVars(Mapping):
''' A special view of vars_cache that adds values from the inventory when needed. '''
def __init__(self, inventory, variable_manager, loader):
- self._lookup = dict()
self._inventory = inventory
self._loader = loader
self._variable_manager = variable_manager
@@ -77,6 +76,19 @@ class HostVars(Mapping):
return self._variable_manager.get_vars(host=host, include_hostvars=False)
+ def __setstate__(self, state):
+ self.__dict__.update(state)
+
+ # Methods __getstate__ and __setstate__ of VariableManager do not
+ # preserve _loader and _hostvars attributes to improve pickle
+ # performance and memory utilization. Since HostVars holds values
+ # of those attributes already, assign them if needed.
+ if self._variable_manager._loader is None:
+ self._variable_manager._loader = self._loader
+
+ if self._variable_manager._hostvars is None:
+ self._variable_manager._hostvars = self
+
def __getitem__(self, host_name):
data = self.raw_get(host_name)
if isinstance(data, AnsibleUndefined):
diff --git a/lib/ansible/vars/manager.py b/lib/ansible/vars/manager.py
index 3cf485c07e..91808d8747 100644
--- a/lib/ansible/vars/manager.py
+++ b/lib/ansible/vars/manager.py
@@ -133,6 +133,8 @@ class VariableManager:
self._inventory = data.get('inventory', None)
self._options_vars = data.get('options_vars', dict())
self.safe_basedir = data.get('safe_basedir', False)
+ self._loader = None
+ self._hostvars = None
@property
def extra_vars(self):
diff --git a/test/integration/targets/jinja2_native_types/inventory.jinja2_native_types b/test/integration/targets/jinja2_native_types/inventory.jinja2_native_types
index e69de29bb2..c1ed0a24cf 100644
--- a/test/integration/targets/jinja2_native_types/inventory.jinja2_native_types
+++ b/test/integration/targets/jinja2_native_types/inventory.jinja2_native_types
@@ -0,0 +1 @@
+host1
diff --git a/test/integration/targets/jinja2_native_types/runme.sh b/test/integration/targets/jinja2_native_types/runme.sh
index bd05bd5f1f..0326780b4b 100755
--- a/test/integration/targets/jinja2_native_types/runme.sh
+++ b/test/integration/targets/jinja2_native_types/runme.sh
@@ -4,3 +4,4 @@ set -eux
ANSIBLE_JINJA2_NATIVE=1 ansible-playbook -i inventory.jinja2_native_types runtests.yml -v "$@"
ANSIBLE_JINJA2_NATIVE=1 ansible-playbook -i inventory.jinja2_native_types --vault-password-file test_vault_pass test_vault.yml -v "$@"
+ANSIBLE_JINJA2_NATIVE=1 ansible-playbook -i inventory.jinja2_native_types test_hostvars.yml -v "$@"
diff --git a/test/integration/targets/jinja2_native_types/test_hostvars.yml b/test/integration/targets/jinja2_native_types/test_hostvars.yml
new file mode 100644
index 0000000000..31f5ec9d3a
--- /dev/null
+++ b/test/integration/targets/jinja2_native_types/test_hostvars.yml
@@ -0,0 +1,10 @@
+- hosts: host1
+ gather_facts: no
+ tasks:
+ - name: Print vars
+ debug:
+ var: vars
+
+ - name: Print hostvars
+ debug:
+ var: hostvars
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment