api/admin: implement *.property.GetAll methods
Allow getting all the VM properties with one call. This greatly improve performance of an applications retrieving many/all of them (qvm-ls, qubes manager etc) QubesOS/qubes-issues#5415 Fixes QubesOS/qubes-issues#3293
This commit is contained in:
parent
5d77cf2298
commit
10f99e5c4a
2
Makefile
2
Makefile
@ -35,6 +35,7 @@ ADMIN_API_METHODS_SIMPLE = \
|
||||
admin.pool.volume.Set.rw \
|
||||
admin.pool.volume.Snapshot \
|
||||
admin.property.Get \
|
||||
admin.property.GetAll \
|
||||
admin.property.GetDefault \
|
||||
admin.property.Help \
|
||||
admin.property.HelpRst \
|
||||
@ -87,6 +88,7 @@ ADMIN_API_METHODS_SIMPLE = \
|
||||
admin.vm.firewall.SetPolicy \
|
||||
admin.vm.firewall.Reload \
|
||||
admin.vm.property.Get \
|
||||
admin.vm.property.GetAll \
|
||||
admin.vm.property.GetDefault \
|
||||
admin.vm.property.Help \
|
||||
admin.vm.property.HelpRst \
|
||||
|
@ -169,7 +169,11 @@ class QubesAdminAPI(qubes.api.AbstractQubesAPI):
|
||||
|
||||
self.fire_event_for_permission()
|
||||
|
||||
property_def = dest.property_get_def(self.arg)
|
||||
return self._serialize_property(dest, self.arg)
|
||||
|
||||
@staticmethod
|
||||
def _serialize_property(dest, prop):
|
||||
property_def = dest.property_get_def(prop)
|
||||
# explicit list to be sure that it matches protocol spec
|
||||
if isinstance(property_def, qubes.vm.VMProperty):
|
||||
property_type = 'vm'
|
||||
@ -177,21 +181,51 @@ class QubesAdminAPI(qubes.api.AbstractQubesAPI):
|
||||
property_type = 'int'
|
||||
elif property_def.type is bool:
|
||||
property_type = 'bool'
|
||||
elif self.arg == 'label':
|
||||
elif prop == 'label':
|
||||
property_type = 'label'
|
||||
else:
|
||||
property_type = 'str'
|
||||
|
||||
try:
|
||||
value = getattr(dest, self.arg)
|
||||
value = getattr(dest, str(prop))
|
||||
except AttributeError:
|
||||
return 'default=True type={} '.format(property_type)
|
||||
else:
|
||||
return 'default={} type={} {}'.format(
|
||||
str(dest.property_is_default(self.arg)),
|
||||
str(dest.property_is_default(prop)),
|
||||
property_type,
|
||||
str(value) if value is not None else '')
|
||||
|
||||
@qubes.api.method('admin.vm.property.GetAll', no_payload=True,
|
||||
scope='local', read=True)
|
||||
@asyncio.coroutine
|
||||
def vm_property_get_all(self):
|
||||
"""Get values of all VM properties"""
|
||||
return self._property_get_all(self.dest)
|
||||
|
||||
@qubes.api.method('admin.property.GetAll', no_payload=True,
|
||||
scope='global', read=True)
|
||||
@asyncio.coroutine
|
||||
def property_get_all(self):
|
||||
"""Get value all global properties"""
|
||||
self.enforce(self.dest.name == 'dom0')
|
||||
return self._property_get_all(self.app)
|
||||
|
||||
def _property_get_all(self, dest):
|
||||
self.enforce(not self.arg)
|
||||
|
||||
properties = dest.property_list()
|
||||
|
||||
properties = self.fire_event_for_filter(properties)
|
||||
|
||||
return ''.join(
|
||||
'{} {}\n'.format(str(prop),
|
||||
self._serialize_property(dest, prop).
|
||||
replace('\\', '\\\\').replace('\n', '\\n'))
|
||||
for prop in sorted(properties))
|
||||
|
||||
|
||||
|
||||
@qubes.api.method('admin.vm.property.GetDefault', no_payload=True,
|
||||
scope='local', read=True)
|
||||
@asyncio.coroutine
|
||||
|
@ -180,6 +180,38 @@ class TC_00_VMs(AdminAPITestCase):
|
||||
b'provides_network')
|
||||
self.assertEqual(value, 'type=bool False')
|
||||
|
||||
def test_027_vm_property_get_all(self):
|
||||
# any string property, test \n encoding
|
||||
self.vm.kernelopts = 'opt1\nopt2\nopt3\\opt4'
|
||||
with unittest.mock.patch.object(self.vm, 'property_list') as list_mock:
|
||||
list_mock.return_value = [
|
||||
self.vm.property_get_def('name'),
|
||||
self.vm.property_get_def('default_user'),
|
||||
self.vm.property_get_def('netvm'),
|
||||
self.vm.property_get_def('klass'),
|
||||
self.vm.property_get_def('debug'),
|
||||
self.vm.property_get_def('label'),
|
||||
self.vm.property_get_def('kernelopts'),
|
||||
self.vm.property_get_def('qrexec_timeout'),
|
||||
self.vm.property_get_def('qid'),
|
||||
self.vm.property_get_def('updateable'),
|
||||
]
|
||||
value = self.call_mgmt_func(b'admin.vm.property.GetAll', b'test-vm1')
|
||||
self.maxDiff = None
|
||||
expected = '''debug default=True type=bool False
|
||||
default_user default=True type=str user
|
||||
klass default=True type=str AppVM
|
||||
label default=False type=label red
|
||||
name default=False type=str test-vm1
|
||||
qid default=False type=int 2
|
||||
qrexec_timeout default=True type=int 60
|
||||
updateable default=True type=bool False
|
||||
kernelopts default=False type=str opt1\\nopt2\\nopt3\\\\opt4
|
||||
netvm default=True type=vm
|
||||
'''
|
||||
self.assertEqual(value, expected)
|
||||
|
||||
|
||||
def test_030_vm_property_set_vm(self):
|
||||
netvm = self.app.add_new_vm('AppVM', label='red', name='test-net',
|
||||
template='test-template', provides_network=True)
|
||||
|
Loading…
Reference in New Issue
Block a user