Blame SOURCES/virt-manager-virtinst-Add-DomainCapabilities-parser.patch

e2df08
From 309b82d9b1ef47239d1d6fe6f0d72e7eedd1071b Mon Sep 17 00:00:00 2001
e2df08
From: Cole Robinson <crobinso@redhat.com>
e2df08
Date: Wed, 17 Sep 2014 14:56:52 -0400
e2df08
Subject: [PATCH 08/12] virtinst: Add DomainCapabilities parser
e2df08
e2df08
Closes: https://bugzilla.redhat.com/show_bug.cgi?id=1111986
e2df08
e2df08
(cherry picked from commit 052220cfc80a9e262b39a15a4c5bdb09d5686602)
e2df08
---
e2df08
 tests/capabilities-xml/domain-capabilities.xml | 71 ++++++++++++++++++++++
e2df08
 tests/capabilities.py                          | 12 ++++
e2df08
 virtinst/__init__.py                           |  1 +
e2df08
 virtinst/domcapabilities.py                    | 81 ++++++++++++++++++++++++++
e2df08
 virtinst/nodedev.py                            | 12 +---
e2df08
 virtinst/xmlbuilder.py                         |  9 ++-
e2df08
 6 files changed, 172 insertions(+), 14 deletions(-)
e2df08
 create mode 100644 tests/capabilities-xml/domain-capabilities.xml
e2df08
 create mode 100644 virtinst/domcapabilities.py
e2df08
e2df08
diff --git a/tests/capabilities-xml/domain-capabilities.xml b/tests/capabilities-xml/domain-capabilities.xml
e2df08
new file mode 100644
e2df08
index 0000000..96202bc
e2df08
--- /dev/null
e2df08
+++ b/tests/capabilities-xml/domain-capabilities.xml
e2df08
@@ -0,0 +1,71 @@
e2df08
+<domainCapabilities>
e2df08
+  <path>/bin/emulatorbin</path>
e2df08
+  <domain>kvm</domain>
e2df08
+  <machine>my-machine-type</machine>
e2df08
+  <arch>x86_64</arch>
e2df08
+  <vcpu max='255'/>
e2df08
+  <os supported='yes'>
e2df08
+    <loader supported='yes'>
e2df08
+      <value>/foo/bar</value>
e2df08
+      <value>/tmp/my_path</value>
e2df08
+      <enum name='type'>
e2df08
+        <value>rom</value>
e2df08
+        <value>pflash</value>
e2df08
+      </enum>
e2df08
+      <enum name='readonly'>
e2df08
+        <value>default</value>
e2df08
+        <value>yes</value>
e2df08
+        <value>no</value>
e2df08
+      </enum>
e2df08
+    </loader>
e2df08
+  </os>
e2df08
+  <devices>
e2df08
+    <disk supported='yes'>
e2df08
+      <enum name='diskDevice'>
e2df08
+        <value>disk</value>
e2df08
+        <value>cdrom</value>
e2df08
+        <value>floppy</value>
e2df08
+        <value>lun</value>
e2df08
+      </enum>
e2df08
+      <enum name='bus'>
e2df08
+        <value>ide</value>
e2df08
+        <value>fdc</value>
e2df08
+        <value>scsi</value>
e2df08
+        <value>virtio</value>
e2df08
+        <value>xen</value>
e2df08
+        <value>usb</value>
e2df08
+        <value>uml</value>
e2df08
+        <value>sata</value>
e2df08
+        <value>sd</value>
e2df08
+      </enum>
e2df08
+    </disk>
e2df08
+    <hostdev supported='yes'>
e2df08
+      <enum name='mode'>
e2df08
+        <value>subsystem</value>
e2df08
+        <value>capabilities</value>
e2df08
+      </enum>
e2df08
+      <enum name='startupPolicy'>
e2df08
+        <value>default</value>
e2df08
+        <value>mandatory</value>
e2df08
+        <value>requisite</value>
e2df08
+        <value>optional</value>
e2df08
+      </enum>
e2df08
+      <enum name='subsysType'>
e2df08
+        <value>usb</value>
e2df08
+        <value>pci</value>
e2df08
+        <value>scsi</value>
e2df08
+      </enum>
e2df08
+      <enum name='capsType'>
e2df08
+        <value>storage</value>
e2df08
+        <value>misc</value>
e2df08
+        <value>net</value>
e2df08
+      </enum>
e2df08
+      <enum name='pciBackend'>
e2df08
+        <value>default</value>
e2df08
+        <value>kvm</value>
e2df08
+        <value>vfio</value>
e2df08
+        <value>xen</value>
e2df08
+      </enum>
e2df08
+    </hostdev>
e2df08
+  </devices>
e2df08
+</domainCapabilities>
e2df08
diff --git a/tests/capabilities.py b/tests/capabilities.py
e2df08
index 394d6ed..8f6eaae 100644
e2df08
--- a/tests/capabilities.py
e2df08
+++ b/tests/capabilities.py
e2df08
@@ -21,6 +21,7 @@ import unittest
e2df08
 from tests import utils
