Make file.symlink/_symlink_check() respect follow_symlinks
Some checks failed
CI / Prepare Workflow Run (push) Has been cancelled
CI / Pre-Commit (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / NSIS Tests (push) Has been cancelled
CI / Prepare Release: (push) Has been cancelled
CI / Documentation (push) Has been cancelled
CI / Build Source Tarball (push) Has been cancelled
CI / Build Salt Onedir (push) Has been cancelled
CI / Build Packages (push) Has been cancelled
CI / CI Deps (push) Has been cancelled
CI / Test Package (push) Has been cancelled
CI / Test Salt (push) Has been cancelled
CI / Combine Code Coverage (push) Has been cancelled
CI / Set the Pipeline Exit Status (push) Has been cancelled

Fixes: #66980
This commit is contained in:
Tom Doherty 2024-10-18 11:27:36 +01:00 committed by Daniel Wozniak
parent f8ba8c2c62
commit bd819e6ab3
4 changed files with 24 additions and 5 deletions

1
changelog/66980.fixed.md Normal file
View file

@ -0,0 +1 @@
make file.symlink/_symlink_check() respect follow_symlinks

View file

@ -4201,9 +4201,10 @@ def stats(path, hash_type=None, follow_symlinks=True):
salt '*' file.stats /etc/passwd
"""
path = os.path.expanduser(path)
exists = os.path.exists if follow_symlinks else os.path.lexists
ret = {}
if not os.path.exists(path):
if not exists(path):
try:
# Broken symlinks will return False for os.path.exists(), but still
# have a uid and gid
@ -4247,7 +4248,7 @@ def stats(path, hash_type=None, follow_symlinks=True):
ret["type"] = "pipe"
if stat.S_ISSOCK(pstat.st_mode):
ret["type"] = "socket"
ret["target"] = os.path.realpath(path)
ret["target"] = os.path.realpath(path) if follow_symlinks else os.path.abspath(path)
return ret

View file

@ -983,12 +983,14 @@ def _set_symlink_ownership(path, user, group, win_owner):
return _check_symlink_ownership(path, user, group, win_owner)
def _symlink_check(name, target, force, user, group, win_owner):
def _symlink_check(name, target, force, user, group, win_owner, follow_symlinks=False):
"""
Check the symlink function
"""
changes = {}
if not os.path.exists(name) and not __salt__["file.is_link"](name):
exists = os.path.exists if follow_symlinks else os.path.lexists
if not exists(name) and not __salt__["file.is_link"](name):
changes["new"] = name
return (
None,
@ -1788,7 +1790,7 @@ def symlink(
return _error(ret, msg)
tresult, tcomment, tchanges = _symlink_check(
name, target, force, user, group, win_owner
name, target, force, user, group, win_owner, follow_symlinks
)
if not os.path.isdir(os.path.dirname(name)):

View file

@ -294,3 +294,18 @@ def test_symlink_lexists_called_follow_symlinks_false():
filemod.symlink(tfile, a_link, follow_symlinks=False)
lexists.assert_called()
exists.assert_not_called()
def test_symlink_lexists_called_follow_symlinks_true():
tfile = "/tmp/file-basics-test-file"
a_link = "/tmp/a_link"
exists = MagicMock(return_value=False)
lexists = MagicMock(return_value=False)
with patch("os.path.exists", exists), patch("os.path.lexists", lexists), patch(
"os.symlink", MagicMock(return_value=True)
):
filemod.symlink(tfile, a_link, follow_symlinks=True)
lexists.assert_not_called()
exists.assert_called()