bootstrap.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import glob
  2. import importlib
  3. import json
  4. import logging
  5. import os
  6. import borgmatic.borg.pattern
  7. import borgmatic.config.paths
  8. logger = logging.getLogger(__name__)
  9. def use_streaming(hook_config, config, log_prefix): # pragma: no cover
  10. '''
  11. Return whether dump streaming is used for this hook. (Spoiler: It isn't.)
  12. '''
  13. return False
  14. def dump_data_sources(
  15. hook_config,
  16. config,
  17. log_prefix,
  18. config_paths,
  19. borgmatic_runtime_directory,
  20. patterns,
  21. dry_run,
  22. ):
  23. '''
  24. Given a bootstrap configuration dict, a configuration dict, a log prefix, the borgmatic
  25. configuration file paths, the borgmatic runtime directory, the configured patterns, and whether
  26. this is a dry run, create a borgmatic manifest file to store the paths of the configuration
  27. files used to create the archive. But skip this if the bootstrap store_config_files option is
  28. False or if this is a dry run.
  29. Return an empty sequence, since there are no ongoing dump processes from this hook.
  30. '''
  31. if hook_config and hook_config.get('store_config_files') is False:
  32. return []
  33. borgmatic_manifest_path = os.path.join(
  34. borgmatic_runtime_directory, 'bootstrap', 'manifest.json'
  35. )
  36. if dry_run:
  37. return []
  38. os.makedirs(os.path.dirname(borgmatic_manifest_path), exist_ok=True)
  39. with open(borgmatic_manifest_path, 'w') as manifest_file:
  40. json.dump(
  41. {
  42. 'borgmatic_version': importlib.metadata.version('borgmatic'),
  43. 'config_paths': config_paths,
  44. },
  45. manifest_file,
  46. )
  47. patterns.extend(borgmatic.borg.pattern.Pattern(config_path) for config_path in config_paths)
  48. patterns.append(
  49. borgmatic.borg.pattern.Pattern(os.path.join(borgmatic_runtime_directory, 'bootstrap'))
  50. )
  51. return []
  52. def remove_data_source_dumps(hook_config, config, log_prefix, borgmatic_runtime_directory, dry_run):
  53. '''
  54. Given a bootstrap configuration dict, a configuration dict, a log prefix, the borgmatic runtime
  55. directory, and whether this is a dry run, then remove the manifest file created above. If this
  56. is a dry run, then don't actually remove anything.
  57. '''
  58. dry_run_label = ' (dry run; not actually removing anything)' if dry_run else ''
  59. manifest_glob = os.path.join(
  60. borgmatic.config.paths.replace_temporary_subdirectory_with_glob(
  61. os.path.normpath(borgmatic_runtime_directory),
  62. ),
  63. 'bootstrap',
  64. )
  65. logger.debug(
  66. f'{log_prefix}: Looking for bootstrap manifest files to remove in {manifest_glob}{dry_run_label}'
  67. )
  68. for manifest_directory in glob.glob(manifest_glob):
  69. manifest_file_path = os.path.join(manifest_directory, 'manifest.json')
  70. logger.debug(
  71. f'{log_prefix}: Removing bootstrap manifest at {manifest_file_path}{dry_run_label}'
  72. )
  73. if dry_run:
  74. continue
  75. try:
  76. os.remove(manifest_file_path)
  77. except FileNotFoundError:
  78. pass
  79. try:
  80. os.rmdir(manifest_directory)
  81. except FileNotFoundError:
  82. pass
  83. def make_data_source_dump_patterns(
  84. hook_config, config, log_prefix, borgmatic_runtime_directory, name=None
  85. ): # pragma: no cover
  86. '''
  87. Restores are implemented via the separate, purpose-specific "bootstrap" action rather than the
  88. generic "restore".
  89. '''
  90. return ()
  91. def restore_data_source_dump(
  92. hook_config,
  93. config,
  94. log_prefix,
  95. data_source,
  96. dry_run,
  97. extract_process,
  98. connection_params,
  99. borgmatic_runtime_directory,
  100. ): # pragma: no cover
  101. '''
  102. Restores are implemented via the separate, purpose-specific "bootstrap" action rather than the
  103. generic "restore".
  104. '''
  105. raise NotImplementedError()