qubes/events: they accept only keyword arguments
Positional arguments are hereby deprecated, with immediate effect. QubesOS/qubes-issues#2622
This commit is contained in:
parent
48f10a79c9
commit
be53db4db9
@ -13,8 +13,9 @@ Firing events
|
|||||||
Events are fired by calling :py:meth:`qubes.events.Emitter.fire_event`. The
|
Events are fired by calling :py:meth:`qubes.events.Emitter.fire_event`. The
|
||||||
first argument is event name (a string). You can fire any event you wish, the
|
first argument is event name (a string). You can fire any event you wish, the
|
||||||
names are not checked in any way, however each class' documentation tells what
|
names are not checked in any way, however each class' documentation tells what
|
||||||
standard events will be fired on it. The rest of arguments are dependent on the
|
standard events will be fired on it. When firing an event, caller may specify
|
||||||
particular event in question -- they are passed as-is to handlers.
|
some optional keyword arguments. Those are dependent on the particular event in
|
||||||
|
question -- they are passed as-is to handlers.
|
||||||
|
|
||||||
Event handlers are fired in reverse method resolution order, that is, first for
|
Event handlers are fired in reverse method resolution order, that is, first for
|
||||||
parent class and then for it's child. For each class, first are called handlers
|
parent class and then for it's child. For each class, first are called handlers
|
||||||
|
@ -250,19 +250,19 @@ class property(object): # pylint: disable=redefined-builtin,invalid-name
|
|||||||
|
|
||||||
if has_oldvalue:
|
if has_oldvalue:
|
||||||
instance.fire_event_pre('property-pre-set:' + self.__name__,
|
instance.fire_event_pre('property-pre-set:' + self.__name__,
|
||||||
self.__name__, value, oldvalue)
|
name=self.__name__, newvalue=value, oldvalue=oldvalue)
|
||||||
else:
|
else:
|
||||||
instance.fire_event_pre('property-pre-set:' + self.__name__,
|
instance.fire_event_pre('property-pre-set:' + self.__name__,
|
||||||
self.__name__, value)
|
name=self.__name__, newvalue=value)
|
||||||
|
|
||||||
instance._property_init(self, value) # pylint: disable=protected-access
|
instance._property_init(self, value) # pylint: disable=protected-access
|
||||||
|
|
||||||
if has_oldvalue:
|
if has_oldvalue:
|
||||||
instance.fire_event('property-set:' + self.__name__, self.__name__,
|
instance.fire_event('property-set:' + self.__name__,
|
||||||
value, oldvalue)
|
name=self.__name__, newvalue=value, oldvalue=oldvalue)
|
||||||
else:
|
else:
|
||||||
instance.fire_event('property-set:' + self.__name__, self.__name__,
|
instance.fire_event('property-set:' + self.__name__,
|
||||||
value)
|
name=self.__name__, newvalue=value)
|
||||||
|
|
||||||
|
|
||||||
def __delete__(self, instance):
|
def __delete__(self, instance):
|
||||||
@ -276,16 +276,16 @@ class property(object): # pylint: disable=redefined-builtin,invalid-name
|
|||||||
|
|
||||||
if has_oldvalue:
|
if has_oldvalue:
|
||||||
instance.fire_event_pre('property-pre-del:' + self.__name__,
|
instance.fire_event_pre('property-pre-del:' + self.__name__,
|
||||||
self.__name__, 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__,
|
||||||
self.__name__, oldvalue)
|
name=self.__name__, oldvalue=oldvalue)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
instance.fire_event_pre('property-pre-del:' + self.__name__,
|
instance.fire_event_pre('property-pre-del:' + self.__name__,
|
||||||
self.__name__)
|
name=self.__name__)
|
||||||
instance.fire_event('property-del:' + self.__name__,
|
instance.fire_event('property-del:' + self.__name__,
|
||||||
self.__name__)
|
name=self.__name__)
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
@ -601,7 +601,7 @@ class PropertyHolder(qubes.events.Emitter):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.fire_event('clone-properties', src, proplist)
|
self.fire_event('clone-properties', src=src, proplist=proplist)
|
||||||
|
|
||||||
|
|
||||||
def property_require(self, prop, allow_none=False, hard=False):
|
def property_require(self, prop, allow_none=False, hard=False):
|
||||||
|
12
qubes/app.py
12
qubes/app.py
@ -416,7 +416,7 @@ class VMCollection(object):
|
|||||||
self._dict[value.qid] = value
|
self._dict[value.qid] = value
|
||||||
if _enable_events:
|
if _enable_events:
|
||||||
value.events_enabled = True
|
value.events_enabled = True
|
||||||
self.app.fire_event('domain-add', value)
|
self.app.fire_event('domain-add', vm=value)
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
@ -445,7 +445,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)
|
self.app.fire_event_pre('domain-pre-delete', vm=vm)
|
||||||
try:
|
try:
|
||||||
vm.libvirt_domain.undefine()
|
vm.libvirt_domain.undefine()
|
||||||
except libvirt.libvirtError as e:
|
except libvirt.libvirtError as e:
|
||||||
@ -453,7 +453,7 @@ class VMCollection(object):
|
|||||||
# already undefined
|
# already undefined
|
||||||
pass
|
pass
|
||||||
del self._dict[vm.qid]
|
del self._dict[vm.qid]
|
||||||
self.app.fire_event('domain-delete', vm)
|
self.app.fire_event('domain-delete', vm=vm)
|
||||||
|
|
||||||
def __contains__(self, key):
|
def __contains__(self, key):
|
||||||
return any((key == vm or key == vm.qid or key == vm.name)
|
return any((key == vm or key == vm.qid or key == vm.name)
|
||||||
@ -1074,7 +1074,8 @@ class Qubes(qubes.PropertyHolder):
|
|||||||
if not vm.provides_network and vm.property_is_default('netvm'):
|
if not vm.provides_network and vm.property_is_default('netvm'):
|
||||||
# fire property-del:netvm as it is responsible for resetting
|
# fire property-del:netvm as it is responsible for resetting
|
||||||
# netvm to it's default value
|
# netvm to it's default value
|
||||||
vm.fire_event('property-del:netvm', 'netvm', newvalue, oldvalue)
|
vm.fire_event('property-del:netvm',
|
||||||
|
name='netvm', newvalue=newvalue, oldvalue=oldvalue)
|
||||||
|
|
||||||
|
|
||||||
@qubes.events.handler('property-set:default_netvm')
|
@qubes.events.handler('property-set:default_netvm')
|
||||||
@ -1085,4 +1086,5 @@ class Qubes(qubes.PropertyHolder):
|
|||||||
if vm.provides_network and vm.property_is_default('netvm'):
|
if vm.provides_network and vm.property_is_default('netvm'):
|
||||||
# fire property-del:netvm as it is responsible for resetting
|
# fire property-del:netvm as it is responsible for resetting
|
||||||
# netvm to it's default value
|
# netvm to it's default value
|
||||||
vm.fire_event('property-del:netvm', 'netvm', oldvalue)
|
vm.fire_event('property-del:netvm',
|
||||||
|
name='netvm', oldvalue=oldvalue)
|
||||||
|
@ -130,10 +130,10 @@ class DeviceCollection(object):
|
|||||||
raise DeviceAlreadyAttached(
|
raise DeviceAlreadyAttached(
|
||||||
'device {!r} of class {} already attached to {!r}'.format(
|
'device {!r} of class {} already attached to {!r}'.format(
|
||||||
device, self._class, self._vm))
|
device, self._class, self._vm))
|
||||||
self._vm.fire_event_pre('device-pre-attach:' + self._class, device)
|
self._vm.fire_event_pre('device-pre-attach:'+self._class, device=device)
|
||||||
if persistent:
|
if persistent:
|
||||||
self._set.add(device)
|
self._set.add(device)
|
||||||
self._vm.fire_event('device-attach:' + self._class, device)
|
self._vm.fire_event('device-attach:' + self._class, device=device)
|
||||||
|
|
||||||
|
|
||||||
def detach(self, device, persistent=True):
|
def detach(self, device, persistent=True):
|
||||||
@ -146,10 +146,10 @@ class DeviceCollection(object):
|
|||||||
raise DeviceNotAttached(
|
raise DeviceNotAttached(
|
||||||
'device {!s} of class {} not attached to {!s}'.format(
|
'device {!s} of class {} not attached to {!s}'.format(
|
||||||
device, self._class, self._vm))
|
device, self._class, self._vm))
|
||||||
self._vm.fire_event_pre('device-pre-detach:' + self._class, device)
|
self._vm.fire_event_pre('device-pre-detach:'+self._class, device=device)
|
||||||
if persistent:
|
if persistent:
|
||||||
self._set.remove(device)
|
self._set.remove(device)
|
||||||
self._vm.fire_event('device-detach:' + self._class, device)
|
self._vm.fire_event('device-detach:' + self._class, device=device)
|
||||||
|
|
||||||
def attached(self, persistent=None):
|
def attached(self, persistent=None):
|
||||||
'''List devices which are (or may be) attached to this vm
|
'''List devices which are (or may be) attached to this vm
|
||||||
@ -212,7 +212,7 @@ class DeviceCollection(object):
|
|||||||
:raises AssertionError: when multiple devices with the same ident are
|
:raises AssertionError: when multiple devices with the same ident are
|
||||||
found
|
found
|
||||||
'''
|
'''
|
||||||
dev = self._vm.fire_event('device-get:' + self._class, ident)
|
dev = self._vm.fire_event('device-get:' + self._class, ident=ident)
|
||||||
if dev:
|
if dev:
|
||||||
assert len(dev) == 1
|
assert len(dev) == 1
|
||||||
return dev[0]
|
return dev[0]
|
||||||
|
@ -116,7 +116,7 @@ class Emitter(object, metaclass=EmitterMeta):
|
|||||||
cls.__handlers__[event].add(func)
|
cls.__handlers__[event].add(func)
|
||||||
|
|
||||||
|
|
||||||
def _fire_event_in_order(self, order, event, *args, **kwargs):
|
def _fire_event_in_order(self, order, event, kwargs):
|
||||||
'''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` or
|
||||||
@ -136,13 +136,13 @@ class Emitter(object, metaclass=EmitterMeta):
|
|||||||
for func in sorted(handlers,
|
for func in sorted(handlers,
|
||||||
key=(lambda handler: hasattr(handler, 'ha_bound')),
|
key=(lambda handler: hasattr(handler, 'ha_bound')),
|
||||||
reverse=True):
|
reverse=True):
|
||||||
effect = func(self, event, *args, **kwargs)
|
effect = func(self, event, **kwargs)
|
||||||
if effect is not None:
|
if effect is not None:
|
||||||
effects.extend(effect)
|
effects.extend(effect)
|
||||||
return effects
|
return effects
|
||||||
|
|
||||||
|
|
||||||
def fire_event(self, event, *args, **kwargs):
|
def fire_event(self, event, **kwargs):
|
||||||
'''Call all handlers for an event.
|
'''Call all handlers for an event.
|
||||||
|
|
||||||
Handlers are called for class and all parent classess, in **reversed**
|
Handlers are called for class and all parent classess, in **reversed**
|
||||||
@ -156,15 +156,15 @@ class Emitter(object, metaclass=EmitterMeta):
|
|||||||
:param str event: event identificator
|
:param str event: event identificator
|
||||||
:returns: list of effects
|
:returns: list of effects
|
||||||
|
|
||||||
All *args* and *kwargs* are passed verbatim. They are different for
|
All *kwargs* are passed verbatim. They are different for different
|
||||||
different events.
|
events.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
return self._fire_event_in_order(reversed(self.__class__.__mro__),
|
return self._fire_event_in_order(reversed(self.__class__.__mro__),
|
||||||
event, *args, **kwargs)
|
event, kwargs)
|
||||||
|
|
||||||
|
|
||||||
def fire_event_pre(self, event, *args, **kwargs):
|
def fire_event_pre(self, event, **kwargs):
|
||||||
'''Call all handlers for an event.
|
'''Call all handlers for an event.
|
||||||
|
|
||||||
Handlers are called for class and all parent classess, in **true**
|
Handlers are called for class and all parent classess, in **true**
|
||||||
@ -177,9 +177,9 @@ class Emitter(object, metaclass=EmitterMeta):
|
|||||||
:param str event: event identificator
|
:param str event: event identificator
|
||||||
:returns: list of effects
|
:returns: list of effects
|
||||||
|
|
||||||
All *args* and *kwargs* are passed verbatim. They are different for
|
All *kwargs* are passed verbatim. They are different for different
|
||||||
different events.
|
events.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
return self._fire_event_in_order(self.__class__.__mro__,
|
return self._fire_event_in_order(self.__class__.__mro__,
|
||||||
event, *args, **kwargs)
|
event, kwargs)
|
||||||
|
@ -263,21 +263,21 @@ class GUI(qubes.ext.Extension):
|
|||||||
|
|
||||||
|
|
||||||
@qubes.ext.handler('monitor-layout-change')
|
@qubes.ext.handler('monitor-layout-change')
|
||||||
def on_monitor_layout_change(self, vm, event, monitor_layout=None):
|
def on_monitor_layout_change(self, vm, event, layout=None):
|
||||||
# pylint: disable=no-self-use,unused-argument
|
# pylint: disable=no-self-use,unused-argument
|
||||||
if vm.features.check_with_template('no-monitor-layout', False) \
|
if vm.features.check_with_template('no-monitor-layout', False) \
|
||||||
or not vm.is_running():
|
or not vm.is_running():
|
||||||
return
|
return
|
||||||
|
|
||||||
if monitor_layout is None:
|
if layout is None:
|
||||||
monitor_layout = get_monitor_layout()
|
layout = get_monitor_layout()
|
||||||
if not monitor_layout:
|
if not layout:
|
||||||
return
|
return
|
||||||
|
|
||||||
pipe = vm.run('QUBESRPC qubes.SetMonitorLayout dom0',
|
pipe = vm.run('QUBESRPC qubes.SetMonitorLayout dom0',
|
||||||
passio_popen=True, wait=True)
|
passio_popen=True, wait=True)
|
||||||
|
|
||||||
pipe.stdin.write(''.join(monitor_layout))
|
pipe.stdin.write(''.join(layout))
|
||||||
pipe.stdin.close()
|
pipe.stdin.close()
|
||||||
pipe.wait()
|
pipe.wait()
|
||||||
|
|
||||||
|
@ -269,27 +269,31 @@ class Rule(qubes.PropertyHolder):
|
|||||||
|
|
||||||
# noinspection PyUnusedLocal
|
# noinspection PyUnusedLocal
|
||||||
@qubes.events.handler('property-pre-set:dstports')
|
@qubes.events.handler('property-pre-set:dstports')
|
||||||
def on_set_dstports(self, _event, _prop, _new_value, _old_value=None):
|
def on_set_dstports(self, event, name, newvalue, oldvalue=None):
|
||||||
|
# pylint: disable=unused-argument
|
||||||
if self.proto not in ('tcp', 'udp'):
|
if self.proto not in ('tcp', 'udp'):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'dstports valid only for \'tcp\' and \'udp\' protocols')
|
'dstports valid only for \'tcp\' and \'udp\' protocols')
|
||||||
|
|
||||||
# noinspection PyUnusedLocal
|
# noinspection PyUnusedLocal
|
||||||
@qubes.events.handler('property-pre-set:icmptype')
|
@qubes.events.handler('property-pre-set:icmptype')
|
||||||
def on_set_icmptype(self, _event, _prop, _new_value, _old_value=None):
|
def on_set_icmptype(self, event, name, newvalue, oldvalue=None):
|
||||||
|
# pylint: disable=unused-argument
|
||||||
if self.proto not in ('icmp',):
|
if self.proto not in ('icmp',):
|
||||||
raise ValueError('icmptype valid only for \'icmp\' protocol')
|
raise ValueError('icmptype valid only for \'icmp\' protocol')
|
||||||
|
|
||||||
# noinspection PyUnusedLocal
|
# noinspection PyUnusedLocal
|
||||||
@qubes.events.handler('property-set:proto')
|
@qubes.events.handler('property-set:proto')
|
||||||
def on_set_proto(self, _event, _prop, new_value, _old_value=None):
|
def on_set_proto(self, event, name, newvalue, oldvalue=None):
|
||||||
if new_value not in ('tcp', 'udp'):
|
# pylint: disable=unused-argument
|
||||||
|
if newvalue not in ('tcp', 'udp'):
|
||||||
self.dstports = qubes.property.DEFAULT
|
self.dstports = qubes.property.DEFAULT
|
||||||
if new_value not in ('icmp',):
|
if newvalue not in ('icmp',):
|
||||||
self.icmptype = qubes.property.DEFAULT
|
self.icmptype = qubes.property.DEFAULT
|
||||||
|
|
||||||
@qubes.events.handler('property-del:proto')
|
@qubes.events.handler('property-del:proto')
|
||||||
def on_del_proto(self, _event, _prop, _old_value):
|
def on_del_proto(self, event, name, oldvalue):
|
||||||
|
# pylint: disable=unused-argument
|
||||||
self.dstports = qubes.property.DEFAULT
|
self.dstports = qubes.property.DEFAULT
|
||||||
self.icmptype = qubes.property.DEFAULT
|
self.icmptype = qubes.property.DEFAULT
|
||||||
|
|
||||||
|
@ -110,13 +110,13 @@ class QubesMgmt(object):
|
|||||||
#
|
#
|
||||||
|
|
||||||
@not_in_api
|
@not_in_api
|
||||||
def fire_event_for_permission(self, *args, **kwargs):
|
def fire_event_for_permission(self, **kwargs):
|
||||||
return self.src.fire_event_pre('mgmt-permission:{}'.format(self.method),
|
return self.src.fire_event_pre('mgmt-permission:{}'.format(self.method),
|
||||||
self.dest, self.arg, *args, **kwargs)
|
self.dest, self.arg, **kwargs)
|
||||||
|
|
||||||
@not_in_api
|
@not_in_api
|
||||||
def fire_event_for_filter(self, iterable, *args, **kwargs):
|
def fire_event_for_filter(self, iterable, **kwargs):
|
||||||
for selector in self.fire_event_for_permission(*args, **kwargs):
|
for selector in self.fire_event_for_permission(**kwargs):
|
||||||
iterable = filter(selector, iterable)
|
iterable = filter(selector, iterable)
|
||||||
return iterable
|
return iterable
|
||||||
|
|
||||||
|
@ -142,8 +142,8 @@ class SystemState(object):
|
|||||||
if dom_name is not None:
|
if dom_name is not None:
|
||||||
try:
|
try:
|
||||||
qubes.Qubes().domains[str(dom_name)].fire_event(
|
qubes.Qubes().domains[str(dom_name)].fire_event(
|
||||||
'status:no-error', 'no-error',
|
'status:no-error', status='no-error',
|
||||||
slow_memset_react_msg)
|
msg=slow_memset_react_msg)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
self.domdict[i].slow_memset_react = False
|
self.domdict[i].slow_memset_react = False
|
||||||
@ -154,8 +154,8 @@ class SystemState(object):
|
|||||||
if dom_name is not None:
|
if dom_name is not None:
|
||||||
try:
|
try:
|
||||||
qubes.Qubes().domains[str(dom_name)].fire_event(
|
qubes.Qubes().domains[str(dom_name)].fire_event(
|
||||||
'status:no-error', 'no-error',
|
'status:no-error', status='no-error',
|
||||||
no_progress_msg)
|
msg=no_progress_msg)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
self.domdict[i].no_progress = False
|
self.domdict[i].no_progress = False
|
||||||
@ -345,8 +345,8 @@ class SystemState(object):
|
|||||||
try:
|
try:
|
||||||
qubes.Qubes().domains[str(
|
qubes.Qubes().domains[str(
|
||||||
dom_name)].fire_event(
|
dom_name)].fire_event(
|
||||||
'status:error', 'error',
|
'status:error', status='error',
|
||||||
no_progress_msg)
|
msg=no_progress_msg)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@ -361,8 +361,8 @@ class SystemState(object):
|
|||||||
try:
|
try:
|
||||||
qubes.Qubes().domains[str(
|
qubes.Qubes().domains[str(
|
||||||
dom_name)].fire_event(
|
dom_name)].fire_event(
|
||||||
'status:error', 'error',
|
'status:error', status='error',
|
||||||
slow_memset_react_msg)
|
msg=slow_memset_react_msg)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
self.mem_set(dom, self.get_free_xen_memory() + self.domdict[dom].memory_actual - self.XEN_FREE_MEM_LEFT)
|
self.mem_set(dom, self.get_free_xen_memory() + self.domdict[dom].memory_actual - self.XEN_FREE_MEM_LEFT)
|
||||||
|
@ -130,7 +130,7 @@ class TestEmitter(qubes.events.Emitter):
|
|||||||
>>> emitter = TestEmitter()
|
>>> emitter = TestEmitter()
|
||||||
>>> emitter.fired_events
|
>>> emitter.fired_events
|
||||||
Counter()
|
Counter()
|
||||||
>>> emitter.fire_event('event', 1, 2, 3, spam='eggs', foo='bar')
|
>>> emitter.fire_event('event', spam='eggs', foo='bar')
|
||||||
>>> emitter.fired_events
|
>>> emitter.fired_events
|
||||||
Counter({('event', (1, 2, 3), (('foo', 'bar'), ('spam', 'eggs'))): 1})
|
Counter({('event', (1, 2, 3), (('foo', 'bar'), ('spam', 'eggs'))): 1})
|
||||||
'''
|
'''
|
||||||
@ -141,15 +141,14 @@ class TestEmitter(qubes.events.Emitter):
|
|||||||
#: :py:class:`collections.Counter` instance
|
#: :py:class:`collections.Counter` instance
|
||||||
self.fired_events = collections.Counter()
|
self.fired_events = collections.Counter()
|
||||||
|
|
||||||
def fire_event(self, event, *args, **kwargs):
|
def fire_event(self, event, **kwargs):
|
||||||
effects = super(TestEmitter, self).fire_event(event, *args, **kwargs)
|
effects = super(TestEmitter, self).fire_event(event, **kwargs)
|
||||||
self.fired_events[(event, args, tuple(sorted(kwargs.items())))] += 1
|
self.fired_events[(event, tuple(kwargs.items()))] += 1
|
||||||
return effects
|
return effects
|
||||||
|
|
||||||
def fire_event_pre(self, event, *args, **kwargs):
|
def fire_event_pre(self, event, **kwargs):
|
||||||
effects = super(TestEmitter, self).fire_event_pre(event, *args,
|
effects = super(TestEmitter, self).fire_event_pre(event, **kwargs)
|
||||||
**kwargs)
|
self.fired_events[(event, tuple(kwargs.items()))] += 1
|
||||||
self.fired_events[(event, args, tuple(sorted(kwargs.items())))] += 1
|
|
||||||
return effects
|
return effects
|
||||||
|
|
||||||
def expectedFailureIfTemplate(templates):
|
def expectedFailureIfTemplate(templates):
|
||||||
@ -349,53 +348,57 @@ class QubesTestCase(unittest.TestCase):
|
|||||||
dev_class, (": " + msg) if msg else "")
|
dev_class, (": " + msg) if msg else "")
|
||||||
)
|
)
|
||||||
|
|
||||||
def assertEventFired(self, emitter, event, args=None, kwargs=None):
|
def assertEventFired(self, subject, event, kwargs=None):
|
||||||
'''Check whether event was fired on given emitter and fail if it did
|
'''Check whether event was fired on given emitter and fail if it did
|
||||||
not.
|
not.
|
||||||
|
|
||||||
:param emitter: emitter which is being checked
|
:param subject: emitter which is being checked
|
||||||
:type emitter: :py:class:`TestEmitter`
|
:type emitter: :py:class:`TestEmitter`
|
||||||
:param str event: event identifier
|
:param str event: event identifier
|
||||||
:param list args: when given, all items must appear in args passed to \
|
|
||||||
an event
|
|
||||||
:param list kwargs: when given, all items must appear in kwargs passed \
|
:param list kwargs: when given, all items must appear in kwargs passed \
|
||||||
to an event
|
to an event
|
||||||
'''
|
'''
|
||||||
|
|
||||||
for ev, ev_args, ev_kwargs in emitter.fired_events:
|
will_not_match = object()
|
||||||
|
for ev, ev_kwargs in subject.fired_events:
|
||||||
if ev != event:
|
if ev != event:
|
||||||
continue
|
continue
|
||||||
if args is not None and any(i not in ev_args for i in args):
|
if kwargs is not None:
|
||||||
continue
|
ev_kwargs = dict(ev_kwargs)
|
||||||
if kwargs is not None and any(i not in ev_kwargs for i in kwargs):
|
if any(ev_kwargs.get(k, will_not_match) != v
|
||||||
|
for k, v in kwargs.items()):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
self.fail('event {!r} did not fire on {!r}'.format(event, emitter))
|
self.fail('event {!r} {}did not fire on {!r}'.format(
|
||||||
|
event, ('' if kwargs is None else '{!r} '.format(kwargs)), subject))
|
||||||
|
|
||||||
|
|
||||||
def assertEventNotFired(self, emitter, event, args=None, kwargs=None):
|
def assertEventNotFired(self, subject, event, kwargs=None):
|
||||||
'''Check whether event was fired on given emitter. Fail if it did.
|
'''Check whether event was fired on given emitter. Fail if it did.
|
||||||
|
|
||||||
:param emitter: emitter which is being checked
|
:param subject: emitter which is being checked
|
||||||
:type emitter: :py:class:`TestEmitter`
|
:type emitter: :py:class:`TestEmitter`
|
||||||
:param str event: event identifier
|
:param str event: event identifier
|
||||||
:param list args: when given, all items must appear in args passed to \
|
|
||||||
an event
|
|
||||||
:param list kwargs: when given, all items must appear in kwargs passed \
|
:param list kwargs: when given, all items must appear in kwargs passed \
|
||||||
to an event
|
to an event
|
||||||
'''
|
'''
|
||||||
|
|
||||||
for ev, ev_args, ev_kwargs in emitter.fired_events:
|
will_not_match = object()
|
||||||
|
for ev, ev_kwargs in subject.fired_events:
|
||||||
if ev != event:
|
if ev != event:
|
||||||
continue
|
continue
|
||||||
if args is not None and any(i not in ev_args for i in args):
|
if kwargs is not None:
|
||||||
continue
|
ev_kwargs = dict(ev_kwargs)
|
||||||
if kwargs is not None and any(i not in ev_kwargs for i in kwargs):
|
if any(ev_kwargs.get(k, will_not_match) != v
|
||||||
|
for k, v in kwargs.items()):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.fail('event {!r} did fire on {!r}'.format(event, emitter))
|
self.fail('event {!r} {}did fire on {!r}'.format(
|
||||||
|
event,
|
||||||
|
('' if kwargs is None else '{!r} '.format(kwargs)),
|
||||||
|
subject))
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -67,7 +67,8 @@ class TC_30_VMCollection(qubes.tests.QubesTestCase):
|
|||||||
self.vms.add(self.testvm1)
|
self.vms.add(self.testvm1)
|
||||||
self.assertIn(1, self.vms)
|
self.assertIn(1, self.vms)
|
||||||
|
|
||||||
self.assertEventFired(self.app, 'domain-add', args=[self.testvm1])
|
self.assertEventFired(self.app, 'domain-add',
|
||||||
|
kwargs={'vm': self.testvm1})
|
||||||
|
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
self.vms.add(object())
|
self.vms.add(object())
|
||||||
@ -122,7 +123,8 @@ class TC_30_VMCollection(qubes.tests.QubesTestCase):
|
|||||||
del self.vms['testvm2']
|
del self.vms['testvm2']
|
||||||
|
|
||||||
self.assertCountEqual(self.vms.vms(), [self.testvm1])
|
self.assertCountEqual(self.vms.vms(), [self.testvm1])
|
||||||
self.assertEventFired(self.app, 'domain-delete', args=[self.testvm2])
|
self.assertEventFired(self.app, 'domain-delete',
|
||||||
|
kwargs={'vm': self.testvm2})
|
||||||
|
|
||||||
def test_100_get_new_unused_qid(self):
|
def test_100_get_new_unused_qid(self):
|
||||||
self.vms.add(self.testvm1)
|
self.vms.add(self.testvm1)
|
||||||
|
@ -342,7 +342,8 @@ class TC_30_VMCollection(qubes.tests.QubesTestCase):
|
|||||||
self.vms.add(self.testvm1)
|
self.vms.add(self.testvm1)
|
||||||
self.assertIn(1, self.vms)
|
self.assertIn(1, self.vms)
|
||||||
|
|
||||||
self.assertEventFired(self.app, 'domain-add', args=[self.testvm1])
|
self.assertEventFired(self.app, 'domain-add',
|
||||||
|
kwargs={'vm': self.testvm1})
|
||||||
|
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
self.vms.add(object())
|
self.vms.add(object())
|
||||||
@ -395,7 +396,8 @@ class TC_30_VMCollection(qubes.tests.QubesTestCase):
|
|||||||
del self.vms['testvm2']
|
del self.vms['testvm2']
|
||||||
|
|
||||||
self.assertCountEqual(self.vms.vms(), [self.testvm1])
|
self.assertCountEqual(self.vms.vms(), [self.testvm1])
|
||||||
self.assertEventFired(self.app, 'domain-delete', args=[self.testvm2])
|
self.assertEventFired(self.app, 'domain-delete',
|
||||||
|
kwargs={'vm': self.testvm2})
|
||||||
|
|
||||||
def test_100_get_new_unused_qid(self):
|
def test_100_get_new_unused_qid(self):
|
||||||
self.vms.add(self.testvm1)
|
self.vms.add(self.testvm1)
|
||||||
|
@ -113,9 +113,9 @@ class TC_00_Actions(qubes.tests.QubesTestCase):
|
|||||||
)
|
)
|
||||||
qubes.tools.qvm_device.attach_device(args)
|
qubes.tools.qvm_device.attach_device(args)
|
||||||
self.assertEventFired(self.vm1,
|
self.assertEventFired(self.vm1,
|
||||||
'device-attach:testclass', [self.device])
|
'device-attach:testclass', kwargs={'device': self.device})
|
||||||
self.assertEventNotFired(self.vm2,
|
self.assertEventNotFired(self.vm2,
|
||||||
'device-attach:testclass', [self.device])
|
'device-attach:testclass', kwargs={'device': self.device})
|
||||||
|
|
||||||
def test_011_double_attach(self):
|
def test_011_double_attach(self):
|
||||||
args = TestNamespace(
|
args = TestNamespace(
|
||||||
|
@ -53,14 +53,14 @@ def main(args=None):
|
|||||||
|
|
||||||
subprocess.check_call(['killall', '-HUP', 'qubes-guid'])
|
subprocess.check_call(['killall', '-HUP', 'qubes-guid'])
|
||||||
if args.vm:
|
if args.vm:
|
||||||
args.vm.fire_event('monitor-layout-change', monitor_layout)
|
args.vm.fire_event('monitor-layout-change', layout=monitor_layout)
|
||||||
else:
|
else:
|
||||||
threads = []
|
threads = []
|
||||||
|
|
||||||
for vm in args.app.domains:
|
for vm in args.app.domains:
|
||||||
thread = threading.Thread(name=vm.name, target=vm.fire_event,
|
thread = threading.Thread(name=vm.name, target=vm.fire_event,
|
||||||
args=('monitor-layout-change',),
|
args=('monitor-layout-change',),
|
||||||
kwargs={'monitor_layout': monitor_layout})
|
kwargs={'layout': monitor_layout})
|
||||||
threads.append(thread)
|
threads.append(thread)
|
||||||
thread.run()
|
thread.run()
|
||||||
|
|
||||||
|
@ -68,14 +68,14 @@ class Features(dict):
|
|||||||
|
|
||||||
def __delitem__(self, key):
|
def __delitem__(self, key):
|
||||||
super(Features, self).__delitem__(key)
|
super(Features, self).__delitem__(key)
|
||||||
self.vm.fire_event('domain-feature-delete', key)
|
self.vm.fire_event('domain-feature-delete', key=key)
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key, value):
|
||||||
if value is None or isinstance(value, bool):
|
if value is None or isinstance(value, bool):
|
||||||
value = '1' if value else ''
|
value = '1' if value else ''
|
||||||
else:
|
else:
|
||||||
value = str(value)
|
value = str(value)
|
||||||
self.vm.fire_event('domain-feature-set', key, value)
|
self.vm.fire_event('domain-feature-set', key=key, value=value)
|
||||||
super(Features, self).__setitem__(key, value)
|
super(Features, self).__setitem__(key, value)
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
|
@ -337,7 +337,8 @@ class NetVMMixin(qubes.events.Emitter):
|
|||||||
new_netvm = self.netvm
|
new_netvm = self.netvm
|
||||||
if new_netvm == old_netvm:
|
if new_netvm == old_netvm:
|
||||||
return
|
return
|
||||||
self.fire_event('property-set:netvm', 'netvm', new_netvm, old_netvm)
|
self.fire_event('property-set:netvm',
|
||||||
|
name='netvm', newvalue=new_netvm, oldvalue=old_netvm)
|
||||||
|
|
||||||
@qubes.events.handler('property-pre-set:netvm')
|
@qubes.events.handler('property-pre-set:netvm')
|
||||||
def on_property_pre_set_netvm(self, event, name, new_netvm, old_netvm=None):
|
def on_property_pre_set_netvm(self, event, name, new_netvm, old_netvm=None):
|
||||||
@ -378,7 +379,7 @@ class NetVMMixin(qubes.events.Emitter):
|
|||||||
self.create_qdb_entries()
|
self.create_qdb_entries()
|
||||||
self.attach_network()
|
self.attach_network()
|
||||||
|
|
||||||
new_netvm.fire_event('net-domain-connect', self)
|
new_netvm.fire_event('net-domain-connect', vm=self)
|
||||||
|
|
||||||
@qubes.events.handler('net-domain-connect')
|
@qubes.events.handler('net-domain-connect')
|
||||||
def on_net_domain_connect(self, event, vm):
|
def on_net_domain_connect(self, event, vm):
|
||||||
|
@ -1287,7 +1287,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
shutil.copy(src.icon_path, self.icon_path)
|
shutil.copy(src.icon_path, self.icon_path)
|
||||||
|
|
||||||
# fire hooks
|
# fire hooks
|
||||||
self.fire_event('domain-clone-files', src)
|
self.fire_event('domain-clone-files', src=src)
|
||||||
|
|
||||||
#
|
#
|
||||||
# methods for querying domain state
|
# methods for querying domain state
|
||||||
|
Loading…
Reference in New Issue
Block a user