virtinst: Add DomainCapabilities parser

This commit is contained in:
Cole Robinson 2014-09-17 14:56:52 -04:00
parent 0ad7611b59
commit 052220cfc8
6 changed files with 172 additions and 14 deletions

View File

@ -0,0 +1,71 @@
<domainCapabilities>
<path>/bin/emulatorbin</path>
<domain>kvm</domain>
<machine>my-machine-type</machine>
<arch>x86_64</arch>
<vcpu max='255'/>
<os supported='yes'>
<loader supported='yes'>
<value>/foo/bar</value>
<value>/tmp/my_path</value>
<enum name='type'>
<value>rom</value>
<value>pflash</value>
</enum>
<enum name='readonly'>
<value>default</value>
<value>yes</value>
<value>no</value>
</enum>
</loader>
</os>
<devices>
<disk supported='yes'>
<enum name='diskDevice'>
<value>disk</value>
<value>cdrom</value>
<value>floppy</value>
<value>lun</value>
</enum>
<enum name='bus'>
<value>ide</value>
<value>fdc</value>
<value>scsi</value>
<value>virtio</value>
<value>xen</value>
<value>usb</value>
<value>uml</value>
<value>sata</value>
<value>sd</value>
</enum>
</disk>
<hostdev supported='yes'>
<enum name='mode'>
<value>subsystem</value>
<value>capabilities</value>
</enum>
<enum name='startupPolicy'>
<value>default</value>
<value>mandatory</value>
<value>requisite</value>
<value>optional</value>
</enum>
<enum name='subsysType'>
<value>usb</value>
<value>pci</value>
<value>scsi</value>
</enum>
<enum name='capsType'>
<value>storage</value>
<value>misc</value>
<value>net</value>
</enum>
<enum name='pciBackend'>
<value>default</value>
<value>kvm</value>
<value>vfio</value>
<value>xen</value>
</enum>
</hostdev>
</devices>
</domainCapabilities>

View File

@ -21,6 +21,7 @@ import unittest
from tests import utils
from virtinst import CapabilitiesParser as capabilities
from virtinst.capabilities import _CPUMapFileValues
from virtinst import DomainCapabilities
def build_host_feature_dict(feature_list):
@ -249,6 +250,17 @@ class TestCapabilities(unittest.TestCase):
cpu_64 = caps.get_cpu_values(conn, "x86_64")
self.assertTrue(len(cpu_64) > 0)
def testDomainCapabilities(self):
xml = file("tests/capabilities-xml/domain-capabilities.xml").read()
caps = DomainCapabilities(utils.open_testdriver(), xml)
self.assertEqual(caps.os.loader.supported, True)
self.assertEquals(caps.os.loader.get_values(),
["/foo/bar", "/tmp/my_path"])
self.assertEquals(caps.os.loader.enum_names(), ["type", "readonly"])
self.assertEquals(caps.os.loader.get_enum("type").get_values(),
["rom", "pflash"])
if __name__ == "__main__":
unittest.main()

View File

@ -51,6 +51,7 @@ from virtinst.pm import PM
from virtinst.idmap import IdMap
from virtinst import capabilities as CapabilitiesParser
from virtinst.domcapabilities import DomainCapabilities
from virtinst.interface import Interface, InterfaceProtocol
from virtinst.network import Network
from virtinst.nodedev import NodeDevice

View File

@ -0,0 +1,81 @@
#
# Support for parsing libvirt's domcapabilities XML
#
# Copyright 2014 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
from .xmlbuilder import XMLBuilder, XMLChildProperty
from .xmlbuilder import XMLProperty as _XMLProperty
class XMLProperty(_XMLProperty):
# We don't care about full parsing coverage, so tell the test suite
# not to warn
_track = False
class _Value(XMLBuilder):
_XML_ROOT_NAME = "value"
value = XMLProperty(".")
class _HasValues(XMLBuilder):
values = XMLChildProperty(_Value)
def get_values(self):
return [v.value for v in self.values]
class _Enum(_HasValues):
_XML_ROOT_NAME = "enum"
name = XMLProperty("./@name")
class _CapsBlock(_HasValues):
supported = XMLProperty("./@supported", is_yesno=True)
enums = XMLChildProperty(_Enum)
def enum_names(self):
return [e.name for e in self.enums]
def get_enum(self, name):
d = dict((e.name, e) for e in self.enums)
return d[name]
def _make_capsblock(xml_root_name):
class TmpClass(_CapsBlock):
pass
setattr(TmpClass, "_XML_ROOT_NAME", xml_root_name)
return TmpClass
class _OS(_CapsBlock):
_XML_ROOT_NAME = "os"
loader = XMLChildProperty(_make_capsblock("loader"), is_single=True)
class _Devices(_CapsBlock):
_XML_ROOT_NAME = "devices"
hostdev = XMLChildProperty(_make_capsblock("hostdev"), is_single=True)
disk = XMLChildProperty(_make_capsblock("disk"), is_single=True)
class DomainCapabilities(XMLBuilder):
_XML_ROOT_NAME = "domainCapabilities"
os = XMLChildProperty(_OS, is_single=True)
devices = XMLChildProperty(_Devices, is_single=True)

View File

@ -22,17 +22,11 @@ import logging
import libvirt
from .xmlbuilder import XMLBuilder
from .xmlbuilder import XMLProperty as OrigXMLProperty
from .xmlbuilder import XMLProperty as _XMLProperty
# 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)
class XMLProperty(_XMLProperty):
_track = False
def _lookupNodeName(conn, name):

View File

@ -329,11 +329,12 @@ class XMLChildProperty(property):
class XMLProperty(property):
_track = True
def __init__(self, xpath=None, name=None, doc=None,
set_converter=None, validate_cb=None, make_xpath_cb=None,
is_bool=False, is_int=False, is_yesno=False, is_onoff=False,
clear_first=None, default_cb=None, default_name=None,
track=True):
clear_first=None, default_cb=None, default_name=None):
"""
Set a XMLBuilder class property that represents a value in the
<domain> XML. For example
@ -373,8 +374,6 @@ 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
@ -403,7 +402,7 @@ class XMLProperty(property):
if self._default_name and not self._default_cb:
raise RuntimeError("default_name requires default_cb.")
if _trackprops and track:
if _trackprops and self._track:
_allprops.append(self)
property.__init__(self, fget=self.getter, fset=self.setter)