From fc0c6d2f9ab55554299b2adcac2b08991a9683fd Mon Sep 17 00:00:00 2001 From: Radoslav Gerganov Date: Tue, 21 Mar 2017 14:06:55 +0200 Subject: [PATCH] VMware: add support for different firmwares Add support for explicitly requiring UEFI or BIOS firmware from images by taking hw_firmware_type metadata into account. blueprint vmware-boot-uefi Change-Id: Ibfb57c55569e430a846003472a49a536e94e6a48 --- .../tests/unit/virt/vmwareapi/test_vm_util.py | 42 +++++++++++++++++++ nova/virt/vmwareapi/vm_util.py | 6 ++- nova/virt/vmwareapi/vmops.py | 6 +++ .../vmware-boot-uefi-f26ab3b9bdecf24a.yaml | 6 +++ 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/vmware-boot-uefi-f26ab3b9bdecf24a.yaml diff --git a/nova/tests/unit/virt/vmwareapi/test_vm_util.py b/nova/tests/unit/virt/vmwareapi/test_vm_util.py index 377f3559b118..978df51385f3 100644 --- a/nova/tests/unit/virt/vmwareapi/test_vm_util.py +++ b/nova/tests/unit/virt/vmwareapi/test_vm_util.py @@ -874,6 +874,48 @@ class VMwareVMUtilTestCase(test.NoDBTestCase): self.assertEqual(expected, result) + def test_get_vm_create_spec_with_firmware(self): + extra_specs = vm_util.ExtraSpecs(firmware='efi') + fake_factory = fake.FakeFactory() + result = vm_util.get_vm_create_spec(fake_factory, + self._instance, + 'fake-datastore', [], + extra_specs) + expected = fake_factory.create('ns0:VirtualMachineConfigSpec') + expected.name = self._instance.uuid + expected.instanceUuid = self._instance.uuid + expected.deviceChange = [] + expected.numCPUs = 2 + + expected.version = None + expected.memoryMB = 2048 + expected.guestId = 'otherGuest' + expected.firmware = 'efi' + expected.extraConfig = [] + + extra_config = fake_factory.create("ns0:OptionValue") + extra_config.value = self._instance.uuid + extra_config.key = 'nvp.vm-uuid' + expected.extraConfig.append(extra_config) + extra_config = fake_factory.create("ns0:OptionValue") + extra_config.value = True + extra_config.key = 'disk.EnableUUID' + expected.extraConfig.append(extra_config) + expected.files = fake_factory.create('ns0:VirtualMachineFileInfo') + expected.files.vmPathName = '[fake-datastore]' + + expected.managedBy = fake_factory.create('ns0:ManagedByInfo') + expected.managedBy.extensionKey = 'org.openstack.compute' + expected.managedBy.type = 'instance' + + expected.tools = fake_factory.create('ns0:ToolsConfigInfo') + expected.tools.afterPowerOn = True + expected.tools.afterResume = True + expected.tools.beforeGuestReboot = True + expected.tools.beforeGuestShutdown = True + expected.tools.beforeGuestStandby = True + self.assertEqual(expected, result) + def test_create_vm(self): def fake_call_method(module, method, *args, **kwargs): diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index 3c2766347a80..6d8a09048d1c 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -92,7 +92,7 @@ class ExtraSpecs(object): def __init__(self, cpu_limits=None, hw_version=None, storage_policy=None, cores_per_socket=None, memory_limits=None, disk_io_limits=None, - vif_limits=None): + vif_limits=None, firmware=None): """ExtraSpecs object holds extra_specs for the instance.""" self.cpu_limits = cpu_limits or Limits() self.memory_limits = memory_limits or Limits() @@ -101,6 +101,7 @@ class ExtraSpecs(object): self.hw_version = hw_version self.storage_policy = storage_policy self.cores_per_socket = cores_per_socket + self.firmware = firmware def vm_refs_cache_reset(): @@ -243,6 +244,9 @@ def get_vm_create_spec(client_factory, instance, data_store_name, client_factory, extra_specs.memory_limits, 'ns0:ResourceAllocationInfo') + if extra_specs.firmware: + config_spec.firmware = extra_specs.firmware + devices = [] for vif_info in vif_infos: vif_spec = _create_vif_spec(client_factory, vif_info, diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index 3d928cce3c08..df786660c70b 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -46,6 +46,7 @@ from nova import exception from nova.i18n import _ from nova import network from nova import objects +from nova.objects import fields from nova import utils from nova import version from nova.virt import configdrive @@ -317,6 +318,11 @@ class VMwareVMOps(object): extra_specs.memory_limits.validate() extra_specs.disk_io_limits.validate() extra_specs.vif_limits.validate() + hw_firmware_type = image_meta.properties.get('hw_firmware_type') + if hw_firmware_type == fields.FirmwareType.UEFI: + extra_specs.firmware = 'efi' + elif hw_firmware_type == fields.FirmwareType.BIOS: + extra_specs.firmware = 'bios' hw_version = flavor.extra_specs.get('vmware:hw_version') extra_specs.hw_version = hw_version if CONF.vmware.pbm_enabled: diff --git a/releasenotes/notes/vmware-boot-uefi-f26ab3b9bdecf24a.yaml b/releasenotes/notes/vmware-boot-uefi-f26ab3b9bdecf24a.yaml new file mode 100644 index 000000000000..02c1084d8494 --- /dev/null +++ b/releasenotes/notes/vmware-boot-uefi-f26ab3b9bdecf24a.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + The VMware vCenter compute driver now supports booting from images + which specify they require UEFI or BIOS firmware, using the + ``hw_firmware_type`` image metadata.