From fe97a15d11cb6a88064e86c59525996a03c55525 Mon Sep 17 00:00:00 2001 From: Rusty Bird Date: Fri, 28 Jun 2019 10:29:24 +0000 Subject: [PATCH] factor out utils.coro_maybe() --- qubes/api/admin.py | 16 +++------------- qubes/app.py | 8 ++------ qubes/ext/windows.py | 8 ++++---- qubes/storage/__init__.py | 31 +++++-------------------------- qubes/tests/integ/storage.py | 36 ++++++++---------------------------- qubes/utils.py | 7 +++++++ 6 files changed, 29 insertions(+), 77 deletions(-) diff --git a/qubes/api/admin.py b/qubes/api/admin.py index 7a23edab..343fbd41 100644 --- a/qubes/api/admin.py +++ b/qubes/api/admin.py @@ -380,10 +380,7 @@ class QubesAdminAPI(qubes.api.AbstractQubesAPI): revision = untrusted_revision self.fire_event_for_permission(volume=volume, revision=revision) - - ret = volume.revert(revision) - if asyncio.iscoroutine(ret): - yield from ret + yield from qubes.utils.coro_maybe(volume.revert(revision)) self.app.save() # write=True because this allow to clone VM - and most likely modify that @@ -432,15 +429,8 @@ class QubesAdminAPI(qubes.api.AbstractQubesAPI): self.fire_event_for_permission(src_volume=src_volume, dst_volume=dst_volume) - - op_retval = dst_volume.import_volume(src_volume) - - # clone/import functions may be either synchronous or asynchronous - # in the later case, we need to wait for them to finish - if asyncio.iscoroutine(op_retval): - op_retval = yield from op_retval - - self.dest.volumes[self.arg] = op_retval + self.dest.volumes[self.arg] = yield from qubes.utils.coro_maybe( + dst_volume.import_volume(src_volume)) self.app.save() @qubes.api.method('admin.vm.volume.Resize', diff --git a/qubes/app.py b/qubes/app.py index 27ae3e09..07353b4b 100644 --- a/qubes/app.py +++ b/qubes/app.py @@ -1257,9 +1257,7 @@ class Qubes(qubes.PropertyHolder): kwargs['name'] = name pool = self._get_pool(**kwargs) - ret = pool.setup() - if asyncio.iscoroutine(ret): - yield from ret + yield from qubes.utils.coro_maybe(pool.setup()) self.pools[name] = pool yield from self.fire_event_async('pool-add', pool=pool) return pool @@ -1283,9 +1281,7 @@ class Qubes(qubes.PropertyHolder): yield from self.fire_event_async('pool-pre-delete', pre_event=True, pool=pool) del self.pools[name] - ret = pool.destroy() - if asyncio.iscoroutine(ret): - yield from ret + yield from qubes.utils.coro_maybe(pool.destroy()) yield from self.fire_event_async('pool-delete', pool=pool) except KeyError: return diff --git a/qubes/ext/windows.py b/qubes/ext/windows.py index 0b417886..5e480608 100644 --- a/qubes/ext/windows.py +++ b/qubes/ext/windows.py @@ -20,6 +20,7 @@ import asyncio import qubes.ext +import qubes.utils class WindowsFeatures(qubes.ext.Extension): # pylint: disable=too-few-public-methods @@ -67,7 +68,6 @@ class WindowsFeatures(qubes.ext.Extension): # until windows tools get ability to prepare private.img on its own, # copy one from the template vm.log.info('Windows template - cloning private volume') - import_op = vm.volumes['private'].import_volume( - template.volumes['private']) - if asyncio.iscoroutine(import_op): - yield from import_op + yield from qubes.utils.coro_maybe( + vm.volumes['private'].import_volume( + template.volumes['private'])) diff --git a/qubes/storage/__init__.py b/qubes/storage/__init__.py index cab68eb1..6c878945 100644 --- a/qubes/storage/__init__.py +++ b/qubes/storage/__init__.py @@ -489,9 +489,7 @@ class Storage: ''' Resizes volume a read-writable volume ''' if isinstance(volume, str): volume = self.vm.volumes[volume] - ret = volume.resize(size) - if asyncio.iscoroutine(ret): - yield from ret + yield from qubes.utils.coro_maybe(volume.resize(size)) if self.vm.is_running(): try: yield from self.vm.run_service_for_stdio('qubes.ResizeDisk', @@ -535,21 +533,8 @@ class Storage: src_volume = src_vm.volumes[name] msg = "Importing volume {!s} from vm {!s}" self.vm.log.info(msg.format(src_volume.name, src_vm.name)) - - # First create the destination volume - create_op_ret = dst.create() - # clone/import functions may be either synchronous or asynchronous - # in the later case, we need to wait for them to finish - if asyncio.iscoroutine(create_op_ret): - yield from create_op_ret - - # Then import data from source volume - clone_op_ret = dst.import_volume(src_volume) - - # clone/import functions may be either synchronous or asynchronous - # in the later case, we need to wait for them to finish - if asyncio.iscoroutine(clone_op_ret): - yield from clone_op_ret + yield from qubes.utils.coro_maybe(dst.create()) + yield from qubes.utils.coro_maybe(dst.import_volume(src_volume)) self.vm.volumes[name] = dst return self.vm.volumes[name] @@ -671,10 +656,7 @@ class Storage: ret = volume.import_data() else: ret = self.vm.volumes[volume].import_data() - - if asyncio.iscoroutine(ret): - ret = yield from ret - return ret + return (yield from qubes.utils.coro_maybe(ret)) @asyncio.coroutine def import_data_end(self, volume, success): @@ -686,10 +668,7 @@ class Storage: ret = volume.import_data_end(success=success) else: ret = self.vm.volumes[volume].import_data_end(success=success) - - if asyncio.iscoroutine(ret): - ret = yield from ret - return ret + return (yield from qubes.utils.coro_maybe(ret)) class VolumesCollection: diff --git a/qubes/tests/integ/storage.py b/qubes/tests/integ/storage.py index 20ea6ef8..64441c54 100644 --- a/qubes/tests/integ/storage.py +++ b/qubes/tests/integ/storage.py @@ -28,6 +28,7 @@ import qubes.storage.lvm import qubes.tests import qubes.tests.storage_lvm import qubes.tests.storage_reflink +import qubes.utils import qubes.vm.appvm @@ -84,11 +85,8 @@ class StorageTestMixin(object): 'rw': True, } testvol = self.vm1.storage.init_volume('testvol', volume_config) - coro_maybe = testvol.create() + yield from qubes.utils.coro_maybe(testvol.create()) del testvol - if asyncio.iscoroutine(coro_maybe): - yield from coro_maybe - del coro_maybe self.app.save() yield from (self.vm1.start()) yield from self.wait_for_session(self.vm1) @@ -120,11 +118,8 @@ class StorageTestMixin(object): 'rw': True, } testvol = self.vm1.storage.init_volume('testvol', volume_config) - coro_maybe = testvol.create() + yield from qubes.utils.coro_maybe(testvol.create()) del testvol - if asyncio.iscoroutine(coro_maybe): - yield from coro_maybe - del coro_maybe self.app.save() yield from self.vm1.start() yield from self.wait_for_session(self.vm1) @@ -158,11 +153,8 @@ class StorageTestMixin(object): 'rw': False, } testvol = self.vm1.storage.init_volume('testvol', volume_config) - coro_maybe = testvol.create() + yield from qubes.utils.coro_maybe(testvol.create()) del testvol - if asyncio.iscoroutine(coro_maybe): - yield from coro_maybe - del coro_maybe self.app.save() yield from self.vm1.start() # non-volatile image not clean @@ -192,10 +184,7 @@ class StorageTestMixin(object): 'rw': True, } testvol = self.vm1.storage.init_volume('testvol', volume_config) - coro_maybe = testvol.create() - if asyncio.iscoroutine(coro_maybe): - yield from coro_maybe - del coro_maybe + yield from qubes.utils.coro_maybe(testvol.create()) volume_config = { 'pool': self.pool.name, 'size': size, @@ -205,11 +194,8 @@ class StorageTestMixin(object): } del testvol testvol_snap = self.vm2.storage.init_volume('testvol', volume_config) - coro_maybe = testvol_snap.create() + yield from qubes.utils.coro_maybe(testvol_snap.create()) del testvol_snap - if asyncio.iscoroutine(coro_maybe): - yield from coro_maybe - del coro_maybe self.app.save() yield from self.vm1.start() yield from self.vm2.start() @@ -284,10 +270,7 @@ class StorageTestMixin(object): 'rw': True, } testvol = self.vm1.storage.init_volume('testvol', volume_config) - coro_maybe = testvol.create() - if asyncio.iscoroutine(coro_maybe): - yield from coro_maybe - del coro_maybe + yield from qubes.utils.coro_maybe(testvol.create()) volume_config = { 'pool': self.pool.name, 'size': size, @@ -297,11 +280,8 @@ class StorageTestMixin(object): } del testvol testvol_snap = self.vm2.storage.init_volume('testvol', volume_config) - coro_maybe = testvol_snap.create() + yield from qubes.utils.coro_maybe(testvol_snap.create()) del testvol_snap - if asyncio.iscoroutine(coro_maybe): - yield from coro_maybe - del coro_maybe self.app.save() yield from self.vm2.start() yield from self.wait_for_session(self.vm2) diff --git a/qubes/utils.py b/qubes/utils.py index 23dddd99..a0587cbb 100644 --- a/qubes/utils.py +++ b/qubes/utils.py @@ -20,6 +20,7 @@ # License along with this library; if not, see . # +import asyncio import hashlib import random import string @@ -183,3 +184,9 @@ def match_vm_name_with_special(vm, name): if name.startswith('@type:'): return name[len('@type:'):] == vm.__class__.__name__ return name == vm.name + +@asyncio.coroutine +def coro_maybe(value): + if asyncio.iscoroutine(value): + return (yield from value) + return value