mirror of
https://github.com/saltstack/salt.git
synced 2025-04-16 09:40:20 +00:00
fixes saltstack/salt#62953 file.symlink backupname operation can copy remote contents to local disk
This commit is contained in:
parent
c20115cc17
commit
a74dde460e
4 changed files with 49 additions and 2 deletions
1
changelog/62953.fixed
Normal file
1
changelog/62953.fixed
Normal file
|
@ -0,0 +1 @@
|
|||
Fix file.symlink backupname operation can copy remote contents to local disk
|
|
@ -7416,16 +7416,29 @@ def join(*args):
|
|||
return os.path.join(*args)
|
||||
|
||||
|
||||
def move(src, dst):
|
||||
def move(src, dst, disallow_copy_and_unlink=False):
|
||||
"""
|
||||
Move a file or directory
|
||||
|
||||
disallow_copy_and_unlink
|
||||
If ``True``, the operation is offloaded to the ``file.rename`` execution
|
||||
module function. This will use ``os.rename`` underneath, which will fail
|
||||
in the event that ``src`` and ``dst`` are on different filesystems. If
|
||||
``False`` (the default), ``shutil.move`` will be used in order to fall
|
||||
back on a "copy then unlink" approach, which is required for moving
|
||||
across filesystems.
|
||||
|
||||
.. versionadded:: 3006.0
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' file.move /path/to/src /path/to/dst
|
||||
"""
|
||||
if disallow_copy_and_unlink:
|
||||
return rename(src, dst)
|
||||
|
||||
src = os.path.expanduser(src)
|
||||
dst = os.path.expanduser(dst)
|
||||
|
||||
|
|
|
@ -1536,6 +1536,7 @@ def symlink(
|
|||
win_deny_perms=None,
|
||||
win_inheritance=None,
|
||||
atomic=False,
|
||||
disallow_copy_and_unlink=False,
|
||||
**kwargs
|
||||
):
|
||||
"""
|
||||
|
@ -1618,6 +1619,17 @@ def symlink(
|
|||
atomic
|
||||
Use atomic file operation to create the symlink.
|
||||
|
||||
.. versionadded:: 3006.0
|
||||
|
||||
disallow_copy_and_unlink
|
||||
Only used if ``backupname`` is used and the name of the symlink exists
|
||||
and is not a symlink. If set to ``True``, the operation is offloaded to
|
||||
the ``file.rename`` execution module function. This will use
|
||||
``os.rename`` underneath, which will fail in the event that ``src`` and
|
||||
``dst`` are on different filesystems. If ``False`` (the default),
|
||||
``shutil.move`` will be used in order to fall back on a "copy then
|
||||
unlink" approach, which is required for moving across filesystems.
|
||||
|
||||
.. versionadded:: 3006.0
|
||||
"""
|
||||
name = os.path.expanduser(name)
|
||||
|
@ -1820,7 +1832,9 @@ def symlink(
|
|||
else:
|
||||
__salt__["file.remove"](backupname)
|
||||
try:
|
||||
__salt__["file.move"](name, backupname)
|
||||
__salt__["file.move"](
|
||||
name, backupname, disallow_copy_and_unlink=disallow_copy_and_unlink
|
||||
)
|
||||
except Exception as exc: # pylint: disable=broad-except
|
||||
ret["changes"] = {}
|
||||
log.debug(
|
||||
|
|
|
@ -589,3 +589,22 @@ def test_stats():
|
|||
ret = filemod.stats("dummy", None, True)
|
||||
assert ret["mode"] == "0644"
|
||||
assert ret["type"] == "file"
|
||||
|
||||
|
||||
def test_file_move_disallow_copy_and_unlink():
|
||||
mock_shutil_move = MagicMock()
|
||||
mock_os_rename = MagicMock()
|
||||
with patch("os.path.expanduser", MagicMock(side_effect=lambda path: path)), patch(
|
||||
"os.path.isabs", MagicMock(return_value=True)
|
||||
), patch("shutil.move", mock_shutil_move), patch("os.rename", mock_os_rename):
|
||||
ret = filemod.move("source", "dest", disallow_copy_and_unlink=False)
|
||||
mock_shutil_move.assert_called_once()
|
||||
mock_os_rename.assert_not_called()
|
||||
assert ret["result"] is True
|
||||
|
||||
mock_shutil_move.reset_mock()
|
||||
|
||||
ret = filemod.move("source", "dest", disallow_copy_and_unlink=True)
|
||||
mock_os_rename.assert_called_once()
|
||||
mock_shutil_move.assert_not_called()
|
||||
assert ret is True
|
||||
|
|
Loading…
Add table
Reference in a new issue