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