salt: Can't use tpldir or slspath in template file
Can’t use tpldir or slspath in template file
I want to load defaults with construction like this
{%- import_yaml slspath ~ "/defaults.yaml" as defaults %}
Which work flawless in sls state file. But fails in template file. On #salt IRC channel I received a recommendation to use ‘tpldir’ variable instead, but it doesn’t work as well.
Setup
init.sls
{%- import_yaml slspath ~ "/defaults.yaml" as defaults %}
config:
file.managed:
- name: "/tmp/test.cfg"
- source: salt://{{ slspath }}/test.cfg.jinja
- template: jinja
test.cfg.jinja
{%- import_yaml tpldir ~ "/defaults.yaml" as defaults %}
opt1 = var1
opt2 = var2
With setup like this I receive error:
ID: config
Function: file.managed
Name: /tmp/test.cfg
Result: False
Comment: An exception occurred in this state: Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/salt/state.py", line 1746, in call
**cdata['kwargs'])
File "/usr/lib/python2.7/dist-packages/salt/loader.py", line 1704, in wrapper
return f(*args, **kwargs)
File "/usr/lib/python2.7/dist-packages/salt/states/file.py", line 1821, in managed
**kwargs
File "/usr/lib/python2.7/dist-packages/salt/modules/file.py", line 4340, in check_managed_changes
**kwargs)
File "/usr/lib/python2.7/dist-packages/salt/modules/file.py", line 3834, in get_managed
**kwargs)
File "/usr/lib/python2.7/dist-packages/salt/utils/templates.py", line 178, in render_tmpl
output = render_str(tmplstr, context, tmplpath)
File "/usr/lib/python2.7/dist-packages/salt/utils/templates.py", line 386, in render_jinja_tmpl
buf=tmplstr)
SaltRenderError: Jinja variable 'tpldir' is undefined
Started: 18:20:39.233032
Duration: 52.652 ms
Changes:
Expected result is ‘tpldir’ will contain path to current template file.
Versions Report
Salt Version:
Salt: 2016.11.4
Dependency Versions:
cffi: 0.8.6
cherrypy: Not Installed
dateutil: 2.2
docker-py: Not Installed
gitdb: 0.5.4
gitpython: 0.3.2 RC1
ioflo: Not Installed
Jinja2: 2.9.4
libgit2: Not Installed
libnacl: Not Installed
M2Crypto: Not Installed
Mako: Not Installed
msgpack-pure: Not Installed
msgpack-python: 0.4.2
mysql-python: 1.2.3
pycparser: 2.10
pycrypto: 2.6.1
pycryptodome: Not Installed
pygit2: Not Installed
Python: 2.7.9 (default, Jun 29 2016, 13:08:31)
python-gnupg: Not Installed
PyYAML: 3.11
PyZMQ: 14.4.0
RAET: Not Installed
smmap: 0.8.2
timelib: Not Installed
Tornado: 4.2.1
ZMQ: 4.0.5
System Versions:
dist: debian 8.8
machine: x86_64
release: 3.16.0-4-amd64
system: Linux
version: debian 8.8
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 4
- Comments: 25 (15 by maintainers)
Commits related to this issue
- feat(tpldata): provide `tplroot` Working on making SaltStack Formulas portable, find the need for a common point of reference. Comparing the import of `map.jinja` with and without context: | `tplda... — committed to myii/salt by myii 5 years ago
- feat(tpldata): provide `tplroot` Working on making SaltStack Formulas portable, find the need for a common point of reference. Comparing the import of `map.jinja` with and without context: | `tplda... — committed to johnclyde/salt by myii 5 years ago
- feat(tpldata): provide `tplroot` Working on making SaltStack Formulas portable, find the need for a common point of reference. Comparing the import of `map.jinja` with and without context: | `tplda... — committed to alexey-zhukovin/salt by myii 5 years ago
- feat(tpldata): provide `tplroot` Working on making SaltStack Formulas portable, find the need for a common point of reference. Comparing the import of `map.jinja` with and without context: | `tplda... — committed to alexey-zhukovin/salt by myii 5 years ago
Workaround described here: https://github.com/saltstack-formulas/mysql-formula/pull/184#issuecomment-398193878
@max-arnold
compile_template_stris designed to take a string, whilecompile_templateis designed to take a path to a template file.With regard to
tpldir,tpldot, andtplfile, these are also SLS-specific. That is, they are different depending on what SLS file is being processed. Whencompile_templateis operating on a template, it is not aware of the URL used to fetch the template, just the contents of the template. So, outside of the context of an SLS file (which has a known relative path), there is no good way for the templating system to know what these values should be. And also, keep in mind that these values are different depending on the path of the SLS file!When I need to use these variables in a jinja template, I just pass them in the
contextargument, like so:@myii (salt-formulas org maintainer) informed me about a problem with the
tpldir,slspath,tplfile, andtpldottemplate variables when using the newmap.jinjatroubleshooting module introduced in https://github.com/saltstack/salt/pull/55253.I’m not 100% familiar with the code (I just backported it to Salt Neon), but on a first glance it looks like the problem is caused by using the
salt.template.compile_template_strinmodules/jinja.py. To evaluate amap.jinjafile it renders the following inline template string that imports the specifiedmap.jinja:(1) The above snippet gets saved into a tempfile (something like
/tmp/__salt.tmp.f1t0s2c_). That is probably the reason why these path variables aren’t defined.(2) The second part of the problem is that a
map.jinjacould be imported in differentslsfiles that are located in a formula root or in a subfolder. This produces different values of the above mentioned template variables.(3) And the final issue is that these variables have different values depending on the presence of
with contextimport clause.Below is a reproducible test case:
init.sls(both files are the same):map.jinja:Below is how issues (2) and (3) mainfest themselves:
And below is the issue (1) with the new
jinja.pymodule:I made an experimental patch to
modules/jinja.pythat improves the behavior:However, the
slspathis obviously incorrect.One potential workaround is to introduce the
tplrootvariable (see https://github.com/saltstack/salt/pull/51814, however if you place a formula into a deeply nested dir (e.g.,blah/blah/blah/blah/template-formula), thetplrootvariable will be justblahand all the import paths inside the formula will be broken.TLDR: salt-formulas need path-independent ways to reference
map.jinjafiles (and also*.yamland*.jsondata files) inside of*.slsfiles. Also we need a simple way to debug these files in isolation. Plus, all template variables should be documented: https://github.com/saltstack/salt/issues/50925CC: @terminalmage You wrote the original
jinja.pytroubleshooting module and have much more experience in Salt renderer subsystem. Maybe you can provide some clues on how to fix this? Also, are there any reasons why you used thesalt.template.compile_template_strfunction instead ofsalt.template.compile_template?This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
If this issue is closed prematurely, please leave a comment and we will gladly reopen the issue.
Where
map.jinjais importedwith context, here’s another workaround: