def _generate_random_mac(self): if self.conn and not self._random_mac: found = False for ignore in range(256): self._random_mac = _util.randomMAC(self.conn.getType().lower()) ret = self.is_conflict_net(self.conn, self._random_mac) if ret[1] is not None: continue found = True break if not found: logging.debug("Failed to generate non-conflicting MAC") return self._random_mac
def setup(self, conn=None): """ DEPRECATED: Please use setup_dev instead """ if not conn: conn = self.conn if self.macaddr is None: while 1: self.macaddr = _util.randomMAC(type=conn.getType().lower()) if self.is_conflict_net(conn)[1] is not None: continue else: break else: ret, msg = self.is_conflict_net(conn) if msg is not None: if ret is False: logging.warning(msg) else: raise RuntimeError(msg) if not self.bridge and self.type == "bridge": self.bridge = _util.default_bridge2(self.conn)
def setup_clone(self): """ Validate and set up all parameters needed for the new (clone) VM """ logging.debug("Validating clone parameters.") self._clone_xml = self.original_xml # XXX: Make sure a clone name has been specified? or generate one? logging.debug("Clone paths: %s" % (self._clone_devices)) # We simply edit the original VM xml in place doc = libxml2.parseDoc(self._clone_xml) ctx = doc.xpathNewContext() # changing name node = ctx.xpathEval("/domain/name") node[0].setContent(self._clone_name) # We always have a UUID since one is generated at init time node = ctx.xpathEval("/domain/uuid") node[0].setContent(self._clone_uuid) # changing mac count = ctx.xpathEval("count(/domain/devices/interface/mac)") for i in range(1, int(count + 1)): base_xpath = "/domain/devices/interface[%d]" % i base_node = ctx.xpathEval(base_xpath)[0] node = ctx.xpathEval(base_xpath + "/mac/@address") node = node and node[0] or None if not node: node = base_node.newChild(None, "mac", None) node.setProp("address", "tmp") node = ctx.xpathEval(base_xpath + "/mac/@address")[0] mac = None try: mac = self._clone_mac[i - 1] except Exception: while 1: mac = _util.randomMAC(self.original_conn.getType().lower()) dummy, msg = self._check_mac(mac) if msg is not None: continue else: break node.setContent(mac) if len(self.clone_virtual_disks) < len(self.original_virtual_disks): raise ValueError( _("More disks to clone than new paths specified. " "(%(passed)d specified, %(need)d needed") % { "passed": len(self.clone_virtual_disks), "need": len(self.original_virtual_disks) }) # Changing storage XML for i in range(0, len(self.original_virtual_disks)): orig_disk = self._original_virtual_disks[i] clone_disk = self._clone_virtual_disks[i] self._change_storage_xml(ctx, orig_disk, clone_disk) # Sync 'size' between the two if orig_disk.size: clone_disk.size = orig_disk.size # Setup proper cloning inputs for the new virtual disks if orig_disk.vol_object and clone_disk.vol_install: # Source and dest are managed. If they share the same pool, # replace vol_install with a CloneVolume instance, otherwise # simply set input_vol on the dest vol_install if (clone_disk.vol_install.pool.name() == orig_disk.vol_object. storagePoolLookupByVolume().name()): newname = clone_disk.vol_install.name clone_disk.vol_install = Storage.CloneVolume( newname, orig_disk.vol_object) else: clone_disk.vol_install.input_vol = orig_disk.vol_object elif not self.preserve_dest_disks: clone_disk.clone_path = orig_disk.path # Save altered clone xml self._clone_xml = str(doc) ctx.xpathFreeContext() doc.freeDoc()
def setup_clone(self): """ Validate and set up all parameters needed for the new (clone) VM """ logging.debug("Validating clone parameters.") self._clone_xml = self.original_xml if len(self.clone_virtual_disks) < len(self.original_virtual_disks): raise ValueError(_("More disks to clone than new paths specified. " "(%(passed)d specified, %(need)d needed") % {"passed" : len(self.clone_virtual_disks), "need" : len(self.original_virtual_disks) }) logging.debug("Clone paths: %s", self._clone_devices) self._guest.name = self._clone_name self._guest.uuid = self._clone_uuid self._clone_mac.reverse() for dev in self._guest.get_devices("graphics"): if dev.port and dev.port != -1: logging.warn(_("Setting the graphics device port to autoport, " "in order to avoid conflicting.")) dev.port = -1 for iface in self._guest.get_devices("interface"): iface.target_dev = None if self._clone_mac: mac = self._clone_mac.pop() else: while 1: mac = _util.randomMAC(self.original_conn.getType().lower(), conn=self.original_conn) dummy, msg = self._check_mac(mac) if msg is not None: continue else: break iface.macaddr = mac # Changing storage XML for i in range(len(self._original_virtual_disks)): orig_disk = self._original_virtual_disks[i] clone_disk = self._clone_virtual_disks[i] for disk in self._guest.get_devices("disk"): if disk.target == orig_disk.target: xmldisk = disk if clone_disk.vol_object: # XXX We could always do this with vol upload? # Special case: non remote cloning of a guest using # managed block devices: fall back to local cloning if # we have permissions to do so. This validation check # caused a few bug reports in a short period of time, # so must be a common case. if (clone_disk.is_remote() or clone_disk.type != clone_disk.TYPE_BLOCK or not orig_disk.path or not os.access(orig_disk.path, os.R_OK) or not clone_disk.path or not os.access(clone_disk.path, os.W_OK)): raise RuntimeError( _("Clone onto existing storage volume is not " "currently supported: '%s'") % clone_disk.path) # Sync 'size' between the two if orig_disk.size: clone_disk.size = orig_disk.size # Setup proper cloning inputs for the new virtual disks if orig_disk.vol_object and clone_disk.vol_install: # Source and dest are managed. If they share the same pool, # replace vol_install with a CloneVolume instance, otherwise # simply set input_vol on the dest vol_install if (clone_disk.vol_install.pool.name() == orig_disk.vol_object.storagePoolLookupByVolume().name()): newname = clone_disk.vol_install.name clone_disk.vol_install = Storage.CloneVolume(newname, orig_disk.vol_object) else: clone_disk.vol_install.input_vol = orig_disk.vol_object elif not self.preserve_dest_disks: clone_disk.clone_path = orig_disk.path # Change the XML xmldisk.path = None xmldisk.type = clone_disk.type xmldisk.path = clone_disk.path xmldisk.driver_type = orig_disk.driver_type # Save altered clone xml self._clone_xml = self._guest.get_xml_config() logging.debug("Clone guest xml is\n%s", self._clone_xml)
def setup_clone(self): """ Validate and set up all parameters needed for the new (clone) VM """ logging.debug("Validating clone parameters.") self._clone_xml = self.original_xml # XXX: Make sure a clone name has been specified? or generate one? logging.debug("Clone paths: %s", self._clone_devices) # We simply edit the original VM xml in place doc = libxml2.parseDoc(self._clone_xml) ctx = doc.xpathNewContext() # changing name node = ctx.xpathEval("/domain/name") node[0].setContent(self._clone_name) # We always have a UUID since one is generated at init time node = ctx.xpathEval("/domain/uuid") node[0].setContent(self._clone_uuid) # changing mac count = ctx.xpathEval("count(/domain/devices/interface/mac)") for i in range(1, int(count + 1)): base_xpath = "/domain/devices/interface[%d]" % i base_node = ctx.xpathEval(base_xpath)[0] node = ctx.xpathEval(base_xpath + "/mac/@address") node = node and node[0] or None if not node: node = base_node.newChild(None, "mac", None) node.setProp("address", "tmp") node = ctx.xpathEval(base_xpath + "/mac/@address")[0] mac = None try: mac = self._clone_mac[i - 1] except Exception: while 1: mac = _util.randomMAC(self.original_conn.getType().lower()) dummy, msg = self._check_mac(mac) if msg is not None: continue else: break node.setContent(mac) if len(self.clone_virtual_disks) < len(self.original_virtual_disks): raise ValueError(_("More disks to clone than new paths specified. " "(%(passed)d specified, %(need)d needed") % {"passed" : len(self.clone_virtual_disks), "need" : len(self.original_virtual_disks) }) # Changing storage XML for i in range(0, len(self.original_virtual_disks)): orig_disk = self._original_virtual_disks[i] clone_disk = self._clone_virtual_disks[i] self._change_storage_xml(ctx, orig_disk, clone_disk) # Sync 'size' between the two if orig_disk.size: clone_disk.size = orig_disk.size # Setup proper cloning inputs for the new virtual disks if orig_disk.vol_object and clone_disk.vol_install: # Source and dest are managed. If they share the same pool, # replace vol_install with a CloneVolume instance, otherwise # simply set input_vol on the dest vol_install if (clone_disk.vol_install.pool.name() == orig_disk.vol_object.storagePoolLookupByVolume().name()): newname = clone_disk.vol_install.name clone_disk.vol_install = Storage.CloneVolume(newname, orig_disk.vol_object) else: clone_disk.vol_install.input_vol = orig_disk.vol_object elif not self.preserve_dest_disks: clone_disk.clone_path = orig_disk.path # Save altered clone xml self._clone_xml = str(doc) ctx.xpathFreeContext() doc.freeDoc()