Add img_hide_hypervisor_id
image property
Image hide_hypervisor_id property helps libvirt set an xml instance file property, which will hide on guest host KVM hypervisor signature ("KVMKVMKVM\0\0\0"). According to the commit message in QEMU repository [1]: "The latest Nvidia driver (337.88) specifically checks for KVM as the hypervisor and reports Code 43 for the driver in a Windows guest when found. Removing or changing the KVM signature is sufficient for the driver to load and work." DocImpact: New feature ``img_hide_hypervisor_id`` image property should be added in the glance-property-keys page of the cli-reference docs [2]. [1]: http://git.qemu.org/?p=qemu.git;a=commitdiff;h=f522d2a [2]: https://docs.openstack.org/cli-reference/glance-property-keys.html Implements: blueprint add-kvm-hidden-feature Co-Authored-By: Adam Kijak <adam.kijak@corp.ovh.com> Change-Id: Ie8227fececa40e502aaa39d77de2a1cd0cd72682
This commit is contained in:
parent
3d09b67205
commit
c7c08e590e
@ -167,12 +167,15 @@ class ImageMetaProps(base.NovaObject):
|
||||
# Version 1.16: WatchdogActionField supports 'disabled' enum.
|
||||
# Version 1.17: Add lan9118 as valid nic for hw_vif_model property for qemu
|
||||
# Version 1.18: Pull signature properties from cursive library
|
||||
VERSION = '1.18'
|
||||
# Version 1.19: Added 'img_hide_hypervisor_id' type field
|
||||
VERSION = '1.19'
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
super(ImageMetaProps, self).obj_make_compatible(primitive,
|
||||
target_version)
|
||||
target_version = versionutils.convert_version_to_tuple(target_version)
|
||||
if target_version < (1, 19):
|
||||
primitive.pop('img_hide_hypervisor_id', None)
|
||||
if target_version < (1, 16) and 'hw_watchdog_action' in primitive:
|
||||
# Check to see if hw_watchdog_action was set to 'disabled' and if
|
||||
# so, remove it since not specifying it is the same behavior.
|
||||
@ -415,6 +418,9 @@ class ImageMetaProps(base.NovaObject):
|
||||
# string indicating type of key used to compute image signature
|
||||
'img_signature_key_type': fields.ImageSignatureKeyTypeField(),
|
||||
|
||||
# boolean - hide hypervisor signature on instance
|
||||
'img_hide_hypervisor_id': fields.FlexibleBooleanField(),
|
||||
|
||||
# string of username with admin privileges
|
||||
'os_admin_user': fields.StringField(),
|
||||
|
||||
|
@ -323,3 +323,10 @@ class TestImageMetaProps(test.NoDBTestCase):
|
||||
props = {'os_secure_boot': "required"}
|
||||
secure_props = objects.ImageMetaProps.from_dict(props)
|
||||
self.assertEqual("required", secure_props.os_secure_boot)
|
||||
|
||||
def test_obj_make_compatible_img_hide_hypervisor_id(self):
|
||||
"""Tests that checks if we pop img_hide_hypervisor_id."""
|
||||
obj = objects.ImageMetaProps(img_hide_hypervisor_id=True)
|
||||
primitive = obj.obj_to_primitive('1.0')
|
||||
self.assertNotIn('img_hide_hypervisor_id',
|
||||
primitive['nova_object.data'])
|
||||
|
@ -1096,7 +1096,7 @@ object_data = {
|
||||
'HVSpec': '1.2-de06bcec472a2f04966b855a49c46b41',
|
||||
'IDEDeviceBus': '1.0-29d4c9f27ac44197f01b6ac1b7e16502',
|
||||
'ImageMeta': '1.8-642d1b2eb3e880a367f37d72dd76162d',
|
||||
'ImageMetaProps': '1.18-3e5975251f5843e817de68ac83274c27',
|
||||
'ImageMetaProps': '1.19-dc9581ff2b80d8c33462889916b82df0',
|
||||
'Instance': '2.3-4f98ab23f4b0a25fabb1040c8f5edecc',
|
||||
'InstanceAction': '1.1-f9f293e526b66fca0d05c3b3a2d13914',
|
||||
'InstanceActionEvent': '1.1-e56a64fa4710e43ef7af2ad9d6028b33',
|
||||
|
@ -2100,6 +2100,7 @@ class LibvirtConfigGuestTest(LibvirtConfigBaseTest):
|
||||
config.LibvirtConfigGuestFeatureACPI(),
|
||||
config.LibvirtConfigGuestFeatureAPIC(),
|
||||
config.LibvirtConfigGuestFeaturePAE(),
|
||||
config.LibvirtConfigGuestFeatureKvmHidden()
|
||||
]
|
||||
|
||||
obj.sysinfo = config.LibvirtConfigGuestSysinfo()
|
||||
@ -2158,6 +2159,9 @@ class LibvirtConfigGuestTest(LibvirtConfigBaseTest):
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
<kvm>
|
||||
<hidden state='on'/>
|
||||
</kvm>
|
||||
</features>
|
||||
<cputune>
|
||||
<shares>100</shares>
|
||||
|
@ -4916,6 +4916,54 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
||||
self.assertEqual(10000, cfg.cputune.shares)
|
||||
self.assertEqual(20000, cfg.cputune.period)
|
||||
|
||||
def test_get_guest_config_with_hiding_hypervisor_id(self):
|
||||
self.flags(virt_type='kvm', group='libvirt')
|
||||
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
|
||||
image_meta = objects.ImageMeta.from_dict({
|
||||
"disk_format": "raw",
|
||||
"properties": {"img_hide_hypervisor_id": "true"}})
|
||||
|
||||
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')
|
||||
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
|
||||
image_meta = objects.ImageMeta.from_dict({
|
||||
"disk_format": "raw",
|
||||
"properties": {"img_hide_hypervisor_id": "false"}})
|
||||
|
||||
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))
|
||||
|
||||
@mock.patch.object(
|
||||
host.Host, "is_cpu_control_policy_capable", return_value=True)
|
||||
def test_get_guest_config_with_bogus_cpu_quota(self, is_able):
|
||||
|
@ -2000,6 +2000,20 @@ class LibvirtConfigGuestFeaturePAE(LibvirtConfigGuestFeature):
|
||||
**kwargs)
|
||||
|
||||
|
||||
class LibvirtConfigGuestFeatureKvmHidden(LibvirtConfigGuestFeature):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(LibvirtConfigGuestFeatureKvmHidden, self).__init__("kvm",
|
||||
**kwargs)
|
||||
|
||||
def format_dom(self):
|
||||
root = super(LibvirtConfigGuestFeatureKvmHidden, self).format_dom()
|
||||
|
||||
root.append(etree.Element("hidden", state="on"))
|
||||
|
||||
return root
|
||||
|
||||
|
||||
class LibvirtConfigGuestFeatureHyperV(LibvirtConfigGuestFeature):
|
||||
|
||||
# QEMU requires at least this value to be set
|
||||
|
@ -4156,7 +4156,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
tmhyperv.present = True
|
||||
clk.add_timer(tmhyperv)
|
||||
|
||||
def _set_features(self, guest, os_type, caps, virt_type):
|
||||
def _set_features(self, guest, os_type, caps, virt_type, image_meta):
|
||||
if virt_type == "xen":
|
||||
# PAE only makes sense in X86
|
||||
if caps.host.cpu.arch in (fields.Architecture.I686,
|
||||
@ -4181,6 +4181,10 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
hv.vapic = True
|
||||
guest.features.append(hv)
|
||||
|
||||
if (virt_type in ("qemu", "kvm") and
|
||||
image_meta.properties.get('img_hide_hypervisor_id')):
|
||||
guest.features.append(vconfig.LibvirtConfigGuestFeatureKvmHidden())
|
||||
|
||||
def _check_number_of_serial_console(self, num_ports):
|
||||
virt_type = CONF.libvirt.virt_type
|
||||
if (virt_type in ("kvm", "qemu") and
|
||||
@ -4695,7 +4699,8 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
self._conf_non_lxc_uml(virt_type, guest, root_device_name, rescue,
|
||||
instance, inst_path, image_meta, disk_info)
|
||||
|
||||
self._set_features(guest, instance.os_type, caps, virt_type)
|
||||
self._set_features(guest, instance.os_type, caps, virt_type,
|
||||
image_meta)
|
||||
self._set_clock(guest, instance.os_type, image_meta, virt_type)
|
||||
|
||||
storage_configs = self._get_guest_storage_config(
|
||||
|
32
releasenotes/notes/hide_hypervisor_id-6f93e7552336930d.yaml
Normal file
32
releasenotes/notes/hide_hypervisor_id-6f93e7552336930d.yaml
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Some hypervisors add a signature to their guests, e.g. KVM is adding
|
||||
``KVMKVMKVM\0\0\0``, Xen: ``XenVMMXenVMM``.
|
||||
The existence of a hypervisor signature enables some paravirtualization
|
||||
features on the guest as well as disallowing certain drivers which test
|
||||
for the hypervisor to load e.g. Nvidia driver [1]:
|
||||
"The latest Nvidia driver (337.88) specifically checks
|
||||
for KVM as the hypervisor and reports Code 43 for the
|
||||
driver in a Windows guest when found. Removing or
|
||||
changing the KVM signature is sufficient for the driver
|
||||
to load and work."
|
||||
|
||||
The new ``img_hide_hypervisor_id`` image metadata property hides the
|
||||
hypervisor signature for the guest.
|
||||
|
||||
Currently only the libvirt compute driver can hide hypervisor signature
|
||||
for the guest host.
|
||||
|
||||
To verify if hiding hypervisor id is working on Linux based system::
|
||||
|
||||
$ cpuid | grep -i hypervisor_id
|
||||
|
||||
The result should not be (for KVM hypervisor)::
|
||||
|
||||
$ hypervisor_id = KVMKVMKVM\0\0\0
|
||||
|
||||
You can enable this feature by setting the ``img_hide_hypervisor_id=true``
|
||||
property in a Glance image.
|
||||
|
||||
[1]: http://git.qemu.org/?p=qemu.git;a=commitdiff;h=f522d2a
|
Loading…
Reference in New Issue
Block a user