Add `hide_hypervisor_id` flavor extra_spec

Blueprint add-kvm-hidden-feature added the capability of hiding the kvm
signature from guests. However, it was implemented only through an image
property.

A major reason for this feature is to allow passed-through Nvidia GPUs
to work correctly. GPU pci-passthrough is specified on the flavor's
extra_specs, without requiring an image with special properties.
Therefore, hiding the KVM signature should also be specifiable through
the flavor's extra_specs, in order to not require a special image for
this use case.

If the new flavor extra_spec is present and set to 'true', the libvirt
driver will produce an additional element to hide kvm's signature on
the vm, in the same way as with the image property
`img_hide_hypervisor_id`.

Implements: blueprint hide-hypervisor-id-flavor-extra-spec
Closes-Bug: 1757424
Change-Id: I41c5913b4148629b448ea5fb43b7597dc067dc22
This commit is contained in:
Konstantinos Samaras-Tsakiris 2018-03-22 14:45:25 +01:00 committed by Eric Fried
parent f80b4e5009
commit edf67cfda2
4 changed files with 165 additions and 3 deletions

View File

@ -600,6 +600,28 @@ PCI passthrough
- COUNT: (integer) The amount of PCI devices of type ALIAS to be assigned to
a guest.
Hiding hypervisor signature
Some hypervisors add a signature to their guests. While the presence
of the signature can enable some paravirtualization features on the
guest, it can also have the effect of preventing some drivers from
loading. Hiding the signature by setting this property to true may
allow such drivers to load and work.
.. note::
As of the 18.0.0 Rocky release, this is only supported by the libvirt
driver.
.. code:: console
$ openstack flavor set FLAVOR-NAME \
--property hide_hypervisor_id=VALUE
Where:
- VALUE: (string) 'true' or 'false'. 'false' is equivalent to the
property not existing.
Secure Boot
When your Compute services use the Hyper-V hypervisor, you can enable secure
boot for Windows and Linux instances.

View File

