diff --git a/NEWS b/NEWS index f2227361..f577e9c6 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +2.0.4.dev0 + * #1075: Fix an incorrect warning about Borg placeholders being unsupported in a command hook. + 2.0.3 * #1065: Fix a regression in monitoring hooks in which an error pinged the finish state instead of the fail state. diff --git a/borgmatic/borg/create.py b/borgmatic/borg/create.py index ae268cf4..03524ff7 100644 --- a/borgmatic/borg/create.py +++ b/borgmatic/borg/create.py @@ -69,7 +69,7 @@ def collect_special_file_paths( ''' # 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 - # paths output parsing below such that path lines no longer start with th expected "- ". + # paths output parsing below such that path lines no longer start with the expected "- ". paths_output = execute_command_and_capture_output( flags.omit_flag_and_value(flags.omit_flag(create_command, '--exclude-nodump'), '--filter') + ('--dry-run', '--list'), diff --git a/borgmatic/hooks/command.py b/borgmatic/hooks/command.py index e0843da6..7d3347c1 100644 --- a/borgmatic/hooks/command.py +++ b/borgmatic/hooks/command.py @@ -13,6 +13,19 @@ logger = logging.getLogger(__name__) SOFT_FAIL_EXIT_CODE = 75 +BORG_PLACEHOLDERS = { + '{hostname}', + '{fqdn}', + '{reverse-fqdn}', + '{now}', + '{utcnow}', + '{user}', + '{pid}', + '{borgversion}', + '{borgmajor}', + '{borgminor}', + '{borgpatch}', +} def interpolate_context(hook_description, command, context): @@ -23,10 +36,13 @@ def interpolate_context(hook_description, command, context): for name, value in context.items(): command = command.replace(f'{{{name}}}', shlex.quote(str(value))) - for unsupported_variable in re.findall(r'{\w+}', command): - logger.warning( - f"Variable '{unsupported_variable}' is not supported in {hook_description} hook" - ) + for unsupported_variable in re.findall(r'\{\w+\}', command): + # Warn about variables unknown to borgmatic, but don't warn if the variable name happens to + # be a Borg placeholder, as Borg should hopefully consume it. + if unsupported_variable not in BORG_PLACEHOLDERS: + logger.warning( + f'Variable "{unsupported_variable}" is not supported in the {hook_description} hook' + ) return command diff --git a/pyproject.toml b/pyproject.toml index 83177c81..d9b6be7d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "borgmatic" -version = "2.0.3" +version = "2.0.4.dev0" authors = [ { name="Dan Helfman", email="witten@torsion.org" }, ] diff --git a/tests/unit/hooks/test_command.py b/tests/unit/hooks/test_command.py index 667e6ab3..edf5dfa7 100644 --- a/tests/unit/hooks/test_command.py +++ b/tests/unit/hooks/test_command.py @@ -11,8 +11,16 @@ def test_interpolate_context_passes_through_command_without_variable(): assert module.interpolate_context('pre-backup', 'ls', {'foo': 'bar'}) == 'ls' -def test_interpolate_context_passes_through_command_with_unknown_variable(): +def test_interpolate_context_warns_and_passes_through_command_with_unknown_variable(): command = 'ls {baz}' # noqa: FS003 + flexmock(module.logger).should_receive('warning').once() + + assert module.interpolate_context('pre-backup', command, {'foo': 'bar'}) == command + + +def test_interpolate_context_does_not_warn_and_passes_through_command_with_unknown_variable_matching_borg_placeholder(): + command = 'ls {hostname}' # noqa: FS003 + flexmock(module.logger).should_receive('warning').never() assert module.interpolate_context('pre-backup', command, {'foo': 'bar'}) == command