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:
parent
f80b4e5009
commit
edf67cfda2
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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.
|
Loading…
Reference in New Issue
Block a user