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):
|
def close(self):
|
||||||
self.clear()
|
self.clear()
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(self.values())
|
||||||
|
|
||||||
class TestVolume(object):
|
class TestVolume(object):
|
||||||
def __init__(self, pool):
|
def __init__(self, pool):
|
||||||
self.pool = pool
|
self.pool = pool
|
||||||
|
@ -60,6 +60,9 @@ class TC_00_DispVM(qubes.tests.QubesTestCase):
|
|||||||
self.addCleanup(self.cleanup_dispvm)
|
self.addCleanup(self.cleanup_dispvm)
|
||||||
|
|
||||||
def cleanup_dispvm(self):
|
def cleanup_dispvm(self):
|
||||||
|
if hasattr(self, 'dispvm'):
|
||||||
|
self.dispvm.close()
|
||||||
|
del self.dispvm
|
||||||
self.template.close()
|
self.template.close()
|
||||||
self.appvm.close()
|
self.appvm.close()
|
||||||
del self.template
|
del self.template
|
||||||
@ -120,6 +123,41 @@ class TC_00_DispVM(qubes.tests.QubesTestCase):
|
|||||||
with self.assertRaises(qubes.exc.QubesValueError):
|
with self.assertRaises(qubes.exc.QubesValueError):
|
||||||
dispvm.template = qubes.property.DEFAULT
|
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):
|
def test_010_create_direct(self):
|
||||||
self.appvm.template_for_dispvms = True
|
self.appvm.template_for_dispvms = True
|
||||||
|
@ -28,6 +28,23 @@ class DVMTemplateMixin(qubes.events.Emitter):
|
|||||||
default=False,
|
default=False,
|
||||||
doc='Should this VM be allowed to start as Disposable VM')
|
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')
|
@qubes.events.handler('property-pre-set:template')
|
||||||
def __on_property_pre_set_template(self, event, name, newvalue,
|
def __on_property_pre_set_template(self, event, name, newvalue,
|
||||||
oldvalue=None):
|
oldvalue=None):
|
||||||
|
Loading…
Reference in New Issue
Block a user