convert_config.py 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. from argparse import ArgumentParser
  2. import os
  3. from subprocess import CalledProcessError
  4. import sys
  5. import textwrap
  6. from ruamel import yaml
  7. from borgmatic.config import convert, generate, legacy, validate
  8. DEFAULT_SOURCE_CONFIG_FILENAME = '/etc/borgmatic/config'
  9. DEFAULT_SOURCE_EXCLUDES_FILENAME = '/etc/borgmatic/excludes'
  10. DEFAULT_DESTINATION_CONFIG_FILENAME = '/etc/borgmatic/config.yaml'
  11. def parse_arguments(*arguments):
  12. '''
  13. Given command-line arguments with which this script was invoked, parse the arguments and return
  14. them as an ArgumentParser instance.
  15. '''
  16. parser = ArgumentParser(
  17. description='''
  18. Convert legacy INI-style borgmatic configuration and excludes files to a single YAML
  19. configuration file. Note that this replaces any comments from the source files.
  20. '''
  21. )
  22. parser.add_argument(
  23. '-s', '--source-config',
  24. dest='source_config_filename',
  25. default=DEFAULT_SOURCE_CONFIG_FILENAME,
  26. help='Source INI-style configuration filename. Default: {}'.format(DEFAULT_SOURCE_CONFIG_FILENAME),
  27. )
  28. parser.add_argument(
  29. '-e', '--source-excludes',
  30. dest='source_excludes_filename',
  31. default=DEFAULT_SOURCE_EXCLUDES_FILENAME if os.path.exists(DEFAULT_SOURCE_EXCLUDES_FILENAME) else None,
  32. help='Excludes filename',
  33. )
  34. parser.add_argument(
  35. '-d', '--destination-config',
  36. dest='destination_config_filename',
  37. default=DEFAULT_DESTINATION_CONFIG_FILENAME,
  38. help='Destination YAML configuration filename. Default: {}'.format(DEFAULT_DESTINATION_CONFIG_FILENAME),
  39. )
  40. return parser.parse_args(arguments)
  41. TEXT_WRAP_CHARACTERS = 80
  42. def display_result(args): # pragma: no cover
  43. result_lines = textwrap.wrap(
  44. 'Your borgmatic configuration has been upgraded. Please review the result in {}.'.format(
  45. args.destination_config_filename
  46. ),
  47. TEXT_WRAP_CHARACTERS,
  48. )
  49. delete_lines = textwrap.wrap(
  50. 'Once you are satisfied, you can safely delete {}{}.'.format(
  51. args.source_config_filename,
  52. ' and {}'.format(args.source_excludes_filename) if args.source_excludes_filename else '',
  53. ),
  54. TEXT_WRAP_CHARACTERS,
  55. )
  56. print('\n'.join(result_lines))
  57. print()
  58. print('\n'.join(delete_lines))
  59. def main(): # pragma: no cover
  60. try:
  61. args = parse_arguments(*sys.argv[1:])
  62. schema = yaml.round_trip_load(open(validate.schema_filename()).read())
  63. source_config = legacy.parse_configuration(args.source_config_filename, legacy.CONFIG_FORMAT)
  64. source_config_file_mode = os.stat(args.source_config_filename).st_mode
  65. source_excludes = (
  66. open(args.source_excludes_filename).read().splitlines()
  67. if args.source_excludes_filename
  68. else []
  69. )
  70. destination_config = convert.convert_legacy_parsed_config(source_config, source_excludes, schema)
  71. generate.write_configuration(
  72. args.destination_config_filename,
  73. destination_config,
  74. mode=source_config_file_mode,
  75. )
  76. display_result(args)
  77. except (ValueError, OSError) as error:
  78. print(error, file=sys.stderr)
  79. sys.exit(1)