def test_with_sysprep_floppy(self): dom_str = read_data('vm_sysprep_floppy.xml') dom = xmlutils.fromstring(dom_str) # taken and amended from vm_sysprep_floppy.xml floppy_params = { 'index': 0, 'iface': 'fdc', 'name': 'fda', 'alias': 'ua-cc9acd76-7b44-4adf-881d-e98e1cf4e639', 'vmid': 'e9252f48-6b22-4c9b-8d9a-8531fcf71f4c', 'diskType': 'file', 'readonly': True, 'device': 'floppy', 'path': 'PAYLOAD:', 'propagateErrors': 'off', 'type': 'disk' } floppy_obj = vmdevices.storage.Drive(self.log, **floppy_params) disk_devs = [floppy_obj] domxml_preprocess.update_disks_xml_from_objs( FakeVM(self.log), dom, disk_devs) floppy_elem = dom.find('./devices/disk[@device="floppy"]') self.assertXMLEqual( xmlutils.tostring(floppy_elem, pretty=True), xmlutils.tostring(floppy_obj.getXML(), pretty=True), )
def test_replace_cdrom_with_minimal_drive(self): dom_str = read_data('vm_hibernated_390.xml') dom = xmlutils.fromstring(dom_str) # taken from the test XML and amended manually # please note: # - the lack of empty 'backingStore' element # - the 'driver' elements lack name="qemu" (default) cdrom_xml = u'''<disk device="cdrom" type="file"> <driver error_policy="report" type="raw" /> <source file="" startupPolicy="optional"> <seclabel model="dac" relabel="no" type="none" /> </source> <target bus="ide" dev="hdc" /> <readonly /> <alias name="ua-096534a7-5fbd-4bd1-add0-65501bce51f9" /> <address bus="1" controller="0" target="0" type="drive" unit="0" /> </disk>''' cdrom_params = vmdevices.storagexml.parse( xmlutils.fromstring(cdrom_xml), {} ) disk_devs = [ vmdevices.storage.Drive(self.log, **cdrom_params), ] domxml_preprocess.update_disks_xml_from_objs( FakeVM(self.log), dom, disk_devs) cdrom_elem = dom.find('./devices/disk[@device="cdrom"]') self.assertXMLEqual( xmlutils.tostring(cdrom_elem, pretty=True), cdrom_xml )
def create_backup_xml(address, drives, scratch_disks): domainbackup = vmxml.Element('domainbackup', mode='pull') server = vmxml.Element( 'server', transport=address.transport, socket=address.path) domainbackup.appendChild(server) disks = vmxml.Element('disks') # fill the backup XML disks for drive in drives.values(): disk = vmxml.Element('disk', name=drive.name, type='file') # scratch element can have dev=/path/to/block/disk # or file=/path/to/file/disk attribute according to # the disk type. # Currently, all the scratch disks resides on the # host local file storage. scratch = vmxml.Element('scratch', file=scratch_disks[drive.name]) storage.disable_dynamic_ownership(scratch, write_type=False) disk.appendChild(scratch) disks.appendChild(disk) domainbackup.appendChild(disks) return xmlutils.tostring(domainbackup)
def test_update_bandwidth_xml(self, base_spec_params): specParams = { 'inbound': { 'average': 1000, 'peak': 5000, 'floor': 200, 'burst': 1024, }, 'outbound': { 'average': 128, 'peak': 256, 'burst': 256, }, } conf = { 'device': 'network', 'macAddr': 'fake', 'network': 'default', 'specParams': base_spec_params, } XML = u""" <interface type='network'> <mac address="fake" /> <source bridge='default'/> <link state="up"/> <bandwidth> <inbound average='1000' peak='5000' floor='200' burst='1024'/> <outbound average='128' peak='256' burst='256'/> </bandwidth> </interface> """ dev = vmdevices.network.Interface(self.log, **conf) vnic_xml = dev.getXML() vmdevices.network.update_bandwidth_xml(dev, vnic_xml, specParams) self.assertXMLEqual(xmlutils.tostring(vnic_xml), XML)
def test_interface(self): interfaceXML = """ <interface type="bridge"> <address %s/> <mac address="52:54:00:59:F5:3F"/> <model type="virtio"/> <source bridge="ovirtmgmt"/> <filterref filter="no-mac-spoofing"/> <link state="up"/> <boot order="1"/> <driver name="vhost" queues="7"/> <tune> <sndbuf>0</sndbuf> </tune> <bandwidth> <inbound average="1000" burst="1024" peak="5000"/> <outbound average="128" burst="256"/> </bandwidth> </interface>""" % self.PCI_ADDR dev = {'nicModel': 'virtio', 'macAddr': '52:54:00:59:F5:3F', 'network': 'ovirtmgmt', 'address': self.PCI_ADDR_DICT, 'device': 'bridge', 'type': 'interface', 'bootOrder': '1', 'filter': 'no-mac-spoofing', 'specParams': {'inbound': {'average': 1000, 'peak': 5000, 'burst': 1024}, 'outbound': {'average': 128, 'burst': 256}}, 'custom': {'queues': '7'}, 'vm_custom': {'vhost': 'ovirtmgmt:true', 'sndbuf': '0'}, } iface = vmdevices.network.Interface(self.log, **dev) self.assertXMLEqual(xmlutils.tostring(iface.getXML()), interfaceXML)
def test_replace_cdrom_without_source_file(self): dom_str = read_data('vm_hibernated.xml') dom = xmlutils.fromstring(dom_str) cdrom_xml = u'''<disk device="cdrom" type="file"> <driver error_policy="report" name="qemu" type="raw" /> <source {file_src}startupPolicy="optional" /> <backingStore /> <target bus="ide" dev="hdc" /> <readonly /> <alias name="ide0-1-0" /> <address bus="1" controller="0" target="0" type="drive" unit="0" /> </disk>''' cdrom_params = vmdevices.storagexml.parse( xmlutils.fromstring(cdrom_xml.format(file_src='')), {} ) disk_devs = [ vmdevices.storage.Drive(self.log, **cdrom_params), ] domxml_preprocess.update_disks_xml_from_objs( FakeVM(self.log), dom, disk_devs) cdrom_elem = dom.find('./devices/disk[@device="cdrom"]') self.assertXMLEqual( xmlutils.tostring(cdrom_elem, pretty=True), cdrom_xml.format(file_src="file='' ") )
def test_interface_filter_parameters(self): interfaceXML = """ <interface type="bridge"> <address %s/> <mac address="52:54:00:59:F5:3F"/> <model type="virtio"/> <source bridge="ovirtmgmt"/> <filterref filter="clean-traffic"> <parameter name='IP' value='10.0.0.1'/> <parameter name='IP' value='10.0.0.2'/> </filterref> <link state="up"/> <boot order="1"/> <driver name="vhost"/> <tune> <sndbuf>0</sndbuf> </tune> </interface>""" % self.PCI_ADDR dev = { 'nicModel': 'virtio', 'macAddr': '52:54:00:59:F5:3F', 'network': 'ovirtmgmt', 'address': self.PCI_ADDR_DICT, 'device': 'bridge', 'type': 'interface', 'bootOrder': '1', 'filter': 'clean-traffic', 'filterParameters': [ {'name': 'IP', 'value': '10.0.0.1'}, {'name': 'IP', 'value': '10.0.0.2'}, ], 'vm_custom': {'vhost': 'ovirtmgmt:true', 'sndbuf': '0'}, } iface = vmdevices.network.Interface(self.log, **dev) self.assertXMLEqual(xmlutils.tostring(iface.getXML()), interfaceXML)
def test_replace_cdrom_with_minimal_drive(self): dom_str = read_data('vm_hibernated_390.xml') dom = xmlutils.fromstring(dom_str) # taken from the test XML and amended manually # please note: # - the lack of empty 'backingStore' element # - the 'driver' elements lack name="qemu" (default) cdrom_xml = u'''<disk device="cdrom" type="file"> <driver error_policy="report" type="raw" /> <source file="" startupPolicy="optional" /> <target bus="ide" dev="hdc" /> <readonly /> <alias name="ua-096534a7-5fbd-4bd1-add0-65501bce51f9" /> <address bus="1" controller="0" target="0" type="drive" unit="0" /> </disk>''' cdrom_params = vmdevices.storagexml.parse( xmlutils.fromstring(cdrom_xml), {} ) disk_devs = [ vmdevices.storage.Drive(self.log, **cdrom_params), ] domxml_preprocess.update_disks_xml_from_objs( FakeVM(self.log), dom, disk_devs) cdrom_elem = dom.find('./devices/disk[@device="cdrom"]') self.assertXMLEqual( xmlutils.tostring(cdrom_elem, pretty=True), cdrom_xml )
def _migration_params(self, muri): params = {libvirt.VIR_MIGRATE_PARAM_BANDWIDTH: self._maxBandwidth} if not self.tunneled: params[libvirt.VIR_MIGRATE_PARAM_URI] = str(muri) if self._consoleAddress: graphics = 'spice' if self._vm.hasSpice else 'vnc' params[libvirt.VIR_MIGRATE_PARAM_GRAPHICS_URI] = str( '%s://%s' % (graphics, self._consoleAddress)) if self._encrypted: # Use the standard host name or IP address when checking # the remote certificate. Not the migration destination, # which may be e.g. an IP address from a migration # network, not present in the certificate. params[libvirt.VIR_MIGRATE_PARAM_TLS_DESTINATION] = \ normalize_literal_addr(self.remoteHost) # REQUIRED_FOR: destination Vdsm < 4.3 if self._legacy_payload_path is not None: alias, path = self._legacy_payload_path dom = xmlutils.fromstring(self._vm.migratable_domain_xml()) source = dom.find(".//alias[@name='%s']/../source" % (alias, )) source.set('file', path) xml = xmlutils.tostring(dom) self._vm.log.debug("Migrating domain XML: %s", xml) params[libvirt.VIR_MIGRATE_PARAM_DEST_XML] = xml return params
def create_checkpoint_xml(backup_cfg, drives): if backup_cfg.to_checkpoint_id is None: return None # create the checkpoint XML for a backup checkpoint = vmxml.Element('domaincheckpoint') name = vmxml.Element('name') name.appendTextNode(backup_cfg.to_checkpoint_id) checkpoint.appendChild(name) cp_description = "checkpoint for backup '{}'".format(backup_cfg.backup_id) description = vmxml.Element('description') description.appendTextNode(cp_description) checkpoint.appendChild(description) if backup_cfg.parent_checkpoint_id is not None: cp_parent = vmxml.Element('parent') parent_name = vmxml.Element('name') parent_name.appendTextNode(backup_cfg.parent_checkpoint_id) cp_parent.appendChild(parent_name) checkpoint.appendChild(cp_parent) disks = vmxml.Element('disks') for disk in backup_cfg.disks: if disk.checkpoint: drive = drives[disk.img_id] disk_elm = vmxml.Element('disk', name=drive.name, checkpoint='bitmap') disks.appendChild(disk_elm) checkpoint.appendChild(disks) return xmlutils.tostring(checkpoint)
def memory_xml(params): """ Return <memory> device XML string specified by `params`. :param params (dict): dictionary of device parameters as sent by Engine :returns: XML string Example XML string: <memory model='dimm'> <target> <size unit='KiB'>524287</size> <node>1</node> </target> <alias name='dimm0'/> <address type='dimm' slot='0' base='0x100000000'/> </memory> """ # We get size in MB and send in KB size = int(params['size']) * 1024 node = params['node'] alias = params.get('alias') address = params.get('address') e_memory = etree.Element('memory', model='dimm') e_target = etree.SubElement(e_memory, 'target') e_size = etree.SubElement(e_target, 'size', unit='KiB') e_size.text = str(size) e_node = etree.SubElement(e_target, 'node') e_node.text = str(node) if alias is not None: etree.SubElement(e_memory, 'alias', name=alias) if address: etree.SubElement(e_memory, 'address', attrib=address) return xmlutils.tostring(e_memory)
def attachDevice(self, device_xml): if self._xml: dom = xmlutils.fromstring(self._xml) devices = dom.find('.//devices') attached_device = xmlutils.fromstring(device_xml) devices.append(attached_device) self._xml = xmlutils.tostring(dom)
def test_replace_disks_xml(self): dom, disk_devs = self._make_env() domxml_preprocess.replace_disks_xml(dom, disk_devs) self.assertXMLEqual( xmlutils.tostring(dom, pretty=True), read_data('domain_disk_block.xml') )
def extract_device_snippet(device_type, xml_str=None, dom=None): if dom is None: dom = xmlutils.fromstring(xml_str) devs = vmxml.Element('devices') for dev in dom.findall('./devices/%s' % device_type): vmxml.append_child(devs, etree_child=dev) return xmlutils.tostring(devs, pretty=True)
def test_replace_cdrom_withoutource_file(self): dom_str = read_data('vm_hibernated.xml') dom = xmlutils.fromstring(dom_str) cdrom_xml = u'''<disk device="cdrom" type="file"> <driver error_policy="report" name="qemu" type="raw" /> <source {file_src}startupPolicy="optional"> <seclabel model="dac" relabel="no" type="none" /> </source> <backingStore /> <target bus="ide" dev="hdc" /> <readonly /> <alias name="ide0-1-0" /> <address bus="1" controller="0" target="0" type="drive" unit="0" /> </disk>''' cdrom_params = vmdevices.storagexml.parse( xmlutils.fromstring(cdrom_xml.format(file_src='')), {} ) disk_devs = [ vmdevices.storage.Drive(self.log, **cdrom_params), ] domxml_preprocess.update_disks_xml_from_objs( FakeVM(self.log), dom, disk_devs) cdrom_elem = dom.find('./devices/disk[@device="cdrom"]') self.assertXMLEqual( xmlutils.tostring(cdrom_elem, pretty=True), cdrom_xml.format(file_src="file='' ") )
def testCreatePCIHostDeviceWithAddress(self, device_name): dev_spec = {'type': 'hostdev', 'device': device_name, 'address': self._PCI_ADDRESS} device = hostdevice.HostDevice(self.log, **dev_spec) self.assertXMLEqual( xmlutils.tostring(device.getXML()), hostdevlib.DEVICE_XML[device_name] % (self._PCI_ADDRESS_XML))
def test_dump_ns(self): expected_xml = u'''<ovirt-vm:vm xmlns:ovirt-vm="http://ovirt.org/vm/1.0"> <ovirt-vm:version type="float">4.2</ovirt-vm:version> </ovirt-vm:vm>''' metadata_obj = metadata.Metadata('ovirt-vm', 'http://ovirt.org/vm/1.0') self.assertXMLEqual( xmlutils.tostring(metadata_obj.dump('vm', version=4.2)), expected_xml)
def normalized(xml, sort_attrs=True): """ Returns indented XML string with optionally sorted attributes. """ element = xmlutils.fromstring(xml) if sort_attrs: xmlutils.sort_attributes(element) xmlutils.indent(element) return xmlutils.tostring(element)
def test_metadata_descriptor(self, values, expected_metadata): desc = MutableDomainDescriptor(METADATA) with desc.metadata_descriptor() as md: with md.values() as vals: vals.update(values) desc2 = DomainDescriptor(desc.xml) self.assertXMLEqual(expected_metadata, xmlutils.tostring(desc2.metadata, pretty=True))
def dev_elems_from_xml(vm, xml): """ Return device instance building elements from provided XML. The XML must contain <devices> element with a single device subelement, the one to create the instance for. Depending on the device kind <metadata> element may be required to provide device metadata; the element may and needn't contain unrelated metadata. This function is used in device hot(un)plugs. Example `xml` value (top element tag may be arbitrary): <?xml version='1.0' encoding='UTF-8'?> <hotplug> <devices> <interface type="bridge"> <mac address="66:55:44:33:22:11"/> <model type="virtio" /> <source bridge="ovirtmgmt" /> <filterref filter="vdsm-no-mac-spoofing" /> <link state="up" /> <bandwidth /> </interface> </devices> <metadata xmlns:ns0="http://ovirt.org/vm/tune/1.0" xmlns:ovirt-vm="http://ovirt.org/vm/1.0"> <ovirt-vm:vm xmlns:ovirt-vm="http://ovirt.org/vm/1.0"> <ovirt-vm:device mac_address='66:55:44:33:22:11'> <ovirt-vm:network>test</ovirt-vm:network> <ovirt-vm:portMirroring> <ovirt-vm:network>network1</ovirt-vm:network> <ovirt-vm:network>network2</ovirt-vm:network> </ovirt-vm:portMirroring> </ovirt-vm:device> </ovirt-vm:vm> </metadata> </hotplug> :param xml: XML specifying the device as described above. :type xml: basestring :returns: Triplet (device_class, device_element, device_meta) where `device_class` is the class to be used to create the device instance; `device_element` and `device_meta` are objects to be passed as arguments to device_class `from_xml_tree` method. """ dom = xmlutils.fromstring(xml) devices = vmxml.find_first(dom, 'devices') dev_elem = next(vmxml.children(devices)) _dev_type, dev_class = identify_from_xml_elem(dev_elem) meta = vmxml.find_first(dom, 'metadata', None) if meta is None: md_desc = metadata.Descriptor() else: md_desc = metadata.Descriptor.from_xml(xmlutils.tostring(meta)) dev_meta = _get_metadata_from_elem_xml(vm.id, md_desc, dev_class, dev_elem) return dev_class, dev_elem, dev_meta
def testCreatePCIHostDeviceWithAddress(self, device_name): dev_spec = { 'type': 'hostdev', 'device': device_name, 'address': self._PCI_ADDRESS } device = hostdevice.HostDevice(self.log, **dev_spec) self.assertXMLEqual( xmlutils.tostring(device.getXML()), hostdevlib.DEVICE_XML[device_name] % (self._PCI_ADDRESS_XML))
def testCreateSRIOVVF(self): dev_spec = {'type': hwclass.NIC, 'device': 'hostdev', 'hostdev': hostdevlib.SRIOV_VF, 'macAddr': 'ff:ff:ff:ff:ff:ff', 'specParams': {'vlanid': 3}, 'bootOrder': '9'} device = network.Interface(self.log, **dev_spec) self.assertXMLEqual( xmlutils.tostring(device.getXML()), hostdevlib.DEVICE_XML[hostdevlib.SRIOV_VF] % ('',))
def _check_device_xml(self, dev, dev_xml, expected_xml=None): dev.setup() try: rebuilt_xml = xmlutils.tostring(dev.getXML(), pretty=True) # make troubleshooting easier print(rebuilt_xml) result_xml = dev_xml if expected_xml is None else expected_xml self.assertXMLEqual(rebuilt_xml, result_xml) finally: dev.teardown()
def test_createXmlElem(self): dev = {'type': 'graphics', 'device': 'spice'} expected_xml = '''<?xml version=\'1.0\' encoding=\'utf-8\'?> <graphics device="spice" type="test" />''' with fake.VM(self.conf, devices=(dev,), create_device_objects=True) as testvm: graphics = testvm._devices[hwclass.GRAPHICS][0] element = graphics.createXmlElem('graphics', 'test', attributes=('device', 'foo',)) result = xmlutils.tostring(element) self.assertXMLEqual(result, expected_xml)
def test_file(self): drive = Drive(self.log, diskType=DISK_TYPE.FILE, **self.conf) expected = """ <disk name='vda' snapshot='external' type='file'> <source file='/image' type='file'/> </disk> """ snap_info = {'path': '/image', 'device': 'disk'} actual = drive.get_snapshot_xml(snap_info) self.assertXMLEqual(xmlutils.tostring(actual), expected)
def test_skip_without_placeholders(self): # any domain without placeholders is fine, picked random one xml_str = read_data('vm_hosted_engine_42.xml') dom = xmlutils.fromstring(xml_str) with MonkeyPatchScope([ (osinfo, 'version', self._version), ]): domxml_preprocess.replace_placeholders(dom, cpuarch.X86_64, serial='test-serial') self.assertXMLEqual(xmlutils.tostring(dom, pretty=True), xml_str)
def test_block(self): drive = Drive(self.log, diskType=DISK_TYPE.BLOCK, **self.conf) expected = """ <disk name='vda' snapshot='external' type='block'> <source dev='/dev/dm-1' type='block'/> </disk> """ snap_info = {'path': '/dev/dm-1', 'device': 'disk'} actual = drive.get_snapshot_xml(snap_info) self.assertXMLEqual(xmlutils.tostring(actual), expected)
def test_replace_values(self): xml_str = read_data('sysinfo_snippet_template.xml') dom = xmlutils.fromstring(xml_str) with MonkeyPatchScope([ (osinfo, 'version', self._version), ]): domxml_preprocess.replace_placeholders(dom, cpuarch.X86_64, serial='test-serial') self.assertXMLEqual(xmlutils.tostring(dom, pretty=True), read_data('sysinfo_snippet_filled.xml'))
def setup_device(dom, meta, log): name, type_ = _get_device_name_type(dom) if name is None: log.debug("Unknown kind of host device: %s", xmlutils.tostring(dom, pretty=True)) elif type_ == 'mdev': spawn_mdev(_mdev_properties(dom, meta), name, log) else: log.info('Detaching device %s from the host.' % (name, )) detach_detachable(name) log.info('Device %s dettached from the host.' % (name, ))
def test_drive_lease(self): """ we fill the drive lease. Happy path. """ disk_devs = self._inject_volume_chain( self.disk_devs, self.driveVolInfo) domxml_preprocess.update_leases_xml_from_disk_objs( self.vm, self.dom, disk_devs) xml_str = xmlutils.tostring(self.dom) self._check_leases(xml_str, [self.driveVolInfo])
def check_leases(self, conf): drive = Drive(self.log, diskType=DISK_TYPE.FILE, **conf) leases = list(drive.getLeasesXML()) self.assertEqual(1, len(leases)) xml = """ <lease> <key>vol_id</key> <lockspace>dom_id</lockspace> <target offset="0" path="path" /> </lease> """ self.assertXMLEqual(xmlutils.tostring(leases[0]), xml)
def test_disk_ignore_volumeinfo_from_metadata_xml(self): xml_snippet = u'''<volumeInfo> <path>/rhev/data-center/omitted/for/brevity</path> <volType>path</volType> </volumeInfo>''' root = xmlutils.fromstring(_DISK_DATA.metadata_xml) dev = vmxml.find_first(root, 'device') vmxml.append_child(dev, etree_child=xmlutils.fromstring(xml_snippet)) data = _TestData( copy.deepcopy(_DISK_DATA.conf), xmlutils.tostring(root)) self._check_drive_from_metadata_xml(data)
def test_drive_lease(self): """ we fill the drive lease. Happy path. """ disk_devs = self._inject_volume_chain(self.disk_devs, self.driveVolInfo) domxml_preprocess.update_leases_xml_from_disk_objs( self.vm, self.dom, disk_devs) xml_str = xmlutils.tostring(self.dom) self._check_leases(xml_str, [self.driveVolInfo])
def test_disk_ignore_volumeinfo_from_metadata_xml(self): xml_snippet = u'''<volumeInfo> <path>/rhev/data-center/omitted/for/brevity</path> <volType>path</volType> </volumeInfo>''' root = xmlutils.fromstring(_DISK_DATA.metadata_xml) dev = vmxml.find_first(root, 'device') vmxml.append_child(dev, etree_child=xmlutils.fromstring(xml_snippet)) data = _TestData(copy.deepcopy(_DISK_DATA.conf), xmlutils.tostring(root)) self._check_drive_from_metadata_xml(data)
def test_drive_lease_without_volume_chain(self): """ Lacking volumeChain attribute (like cdroms), don't raise. We treat leases like VM lease, because we cannot distinguish this case. """ domxml_preprocess.update_leases_xml_from_disk_objs( self.vm, self.dom, self.disk_devs) xml_str = xmlutils.tostring(self.dom) self._check_leases(xml_str, [self.vmVolInfo])
def teardown_device(dom, log): name, type_ = _get_device_name_type(dom) if name is None: log.debug("Unknown kind of host device: %s", xmlutils.tostring(dom, pretty=True)) elif type_ == 'mdev': despawn_mdev(name) else: pci_reattach = type_ == 'pci' log.info('Reattaching device %s to the host.' % (name,)) reattach_detachable(name, pci_reattach=pci_reattach) log.info('Device %s reattached to the host.' % (name,))
def check_leases(self, conf): drive = Drive(self.log, diskType=DISK_TYPE.FILE, **conf) leases = list(drive.getLeasesXML()) assert 1 == len(leases) xml = """ <lease> <key>vol_id</key> <lockspace>dom_id</lockspace> <target offset="0" path="path" /> </lease> """ self.assertXMLEqual(xmlutils.tostring(leases[0]), xml)
def test_skip_without_placeholders(self): # any domain without placeholders is fine, picked random one xml_str = read_data('vm_hosted_engine_42.xml') dom = xmlutils.fromstring(xml_str) with MonkeyPatchScope([ (osinfo, 'version', self._version), ]): domxml_preprocess.replace_placeholders( dom, cpuarch.X86_64, serial='test-serial') self.assertXMLEqual( xmlutils.tostring(dom, pretty=True), xml_str )
def testNumaTuneXMLMultiNode(self): domxml = libvirtxml.Domain(self.conf, self.log, cpuarch.X86_64) devices = [ hostdevice.HostDevice( self.log, **{'type': 'hostdev', 'device': device} ) for device in [ hostdevlib.SRIOV_PF, hostdevlib.SRIOV_VF, 'pci_0000_00_02_0' ] ] domxml.appendHostdevNumaTune(devices) xml = xmlutils.tostring(domxml.dom) self.assertRaises(AssertionError, lambda: find_xml_element(xml, './numatune'))
def testNumaTuneXMLMultiNode(self): domxml = libvirtxml.Domain(self.conf, self.log, cpuarch.X86_64) devices = [ hostdevice.HostDevice(self.log, **{ 'type': 'hostdev', 'device': device }) for device in [hostdevlib.SRIOV_PF, hostdevlib.SRIOV_VF, 'pci_0000_00_02_0'] ] domxml.appendHostdevNumaTune(devices) xml = xmlutils.tostring(domxml.dom) self.assertRaises(AssertionError, lambda: find_xml_element(xml, './numatune'))
def test_replace_values(self): xml_str = read_data('sysinfo_snippet_template.xml') dom = xmlutils.fromstring(xml_str) with MonkeyPatchScope([ (osinfo, 'version', self._version), (constants, 'SMBIOS_OSNAME', 'test-product'), ]): domxml_preprocess.replace_placeholders( dom, cpuarch.X86_64, serial='test-serial') self.assertXMLEqual( xmlutils.tostring(dom, pretty=True), read_data('sysinfo_snippet_filled.xml') )
def testNumaTuneXMLSingleNode(self, devices, numa_node): numatuneXML = """ <numatune> <memory mode="preferred" nodeset="{}" /> </numatune> """.format(numa_node) domxml = libvirtxml.Domain(self.conf, self.log, cpuarch.X86_64) devices = [hostdevice.HostDevice( self.log, **{'type': 'hostdev', 'device': device}) for device in devices] domxml.appendHostdevNumaTune(devices) xml = xmlutils.tostring(domxml.dom) self.assertXMLEqual(find_xml_element(xml, './numatune'), numatuneXML)
def test_getxml(self): spec = dict(sd_id="sd_id", lease_id="lease_id", path="/path", offset=1048576) lease = vmdevices.lease.Device(self.log, **spec) lease_xml = xmlutils.tostring(lease.getXML()) xml = """ <lease> <key>lease_id</key> <lockspace>sd_id</lockspace> <target offset="1048576" path="/path" /> </lease> """ self.assertXMLEqual(lease_xml, xml)
def test_block(self): drive = Drive(self.log, diskType=DISK_TYPE.BLOCK, **self.conf) expected = """ <disk name='vda' snapshot='external' type='block'> <source dev='/dev/dm-1' type='block'> <seclabel model="dac" relabel="no" type="none" /> </source> </disk> """ snap_info = {'path': '/dev/dm-1', 'device': 'disk'} actual = drive.get_snapshot_xml(snap_info) self.assertXMLEqual(xmlutils.tostring(actual), expected)
def _parse_tree(self, root): selector = '{%s}%s' % (self._namespace_uri, self._name) if root.tag == 'metadata': md_elem = root.find('./' + selector) else: md_elem = root.find('./metadata/' + selector) if md_elem is not None: md_uuid = root.find('./uuid') # UUID may not be present in hotplug/hotunplug metadata snippets uuid_text = '?' if md_uuid is None else md_uuid.text self._log.debug( 'parsing metadata for %s: %s', uuid_text, xmlutils.tostring(md_elem, pretty=True)) self._load(md_elem, self._namespace, self._namespace_uri)
def test_createXmlElem(self): devices = ''' <graphics type="spice"> <listen type="network" network="vdsm-ovirtmgmt"/> </graphics> ''' expected_xml = '''<?xml version=\'1.0\' encoding=\'utf-8\'?> <graphics device="spice" type="test" />''' with fake.VM(self.conf, xmldevices=devices, create_device_objects=True) as testvm: graphics = testvm._devices[hwclass.GRAPHICS][0] element = graphics.createXmlElem('graphics', 'test', attributes=('device', 'foo',)) result = xmlutils.tostring(element) self.assertXMLEqual(result, expected_xml)
def testCreateSRIOVVFWithAddress(self): dev_spec = {'type': hwclass.NIC, 'device': 'hostdev', 'hostdev': hostdevlib.SRIOV_VF, 'macAddr': 'ff:ff:ff:ff:ff:ff', 'specParams': {'vlanid': 3}, 'bootOrder': '9', 'address': {'slot': '0x02', 'bus': '0x01', 'domain': '0x0000', 'function': '0x0', 'type': 'pci'}} device = network.Interface(self.log, **dev_spec) self.assertXMLEqual( xmlutils.tostring(device.getXML()), hostdevlib.DEVICE_XML[hostdevlib.SRIOV_VF] % ( self._PCI_ADDRESS_XML ) )
def test_drive_lease_chain_not_matches(self): """ We have no choice but consider this a VM lease. """ disk_devs = self._inject_volume_chain( self.disk_devs, self.driveVolInfo, domainID='unknwonDomainID', volumeID='unknownVolumeID') domxml_preprocess.update_leases_xml_from_disk_objs( self.vm, self.dom, disk_devs) xml_str = xmlutils.tostring(self.dom) self._check_leases(xml_str, [self.vmVolInfo])
def dev_map_from_domain_xml(vmid, dom_desc, md_desc, log, noerror=False): """ Create a device map - same format as empty_dev_map from a domain XML representation. The domain XML is accessed through a Domain Descriptor. :param vmid: UUID of the vm whose devices need to be initialized. :type vmid: basestring :param dom_desc: domain descriptor to provide access to the domain XML :type dom_desc: `class DomainDescriptor` :param md_desc: metadata descriptor to provide access to the device metadata :type md_desc: `class metadata.Descriptor` :param log: logger instance to use for messages, and to pass to device objects. :type log: logger instance, as returned by logging.getLogger() :param noerror: Iff true, don't raise unexpected exceptions on device object initialization, just log them. :type noerror: bool :return: map of initialized devices, map of devices needing refresh. :rtype: A device map, in the same format as empty_dev_map() would return. """ log.debug('Initializing device classes from domain XML') dev_map = empty_dev_map() for dev_type, dev_class, dev_elem in _device_elements(dom_desc, log): dev_meta = _get_metadata_from_elem_xml(vmid, md_desc, dev_class, dev_elem) try: dev_obj = dev_class.from_xml_tree(log, dev_elem, dev_meta) except NotImplementedError: log.debug('Cannot initialize %s device: not implemented', dev_type) except Exception: if noerror: log.exception("Device initialization from XML failed") dev_elem_xml = xmlutils.tostring(dev_elem, pretty=True) log.error("Failed XML: %s", dev_elem_xml) log.error("Failed metadata: %s", dev_meta) else: raise else: dev_map[dev_type].append(dev_obj) log.debug('Initialized %d device classes from domain XML', len(dev_map)) return dev_map
def test_network(self): drive = Drive(self.log, diskType=DISK_TYPE.NETWORK, protocol='gluster', **self.conf) expected = """ <disk name='vda' snapshot='external' type='network'> <source protocol='gluster' name='volume/11111111-1111-1111-1111-111111111111' type='network'> <host name="brick1.example.com" port="49152" transport="tcp"/> <host name="brick2.example.com" port="49153" transport="tcp"/> </source> </disk> """ snap_info = { 'protocol': 'gluster', 'path': 'volume/11111111-1111-1111-1111-111111111111', 'diskType': 'network', 'device': 'disk', 'hosts': [ { 'name': 'brick1.example.com', 'port': '49152', 'transport': 'tcp' }, { 'name': 'brick2.example.com', 'port': '49153', 'transport': 'tcp' } ] } actual = drive.get_snapshot_xml(snap_info) self.assertXMLEqual(xmlutils.tostring(actual), expected)
def testCreateHostDevice(self, device_name): dev_spec = {'type': 'hostdev', 'device': device_name} device = hostdevice.HostDevice(self.log, **dev_spec) self.assertXMLEqual(xmlutils.tostring(device.getXML()), hostdevlib.DEVICE_XML[device_name] % ('',))
def check(self, device_conf, xml, diskType=DISK_TYPE.FILE): drive = Drive(self.log, diskType=diskType, **device_conf) self.assertXMLEqual(xmlutils.tostring(drive.getReplicaXML()), xml)
def check(self, device_conf, xml): drive = Drive(self.log, **device_conf) self.assertXMLEqual(xmlutils.tostring(drive.getXML()), xml)
def _build_xml(self, namespace=None, namespace_uri=None): with self._lock: md_elem = self._build_tree(namespace, namespace_uri) return xmlutils.tostring(md_elem, pretty=True)