Ver código fonte

add upgrader which moves the keys to new location

Thomas Waldmann 9 anos atrás
pai
commit
e7add135a2
2 arquivos alterados com 55 adições e 1 exclusões
  1. 6 1
      borg/archiver.py
  2. 49 0
      borg/upgrader.py

+ 6 - 1
borg/archiver.py

@@ -23,7 +23,7 @@ from .helpers import Error, location_validator, format_time, format_file_size, \
 from .logger import create_logger, setup_logging
 logger = create_logger()
 from .compress import Compressor, COMPR_BUFFER
-from .upgrader import AtticRepositoryUpgrader
+from .upgrader import AtticRepositoryUpgrader, BorgRepositoryUpgrader
 from .repository import Repository
 from .cache import Cache
 from .key import key_creator, RepoKey, PassphraseKey
@@ -556,6 +556,11 @@ class Archiver:
 
         # XXX: should auto-detect if it is an attic repository here
         repo = AtticRepositoryUpgrader(args.location.path, create=False)
+        try:
+            repo.upgrade(args.dry_run, inplace=args.inplace, progress=args.progress)
+        except NotImplementedError as e:
+            print("warning: %s" % e)
+        repo = BorgRepositoryUpgrader(args.location.path, create=False)
         try:
             repo.upgrade(args.dry_run, inplace=args.inplace, progress=args.progress)
         except NotImplementedError as e:

+ 49 - 0
borg/upgrader.py

@@ -276,3 +276,52 @@ class AtticKeyfileKey(KeyfileKey):
                 if line and line.startswith(cls.FILE_ID) and line[10:] == id:
                     return filename
         raise KeyfileNotFoundError(repository.path, keys_dir)
+
+
+class BorgRepositoryUpgrader(Repository):
+    def upgrade(self, dryrun=True, inplace=False, progress=False):
+        """convert an old borg repository to a current borg repository
+        """
+        logger.info("converting borg 0.xx to borg current")
+        try:
+            keyfile = self.find_borg0xx_keyfile()
+        except KeyfileNotFoundError:
+            logger.warning("no key file found for repository")
+        else:
+            self.move_keyfiles(keyfile, dryrun)
+
+    def find_borg0xx_keyfile(self):
+        return Borg0xxKeyfileKey.find_key_file(self)
+
+    def move_keyfiles(self, keyfile, dryrun):
+        filename = os.path.basename(keyfile)
+        new_keyfile = os.path.join(get_keys_dir(), filename)
+        try:
+            os.rename(keyfile, new_keyfile)
+        except FileExistsError:
+            # likely the attic -> borg upgrader already put it in the final location
+            pass
+
+
+class Borg0xxKeyfileKey(KeyfileKey):
+    """backwards compatible borg 0.xx key file parser"""
+
+    @staticmethod
+    def get_keys_dir():
+        return os.environ.get('BORG_KEYS_DIR',
+                              os.path.join(os.path.expanduser('~'), '.borg', 'keys'))
+
+    @classmethod
+    def find_key_file(cls, repository):
+        get_keys_dir = cls.get_keys_dir
+        id = hexlify(repository.id).decode('ascii')
+        keys_dir = get_keys_dir()
+        if not os.path.exists(keys_dir):
+            raise KeyfileNotFoundError(repository.path, keys_dir)
+        for name in os.listdir(keys_dir):
+            filename = os.path.join(keys_dir, name)
+            with open(filename, 'r') as fd:
+                line = fd.readline().strip()
+                if line and line.startswith(cls.FILE_ID) and line[len(cls.FILE_ID)+1:] == id:
+                    return filename
+        raise KeyfileNotFoundError(repository.path, keys_dir)