Browse Source

factor out utils.coro_maybe()

Rusty Bird 4 years ago
parent
commit
fe97a15d11
6 changed files with 29 additions and 77 deletions
  1. 3 13
      qubes/api/admin.py
  2. 2 6
      qubes/app.py
  3. 4 4
      qubes/ext/windows.py
  4. 5 26
      qubes/storage/__init__.py
  5. 8 28
      qubes/tests/integ/storage.py
  6. 7 0
      qubes/utils.py

+ 3 - 13
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',

+ 2 - 6
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

+ 4 - 4
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']))

+ 5 - 26
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:

+ 8 - 28
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)

+ 7 - 0
qubes/utils.py

@@ -20,6 +20,7 @@
 # License along with this library; if not, see <https://www.gnu.org/licenses/>.
 #
 
+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