Add validate-borgmatic-config command

Useful when generating the borgmatic configuration file with
configuration management and before moving the generated file in place
checking if it is actually valid.
This commit is contained in:
Robin Schneider 2019-05-10 00:10:28 +02:00
parent f5e1e8bec9
commit 52e4f48eb9
No known key found for this signature in database
GPG key ID: A81E8006DC95EFE6
4 changed files with 92 additions and 1 deletions

View file

@ -7,6 +7,6 @@ Johannes Feichtner: Support for user hooks
Michele Lazzeri: Custom archive names
Nick Whyte: Support prefix filtering for archive consistency checks
newtonne: Read encryption password from external file
Robin `ypid` Schneider: Support additional options of Borg
Robin `ypid` Schneider: Support additional options of Borg and add validate-borgmatic-config command
Scott Squires: Custom archive names
Thomas LÉVEIL: Support for a keep_minutely prune option. Support for the --json option

View file

@ -0,0 +1,56 @@
from argparse import ArgumentParser
import sys
import logging
from borgmatic.config import collect, validate
logger = logging.getLogger(__name__)
def parse_arguments(*arguments):
'''
Given command-line arguments with which this script was invoked, parse the arguments and return
them as an ArgumentParser instance.
'''
config_paths = collect.get_default_config_paths()
parser = ArgumentParser(description='Validate borgmatic configuration file(s).')
parser.add_argument(
'-c',
'--config',
nargs='+',
dest='config_paths',
default=config_paths,
help='Configuration filenames or directories, defaults to: {}'.format(
' '.join(config_paths)
),
)
return parser.parse_args(arguments)
def main(): # pragma: no cover
args = parse_arguments(*sys.argv[1:])
logging.basicConfig(level=logging.INFO, format='%(message)s')
config_filenames = tuple(collect.collect_config_filenames(args.config_paths))
if len(config_filenames) == 0:
logger.critical('No files to validate found')
sys.exit(1)
found_issues = False
for config_filename in config_filenames:
try:
validate.parse_configuration(
config_filename, validate.schema_filename()
)
except (ValueError, OSError, validate.Validation_error) as error:
logging.critical('{}: Error parsing configuration file'.format(config_filename))
logging.critical(error)
found_issues = True
if found_issues:
sys.exit(1)
else:
logger.info('All given configuration files are valid: {}'.format(config_filenames))

View file

@ -26,6 +26,7 @@ setup(
'borgmatic = borgmatic.commands.borgmatic:main',
'upgrade-borgmatic-config = borgmatic.commands.convert_config:main',
'generate-borgmatic-config = borgmatic.commands.generate_config:main',
'validate-borgmatic-config = borgmatic.commands.validate_config:main',
]
},
obsoletes=['atticmatic'],

View file

@ -29,6 +29,36 @@ def generate_configuration(config_path, repository_path):
config_file.close()
def validate_valid_configuration(config_path):
'''
Validate borgmatic configuration which is valid.
'''
subprocess.check_call(
'validate-borgmatic-config --config {}'.format(config_path).split(' ')
)
def validate_invalid_configuration(config_path):
'''
Validate borgmatic configuration which is invalid.
'''
config = (
open(config_path)
.read()
.replace('keep_daily: 7', 'keep_daily: "7"')
)
config_file = open(config_path, 'w')
config_file.write(config)
config_file.close()
exit_code = subprocess.call(
'validate-borgmatic-config --config {}'.format(config_path).split(' ')
)
assert exit_code == 1
def test_borgmatic_command():
# Create a Borg repository.
temporary_directory = tempfile.mkdtemp()
@ -41,7 +71,11 @@ def test_borgmatic_command():
try:
config_path = os.path.join(temporary_directory, 'test.yaml')
invalid_config_path = os.path.join(temporary_directory, 'test_invalid.yaml')
generate_configuration(config_path, repository_path)
generate_configuration(invalid_config_path, repository_path)
validate_valid_configuration(config_path)
validate_invalid_configuration(invalid_config_path)
subprocess.check_call(
'borgmatic -v 2 --config {} --init --encryption repokey'.format(config_path).split(' ')