mirror of https://github.com/borgbackup/borg.git
rename convert command to upgrade
convert is too generic for the Attic conversion: we may have other converters, from other, more foreign systems that will require different options and different upgrade mechanisms that convert could never cover appropriately. we are more likely to use an approach similar to "git fast-import" instead here, and have the conversion tools be external tool that feed standard data into borg during conversion. upgrade seems like a more natural fit: Attic could be considered like a pre-historic version of Borg that requires invasive changes for borg to be able to use the repository. we may require such changes in the future of borg as well: if we make backwards-incompatible changes to the repository layout or data format, it is possible that we require such changes to be performed on the repository before it is usable again. instead of scattering those conversions all over the code, we should simply have assertions that check the layout is correct and point the user to upgrade if it is not. upgrade should eventually automatically detect the repository format or version and perform appropriate conversions. Attic is only the first one. we still need to implement an adequate API for auto-detection and upgrade, only the seeds of that are present for now. of course, changes to the upgrade command should be thoroughly documented in the release notes and an eventual upgrade manual.
This commit is contained in:
parent
48b7c8cea3
commit
c91c5d0029
|
@ -17,7 +17,7 @@ import traceback
|
|||
from . import __version__
|
||||
from .archive import Archive, ArchiveChecker, CHUNKER_PARAMS
|
||||
from .compress import Compressor, COMPR_BUFFER
|
||||
from .converter import AtticRepositoryConverter
|
||||
from .upgrader import AtticRepositoryUpgrader
|
||||
from .repository import Repository
|
||||
from .cache import Cache
|
||||
from .key import key_creator
|
||||
|
@ -463,11 +463,20 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
|
|||
stats.print_('Deleted data:', cache)
|
||||
return self.exit_code
|
||||
|
||||
def do_convert(self, args):
|
||||
"""convert a repository from attic to borg"""
|
||||
repo = AtticRepositoryConverter(args.repository.path, create=False)
|
||||
def do_upgrade(self, args):
|
||||
"""upgrade a repository from a previous version"""
|
||||
# XXX: currently only upgrades from Attic repositories, but may
|
||||
# eventually be extended to deal with major upgrades for borg
|
||||
# itself.
|
||||
#
|
||||
# in this case, it should auto-detect the current repository
|
||||
# format and fire up necessary upgrade mechanism. this remains
|
||||
# to be implemented.
|
||||
|
||||
# XXX: should auto-detect if it is an attic repository here
|
||||
repo = AtticRepositoryUpgrader(args.repository.path, create=False)
|
||||
try:
|
||||
repo.convert(args.dry_run)
|
||||
repo.upgrade(args.dry_run)
|
||||
except NotImplementedError as e:
|
||||
print("warning: %s" % e)
|
||||
return self.exit_code
|
||||
|
@ -906,8 +915,10 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
|
|||
type=location_validator(archive=False),
|
||||
help='repository to prune')
|
||||
|
||||
convert_epilog = textwrap.dedent("""
|
||||
convert will convert an existing Attic repository to Borg in place.
|
||||
upgrade_epilog = textwrap.dedent("""
|
||||
upgrade an existing Borg repository in place. this currently
|
||||
only support converting an Attic repository, but may
|
||||
eventually be extended to cover major Borg upgrades as well.
|
||||
|
||||
it will change the magic strings in the repository's segments
|
||||
to match the new Borg magic strings. the keyfiles found in
|
||||
|
@ -928,21 +939,21 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
|
|||
repository, in case something goes wrong, for example:
|
||||
|
||||
cp -a attic borg
|
||||
borg convert -n borg
|
||||
borg convert borg
|
||||
borg upgrade -n borg
|
||||
borg upgrade borg
|
||||
|
||||
you have been warned.""")
|
||||
subparser = subparsers.add_parser('convert', parents=[common_parser],
|
||||
description=self.do_convert.__doc__,
|
||||
epilog=convert_epilog,
|
||||
subparser = subparsers.add_parser('upgrade', parents=[common_parser],
|
||||
description=self.do_upgrade.__doc__,
|
||||
epilog=upgrade_epilog,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
subparser.set_defaults(func=self.do_convert)
|
||||
subparser.set_defaults(func=self.do_upgrade)
|
||||
subparser.add_argument('-n', '--dry-run', dest='dry_run',
|
||||
default=False, action='store_true',
|
||||
help='do not change repository')
|
||||
subparser.add_argument('repository', metavar='REPOSITORY', nargs='?', default='',
|
||||
type=location_validator(archive=False),
|
||||
help='path to the attic repository to be converted')
|
||||
help='path to the repository to be upgraded')
|
||||
|
||||
subparser = subparsers.add_parser('help', parents=[common_parser],
|
||||
description='Extra help')
|
||||
|
|
|
@ -11,7 +11,7 @@ try:
|
|||
except ImportError:
|
||||
attic = None
|
||||
|
||||
from ..converter import AtticRepositoryConverter, AtticKeyfileKey
|
||||
from ..upgrader import AtticRepositoryUpgrader, AtticKeyfileKey
|
||||
from ..helpers import get_keys_dir
|
||||
from ..key import KeyfileKey
|
||||
from ..repository import Repository, MAGIC
|
||||
|
@ -78,7 +78,7 @@ def test_convert_segments(tmpdir, attic_repo):
|
|||
# check should fail because of magic number
|
||||
assert not repo_valid(tmpdir)
|
||||
print("opening attic repository with borg and converting")
|
||||
repo = AtticRepositoryConverter(str(tmpdir), create=False)
|
||||
repo = AtticRepositoryUpgrader(str(tmpdir), create=False)
|
||||
segments = [filename for i, filename in repo.io.segment_iterator()]
|
||||
repo.close()
|
||||
repo.convert_segments(segments, dryrun=False)
|
||||
|
@ -136,9 +136,9 @@ def test_keys(tmpdir, attic_repo, attic_key_file):
|
|||
define above)
|
||||
:param attic_key_file: an attic.key.KeyfileKey (fixture created above)
|
||||
"""
|
||||
repository = AtticRepositoryConverter(str(tmpdir), create=False)
|
||||
repository = AtticRepositoryUpgrader(str(tmpdir), create=False)
|
||||
keyfile = AtticKeyfileKey.find_key_file(repository)
|
||||
AtticRepositoryConverter.convert_keyfiles(keyfile, dryrun=False)
|
||||
AtticRepositoryUpgrader.convert_keyfiles(keyfile, dryrun=False)
|
||||
assert key_valid(attic_key_file.path)
|
||||
|
||||
|
||||
|
@ -157,7 +157,7 @@ def test_convert_all(tmpdir, attic_repo, attic_key_file):
|
|||
# check should fail because of magic number
|
||||
assert not repo_valid(tmpdir)
|
||||
print("opening attic repository with borg and converting")
|
||||
repo = AtticRepositoryConverter(str(tmpdir), create=False)
|
||||
repo.convert(dryrun=False)
|
||||
repo = AtticRepositoryUpgrader(str(tmpdir), create=False)
|
||||
repo.upgrade(dryrun=False)
|
||||
assert key_valid(attic_key_file.path)
|
||||
assert repo_valid(tmpdir)
|
|
@ -11,11 +11,11 @@ from .key import KeyfileKey, KeyfileNotFoundError
|
|||
ATTIC_MAGIC = b'ATTICSEG'
|
||||
|
||||
|
||||
class AtticRepositoryConverter(Repository):
|
||||
def convert(self, dryrun=True):
|
||||
class AtticRepositoryUpgrader(Repository):
|
||||
def upgrade(self, dryrun=True):
|
||||
"""convert an attic repository to a borg repository
|
||||
|
||||
those are the files that need to be converted here, from most
|
||||
those are the files that need to be upgraded here, from most
|
||||
important to least important: segments, key files, and various
|
||||
caches, the latter being optional, as they will be rebuilt if
|
||||
missing.
|
||||
|
@ -62,7 +62,7 @@ class AtticRepositoryConverter(Repository):
|
|||
if dryrun:
|
||||
time.sleep(0.001)
|
||||
else:
|
||||
AtticRepositoryConverter.header_replace(filename, ATTIC_MAGIC, MAGIC)
|
||||
AtticRepositoryUpgrader.header_replace(filename, ATTIC_MAGIC, MAGIC)
|
||||
print()
|
||||
|
||||
@staticmethod
|
||||
|
@ -197,7 +197,7 @@ class AtticRepositoryConverter(Repository):
|
|||
for cache in caches:
|
||||
print("converting cache %s" % cache)
|
||||
if not dryrun:
|
||||
AtticRepositoryConverter.header_replace(cache, b'ATTICIDX', b'BORG_IDX')
|
||||
AtticRepositoryUpgrader.header_replace(cache, b'ATTICIDX', b'BORG_IDX')
|
||||
|
||||
|
||||
class AtticKeyfileKey(KeyfileKey):
|
Loading…
Reference in New Issue