From 8cd95a8e664ccd634dc3a95642ef7ad41f007169 Mon Sep 17 00:00:00 2001 From: Martin Krizek Date: Thu, 4 May 2023 14:55:27 +0200 Subject: Account for overlays when interacting with Jinja envs (#80705) Instead of using Templar.environment in Templar.do_template for accessing/mutating the environment, myenv local variable should be used because it is the environment used for actual templating. It can either point to Templar.environment or newly created environment overlay. Fixes #80605 --- .../fragments/80605-template-overlay-native-jinja.yml | 2 ++ lib/ansible/template/__init__.py | 8 ++++---- .../targets/template_jinja2_non_native/macro_override.yml | 15 +++++++++++++++ .../targets/template_jinja2_non_native/runme.sh | 2 ++ .../templates/macro_override.j2 | 7 +++++++ 5 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 changelogs/fragments/80605-template-overlay-native-jinja.yml create mode 100644 test/integration/targets/template_jinja2_non_native/macro_override.yml create mode 100644 test/integration/targets/template_jinja2_non_native/templates/macro_override.j2 diff --git a/changelogs/fragments/80605-template-overlay-native-jinja.yml b/changelogs/fragments/80605-template-overlay-native-jinja.yml new file mode 100644 index 0000000000..75ed97170c --- /dev/null +++ b/changelogs/fragments/80605-template-overlay-native-jinja.yml @@ -0,0 +1,2 @@ +bugfixes: + - "Properly disable ``jinja2_native`` in the template module when jinja2 override is used in the template (https://github.com/ansible/ansible/issues/80605)" diff --git a/lib/ansible/template/__init__.py b/lib/ansible/template/__init__.py index dd5bd90ac6..f08cfcebb7 100644 --- a/lib/ansible/template/__init__.py +++ b/lib/ansible/template/__init__.py @@ -960,7 +960,7 @@ class Templar: # In case this is a recursive call and we set different concat # function up the stack, reset it in case the value of convert_data # changed in this call - self.environment.concat = self.environment.__class__.concat + myenv.concat = myenv.__class__.concat # the concat function is set for each Ansible environment, # however for convert_data=False we need to use the concat # function that avoids any evaluation and set it temporarily @@ -968,13 +968,13 @@ class Templar: # the concat function is called internally in Jinja, # most notably for macro execution if not self.jinja2_native and not convert_data: - self.environment.concat = ansible_concat + myenv.concat = ansible_concat self.cur_context = t.new_context(jvars, shared=True) rf = t.root_render_func(self.cur_context) try: - res = self.environment.concat(rf) + res = myenv.concat(rf) unsafe = getattr(self.cur_context, 'unsafe', False) if unsafe: res = wrap_var(res) @@ -1002,7 +1002,7 @@ class Templar: # "Hello world\n!\n" instead of "Hello world!\n". res_newlines = _count_newlines_from_end(res) if data_newlines > res_newlines: - res += self.environment.newline_sequence * (data_newlines - res_newlines) + res += myenv.newline_sequence * (data_newlines - res_newlines) if unsafe: res = wrap_var(res) return res diff --git a/test/integration/targets/template_jinja2_non_native/macro_override.yml b/test/integration/targets/template_jinja2_non_native/macro_override.yml new file mode 100644 index 0000000000..8a1cabd26e --- /dev/null +++ b/test/integration/targets/template_jinja2_non_native/macro_override.yml @@ -0,0 +1,15 @@ +- hosts: localhost + gather_facts: false + vars: + output_dir: "{{ lookup('env', 'OUTPUT_DIR') }}" + tasks: + - template: + src: macro_override.j2 + dest: "{{ output_dir }}/macro_override.out" + + - assert: + that: + - "'foobar' not in data" + - "'\"foo\" \"bar\"' in data" + vars: + data: "{{ lookup('file', '{{ output_dir }}/macro_override.out') }}" diff --git a/test/integration/targets/template_jinja2_non_native/runme.sh b/test/integration/targets/template_jinja2_non_native/runme.sh index fe9d495a3e..c02d6b33cf 100755 --- a/test/integration/targets/template_jinja2_non_native/runme.sh +++ b/test/integration/targets/template_jinja2_non_native/runme.sh @@ -4,4 +4,6 @@ set -eux export ANSIBLE_JINJA2_NATIVE=1 ansible-playbook 46169.yml -v "$@" +python -m pip install "Jinja2>=3.1.0" +ansible-playbook macro_override.yml -v "$@" unset ANSIBLE_JINJA2_NATIVE diff --git a/test/integration/targets/template_jinja2_non_native/templates/macro_override.j2 b/test/integration/targets/template_jinja2_non_native/templates/macro_override.j2 new file mode 100644 index 0000000000..51908da0cd --- /dev/null +++ b/test/integration/targets/template_jinja2_non_native/templates/macro_override.j2 @@ -0,0 +1,7 @@ +#jinja2: variable_start_string:'<<',variable_end_string:'>>' +Use a jinja2 override to trigger creating and using an environment overlay. + +{% macro m() %} +"foo" "bar" +{% endmacro %} +<< m() >> -- cgit v1.2.1