def import_file(input_file): """ Import a configuration file. Raises if the file couldn't be opened, or parsing otherwise failed. """ vm = vmcfg.vm() infile = open(input_file, "r") contents = infile.readlines() infile.close() lines = [] # strip out comment and blank lines for easy splitting of values for line in contents: if not line.strip() or line.startswith("#"): continue else: lines.append(line) config = {} # split out all remaining entries of key = value form for (line_nr, line) in enumerate(lines): try: before_eq, after_eq = line.split("=", 1) key = before_eq.strip().lower() value = after_eq.strip().strip('"') config[key] = value if key.startswith("scsi") or key.startswith("ide"): parse_disk_entry(vm, key, value) if key.startswith("ethernet"): parse_netdev_entry(vm, key, value) except: raise Exception(_("Syntax error at line %d: %s") % (line_nr + 1, line.strip())) for devid, disk in vm.disks.iteritems(): if disk.type == diskcfg.DISK_TYPE_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)): vm.disks[devid].path = None if not config.get("displayname"): raise ValueError(_("No displayName defined in \"%s\"") % input_file) vm.name = config.get("displayname") vm.memory = config.get("memsize") vm.description = config.get("annotation") vm.nr_vcpus = config.get("numvcpus") vm.validate() return vm
def import_file(input_file): """ Import a configuration file. Raises if the file couldn't be opened, or parsing otherwise failed. """ vm = vmcfg.vm() infile = open(input_file, "r") contents = infile.readlines() infile.close() lines = [] # strip out comment and blank lines for easy splitting of values for line in contents: if not line.strip() or line.startswith("#"): continue else: lines.append(line) config = {} # split out all remaining entries of key = value form for (line_nr, line) in enumerate(lines): try: before_eq, after_eq = line.split("=", 1) key = before_eq.strip().lower() value = after_eq.strip().strip('"') config[key] = value if key.startswith("scsi") or key.startswith("ide"): parse_disk_entry(vm, key, value) if key.startswith("ethernet"): parse_netdev_entry(vm, key, value) except: raise Exception( _("Syntax error at line %d: %s") % (line_nr + 1, line.strip())) for devid, disk in vm.disks.iteritems(): if disk.type == diskcfg.DISK_TYPE_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)): vm.disks[devid].path = None if not config.get("displayname"): raise ValueError( _("No displayName defined in \"%s\"") % input_file) vm.name = config.get("displayname") vm.memory = config.get("memsize") vm.description = config.get("annotation") vm.nr_vcpus = config.get("numvcpus") vm.validate() return vm
def convert(self, indir, outdir, output_format): """ Convert a disk into the requested format if possible, in the given output directory. Raises RuntimeError or other failures. """ if self.type != DISK_TYPE_DISK: return out_format = disk_format_names[output_format] if not (out_format == DISK_FORMAT_NONE or out_format == DISK_FORMAT_VDISK or out_format == DISK_FORMAT_RAW or out_format == DISK_FORMAT_VMDK or out_format == DISK_FORMAT_QCOW or out_format == DISK_FORMAT_QCOW2 or out_format == DISK_FORMAT_COW): raise NotImplementedError(_("Cannot convert to disk format %s") % output_format) indir = os.path.normpath(os.path.abspath(indir)) outdir = os.path.normpath(os.path.abspath(outdir)) input_in_outdir, need_conversion = self.copy(indir, outdir, out_format) if not need_conversion: assert(input_in_outdir) return if os.path.isabs(self.path): raise NotImplementedError(_("Cannot convert disk with absolute" " path %s") % self.path) if input_in_outdir: indir = outdir relin = self.path absin = os.path.join(indir, relin) relout = self.out_file(out_format) absout = os.path.join(outdir, relout) ensuredirs(absout) if os.getenv("VIRTCONV_TEST_NO_DISK_CONVERSION"): self.format = out_format self.path = self.out_file(self.format) return if out_format == DISK_FORMAT_VDISK: self.vdisk_convert(absin, absout) else: self.qemu_convert(absin, absout, out_format) self.format = out_format self.path = relout
def convert(self, indir, outdir, output_format): """ Convert a disk into the requested format if possible, in the given output directory. Raises RuntimeError or other failures. """ if self.type != DISK_TYPE_DISK: return out_format = disk_format_names[output_format] if not (out_format == DISK_FORMAT_NONE or out_format == DISK_FORMAT_VDISK or out_format == DISK_FORMAT_RAW or out_format == DISK_FORMAT_VMDK or out_format == DISK_FORMAT_QCOW or out_format == DISK_FORMAT_QCOW2 or out_format == DISK_FORMAT_COW): raise NotImplementedError( _("Cannot convert to disk format %s") % output_format) indir = os.path.normpath(os.path.abspath(indir)) outdir = os.path.normpath(os.path.abspath(outdir)) input_in_outdir, need_conversion = self.copy(indir, outdir, out_format) if not need_conversion: assert (input_in_outdir) return if os.path.isabs(self.path): raise NotImplementedError( _("Cannot convert disk with absolute" " path %s") % self.path) if input_in_outdir: indir = outdir relin = self.path absin = os.path.join(indir, relin) relout = self.out_file(out_format) absout = os.path.join(outdir, relout) ensuredirs(absout) if os.getenv("VIRTCONV_TEST_NO_DISK_CONVERSION"): self.format = out_format self.path = self.out_file(self.format) return if out_format == DISK_FORMAT_VDISK: self.vdisk_convert(absin, absout) else: self.qemu_convert(absin, absout, out_format) self.format = out_format self.path = relout
def _parse(self): for line in self.content: try: lineobj = _VMXLine(line) self.lines.append(lineobj) except Exception, e: raise Exception(_("Syntax error at line %d: %s\n%s") % (len(self.lines) + 1, line.strip(), e))
def _parse(self): for line in self.content: try: lineobj = _VMXLine(line) self.lines.append(lineobj) except Exception, e: raise Exception( _("Syntax error at line %d: %s\n%s") % (len(self.lines) + 1, line.strip(), e))
def import_file(input_file): """ Import a configuration file. Raises if the file couldn't be opened, or parsing otherwise failed. """ vm = vmcfg.vm() try: config = ImageParser.parse_file(input_file) except Exception, e: raise ValueError(_("Couldn't import file '%s': %s") % (input_file, e))
def validate(self): """ Validate all parameters, and fix up any unset values to meet the guarantees we make above. """ if not self.name: raise ValueError(_("VM name is not set")) if not self.description: self.description = "" if not self.nr_vcpus: self.nr_vcpus = 1 if self.type == VM_TYPE_UNKNOWN: raise ValueError(_("VM type is not set")) if not self.arch: raise ValueError(_("VM arch is not set")) for (bus, inst), disk in sorted(self.disks.iteritems()): if disk.type == diskcfg.DISK_TYPE_DISK and not disk.path: raise ValueError( _("Disk %s:%s storage does not exist") % (bus, inst))
def validate(self): """ Validate all parameters, and fix up any unset values to meet the guarantees we make above. """ if not self.name: raise ValueError(_("VM name is not set")) if not self.description: self.description = "" if not self.nr_vcpus: self.nr_vcpus = 1 if self.type == VM_TYPE_UNKNOWN: raise ValueError(_("VM type is not set")) if not self.arch: raise ValueError(_("VM arch is not set")) for (bus, inst), disk in sorted(self.disks.iteritems()): if disk.type == diskcfg.DISK_TYPE_DISK and not disk.path: raise ValueError(_("Disk %s:%s storage does not exist") % (bus, inst))
def parse_vmdk(disk, filename): """ Parse a VMDK descriptor file Reference: http://sanbarrow.com/vmdk-basics.html """ # Detect if passed file is a descriptor file # Assume descriptor isn't larger than 10K if not os.path.exists(filename): logging.debug("VMDK file '%s' doesn't exist" % filename) return if os.path.getsize(filename) > (10 * 1024): logging.debug("VMDK file '%s' too big to be a descriptor" % filename) return f = open(filename, "r") content = f.readlines() f.close() try: vmdkfile = _VMXFile(content) except: logging.exception("%s looked like a vmdk file, but parsing failed" % filename) return disklines = filter(lambda l: l.is_disk, vmdkfile.lines) if len(disklines) == 0: raise RuntimeError( _("Didn't detect a storage line in the VMDK " "descriptor file")) if len(disklines) > 1: raise RuntimeError( _("Don't know how to handle multistorage VMDK " "descriptors")) diskline = disklines[0] newpath = diskline.parse_disk_path() logging.debug("VMDK file parsed path %s->%s" % (disk.path, newpath)) disk.path = newpath
def parse_vmdk(disk, filename): """ Parse a VMDK descriptor file Reference: http://sanbarrow.com/vmdk-basics.html """ # Detect if passed file is a descriptor file # Assume descriptor isn't larger than 10K if not os.path.exists(filename): logging.debug("VMDK file '%s' doesn't exist", filename) return if os.path.getsize(filename) > (10 * 1024): logging.debug("VMDK file '%s' too big to be a descriptor", filename) return f = open(filename, "r") content = f.readlines() f.close() try: vmdkfile = _VMXFile(content) except: logging.exception("%s looked like a vmdk file, but parsing failed", filename) return disklines = filter(lambda l: l.is_disk, vmdkfile.lines) if len(disklines) == 0: raise RuntimeError(_("Didn't detect a storage line in the VMDK " "descriptor file")) if len(disklines) > 1: raise RuntimeError(_("Don't know how to handle multistorage VMDK " "descriptors")) diskline = disklines[0] newpath = diskline.parse_disk_path() logging.debug("VMDK file parsed path %s->%s", disk.path, newpath) disk.path = newpath
def export(vm): """ Export a configuration file as a string. @vm vm configuration instance Raises ValueError if configuration is not suitable. """ if not vm.memory: raise ValueError(_("VM must have a memory setting")) # xend wants the name to match r'^[A-Za-z0-9_\-\.\:\/\+]+$', and # the schema agrees. vmname = re.sub(r'[^A-Za-z0-9_\-\.:\/\+]+', '_', vm.name) # Hmm. Any interface is a good interface? interface = None if len(vm.netdevs): interface = "<interface />" acpi, apic = export_os_params(vm) if vm.type == vmcfg.VM_TYPE_PV: boot_template = pv_boot_template else: boot_template = hvm_boot_template (storage, disks) = export_disks(vm) boot_xml = boot_template % { "disks" : "".join(disks), "arch" : vm.arch, "acpi" : acpi, "apic" : apic, } out = image_template % { "boot_template": boot_xml, "name" : vmname, "description" : escape(vm.description), "nr_vcpus" : vm.nr_vcpus, # Mb to Kb "memory" : int(vm.memory) * 1024, "interface" : interface, "storage" : "".join(storage), } return out
def import_file(input_file): """ Import a configuration file. Raises if the file couldn't be opened, or parsing otherwise failed. """ vm = vmcfg.vm() try: f = file(input_file, "r") output = f.read() f.close() logging.debug("Importing virt-image XML:\n%s", output) config = ImageParser.parse(output, input_file) except Exception, e: raise ValueError( _("Couldn't import file '%s': %s") % (input_file, e))
def import_file(input_file): """ Import a configuration file. Raises if the file couldn't be opened, or parsing otherwise failed. """ vm = vmcfg.vm() try: f = file(input_file, "r") output = f.read() f.close() logging.debug("Importing virt-image XML:\n%s", output) config = ImageParser.parse(output, input_file) except Exception, e: raise ValueError(_("Couldn't import file '%s': %s") % (input_file, e))
def _get_xml_path(ctx): result = None if path: ret = ctx.xpathEval(path) if ret != None: if type(ret) == list: if len(ret) >= 1: #result = ret[0].content result = ret else: result = ret elif func: result = func(ctx) else: raise ValueError(_("'path' or 'func' is required.")) return result
def import_file(input_file): """ Import a configuration file. Raises if the file couldn't be opened, or parsing otherwise failed. """ vm = vmcfg.vm() 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) vm.name = config.get("displayname") vm.memory = config.get("memsize") vm.description = config.get("annotation") vm.nr_vcpus = config.get("numvcpus") for key, value in config.items(): if key.startswith("scsi") or key.startswith("ide"): parse_disk_entry(vm, key, value) if key.startswith("ethernet"): parse_netdev_entry(vm, key, value) for devid, disk in vm.disks.iteritems(): if disk.type == diskcfg.DISK_TYPE_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)): vm.disks[devid].path = None vm.validate() return vm
def import_file(input_file): """ Import a configuration file. Raises if the file couldn't be opened, or parsing otherwise failed. """ vm = vmcfg.vm() 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) vm.name = config.get("displayname") vm.memory = config.get("memsize") vm.description = config.get("annotation") vm.nr_vcpus = config.get("numvcpus") for key, value in config.items(): if key.startswith("scsi") or key.startswith("ide"): parse_disk_entry(vm, key, value) if key.startswith("ethernet"): parse_netdev_entry(vm, key, value) for devid, disk in vm.disks.iteritems(): if disk.type == diskcfg.DISK_TYPE_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)): vm.disks[devid].path = None vm.validate() return vm
def find_input(path, format = None): """ Search for a configuration file automatically. If @format is given, then only search using a matching format parser. """ if os.path.isdir(path): files = os.listdir(path) for p in _parsers: if not p.can_identify: continue if format and format != p.name: continue if os.path.isfile(path): if p.identify_file(path): return (path, p.name) elif os.path.isdir(path): for cfgfile in [ x for x in files if x.endswith(p.suffix) ]: if p.identify_file(os.path.join(path, cfgfile)): return (os.path.join(path, cfgfile), p.name) raise StandardError(_("Unknown format"))
def find_input(path, format=None): """ Search for a configuration file automatically. If @format is given, then only search using a matching format parser. """ if os.path.isdir(path): files = os.listdir(path) for p in _parsers: if not p.can_identify: continue if format and format != p.name: continue if os.path.isfile(path): if p.identify_file(path): return (path, p.name) elif os.path.isdir(path): for cfgfile in [x for x in files if x.endswith(p.suffix)]: if p.identify_file(os.path.join(path, cfgfile)): return (os.path.join(path, cfgfile), p.name) raise StandardError(_("Unknown format"))
def _parse_hw_section(vm, nodes, file_refs, disk_section): vm.nr_vcpus = 0 disk_buses = {} for device_node in nodes: if device_node.name != "Item": continue devtype = None for item_node in node_list(device_node): if item_node.name == "ResourceType": devtype = item_node.content if devtype == DEVICE_CPU: cpus = get_child_content(device_node, "VirtualQuantity") if cpus: vm.nr_vcpus += int(cpus) elif devtype == DEVICE_MEMORY: mem = get_child_content(device_node, "VirtualQuantity") alloc_str = get_child_content(device_node, "AllocationUnits") if mem: vm.memory = convert_alloc_val(alloc_str, mem) elif devtype == DEVICE_ETHERNET: net_model = get_child_content(device_node, "ResourceSubType") if net_model: net_model = net_model.lower() netdev = netdevcfg.netdev(driver=net_model) vm.netdevs[len(vm.netdevs)] = netdev elif devtype == DEVICE_IDE_BUS: instance_id = get_child_content(device_node, "InstanceID") disk_buses[instance_id] = "ide" elif devtype == DEVICE_SCSI_BUS: instance_id = get_child_content(device_node, "InstanceID") disk_buses[instance_id] = "scsi" elif devtype in [DEVICE_DISK]: bus_id = get_child_content(device_node, "Parent") path = get_child_content(device_node, "HostResource") dev_num = int(get_child_content(device_node, "AddressOnParent")) if bus_id and bus_id not in disk_buses: raise ValueError( _("Didn't find parent bus for disk '%s'" % path)) bus = (bus_id and disk_buses[bus_id]) or "ide" fmt = diskcfg.DISK_FORMAT_RAW if path: ref = None fmt = diskcfg.DISK_FORMAT_VMDK if path.startswith("ovf:/disk/"): disk_ref = path[len("ovf:/disk/"):] if disk_ref not in disk_section: raise ValueError( _("Unknown reference id '%s' " "for path %s.") % (path, ref)) ref, fmt = disk_section[disk_ref] elif path.startswith("ovf:/file/"): ref = path[len("ovf:/file/"):] else: raise ValueError(_("Unknown storage path type %s." % path)) if not ref: # XXX: This means allocate the disk. pass if ref not in file_refs: raise ValueError( _("Unknown reference id '%s' " "for path %s.") % (path, ref)) path = file_refs[ref] disk = diskcfg.disk(path=path, format=fmt, bus=bus, type=diskcfg.DISK_TYPE_DISK) vm.disks[(bus, dev_num)] = disk else: desc = get_child_content(device_node, "Description") logging.debug("Unhandled device type=%s desc=%s", devtype, desc)
def _parse_hw_section(vm, nodes, file_refs, disk_section): vm.nr_vcpus = 0 disk_buses = {} for device_node in nodes: if device_node.name != "Item": continue devtype = None for item_node in node_list(device_node): if item_node.name == "ResourceType": devtype = item_node.content if devtype == DEVICE_CPU: cpus = get_child_content(device_node, "VirtualQuantity") if cpus: vm.nr_vcpus += int(cpus) elif devtype == DEVICE_MEMORY: mem = get_child_content(device_node, "VirtualQuantity") alloc_str = get_child_content(device_node, "AllocationUnits") if mem: vm.memory = convert_alloc_val(alloc_str, mem) elif devtype == DEVICE_ETHERNET: net_model = get_child_content(device_node, "ResourceSubType") if net_model: net_model = net_model.lower() netdev = netdevcfg.netdev(driver=net_model) vm.netdevs[len(vm.netdevs)] = netdev elif devtype == DEVICE_IDE_BUS: instance_id = get_child_content(device_node, "InstanceID") disk_buses[instance_id] = "ide" elif devtype == DEVICE_SCSI_BUS: instance_id = get_child_content(device_node, "InstanceID") disk_buses[instance_id] = "scsi" elif devtype in [ DEVICE_DISK ]: bus_id = get_child_content(device_node, "Parent") path = get_child_content(device_node, "HostResource") dev_num = int(get_child_content(device_node, "AddressOnParent")) if bus_id and bus_id not in disk_buses: raise ValueError(_("Didn't find parent bus for disk '%s'" % path)) bus = (bus_id and disk_buses[bus_id]) or "ide" fmt = diskcfg.DISK_FORMAT_RAW if path: ref = None fmt = diskcfg.DISK_FORMAT_VMDK if path.startswith("ovf:/disk/"): disk_ref = path[len("ovf:/disk/"):] if disk_ref not in disk_section: raise ValueError(_("Unknown reference id '%s' " "for path %s.") % (path, ref)) ref, fmt = disk_section[disk_ref] elif path.startswith("ovf:/file/"): ref = path[len("ovf:/file/"):] else: raise ValueError(_("Unknown storage path type %s." % path)) if not ref: # XXX: This means allocate the disk. pass if ref not in file_refs: raise ValueError(_("Unknown reference id '%s' " "for path %s.") % (path, ref)) path = file_refs[ref] disk = diskcfg.disk(path=path, format=fmt, bus=bus, type=diskcfg.DISK_TYPE_DISK) vm.disks[(bus, dev_num)] = disk else: desc = get_child_content(device_node, "Description") logging.debug("Unhandled device type=%s desc=%s" % (devtype, desc))
class virtimage_parser(formats.parser): """ Support for virt-install's image format (see virt-image man page). """ name = "virt-image" suffix = ".virt-image.xml" can_import = True can_export = True can_identify = True @staticmethod def identify_file(input_file): """ Return True if the given file is of this format. """ try: ImageParser.parse_file(input_file) except ImageParser.ParserException: return False return True @staticmethod def import_file(input_file): """ Import a configuration file. Raises if the file couldn't be opened, or parsing otherwise failed. """ vm = vmcfg.vm() try: config = ImageParser.parse_file(input_file) except Exception, e: raise ValueError(_("Couldn't import file '%s': %s") % (input_file, e)) domain = config.domain boot = domain.boots[0] if not config.name: raise ValueError(_("No Name defined in '%s'") % input_file) vm.name = config.name vm.memory = int(config.domain.memory / 1024) if config.descr: vm.description = config.descr vm.nr_vcpus = config.domain.vcpu bus = "ide" nr_disk = 0 for d in boot.drives: disk = d.disk fmt = None if disk.format == ImageParser.Disk.FORMAT_RAW: fmt = diskcfg.DISK_FORMAT_RAW elif disk.format == ImageParser.Disk.FORMAT_VMDK: fmt = diskcfg.DISK_FORMAT_VMDK if fmt is None: raise ValueError(_("Unable to determine disk format")) devid = (bus, nr_disk) vm.disks[devid] = diskcfg.disk(bus = bus, type = diskcfg.DISK_TYPE_DISK) vm.disks[devid].format = fmt vm.disks[devid].path = disk.file nr_disk = nr_disk + 1 nics = domain.interface nic_idx = 0 while nic_idx in range(0, nics): vm.netdevs[nic_idx] = netdevcfg.netdev(type = netdevcfg.NETDEV_TYPE_UNKNOWN) nic_idx = nic_idx + 1 """ Eventually need to add support for mac addresses if given""" vm.validate() return vm
def _import_file(ctx): def xpath_str(path): ret = ctx.xpathEval(path) result = None if ret != 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_nodes(path): return ctx.xpathEval(path) vm = vmcfg.vm() file_refs = {} disk_section = {} net_section = {} name = None desc = None os_id_ignore = None os_ver_ignore = None os_type_ignore = None # XXX: Can have multiple machines nested as VirtualSystemCollection # XXX: Need to check all Envelope # General info name = xpath_str("/ovf:Envelope/ovf:VirtualSystem/ovf:Name") # Map files in <References> to actual filename ens = xpath_nodes("/ovf:Envelope[1]")[0] envelope_node = ens.children for envelope_node in node_list(ens): if envelope_node.name == "References": for reference_node in envelope_node.children: if reference_node.name != "File": continue file_id = reference_node.prop("id") path = reference_node.prop("href") # XXX: Should we validate the path exists? This can # be http. if file_id and path: file_refs[file_id] = path elif envelope_node.name == "DiskSection": for disk_node in envelope_node.children: if disk_node.name != "Disk": continue fmt = disk_node.prop("format") if not fmt: fmt = diskcfg.DISK_FORMAT_VMDK elif fmt.lower().count("vmdk"): fmt = diskcfg.DISK_FORMAT_VMDK else: fmt = diskcfg.DISK_FORMAT_VMDK disk_id = disk_node.prop("diskId") file_ref = disk_node.prop("fileRef") capacity = disk_node.prop("capacity") alloc_str = disk_node.prop("AllocationUnits") capacity = convert_alloc_val(alloc_str, capacity) # XXX: Empty fileref means 'create this disk' disk_section[disk_id] = (file_ref, fmt) elif envelope_node.name == "NetworkSection": for net_node in envelope_node.children: if net_node.name != "Network": continue net_name_ignore = net_node.prop("name") net_section[name] = None elif not envelope_node.isText(): logging.debug("Unhandled XML section '%s'" % envelope_node.name) req = bool_val(envelope_node.prop("required")) if req: raise StandardError(_("OVF section '%s' is listed as " "required, but parser doesn't know " "how to handle it.") % envelope_node.name) # Now parse VirtualSystem, since we should have set up all the # necessary file/disk/whatever refs for envelope_node in node_list(ens): if envelope_node.name != "VirtualSystem": continue for vs_node in node_list(envelope_node): if vs_node.name == "Info": pass elif vs_node.name == "Name": name = vs_node.content elif vs_node.name == "OperatingSystemSection": os_id_ignore = vs_node.prop("id") os_ver_ignore = vs_node.prop("version") # This is the VMWare OS name os_type_ignore = vs_node.prop("osType") elif vs_node.name == "VirtualHardwareSection": _parse_hw_section(vm, node_list(vs_node), file_refs, disk_section) elif vs_node.name == "AnnotationSection": for an_node in node_list(vs_node): if an_node.name == "Annotation": desc = an_node.content vm.name = name vm.description = desc vm.validate() return vm
def _import_file(ctx): def xpath_str(path): ret = ctx.xpathEval(path) result = None if ret != 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_nodes(path): return ctx.xpathEval(path) vm = vmcfg.vm() file_refs = {} disk_section = {} net_section = {} name = None desc = None os_id_ignore = None os_ver_ignore = None os_type_ignore = None # XXX: Can have multiple machines nested as VirtualSystemCollection # XXX: Need to check all Envelope # General info name = xpath_str("/ovf:Envelope/ovf:VirtualSystem/ovf:Name") # Map files in <References> to actual filename ens = xpath_nodes("/ovf:Envelope[1]")[0] envelope_node = ens.children for envelope_node in node_list(ens): if envelope_node.name == "References": for reference_node in envelope_node.children: if reference_node.name != "File": continue file_id = reference_node.prop("id") path = reference_node.prop("href") # XXX: Should we validate the path exists? This can # be http. if file_id and path: file_refs[file_id] = path elif envelope_node.name == "DiskSection": for disk_node in envelope_node.children: if disk_node.name != "Disk": continue fmt = disk_node.prop("format") if not fmt: fmt = diskcfg.DISK_FORMAT_VMDK elif fmt.lower().count("vmdk"): fmt = diskcfg.DISK_FORMAT_VMDK else: fmt = diskcfg.DISK_FORMAT_VMDK disk_id = disk_node.prop("diskId") file_ref = disk_node.prop("fileRef") capacity = disk_node.prop("capacity") alloc_str = disk_node.prop("AllocationUnits") capacity = convert_alloc_val(alloc_str, capacity) # XXX: Empty fileref means 'create this disk' disk_section[disk_id] = (file_ref, fmt) elif envelope_node.name == "NetworkSection": for net_node in envelope_node.children: if net_node.name != "Network": continue net_name_ignore = net_node.prop("name") net_section[name] = None elif not envelope_node.isText(): logging.debug("Unhandled XML section '%s'", envelope_node.name) req = bool_val(envelope_node.prop("required")) if req: raise StandardError( _("OVF section '%s' is listed as " "required, but parser doesn't know " "how to handle it.") % envelope_node.name) # Now parse VirtualSystem, since we should have set up all the # necessary file/disk/whatever refs for envelope_node in node_list(ens): if envelope_node.name != "VirtualSystem": continue for vs_node in node_list(envelope_node): if vs_node.name == "Info": pass elif vs_node.name == "Name": name = vs_node.content elif vs_node.name == "OperatingSystemSection": os_id_ignore = vs_node.prop("id") os_ver_ignore = vs_node.prop("version") # This is the VMWare OS name os_type_ignore = vs_node.prop("osType") elif vs_node.name == "VirtualHardwareSection": _parse_hw_section(vm, node_list(vs_node), file_refs, disk_section) elif vs_node.name == "AnnotationSection": for an_node in node_list(vs_node): if an_node.name == "Annotation": desc = an_node.content vm.name = name vm.description = desc vm.validate() return vm