qubes: revert async def, use @asyncio.coroutine

Current pylint (any released version) stumbles on async def'ined
functions. Let's use @asyncio.coroutines for now.

Seems like python-3.5 is not that mature yet.

QubesOS/qubes-issues#2622
QubesOS/qubes-issues#2738
PyCQA/pylint#1126
This commit is contained in:
Wojtek Porczyk 2017-04-05 16:44:13 +02:00
parent 78693c265c
commit 64d358562b
2 changed files with 106 additions and 66 deletions

View File

@ -22,6 +22,7 @@
Qubes OS Management API Qubes OS Management API
''' '''
import asyncio
import functools import functools
import string import string
@ -159,7 +160,8 @@ class QubesMgmt(AbstractQubesMgmt):
''' '''
@api('mgmt.vmclass.List', no_payload=True) @api('mgmt.vmclass.List', no_payload=True)
async def vmclass_list(self): @asyncio.coroutine
def vmclass_list(self):
'''List all VM classes''' '''List all VM classes'''
assert not self.arg assert not self.arg
assert self.dest.name == 'dom0' assert self.dest.name == 'dom0'
@ -171,7 +173,8 @@ class QubesMgmt(AbstractQubesMgmt):
for ep in entrypoints) for ep in entrypoints)
@api('mgmt.vm.List', no_payload=True) @api('mgmt.vm.List', no_payload=True)
async def vm_list(self): @asyncio.coroutine
def vm_list(self):
'''List all the domains''' '''List all the domains'''
assert not self.arg assert not self.arg
@ -187,7 +190,8 @@ class QubesMgmt(AbstractQubesMgmt):
for vm in sorted(domains)) for vm in sorted(domains))
@api('mgmt.vm.property.List', no_payload=True) @api('mgmt.vm.property.List', no_payload=True)
async def vm_property_list(self): @asyncio.coroutine
def vm_property_list(self):
'''List all properties on a qube''' '''List all properties on a qube'''
assert not self.arg assert not self.arg
@ -196,7 +200,8 @@ class QubesMgmt(AbstractQubesMgmt):
return ''.join('{}\n'.format(prop.__name__) for prop in properties) return ''.join('{}\n'.format(prop.__name__) for prop in properties)
@api('mgmt.vm.property.Get', no_payload=True) @api('mgmt.vm.property.Get', no_payload=True)
async def vm_property_get(self): @asyncio.coroutine
def vm_property_get(self):
'''Get a value of one property''' '''Get a value of one property'''
assert self.arg in self.dest.property_list() assert self.arg in self.dest.property_list()
@ -226,7 +231,8 @@ class QubesMgmt(AbstractQubesMgmt):
str(value) if value is not None else '') str(value) if value is not None else '')
@api('mgmt.vm.property.Set') @api('mgmt.vm.property.Set')
async def vm_property_set(self, untrusted_payload): @asyncio.coroutine
def vm_property_set(self, untrusted_payload):
assert self.arg in self.dest.property_list() assert self.arg in self.dest.property_list()
property_def = self.dest.property_get_def(self.arg) property_def = self.dest.property_get_def(self.arg)
@ -238,7 +244,8 @@ class QubesMgmt(AbstractQubesMgmt):
self.app.save() self.app.save()
@api('mgmt.vm.property.Help', no_payload=True) @api('mgmt.vm.property.Help', no_payload=True)
async def vm_property_help(self): @asyncio.coroutine
def vm_property_help(self):
'''Get help for one property''' '''Get help for one property'''
assert self.arg in self.dest.property_list() assert self.arg in self.dest.property_list()
@ -252,7 +259,8 @@ class QubesMgmt(AbstractQubesMgmt):
return qubes.utils.format_doc(doc) return qubes.utils.format_doc(doc)
@api('mgmt.vm.property.Reset', no_payload=True) @api('mgmt.vm.property.Reset', no_payload=True)
async def vm_property_reset(self): @asyncio.coroutine
def vm_property_reset(self):
'''Reset a property to a default value''' '''Reset a property to a default value'''
assert self.arg in self.dest.property_list() assert self.arg in self.dest.property_list()
@ -262,14 +270,16 @@ class QubesMgmt(AbstractQubesMgmt):
self.app.save() self.app.save()
@api('mgmt.vm.volume.List', no_payload=True) @api('mgmt.vm.volume.List', no_payload=True)
async def vm_volume_list(self): @asyncio.coroutine
def vm_volume_list(self):
assert not self.arg assert not self.arg
volume_names = self.fire_event_for_filter(self.dest.volumes.keys()) volume_names = self.fire_event_for_filter(self.dest.volumes.keys())
return ''.join('{}\n'.format(name) for name in volume_names) return ''.join('{}\n'.format(name) for name in volume_names)
@api('mgmt.vm.volume.Info', no_payload=True) @api('mgmt.vm.volume.Info', no_payload=True)
async def vm_volume_info(self): @asyncio.coroutine
def vm_volume_info(self):
assert self.arg in self.dest.volumes.keys() assert self.arg in self.dest.volumes.keys()
self.fire_event_for_permission() self.fire_event_for_permission()
@ -283,7 +293,8 @@ class QubesMgmt(AbstractQubesMgmt):
volume_properties) volume_properties)
@api('mgmt.vm.volume.ListSnapshots', no_payload=True) @api('mgmt.vm.volume.ListSnapshots', no_payload=True)
async def vm_volume_listsnapshots(self): @asyncio.coroutine
def vm_volume_listsnapshots(self):
assert self.arg in self.dest.volumes.keys() assert self.arg in self.dest.volumes.keys()
volume = self.dest.volumes[self.arg] volume = self.dest.volumes[self.arg]
@ -293,7 +304,8 @@ class QubesMgmt(AbstractQubesMgmt):
return ''.join('{}\n'.format(revision) for revision in revisions) return ''.join('{}\n'.format(revision) for revision in revisions)
@api('mgmt.vm.volume.Revert') @api('mgmt.vm.volume.Revert')
async def vm_volume_revert(self, untrusted_payload): @asyncio.coroutine
def vm_volume_revert(self, untrusted_payload):
assert self.arg in self.dest.volumes.keys() assert self.arg in self.dest.volumes.keys()
untrusted_revision = untrusted_payload.decode('ascii').strip() untrusted_revision = untrusted_payload.decode('ascii').strip()
del untrusted_payload del untrusted_payload
@ -309,7 +321,8 @@ class QubesMgmt(AbstractQubesMgmt):
self.app.save() self.app.save()
@api('mgmt.vm.volume.Resize') @api('mgmt.vm.volume.Resize')
async def vm_volume_resize(self, untrusted_payload): @asyncio.coroutine
def vm_volume_resize(self, untrusted_payload):
assert self.arg in self.dest.volumes.keys() assert self.arg in self.dest.volumes.keys()
untrusted_size = untrusted_payload.decode('ascii').strip() untrusted_size = untrusted_payload.decode('ascii').strip()
del untrusted_payload del untrusted_payload
@ -324,7 +337,8 @@ class QubesMgmt(AbstractQubesMgmt):
self.app.save() self.app.save()
@api('mgmt.pool.List', no_payload=True) @api('mgmt.pool.List', no_payload=True)
async def pool_list(self): @asyncio.coroutine
def pool_list(self):
assert not self.arg assert not self.arg
assert self.dest.name == 'dom0' assert self.dest.name == 'dom0'
@ -333,7 +347,8 @@ class QubesMgmt(AbstractQubesMgmt):
return ''.join('{}\n'.format(pool) for pool in pools) return ''.join('{}\n'.format(pool) for pool in pools)
@api('mgmt.pool.ListDrivers', no_payload=True) @api('mgmt.pool.ListDrivers', no_payload=True)
async def pool_listdrivers(self): @asyncio.coroutine
def pool_listdrivers(self):
assert self.dest.name == 'dom0' assert self.dest.name == 'dom0'
assert not self.arg assert not self.arg
@ -345,7 +360,8 @@ class QubesMgmt(AbstractQubesMgmt):
for driver in drivers) for driver in drivers)
@api('mgmt.pool.Info', no_payload=True) @api('mgmt.pool.Info', no_payload=True)
async def pool_info(self): @asyncio.coroutine
def pool_info(self):
assert self.dest.name == 'dom0' assert self.dest.name == 'dom0'
assert self.arg in self.app.pools.keys() assert self.arg in self.app.pools.keys()
@ -357,7 +373,8 @@ class QubesMgmt(AbstractQubesMgmt):
for prop, val in sorted(pool.config.items())) for prop, val in sorted(pool.config.items()))
@api('mgmt.pool.Add') @api('mgmt.pool.Add')
async def pool_add(self, untrusted_payload): @asyncio.coroutine
def pool_add(self, untrusted_payload):
assert self.dest.name == 'dom0' assert self.dest.name == 'dom0'
drivers = qubes.storage.pool_drivers() drivers = qubes.storage.pool_drivers()
assert self.arg in drivers assert self.arg in drivers
@ -391,7 +408,8 @@ class QubesMgmt(AbstractQubesMgmt):
self.app.save() self.app.save()
@api('mgmt.pool.Remove', no_payload=True) @api('mgmt.pool.Remove', no_payload=True)
async def pool_remove(self): @asyncio.coroutine
def pool_remove(self):
assert self.dest.name == 'dom0' assert self.dest.name == 'dom0'
assert self.arg in self.app.pools.keys() assert self.arg in self.app.pools.keys()
@ -401,7 +419,8 @@ class QubesMgmt(AbstractQubesMgmt):
self.app.save() self.app.save()
@api('mgmt.label.List', no_payload=True) @api('mgmt.label.List', no_payload=True)
async def label_list(self): @asyncio.coroutine
def label_list(self):
assert self.dest.name == 'dom0' assert self.dest.name == 'dom0'
assert not self.arg assert not self.arg
@ -410,7 +429,8 @@ class QubesMgmt(AbstractQubesMgmt):
return ''.join('{}\n'.format(label.name) for label in labels) return ''.join('{}\n'.format(label.name) for label in labels)
@api('mgmt.label.Get', no_payload=True) @api('mgmt.label.Get', no_payload=True)
async def label_get(self): @asyncio.coroutine
def label_get(self):
assert self.dest.name == 'dom0' assert self.dest.name == 'dom0'
try: try:
@ -423,7 +443,8 @@ class QubesMgmt(AbstractQubesMgmt):
return label.color return label.color
@api('mgmt.label.Create') @api('mgmt.label.Create')
async def label_create(self, untrusted_payload): @asyncio.coroutine
def label_create(self, untrusted_payload):
assert self.dest.name == 'dom0' assert self.dest.name == 'dom0'
# don't confuse label name with label index # don't confuse label name with label index
@ -458,7 +479,8 @@ class QubesMgmt(AbstractQubesMgmt):
self.app.save() self.app.save()
@api('mgmt.label.Remove', no_payload=True) @api('mgmt.label.Remove', no_payload=True)
async def label_remove(self): @asyncio.coroutine
def label_remove(self):
assert self.dest.name == 'dom0' assert self.dest.name == 'dom0'
try: try:
@ -479,31 +501,36 @@ class QubesMgmt(AbstractQubesMgmt):
self.app.save() self.app.save()
@api('mgmt.vm.Start', no_payload=True) @api('mgmt.vm.Start', no_payload=True)
async def vm_start(self): @asyncio.coroutine
def vm_start(self):
assert not self.arg assert not self.arg
self.fire_event_for_permission() self.fire_event_for_permission()
await self.dest.start() yield from self.dest.start()
@api('mgmt.vm.Shutdown', no_payload=True) @api('mgmt.vm.Shutdown', no_payload=True)
async def vm_shutdown(self): @asyncio.coroutine
def vm_shutdown(self):
assert not self.arg assert not self.arg
self.fire_event_for_permission() self.fire_event_for_permission()
await self.dest.shutdown() yield from self.dest.shutdown()
@api('mgmt.vm.Pause', no_payload=True) @api('mgmt.vm.Pause', no_payload=True)
async def vm_pause(self): @asyncio.coroutine
def vm_pause(self):
assert not self.arg assert not self.arg
self.fire_event_for_permission() self.fire_event_for_permission()
await self.dest.pause() yield from self.dest.pause()
@api('mgmt.vm.Unpause', no_payload=True) @api('mgmt.vm.Unpause', no_payload=True)
async def vm_unpause(self): @asyncio.coroutine
def vm_unpause(self):
assert not self.arg assert not self.arg
self.fire_event_for_permission() self.fire_event_for_permission()
await self.dest.unpause() yield from self.dest.unpause()
@api('mgmt.vm.Kill', no_payload=True) @api('mgmt.vm.Kill', no_payload=True)
async def vm_kill(self): @asyncio.coroutine
def vm_kill(self):
assert not self.arg assert not self.arg
self.fire_event_for_permission() self.fire_event_for_permission()
await self.dest.kill() yield from self.dest.kill()

