diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-06-28 19:37:53 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-06-28 19:37:53 +0000 |
| commit | 2264c1c0b6ccfe7dc3e4c7e448b4a5eac92758d4 (patch) | |
| tree | a8338a469933c943a6cf19d197bf76941d812ce6 | |
| parent | 92dff6857d8359723a6f68fd311e5c10c277677f (diff) | |
| parent | 4f4ffc91a8fc28b273660837593d925aa6892efb (diff) | |
Merge "Allow specification of the libvirt guest CPU model per host"
| -rw-r--r-- | nova/tests/test_libvirt.py | 70 | ||||
| -rw-r--r-- | nova/virt/libvirt/driver.py | 44 |
2 files changed, 114 insertions, 0 deletions
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index 3bb377e26..55e8286ad 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -614,6 +614,76 @@ class LibvirtConnTestCase(test.TestCase): config.LibvirtConfigGuestDisk) self.assertEquals(cfg.devices[3].target_dev, 'vdd') + def test_get_guest_cpu_config_none(self): + conn = libvirt_driver.LibvirtDriver(True) + instance_ref = db.instance_create(self.context, self.test_instance) + + conf = conn.get_guest_config(instance_ref, + _fake_network_info(self.stubs, 1), + None, None) + self.assertEquals(conf.cpu, None) + + @test.skip_if(missing_libvirt(), "Test requires libvirt") + def test_get_guest_cpu_config_host_passthrough_new(self): + def get_lib_version_stub(self): + return (0 * 1000 * 1000) + (9 * 1000) + 11 + + self.stubs.Set(libvirt.virConnect, + "getLibVersion", + get_lib_version_stub) + conn = libvirt_driver.LibvirtDriver(True) + instance_ref = db.instance_create(self.context, self.test_instance) + + self.flags(libvirt_cpu_mode="host-passthrough") + conf = conn.get_guest_config(instance_ref, + _fake_network_info(self.stubs, 1), + None, None) + self.assertEquals(type(conf.cpu), + config.LibvirtConfigGuestCPU) + self.assertEquals(conf.cpu.mode, "host-passthrough") + self.assertEquals(conf.cpu.model, None) + + @test.skip_if(missing_libvirt(), "Test requires libvirt") + def test_get_guest_cpu_config_host_model_new(self): + def get_lib_version_stub(self): + return (0 * 1000 * 1000) + (9 * 1000) + 11 + + self.stubs.Set(libvirt.virConnect, + "getLibVersion", + get_lib_version_stub) + conn = libvirt_driver.LibvirtDriver(True) + instance_ref = db.instance_create(self.context, self.test_instance) + + self.flags(libvirt_cpu_mode="host-model") + conf = conn.get_guest_config(instance_ref, + _fake_network_info(self.stubs, 1), + None, None) + self.assertEquals(type(conf.cpu), + config.LibvirtConfigGuestCPU) + self.assertEquals(conf.cpu.mode, "host-model") + self.assertEquals(conf.cpu.model, None) + + @test.skip_if(missing_libvirt(), "Test requires libvirt") + def test_get_guest_cpu_config_custom_new(self): + def get_lib_version_stub(self): + return (0 * 1000 * 1000) + (9 * 1000) + 11 + + self.stubs.Set(libvirt.virConnect, + "getLibVersion", + get_lib_version_stub) + conn = libvirt_driver.LibvirtDriver(True) + instance_ref = db.instance_create(self.context, self.test_instance) + + self.flags(libvirt_cpu_mode="custom") + self.flags(libvirt_cpu_model="Penryn") + conf = conn.get_guest_config(instance_ref, + _fake_network_info(self.stubs, 1), + None, None) + self.assertEquals(type(conf.cpu), + config.LibvirtConfigGuestCPU) + self.assertEquals(conf.cpu.mode, "custom") + self.assertEquals(conf.cpu.model, "Penryn") + def test_xml_and_uri_no_ramdisk_no_kernel(self): instance_data = dict(self.test_instance) self._check_xml_and_uri(instance_data, diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 533597923..96ae61d70 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -165,6 +165,17 @@ libvirt_opts = [ default=None, help='Set to force injection to take place on a config drive ' '(if set, valid options are: always)'), + cfg.StrOpt('libvirt_cpu_mode', + default=None, + help='Set to "host-model" to clone the host CPU feature flags; ' + 'to "host-passthrough" to use the host CPU model ' + 'exactly; or to "custom" to use a named CPU model. Only ' + 'has effect if libvirt_type="kvm|qemu"'), + cfg.StrOpt('libvirt_cpu_model', + default=None, + help='Set to a named libvirt CPU model (see names listed ' + 'in /usr/share/libvirt/cpu_map.xml). Only has effect if ' + 'libvirt_cpu_mode="custom" and libvirt_type="kvm|qemu"'), ] FLAGS = flags.FLAGS @@ -1438,6 +1449,37 @@ class LibvirtDriver(driver.ComputeDriver): caps.parse_str(xmlstr) return caps + def get_guest_cpu_config(self): + mode = FLAGS.libvirt_cpu_mode + model = FLAGS.libvirt_cpu_model + + if mode is None: + return None + + if FLAGS.libvirt_type != "kvm" and FLAGS.libvirt_type != "qemu": + msg = _("Config requested an explicit CPU model, but " + "the current libvirt hypervisor '%s' does not " + "support selecting CPU models") % FLAGS.libvirt_type + raise exception.Invalid(msg) + + if mode == "custom" and model is None: + msg = _("Config requested a custom CPU model, but no " + "model name was provided") + raise exception.Invalid(msg) + elif mode != "custom" and model is not None: + msg = _("A CPU model name should not be set when a " + "host CPU model is requested") + raise exception.Invalid(msg) + + LOG.debug(_("CPU mode '%(mode)s' model '%(model)s' was chosen") + % {'mode': mode, 'model': (model or "")}) + + cpu = config.LibvirtConfigGuestCPU() + cpu.mode = mode + cpu.model = model + + return cpu + def get_guest_config(self, instance, network_info, image_meta, rescue=None, block_device_info=None): """Get config data for parameters. @@ -1462,6 +1504,8 @@ class LibvirtDriver(driver.ComputeDriver): guest.memory = inst_type['memory_mb'] * 1024 guest.vcpus = inst_type['vcpus'] + guest.cpu = self.get_guest_cpu_config() + root_device_name = driver.block_device_info_get_root(block_device_info) if root_device_name: root_device = block_device.strip_dev(root_device_name) |
