Skip to content

Commit

Permalink
q-dev: keep one DeviceInfo API
Browse files Browse the repository at this point in the history
the same as in client
  • Loading branch information
piotrbartman committed Jun 12, 2024
1 parent a044cf5 commit 14e431f
Show file tree
Hide file tree
Showing 12 changed files with 657 additions and 132 deletions.
4 changes: 2 additions & 2 deletions qubes/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ def __init__(self, app, src, method_name, dest, arg, send_event=None):
#: destination qube
self.dest = self.app.domains[vm]
except KeyError:
# normally this should filtered out by qrexec policy, but there are
# two cases it might not be:
# normally this should be filtered out by qrexec policy, but there
# are two cases it might not be:
# 1. The call comes from dom0, which bypasses qrexec policy
# 2. Domain was removed between checking the policy and here
# we inform the client accordingly
Expand Down
31 changes: 18 additions & 13 deletions qubes/api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1200,26 +1200,31 @@ async def vm_device_available(self, endpoint):
devices = self.dest.devices[devclass].available()
if self.arg:
devices = [dev for dev in devices if dev.ident == self.arg]
# no duplicated devices, but device may not exists, in which case
# no duplicated devices, but device may not exist, in which case
# the list is empty
self.enforce(len(devices) <= 1)
devices = self.fire_event_for_filter(devices, devclass=devclass)

# dev_info = {dev.ident: dev.serialize() for dev in devices}
dev_info = {}
for dev in devices:
non_default_attrs = set(attr for attr in dir(dev) if
not attr.startswith('_')).difference((
# TODO:
if hasattr(dev, "serialize"):
properties_txt = dev.serialize().decode()
else:
non_default_attrs = set(attr for attr in dir(dev) if
not attr.startswith('_')).difference((
'backend_domain', 'ident', 'frontend_domain',
'description', 'options', 'regex'))
properties_txt = ' '.join(
'{}={!s}'.format(prop, value) for prop, value
in itertools.chain(
((key, getattr(dev, key)) for key in non_default_attrs),
# keep description as the last one, according to API
# specification
(('description', dev.description),)
))
self.enforce('\n' not in properties_txt)
properties_txt = ' '.join(
'{}={!s}'.format(prop, value) for prop, value
in itertools.chain(
((key, getattr(dev, key)) for key in non_default_attrs),
# keep description as the last one, according to API
# specification
(('description', dev.description),)
))
self.enforce('\n' not in properties_txt)
dev_info[dev.ident] = properties_txt

return ''.join('{} {}\n'.format(ident, dev_info[ident])
Expand All @@ -1237,7 +1242,7 @@ async def vm_device_list(self, endpoint):
device_assignments = [dev for dev in device_assignments
if (str(dev.backend_domain), dev.ident)
== (select_backend, select_ident)]
# no duplicated devices, but device may not exists, in which case
# no duplicated devices, but device may not exist, in which case
# the list is empty
self.enforce(len(device_assignments) <= 1)
device_assignments = self.fire_event_for_filter(device_assignments,
Expand Down
16 changes: 8 additions & 8 deletions qubes/api/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, see <https://www.gnu.org/licenses/>.

''' Interface for methods not being part of Admin API, but still handled by
qubesd. '''
""" Interface for methods not being part of Admin API, but still handled by
qubesd. """

import string
from datetime import datetime
Expand All @@ -34,7 +34,7 @@ class QubesMiscAPI(qubes.api.AbstractQubesAPI):

@qubes.api.method('qubes.FeaturesRequest', no_payload=True)
async def qubes_features_request(self):
''' qubes.FeaturesRequest handler
""" qubes.FeaturesRequest handler
VM (mostly templates) can request some features from dom0 for itself.
Then dom0 (qubesd extension) may respect this request or ignore it.
Expand All @@ -44,7 +44,7 @@ async def qubes_features_request(self):
dispatch 'features-request' event, which may be handled by
appropriate extensions. Requests not explicitly handled by some
extension are ignored.
'''
"""
self.enforce(self.dest.name == 'dom0')
self.enforce(not self.arg)

Expand All @@ -66,9 +66,9 @@ async def qubes_features_request(self):

@qubes.api.method('qubes.NotifyTools', no_payload=True)
async def qubes_notify_tools(self):
'''
"""
Legacy version of qubes.FeaturesRequest, used by Qubes Windows Tools
'''
"""
self.enforce(self.dest.name == 'dom0')
self.enforce(not self.arg)

Expand All @@ -92,12 +92,12 @@ async def qubes_notify_tools(self):

@qubes.api.method('qubes.NotifyUpdates')
async def qubes_notify_updates(self, untrusted_payload):
'''
"""
Receive VM notification about updates availability
Payload contains a single integer - either 0 (no updates) or some
positive value (some updates).
'''
"""

untrusted_update_count = untrusted_payload.strip()
self.enforce(untrusted_update_count.isdigit())
Expand Down
8 changes: 4 additions & 4 deletions qubes/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,7 @@ def load(self, lock=False):
vm.fire_event('domain-load')

# get a file timestamp (before closing it - still holding the lock!),
# to detect whether anyone else have modified it in the meantime
# to detect whether anyone else has modified it in the meantime
self.__load_timestamp = os.path.getmtime(self._store)

if not lock:
Expand Down Expand Up @@ -1509,7 +1509,7 @@ def on_domain_pre_deleted(self, event, vm):
assignment.ident for assignment in assignments)
raise qubes.exc.QubesVMInUseError(
vm,
'VM has devices attached persistently to other VMs: ' +
'VM has devices attached persistently to other VMs: ' + # TODO
desc)

@qubes.events.handler('domain-delete')
Expand Down Expand Up @@ -1564,7 +1564,7 @@ def on_property_set_default_netvm(self, event, name, newvalue,
if hasattr(vm, 'provides_network') and not vm.provides_network and \
hasattr(vm, 'netvm') and vm.property_is_default('netvm'):
# fire property-reset:netvm as it is responsible for resetting
# netvm to it's default value
# netvm to its default value
vm.fire_event('property-reset:netvm',
name='netvm', oldvalue=oldvalue)

Expand All @@ -1576,6 +1576,6 @@ def on_property_set_default_dispvm(self, event, name, newvalue,
if hasattr(vm, 'default_dispvm') and \
vm.property_is_default('default_dispvm'):
# fire property-reset:default_dispvm as it is responsible for
# resetting dispvm to it's default value
# resetting dispvm to its default value
vm.fire_event('property-reset:default_dispvm',
name='default_dispvm', oldvalue=oldvalue)
Loading

0 comments on commit 14e431f

Please sign in to comment.