forked from borgmatic-collective/borgmatic
89 lines
3.5 KiB
Python
89 lines
3.5 KiB
Python
import logging
|
|
import os
|
|
|
|
from borgmatic.execute import execute_command
|
|
|
|
DUMP_PATH = '~/.borgmatic/postgresql_databases'
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def dump_databases(databases, config_filename, dry_run):
|
|
'''
|
|
Dump the given PostgreSQL databases to disk. The databases are supplied as a sequence of dicts,
|
|
one dict describing each database as per the configuration schema. Use the given configuration
|
|
filename in any log entries. If this is a dry run, then don't actually dump anything.
|
|
'''
|
|
if not databases:
|
|
logger.debug('{}: No PostgreSQL databases configured'.format(config_filename))
|
|
return
|
|
|
|
dry_run_label = ' (dry run; not actually dumping anything)' if dry_run else ''
|
|
|
|
logger.info('{}: Dumping PostgreSQL databases{}'.format(config_filename, dry_run_label))
|
|
|
|
for database in databases:
|
|
if os.path.sep in database['name']:
|
|
raise ValueError('Invalid database name {}'.format(database['name']))
|
|
|
|
dump_path = os.path.join(
|
|
os.path.expanduser(DUMP_PATH), database.get('hostname', 'localhost')
|
|
)
|
|
name = database['name']
|
|
all_databases = bool(name == 'all')
|
|
command = (
|
|
('pg_dumpall' if all_databases else 'pg_dump', '--no-password', '--clean')
|
|
+ ('--file', os.path.join(dump_path, name))
|
|
+ (('--host', database['hostname']) if 'hostname' in database else ())
|
|
+ (('--port', str(database['port'])) if 'port' in database else ())
|
|
+ (('--username', database['username']) if 'username' in database else ())
|
|
+ (() if all_databases else ('--format', database.get('format', 'custom')))
|
|
+ (tuple(database['options'].split(' ')) if 'options' in database else ())
|
|
+ (() if all_databases else (name,))
|
|
)
|
|
extra_environment = {'PGPASSWORD': database['password']} if 'password' in database else None
|
|
|
|
logger.debug(
|
|
'{}: Dumping PostgreSQL database {}{}'.format(config_filename, name, dry_run_label)
|
|
)
|
|
if not dry_run:
|
|
os.makedirs(dump_path, mode=0o700, exist_ok=True)
|
|
execute_command(command, extra_environment=extra_environment)
|
|
|
|
|
|
def remove_database_dumps(databases, config_filename, dry_run):
|
|
'''
|
|
Remove the database dumps for the given databases. The databases are supplied as a sequence of
|
|
dicts, one dict describing each database as per the configuration schema. Use the given
|
|
configuration filename in any log entries. If this is a dry run, then don't actually remove
|
|
anything.
|
|
'''
|
|
if not databases:
|
|
logger.debug('{}: No PostgreSQL databases configured'.format(config_filename))
|
|
return
|
|
|
|
dry_run_label = ' (dry run; not actually removing anything)' if dry_run else ''
|
|
|
|
logger.info('{}: Removing PostgreSQL database dumps{}'.format(config_filename, dry_run_label))
|
|
|
|
for database in databases:
|
|
if os.path.sep in database['name']:
|
|
raise ValueError('Invalid database name {}'.format(database['name']))
|
|
|
|
name = database['name']
|
|
dump_path = os.path.join(
|
|
os.path.expanduser(DUMP_PATH), database.get('hostname', 'localhost')
|
|
)
|
|
dump_filename = os.path.join(dump_path, name)
|
|
|
|
logger.debug(
|
|
'{}: Remove PostgreSQL database dump {} from {}{}'.format(
|
|
config_filename, name, dump_filename, dry_run_label
|
|
)
|
|
)
|
|
if dry_run:
|
|
continue
|
|
|
|
os.remove(dump_filename)
|
|
if len(os.listdir(dump_path)) == 0:
|
|
os.rmdir(dump_path)
|