summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-06-28 17:47:33 +0000
committerGerrit Code Review <review@openstack.org>2012-06-28 17:47:33 +0000
commit49504a349ee7ce7e0956b7aed208442284bd0ef1 (patch)
tree35581e09b294e3207bded3eefe12eabf592e181a
parent12287031c0e1d493211074eebc78fb2d2506b72e (diff)
parentb4abb92b815988a4700313274ac7182f374a2286 (diff)
downloadnova-49504a349ee7ce7e0956b7aed208442284bd0ef1.tar.gz
nova-49504a349ee7ce7e0956b7aed208442284bd0ef1.tar.xz
nova-49504a349ee7ce7e0956b7aed208442284bd0ef1.zip
Merge "Switch libvirt get_cpu_info method over to use config APIs"
-rw-r--r--nova/tests/test_libvirt.py45
-rw-r--r--nova/virt/libvirt/driver.py76
2 files changed, 80 insertions, 41 deletions
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py
index 2bc20d2b0..3bb377e26 100644
--- a/nova/tests/test_libvirt.py
+++ b/nova/tests/test_libvirt.py
@@ -1747,6 +1747,51 @@ class LibvirtConnTestCase(test.TestCase):
space = fake_libvirt_utils.get_fs_info(FLAGS.instances_path)['free']
self.assertEqual(result, space / 1024 ** 3)
+ def test_cpu_info(self):
+ conn = libvirt_driver.LibvirtDriver(True)
+
+ def get_host_capabilities_stub(self):
+ cpu = config.LibvirtConfigCPU()
+ cpu.model = "Opteron_G4"
+ cpu.vendor = "AMD"
+ cpu.arch = "x86_64"
+
+ cpu.cores = 2
+ cpu.threads = 1
+ cpu.sockets = 4
+
+ cpu.add_feature(config.LibvirtConfigCPUFeature("extapic"))
+ cpu.add_feature(config.LibvirtConfigCPUFeature("3dnow"))
+
+ caps = config.LibvirtConfigCaps()
+ caps.host = config.LibvirtConfigCapsHost()
+ caps.host.cpu = cpu
+
+ guest = config.LibvirtConfigGuest()
+ guest.ostype = "hvm"
+ guest.arch = "x86_64"
+ caps.guests.append(guest)
+
+ guest = config.LibvirtConfigGuest()
+ guest.ostype = "hvm"
+ guest.arch = "i686"
+ caps.guests.append(guest)
+
+ return caps
+
+ self.stubs.Set(libvirt_driver.LibvirtDriver,
+ 'get_host_capabilities',
+ get_host_capabilities_stub)
+
+ want = {"vendor": "AMD",
+ "features": ["extapic", "3dnow"],
+ "permitted_instance_types": ["x86_64", "i686"],
+ "model": "Opteron_G4",
+ "arch": "x86_64",
+ "topology": {"cores": 2, "threads": 1, "sockets": 4}}
+ got = jsonutils.loads(conn.get_cpu_info())
+ self.assertEqual(want, got)
+
class HostStateTestCase(test.TestCase):
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index 08de82d62..533597923 100644
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -1429,6 +1429,15 @@ class LibvirtDriver(driver.ComputeDriver):
config_drive, config_drive_id = self._get_config_drive_info(instance)
return any((config_drive, config_drive_id))
+ def get_host_capabilities(self):
+ """Returns an instance of config.LibvirtConfigCaps representing
+ the capabilities of the host"""
+ xmlstr = self._conn.getCapabilities()
+
+ caps = config.LibvirtConfigCaps()
+ caps.parse_str(xmlstr)
+ return caps
+
def get_guest_config(self, instance, network_info, image_meta, rescue=None,
block_device_info=None):
"""Get config data for parameters.
@@ -1974,53 +1983,38 @@ class LibvirtDriver(driver.ComputeDriver):
"""
- xml = self._conn.getCapabilities()
- xml = etree.fromstring(xml)
- nodes = xml.findall('.//host/cpu')
- if len(nodes) != 1:
- reason = _("'<cpu>' must be 1, but %d\n") % len(nodes)
- reason += xml.serialize()
- raise exception.InvalidCPUInfo(reason=reason)
-
+ caps = self.get_host_capabilities()
cpu_info = dict()
- arch_nodes = xml.findall('.//host/cpu/arch')
- if arch_nodes:
- cpu_info['arch'] = arch_nodes[0].text
+ cpu_info['arch'] = caps.host.cpu.arch
+ cpu_info['model'] = caps.host.cpu.model
+ cpu_info['vendor'] = caps.host.cpu.vendor
- model_nodes = xml.findall('.//host/cpu/model')
- if model_nodes:
- cpu_info['model'] = model_nodes[0].text
-
- vendor_nodes = xml.findall('.//host/cpu/vendor')
- if vendor_nodes:
- cpu_info['vendor'] = vendor_nodes[0].text
-
- topology_nodes = xml.findall('.//host/cpu/topology')
topology = dict()
- if topology_nodes:
- topology_node = topology_nodes[0]
-
- keys = ['cores', 'sockets', 'threads']
- tkeys = topology_node.keys()
- if set(tkeys) != set(keys):
- ks = ', '.join(keys)
- reason = _("topology (%(topology)s) must have %(ks)s")
- raise exception.InvalidCPUInfo(reason=reason % locals())
- for key in keys:
- topology[key] = topology_node.get(key)
-
- feature_nodes = xml.findall('.//host/cpu/feature')
- features = list()
- for nodes in feature_nodes:
- features.append(nodes.get('name'))
-
- arch_nodes = xml.findall('.//guest/arch')
- guest_cpu_arches = list(node.get('name') for node in arch_nodes)
-
+ topology['sockets'] = caps.host.cpu.sockets
+ topology['cores'] = caps.host.cpu.cores
+ topology['threads'] = caps.host.cpu.threads
cpu_info['topology'] = topology
+
+ features = list()
+ for f in caps.host.cpu.features:
+ features.append(f.name)
cpu_info['features'] = features
- cpu_info['permitted_instance_types'] = guest_cpu_arches
+
+ guest_arches = list()
+ for g in caps.guests:
+ guest_arches.append(g.arch)
+ cpu_info['permitted_instance_types'] = guest_arches
+
+ # TODO(berrange): why do we bother converting the
+ # libvirt capabilities XML into a special JSON format ?
+ # The data format is different across all the drivers
+ # so we could just return the raw capabilties XML
+ # which 'compare_cpu' could use directly
+ #
+ # That said, arch_filter.py now seems to rely on
+ # the libvirt drivers format which suggests this
+ # data format needs to be standardized across drivers
return jsonutils.dumps(cpu_info)
def block_stats(self, instance_name, disk):