瀏覽代碼

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 6 年之前
父節點
當前提交
7c4566ec14
共有 3 個文件被更改,包括 17 次插入10 次删除
  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.