diff --git a/qubesadmin/tests/utils.py b/qubesadmin/tests/utils.py index e35bdf36..36f7434c 100644 --- a/qubesadmin/tests/utils.py +++ b/qubesadmin/tests/utils.py @@ -35,7 +35,10 @@ def setUp(self): b'template2 class=TemplateVM state=Running\n' \ b'vm2 class=AppVM state=Running\n' \ b'sys-net class=AppVM state=Running\n' \ - b'sys-firewall class=AppVM state=Running\n' + b'sys-firewall class=AppVM state=Running\n' \ + b'test-dvm class=AppVM state=Running\n' \ + b'disp1 class=DispVM state=Running\n' \ + b'disp2 class=DispVM state=Running\n' self.global_properties = ['default_dispvm', 'default_netvm', 'default_guivm', 'default_audiovm', @@ -47,13 +50,20 @@ def setUp(self): ('dom0', 'admin.property.Get', prop, None)] = \ b'0\x00default=True type=vm vm2' - self.vms = ['vm1', 'vm2', 'sys-net', 'sys-firewall', - 'template1', 'template2'] + self.vms = [ + 'vm1', 'vm2', 'sys-net', 'sys-firewall', 'template1', 'template2', + 'test-dvm', 'disp1', 'disp2', + ] - self.vm_properties = ['template', 'netvm', 'guivm', 'audiovm', - 'default_dispvm', 'management_dispvm'] + self.vm_properties = [ + 'template', 'netvm', 'guivm', 'audiovm', 'default_dispvm', + 'management_dispvm' + ] for vm in self.vms: + self.app.expected_calls[ + (vm, 'admin.vm.property.Get', 'is_preload', None) + ] = b'2\0QubesNoSuchPropertyError\0\0invalid property\0' for prop in self.vm_properties: if not prop.startswith('template') or \ not vm.startswith('template'): @@ -65,6 +75,7 @@ def setUp(self): (vm, 'admin.vm.property.Get', prop, None)] = \ b'2\0QubesNoSuchPropertyError\0\0invalid property\0' + def test_00_only_global(self): result = qubesadmin.utils.vm_dependencies(self.app, self.app.domains['vm2']) @@ -114,6 +125,27 @@ def test_04_defaults(self): self.assertListEqual(result, [(self.app.domains['vm1'], 'netvm')]) + def test_05_preloaded_disposables(self): + self.app.expected_calls[ + ('disp1', 'admin.vm.property.Get', 'template', None) + ] = b'0\x00default=False type=vm test-dvm' + self.app.expected_calls[ + ('disp2', 'admin.vm.property.Get', 'template', None) + ] = b'0\x00default=False type=vm test-dvm' + self.app.expected_calls[ + ('disp1', 'admin.vm.property.Get', 'is_preload', None) + ] = b'0\x00default=False type=bool False' + self.app.expected_calls[ + ('disp2', 'admin.vm.property.Get', 'is_preload', None) + ] = b'0\x00default=False type=bool True' + + result = qubesadmin.utils.vm_dependencies( + self.app, self.app.domains['test-dvm'] + ) + self.assertListEqual( + result, [(self.app.domains['disp1'], 'template')] + ) + class TestVMExecEncode(qubesadmin.tests.QubesTestCase): def test_00_encode(self): diff --git a/qubesadmin/utils.py b/qubesadmin/utils.py index 9614f0f3..128c5a02 100644 --- a/qubesadmin/utils.py +++ b/qubesadmin/utils.py @@ -143,6 +143,7 @@ def vm_dependencies(app, reference_vm): for vm in app.domains: if vm == reference_vm: continue + is_preload = getattr(vm, "is_preload", False) for prop in vm_properties: if not hasattr(vm, prop): continue @@ -150,7 +151,18 @@ def vm_dependencies(app, reference_vm): is_prop_default = vm.property_is_default(prop) except qubesadmin.exc.QubesPropertyAccessError: is_prop_default = False - if reference_vm == getattr(vm, prop, None) and not is_prop_default: + if ( + reference_vm == getattr(vm, prop, None) + and not is_prop_default + and not ( + is_preload + and prop == "template" + or ( + prop == "default_dispvm" + and getattr(vm, "template", None) == vm + ) + ) + ): result.append((vm, prop)) return result