dump.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import logging
  2. import os
  3. import shutil
  4. from borgmatic.borg.state import DEFAULT_BORGMATIC_SOURCE_DIRECTORY
  5. logger = logging.getLogger(__name__)
  6. DATABASE_HOOK_NAMES = (
  7. 'postgresql_databases',
  8. 'mysql_databases',
  9. 'mongodb_databases',
  10. 'sqlite_databases',
  11. )
  12. def make_database_dump_path(borgmatic_source_directory, database_hook_name):
  13. '''
  14. Given a borgmatic source directory (or None) and a database hook name, construct a database dump
  15. path.
  16. '''
  17. if not borgmatic_source_directory:
  18. borgmatic_source_directory = DEFAULT_BORGMATIC_SOURCE_DIRECTORY
  19. return os.path.join(borgmatic_source_directory, database_hook_name)
  20. def make_database_dump_filename(dump_path, name, hostname=None):
  21. '''
  22. Based on the given dump directory path, database name, and hostname, return a filename to use
  23. for the database dump. The hostname defaults to localhost.
  24. Raise ValueError if the database name is invalid.
  25. '''
  26. if os.path.sep in name:
  27. raise ValueError(f'Invalid database name {name}')
  28. return os.path.join(os.path.expanduser(dump_path), hostname or 'localhost', name)
  29. def create_parent_directory_for_dump(dump_path):
  30. '''
  31. Create a directory to contain the given dump path.
  32. '''
  33. os.makedirs(os.path.dirname(dump_path), mode=0o700, exist_ok=True)
  34. def create_named_pipe_for_dump(dump_path):
  35. '''
  36. Create a named pipe at the given dump path.
  37. '''
  38. create_parent_directory_for_dump(dump_path)
  39. os.mkfifo(dump_path, mode=0o600)
  40. def remove_database_dumps(dump_path, database_type_name, log_prefix, dry_run):
  41. '''
  42. Remove all database dumps in the given dump directory path (including the directory itself). If
  43. this is a dry run, then don't actually remove anything.
  44. '''
  45. dry_run_label = ' (dry run; not actually removing anything)' if dry_run else ''
  46. logger.debug(f'{log_prefix}: Removing {database_type_name} database dumps{dry_run_label}')
  47. expanded_path = os.path.expanduser(dump_path)
  48. if dry_run:
  49. return
  50. if os.path.exists(expanded_path):
  51. shutil.rmtree(expanded_path)
  52. def convert_glob_patterns_to_borg_patterns(patterns):
  53. '''
  54. Convert a sequence of shell glob patterns like "/etc/*" to the corresponding Borg archive
  55. patterns like "sh:etc/*".
  56. '''
  57. return [f'sh:{pattern.lstrip(os.path.sep)}' for pattern in patterns]