Merge branch 'master' into hvm
Conflicts: dom0/qvm-core/qubes.py dom0/qvm-tools/qvm-create dom0/qvm-tools/qvm-prefs
This commit is contained in:
		
						commit
						3171cdbdcc
					
				| @ -18,7 +18,7 @@ def main(): | |||||||
|         print templ, 'is not a template' |         print templ, 'is not a template' | ||||||
|         sys.exit(1) |         sys.exit(1) | ||||||
|     for vm in qvm_collection.values(): |     for vm in qvm_collection.values(): | ||||||
|         if vm.template_vm is not None and vm.template_vm.qid == tvm.qid: |         if vm.template is not None and vm.template.qid == tvm.qid: | ||||||
|             vm.create_config_file() |             vm.create_config_file() | ||||||
|      |      | ||||||
| main() | main() | ||||||
|  | |||||||
| @ -235,8 +235,7 @@ class QubesVm(object): | |||||||
|             "volatile_img": { "eval": 'self.absolute_path(value, default_volatile_img)', 'order': 10 }, |             "volatile_img": { "eval": 'self.absolute_path(value, default_volatile_img)', 'order': 10 }, | ||||||
|             "firewall_conf": { "eval": 'self.absolute_path(value, default_firewall_conf_file)', 'order': 10 }, |             "firewall_conf": { "eval": 'self.absolute_path(value, default_firewall_conf_file)', 'order': 10 }, | ||||||
|             "installed_by_rpm": { "default": False, 'order': 10 }, |             "installed_by_rpm": { "default": False, 'order': 10 }, | ||||||
|             "updateable": { "default": False, 'order': 10 }, |             "template": { "default": None, 'order': 10 }, | ||||||
|             "template_vm": { "default": None, 'order': 10 }, |  | ||||||
|             # order >= 20: have template set |             # order >= 20: have template set | ||||||
|             "uses_default_netvm": { "default": True, 'order': 20 }, |             "uses_default_netvm": { "default": True, 'order': 20 }, | ||||||
|             "netvm": { "default": None, "attr": "_netvm", 'order': 20 }, |             "netvm": { "default": None, "attr": "_netvm", 'order': 20 }, | ||||||
| @ -249,7 +248,7 @@ class QubesVm(object): | |||||||
|             "internal": { "default": False }, |             "internal": { "default": False }, | ||||||
|             "vcpus": { "default": None }, |             "vcpus": { "default": None }, | ||||||
|             "kernel": { "default": None, 'eval': \ |             "kernel": { "default": None, 'eval': \ | ||||||
|                 'self.template_vm.kernel if self.template_vm is not None else value' }, |                 'self.template.kernel if self.template is not None else value' }, | ||||||
|             "uses_default_kernel": { "default": True }, |             "uses_default_kernel": { "default": True }, | ||||||
|             "uses_default_kernelopts": { "default": True }, |             "uses_default_kernelopts": { "default": True }, | ||||||
|             "kernelopts": { "default": "", "eval": \ |             "kernelopts": { "default": "", "eval": \ | ||||||
| @ -260,10 +259,10 @@ class QubesVm(object): | |||||||
|             ##### Internal attributes - will be overriden in __init__ regardless of args |             ##### Internal attributes - will be overriden in __init__ regardless of args | ||||||
|             "appmenus_templates_dir": { "eval": \ |             "appmenus_templates_dir": { "eval": \ | ||||||
|                 'self.dir_path + "/" + default_appmenus_templates_subdir if self.updateable else ' + \ |                 'self.dir_path + "/" + default_appmenus_templates_subdir if self.updateable else ' + \ | ||||||
|                 'self.template_vm.appmenus_templates_dir if self.template_vm is not None else None' }, |                 'self.template.appmenus_templates_dir if self.template is not None else None' }, | ||||||
|             "config_file_template": { "eval": "config_template_pv" }, |             "config_file_template": { "eval": "config_template_pv" }, | ||||||
|             "icon_path": { "eval": 'self.dir_path + "/icon.png" if self.dir_path is not None else None' }, |             "icon_path": { "eval": 'self.dir_path + "/icon.png" if self.dir_path is not None else None' }, | ||||||
|             "kernels_dir": { 'eval': 'self.template_vm.kernels_dir if self.template_vm is not None else ' + \ |             "kernels_dir": { 'eval': 'self.template.kernels_dir if self.template is not None else ' + \ | ||||||
|                 'qubes_kernels_base_dir + "/" + self.kernel if self.kernel is not None else ' + \ |                 'qubes_kernels_base_dir + "/" + self.kernel if self.kernel is not None else ' + \ | ||||||
|                 # for backward compatibility (or another rare case): kernel=None -> kernel in VM dir |                 # for backward compatibility (or another rare case): kernel=None -> kernel in VM dir | ||||||
|                 'self.dir_path + "/" + default_kernels_subdir' }, |                 'self.dir_path + "/" + default_kernels_subdir' }, | ||||||
| @ -273,7 +272,7 @@ class QubesVm(object): | |||||||
|         # Simple string attrs |         # Simple string attrs | ||||||
|         for prop in ['qid', 'name', 'dir_path', 'memory', 'maxmem', 'pcidevs', 'vcpus', 'internal',\ |         for prop in ['qid', 'name', 'dir_path', 'memory', 'maxmem', 'pcidevs', 'vcpus', 'internal',\ | ||||||
|             'uses_default_kernel', 'kernel', 'uses_default_kernelopts',\ |             'uses_default_kernel', 'kernel', 'uses_default_kernelopts',\ | ||||||
|             'kernelopts', 'services', 'updateable', 'installed_by_rpm',\ |             'kernelopts', 'services', 'installed_by_rpm',\ | ||||||
|             'uses_default_netvm', 'include_in_backups' ]: |             'uses_default_netvm', 'include_in_backups' ]: | ||||||
|             attrs[prop]['save'] = 'str(self.%s)' % prop |             attrs[prop]['save'] = 'str(self.%s)' % prop | ||||||
|         # Simple paths |         # Simple paths | ||||||
| @ -286,8 +285,8 @@ class QubesVm(object): | |||||||
| 
 | 
 | ||||||
|         attrs['netvm']['save'] = 'str(self.netvm.qid) if self.netvm is not None else "none"' |         attrs['netvm']['save'] = 'str(self.netvm.qid) if self.netvm is not None else "none"' | ||||||
|         attrs['netvm']['save_attr'] = "netvm_qid" |         attrs['netvm']['save_attr'] = "netvm_qid" | ||||||
|         attrs['template_vm']['save'] = 'str(self.template_vm.qid) if self.template_vm and not self.is_updateable() else "none"' |         attrs['template']['save'] = 'str(self.template.qid) if self.template else "none"' | ||||||
|         attrs['template_vm']['save_attr'] = "template_qid" |         attrs['template']['save_attr'] = "template_qid" | ||||||
|         attrs['label']['save'] = 'self.label.name' |         attrs['label']['save'] = 'self.label.name' | ||||||
| 
 | 
 | ||||||
|         return attrs |         return attrs | ||||||
| @ -333,15 +332,12 @@ class QubesVm(object): | |||||||
|             self.vcpus = qubes_host.no_cpus |             self.vcpus = qubes_host.no_cpus | ||||||
| 
 | 
 | ||||||
|         # Some additional checks for template based VM |         # Some additional checks for template based VM | ||||||
|         if self.template_vm is not None: |         if self.template is not None: | ||||||
|             if self.updateable: |             if not self.template.is_template(): | ||||||
|                 print >> sys.stderr, "ERROR: Template based VM cannot be updateable!" |  | ||||||
|                 return False |  | ||||||
|             if not self.template_vm.is_template(): |  | ||||||
|                 print >> sys.stderr, "ERROR: template_qid={0} doesn't point to a valid TemplateVM".\ |                 print >> sys.stderr, "ERROR: template_qid={0} doesn't point to a valid TemplateVM".\ | ||||||
|                     format(self.template_vm.qid) |                     format(self.template.qid) | ||||||
|                 return False |                 return False | ||||||
|             self.template_vm.appvms[self.qid] = self |             self.template.appvms[self.qid] = self | ||||||
|         else: |         else: | ||||||
|             assert self.root_img is not None, "Missing root_img for standalone VM!" |             assert self.root_img is not None, "Missing root_img for standalone VM!" | ||||||
| 
 | 
 | ||||||
| @ -464,6 +460,11 @@ class QubesVm(object): | |||||||
|     def mac(self, new_mac): |     def mac(self, new_mac): | ||||||
|         self._mac = new_mac |         self._mac = new_mac | ||||||
| 
 | 
 | ||||||
|  |     @property | ||||||
|  |     def updateable(self): | ||||||
|  |         return self.template is None | ||||||
|  | 
 | ||||||
|  |     # Leaved for compatibility | ||||||
|     def is_updateable(self): |     def is_updateable(self): | ||||||
|         return self.updateable |         return self.updateable | ||||||
| 
 | 
 | ||||||
| @ -476,19 +477,6 @@ class QubesVm(object): | |||||||
|         else: |         else: | ||||||
|             return False |             return False | ||||||
| 
 | 
 | ||||||
|     def set_updateable(self): |  | ||||||
|         if self.is_updateable(): |  | ||||||
|             return |  | ||||||
| 
 |  | ||||||
|         raise QubesException ("Change 'updateable' flag is not supported. Please use qvm-create.") |  | ||||||
| 
 |  | ||||||
|     def set_nonupdateable(self): |  | ||||||
|         if not self.is_updateable(): |  | ||||||
|             return |  | ||||||
| 
 |  | ||||||
|         raise QubesException ("Change 'updateable' flag is not supported. Please use qvm-create.") |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     def pre_rename(self, new_name): |     def pre_rename(self, new_name): | ||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
| @ -683,14 +671,14 @@ class QubesVm(object): | |||||||
| 
 | 
 | ||||||
|     def is_outdated(self): |     def is_outdated(self): | ||||||
|         # Makes sense only on VM based on template |         # Makes sense only on VM based on template | ||||||
|         if self.template_vm is None: |         if self.template is None: | ||||||
|             return False |             return False | ||||||
| 
 | 
 | ||||||
|         if not self.is_running(): |         if not self.is_running(): | ||||||
|             return False |             return False | ||||||
| 
 | 
 | ||||||
|         rootimg_inode = os.stat(self.template_vm.root_img) |         rootimg_inode = os.stat(self.template.root_img) | ||||||
|         rootcow_inode = os.stat(self.template_vm.rootcow_img) |         rootcow_inode = os.stat(self.template.rootcow_img) | ||||||
| 
 | 
 | ||||||
|         current_dmdev = "/dev/mapper/snapshot-{0:x}:{1}-{2:x}:{3}".format( |         current_dmdev = "/dev/mapper/snapshot-{0:x}:{1}-{2:x}:{3}".format( | ||||||
|                 rootimg_inode[2], rootimg_inode[1], |                 rootimg_inode[2], rootimg_inode[1], | ||||||
| @ -851,8 +839,8 @@ class QubesVm(object): | |||||||
|                 [{ 'dom': xid }]) |                 [{ 'dom': xid }]) | ||||||
| 
 | 
 | ||||||
|     def get_rootdev(self, source_template=None): |     def get_rootdev(self, source_template=None): | ||||||
|         if self.template_vm: |         if self.template: | ||||||
|             return "'script:snapshot:{dir}/root.img:{dir}/root-cow.img,xvda,r',".format(dir=self.template_vm.dir_path) |             return "'script:snapshot:{dir}/root.img:{dir}/root-cow.img,xvda,r',".format(dir=self.template.dir_path) | ||||||
|         else: |         else: | ||||||
|             return "'script:file:{dir}/root.img,xvda,w',".format(dir=self.dir_path) |             return "'script:file:{dir}/root.img,xvda,w',".format(dir=self.dir_path) | ||||||
| 
 | 
 | ||||||
| @ -884,7 +872,7 @@ class QubesVm(object): | |||||||
|         args['volatiledev'] = "'script:file:{dir}/volatile.img,xvdc,w',".format(dir=self.dir_path) |         args['volatiledev'] = "'script:file:{dir}/volatile.img,xvdc,w',".format(dir=self.dir_path) | ||||||
|         if hasattr(self, 'kernel'): |         if hasattr(self, 'kernel'): | ||||||
|             modulesmode='r' |             modulesmode='r' | ||||||
|             if self.is_updateable() and self.kernel is None: |             if self.updateable and self.kernel is None: | ||||||
|                 modulesmode='w' |                 modulesmode='w' | ||||||
|             args['otherdevs'] = "'script:file:{dir}/modules.img,xvdd,{mode}',".format(dir=self.kernels_dir, mode=modulesmode) |             args['otherdevs'] = "'script:file:{dir}/modules.img,xvdd,{mode}',".format(dir=self.kernels_dir, mode=modulesmode) | ||||||
|         if hasattr(self, 'kernelopts'): |         if hasattr(self, 'kernelopts'): | ||||||
| @ -896,7 +884,7 @@ class QubesVm(object): | |||||||
|         if file_path is None: |         if file_path is None: | ||||||
|             file_path = self.conf_file |             file_path = self.conf_file | ||||||
|         if source_template is None: |         if source_template is None: | ||||||
|             source_template = self.template_vm |             source_template = self.template | ||||||
| 
 | 
 | ||||||
|         f_conf_template = open(self.config_file_template, 'r') |         f_conf_template = open(self.config_file_template, 'r') | ||||||
|         conf_template = f_conf_template.read() |         conf_template = f_conf_template.read() | ||||||
| @ -914,7 +902,7 @@ class QubesVm(object): | |||||||
| 
 | 
 | ||||||
|     def create_on_disk(self, verbose, source_template = None): |     def create_on_disk(self, verbose, source_template = None): | ||||||
|         if source_template is None: |         if source_template is None: | ||||||
|             source_template = self.template_vm |             source_template = self.template | ||||||
|         assert source_template is not None |         assert source_template is not None | ||||||
| 
 | 
 | ||||||
|         if dry_run: |         if dry_run: | ||||||
| @ -947,7 +935,7 @@ class QubesVm(object): | |||||||
|             shutil.copy(source_template.dir_path + '/vm-' + qubes_whitelisted_appmenus, |             shutil.copy(source_template.dir_path + '/vm-' + qubes_whitelisted_appmenus, | ||||||
|                     self.dir_path + '/' + qubes_whitelisted_appmenus) |                     self.dir_path + '/' + qubes_whitelisted_appmenus) | ||||||
| 
 | 
 | ||||||
|         if self.is_updateable(): |         if self.updateable: | ||||||
|             template_root = source_template.root_img |             template_root = source_template.root_img | ||||||
|             if verbose: |             if verbose: | ||||||
|                 print >> sys.stderr, "--> Copying the template's root image: {0}".\ |                 print >> sys.stderr, "--> Copying the template's root image: {0}".\ | ||||||
| @ -973,7 +961,7 @@ class QubesVm(object): | |||||||
| 
 | 
 | ||||||
|     def create_appmenus(self, verbose, source_template = None): |     def create_appmenus(self, verbose, source_template = None): | ||||||
|         if source_template is None: |         if source_template is None: | ||||||
|             source_template = self.template_vm |             source_template = self.template | ||||||
| 
 | 
 | ||||||
|         vmtype = None |         vmtype = None | ||||||
|         if self.is_netvm(): |         if self.is_netvm(): | ||||||
| @ -1077,7 +1065,7 @@ class QubesVm(object): | |||||||
|                 "VM directory doesn't exist: {0}".\ |                 "VM directory doesn't exist: {0}".\ | ||||||
|                 format(self.dir_path)) |                 format(self.dir_path)) | ||||||
| 
 | 
 | ||||||
