소스 검색

Implement changing the template of a DispVM

Demi Marie Obenour 3 년 전
부모
커밋
e11f94b496
2개의 변경된 파일30개의 추가작업 그리고 13개의 파일을 삭제
  1. 26 7
      qubes/vm/dispvm.py
  2. 4 6
      qubes/vm/mix/dvmtemplate.py

+ 26 - 7
qubes/vm/dispvm.py

@@ -145,14 +145,33 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
         '''  # pylint: disable=unused-argument
         assert self.template
 
-    @qubes.events.handler('property-pre-set:template',
-        'property-pre-reset:template')
-    def on_property_pre_set_template(self, event, name, newvalue=None,
+    @qubes.events.handler('property-pre-reset:template')
+    def on_property_pre_reset_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):
-        ''' Disposable VM cannot have template changed '''
-        # pylint: disable=unused-argument
-        raise qubes.exc.QubesValueError(self,
-            'Cannot change template of Disposable VM')
+        '''Forbid changing template of running VM
+        '''  # pylint: disable=unused-argument
+        if not self.is_halted():
+            raise qubes.exc.QubesVMNotHaltedError(self,
+                'Cannot change template while qube is running')
+
+    @qubes.events.handler('property-set:template')
+    def on_property_set_template(self, event, name, newvalue, oldvalue=None):
+        ''' Adjust root (and possibly other snap_on_start=True) volume
+        on template change.
+        '''  # pylint: disable=unused-argument
+
+        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()
+                self.volume_config[volume_name] = config
+                self.storage.init_volume(volume_name, config)
 
     @qubes.events.handler('domain-shutdown')
     @asyncio.coroutine

+ 4 - 6
qubes/vm/mix/dvmtemplate.py

@@ -45,14 +45,12 @@ class DVMTemplateMixin(qubes.events.Emitter):
         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,
+    @qubes.events.handler('property-set:template')
+    def __on_property_set_template(self, event, name, newvalue,
             oldvalue=None):
         # pylint: disable=unused-argument
-        if any(self.dispvms):
-            raise qubes.exc.QubesVMInUseError(self,
-                'Cannot change template '
-                'while there are DispVMs based on this qube')
+        for vm in self.dispvms:
+            vm.on_property_set_template(event, name, newvalue, oldvalue)
 
     @property
     def dispvms(self):