From 020e2defaf8bfbad48869599b8109c7b706c360e Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Mon, 2 May 2022 18:48:14 +0200 Subject: [PATCH] implement with_other_repository and BORG_OTHER_REPO --- src/borg/archiver.py | 45 +++++++++++++++++++++++++++++++++ src/borg/helpers/parseformat.py | 9 ++++--- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/borg/archiver.py b/src/borg/archiver.py index 2187fc975..82d3319b3 100644 --- a/src/borg/archiver.py +++ b/src/borg/archiver.py @@ -206,6 +206,51 @@ def wrapper(self, args, **kwargs): return decorator +def with_other_repository(manifest=False, key=False, cache=False, compatibility=None): + """ + this is a simplified version of "with_repository", just for the "other location". + + the repository at the "other location" is intended to get used as a **source** (== read operations). + """ + + compatibility = compat_check(create=False, manifest=manifest, key=key, cache=cache, + compatibility=compatibility, decorator_name='with_other_repository') + + def decorator(method): + @functools.wraps(method) + def wrapper(self, args, **kwargs): + location = getattr(args, 'other_location', None) + if location is None: # nothing to do + return method(self, args, **kwargs) + + repository = get_repository(location, create=False, exclusive=True, + lock_wait=self.lock_wait, lock=True, append_only=False, + make_parent_dirs=False, storage_quota=None, + args=args) + + with repository: + kwargs['other_repository'] = repository + if manifest or key or cache: + manifest_, key_ = Manifest.load(repository, compatibility) + assert_secure(repository, manifest_, self.lock_wait) + if manifest: + kwargs['other_manifest'] = manifest_ + if key: + kwargs['other_key'] = key_ + if cache: + with Cache(repository, key_, manifest_, + progress=False, lock_wait=self.lock_wait, + cache_mode=getattr(args, 'files_cache_mode', DEFAULT_FILES_CACHE_MODE), + consider_part_files=getattr(args, 'consider_part_files', False), + iec=getattr(args, 'iec', False)) as cache_: + kwargs['other_cache'] = cache_ + return method(self, args, **kwargs) + else: + return method(self, args, **kwargs) + return wrapper + return decorator + + def with_archive(method): @functools.wraps(method) def wrapper(self, args, repository, key, manifest, **kwargs): diff --git a/src/borg/helpers/parseformat.py b/src/borg/helpers/parseformat.py index 08ec8df8e..b68157128 100644 --- a/src/borg/helpers/parseformat.py +++ b/src/borg/helpers/parseformat.py @@ -386,7 +386,8 @@ class Location: ) """ + optional_archive_re, re.VERBOSE) # archive name (optional, may be empty) - def __init__(self, text='', overrides={}): + def __init__(self, text='', overrides={}, other=False): + self.repo_env_var = 'BORG_OTHER_REPO' if other else 'BORG_REPO' if not self.parse(text, overrides): raise ValueError('Invalid location format: "%s"' % self.processed) @@ -399,7 +400,7 @@ def parse(self, text, overrides={}): m = self.env_re.match(text) if not m: return False - repo_raw = os.environ.get('BORG_REPO') + repo_raw = os.environ.get(self.repo_env_var) if repo_raw is None: return False repo = replace_placeholders(repo_raw, overrides) @@ -512,10 +513,10 @@ def omit_archive(self): return loc -def location_validator(archive=None, proto=None): +def location_validator(archive=None, proto=None, other=False): def validator(text): try: - loc = Location(text) + loc = Location(text, other=other) except ValueError as err: raise argparse.ArgumentTypeError(str(err)) from None if archive is True and not loc.archive: