Support Jinja imports with relative paths. Issue #13889#47490
Support Jinja imports with relative paths. Issue #13889#47490rallytime merged 16 commits intosaltstack:developfrom
Conversation
Jinja imports will be interpreted as originating from the top of each
of the directories in the searchpath when the template name does not
begin with './' or '../'. When a template name begins with './' or
'../' then the import will be relative to the importing file.
Prior practices required the following construct:
.. code-block:: yaml
{% from tpldir ~ '/foo' import bar %}
This patch supports a more "natural" construct:
.. code-block:: yaml
{% from './foo' import bar %}
Comparatively when importing from a parent directory - prior practice:
.. code-block:: yaml
{% from tpldir ~ '/../foo' import bar %}
Construct supported by this patch:
.. code-block:: yaml
{% from '../foo' import bar %}
plastikos
left a comment
There was a problem hiding this comment.
There are a few details that should be cleaned-up before this is merged.
| the importing file. | ||
|
|
||
| ''' | ||
| # FIXME: somewhere do seprataor replacement: '\\' => '/' |
There was a problem hiding this comment.
Translation of \ => / might be broken. Help me, Obi Juan, you're my only hope!
There was a problem hiding this comment.
@dwoz @twangboy When using jinja imports on Windows, are Windows-specific path-separators supported? If so, are they the only ones supported, or are forward slashes also supported? I would assume both are supported, since they are in Python proper, but I don't want to assume without knowing for sure.
There was a problem hiding this comment.
I use Windows separators in my Jinja. I don't even have to escape them. Jinja apparently does some escaping for you.
There was a problem hiding this comment.
The tpldir = os.path.dirname(template).replace('\\', '/') construct was in the original code and appears to do some path translation on Windows. I'm not sure how to test it to ensure that I haven't broken the functionality. Is there a unit test?
| ''' | ||
| Salt-specific loader to find imported jinja files. | ||
|
|
||
| Jinja imports will be interpreted as originating from the top |
There was a problem hiding this comment.
This import behavior needs to be in the documentation. Where is the best location for it?
|
RETEST |
|
Help! Suggestions welcome! |
| self.options.name.append(fpath) | ||
| continue | ||
| self.exit(status=1, msg='\'{}\' is not a valid test module'.format(fpath)) | ||
| self.exit(status=1, msg='\'{}\' is not a valid test module\n'.format(fpath)) |
There was a problem hiding this comment.
Can you help me understand this change? I don't know what adding a newline here fixes.
There was a problem hiding this comment.
Without the newline then the error message is not on a line by itself and the command prompt is left on the same line as the error message.
salt/utils/jinja.py
Outdated
| 'Relative path "%s" cannot be resolved without an environment', | ||
| template | ||
| ) | ||
| print('Relative path "{0}" cannot be resolved without an environment'.format(template)) |
There was a problem hiding this comment.
We should not be printing to the CLI here.
There was a problem hiding this comment.
Well that's embarrassing - that should have been removed.
salt/utils/jinja.py
Outdated
| if _template.split('/', 1)[0] == '..': | ||
| log.warning( | ||
| 'Discarded template path "%s": attempts to' | ||
| ' ascend outside of file roots', template |
There was a problem hiding this comment.
Since we have multiple backends, we can't assume people will be using file_roots, so this log message should reference salt:// instead.
| the importing file. | ||
|
|
||
| ''' | ||
| # FIXME: somewhere do seprataor replacement: '\\' => '/' |
There was a problem hiding this comment.
@dwoz @twangboy When using jinja imports on Windows, are Windows-specific path-separators supported? If so, are they the only ones supported, or are forward slashes also supported? I would assume both are supported, since they are in Python proper, but I don't want to assume without knowing for sure.
Change message referencing "file roots" to "salt://"
|
@terminalmage - review changes, please. |
|
@plastikos Is this ready to go from your side? If so, can you also add a mention of this addition to the Fluorine release notes? |
|
@rallytime - I'll add the mention in the release notes and it will be ready to go. |
|
@rallytime , thanks for the fix-ups. |
Fix saltstack#61040. Jinja imports with relative paths was introduced in saltstack#47490. Unfortunately, relative imports have never been working on Windows. That's due to backslashes being unhandled by the `cache_file` function: * https://github.com/saltstack/salt/blob/7275ecf073197faed26f3a571c25fcd59bfbfd60/salt/utils/jinja.py#L114 Instead of getting: * `salt://packages/map.jinja` We're ending up with: * `salt://packages\map.jinja` Thus, the file isn't cached from the master. There's actually a `FIXME` note about it: * https://github.com/saltstack/salt/blob/7275ecf073197faed26f3a571c25fcd59bfbfd60/salt/utils/jinja.py#L136 And the replacement is actually done for setting `tpldir`: * https://github.com/saltstack/salt/blob/7275ecf073197faed26f3a571c25fcd59bfbfd60/salt/utils/jinja.py#L165 This commit ensures the replacement is also done when caching files.
Fix #61040. Jinja imports with relative paths was introduced in #47490. Unfortunately, relative imports have never been working on Windows. That's due to backslashes being unhandled by the `cache_file` function: * https://github.com/saltstack/salt/blob/7275ecf073197faed26f3a571c25fcd59bfbfd60/salt/utils/jinja.py#L114 Instead of getting: * `salt://packages/map.jinja` We're ending up with: * `salt://packages\map.jinja` Thus, the file isn't cached from the master. There's actually a `FIXME` note about it: * https://github.com/saltstack/salt/blob/7275ecf073197faed26f3a571c25fcd59bfbfd60/salt/utils/jinja.py#L136 And the replacement is actually done for setting `tpldir`: * https://github.com/saltstack/salt/blob/7275ecf073197faed26f3a571c25fcd59bfbfd60/salt/utils/jinja.py#L165 This commit ensures the replacement is also done when caching files.
Jinja imports will be interpreted as originating from the top of each
of the directories in the searchpath when the template name does not
begin with './' or '../'. When a template name begins with './' or
'../' then the import will be relative to the importing file.
Prior practices required the following construct:
This patch supports a more "natural" construct:
Comparatively when importing from a parent directory - prior practice:
Construct supported by this patch:
What does this PR do?
Supports relative Jinja imports.
What issues does this PR fix or reference?
#13889
Previous Behavior
Unfortunately
{% from './foo' import bar %}does not work. This super-secret technique was required:{% from tpldir ~ '/foo' import bar %}New Behavior
This works:
{% from './foo' import bar %}Tests written?
Yes
Commits signed with GPG?
No
Please review Salt's Contributing Guide for best practices.
See GitHub's page on GPG signing for more information about signing commits with GPG.