events: add support for wildcard event handlers

Port 5a39e777089d8bde6d0a620830a898c1cf3dd924 ("events: add support for
wildcard event handlers") from qubes-core-admin:

    Support registering handlers for more flexible wildcard events: not only
    '*', but also 'something*'. This allows to register handlers for
    'property-set:*' and such.
This commit is contained in:
Marek Marczykowski-Górecki 2018-09-07 18:59:05 +02:00
parent 045bad13e7
commit fe73313da1
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
2 changed files with 22 additions and 3 deletions

View File

@ -21,6 +21,7 @@
'''Event handling implementation, require Python >=3.5.2 for asyncio.'''
import asyncio
import fnmatch
import subprocess
import qubesadmin.config
@ -200,7 +201,8 @@ class EventsDispatcher(object):
if event in ['domain-add', 'domain-delete']:
self.app.domains.clear_cache()
subject = None
for handler in self.handlers.get(event, []):
handler(subject, event, **kwargs)
for handler in self.handlers.get('*', []):
handlers = [h_func for h_name, h_func_set in self.handlers.items()
for h_func in h_func_set
if fnmatch.fnmatch(event, h_name)]
for handler in handlers:
handler(subject, event, **kwargs)

View File

@ -79,6 +79,23 @@ class TC_00_Events(qubesadmin.tests.QubesTestCase):
self.dispatcher.handle('', 'some-event', arg1='value1')
self.assertFalse(handler.called)
def test_002_handler_glob_partial(self):
handler = unittest.mock.Mock()
self.dispatcher.add_handler('some-*', handler)
self.dispatcher.handle('', 'some-event', arg1='value1')
handler.assert_called_once_with(None, 'some-event', arg1='value1')
handler.reset_mock()
self.dispatcher.handle('test-vm', 'some-event', arg1='value1')
handler.assert_called_once_with(
self.app.domains.get_blind('test-vm'), 'some-event', arg1='value1')
handler.reset_mock()
self.dispatcher.handle('', 'other-event', arg1='value1')
self.assertFalse(handler.called)
handler.reset_mock()
self.dispatcher.remove_handler('some-*', handler)
self.dispatcher.handle('', 'some-event', arg1='value1')
self.assertFalse(handler.called)
@asyncio.coroutine
def mock_get_events_reader(self, stream, cleanup_func, expected_vm,
vm=None):