From 5f4fbafee4fc828db276a63c68a1e0b23ca6e6f2 Mon Sep 17 00:00:00 2001 From: Ali Mirjamali Date: Mon, 17 Feb 2025 13:39:13 +0330 Subject: [PATCH] Revert to red label while restoring on missing labels If we allow users to create custom labels and they backup such qubes, restore operation will fail on new systems without those custom labels. Fix this by reverting to red label and allow users to restore their backup. fixes: https://github.com/QubesOS/qubes-issues/issues/9781 --- qubesadmin/backup/restore.py | 6 ++++++ qubesadmin/tests/backup/backupcompatibility.py | 12 +++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/qubesadmin/backup/restore.py b/qubesadmin/backup/restore.py index 54288d72..0dce45c9 100644 --- a/qubesadmin/backup/restore.py +++ b/qubesadmin/backup/restore.py @@ -2020,6 +2020,12 @@ def _restore_vms_metadata(self, restore_info): # can't create vm, but need backup info new_vm = self.backup_app.domains[vm_name] else: + # do not fail if VM had a custom label. revert to red label + if not vm.label in self.app.labels: + self.log.warning( + 'Reverting to red label while restoring %s ' \ + 'since %s label does not exist', vm.name, vm.label) + vm.label = "red" try: # first only create VMs, later setting may require other VMs # be already created diff --git a/qubesadmin/tests/backup/backupcompatibility.py b/qubesadmin/tests/backup/backupcompatibility.py index d6b325f0..4184ad73 100644 --- a/qubesadmin/tests/backup/backupcompatibility.py +++ b/qubesadmin/tests/backup/backupcompatibility.py @@ -695,7 +695,7 @@ }, 'test-net': { 'klass': 'AppVM', - 'label': 'red', + 'label': 'scarlet', 'properties': { 'maxmem': '300', 'memory': '300', @@ -749,8 +749,11 @@ def assertCorrectlyConverted(self, backup_app, expected_data): expected_data['domains'][vm]['template'], vm) self.assertEqual(backup_app.domains[vm].klass, expected_data['domains'][vm]['klass'], vm) - self.assertEqual(backup_app.domains[vm].label, - expected_data['domains'][vm]['label'], vm) + if expected_data['domains'][vm]['label'] == 'scarlet': + self.assertEqual(backup_app.domains[vm].label, 'red', vm) + else: + self.assertEqual(backup_app.domains[vm].label, + expected_data['domains'][vm]['label'], vm) self.assertEqual(backup_app.domains[vm].backup_path, expected_data['domains'][vm]['backup_path'], vm) self.assertEqual(backup_app.domains[vm].included_in_backup, @@ -1487,6 +1490,9 @@ def setup_expected_calls(self, parsed_qubes_xml, templates_map=None): [orig_admin_vm_list] + \ [orig_admin_vm_list + b''.join(extra_vm_list_lines)] * \ len(extra_vm_list_lines) + self.app.expected_calls[('dom0', 'admin.label.List', None, None)] = ( + b'0\0red\norange\nyellow\ngreen\ngray\nblue\npurple\nblack\n' + ) def mock_appmenus(self, queue, vm, stream): queue.put((vm.name, 'appmenus', None, stream.read()))