Source code for virttest.libvirt_xml.nodedev_xml

"""
Module simplifying manipulation of XML described at
http://libvirt.org/formatnode.html
"""

import os
from virttest.libvirt_xml import base, xcepts, accessors


[docs]class CAPXML(base.LibvirtXMLBase): """ The base class for capability. """
[docs] def get_sysfs_sub_path(self): """ return the sub path store the info of capibility. """ raise NotImplementedError('get_sysfs_sub_path is not implemented.')
@staticmethod
[docs] def get_key2filename_dict(): """ Return a dict which contain the key and the name of info file. """ raise NotImplementedError('get_key2filename_dict is not implemeneted.')
[docs] def get_key2value_dict(self): """ Reutn a dict which contain the key and the value in capability xml. """ raise NotImplementedError('get_key2value_dict is not implemented.')
[docs]class SystemXML(CAPXML): """ class for capability which type is system. """ __slots__ = ('product', 'hdware_vendor', 'hdware_serial', 'hdware_uuid', 'firmware_vendor', 'firmversion', 'firm_release_date') __sysfs_sub_path__ = 'dmi/id/' __key2filename_dict__ = {'product': 'product_name', 'hdware_vendor': 'sys_vendor', 'hdware_serial': 'product_serial', 'hdware_uuid': 'product_uuid', 'firmware_vendor': 'bios_vendor', 'firmversion': 'bios_version', 'firm_release_date': 'bios_date'} @staticmethod
[docs] def get_key2filename_dict(): """ Return a dict which contain the key and the name of info file for System node device. """ return SystemXML.__key2filename_dict__
[docs] def get_key2value_dict(self): """ return the dict key2value key: the key in xml need to check. value: value in xml for this key. """ key2value_dict = {} for key in SystemXML.__key2filename_dict__: key2value_dict[key] = self[key] return key2value_dict
@staticmethod
[docs] def make_sysfs_sub_path(): """ return __sysfs_sub_path__ immediately. """ return SystemXML.__sysfs_sub_path__
[docs] def get_sysfs_sub_path(self): """ Return the sysfs_subdir. """ return self.make_sysfs_sub_path()
[docs]class NetXML(CAPXML): """ class for capability whose type is net. """ __slots__ = ('interface', 'address') def __init__(self, virsh_instance=base.virsh): accessors.XMLElementText('interface', self, parent_xpath='/', tag_name='interface') accessors.XMLElementText('address', self, parent_xpath='/', tag_name='address')
[docs]class StorageXML(CAPXML): """ class for capability whose type is storage. """ __slots__ = ('block', 'bus', 'driver_type') def __init__(self, virsh_instance=base.virsh): accessors.XMLElementText('block', self, parent_xpath='/', tag_name='block') accessors.XMLElementText('bus', self, parent_xpath='/', tag_name='bus') accessors.XMLElementText('driver_type', self, parent_xpath='/', tag_name='driver_type')
[docs]class PCIXML(CAPXML): """ class for capability whose type is pci. """ #Example: #<capability type='pci'> # <domain>0</domain> # <bus>7</bus> # <slot>0</slot> # <function>0</function> # <product id='0x1521'>I350 Gigabit Network Connection</product> # <vendor id='0x8086'>Intel Corporation</vendor> # <capability type='virt_functions'> # <address domain='0x0000' bus='0x08' slot='0x10' function='0x0'/> # <address domain='0x0000' bus='0x08' slot='0x10' function='0x4'/> # </capability> # <numa node='0'/> #</capability> __slots__ = ('domain', 'bus', 'slot', 'function', 'product_id', 'vendor_id', 'virt_functions', 'numa_node') def __init__(self, virsh_instance=base.virsh): accessors.XMLElementInt('domain', self, parent_xpath='/', tag_name='domain') accessors.XMLElementInt('bus', self, parent_xpath='/', tag_name='bus') accessors.XMLElementInt('slot', self, parent_xpath='/', tag_name='slot') accessors.XMLElementInt('function', self, parent_xpath='/', tag_name='function') accessors.XMLAttribute('product_id', self, parent_xpath='/', tag_name='product', attribute='id') accessors.XMLAttribute('vendor_id', self, parent_xpath='/', tag_name='vendor', attribute='id') accessors.XMLAttribute('numa_node', self, parent_xpath='/', tag_name='numa', attribute='node') accessors.XMLElementList('virt_functions', self, parent_xpath='/capability', marshal_from=self.marshal_from_address, marshal_to=self.marshal_to_address) super(PCIXML, self).__init__(virsh_instance=virsh_instance) self.xml = (' <capability type=\'pci\'></capability>')
[docs] class Address(base.LibvirtXMLBase): """ Address of Virtual Function device. """ #Example: # <address domain='0x0000' bus='0x08' slot='0x10' function='0x0'/> # <address domain='0x0000' bus='0x08' slot='0x10' function='0x4'/> __slots__ = ('domain', 'bus', 'slot', 'function') def __init__(self, virsh_instance=base.virsh): accessors.XMLAttribute('domain', self, parent_xpath='/', tag_name='address', attribute='domain') accessors.XMLAttribute('bus', self, parent_xpath='/', tag_name='address', attribute='bus') accessors.XMLAttribute('slot', self, parent_xpath='/', tag_name='address', attribute='slot') accessors.XMLAttribute('function', self, parent_xpath='/', tag_name='address', attribute='function') super(PCIXML.Address, self).__init__(virsh_instance=virsh_instance) self.xml = ('<address/>')
@staticmethod
[docs] def marshal_from_address(item, index, libvirtxml): """Convert an Address instance into tag + attributes""" root = item.xmltreefile.getroot() if root.tag == 'address': return (root.tag, dict(root.items())) else: raise xcepts.LibvirtXMLError("Expected a list of address " "instances, not a %s" % str(item))
@staticmethod
[docs] def marshal_to_address(tag, attr_dict, index, libvirtxml): """Convert a tag + attributes into an Address instance""" if not tag == 'address': return None # Don't convert this item newone = PCIXML.Address(virsh_instance=libvirtxml.virsh) newone.update(attr_dict, excpt=xcepts.LibvirtXMLError) return newone
@staticmethod
[docs] def make_sysfs_sub_path(domain, bus, slot, function): """ Make sysfs_sub_path for pci by domain,bus,slot and function. """ pci_bus_path = ("%04x:%02x" % (domain, bus)) pci_device_path = ("%04x:%02x:%02x.%01x" % (domain, bus, slot, function)) pci_sysfs_sub_path = ("pci_bus/%s/device/%s" % (pci_bus_path, pci_device_path)) return pci_sysfs_sub_path
[docs] def get_sysfs_sub_path(self): """ Return the sysfs_subdir in . Example: pci_bus/0000\:00/device/0000\:00\:00.0/ """ domain = self.domain bus = self.bus slot = self.slot function = self.function return PCIXML.make_sysfs_sub_path(domain, bus, slot, function)
__key2filename_dict__ = {'product_id': 'device', 'vendor_id': 'vendor', 'numa_node': 'numa_node'} @staticmethod
[docs] def get_key2filename_dict(): """ return the dict key2filename. key: the keys in pcixml need to check. filename: the name of file stored info for this key. """ return PCIXML.__key2filename_dict__
[docs] def get_key2value_dict(self): """ return the dict key2value key: the key in xml need to check. value: value in xml for this key. """ key2value_dict = {} for key in PCIXML.__key2filename_dict__: if key != "numa_node": key2value_dict[key] = self[key] else: try: key2value_dict[key] = self[key] except xcepts.LibvirtXMLNotFoundError: key2value_dict[key] = "-1" return key2value_dict
[docs] def get_address_dict(self): """ Return a dict contain the address. """ address = {'domain': self.domain, 'bus': self.bus, 'slot': self.slot, 'function': self.function} return address
[docs]class NodedevXMLBase(base.LibvirtXMLBase): """ Accessor methods for NodedevXML class. """ __slots__ = ('name', 'parent', 'cap_type', 'cap', 'sysfs_main_path', 'host', 'fc_type', 'wwnn', 'wwpn', 'fabric_wwn') __schema_name__ = "nodedev" __sysfs_dir__ = "/sys/class" __type2class_dict__ = {'system': 'SystemXML', 'pci': 'PCIXML', 'usb_device': 'USBDeviceXML', 'usb': 'USBXML', 'net': 'NetXML', 'scsi_host': 'SCSIHostXML', 'scsi': 'SCSIXML', 'storage': 'StorageXML'} def __init__(self, virsh_instance=base.virsh): accessors.XMLElementText('name', self, parent_xpath='/', tag_name='name') accessors.XMLElementText('parent', self, parent_xpath='/', tag_name='parent') accessors.XMLAttribute('cap_type', self, parent_xpath='/', tag_name='capability', attribute='type') accessors.XMLElementText('host', self, parent_xpath='/capability', tag_name='host') accessors.XMLAttribute('fc_type', self, parent_xpath='/capability', tag_name='capability', attribute='type') accessors.XMLElementText('wwnn', self, parent_xpath='/capability/capability', tag_name='wwnn') accessors.XMLElementText('wwpn', self, parent_xpath='/capability/capability', tag_name='wwpn') accessors.XMLElementText('fabric_wwn', self, parent_xpath='/capability/capability', tag_name='fabric_wwn') super(NodedevXMLBase, self).__init__(virsh_instance=virsh_instance) self.xml = '<device></device>' @staticmethod
[docs] def get_cap_by_type(cap_type): """ Init a cap class for a specific type. :param cap_type: the type of capability. :return: instanse of the cap. """ cap_class_name = NodedevXMLBase.__type2class_dict__[cap_type] cap_class = globals()[cap_class_name] capxml = cap_class() return capxml
[docs] def get_cap(self): """ Return the capability of nodedev_xml. """ try: cap_root = self.xmltreefile.reroot('/capability') except KeyError, detail: raise xcepts.LibvirtXMLError(detail) capxml = NodedevXMLBase.get_cap_by_type(self.cap_type) capxml.xmltreefile = cap_root return capxml
[docs] def set_cap(self, value): """ Set the capability by value. """ if not issubclass(type(value), CAPXML): raise xcepts.LibvirtXMLError("value must be a CAPXML or subclass") # remove any existing capability block self.del_cap() root = self.xmltreefile.getroot() root.append(value.getroot()) self.xmltreefile.write()
[docs] def del_cap(self): """ Delete the capability from nodedev xml. """ element = self.xmltreefile.find('/capability') if element is not None: self.mltreefile.remove(element) self.xmltreefile.write()
[docs] def get_sysfs_sub_path(self): """ Get the sub sysfs path of the capability. """ capxml = self.cap sysfs_sub_path = capxml.get_sysfs_sub_path() return sysfs_sub_path
[docs] def get_sysfs_path(self): """ Get the abs path of the capability info. """ sysfs_main_path = self.__sysfs_dir__ sysfs_sub_path = self.get_sysfs_sub_path() sysfs_path = os.path.join(sysfs_main_path, sysfs_sub_path) return sysfs_path
[docs]class NodedevXML(NodedevXMLBase): """ class for Node device XML. """ __slots__ = [] def __init__(self, virsh_instance=base.virsh): """ Initialize new instance. """ super(NodedevXML, self).__init__(virsh_instance=virsh_instance) self.xml = ('<device></device>') @staticmethod
[docs] def new_from_dumpxml(dev_name, virsh_instance=base.virsh): """ Get a instance of NodedevXML by dumpxml dev_name. """ nodedevxml = NodedevXML(virsh_instance=virsh_instance) dumpxml_result = virsh_instance.nodedev_dumpxml(dev_name) if dumpxml_result.exit_status: raise xcepts.LibvirtXMLError("Nodedev_dumpxml %s failed.\n" "Error: %s." % (dev_name, dumpxml_result.stderr)) nodedevxml.xml = dumpxml_result.stdout return nodedevxml
[docs] def get_key2value_dict(self): """ Get the dict which contain key and value in xml. key: keys in nodedev xml need to check. value: value in xml for the key. """ capxml = self.cap key2value_dict = capxml.get_key2value_dict() return key2value_dict
[docs] def get_key2syspath_dict(self): """ Get the dict which contains key and path. key: keys in nodedev xml need to check. syspath: the abs path for the file stores info for the key. """ sysfs_path = self.get_sysfs_path() capxml = self.cap key2filename_dict = capxml.__class__.get_key2filename_dict() key2syspath_dict = {} for key in key2filename_dict: filename = key2filename_dict[key] abs_syspath = os.path.join(sysfs_path, filename) key2syspath_dict[key] = abs_syspath return key2syspath_dict