Fix tests for DispVMs

This commit is contained in:
Demi Marie Obenour 2020-11-27 19:32:53 -05:00
parent 13cd47ecb4
commit 88cb57ca7a
No known key found for this signature in database
GPG Key ID: 28A45C93B0B5B6E0
4 changed files with 63 additions and 61 deletions

View File

@ -228,12 +228,12 @@ class TC_00_DispVM(qubes.tests.QubesTestCase):
dispvm = self.app.add_new_vm(qubes.vm.dispvm.DispVM, dispvm = self.app.add_new_vm(qubes.vm.dispvm.DispVM,
name='test-dispvm', template=self.appvm) name='test-dispvm', template=self.appvm)
self.loop.run_until_complete(dispvm.create_on_disk()) self.loop.run_until_complete(dispvm.create_on_disk())
self.assertEqual(dispvm.template, self.appvm) self.assertIs(dispvm.template, self.appvm)
self.assertEqual(dispvm.volumes['private'].pool, self.assertIs(dispvm.volumes['private'].pool,
self.appvm.volumes['private'].pool) self.appvm.volumes['private'].pool)
self.assertEqual(dispvm.volumes['root'].pool, self.assertIs(dispvm.volumes['root'].pool,
self.appvm.volumes['root'].pool) self.appvm.volumes['root'].pool)
self.assertEqual(dispvm.volumes['volatile'].pool, self.assertIs(dispvm.volumes['volatile'].pool,
self.appvm.volumes['volatile'].pool) self.appvm.volumes['volatile'].pool)
def test_021_storage_template_change(self): def test_021_storage_template_change(self):
@ -250,6 +250,8 @@ class TC_00_DispVM(qubes.tests.QubesTestCase):
vm = self.dispvm = self.app.add_new_vm(qubes.vm.dispvm.DispVM, vm = self.dispvm = self.app.add_new_vm(qubes.vm.dispvm.DispVM,
name='test-dispvm', template=self.appvm) name='test-dispvm', template=self.appvm)
self.loop.run_until_complete(vm.create_on_disk()) self.loop.run_until_complete(vm.create_on_disk())
self.assertIs(vm.volume_config['root']['source'],
self.template.volumes['root'])
# create new mock, so new template will get different volumes # create new mock, so new template will get different volumes
self.app.pools['default'] = mock.Mock(**{ self.app.pools['default'] = mock.Mock(**{
'init_volume.return_value.pool': 'default'}) 'init_volume.return_value.pool': 'default'})
@ -261,11 +263,14 @@ class TC_00_DispVM(qubes.tests.QubesTestCase):
self.assertFalse(vm.volume_config['root']['save_on_stop']) self.assertFalse(vm.volume_config['root']['save_on_stop'])
self.assertTrue(vm.volume_config['root']['snap_on_start']) self.assertTrue(vm.volume_config['root']['snap_on_start'])
self.assertNotEqual(vm.volume_config['root'].get('source', None), self.assertNotEqual(vm.volume_config['root']['source'],
self.template.volumes['root'].source) self.template.volumes['root'])
self.assertIs(template2, self.app.domains[template2.name]) self.assertIs(vm.volume_config['root']['source'],
self.assertEqual(vm.volume_config['root'].get('source', None), template2.volumes['root'])
template2.volumes['root'].source) self.assertIs(vm.volume_config['root']['source'],
self.appvm.volume_config['root']['source'])
self.assertIs(vm.volume_config['private']['source'],
self.appvm.volumes['private'])
def test_022_storage_app_change(self): def test_022_storage_app_change(self):
self.appvm.template_for_dispvms = True self.appvm.template_for_dispvms = True
@ -302,13 +307,17 @@ class TC_00_DispVM(qubes.tests.QubesTestCase):
self.assertIs(vm, self.dispvm) self.assertIs(vm, self.dispvm)
self.assertFalse(vm.volume_config['root']['save_on_stop']) self.assertFalse(vm.volume_config['root']['save_on_stop'])
self.assertTrue(vm.volume_config['root']['snap_on_start']) self.assertTrue(vm.volume_config['root']['snap_on_start'])
self.assertNotEqual(vm.volume_config['root'].get('source', None), self.assertFalse(vm.volume_config['private']['save_on_stop'])
self.template.volumes['root'].source) self.assertTrue(vm.volume_config['private']['snap_on_start'])
self.assertNotEqual(vm.volume_config['root'].get('source', None), self.assertNotEqual(vm.volume_config['root']['source'],
self.template.volumes['root'])
self.assertNotEqual(vm.volume_config['root']['source'],
self.appvm.volumes['root'].source) self.appvm.volumes['root'].source)
self.assertNotEqual(vm.volume_config['private'].get('source', None), self.assertNotEqual(vm.volume_config['private']['source'],
self.appvm.volumes['private'].source) self.appvm.volumes['private'])
self.assertEqual(vm.volume_config['root'].get('source', None), self.assertIs(vm.volume_config['root']['source'],
app2.volumes['root']) template2.volumes['root'])
self.assertEqual(vm.volume_config['private'].get('source', None), self.assertIs(app2.volume_config['root']['source'],
template2.volumes['root'])
self.assertIs(vm.volume_config['private']['source'],
app2.volumes['private']) app2.volumes['private'])

