Explorar o código

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.
Marek Marczykowski-Górecki %!s(int64=6) %!d(string=hai) anos
pai
achega
7c4566ec14
Modificáronse 3 ficheiros con 17 adicións e 10 borrados
  1. 2 2
      qubes/api/misc.py
  2. 10 5
      qubes/tests/api_misc.py
  3. 5 3
      qubes/vm/qubesvm.py

+ 2 - 2
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()
 

+ 10 - 5
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()])
 

+ 5 - 3
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.