events: merge fire_event and fire_event_pre functions
Those functions really do very similar things - lets merge them and add simple parameter.
This commit is contained in:
parent
aed6de4937
commit
6238254f49
@ -22,10 +22,10 @@ parent class and then for it's child. For each class, first are called handlers
|
||||
defined in it's source, then handlers from extensions and last the callers added
|
||||
manually.
|
||||
|
||||
There is second method, :py:meth:`qubes.events.Emitter.fire_event_pre`, which
|
||||
fires events in reverse order. It is suitable for events fired before some
|
||||
action is performed. You may at your own responsibility raise exceptions from
|
||||
such events to try to prevent such action.
|
||||
The :py:meth:`qubes.events.Emitter.fire_event` method have keyword argument
|
||||
`pre_event`, which fires events in reverse order. It is suitable for events
|
||||
fired before some action is performed. You may at your own responsibility raise
|
||||
exceptions from such events to try to prevent such action.
|
||||
|
||||
Events handlers may yield values. Those values are aggregated and returned
|
||||
to the caller as a list of those values. See below for details.
|
||||
|
@ -250,10 +250,12 @@ class property(object): # pylint: disable=redefined-builtin,invalid-name
|
||||
value = self.type(value)
|
||||
|
||||
if has_oldvalue:
|
||||
instance.fire_event_pre('property-pre-set:' + self.__name__,
|
||||
instance.fire_event('property-pre-set:' + self.__name__,
|
||||
pre_event=True,
|
||||
name=self.__name__, newvalue=value, oldvalue=oldvalue)
|
||||
else:
|
||||
instance.fire_event_pre('property-pre-set:' + self.__name__,
|
||||
instance.fire_event('property-pre-set:' + self.__name__,
|
||||
pre_event=True,
|
||||
name=self.__name__, newvalue=value)
|
||||
|
||||
instance._property_init(self, value) # pylint: disable=protected-access
|
||||
@ -276,14 +278,16 @@ class property(object): # pylint: disable=redefined-builtin,invalid-name
|
||||
has_oldvalue = False
|
||||
|
||||
if has_oldvalue:
|
||||
instance.fire_event_pre('property-pre-del:' + self.__name__,
|
||||
instance.fire_event('property-pre-del:' + self.__name__,
|
||||
pre_event=True,
|
||||
name=self.__name__, oldvalue=oldvalue)
|
||||
delattr(instance, self._attr_name)
|
||||
instance.fire_event('property-del:' + self.__name__,
|
||||
name=self.__name__, oldvalue=oldvalue)
|
||||
|
||||
else:
|
||||
instance.fire_event_pre('property-pre-del:' + self.__name__,
|
||||
instance.fire_event('property-pre-del:' + self.__name__,
|
||||
pre_event=True,
|
||||
name=self.__name__)
|
||||
instance.fire_event('property-del:' + self.__name__,
|
||||
name=self.__name__)
|
||||
|
@ -181,8 +181,8 @@ class AbstractQubesAPI(object):
|
||||
|
||||
def fire_event_for_permission(self, **kwargs):
|
||||
'''Fire an event on the source qube to check for permission'''
|
||||
return self.src.fire_event_pre('mgmt-permission:' + self.method,
|
||||
dest=self.dest, arg=self.arg, **kwargs)
|
||||
return self.src.fire_event('mgmt-permission:' + self.method,
|
||||
pre_event=True, dest=self.dest, arg=self.arg, **kwargs)
|
||||
|
||||
def fire_event_for_filter(self, iterable, **kwargs):
|
||||
'''Fire an event on the source qube to filter for permission'''
|
||||
|
@ -476,7 +476,7 @@ class VMCollection(object):
|
||||
vm = self[key]
|
||||
if not vm.is_halted():
|
||||
raise qubes.exc.QubesVMNotHaltedError(vm)
|
||||
self.app.fire_event_pre('domain-pre-delete', vm=vm)
|
||||
self.app.fire_event('domain-pre-delete', pre_event=True, vm=vm)
|
||||
try:
|
||||
vm.libvirt_domain.undefine()
|
||||
except libvirt.libvirtError as e:
|
||||
|
@ -180,7 +180,7 @@ class DeviceCollection(object):
|
||||
raise DeviceAlreadyAttached(
|
||||
'device {!s} of class {} already attached to {!s}'.format(
|
||||
device, self._bus, self._vm))
|
||||
self._vm.fire_event_pre('device-pre-attach:'+self._bus,
|
||||
self._vm.fire_event('device-pre-attach:'+self._bus, pre_event=True,
|
||||
device=device, options=device_assignment.options)
|
||||
if device_assignment.persistent:
|
||||
self._set.add(device_assignment)
|
||||
@ -208,7 +208,8 @@ class DeviceCollection(object):
|
||||
device_assignment.ident, self._bus, self._vm))
|
||||
|
||||
device = device_assignment.device
|
||||
self._vm.fire_event_pre('device-pre-detach:'+self._bus, device=device)
|
||||
self._vm.fire_event('device-pre-detach:' + self._bus,
|
||||
pre_event=True, device=device)
|
||||
if device in self._set:
|
||||
device_assignment.persistent = True
|
||||
self._set.discard(device_assignment)
|
||||
|
@ -134,16 +134,19 @@ class Emitter(object, metaclass=EmitterMeta):
|
||||
# pylint: disable=no-member
|
||||
self.__handlers__[event].remove(func)
|
||||
|
||||
def _fire_event_in_order(self, order, event, kwargs):
|
||||
def _fire_event(self, event, kwargs, pre_event=False):
|
||||
'''Fire event for classes in given order.
|
||||
|
||||
Do not use this method. Use :py:meth:`fire_event` or
|
||||
:py:meth:`fire_event_pre`.
|
||||
Do not use this method. Use :py:meth:`fire_event`.
|
||||
'''
|
||||
|
||||
if not self.events_enabled:
|
||||
return []
|
||||
|
||||
order = itertools.chain((self,), self.__class__.__mro__)
|
||||
if not pre_event:
|
||||
order = reversed(list(order))
|
||||
|
||||
effects = []
|
||||
for i in order:
|
||||
try:
|
||||
@ -161,46 +164,21 @@ class Emitter(object, metaclass=EmitterMeta):
|
||||
effects.extend(effect)
|
||||
return effects
|
||||
|
||||
def fire_event(self, event, **kwargs):
|
||||
def fire_event(self, event, pre_event=False, **kwargs):
|
||||
'''Call all handlers for an event.
|
||||
|
||||
Handlers are called for class and all parent classes, in **reversed**
|
||||
or **true** (depending on *pre_event* parameter)
|
||||
method resolution order. For each class first are called bound handlers
|
||||
(specified in class definition), then handlers from extensions. Aside
|
||||
from above, remaining order is undefined.
|
||||
|
||||
.. seealso::
|
||||
:py:meth:`fire_event_pre`
|
||||
|
||||
:param str event: event identifier
|
||||
:param pre_event: is this -pre- event? reverse handlers calling order
|
||||
:returns: list of effects
|
||||
|
||||
All *kwargs* are passed verbatim. They are different for different
|
||||
events.
|
||||
'''
|
||||
|
||||
return self._fire_event_in_order(
|
||||
itertools.chain(reversed(self.__class__.__mro__), (self,)),
|
||||
event, kwargs)
|
||||
|
||||
|
||||
def fire_event_pre(self, event, **kwargs):
|
||||
'''Call all handlers for an event.
|
||||
|
||||
Handlers are called for class and all parent classes, in **true**
|
||||
method resolution order. This is intended for ``-pre-`` events, where
|
||||
order of invocation should be reversed.
|
||||
|
||||
.. seealso::
|
||||
:py:meth:`fire_event`
|
||||
|
||||
:param str event: event identifier
|
||||
:returns: list of effects
|
||||
|
||||
All *kwargs* are passed verbatim. They are different for different
|
||||
events.
|
||||
'''
|
||||
|
||||
return self._fire_event_in_order(
|
||||
itertools.chain((self,), self.__class__.__mro__),
|
||||
event, kwargs)
|
||||
return self._fire_event(event, kwargs, pre_event=pre_event)
|
||||
|
@ -159,17 +159,6 @@ class TestEmitter(qubes.events.Emitter):
|
||||
self.fired_events[(event, ev_kwargs)] += 1
|
||||
return effects
|
||||
|
||||
def fire_event_pre(self, event, **kwargs):
|
||||
effects = super(TestEmitter, self).fire_event_pre(event, **kwargs)
|
||||
ev_kwargs = frozenset(
|
||||
(key,
|
||||
frozenset(value.items()) if isinstance(value, dict)
|
||||
else tuple(value) if isinstance(value, list)
|
||||
else value)
|
||||
for key, value in kwargs.items()
|
||||
)
|
||||
self.fired_events[(event, ev_kwargs)] += 1
|
||||
return effects
|
||||
|
||||
def expectedFailureIfTemplate(templates):
|
||||
"""
|
||||
|
@ -76,7 +76,6 @@ class AdminAPITestCase(qubes.tests.QubesTestCase):
|
||||
|
||||
self.emitter = qubes.tests.TestEmitter()
|
||||
self.app.domains[0].fire_event = self.emitter.fire_event
|
||||
self.app.domains[0].fire_event_pre = self.emitter.fire_event_pre
|
||||
|
||||
def tearDown(self):
|
||||
self.base_dir_patch2.stop()
|
||||
@ -1793,8 +1792,6 @@ class TC_00_VMs(AdminAPITestCase):
|
||||
def test_590_firewall_reload(self):
|
||||
self.vm.firewall.save = unittest.mock.Mock()
|
||||
self.app.domains['test-vm1'].fire_event = self.emitter.fire_event
|
||||
self.app.domains['test-vm1'].fire_event_pre = \
|
||||
self.emitter.fire_event_pre
|
||||
value = self.call_mgmt_func(b'admin.vm.firewall.Reload',
|
||||
b'test-vm1', b'')
|
||||
self.assertIsNone(value)
|
||||
|
@ -73,7 +73,6 @@ class TC_00_Emitter(qubes.tests.QubesTestCase):
|
||||
|
||||
emitter = TestEmitter()
|
||||
emitter.events_enabled = True
|
||||
emitter.fire_event('testevent')
|
||||
|
||||
effect = emitter.fire_event('testevent')
|
||||
|
||||
@ -129,8 +128,8 @@ class TC_00_Emitter(qubes.tests.QubesTestCase):
|
||||
['testevent_1'])
|
||||
|
||||
with self.subTest('fire_event_pre'):
|
||||
effect = emitter.fire_event_pre('testevent')
|
||||
effect2 = emitter2.fire_event_pre('testevent')
|
||||
effect = emitter.fire_event('testevent', pre_event=True)
|
||||
effect2 = emitter2.fire_event('testevent', pre_event=True)
|
||||
self.assertEqual(list(effect),
|
||||
['testevent_2', 'testevent_1'])
|
||||
self.assertEqual(list(effect2),
|
||||
|
@ -847,7 +847,8 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
||||
|
||||
self.log.info('Starting {}'.format(self.name))
|
||||
|
||||
self.fire_event_pre('domain-pre-start',
|
||||
self.fire_event('domain-pre-start',
|
||||
pre_event=True,
|
||||
start_guid=start_guid, mem_required=mem_required)
|
||||
|
||||
yield from self.storage.verify()
|
||||
@ -935,7 +936,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
||||
if self.is_halted():
|
||||
raise qubes.exc.QubesVMNotStartedError(self)
|
||||
|
||||
self.fire_event_pre('domain-pre-shutdown', force=force)
|
||||
self.fire_event('domain-pre-shutdown', pre_event=True, force=force)
|
||||
|
||||
self.libvirt_domain.shutdown()
|
||||
|
||||
@ -1071,7 +1072,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
||||
raise qubes.exc.QubesVMError(
|
||||
self, 'Domain {!r}: qrexec not connected'.format(self.name))
|
||||
|
||||
self.fire_event_pre('domain-cmd-pre-run', start_guid=gui)
|
||||
self.fire_event('domain-cmd-pre-run', pre_event=True, start_guid=gui)
|
||||
|
||||
return (yield from asyncio.create_subprocess_exec(
|
||||
qubes.config.system_path['qrexec_client_path'],
|
||||
|
Loading…
Reference in New Issue
Block a user