Explorar o código

qubes/dispvm: misc fixes, make it actually working

- DispVM is no longer a special case for storage
- Add missing 'rw=True' for volatile volume
- Handle storage initialization (copy&paste from AppVM)
- Clone properties from DispVM template

QubesOS/qubes-issues#2253
Marek Marczykowski-Górecki %!s(int64=7) %!d(string=hai) anos
pai
achega
ab6f961931
Modificáronse 3 ficheiros con 38 adicións e 4 borrados
  1. 1 1
      qubes/app.py
  2. 0 3
      qubes/storage/file.py
  3. 37 0
      qubes/vm/dispvm.py

+ 1 - 1
qubes/app.py

@@ -507,7 +507,7 @@ class VMCollection(object):
 
 
     def get_new_unused_dispid(self):
-        for _ in range(qubes.config.max_dispid ** 0.5):
+        for _ in range(int(qubes.config.max_dispid ** 0.5)):
             dispid = random.SystemRandom().randrange(qubes.config.max_dispid)
             if not any(getattr(vm, 'dispid', None) == dispid for vm in self):
                 return dispid

+ 0 - 3
qubes/storage/file.py

@@ -260,9 +260,6 @@ class FilePool(qubes.storage.Pool):
         import qubes.vm.dispvm  # pylint: disable=redefined-outer-name
         if isinstance(vm, qubes.vm.templatevm.TemplateVM):
             subdir = 'vm-templates'
-        elif isinstance(vm, qubes.vm.dispvm.DispVM):
-            subdir = 'appvms'
-            return os.path.join(subdir, vm.template.name + '-dvm')
         else:
             subdir = 'appvms'
 

+ 37 - 0
qubes/vm/dispvm.py

@@ -22,6 +22,7 @@
 #
 
 ''' A disposable vm implementation '''
+import copy
 
 import qubes.vm.qubesvm
 import qubes.vm.appvm
@@ -63,6 +64,7 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
                 'name': 'volatile',
                 'pool': 'default',
                 'internal': True,
+                'rw': True,
                 'size': qubes.config.defaults['root_img_size'] +
                         qubes.config.defaults['private_img_size'],
             },
@@ -74,6 +76,40 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
                 'internal': True
             }
         }
+        if 'name' not in kwargs and 'dispid' in kwargs:
+            kwargs['name'] = 'disp' + str(kwargs['dispid'])
+        template = kwargs.get('template', None)
+
+        if template is not None:
+            # template is only passed if the AppVM is created, in other cases we
+            # don't need to patch the volume_config because the config is
+            # coming from XML, already as we need it
+
+            for name, conf in self.volume_config.items():
+                tpl_volume = template.volumes[name]
+
+                conf['size'] = tpl_volume.size
+                conf['pool'] = tpl_volume.pool
+
+                has_source = ('source' in conf and conf['source'] is not None)
+                is_snapshot = 'snap_on_start' in conf and conf['snap_on_start']
+                if is_snapshot and not has_source:
+                    if tpl_volume.source is not None:
+                        conf['source'] = tpl_volume.source
+                    else:
+                        conf['source'] = tpl_volume.vid
+
+            for name, config in template.volume_config.items():
+                # in case the template vm has more volumes add them to own
+                # config
+                if name not in self.volume_config:
+                    self.volume_config[name] = copy.deepcopy(config)
+                    if 'vid' in self.volume_config[name]:
+                        del self.volume_config[name]['vid']
+
+            # by default inherit label from the DispVM template
+            if 'label' not in kwargs:
+                kwargs['label'] = template.label
 
         super(DispVM, self).__init__(*args, **kwargs)
 
@@ -109,6 +145,7 @@ class DispVM(qubes.vm.qubesvm.QubesVM):
             dispid=app.domains.get_new_unused_dispid(),
             template=app.domains[appvm],
             **kwargs)
+        dispvm.clone_properties(app.domains[appvm])
         dispvm.create_on_disk()
         app.save()
         return dispvm