Convert NodeDevice to XMLBuilder

This commit is contained in:
Cole Robinson 2013-09-22 18:13:24 -04:00
parent 1c0475feff
commit b690557a53
7 changed files with 196 additions and 382 deletions

View File

@ -17,7 +17,7 @@
import os.path import os.path
import unittest import unittest
from virtinst import NodeDeviceParser as nodeparse from virtinst import NodeDevice
from virtinst import VirtualHostDevice from virtinst import VirtualHostDevice
from tests import utils from tests import utils
@ -42,15 +42,20 @@ class TestNodeDev(unittest.TestCase):
def _nodeDevFromName(self, devname): def _nodeDevFromName(self, devname):
node = conn.nodeDeviceLookupByName(devname) node = conn.nodeDeviceLookupByName(devname)
xml = node.XMLDesc(0) xml = node.XMLDesc(0)
return nodeparse.parse(xml) return NodeDevice.parse(conn, xml)
def _testCompare(self, devname, vals, devxml=None): def _testCompare(self, devname, vals, devxml=None):
if devxml: if devxml:
dev = nodeparse.parse(devxml) dev = NodeDevice.parse(conn, devxml)
else: else:
dev = self._nodeDevFromName(devname) dev = self._nodeDevFromName(devname)
for attr in vals.keys(): for attr in vals.keys():
expect = vals[attr]
actual = getattr(dev, attr)
if expect != actual:
raise AssertionError("devname=%s attribute=%s did not match:\n"
"expect=%s\nactual=%s" % (devname, attr, expect, actual))
self.assertEqual(vals[attr], getattr(dev, attr)) self.assertEqual(vals[attr], getattr(dev, attr))
def _testNode2DeviceCompare(self, nodename, devfile, def _testNode2DeviceCompare(self, nodename, devfile,
@ -70,14 +75,14 @@ class TestNodeDev(unittest.TestCase):
"hw_uuid": "97e80381-494f-11cb-8e0e-cbc168f7d753", "hw_uuid": "97e80381-494f-11cb-8e0e-cbc168f7d753",
"fw_vendor": "LENOVO", "fw_version": "7LET51WW (1.21 )", "fw_vendor": "LENOVO", "fw_version": "7LET51WW (1.21 )",
"fw_date": "08/22/2007", "fw_date": "08/22/2007",
"device_type": nodeparse.CAPABILITY_TYPE_SYSTEM, "device_type": NodeDevice.CAPABILITY_TYPE_SYSTEM,
"name": "computer", "parent": None} "name": "computer", "parent": None}
self._testCompare(devname, vals) self._testCompare(devname, vals)
def testNetDevice1(self): def testNetDevice1(self):
devname = "net_00_1c_25_10_b1_e4" devname = "net_00_1c_25_10_b1_e4"
vals = {"name": "net_00_1c_25_10_b1_e4", "parent": "pci_8086_1049", vals = {"name": "net_00_1c_25_10_b1_e4", "parent": "pci_8086_1049",
"device_type": nodeparse.CAPABILITY_TYPE_NET, "device_type": NodeDevice.CAPABILITY_TYPE_NET,
"interface": "eth0", "address": "00:1c:25:10:b1:e4", "interface": "eth0", "address": "00:1c:25:10:b1:e4",
"capability_type": "80203"} "capability_type": "80203"}
self._testCompare(devname, vals) self._testCompare(devname, vals)
@ -85,7 +90,7 @@ class TestNodeDev(unittest.TestCase):
def testNetDevice2(self): def testNetDevice2(self):
devname = "net_00_1c_bf_04_29_a4" devname = "net_00_1c_bf_04_29_a4"
vals = {"name": "net_00_1c_bf_04_29_a4", "parent": "pci_8086_4227", vals = {"name": "net_00_1c_bf_04_29_a4", "parent": "pci_8086_4227",
"device_type": nodeparse.CAPABILITY_TYPE_NET, "device_type": NodeDevice.CAPABILITY_TYPE_NET,
"interface": "wlan0", "address": "00:1c:bf:04:29:a4", "interface": "wlan0", "address": "00:1c:bf:04:29:a4",
"capability_type": "80211"} "capability_type": "80211"}
self._testCompare(devname, vals) self._testCompare(devname, vals)
@ -93,7 +98,7 @@ class TestNodeDev(unittest.TestCase):
def testPCIDevice1(self): def testPCIDevice1(self):
devname = "pci_1180_592" devname = "pci_1180_592"
vals = {"name": "pci_1180_592", "parent": "pci_8086_2448", vals = {"name": "pci_1180_592", "parent": "pci_8086_2448",
"device_type": nodeparse.CAPABILITY_TYPE_PCI, "device_type": NodeDevice.CAPABILITY_TYPE_PCI,
"domain": "0", "bus": "21", "slot": "0", "function": "4", "domain": "0", "bus": "21", "slot": "0", "function": "4",
"product_id": "0x0592", "vendor_id": "0x1180", "product_id": "0x0592", "vendor_id": "0x1180",
"product_name": "R5C592 Memory Stick Bus Host Adapter", "product_name": "R5C592 Memory Stick Bus Host Adapter",
@ -103,7 +108,7 @@ class TestNodeDev(unittest.TestCase):
def testPCIDevice2(self): def testPCIDevice2(self):
devname = "pci_8086_1049" devname = "pci_8086_1049"
vals = {"name": "pci_8086_1049", "parent": "computer", vals = {"name": "pci_8086_1049", "parent": "computer",
"device_type": nodeparse.CAPABILITY_TYPE_PCI, "device_type": NodeDevice.CAPABILITY_TYPE_PCI,
"domain": "0", "bus": "0", "slot": "25", "function": "0", "domain": "0", "bus": "0", "slot": "25", "function": "0",
"product_id": "0x1049", "vendor_id": "0x8086", "product_id": "0x1049", "vendor_id": "0x8086",
"product_name": "82566MM Gigabit Network Connection", "product_name": "82566MM Gigabit Network Connection",
@ -114,7 +119,7 @@ class TestNodeDev(unittest.TestCase):
devname = "usb_device_781_5151_2004453082054CA1BEEE" devname = "usb_device_781_5151_2004453082054CA1BEEE"
vals = {"name": "usb_device_781_5151_2004453082054CA1BEEE", vals = {"name": "usb_device_781_5151_2004453082054CA1BEEE",
"parent": "usb_device_1d6b_2_0000_00_1a_7", "parent": "usb_device_1d6b_2_0000_00_1a_7",
"device_type": nodeparse.CAPABILITY_TYPE_USBDEV, "device_type": NodeDevice.CAPABILITY_TYPE_USBDEV,
"bus": "1", "device": "4", "product_id": '0x5151', "bus": "1", "device": "4", "product_id": '0x5151',
"vendor_id": '0x0781', "vendor_id": '0x0781',
"vendor_name": "SanDisk Corp.", "vendor_name": "SanDisk Corp.",
@ -125,7 +130,7 @@ class TestNodeDev(unittest.TestCase):
devname = "usb_device_483_2016_noserial" devname = "usb_device_483_2016_noserial"
vals = {"name": "usb_device_483_2016_noserial", vals = {"name": "usb_device_483_2016_noserial",
"parent": "usb_device_1d6b_1_0000_00_1a_0", "parent": "usb_device_1d6b_1_0000_00_1a_0",
"device_type": nodeparse.CAPABILITY_TYPE_USBDEV, "device_type": NodeDevice.CAPABILITY_TYPE_USBDEV,
"bus": "3", "device": "2", "product_id": '0x2016', "bus": "3", "device": "2", "product_id": '0x2016',
"vendor_id": '0x0483', "vendor_id": '0x0483',
"vendor_name": "SGS Thomson Microelectronics", "vendor_name": "SGS Thomson Microelectronics",
@ -136,21 +141,21 @@ class TestNodeDev(unittest.TestCase):
devname = "storage_serial_SATA_WDC_WD1600AAJS__WD_WCAP95119685" devname = "storage_serial_SATA_WDC_WD1600AAJS__WD_WCAP95119685"
vals = {"name": "storage_serial_SATA_WDC_WD1600AAJS__WD_WCAP95119685", vals = {"name": "storage_serial_SATA_WDC_WD1600AAJS__WD_WCAP95119685",
"parent": "pci_8086_27c0_scsi_host_scsi_device_lun0", "parent": "pci_8086_27c0_scsi_host_scsi_device_lun0",
"device_type": nodeparse.CAPABILITY_TYPE_STORAGE, "device_type": NodeDevice.CAPABILITY_TYPE_STORAGE,
"block": "/dev/sda", "bus": "scsi", "drive_type": "disk", "block": "/dev/sda", "bus": "scsi", "drive_type": "disk",
"model": "WDC WD1600AAJS-2", "vendor": "ATA", "model": "WDC WD1600AAJS-2", "vendor": "ATA",
"size": 160041885696, "removable": False, "size": 160041885696, "removable": False,
"hotpluggable": False, "media_available": False, "hotpluggable": False, "media_available": None,
"media_size": 0, "media_label": None} "media_size": None, "media_label": None}
self._testCompare(devname, vals) self._testCompare(devname, vals)
def testStorageDevice2(self): def testStorageDevice2(self):
devname = "storage_serial_SanDisk_Cruzer_Micro_2004453082054CA1BEEE_0_0" devname = "storage_serial_SanDisk_Cruzer_Micro_2004453082054CA1BEEE_0_0"
vals = {"name": "storage_serial_SanDisk_Cruzer_Micro_2004453082054CA1BEEE_0_0", vals = {"name": "storage_serial_SanDisk_Cruzer_Micro_2004453082054CA1BEEE_0_0",
"parent": "usb_device_781_5151_2004453082054CA1BEEE_if0_scsi_host_0_scsi_device_lun0", "parent": "usb_device_781_5151_2004453082054CA1BEEE_if0_scsi_host_0_scsi_device_lun0",
"device_type": nodeparse.CAPABILITY_TYPE_STORAGE, "device_type": NodeDevice.CAPABILITY_TYPE_STORAGE,
"block": "/dev/sdb", "bus": "usb", "drive_type": "disk", "block": "/dev/sdb", "bus": "usb", "drive_type": "disk",
"model": "Cruzer Micro", "vendor": "SanDisk", "size": 0, "model": "Cruzer Micro", "vendor": "SanDisk", "size": None,
"removable": True, "hotpluggable": True, "removable": True, "hotpluggable": True,
"media_available": True, "media_size": 12345678} "media_available": True, "media_size": 12345678}
self._testCompare(devname, vals) self._testCompare(devname, vals)
@ -159,7 +164,7 @@ class TestNodeDev(unittest.TestCase):
devname = "usb_device_1d6b_1_0000_00_1d_1_if0" devname = "usb_device_1d6b_1_0000_00_1d_1_if0"
vals = {"name": "usb_device_1d6b_1_0000_00_1d_1_if0", vals = {"name": "usb_device_1d6b_1_0000_00_1d_1_if0",
"parent": "usb_device_1d6b_1_0000_00_1d_1", "parent": "usb_device_1d6b_1_0000_00_1d_1",
"device_type": nodeparse.CAPABILITY_TYPE_USBBUS, "device_type": NodeDevice.CAPABILITY_TYPE_USBBUS,
"number": "0", "classval": "9", "subclass": "0", "number": "0", "classval": "9", "subclass": "0",
"protocol": "0"} "protocol": "0"}
self._testCompare(devname, vals) self._testCompare(devname, vals)
@ -168,14 +173,14 @@ class TestNodeDev(unittest.TestCase):
devname = "pci_8086_2829_scsi_host_1" devname = "pci_8086_2829_scsi_host_1"
vals = {"name": "pci_8086_2829_scsi_host_1", vals = {"name": "pci_8086_2829_scsi_host_1",
"parent": "pci_8086_2829", "parent": "pci_8086_2829",
"device_type": nodeparse.CAPABILITY_TYPE_SCSIBUS, "device_type": NodeDevice.CAPABILITY_TYPE_SCSIBUS,
"host": "2"} "host": "2"}
self._testCompare(devname, vals) self._testCompare(devname, vals)
def testNPIV(self): def testNPIV(self):
devname = "pci_10df_fe00_0_scsi_host" devname = "pci_10df_fe00_0_scsi_host"
vals = {"name": "pci_10df_fe00_0_scsi_host", vals = {"name": "pci_10df_fe00_0_scsi_host",
"device_type": nodeparse.CAPABILITY_TYPE_SCSIBUS, "device_type": NodeDevice.CAPABILITY_TYPE_SCSIBUS,
"host": "4", "fc_host": True, "vport_ops" : True, "host": "4", "fc_host": True, "vport_ops" : True,
"wwnn": "20000000c9848141", "wwpn": "10000000c9848141"} "wwnn": "20000000c9848141", "wwpn": "10000000c9848141"}
self._testCompare(devname, vals) self._testCompare(devname, vals)

View File

@ -24,7 +24,7 @@ from gi.repository import GObject
import logging import logging
import virtinst from virtinst import NodeDevice
from virtManager.baseclass import vmmGObject from virtManager.baseclass import vmmGObject
@ -131,8 +131,8 @@ class vmmMediaDevice(vmmGObject):
return return
try: try:
vobj = virtinst.NodeDeviceParser.parse(xml) vobj = NodeDevice.parse(self.nodedev_obj.conn.get_backend(), xml)
has_media = vobj.media_available has_media = vobj.media_available or False
except: except:
logging.exception("Node device CDROM polling failed") logging.exception("Node device CDROM polling failed")
return return

View File

@ -18,7 +18,7 @@
# MA 02110-1301 USA. # MA 02110-1301 USA.
# #
import virtinst from virtinst import NodeDevice
from virtManager.libvirtobject import vmmLibvirtObject from virtManager.libvirtobject import vmmLibvirtObject
@ -41,7 +41,7 @@ class vmmNodeDevice(vmmLibvirtObject):
def get_virtinst_obj(self): def get_virtinst_obj(self):
if not self._virtinst_obj: if not self._virtinst_obj:
self._virtinst_obj = virtinst.NodeDeviceParser.parse( self._virtinst_obj = NodeDevice.parse(self.conn.get_backend(),
self._backend.XMLDesc(0)) self._backend.XMLDesc(0))
return self._virtinst_obj return self._virtinst_obj

View File

@ -29,10 +29,10 @@ from virtinst.clock import Clock
from virtinst.cpu import CPU, CPUFeature from virtinst.cpu import CPU, CPUFeature
from virtinst.seclabel import Seclabel from virtinst.seclabel import Seclabel
import virtinst.nodedev as NodeDeviceParser
import virtinst.capabilities as CapabilitiesParser import virtinst.capabilities as CapabilitiesParser
from virtinst.interface import Interface, InterfaceProtocol from virtinst.interface import Interface, InterfaceProtocol
from virtinst.network import Network from virtinst.network import Network
from virtinst.nodedev import NodeDevice
from virtinst.storage import StoragePool, StorageVolume from virtinst.storage import StoragePool, StorageVolume
from virtinst.device import VirtualDevice from virtinst.device import VirtualDevice

View File

@ -18,7 +18,7 @@
# MA 02110-1301 USA. # MA 02110-1301 USA.
from virtinst import VirtualDevice from virtinst import VirtualDevice
from virtinst import NodeDeviceParser from virtinst import NodeDevice
from virtinst.xmlbuilder import XMLProperty from virtinst.xmlbuilder import XMLProperty
@ -31,7 +31,7 @@ class VirtualHostDevice(VirtualDevice):
""" """
Convert the passed device name to a VirtualHostDevice Convert the passed device name to a VirtualHostDevice
instance, with proper error reporting. Name can be any of the instance, with proper error reporting. Name can be any of the
values accepted by NodeDeviceParser.lookupNodeName. If a node values accepted by NodeDevice.lookupNodeName. If a node
device name is not specified, a virtinst.NodeDevice instance can device name is not specified, a virtinst.NodeDevice instance can
be passed in to create a dev from. be passed in to create a dev from.
@ -47,11 +47,11 @@ class VirtualHostDevice(VirtualDevice):
if nodedev: if nodedev:
nodeinst = nodedev nodeinst = nodedev
else: else:
nodeinst, addr_type = NodeDeviceParser.lookupNodeName(conn, name) nodeinst, addr_type = NodeDevice.lookupNodeName(conn, name)
if addr_type == NodeDeviceParser.HOSTDEV_ADDR_TYPE_USB_BUSADDR: if addr_type == NodeDevice.HOSTDEV_ADDR_TYPE_USB_BUSADDR:
is_dup = True is_dup = True
if isinstance(nodeinst, NodeDeviceParser.NetDevice): if nodeinst.device_type == nodeinst.CAPABILITY_TYPE_NET:
parentname = nodeinst.parent parentname = nodeinst.parent
return VirtualHostDevice.device_from_node(conn, return VirtualHostDevice.device_from_node(conn,
name=parentname) name=parentname)
@ -61,14 +61,14 @@ class VirtualHostDevice(VirtualDevice):
return dev return dev
def set_from_nodedev(self, nodedev, is_dup=False): def set_from_nodedev(self, nodedev, is_dup=False):
if isinstance(nodedev, NodeDeviceParser.PCIDevice): if nodedev.device_type == NodeDevice.CAPABILITY_TYPE_PCI:
self.type = "pci" self.type = "pci"
self.domain = nodedev.domain self.domain = nodedev.domain
self.bus = nodedev.bus self.bus = nodedev.bus
self.slot = nodedev.slot self.slot = nodedev.slot
self.function = nodedev.function self.function = nodedev.function
elif isinstance(nodedev, NodeDeviceParser.USBDevice): elif nodedev.device_type == NodeDevice.CAPABILITY_TYPE_USBDEV:
self.type = "usb" self.type = "usb"
self.vendor = nodedev.vendor_id self.vendor = nodedev.vendor_id
self.product = nodedev.product_id self.product = nodedev.product_id

View File

@ -21,32 +21,86 @@ import logging
import libvirt import libvirt
from virtinst import util from virtinst.xmlbuilder import XMLBuilder
from virtinst.xmlbuilder import XMLProperty as OrigXMLProperty
# class USBDevice # We had a pre-existing set of parse tests when this was converted to
CAPABILITY_TYPE_SYSTEM = "system" # XMLBuilder. We do this to appease the check in xmlparse.py without
CAPABILITY_TYPE_NET = "net" # moving all the nodedev.py tests to one file. Should find a way to
CAPABILITY_TYPE_PCI = "pci" # drop it.
CAPABILITY_TYPE_USBDEV = "usb_device" class XMLProperty(OrigXMLProperty):
CAPABILITY_TYPE_USBBUS = "usb" def __init__(self, *args, **kwargs):
CAPABILITY_TYPE_STORAGE = "storage" kwargs["track"] = False
CAPABILITY_TYPE_SCSIBUS = "scsi_host" OrigXMLProperty.__init__(self, *args, **kwargs)
CAPABILITY_TYPE_SCSIDEV = "scsi"
HOSTDEV_ADDR_TYPE_LIBVIRT = 0
HOSTDEV_ADDR_TYPE_PCI = 1
HOSTDEV_ADDR_TYPE_USB_BUSADDR = 2
HOSTDEV_ADDR_TYPE_USB_VENPRO = 3
class NodeDevice(object): def _lookupNodeName(conn, name):
def __init__(self, node): nodedev = conn.nodeDeviceLookupByName(name)
self.name = None xml = nodedev.XMLDesc(0)
self.parent = None return NodeDevice.parse(conn, xml)
self.device_type = None
self._parseNodeXML(node)
class NodeDevice(XMLBuilder):
CAPABILITY_TYPE_SYSTEM = "system"
CAPABILITY_TYPE_NET = "net"
CAPABILITY_TYPE_PCI = "pci"
CAPABILITY_TYPE_USBDEV = "usb_device"
CAPABILITY_TYPE_USBBUS = "usb"
CAPABILITY_TYPE_STORAGE = "storage"
CAPABILITY_TYPE_SCSIBUS = "scsi_host"
CAPABILITY_TYPE_SCSIDEV = "scsi"
(HOSTDEV_ADDR_TYPE_LIBVIRT,
HOSTDEV_ADDR_TYPE_PCI,
HOSTDEV_ADDR_TYPE_USB_BUSADDR,
HOSTDEV_ADDR_TYPE_USB_VENPRO) = range(1, 5)
@staticmethod
def lookupNodeName(conn, name):
"""
Convert the passed libvirt node device name to a NodeDevice
instance, with proper error reporting. If the name is name is not
found, we will attempt to parse the name as would be passed to
devAddressToNodeDev
@param conn: libvirt.virConnect instance to perform the lookup on
@param name: libvirt node device name to lookup, or address for
devAddressToNodedev
@rtype: L{NodeDevice} instance
"""
if not conn.check_conn_support(conn.SUPPORT_CONN_NODEDEV):
raise ValueError(_("Connection does not support host device "
"enumeration."))
try:
return (_lookupNodeName(conn, name),
NodeDevice.HOSTDEV_ADDR_TYPE_LIBVIRT)
except libvirt.libvirtError, e:
ret = _isAddressStr(name)
if not ret:
raise e
return devAddressToNodedev(conn, name)
@staticmethod
def parse(conn, xml):
tmpdev = NodeDevice(conn, parsexml=xml, allow_node_instantiate=True)
cls = _typeToDeviceClass(tmpdev.device_type)
return cls(conn, parsexml=xml, allow_node_instantiate=True)
def __init__(self, *args, **kwargs):
instantiate = kwargs.pop("allow_node_instantiate", False)
if self.__class__ is NodeDevice and not instantiate:
raise RuntimeError("Can not instantiate NodeDevice directly")
XMLBuilder.__init__(self, *args, **kwargs)
_XML_ROOT_NAME = "device"
name = XMLProperty("./name")
parent = XMLProperty("./parent")
device_type = XMLProperty("./capability/@type")
def pretty_name(self, child_dev=None): def pretty_name(self, child_dev=None):
""" """
@ -62,66 +116,16 @@ class NodeDevice(object):
ignore = child_dev ignore = child_dev
return self.name return self.name
def _parseNodeXML(self, node):
child = node.children
while child:
if child.name == "name":
self.name = child.content
elif child.name == "parent":
self.parent = child.content
elif child.name == "capability":
self.device_type = child.prop("type")
child = child.next
def _getCapabilityNode(self, node):
child = node.children
while child:
if child.name == "capability":
return child
child = child.next
return None
def _parseValueHelper(self, node, value_map):
if node.name in value_map:
setattr(self, value_map[node.name], node.content)
def _parseHelper(self, main_node, value_map):
node = main_node.children
while node:
self._parseValueHelper(node, value_map)
node = node.next
class SystemDevice(NodeDevice): class SystemDevice(NodeDevice):
def __init__(self, node): hw_vendor = XMLProperty("./capability/hardware/vendor")
NodeDevice.__init__(self, node) hw_version = XMLProperty("./capability/hardware/version")
hw_serial = XMLProperty("./capability/hardware/serial")
hw_uuid = XMLProperty("./capability/hardware/uuid")
self.hw_vendor = None fw_vendor = XMLProperty("./capability/firmware/vendor")
self.hw_version = None fw_version = XMLProperty("./capability/firmware/version")
self.hw_serial = None fw_date = XMLProperty("./capability/firmware/release_date")
self.hw_uuid = None
self.fw_vendor = None
self.fw_version = None
self.fw_date = None
self.parseXML(self._getCapabilityNode(node))
def parseXML(self, node):
child = node.children
hardware_map = {"vendor": "hw_vendor",
"version": "hw_version",
"serial": "hw_serial",
"uuid": "hw_uuid"}
firmware_map = {"vendor": "fw_vendor",
"version": "fw_version",
"release_date": "fw_date"}
while child:
if child.name == "hardware":
self._parseHelper(child, hardware_map)
elif child.name == "firmware":
self._parseHelper(child, firmware_map)
child = child.next
def pretty_name(self, child_dev=None): def pretty_name(self, child_dev=None):
ignore = child_dev ignore = child_dev
@ -135,25 +139,9 @@ class SystemDevice(NodeDevice):
class NetDevice(NodeDevice): class NetDevice(NodeDevice):
def __init__(self, node): interface = XMLProperty("./capability/interface")
NodeDevice.__init__(self, node) address = XMLProperty("./capability/address")
capability_type = XMLProperty("./capability/capability/@type")
self.interface = None
self.address = None
self.capability_type = None
self.parseXML(self._getCapabilityNode(node))
def parseXML(self, node):
value_map = {"interface" : "interface",
"address" : "address"}
child = node.children
while child:
if child.name == "capability":
self.capability_type = child.prop("type")
else:
self._parseValueHelper(child, value_map)
child = child.next
def pretty_name(self, child_dev=None): def pretty_name(self, child_dev=None):
ignore = child_dev ignore = child_dev
@ -165,40 +153,15 @@ class NetDevice(NodeDevice):
class PCIDevice(NodeDevice): class PCIDevice(NodeDevice):
def __init__(self, node): domain = XMLProperty("./capability/domain")
NodeDevice.__init__(self, node) bus = XMLProperty("./capability/bus")
slot = XMLProperty("./capability/slot")
function = XMLProperty("./capability/function")
self.domain = None product_name = XMLProperty("./capability/product")
self.bus = None product_id = XMLProperty("./capability/product/@id")
self.slot = None vendor_name = XMLProperty("./capability/vendor")
self.function = None vendor_id = XMLProperty("./capability/vendor/@id")
self.product_id = None
self.product_name = None
self.vendor_id = None
self.vendor_name = None
self.parseXML(self._getCapabilityNode(node))
def parseXML(self, node):
val_map = {"domain" : "domain",
"bus" : "bus",
"slot" : "slot",
"function" : "function"}
child = node.children
while child:
if child.name == "vendor":
self.vendor_name = child.content
self.vendor_id = child.prop("id")
elif child.name == "product":
self.product_name = child.content
self.product_id = child.prop("id")
else:
self._parseValueHelper(child, val_map)
child = child.next
def pretty_name(self, child_dev=None): def pretty_name(self, child_dev=None):
devstr = "%.2X:%.2X:%X" % (int(self.bus), devstr = "%.2X:%.2X:%X" % (int(self.bus),
@ -213,35 +176,13 @@ class PCIDevice(NodeDevice):
class USBDevice(NodeDevice): class USBDevice(NodeDevice):
def __init__(self, node): bus = XMLProperty("./capability/bus")
NodeDevice.__init__(self, node) device = XMLProperty("./capability/device")
self.bus = None product_name = XMLProperty("./capability/product")
self.device = None product_id = XMLProperty("./capability/product/@id")
vendor_name = XMLProperty("./capability/vendor")
self.product_id = None vendor_id = XMLProperty("./capability/vendor/@id")
self.product_name = None
self.vendor_id = None
self.vendor_name = None
self.parseXML(self._getCapabilityNode(node))
def parseXML(self, node):
val_map = {"bus": "bus", "device": "device"}
child = node.children
while child:
if child.name == "vendor":
self.vendor_name = child.content
self.vendor_id = child.prop("id")
elif child.name == "product":
self.product_name = child.content
self.product_id = child.prop("id")
else:
self._parseValueHelper(child, val_map)
child = child.next
def pretty_name(self, child_dev=None): def pretty_name(self, child_dev=None):
ignore = child_dev ignore = child_dev
@ -252,56 +193,34 @@ class USBDevice(NodeDevice):
class StorageDevice(NodeDevice): class StorageDevice(NodeDevice):
def __init__(self, node): block = XMLProperty("./capability/block")
NodeDevice.__init__(self, node) bus = XMLProperty("./capability/bus")
drive_type = XMLProperty("./capability/drive_type")
size = XMLProperty("./capability/size", is_int=True)
self.block = None model = XMLProperty("./capability/model")
self.bus = None vendor = XMLProperty("./capability/vendor")
self.drive_type = None
self.size = 0
self.model = None hotpluggable = XMLProperty(
self.vendor = None "./capability/capability[@type='hotpluggable']", is_bool=True)
removable = XMLProperty(
"./capability/capability[@type='removable']", is_bool=True)
self.removable = False media_size = XMLProperty(
self.media_available = False "./capability/capability[@type='removable']/media_size", is_int=True)
self.media_size = 0 media_label = XMLProperty(
self.media_label = None "./capability/capability[@type='removable']/media_label")
_media_available = XMLProperty(
self.hotpluggable = False "./capability/capability[@type='removable']/media_available",
is_int=True)
self.parseXML(self._getCapabilityNode(node)) def _get_media_available(self):
m = self._media_available
def parseXML(self, node): if m is None:
val_map = {"block" : "block", return None
"bus" : "bus", return bool(m)
"drive_type" : "drive_type", def _set_media_available(self, val):
"model" : "model", self._media_available = val
"vendor" : "vendor"} media_available = property(_get_media_available, _set_media_available)
child = node.children
while child:
if child.name == "size":
self.size = int(child.content)
elif child.name == "capability":
captype = child.prop("type")
if captype == "hotpluggable":
self.hotpluggable = True
elif captype == "removable":
self.removable = True
rmchild = child.children
while rmchild:
if rmchild.name == "media_available":
self.media_available = bool(int(rmchild.content))
elif rmchild.name == "media_size":
self.media_size = int(rmchild.content)
elif rmchild.name == "media_label":
self.media_label = rmchild.content
rmchild = rmchild.next
else:
self._parseValueHelper(child, val_map)
child = child.next
def pretty_name(self, child_dev=None): def pretty_name(self, child_dev=None):
ignore = child_dev ignore = child_dev
@ -319,116 +238,30 @@ class StorageDevice(NodeDevice):
class USBBus(NodeDevice): class USBBus(NodeDevice):
def __init__(self, node): number = XMLProperty("./capability/number")
NodeDevice.__init__(self, node) classval = XMLProperty("./capability/class")
subclass = XMLProperty("./capability/subclass")
self.number = None protocol = XMLProperty("./capability/protocol")
self.classval = None
self.subclass = None
self.protocol = None
self.parseXML(self._getCapabilityNode(node))
def parseXML(self, node):
val_map = {"number" : "number",
"class" : "classval",
"subclass" : "subclass",
"protocol" : "protocol"}
self._parseHelper(node, val_map)
class SCSIDevice(NodeDevice): class SCSIDevice(NodeDevice):
def __init__(self, node): host = XMLProperty("./capability/host")
NodeDevice.__init__(self, node) bus = XMLProperty("./capability/bus")
target = XMLProperty("./capability/target")
self.host = None lun = XMLProperty("./capability/lun")
self.bus = None type = XMLProperty("./capability/type")
self.target = None
self.lun = None
self.disk = None
self.parseXML(self._getCapabilityNode(node))
def parseXML(self, node):
val_map = {"host" : "host",
"bus" : "bus",
"target": "target",
"lun" : "lun",
"type" : "type"}
self._parseHelper(node, val_map)
class SCSIBus(NodeDevice): class SCSIBus(NodeDevice):
def __init__(self, node): host = XMLProperty("./capability/host")
NodeDevice.__init__(self, node)
self.host = None vport_ops = XMLProperty(
"./capability/capability[@type='vport_ops']", is_bool=True)
self.vport_ops = False fc_host = XMLProperty(
"./capability/capability[@type='fc_host']", is_bool=True)
self.fc_host = False wwnn = XMLProperty("./capability/capability[@type='fc_host']/wwnn")
self.wwnn = None wwpn = XMLProperty("./capability/capability[@type='fc_host']/wwpn")
self.wwpn = None
self.parseXML(self._getCapabilityNode(node))
def parseXML(self, node):
val_map = {"host" : "host"}
child = node.children
while child:
if child.name == "capability":
captype = child.prop("type")
if captype == "vport_ops":
self.vport_ops = True
elif captype == "fc_host":
self.fc_host = True
fcchild = child.children
while fcchild:
if fcchild.name == "wwnn":
self.wwnn = fcchild.content
elif fcchild.name == "wwpn":
self.wwpn = fcchild.content
fcchild = fcchild.next
else:
self._parseValueHelper(child, val_map)
child = child.next
def _lookupNodeName(conn, name):
nodedev = conn.nodeDeviceLookupByName(name)
xml = nodedev.XMLDesc(0)
return parse(xml)
def lookupNodeName(conn, name):
"""
Convert the passed libvirt node device name to a NodeDevice
instance, with proper error reporting. If the name is name is not
found, we will attempt to parse the name as would be passed to
devAddressToNodeDev
@param conn: libvirt.virConnect instance to perform the lookup on
@param name: libvirt node device name to lookup, or address for
devAddressToNodedev
@rtype: L{NodeDevice} instance
"""
if not conn.check_conn_support(conn.SUPPORT_CONN_NODEDEV):
raise ValueError(_("Connection does not support host device "
"enumeration."))
try:
return (_lookupNodeName(conn, name),
HOSTDEV_ADDR_TYPE_LIBVIRT)
except libvirt.libvirtError, e:
ret = _isAddressStr(name)
if not ret:
raise e
return devAddressToNodedev(conn, name)
def _isAddressStr(addrstr): def _isAddressStr(addrstr):
@ -438,7 +271,7 @@ def _isAddressStr(addrstr):
try: try:
# Determine addrstr type # Determine addrstr type
if addrstr.count(":") in [1, 2] and addrstr.count("."): if addrstr.count(":") in [1, 2] and addrstr.count("."):
devtype = CAPABILITY_TYPE_PCI devtype = NodeDevice.CAPABILITY_TYPE_PCI
addrstr, func = addrstr.split(".", 1) addrstr, func = addrstr.split(".", 1)
addrstr, slot = addrstr.rsplit(":", 1) addrstr, slot = addrstr.rsplit(":", 1)
domain = "0" domain = "0"
@ -458,10 +291,10 @@ def _isAddressStr(addrstr):
(int(nodedev.bus) == bus) and (int(nodedev.bus) == bus) and
(int(nodedev.slot) == slot)) (int(nodedev.slot) == slot))
cmp_func = pci_cmp cmp_func = pci_cmp
addr_type = HOSTDEV_ADDR_TYPE_PCI addr_type = NodeDevice.HOSTDEV_ADDR_TYPE_PCI
elif addrstr.count(":"): elif addrstr.count(":"):
devtype = CAPABILITY_TYPE_USBDEV devtype = NodeDevice.CAPABILITY_TYPE_USBDEV
vendor, product = addrstr.split(":") vendor, product = addrstr.split(":")
vendor = int(vendor, 16) vendor = int(vendor, 16)
product = int(product, 16) product = int(product, 16)
@ -470,10 +303,10 @@ def _isAddressStr(addrstr):
return ((int(nodedev.vendor_id, 16) == vendor) and return ((int(nodedev.vendor_id, 16) == vendor) and
(int(nodedev.product_id, 16) == product)) (int(nodedev.product_id, 16) == product))
cmp_func = usbprod_cmp cmp_func = usbprod_cmp
addr_type = HOSTDEV_ADDR_TYPE_USB_VENPRO addr_type = NodeDevice.HOSTDEV_ADDR_TYPE_USB_VENPRO
elif addrstr.count("."): elif addrstr.count("."):
devtype = CAPABILITY_TYPE_USBDEV devtype = NodeDevice.CAPABILITY_TYPE_USBDEV
bus, addr = addrstr.split(".", 1) bus, addr = addrstr.split(".", 1)
bus = int(bus) bus = int(bus)
addr = int(addr) addr = int(addr)
@ -482,7 +315,7 @@ def _isAddressStr(addrstr):
return ((int(nodedev.bus) == bus) and return ((int(nodedev.bus) == bus) and
(int(nodedev.device) == addr)) (int(nodedev.device) == addr))
cmp_func = usbaddr_cmp cmp_func = usbaddr_cmp
addr_type = HOSTDEV_ADDR_TYPE_USB_BUSADDR addr_type = NodeDevice.HOSTDEV_ADDR_TYPE_USB_BUSADDR
except: except:
logging.exception("Error parsing node device string.") logging.exception("Error parsing node device string.")
return None return None
@ -533,49 +366,22 @@ def devAddressToNodedev(conn, addrstr):
addrstr) addrstr)
def parse(xml):
"""
Convert the passed libvirt node device xml into a NodeDevice object
@param xml: libvirt node device xml
@type xml: C{str}
@returns: L{NodeDevice} instance
"""
def _parse_func(root):
t = _findNodeType(root)
devclass = _typeToDeviceClass(t)
device = devclass(root)
return device
return util.parse_node_helper(xml, "device", _parse_func)
def _findNodeType(node):
child = node.children
while child:
if child.name == "capability":
return child.prop("type")
child = child.next
return None
def _typeToDeviceClass(t): def _typeToDeviceClass(t):
if t == CAPABILITY_TYPE_SYSTEM: if t == NodeDevice.CAPABILITY_TYPE_SYSTEM:
return SystemDevice return SystemDevice
elif t == CAPABILITY_TYPE_NET: elif t == NodeDevice.CAPABILITY_TYPE_NET:
return NetDevice return NetDevice
elif t == CAPABILITY_TYPE_PCI: elif t == NodeDevice.CAPABILITY_TYPE_PCI:
return PCIDevice return PCIDevice
elif t == CAPABILITY_TYPE_USBDEV: elif t == NodeDevice.CAPABILITY_TYPE_USBDEV:
return USBDevice return USBDevice
elif t == CAPABILITY_TYPE_USBBUS: elif t == NodeDevice.CAPABILITY_TYPE_USBBUS:
return USBBus return USBBus
elif t == CAPABILITY_TYPE_STORAGE: elif t == NodeDevice.CAPABILITY_TYPE_STORAGE:
return StorageDevice return StorageDevice
elif t == CAPABILITY_TYPE_SCSIBUS: elif t == NodeDevice.CAPABILITY_TYPE_SCSIBUS:
return SCSIBus return SCSIBus
elif t == CAPABILITY_TYPE_SCSIDEV: elif t == NodeDevice.CAPABILITY_TYPE_SCSIDEV:
return SCSIDevice return SCSIDevice
else: else:
return NodeDevice return NodeDevice

View File

@ -333,7 +333,8 @@ class XMLProperty(property):
set_converter=None, validate_cb=None, set_converter=None, validate_cb=None,
make_getter_xpath_cb=None, make_setter_xpath_cb=None, make_getter_xpath_cb=None, make_setter_xpath_cb=None,
is_bool=False, is_int=False, is_yesno=False, is_onoff=False, is_bool=False, is_int=False, is_yesno=False, is_onoff=False,
clear_first=None, default_cb=None, default_name=None): clear_first=None, default_cb=None, default_name=None,
track=True):
""" """
Set a XMLBuilder class property that represents a value in the Set a XMLBuilder class property that represents a value in the
<domain> XML. For example <domain> XML. For example
@ -374,6 +375,8 @@ class XMLProperty(property):
first explicit 'set'. first explicit 'set'.
@param default_name: If the user does a set and passes in this @param default_name: If the user does a set and passes in this
value, instead use the value of default_cb() value, instead use the value of default_cb()
@param track: If False, opt out of property tracking for the
test suite.
""" """
self._xpath = xpath self._xpath = xpath
@ -404,7 +407,7 @@ class XMLProperty(property):
if self._default_name and not self._default_cb: if self._default_name and not self._default_cb:
raise RuntimeError("default_name requires default_cb.") raise RuntimeError("default_name requires default_cb.")
if _trackprops: if _trackprops and track:
_allprops.append(self) _allprops.append(self)
property.__init__(self, fget=self.getter, fset=self.setter) property.__init__(self, fget=self.getter, fset=self.setter)
@ -907,7 +910,7 @@ class XMLBuilder(object):
ret = {} ret = {}
for c in reversed(type.mro(self.__class__)[:-1]): for c in reversed(type.mro(self.__class__)[:-1]):
for key, val in c.__dict__.items(): for key, val in c.__dict__.items():
if val.__class__ is checkclass: if isinstance(val, checkclass):
ret[key] = val ret[key] = val
setattr(self.__class__, cachename, ret) setattr(self.__class__, cachename, ret)
return getattr(self.__class__, cachename) return getattr(self.__class__, cachename)