Fix handling of "repository" and "data" consistency checks to prevent invalid Borg flags (#565).

This commit is contained in:
Dan Helfman 2022-07-23 21:02:21 -07:00
parent 23feac2f4c
commit 6ddae20fa1
4 changed files with 20 additions and 28 deletions

3
NEWS
View file

@ -1,3 +1,6 @@
1.6.7.dev0
* #565: Fix handling of "repository" and "data" consistency checks to prevent invalid Borg flags.
1.6.6 1.6.6
* #559: Update documentation about configuring multiple consistency checks or multiple databases. * #559: Update documentation about configuring multiple consistency checks or multiple databases.
* #560: Fix all database hooks to error when the requested database to restore isn't present in the * #560: Fix all database hooks to error when the requested database to restore isn't present in the

View file

@ -33,8 +33,6 @@ def parse_checks(consistency_config, only_checks=None):
If no "checks" option is present in the config, return the DEFAULT_CHECKS. If a checks value If no "checks" option is present in the config, return the DEFAULT_CHECKS. If a checks value
has a name of "disabled", return an empty tuple, meaning that no checks should be run. has a name of "disabled", return an empty tuple, meaning that no checks should be run.
If the "data" check is present, then make sure the "archives" check is included as well.
''' '''
checks = only_checks or tuple( checks = only_checks or tuple(
check_config['name'] check_config['name']
@ -48,9 +46,6 @@ def parse_checks(consistency_config, only_checks=None):
) )
return () return ()
if 'data' in checks and 'archives' not in checks:
return checks + ('archives',)
return checks return checks
@ -164,7 +159,7 @@ def make_check_flags(checks, check_last=None, prefix=None):
('--repository-only',) ('--repository-only',)
However, if both "repository" and "archives" are in checks, then omit them from the returned However, if both "repository" and "archives" are in checks, then omit them from the returned
flags because Borg does both checks by default. flags because Borg does both checks by default. If "data" is in checks, that implies "archives".
Additionally, if a check_last value is given and "archives" is in checks, then include a Additionally, if a check_last value is given and "archives" is in checks, then include a
"--last" flag. And if a prefix value is given and "archives" is in checks, then include a "--last" flag. And if a prefix value is given and "archives" is in checks, then include a
@ -183,7 +178,13 @@ def make_check_flags(checks, check_last=None, prefix=None):
'Ignoring consistency prefix option, as "archives" is not in consistency checks' 'Ignoring consistency prefix option, as "archives" is not in consistency checks'
) )
common_flags = last_flags + prefix_flags + (('--verify-data',) if 'data' in checks else ()) if 'data' in checks:
data_flags = ('--verify-data',)
checks += ('archives',)
else:
data_flags = ()
common_flags = last_flags + prefix_flags + data_flags
if {'repository', 'archives'}.issubset(set(checks)): if {'repository', 'archives'}.issubset(set(checks)):
return common_flags return common_flags

View file

@ -1,6 +1,6 @@
from setuptools import find_packages, setup from setuptools import find_packages, setup
VERSION = '1.6.6' VERSION = '1.6.7.dev0'
setup( setup(

View file

@ -49,18 +49,6 @@ def test_parse_checks_with_disabled_returns_no_checks():
assert checks == () assert checks == ()
def test_parse_checks_with_data_check_also_injects_archives():
checks = module.parse_checks({'checks': [{'name': 'data'}]})
assert checks == ('data', 'archives')
def test_parse_checks_with_data_check_passes_through_archives():
checks = module.parse_checks({'checks': [{'name': 'data'}, {'name': 'archives'}]})
assert checks == ('data', 'archives')
def test_parse_checks_prefers_override_checks_to_configured_checks(): def test_parse_checks_prefers_override_checks_to_configured_checks():
checks = module.parse_checks( checks = module.parse_checks(
{'checks': [{'name': 'archives'}]}, only_checks=['repository', 'extract'] {'checks': [{'name': 'archives'}]}, only_checks=['repository', 'extract']
@ -69,12 +57,6 @@ def test_parse_checks_prefers_override_checks_to_configured_checks():
assert checks == ('repository', 'extract') assert checks == ('repository', 'extract')
def test_parse_checks_with_override_data_check_also_injects_archives():
checks = module.parse_checks({'checks': [{'name': 'extract'}]}, only_checks=['data'])
assert checks == ('data', 'archives')
@pytest.mark.parametrize( @pytest.mark.parametrize(
'frequency,expected_result', 'frequency,expected_result',
( (
@ -217,10 +199,10 @@ def test_make_check_flags_with_archives_check_returns_flag():
assert flags == ('--archives-only',) assert flags == ('--archives-only',)
def test_make_check_flags_with_data_check_returns_flag(): def test_make_check_flags_with_data_check_returns_flag_and_implies_archives():
flags = module.make_check_flags(('data',)) flags = module.make_check_flags(('data',))
assert flags == ('--verify-data',) assert flags == ('--archives-only', '--verify-data',)
def test_make_check_flags_with_extract_omits_extract_flag(): def test_make_check_flags_with_extract_omits_extract_flag():
@ -229,6 +211,12 @@ def test_make_check_flags_with_extract_omits_extract_flag():
assert flags == () assert flags == ()
def test_make_check_flags_with_repository_and_data_checks_does_not_return_repository_only():
flags = module.make_check_flags(('repository', 'data',))
assert flags == ('--verify-data',)
def test_make_check_flags_with_default_checks_and_default_prefix_returns_default_flags(): def test_make_check_flags_with_default_checks_and_default_prefix_returns_default_flags():
flags = module.make_check_flags(('repository', 'archives'), prefix=module.DEFAULT_PREFIX) flags = module.make_check_flags(('repository', 'archives'), prefix=module.DEFAULT_PREFIX)