Browse Source

vm: include tag/feature name in event name

Rename events:
 - domain-feature-set -> domain-feature-set:feature
 - domain-feature-delete -> domain-feature-delete:feature
 - domain-tag-add -> domain-tag-add:tag
 - domain-tag-delete -> domain-tag-delete:tag

Make it consistent with property-* events. It makes more sense to
include tag/feature name in event name, so handler can watch a single
tag/feature - which is the most common case. Otherwise, most handlers
would begin with `if feature == '...'` anyway, wasting time on most
events.

In cases where multiple features/tags should be handled by a single
handler, it is now possible to register a handler with wildcard, for
example `domain-feature-set:*`.
Marek Marczykowski-Górecki 6 years ago
parent
commit
50d34755fa
4 changed files with 42 additions and 38 deletions
  1. 2 2
      qubes/ext/services.py
  2. 21 20
      qubes/tests/vm/init.py
  3. 7 6
      qubes/vm/__init__.py
  4. 12 10
      qubes/vm/qubesvm.py

+ 2 - 2
qubes/ext/services.py

@@ -39,7 +39,7 @@ class ServicesExtension(qubes.ext.Extension):
             vm.untrusted_qdb.write('/qubes-service/{}'.format(service),
                 str(int(bool(value))))
 
-    @qubes.ext.handler('domain-feature-set')
+    @qubes.ext.handler('domain-feature-set:*')
     def on_domain_feature_set(self, vm, event, feature, value, oldvalue=None):
         '''Update /qubes-service/ QubesDB tree in runtime'''
         # pylint: disable=unused-argument
@@ -52,7 +52,7 @@ class ServicesExtension(qubes.ext.Extension):
         vm.untrusted_qdb.write('/qubes-service/{}'.format(service),
             str(int(bool(value))))
 
-    @qubes.ext.handler('domain-feature-delete')
+    @qubes.ext.handler('domain-feature-delete:*')
     def on_domain_feature_delete(self, vm, event, feature):
         '''Update /qubes-service/ QubesDB tree in runtime'''
         # pylint: disable=unused-argument

+ 21 - 20
qubes/tests/vm/init.py

@@ -155,37 +155,37 @@ class TC_20_Tags(qubes.tests.QubesTestCase):
 
     def test_000_add(self):
         self.tags.add('testtag')
