Browse Source

Bring doc string up to date and rename function for clarity. (#1122).

Dan Helfman 1 week ago
parent
commit
5028fe9ff4
3 changed files with 39 additions and 42 deletions
  1. 11 14
      borgmatic/borg/create.py
  2. 1 1
      tests/end-to-end/test_borgmatic.py
  3. 27 27
      tests/unit/borg/test_create.py

+ 11 - 14
borgmatic/borg/create.py

@@ -45,7 +45,7 @@ def any_parent_directories(path, candidate_parents):
     return False
 
 
-def check_planned_backup_paths(
+def validate_planned_backup_paths(
     dry_run,
     create_command,
     config,
@@ -55,18 +55,15 @@ def check_planned_backup_paths(
 ):
     '''
     Given a dry-run flag, a Borg create command as a tuple, a configuration dict, a local Borg path,
-    a working directory, and the borgmatic runtime directory, collect the paths for any special
-    files (character devices, block devices, and named pipes / FIFOs) that Borg would encounter
-    during a create. These are all paths that could cause Borg to hang if its --read-special flag is
-    used.
-
-    Skip looking for special files in the given borgmatic runtime directory, as borgmatic creates
-    its own special files there for database dumps and we don't want those omitted.
-
-    Additionally, if the borgmatic runtime directory is not contained somewhere in the files Borg
-    plans to backup, that means the user must have excluded the runtime directory (e.g. via
-    "exclude_patterns" or similar). Therefore, raise, because this means Borg won't be able to
-    consume any database dumps and therefore borgmatic will hang when it tries to do so.
+    a working directory, and the borgmatic runtime directory, perform a "borg create --dry-run" to
+    determine whether Borg's planned paths to include in a backup look good. Specifically, if the
+    given runtime directory exists, validate that it will be included in a backup and hasn't been
+    excluded.
+
+    Raise ValueError if the runtime directory has been excluded via "exclude_patterns" or similar,
+    because any features that rely on the runtime directory getting backed up will break.  For
+    instance, without the runtime directory, Borg can't consume any database dumps and borgmatic may
+    hang waiting for them to be consumed.
     '''
     # Omit "--exclude-nodump" from the Borg dry run command, because that flag causes Borg to open
     # files including any named pipe we've created. And omit "--filter" because that can break the
@@ -226,7 +223,7 @@ def make_base_create_command(
     working_directory = borgmatic.config.paths.get_working_directory(config)
 
     logger.debug('Checking file paths Borg plans to include')
-    planned_backup_paths = check_planned_backup_paths(
+    planned_backup_paths = validate_planned_backup_paths(
         dry_run,
         create_flags + create_positional_arguments,
         config,

+ 1 - 1
tests/end-to-end/test_borgmatic.py

@@ -85,7 +85,7 @@ def test_borgmatic_command(generate_configuration):
         )
 
         # Run borgmatic to generate a backup archive, and then list it to make sure it exists.
-        subprocess.check_call(f'borgmatic --config {config_path}'.split(' '))
+        subprocess.check_call(f'borgmatic -v 2 --config {config_path}'.split(' '))
         output = subprocess.check_output(
             f'borgmatic --config {config_path} list --json'.split(' '),
         ).decode(sys.stdout.encoding)

+ 27 - 27
tests/unit/borg/test_create.py

@@ -59,7 +59,7 @@ def test_any_parent_directories_treats_unrelated_paths_as_non_match():
     module.any_parent_directories('/foo/bar.txt', ('/usr', '/etc'))
 
 
-def test_check_planned_backup_paths_parses_borg_dry_run_file_list():
+def test_validate_planned_backup_paths_parses_borg_dry_run_file_list():
     flexmock(module.flags).should_receive('omit_flag').replace_with(
         lambda arguments, flag: arguments,
     )
@@ -73,7 +73,7 @@ def test_check_planned_backup_paths_parses_borg_dry_run_file_list():
     flexmock(module.os.path).should_receive('exists').and_return(False)
     flexmock(module).should_receive('any_parent_directories').never()
 
-    assert module.check_planned_backup_paths(
+    assert module.validate_planned_backup_paths(
         dry_run=False,
         create_command=('borg', 'create'),
         config={},
@@ -83,7 +83,7 @@ def test_check_planned_backup_paths_parses_borg_dry_run_file_list():
     ) == ('/foo', '/bar', '/baz')
 
 
-def test_check_planned_backup_paths_skips_borgmatic_runtime_directory():
+def test_validate_planned_backup_paths_skips_borgmatic_runtime_directory():
     flexmock(module.flags).should_receive('omit_flag').replace_with(
         lambda arguments, flag: arguments,
     )
@@ -108,7 +108,7 @@ def test_check_planned_backup_paths_skips_borgmatic_runtime_directory():
         ('/run/borgmatic',),
     ).and_return(False)
 
-    assert module.check_planned_backup_paths(
+    assert module.validate_planned_backup_paths(
         dry_run=False,
         create_command=('borg', 'create'),
         config={},
@@ -118,7 +118,7 @@ def test_check_planned_backup_paths_skips_borgmatic_runtime_directory():
     ) == ('/foo', '/baz')
 
 
-def test_check_planned_backup_paths_with_borgmatic_runtime_directory_missing_from_paths_output_errors():
+def test_validate_planned_backup_paths_with_borgmatic_runtime_directory_missing_from_paths_output_errors():
     flexmock(module.flags).should_receive('omit_flag').replace_with(
         lambda arguments, flag: arguments,
     )
@@ -133,7 +133,7 @@ def test_check_planned_backup_paths_with_borgmatic_runtime_directory_missing_fro
     flexmock(module).should_receive('any_parent_directories').and_return(False)
 
     with pytest.raises(ValueError):
-        module.check_planned_backup_paths(
+        module.validate_planned_backup_paths(
             dry_run=False,
             create_command=('borg', 'create'),
             config={},
@@ -143,7 +143,7 @@ def test_check_planned_backup_paths_with_borgmatic_runtime_directory_missing_fro
         )
 
 
-def test_check_planned_backup_paths_with_dry_run_and_borgmatic_runtime_directory_missing_from_paths_output_does_not_raise():
+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,
     )
@@ -157,7 +157,7 @@ def test_check_planned_backup_paths_with_dry_run_and_borgmatic_runtime_directory
     flexmock(module.os.path).should_receive('exists').and_return(True)
     flexmock(module).should_receive('any_parent_directories').and_return(False)
 
-    assert module.check_planned_backup_paths(
+    assert module.validate_planned_backup_paths(
         dry_run=True,
         create_command=('borg', 'create'),
         config={},
@@ -180,7 +180,7 @@ def test_make_base_create_produces_borg_command():
     flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
         (f'repo::{DEFAULT_ARCHIVE_NAME}',),
     )
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,
@@ -216,7 +216,7 @@ def test_make_base_create_command_includes_patterns_file_in_borg_command():
     flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
         (f'repo::{DEFAULT_ARCHIVE_NAME}',),
     )
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,
@@ -249,7 +249,7 @@ def test_make_base_create_command_with_store_config_false_omits_config_files():
     flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
         (f'repo::{DEFAULT_ARCHIVE_NAME}',),
     )
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,
@@ -318,7 +318,7 @@ def test_make_base_create_command_includes_configuration_option_as_command_flag(
     flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
         (f'repo::{DEFAULT_ARCHIVE_NAME}',),
     )
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,
@@ -351,7 +351,7 @@ def test_make_base_create_command_includes_dry_run_in_borg_command():
     flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
         (f'repo::{DEFAULT_ARCHIVE_NAME}',),
     )
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=True,
@@ -384,7 +384,7 @@ def test_make_base_create_command_includes_comment_in_borg_command():
     flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
         (f'repo::{DEFAULT_ARCHIVE_NAME}',),
     )
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,
@@ -418,7 +418,7 @@ def test_make_base_create_command_includes_local_path_in_borg_command():
     flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
         (f'repo::{DEFAULT_ARCHIVE_NAME}',),
     )
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,
@@ -451,7 +451,7 @@ def test_make_base_create_command_includes_remote_path_in_borg_command():
     flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
         (f'repo::{DEFAULT_ARCHIVE_NAME}',),
     )
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,
@@ -484,7 +484,7 @@ def test_make_base_create_command_includes_log_json_in_borg_command():
     flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
         (f'repo::{DEFAULT_ARCHIVE_NAME}',),
     )
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,
@@ -517,7 +517,7 @@ def test_make_base_create_command_includes_list_flags_in_borg_command():
     flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
         (f'repo::{DEFAULT_ARCHIVE_NAME}',),
     )
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,
@@ -557,7 +557,7 @@ def test_make_base_create_command_with_stream_processes_ignores_read_special_fal
     )
     flexmock(module.logger).should_receive('warning').twice()
     flexmock(module.environment).should_receive('make_environment')
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(
         (
             '/non/special',
             '/dev/null',
@@ -620,7 +620,7 @@ def test_make_base_create_command_without_patterns_and_with_stream_processes_ign
     )
     flexmock(module.logger).should_receive('warning').twice()
     flexmock(module.environment).should_receive('make_environment')
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(
         (
             '/non/special',
             '/dev/null',
@@ -679,7 +679,7 @@ def test_make_base_create_command_with_stream_processes_and_read_special_true_sk
         (f'repo::{DEFAULT_ARCHIVE_NAME}',),
     )
     flexmock(module.logger).should_receive('warning').never()
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,
@@ -713,7 +713,7 @@ def test_make_base_create_command_includes_archive_name_format_in_borg_command()
     flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
         ('repo::ARCHIVE_NAME',),
     )
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,
@@ -746,7 +746,7 @@ def test_make_base_create_command_includes_default_archive_name_format_in_borg_c
     flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
         ('repo::{hostname}',),
     )
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,
@@ -778,7 +778,7 @@ def test_make_base_create_command_includes_archive_name_format_with_placeholders
     flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
         (repository_archive_pattern,),
     )
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,
@@ -811,7 +811,7 @@ def test_make_base_create_command_includes_repository_and_archive_name_format_wi
     flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
         (repository_archive_pattern,),
     )
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,
@@ -840,7 +840,7 @@ def test_make_base_create_command_includes_archive_suffix_in_borg_command():
         DEFAULT_ARCHIVE_NAME,
     )
     flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(())
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,
@@ -873,7 +873,7 @@ def test_make_base_create_command_includes_extra_borg_options_in_borg_command():
     flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
         (f'repo::{DEFAULT_ARCHIVE_NAME}',),
     )
-    flexmock(module).should_receive('check_planned_backup_paths').and_return(())
+    flexmock(module).should_receive('validate_planned_backup_paths').and_return(())
 
     (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command(
         dry_run=False,