فهرست منبع

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.
Robin Schneider 6 سال پیش
والد
کامیت
52e4f48eb9
4فایلهای تغییر یافته به همراه92 افزوده شده و 1 حذف شده
  1. 1 1
      AUTHORS
  2. 56 0
      borgmatic/commands/validate_config.py
  3. 1 0
      setup.py
  4. 34 0
      tests/end-to-end/test_borgmatic.py

+ 1 - 1
AUTHORS

@@ -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

+ 56 - 0
borgmatic/commands/validate_config.py

@@ -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))

+ 1 - 0
setup.py

@@ -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'],

+ 34 - 0
tests/end-to-end/test_borgmatic.py

@@ -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(' ')