From c965024287d6263974731696513ef028655fa951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Fri, 20 May 2016 03:58:57 +0200 Subject: [PATCH] qubes/vm: Implement Disposable VM Implement DispVM as a VM based on AppVM. QubesOS/qubes-issues#866 --- qubes/tests/storage_file.py | 19 ++++++++++---- qubes/vm/appvm.py | 2 +- qubes/vm/dispvm.py | 50 +++++++++++++++++++++++++++++++++++-- setup.py | 1 + 4 files changed, 64 insertions(+), 8 deletions(-) diff --git a/qubes/tests/storage_file.py b/qubes/tests/storage_file.py index 6adcc0c2..14005490 100644 --- a/qubes/tests/storage_file.py +++ b/qubes/tests/storage_file.py @@ -162,12 +162,13 @@ class TC_01_FileVolumes(SystemTestsMixin, QubesTestCase): volumes = vm.volumes self.assertIsInstance(volumes['root'], SnapshotFile) - self.assertIsInstance(volumes['private'], ReadWriteFile) + self.assertIsInstance(volumes['private'], OriginFile) self.assertIsInstance(volumes['volatile'], VolatileFile) expected = vm.template.dir_path + '/root.img:' + vm.template.dir_path \ + '/root-cow.img' self.assertVolumePath(vm, 'root', expected, rw=False) - expected = vm.dir_path + '/private.img' + expected = vm.dir_path + '/private.img:' + \ + vm.dir_path + '/private-cow.img' self.assertVolumePath(vm, 'private', expected, rw=True) expected = vm.dir_path + '/volatile.img' self.assertVolumePath(vm, 'volatile', expected, rw=True) @@ -264,9 +265,17 @@ class TC_03_FilePool(SystemTestsMixin, QubesTestCase): expected_vmdir = os.path.join(self.APPVMS_DIR, vm.name) - expected_private_path = os.path.join(expected_vmdir, 'private.img') - self.assertEqualsAndExists(vm.volumes['private'].path, - expected_private_path) + expected_private_origin_path = \ + os.path.join(expected_vmdir, 'private.img') + expected_private_cow_path = \ + os.path.join(expected_vmdir, 'private-cow.img') + expected_private_path = '%s:%s' % (expected_private_origin_path, + expected_private_cow_path) + self.assertEquals(vm.volumes['private'].path, expected_private_path) + self.assertEqualsAndExists(vm.volumes['private'].path_origin, + expected_private_origin_path) + self.assertEqualsAndExists(vm.volumes['private'].path_cow, + expected_private_cow_path) expected_volatile_path = os.path.join(expected_vmdir, 'volatile.img') self.assertEqualsAndExists(vm.volumes['volatile'].path, diff --git a/qubes/vm/appvm.py b/qubes/vm/appvm.py index d310ca99..8544335b 100644 --- a/qubes/vm/appvm.py +++ b/qubes/vm/appvm.py @@ -26,7 +26,7 @@ class AppVM(qubes.vm.qubesvm.QubesVM): 'private': { 'name': 'private', 'pool': 'default', - 'volume_type': 'read-write', + 'volume_type': 'origin', 'size': defaults['private_img_size'], }, 'volatile': { diff --git a/qubes/vm/dispvm.py b/qubes/vm/dispvm.py index 6aabd28f..84ba9d15 100644 --- a/qubes/vm/dispvm.py +++ b/qubes/vm/dispvm.py @@ -2,8 +2,54 @@ # vim: fileencoding=utf-8 import qubes.vm.qubesvm +import qubes.vm.appvm +import qubes.config class DispVM(qubes.vm.qubesvm.QubesVM): '''Disposable VM''' - def __init__(self, D): - super(DispVM, self).__init__(D) + + template = qubes.VMProperty('template', + load_stage=4, + vmclass=qubes.vm.appvm.AppVM, + ls_width=31, + doc='AppVM, on which this DispVM is based.') + + dispid = qubes.property('dispid', type=int, write_once=True, + clone=False, + ls_width=3, + doc='''Internal, persistent identifier of particular DispVM.''') + + def __init__(self, *args, **kwargs): + self.volumes = {} + self.volume_config = { + 'root': { + 'name': 'root', + 'pool': 'default', + 'volume_type': 'snapshot', + }, + 'private': { + 'name': 'private', + 'pool': 'default', + 'volume_type': 'snapshot', + }, + 'volatile': { + 'name': 'volatile', + 'pool': 'default', + 'volume_type': 'volatile', + 'size': qubes.config.defaults['root_img_size'] + + qubes.config.defaults['private_img_size'], + }, + 'kernel': { + 'name': 'kernel', + 'pool': 'linux-kernel', + 'volume_type': 'read-only', + } + } + super(DispVM, self).__init__(*args, **kwargs) + + @qubes.events.handler('domain-load') + def on_domain_loaded(self, event): + # pylint: disable=unused-argument + # Some additional checks for template based VM + assert self.template + # self.template.appvms.add(self) # XXX diff --git a/setup.py b/setup.py index 67226e80..bc10ce5e 100644 --- a/setup.py +++ b/setup.py @@ -34,6 +34,7 @@ if __name__ == '__main__': 'TemplateVM = qubes.vm.templatevm:TemplateVM', 'StandaloneVM = qubes.vm.standalonevm:StandaloneVM', 'AdminVM = qubes.vm.adminvm:AdminVM', + 'DispVM = qubes.vm.dispvm:DispVM', ], 'qubes.ext': [ 'qubes.ext.qubesmanager = qubes.ext.qubesmanager:QubesManager',