@ -78,6 +78,7 @@ from nova import rc_fields
from nova import test
from nova.tests.unit import fake_block_device
from nova.tests.unit import fake_diagnostics
from nova.tests.unit import fake_flavor
from nova.tests.unit import fake_instance
from nova.tests.unit import fake_network
import nova.tests.unit.image.fake
@ -5270,6 +5271,108 @@ class LibvirtConnTestCase(test.NoDBTestCase,
any(isinstance(feature, vconfig.LibvirtConfigGuestFeatureKvmHidden)
for feature in cfg.features))
def test_get_guest_config_with_hiding_hypervisor_id_flavor_extra_specs(
self):
# Input to the test: flavor extra_specs
flavor_hide_id = fake_flavor.fake_flavor_obj(self.context,
extra_specs={"hide_hypervisor_id": "true"},
expected_attrs={"extra_specs"})
self.flags(virt_type='kvm', group='libvirt')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
instance_ref = objects.Instance(**self.test_instance)
instance_ref.flavor = flavor_hide_id
image_meta = objects.ImageMeta.from_dict({
"disk_format": "raw"})
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
instance_ref,
image_meta)
cfg = drvr._get_guest_config(instance_ref,
[],
image_meta,
disk_info)
self.assertTrue(
any(isinstance(feature, vconfig.LibvirtConfigGuestFeatureKvmHidden)
for feature in cfg.features))
def test_get_guest_config_with_hiding_hypervisor_id_img_and_flavor(
self):
# Input to the test: image metadata (true) and flavor
# extra_specs (true)
flavor_hide_id = fake_flavor.fake_flavor_obj(self.context,
extra_specs={"hide_hypervisor_id": "true"},
expected_attrs={"extra_specs"})
image_meta = objects.ImageMeta.from_dict({
"disk_format": "raw",
"properties": {"img_hide_hypervisor_id": "true"}})
self.flags(virt_type='kvm', group='libvirt')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
instance_ref = objects.Instance(**self.test_instance)
instance_ref.flavor = flavor_hide_id
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
instance_ref,
image_meta)
cfg = drvr._get_guest_config(instance_ref,
[],
image_meta,
disk_info)
self.assertTrue(
any(isinstance(feature, vconfig.LibvirtConfigGuestFeatureKvmHidden)
for feature in cfg.features))
def test_get_guest_config_with_hiding_hypervisor_id_img_or_flavor(
self):
# Input to the test: image metadata (false) and flavor
# extra_specs (true)
flavor_hide_id = fake_flavor.fake_flavor_obj(self.context,
extra_specs={"hide_hypervisor_id": "true"},
expected_attrs={"extra_specs"})
image_meta = objects.ImageMeta.from_dict({
"disk_format": "raw",
"properties": {"img_hide_hypervisor_id": "false"}})
self.flags(virt_type='kvm', group='libvirt')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
instance_ref = objects.Instance(**self.test_instance)
instance_ref.flavor = flavor_hide_id
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
instance_ref,
image_meta)
cfg = drvr._get_guest_config(instance_ref,
[],
image_meta,
disk_info)
self.assertTrue(
any(isinstance(feature, vconfig.LibvirtConfigGuestFeatureKvmHidden)
for feature in cfg.features))
# Input to the test: image metadata (true) and flavor
# extra_specs (false)
flavor_hide_id = fake_flavor.fake_flavor_obj(self.context,
extra_specs={"hide_hypervisor_id": "false"},
expected_attrs={"extra_specs"})
image_meta = objects.ImageMeta.from_dict({
"disk_format": "raw",
"properties": {"img_hide_hypervisor_id": "true"}})
instance_ref.flavor = flavor_hide_id
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
instance_ref,
image_meta)
cfg = drvr._get_guest_config(instance_ref,
[],
image_meta,
disk_info)
self.assertTrue(
any(isinstance(feature, vconfig.LibvirtConfigGuestFeatureKvmHidden)
for feature in cfg.features))
def test_get_guest_config_without_hiding_hypervisor_id(self):
self.flags(virt_type='kvm', group='libvirt')
@ -5294,6 +5397,30 @@ class LibvirtConnTestCase(test.NoDBTestCase,
any(isinstance(feature, vconfig.LibvirtConfigGuestFeatureKvmHidden)
for feature in cfg.features))
def test_get_guest_config_without_hiding_hypervisor_id_flavor_extra_specs(
self):
flavor_hide_id = fake_flavor.fake_flavor_obj(self.context,
extra_specs={"hide_hypervisor_id": "false"},
expected_attrs={"extra_specs"})
self.flags(virt_type='qemu', group='libvirt')
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
instance_ref = objects.Instance(**self.test_instance)
instance_ref.flavor = flavor_hide_id
image_meta = objects.ImageMeta.from_dict({
"disk_format": "raw"})
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
instance_ref,
image_meta)
cfg = drvr._get_guest_config(instance_ref,
[],
image_meta,
disk_info)
self.assertFalse(
any(isinstance(feature, vconfig.LibvirtConfigGuestFeatureKvmHidden)
for feature in cfg.features))
def _test_get_guest_config_disk_cachemodes(self, images_type):
# Verify that the configured cachemodes are propagated to the device
# configurations.

View File

@ -4584,7 +4584,8 @@ class LibvirtDriver(driver.ComputeDriver):
tmhyperv.present = True
clk.add_timer(tmhyperv)
def _set_features(self, guest, os_type, caps, virt_type, image_meta):
def _set_features(self, guest, os_type, caps, virt_type, image_meta,
flavor):
if virt_type == "xen":
# PAE only makes sense in X86
if caps.host.cpu.arch in (fields.Architecture.I686,
@ -4609,8 +4610,11 @@ class LibvirtDriver(driver.ComputeDriver):
hv.vapic = 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')):
(image_meta.properties.get('img_hide_hypervisor_id') or
flavor_hide_kvm)):
guest.features.append(vconfig.LibvirtConfigGuestFeatureKvmHidden())
def _check_number_of_serial_console(self, num_ports):
@ -5171,7 +5175,7 @@ class LibvirtDriver(driver.ComputeDriver):
instance, inst_path, image_meta, disk_info)
self._set_features(guest, instance.os_type, caps, virt_type,
image_meta)
image_meta, flavor)
self._set_clock(guest, instance.os_type, image_meta, virt_type)
storage_configs = self._get_guest_storage_config(context,

View File

@ -0,0 +1,9 @@
---
features:
- |
Added a new flavor extra_spec, ``hide_hypervisor_id``, which hides
the hypervisor signature for the guest when true ('kvm' won't appear
in ``lscpu``). This acts exactly like and in parallel to the image
property ``img_hide_hypervisor_id`` and is useful for running the
nvidia drivers in the guest.
Currently, this is only supported in the libvirt driver.