Beispiel #1
0
    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
Beispiel #2
0
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
Beispiel #3
0
def make_import_installer(os_type="hvm"):
    inst = virtinst.ImportInstaller(type="xen", os_type=os_type, conn=_conn)
    return inst
Beispiel #4
0
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
Beispiel #5
0
def make_import_installer():
    return virtinst.ImportInstaller(_conn)