Skip to content

Commit

Permalink
vm/qubesvm: have VM lifecycle related events async
Browse files Browse the repository at this point in the history
Those functions are coroutines anyway, so allow event handlers to be
too.
Some of this (`domain-create-on-disk`, `domain-remove-from-disk`) will
be useful for appmenus handling.
  • Loading branch information
marmarek committed Jul 4, 2017
1 parent d00e453 commit b5ad245
Showing 1 changed file with 27 additions and 8 deletions.
35 changes: 27 additions & 8 deletions qubes/vm/qubesvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
Fired at the beginning of :py:meth:`start` method.
Handler for this event can be asynchronous (a coroutine).
:param subject: Event emitter (the qube object)
:param event: Event name (``'domain-pre-start'``)
Expand All @@ -161,12 +163,16 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
:param subject: Event emitter (the qube object)
:param event: Event name (``'domain-spawn'``)
Handler for this event can be asynchronous (a coroutine).
*other arguments are as in :py:meth:`start`*
.. event:: domain-start (subject, event, start_guid)
Fired at the end of :py:meth:`start` method.
Handler for this event can be asynchronous (a coroutine).
:param subject: Event emitter (the qube object)
:param event: Event name (``'domain-start'``)
Expand All @@ -183,6 +189,8 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
Fired at the beginning of :py:meth:`shutdown` method.
Handler for this event can be asynchronous (a coroutine).
:param subject: Event emitter (the qube object)
:param event: Event name (``'domain-pre-shutdown'``)
:param force: If the shutdown is to be forceful
Expand All @@ -191,6 +199,8 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
Fired at the beginning of :py:meth:`run_service` method.
Handler for this event can be asynchronous (a coroutine).
:param subject: Event emitter (the qube object)
:param event: Event name (``'domain-cmd-pre-run'``)
:param start_guid: If the gui daemon can be started
Expand All @@ -199,6 +209,8 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
Fired at the end of :py:meth:`create_on_disk` method.
Handler for this event can be asynchronous (a coroutine).
:param subject: Event emitter (the qube object)
:param event: Event name (``'domain-create-on-disk'``)
Expand All @@ -207,13 +219,17 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
Fired at the beginning of :py:meth:`remove_from_disk` method, before
the qube directory is removed.
Handler for this event can be asynchronous (a coroutine).
:param subject: Event emitter (the qube object)
:param event: Event name (``'domain-remove-from-disk'``)
.. event:: domain-clone-files (subject, event, src)
Fired at the end of :py:meth:`clone_disk_files` method.
Handler for this event can be asynchronous (a coroutine).
:param subject: Event emitter (the qube object)
:param event: Event name (``'domain-clone-files'``)
:param src: source qube
Expand Down Expand Up @@ -847,7 +863,7 @@ def start(self, start_guid=True, notify_function=None,

self.log.info('Starting {}'.format(self.name))

self.fire_event('domain-pre-start',
yield from self.fire_event_async('domain-pre-start',
pre_event=True,
start_guid=start_guid, mem_required=mem_required)

Expand All @@ -874,7 +890,7 @@ def start(self, start_guid=True, notify_function=None,
qmemman_client.close()

try:
self.fire_event('domain-spawn',
yield from self.fire_event_async('domain-spawn',
start_guid=start_guid)

self.log.info('Setting Qubes DB info for the VM')
Expand All @@ -895,7 +911,8 @@ def start(self, start_guid=True, notify_function=None,

yield from self.start_qrexec_daemon()

self.fire_event('domain-start', start_guid=start_guid)
yield from self.fire_event_async('domain-start',
start_guid=start_guid)

except: # pylint: disable=bare-except
if self.is_running() or self.is_paused():
Expand Down Expand Up @@ -936,7 +953,8 @@ def shutdown(self, force=False, wait=False):
if self.is_halted():
raise qubes.exc.QubesVMNotStartedError(self)

self.fire_event('domain-pre-shutdown', pre_event=True, force=force)
yield from self.fire_event_async('domain-pre-shutdown', pre_event=True,
force=force)

self.libvirt_domain.shutdown()

Expand Down Expand Up @@ -1072,7 +1090,8 @@ def run_service(self, service, source=None, user=None,
raise qubes.exc.QubesVMError(
self, 'Domain {!r}: qrexec not connected'.format(self.name))

self.fire_event('domain-cmd-pre-run', pre_event=True, start_guid=gui)
yield from self.fire_event_async('domain-cmd-pre-run', pre_event=True,
start_guid=gui)

return (yield from asyncio.create_subprocess_exec(
qubes.config.system_path['qrexec_client_path'],
Expand Down Expand Up @@ -1299,7 +1318,7 @@ def create_on_disk(self, pool=None, pools=None):
shutil.copy(self.label.icon_path, self.icon_path)

# fire hooks
self.fire_event('domain-create-on-disk')
yield from self.fire_event_async('domain-create-on-disk')

@asyncio.coroutine
def remove_from_disk(self):
Expand All @@ -1309,7 +1328,7 @@ def remove_from_disk(self):
"Can't remove VM {!s}, beacuse it's in state {!r}.".format(
self, self.get_power_state()))

self.fire_event('domain-remove-from-disk')
yield from self.fire_event_async('domain-remove-from-disk')
try:
# TODO: make it async?
shutil.rmtree(self.dir_path)
Expand Down Expand Up @@ -1367,7 +1386,7 @@ def clone_disk_files(self, src, pool=None, pools=None, ):
shutil.copy(src.icon_path, self.icon_path)

# fire hooks
self.fire_event('domain-clone-files', src=src)
yield from self.fire_event_async('domain-clone-files', src=src)

#
# methods for querying domain state
Expand Down

0 comments on commit b5ad245

Please sign in to comment.