|         if self.is_updateable() and not os.path.exists (self.root_img): |         if self.updateable and not os.path.exists (self.root_img): | ||||||
|             raise QubesException ( |             raise QubesException ( | ||||||
|                 "VM root image file doesn't exist: {0}".\ |                 "VM root image file doesn't exist: {0}".\ | ||||||
|                 format(self.root_img)) |                 format(self.root_img)) | ||||||
| @ -1107,7 +1095,7 @@ class QubesVm(object): | |||||||
|         assert not self.is_running(), "Attempt to clean volatile image of running VM!" |         assert not self.is_running(), "Attempt to clean volatile image of running VM!" | ||||||
| 
 | 
 | ||||||
|         if source_template is None: |         if source_template is None: | ||||||
|             source_template = self.template_vm |             source_template = self.template | ||||||
| 
 | 
 | ||||||
|         # Only makes sense on template based VM |         # Only makes sense on template based VM | ||||||
|         if source_template is None: |         if source_template is None: | ||||||
| @ -1497,7 +1485,6 @@ class QubesTemplateVm(QubesVm): | |||||||
|     def _get_attrs_config(self): |     def _get_attrs_config(self): | ||||||
|         attrs_config = super(QubesTemplateVm, self)._get_attrs_config() |         attrs_config = super(QubesTemplateVm, self)._get_attrs_config() | ||||||
|         attrs_config['dir_path']['eval'] = 'value if value is not None else qubes_templates_dir + "/" + self.name' |         attrs_config['dir_path']['eval'] = 'value if value is not None else qubes_templates_dir + "/" + self.name' | ||||||
|         attrs_config['updateable']['default'] = True |  | ||||||
|         attrs_config['label']['default'] = default_template_label |         attrs_config['label']['default'] = default_template_label | ||||||
| 
 | 
 | ||||||
|         # New attributes |         # New attributes | ||||||
| @ -1520,18 +1507,9 @@ class QubesTemplateVm(QubesVm): | |||||||
|     def type(self): |     def type(self): | ||||||
|         return "TemplateVM" |         return "TemplateVM" | ||||||
| 
 | 
 | ||||||
|     def set_updateable(self): |     @property | ||||||
|         if self.is_updateable(): |     def updateable(self): | ||||||
|             return |         return True | ||||||
| 
 |  | ||||||
