Sfoglia il codice sorgente

Fix use of borgmatic runtime directory in the restore action (#934).

Dan Helfman 6 mesi fa
parent
commit
8f5ea95348

+ 2 - 1
borgmatic/actions/restore.py

@@ -171,6 +171,7 @@ def restore_single_data_source(
         dry_run=global_arguments.dry_run,
         extract_process=extract_process,
         connection_params=connection_params,
+        borgmatic_runtime_directory=borgmatic_runtime_directory,
     )
 
 
@@ -331,7 +332,6 @@ def run_restore(
     global_arguments,
     local_path,
     remote_path,
-    borgmatic_runtime_directory,
 ):
     '''
     Run the "restore" action for the given repository, but only if the repository matches the
@@ -375,6 +375,7 @@ def run_restore(
             global_arguments,
             local_path,
             remote_path,
+            borgmatic_runtime_directory,
         )
         restore_names = find_data_sources_to_restore(
             restore_arguments.data_sources, archive_data_source_names

+ 11 - 5
borgmatic/hooks/mariadb.py

@@ -216,14 +216,20 @@ def make_data_source_dump_patterns(
 
 
 def restore_data_source_dump(
-    hook_config, config, log_prefix, data_source, dry_run, extract_process, connection_params
+    hook_config,
+    config,
+    log_prefix,
+    data_source,
+    dry_run,
+    extract_process,
+    connection_params,
+    borgmatic_runtime_directory,
 ):
     '''
     Restore a database from the given extract stream. The database is supplied as a data source
-    configuration dict, but the given hook configuration is ignored. The given configuration dict is
-    used to construct the destination path, and the given log prefix is used for any log entries. If
-    this is a dry run, then don't actually restore anything. Trigger the given active extract
-    process (an instance of subprocess.Popen) to produce output to consume.
+    configuration dict, but the given hook configuration is ignored. The given log prefix is used
+    for any log entries. If this is a dry run, then don't actually restore anything. Trigger the
+    given active extract process (an instance of subprocess.Popen) to produce output to consume.
     '''
     dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
     hostname = connection_params['hostname'] or data_source.get(

+ 13 - 3
borgmatic/hooks/mongodb.py

@@ -27,7 +27,8 @@ def dump_data_sources(databases, config, log_prefix, borgmatic_runtime_directory
     '''
     Dump the given MongoDB databases to a named pipe. The databases are supplied as a sequence of
     dicts, one dict describing each database as per the configuration schema. Use the borgmatic
-    runtime directory to construct the destination path and the given log prefix in any log entries.
+    runtime directory to construct the destination path (used for the directory format and the given
+    log prefix in any log entries.
 
     Return a sequence of subprocess.Popen instances for the dump processes ready to spew to a named
     pipe. But if this is a dry run, then don't actually dump anything and return an empty sequence.
@@ -125,7 +126,14 @@ def make_data_source_dump_patterns(
 
 
 def restore_data_source_dump(
-    hook_config, config, log_prefix, data_source, dry_run, extract_process, connection_params
+    hook_config,
+    config,
+    log_prefix,
+    data_source,
+    dry_run,
+    extract_process,
+    connection_params,
+    borgmatic_runtime_directory,
 ):
     '''
     Restore a database from the given extract stream. The database is supplied as a data source
@@ -139,7 +147,9 @@ def restore_data_source_dump(
     '''
     dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
     dump_filename = dump.make_data_source_dump_filename(
-        make_dump_path(config), data_source['name'], data_source.get('hostname')
+        make_dump_path(borgmatic_runtime_directory),
+        data_source['name'],
+        data_source.get('hostname'),
     )
     restore_command = build_restore_command(
         extract_process, data_source, dump_filename, connection_params

+ 11 - 5
borgmatic/hooks/mysql.py

@@ -215,14 +215,20 @@ def make_data_source_dump_patterns(
 
 
 def restore_data_source_dump(
-    hook_config, config, log_prefix, data_source, dry_run, extract_process, connection_params
+    hook_config,
+    config,
+    log_prefix,
+    data_source,
+    dry_run,
+    extract_process,
+    connection_params,
+    borgmatic_runtime_directory,
 ):
     '''
     Restore a database from the given extract stream. The database is supplied as a data source
-    configuration dict, but the given hook configuration is ignored. The given configuration dict is
-    used to construct the destination path, and the given log prefix is used for any log entries. If
-    this is a dry run, then don't actually restore anything. Trigger the given active extract
-    process (an instance of subprocess.Popen) to produce output to consume.
+    configuration dict, but the given hook configuration is ignored. The given log prefix is used
+    for any log entries. If this is a dry run, then don't actually restore anything. Trigger the
+    given active extract process (an instance of subprocess.Popen) to produce output to consume.
     '''
     dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
     hostname = connection_params['hostname'] or data_source.get(

+ 16 - 6
borgmatic/hooks/postgresql.py

@@ -241,14 +241,22 @@ def make_data_source_dump_patterns(
 
 
 def restore_data_source_dump(
-    hook_config, config, log_prefix, data_source, dry_run, extract_process, connection_params
+    hook_config,
+    config,
+    log_prefix,
+    data_source,
+    dry_run,
+    extract_process,
+    connection_params,
+    borgmatic_runtime_directory,
 ):
     '''
     Restore a database from the given extract stream. The database is supplied as a data source
-    configuration dict, but the given hook configuration is ignored. The given configuration dict is
-    used to construct the destination path, and the given log prefix is used for any log entries. If
-    this is a dry run, then don't actually restore anything. Trigger the given active extract
-    process (an instance of subprocess.Popen) to produce output to consume.
+    configuration dict, but the given hook configuration is ignored. The given borgmatic runtime
+    directory is used to construct the destination path (used for the directory format), and the
+    given log prefix is used for any log entries. If this is a dry run, then don't actually restore
+    anything. Trigger the given active extract process (an instance of subprocess.Popen) to produce
+    output to consume.
 
     If the extract process is None, then restore the dump from the filesystem rather than from an
     extract stream.
@@ -269,7 +277,9 @@ def restore_data_source_dump(
 
     all_databases = bool(data_source['name'] == 'all')
     dump_filename = dump.make_data_source_dump_filename(
-        make_dump_path(config), data_source['name'], data_source.get('hostname')
+        make_dump_path(borgmatic_runtime_directory),
+        data_source['name'],
+        data_source.get('hostname'),
     )
     psql_command = tuple(
         shlex.quote(part) for part in shlex.split(data_source.get('psql_command') or 'psql')

+ 11 - 5
borgmatic/hooks/sqlite.py

@@ -111,14 +111,20 @@ def make_data_source_dump_patterns(
 
 
 def restore_data_source_dump(
-    hook_config, config, log_prefix, data_source, dry_run, extract_process, connection_params
+    hook_config,
+    config,
+    log_prefix,
+    data_source,
+    dry_run,
+    extract_process,
+    connection_params,
+    borgmatic_runtime_directory,
 ):
     '''
     Restore a database from the given extract stream. The database is supplied as a data source
-    configuration dict, but the given hook configuration is ignored. The given configuration dict is
-    used to construct the destination path, and the given log prefix is used for any log entries. If
-    this is a dry run, then don't actually restore anything. Trigger the given active extract
-    process (an instance of subprocess.Popen) to produce output to consume.
+    configuration dict, but the given hook configuration is ignored. The given log prefix is used
+    for any log entries. If this is a dry run, then don't actually restore anything. Trigger the
+    given active extract process (an instance of subprocess.Popen) to produce output to consume.
     '''
     dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
     database_path = connection_params['restore_path'] or data_source.get(

+ 5 - 8
tests/unit/actions/test_restore.py

@@ -107,6 +107,7 @@ def test_restore_single_data_source_extracts_and_restores_single_file_dump():
         dry_run=object,
         extract_process=object,
         connection_params=object,
+        borgmatic_runtime_directory=object,
     ).once()
 
     module.restore_single_data_source(
@@ -148,6 +149,7 @@ def test_restore_single_data_source_extracts_and_restores_directory_dump():
         dry_run=object,
         extract_process=object,
         connection_params=object,
+        borgmatic_runtime_directory='/run/borgmatic',
     ).once()
 
     module.restore_single_data_source(
@@ -189,6 +191,7 @@ def test_restore_single_data_source_with_directory_dump_error_cleans_up_temporar
         dry_run=object,
         extract_process=object,
         connection_params=object,
+        borgmatic_runtime_directory='/run/user/0/borgmatic/tmp1234',
     ).never()
 
     with pytest.raises(ValueError):
@@ -211,9 +214,7 @@ def test_restore_single_data_source_with_directory_dump_and_dry_run_skips_direct
     flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').with_args(
         'make_data_source_dump_patterns', object, object, object, object, object
     ).and_return({'postgresql': flexmock()})
-    flexmock(module.tempfile).should_receive('mkdtemp').once().and_return(
-        '/run/user/0/borgmatic/tmp1234'
-    )
+    flexmock(module.tempfile).should_receive('mkdtemp').once().and_return('/run/borgmatic/tmp1234')
     flexmock(module.borgmatic.hooks.dump).should_receive(
         'convert_glob_patterns_to_borg_pattern'
     ).and_return(flexmock())
@@ -231,6 +232,7 @@ def test_restore_single_data_source_with_directory_dump_and_dry_run_skips_direct
         dry_run=object,
         extract_process=object,
         connection_params=object,
+        borgmatic_runtime_directory='/run/borgmatic',
     ).once()
 
     module.restore_single_data_source(
@@ -524,7 +526,6 @@ def test_run_restore_restores_each_data_source():
         global_arguments=flexmock(dry_run=False),
         local_path=flexmock(),
         remote_path=flexmock(),
-        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -548,7 +549,6 @@ def test_run_restore_bails_for_non_matching_repository():
         global_arguments=flexmock(dry_run=False),
         local_path=flexmock(),
         remote_path=flexmock(),
-        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -633,7 +633,6 @@ def test_run_restore_restores_data_source_configured_with_all_name():
         global_arguments=flexmock(dry_run=False),
         local_path=flexmock(),
         remote_path=flexmock(),
-        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -718,7 +717,6 @@ def test_run_restore_skips_missing_data_source():
         global_arguments=flexmock(dry_run=False),
         local_path=flexmock(),
         remote_path=flexmock(),
-        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -797,5 +795,4 @@ def test_run_restore_restores_data_sources_from_different_hooks():
         global_arguments=flexmock(dry_run=False),
         local_path=flexmock(),
         remote_path=flexmock(),
-        borgmatic_runtime_directory='/run/borgmatic',
     )

+ 8 - 0
tests/unit/hooks/test_mariadb.py

@@ -494,6 +494,7 @@ def test_restore_data_source_dump_runs_mariadb_to_restore():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -522,6 +523,7 @@ def test_restore_data_source_dump_runs_mariadb_with_options():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -552,6 +554,7 @@ def test_restore_data_source_dump_runs_non_default_mariadb_with_options():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -589,6 +592,7 @@ def test_restore_data_source_dump_runs_mariadb_with_hostname_and_port():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -617,6 +621,7 @@ def test_restore_data_source_dump_runs_mariadb_with_username_and_password():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -666,6 +671,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
             'username': 'cliusername',
             'password': 'clipassword',
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -717,6 +723,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -738,4 +745,5 @@ def test_restore_data_source_dump_with_dry_run_skips_restore():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )

+ 10 - 0
tests/unit/hooks/test_mongodb.py

@@ -241,6 +241,7 @@ def test_restore_data_source_dump_runs_mongorestore():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -280,6 +281,7 @@ def test_restore_data_source_dump_runs_mongorestore_with_hostname_and_port():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -327,6 +329,7 @@ def test_restore_data_source_dump_runs_mongorestore_with_username_and_password()
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -382,6 +385,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
             'username': 'cliusername',
             'password': 'clipassword',
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -437,6 +441,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -466,6 +471,7 @@ def test_restore_data_source_dump_runs_mongorestore_with_options():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -503,6 +509,7 @@ def test_restore_databases_dump_runs_mongorestore_with_schemas():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -532,6 +539,7 @@ def test_restore_data_source_dump_runs_psql_for_all_database_dump():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -555,6 +563,7 @@ def test_restore_data_source_dump_with_dry_run_skips_restore():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -583,4 +592,5 @@ def test_restore_data_source_dump_without_extract_process_restores_from_disk():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )

+ 8 - 0
tests/unit/hooks/test_mysql.py

@@ -492,6 +492,7 @@ def test_restore_data_source_dump_runs_mysql_to_restore():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -520,6 +521,7 @@ def test_restore_data_source_dump_runs_mysql_with_options():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -548,6 +550,7 @@ def test_restore_data_source_dump_runs_non_default_mysql_with_options():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -585,6 +588,7 @@ def test_restore_data_source_dump_runs_mysql_with_hostname_and_port():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -613,6 +617,7 @@ def test_restore_data_source_dump_runs_mysql_with_username_and_password():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -662,6 +667,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
             'username': 'cliusername',
             'password': 'clipassword',
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -713,6 +719,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -734,4 +741,5 @@ def test_restore_data_source_dump_with_dry_run_skips_restore():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )

+ 12 - 0
tests/unit/hooks/test_postgresql.py

@@ -620,6 +620,7 @@ def test_restore_data_source_dump_runs_pg_restore():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -682,6 +683,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_hostname_and_port():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -742,6 +744,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_username_and_password():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -821,6 +824,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
             'username': 'cliusername',
             'password': 'clipassword',
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -900,6 +904,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -961,6 +966,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_options():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -1000,6 +1006,7 @@ def test_restore_data_source_dump_runs_psql_for_all_database_dump():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -1044,6 +1051,7 @@ def test_restore_data_source_dump_runs_psql_for_plain_database_dump():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -1113,6 +1121,7 @@ def test_restore_data_source_dump_runs_non_default_pg_restore_and_psql():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -1137,6 +1146,7 @@ def test_restore_data_source_dump_with_dry_run_skips_restore():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -1189,6 +1199,7 @@ def test_restore_data_source_dump_without_extract_process_restores_from_disk():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -1245,4 +1256,5 @@ def test_restore_data_source_dump_with_schemas_restores_schemas():
             'username': None,
             'password': None,
         },
+        borgmatic_runtime_directory='/run/borgmatic',
     )

+ 4 - 0
tests/unit/hooks/test_sqlite.py

@@ -182,6 +182,7 @@ def test_restore_data_source_dump_restores_database():
         dry_run=False,
         extract_process=extract_process,
         connection_params={'restore_path': None},
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -211,6 +212,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
         dry_run=False,
         extract_process=extract_process,
         connection_params={'restore_path': 'cli/path/to/database'},
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -240,6 +242,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
         dry_run=False,
         extract_process=extract_process,
         connection_params={'restore_path': None},
+        borgmatic_runtime_directory='/run/borgmatic',
     )
 
 
@@ -258,4 +261,5 @@ def test_restore_data_source_dump_does_not_restore_database_if_dry_run():
         dry_run=True,
         extract_process=extract_process,
         connection_params={'restore_path': None},
+        borgmatic_runtime_directory='/run/borgmatic',
     )