mirror of
https://github.com/borgbackup/borg.git
synced 2024-12-21 23:33:07 +00:00
remove borg upgrade
This commit is contained in:
parent
3fbb297fd7
commit
dbae8e60eb
7 changed files with 2 additions and 292 deletions
|
@ -60,7 +60,6 @@ Usage
|
|||
usage/tar
|
||||
|
||||
usage/transfer
|
||||
usage/upgrade
|
||||
usage/benchmark
|
||||
|
||||
usage/help
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
.. include:: upgrade.rst.inc
|
||||
|
||||
Examples
|
||||
~~~~~~~~
|
||||
::
|
||||
|
||||
# Upgrade the borg repository to the most recent version.
|
||||
$ borg upgrade -v /path/to/repo
|
||||
making a hardlink copy in /path/to/repo.before-upgrade-2016-02-15-20:51:55
|
||||
opening attic repository with borg and converting
|
||||
no key file found for repository
|
||||
converting repo index /path/to/repo/index.0
|
||||
converting 1 segments...
|
||||
converting borg 0.xx to borg current
|
||||
no key file found for repository
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
.. IMPORTANT: this file is auto-generated from borg's built-in help, do not edit!
|
||||
|
||||
.. _borg_upgrade:
|
||||
|
||||
borg upgrade
|
||||
------------
|
||||
.. code-block:: none
|
||||
|
||||
borg [common options] upgrade [options]
|
||||
|
||||
.. only:: html
|
||||
|
||||
.. class:: borg-options-table
|
||||
|
||||
+-------------------------------------------------------+-----------------------+------------------------------------------------------------------------------------------------+
|
||||
| **optional arguments** |
|
||||
+-------------------------------------------------------+-----------------------+------------------------------------------------------------------------------------------------+
|
||||
| | ``-n``, ``--dry-run`` | do not change repository |
|
||||
+-------------------------------------------------------+-----------------------+------------------------------------------------------------------------------------------------+
|
||||
| | ``--inplace`` | rewrite repository in place, with no chance of going back to older versions of the repository. |
|
||||
+-------------------------------------------------------+-----------------------+------------------------------------------------------------------------------------------------+
|
||||
| | ``--force`` | Force upgrade |
|
||||
+-------------------------------------------------------+-----------------------+------------------------------------------------------------------------------------------------+
|
||||
| | ``--tam`` | Enable manifest authentication (in key and cache) (Borg 1.0.9 and later). |
|
||||
+-------------------------------------------------------+-----------------------+------------------------------------------------------------------------------------------------+
|
||||
| | ``--disable-tam`` | Disable manifest authentication (in key and cache). |
|
||||
+-------------------------------------------------------+-----------------------+------------------------------------------------------------------------------------------------+
|
||||
| .. class:: borg-common-opt-ref |
|
||||
| |
|
||||
| :ref:`common_options` |
|
||||
+-------------------------------------------------------+-----------------------+------------------------------------------------------------------------------------------------+
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<script type='text/javascript'>
|
||||
$(document).ready(function () {
|
||||
$('.borg-options-table colgroup').remove();
|
||||
})
|
||||
</script>
|
||||
|
||||
.. only:: latex
|
||||
|
||||
|
||||
|
||||
optional arguments
|
||||
-n, --dry-run do not change repository
|
||||
--inplace rewrite repository in place, with no chance of going back to older versions of the repository.
|
||||
--force Force upgrade
|
||||
--tam Enable manifest authentication (in key and cache) (Borg 1.0.9 and later).
|
||||
--disable-tam Disable manifest authentication (in key and cache).
|
||||
|
||||
|
||||
:ref:`common_options`
|
||||
|
|
||||
|
||||
Description
|
||||
~~~~~~~~~~~
|
||||
|
||||
Upgrade an existing, local Borg repository.
|
||||
|
||||
When you do not need borg upgrade
|
||||
+++++++++++++++++++++++++++++++++
|
||||
|
||||
Not every change requires that you run ``borg upgrade``.
|
||||
|
||||
You do **not** need to run it when:
|
||||
|
||||
- moving your repository to a different place
|
||||
- upgrading to another point release (like 1.0.x to 1.0.y),
|
||||
except when noted otherwise in the changelog
|
||||
- upgrading from 1.0.x to 1.1.x,
|
||||
except when noted otherwise in the changelog
|
||||
|
||||
Borg 1.x.y upgrades
|
||||
+++++++++++++++++++
|
||||
|
||||
Use ``borg upgrade --tam REPO`` to require manifest authentication
|
||||
introduced with Borg 1.0.9 to address security issues. This means
|
||||
that modifying the repository after doing this with a version prior
|
||||
to 1.0.9 will raise a validation error, so only perform this upgrade
|
||||
after updating all clients using the repository to 1.0.9 or newer.
|
||||
|
||||
This upgrade should be done on each client for safety reasons.
|
||||
|
||||
If a repository is accidentally modified with a pre-1.0.9 client after
|
||||
this upgrade, use ``borg upgrade --tam --force REPO`` to remedy it.
|
||||
|
||||
If you routinely do this you might not want to enable this upgrade
|
||||
(which will leave you exposed to the security issue). You can
|
||||
reverse the upgrade by issuing ``borg upgrade --disable-tam REPO``.
|
||||
|
||||
See
|
||||
https://borgbackup.readthedocs.io/en/stable/changes.html#pre-1-0-9-manifest-spoofing-vulnerability
|
||||
for details.
|
||||
|
||||
Borg 0.xx to Borg 1.x
|
||||
+++++++++++++++++++++
|
||||
|
||||
This currently supports converting Borg 0.xx to 1.0.
|
||||
|
||||
Currently, only LOCAL repositories can be upgraded (issue #465).
|
||||
|
||||
Please note that ``borg create`` (since 1.0.0) uses bigger chunks by
|
||||
default than old borg did, so the new chunks won't deduplicate
|
||||
with the old chunks in the upgraded repository.
|
||||
See ``--chunker-params`` option of ``borg create`` and ``borg recreate``.
|
|
@ -490,16 +490,6 @@ def do_rcreate(self, args, repository, *, other_repository=None, other_key=None)
|
|||
if key.tam_required:
|
||||
tam_file = tam_required_file(repository)
|
||||
open(tam_file, 'w').close()
|
||||
logger.warning(
|
||||
'\n'
|
||||
'By default repositories initialized with this version will produce security\n'
|
||||
'errors if written to with an older version (up to and including Borg 1.0.8).\n'
|
||||
'\n'
|
||||
'If you want to use these older versions, you can disable the check by running:\n'
|
||||
'borg upgrade --disable-tam %s\n'
|
||||
'\n'
|
||||
'See https://borgbackup.readthedocs.io/en/stable/changes.html#pre-1-0-9-manifest-spoofing-vulnerability '
|
||||
'for details about the security implications.', shlex.quote(path))
|
||||
|
||||
if key.NAME != 'plaintext':
|
||||
logger.warning(
|
||||
|
@ -1892,56 +1882,6 @@ def do_prune(self, args, repository, manifest, key):
|
|||
logger=logging.getLogger('borg.output.stats'))
|
||||
return self.exit_code
|
||||
|
||||
@with_repository(fake=('tam', 'disable_tam'), invert_fake=True, manifest=False, exclusive=True)
|
||||
def do_upgrade(self, args, repository, manifest=None, key=None):
|
||||
"""upgrade a repository from a previous version"""
|
||||
if args.tam:
|
||||
manifest, key = Manifest.load(repository, (Manifest.Operation.CHECK,), force_tam_not_required=args.force)
|
||||
|
||||
if not hasattr(key, 'change_passphrase'):
|
||||
print('This repository is not encrypted, cannot enable TAM.')
|
||||
return EXIT_ERROR
|
||||
|
||||
if not manifest.tam_verified or not manifest.config.get('tam_required', False):
|
||||
# The standard archive listing doesn't include the archive ID like in borg 1.1.x
|
||||
print('Manifest contents:')
|
||||
for archive_info in manifest.archives.list(sort_by=['ts']):
|
||||
print(format_archive(archive_info), '[%s]' % bin_to_hex(archive_info.id))
|
||||
manifest.config['tam_required'] = True
|
||||
manifest.write()
|
||||
repository.commit(compact=False)
|
||||
if not key.tam_required:
|
||||
key.tam_required = True
|
||||
key.change_passphrase(key._passphrase)
|
||||
print('Key updated')
|
||||
if hasattr(key, 'find_key'):
|
||||
print('Key location:', key.find_key())
|
||||
if not tam_required(repository):
|
||||
tam_file = tam_required_file(repository)
|
||||
open(tam_file, 'w').close()
|
||||
print('Updated security database')
|
||||
elif args.disable_tam:
|
||||
manifest, key = Manifest.load(repository, Manifest.NO_OPERATION_CHECK, force_tam_not_required=True)
|
||||
if tam_required(repository):
|
||||
os.unlink(tam_required_file(repository))
|
||||
if key.tam_required:
|
||||
key.tam_required = False
|
||||
key.change_passphrase(key._passphrase)
|
||||
print('Key updated')
|
||||
if hasattr(key, 'find_key'):
|
||||
print('Key location:', key.find_key())
|
||||
manifest.config['tam_required'] = False
|
||||
manifest.write()
|
||||
repository.commit(compact=False)
|
||||
else:
|
||||
# mainly for upgrades from borg 0.xx -> 1.0.
|
||||
repo = BorgRepositoryUpgrader(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)
|
||||
return self.exit_code
|
||||
|
||||
@with_repository(cache=True, exclusive=True, compatibility=(Manifest.Operation.CHECK,))
|
||||
def do_recreate(self, args, repository, manifest, key, cache):
|
||||
"""Re-create archives"""
|
||||
|
@ -5070,74 +5010,6 @@ def define_borg_mount(parser):
|
|||
subparser.add_argument('mountpoint', metavar='MOUNTPOINT', type=str,
|
||||
help='mountpoint of the filesystem to umount')
|
||||
|
||||
# borg upgrade
|
||||
upgrade_epilog = process_epilog("""
|
||||
Upgrade an existing, local Borg repository.
|
||||
|
||||
When you do not need borg upgrade
|
||||
+++++++++++++++++++++++++++++++++
|
||||
|
||||
Not every change requires that you run ``borg upgrade``.
|
||||
|
||||
You do **not** need to run it when:
|
||||
|
||||
- moving your repository to a different place
|
||||
- upgrading to another point release (like 1.0.x to 1.0.y),
|
||||
except when noted otherwise in the changelog
|
||||
- upgrading from 1.0.x to 1.1.x,
|
||||
except when noted otherwise in the changelog
|
||||
|
||||
Borg 1.x.y upgrades
|
||||
+++++++++++++++++++
|
||||
|
||||
Use ``borg upgrade --tam REPO`` to require manifest authentication
|
||||
introduced with Borg 1.0.9 to address security issues. This means
|
||||
that modifying the repository after doing this with a version prior
|
||||
to 1.0.9 will raise a validation error, so only perform this upgrade
|
||||
after updating all clients using the repository to 1.0.9 or newer.
|
||||
|
||||
This upgrade should be done on each client for safety reasons.
|
||||
|
||||
If a repository is accidentally modified with a pre-1.0.9 client after
|
||||
this upgrade, use ``borg upgrade --tam --force REPO`` to remedy it.
|
||||
|
||||
If you routinely do this you might not want to enable this upgrade
|
||||
(which will leave you exposed to the security issue). You can
|
||||
reverse the upgrade by issuing ``borg upgrade --disable-tam REPO``.
|
||||
|
||||
See
|
||||
https://borgbackup.readthedocs.io/en/stable/changes.html#pre-1-0-9-manifest-spoofing-vulnerability
|
||||
for details.
|
||||
|
||||
Borg 0.xx to Borg 1.x
|
||||
+++++++++++++++++++++
|
||||
|
||||
This currently supports converting Borg 0.xx to 1.0.
|
||||
|
||||
Currently, only LOCAL repositories can be upgraded (issue #465).
|
||||
|
||||
Please note that ``borg create`` (since 1.0.0) uses bigger chunks by
|
||||
default than old borg did, so the new chunks won't deduplicate
|
||||
with the old chunks in the upgraded repository.
|
||||
See ``--chunker-params`` option of ``borg create`` and ``borg recreate``.""")
|
||||
subparser = subparsers.add_parser('upgrade', parents=[common_parser], add_help=False,
|
||||
description=self.do_upgrade.__doc__,
|
||||
epilog=upgrade_epilog,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
help='upgrade repository format')
|
||||
subparser.set_defaults(func=self.do_upgrade)
|
||||
subparser.add_argument('-n', '--dry-run', dest='dry_run', action='store_true',
|
||||
help='do not change repository')
|
||||
subparser.add_argument('--inplace', dest='inplace', action='store_true',
|
||||
help='rewrite repository in place, with no chance of going back '
|
||||
'to older versions of the repository.')
|
||||
subparser.add_argument('--force', dest='force', action='store_true',
|
||||
help='Force upgrade')
|
||||
subparser.add_argument('--tam', dest='tam', action='store_true',
|
||||
help='Enable manifest authentication (in key and cache) (Borg 1.0.9 and later).')
|
||||
subparser.add_argument('--disable-tam', dest='disable_tam', action='store_true',
|
||||
help='Disable manifest authentication (in key and cache).')
|
||||
|
||||
# borg with-lock
|
||||
with_lock_epilog = process_epilog("""
|
||||
This command runs a user-specified command while the repository lock is held.
|
||||
|
|
|
@ -61,12 +61,7 @@ class UnsupportedKeyFormatError(Error):
|
|||
|
||||
class TAMRequiredError(IntegrityError):
|
||||
__doc__ = textwrap.dedent("""
|
||||
Manifest is unauthenticated, but it is required for this repository.
|
||||
|
||||
This either means that you are under attack, or that you modified this repository
|
||||
with a Borg version older than 1.0.9 after TAM authentication was enabled.
|
||||
|
||||
In the latter case, use "borg upgrade --tam --force '{}'" to re-authenticate the manifest.
|
||||
Manifest is unauthenticated, but it is required for this repository. Is somebody attacking you?
|
||||
""").strip()
|
||||
traceback = False
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ class InvalidRepositoryConfig(Error):
|
|||
"""{} does not have a valid configuration. Check repo config [{}]."""
|
||||
|
||||
class AtticRepository(Error):
|
||||
"""Attic repository detected. Please use borg < 1.3 to run "borg upgrade {}"."""
|
||||
"""Attic repository detected. Please use borg <= 1.2 to run "borg upgrade {}"."""
|
||||
|
||||
class CheckNeeded(ErrorWithTraceback):
|
||||
"""Inconsistency detected. Please run "borg check {}"."""
|
||||
|
|
|
@ -3888,21 +3888,6 @@ def test_not_required(self):
|
|||
self.cmd(f'--repo={self.repository_location}', 'rcreate', '--encryption=repokey')
|
||||
self.create_src_archive('archive1234')
|
||||
repository = Repository(self.repository_path, exclusive=True)
|
||||
with repository:
|
||||
shutil.rmtree(get_security_dir(bin_to_hex(repository.id)))
|
||||
_, key = Manifest.load(repository, Manifest.NO_OPERATION_CHECK)
|
||||
key.tam_required = False
|
||||
key.change_passphrase(key._passphrase)
|
||||
|
||||
manifest = msgpack.unpackb(key.decrypt(Manifest.MANIFEST_ID, repository.get(Manifest.MANIFEST_ID)))
|
||||
del manifest['tam']
|
||||
repository.put(Manifest.MANIFEST_ID, key.encrypt(Manifest.MANIFEST_ID, msgpack.packb(manifest)))
|
||||
repository.commit(compact=False)
|
||||
output = self.cmd(f'--repo={self.repository_location}', 'rlist', '--debug')
|
||||
assert 'archive1234' in output
|
||||
assert 'TAM not found and not required' in output
|
||||
# Run upgrade
|
||||
self.cmd(f'--repo={self.repository_location}', 'upgrade', '--tam')
|
||||
# Manifest must be authenticated now
|
||||
output = self.cmd(f'--repo={self.repository_location}', 'rlist', '--debug')
|
||||
assert 'archive1234' in output
|
||||
|
@ -3912,25 +3897,6 @@ def test_not_required(self):
|
|||
# Fails
|
||||
with pytest.raises(TAMRequiredError):
|
||||
self.cmd(f'--repo={self.repository_location}', 'rlist')
|
||||
# Force upgrade
|
||||
self.cmd(f'--repo={self.repository_location}', 'upgrade', '--tam', '--force')
|
||||
self.cmd(f'--repo={self.repository_location}', 'rlist')
|
||||
|
||||
def test_disable(self):
|
||||
self.cmd(f'--repo={self.repository_location}', 'rcreate', '--encryption=repokey')
|
||||
self.create_src_archive('archive1234')
|
||||
self.cmd(f'--repo={self.repository_location}', 'upgrade', '--disable-tam')
|
||||
repository = Repository(self.repository_path, exclusive=True)
|
||||
self.spoof_manifest(repository)
|
||||
assert not self.cmd(f'--repo={self.repository_location}', 'rlist')
|
||||
|
||||
def test_disable2(self):
|
||||
self.cmd(f'--repo={self.repository_location}', 'rcreate', '--encryption=repokey')
|
||||
self.create_src_archive('archive1234')
|
||||
repository = Repository(self.repository_path, exclusive=True)
|
||||
self.spoof_manifest(repository)
|
||||
self.cmd(f'--repo={self.repository_location}', 'upgrade', '--disable-tam')
|
||||
assert not self.cmd(f'--repo={self.repository_location}', 'rlist')
|
||||
|
||||
|
||||
class RemoteArchiverTestCase(ArchiverTestCase):
|
||||
|
|
Loading…
Reference in a new issue