Merge pull request #6199 from ThomasWaldmann/cleanup-location-1.1

repo::archive location placeholder expansion fixes
This commit is contained in:
TW 2022-01-31 21:10:16 +01:00 committed by GitHub
commit 887c90d50a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 38 additions and 23 deletions

View file

@ -581,7 +581,7 @@ class Archiver:
dry_run = args.dry_run
t0 = datetime.utcnow()
t0_monotonic = time.monotonic()
logger.info('Creating archive at "%s"' % args.location.orig)
logger.info('Creating archive at "%s"' % args.location.processed)
if not dry_run:
with Cache(repository, key, manifest, do_files=args.cache_files, progress=args.progress,
lock_wait=self.lock_wait, permit_adhoc_cache=args.no_cache_sync,

View file

@ -1136,23 +1136,25 @@ class Location:
def __init__(self, text='', overrides={}):
if not self.parse(text, overrides):
raise ValueError('Invalid location format: "%s"' % self.orig)
raise ValueError('Invalid location format: "%s"' % self.processed)
def parse(self, text, overrides={}):
self.orig = text
text = replace_placeholders(text, overrides)
self.raw = text # as given by user, might contain placeholders
self.processed = 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.orig = repo if not self.archive else '%s::%s' % (repo, self.archive)
self.raw = repo_raw if not self.archive else repo_raw + self.raw
self.processed = repo if not self.archive else '%s::%s' % (repo, self.archive)
return valid
def _parse(self, text):
@ -1234,15 +1236,16 @@ 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.orig = loc.orig.split("::")[0]
loc.raw = loc.raw.split("::")[0]
loc.processed = loc.processed.split("::")[0]
return loc

View file

@ -728,11 +728,11 @@ This problem will go away as soon as the server has been upgraded to 1.0.7+.
args = unpacked.get(b'exception_args')
if error == 'DoesNotExist':
raise Repository.DoesNotExist(self.location.orig)
raise Repository.DoesNotExist(self.location.processed)
elif error == 'AlreadyExists':
raise Repository.AlreadyExists(self.location.orig)
raise Repository.AlreadyExists(self.location.processed)
elif error == 'CheckNeeded':
raise Repository.CheckNeeded(self.location.orig)
raise Repository.CheckNeeded(self.location.processed)
elif error == 'IntegrityError':
if old_server:
raise IntegrityError('(not available)')
@ -752,9 +752,9 @@ This problem will go away as soon as the server has been upgraded to 1.0.7+.
raise Repository.ParentPathDoesNotExist(args[0].decode())
elif error == 'ObjectNotFound':
if old_server:
raise Repository.ObjectNotFound('(not available)', self.location.orig)
raise Repository.ObjectNotFound('(not available)', self.location.processed)
else:
raise Repository.ObjectNotFound(args[0].decode(), self.location.orig)
raise Repository.ObjectNotFound(args[0].decode(), self.location.processed)
elif error == 'InvalidRPCMethod':
if old_server:
raise InvalidRPCMethod('(not available)')

View file

@ -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.processed == "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')) == \

View file

@ -85,10 +85,10 @@ class TestKey:
class MockRepository:
class _Location:
orig = '/some/place'
raw = processed = '/some/place'
def canonical_path(self):
return self.orig
return self.processed
_location = _Location()
id = bytes(32)

View file

@ -864,19 +864,19 @@ class RemoteRepositoryTestCase(RepositoryTestCase):
self.repository.call('inject_exception', {'kind': 'DoesNotExist'})
except Repository.DoesNotExist as e:
assert len(e.args) == 1
assert e.args[0] == self.repository.location.orig
assert e.args[0] == self.repository.location.processed
try:
self.repository.call('inject_exception', {'kind': 'AlreadyExists'})
except Repository.AlreadyExists as e:
assert len(e.args) == 1
assert e.args[0] == self.repository.location.orig
assert e.args[0] == self.repository.location.processed
try:
self.repository.call('inject_exception', {'kind': 'CheckNeeded'})
except Repository.CheckNeeded as e:
assert len(e.args) == 1
assert e.args[0] == self.repository.location.orig
assert e.args[0] == self.repository.location.processed
try:
self.repository.call('inject_exception', {'kind': 'IntegrityError'})
@ -895,7 +895,7 @@ class RemoteRepositoryTestCase(RepositoryTestCase):
except Repository.ObjectNotFound as e:
assert len(e.args) == 2
assert e.args[0] == s1
assert e.args[1] == self.repository.location.orig
assert e.args[1] == self.repository.location.processed
try:
self.repository.call('inject_exception', {'kind': 'InvalidRPCMethod'})