Merge "Hide hypervisor id on windows guests"
This commit is contained in:
commit
6009cdaa47
nova
releasenotes/notes
@ -2182,6 +2182,7 @@ class LibvirtConfigGuestFeatureTest(LibvirtConfigBaseTest):
|
||||
obj.relaxed = True
|
||||
obj.vapic = True
|
||||
obj.spinlocks = True
|
||||
obj.vendorid_spoof = True
|
||||
|
||||
xml = obj.to_xml()
|
||||
self.assertXmlEqual(xml, """
|
||||
@ -2189,6 +2190,7 @@ class LibvirtConfigGuestFeatureTest(LibvirtConfigBaseTest):
|
||||
<relaxed state="on"/>
|
||||
<vapic state="on"/>
|
||||
<spinlocks state="on" retries="4095"/>
|
||||
<vendor_id state="on" value="1234567890ab"/>
|
||||
</hyperv>""")
|
||||
|
||||
|
||||
|
@ -3812,13 +3812,17 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
self.assertIsInstance(cfg.features[2],
|
||||
vconfig.LibvirtConfigGuestFeatureHyperV)
|
||||
|
||||
@mock.patch.object(host.Host, 'has_min_version')
|
||||
def test_get_guest_config_windows_hyperv_feature2(self, mock_version):
|
||||
mock_version.return_value = True
|
||||
@mock.patch.object(host.Host, 'has_min_version',
|
||||
new=mock.Mock(return_value=True))
|
||||
def _test_get_guest_config_windows_hyperv(
|
||||
self, flavor=None, image_meta=None, hvid_hidden=False):
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
instance_ref['os_type'] = 'windows'
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
if flavor is not None:
|
||||
instance_ref.flavor = flavor
|
||||
if image_meta is None:
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
|
||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||
instance_ref,
|
||||
@ -3831,18 +3835,67 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
vconfig.LibvirtConfigGuestClock)
|
||||
self.assertEqual(cfg.clock.offset, "localtime")
|
||||
|
||||
self.assertEqual(3, len(cfg.features))
|
||||
num_features = 4 if hvid_hidden else 3
|
||||
self.assertEqual(num_features, len(cfg.features))
|
||||
self.assertIsInstance(cfg.features[0],
|
||||
vconfig.LibvirtConfigGuestFeatureACPI)
|
||||
self.assertIsInstance(cfg.features[1],
|
||||
vconfig.LibvirtConfigGuestFeatureAPIC)
|
||||
self.assertIsInstance(cfg.features[2],
|
||||
vconfig.LibvirtConfigGuestFeatureHyperV)
|
||||
if hvid_hidden:
|
||||
self.assertIsInstance(cfg.features[3],
|
||||
vconfig.LibvirtConfigGuestFeatureKvmHidden)
|
||||
|
||||
self.assertTrue(cfg.features[2].relaxed)
|
||||
self.assertTrue(cfg.features[2].spinlocks)
|
||||
self.assertEqual(8191, cfg.features[2].spinlock_retries)
|
||||
self.assertTrue(cfg.features[2].vapic)
|
||||
self.assertEqual(hvid_hidden, cfg.features[2].vendorid_spoof)
|
||||
|
||||
def test_get_guest_config_windows_hyperv_feature2(self):
|
||||
self._test_get_guest_config_windows_hyperv()
|
||||
|
||||
def test_get_guest_config_windows_hyperv_all_hide_flv(self):
|
||||
# Similar to test_get_guest_config_windows_hyperv_feature2
|
||||
# but also test hiding the HyperV signature with the flavor
|
||||
# extra_spec "hide_hypervisor_id"
|
||||
flavor_hide_id = fake_flavor.fake_flavor_obj(self.context,
|
||||
extra_specs={"hide_hypervisor_id": "true"},
|
||||
expected_attrs={"extra_specs"})
|
||||
# this works for kvm (the default, tested below) and qemu
|
||||
self.flags(virt_type='qemu', group='libvirt')
|
||||
|
||||
self._test_get_guest_config_windows_hyperv(
|
||||
flavor=flavor_hide_id, hvid_hidden=True)
|
||||
|
||||
def test_get_guest_config_windows_hyperv_all_hide_img(self):
|
||||
# Similar to test_get_guest_config_windows_hyperv_feature2
|
||||
# but also test hiding the HyperV signature with the image
|
||||
# property "img_hide_hypervisor_id"
|
||||
image_meta = objects.ImageMeta.from_dict({
|
||||
"disk_format": "raw",
|
||||
"properties": {"img_hide_hypervisor_id": "true"}})
|
||||
|
||||
self._test_get_guest_config_windows_hyperv(
|
||||
image_meta=image_meta, hvid_hidden=True)
|
||||
|
||||
def test_get_guest_config_windows_hyperv_all_hide_flv_img(self):
|
||||
# Similar to test_get_guest_config_windows_hyperv_feature2
|
||||
# but also test hiding the HyperV signature with both the flavor
|
||||
# extra_spec "hide_hypervisor_id" and the image property
|
||||
# "img_hide_hypervisor_id"
|
||||
flavor_hide_id = fake_flavor.fake_flavor_obj(self.context,
|
||||
extra_specs={"hide_hypervisor_id": "true"},
|
||||
expected_attrs={"extra_specs"})
|
||||
self.flags(virt_type='qemu', group='libvirt')
|
||||
|
||||
image_meta = objects.ImageMeta.from_dict({
|
||||
"disk_format": "raw",
|
||||
"properties": {"img_hide_hypervisor_id": "true"}})
|
||||
|
||||
self._test_get_guest_config_windows_hyperv(
|
||||
flavor=flavor_hide_id, image_meta=image_meta, hvid_hidden=True)
|
||||
|
||||
def test_get_guest_config_with_two_nics(self):
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
|
@ -2334,6 +2334,8 @@ class LibvirtConfigGuestFeatureHyperV(LibvirtConfigGuestFeature):
|
||||
|
||||
# QEMU requires at least this value to be set
|
||||
MIN_SPINLOCK_RETRIES = 4095
|
||||
# The spoofed vendor_id can be any alphanumeric string
|
||||
SPOOFED_VENDOR_ID = "1234567890ab"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(LibvirtConfigGuestFeatureHyperV, self).__init__("hyperv",
|
||||
@ -2343,6 +2345,8 @@ class LibvirtConfigGuestFeatureHyperV(LibvirtConfigGuestFeature):
|
||||
self.vapic = False
|
||||
self.spinlocks = False
|
||||
self.spinlock_retries = self.MIN_SPINLOCK_RETRIES
|
||||
self.vendorid_spoof = False
|
||||
self.vendorid = self.SPOOFED_VENDOR_ID
|
||||
|
||||
def format_dom(self):
|
||||
root = super(LibvirtConfigGuestFeatureHyperV, self).format_dom()
|
||||
@ -2354,6 +2358,9 @@ class LibvirtConfigGuestFeatureHyperV(LibvirtConfigGuestFeature):
|
||||
if self.spinlocks:
|
||||
root.append(etree.Element("spinlocks", state="on",
|
||||
retries=str(self.spinlock_retries)))
|
||||
if self.vendorid_spoof:
|
||||
root.append(etree.Element("vendor_id", state="on",
|
||||
value=self.vendorid))
|
||||
|
||||
return root
|
||||
|
||||
|
@ -4760,6 +4760,10 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
|
||||
def _set_features(self, guest, os_type, caps, virt_type, image_meta,
|
||||
flavor):
|
||||
hide_hypervisor_id = (strutils.bool_from_string(
|
||||
flavor.extra_specs.get('hide_hypervisor_id')) or
|
||||
image_meta.properties.get('img_hide_hypervisor_id'))
|
||||
|
||||
if virt_type == "xen":
|
||||
# PAE only makes sense in X86
|
||||
if caps.host.cpu.arch in (fields.Architecture.I686,
|
||||
@ -4782,13 +4786,23 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
# with Microsoft
|
||||
hv.spinlock_retries = 8191
|
||||
hv.vapic = True
|
||||
|
||||
# NOTE(kosamara): Spoofing the vendor_id aims to allow the nvidia
|
||||
# driver to work on windows VMs. At the moment, the nvidia driver
|
||||
# checks for the hyperv vendorid, and if it doesn't find that, it
|
||||
# works. In the future, its behaviour could become more strict,
|
||||
# checking for the presence of other hyperv feature flags to
|
||||
# determine that it's loaded in a VM. If that happens, this
|
||||
# workaround will not be enough, and we'll need to drop the whole
|
||||
# hyperv element.
|
||||
# That would disable some optimizations, reducing the guest's
|
||||
# performance.
|
||||
if hide_hypervisor_id:
|
||||
hv.vendorid_spoof = True
|
||||
|
||||
guest.features.append(hv)
|
||||
|
||||
flavor_hide_kvm = strutils.bool_from_string(
|
||||
flavor.get('extra_specs', {}).get('hide_hypervisor_id'))
|
||||
if (virt_type in ("qemu", "kvm") and
|
||||
(image_meta.properties.get('img_hide_hypervisor_id') or
|
||||
flavor_hide_kvm)):
|
||||
if (virt_type in ("qemu", "kvm") and hide_hypervisor_id):
|
||||
guest.features.append(vconfig.LibvirtConfigGuestFeatureKvmHidden())
|
||||
|
||||
def _check_number_of_serial_console(self, num_ports):
|
||||
|
11
releasenotes/notes/bug-1779845-8819eea6e91fb09c.yaml
Normal file
11
releasenotes/notes/bug-1779845-8819eea6e91fb09c.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Blueprints `hide-hypervisor-id-flavor-extra-spec`_ and
|
||||
`add-kvm-hidden-feature`_ enabled NVIDIA drivers in Linux guests using KVM
|
||||
and QEMU, but support was not included for Windows guests. This is now
|
||||
fixed. See `bug 1779845`_ for details.
|
||||
|
||||
.. _hide-hypervisor-id-flavor-extra-spec: https://blueprints.launchpad.net/nova/+spec/hide-hypervisor-id-flavor-extra-spec
|
||||
.. _add-kvm-hidden-feature: https://blueprints.launchpad.net/nova/+spec/add-kvm-hidden-feature
|
||||
.. _bug 1779845: https://bugs.launchpad.net/nova/+bug/1779845
|
Loading…
x
Reference in New Issue
Block a user