Bläddra i källkod

Merge branch 'dispvm-fix'

* dispvm-fix:
  storage: add comment about source volume lookup
  vm/dispvm: convert DispVM related function to coroutines
  vm/dispvm: fix DispVM storage definition
Marek Marczykowski-Górecki 6 år sedan
förälder
incheckning
ab7ed776f9
3 ändrade filer med 20 tillägg och 8 borttagningar
  1. 2 4
      qubes/api/internal.py
  2. 8 1
      qubes/storage/__init__.py
  3. 10 3
      qubes/vm/dispvm.py

+ 2 - 4
qubes/api/internal.py

@@ -69,8 +69,7 @@ class QubesInternalAPI(qubes.api.AbstractQubesAPI):
     def create_dispvm(self):
         assert not self.arg
 
-        # TODO convert to coroutine
-        dispvm = qubes.vm.dispvm.DispVM.from_appvm(self.dest)
+        dispvm = yield from qubes.vm.dispvm.DispVM.from_appvm(self.dest)
         return dispvm.name
 
     @qubes.api.method('internal.vm.CleanupDispVM', no_payload=True)
@@ -78,8 +77,7 @@ class QubesInternalAPI(qubes.api.AbstractQubesAPI):
     def cleanup_dispvm(self):
         assert not self.arg
 
-        # TODO convert to coroutine
-        self.dest.cleanup()
+        yield from self.dest.cleanup()
 
     @qubes.api.method('internal.vm.volume.ImportEnd')
     @asyncio.coroutine

+ 8 - 1
qubes/storage/__init__.py

@@ -352,7 +352,10 @@ class Storage(object):
                 conf = conf.copy()
                 if 'source' in conf:
                     template = getattr(vm, 'template', None)
-                    if template:
+                    # recursively lookup source volume - templates may be
+                    # chained (TemplateVM -> AppVM -> DispVM, where the
+                    # actual source should be used from TemplateVM)
+                    while template:
                         # we have no control over VM load order,
                         # so initialize storage recursively if needed
                         if template.storage is None:
@@ -361,6 +364,10 @@ class Storage(object):
                         # maybe we don't need it at all if it's always from
                         # VM's template?
                         conf['source'] = template.volumes[name]
+                        if conf['source'].source is not None:
+                            template = getattr(template, 'template', None)
+                        else:
+                            break
 
                 self.init_volume(name, conf)
 

+ 10 - 3
qubes/vm/dispvm.py

@@ -21,6 +21,8 @@
 
 ''' A disposable vm implementation '''
 
+import asyncio
+
 import qubes.vm.qubesvm
 import qubes.vm.appvm
 import qubes.config
@@ -45,6 +47,7 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
                 'snap_on_start': True,
                 'save_on_stop': False,
                 'rw': False,
+                'source': None,
             },
             'private': {
                 'name': 'private',
@@ -52,6 +55,7 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
                 'snap_on_start': True,
                 'save_on_stop': False,
                 'rw': True,
+                'source': None,
             },
             'volatile': {
                 'name': 'volatile',
@@ -112,6 +116,7 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
             'Cannot change template of Disposable VM')
 
     @classmethod
+    @asyncio.coroutine
     def from_appvm(cls, appvm, **kwargs):
         '''Create a new instance from given AppVM
 
@@ -143,10 +148,11 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
         proplist = [prop for prop in dispvm.property_list()
             if prop.clone and prop.__name__ not in ['template']]
         dispvm.clone_properties(app.domains[appvm], proplist=proplist)
-        dispvm.create_on_disk()
+        yield from dispvm.create_on_disk()
         app.save()
         return dispvm
 
+    @asyncio.coroutine
     def cleanup(self):
         '''Clean up after the DispVM
 
@@ -154,9 +160,10 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
         This method modifies :file:`qubes.xml` file.
         '''
         try:
-            self.force_shutdown()
+            # pylint: disable=not-an-iterable
+            yield from self.kill()
         except qubes.exc.QubesVMNotStartedError:
             pass
-        self.remove_from_disk()
+        yield from self.remove_from_disk()
         del self.app.domains[self]
         self.app.save()