From 9912cebb70792081659dc3a7daffaec4e514ad4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marta=20Marczykowska-G=C3=B3recka?= Date: Thu, 9 Sep 2021 14:25:01 +0200 Subject: [PATCH] Better error reporting if backup file not found qvm-backup-restore will now show a File Not Found message if specified backup file is not found. fixes QubesOS/qubes-issues#3446 --- qubesadmin/tests/tools/qvm_backup_restore.py | 16 ++++++++++++++-- qubesadmin/tools/qvm_backup_restore.py | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/qubesadmin/tests/tools/qvm_backup_restore.py b/qubesadmin/tests/tools/qvm_backup_restore.py index 02feae4c..3d3e44e2 100644 --- a/qubesadmin/tests/tools/qvm_backup_restore.py +++ b/qubesadmin/tests/tools/qvm_backup_restore.py @@ -38,7 +38,9 @@ def tearDown(self): @mock.patch('qubesadmin.tools.qvm_backup_restore.input', create=True) @mock.patch('getpass.getpass') @mock.patch('qubesadmin.tools.qvm_backup_restore.BackupRestore') - def test_000_simple(self, mock_backup, mock_getpass, mock_input): + @mock.patch('os.path.exists', return_value=True) + def test_000_simple(self, _mock_exists, + mock_backup, mock_getpass, mock_input): mock_getpass.return_value = 'testpass' mock_input.return_value = 'Y' vm1 = BackupVM() @@ -68,7 +70,9 @@ def test_000_simple(self, mock_backup, mock_getpass, mock_input): @mock.patch('qubesadmin.tools.qvm_backup_restore.input', create=True) @mock.patch('getpass.getpass') @mock.patch('qubesadmin.tools.qvm_backup_restore.BackupRestore') - def test_001_selected_vms(self, mock_backup, mock_getpass, mock_input): + @mock.patch('os.path.exists', return_value=True) + def test_001_selected_vms(self, _mock_exist, + mock_backup, mock_getpass, mock_input): mock_getpass.return_value = 'testpass' mock_input.return_value = 'Y' vm1 = BackupVM() @@ -235,6 +239,14 @@ def test_012_handle_broken_missing_netvm(self): self.app, mock_args, mock_restore_info) self.assertAppropriateLogging('NetVM', 'error') + @mock.patch('argparse.ArgumentParser.error') + def test_013_missing_file(self, mock_argparse): + mock_argparse.side_effect = qubesadmin.exc.QubesException('Error') + with self.assertRaises(qubesadmin.exc.QubesException): + qubesadmin.tools.qvm_backup_restore.main(['/some/path'], + app=self.app) + mock_argparse.assert_called_once_with("File not found: '/some/path'") + def test_100_restore_in_dispvm_parser(self): """Verify if qvm-backup-restore tool options matches un-parser for paranoid restore mode""" diff --git a/qubesadmin/tools/qvm_backup_restore.py b/qubesadmin/tools/qvm_backup_restore.py index d7e3449c..a4eaf413 100644 --- a/qubesadmin/tools/qvm_backup_restore.py +++ b/qubesadmin/tools/qvm_backup_restore.py @@ -238,6 +238,9 @@ def main(args=None, app=None): if args.location_is_service and not args.appvm: parser.error('--location-is-service option requires -d') + if not os.path.exists(args.backup_location): + parser.error('File not found: {!r}'.format(args.backup_location)) + if args.paranoid_mode: args.dom0_home = False args.app.log.info("Starting restore process in a DisposableVM...")