|         assert not self.is_running() |  | ||||||
|         # Make sure that all the AppVMs are non-updateable... |  | ||||||
|         for appvm in self.appvms.values(): |  | ||||||
|             if appvm.is_updateable(): |  | ||||||
|                 raise QubesException("One of the AppVMs ('{0}')is also 'updateable'\ |  | ||||||
|                                      -- cannot make the TemplateVM {'{1}'} 'nonupdatable'".\ |  | ||||||
|                                      format (appvm.name, self.name)) |  | ||||||
|         self.updateable = True |  | ||||||
| 
 | 
 | ||||||
|     def get_rootdev(self, source_template=None): |     def get_rootdev(self, source_template=None): | ||||||
|         return "'script:origin:{dir}/root.img:{dir}/root-cow.img,xvda,w',".format(dir=self.dir_path) |         return "'script:origin:{dir}/root.img:{dir}/root-cow.img,xvda,w',".format(dir=self.dir_path) | ||||||
| @ -1556,7 +1534,7 @@ class QubesTemplateVm(QubesVm): | |||||||
|         retcode = subprocess.call (["cp", src_vm.clean_volatile_img, self.clean_volatile_img]) |         retcode = subprocess.call (["cp", src_vm.clean_volatile_img, self.clean_volatile_img]) | ||||||
|         if retcode != 0: |         if retcode != 0: | ||||||
|             raise IOError ("Error while copying {0} to {1}".\ |             raise IOError ("Error while copying {0} to {1}".\ | ||||||
|                            format(src_template_vm.clean_volatile_img, self.clean_volatile_img)) |                            format(src_vm.clean_volatile_img, self.clean_volatile_img)) | ||||||
|         if verbose: |         if verbose: | ||||||
|             print >> sys.stderr, "--> Copying the template's volatile image:\n{0} ==>\n{1}".\ |             print >> sys.stderr, "--> Copying the template's volatile image:\n{0} ==>\n{1}".\ | ||||||
|                     format(self.clean_volatile_img, self.volatile_img) |                     format(self.clean_volatile_img, self.volatile_img) | ||||||
| @ -1577,7 +1555,7 @@ class QubesTemplateVm(QubesVm): | |||||||
| 
 | 
 | ||||||
|     def create_appmenus(self, verbose, source_template = None): |     def create_appmenus(self, verbose, source_template = None): | ||||||
|         if source_template is None: |         if source_template is None: | ||||||
|             source_template = self.template_vm |             source_template = self.template | ||||||
| 
 | 
 | ||||||
|         try: |         try: | ||||||
|             subprocess.check_call ([qubes_appmenu_create_cmd, self.appmenus_templates_dir, self.name, "vm-templates"]) |             subprocess.check_call ([qubes_appmenu_create_cmd, self.appmenus_templates_dir, self.name, "vm-templates"]) | ||||||
| @ -1647,7 +1625,7 @@ class QubesTemplateVm(QubesVm): | |||||||
| 
 | 
 | ||||||
|         self.reset_volatile_storage(verbose=verbose) |         self.reset_volatile_storage(verbose=verbose) | ||||||
| 
 | 
 | ||||||
|         if not self.is_updateable(): |         if not self.updateable: | ||||||
|             raise QubesException ("Cannot start Template VM that is marked \"nonupdatable\"") |             raise QubesException ("Cannot start Template VM that is marked \"nonupdatable\"") | ||||||
| 
 | 
 | ||||||
|         # TODO?: check if none of running appvms are outdated |         # TODO?: check if none of running appvms are outdated | ||||||
| @ -1667,7 +1645,7 @@ class QubesTemplateVm(QubesVm): | |||||||
|         retcode = subprocess.call (["tar", "xf", self.clean_volatile_img, "-C", self.dir_path]) |         retcode = subprocess.call (["tar", "xf", self.clean_volatile_img, "-C", self.dir_path]) | ||||||
|         if retcode != 0: |         if retcode != 0: | ||||||
|             raise IOError ("Error while unpacking {0} to {1}".\ |             raise IOError ("Error while unpacking {0} to {1}".\ | ||||||
|                            format(self.template_vm.clean_volatile_img, self.volatile_img)) |                            format(self.template.clean_volatile_img, self.volatile_img)) | ||||||
| 
 | 
 | ||||||
|     def commit_changes (self, verbose = False): |     def commit_changes (self, verbose = False): | ||||||
| 
 | 
 | ||||||
| @ -1992,7 +1970,7 @@ class QubesDom0NetVm(QubesNetVm): | |||||||
|         super(QubesDom0NetVm, self).__init__(qid=0, name="dom0", netid=0, |         super(QubesDom0NetVm, self).__init__(qid=0, name="dom0", netid=0, | ||||||
|                                              dir_path=None, |                                              dir_path=None, | ||||||
|                                              private_img = None, |                                              private_img = None, | ||||||
|                                              template_vm = None, |                                              template = None, | ||||||
|                                              label = default_template_label) |                                              label = default_template_label) | ||||||
|         self.xid = 0 |         self.xid = 0 | ||||||
| 
 | 
 | ||||||
| @ -2064,7 +2042,7 @@ class QubesDisposableVm(QubesVm): | |||||||
| 
 | 
 | ||||||
|         super(QubesDisposableVm, self).__init__(dir_path="/nonexistent", **kwargs) |         super(QubesDisposableVm, self).__init__(dir_path="/nonexistent", **kwargs) | ||||||
| 
 | 
 | ||||||
|         assert self.template_vm is not None, "Missing template_vm for DisposableVM!" |         assert self.template is not None, "Missing template for DisposableVM!" | ||||||
| 
 | 
 | ||||||
|         # Use DispVM icon with the same color |         # Use DispVM icon with the same color | ||||||
|         if self._label: |         if self._label: | ||||||
| @ -2089,7 +2067,7 @@ class QubesDisposableVm(QubesVm): | |||||||
|         attrs["qid"] = str(self.qid) |         attrs["qid"] = str(self.qid) | ||||||
|         attrs["name"] = self.name |         attrs["name"] = self.name | ||||||
|         attrs["dispid"] = str(self.dispid) |         attrs["dispid"] = str(self.dispid) | ||||||
|         attrs["template_qid"] = str(self.template_vm.qid) |         attrs["template_qid"] = str(self.template.qid) | ||||||
|         attrs["label"] = self.label.name |         attrs["label"] = self.label.name | ||||||
|         attrs["firewall_conf"] = self.relative_path(self.firewall_conf) |         attrs["firewall_conf"] = self.relative_path(self.firewall_conf) | ||||||
|         return attrs |         return attrs | ||||||
| @ -2118,7 +2096,7 @@ class QubesAppVm(QubesVm): | |||||||
| 
 | 
 | ||||||
|         super(QubesAppVm, self).create_on_disk(verbose, source_template=source_template) |         super(QubesAppVm, self).create_on_disk(verbose, source_template=source_template) | ||||||
| 
 | 
 | ||||||
|         if self.is_updateable(): |         if self.updateable: | ||||||
|             if verbose: |             if verbose: | ||||||
|                 print >> sys.stderr, "--> Copying the template's appmenus templates dir:\n{0} ==>\n{1}".\ |                 print >> sys.stderr, "--> Copying the template's appmenus templates dir:\n{0} ==>\n{1}".\ | ||||||
|                         format(source_template.appmenus_templates_dir, self.appmenus_templates_dir) |                         format(source_template.appmenus_templates_dir, self.appmenus_templates_dir) | ||||||
| @ -2346,20 +2324,18 @@ class QubesVmCollection(dict): | |||||||
|             assert False, "Attempt to add VM with qid that already exists in the collection!" |             assert False, "Attempt to add VM with qid that already exists in the collection!" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     def add_new_appvm(self, name, template_vm, |     def add_new_appvm(self, name, template, | ||||||
|                       dir_path = None, conf_file = None, |                       dir_path = None, conf_file = None, | ||||||
|                       private_img = None, |                       private_img = None, | ||||||
|                       updateable = False, |  | ||||||
|                       label = None): |                       label = None): | ||||||
| 
 | 
 | ||||||
|         qid = self.get_new_unused_qid() |         qid = self.get_new_unused_qid() | ||||||
|         vm = QubesAppVm (qid=qid, name=name, template_vm=template_vm, |         vm = QubesAppVm (qid=qid, name=name, template=template, | ||||||
|                          dir_path=dir_path, conf_file=conf_file, |                          dir_path=dir_path, conf_file=conf_file, | ||||||
|                          private_img=private_img, |                          private_img=private_img, | ||||||
|                          netvm = self.get_default_netvm(), |                          netvm = self.get_default_netvm(), | ||||||
|                          kernel = self.get_default_kernel(), |                          kernel = self.get_default_kernel(), | ||||||
|                          uses_default_kernel = True, |                          uses_default_kernel = True, | ||||||
|                          updateable=updateable, |  | ||||||
|                          label=label) |                          label=label) | ||||||
| 
 | 
 | ||||||
|         if not self.verify_new_vm (vm): |         if not self.verify_new_vm (vm): | ||||||
| @ -2381,11 +2357,11 @@ class QubesVmCollection(dict): | |||||||
|         self[vm.qid]=vm |         self[vm.qid]=vm | ||||||
|         return vm |         return vm | ||||||
| 
 | 
 | ||||||
|     def add_new_disposablevm(self, name, template_vm, dispid, |     def add_new_disposablevm(self, name, template, dispid, | ||||||
|                       label = None): |                       label = None): | ||||||
| 
 | 
 | ||||||
|         qid = self.get_new_unused_qid() |         qid = self.get_new_unused_qid() | ||||||
|         vm = QubesDisposableVm (qid=qid, name=name, template_vm=template_vm, |         vm = QubesDisposableVm (qid=qid, name=name, template=template, | ||||||
|                          netvm = self.get_default_netvm(), |                          netvm = self.get_default_netvm(), | ||||||
|                          label=label, dispid=dispid) |                          label=label, dispid=dispid) | ||||||
| 
 | 
 | ||||||
| @ -2413,30 +2389,29 @@ class QubesVmCollection(dict): | |||||||
|         self[vm.qid]=vm |         self[vm.qid]=vm | ||||||
| 
 | 
 | ||||||
|         if self.default_template_qid is None: |         if self.default_template_qid is None: | ||||||
|             self.set_default_template_vm(vm) |             self.set_default_template(vm) | ||||||
| 
 | 
 | ||||||
|         return vm |         return vm | ||||||
| 
 | 
 | ||||||
|     def clone_templatevm(self, src_template_vm, name, dir_path = None, verbose = False): |     def clone_templatevm(self, src_template, name, dir_path = None, verbose = False): | ||||||
| 
 | 
 | ||||||
|         assert not src_template_vm.is_running(), "Attempt to clone a running Template VM!" |         assert not src_template.is_running(), "Attempt to clone a running Template VM!" | ||||||
| 
 | 
 | ||||||
|         vm = self.add_new_templatevm (name=name, dir_path=dir_path, installed_by_rpm = False) |         vm = self.add_new_templatevm (name=name, dir_path=dir_path, installed_by_rpm = False) | ||||||
| 
 | 
 | ||||||
|         return vm |         return vm | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     def add_new_netvm(self, name, template_vm, |     def add_new_netvm(self, name, template, | ||||||
|                       dir_path = None, conf_file = None, |                       dir_path = None, conf_file = None, | ||||||
|                       private_img = None, installed_by_rpm = False, |                       private_img = None, installed_by_rpm = False, | ||||||
|                       label = None, updateable = False): |                       label = None): | ||||||
| 
 | 
 | ||||||
|         qid = self.get_new_unused_qid() |         qid = self.get_new_unused_qid() | ||||||
|         netid = self.get_new_unused_netid() |         netid = self.get_new_unused_netid() | ||||||
|         vm = QubesNetVm (qid=qid, name=name, template_vm=template_vm, |         vm = QubesNetVm (qid=qid, name=name, template=template, | ||||||
|                          netid=netid, label=label, |                          netid=netid, label=label, | ||||||
|                          private_img=private_img, installed_by_rpm=installed_by_rpm, |                          private_img=private_img, installed_by_rpm=installed_by_rpm, | ||||||
|                          updateable=updateable, |  | ||||||
|                          kernel = self.get_default_kernel(), |                          kernel = self.get_default_kernel(), | ||||||
|                          uses_default_kernel = True, |                          uses_default_kernel = True, | ||||||
|                          dir_path=dir_path, conf_file=conf_file) |                          dir_path=dir_path, conf_file=conf_file) | ||||||
| @ -2454,18 +2429,17 @@ class QubesVmCollection(dict): | |||||||
| 
 | 
 | ||||||
|         return vm |         return vm | ||||||
| 
 | 
 | ||||||
|     def add_new_proxyvm(self, name, template_vm, |     def add_new_proxyvm(self, name, template, | ||||||
|                      dir_path = None, conf_file = None, |                      dir_path = None, conf_file = None, | ||||||
|                      private_img = None, installed_by_rpm = False, |                      private_img = None, installed_by_rpm = False, | ||||||
|                      label = None, updateable = False): |                      label = None): | ||||||
| 
 | 
 | ||||||
|         qid = self.get_new_unused_qid() |         qid = self.get_new_unused_qid() | ||||||
|         netid = self.get_new_unused_netid() |         netid = self.get_new_unused_netid() | ||||||
|         vm = QubesProxyVm (qid=qid, name=name, template_vm=template_vm, |         vm = QubesProxyVm (qid=qid, name=name, template=template, | ||||||
|                               netid=netid, label=label, |                               netid=netid, label=label, | ||||||
|                               private_img=private_img, installed_by_rpm=installed_by_rpm, |                               private_img=private_img, installed_by_rpm=installed_by_rpm, | ||||||
|                               dir_path=dir_path, conf_file=conf_file, |                               dir_path=dir_path, conf_file=conf_file, | ||||||
|                               updateable=updateable, |  | ||||||
|                               kernel = self.get_default_kernel(), |                               kernel = self.get_default_kernel(), | ||||||
|                               uses_default_kernel = True, |                               uses_default_kernel = True, | ||||||
|                               netvm = self.get_default_fw_netvm()) |                               netvm = self.get_default_fw_netvm()) | ||||||
| @ -2482,11 +2456,11 @@ class QubesVmCollection(dict): | |||||||
| 
 | 
 | ||||||
|         return vm |         return vm | ||||||
| 
 | 
 | ||||||
|     def set_default_template_vm(self, vm): |     def set_default_template(self, vm): | ||||||
|         assert vm.is_template(), "VM {0} is not a TemplateVM!".format(vm.name) |         assert vm.is_template(), "VM {0} is not a TemplateVM!".format(vm.name) | ||||||
|         self.default_template_qid = vm.qid |         self.default_template_qid = vm.qid | ||||||
| 
 | 
 | ||||||
|     def get_default_template_vm(self): |     def get_default_template(self): | ||||||
|         if self.default_template_qid is None: |         if self.default_template_qid is None: | ||||||
|             return None |             return None | ||||||
|         else: |         else: | ||||||
| @ -2549,7 +2523,7 @@ class QubesVmCollection(dict): | |||||||
| 
 | 
 | ||||||
|     def get_vms_based_on(self, template_qid): |     def get_vms_based_on(self, template_qid): | ||||||
|         vms = set([vm for vm in self.values() |         vms = set([vm for vm in self.values() | ||||||
|                    if (vm.template_vm and vm.template_vm.qid == template_qid)]) |                    if (vm.template and vm.template.qid == template_qid)]) | ||||||
|         return vms |         return vms | ||||||
| 
 | 
 | ||||||
|     def get_vms_connected_to(self, netvm_qid): |     def get_vms_connected_to(self, netvm_qid): | ||||||
| @ -2675,7 +2649,7 @@ class QubesVmCollection(dict): | |||||||
|         kwargs = {} |         kwargs = {} | ||||||
|         common_attr_list = ("qid", "name", "dir_path", "conf_file", |         common_attr_list = ("qid", "name", "dir_path", "conf_file", | ||||||
|                 "private_img", "root_img", "template_qid", |                 "private_img", "root_img", "template_qid", | ||||||
|                 "installed_by_rpm", "updateable", "internal", |                 "installed_by_rpm", "internal", | ||||||
|                 "uses_default_netvm", "label", "memory", "vcpus", "pcidevs", |                 "uses_default_netvm", "label", "memory", "vcpus", "pcidevs", | ||||||
|                 "maxmem", "kernel", "uses_default_kernel", "kernelopts", "uses_default_kernelopts", |                 "maxmem", "kernel", "uses_default_kernel", "kernelopts", "uses_default_kernelopts", | ||||||
|                 "mac", "services", "include_in_backups" ) |                 "mac", "services", "include_in_backups" ) | ||||||
| @ -2686,8 +2660,6 @@ class QubesVmCollection(dict): | |||||||
|                 kwargs.pop(attribute) |                 kwargs.pop(attribute) | ||||||
| 
 | 
 | ||||||
|         kwargs["qid"] = int(kwargs["qid"]) |         kwargs["qid"] = int(kwargs["qid"]) | ||||||
|         if "updateable" in kwargs: |  | ||||||
|             kwargs["updateable"] = True if kwargs["updateable"] == "True" else False |  | ||||||
| 
 | 
 | ||||||
|         if "include_in_backups" in kwargs: |         if "include_in_backups" in kwargs: | ||||||
|             kwargs["include_in_backups"] = True if kwargs["include_in_backups"] == "True" else False |             kwargs["include_in_backups"] = True if kwargs["include_in_backups"] == "True" else False | ||||||
| @ -2703,12 +2675,12 @@ class QubesVmCollection(dict): | |||||||
|                 kwargs.pop("template_qid") |                 kwargs.pop("template_qid") | ||||||
|             else: |             else: | ||||||
|                 kwargs["template_qid"] = int(kwargs["template_qid"]) |                 kwargs["template_qid"] = int(kwargs["template_qid"]) | ||||||
|                 template_vm = self[kwargs.pop("template_qid")] |                 template = self[kwargs.pop("template_qid")] | ||||||
|                 if template_vm is None: |                 if template is None: | ||||||
|                     print >> sys.stderr, "ERROR: VM '{0}' uses unkown template qid='{1}'!".\ |                     print >> sys.stderr, "ERROR: VM '{0}' uses unkown template qid='{1}'!".\ | ||||||
|                             format(kwargs["name"], kwargs["template_qid"]) |                             format(kwargs["name"], kwargs["template_qid"]) | ||||||
|                 else: |                 else: | ||||||
|                     kwargs["template_vm"] = template_vm |                     kwargs["template"] = template | ||||||
| 
 | 
 | ||||||
