diff --git a/qubes/api/misc.py b/qubes/api/misc.py index c8d2bb5c..50652e3c 100644 --- a/qubes/api/misc.py +++ b/qubes/api/misc.py @@ -61,7 +61,7 @@ class QubesMiscAPI(qubes.api.AbstractQubesAPI): untrusted_value = untrusted_features[untrusted_key] 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) self.app.save() @@ -87,7 +87,7 @@ class QubesMiscAPI(qubes.api.AbstractQubesAPI): untrusted_features[feature] = untrusted_value del untrusted_value - self.src.fire_event('features-request', + yield from self.src.fire_event_async('features-request', untrusted_features=untrusted_features) self.app.save() diff --git a/qubes/tests/api_misc.py b/qubes/tests/api_misc.py index 093c11c3..b7ffc9a0 100644 --- a/qubes/tests/api_misc.py +++ b/qubes/tests/api_misc.py @@ -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/feature2'), mock.call.untrusted_qdb.read('/features-request/feature3'), - mock.call.fire_event('features-request', untrusted_features={ - 'feature1': '1', 'feature2': '', 'feature3': 'other'}) + mock.call.fire_event_async('features-request', untrusted_features={ + 'feature1': '1', 'feature2': '', 'feature3': 'other'}), + ('fire_event_async().__iter__', (), {}), ]) 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, [ 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): @@ -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/gui'), 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', 'default-user': 'user', 'qrexec': '1'}), + ('fire_event_async().__iter__', (), {}), ]) 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/gui'), 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', 'default-user': 'user', 'qrexec': '1'}), + ('fire_event_async().__iter__', (), {}), ]) self.assertEqual(self.app.mock_calls, [mock.call.save()]) diff --git a/qubes/vm/qubesvm.py b/qubes/vm/qubesvm.py index 7fc743fa..f5f67b53 100644 --- a/qubes/vm/qubesvm.py +++ b/qubes/vm/qubesvm.py @@ -334,12 +334,12 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM): :param event: Event name (``'domain-tag-delete:' tag``) :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 event: Event name (``'feature-request'``) + :param event: Event name (``'features-request'``) :param untrusted_features: :py:class:`dict` containing the feature \ 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 :py:attr:`features` with only minimal sanitisation. + Handler for this event can be asynchronous (a coroutine). + .. event:: firewall-changed (subject, event) Firewall was changed.