vm: do not allow setting template_for_dispvms=False if there are any DispVMs
Setting template_for_dispvms=False will at least prevent starting (already existing) DispVMs based on it. Those should be first removed. Add also tests for this case.
This commit is contained in:
parent
4a3772bb57
commit
8041b72e42
@ -48,6 +48,9 @@ class TestVMsCollection(dict):
|
||||
def close(self):
|
||||
self.clear()
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.values())
|
||||
|
||||
class TestVolume(object):
|
||||
def __init__(self, pool):
|
||||
self.pool = pool
|
||||
|
@ -60,6 +60,9 @@ class TC_00_DispVM(qubes.tests.QubesTestCase):
|
||||
self.addCleanup(self.cleanup_dispvm)
|
||||
|
||||
def cleanup_dispvm(self):
|
||||
if hasattr(self, 'dispvm'):
|
||||
self.dispvm.close()
|
||||
del self.dispvm
|
||||
self.template.close()
|
||||
self.appvm.close()
|
||||
del self.template
|
||||
@ -120,6 +123,41 @@ class TC_00_DispVM(qubes.tests.QubesTestCase):
|
||||
with self.assertRaises(qubes.exc.QubesValueError):
|
||||
dispvm.template = qubes.property.DEFAULT
|
||||
|
||||
def test_003_dvmtemplate_template_change(self):
|
||||
self.appvm.template_for_dispvms = True
|
||||
orig_domains = self.app.domains
|
||||
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_domains.__getitem__,
|
||||
'__iter__.side_effect': orig_domains.__iter__,
|
||||
'__setitem__.side_effect': orig_domains.__setitem__,
|
||||
})
|
||||
self.dispvm = self.app.add_new_vm(qubes.vm.dispvm.DispVM,
|
||||
name='test-dispvm', template=self.appvm)
|
||||
|
||||
with self.assertRaises(qubes.exc.QubesVMInUseError):
|
||||
self.appvm.template = self.template
|
||||
with self.assertRaises(qubes.exc.QubesValueError):
|
||||
self.appvm.template = qubes.property.DEFAULT
|
||||
|
||||
def test_004_dvmtemplate_allowed_change(self):
|
||||
self.appvm.template_for_dispvms = True
|
||||
orig_domains = self.app.domains
|
||||
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_domains.__getitem__,
|
||||
'__iter__.side_effect': orig_domains.__iter__,
|
||||
'__setitem__.side_effect': orig_domains.__setitem__,
|
||||
})
|
||||
self.dispvm = self.app.add_new_vm(qubes.vm.dispvm.DispVM,
|
||||
name='test-dispvm', template=self.appvm)
|
||||
|
||||
with self.assertRaises(qubes.exc.QubesVMInUseError):
|
||||
self.appvm.template_for_dispvms = False
|
||||
|
||||
def test_010_create_direct(self):
|
||||
self.appvm.template_for_dispvms = True
|
||||
|
@ -28,6 +28,23 @@ class DVMTemplateMixin(qubes.events.Emitter):
|
||||
default=False,
|
||||
doc='Should this VM be allowed to start as Disposable VM')
|
||||
|
||||
@qubes.events.handler('property-pre-set:template_for_dispvms')
|
||||
def __on_pre_set_dvmtemplate(self, event, name,
|
||||
newvalue, oldvalue=None):
|
||||
# pylint: disable=unused-argument
|
||||
if newvalue:
|
||||
return
|
||||
if any(self.dispvms):
|
||||
raise qubes.exc.QubesVMInUseError(self,
|
||||
'Cannot change template_for_dispvms to False while there are '
|
||||
'some DispVMs based on this DVM template')
|
||||
|
||||
@qubes.events.handler('property-pre-del:template_for_dispvms')
|
||||
def __on_pre_del_dvmtemplate(self, event, name,
|
||||
oldvalue=None):
|
||||
self.__on_pre_set_dvmtemplate(
|
||||
event, name, False, oldvalue)
|
||||
|
||||
@qubes.events.handler('property-pre-set:template')
|
||||
def __on_property_pre_set_template(self, event, name, newvalue,
|
||||
oldvalue=None):
|
||||
|
Loading…
Reference in New Issue
Block a user