mirror of
https://github.com/borgbackup/borg.git
synced 2026-04-22 23:01:33 -04:00
Merge pull request #9348 from trxvorr/fix-9339-msys2-paths
Some checks failed
Lint / lint (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / security (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
CI / asan_ubsan (push) Has been cancelled
CI / native_tests (push) Has been cancelled
CI / vm_tests (Haiku, false, haiku, r1beta5) (push) Has been cancelled
CI / vm_tests (NetBSD, false, netbsd, 10.1) (push) Has been cancelled
CI / vm_tests (OmniOS, false, omnios, r151056) (push) Has been cancelled
CI / vm_tests (OpenBSD, false, openbsd, 7.8) (push) Has been cancelled
CI / vm_tests (borg-freebsd-14-x86_64-gh, FreeBSD, true, freebsd, 14.3) (push) Has been cancelled
CI / windows_tests (push) Has been cancelled
Some checks failed
Lint / lint (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / security (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
CI / asan_ubsan (push) Has been cancelled
CI / native_tests (push) Has been cancelled
CI / vm_tests (Haiku, false, haiku, r1beta5) (push) Has been cancelled
CI / vm_tests (NetBSD, false, netbsd, 10.1) (push) Has been cancelled
CI / vm_tests (OmniOS, false, omnios, r151056) (push) Has been cancelled
CI / vm_tests (OpenBSD, false, openbsd, 7.8) (push) Has been cancelled
CI / vm_tests (borg-freebsd-14-x86_64-gh, FreeBSD, true, freebsd, 14.3) (push) Has been cancelled
CI / windows_tests (push) Has been cancelled
archiver: warn about MSYS2 path translation, fixes #9339
This commit is contained in:
commit
be640e982f
5 changed files with 80 additions and 1 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
|
@ -626,6 +626,8 @@ jobs:
|
|||
|
||||
env:
|
||||
PY_COLORS: 1
|
||||
MSYS2_ARG_CONV_EXCL: "*"
|
||||
MSYS2_ENV_CONV_EXCL: "*"
|
||||
|
||||
defaults:
|
||||
run:
|
||||
|
|
|
|||
|
|
@ -326,6 +326,29 @@ Install the dependencies with the provided script::
|
|||
|
||||
./scripts/msys2-install-deps
|
||||
|
||||
.. _msys2_path_translation:
|
||||
|
||||
MSYS2 Path Translation
|
||||
++++++++++++++++++++++
|
||||
|
||||
When running Borg within an MSYS2 environment, the shell
|
||||
automatically translates POSIX-style paths (like ``/tmp`` or ``/C/Users``) to
|
||||
Windows paths (like ``C:\msys64\tmp`` or ``C:\Users``) before they reach the
|
||||
Borg process.
|
||||
|
||||
This behavior can result in absolute Windows paths being stored in your backups,
|
||||
which may not be what you intended if you use POSIX paths for portability.
|
||||
|
||||
To disable this automatic translation for Borg, you can use environment variables
|
||||
to exclude everything from conversion. Similarly, MSYS2 also translates
|
||||
environment variables that look like paths. To disable this generally for Borg,
|
||||
set both variables::
|
||||
|
||||
export MSYS2_ARG_CONV_EXCL="*"
|
||||
export MSYS2_ENV_CONV_EXCL="*"
|
||||
|
||||
For more details, see the `MSYS2 documentation on filesystem paths <https://www.msys2.org/docs/filesystem-paths/>`__.
|
||||
|
||||
Windows 10's Linux Subsystem
|
||||
++++++++++++++++++++++++++++
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ try:
|
|||
from ..helpers import msgpack
|
||||
from ..helpers import sig_int
|
||||
from ..helpers import get_config_dir
|
||||
from ..platformflags import is_msystem
|
||||
from ..remote import RemoteRepository
|
||||
from ..selftest import selftest
|
||||
except BaseException:
|
||||
|
|
@ -397,7 +398,16 @@ class Archiver(
|
|||
return functools.partial(self.do_maincommand_help, parser)
|
||||
|
||||
def prerun_checks(self, logger, is_serve):
|
||||
|
||||
if (
|
||||
not is_serve
|
||||
and is_msystem
|
||||
and ("MSYS2_ARG_CONV_EXCL" not in os.environ or "MSYS2_ENV_CONV_EXCL" not in os.environ)
|
||||
):
|
||||
logger.warning(
|
||||
"MSYS2 path translation is active. This can cause POSIX paths to be mangled into "
|
||||
"Windows paths in archives. Consider setting MSYS2_ARG_CONV_EXCL='*' and "
|
||||
"MSYS2_ENV_CONV_EXCL='*'. See https://www.msys2.org/docs/filesystem-paths/ for details."
|
||||
)
|
||||
selftest(logger)
|
||||
|
||||
def _setup_implied_logging(self, args):
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ Flags for platform-specific APIs.
|
|||
Use these flags instead of sys.platform.startswith('<os>') or try/except.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
is_win32 = sys.platform.startswith("win32")
|
||||
|
|
@ -15,3 +16,6 @@ is_netbsd = sys.platform.startswith("netbsd")
|
|||
is_openbsd = sys.platform.startswith("openbsd")
|
||||
is_darwin = sys.platform.startswith("darwin")
|
||||
is_haiku = sys.platform.startswith("haiku")
|
||||
|
||||
# MSYS2 (on Windows)
|
||||
is_msystem = is_win32 and "MSYSTEM" in os.environ
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ from ...constants import * # NOQA
|
|||
from ...constants import zeros
|
||||
from ...manifest import Manifest
|
||||
from ...platform import is_win32
|
||||
from ...platformflags import is_msystem
|
||||
from ...repository import Repository
|
||||
from ...helpers import CommandError, BackupPermissionError
|
||||
from .. import has_lchflags, has_mknod
|
||||
|
|
@ -150,6 +151,45 @@ def test_archived_paths(archivers, request):
|
|||
assert expected_paths == sorted([json.loads(line)["path"] for line in archive_list.splitlines() if line])
|
||||
|
||||
|
||||
@pytest.mark.skipif(not is_msystem, reason="only for msystem")
|
||||
def test_create_msys2_path_translation_warning(archivers, request, monkeypatch):
|
||||
archiver = request.getfixturevalue(archivers)
|
||||
cmd(archiver, "repo-create", RK_ENCRYPTION)
|
||||
create_regular_file(archiver.input_path, "test")
|
||||
|
||||
# When MSYS2 path translation is active (variables NOT set), a warning should be emitted.
|
||||
monkeypatch.delenv("MSYS2_ARG_CONV_EXCL", raising=False)
|
||||
monkeypatch.delenv("MSYS2_ENV_CONV_EXCL", raising=False)
|
||||
output = cmd(archiver, "create", "test1", "input", fork=True)
|
||||
assert "MSYS2 path translation is active." in output
|
||||
|
||||
# When the variables ARE set, the warning should not be emitted,
|
||||
# and /tmp should be archived properly without being translated to msys64/tmp.
|
||||
monkeypatch.setenv("MSYS2_ARG_CONV_EXCL", "*")
|
||||
monkeypatch.setenv("MSYS2_ENV_CONV_EXCL", "*")
|
||||
|
||||
# We must create a real /tmp directory to avoid file not found errors,
|
||||
# since we will pass '/tmp' directly to Borg
|
||||
tmp_path = os.path.abspath("/tmp")
|
||||
os.makedirs(tmp_path, exist_ok=True)
|
||||
test_filepath = os.path.join(tmp_path, "borg_msys2_test_file")
|
||||
with open(test_filepath, "w") as f:
|
||||
f.write("test")
|
||||
|
||||
try:
|
||||
output2 = cmd(archiver, "create", "test2", "/tmp", fork=True)
|
||||
assert "MSYS2 path translation is active." not in output2
|
||||
|
||||
archive_list = cmd(archiver, "list", "test2", "--json-lines")
|
||||
paths = [json.loads(line)["path"] for line in archive_list.splitlines() if line]
|
||||
|
||||
# Verify that msys64 is not present and paths start with tmp/
|
||||
assert not any("msys64" in p for p in paths)
|
||||
assert any(p.startswith("tmp/borg_msys2_test_file") for p in paths)
|
||||
finally:
|
||||
os.unlink(test_filepath)
|
||||
|
||||
|
||||
@requires_hardlinks
|
||||
def test_create_duplicate_root(archivers, request):
|
||||
archiver = request.getfixturevalue(archivers)
|
||||
|
|
|
|||
Loading…
Reference in a new issue