Skip to content

Commit

Permalink
Make file.symlink/_symlink_check() respect follow_symlinks
Browse files Browse the repository at this point in the history
Fixes: #66980
  • Loading branch information
Tom Doherty committed Oct 22, 2024
1 parent ef2fb24 commit eef04d9
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 5 deletions.
1 change: 1 addition & 0 deletions changelog/66980.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
make file.symlink/_symlink_check() respect follow_symlinks
5 changes: 3 additions & 2 deletions salt/modules/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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


Expand Down
8 changes: 5 additions & 3 deletions salt/states/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)):
Expand Down
15 changes: 15 additions & 0 deletions tests/pytests/unit/modules/file/test_file_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

0 comments on commit eef04d9

Please sign in to comment.