mirror of
https://github.com/borgmatic-collective/borgmatic.git
synced 2026-07-30 05:13:01 +02:00
Add support for a database backup label instead of host:port (#1116)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
2.0.8.dev0
|
||||
* #1116: Add support for database backup labels.
|
||||
* #1114: Document systemd configuration changes for the ZFS filesystem hook.
|
||||
* #1118: Fix a bug in which Borg hangs during database backup when different filesystems are in
|
||||
use.
|
||||
|
||||
@@ -1323,6 +1323,11 @@ properties:
|
||||
implicitly enables read_special (see above) to support
|
||||
dump and restore streaming.
|
||||
example: users
|
||||
label:
|
||||
type: string
|
||||
description: |
|
||||
Label to identify the database dump in the backup.
|
||||
example: my_backup_label
|
||||
hostname:
|
||||
type: string
|
||||
description: |
|
||||
@@ -1524,6 +1529,11 @@ properties:
|
||||
database hook implicitly enables read_special (see
|
||||
above) to support dump and restore streaming.
|
||||
example: users
|
||||
label:
|
||||
type: string
|
||||
description: |
|
||||
Label to identify the database dump in the backup.
|
||||
example: my_backup_label
|
||||
hostname:
|
||||
type: string
|
||||
description: |
|
||||
@@ -1689,6 +1699,11 @@ properties:
|
||||
database hook implicitly enables read_special (see
|
||||
above) to support dump and restore streaming.
|
||||
example: users
|
||||
label:
|
||||
type: string
|
||||
description: |
|
||||
Label to identify the database dump in the backup.
|
||||
example: my_backup_label
|
||||
hostname:
|
||||
type: string
|
||||
description: |
|
||||
@@ -1862,6 +1877,11 @@ properties:
|
||||
read_special (see above) to support dump and restore
|
||||
streaming.
|
||||
example: /var/lib/sqlite/users.db
|
||||
label:
|
||||
type: string
|
||||
description: |
|
||||
Label to identify the database dump in the backup.
|
||||
example: my_backup_label
|
||||
restore_path:
|
||||
type: string
|
||||
description: |
|
||||
@@ -1910,6 +1930,11 @@ properties:
|
||||
database hook implicitly enables read_special (see
|
||||
above) to support dump and restore streaming.
|
||||
example: users
|
||||
label:
|
||||
type: string
|
||||
description: |
|
||||
Label to identify the database dump in the backup.
|
||||
example: my_backup_label
|
||||
hostname:
|
||||
type: string
|
||||
description: |
|
||||
|
||||
@@ -19,7 +19,7 @@ def make_data_source_dump_path(borgmatic_runtime_directory, data_source_hook_nam
|
||||
return os.path.join(borgmatic_runtime_directory, data_source_hook_name)
|
||||
|
||||
|
||||
def make_data_source_dump_filename(dump_path, name, hostname=None, port=None):
|
||||
def make_data_source_dump_filename(dump_path, name, hostname=None, port=None, label=None):
|
||||
'''
|
||||
Based on the given dump directory path, data source name, hostname, and port, return a filename
|
||||
to use for the data source dump. The hostname defaults to localhost.
|
||||
@@ -29,12 +29,12 @@ def make_data_source_dump_filename(dump_path, name, hostname=None, port=None):
|
||||
if os.path.sep in name:
|
||||
raise ValueError(f'Invalid data source name {name}')
|
||||
|
||||
return os.path.join(
|
||||
dump_path,
|
||||
(hostname or 'localhost') + ('' if port is None else f':{port}'),
|
||||
name,
|
||||
identifier = (
|
||||
label if label else (hostname or 'localhost') + ('' if port is None else f':{port}')
|
||||
)
|
||||
|
||||
return os.path.join(dump_path, identifier, name)
|
||||
|
||||
|
||||
def write_data_source_dumps_metadata(borgmatic_runtime_directory, hook_name, dumps_metadata):
|
||||
'''
|
||||
|
||||
@@ -178,6 +178,7 @@ def execute_dump_command(
|
||||
database['name'],
|
||||
database.get('hostname'),
|
||||
database.get('port'),
|
||||
database.get('label'),
|
||||
)
|
||||
|
||||
if os.path.exists(dump_filename):
|
||||
@@ -384,16 +385,16 @@ def make_data_source_dump_patterns(
|
||||
borgmatic_source_directory = borgmatic.config.paths.get_borgmatic_source_directory(config)
|
||||
|
||||
return (
|
||||
dump.make_data_source_dump_filename(make_dump_path('borgmatic'), name, hostname='*'),
|
||||
dump.make_data_source_dump_filename(make_dump_path('borgmatic'), name, label='*'),
|
||||
dump.make_data_source_dump_filename(
|
||||
make_dump_path(borgmatic_runtime_directory),
|
||||
name,
|
||||
hostname='*',
|
||||
label='*',
|
||||
),
|
||||
dump.make_data_source_dump_filename(
|
||||
make_dump_path(borgmatic_source_directory),
|
||||
name,
|
||||
hostname='*',
|
||||
label='*',
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ def dump_data_sources(
|
||||
name,
|
||||
database.get('hostname'),
|
||||
database.get('port'),
|
||||
database.get('label'),
|
||||
)
|
||||
dump_format = database.get('format', 'archive')
|
||||
|
||||
@@ -200,16 +201,16 @@ def make_data_source_dump_patterns(
|
||||
borgmatic_source_directory = borgmatic.config.paths.get_borgmatic_source_directory(config)
|
||||
|
||||
return (
|
||||
dump.make_data_source_dump_filename(make_dump_path('borgmatic'), name, hostname='*'),
|
||||
dump.make_data_source_dump_filename(make_dump_path('borgmatic'), name, label='*'),
|
||||
dump.make_data_source_dump_filename(
|
||||
make_dump_path(borgmatic_runtime_directory),
|
||||
name,
|
||||
hostname='*',
|
||||
label='*',
|
||||
),
|
||||
dump.make_data_source_dump_filename(
|
||||
make_dump_path(borgmatic_source_directory),
|
||||
name,
|
||||
hostname='*',
|
||||
label='*',
|
||||
),
|
||||
)
|
||||
|
||||
@@ -238,6 +239,7 @@ def restore_data_source_dump(
|
||||
make_dump_path(borgmatic_runtime_directory),
|
||||
data_source['name'],
|
||||
data_source.get('hostname'),
|
||||
data_source.get('label'),
|
||||
)
|
||||
restore_command = build_restore_command(
|
||||
extract_process,
|
||||
|
||||
@@ -104,6 +104,7 @@ def execute_dump_command(
|
||||
database['name'],
|
||||
database.get('hostname'),
|
||||
database.get('port'),
|
||||
database.get('label'),
|
||||
)
|
||||
|
||||
if os.path.exists(dump_filename):
|
||||
@@ -315,16 +316,16 @@ def make_data_source_dump_patterns(
|
||||
borgmatic_source_directory = borgmatic.config.paths.get_borgmatic_source_directory(config)
|
||||
|
||||
return (
|
||||
dump.make_data_source_dump_filename(make_dump_path('borgmatic'), name, hostname='*'),
|
||||
dump.make_data_source_dump_filename(make_dump_path('borgmatic'), name, label='*'),
|
||||
dump.make_data_source_dump_filename(
|
||||
make_dump_path(borgmatic_runtime_directory),
|
||||
name,
|
||||
hostname='*',
|
||||
label='*',
|
||||
),
|
||||
dump.make_data_source_dump_filename(
|
||||
make_dump_path(borgmatic_source_directory),
|
||||
name,
|
||||
hostname='*',
|
||||
label='*',
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -186,6 +186,7 @@ def dump_data_sources(
|
||||
database_name,
|
||||
database.get('hostname'),
|
||||
database.get('port'),
|
||||
database.get('label'),
|
||||
)
|
||||
|
||||
if os.path.exists(dump_filename):
|
||||
@@ -302,16 +303,16 @@ def make_data_source_dump_patterns(
|
||||
borgmatic_source_directory = borgmatic.config.paths.get_borgmatic_source_directory(config)
|
||||
|
||||
return (
|
||||
dump.make_data_source_dump_filename(make_dump_path('borgmatic'), name, hostname='*'),
|
||||
dump.make_data_source_dump_filename(make_dump_path('borgmatic'), name, label='*'),
|
||||
dump.make_data_source_dump_filename(
|
||||
make_dump_path(borgmatic_runtime_directory),
|
||||
name,
|
||||
hostname='*',
|
||||
label='*',
|
||||
),
|
||||
dump.make_data_source_dump_filename(
|
||||
make_dump_path(borgmatic_source_directory),
|
||||
name,
|
||||
hostname='*',
|
||||
label='*',
|
||||
),
|
||||
)
|
||||
|
||||
@@ -359,6 +360,7 @@ def restore_data_source_dump(
|
||||
make_dump_path(borgmatic_runtime_directory),
|
||||
data_source['name'],
|
||||
data_source.get('hostname'),
|
||||
data_source.get('label'),
|
||||
)
|
||||
psql_command = tuple(
|
||||
shlex.quote(part) for part in shlex.split(data_source.get('psql_command') or 'psql')
|
||||
|
||||
@@ -71,7 +71,9 @@ def dump_data_sources(
|
||||
)
|
||||
|
||||
dump_path = make_dump_path(borgmatic_runtime_directory)
|
||||
dump_filename = dump.make_data_source_dump_filename(dump_path, database['name'])
|
||||
dump_filename = dump.make_data_source_dump_filename(
|
||||
dump_path, database['name'], label=database.get('label')
|
||||
)
|
||||
|
||||
if os.path.exists(dump_filename):
|
||||
logger.warning(
|
||||
@@ -143,16 +145,16 @@ def make_data_source_dump_patterns(
|
||||
borgmatic_source_directory = borgmatic.config.paths.get_borgmatic_source_directory(config)
|
||||
|
||||
return (
|
||||
dump.make_data_source_dump_filename(make_dump_path('borgmatic'), name, hostname='*'),
|
||||
dump.make_data_source_dump_filename(make_dump_path('borgmatic'), name, label='*'),
|
||||
dump.make_data_source_dump_filename(
|
||||
make_dump_path(borgmatic_runtime_directory),
|
||||
name,
|
||||
hostname='*',
|
||||
label='*',
|
||||
),
|
||||
dump.make_data_source_dump_filename(
|
||||
make_dump_path(borgmatic_source_directory),
|
||||
name,
|
||||
hostname='*',
|
||||
label='*',
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -72,8 +72,10 @@ Here's a more involved example that connects to remote databases:
|
||||
```yaml
|
||||
postgresql_databases:
|
||||
- name: users
|
||||
label: database_server1
|
||||
hostname: database1.example.org
|
||||
- name: orders
|
||||
label: database_server2
|
||||
hostname: database2.example.org
|
||||
port: 5433
|
||||
username: postgres
|
||||
|
||||
@@ -25,6 +25,13 @@ def test_make_data_source_dump_filename_uses_name_and_hostname_and_port():
|
||||
)
|
||||
|
||||
|
||||
def test_make_data_source_dump_filename_users_label():
|
||||
assert (
|
||||
module.make_data_source_dump_filename('databases', 'test', 'hostname', 1234, 'custom_label')
|
||||
== 'databases/custom_label/test'
|
||||
)
|
||||
|
||||
|
||||
def test_make_data_source_dump_filename_without_hostname_defaults_to_localhost():
|
||||
assert module.make_data_source_dump_filename('databases', 'test') == 'databases/localhost/test'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user