command.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. from __future__ import print_function
  2. from argparse import ArgumentParser
  3. from importlib import import_module
  4. import os
  5. from subprocess import CalledProcessError
  6. import sys
  7. from atticmatic.config import parse_configuration
  8. DEFAULT_CONFIG_FILENAME_PATTERN = '/etc/{}/config'
  9. DEFAULT_EXCLUDES_FILENAME_PATTERN = '/etc/{}/excludes'
  10. def parse_arguments(command_name, *arguments):
  11. '''
  12. Given the name of the command with which this script was invoked and command-line arguments,
  13. parse the arguments and return them as an ArgumentParser instance. Use the command name to
  14. determine the default configuration and excludes paths.
  15. '''
  16. config_filename_default = DEFAULT_CONFIG_FILENAME_PATTERN.format(command_name)
  17. excludes_filename_default = DEFAULT_EXCLUDES_FILENAME_PATTERN.format(command_name)
  18. parser = ArgumentParser()
  19. parser.add_argument(
  20. '-c', '--config',
  21. dest='config_filename',
  22. default=config_filename_default,
  23. help='Configuration filename',
  24. )
  25. parser.add_argument(
  26. '--excludes',
  27. dest='excludes_filename',
  28. default=excludes_filename_default if os.path.exists(excludes_filename_default) else None,
  29. help='Excludes filename',
  30. )
  31. parser.add_argument(
  32. '-v', '--verbosity',
  33. type=int,
  34. help='Display verbose progress (1 for some, 2 for lots)',
  35. )
  36. return parser.parse_args(arguments)
  37. def load_backend(command_name):
  38. '''
  39. Given the name of the command with which this script was invoked, return the corresponding
  40. backend module responsible for actually dealing with backups.
  41. '''
  42. backend_name = {
  43. 'atticmatic': 'attic',
  44. 'borgmatic': 'borg',
  45. }.get(command_name, 'attic')
  46. return import_module('atticmatic.backends.{}'.format(backend_name))
  47. def main():
  48. try:
  49. command_name = os.path.basename(sys.argv[0])
  50. args = parse_arguments(command_name, *sys.argv[1:])
  51. backend = load_backend(command_name)
  52. config = parse_configuration(args.config_filename, backend.CONFIG_FORMAT)
  53. repository = config.location['repository']
  54. backend.initialize(config.storage)
  55. backend.create_archive(
  56. args.excludes_filename, args.verbosity, config.storage, **config.location
  57. )
  58. backend.prune_archives(args.verbosity, repository, config.retention)
  59. backend.check_archives(args.verbosity, repository, config.consistency)
  60. except (ValueError, IOError, CalledProcessError) as error:
  61. print(error, file=sys.stderr)
  62. sys.exit(1)