Skip to content

Commit

Permalink
When running the "rcreate" action and the repository already exists b…
Browse files Browse the repository at this point in the history
…ut with a different encryption mode than requested, error (#840).
  • Loading branch information
witten committed Mar 11, 2024
1 parent cf9e387 commit a08c7fc
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 9 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#apprise-hook
* #839: Document a potentially breaking shell quoting edge case within error hooks:
https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#error-hooks
* #840: When running the "rcreate" action and the repository already exists but with a different
encryption mode than requested, error.
* Switch from Drone to Gitea Actions for continuous integration.
* Rename scripts/run-end-to-end-dev-tests to scripts/run-end-to-end-tests and use it in both dev
and CI for better dev-CI parity.
Expand Down
30 changes: 22 additions & 8 deletions borgmatic/borg/rcreate.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import argparse
import json
import logging
import subprocess

Expand Down Expand Up @@ -31,17 +32,30 @@ def create_repository(
version, a Borg encryption mode, the path to another repo whose key material should be reused,
whether the repository should be append-only, and the storage quota to use, create the
repository. If the repository already exists, then log and skip creation.
Raise ValueError if the requested encryption mode does not match that of the repository.
Raise json.decoder.JSONDecodeError if the "borg info" JSON outputcannot be decoded.
Raise subprocess.CalledProcessError if "borg info" returns an error exit code.
'''
try:
rinfo.display_repository_info(
repository_path,
config,
local_borg_version,
argparse.Namespace(json=True),
global_arguments,
local_path,
remote_path,
info_data = json.loads(
rinfo.display_repository_info(
repository_path,
config,
local_borg_version,
argparse.Namespace(json=True),
global_arguments,
local_path,
remote_path,
)
)
repository_encryption_mode = info_data.get('encryption', {}).get('mode')

if repository_encryption_mode != encryption_mode:
raise ValueError(
f'Requested encryption mode "{encryption_mode}" does not match existing repository encryption mode "{repository_encryption_mode}"'
)

logger.info(f'{repository_path}: Repository already exists. Skipping creation.')
return
except subprocess.CalledProcessError as error:
Expand Down
25 changes: 24 additions & 1 deletion tests/unit/borg/test_rcreate.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@


def insert_rinfo_command_found_mock():
flexmock(module.rinfo).should_receive('display_repository_info')
flexmock(module.rinfo).should_receive('display_repository_info').and_return(
'{"encryption": {"mode": "repokey"}}'
)


def insert_rinfo_command_not_found_mock():
Expand Down Expand Up @@ -120,6 +122,27 @@ def test_create_repository_skips_creation_when_repository_already_exists():
)


def test_create_repository_errors_when_repository_with_differing_encryption_mode_already_exists():
insert_rinfo_command_found_mock()
flexmock(module.feature).should_receive('available').and_return(True)
flexmock(module.flags).should_receive('make_repository_flags').and_return(
(
'--repo',
'repo',
)
)

with pytest.raises(ValueError):
module.create_repository(
dry_run=False,
repository_path='repo',
config={},
local_borg_version='2.3.4',
global_arguments=flexmock(log_json=False),
encryption_mode='repokey-blake2',
)


def test_create_repository_raises_for_unknown_rinfo_command_error():
flexmock(module.rinfo).should_receive('display_repository_info').and_raise(
subprocess.CalledProcessError(RINFO_SOME_UNKNOWN_EXIT_CODE, [])
Expand Down

0 comments on commit a08c7fc

Please sign in to comment.