summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCole Robinson <crobinso@redhat.com>2013-09-22 18:13:24 -0400
committerCole Robinson <crobinso@redhat.com>2013-09-23 08:25:20 -0400
commitb690557a53bc46bbcc9ad0750e93e4eeef3acaa9 (patch)
tree7966a50d7435f97034947892902ad41e3e99b28c
parent1c0475feff1d6dc657778ecaba5a7e305ee3cac5 (diff)
downloadvirt-manager-b690557a53bc46bbcc9ad0750e93e4eeef3acaa9.tar.gz
Convert NodeDevice to XMLBuilder
-rw-r--r--tests/nodedev.py41
-rw-r--r--virtManager/mediadev.py6
-rw-r--r--virtManager/nodedev.py4
-rw-r--r--virtinst/__init__.py2
-rw-r--r--virtinst/devicehostdev.py14
-rw-r--r--virtinst/nodedev.py508
-rw-r--r--virtinst/xmlbuilder.py9
7 files changed, 199 insertions, 385 deletions
diff --git a/tests/nodedev.py b/tests/nodedev.py
index ce0c7538..1aeea7d9 100644
--- a/tests/nodedev.py
+++ b/tests/nodedev.py
@@ -17,7 +17,7 @@
import os.path
import unittest
-from virtinst import NodeDeviceParser as nodeparse
+from virtinst import NodeDevice
from virtinst import VirtualHostDevice
from tests import utils
@@ -42,15 +42,20 @@ class TestNodeDev(unittest.TestCase):
def _nodeDevFromName(self, devname):
node = conn.nodeDeviceLookupByName(devname)
xml = node.XMLDesc(0)
- return nodeparse.parse(xml)
+ return NodeDevice.parse(conn, xml)
def _testCompare(self, devname, vals, devxml=None):
if devxml:
- dev = nodeparse.parse(devxml)
+ dev = NodeDevice.parse(conn, devxml)
else:
dev = self._nodeDevFromName(devname)
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))
def _testNode2DeviceCompare(self, nodename, devfile,
@@ -70,14 +75,14 @@ class TestNodeDev(unittest.TestCase):
"hw_uuid": "97e80381-494f-11cb-8e0e-cbc168f7d753",
"fw_vendor": "LENOVO", "fw_version": "7LET51WW (1.21 )",
"fw_date": "08/22/2007",
- "device_type": nodeparse.CAPABILITY_TYPE_SYSTEM,
+ "device_type": NodeDevice.CAPABILITY_TYPE_SYSTEM,
"name": "computer", "parent": None}
self._testCompare(devname, vals)
def testNetDevice1(self):
devname = "net_00_1c_25_10_b1_e4"
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",
"capability_type": "80203"}
self._testCompare(devname, vals)
@@ -85,7 +90,7 @@ class TestNodeDev(unittest.TestCase):
def testNetDevice2(self):
devname = "net_00_1c_bf_04_29_a4"
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",
"capability_type": "80211"}
self._testCompare(devname, vals)
@@ -93,7 +98,7 @@ class TestNodeDev(unittest.TestCase):
def testPCIDevice1(self):
devname = "pci_1180_592"
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",
"product_id": "0x0592", "vendor_id": "0x1180",
"product_name": "R5C592 Memory Stick Bus Host Adapter",
@@ -103,7 +108,7 @@ class TestNodeDev(unittest.TestCase):
def testPCIDevice2(self):
devname = "pci_8086_1049"
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",
"product_id": "0x1049", "vendor_id": "0x8086",
"product_name": "82566MM Gigabit Network Connection",
@@ -114,7 +119,7 @@ class TestNodeDev(unittest.TestCase):
devname = "usb_device_781_5151_2004453082054CA1BEEE"
vals = {"name": "usb_device_781_5151_2004453082054CA1BEEE",
"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',
"vendor_id": '0x0781',
"vendor_name": "SanDisk Corp.",
@@ -125,7 +130,7 @@ class TestNodeDev(unittest.TestCase):
devname = "usb_device_483_2016_noserial"
vals = {"name": "usb_device_483_2016_noserial",
"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',
"vendor_id": '0x0483',
"vendor_name": "SGS Thomson Microelectronics",
@@ -136,21 +141,21 @@ class TestNodeDev(unittest.TestCase):
devname = "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",
- "device_type": nodeparse.CAPABILITY_TYPE_STORAGE,
+ "device_type": NodeDevice.CAPABILITY_TYPE_STORAGE,
"block": "/dev/sda", "bus": "scsi", "drive_type": "disk",
"model": "WDC WD1600AAJS-2", "vendor": "ATA",
"size": 160041885696, "removable": False,
- "hotpluggable": False, "media_available": False,
- "media_size": 0, "media_label": None}
+ "hotpluggable": False, "media_available": None,
+ "media_size": None, "media_label": None}
self._testCompare(devname, vals)
def testStorageDevice2(self):
devname = "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",
- "device_type": nodeparse.CAPABILITY_TYPE_STORAGE,
+ "device_type": NodeDevice.CAPABILITY_TYPE_STORAGE,
"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,
"media_available": True, "media_size": 12345678}
self._testCompare(devname, vals)
@@ -159,7 +164,7 @@ class TestNodeDev(unittest.TestCase):
devname = "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",
- "device_type": nodeparse.CAPABILITY_TYPE_USBBUS,
+ "device_type": NodeDevice.CAPABILITY_TYPE_USBBUS,
"number": "0", "classval": "9", "subclass": "0",
"protocol": "0"}
self._testCompare(devname, vals)
@@ -168,14 +173,14 @@ class TestNodeDev(unittest.TestCase):
devname = "pci_8086_2829_scsi_host_1"
vals = {"name": "pci_8086_2829_scsi_host_1",
"parent": "pci_8086_2829",
- "device_type": nodeparse.CAPABILITY_TYPE_SCSIBUS,
+ "device_type": NodeDevice.CAPABILITY_TYPE_SCSIBUS,
"host": "2"}
self._testCompare(devname, vals)
def testNPIV(self):
devname = "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,
"wwnn": "20000000c9848141", "wwpn": "10000000c9848141"}
self._testCompare(devname, vals)
diff --git a/virtManager/mediadev.py b/virtManager/mediadev.py
index b8d88438..69749a60 100644
--- a/virtManager/mediadev.py
+++ b/virtManager/mediadev.py
@@ -24,7 +24,7 @@ from gi.repository import GObject
import logging
-import virtinst
+from virtinst import NodeDevice
from virtManager.baseclass import vmmGObject
@@ -131,8 +131,8 @@ class vmmMediaDevice(vmmGObject):
return
try:
- vobj = virtinst.NodeDeviceParser.parse(xml)
- has_media = vobj.media_available
+ vobj = NodeDevice.parse(self.nodedev_obj.conn.get_backend(), xml)
+ has_media = vobj.media_available or False
except:
logging.exception("Node device CDROM polling failed")
return
diff --git a/virtManager/nodedev.py b/virtManager/nodedev.py
index 003354da..0dff39db 100644
--- a/virtManager/nodedev.py
+++ b/virtManager/nodedev.py
@@ -18,7 +18,7 @@
# MA 02110-1301 USA.
#
-import virtinst
+from virtinst import NodeDevice
from virtManager.libvirtobject import vmmLibvirtObject
@@ -41,7 +41,7 @@ class vmmNodeDevice(vmmLibvirtObject):
def get_virtinst_obj(self):
if not self._virtinst_obj:
- self._virtinst_obj = virtinst.NodeDeviceParser.parse(
+ self._virtinst_obj = NodeDevice.parse(self.conn.get_backend(),
self._backend.XMLDesc(0))
return self._virtinst_obj
diff --git a/virtinst/__init__.py b/virtinst/__init__.py
index f48239a9..a2fc25be 100644
--- a/virtinst/__init__.py
+++ b/virtinst/__init__.py
@@ -29,10 +29,10 @@ from virtinst.clock import Clock
from virtinst.cpu import CPU, CPUFeature
from virtinst.seclabel import Seclabel
-import virtinst.nodedev as NodeDeviceParser
import virtinst.capabilities as CapabilitiesParser
from virtinst.interface import Interface, InterfaceProtocol
from virtinst.network import Network
+from virtinst.nodedev import NodeDevice
from virtinst.storage import StoragePool, StorageVolume
from virtinst.device import VirtualDevice
diff --git a/virtinst/devicehostdev.py b/virtinst/devicehostdev.py
index a1315a99..7f8793ae 100644
--- a/virtinst/devicehostdev.py
+++ b/virtinst/devicehostdev.py
@@ -18,7 +18,7 @@
# MA 02110-1301 USA.
from virtinst import VirtualDevice
-from virtinst import NodeDeviceParser
+from virtinst import NodeDevice
from virtinst.xmlbuilder import XMLProperty
@@ -31,7 +31,7 @@ class VirtualHostDevice(VirtualDevice):
"""
Convert the passed device name to a VirtualHostDevice
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
be passed in to create a dev from.
@@ -47,11 +47,11 @@ class VirtualHostDevice(VirtualDevice):
if nodedev:
nodeinst = nodedev
else:
- nodeinst, addr_type = NodeDeviceParser.lookupNodeName(conn, name)
- if addr_type == NodeDeviceParser.HOSTDEV_ADDR_TYPE_USB_BUSADDR:
+ nodeinst, addr_type = NodeDevice.lookupNodeName(conn, name)
+ if addr_type == NodeDevice.HOSTDEV_ADDR_TYPE_USB_BUSADDR:
is_dup = True
- if isinstance(nodeinst, NodeDeviceParser.NetDevice):
+ if nodeinst.device_type == nodeinst.CAPABILITY_TYPE_NET:
parentname = nodeinst.parent
return VirtualHostDevice.device_from_node(conn,
name=parentname)
@@ -61,14 +61,14 @@ class VirtualHostDevice(VirtualDevice):
return dev
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.domain = nodedev.domain
self.bus = nodedev.bus
self.slot = nodedev.slot
self.function = nodedev.function
- elif isinstance(nodedev, NodeDeviceParser.USBDevice):
+ elif nodedev.device_type == NodeDevice.CAPABILITY_TYPE_USBDEV:
self.type = "usb"
self.vendor = nodedev.vendor_id
self.product = nodedev.product_id
diff --git a/virtinst/nodedev.py b/virtinst/nodedev.py
index 86dc0354..74b34b68 100644
--- a/virtinst/nodedev.py
+++ b/virtinst/nodedev.py
@@ -21,32 +21,86 @@ import logging
import libvirt
-from virtinst import util
+from virtinst.xmlbuilder import XMLBuilder
+from virtinst.xmlbuilder import XMLProperty as OrigXMLProperty
-# class USBDevice
-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"
+# We had a pre-existing set of parse tests when this was converted to
+# XMLBuilder. We do this to appease the check in xmlparse.py without
+# moving all the nodedev.py tests to one file. Should find a way to
+# drop it.
+class XMLProperty(OrigXMLProperty):
+ def __init__(self, *args, **kwargs):
+ kwargs["track"] = False
+ OrigXMLProperty.__init__(self, *args, **kwargs)
-HOSTDEV_ADDR_TYPE_LIBVIRT = 0
-HOSTDEV_ADDR_TYPE_PCI = 1
-HOSTDEV_ADDR_TYPE_USB_BUSADDR = 2
-HOSTDEV_ADDR_TYPE_USB_VENPRO = 3
+def _lookupNodeName(conn, name):
+ nodedev = conn.nodeDeviceLookupByName(name)
+ xml = nodedev.XMLDesc(0)
+ return NodeDevice.parse(conn, xml)
+
+
+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
-class NodeDevice(object):
- def __init__(self, node):
- self.name = None
- self.parent = None
- self.device_type = None
+ @param conn: libvirt.virConnect instance to perform the lookup on
+ @param name: libvirt node device name to lookup, or address for
+ devAddressToNodedev
- self._parseNodeXML(node)
+ @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):
"""
@@ -62,66 +116,16 @@ class NodeDevice(object):
ignore = child_dev
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):
- def __init__(self, node):
- NodeDevice.__init__(self, node)
-
- self.hw_vendor = None
- self.hw_version = None
- self.hw_serial = None
- 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
+ hw_vendor = XMLProperty("./capability/hardware/vendor")
+ hw_version = XMLProperty("./capability/hardware/version")
+ hw_serial = XMLProperty("./capability/hardware/serial")
+ hw_uuid = XMLProperty("./capability/hardware/uuid")
+
+ fw_vendor = XMLProperty("./capability/firmware/vendor")
+ fw_version = XMLProperty("./capability/firmware/version")
+ fw_date = XMLProperty("./capability/firmware/release_date")
def pretty_name(self, child_dev=None):
ignore = child_dev
@@ -135,25 +139,9 @@ class SystemDevice(NodeDevice):
class NetDevice(NodeDevice):
- def __init__(self, node):
- NodeDevice.__init__(self, node)
-
- 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
+ interface = XMLProperty("./capability/interface")
+ address = XMLProperty("./capability/address")
+ capability_type = XMLProperty("./capability/capability/@type")
def pretty_name(self, child_dev=None):
ignore = child_dev
@@ -165,40 +153,15 @@ class NetDevice(NodeDevice):
class PCIDevice(NodeDevice):
- def __init__(self, node):
- NodeDevice.__init__(self, node)
-
- self.domain = None
- self.bus = None
- self.slot = None
- self.function = None
-
- 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")
+ domain = XMLProperty("./capability/domain")
+ bus = XMLProperty("./capability/bus")
+ slot = XMLProperty("./capability/slot")
+ function = XMLProperty("./capability/function")
- else:
- self._parseValueHelper(child, val_map)
-
- child = child.next
+ product_name = XMLProperty("./capability/product")
+ product_id = XMLProperty("./capability/product/@id")
+ vendor_name = XMLProperty("./capability/vendor")
+ vendor_id = XMLProperty("./capability/vendor/@id")
def pretty_name(self, child_dev=None):
devstr = "%.2X:%.2X:%X" % (int(self.bus),
@@ -213,35 +176,13 @@ class PCIDevice(NodeDevice):
class USBDevice(NodeDevice):
- def __init__(self, node):
- NodeDevice.__init__(self, node)
-
- self.bus = None
- self.device = None
+ bus = XMLProperty("./capability/bus")
+ device = XMLProperty("./capability/device")
- 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 = {"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
+ product_name = XMLProperty("./capability/product")
+ product_id = XMLProperty("./capability/product/@id")
+ vendor_name = XMLProperty("./capability/vendor")
+ vendor_id = XMLProperty("./capability/vendor/@id")
def pretty_name(self, child_dev=None):
ignore = child_dev
@@ -252,56 +193,34 @@ class USBDevice(NodeDevice):
class StorageDevice(NodeDevice):
- def __init__(self, node):
- NodeDevice.__init__(self, node)
-
- self.block = None
- self.bus = None
- self.drive_type = None
- self.size = 0
-
- self.model = None
- self.vendor = None
-
- self.removable = False
- self.media_available = False
- self.media_size = 0
- self.media_label = None
-
- self.hotpluggable = False
-
- self.parseXML(self._getCapabilityNode(node))
-
- def parseXML(self, node):
- val_map = {"block" : "block",
- "bus" : "bus",
- "drive_type" : "drive_type",
- "model" : "model",
- "vendor" : "vendor"}
- 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
+ block = XMLProperty("./capability/block")
+ bus = XMLProperty("./capability/bus")
+ drive_type = XMLProperty("./capability/drive_type")
+ size = XMLProperty("./capability/size", is_int=True)
+
+ model = XMLProperty("./capability/model")
+ vendor = XMLProperty("./capability/vendor")
+
+ hotpluggable = XMLProperty(
+ "./capability/capability[@type='hotpluggable']", is_bool=True)
+ removable = XMLProperty(
+ "./capability/capability[@type='removable']", is_bool=True)
+
+ media_size = XMLProperty(
+ "./capability/capability[@type='removable']/media_size", is_int=True)
+ media_label = XMLProperty(
+ "./capability/capability[@type='removable']/media_label")
+ _media_available = XMLProperty(
+ "./capability/capability[@type='removable']/media_available",
+ is_int=True)
+ def _get_media_available(self):
+ m = self._media_available
+ if m is None:
+ return None
+ return bool(m)
+ def _set_media_available(self, val):
+ self._media_available = val
+ media_available = property(_get_media_available, _set_media_available)
def pretty_name(self, child_dev=None):
ignore = child_dev
@@ -319,116 +238,30 @@ class StorageDevice(NodeDevice):
class USBBus(NodeDevice):
- def __init__(self, node):
- NodeDevice.__init__(self, node)
-
- self.number = None
- 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)
+ number = XMLProperty("./capability/number")
+ classval = XMLProperty("./capability/class")
+ subclass = XMLProperty("./capability/subclass")
+ protocol = XMLProperty("./capability/protocol")
class SCSIDevice(NodeDevice):
- def __init__(self, node):
- NodeDevice.__init__(self, node)
-
- self.host = None
- self.bus = None
- 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)
+ host = XMLProperty("./capability/host")
+ bus = XMLProperty("./capability/bus")
+ target = XMLProperty("./capability/target")
+ lun = XMLProperty("./capability/lun")
+ type = XMLProperty("./capability/type")
class SCSIBus(NodeDevice):
- def __init__(self, node):
- NodeDevice.__init__(self, node)
-
- self.host = None
-
- self.vport_ops = False
-
- self.fc_host = False
- self.wwnn = None
- 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)
+ host = XMLProperty("./capability/host")
+ vport_ops = XMLProperty(
+ "./capability/capability[@type='vport_ops']", is_bool=True)
-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)
+ fc_host = XMLProperty(
+ "./capability/capability[@type='fc_host']", is_bool=True)
+ wwnn = XMLProperty("./capability/capability[@type='fc_host']/wwnn")
+ wwpn = XMLProperty("./capability/capability[@type='fc_host']/wwpn")
def _isAddressStr(addrstr):
@@ -438,7 +271,7 @@ def _isAddressStr(addrstr):
try:
# Determine addrstr type
if addrstr.count(":") in [1, 2] and addrstr.count("."):
- devtype = CAPABILITY_TYPE_PCI
+ devtype = NodeDevice.CAPABILITY_TYPE_PCI
addrstr, func = addrstr.split(".", 1)
addrstr, slot = addrstr.rsplit(":", 1)
domain = "0"
@@ -458,10 +291,10 @@ def _isAddressStr(addrstr):
(int(nodedev.bus) == bus) and
(int(nodedev.slot) == slot))
cmp_func = pci_cmp
- addr_type = HOSTDEV_ADDR_TYPE_PCI
+ addr_type = NodeDevice.HOSTDEV_ADDR_TYPE_PCI
elif addrstr.count(":"):
- devtype = CAPABILITY_TYPE_USBDEV
+ devtype = NodeDevice.CAPABILITY_TYPE_USBDEV
vendor, product = addrstr.split(":")
vendor = int(vendor, 16)
product = int(product, 16)
@@ -470,10 +303,10 @@ def _isAddressStr(addrstr):
return ((int(nodedev.vendor_id, 16) == vendor) and
(int(nodedev.product_id, 16) == product))
cmp_func = usbprod_cmp
- addr_type = HOSTDEV_ADDR_TYPE_USB_VENPRO
+ addr_type = NodeDevice.HOSTDEV_ADDR_TYPE_USB_VENPRO
elif addrstr.count("."):
- devtype = CAPABILITY_TYPE_USBDEV
+ devtype = NodeDevice.CAPABILITY_TYPE_USBDEV
bus, addr = addrstr.split(".", 1)
bus = int(bus)
addr = int(addr)
@@ -482,7 +315,7 @@ def _isAddressStr(addrstr):
return ((int(nodedev.bus) == bus) and
(int(nodedev.device) == addr))
cmp_func = usbaddr_cmp
- addr_type = HOSTDEV_ADDR_TYPE_USB_BUSADDR
+ addr_type = NodeDevice.HOSTDEV_ADDR_TYPE_USB_BUSADDR
except:
logging.exception("Error parsing node device string.")
return None
@@ -533,49 +366,22 @@ def devAddressToNodedev(conn, 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):
- if t == CAPABILITY_TYPE_SYSTEM:
+ if t == NodeDevice.CAPABILITY_TYPE_SYSTEM:
return SystemDevice
- elif t == CAPABILITY_TYPE_NET:
+ elif t == NodeDevice.CAPABILITY_TYPE_NET:
return NetDevice
- elif t == CAPABILITY_TYPE_PCI:
+ elif t == NodeDevice.CAPABILITY_TYPE_PCI:
return PCIDevice
- elif t == CAPABILITY_TYPE_USBDEV:
+ elif t == NodeDevice.CAPABILITY_TYPE_USBDEV:
return USBDevice
- elif t == CAPABILITY_TYPE_USBBUS:
+ elif t == NodeDevice.CAPABILITY_TYPE_USBBUS:
return USBBus
- elif t == CAPABILITY_TYPE_STORAGE:
+ elif t == NodeDevice.CAPABILITY_TYPE_STORAGE:
return StorageDevice
- elif t == CAPABILITY_TYPE_SCSIBUS:
+ elif t == NodeDevice.CAPABILITY_TYPE_SCSIBUS:
return SCSIBus
- elif t == CAPABILITY_TYPE_SCSIDEV:
+ elif t == NodeDevice.CAPABILITY_TYPE_SCSIDEV:
return SCSIDevice
else:
return NodeDevice
diff --git a/virtinst/xmlbuilder.py b/virtinst/xmlbuilder.py
index 7c880c4d..78daaf64 100644
--- a/virtinst/xmlbuilder.py
+++ b/virtinst/xmlbuilder.py
@@ -333,7 +333,8 @@ class XMLProperty(property):
set_converter=None, validate_cb=None,
make_getter_xpath_cb=None, make_setter_xpath_cb=None,
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
<domain> XML. For example
@@ -374,6 +375,8 @@ class XMLProperty(property):
first explicit 'set'.
@param default_name: If the user does a set and passes in this
value, instead use the value of default_cb()
+ @param track: If False, opt out of property tracking for the
+ test suite.
"""
self._xpath = xpath
@@ -404,7 +407,7 @@ class XMLProperty(property):
if self._default_name and not self._default_cb:
raise RuntimeError("default_name requires default_cb.")
- if _trackprops:
+ if _trackprops and track:
_allprops.append(self)
property.__init__(self, fget=self.getter, fset=self.setter)
@@ -907,7 +910,7 @@ class XMLBuilder(object):
ret = {}
for c in reversed(type.mro(self.__class__)[:-1]):
for key, val in c.__dict__.items():
- if val.__class__ is checkclass:
+ if isinstance(val, checkclass):
ret[key] = val
setattr(self.__class__, cachename, ret)
return getattr(self.__class__, cachename)