diff --git a/borgmatic/borg/environment.py b/borgmatic/borg/environment.py index ac7ffcfd..e626dbe0 100644 --- a/borgmatic/borg/environment.py +++ b/borgmatic/borg/environment.py @@ -14,16 +14,18 @@ OPTION_TO_ENVIRONMENT_VARIABLE = { 'temporary_directory': 'TMPDIR', } -DEFAULT_BOOL_OPTION_TO_DOWNCASE_ENVIRONMENT_VARIABLE = { +DEFAULT_BOOL_OPTION_TO_UPPERCASE_ENVIRONMENT_VARIABLE = { + 'check_i_know_what_i_am_doing': 'BORG_CHECK_I_KNOW_WHAT_I_AM_DOING', +} + +DEFAULT_BOOL_OPTION_TO_ENVIRONMENT_VARIABLE = { + 'debug_passphrase': 'BORG_DEBUG_PASSPHRASE', + 'display_passphrase': 'BORG_DISPLAY_PASSPHRASE', 'relocated_repo_access_is_ok': 'BORG_RELOCATED_REPO_ACCESS_IS_OK', 'unknown_unencrypted_repo_access_is_ok': 'BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK', 'use_chunks_archive': 'BORG_USE_CHUNKS_ARCHIVE', } -DEFAULT_BOOL_OPTION_TO_UPPERCASE_ENVIRONMENT_VARIABLE = { - 'check_i_know_what_i_am_doing': 'BORG_CHECK_I_KNOW_WHAT_I_AM_DOING', -} - def make_environment(config): ''' @@ -83,10 +85,10 @@ def make_environment(config): for ( option_name, environment_variable_name, - ) in DEFAULT_BOOL_OPTION_TO_DOWNCASE_ENVIRONMENT_VARIABLE.items(): + ) in DEFAULT_BOOL_OPTION_TO_ENVIRONMENT_VARIABLE.items(): if os.environ.get(environment_variable_name) is None: value = config.get(option_name) - environment[environment_variable_name] = 'yes' if value else 'no' + environment[environment_variable_name] = 'YES' if value else 'NO' for ( option_name, diff --git a/borgmatic/commands/arguments.py b/borgmatic/commands/arguments.py index c3ff7706..f836ad22 100644 --- a/borgmatic/commands/arguments.py +++ b/borgmatic/commands/arguments.py @@ -667,7 +667,7 @@ def make_parsers(schema, unparsed_arguments): dest='make_parent_directories', default=None, action='store_true', - help='Create any missing parent directories of the repository directory', + help='Create any missing parent directories of the repository directory [Borg 1.x only]', ) repo_create_group.add_argument( '-h', '--help', action='help', help='Show this help message and exit' diff --git a/borgmatic/config/schema.yaml b/borgmatic/config/schema.yaml index a2cdbca8..0a49416a 100644 --- a/borgmatic/config/schema.yaml +++ b/borgmatic/config/schema.yaml @@ -72,7 +72,8 @@ properties: description: | Whether any missing parent directories of the repository path should be created, only used for the repo-create - action. Defaults to false. + action. Defaults to false. (This option is supported + for Borg 1.x only) example: true description: | A required list of local or remote repositories with paths and @@ -490,6 +491,19 @@ properties: Bypass Borg error about a previously unknown unencrypted repository. Defaults to false. example: true + debug_passphrase: + type: boolean + description: | + When set true, display debugging information that includes + passphrases used and passphrase related environment variables set. + Defaults to false. + example: true + display_passphrase: + type: boolean + description: | + When set true, always shows passphrase and its hex UTF-8 byte + sequence. Defaults to false. + example: true check_i_know_what_i_am_doing: type: boolean description: | diff --git a/tests/unit/borg/test_environment.py b/tests/unit/borg/test_environment.py index a4545168..750d50fb 100644 --- a/tests/unit/borg/test_environment.py +++ b/tests/unit/borg/test_environment.py @@ -90,9 +90,11 @@ def test_make_environment_without_configuration_sets_certain_environment_variabl assert environment == { 'USER': 'root', 'BORG_EXIT_CODES': 'modern', - 'BORG_RELOCATED_REPO_ACCESS_IS_OK': 'no', - 'BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK': 'no', - 'BORG_USE_CHUNKS_ARCHIVE': 'no', + 'BORG_RELOCATED_REPO_ACCESS_IS_OK': 'NO', + 'BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK': 'NO', + 'BORG_USE_CHUNKS_ARCHIVE': 'NO', + 'BORG_DEBUG_PASSPHRASE': 'NO', + 'BORG_DISPLAY_PASSPHRASE': 'NO', } @@ -103,6 +105,8 @@ def test_make_environment_without_configuration_passes_through_default_environme 'BORG_RELOCATED_REPO_ACCESS_IS_OK': 'yup', 'BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK': 'nah', 'BORG_USE_CHUNKS_ARCHIVE': 'yup', + 'BORG_DEBUG_PASSPHRASE': 'nah', + 'BORG_DISPLAY_PASSPHRASE': 'yup', } ) flexmock(module.borgmatic.hooks.credential.parse).should_receive( @@ -116,11 +120,13 @@ def test_make_environment_without_configuration_passes_through_default_environme 'BORG_RELOCATED_REPO_ACCESS_IS_OK': 'yup', 'BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK': 'nah', 'BORG_USE_CHUNKS_ARCHIVE': 'yup', + 'BORG_DEBUG_PASSPHRASE': 'nah', + 'BORG_DISPLAY_PASSPHRASE': 'yup', 'BORG_EXIT_CODES': 'modern', } -def test_make_environment_with_relocated_repo_access_true_should_set_environment_yes(): +def test_make_environment_with_relocated_repo_access_true_should_set_environment_YES(): flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' @@ -128,10 +134,10 @@ def test_make_environment_with_relocated_repo_access_true_should_set_environment flexmock(module.os).should_receive('pipe').never() environment = module.make_environment({'relocated_repo_access_is_ok': True}) - assert environment.get('BORG_RELOCATED_REPO_ACCESS_IS_OK') == 'yes' + assert environment.get('BORG_RELOCATED_REPO_ACCESS_IS_OK') == 'YES' -def test_make_environment_with_relocated_repo_access_false_should_set_environment_no(): +def test_make_environment_with_relocated_repo_access_false_should_set_environment_NO(): flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' @@ -139,7 +145,7 @@ def test_make_environment_with_relocated_repo_access_false_should_set_environmen flexmock(module.os).should_receive('pipe').never() environment = module.make_environment({'relocated_repo_access_is_ok': False}) - assert environment.get('BORG_RELOCATED_REPO_ACCESS_IS_OK') == 'no' + assert environment.get('BORG_RELOCATED_REPO_ACCESS_IS_OK') == 'NO' def test_make_environment_check_i_know_what_i_am_doing_true_should_set_environment_YES(): @@ -164,6 +170,50 @@ def test_make_environment_check_i_know_what_i_am_doing_false_should_set_environm assert environment.get('BORG_CHECK_I_KNOW_WHAT_I_AM_DOING') == 'NO' +def test_make_environment_debug_passphrase_true_should_set_environment_YES(): + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) + flexmock(module.borgmatic.hooks.credential.parse).should_receive( + 'resolve_credential' + ).and_return(None) + flexmock(module.os).should_receive('pipe').never() + environment = module.make_environment({'debug_passphrase': True}) + + assert environment.get('BORG_DEBUG_PASSPHRASE') == 'YES' + + +def test_make_environment_debug_passphrase_false_should_set_environment_NO(): + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) + flexmock(module.borgmatic.hooks.credential.parse).should_receive( + 'resolve_credential' + ).and_return(None) + flexmock(module.os).should_receive('pipe').never() + environment = module.make_environment({'debug_passphrase': False}) + + assert environment.get('BORG_DEBUG_PASSPHRASE') == 'NO' + + +def test_make_environment_display_passphrase_true_should_set_environment_YES(): + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) + flexmock(module.borgmatic.hooks.credential.parse).should_receive( + 'resolve_credential' + ).and_return(None) + flexmock(module.os).should_receive('pipe').never() + environment = module.make_environment({'display_passphrase': True}) + + assert environment.get('BORG_DISPLAY_PASSPHRASE') == 'YES' + + +def test_make_environment_display_passphrase_false_should_set_environment_NO(): + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) + flexmock(module.borgmatic.hooks.credential.parse).should_receive( + 'resolve_credential' + ).and_return(None) + flexmock(module.os).should_receive('pipe').never() + environment = module.make_environment({'display_passphrase': False}) + + assert environment.get('BORG_DISPLAY_PASSPHRASE') == 'NO' + + def test_make_environment_with_integer_variable_value(): flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( @@ -183,7 +233,7 @@ def test_make_environment_with_use_chunks_archive_should_set_correct_environment flexmock(module.os).should_receive('pipe').never() environment = module.make_environment({'use_chunks_archive': True}) - assert environment.get('BORG_USE_CHUNKS_ARCHIVE') == 'yes' + assert environment.get('BORG_USE_CHUNKS_ARCHIVE') == 'YES' environment = module.make_environment({'use_chunks_archive': False}) - assert environment.get('BORG_USE_CHUNKS_ARCHIVE') == 'no' + assert environment.get('BORG_USE_CHUNKS_ARCHIVE') == 'NO'