Override configured consistency checks via "borgmatic check --only" command-line flag (#210).
This commit is contained in:
parent
4cdff74e9b
commit
81739791e0
6 changed files with 46 additions and 11 deletions
3
NEWS
3
NEWS
|
@ -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: 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 "#"
|
* When generating sample configuration with generate-borgmatic-config, add a space after each "#"
|
||||||
comment indicator.
|
comment indicator.
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,10 @@ DEFAULT_PREFIX = '{hostname}-'
|
||||||
logger = logging.getLogger(__name__)
|
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:
|
For example, given a retention config of:
|
||||||
|
|
||||||
|
@ -22,12 +23,14 @@ def _parse_checks(consistency_config):
|
||||||
|
|
||||||
('repository', 'archives')
|
('repository', 'archives')
|
||||||
|
|
||||||
If no "checks" option is present, return the DEFAULT_CHECKS. If the checks value is the string
|
If no "checks" option is present in the config, return the DEFAULT_CHECKS. If the checks value
|
||||||
"disabled", return an empty tuple, meaning that no checks should be run.
|
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.
|
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']:
|
if checks == ['disabled']:
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
|
@ -83,15 +86,21 @@ def _make_check_flags(checks, check_last=None, prefix=None):
|
||||||
|
|
||||||
|
|
||||||
def check_archives(
|
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,
|
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.
|
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)
|
check_last = consistency_config.get('check_last', None)
|
||||||
lock_wait = None
|
lock_wait = None
|
||||||
|
|
||||||
|
|
|
@ -212,6 +212,14 @@ def parse_arguments(*unparsed_arguments):
|
||||||
add_help=False,
|
add_help=False,
|
||||||
)
|
)
|
||||||
check_group = check_parser.add_argument_group('check arguments')
|
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')
|
check_group.add_argument('-h', '--help', action='help', help='Show this help message and exit')
|
||||||
|
|
||||||
extract_parser = subparsers.add_parser(
|
extract_parser = subparsers.add_parser(
|
||||||
|
|
|
@ -147,7 +147,12 @@ def run_actions(
|
||||||
if 'check' in arguments and checks.repository_enabled_for_checks(repository, consistency):
|
if 'check' in arguments and checks.repository_enabled_for_checks(repository, consistency):
|
||||||
logger.info('{}: Running consistency checks'.format(repository))
|
logger.info('{}: Running consistency checks'.format(repository))
|
||||||
borg_check.check_archives(
|
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 'extract' in arguments:
|
||||||
if arguments['extract'].repository is None or repository == arguments['extract'].repository:
|
if arguments['extract'].repository is None or repository == arguments['extract'].repository:
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -1,6 +1,6 @@
|
||||||
from setuptools import find_packages, setup
|
from setuptools import find_packages, setup
|
||||||
|
|
||||||
VERSION = '1.3.16.dev0'
|
VERSION = '1.3.16'
|
||||||
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
|
|
|
@ -58,6 +58,18 @@ def test_parse_checks_with_data_check_passes_through_archives():
|
||||||
assert checks == ('data', '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():
|
def test_make_check_flags_with_repository_check_returns_flag():
|
||||||
flags = module._make_check_flags(('repository',))
|
flags = module._make_check_flags(('repository',))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue