From 88cb57ca7acff875b3b31b4c9e65ecd948374ab9 Mon Sep 17 00:00:00 2001 From: Demi Marie Obenour Date: Fri, 27 Nov 2020 19:32:53 -0500 Subject: [PATCH] Fix tests for DispVMs --- qubes/tests/vm/dispvm.py | 43 ++++++++++++--------- qubes/vm/appvm.py | 2 +- qubes/vm/dispvm.py | 75 +++++++++++++++++-------------------- qubes/vm/mix/dvmtemplate.py | 4 +- 4 files changed, 63 insertions(+), 61 deletions(-) diff --git a/qubes/tests/vm/dispvm.py b/qubes/tests/vm/dispvm.py index 15dc5aad..cb5fb55d 100644 --- a/qubes/tests/vm/dispvm.py +++ b/qubes/tests/vm/dispvm.py @@ -228,12 +228,12 @@ class TC_00_DispVM(qubes.tests.QubesTestCase): dispvm = self.app.add_new_vm(qubes.vm.dispvm.DispVM, name='test-dispvm', template=self.appvm) self.loop.run_until_complete(dispvm.create_on_disk()) - self.assertEqual(dispvm.template, self.appvm) - self.assertEqual(dispvm.volumes['private'].pool, + self.assertIs(dispvm.template, self.appvm) + self.assertIs(dispvm.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.assertEqual(dispvm.volumes['volatile'].pool, + self.assertIs(dispvm.volumes['volatile'].pool, self.appvm.volumes['volatile'].pool) 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, name='test-dispvm', template=self.appvm) 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 self.app.pools['default'] = mock.Mock(**{ '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.assertTrue(vm.volume_config['root']['snap_on_start']) - self.assertNotEqual(vm.volume_config['root'].get('source', None), - self.template.volumes['root'].source) - self.assertIs(template2, self.app.domains[template2.name]) - self.assertEqual(vm.volume_config['root'].get('source', None), - template2.volumes['root'].source) + self.assertNotEqual(vm.volume_config['root']['source'], + self.template.volumes['root']) + self.assertIs(vm.volume_config['root']['source'], + template2.volumes['root']) + 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): self.appvm.template_for_dispvms = True @@ -302,13 +307,17 @@ class TC_00_DispVM(qubes.tests.QubesTestCase): self.assertIs(vm, self.dispvm) self.assertFalse(vm.volume_config['root']['save_on_stop']) self.assertTrue(vm.volume_config['root']['snap_on_start']) - self.assertNotEqual(vm.volume_config['root'].get('source', None), - self.template.volumes['root'].source) - self.assertNotEqual(vm.volume_config['root'].get('source', None), + self.assertFalse(vm.volume_config['private']['save_on_stop']) + self.assertTrue(vm.volume_config['private']['snap_on_start']) + self.assertNotEqual(vm.volume_config['root']['source'], + self.template.volumes['root']) + self.assertNotEqual(vm.volume_config['root']['source'], self.appvm.volumes['root'].source) - self.assertNotEqual(vm.volume_config['private'].get('source', None), - self.appvm.volumes['private'].source) - self.assertEqual(vm.volume_config['root'].get('source', None), - app2.volumes['root']) - self.assertEqual(vm.volume_config['private'].get('source', None), + self.assertNotEqual(vm.volume_config['private']['source'], + self.appvm.volumes['private']) + self.assertIs(vm.volume_config['root']['source'], + template2.volumes['root']) + self.assertIs(app2.volume_config['root']['source'], + template2.volumes['root']) + self.assertIs(vm.volume_config['private']['source'], app2.volumes['private']) diff --git a/qubes/vm/appvm.py b/qubes/vm/appvm.py index 4e23abe0..6032754f 100644 --- a/qubes/vm/appvm.py +++ b/qubes/vm/appvm.py @@ -29,7 +29,7 @@ from qubes.config import defaults def template_changed_update_storage(self): '''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 \ conf.get('source', None) is None: config = conf.copy() diff --git a/qubes/vm/dispvm.py b/qubes/vm/dispvm.py index 342190aa..6358332b 100644 --- a/qubes/vm/dispvm.py +++ b/qubes/vm/dispvm.py @@ -20,7 +20,7 @@ ''' A disposable vm implementation ''' -import asyncio +import asyncio, copy import qubes.vm.qubesvm import qubes.vm.appvm @@ -57,38 +57,39 @@ class DispVM(qubes.vm.qubesvm.QubesVM): default=(lambda self: self.template), doc='Default VM to be used as Disposable VM for service calls.') - def __init__(self, app, xml, *args, **kwargs): - self.volume_config = { - 'root': { - 'name': 'root', - 'snap_on_start': True, - 'save_on_stop': False, - 'rw': True, - 'source': None, - }.copy(), - 'private': { - 'name': 'private', - 'snap_on_start': True, - 'save_on_stop': False, - 'rw': True, - 'source': None, - }.copy(), - 'volatile': { - 'name': 'volatile', - 'snap_on_start': False, - 'save_on_stop': False, - 'rw': True, - 'size': qubes.config.defaults['root_img_size'] + - qubes.config.defaults['private_img_size'], - }.copy(), - 'kernel': { - 'name': 'kernel', - 'snap_on_start': False, - 'save_on_stop': False, - 'rw': False, - }.copy() - } + default_volume_config = { + 'root': { + 'name': 'root', + 'snap_on_start': True, + 'save_on_stop': False, + 'rw': True, + 'source': None, + }, + 'private': { + 'name': 'private', + 'snap_on_start': True, + 'save_on_stop': False, + 'rw': True, + 'source': None, + }, + 'volatile': { + 'name': 'volatile', + 'snap_on_start': False, + 'save_on_stop': False, + 'rw': True, + 'size': qubes.config.defaults['root_img_size'] + + qubes.config.defaults['private_img_size'], + }, + 'kernel': { + 'name': 'kernel', + 'snap_on_start': False, + 'save_on_stop': False, + 'rw': False, + }, + } + def __init__(self, app, xml, *args, **kwargs): + self.volume_config = copy.deepcopy(self.default_volume_config) template = kwargs.get('template', None) if xml is None: @@ -147,7 +148,7 @@ class DispVM(qubes.vm.qubesvm.QubesVM): @qubes.events.handler('property-pre-reset:template') 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 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 on template change. ''' # pylint: disable=unused-argument - for volume_name, conf in self.volume_config.items(): - 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.vm.appvm.template_changed_update_storage(self) @qubes.events.handler('domain-shutdown') @asyncio.coroutine diff --git a/qubes/vm/mix/dvmtemplate.py b/qubes/vm/mix/dvmtemplate.py index f2692f58..7106aad8 100644 --- a/qubes/vm/mix/dvmtemplate.py +++ b/qubes/vm/mix/dvmtemplate.py @@ -50,9 +50,7 @@ class DVMTemplateMixin(qubes.events.Emitter): oldvalue=None): # pylint: disable=unused-argument for vm in self.dispvms: - running = vm.is_running() - assert type(running) is bool - if running: + if vm.is_running(): raise qubes.exc.QubesVMNotHaltedError(self, 'Cannot change template while there are running DispVMs ' 'based on this DVM template')