Skip to content

Commit 84edd42

Browse files
committed
Use admin.vm.List method to get VM class
Normally, VM class is cached when getting list of all (accessible) VMs. This means the admin.vm.property.Get+klass is normally not used. But if there is a case where VM object is created without listing all VMs first, it will not get the 'klass' property set. Apparently preloaded disposables trigger this case in audiovm. The thing is, admin.vm.property.Get+klass is mostly redundant with admin.vm.List (directed at a specific qube), since admin.vm.List contains that information already - so it doesn't make much sense to force everybody to add both to the policy. Fix this by using admin.vm.List to get the VM class. Fixes QubesOS/qubes-issues#10717
1 parent aade160 commit 84edd42

2 files changed

Lines changed: 23 additions & 2 deletions

File tree

qubesadmin/tests/vm/properties.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
# pylint: disable=missing-docstring
2222

23+
import qubesadmin.vm
2324
import qubesadmin.tests.vm
2425

2526

@@ -305,3 +306,10 @@ def test_015_mem(self):
305306
('test-vm', 'admin.vm.CurrentState', None, None)] = \
306307
b'0\x00mem=1234'
307308
self.assertEqual(self.vm.get_mem(), 1234)
309+
310+
def test_020_klass(self):
311+
vm = qubesadmin.vm.QubesVM(self.app, "test-vm")
312+
self.app.expected_calls[("test-vm", "admin.vm.List", None, None)] = \
313+
b"0\x00test-vm class=AppVM state=Running\n"
314+
self.assertEqual(vm.klass, "AppVM")
315+
self.assertAllCalled()

qubesadmin/vm/__init__.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,8 +446,21 @@ def klass(self):
446446
"""Qube class"""
447447
# use cached value if available
448448
if self._klass is None:
449-
# pylint: disable=no-member
450-
self._klass = super().klass
449+
try:
450+
# use List method as that should be allowed for VMs that are
451+
# visible
452+
vm_list_data = self.qubesd_call(
453+
self._method_dest, "admin.vm.List"
454+
)
455+
assert vm_list_data.count(b"\n") == 1
456+
vm_name, props = vm_list_data.decode("ascii").split(" ", 1)
457+
assert vm_name == self.name
458+
props = props.split(" ")
459+
props_dict = dict([vm_prop.split("=", 1) for vm_prop in props])
460+
self._klass = props_dict["class"]
461+
except qubesadmin.exc.QubesDaemonAccessError:
462+
# pylint: disable=no-member
463+
self._klass = super().klass
451464
return self._klass
452465

453466
def get_notes(self) -> str:

0 commit comments

Comments
 (0)