e2df08
 from virtinst import CapabilitiesParser as capabilities
e2df08
 from virtinst.capabilities import _CPUMapFileValues
e2df08
+from virtinst import DomainCapabilities
e2df08
 
e2df08
 
e2df08
 def build_host_feature_dict(feature_list):
e2df08
@@ -249,6 +250,17 @@ class TestCapabilities(unittest.TestCase):
e2df08
         cpu_64 = caps.get_cpu_values(conn, "x86_64")
e2df08
         self.assertTrue(len(cpu_64) > 0)
e2df08
 
e2df08
+    def testDomainCapabilities(self):
e2df08
+        xml = file("tests/capabilities-xml/domain-capabilities.xml").read()
e2df08
+        caps = DomainCapabilities(utils.open_testdriver(), xml)
e2df08
+
e2df08
+        self.assertEqual(caps.os.loader.supported, True)
e2df08
+        self.assertEquals(caps.os.loader.get_values(),
e2df08
+            ["/foo/bar", "/tmp/my_path"])
e2df08
+        self.assertEquals(caps.os.loader.enum_names(), ["type", "readonly"])
e2df08
+        self.assertEquals(caps.os.loader.get_enum("type").get_values(),
e2df08
+            ["rom", "pflash"])
e2df08
+
e2df08
 
e2df08
 if __name__ == "__main__":
e2df08
     unittest.main()
e2df08
diff --git a/virtinst/__init__.py b/virtinst/__init__.py
e2df08
index 3a81173..e416054 100644
e2df08
--- a/virtinst/__init__.py
e2df08
+++ b/virtinst/__init__.py
e2df08
@@ -51,6 +51,7 @@ from virtinst.pm import PM
e2df08
 from virtinst.idmap import IdMap
e2df08
 
e2df08
 from virtinst import capabilities as CapabilitiesParser
e2df08
+from virtinst.domcapabilities import DomainCapabilities
e2df08
 from virtinst.interface import Interface, InterfaceProtocol
e2df08
 from virtinst.network import Network
e2df08
 from virtinst.nodedev import NodeDevice
e2df08
diff --git a/virtinst/domcapabilities.py b/virtinst/domcapabilities.py
e2df08
new file mode 100644
e2df08
index 0000000..6de7afb
e2df08
--- /dev/null
e2df08
+++ b/virtinst/domcapabilities.py
e2df08
@@ -0,0 +1,81 @@
e2df08
+#
e2df08
+# Support for parsing libvirt's domcapabilities XML
e2df08
+#
e2df08
+# Copyright 2014 Red Hat, Inc.
e2df08
+#
e2df08
+# This program is free software; you can redistribute it and/or modify
e2df08
+# it under the terms of the GNU General Public License as published by
e2df08
+# the Free Software Foundation; either version 2 of the License, or
e2df08
+# (at your option) any later version.
e2df08
+#
e2df08
+# This program is distributed in the hope that it will be useful,
e2df08
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
e2df08
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
e2df08
+# GNU General Public License for more details.
e2df08
+#
e2df08
+# You should have received a copy of the GNU General Public License
e2df08
+# along with this program; if not, write to the Free Software
e2df08
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
e2df08
+# MA 02110-1301 USA.
e2df08
+
e2df08
+from .xmlbuilder import XMLBuilder, XMLChildProperty
e2df08
+from .xmlbuilder import XMLProperty as _XMLProperty
e2df08
+
e2df08
+
e2df08
+class XMLProperty(_XMLProperty):
e2df08
+    # We don't care about full parsing coverage, so tell the test suite
e2df08
+    # not to warn
e2df08
+    _track = False
e2df08
+
e2df08
+
e2df08
+class _Value(XMLBuilder):
e2df08
+    _XML_ROOT_NAME = "value"
e2df08
+    value = XMLProperty(".")
e2df08
+
e2df08
+
e2df08
+class _HasValues(XMLBuilder):
e2df08
+    values = XMLChildProperty(_Value)
e2df08
+
e2df08
+    def get_values(self):
e2df08
+        return [v.value for v in self.values]
e2df08
+
e2df08
+
e2df08
+class _Enum(_HasValues):
e2df08
+    _XML_ROOT_NAME = "enum"
e2df08
+    name = XMLProperty("./@name")
e2df08
+
e2df08
+
e2df08
+class _CapsBlock(_HasValues):
e2df08
+    supported = XMLProperty("./@supported", is_yesno=True)
e2df08
+    enums = XMLChildProperty(_Enum)
e2df08
+
e2df08
+    def enum_names(self):
e2df08
+        return [e.name for e in self.enums]
e2df08
+
e2df08
+    def get_enum(self, name):
e2df08
+        d = dict((e.name, e) for e in self.enums)
e2df08
+        return d[name]
e2df08
+
e2df08
+
e2df08
+def _make_capsblock(xml_root_name):
e2df08
+    class TmpClass(_CapsBlock):
e2df08
+        pass
e2df08
+    setattr(TmpClass, "_XML_ROOT_NAME", xml_root_name)
e2df08
+    return TmpClass
e2df08
+
e2df08
+
e2df08
+class _OS(_CapsBlock):
e2df08
+    _XML_ROOT_NAME = "os"
e2df08
+    loader = XMLChildProperty(_make_capsblock("loader"), is_single=True)
e2df08
+
e2df08
+
e2df08
+class _Devices(_CapsBlock):
e2df08
+    _XML_ROOT_NAME = "devices"
e2df08
+    hostdev = XMLChildProperty(_make_capsblock("hostdev"), is_single=True)
e2df08
+    disk = XMLChildProperty(_make_capsblock("disk"), is_single=True)
e2df08
+
e2df08
+
e2df08
+class DomainCapabilities(XMLBuilder):
e2df08
+    _XML_ROOT_NAME = "domainCapabilities"
e2df08
+    os = XMLChildProperty(_OS, is_single=True)
e2df08
+    devices = XMLChildProperty(_Devices, is_single=True)
e2df08
diff --git a/virtinst/nodedev.py b/virtinst/nodedev.py
e2df08
index a42c20d..836f596 100644
e2df08
--- a/virtinst/nodedev.py
e2df08
+++ b/virtinst/nodedev.py
e2df08
@@ -22,17 +22,11 @@ import logging
e2df08
 import libvirt
