def export_libvirt(conn, input_file): topdir = os.path.dirname(os.path.abspath(input_file)) infile = open(input_file, "r") contents = infile.readlines() infile.close() logging.debug("Importing VMX file:\n%s", "".join(contents)) vmxfile = _VMXFile(contents) config = vmxfile.pairs() if not config.get("displayname"): raise ValueError(_("No displayName defined in '%s'") % input_file) name = config.get("displayname") mem = config.get("memsize") desc = config.get("annotation") vcpus = config.get("numvcpus") def _find_keys(prefixes): ret = [] for key, value in config.items(): for p in util.listify(prefixes): if key.startswith(p): ret.append((key, value)) break return ret disks = [] for key, value in _find_keys(["scsi", "ide"]): parse_disk_entry(conn, disks, key, value, topdir) ifaces = [] for key, value in _find_keys("ethernet"): parse_netdev_entry(conn, ifaces, key, value) for disk in disks: if disk.device == "disk": continue # vmx files often have dross left in path for CD entries if (disk.path is None or disk.path.lower() == "auto detect" or not os.path.exists(disk.path)): disk.path = None guest = conn.caps.lookup_virtinst_guest() guest.installer = virtinst.ImportInstaller(conn) guest.name = name.replace(" ", "_") guest.description = desc or None if vcpus: guest.vcpus = int(vcpus) if mem: guest.memory = int(mem) * 1024 for dev in ifaces + disks: guest.add_device(dev) return guest
def _import_file(conn, input_file): """ Parse the OVF file and generate a virtinst.Guest object from it """ root = xml.etree.ElementTree.parse(input_file).getroot() vsnode = _find(root, "./ovf:VirtualSystem") vhnode = _find(vsnode, "./ovf:VirtualHardwareSection") # General info name = _text(vsnode.find("./ovf:Name", OVF_NAMESPACES)) desc = _text( vsnode.find("./ovf:AnnotationSection/ovf:Annotation", OVF_NAMESPACES)) if not desc: desc = _text(vsnode.find("./ovf:Description", OVF_NAMESPACES)) vhxpath = "./ovf:Item[rasd:ResourceType='%s']" vcpus = _text( _find(vhnode, (vhxpath % DEVICE_CPU) + "/rasd:VirtualQuantity")) mem = _text( _find(vhnode, (vhxpath % DEVICE_MEMORY) + "/rasd:VirtualQuantity")) alloc_mem = _text( _find(vhnode, (vhxpath % DEVICE_MEMORY) + "/rasd:AllocationUnits")) # Sections that we handle # NetworkSection is ignored, since I don't have an example of # a valid section in the wild. parsed_sections = [ "References", "DiskSection", "NetworkSection", "VirtualSystem" ] # Check for unhandled 'required' sections for env_node in root.findall("./"): if any([p for p in parsed_sections if p in env_node.tag]): continue logging.debug("Unhandled XML section '%s'", env_node.tag) if not _convert_bool_val(env_node.attrib.get("required")): continue raise Exception( _("OVF section '%s' is listed as " "required, but parser doesn't know " "how to handle it.") % env_node.name) disk_buses = {} for node in _findall(vhnode, vhxpath % DEVICE_IDE_BUS): instance_id = _text(_find(node, "rasd:InstanceID")) disk_buses[instance_id] = "ide" for node in _findall(vhnode, vhxpath % DEVICE_SCSI_BUS): instance_id = _text(_find(node, "rasd:InstanceID")) disk_buses[instance_id] = "scsi" ifaces = [] for node in _findall(vhnode, vhxpath % DEVICE_ETHERNET): iface = virtinst.DeviceInterface(conn) # Just ignore 'source' info for now and choose the default net_model = _text(_find(node, "rasd:ResourceSubType")) if net_model and not net_model.isdigit(): iface.model = net_model.lower() iface.set_default_source() ifaces.append(iface) disks = [] for node in _findall(vhnode, vhxpath % DEVICE_DISK): bus_id = _text(_find(node, "rasd:Parent")) path = _text(_find(node, "rasd:HostResource")) bus = disk_buses.get(bus_id, "ide") fmt = "raw" if path: path = _lookup_disk_path(root, path) fmt = "vmdk" disk = virtinst.DeviceDisk(conn) disk.path = path disk.driver_type = fmt disk.bus = bus disk.device = "disk" disks.append(disk) # Generate the Guest guest = conn.caps.lookup_virtinst_guest() guest.installer = virtinst.ImportInstaller(conn) if not name: name = os.path.basename(input_file) guest.name = name.replace(" ", "_") guest.description = desc or None if vcpus: guest.vcpus = int(vcpus) if mem: guest.memory = _convert_alloc_val(alloc_mem, mem) * 1024 for dev in ifaces + disks: guest.add_device(dev) return guest
def make_import_installer(os_type="hvm"): inst = virtinst.ImportInstaller(type="xen", os_type=os_type, conn=_conn) return inst
def _import_file(doc, ctx, conn, input_file): ignore = doc def xpath_str(path): ret = ctx.xpathEval(path) result = None if ret is not None: if type(ret) == list: if len(ret) >= 1: result = ret[0].content else: result = ret return result def bool_val(val): if str(val).lower() == "false": return False elif str(val).lower() == "true": return True return False def xpath_nodechildren(path): # Return the children of the first node found by the xpath nodes = ctx.xpathEval(path) if not nodes: return [] return node_list(nodes[0]) def _lookup_disk_path(path): fmt = "vmdk" ref = None def _path_has_prefix(prefix): if path.startswith(prefix): return path[len(prefix):] if path.startswith("ovf:" + prefix): return path[len("ovf:" + prefix):] return False if _path_has_prefix("/disk/"): disk_ref = _path_has_prefix("/disk/") xpath = (_make_section_xpath(envbase, "DiskSection") + "/ovf:Disk[@ovf:diskId='%s']" % disk_ref) if not ctx.xpathEval(xpath): raise ValueError( _("Unknown disk reference id '%s' " "for path %s.") % (path, disk_ref)) ref = xpath_str(xpath + "/@ovf:fileRef") elif _path_has_prefix("/file/"): ref = _path_has_prefix("/file/") else: raise ValueError(_("Unknown storage path type %s." % path)) xpath = (envbase + "/ovf:References/ovf:File[@ovf:id='%s']" % ref) if not ctx.xpathEval(xpath): raise ValueError( _("Unknown reference id '%s' " "for path %s.") % (ref, path)) return xpath_str(xpath + "/@ovf:href"), fmt is_ovirt_format = False envbase = "/ovf:Envelope[1]" vsbase = envbase + "/ovf:VirtualSystem" if not ctx.xpathEval(vsbase): vsbase = envbase + "/ovf:Content[@xsi:type='ovf:VirtualSystem_Type']" is_ovirt_format = True def _make_section_xpath(base, section_name): if is_ovirt_format: return (base + "/ovf:Section[@xsi:type='ovf:%s_Type']" % section_name) return base + "/ovf:%s" % section_name osbase = _make_section_xpath(vsbase, "OperatingSystemSection") vhstub = _make_section_xpath(vsbase, "VirtualHardwareSection") if not ctx.xpathEval(vsbase): raise RuntimeError("Did not find any VirtualSystem section") if not ctx.xpathEval(vhstub): raise RuntimeError("Did not find any VirtualHardwareSection") vhbase = vhstub + "/ovf:Item[rasd:ResourceType='%s']" # General info name = xpath_str(vsbase + "/ovf:Name") desc = xpath_str(vsbase + "/ovf:AnnotationSection/ovf:Annotation") if not desc: desc = xpath_str(vsbase + "/ovf:Description") vcpus = xpath_str((vhbase % DEVICE_CPU) + "/rasd:VirtualQuantity") sockets = xpath_str((vhbase % DEVICE_CPU) + "/rasd:num_of_sockets") cores = xpath_str((vhbase % DEVICE_CPU) + "/rasd:num_of_cores") mem = xpath_str((vhbase % DEVICE_MEMORY) + "/rasd:VirtualQuantity") alloc_mem = xpath_str((vhbase % DEVICE_MEMORY) + "/rasd:AllocationUnits") os_id = xpath_str(osbase + "/@id") os_version = xpath_str(osbase + "/@version") # This is the VMWare OS name os_vmware = xpath_str(osbase + "/@osType") logging.debug("OS parsed as: id=%s version=%s vmware=%s", os_id, os_version, os_vmware) # Sections that we handle # NetworkSection is ignored, since I don't have an example of # a valid section in the wild. parsed_sections = [ "References", "DiskSection", "NetworkSection", "VirtualSystem" ] # Check for unhandled 'required' sections for env_node in xpath_nodechildren(envbase): if env_node.name in parsed_sections: continue elif env_node.isText(): continue logging.debug("Unhandled XML section '%s'", env_node.name) if not bool_val(env_node.prop("required")): continue raise StandardError( _("OVF section '%s' is listed as " "required, but parser doesn't know " "how to handle it.") % env_node.name) disk_buses = {} for node in ctx.xpathEval(vhbase % DEVICE_IDE_BUS): instance_id = _get_child_content(node, "InstanceID") disk_buses[instance_id] = "ide" for node in ctx.xpathEval(vhbase % DEVICE_SCSI_BUS): instance_id = _get_child_content(node, "InstanceID") disk_buses[instance_id] = "scsi" ifaces = [] for node in ctx.xpathEval(vhbase % DEVICE_ETHERNET): iface = virtinst.VirtualNetworkInterface(conn) # XXX: Just ignore 'source' info and choose the default net_model = _get_child_content(node, "ResourceSubType") if net_model and not net_model.isdigit(): iface.model = net_model.lower() iface.set_default_source() ifaces.append(iface) disks = [] for node in ctx.xpathEval(vhbase % DEVICE_DISK): bus_id = _get_child_content(node, "Parent") path = _get_child_content(node, "HostResource") bus = disk_buses.get(bus_id, "ide") fmt = "raw" if path: path, fmt = _lookup_disk_path(path) disk = virtinst.VirtualDisk(conn) disk.path = path disk.driver_type = fmt disk.bus = bus disk.device = "disk" disks.append(disk) # XXX: Convert these OS values to something useful ignore = os_version ignore = os_id ignore = os_vmware (capsguest, capsdomain) = conn.caps.guest_lookup() guest = conn.caps.build_virtinst_guest(conn, capsguest, capsdomain) guest.installer = virtinst.ImportInstaller(conn) if not name: name = os.path.basename(input_file) guest.name = name.replace(" ", "_") guest.description = desc or None if vcpus: guest.vcpus = int(vcpus) elif sockets or cores: if sockets: guest.cpu.sockets = int(sockets) if cores: guest.cpu.cores = int(cores) guest.cpu.vcpus_from_topology() if mem: guest.memory = _convert_alloc_val(alloc_mem, mem) * 1024 for dev in ifaces + disks: guest.add_device(dev) return guest
def make_import_installer(): return virtinst.ImportInstaller(_conn)