mirror of
https://github.com/borgbackup/borg.git
synced 2025-02-22 06:01:54 +00:00
Merge pull request #6216 from ThomasWaldmann/cleanup-location-master
repo::archive location placeholder expansion fixes (master)
This commit is contained in:
commit
444ef02262
6 changed files with 38 additions and 23 deletions
|
@ -636,7 +636,7 @@ def create_inner(archive, cache, fso):
|
||||||
dry_run = args.dry_run
|
dry_run = args.dry_run
|
||||||
t0 = datetime.utcnow()
|
t0 = datetime.utcnow()
|
||||||
t0_monotonic = time.monotonic()
|
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:
|
if not dry_run:
|
||||||
with Cache(repository, key, manifest, progress=args.progress,
|
with Cache(repository, key, manifest, progress=args.progress,
|
||||||
lock_wait=self.lock_wait, permit_adhoc_cache=args.no_cache_sync,
|
lock_wait=self.lock_wait, permit_adhoc_cache=args.no_cache_sync,
|
||||||
|
|
|
@ -379,23 +379,25 @@ class Location:
|
||||||
|
|
||||||
def __init__(self, text='', overrides={}):
|
def __init__(self, text='', overrides={}):
|
||||||
if not self.parse(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={}):
|
def parse(self, text, overrides={}):
|
||||||
self.orig = text
|
self.raw = text # as given by user, might contain placeholders
|
||||||
text = replace_placeholders(text, overrides)
|
self.processed = text = replace_placeholders(text, overrides) # after placeholder replacement
|
||||||
valid = self._parse(text)
|
valid = self._parse(text)
|
||||||
if valid:
|
if valid:
|
||||||
return True
|
return True
|
||||||
m = self.env_re.match(text)
|
m = self.env_re.match(text)
|
||||||
if not m:
|
if not m:
|
||||||
return False
|
return False
|
||||||
repo = os.environ.get('BORG_REPO')
|
repo_raw = os.environ.get('BORG_REPO')
|
||||||
if repo is None:
|
if repo_raw is None:
|
||||||
return False
|
return False
|
||||||
|
repo = replace_placeholders(repo_raw, overrides)
|
||||||
valid = self._parse(repo)
|
valid = self._parse(repo)
|
||||||
self.archive = m.group('archive')
|
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
|
return valid
|
||||||
|
|
||||||
def _parse(self, text):
|
def _parse(self, text):
|
||||||
|
@ -488,15 +490,16 @@ def canonical_path(self):
|
||||||
path)
|
path)
|
||||||
|
|
||||||
def with_timestamp(self, timestamp):
|
def with_timestamp(self, timestamp):
|
||||||
return Location(self.orig, overrides={
|
return Location(self.raw, overrides={
|
||||||
'now': DatetimeWrapper(timestamp.astimezone(None)),
|
'now': DatetimeWrapper(timestamp.astimezone(None)),
|
||||||
'utcnow': DatetimeWrapper(timestamp),
|
'utcnow': DatetimeWrapper(timestamp),
|
||||||
})
|
})
|
||||||
|
|
||||||
def omit_archive(self):
|
def omit_archive(self):
|
||||||
loc = Location(self.orig)
|
loc = Location(self.raw)
|
||||||
loc.archive = None
|
loc.archive = None
|
||||||
loc.orig = loc.orig.split("::")[0]
|
loc.raw = loc.raw.split("::")[0]
|
||||||
|
loc.processed = loc.processed.split("::")[0]
|
||||||
return loc
|
return loc
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -738,11 +738,11 @@ def handle_error(unpacked):
|
||||||
args = unpacked.get(b'exception_args')
|
args = unpacked.get(b'exception_args')
|
||||||
|
|
||||||
if error == 'DoesNotExist':
|
if error == 'DoesNotExist':
|
||||||
raise Repository.DoesNotExist(self.location.orig)
|
raise Repository.DoesNotExist(self.location.processed)
|
||||||
elif error == 'AlreadyExists':
|
elif error == 'AlreadyExists':
|
||||||
raise Repository.AlreadyExists(self.location.orig)
|
raise Repository.AlreadyExists(self.location.processed)
|
||||||
elif error == 'CheckNeeded':
|
elif error == 'CheckNeeded':
|
||||||
raise Repository.CheckNeeded(self.location.orig)
|
raise Repository.CheckNeeded(self.location.processed)
|
||||||
elif error == 'IntegrityError':
|
elif error == 'IntegrityError':
|
||||||
if old_server:
|
if old_server:
|
||||||
raise IntegrityError('(not available)')
|
raise IntegrityError('(not available)')
|
||||||
|
@ -762,9 +762,9 @@ def handle_error(unpacked):
|
||||||
raise Repository.ParentPathDoesNotExist(args[0].decode())
|
raise Repository.ParentPathDoesNotExist(args[0].decode())
|
||||||
elif error == 'ObjectNotFound':
|
elif error == 'ObjectNotFound':
|
||||||
if old_server:
|
if old_server:
|
||||||
raise Repository.ObjectNotFound('(not available)', self.location.orig)
|
raise Repository.ObjectNotFound('(not available)', self.location.processed)
|
||||||
else:
|
else:
|
||||||
raise Repository.ObjectNotFound(args[0].decode(), self.location.orig)
|
raise Repository.ObjectNotFound(args[0].decode(), self.location.processed)
|
||||||
elif error == 'InvalidRPCMethod':
|
elif error == 'InvalidRPCMethod':
|
||||||
if old_server:
|
if old_server:
|
||||||
raise InvalidRPCMethod('(not available)')
|
raise InvalidRPCMethod('(not available)')
|
||||||
|
|
|
@ -235,10 +235,12 @@ def test_bad_syntax(self):
|
||||||
Location('ssh://user@host:/path')
|
Location('ssh://user@host:/path')
|
||||||
|
|
||||||
def test_omit_archive(self):
|
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()
|
loc_without_archive = loc.omit_archive()
|
||||||
assert loc_without_archive.archive is None
|
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:
|
class TestLocationWithEnv:
|
||||||
|
@ -251,6 +253,16 @@ def test_ssh(self, monkeypatch):
|
||||||
assert repr(Location()) == \
|
assert repr(Location()) == \
|
||||||
"Location(proto='ssh', user='user', host='host', port=1234, path='/some/path', archive=None)"
|
"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):
|
def test_file(self, monkeypatch):
|
||||||
monkeypatch.setenv('BORG_REPO', 'file:///some/path')
|
monkeypatch.setenv('BORG_REPO', 'file:///some/path')
|
||||||
assert repr(Location('::archive')) == \
|
assert repr(Location('::archive')) == \
|
||||||
|
|
|
@ -87,10 +87,10 @@ def key(self, request, monkeypatch):
|
||||||
|
|
||||||
class MockRepository:
|
class MockRepository:
|
||||||
class _Location:
|
class _Location:
|
||||||
orig = '/some/place'
|
raw = processed = '/some/place'
|
||||||
|
|
||||||
def canonical_path(self):
|
def canonical_path(self):
|
||||||
return self.orig
|
return self.processed
|
||||||
|
|
||||||
_location = _Location()
|
_location = _Location()
|
||||||
id = bytes(32)
|
id = bytes(32)
|
||||||
|
|
|
@ -887,19 +887,19 @@ def test_rpc_exception_transport(self):
|
||||||
self.repository.call('inject_exception', {'kind': 'DoesNotExist'})
|
self.repository.call('inject_exception', {'kind': 'DoesNotExist'})
|
||||||
except Repository.DoesNotExist as e:
|
except Repository.DoesNotExist as e:
|
||||||
assert len(e.args) == 1
|
assert len(e.args) == 1
|
||||||
assert e.args[0] == self.repository.location.orig
|
assert e.args[0] == self.repository.location.processed
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.repository.call('inject_exception', {'kind': 'AlreadyExists'})
|
self.repository.call('inject_exception', {'kind': 'AlreadyExists'})
|
||||||
except Repository.AlreadyExists as e:
|
except Repository.AlreadyExists as e:
|
||||||
assert len(e.args) == 1
|
assert len(e.args) == 1
|
||||||
assert e.args[0] == self.repository.location.orig
|
assert e.args[0] == self.repository.location.processed
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.repository.call('inject_exception', {'kind': 'CheckNeeded'})
|
self.repository.call('inject_exception', {'kind': 'CheckNeeded'})
|
||||||
except Repository.CheckNeeded as e:
|
except Repository.CheckNeeded as e:
|
||||||
assert len(e.args) == 1
|
assert len(e.args) == 1
|
||||||
assert e.args[0] == self.repository.location.orig
|
assert e.args[0] == self.repository.location.processed
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.repository.call('inject_exception', {'kind': 'IntegrityError'})
|
self.repository.call('inject_exception', {'kind': 'IntegrityError'})
|
||||||
|
@ -918,7 +918,7 @@ def test_rpc_exception_transport(self):
|
||||||
except Repository.ObjectNotFound as e:
|
except Repository.ObjectNotFound as e:
|
||||||
assert len(e.args) == 2
|
assert len(e.args) == 2
|
||||||
assert e.args[0] == s1
|
assert e.args[0] == s1
|
||||||
assert e.args[1] == self.repository.location.orig
|
assert e.args[1] == self.repository.location.processed
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.repository.call('inject_exception', {'kind': 'InvalidRPCMethod'})
|
self.repository.call('inject_exception', {'kind': 'InvalidRPCMethod'})
|
||||||
|
|
Loading…
Reference in a new issue