Переглянути джерело

implement with_other_repository and BORG_OTHER_REPO

Thomas Waldmann 3 роки тому
батько
коміт
020e2defaf
2 змінених файлів з 50 додано та 4 видалено
  1. 45 0
      src/borg/archiver.py
  2. 5 4
      src/borg/helpers/parseformat.py

+ 45 - 0
src/borg/archiver.py

@@ -206,6 +206,51 @@ def with_repository(fake=False, invert_fake=False, create=False, lock=True,
     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):

+ 5 - 4
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 @@ class Location:
         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 @@ class Location:
         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: