Merge branch 'hvm' of 10.141.1.101:/var/lib/qubes/git/marmarek/core into hvm
This commit is contained in:
		
						commit
						e574eb8bec
					
				| @ -80,6 +80,7 @@ default_kernelopts = "" | |||||||
| default_kernelopts_pcidevs = "iommu=soft swiotlb=2048" | default_kernelopts_pcidevs = "iommu=soft swiotlb=2048" | ||||||
| 
 | 
 | ||||||
| default_hvm_disk_size = 20*1024*1024*1024 | default_hvm_disk_size = 20*1024*1024*1024 | ||||||
|  | default_hvm_memory = 512 | ||||||
| 
 | 
 | ||||||
| config_template_pv = '/usr/share/qubes/vm-template.conf' | config_template_pv = '/usr/share/qubes/vm-template.conf' | ||||||
| config_template_hvm = '/usr/share/qubes/vm-template-hvm.conf' | config_template_hvm = '/usr/share/qubes/vm-template-hvm.conf' | ||||||
| @ -218,6 +219,7 @@ class QubesVm(object): | |||||||
|                  uses_default_kernel = True, |                  uses_default_kernel = True, | ||||||
|                  kernelopts = "", |                  kernelopts = "", | ||||||
|                  uses_default_kernelopts = True, |                  uses_default_kernelopts = True, | ||||||
|  |                  mac = None, | ||||||
|                  services = None): |                  services = None): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -234,6 +236,8 @@ class QubesVm(object): | |||||||
|         if netvm_vm is not None: |         if netvm_vm is not None: | ||||||
|             netvm_vm.connected_vms[qid] = self |             netvm_vm.connected_vms[qid] = self | ||||||
| 
 | 
 | ||||||
|  |         self._mac = mac | ||||||
|  | 
 | ||||||
|         # We use it in remove from disk to avoid removing rpm files (for templates) |         # We use it in remove from disk to avoid removing rpm files (for templates) | ||||||
|         self.installed_by_rpm = installed_by_rpm |         self.installed_by_rpm = installed_by_rpm | ||||||
| 
 | 
 | ||||||
| @ -396,6 +400,17 @@ class QubesVm(object): | |||||||
|             return None |             return None | ||||||
|         return "vif{0}.+".format(self.xid) |         return "vif{0}.+".format(self.xid) | ||||||
| 
 | 
 | ||||||
|  |     @property | ||||||
|  |     def mac(self): | ||||||
|  |         if self._mac is not None: | ||||||
|  |             return self._mac | ||||||
|  |         else: | ||||||
|  |             return "00:16:3E:5E:6C:{qid:02X}".format(qid=self.qid) | ||||||
|  | 
 | ||||||
|  |     @mac.setter | ||||||
|  |     def mac(self, new_mac): | ||||||
|  |         self._mac = new_mac | ||||||
|  | 
 | ||||||
|     def is_updateable(self): |     def is_updateable(self): | ||||||
|         return self.updateable |         return self.updateable | ||||||
| 
 | 
 | ||||||
| @ -815,7 +830,7 @@ class QubesVm(object): | |||||||
|         args['maxmem'] = str(self.maxmem) |         args['maxmem'] = str(self.maxmem) | ||||||
|         args['vcpus'] = str(self.vcpus) |         args['vcpus'] = str(self.vcpus) | ||||||
|         if self.netvm_vm is not None: |         if self.netvm_vm is not None: | ||||||
|             args['netdev'] = "'mac=00:16:3E:5E:6C:{qid:02X},script=/etc/xen/scripts/vif-route-qubes,ip={ip}".format(ip=self.ip, qid=self.qid) |             args['netdev'] = "'mac={mac},script=/etc/xen/scripts/vif-route-qubes,ip={ip}".format(ip=self.ip, mac=self.mac) | ||||||
|             if self.netvm_vm.qid != 0: |             if self.netvm_vm.qid != 0: | ||||||
|                 args['netdev'] += ",backend={0}".format(self.netvm_vm.name) |                 args['netdev'] += ",backend={0}".format(self.netvm_vm.name) | ||||||
|             args['netdev'] += "'" |             args['netdev'] += "'" | ||||||
| @ -934,6 +949,74 @@ class QubesVm(object): | |||||||
|         except subprocess.CalledProcessError: |         except subprocess.CalledProcessError: | ||||||
|             print >> sys.stderr, "Ooops, there was a problem creating appmenus for {0} VM!".format (self.name) |             print >> sys.stderr, "Ooops, there was a problem creating appmenus for {0} VM!".format (self.name) | ||||||
| 
 | 
 | ||||||
|  |     def get_clone_attrs(self): | ||||||
|  |         return ['kernel', 'uses_default_kernel', 'netvm_vm', 'uses_default_netvm', \ | ||||||
|  |             'memory', 'maxmem', 'kernelopts', 'uses_default_kernelopts', 'services', 'vcpus', \ | ||||||
|  |             '_mac'] | ||||||
|  | 
 | ||||||
|  |     def clone_attrs(self, src_vm): | ||||||
|  |         for prop in self.get_clone_attrs(): | ||||||
|  |             setattr(self, prop, getattr(src_vm, prop)) | ||||||
|  | 
 | ||||||
|  |     def clone_disk_files(self, src_vm, verbose): | ||||||
|  |         if dry_run: | ||||||
|  |             return | ||||||
|  | 
 | ||||||
|  |         if src_vm.is_running(): | ||||||
|  |             raise QubesException("Attempt to clone a running VM!") | ||||||
|  | 
 | ||||||
|  |         if verbose: | ||||||
|  |             print >> sys.stderr, "--> Creating directory: {0}".format(self.dir_path) | ||||||
|  |         os.mkdir (self.dir_path) | ||||||
|  | 
 | ||||||
|  |         if src_vm.private_img is not None and self.private_img is not None: | ||||||
|  |             if verbose: | ||||||
|  |                 print >> sys.stderr, "--> Copying the private image:\n{0} ==>\n{1}".\ | ||||||
|  |                         format(src_vm.private_img, self.private_img) | ||||||
|  |             # We prefer to use Linux's cp, because it nicely handles sparse files | ||||||
|  |             retcode = subprocess.call (["cp", src_vm.private_img, self.private_img]) | ||||||
|  |             if retcode != 0: | ||||||
|  |                 raise IOError ("Error while copying {0} to {1}".\ | ||||||
|  |                                format(src_vm.private_img, self.private_img)) | ||||||
|  | 
 | ||||||
|  |         if src_vm.updateable and src_vm.root_img is not None and self.root_img is not None: | ||||||
|  |             if verbose: | ||||||
|  |                 print >> sys.stderr, "--> Copying the root image:\n{0} ==>\n{1}".\ | ||||||
|  |                         format(src_vm.root_img, self.root_img) | ||||||
|  |             # We prefer to use Linux's cp, because it nicely handles sparse files | ||||||
|  |             retcode = subprocess.call (["cp", src_vm.root_img, self.root_img]) | ||||||
|  |             if retcode != 0: | ||||||
|  |                 raise IOError ("Error while copying {0} to {1}".\ | ||||||
|  |                            format(src_vm.root_img, self.root_img)) | ||||||
|  | 
 | ||||||
|  |         if src_vm.updateable and src_vm.appmenus_templates_dir is not None and self.appmenus_templates_dir is not None: | ||||||
|  |             if verbose: | ||||||
|  |                 print >> sys.stderr, "--> Copying the template's appmenus templates dir:\n{0} ==>\n{1}".\ | ||||||
|  |                         format(src_vm.appmenus_templates_dir, self.appmenus_templates_dir) | ||||||
|  |             shutil.copytree (src_vm.appmenus_templates_dir, self.appmenus_templates_dir) | ||||||
|  | 
 | ||||||
|  |         if os.path.exists(src_vm.dir_path + '/' + qubes_whitelisted_appmenus): | ||||||
|  |             if verbose: | ||||||
|  |                 print >> sys.stderr, "--> Copying whitelisted apps list: {0}".\ | ||||||
|  |                     format(self.dir_path + '/' + qubes_whitelisted_appmenus) | ||||||
|  |             shutil.copy(src_vm.dir_path + '/' + qubes_whitelisted_appmenus, | ||||||
|  |                     self.dir_path + '/' + qubes_whitelisted_appmenus) | ||||||
|  | 
 | ||||||
|  |         if src_vm.icon_path is not None and self.icon_path is not None: | ||||||
|  |             if os.path.exists (src_vm.dir_path): | ||||||
|  |                 if os.path.islink(src_vm.dir_path): | ||||||
|  |                     icon_path = os.readlink(src_vm.dir_path) | ||||||
|  |                     if verbose: | ||||||
|  |                         print >> sys.stderr, "--> Creating icon symlink: {0} -> {1}".format(self.icon_path, icon_path) | ||||||
|  |                     os.symlink (icon_path, self.icon_path) | ||||||
|  |                 else: | ||||||
|  |                     if verbose: | ||||||
|  |                         print >> sys.stderr, "--> Copying icon: {0} -> {1}".format(src_vm.icon_path, self.icon_path) | ||||||
|  |                     shutil.copy(src_vm.icon_path, self.icon_path) | ||||||
|  | 
 | ||||||
|  |         # Create appmenus | ||||||
|  |         self.create_appmenus(verbose) | ||||||
|  | 
 | ||||||
|     def remove_appmenus(self): |     def remove_appmenus(self): | ||||||
|         vmtype = None |         vmtype = None | ||||||
|         if self.is_netvm(): |         if self.is_netvm(): | ||||||
| @ -1342,6 +1425,8 @@ class QubesVm(object): | |||||||
|             'uses_default_netvm' ]: |             'uses_default_netvm' ]: | ||||||
|             if hasattr(self, prop): |             if hasattr(self, prop): | ||||||
|                 attrs[prop] = str(self.__getattribute__(prop)) |                 attrs[prop] = str(self.__getattribute__(prop)) | ||||||
|  |         if self._mac is not None: | ||||||
|  |             attrs["mac"] = str(self._mac) | ||||||
|         attrs["netvm_qid"] = str(self.netvm_vm.qid) if self.netvm_vm is not None else "none" |         attrs["netvm_qid"] = str(self.netvm_vm.qid) if self.netvm_vm is not None else "none" | ||||||
|         attrs["template_qid"] = str(self.template_vm.qid) if self.template_vm and not self.is_updateable() else "none" |         attrs["template_qid"] = str(self.template_vm.qid) if self.template_vm and not self.is_updateable() else "none" | ||||||
|         attrs["label"] = self.label.name |         attrs["label"] = self.label.name | ||||||
| @ -1406,39 +1491,24 @@ class QubesTemplateVm(QubesVm): | |||||||
|     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) | ||||||
| 
 | 
 | ||||||
|     def clone_disk_files(self, src_template_vm, verbose): |     def clone_disk_files(self, src_vm, verbose): | ||||||
|         if dry_run: |         if dry_run: | ||||||
|             return |             return | ||||||
| 
 | 
 | ||||||
|  |         super(QubesTemplateVM, self).clone_disk_files(src_vm=src_vm, verbose=verbose) | ||||||
| 
 | 
 | ||||||
|         assert not src_template_vm.is_running(), "Attempt to clone a running Template VM!" |         if os.path.exists(src_vm.dir_path + '/vm-' + qubes_whitelisted_appmenus): | ||||||
|  |             if verbose: | ||||||
|  |                 print >> sys.stderr, "--> Copying default whitelisted apps list: {0}".\ | ||||||
|  |                     format(self.dir_path + '/vm-' + qubes_whitelisted_appmenus) | ||||||
|  |             shutil.copy(src_vm.dir_path + '/vm-' + qubes_whitelisted_appmenus, | ||||||
|  |                     self.dir_path + '/vm-' + qubes_whitelisted_appmenus) | ||||||
| 
 | 
 | ||||||
|         if verbose: |  | ||||||
|             print >> sys.stderr, "--> Creating directory: {0}".format(self.dir_path) |  | ||||||
|         os.mkdir (self.dir_path) |  | ||||||
| 
 |  | ||||||
|         if verbose: |  | ||||||
|             print >> sys.stderr, "--> Copying the template's private image:\n{0} ==>\n{1}".\ |  | ||||||
|                     format(src_template_vm.private_img, self.private_img) |  | ||||||
|         # We prefer to use Linux's cp, because it nicely handles sparse files |  | ||||||
|         retcode = subprocess.call (["cp", src_template_vm.private_img, self.private_img]) |  | ||||||
|         if retcode != 0: |  | ||||||
|             raise IOError ("Error while copying {0} to {1}".\ |  | ||||||
|                            format(src_template_vm.private_img, self.private_img)) |  | ||||||
| 
 |  | ||||||
|         if verbose: |  | ||||||
|             print >> sys.stderr, "--> Copying the template's root image:\n{0} ==>\n{1}".\ |  | ||||||
|                     format(src_template_vm.root_img, self.root_img) |  | ||||||
|         # We prefer to use Linux's cp, because it nicely handles sparse files |  | ||||||
|         retcode = subprocess.call (["cp", src_template_vm.root_img, self.root_img]) |  | ||||||
|         if retcode != 0: |  | ||||||
|             raise IOError ("Error while copying {0} to {1}".\ |  | ||||||
|                            format(src_template_vm.root_img, self.root_img)) |  | ||||||
|         if verbose: |         if verbose: | ||||||
|             print >> sys.stderr, "--> Copying the template's clean volatile image:\n{0} ==>\n{1}".\ |             print >> sys.stderr, "--> Copying the template's clean volatile image:\n{0} ==>\n{1}".\ | ||||||
|                     format(src_template_vm.clean_volatile_img, self.clean_volatile_img) |                     format(src_vm.clean_volatile_img, self.clean_volatile_img) | ||||||
|         # We prefer to use Linux's cp, because it nicely handles sparse files |         # We prefer to use Linux's cp, because it nicely handles sparse files | ||||||
|         retcode = subprocess.call (["cp", src_template_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_template_vm.clean_volatile_img, self.clean_volatile_img)) | ||||||
| @ -1449,44 +1519,17 @@ class QubesTemplateVm(QubesVm): | |||||||
|         retcode = subprocess.call (["cp", self.clean_volatile_img, self.volatile_img]) |         retcode = subprocess.call (["cp", self.clean_volatile_img, self.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(self.clean_volatile_img, self.volatile_img)) |                            format(self.clean_img, self.volatile_img)) | ||||||
| 
 | 
 | ||||||
|         if verbose: |         if verbose: | ||||||
|             print >> sys.stderr, "--> Copying the template's DispVM prerun script..." |             print >> sys.stderr, "--> Copying the template's DispVM prerun script..." | ||||||
|         retcode = subprocess.call (["cp", src_template_vm.dir_path + '/dispvm-prerun.sh', self.dir_path + '/dispvm-prerun.sh']) |         retcode = subprocess.call (["cp", src_vm.dir_path + '/dispvm-prerun.sh', self.dir_path + '/dispvm-prerun.sh']) | ||||||
|         if retcode != 0: |         if retcode != 0: | ||||||
|             raise IOError ("Error while copying DispVM prerun script") |             raise IOError ("Error while copying DispVM prerun script") | ||||||
| 
 | 
 | ||||||
|         if verbose: |  | ||||||
|             print >> sys.stderr, "--> Copying the template's appmenus templates dir:\n{0} ==>\n{1}".\ |  | ||||||
|                     format(src_template_vm.appmenus_templates_dir, self.appmenus_templates_dir) |  | ||||||
|         shutil.copytree (src_template_vm.appmenus_templates_dir, self.appmenus_templates_dir) |  | ||||||
| 
 |  | ||||||
|         if os.path.exists(src_template_vm.dir_path + '/' + qubes_whitelisted_appmenus): |  | ||||||
|             if verbose: |  | ||||||
|                 print >> sys.stderr, "--> Copying whitelisted apps list: {0}".\ |  | ||||||
|                     format(self.dir_path + '/' + qubes_whitelisted_appmenus) |  | ||||||
|             shutil.copy(src_template_vm.dir_path + '/' + qubes_whitelisted_appmenus, |  | ||||||
|                     self.dir_path + '/' + qubes_whitelisted_appmenus) |  | ||||||
| 
 |  | ||||||
|         if os.path.exists(src_template_vm.dir_path + '/vm-' + qubes_whitelisted_appmenus): |  | ||||||
|             if verbose: |  | ||||||
|                 print >> sys.stderr, "--> Copying default whitelisted apps list: {0}".\ |  | ||||||
|                     format(self.dir_path + '/vm-' + qubes_whitelisted_appmenus) |  | ||||||
|             shutil.copy(src_template_vm.dir_path + '/vm-' + qubes_whitelisted_appmenus, |  | ||||||
|                     self.dir_path + '/vm-' + qubes_whitelisted_appmenus) |  | ||||||
| 
 |  | ||||||
|         icon_path = "/usr/share/qubes/icons/template.png" |  | ||||||
|         if verbose: |  | ||||||
|             print >> sys.stderr, "--> Creating icon symlink: {0} -> {1}".format(self.icon_path, icon_path) |  | ||||||
|         os.symlink (icon_path, self.icon_path) |  | ||||||
| 
 |  | ||||||
|         # Create root-cow.img |         # Create root-cow.img | ||||||
|         self.commit_changes(verbose=verbose) |         self.commit_changes(verbose=verbose) | ||||||
| 
 | 
 | ||||||
|         # Create appmenus |  | ||||||
|         self.create_appmenus(verbose, source_template = src_template_vm) |  | ||||||
| 
 |  | ||||||
|     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_vm | ||||||
| @ -2049,6 +2092,8 @@ class QubesHVm(QubesVm): | |||||||
|         # only updateable HVM supported |         # only updateable HVM supported | ||||||
|         kwargs["updateable"] = True |         kwargs["updateable"] = True | ||||||
|         kwargs["template_vm"] = None |         kwargs["template_vm"] = None | ||||||
|  |         if "memory" not in kwargs or kwargs["memory"] is None: | ||||||
|  |             kwargs["memory"] = default_hvm_memory | ||||||
| 
 | 
 | ||||||
|         super(QubesHVm, self).__init__(**kwargs) |         super(QubesHVm, self).__init__(**kwargs) | ||||||
|         self.updateable = True |         self.updateable = True | ||||||
| @ -2074,6 +2119,15 @@ class QubesHVm(QubesVm): | |||||||
|     def is_appvm(self): |     def is_appvm(self): | ||||||
|         return True |         return True | ||||||
| 
 | 
 | ||||||
|  |     def get_clone_attrs(self): | ||||||
|  |         attrs = super(QubesHVm, self).get_clone_attrs() | ||||||
|  |         attrs.remove('kernel') | ||||||
|  |         attrs.remove('uses_default_kernel') | ||||||
|  |         attrs.remove('kernelopts') | ||||||
|  |         attrs.remove('uses_default_kernelopts') | ||||||
|  |         attrs.remove('maxmem') | ||||||
|  |         return attrs | ||||||
|  | 
 | ||||||
|     def create_on_disk(self, verbose, source_template = None): |     def create_on_disk(self, verbose, source_template = None): | ||||||
|         if dry_run: |         if dry_run: | ||||||
|             return |             return | ||||||
| @ -2548,7 +2602,7 @@ class QubesVmCollection(dict): | |||||||
|                 "installed_by_rpm", "updateable", "internal", |                 "installed_by_rpm", "updateable", "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", | ||||||
|                 "services" ) |                 "mac", "services" ) | ||||||
| 
 | 
 | ||||||
|         for attribute in common_attr_list: |         for attribute in common_attr_list: | ||||||
|             kwargs[attribute] = element.get(attribute) |             kwargs[attribute] = element.get(attribute) | ||||||
|  | |||||||
| @ -21,13 +21,14 @@ | |||||||
| # | # | ||||||
| 
 | 
 | ||||||
| from qubes.qubes import QubesVmCollection | from qubes.qubes import QubesVmCollection | ||||||
|  | from qubes.qubes import QubesAppVm, QubesTemplateVm, QubesHVm | ||||||
| from qubes.qubes import QubesException | from qubes.qubes import QubesException | ||||||
| from optparse import OptionParser; | from optparse import OptionParser; | ||||||
| import sys | import sys | ||||||
| 
 | 
 | ||||||
| def main(): | def main(): | ||||||
|     usage = "usage: %prog [options] <src-template-name> <new-template-name>\n"\ |     usage = "usage: %prog [options] <src-name> <new-name>\n"\ | ||||||
|             "Clones an existing template by copying all its disk files" |             "Clones an existing VM by copying all its disk files" | ||||||
|            |            | ||||||
|     parser = OptionParser (usage) |     parser = OptionParser (usage) | ||||||
|     parser.add_option ("-q", "--quiet", action="store_false", dest="verbose", default=True) |     parser.add_option ("-q", "--quiet", action="store_false", dest="verbose", default=True) | ||||||
| @ -44,8 +45,8 @@ def main(): | |||||||
|     qvm_collection.lock_db_for_writing() |     qvm_collection.lock_db_for_writing() | ||||||
|     qvm_collection.load() |     qvm_collection.load() | ||||||
| 
 | 
 | ||||||
|     src_tvm = qvm_collection.get_vm_by_name(srcname) |     src_vm = qvm_collection.get_vm_by_name(srcname) | ||||||
|     if src_tvm is  None: |     if src_vm is  None: | ||||||
|         print >> sys.stderr, "ERROR: A VM with the name '{0}' does not exist in the system.".format(srcname) |         print >> sys.stderr, "ERROR: A VM with the name '{0}' does not exist in the system.".format(srcname) | ||||||
|         exit(1) |         exit(1) | ||||||
| 
 | 
 | ||||||
| @ -53,15 +54,26 @@ def main(): | |||||||
|         print >> sys.stderr, "ERROR: A VM with the name '{0}' already exists in the system.".format(dstname) |         print >> sys.stderr, "ERROR: A VM with the name '{0}' already exists in the system.".format(dstname) | ||||||
|         exit(1) |         exit(1) | ||||||
| 
 | 
 | ||||||
|     dst_tvm = qvm_collection.clone_templatevm(src_template_vm=src_tvm, |     dst_vm = None | ||||||
|                                               name=dstname,  |     if isinstance(src_vm, QubesTemplateVm): | ||||||
|  |         dst_vm = qvm_collection.add_new_templatevm(name=dstname, | ||||||
|  |                                               dir_path=options.dir_path, installed_by_rpm=False) | ||||||
|  |     elif isinstance(src_vm, QubesAppVm): | ||||||
|  |         dst_vm = qvm_collection.add_new_appvm(name=dstname, template_vm=src_vm.template_vm, | ||||||
|  |                                               updateable=src_vm.updateable, label=src_vm.label,  | ||||||
|                                               dir_path=options.dir_path) |                                               dir_path=options.dir_path) | ||||||
|  |     elif isinstance(src_vm, QubesHVm): | ||||||
|  |         dst_vm = qvm_collection.add_new_hvm(name=dstname, label=src_vm.label) | ||||||
|  |     else: | ||||||
|  |         print >> sys.stderr, "ERROR: Clone not supported for this type of VM" | ||||||
|  |         exit(1) | ||||||
| 
 | 
 | ||||||
|     try: |     try: | ||||||
|         dst_tvm.clone_disk_files (src_template_vm=src_tvm, verbose=options.verbose) |         dst_vm.clone_attrs(src_vm) | ||||||
|  |         dst_vm.clone_disk_files (src_vm=src_vm, verbose=options.verbose) | ||||||
|     except (IOError, OSError) as err: |     except (IOError, OSError) as err: | ||||||
|         print >> sys.stderr, "ERROR: {0}".format(err) |         print >> sys.stderr, "ERROR: {0}".format(err) | ||||||
|         qvm_collection.pop(dst_tvm.qid) |         qvm_collection.pop(dst_vm.qid) | ||||||
|         exit (1) |         exit (1) | ||||||
| 
 | 
 | ||||||
|     qvm_collection.save() |     qvm_collection.save() | ||||||
| @ -28,6 +28,7 @@ from optparse import OptionParser | |||||||
| import subprocess | import subprocess | ||||||
| import os | import os | ||||||
| import sys | import sys | ||||||
|  | import re | ||||||
| 
 | 
 | ||||||
| def do_list(vm): | def do_list(vm): | ||||||
|     label_width = 18 |     label_width = 18 | ||||||
| @ -60,6 +61,7 @@ def do_list(vm): | |||||||
|     print fmt.format ("memory", vm.memory) |     print fmt.format ("memory", vm.memory) | ||||||
|     if hasattr(vm, 'maxmem'): |     if hasattr(vm, 'maxmem'): | ||||||
|         print fmt.format ("maxmem", vm.maxmem) |         print fmt.format ("maxmem", vm.maxmem) | ||||||
|  |     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_vm is not None: | ||||||
| @ -78,7 +80,6 @@ def do_list(vm): | |||||||
|     if hasattr(vm, 'drive'): |     if hasattr(vm, 'drive'): | ||||||
|         print fmt.format("drive", str(vm.drive)) |         print fmt.format("drive", str(vm.drive)) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| def set_label(vms, vm, args): | def set_label(vms, vm, args): | ||||||
|     if len (args) != 1: |     if len (args) != 1: | ||||||
|         print >> sys.stderr, "Missing label name argument!" |         print >> sys.stderr, "Missing label name argument!" | ||||||
| @ -96,18 +97,38 @@ def set_label(vms, vm, args): | |||||||
| def set_memory(vms, vm, args): | def set_memory(vms, vm, args): | ||||||
|     if len (args) != 1: |     if len (args) != 1: | ||||||
|         print >> sys.stderr, "Missing memory argument!" |         print >> sys.stderr, "Missing memory argument!" | ||||||
|  |         exit (1) | ||||||
| 
 | 
 | ||||||
|     vm.memory = int(args[0]) |     vm.memory = int(args[0]) | ||||||
| 
 | 
 | ||||||
| def set_maxmem(vms, vm, args): | def set_maxmem(vms, vm, args): | ||||||
|     if len (args) != 1: |     if len (args) != 1: | ||||||
|         print >> sys.stderr, "Missing maxmem argument!" |         print >> sys.stderr, "Missing maxmem argument!" | ||||||
|  |         exit (1) | ||||||
| 
 | 
 | ||||||
|     vm.maxmem = int(args[0]) |     vm.maxmem = int(args[0]) | ||||||
| 
 | 
 | ||||||
|  | def set_mac(vms, vm, args): | ||||||
|  |     if len (args) != 1: | ||||||
|  |         print >> sys.stderr, "Missing MAC argument!" | ||||||
|  |         exit (1) | ||||||
|  | 
 | ||||||
|  |     if not re.match("[0-9a-fA-F:]{17}|auto", args[0]): | ||||||
|  |         print >> sys.stderr, "Invalid MAC argument!" | ||||||
|  |         print >> sys.stderr, "Possible values:" | ||||||
|  |         print >> sys.stderr, "1) auto" | ||||||
|  |         print >> sys.stderr, "2) MAC in format: XX:XX:XX:XX:XX:XX" | ||||||
|  |         exit (1) | ||||||
|  | 
 | ||||||
|  |     mac = args[0] | ||||||
|  |     if mac == "auto": | ||||||
|  |         mac = None | ||||||
|  |     vm.mac = mac | ||||||
|  | 
 | ||||||
| def set_pcidevs(vms, vm, args): | def set_pcidevs(vms, vm, args): | ||||||
|     if len (args) != 1: |     if len (args) != 1: | ||||||
|         print >> sys.stderr, "Missing pcidevs argument!" |         print >> sys.stderr, "Missing pcidevs argument!" | ||||||
|  |         exit (1) | ||||||
| 
 | 
 | ||||||
|     vm.pcidevs = list(eval(args[0])) |     vm.pcidevs = list(eval(args[0])) | ||||||
| 
 | 
 | ||||||
| @ -319,6 +340,7 @@ properties = { | |||||||
|     "kernelopts": set_kernelopts, |     "kernelopts": set_kernelopts, | ||||||
|     "name": set_name, |     "name": set_name, | ||||||
|     "drive": set_drive, |     "drive": set_drive, | ||||||
|  |     "mac": set_mac, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Joanna Rutkowska
						Joanna Rutkowska