-        self.assertEventFired(self.vm, 'domain-tag-add',
+        self.assertEventFired(self.vm, 'domain-tag-add:testtag',
             kwargs={'tag': 'testtag'})
 
     def test_001_add_existing(self):
         self.tags.add('testtag')
         self.vm.fired_events.clear()
         self.tags.add('testtag')
-        self.assertEventNotFired(self.vm, 'domain-tag-add')
+        self.assertEventNotFired(self.vm, 'domain-tag-add:testtag')
 
     def test_002_remove(self):
         self.tags.add('testtag')
         self.vm.fired_events.clear()
         self.tags.remove('testtag')
-        self.assertEventFired(self.vm, 'domain-tag-delete',
+        self.assertEventFired(self.vm, 'domain-tag-delete:testtag',
             kwargs={'tag': 'testtag'})
 
     def test_003_remove_not_present(self):
         with self.assertRaises(KeyError):
             self.tags.remove('testtag')
-        self.assertEventNotFired(self.vm, 'domain-tag-delete')
+        self.assertEventNotFired(self.vm, 'domain-tag-delete:testtag')
 
     def test_004_discard_not_present(self):
         with self.assertNotRaises(KeyError):
             self.tags.discard('testtag')
-        self.assertEventNotFired(self.vm, 'domain-tag-delete')
+        self.assertEventNotFired(self.vm, 'domain-tag-delete:testtag')
 
     def test_005_discard_present(self):
         self.tags.add('testtag')
         with self.assertNotRaises(KeyError):
             self.tags.discard('testtag')
-        self.assertEventFired(self.vm, 'domain-tag-delete',
+        self.assertEventFired(self.vm, 'domain-tag-delete:testtag',
             kwargs={'tag': 'testtag'})
 
     def test_006_clear(self):
@@ -193,9 +193,9 @@ class TC_20_Tags(qubes.tests.QubesTestCase):
         self.tags.add('testtag2')
         self.vm.fired_events.clear()
         self.tags.clear()
-        self.assertEventFired(self.vm, 'domain-tag-delete',
+        self.assertEventFired(self.vm, 'domain-tag-delete:testtag',
             kwargs={'tag': 'testtag'})
-        self.assertEventFired(self.vm, 'domain-tag-delete',
+        self.assertEventFired(self.vm, 'domain-tag-delete:testtag2',
             kwargs={'tag': 'testtag2'})
 
     def test_007_update(self):
@@ -203,9 +203,9 @@ class TC_20_Tags(qubes.tests.QubesTestCase):
         self.tags.add('testtag2')
         self.vm.fired_events.clear()
         self.tags.update(('testtag2', 'testtag3'))
-        self.assertEventFired(self.vm, 'domain-tag-add',
+        self.assertEventFired(self.vm, 'domain-tag-add:testtag3',
             kwargs={'tag': 'testtag3'})
-        self.assertEventNotFired(self.vm, 'domain-tag-add',
+        self.assertEventNotFired(self.vm, 'domain-tag-add:testtag2',
             kwargs={'tag': 'testtag2'})
 
 
@@ -217,14 +217,14 @@ class TC_21_Features(qubes.tests.QubesTestCase):
 
     def test_000_set(self):
         self.features['testfeature'] = 'value'
-        self.assertEventFired(self.vm, 'domain-feature-set',
+        self.assertEventFired(self.vm, 'domain-feature-set:testfeature',
             kwargs={'feature': 'testfeature', 'value': 'value'})
 
     def test_001_set_existing(self):
         self.features['test'] = 'oldvalue'
         self.vm.fired_events.clear()
         self.features['test'] = 'value'
-        self.assertEventFired(self.vm, 'domain-feature-set',
+        self.assertEventFired(self.vm, 'domain-feature-set:test',
             kwargs={'feature': 'test', 'value': 'value', 'oldvalue':
                 'oldvalue'})
 
@@ -232,29 +232,30 @@ class TC_21_Features(qubes.tests.QubesTestCase):
         self.features['test'] = 'value'
         self.vm.fired_events.clear()
         del self.features['test']
-        self.assertEventFired(self.vm, 'domain-feature-delete',
+        self.assertEventFired(self.vm, 'domain-feature-delete:test',
             kwargs={'feature': 'test'})
 
     def test_003_unset_not_present(self):
         with self.assertRaises(KeyError):
             del self.features['test']
         self.assertEventNotFired(self.vm, 'domain-feature-delete')
+        self.assertEventNotFired(self.vm, 'domain-feature-delete:test')
 
     def test_004_set_bool_true(self):
         self.features['test'] = True
         self.assertTrue(self.features['test'])
-        self.assertEventFired(self.vm, 'domain-feature-set',
+        self.assertEventFired(self.vm, 'domain-feature-set:test',
             kwargs={'feature': 'test', 'value': '1'})
 
     def test_005_set_bool_false(self):
         self.features['test'] = False
         self.assertFalse(self.features['test'])
-        self.assertEventFired(self.vm, 'domain-feature-set',
+        self.assertEventFired(self.vm, 'domain-feature-set:test',
             kwargs={'feature': 'test', 'value': ''})
 
     def test_006_set_int(self):
         self.features['test'] = 123
-        self.assertEventFired(self.vm, 'domain-feature-set',
+        self.assertEventFired(self.vm, 'domain-feature-set:test',
             kwargs={'feature': 'test', 'value': '123'})
 
     def test_007_clear(self):
@@ -262,9 +263,9 @@ class TC_21_Features(qubes.tests.QubesTestCase):
         self.features['test2'] = 'value2'
         self.vm.fired_events.clear()
         self.features.clear()
-        self.assertEventFired(self.vm, 'domain-feature-delete',
+        self.assertEventFired(self.vm, 'domain-feature-delete:test',
             kwargs={'feature': 'test'})
-        self.assertEventFired(self.vm, 'domain-feature-delete',
+        self.assertEventFired(self.vm, 'domain-feature-delete:test2',
             kwargs={'feature': 'test2'})
 
     def test_008_update(self):
@@ -275,8 +276,8 @@ class TC_21_Features(qubes.tests.QubesTestCase):
         self.assertEqual(self.features['test2'], 'value3')
         self.assertEqual(self.features['test3'], 'value4')
         self.assertEqual(self.features['test'], 'value')
-        self.assertEventFired(self.vm, 'domain-feature-set',
+        self.assertEventFired(self.vm, 'domain-feature-set:test2',
             kwargs={'feature': 'test2', 'value': 'value3',
                 'oldvalue': 'value2'})
-        self.assertEventFired(self.vm, 'domain-feature-set',
+        self.assertEventFired(self.vm, 'domain-feature-set:test3',
             kwargs={'feature': 'test3', 'value': 'value4'})

+ 7 - 6
qubes/vm/__init__.py

@@ -113,7 +113,7 @@ class Features(dict):
 
     def __delitem__(self, key):
         super(Features, self).__delitem__(key)
-        self.vm.fire_event('domain-feature-delete', feature=key)
+        self.vm.fire_event('domain-feature-delete:' + key, feature=key)
 
     def __setitem__(self, key, value):
         if value is None or isinstance(value, bool):
@@ -127,10 +127,11 @@ class Features(dict):
             has_oldvalue = False
         super(Features, self).__setitem__(key, value)
         if has_oldvalue:
-            self.vm.fire_event('domain-feature-set', feature=key, value=value,
-                oldvalue=oldvalue)
+            self.vm.fire_event('domain-feature-set:' + key, feature=key,
+                value=value, oldvalue=oldvalue)
         else:
-            self.vm.fire_event('domain-feature-set', feature=key, value=value)
+            self.vm.fire_event('domain-feature-set:' + key, feature=key,
+                value=value)
 
     def clear(self):
         for key in tuple(self):
@@ -265,12 +266,12 @@ class Tags(set):
         if elem in self:
             return
         super(Tags, self).add(elem)
-        self.vm.fire_event('domain-tag-add', tag=elem)
+        self.vm.fire_event('domain-tag-add:' + elem, tag=elem)
 
     def remove(self, elem):
         '''Remove a tag'''
         super(Tags, self).remove(elem)
-        self.vm.fire_event('domain-tag-delete', tag=elem)
+        self.vm.fire_event('domain-tag-delete:' + elem, tag=elem)
 
     #
     # end of overriding

+ 12 - 10
qubes/vm/qubesvm.py

@@ -292,40 +292,42 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
             :param subject: Event emitter (the qube object)
             :param event: Event name (``'domain-restore'``)
 
-        .. event:: domain-feature-set (subject, event, feature, value
+        .. event:: domain-feature-set:feature (subject, event, feature, value
             [, oldvalue])
 
-            A feature was changed.
+            A feature was changed. This event is fired before bare
+            `domain-feature-set` event.
             *oldvalue* is present only when there was any.
 
             :param subject: Event emitter (the qube object)
-            :param event: Event name (``'domain-feature-set'``)
+            :param event: Event name (``'domain-feature-set:' feature``)
             :param feature: feature name
             :param value: new value
             :param oldvalue: old value, if any
 
-        .. event:: domain-feature-delete (subject, event, feature)
+        .. event:: domain-feature-delete:feature (subject, event, feature)
 
-            A feature was removed.
+            A feature was removed. This event is fired before bare
+            `domain-feature-delete` event.
 
             :param subject: Event emitter (the qube object)
-            :param event: Event name (``'domain-feature-delete'``)
+            :param event: Event name (``'domain-feature-delete:' feature``)
             :param feature: feature name
 
-        .. event:: domain-tag-add (subject, event, tag)
+        .. event:: domain-tag-add:tag (subject, event, tag)
 
             A tag was added.
 
             :param subject: Event emitter (the qube object)
-            :param event: Event name (``'domain-tag-add'``)
+            :param event: Event name (``'domain-tag-add:' tag``)
             :param tag: tag name
 
-        .. event:: domain-tag-delete (subject, event, tag)
+        .. event:: domain-tag-delete:tag (subject, event, tag)
 
             A feature was removed.
 
             :param subject: Event emitter (the qube object)
-            :param event: Event name (``'domain-tag-delete'``)
+            :param event: Event name (``'domain-tag-delete:' tag``)
             :param tag: tag name
 
         .. event:: feature-request (subject, event, *, untrusted_features)