View File

@ -794,8 +794,9 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
# methods for changing domain state # methods for changing domain state
# #
async def start(self, preparing_dvm=False, start_guid=True, @asyncio.coroutine
notify_function=None, mem_required=None): def start(self, preparing_dvm=False, start_guid=True, notify_function=None,
mem_required=None):
'''Start domain '''Start domain
:param bool preparing_dvm: FIXME :param bool preparing_dvm: FIXME
@ -814,22 +815,22 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
self.fire_event_pre('domain-pre-start', preparing_dvm=preparing_dvm, self.fire_event_pre('domain-pre-start', preparing_dvm=preparing_dvm,
start_guid=start_guid, mem_required=mem_required) start_guid=start_guid, mem_required=mem_required)
await asyncio.get_event_loop().run_in_executor(None, yield from asyncio.get_event_loop().run_in_executor(None,
self.storage.verify) self.storage.verify)
if self.netvm is not None: if self.netvm is not None:
# pylint: disable = no-member # pylint: disable = no-member
if self.netvm.qid != 0: if self.netvm.qid != 0:
if not self.netvm.is_running(): if not self.netvm.is_running():
await self.netvm.start(start_guid=start_guid, yield from self.netvm.start(start_guid=start_guid,
notify_function=notify_function) notify_function=notify_function)
await asyncio.get_event_loop().run_in_executor(None, yield from asyncio.get_event_loop().run_in_executor(None,
self.storage.start) self.storage.start)
self._update_libvirt_domain() self._update_libvirt_domain()
qmemman_client = await asyncio.get_event_loop().run_in_executor(None, qmemman_client = yield from asyncio.get_event_loop().run_in_executor(
self.request_memory, mem_required) None, self.request_memory, mem_required)
try: try:
self.libvirt_domain.createWithFlags(libvirt.VIR_DOMAIN_START_PAUSED) self.libvirt_domain.createWithFlags(libvirt.VIR_DOMAIN_START_PAUSED)
except: except:
@ -842,7 +843,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
preparing_dvm=preparing_dvm, start_guid=start_guid) preparing_dvm=preparing_dvm, start_guid=start_guid)
self.log.info('Setting Qubes DB info for the VM') self.log.info('Setting Qubes DB info for the VM')
await self.start_qubesdb() yield from self.start_qubesdb()
self.create_qdb_entries() self.create_qdb_entries()
if preparing_dvm: if preparing_dvm:
@ -864,7 +865,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
# self.start_guid() # self.start_guid()
if not preparing_dvm: if not preparing_dvm:
await self.start_qrexec_daemon() yield from self.start_qrexec_daemon()
self.fire_event('domain-start', self.fire_event('domain-start',
preparing_dvm=preparing_dvm, start_guid=start_guid) preparing_dvm=preparing_dvm, start_guid=start_guid)
@ -873,14 +874,15 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
if self.is_running() or self.is_paused(): if self.is_running() or self.is_paused():
# This avoids losing the exception if an exception is raised in # This avoids losing the exception if an exception is raised in
# self.force_shutdown(), because the vm is not running or paused # self.force_shutdown(), because the vm is not running or paused
await self.kill() yield from self.kill()
raise raise
asyncio.ensure_future(self._wait_for_session()) asyncio.ensure_future(self._wait_for_session())
return self return self
async def shutdown(self, force=False, wait=False): @asyncio.coroutine
def shutdown(self, force=False, wait=False):
'''Shutdown domain. '''Shutdown domain.
:raises qubes.exc.QubesVMNotStartedError: \ :raises qubes.exc.QubesVMNotStartedError: \
@ -894,15 +896,16 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
self.libvirt_domain.shutdown() self.libvirt_domain.shutdown()
await asyncio.get_event_loop().run_in_executor(None, yield from asyncio.get_event_loop().run_in_executor(None,
self.storage.stop) self.storage.stop)
while wait and not self.is_halted(): while wait and not self.is_halted():
await asyncio.sleep(0.25) yield from asyncio.sleep(0.25)
return self return self
async def kill(self): @asyncio.coroutine
def kill(self):
'''Forcefuly shutdown (destroy) domain. '''Forcefuly shutdown (destroy) domain.
:raises qubes.exc.QubesVMNotStartedError: \ :raises qubes.exc.QubesVMNotStartedError: \
@ -913,7 +916,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
raise qubes.exc.QubesVMNotStartedError(self) raise qubes.exc.QubesVMNotStartedError(self)
self.libvirt_domain.destroy() self.libvirt_domain.destroy()
await asyncio.get_event_loop().run_in_executor(None, yield from asyncio.get_event_loop().run_in_executor(None,
self.storage.stop) self.storage.stop)
return self return self
@ -925,7 +928,8 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
DeprecationWarning, stacklevel=2) DeprecationWarning, stacklevel=2)
return self.kill(*args, **kwargs) return self.kill(*args, **kwargs)
async def suspend(self): @asyncio.coroutine
def suspend(self):
'''Suspend (pause) domain. '''Suspend (pause) domain.
:raises qubes.exc.QubesVMNotRunnignError: \ :raises qubes.exc.QubesVMNotRunnignError: \
@ -946,7 +950,8 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
return self return self
async def pause(self): @asyncio.coroutine
def pause(self):
'''Pause (suspend) domain. This currently delegates to \ '''Pause (suspend) domain. This currently delegates to \
:py:meth:`suspend`.''' :py:meth:`suspend`.'''
@ -957,7 +962,8 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
return self return self
async def resume(self): @asyncio.coroutine
def resume(self):
'''Resume suspended domain. '''Resume suspended domain.
:raises qubes.exc.QubesVMNotSuspendedError: when machine is not paused :raises qubes.exc.QubesVMNotSuspendedError: when machine is not paused
@ -972,7 +978,8 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
return self return self
async def unpause(self): @asyncio.coroutine
def unpause(self):
'''Resume (unpause) a domain''' '''Resume (unpause) a domain'''
if not self.is_paused(): if not self.is_paused():
raise qubes.exc.QubesVMNotPausedError(self) raise qubes.exc.QubesVMNotPausedError(self)
@ -981,7 +988,8 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
return self return self
async def run_service(self, service, source=None, user=None, @asyncio.coroutine
def run_service(self, service, source=None, user=None,
filter_esc=False, autostart=False, gui=False, **kwargs): filter_esc=False, autostart=False, gui=False, **kwargs):
'''Run service on this VM '''Run service on this VM
@ -1020,7 +1028,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
elif not self.is_running(): elif not self.is_running():
if not autostart: if not autostart:
raise qubes.exc.QubesVMNotRunningError(self) raise qubes.exc.QubesVMNotRunningError(self)
await self.start(start_guid=gui) yield from self.start(start_guid=gui)
if not self.is_qrexec_running(): if not self.is_qrexec_running():
raise qubes.exc.QubesVMError( raise qubes.exc.QubesVMError(
@ -1031,14 +1039,15 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
self.fire_event_pre('domain-cmd-pre-run', start_guid=gui) self.fire_event_pre('domain-cmd-pre-run', start_guid=gui)
return await 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'],
'-d', str(self.name), '-d', str(self.name),
*(('-t', '-T') if filter_esc else ()), *(('-t', '-T') if filter_esc else ()),
'{}:QUBESRPC {} {}'.format(user, service, source), '{}:QUBESRPC {} {}'.format(user, service, source),
**kwargs) **kwargs))
async def run_service_for_stdio(self, *args, input=None, **kwargs): @asyncio.coroutine
def run_service_for_stdio(self, *args, input=None, **kwargs):
'''Run a service, pass an optional input and return (stdout, stderr). '''Run a service, pass an optional input and return (stdout, stderr).
Raises an exception if return code != 0. Raises an exception if return code != 0.
@ -1050,10 +1059,10 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
not filtered for problems originating between the keyboard and the not filtered for problems originating between the keyboard and the
chair. chair.
''' # pylint: disable=redefined-builtin ''' # pylint: disable=redefined-builtin
p = await self.run_service(*args, **kwargs) p = yield from self.run_service(*args, **kwargs)
# this one is actually a tuple, but there is no need to unpack it # this one is actually a tuple, but there is no need to unpack it
stdouterr = await p.communicate(input=input) stdouterr = yield from p.communicate(input=input)
if p.returncode: if p.returncode:
raise qubes.exc.QubesVMError(self, raise qubes.exc.QubesVMError(self,
@ -1121,7 +1130,8 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
return qmemman_client return qmemman_client
@staticmethod @staticmethod
async def start_daemon(*command, input=None, **kwargs): @asyncio.coroutine
def start_daemon(*command, input=None, **kwargs):
'''Start a daemon for the VM '''Start a daemon for the VM
This function take care to run it as appropriate user. This function take care to run it as appropriate user.
@ -1138,13 +1148,14 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
# permission problems # permission problems
qubes_group = grp.getgrnam('qubes') qubes_group = grp.getgrnam('qubes')
command = ['runuser', '-u', qubes_group.gr_mem[0], '--'] + command command = ['runuser', '-u', qubes_group.gr_mem[0], '--'] + command
p = await asyncio.create_subprocess_exec(*command, **kwargs) p = yield from asyncio.create_subprocess_exec(*command, **kwargs)
stdout, stderr = await p.communicate(input=input) stdout, stderr = yield from p.communicate(input=input)
if p.returncode: if p.returncode:
raise subprocess.CalledProcessError(p.returncode, command, raise subprocess.CalledProcessError(p.returncode, command,
output=stdout, stderr=stderr) output=stdout, stderr=stderr)
async def start_qrexec_daemon(self): @asyncio.coroutine
def start_qrexec_daemon(self):
'''Start qrexec daemon. '''Start qrexec daemon.
:raises OSError: when starting fails. :raises OSError: when starting fails.
@ -1164,13 +1175,14 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
qrexec_env['QREXEC_STARTUP_TIMEOUT'] = str(self.qrexec_timeout) qrexec_env['QREXEC_STARTUP_TIMEOUT'] = str(self.qrexec_timeout)
try: try:
await self.start_daemon( yield from self.start_daemon(
qubes.config.system_path['qrexec_daemon_path'], *qrexec_args, qubes.config.system_path['qrexec_daemon_path'], *qrexec_args,
env=qrexec_env) env=qrexec_env)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
raise qubes.exc.QubesVMError(self, 'Cannot execute qrexec-daemon!') raise qubes.exc.QubesVMError(self, 'Cannot execute qrexec-daemon!')
async def start_qubesdb(self): @asyncio.coroutine
def start_qubesdb(self):
'''Start QubesDB daemon. '''Start QubesDB daemon.
:raises OSError: when starting fails. :raises OSError: when starting fails.
@ -1181,14 +1193,15 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
self.log.info('Starting Qubes DB') self.log.info('Starting Qubes DB')
try: try:
await self.start_daemon( yield from self.start_daemon(
qubes.config.system_path['qubesdb_daemon_path'], qubes.config.system_path['qubesdb_daemon_path'],
str(self.xid), str(self.xid),
self.name) self.name)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
raise qubes.exc.QubesException('Cannot execute qubesdb-daemon') raise qubes.exc.QubesException('Cannot execute qubesdb-daemon')
async def _wait_for_session(self): @asyncio.coroutine
def _wait_for_session(self):
'''Wait until machine finished boot sequence. '''Wait until machine finished boot sequence.
This is done by executing qubes RPC call that checks if dummy system This is done by executing qubes RPC call that checks if dummy system
@ -1197,7 +1210,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
self.log.info('Waiting for qubes-session') self.log.info('Waiting for qubes-session')
await self.run_service_for_stdio('qubes.WaitForSession', yield from self.run_service_for_stdio('qubes.WaitForSession',
user='root', gui=False, input=self.default_user.encode()) user='root', gui=False, input=self.default_user.encode())
self.log.info('qubes-session acquired') self.log.info('qubes-session acquired')