Fix asyncio.Lock usage for Python 3.9+
'with (yield from alock):' is incompatible with Python 3.9+. Change it to 'async with alock:', and then change the affected functions to 'async def'. This makes the test suite pass again in a Fedora 33 VM. QubesOS/qubes-issues#2738
This commit is contained in:
parent
7a91af9b2c
commit
a7fe59449a
@ -1191,13 +1191,12 @@ class QubesAdminAPI(qubes.api.AbstractQubesAPI):
|
|||||||
|
|
||||||
@qubes.api.method('admin.vm.Remove', no_payload=True,
|
@qubes.api.method('admin.vm.Remove', no_payload=True,
|
||||||
scope='global', write=True)
|
scope='global', write=True)
|
||||||
@asyncio.coroutine
|
async def vm_remove(self):
|
||||||
def vm_remove(self):
|
|
||||||
self.enforce(not self.arg)
|
self.enforce(not self.arg)
|
||||||
|
|
||||||
self.fire_event_for_permission()
|
self.fire_event_for_permission()
|
||||||
|
|
||||||
with (yield from self.dest.startup_lock):
|
async with self.dest.startup_lock:
|
||||||
if not self.dest.is_halted():
|
if not self.dest.is_halted():
|
||||||
raise qubes.exc.QubesVMNotHaltedError(self.dest)
|
raise qubes.exc.QubesVMNotHaltedError(self.dest)
|
||||||
|
|
||||||
@ -1207,7 +1206,7 @@ class QubesAdminAPI(qubes.api.AbstractQubesAPI):
|
|||||||
|
|
||||||
del self.app.domains[self.dest]
|
del self.app.domains[self.dest]
|
||||||
try:
|
try:
|
||||||
yield from self.dest.remove_from_disk()
|
await self.dest.remove_from_disk()
|
||||||
except: # pylint: disable=bare-except
|
except: # pylint: disable=bare-except
|
||||||
self.app.log.exception('Error while removing VM \'%s\' files',
|
self.app.log.exception('Error while removing VM \'%s\' files',
|
||||||
self.dest.name)
|
self.dest.name)
|
||||||
|
@ -168,11 +168,10 @@ class Volume:
|
|||||||
>>>def start(self):
|
>>>def start(self):
|
||||||
>>> pass
|
>>> pass
|
||||||
'''
|
'''
|
||||||
@asyncio.coroutine
|
|
||||||
@functools.wraps(method)
|
@functools.wraps(method)
|
||||||
def wrapper(self, *args, **kwargs):
|
async def wrapper(self, *args, **kwargs):
|
||||||
with (yield from self._lock): # pylint: disable=protected-access
|
async with self._lock: # pylint: disable=protected-access
|
||||||
return (yield from method(self, *args, **kwargs))
|
return await method(self, *args, **kwargs)
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
|
@ -242,15 +242,14 @@ class CallbackPool(qubes.storage.Pool):
|
|||||||
cmd = self._cb_conf.get('cmd')
|
cmd = self._cb_conf.get('cmd')
|
||||||
return bool(cmd and cmd != '-')
|
return bool(cmd and cmd != '-')
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def _init(self, callback=True):
|
||||||
def _init(self, callback=True):
|
|
||||||
''' Late storage initialization on first use for e.g. decryption on first usage request.
|
''' Late storage initialization on first use for e.g. decryption on first usage request.
|
||||||
:param callback: Whether to trigger the `pre_sinit` callback or not.
|
:param callback: Whether to trigger the `pre_sinit` callback or not.
|
||||||
'''
|
'''
|
||||||
with (yield from self._cb_init_lock):
|
async with self._cb_init_lock:
|
||||||
if self._cb_requires_init:
|
if self._cb_requires_init:
|
||||||
if callback:
|
if callback:
|
||||||
yield from self._callback('pre_sinit')
|
await self._callback('pre_sinit')
|
||||||
self._cb_requires_init = False
|
self._cb_requires_init = False
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
|
@ -1060,12 +1060,11 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
# methods for changing domain state
|
# methods for changing domain state
|
||||||
#
|
#
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def _ensure_shutdown_handled(self):
|
||||||
def _ensure_shutdown_handled(self):
|
|
||||||
"""Make sure previous shutdown is fully handled.
|
"""Make sure previous shutdown is fully handled.
|
||||||
MUST NOT be called when domain is running.
|
MUST NOT be called when domain is running.
|
||||||
"""
|
"""
|
||||||
with (yield from self._domain_stopped_lock):
|
async with self._domain_stopped_lock:
|
||||||
# Don't accept any new stopped event's till a new VM has been
|
# Don't accept any new stopped event's till a new VM has been
|
||||||
# created. If we didn't received any stopped event or it wasn't
|
# created. If we didn't received any stopped event or it wasn't
|
||||||
# handled yet we will handle this in the next lines.
|
# handled yet we will handle this in the next lines.
|
||||||
@ -1086,11 +1085,10 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
# twice if an exception gets thrown.
|
# twice if an exception gets thrown.
|
||||||
self._domain_stopped_event_handled = True
|
self._domain_stopped_event_handled = True
|
||||||
|
|
||||||
yield from self.fire_event_async('domain-stopped')
|
await self.fire_event_async('domain-stopped')
|
||||||
yield from self.fire_event_async('domain-shutdown')
|
await self.fire_event_async('domain-shutdown')
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def start(self, start_guid=True, notify_function=None,
|
||||||
def start(self, start_guid=True, notify_function=None,
|
|
||||||
mem_required=None):
|
mem_required=None):
|
||||||
"""Start domain
|
"""Start domain
|
||||||
|
|
||||||
@ -1099,7 +1097,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
:param int mem_required: FIXME
|
:param int mem_required: FIXME
|
||||||
"""
|
"""
|
||||||
|
|
||||||
with (yield from self.startup_lock):
|
async with self.startup_lock:
|
||||||
# check if domain wasn't removed in the meantime
|
# check if domain wasn't removed in the meantime
|
||||||
if self not in self.app.domains:
|
if self not in self.app.domains:
|
||||||
raise qubes.exc.QubesVMNotFoundError(self.name)
|
raise qubes.exc.QubesVMNotFoundError(self.name)
|
||||||
@ -1108,18 +1106,18 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
if self.get_power_state() != 'Halted':
|
if self.get_power_state() != 'Halted':
|
||||||
return self
|
return self
|
||||||
|
|
||||||
yield from self._ensure_shutdown_handled()
|
await self._ensure_shutdown_handled()
|
||||||
|
|
||||||
self.log.info('Starting {}'.format(self.name))
|
self.log.info('Starting {}'.format(self.name))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
yield from self.fire_event_async('domain-pre-start',
|
await self.fire_event_async('domain-pre-start',
|
||||||
pre_event=True,
|
pre_event=True,
|
||||||
start_guid=start_guid,
|
start_guid=start_guid,
|
||||||
mem_required=mem_required)
|
mem_required=mem_required)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
self.log.error('Start failed: %s', str(exc))
|
self.log.error('Start failed: %s', str(exc))
|
||||||
yield from self.fire_event_async('domain-start-failed',
|
await self.fire_event_async('domain-start-failed',
|
||||||
reason=str(exc))
|
reason=str(exc))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@ -1135,25 +1133,25 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
if self.virt_mode == 'pvh' and not self.kernel:
|
if self.virt_mode == 'pvh' and not self.kernel:
|
||||||
raise qubes.exc.QubesException(
|
raise qubes.exc.QubesException(
|
||||||
'virt_mode PVH require kernel to be set')
|
'virt_mode PVH require kernel to be set')
|
||||||
yield from self.storage.verify()
|
await 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():
|
||||||
yield from self.netvm.start(
|
await self.netvm.start(
|
||||||
start_guid=start_guid,
|
start_guid=start_guid,
|
||||||
notify_function=notify_function)
|
notify_function=notify_function)
|
||||||
|
|
||||||
qmemman_client = yield from asyncio.get_event_loop(). \
|
qmemman_client = await asyncio.get_event_loop(). \
|
||||||
run_in_executor(None, self.request_memory, mem_required)
|
run_in_executor(None, self.request_memory, mem_required)
|
||||||
|
|
||||||
yield from self.storage.start()
|
await self.storage.start()
|
||||||
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
self.log.error('Start failed: %s', str(exc))
|
self.log.error('Start failed: %s', str(exc))
|
||||||
# let anyone receiving domain-pre-start know that startup failed
|
# let anyone receiving domain-pre-start know that startup failed
|
||||||
yield from self.fire_event_async('domain-start-failed',
|
await self.fire_event_async('domain-start-failed',
|
||||||
reason=str(exc))
|
reason=str(exc))
|
||||||
if qmemman_client:
|
if qmemman_client:
|
||||||
qmemman_client.close()
|
qmemman_client.close()
|
||||||
@ -1179,16 +1177,16 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
'Failed to start an HVM qube with PCI devices assigned '
|
'Failed to start an HVM qube with PCI devices assigned '
|
||||||
'- hardware does not support IOMMU/VT-d/AMD-Vi')
|
'- hardware does not support IOMMU/VT-d/AMD-Vi')
|
||||||
self.log.error('Start failed: %s', str(exc))
|
self.log.error('Start failed: %s', str(exc))
|
||||||
yield from self.fire_event_async('domain-start-failed',
|
await self.fire_event_async('domain-start-failed',
|
||||||
reason=str(exc))
|
reason=str(exc))
|
||||||
yield from self.storage.stop()
|
await self.storage.stop()
|
||||||
raise exc
|
raise exc
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
self.log.error('Start failed: %s', str(exc))
|
self.log.error('Start failed: %s', str(exc))
|
||||||
# let anyone receiving domain-pre-start know that startup failed
|
# let anyone receiving domain-pre-start know that startup failed
|
||||||
yield from self.fire_event_async('domain-start-failed',
|
await self.fire_event_async('domain-start-failed',
|
||||||
reason=str(exc))
|
reason=str(exc))
|
||||||
yield from self.storage.stop()
|
await self.storage.stop()
|
||||||
raise
|
raise
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
@ -1199,20 +1197,20 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
self._domain_stopped_event_handled = False
|
self._domain_stopped_event_handled = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
yield from self.fire_event_async('domain-spawn',
|
await self.fire_event_async('domain-spawn',
|
||||||
start_guid=start_guid)
|
start_guid=start_guid)
|
||||||
|
|
||||||
self.log.info('Setting Qubes DB info for the VM')
|
self.log.info('Setting Qubes DB info for the VM')
|
||||||
yield from self.start_qubesdb()
|
await self.start_qubesdb()
|
||||||
self.create_qdb_entries()
|
self.create_qdb_entries()
|
||||||
self.start_qdb_watch()
|
self.start_qdb_watch()
|
||||||
|
|
||||||
self.log.warning('Activating the {} VM'.format(self.name))
|
self.log.warning('Activating the {} VM'.format(self.name))
|
||||||
self.libvirt_domain.resume()
|
self.libvirt_domain.resume()
|
||||||
|
|
||||||
yield from self.start_qrexec_daemon()
|
await self.start_qrexec_daemon()
|
||||||
|
|
||||||
yield from self.fire_event_async('domain-start',
|
await self.fire_event_async('domain-start',
|
||||||
start_guid=start_guid)
|
start_guid=start_guid)
|
||||||
|
|
||||||
except Exception as exc: # pylint: disable=bare-except
|
except Exception as exc: # pylint: disable=bare-except
|
||||||
@ -1221,12 +1219,12 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
# raised in self._kill_locked(), because the vm is not
|
# raised in self._kill_locked(), because the vm is not
|
||||||
# running or paused
|
# running or paused
|
||||||
try:
|
try:
|
||||||
yield from self._kill_locked()
|
await self._kill_locked()
|
||||||
except qubes.exc.QubesVMNotStartedError:
|
except qubes.exc.QubesVMNotStartedError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# let anyone receiving domain-pre-start know that startup failed
|
# let anyone receiving domain-pre-start know that startup failed
|
||||||
yield from self.fire_event_async('domain-start-failed',
|
await self.fire_event_async('domain-start-failed',
|
||||||
reason=str(exc))
|
reason=str(exc))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@ -1255,9 +1253,8 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
self._domain_stopped_future = \
|
self._domain_stopped_future = \
|
||||||
asyncio.ensure_future(self._domain_stopped_coro())
|
asyncio.ensure_future(self._domain_stopped_coro())
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def _domain_stopped_coro(self):
|
||||||
def _domain_stopped_coro(self):
|
async with self._domain_stopped_lock:
|
||||||
with (yield from self._domain_stopped_lock):
|
|
||||||
assert not self._domain_stopped_event_handled
|
assert not self._domain_stopped_event_handled
|
||||||
|
|
||||||
# Set this immediately such that we don't generate events twice if
|
# Set this immediately such that we don't generate events twice if
|
||||||
@ -1265,9 +1262,9 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
self._domain_stopped_event_handled = True
|
self._domain_stopped_event_handled = True
|
||||||
|
|
||||||
while self.get_power_state() == 'Dying':
|
while self.get_power_state() == 'Dying':
|
||||||
yield from asyncio.sleep(0.25)
|
await asyncio.sleep(0.25)
|
||||||
yield from self.fire_event_async('domain-stopped')
|
await self.fire_event_async('domain-stopped')
|
||||||
yield from self.fire_event_async('domain-shutdown')
|
await self.fire_event_async('domain-shutdown')
|
||||||
|
|
||||||
@qubes.events.handler('domain-stopped')
|
@qubes.events.handler('domain-stopped')
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
@ -1282,8 +1279,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
self.fire_event('property-reset:stubdom_xid', name='stubdom_xid')
|
self.fire_event('property-reset:stubdom_xid', name='stubdom_xid')
|
||||||
self.fire_event('property-reset:start_time', name='start_time')
|
self.fire_event('property-reset:start_time', name='start_time')
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def shutdown(self, force=False, wait=False, timeout=None):
|
||||||
def shutdown(self, force=False, wait=False, timeout=None):
|
|
||||||
"""Shutdown domain.
|
"""Shutdown domain.
|
||||||
|
|
||||||
:param force: ignored
|
:param force: ignored
|
||||||
@ -1298,7 +1294,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
raise qubes.exc.QubesVMNotStartedError(self)
|
raise qubes.exc.QubesVMNotStartedError(self)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
yield from self.fire_event_async('domain-pre-shutdown',
|
await self.fire_event_async('domain-pre-shutdown',
|
||||||
pre_event=True, force=force)
|
pre_event=True, force=force)
|
||||||
|
|
||||||
self.libvirt_domain.shutdown()
|
self.libvirt_domain.shutdown()
|
||||||
@ -1307,23 +1303,22 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
if timeout is None:
|
if timeout is None:
|
||||||
timeout = self.shutdown_timeout
|
timeout = self.shutdown_timeout
|
||||||
while timeout > 0 and not self.is_halted():
|
while timeout > 0 and not self.is_halted():
|
||||||
yield from asyncio.sleep(0.25)
|
await asyncio.sleep(0.25)
|
||||||
timeout -= 0.25
|
timeout -= 0.25
|
||||||
with (yield from self.startup_lock):
|
async with self.startup_lock:
|
||||||
if self.is_halted():
|
if self.is_halted():
|
||||||
# make sure all shutdown tasks are completed
|
# make sure all shutdown tasks are completed
|
||||||
yield from self._ensure_shutdown_handled()
|
await self._ensure_shutdown_handled()
|
||||||
else:
|
else:
|
||||||
raise qubes.exc.QubesVMShutdownTimeoutError(self)
|
raise qubes.exc.QubesVMShutdownTimeoutError(self)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
yield from self.fire_event_async('domain-shutdown-failed',
|
await self.fire_event_async('domain-shutdown-failed',
|
||||||
reason=str(ex))
|
reason=str(ex))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def kill(self):
|
||||||
def kill(self):
|
|
||||||
"""Forcefully shutdown (destroy) domain.
|
"""Forcefully shutdown (destroy) domain.
|
||||||
|
|
||||||
:raises qubes.exc.QubesVMNotStartedError: \
|
:raises qubes.exc.QubesVMNotStartedError: \
|
||||||
@ -1333,8 +1328,8 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
if not self.is_running() and not self.is_paused():
|
if not self.is_running() and not self.is_paused():
|
||||||
raise qubes.exc.QubesVMNotStartedError(self)
|
raise qubes.exc.QubesVMNotStartedError(self)
|
||||||
|
|
||||||
with (yield from self.startup_lock):
|
async with self.startup_lock:
|
||||||
yield from self._kill_locked()
|
await self._kill_locked()
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user