mirror of
https://github.com/borgmatic-collective/borgmatic.git
synced 2026-07-22 02:03:01 +02:00
Account for the case where "store_config_files: false" and the runtime directory never gets added to patterns to begin with (#1122).
This commit is contained in:
+25
-12
@@ -49,6 +49,7 @@ def validate_planned_backup_paths(
|
||||
dry_run,
|
||||
create_command,
|
||||
config,
|
||||
patterns,
|
||||
local_path,
|
||||
working_directory,
|
||||
borgmatic_runtime_directory,
|
||||
@@ -91,21 +92,32 @@ def validate_planned_backup_paths(
|
||||
if path_line and path_line.startswith(('- ', '+ '))
|
||||
)
|
||||
|
||||
# These are the subset of those files that contain the borgmatic runtime directory.
|
||||
paths_containing_runtime_directory = {}
|
||||
# These are the subset of output paths contained within the borgmatic runtime directory.
|
||||
paths_inside_runtime_directory = {
|
||||
path for path in paths if any_parent_directories(path, (borgmatic_runtime_directory,))
|
||||
}
|
||||
|
||||
if os.path.exists(borgmatic_runtime_directory):
|
||||
paths_containing_runtime_directory = {
|
||||
path for path in paths if any_parent_directories(path, (borgmatic_runtime_directory,))
|
||||
}
|
||||
# If the runtime directory isn't present in the source patterns, then we shouldn't expect it to
|
||||
# be in the paths output from the Borg dry run.
|
||||
runtime_directory_present_in_patterns = any(
|
||||
pattern
|
||||
for pattern in patterns
|
||||
if any_parent_directories(pattern.path, (borgmatic_runtime_directory,))
|
||||
if pattern.type == borgmatic.borg.pattern.Pattern_type.ROOT
|
||||
)
|
||||
|
||||
# If no paths to backup contain the runtime directory, it must've been excluded.
|
||||
if not paths_containing_runtime_directory and not dry_run:
|
||||
raise ValueError(
|
||||
f'The runtime directory {os.path.normpath(borgmatic_runtime_directory)} overlaps with the configured excludes or patterns with excludes. Please ensure the runtime directory is not excluded.',
|
||||
)
|
||||
# If no paths to backup are inside the runtime directory, it must've been excluded.
|
||||
if (
|
||||
not paths_inside_runtime_directory
|
||||
and runtime_directory_present_in_patterns
|
||||
and not dry_run
|
||||
and os.path.exists(borgmatic_runtime_directory)
|
||||
):
|
||||
raise ValueError(
|
||||
f'The runtime directory {os.path.normpath(borgmatic_runtime_directory)} overlaps with the configured excludes or patterns with excludes. Please ensure the runtime directory is not excluded.',
|
||||
)
|
||||
|
||||
return tuple(path for path in paths if path not in paths_containing_runtime_directory)
|
||||
return tuple(path for path in paths if path not in paths_inside_runtime_directory)
|
||||
|
||||
|
||||
MAX_SPECIAL_FILE_PATHS_LENGTH = 1000
|
||||
@@ -227,6 +239,7 @@ def make_base_create_command(
|
||||
dry_run,
|
||||
create_flags + create_positional_arguments,
|
||||
config,
|
||||
patterns,
|
||||
local_path,
|
||||
working_directory,
|
||||
borgmatic_runtime_directory=borgmatic_runtime_directory,
|
||||
|
||||
@@ -71,12 +71,17 @@ def test_validate_planned_backup_paths_parses_borg_dry_run_file_list():
|
||||
'Processing files ...\n- /foo\n+ /bar\n- /baz',
|
||||
)
|
||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||
flexmock(module).should_receive('any_parent_directories').never()
|
||||
flexmock(module).should_receive('any_parent_directories').and_return(False)
|
||||
|
||||
assert module.validate_planned_backup_paths(
|
||||
dry_run=False,
|
||||
create_command=('borg', 'create'),
|
||||
config={},
|
||||
patterns=(
|
||||
module.borgmatic.borg.pattern.Pattern('/foo'),
|
||||
module.borgmatic.borg.pattern.Pattern('/bar'),
|
||||
module.borgmatic.borg.pattern.Pattern('/baz'),
|
||||
),
|
||||
local_path=None,
|
||||
working_directory=None,
|
||||
borgmatic_runtime_directory='/run/borgmatic',
|
||||
@@ -95,23 +100,21 @@ def test_validate_planned_backup_paths_skips_borgmatic_runtime_directory():
|
||||
'+ /foo\n- /run/borgmatic/bar\n- /baz',
|
||||
)
|
||||
flexmock(module.os.path).should_receive('exists').and_return(True)
|
||||
flexmock(module).should_receive('any_parent_directories').with_args(
|
||||
'/foo',
|
||||
('/run/borgmatic',),
|
||||
).and_return(False)
|
||||
flexmock(module).should_receive('any_parent_directories').with_args(
|
||||
'/run/borgmatic/bar',
|
||||
('/run/borgmatic',),
|
||||
).and_return(True)
|
||||
flexmock(module).should_receive('any_parent_directories').with_args(
|
||||
'/baz',
|
||||
('/run/borgmatic',),
|
||||
).and_return(False)
|
||||
flexmock(module).should_receive('any_parent_directories').replace_with(
|
||||
lambda path, _: path == '/run/borgmatic/bar'
|
||||
)
|
||||
|
||||
assert module.validate_planned_backup_paths(
|
||||
dry_run=False,
|
||||
create_command=('borg', 'create'),
|
||||
config={},
|
||||
patterns=(
|
||||
module.borgmatic.borg.pattern.Pattern('/foo'),
|
||||
module.borgmatic.borg.pattern.Pattern(
|
||||
'/run/borgmatic/bar', module.borgmatic.borg.pattern.Pattern_type.ROOT
|
||||
),
|
||||
module.borgmatic.borg.pattern.Pattern('/baz'),
|
||||
),
|
||||
local_path=None,
|
||||
working_directory=None,
|
||||
borgmatic_runtime_directory='/run/borgmatic',
|
||||
@@ -130,19 +133,58 @@ def test_validate_planned_backup_paths_with_borgmatic_runtime_directory_missing_
|
||||
'+ /foo\n- /bar\n- /baz',
|
||||
)
|
||||
flexmock(module.os.path).should_receive('exists').and_return(True)
|
||||
flexmock(module).should_receive('any_parent_directories').and_return(False)
|
||||
flexmock(module).should_receive('any_parent_directories').replace_with(
|
||||
lambda path, _: path == '/run/borgmatic/bar'
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
module.validate_planned_backup_paths(
|
||||
dry_run=False,
|
||||
create_command=('borg', 'create'),
|
||||
config={},
|
||||
patterns=(
|
||||
module.borgmatic.borg.pattern.Pattern('/foo'),
|
||||
module.borgmatic.borg.pattern.Pattern(
|
||||
'/run/borgmatic/bar', module.borgmatic.borg.pattern.Pattern_type.ROOT
|
||||
),
|
||||
module.borgmatic.borg.pattern.Pattern('/baz'),
|
||||
),
|
||||
local_path=None,
|
||||
working_directory=None,
|
||||
borgmatic_runtime_directory='/run/borgmatic',
|
||||
)
|
||||
|
||||
|
||||
def test_validate_planned_backup_paths_with_borgmatic_runtime_directory_missing_from_patterns_does_not_raise():
|
||||
flexmock(module.flags).should_receive('omit_flag').replace_with(
|
||||
lambda arguments, flag: arguments,
|
||||
)
|
||||
flexmock(module.flags).should_receive('omit_flag_and_value').replace_with(
|
||||
lambda arguments, flag: arguments,
|
||||
)
|
||||
flexmock(module.environment).should_receive('make_environment').and_return(None)
|
||||
flexmock(module).should_receive('execute_command_and_capture_output').and_return(
|
||||
'+ /foo\n- /run/borgmatic/bar\n- /baz',
|
||||
)
|
||||
flexmock(module.os.path).should_receive('exists').and_return(True)
|
||||
flexmock(module).should_receive('any_parent_directories').replace_with(
|
||||
lambda path, _: path == '/run/borgmatic/bar'
|
||||
)
|
||||
|
||||
assert module.validate_planned_backup_paths(
|
||||
dry_run=False,
|
||||
create_command=('borg', 'create'),
|
||||
config={},
|
||||
patterns=(
|
||||
module.borgmatic.borg.pattern.Pattern('/foo'),
|
||||
module.borgmatic.borg.pattern.Pattern('/baz'),
|
||||
),
|
||||
local_path=None,
|
||||
working_directory=None,
|
||||
borgmatic_runtime_directory='/run/borgmatic',
|
||||
) == ('/foo', '/baz')
|
||||
|
||||
|
||||
def test_validate_planned_backup_paths_with_dry_run_and_borgmatic_runtime_directory_missing_from_paths_output_does_not_raise():
|
||||
flexmock(module.flags).should_receive('omit_flag').replace_with(
|
||||
lambda arguments, flag: arguments,
|
||||
@@ -152,7 +194,7 @@ def test_validate_planned_backup_paths_with_dry_run_and_borgmatic_runtime_direct
|
||||
)
|
||||
flexmock(module.environment).should_receive('make_environment').and_return(None)
|
||||
flexmock(module).should_receive('execute_command_and_capture_output').and_return(
|
||||
'+ /foo\n- /bar\n- /baz',
|
||||
'+ /foo\n- /run/borgmatic/bar\n- /baz',
|
||||
)
|
||||
flexmock(module.os.path).should_receive('exists').and_return(True)
|
||||
flexmock(module).should_receive('any_parent_directories').and_return(False)
|
||||
@@ -161,10 +203,17 @@ def test_validate_planned_backup_paths_with_dry_run_and_borgmatic_runtime_direct
|
||||
dry_run=True,
|
||||
create_command=('borg', 'create'),
|
||||
config={},
|
||||
patterns=(
|
||||
module.borgmatic.borg.pattern.Pattern('/foo'),
|
||||
module.borgmatic.borg.pattern.Pattern(
|
||||
'/run/borgmatic/bar', module.borgmatic.borg.pattern.Pattern_type.ROOT
|
||||
),
|
||||
module.borgmatic.borg.pattern.Pattern('/baz'),
|
||||
),
|
||||
local_path=None,
|
||||
working_directory=None,
|
||||
borgmatic_runtime_directory='/run/borgmatic',
|
||||
) == ('/foo', '/bar', '/baz')
|
||||
) == ('/foo', '/run/borgmatic/bar', '/baz')
|
||||
|
||||
|
||||
DEFAULT_ARCHIVE_NAME = '{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}'
|
||||
|
||||
Reference in New Issue
Block a user