summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
Diffstat (limited to 'nova')
-rw-r--r--nova/tests/test_libvirt.py73
-rw-r--r--nova/virt/libvirt/driver.py43
2 files changed, 113 insertions, 3 deletions
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py
index 55163b4c4..982d08554 100644
--- a/nova/tests/test_libvirt.py
+++ b/nova/tests/test_libvirt.py
@@ -684,6 +684,79 @@ class LibvirtConnTestCase(test.TestCase):
self.assertEquals(conf.cpu.mode, "custom")
self.assertEquals(conf.cpu.model, "Penryn")
+ @test.skip_if(missing_libvirt(), "Test requires libvirt")
+ def test_get_guest_cpu_config_host_passthrough_old(self):
+ def get_lib_version_stub(self):
+ return (0 * 1000 * 1000) + (9 * 1000) + 7
+
+ 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")
+ self.assertRaises(exception.NovaException,
+ conn.get_guest_config,
+ instance_ref,
+ _fake_network_info(self.stubs, 1),
+ None, None)
+
+ @test.skip_if(missing_libvirt(), "Test requires libvirt")
+ def test_get_guest_cpu_config_host_model_old(self):
+ def get_lib_version_stub(self):
+ return (0 * 1000 * 1000) + (9 * 1000) + 7
+
+ # Ensure we have a predictable host CPU
+ def get_host_capabilities_stub(self):
+ cpu = config.LibvirtConfigGuestCPU()
+ cpu.model = "Opteron_G4"
+ cpu.vendor = "AMD"
+
+ caps = config.LibvirtConfigCaps()
+ caps.host = config.LibvirtConfigCapsHost()
+ caps.host.cpu = cpu
+ return caps
+
+ self.stubs.Set(libvirt.virConnect,
+ "getLibVersion",
+ get_lib_version_stub)
+ self.stubs.Set(libvirt_driver.LibvirtDriver,
+ "get_host_capabilities",
+ get_host_capabilities_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, None)
+ self.assertEquals(conf.cpu.model, "Opteron_G4")
+ self.assertEquals(conf.cpu.vendor, "AMD")
+
+ @test.skip_if(missing_libvirt(), "Test requires libvirt")
+ def test_get_guest_cpu_config_custom_old(self):
+ def get_lib_version_stub(self):
+ return (0 * 1000 * 1000) + (9 * 1000) + 7
+
+ 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, None)
+ 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 950494d97..f41cdba8a 100644
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -231,6 +231,9 @@ LIBVIRT_POWER_STATE = {
}
MIN_LIBVIRT_VERSION = (0, 9, 6)
+# When the above version matches/exceeds this version
+# delete it & corresponding code using it
+MIN_LIBVIRT_HOST_CPU_VERSION = (0, 9, 10)
def _late_load_cheetah():
@@ -1469,6 +1472,27 @@ class LibvirtDriver(driver.ComputeDriver):
caps.parse_str(xmlstr)
return caps
+ def get_host_cpu_for_guest(self):
+ """Returns an instance of config.LibvirtConfigGuestCPU
+ representing the host's CPU model & topology with
+ policy for configuring a guest to match"""
+
+ caps = self.get_host_capabilities()
+ hostcpu = caps.host.cpu
+ guestcpu = config.LibvirtConfigGuestCPU()
+
+ guestcpu.model = hostcpu.model
+ guestcpu.vendor = hostcpu.vendor
+ guestcpu.arch = hostcpu.arch
+
+ guestcpu.match = "exact"
+
+ for hostfeat in hostcpu.features:
+ guestfeat = config.LibvirtConfigGuestCPUFeature(hostfeat.name)
+ guestfeat.policy = "require"
+
+ return guestcpu
+
def get_guest_cpu_config(self):
mode = FLAGS.libvirt_cpu_mode
model = FLAGS.libvirt_cpu_model
@@ -1494,9 +1518,22 @@ class LibvirtDriver(driver.ComputeDriver):
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
+ # TODO(berrange): in the future, when MIN_LIBVIRT_VERSION is
+ # updated to be at least this new, we can kill off the elif
+ # blocks here
+ if self.has_min_version(MIN_LIBVIRT_HOST_CPU_VERSION):
+ cpu = config.LibvirtConfigGuestCPU()
+ cpu.mode = mode
+ cpu.model = model
+ elif mode == "custom":
+ cpu = config.LibvirtConfigGuestCPU()
+ cpu.model = model
+ elif mode == "host-model":
+ cpu = self.get_host_cpu_for_guest()
+ elif mode == "host-passthrough":
+ msg = _("Passthrough of the host CPU was requested but "
+ "this libvirt version does not support this feature")
+ raise exception.NovaException(msg)
return cpu