|         if "label" in kwargs: |         if "label" in kwargs: | ||||||
|             if kwargs["label"] not in QubesVmLabels: |             if kwargs["label"] not in QubesVmLabels: | ||||||
| @ -2940,12 +2912,12 @@ class QubesVmCollection(dict): | |||||||
|                 kwargs["dispid"] = int(kwargs["dispid"]) |                 kwargs["dispid"] = int(kwargs["dispid"]) | ||||||
|                 kwargs["template_qid"] = int(kwargs["template_qid"]) |                 kwargs["template_qid"] = int(kwargs["template_qid"]) | ||||||
| 
 | 
 | ||||||
|                 template_vm = self[kwargs.pop("template_qid")] |                 template = self[kwargs.pop("template_qid")] | ||||||
|                 if template_vm is None: |                 if template is None: | ||||||
|                     print >> sys.stderr, "ERROR: DisposableVM '{0}' uses unkown template qid='{1}'!".\ |                     print >> sys.stderr, "ERROR: DisposableVM '{0}' uses unkown template qid='{1}'!".\ | ||||||
|                             format(kwargs["name"], kwargs["template_qid"]) |                             format(kwargs["name"], kwargs["template_qid"]) | ||||||
|                 else: |                 else: | ||||||
|                     kwargs["template_vm"] = template_vm |                     kwargs["template"] = template | ||||||
| 
 | 
 | ||||||
