From ccc41b394efcf836fb0151d535e1373fd2821e4b Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Sun, 30 Jan 2022 03:10:55 +0100 Subject: [PATCH] repo::archive location placeholder expansion fixes, fixes #5826, fixes #5998 - use expanded location for log output - support placeholder expansion for BORG_REPO env var - use Location.raw for the unprocessed, not expanded location string --- src/borg/helpers.py | 15 +++++++++------ src/borg/testsuite/helpers.py | 16 ++++++++++++++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/borg/helpers.py b/src/borg/helpers.py index 42c432bcb..a1cd7eca6 100644 --- a/src/borg/helpers.py +++ b/src/borg/helpers.py @@ -1139,19 +1139,21 @@ class Location: raise ValueError('Invalid location format: "%s"' % self.orig) def parse(self, text, overrides={}): - self.orig = text - text = replace_placeholders(text, overrides) + self.raw = text # as given by user, might contain placeholders + self.orig = text = replace_placeholders(text, overrides) # after placeholder replacement valid = self._parse(text) if valid: return True m = self.env_re.match(text) if not m: return False - repo = os.environ.get('BORG_REPO') - if repo is None: + repo_raw = os.environ.get('BORG_REPO') + if repo_raw is None: return False + repo = replace_placeholders(repo_raw, overrides) valid = self._parse(repo) self.archive = m.group('archive') + self.raw = repo_raw if not self.archive else repo_raw + self.raw self.orig = repo if not self.archive else '%s::%s' % (repo, self.archive) return valid @@ -1234,14 +1236,15 @@ class Location: path) def with_timestamp(self, timestamp): - return Location(self.orig, overrides={ + return Location(self.raw, overrides={ 'now': DatetimeWrapper(timestamp.astimezone(None)), 'utcnow': DatetimeWrapper(timestamp), }) def omit_archive(self): - loc = Location(self.orig) + loc = Location(self.raw) loc.archive = None + loc.raw = loc.raw.split("::")[0] loc.orig = loc.orig.split("::")[0] return loc diff --git a/src/borg/testsuite/helpers.py b/src/borg/testsuite/helpers.py index 04331c55f..6b7884b42 100644 --- a/src/borg/testsuite/helpers.py +++ b/src/borg/testsuite/helpers.py @@ -232,10 +232,12 @@ class TestLocationWithoutEnv: Location('ssh://user@host:/path') def test_omit_archive(self): - loc = Location('ssh://user@host:1234/some/path::archive') + from borg.platform import hostname + loc = Location('ssh://user@host:1234/repos/{hostname}::archive') loc_without_archive = loc.omit_archive() assert loc_without_archive.archive is None - assert loc_without_archive.orig == "ssh://user@host:1234/some/path" + assert loc_without_archive.raw == "ssh://user@host:1234/repos/{hostname}" + assert loc_without_archive.orig == "ssh://user@host:1234/repos/%s" % hostname class TestLocationWithEnv: @@ -248,6 +250,16 @@ class TestLocationWithEnv: assert repr(Location()) == \ "Location(proto='ssh', user='user', host='host', port=1234, path='/some/path', archive=None)" + def test_ssh_placeholder(self, monkeypatch): + from borg.platform import hostname + monkeypatch.setenv('BORG_REPO', 'ssh://user@host:1234/{hostname}') + assert repr(Location('::archive')) == \ + "Location(proto='ssh', user='user', host='host', port=1234, path='/{}', archive='archive')".format(hostname) + assert repr(Location('::')) == \ + "Location(proto='ssh', user='user', host='host', port=1234, path='/{}', archive=None)".format(hostname) + assert repr(Location()) == \ + "Location(proto='ssh', user='user', host='host', port=1234, path='/{}', archive=None)".format(hostname) + def test_file(self, monkeypatch): monkeypatch.setenv('BORG_REPO', 'file:///some/path') assert repr(Location('::archive')) == \