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
This commit is contained in:
Marek Marczykowski-Górecki 2017-07-14 01:13:20 +02:00
commit ab7ed776f9
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
3 changed files with 20 additions and 8 deletions

View File

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

View File

@ -352,7 +352,10 @@ class Storage(object):
conf = conf.copy() conf = conf.copy()
if 'source' in conf: if 'source' in conf:
template = getattr(vm, 'template', None) 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, # we have no control over VM load order,
# so initialize storage recursively if needed # so initialize storage recursively if needed
if template.storage is None: 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 # maybe we don't need it at all if it's always from
# VM's template? # VM's template?
conf['source'] = template.volumes[name] conf['source'] = template.volumes[name]
if conf['source'].source is not None:
template = getattr(template, 'template', None)
else:
break
self.init_volume(name, conf) self.init_volume(name, conf)

View File

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