diff --git a/borg/archiver.py b/borg/archiver.py index f704f5367..1e5e80ee1 100644 --- a/borg/archiver.py +++ b/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: diff --git a/borg/upgrader.py b/borg/upgrader.py index 2d8856ee7..6884f7d34 100644 --- a/borg/upgrader.py +++ b/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)