fix(utils/url): handle Windows relative path backslash when caching file

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:

* 7275ecf073/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:

* 7275ecf073/salt/utils/jinja.py (L136)

And the replacement is actually done for setting `tpldir`:

* 7275ecf073/salt/utils/jinja.py (L165)

This commit ensures the replacement is also done when caching files.
This commit is contained in:
Imran Iqbal 2022-03-22 12:33:30 +00:00 committed by Megan Wilhite
parent 20dfcdc550
commit fe6830157b
4 changed files with 30 additions and 2 deletions

1
changelog/61829.fixed Normal file
View file

@ -0,0 +1 @@
Ensure that `salt://` URIs never contain backslashes, converting them to forward slashes instead. A specific situation to handle is caching files on Windows minions, where Jinja relative imports introduce a backslash into the path.

View file

@ -41,6 +41,7 @@ def create(path, saltenv=None):
"""
join `path` and `saltenv` into a 'salt://' URL.
"""
path = path.replace("\\", "/")
if salt.utils.platform.is_windows():
path = salt.utils.path.sanitize_win_path(path)
path = salt.utils.data.decode(path)

View file

@ -176,8 +176,8 @@ def test_relative_import(
result = tmpl.render()
assert result == "Hey world !a b !"
assert len(fc.requests) == 3
assert fc.requests[0]["path"] == os.path.join("salt://relative", "rhello")
assert fc.requests[1]["path"] == os.path.join("salt://relative", "rmacro")
assert fc.requests[0]["path"] == "salt://relative/rhello"
assert fc.requests[1]["path"] == "salt://relative/rmacro"
assert fc.requests[2]["path"] == "salt://macro"
# This must fail when rendered: attempts to import from outside file root
template = jinja.get_template("relative/rescape")

View file

@ -68,6 +68,32 @@ class UrlTestCase(TestCase):
self.assertEqual(salt.utils.url.create(path, saltenv), url)
def test_create_url_with_backslash_in_path(self):
"""
Test creating a 'salt://' URL
"""
src_path = r"? interesting\&path.filetype"
tgt_path = "? interesting/&path.filetype"
url = "salt://" + tgt_path
if salt.utils.platform.is_windows():
url = "salt://_ interesting/&path.filetype"
self.assertEqual(salt.utils.url.create(src_path), url)
def test_create_url_saltenv_with_backslash_in_path(self):
"""
Test creating a 'salt://' URL with a saltenv
"""
saltenv = "raumklang"
src_path = r"? interesting\&path.filetype"
tgt_path = "? interesting/&path.filetype"
if salt.utils.platform.is_windows():
tgt_path = "_ interesting/&path.filetype"
url = "salt://" + tgt_path + "?saltenv=" + saltenv
self.assertEqual(salt.utils.url.create(src_path, saltenv), url)
# is_escaped tests
def test_is_escaped_windows(self):