diff --git a/NEWS b/NEWS index 20214674..e196a70f 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,8 @@ * #682: Fix "source_directories_must_exist" option to expand globs and tildes in source directories. * #684: Rename "master" development branch to "main" to use more inclusive language. You'll need to update your development checkouts accordingly. + * Run "borgmatic borg" action without capturing output so interactive prompts and flags like + "--progress" still work. 1.7.12 * #413: Add "log_file" context to command hooks so your scripts can consume the borgmatic log file. diff --git a/borgmatic/borg/borg.py b/borgmatic/borg/borg.py index f19d6555..1c41b8ec 100644 --- a/borgmatic/borg/borg.py +++ b/borgmatic/borg/borg.py @@ -2,7 +2,7 @@ import logging import borgmatic.logger from borgmatic.borg import environment, flags -from borgmatic.execute import execute_command +from borgmatic.execute import DO_NOT_CAPTURE, execute_command logger = logging.getLogger(__name__) @@ -62,7 +62,7 @@ def run_arbitrary_borg( return execute_command( full_command, - output_log_level=logging.ANSWER, + output_file=DO_NOT_CAPTURE, borg_local_path=local_path, extra_environment=environment.make_environment(storage_config), ) diff --git a/docs/how-to/monitor-your-backups.md b/docs/how-to/monitor-your-backups.md index eb7a6200..517f9c79 100644 --- a/docs/how-to/monitor-your-backups.md +++ b/docs/how-to/monitor-your-backups.md @@ -73,7 +73,7 @@ from borgmatic for a configured interval. ### Consistency checks -While not strictly part of monitoring, if you really want confidence that your +While not strictly part of monitoring, if you want confidence that your backups are not only running but are restorable as well, you can configure particular [consistency checks](https://torsion.org/borgmatic/docs/how-to/deal-with-very-large-backups/#consistency-check-configuration) diff --git a/docs/how-to/run-arbitrary-borg-commands.md b/docs/how-to/run-arbitrary-borg-commands.md index 0777ebba..ea265eaa 100644 --- a/docs/how-to/run-arbitrary-borg-commands.md +++ b/docs/how-to/run-arbitrary-borg-commands.md @@ -89,8 +89,10 @@ borgmatic's `borg` action is not without limitations: * Unlike normal borgmatic actions that support JSON, the `borg` action will not disable certain borgmatic logs to avoid interfering with JSON output. * Unlike other borgmatic actions, the `borg` action captures (and logs) all - output, so interactive prompts or flags like `--progress` will not work as - expected. + output, so interactive prompts and flags like `--progress` will not work as + expected. New in version + 1.7.13 borgmatic now runs the `borg` action without capturing output, + so interactive prompts work. In general, this `borgmatic borg` feature should be considered an escape valveā€”a feature of second resort. In the long run, it's preferable to wrap diff --git a/tests/unit/borg/test_borg.py b/tests/unit/borg/test_borg.py index 5b735960..4c71ce1a 100644 --- a/tests/unit/borg/test_borg.py +++ b/tests/unit/borg/test_borg.py @@ -15,7 +15,7 @@ def test_run_arbitrary_borg_calls_borg_with_parameters(): flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'break-lock', 'repo'), - output_log_level=module.borgmatic.logger.ANSWER, + output_file=module.borgmatic.execute.DO_NOT_CAPTURE, borg_local_path='borg', extra_environment=None, ) @@ -36,7 +36,7 @@ def test_run_arbitrary_borg_with_log_info_calls_borg_with_info_parameter(): flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'break-lock', 'repo', '--info'), - output_log_level=module.borgmatic.logger.ANSWER, + output_file=module.borgmatic.execute.DO_NOT_CAPTURE, borg_local_path='borg', extra_environment=None, ) @@ -58,7 +58,7 @@ def test_run_arbitrary_borg_with_log_debug_calls_borg_with_debug_parameter(): flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'break-lock', 'repo', '--debug', '--show-rc'), - output_log_level=module.borgmatic.logger.ANSWER, + output_file=module.borgmatic.execute.DO_NOT_CAPTURE, borg_local_path='borg', extra_environment=None, ) @@ -83,7 +83,7 @@ def test_run_arbitrary_borg_with_lock_wait_calls_borg_with_lock_wait_parameters( flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'break-lock', 'repo', '--lock-wait', '5'), - output_log_level=module.borgmatic.logger.ANSWER, + output_file=module.borgmatic.execute.DO_NOT_CAPTURE, borg_local_path='borg', extra_environment=None, ) @@ -106,7 +106,7 @@ def test_run_arbitrary_borg_with_archive_calls_borg_with_archive_parameter(): flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'break-lock', 'repo::archive'), - output_log_level=module.borgmatic.logger.ANSWER, + output_file=module.borgmatic.execute.DO_NOT_CAPTURE, borg_local_path='borg', extra_environment=None, ) @@ -128,7 +128,7 @@ def test_run_arbitrary_borg_with_local_path_calls_borg_via_local_path(): flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg1', 'break-lock', 'repo'), - output_log_level=module.borgmatic.logger.ANSWER, + output_file=module.borgmatic.execute.DO_NOT_CAPTURE, borg_local_path='borg1', extra_environment=None, ) @@ -152,7 +152,7 @@ def test_run_arbitrary_borg_with_remote_path_calls_borg_with_remote_path_paramet flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'break-lock', 'repo', '--remote-path', 'borg1'), - output_log_level=module.borgmatic.logger.ANSWER, + output_file=module.borgmatic.execute.DO_NOT_CAPTURE, borg_local_path='borg', extra_environment=None, ) @@ -174,7 +174,7 @@ def test_run_arbitrary_borg_passes_borg_specific_parameters_to_borg(): flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', 'repo', '--progress'), - output_log_level=module.borgmatic.logger.ANSWER, + output_file=module.borgmatic.execute.DO_NOT_CAPTURE, borg_local_path='borg', extra_environment=None, ) @@ -195,7 +195,7 @@ def test_run_arbitrary_borg_omits_dash_dash_in_parameters_passed_to_borg(): flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'break-lock', 'repo'), - output_log_level=module.borgmatic.logger.ANSWER, + output_file=module.borgmatic.execute.DO_NOT_CAPTURE, borg_local_path='borg', extra_environment=None, ) @@ -216,7 +216,7 @@ def test_run_arbitrary_borg_without_borg_specific_parameters_does_not_raise(): flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg',), - output_log_level=module.borgmatic.logger.ANSWER, + output_file=module.borgmatic.execute.DO_NOT_CAPTURE, borg_local_path='borg', extra_environment=None, ) @@ -237,7 +237,7 @@ def test_run_arbitrary_borg_passes_key_sub_command_to_borg_before_repository(): flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'key', 'export', 'repo'), - output_log_level=module.borgmatic.logger.ANSWER, + output_file=module.borgmatic.execute.DO_NOT_CAPTURE, borg_local_path='borg', extra_environment=None, ) @@ -258,7 +258,7 @@ def test_run_arbitrary_borg_passes_debug_sub_command_to_borg_before_repository() flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'debug', 'dump-manifest', 'repo', 'path'), - output_log_level=module.borgmatic.logger.ANSWER, + output_file=module.borgmatic.execute.DO_NOT_CAPTURE, borg_local_path='borg', extra_environment=None, ) @@ -279,7 +279,7 @@ def test_run_arbitrary_borg_with_debug_info_command_does_not_pass_borg_repositor flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'debug', 'info'), - output_log_level=module.borgmatic.logger.ANSWER, + output_file=module.borgmatic.execute.DO_NOT_CAPTURE, borg_local_path='borg', extra_environment=None, ) @@ -300,7 +300,7 @@ def test_run_arbitrary_borg_with_debug_convert_profile_command_does_not_pass_bor flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'debug', 'convert-profile', 'in', 'out'), - output_log_level=module.borgmatic.logger.ANSWER, + output_file=module.borgmatic.execute.DO_NOT_CAPTURE, borg_local_path='borg', extra_environment=None, )