View File

@ -29,7 +29,7 @@ from qubes.config import defaults
def template_changed_update_storage(self): def template_changed_update_storage(self):
'''Update storage configuration for TemplateVM changes''' '''Update storage configuration for TemplateVM changes'''
for volume_name, conf in self.volume_config.items(): for volume_name, conf in self.default_volume_config.items():
if conf.get('snap_on_start', False) and \ if conf.get('snap_on_start', False) and \
conf.get('source', None) is None: conf.get('source', None) is None:
config = conf.copy() config = conf.copy()

View File

@ -20,7 +20,7 @@
''' A disposable vm implementation ''' ''' A disposable vm implementation '''
import asyncio import asyncio, copy
import qubes.vm.qubesvm import qubes.vm.qubesvm
import qubes.vm.appvm import qubes.vm.appvm
@ -57,38 +57,39 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
default=(lambda self: self.template), default=(lambda self: self.template),
doc='Default VM to be used as Disposable VM for service calls.') doc='Default VM to be used as Disposable VM for service calls.')
def __init__(self, app, xml, *args, **kwargs): default_volume_config = {
self.volume_config = { 'root': {
'root': { 'name': 'root',
'name': 'root', 'snap_on_start': True,
'snap_on_start': True, 'save_on_stop': False,
'save_on_stop': False, 'rw': True,
'rw': True, 'source': None,
'source': None, },
}.copy(), 'private': {
'private': { 'name': 'private',
'name': 'private', 'snap_on_start': True,
'snap_on_start': True, 'save_on_stop': False,
'save_on_stop': False, 'rw': True,
'rw': True, 'source': None,
'source': None, },
}.copy(), 'volatile': {
'volatile': { 'name': 'volatile',
'name': 'volatile', 'snap_on_start': False,
'snap_on_start': False, 'save_on_stop': False,
'save_on_stop': False, 'rw': True,
'rw': True, 'size': qubes.config.defaults['root_img_size'] +
'size': qubes.config.defaults['root_img_size'] + qubes.config.defaults['private_img_size'],
qubes.config.defaults['private_img_size'], },
}.copy(), 'kernel': {
'kernel': { 'name': 'kernel',
'name': 'kernel', 'snap_on_start': False,
'snap_on_start': False, 'save_on_stop': False,
'save_on_stop': False, 'rw': False,
'rw': False, },
}.copy() }
}
def __init__(self, app, xml, *args, **kwargs):
self.volume_config = copy.deepcopy(self.default_volume_config)
template = kwargs.get('template', None) template = kwargs.get('template', None)
if xml is None: if xml is None:
@ -147,7 +148,7 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
@qubes.events.handler('property-pre-reset:template') @qubes.events.handler('property-pre-reset:template')
def on_property_pre_reset_template(self, event, name, oldvalue=None): def on_property_pre_reset_template(self, event, name, oldvalue=None):
'''Forbid deleting template of running VM '''Forbid deleting template of VM
''' # pylint: disable=unused-argument,no-self-use ''' # pylint: disable=unused-argument,no-self-use
raise qubes.exc.QubesValueError('Cannot unset template') raise qubes.exc.QubesValueError('Cannot unset template')
@ -165,13 +166,7 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
''' Adjust root (and possibly other snap_on_start=True) volume ''' Adjust root (and possibly other snap_on_start=True) volume
on template change. on template change.
''' # pylint: disable=unused-argument ''' # pylint: disable=unused-argument
for volume_name, conf in self.volume_config.items(): qubes.vm.appvm.template_changed_update_storage(self)
if conf.get('snap_on_start', False) and \
conf.get('source', None) is None:
config = conf.copy()
self.volume_config[volume_name] = config
self.storage.init_volume(volume_name, config)
qubes.vm.appvm.template_changed_update_storage(self)
@qubes.events.handler('domain-shutdown') @qubes.events.handler('domain-shutdown')
@asyncio.coroutine @asyncio.coroutine

View File

@ -50,9 +50,7 @@ class DVMTemplateMixin(qubes.events.Emitter):
oldvalue=None): oldvalue=None):
# pylint: disable=unused-argument # pylint: disable=unused-argument
for vm in self.dispvms: for vm in self.dispvms:
running = vm.is_running() if vm.is_running():
assert type(running) is bool
if running:
raise qubes.exc.QubesVMNotHaltedError(self, raise qubes.exc.QubesVMNotHaltedError(self,
'Cannot change template while there are running DispVMs ' 'Cannot change template while there are running DispVMs '
'based on this DVM template') 'based on this DVM template')