vm/qubesvm: allow 'features-request' to have async handlers
Some handlers may want to call into other VMs (or even the one asking), but vm.run() functions are coroutines, so needs to be called from another coroutine. Allow for that. Also fix typo in documentation.
This commit is contained in:
parent
5840dd76f9
commit
7c4566ec14
@ -61,7 +61,7 @@ class QubesMiscAPI(qubes.api.AbstractQubesAPI):
|
|||||||
untrusted_value = untrusted_features[untrusted_key]
|
untrusted_value = untrusted_features[untrusted_key]
|
||||||
assert all((c in safe_set) for c in untrusted_value)
|
assert all((c in safe_set) for c in untrusted_value)
|
||||||
|
|
||||||
self.src.fire_event('features-request',
|
yield from self.src.fire_event_async('features-request',
|
||||||
untrusted_features=untrusted_features)
|
untrusted_features=untrusted_features)
|
||||||
self.app.save()
|
self.app.save()
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ class QubesMiscAPI(qubes.api.AbstractQubesAPI):
|
|||||||
untrusted_features[feature] = untrusted_value
|
untrusted_features[feature] = untrusted_value
|
||||||
del untrusted_value
|
del untrusted_value
|
||||||
|
|
||||||
self.src.fire_event('features-request',
|
yield from self.src.fire_event_async('features-request',
|
||||||
untrusted_features=untrusted_features)
|
untrusted_features=untrusted_features)
|
||||||
self.app.save()
|
self.app.save()
|
||||||
|
|
||||||
|
@ -69,8 +69,9 @@ class TC_00_API_Misc(qubes.tests.QubesTestCase):
|
|||||||
mock.call.untrusted_qdb.read('/features-request/feature1'),
|
mock.call.untrusted_qdb.read('/features-request/feature1'),
|
||||||
mock.call.untrusted_qdb.read('/features-request/feature2'),
|
mock.call.untrusted_qdb.read('/features-request/feature2'),
|
||||||
mock.call.untrusted_qdb.read('/features-request/feature3'),
|
mock.call.untrusted_qdb.read('/features-request/feature3'),
|
||||||
mock.call.fire_event('features-request', untrusted_features={
|
mock.call.fire_event_async('features-request', untrusted_features={
|
||||||
'feature1': '1', 'feature2': '', 'feature3': 'other'})
|
'feature1': '1', 'feature2': '', 'feature3': 'other'}),
|
||||||
|
('fire_event_async().__iter__', (), {}),
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_001_features_request_empty(self):
|
def test_001_features_request_empty(self):
|
||||||
@ -82,7 +83,9 @@ class TC_00_API_Misc(qubes.tests.QubesTestCase):
|
|||||||
])
|
])
|
||||||
self.assertEqual(self.src.mock_calls, [
|
self.assertEqual(self.src.mock_calls, [
|
||||||
mock.call.untrusted_qdb.list('/features-request/'),
|
mock.call.untrusted_qdb.list('/features-request/'),
|
||||||
mock.call.fire_event('features-request', untrusted_features={})
|
mock.call.fire_event_async('features-request',
|
||||||
|
untrusted_features={}),
|
||||||
|
('fire_event_async().__iter__', (), {}),
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_002_features_request_invalid1(self):
|
def test_002_features_request_invalid1(self):
|
||||||
@ -129,10 +132,11 @@ class TC_00_API_Misc(qubes.tests.QubesTestCase):
|
|||||||
mock.call.untrusted_qdb.read('/qubes-tools/qrexec'),
|
mock.call.untrusted_qdb.read('/qubes-tools/qrexec'),
|
||||||
mock.call.untrusted_qdb.read('/qubes-tools/gui'),
|
mock.call.untrusted_qdb.read('/qubes-tools/gui'),
|
||||||
mock.call.untrusted_qdb.read('/qubes-tools/default-user'),
|
mock.call.untrusted_qdb.read('/qubes-tools/default-user'),
|
||||||
mock.call.fire_event('features-request', untrusted_features={
|
mock.call.fire_event_async('features-request', untrusted_features={
|
||||||
'gui': '1',
|
'gui': '1',
|
||||||
'default-user': 'user',
|
'default-user': 'user',
|
||||||
'qrexec': '1'}),
|
'qrexec': '1'}),
|
||||||
|
('fire_event_async().__iter__', (), {}),
|
||||||
])
|
])
|
||||||
self.assertEqual(self.app.mock_calls, [mock.call.save()])
|
self.assertEqual(self.app.mock_calls, [mock.call.save()])
|
||||||
|
|
||||||
@ -150,10 +154,11 @@ class TC_00_API_Misc(qubes.tests.QubesTestCase):
|
|||||||
mock.call.untrusted_qdb.read('/qubes-tools/qrexec'),
|
mock.call.untrusted_qdb.read('/qubes-tools/qrexec'),
|
||||||
mock.call.untrusted_qdb.read('/qubes-tools/gui'),
|
mock.call.untrusted_qdb.read('/qubes-tools/gui'),
|
||||||
mock.call.untrusted_qdb.read('/qubes-tools/default-user'),
|
mock.call.untrusted_qdb.read('/qubes-tools/default-user'),
|
||||||
mock.call.fire_event('features-request', untrusted_features={
|
mock.call.fire_event_async('features-request', untrusted_features={
|
||||||
'gui': '1',
|
'gui': '1',
|
||||||
'default-user': 'user',
|
'default-user': 'user',
|
||||||
'qrexec': '1'}),
|
'qrexec': '1'}),
|
||||||
|
('fire_event_async().__iter__', (), {}),
|
||||||
])
|
])
|
||||||
self.assertEqual(self.app.mock_calls, [mock.call.save()])
|
self.assertEqual(self.app.mock_calls, [mock.call.save()])
|
||||||
|
|
||||||
|
@ -334,12 +334,12 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
:param event: Event name (``'domain-tag-delete:' tag``)
|
:param event: Event name (``'domain-tag-delete:' tag``)
|
||||||
:param tag: tag name
|
:param tag: tag name
|
||||||
|
|
||||||
.. event:: feature-request (subject, event, *, untrusted_features)
|
.. event:: features-request (subject, event, *, untrusted_features)
|
||||||
|
|
||||||
The domain is performing a feature request.
|
The domain is performing a features request.
|
||||||
|
|
||||||
:param subject: Event emitter (the qube object)
|
:param subject: Event emitter (the qube object)
|
||||||
:param event: Event name (``'feature-request'``)
|
:param event: Event name (``'features-request'``)
|
||||||
:param untrusted_features: :py:class:`dict` containing the feature \
|
:param untrusted_features: :py:class:`dict` containing the feature \
|
||||||
request
|
request
|
||||||
|
|
||||||
@ -351,6 +351,8 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
ranging from plainly ignoring the request to verbatim copy into
|
ranging from plainly ignoring the request to verbatim copy into
|
||||||
:py:attr:`features` with only minimal sanitisation.
|
:py:attr:`features` with only minimal sanitisation.
|
||||||
|
|
||||||
|
Handler for this event can be asynchronous (a coroutine).
|
||||||
|
|
||||||
.. event:: firewall-changed (subject, event)
|
.. event:: firewall-changed (subject, event)
|
||||||
|
|
||||||
Firewall was changed.
|
Firewall was changed.
|
||||||
|
Loading…
Reference in New Issue
Block a user