|                 kwargs["netvm"] = self.get_default_netvm() |                 kwargs["netvm"] = self.get_default_netvm() | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -390,7 +390,7 @@ def backup_prepare(base_backup_dir, vms_list = None, exclude_list = [], print_ca | |||||||
| 
 | 
 | ||||||
|         if vm.is_appvm(): |         if vm.is_appvm(): | ||||||
|             files_to_backup += file_to_backup(vm.icon_path) |             files_to_backup += file_to_backup(vm.icon_path) | ||||||
|         if vm.is_updateable(): |         if vm.updateable: | ||||||
|             if os.path.exists(vm.dir_path + "/apps.templates"): |             if os.path.exists(vm.dir_path + "/apps.templates"): | ||||||
|                 # template |                 # template | ||||||
|                 files_to_backup += file_to_backup(vm.dir_path + "/apps.templates") |                 files_to_backup += file_to_backup(vm.dir_path + "/apps.templates") | ||||||
| @ -405,7 +405,7 @@ def backup_prepare(base_backup_dir, vms_list = None, exclude_list = [], print_ca | |||||||
|         if os.path.exists(vm.dir_path + '/whitelisted-appmenus.list'): |         if os.path.exists(vm.dir_path + '/whitelisted-appmenus.list'): | ||||||
|             files_to_backup += file_to_backup(vm.dir_path + '/whitelisted-appmenus.list') |             files_to_backup += file_to_backup(vm.dir_path + '/whitelisted-appmenus.list') | ||||||
| 
 | 
 | ||||||
|         if vm.is_updateable(): |         if vm.updateable: | ||||||
|             sz = vm.get_disk_usage(vm.root_img) |             sz = vm.get_disk_usage(vm.root_img) | ||||||
|             files_to_backup += file_to_backup(vm.root_img, sz) |             files_to_backup += file_to_backup(vm.root_img, sz) | ||||||
|             vm_sz += sz |             vm_sz += sz | ||||||
| @ -419,9 +419,9 @@ def backup_prepare(base_backup_dir, vms_list = None, exclude_list = [], print_ca | |||||||
| 
 | 
 | ||||||
|         fmt="{{0:>{0}}} |".format(fields_to_display[1]["width"] + 1) |         fmt="{{0:>{0}}} |".format(fields_to_display[1]["width"] + 1) | ||||||
|         if vm.is_netvm(): |         if vm.is_netvm(): | ||||||
|             s += fmt.format("NetVM" + (" + Sys" if vm.is_updateable() else "")) |             s += fmt.format("NetVM" + (" + Sys" if vm.updateable else "")) | ||||||
|         else: |         else: | ||||||
|             s += fmt.format("AppVM" + (" + Sys" if vm.is_updateable() else "")) |             s += fmt.format("AppVM" + (" + Sys" if vm.updateable else "")) | ||||||
| 
 | 
 | ||||||
|         fmt="{{0:>{0}}} |".format(fields_to_display[2]["width"] + 1) |         fmt="{{0:>{0}}} |".format(fields_to_display[2]["width"] + 1) | ||||||
|         s += fmt.format(size_to_human(vm_sz)) |         s += fmt.format(size_to_human(vm_sz)) | ||||||
| @ -624,10 +624,10 @@ def backup_restore_prepare(backup_dir, options = {}, host_collection = None): | |||||||
|                 vms_to_restore[vm.name]['already-exists'] = True |                 vms_to_restore[vm.name]['already-exists'] = True | ||||||
|                 vms_to_restore[vm.name]['good-to-go'] = False |                 vms_to_restore[vm.name]['good-to-go'] = False | ||||||
| 
 | 
 | ||||||
|             if vm.template_vm is None: |             if vm.template is None: | ||||||
|                 vms_to_restore[vm.name]['template'] = None |                 vms_to_restore[vm.name]['template'] = None | ||||||
|             else: |             else: | ||||||
|                 templatevm_name = find_template_name(vm.template_vm.name, options['replace-template']) |                 templatevm_name = find_template_name(vm.template.name, options['replace-template']) | ||||||
|                 vms_to_restore[vm.name]['template'] = templatevm_name |                 vms_to_restore[vm.name]['template'] = templatevm_name | ||||||
|                 template_vm_on_host = host_collection.get_vm_by_name (templatevm_name) |                 template_vm_on_host = host_collection.get_vm_by_name (templatevm_name) | ||||||
| 
 | 
 | ||||||
| @ -638,7 +638,7 @@ def backup_restore_prepare(backup_dir, options = {}, host_collection = None): | |||||||
|                     if template_vm_on_backup is None or not template_vm_on_backup.is_template(): |                     if template_vm_on_backup is None or not template_vm_on_backup.is_template(): | ||||||
|                         if options['use-default-template']: |                         if options['use-default-template']: | ||||||
|                             vms_to_restore[vm.name]['orig-template'] = templatevm_name |                             vms_to_restore[vm.name]['orig-template'] = templatevm_name | ||||||
|                             vms_to_restore[vm.name]['template'] = host_collection.get_default_template_vm().name |                             vms_to_restore[vm.name]['template'] = host_collection.get_default_template().name | ||||||
|                         else: |                         else: | ||||||
|                             vms_to_restore[vm.name]['missing-template'] = True |                             vms_to_restore[vm.name]['missing-template'] = True | ||||||
|                             vms_to_restore[vm.name]['good-to-go'] = False |                             vms_to_restore[vm.name]['good-to-go'] = False | ||||||
| @ -702,9 +702,9 @@ def backup_restore_print_summary(restore_info, print_callback = print_stdout): | |||||||
|                  ('Proxy' if vm.is_proxyvm() else \ |                  ('Proxy' if vm.is_proxyvm() else \ | ||||||
|                  (' Net' if vm.is_netvm() else 'App'))"}, |                  (' Net' if vm.is_netvm() else 'App'))"}, | ||||||
| 
 | 
 | ||||||
|         "updbl" : {"func": "'Yes' if vm.is_updateable() else ''"}, |         "updbl" : {"func": "'Yes' if vm.updateable else ''"}, | ||||||
| 
 | 
 | ||||||
|         "template": {"func": "'n/a' if vm.is_template() or vm.template_vm is None else\ |         "template": {"func": "'n/a' if vm.is_template() or vm.template is None else\ | ||||||
|                      vm_info['template']"}, |                      vm_info['template']"}, | ||||||
| 
 | 
 | ||||||
|         "netvm": {"func": "'n/a' if vm.is_netvm() else\ |         "netvm": {"func": "'n/a' if vm.is_netvm() else\ | ||||||
| @ -834,8 +834,6 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca | |||||||
|             error_callback("Skiping...") |             error_callback("Skiping...") | ||||||
|             continue |             continue | ||||||
| 
 | 
 | ||||||
|         updateable = vm.updateable |  | ||||||
| 
 |  | ||||||
|         new_vm = None |         new_vm = None | ||||||
| 
 | 
 | ||||||
|         try: |         try: | ||||||
| @ -845,7 +843,6 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca | |||||||
|                                                dir_path=vm.dir_path, |                                                dir_path=vm.dir_path, | ||||||
|                                                installed_by_rpm=False) |                                                installed_by_rpm=False) | ||||||
| 
 | 
 | ||||||
|             new_vm.updateable = updateable |  | ||||||
|             new_vm.verify_files() |             new_vm.verify_files() | ||||||
|         except Exception as err: |         except Exception as err: | ||||||
|             error_callback("ERROR: {0}".format(err)) |             error_callback("ERROR: {0}".format(err)) | ||||||
| @ -877,10 +874,10 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca | |||||||
|             error_callback("Skiping...") |             error_callback("Skiping...") | ||||||
|             continue |             continue | ||||||
| 
 | 
 | ||||||
|         template_vm = None |         template = None | ||||||
|         if vm.template_vm is not None: |         if vm.template is not None: | ||||||
|             template_name = vm_info['template'] |             template_name = vm_info['template'] | ||||||
|             template_vm = host_collection.get_vm_by_name(template_name) |             template = host_collection.get_vm_by_name(template_name) | ||||||
| 
 | 
 | ||||||
|         if not vm.uses_default_netvm: |         if not vm.uses_default_netvm: | ||||||
|             uses_default_netvm = False |             uses_default_netvm = False | ||||||
| @ -888,23 +885,19 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca | |||||||
|         else: |         else: | ||||||
|             uses_default_netvm = True |             uses_default_netvm = True | ||||||
| 
 | 
 | ||||||
|         updateable = vm.updateable |  | ||||||
| 
 |  | ||||||
|         new_vm = None |         new_vm = None | ||||||
|         try: |         try: | ||||||
|             restore_vm_dir (backup_dir, vm.dir_path, qubes_servicevms_dir); |             restore_vm_dir (backup_dir, vm.dir_path, qubes_servicevms_dir); | ||||||
| 
 | 
 | ||||||
|             if vm.type == "NetVM": |             if vm.type == "NetVM": | ||||||
|                 new_vm = host_collection.add_new_netvm(vm.name, template_vm, |                 new_vm = host_collection.add_new_netvm(vm.name, template, | ||||||
|                                               conf_file=vm.conf_file, |                                               conf_file=vm.conf_file, | ||||||
|                                               dir_path=vm.dir_path, |                                               dir_path=vm.dir_path, | ||||||
|                                               updateable=updateable, |  | ||||||
|                                               label=vm.label) |                                               label=vm.label) | ||||||
|             elif vm.type == "ProxyVM": |             elif vm.type == "ProxyVM": | ||||||
|                 new_vm = host_collection.add_new_proxyvm(vm.name, template_vm, |                 new_vm = host_collection.add_new_proxyvm(vm.name, template, | ||||||
|                                               conf_file=vm.conf_file, |                                               conf_file=vm.conf_file, | ||||||
|                                               dir_path=vm.dir_path, |                                               dir_path=vm.dir_path, | ||||||
|                                               updateable=updateable, |  | ||||||
|                                               label=vm.label) |                                               label=vm.label) | ||||||
|         except Exception as err: |         except Exception as err: | ||||||
|             error_callback("ERROR: {0}".format(err)) |             error_callback("ERROR: {0}".format(err)) | ||||||
| @ -942,10 +935,10 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca | |||||||
|             error_callback("Skiping...") |             error_callback("Skiping...") | ||||||
|             continue |             continue | ||||||
| 
 | 
 | ||||||
|         template_vm = None |         template = None | ||||||
|         if vm.template_vm is not None: |         if vm.template is not None: | ||||||
|             template_name = vm_info['template'] |             template_name = vm_info['template'] | ||||||
|             template_vm = host_collection.get_vm_by_name(template_name) |             template = host_collection.get_vm_by_name(template_name) | ||||||
| 
 | 
 | ||||||
|         if not vm.uses_default_netvm: |         if not vm.uses_default_netvm: | ||||||
|             uses_default_netvm = False |             uses_default_netvm = False | ||||||
| @ -953,15 +946,12 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca | |||||||
|         else: |         else: | ||||||
|             uses_default_netvm = True |             uses_default_netvm = True | ||||||
| 
 | 
 | ||||||
|         updateable = vm.updateable |  | ||||||
| 
 |  | ||||||
|         new_vm = None |         new_vm = None | ||||||
|         try: |         try: | ||||||
|             restore_vm_dir (backup_dir, vm.dir_path, qubes_appvms_dir); |             restore_vm_dir (backup_dir, vm.dir_path, qubes_appvms_dir); | ||||||
|             new_vm = host_collection.add_new_appvm(vm.name, template_vm, |             new_vm = host_collection.add_new_appvm(vm.name, template, | ||||||
|                                           conf_file=vm.conf_file, |                                           conf_file=vm.conf_file, | ||||||
|                                           dir_path=vm.dir_path, |                                           dir_path=vm.dir_path, | ||||||
|                                           updateable=updateable, |  | ||||||
|                                           label=vm.label) |                                           label=vm.label) | ||||||
|         except Exception as err: |         except Exception as err: | ||||||
|             error_callback("ERROR: {0}".format(err)) |             error_callback("ERROR: {0}".format(err)) | ||||||
|  | |||||||
| @ -32,7 +32,7 @@ def handle_vm(vms, label, new_value = None): | |||||||
|     functions = { # label: [ getter, setter ], |     functions = { # label: [ getter, setter ], | ||||||
|         'default-netvm': [ 'get_default_netvm', 'set_default_netvm' ], |         'default-netvm': [ 'get_default_netvm', 'set_default_netvm' ], | ||||||
|         'default-fw-netvm': [ 'get_default_fw_netvm', 'set_default_fw_netvm' ], |         'default-fw-netvm': [ 'get_default_fw_netvm', 'set_default_fw_netvm' ], | ||||||
|         'default-template': [ 'get_default_template_vm', 'set_default_template_vm' ], |         'default-template': [ 'get_default_template', 'set_default_template' ], | ||||||
|         'clockvm': [ 'get_clockvm_vm', 'set_clockvm_vm' ], |         'clockvm': [ 'get_clockvm_vm', 'set_clockvm_vm' ], | ||||||
|         'updatevm': [ 'get_updatevm_vm', 'set_updatevm_vm' ], |         'updatevm': [ 'get_updatevm_vm', 'set_updatevm_vm' ], | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -52,13 +52,13 @@ def main(): | |||||||
|         print >> sys.stderr, "ERROR: A VM with the name '{0}' already exists in the system.".format(vmname) |         print >> sys.stderr, "ERROR: A VM with the name '{0}' already exists in the system.".format(vmname) | ||||||
|         exit(1) |         exit(1) | ||||||
| 
 | 
 | ||||||
|     template_vm = qvm_collection.get_vm_by_name(templatename) |     template = qvm_collection.get_vm_by_name(templatename) | ||||||
|     if template_vm is None: |     if template is None: | ||||||
|         print >> sys.stderr, "ERROR: A Template VM with the name '{0}' does not exist in the system.".format(templatename) |         print >> sys.stderr, "ERROR: A Template VM with the name '{0}' does not exist in the system.".format(templatename) | ||||||
|         exit(1) |         exit(1) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     vm = qvm_collection.add_new_appvm(vmname, template_vm, |     vm = qvm_collection.add_new_appvm(vmname, template, | ||||||
|                                       conf_file=options.conf_file, |                                       conf_file=options.conf_file, | ||||||
|                                       dir_path=options.dir_path) |                                       dir_path=options.dir_path) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -59,8 +59,8 @@ def main(): | |||||||
|         dst_vm = qvm_collection.add_new_templatevm(name=dstname, |         dst_vm = qvm_collection.add_new_templatevm(name=dstname, | ||||||
|                                               dir_path=options.dir_path, installed_by_rpm=False) |                                               dir_path=options.dir_path, installed_by_rpm=False) | ||||||
|     elif isinstance(src_vm, QubesAppVm): |     elif isinstance(src_vm, QubesAppVm): | ||||||
|         dst_vm = qvm_collection.add_new_appvm(name=dstname, template_vm=src_vm.template_vm, |         dst_vm = qvm_collection.add_new_appvm(name=dstname, template=src_vm.template, | ||||||
|                                               updateable=src_vm.updateable, label=src_vm.label,  |                                               label=src_vm.label, | ||||||
|                                               dir_path=options.dir_path) |                                               dir_path=options.dir_path) | ||||||
|     elif isinstance(src_vm, QubesHVm): |     elif isinstance(src_vm, QubesHVm): | ||||||
|         dst_vm = qvm_collection.add_new_hvm(name=dstname, label=src_vm.label) |         dst_vm = qvm_collection.add_new_hvm(name=dstname, label=src_vm.label) | ||||||
|  | |||||||
| @ -108,39 +108,39 @@ def main(): | |||||||
| 
 | 
 | ||||||
|     template_vm = None |     template_vm = None | ||||||
|     if options.template is not None: |     if options.template is not None: | ||||||
|         template_vm = qvm_collection.get_vm_by_name(options.template) |         template = qvm_collection.get_vm_by_name(options.template) | ||||||
|         if template_vm is None: |         if template is None: | ||||||
|             print >> sys.stderr, "There is no (Templete)VM with the name '{0}'".format(options.template) |             print >> sys.stderr, "There is no (Templete)VM with the name '{0}'".format(options.template) | ||||||
|             exit (1) |             exit (1) | ||||||
|         if not template_vm.is_template(): |         if not template.is_template(): | ||||||
|             print >> sys.stderr, "VM '{0}' is not a TemplateVM".format(options.template) |             print >> sys.stderr, "VM '{0}' is not a TemplateVM".format(options.template) | ||||||
|             exit (1) |             exit (1) | ||||||
|         if (options.verbose): |         if (options.verbose): | ||||||
|             print "--> Using TemplateVM: {0}".format(template_vm.name) |             print "--> Using TemplateVM: {0}".format(template.name) | ||||||
| 
 | 
 | ||||||
|     elif not options.hvm: |     elif not options.hvm: | ||||||
|         if qvm_collection.get_default_template_vm() is None: |         if qvm_collection.get_default_template() is None: | ||||||
|             print >> sys.stderr, "No default TempleteVM defined!" |             print >> sys.stderr, "No default TempleteVM defined!" | ||||||
|             exit (1) |             exit (1) | ||||||
|         else: |         else: | ||||||
|             template_vm = qvm_collection.get_default_template_vm() |             template = qvm_collection.get_default_template() | ||||||
|             if (options.verbose): |             if (options.verbose): | ||||||
|                 print "--> Using default TemplateVM: {0}".format(template_vm.name) |                 print "--> Using default TemplateVM: {0}".format(template.name) | ||||||
| 
 | 
 | ||||||
|     if options.standalone: |     if options.standalone: | ||||||
|         new_vm_template = None |         new_vm_template = None | ||||||
|     else: |     else: | ||||||
|         new_vm_template = template_vm |         new_vm_template = template | ||||||
| 
 | 
 | ||||||
|     vm = None |     vm = None | ||||||
|     if options.netvm: |     if options.netvm: | ||||||
|         vm = qvm_collection.add_new_netvm(vmname, new_vm_template, label = label, updateable = options.standalone) |         vm = qvm_collection.add_new_netvm(vmname, new_vm_template, label = label) | ||||||
|     elif options.proxyvm: |     elif options.proxyvm: | ||||||
|         vm = qvm_collection.add_new_proxyvm(vmname, new_vm_template, label = label, updateable = options.standalone) |         vm = qvm_collection.add_new_proxyvm(vmname, new_vm_template, label = label) | ||||||
|     elif options.hvm: |     elif options.hvm: | ||||||
|         vm = qvm_collection.add_new_hvm(vmname, label = label) |         vm = qvm_collection.add_new_hvm(vmname, label = label) | ||||||
|     else: |     else: | ||||||
|         vm = qvm_collection.add_new_appvm(vmname, new_vm_template, label = label, updateable = options.standalone) |         vm = qvm_collection.add_new_appvm(vmname, new_vm_template, label = label) | ||||||
| 
 | 
 | ||||||
|     if options.internal: |     if options.internal: | ||||||
|         vm.internal = True |         vm.internal = True | ||||||
| @ -152,7 +152,7 @@ def main(): | |||||||
|         vm.vcpus = options.vcpus |         vm.vcpus = options.vcpus | ||||||
| 
 | 
 | ||||||
|     try: |     try: | ||||||
|         vm.create_on_disk(verbose=options.verbose, source_template=template_vm) |         vm.create_on_disk(verbose=options.verbose, source_template=template) | ||||||
|         if options.root: |         if options.root: | ||||||
|             os.unlink(vm.root_img) |             os.unlink(vm.root_img) | ||||||
|             os.rename(options.root, vm.root_img) |             os.rename(options.root, vm.root_img) | ||||||
|  | |||||||
| @ -30,8 +30,8 @@ import sys | |||||||
| fields = { | fields = { | ||||||
|     "qid": {"func": "vm.qid"}, |     "qid": {"func": "vm.qid"}, | ||||||
| 
 | 
 | ||||||
|     "name": {"func": "('=>' if qvm_collection.get_default_template_vm() is not None\ |     "name": {"func": "('=>' if qvm_collection.get_default_template() is not None\ | ||||||
|              and vm.qid == qvm_collection.get_default_template_vm().qid else '')\ |              and vm.qid == qvm_collection.get_default_template().qid else '')\ | ||||||
|              + ('[' if vm.is_template() else '')\ |              + ('[' if vm.is_template() else '')\ | ||||||
|              + ('<' if vm.is_disposablevm() else '')\ |              + ('<' if vm.is_disposablevm() else '')\ | ||||||
|              + ('{' if vm.is_netvm() else '')\ |              + ('{' if vm.is_netvm() else '')\ | ||||||
| @ -44,11 +44,11 @@ fields = { | |||||||
|              ('Proxy' if vm.is_proxyvm() else \ |              ('Proxy' if vm.is_proxyvm() else \ | ||||||
|              (' Net' if vm.is_netvm() else ''))"}, |              (' Net' if vm.is_netvm() else ''))"}, | ||||||
| 
 | 
 | ||||||
|     "updbl" : {"func": "'Yes' if vm.is_updateable() else ''"}, |     "updbl" : {"func": "'Yes' if vm.updateable else ''"}, | ||||||
| 
 | 
 | ||||||
|     "template": {"func": "'n/a' if vm.is_template() else\ |     "template": {"func": "'n/a' if vm.is_template() else\ | ||||||
|                  ('None' if vm.template_vm is None else\ |                  ('None' if vm.template is None else\ | ||||||
|                  qvm_collection[vm.template_vm.qid].name)"}, |                  qvm_collection[vm.template.qid].name)"}, | ||||||
| 
 | 
 | ||||||
|     "netvm": {"func": "'n/a' if vm.is_netvm() and not vm.is_proxyvm() else\ |     "netvm": {"func": "'n/a' if vm.is_netvm() and not vm.is_proxyvm() else\ | ||||||
|               ('*' if vm.uses_default_netvm else '') +\ |               ('*' if vm.uses_default_netvm else '') +\ | ||||||
| @ -149,7 +149,7 @@ def main(): | |||||||
| 
 | 
 | ||||||
|     # Now, the AppVMs without template... |     # Now, the AppVMs without template... | ||||||
|     for appvm in vms_list: |     for appvm in vms_list: | ||||||
|         if appvm.is_appvm() and appvm.template_vm is None: |         if appvm.is_appvm() and appvm.template is None: | ||||||
|             vms_to_display.append (appvm) |             vms_to_display.append (appvm) | ||||||
| 
 | 
 | ||||||
|     # Now, the template, and all its AppVMs... |     # Now, the template, and all its AppVMs... | ||||||
| @ -158,7 +158,7 @@ def main(): | |||||||
|             vms_to_display.append (tvm) |             vms_to_display.append (tvm) | ||||||
|             for vm in vms_list: |             for vm in vms_list: | ||||||
|                 if (vm.is_appvm() or vm.is_disposablevm()) and \ |                 if (vm.is_appvm() or vm.is_disposablevm()) and \ | ||||||
| 		    vm.template_vm and vm.template_vm.qid == tvm.qid: | 		    vm.template and vm.template.qid == tvm.qid: | ||||||
|                     vms_to_display.append(vm) |                     vms_to_display.append(vm) | ||||||
| 
 | 
 | ||||||
|     assert len(vms_to_display) == no_vms |     assert len(vms_to_display) == no_vms | ||||||
|  | |||||||
| @ -37,22 +37,22 @@ def do_list(vm): | |||||||
|     print fmt.format ("name", vm.name) |     print fmt.format ("name", vm.name) | ||||||
|     print fmt.format ("label", vm.label.name) |     print fmt.format ("label", vm.label.name) | ||||||
|     print fmt.format ("type", vm.type) |     print fmt.format ("type", vm.type) | ||||||
|     if vm.template_vm is not None: |     if vm.template is not None: | ||||||
|         print fmt.format ("template", vm.template_vm.name) |         print fmt.format ("template", vm.template.name) | ||||||
|     if vm.netvm is not None: |     if vm.netvm is not None: | ||||||
|         print fmt.format ("netvm", vm.netvm.name) |         print fmt.format ("netvm", vm.netvm.name) | ||||||
|     print fmt.format ("updateable?", vm.is_updateable()) |     print fmt.format ("updateable?", vm.updateable) | ||||||
|     print fmt.format ("installed by RPM?", vm.installed_by_rpm) |     print fmt.format ("installed by RPM?", vm.installed_by_rpm) | ||||||
|     print fmt.format ("include in backups", vm.include_in_backups) |     print fmt.format ("include in backups", vm.include_in_backups) | ||||||
|     print fmt.format ("dir", vm.dir_path) |     print fmt.format ("dir", vm.dir_path) | ||||||
|     print fmt.format ("config", vm.conf_file) |     print fmt.format ("config", vm.conf_file) | ||||||
|     print fmt.format ("pcidevs", vm.pcidevs) |     print fmt.format ("pcidevs", vm.pcidevs) | ||||||
|     if vm.template_vm is None: |     if vm.template is None: | ||||||
|         print fmt.format ("root img", vm.root_img) |         print fmt.format ("root img", vm.root_img) | ||||||
|     if vm.is_template(): |     if vm.is_template(): | ||||||
|         print fmt.format ("root COW img", vm.rootcow_img) |         print fmt.format ("root COW img", vm.rootcow_img) | ||||||
|     if vm.template_vm is not None: |     if vm.template is not None: | ||||||
|         print fmt.format ("root img", vm.template_vm.root_img) |         print fmt.format ("root img", vm.template.root_img) | ||||||
|     if hasattr(vm, 'volatile_img') and vm.volatile_img is not None: |     if hasattr(vm, 'volatile_img') and vm.volatile_img is not None: | ||||||
|         print fmt.format ("root volatile img", vm.volatile_img) |         print fmt.format ("root volatile img", vm.volatile_img) | ||||||
| 
 | 
 | ||||||
| @ -65,7 +65,7 @@ def do_list(vm): | |||||||
|     print fmt.format ("MAC", "%s%s" % (vm.mac, " (auto)" if vm._mac is None else "")) |     print fmt.format ("MAC", "%s%s" % (vm.mac, " (auto)" if vm._mac is None else "")) | ||||||
| 
 | 
 | ||||||
|     if hasattr(vm, 'kernel'): |     if hasattr(vm, 'kernel'): | ||||||
|         if vm.template_vm is not None: |         if vm.template is not None: | ||||||
|             print fmt.format ("kernel", "%s (from template)" % vm.kernel) |             print fmt.format ("kernel", "%s (from template)" % vm.kernel) | ||||||
|         elif vm.uses_default_kernel: |         elif vm.uses_default_kernel: | ||||||
|             print fmt.format ("kernel", "%s (default)" % vm.kernel) |             print fmt.format ("kernel", "%s (default)" % vm.kernel) | ||||||
| @ -161,61 +161,8 @@ def set_netvm(vms, vm, args): | |||||||
| 
 | 
 | ||||||
|     vm.netvm = netvm |     vm.netvm = netvm | ||||||
| 
 | 
 | ||||||
| def set_updateable(vms, vm, args): |  | ||||||
|     if vm.is_updateable(): |  | ||||||
|         print >> sys.stderr, "VM '{0}' is already set 'updateable', no action required.".format(vm.name) |  | ||||||
|         return True |  | ||||||
| 
 |  | ||||||
|     if vm.is_running(): |  | ||||||
|         print >> sys.stderr, "Cannot change 'updateable' attribute of a running VM. Shut it down first." |  | ||||||
|         return False |  | ||||||
| 
 |  | ||||||
|     if vm.is_appvm(): |  | ||||||
|         # Check if the Template is *non* updateable... |  | ||||||
|         if not vm.template_vm.is_updateable(): |  | ||||||
|             print >> sys.stderr, "VM '{0}': Setting 'updateable' attribute to True.".format(vm.name) |  | ||||||
|             vm.set_updateable() |  | ||||||
|         else: |  | ||||||
|             print >> sys.stderr, "The Template VM ('{0}') is marked as 'updateable' itself!".format(vm.template_vm.name) |  | ||||||
|             print >> sys.stderr, "Cannot make the AppVM updateable too, as this might cause COW-backed storage incoherency." |  | ||||||
|             print >> sys.stderr, "If you want to make this AppVM updateable, you must first make the Template VM nonupdateable." |  | ||||||
|             return False |  | ||||||
| 
 |  | ||||||
|     if vm.is_template(): |  | ||||||
|         # Make sure that all the AppVMs are non-updateable... |  | ||||||
|         for appvm in vm.appvms.values(): |  | ||||||
|             if appvm.is_updateable(): |  | ||||||
|                 print >> sys.stderr, "At least one of the AppVMs ('{0}') of this Template VM is also marked 'updateable'.".format(appvm.name) |  | ||||||
|                 print >> sys.stderr, "Cannot make the Template VM updateable too, as this might cause COW-backed storage incoherency." |  | ||||||
|                 print >> sys.stderr, "If you want to make this Template VM updateable, you must first make all its decedent AppVMs nonupdateable." |  | ||||||
|                 return False |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         print >> sys.stderr, "VM '{0}': Setting 'updateable' attribute to True.".format(vm.name) |  | ||||||
|         vm.set_updateable() |  | ||||||
|   |  | ||||||
|     return True |  | ||||||
| 
 |  | ||||||
| def set_nonupdateable(vms, vm, args): |  | ||||||
|     if not vm.is_updateable(): |  | ||||||
|         print >> sys.stderr, "VM '{0}' is already set 'nonupdateable', no action required.".format(vm.name) |  | ||||||
|         return True |  | ||||||
| 
 |  | ||||||
|     if vm.is_running(): |  | ||||||
|         print >> sys.stderr, "Cannot change 'updateable' attribute of a running VM. Shut it down first." |  | ||||||
|         return False |  | ||||||
| 
 |  | ||||||
|     if vm.is_netvm(): |  | ||||||
|         print >> sys.stderr, "Why, on earth, would you want to make a NetVM 'nonupdateable'?" |  | ||||||
|         return False |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     print >> sys.stderr, "VM '{0}': Setting 'updateable' attribute to False.".format(vm.name) |  | ||||||
|     vm.set_nonupdateable() |  | ||||||
|     return True |  | ||||||
| 
 |  | ||||||
| def set_kernel(vms, vm, args): | def set_kernel(vms, vm, args): | ||||||
|     if vm.template_vm is not None: |     if vm.template is not None: | ||||||
|         print >> sys.stderr, "Cannot set kernel for template-based VM. Set it for template instead." |         print >> sys.stderr, "Cannot set kernel for template-based VM. Set it for template instead." | ||||||
|         return False |         return False | ||||||
| 
 | 
 | ||||||
| @ -250,17 +197,17 @@ def set_template(vms, vm, args): | |||||||
|         return False |         return False | ||||||
| 
 | 
 | ||||||
|     template_name = args[0]; |     template_name = args[0]; | ||||||
|     template_vm = vms.get_vm_by_name(template_name) |     template = vms.get_vm_by_name(template_name) | ||||||
|     if template_vm is None or template_vm.qid not in vms: |     if template is None or template.qid not in vms: | ||||||
|         print >> sys.stderr, "A VM with the name '{0}' does not exist in the system.".format(template_name) |         print >> sys.stderr, "A VM with the name '{0}' does not exist in the system.".format(template_name) | ||||||
|         return False |         return False | ||||||
| 
 | 
 | ||||||
|     if not template_vm.is_template(): |     if not template.is_template(): | ||||||
|         print >> sys.stderr, "VM '{0}' is not a TemplateVM".format(template_name) |         print >> sys.stderr, "VM '{0}' is not a TemplateVM".format(template_name) | ||||||
|         return False |         return False | ||||||
| 
 | 
 | ||||||
|     print >> sys.stderr, "Setting template for VM '{0}' to '{1}'...".format (vm.name, template_name) |     print >> sys.stderr, "Setting template for VM '{0}' to '{1}'...".format (vm.name, template_name) | ||||||
|     vm.template_vm = template_vm |     vm.template = template | ||||||
|     return True |     return True | ||||||
| 
 | 
 | ||||||
| def set_vcpus(vms, vm, args): | def set_vcpus(vms, vm, args): | ||||||
| @ -334,8 +281,6 @@ def set_include_in_backups(vms, vm, args): | |||||||
| 
 | 
 | ||||||
| properties = { | properties = { | ||||||
|     "include_in_backups": set_include_in_backups, |     "include_in_backups": set_include_in_backups, | ||||||
|     "updateable": set_updateable, |  | ||||||
|     "nonupdateable": set_nonupdateable, |  | ||||||
|     "pcidevs": set_pcidevs, |     "pcidevs": set_pcidevs, | ||||||
|     "label" : set_label, |     "label" : set_label, | ||||||
|     "netvm" : set_netvm, |     "netvm" : set_netvm, | ||||||
|  | |||||||
| @ -164,8 +164,8 @@ def main(): | |||||||
|         print >>sys.stderr, "ERROR: A VM with the name '{0}' does not exist in the system.".format(vmname) |         print >>sys.stderr, "ERROR: A VM with the name '{0}' does not exist in the system.".format(vmname) | ||||||
|         exit(1) |         exit(1) | ||||||
| 
 | 
 | ||||||
|     if not vm.is_updateable(): |     if vm.template is not None: | ||||||
|         print >>sys.stderr, "ERROR: To sync appmenus for non-updateable VM, do it on template instead" |         print >>sys.stderr, "ERROR: To sync appmenus for template based VM, do it on template instead" | ||||||
|         exit(1) |         exit(1) | ||||||
| 
 | 
 | ||||||
|     if not vm.is_running(): |     if not vm.is_running(): | ||||||
|  | |||||||
| @ -80,7 +80,7 @@ class QfileDaemonDvm: | |||||||
|             qvm_collection.unlock_db() |             qvm_collection.unlock_db() | ||||||
|             return None |             return None | ||||||
|         dispid=int(disp_name[4:]) |         dispid=int(disp_name[4:]) | ||||||
|         dispvm=qvm_collection.add_new_disposablevm(disp_name, vm_disptempl.template_vm, label=vm.label, dispid=dispid) |         dispvm=qvm_collection.add_new_disposablevm(disp_name, vm_disptempl.template, label=vm.label, dispid=dispid) | ||||||
|         # By default inherit firewall rules from calling VM |         # By default inherit firewall rules from calling VM | ||||||
|         if os.path.exists(vm.firewall_conf): |         if os.path.exists(vm.firewall_conf): | ||||||
|             disp_firewall_conf = '/var/run/qubes/%s-firewall.xml' % disp_name |             disp_firewall_conf = '/var/run/qubes/%s-firewall.xml' % disp_name | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Marek Marczykowski
						Marek Marczykowski