Skip to content

Commit c96c995

Browse files
committed
Improve qvm-backup-restore --paranoid-mode
Before openning a Shell window in the DispVM, check for availability of `core-admin-client` in the DisposableVM and show error message if not available resolves: QubesOS/qubes-issues#9962
1 parent c89ed14 commit c96c995

4 files changed

Lines changed: 22 additions & 3 deletions

File tree

doc/manpages/qvm-backup-restore.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ Options
101101
- dom0 home directory (desktop environment settings)
102102
- PCI devices assignments
103103

104+
This operation requires `qubes-core-admin-client` package in the DisposableVM
105+
104106
.. option:: --auto-close
105107

106108
When running with --paranoid-mode (see above), automatically close restore

qubesadmin/backup/dispvm.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,27 @@ def run(self):
276276
lock = qubesadmin.utils.LockFile(LOCKFILE, True)
277277
lock.acquire()
278278
try:
279+
self.app.log.info("Starting restore process in a DisposableVM...")
279280
self.create_dispvm()
280281
self.clear_old_tags()
281282
self.register_backup_source()
282283
self.dispvm.start()
284+
try:
285+
self.app.log.debug(
286+
"Checking for existence of qubes-core-admin-client"
287+
)
288+
self.dispvm.run("which -q qvm-backup-restore")
289+
except subprocess.CalledProcessError:
290+
raise qubesadmin.exc.QubesException(
291+
'qvm-backup-restore tool '
292+
'missing in {} template, install qubes-core-admin-client '
293+
'package there'.format(
294+
getattr(self.dispvm.template,
295+
'template',
296+
self.dispvm.template).name)
297+
)
298+
self.app.log.info("When operation completes, close its window "
299+
"manually.")
283300
self.dispvm.run_service_for_stdio('qubes.WaitForSession')
284301
if self.args.pass_file:
285302
self.args.pass_file = self.transfer_pass_file(

qubesadmin/tests/backup/dispvm.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ def test_100_run(self):
330330
self.assertEqual(len(getattr(obj, m).mock_calls), 1)
331331
self.assertEqual(obj.dispvm.mock_calls, [
332332
call.start(),
333+
call.run('which -q qvm-backup-restore'),
333334
call.run_service_for_stdio('qubes.WaitForSession'),
334335
call.tags.add('backup-restore-mgmt'),
335336
call.run_with_args('terminal', 'qvm-backup-restore', 'args',
@@ -368,6 +369,7 @@ def test_101_run_pass_file(self):
368369
self.assertEqual(len(getattr(obj, m).mock_calls), 1)
369370
self.assertEqual(obj.dispvm.mock_calls, [
370371
call.start(),
372+
call.run('which -q qvm-backup-restore'),
371373
call.run_service_for_stdio('qubes.WaitForSession'),
372374
call.tags.add('backup-restore-mgmt'),
373375
call.run_with_args('terminal', 'qvm-backup-restore', 'args',
@@ -405,6 +407,7 @@ def test_102_run_error(self):
405407
self.assertEqual(len(getattr(obj, m).mock_calls), 1)
406408
self.assertEqual(obj.dispvm.mock_calls, [
407409
call.start(),
410+
call.run('which -q qvm-backup-restore'),
408411
call.run_service_for_stdio('qubes.WaitForSession'),
409412
call.tags.add('backup-restore-mgmt'),
410413
call.run_with_args('terminal', 'qvm-backup-restore', 'args',

qubesadmin/tools/qvm_backup_restore.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,6 @@ def main(args=None, app=None):
240240

241241
if args.paranoid_mode:
242242
args.dom0_home = False
243-
args.app.log.info("Starting restore process in a DisposableVM...")
244-
args.app.log.info("When operation completes, close its window "
245-
"manually.")
246243
restore_in_dispvm = RestoreInDisposableVM(args.app, args)
247244
try:
248245
backup_log = restore_in_dispvm.run()

0 commit comments

Comments
 (0)