summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-06-28 19:37:53 +0000
committerGerrit Code Review <review@openstack.org>2012-06-28 19:37:53 +0000
commit2264c1c0b6ccfe7dc3e4c7e448b4a5eac92758d4 (patch)
treea8338a469933c943a6cf19d197bf76941d812ce6
parent92dff6857d8359723a6f68fd311e5c10c277677f (diff)
parent4f4ffc91a8fc28b273660837593d925aa6892efb (diff)
Merge "Allow specification of the libvirt guest CPU model per host"
-rw-r--r--nova/tests/test_libvirt.py70
-rw-r--r--nova/virt/libvirt/driver.py44
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)