-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Jinja imports with relative paths. Issue #13889 #47490
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 %}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a few details that should be cleaned-up before this is merged.
salt/utils/jinja.py
Outdated
the importing file. | ||
|
||
''' | ||
# FIXME: somewhere do seprataor replacement: '\\' => '/' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Translation of \
=> /
might be broken. Help me, Obi Juan, you're my only hope!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This import behavior needs to be in the documentation. Where is the best location for it?
RETEST |
Help! Suggestions welcome! |
@@ -332,7 +332,7 @@ def parse_args(self, args=None, values=None): | |||
os.path.basename(fpath).startswith('test_'): | |||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you help me understand this change? I don't know what adding a newline here fixes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not be printing to the CLI here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we have multiple backends, we can't assume people will be using file_roots
, so this log message should reference salt://
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay.
salt/utils/jinja.py
Outdated
the importing file. | ||
|
||
''' | ||
# FIXME: somewhere do seprataor replacement: '\\' => '/' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.