diff --git a/borgmatic/actions/create.py b/borgmatic/actions/create.py index 1d750f6..7a6b935 100644 --- a/borgmatic/actions/create.py +++ b/borgmatic/actions/create.py @@ -91,7 +91,10 @@ def run_create( borgmatic.hooks.dump.DATABASE_HOOK_NAMES, global_arguments.dry_run, ) - create_borgmatic_manifest(config, global_arguments.used_config_paths, global_arguments.dry_run) + if config.get('store_config_files', True): + create_borgmatic_manifest( + config, global_arguments.used_config_paths, global_arguments.dry_run + ) stream_processes = [process for processes in active_dumps.values() for process in processes] json_output = borgmatic.borg.create.create_archive( diff --git a/borgmatic/borg/create.py b/borgmatic/borg/create.py index d778e56..db94e2f 100644 --- a/borgmatic/borg/create.py +++ b/borgmatic/borg/create.py @@ -354,7 +354,11 @@ def create_archive( expand_directories( tuple(config.get('source_directories', ())) + borgmatic_source_directories - + tuple(global_arguments.used_config_paths) + + tuple( + global_arguments.used_config_paths + if config.get('store_config_files', True) + else () + ) ) ), additional_directory_devices=map_directories_to_devices( diff --git a/borgmatic/config/schema.yaml b/borgmatic/config/schema.yaml index f5eb001..fdd7df7 100644 --- a/borgmatic/config/schema.yaml +++ b/borgmatic/config/schema.yaml @@ -210,6 +210,13 @@ properties: "borgmatic restore" from finding any database dumps created before the change. Defaults to ~/.borgmatic example: /tmp/borgmatic + store_config_files: + type: boolean + description: | + Store configuration files used to create a backup in the backup + itself. Defaults to true. Changing this to false prevents "borgmatic + bootstrap" from extracting configuration files from the backup. + example: true source_directories_must_exist: type: boolean description: | diff --git a/tests/unit/actions/test_create.py b/tests/unit/actions/test_create.py index 355e544..fbd974c 100644 --- a/tests/unit/actions/test_create.py +++ b/tests/unit/actions/test_create.py @@ -39,6 +39,41 @@ def test_run_create_executes_and_calls_hooks_for_configured_repository(): ) ) +def test_run_create_with_store_config_files_false_does_not_create_borgmatic_manifest(): + flexmock(module.logger).answer = lambda message: None + flexmock(module.borgmatic.config.validate).should_receive('repositories_match').never() + flexmock(module.borgmatic.borg.create).should_receive('create_archive').once() + flexmock(module).should_receive('create_borgmatic_manifest').never() + flexmock(module.borgmatic.hooks.command).should_receive('execute_hook').times(2) + flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').and_return({}) + flexmock(module.borgmatic.hooks.dispatch).should_receive( + 'call_hooks_even_if_unconfigured' + ).and_return({}) + create_arguments = flexmock( + repository=None, + progress=flexmock(), + stats=flexmock(), + json=flexmock(), + list_files=flexmock(), + ) + global_arguments = flexmock(monitoring_verbosity=1, dry_run=False, used_config_paths=[]) + + list( + module.run_create( + config_filename='test.yaml', + repository={'path': 'repo'}, + config={ + 'store_config_files': False + }, + hook_context={}, + local_borg_version=None, + create_arguments=create_arguments, + global_arguments=global_arguments, + dry_run_label='', + local_path=None, + remote_path=None, + ) + ) def test_run_create_runs_with_selected_repository(): flexmock(module.logger).answer = lambda message: None diff --git a/tests/unit/borg/test_create.py b/tests/unit/borg/test_create.py index dfea86e..7f04868 100644 --- a/tests/unit/borg/test_create.py +++ b/tests/unit/borg/test_create.py @@ -646,6 +646,53 @@ def test_create_archive_with_sources_and_used_config_paths_calls_borg_with_sourc global_arguments=flexmock(log_json=False, used_config_paths=['/etc/borgmatic/config.yaml']), ) +def test_create_archive_with_sources_and_used_config_paths_with_store_config_files_false_calls_borg_with_sources_and_no_config_paths(): + flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') + flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER + flexmock(module).should_receive('collect_borgmatic_source_directories').and_return([]) + flexmock(module).should_receive('deduplicate_directories').and_return( + ('foo', 'bar') + ) + flexmock(module).should_receive('map_directories_to_devices').and_return({}) + flexmock(module).should_receive('expand_directories').with_args([]).and_return(()) + flexmock(module).should_receive('expand_directories').with_args( + ('foo', 'bar') + ).and_return(('foo', 'bar')) + flexmock(module).should_receive('expand_directories').with_args([]).and_return(()) + flexmock(module).should_receive('pattern_root_directories').and_return([]) + flexmock(module.os.path).should_receive('expanduser').and_raise(TypeError) + flexmock(module).should_receive('expand_home_directories').and_return(()) + flexmock(module).should_receive('write_pattern_file').and_return(None) + flexmock(module).should_receive('make_list_filter_flags').and_return('FOO') + flexmock(module.feature).should_receive('available').and_return(True) + flexmock(module).should_receive('ensure_files_readable') + flexmock(module).should_receive('make_pattern_flags').and_return(()) + flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( + (f'repo::{DEFAULT_ARCHIVE_NAME}',) + ) + environment = {'BORG_THINGY': 'YUP'} + flexmock(module.environment).should_receive('make_environment').and_return(environment) + flexmock(module).should_receive('execute_command').with_args( + ('borg', 'create') + REPO_ARCHIVE_WITH_PATHS, + output_log_level=logging.INFO, + output_file=None, + borg_local_path='borg', + working_directory=None, + extra_environment=environment, + ) + + module.create_archive( + dry_run=False, + repository_path='repo', + config={ + 'source_directories': ['foo', 'bar'], + 'repositories': ['repo'], + 'store_config_files': False, + }, + local_borg_version='1.2.3', + global_arguments=flexmock(log_json=False, used_config_paths=['/etc/borgmatic/config.yaml']), + ) def test_create_archive_with_exclude_patterns_calls_borg_with_excludes(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')