e2df08
 
e2df08
 from .xmlbuilder import XMLBuilder
e2df08
-from .xmlbuilder import XMLProperty as OrigXMLProperty
e2df08
+from .xmlbuilder import XMLProperty as _XMLProperty
e2df08
 
e2df08
 
e2df08
-# We had a pre-existing set of parse tests when this was converted to
e2df08
-# XMLBuilder. We do this to appease the check in xmlparse.py without
e2df08
-# moving all the nodedev.py tests to one file. Should find a way to
e2df08
-# drop it.
e2df08
-class XMLProperty(OrigXMLProperty):
e2df08
-    def __init__(self, *args, **kwargs):
e2df08
-        kwargs["track"] = False
e2df08
-        OrigXMLProperty.__init__(self, *args, **kwargs)
e2df08
+class XMLProperty(_XMLProperty):
e2df08
+    _track = False
e2df08
 
e2df08
 
e2df08
 def _lookupNodeName(conn, name):
e2df08
diff --git a/virtinst/xmlbuilder.py b/virtinst/xmlbuilder.py
e2df08
index 77f8173..c906337 100644
e2df08
--- a/virtinst/xmlbuilder.py
e2df08
+++ b/virtinst/xmlbuilder.py
e2df08
@@ -329,11 +329,12 @@ class XMLChildProperty(property):
e2df08
 
e2df08
 
e2df08
 class XMLProperty(property):
e2df08
+    _track = True
e2df08
+
e2df08
     def __init__(self, xpath=None, name=None, doc=None,
e2df08
                  set_converter=None, validate_cb=None, make_xpath_cb=None,
e2df08
                  is_bool=False, is_int=False, is_yesno=False, is_onoff=False,
e2df08
-                 clear_first=None, default_cb=None, default_name=None,
e2df08
-                 track=True):
e2df08
+                 clear_first=None, default_cb=None, default_name=None):
e2df08
         """
e2df08
         Set a XMLBuilder class property that represents a value in the
e2df08
         <domain> XML. For example
e2df08
@@ -373,8 +374,6 @@ class XMLProperty(property):
e2df08
             first explicit 'set'.
e2df08
         @param default_name: If the user does a set and passes in this
e2df08
             value, instead use the value of default_cb()
e2df08
-        @param track: If False, opt out of property tracking for the
e2df08
-            test suite.
e2df08
         """
e2df08
 
e2df08
         self._xpath = xpath
e2df08
@@ -403,7 +402,7 @@ class XMLProperty(property):
e2df08
         if self._default_name and not self._default_cb:
e2df08
             raise RuntimeError("default_name requires default_cb.")
e2df08
 
e2df08
-        if _trackprops and track:
e2df08
+        if _trackprops and self._track:
e2df08
             _allprops.append(self)
e2df08
 
e2df08
         property.__init__(self, fget=self.getter, fset=self.setter)
e2df08
-- 
e2df08
1.9.3
e2df08