Skip to content

Commit

Permalink
Add libvirt config classes for handling capabilities XML doc
Browse files Browse the repository at this point in the history
Libvirt exposes the host/hypervisor features using an XML
schema known as "capabilities". Currently the libvirt driver
code just parses this in an adhoc manner using xpath queries.

This change provides a handful of classes LibvirtConfigCaps,
LibvirtConfigCapsHost and LibvirtConfigCapsGuest for maintaining
an object based representation of the capabilities. The
LibvirtConfigCapsHost class also uses the existing LibvirtConfigCPU
class

Fixes: bug #1003373
Implements: blueprint libvirt-xml-cpu-model
Change-Id: Ie962c6378b0da09eddc75983d4824a226ed1c25e
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
  • Loading branch information
berrange committed Jun 28, 2012
1 parent bcc0499 commit 272407b
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 0 deletions.
35 changes: 35 additions & 0 deletions nova/tests/test_libvirt_config.py
Expand Up @@ -59,6 +59,41 @@ def test_config_parse(self):
obj.parse_str(inxml)


class LibvirtConfigCapsTest(LibvirtConfigBaseTest):

def test_config_host(self):
xmlin = """
<capabilities>
<host>
<cpu>
<arch>x86_64</arch>
<model>Opteron_G3</model>
<vendor>AMD</vendor>
<topology sockets='1' cores='4' threads='1'/>
<feature name='ibs'/>
<feature name='osvw'/>
</cpu>
</host>
<guest>
<os_type>hvm</os_type>
<arch name='x86_64'/>
</guest>
<guest>
<os_type>hvm</os_type>
<arch name='i686'/>
</guest>
</capabilities>"""

obj = config.LibvirtConfigCaps()
obj.parse_str(xmlin)

self.assertEqual(type(obj.host), config.LibvirtConfigCapsHost)

xmlout = obj.to_xml()

self.assertXmlEqual(xmlin, xmlout)


class LibvirtConfigGuestTimerTest(LibvirtConfigBaseTest):
def test_config_platform(self):
obj = config.LibvirtConfigGuestTimer()
Expand Down
112 changes: 112 additions & 0 deletions nova/virt/libvirt/config.py
Expand Up @@ -67,6 +67,94 @@ def to_xml(self, pretty_print=True):
return xml_str


class LibvirtConfigCaps(LibvirtConfigObject):

def __init__(self, **kwargs):
super(LibvirtConfigCaps, self).__init__(root_name="capabilities",
**kwargs)
self.host = None
self.guests = []

def parse_dom(self, xmldoc):
super(LibvirtConfigCaps, self).parse_dom(xmldoc)

for c in xmldoc.getchildren():
if c.tag == "host":
host = LibvirtConfigCapsHost()
host.parse_dom(c)
self.host = host
elif c.tag == "guest":
guest = LibvirtConfigCapsGuest()
guest.parse_dom(c)
self.guests.append(guest)

def format_dom(self):
caps = super(LibvirtConfigCaps, self).format_dom()

if self.host:
caps.append(self.host.format_dom())
for g in self.guests:
caps.append(g.format_dom())

return caps


class LibvirtConfigCapsHost(LibvirtConfigObject):

def __init__(self, **kwargs):
super(LibvirtConfigCapsHost, self).__init__(root_name="host",
**kwargs)

self.cpu = None

def parse_dom(self, xmldoc):
super(LibvirtConfigCapsHost, self).parse_dom(xmldoc)

for c in xmldoc.getchildren():
if c.tag == "cpu":
cpu = LibvirtConfigCPU()
cpu.parse_dom(c)
self.cpu = cpu

def format_dom(self):
caps = super(LibvirtConfigCapsHost, self).format_dom()

if self.cpu:
caps.append(self.cpu.format_dom())

return caps


class LibvirtConfigCapsGuest(LibvirtConfigObject):

def __init__(self, **kwargs):
super(LibvirtConfigCapsGuest, self).__init__(root_name="guest",
**kwargs)

self.arch = None
self.ostype = None

def parse_dom(self, xmldoc):
super(LibvirtConfigCapsGuest, self).parse_dom(xmldoc)

for c in xmldoc.getchildren():
if c.tag == "os_type":
self.ostype = c.text
elif c.tag == "arch":
self.arch = c.get("name")

def format_dom(self):
caps = super(LibvirtConfigCapsGuest, self).format_dom()

if self.ostype is not None:
caps.append(self._text_node("os_type", self.ostype))
if self.arch:
arch = etree.Element("arch", name=self.arch)
caps.append(arch)

return caps


class LibvirtConfigGuestTimer(LibvirtConfigObject):

def __init__(self, **kwargs):
Expand Down Expand Up @@ -132,6 +220,11 @@ def __init__(self, name=None, **kwargs):

self.name = name

def parse_dom(self, xmldoc):
super(LibvirtConfigCPUFeature, self).parse_dom(xmldoc)

self.name = xmldoc.get("name")

def format_dom(self):
ft = super(LibvirtConfigCPUFeature, self).format_dom()

Expand All @@ -156,6 +249,25 @@ def __init__(self, **kwargs):

self.features = []

def parse_dom(self, xmldoc):
super(LibvirtConfigCPU, self).parse_dom(xmldoc)

for c in xmldoc.getchildren():
if c.tag == "arch":
self.arch = c.text
elif c.tag == "model":
self.model = c.text
elif c.tag == "vendor":
self.vendor = c.text
elif c.tag == "topology":
self.sockets = int(c.get("sockets"))
self.cores = int(c.get("cores"))
self.threads = int(c.get("threads"))
elif c.tag == "feature":
f = LibvirtConfigCPUFeature()
f.parse_dom(c)
self.add_feature(f)

def format_dom(self):
cpu = super(LibvirtConfigCPU, self).format_dom()

Expand Down

0 comments on commit 272407b

Please sign in to comment.