vm: do not allow deleting template property from AppVM and DispVM

There is intentionally no default template in terms of qubes.property
definition, to not cause problems when switching global default_template
property - like breaking some VMs, or forcing the user to shutdown all
of them for this. But this also means it shouldn't be allowed to reset
template to "default" value, because it will result in a VM without
template at all.

Fixes QubesOS/qubes-issues#3115
This commit is contained in:
Marek Marczykowski-Górecki 2017-09-23 16:02:01 +02:00
parent efe600537e
commit dc0e1a5481
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
4 changed files with 32 additions and 2 deletions

View File

@ -130,6 +130,11 @@ class TC_90_AppVM(qubes.tests.vm.qubesvm.QubesVMTestsMixin,
with self.assertRaises(qubes.exc.QubesVMNotHaltedError):
vm.template = self.template
def test_004_template_reset(self):
vm = self.get_vm()
with self.assertRaises(qubes.exc.QubesValueError):
vm.template = qubes.property.DEFAULT
def test_500_property_migrate_template_for_dispvms(self):
xml_template = '''
<domain class="AppVM" id="domain-1">

View File

@ -103,6 +103,24 @@ class TC_00_DispVM(qubes.tests.QubesTestCase):
dispvm = self.loop.run_until_complete(
qubes.vm.dispvm.DispVM.from_appvm(self.appvm))
def test_002_template_change(self):
self.appvm.template_for_dispvms = True
orig_getitem = self.app.domains.__getitem__
with mock.patch.object(self.app, 'domains', wraps=self.app.domains) \
as mock_domains:
mock_domains.configure_mock(**{
'get_new_unused_dispid': mock.Mock(return_value=42),
'__getitem__.side_effect': orig_getitem
})
dispvm = self.app.add_new_vm(qubes.vm.dispvm.DispVM,
name='test-dispvm', template=self.appvm)
with self.assertRaises(qubes.exc.QubesValueError):
dispvm.template = self.appvm
with self.assertRaises(qubes.exc.QubesValueError):
dispvm.template = qubes.property.DEFAULT
def test_010_create_direct(self):
self.appvm.template_for_dispvms = True
orig_getitem = self.app.domains.__getitem__

View File

@ -104,6 +104,12 @@ class AppVM(qubes.vm.qubesvm.QubesVM):
''' # pylint: disable=unused-argument
assert self.template
@qubes.events.handler('property-pre-del:template')
def on_property_pre_del_template(self, event, name, oldvalue=None):
'''Forbid deleting template of running VM
''' # pylint: disable=unused-argument,no-self-use
raise qubes.exc.QubesValueError('Cannot unset template')
@qubes.events.handler('property-pre-set:template')
def on_property_pre_set_template(self, event, name, newvalue,
oldvalue=None):

View File

@ -121,8 +121,9 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
''' # pylint: disable=unused-argument
assert self.template
@qubes.events.handler('property-pre-set:template')
def on_property_pre_set_template(self, event, name, newvalue,
@qubes.events.handler('property-pre-set:template',
'property-pre-del:template')
def on_property_pre_set_template(self, event, name, newvalue=None,
oldvalue=None):
''' Disposable VM cannot have template changed '''
# pylint: disable=unused-argument