diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-06-28 17:47:33 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-06-28 17:47:33 +0000 |
| commit | 49504a349ee7ce7e0956b7aed208442284bd0ef1 (patch) | |
| tree | 35581e09b294e3207bded3eefe12eabf592e181a | |
| parent | 12287031c0e1d493211074eebc78fb2d2506b72e (diff) | |
| parent | b4abb92b815988a4700313274ac7182f374a2286 (diff) | |
| download | nova-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.py | 45 | ||||
| -rw-r--r-- | nova/virt/libvirt/driver.py | 76 |
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): |
