Override configured consistency checks via "borgmatic check --only" command-line flag (#210).

This commit is contained in:
Dan Helfman 2019-09-19 11:43:53 -07:00
parent 4cdff74e9b
commit 81739791e0
6 changed files with 46 additions and 11 deletions

3
NEWS
View File

@ -1,5 +1,6 @@
1.3.16.dev0
1.3.16
* #210: Support for Borg check --verify-data flag via borgmatic "data" consistency check.
* #210: Override configured consistency checks via "borgmatic check --only" command-line flag.
* When generating sample configuration with generate-borgmatic-config, add a space after each "#"
comment indicator.

View File

@ -10,9 +10,10 @@ DEFAULT_PREFIX = '{hostname}-'
logger = logging.getLogger(__name__)
def _parse_checks(consistency_config):
def _parse_checks(consistency_config, only_checks=None):
'''
Given a consistency config with a "checks" list, transform it to a tuple of named checks to run.
Given a consistency config with a "checks" list, and an optional list of override checks,
transform them a tuple of named checks to run.
For example, given a retention config of:
@ -22,12 +23,14 @@ def _parse_checks(consistency_config):
('repository', 'archives')
If no "checks" option is present, return the DEFAULT_CHECKS. If the checks value is the string
"disabled", return an empty tuple, meaning that no checks should be run.
If no "checks" option is present in the config, return the DEFAULT_CHECKS. If the checks value
is the string "disabled", return an empty tuple, meaning that no checks should be run.
If the "data" option is present, then make sure the "archives" option is included as well.
'''
checks = [check.lower() for check in (consistency_config.get('checks', []) or [])]
checks = [
check.lower() for check in (only_checks or consistency_config.get('checks', []) or [])
]
if checks == ['disabled']:
return ()
@ -83,15 +86,21 @@ def _make_check_flags(checks, check_last=None, prefix=None):
def check_archives(
repository, storage_config, consistency_config, local_path='borg', remote_path=None
repository,
storage_config,
consistency_config,
local_path='borg',
remote_path=None,
only_checks=None,
):
'''
Given a local or remote repository path, a storage config dict, a consistency config dict,
and a local/remote commands to run, check the contained Borg archives for consistency.
local/remote commands to run, and an optional list of checks to use instead of configured
checks, check the contained Borg archives for consistency.
If there are no consistency checks to run, skip running them.
'''
checks = _parse_checks(consistency_config)
checks = _parse_checks(consistency_config, only_checks)
check_last = consistency_config.get('check_last', None)
lock_wait = None

View File

@ -212,6 +212,14 @@ def parse_arguments(*unparsed_arguments):
add_help=False,
)
check_group = check_parser.add_argument_group('check arguments')
check_group.add_argument(
'--only',
metavar='CHECK',
choices=('repository', 'archives', 'data', 'extract'),
dest='only',
action='append',
help='Run a particular consistency check instead of configured checks (can specify multiple times)',
)
check_group.add_argument('-h', '--help', action='help', help='Show this help message and exit')
extract_parser = subparsers.add_parser(

View File

@ -147,7 +147,12 @@ def run_actions(
if 'check' in arguments and checks.repository_enabled_for_checks(repository, consistency):
logger.info('{}: Running consistency checks'.format(repository))
borg_check.check_archives(
repository, storage, consistency, local_path=local_path, remote_path=remote_path
repository,
storage,
consistency,
local_path=local_path,
remote_path=remote_path,
only_checks=arguments['check'].only,
)
if 'extract' in arguments:
if arguments['extract'].repository is None or repository == arguments['extract'].repository:

View File

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

View File

@ -58,6 +58,18 @@ def test_parse_checks_with_data_check_passes_through_archives():
assert checks == ('data', 'archives')
def test_parse_checks_prefers_override_checks_to_configured_checks():
checks = module._parse_checks({'checks': ['archives']}, only_checks=['repository', 'extract'])
assert checks == ('repository', 'extract')
def test_parse_checks_with_override_data_check_also_injects_archives():
checks = module._parse_checks({'checks': ['extract']}, only_checks=['data'])
assert checks == ('data', 'archives')
def test_make_check_flags_with_repository_check_returns_flag():
flags = module._make_check_flags(('repository',))