mirror of
https://github.com/borgmatic-collective/borgmatic.git
synced 2026-08-01 14:13:01 +02:00
Display a nicer error message when the "recreate" action encounters an archive that already exists (#1053).
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
2.0.2.dev0
|
||||
* #1035: Document potential performance issues and workarounds with the ZFS, Btrfs, and LVM hooks:
|
||||
https://torsion.org/borgmatic/docs/how-to/snapshot-your-filesystems/
|
||||
* #1053: Display a nicer error message when running the "recreate" action on a leftover temporary
|
||||
archive from a prior recreate run.
|
||||
* #1053: Display a nicer error message when the "recreate" action encounters an archive that
|
||||
already exists.
|
||||
* #1059: Fix a regression in which soft failure exit codes in command hooks were not respected.
|
||||
* #1060: Fix action command hooks getting run too many times when multiple borgmatic actions are
|
||||
executed (implicitly or explicitly).
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import logging
|
||||
import subprocess
|
||||
|
||||
import borgmatic.borg.info
|
||||
import borgmatic.borg.recreate
|
||||
import borgmatic.borg.repo_list
|
||||
import borgmatic.config.validate
|
||||
@@ -8,6 +10,9 @@ from borgmatic.actions.pattern import collect_patterns, process_patterns
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
BORG_EXIT_CODE_ARCHIVE_ALREADY_EXISTS = 30
|
||||
|
||||
|
||||
def run_recreate(
|
||||
repository,
|
||||
config,
|
||||
@@ -53,14 +58,27 @@ def run_recreate(
|
||||
f'The archive "{recreate_arguments.archive}" is leftover from a prior recreate. Select a different archive.'
|
||||
)
|
||||
|
||||
borgmatic.borg.recreate.recreate_archive(
|
||||
repository['path'],
|
||||
archive,
|
||||
config,
|
||||
local_borg_version,
|
||||
recreate_arguments,
|
||||
global_arguments,
|
||||
local_path=local_path,
|
||||
remote_path=remote_path,
|
||||
patterns=processed_patterns,
|
||||
)
|
||||
try:
|
||||
borgmatic.borg.recreate.recreate_archive(
|
||||
repository['path'],
|
||||
archive,
|
||||
config,
|
||||
local_borg_version,
|
||||
recreate_arguments,
|
||||
global_arguments,
|
||||
local_path=local_path,
|
||||
remote_path=remote_path,
|
||||
patterns=processed_patterns,
|
||||
)
|
||||
except subprocess.CalledProcessError as error:
|
||||
if error.returncode == BORG_EXIT_CODE_ARCHIVE_ALREADY_EXISTS:
|
||||
if recreate_arguments.target:
|
||||
raise ValueError(
|
||||
f'The archive "{recreate_arguments.target}" already exists. Delete it first or set a different target archive name.'
|
||||
)
|
||||
elif archive:
|
||||
raise ValueError(
|
||||
f'The archive "{archive}.recreate" is leftover from a prior recreate. Delete it first or select a different archive.'
|
||||
)
|
||||
|
||||
raise
|
||||
|
||||
@@ -92,3 +92,91 @@ def test_run_recreate_with_latest_archive_resolving_to_leftover_recreate_archive
|
||||
local_path=None,
|
||||
remote_path=None,
|
||||
)
|
||||
|
||||
|
||||
def test_run_recreate_with_archive_already_exists_error_raises():
|
||||
flexmock(module.logger).answer = lambda message: None
|
||||
flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True)
|
||||
flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(
|
||||
flexmock()
|
||||
)
|
||||
flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return(
|
||||
'test-archive'
|
||||
)
|
||||
flexmock(module.borgmatic.borg.recreate).should_receive('recreate_archive').and_raise(
|
||||
module.subprocess.CalledProcessError(
|
||||
returncode=module.BORG_EXIT_CODE_ARCHIVE_ALREADY_EXISTS,
|
||||
cmd='borg recreate or whatever',
|
||||
)
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
module.run_recreate(
|
||||
repository={'path': 'repo'},
|
||||
config={},
|
||||
local_borg_version=None,
|
||||
recreate_arguments=flexmock(repository=flexmock(), archive='test-archive', target=None),
|
||||
global_arguments=flexmock(),
|
||||
local_path=None,
|
||||
remote_path=None,
|
||||
)
|
||||
|
||||
|
||||
def test_run_recreate_with_target_and_archive_already_exists_error_raises():
|
||||
flexmock(module.logger).answer = lambda message: None
|
||||
flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True)
|
||||
flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(
|
||||
flexmock()
|
||||
)
|
||||
flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return(
|
||||
'test-archive'
|
||||
)
|
||||
flexmock(module.borgmatic.borg.recreate).should_receive('recreate_archive').and_raise(
|
||||
module.subprocess.CalledProcessError(
|
||||
returncode=module.BORG_EXIT_CODE_ARCHIVE_ALREADY_EXISTS,
|
||||
cmd='borg recreate or whatever',
|
||||
)
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
module.run_recreate(
|
||||
repository={'path': 'repo'},
|
||||
config={},
|
||||
local_borg_version=None,
|
||||
recreate_arguments=flexmock(
|
||||
repository=flexmock(), archive='test-archive', target='target-archive'
|
||||
),
|
||||
global_arguments=flexmock(),
|
||||
local_path=None,
|
||||
remote_path=None,
|
||||
)
|
||||
|
||||
|
||||
def test_run_recreate_with_other_called_process_error_passes_it_through():
|
||||
flexmock(module.logger).answer = lambda message: None
|
||||
flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True)
|
||||
flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(
|
||||
flexmock()
|
||||
)
|
||||
flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return(
|
||||
'test-archive'
|
||||
)
|
||||
flexmock(module.borgmatic.borg.recreate).should_receive('recreate_archive').and_raise(
|
||||
module.subprocess.CalledProcessError(
|
||||
returncode=1,
|
||||
cmd='borg recreate or whatever',
|
||||
)
|
||||
)
|
||||
|
||||
with pytest.raises(module.subprocess.CalledProcessError):
|
||||
module.run_recreate(
|
||||
repository={'path': 'repo'},
|
||||
config={},
|
||||
local_borg_version=None,
|
||||
recreate_arguments=flexmock(
|
||||
repository=flexmock(), archive='test-archive', target='target-archive'
|
||||
),
|
||||
global_arguments=flexmock(),
|
||||
local_path=None,
|
||||
remote_path=None,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user