Merge "libvirt: Use firmware metadata files to configure instance"
This commit is contained in:
commit
7422eb00bf
|
@ -21,6 +21,7 @@ import typing as ty
|
|||
|
||||
import fixtures
|
||||
from lxml import etree
|
||||
import mock
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils.fixture import uuidsentinel as uuids
|
||||
from oslo_utils import versionutils
|
||||
|
@ -1967,13 +1968,60 @@ class FakeLibvirtFixture(fixtures.Fixture):
|
|||
self.useFixture(
|
||||
fixtures.MockPatch('os.uname', return_value=fake_uname))
|
||||
|
||||
# Ensure UEFI checks don't actually check the host
|
||||
def fake_has_uefi_support():
|
||||
return os.uname().machine == obj_fields.Architecture.AARCH64
|
||||
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'nova.virt.libvirt.driver.LibvirtDriver._has_uefi_support',
|
||||
side_effect=fake_has_uefi_support))
|
||||
# ...and on all machine types
|
||||
fake_loaders = [
|
||||
{
|
||||
'description': 'UEFI firmware for x86_64',
|
||||
'interface-types': ['uefi'],
|
||||
'mapping': {
|
||||
'device': 'flash',
|
||||
'executable': {
|
||||
'filename': '/usr/share/OVMF/OVMF_CODE.fd',
|
||||
'format': 'raw',
|
||||
},
|
||||
'nvram-template': {
|
||||
'filename': '/usr/share/OVMF/OVMF_VARS.fd',
|
||||
'format': 'raw',
|
||||
},
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'architecture': 'x86_64',
|
||||
'machines': ['pc-i440fx-*', 'pc-q35-*'],
|
||||
},
|
||||
],
|
||||
'features': ['acpi-s3', 'amd-sev', 'verbose-dynamic'],
|
||||
'tags': [],
|
||||
},
|
||||
{
|
||||
'description': 'UEFI firmware for aarch64',
|
||||
'interface-types': ['uefi'],
|
||||
'mapping': {
|
||||
'device': 'flash',
|
||||
'executable': {
|
||||
'filename': '/usr/share/AAVMF/AAVMF_CODE.fd',
|
||||
'format': 'raw',
|
||||
},
|
||||
'nvram-template': {
|
||||
'filename': '/usr/share/AAVMF/AAVMF_VARS.fd',
|
||||
'format': 'raw',
|
||||
}
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'architecture': 'aarch64',
|
||||
'machines': ['virt-*'],
|
||||
}
|
||||
],
|
||||
'features': ['verbose-static'],
|
||||
"tags": [],
|
||||
}
|
||||
]
|
||||
self.useFixture(
|
||||
fixtures.MockPatch(
|
||||
'nova.virt.libvirt.host.Host.loaders',
|
||||
new_callable=mock.PropertyMock,
|
||||
return_value=fake_loaders))
|
||||
|
||||
disable_event_thread(self)
|
||||
|
||||
|
|
|
@ -2459,7 +2459,6 @@ class LibvirtConfigGuestTest(LibvirtConfigBaseTest):
|
|||
xml = obj.to_xml()
|
||||
|
||||
self.assertXmlEqual(
|
||||
xml,
|
||||
"""
|
||||
<domain type="kvm">
|
||||
<uuid>f01cf68d-515c-4daf-b85f-ef1424d93bfc</uuid>
|
||||
|
@ -2471,6 +2470,7 @@ class LibvirtConfigGuestTest(LibvirtConfigBaseTest):
|
|||
<loader secure='yes' readonly='yes' type='pflash'>/tmp/OVMF_CODE.secboot.fd</loader>
|
||||
</os>
|
||||
</domain>""", # noqa: E501
|
||||
xml,
|
||||
)
|
||||
|
||||
def _test_config_uefi_autoconfigure(self, secure):
|
||||
|
|
|
@ -3208,6 +3208,9 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
domain_caps = vconfig.LibvirtConfigDomainCaps()
|
||||
domain_caps._features = vconfig.LibvirtConfigDomainCapsFeatures()
|
||||
domain_caps._features.features = [sev_feature]
|
||||
domain_caps._os = vconfig.LibvirtConfigDomainCapsOS()
|
||||
domain_caps._os.loader_paths = ['foo']
|
||||
|
||||
fake_domain_caps.return_value = collections.defaultdict(
|
||||
dict, {'x86_64': {'q35': domain_caps}})
|
||||
|
||||
|
@ -3233,10 +3236,9 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
self.assertEqual(47, feature.cbitpos)
|
||||
self.assertEqual(1, feature.reduced_phys_bits)
|
||||
|
||||
@mock.patch.object(libvirt_driver.LibvirtDriver,
|
||||
"_has_uefi_support", new=mock.Mock(return_value=True))
|
||||
def _setup_sev_guest(self, extra_image_properties=None):
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
drvr._host._supports_uefi = True
|
||||
drvr._host._supports_amd_sev = True
|
||||
|
||||
ctxt = context.RequestContext(project_id=123,
|
||||
|
@ -5002,21 +5004,18 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
"properties": {"hw_firmware_type": "uefi"}})
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
|
||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||
instance_ref,
|
||||
image_meta)
|
||||
with mock.patch.object(drvr, "_has_uefi_support",
|
||||
return_value=True) as mock_support:
|
||||
cfg = drvr._get_guest_config(instance_ref, [],
|
||||
image_meta, disk_info)
|
||||
mock_support.assert_called_once_with()
|
||||
self.assertEqual(cfg.os_loader_type, "pflash")
|
||||
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)
|
||||
# these values are derived from the FakeLibvirtFixture
|
||||
self.assertEqual('/usr/share/OVMF/OVMF_CODE.fd', cfg.os_loader)
|
||||
self.assertEqual('/usr/share/OVMF/OVMF_VARS.fd', cfg.os_nvram_template)
|
||||
|
||||
def test_check_uefi_support_aarch64(self):
|
||||
self.mock_uname.return_value = fakelibvirt.os_uname(
|
||||
'Linux', '', '5.4.0-0-generic', '', fields.Architecture.AARCH64)
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
drvr._has_uefi_support = mock.Mock(return_value=True)
|
||||
self.assertTrue(drvr._check_uefi_support(None))
|
||||
|
||||
def test_get_guest_config_with_block_device(self):
|
||||
|
@ -5971,8 +5970,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
self.mock_uname.return_value = fakelibvirt.os_uname(
|
||||
'Linux', '', '5.4.0-0-generic', '', fields.Architecture.S390X)
|
||||
|
||||
self._stub_host_capabilities_cpu_arch(fields.Architecture.S390X)
|
||||
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
|
||||
cfg = self._get_guest_config_via_fake_api(instance_ref)
|
||||
|
@ -5988,19 +5985,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
self.assertEqual("pty", terminal_device.type)
|
||||
self.assertEqual("s390-ccw-virtio", cfg.os_mach_type)
|
||||
|
||||
def _stub_host_capabilities_cpu_arch(self, cpu_arch):
|
||||
def get_host_capabilities_stub(self):
|
||||
cpu = vconfig.LibvirtConfigGuestCPU()
|
||||
cpu.arch = cpu_arch
|
||||
|
||||
caps = vconfig.LibvirtConfigCaps()
|
||||
caps.host = vconfig.LibvirtConfigCapsHost()
|
||||
caps.host.cpu = cpu
|
||||
return caps
|
||||
|
||||
self.stub_out('nova.virt.libvirt.host.Host.get_capabilities',
|
||||
get_host_capabilities_stub)
|
||||
|
||||
def _get_guest_config_via_fake_api(self, instance):
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
|
@ -6386,7 +6370,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
@mock.patch.object(host.Host, 'get_domain_capabilities')
|
||||
@mock.patch.object(designer, 'set_driver_iommu_for_sev')
|
||||
def test_get_guest_config_with_qga_through_image_meta_with_sev(
|
||||
self, mock_designer, fake_domain_caps):
|
||||
self, mock_designer, fake_domain_caps,
|
||||
):
|
||||
self._setup_fake_domain_caps(fake_domain_caps)
|
||||
extra_properties = {"hw_qemu_guest_agent": "yes"}
|
||||
cfg = self._setup_sev_guest(extra_properties)
|
||||
|
@ -7420,9 +7405,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
_fake_network_info(self),
|
||||
image_meta, disk_info)
|
||||
self.assertTrue(mock_path_exists.called)
|
||||
expected = mock.call(libvirt_driver.
|
||||
DEFAULT_UEFI_LOADER_PATH['aarch64'][0])
|
||||
self.assertIn(expected, mock_path_exists.mock_calls)
|
||||
self.assertEqual(cfg.os_mach_type, "virt")
|
||||
|
||||
num_ports = 0
|
||||
|
@ -7453,9 +7435,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
cfg = self._get_guest_config_with_graphics()
|
||||
|
||||
self.assertTrue(mock_path_exists.called)
|
||||
expected = mock.call(libvirt_driver.
|
||||
DEFAULT_UEFI_LOADER_PATH['aarch64'][0])
|
||||
self.assertIn(expected, mock_path_exists.mock_calls)
|
||||
self.assertEqual(cfg.os_mach_type, "virt")
|
||||
|
||||
usbhost_exists = False
|
||||
|
@ -7714,27 +7693,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
image_meta, disk_info)
|
||||
self.assertIsNone(conf.cpu)
|
||||
|
||||
def test_get_guest_cpu_config_host_passthrough(self):
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
|
||||
self.flags(cpu_mode="host-passthrough", group='libvirt')
|
||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||
instance_ref,
|
||||
image_meta)
|
||||
conf = drvr._get_guest_config(instance_ref,
|
||||
_fake_network_info(self),
|
||||
image_meta, disk_info)
|
||||
self.assertIsInstance(conf.cpu,
|
||||
vconfig.LibvirtConfigGuestCPU)
|
||||
self.assertEqual(conf.cpu.mode, "host-passthrough")
|
||||
self.assertIsNone(conf.cpu.model)
|
||||
self.assertEqual(conf.cpu.sockets, instance_ref.flavor.vcpus)
|
||||
self.assertEqual(conf.cpu.cores, 1)
|
||||
self.assertEqual(conf.cpu.threads, 1)
|
||||
|
||||
def test_get_guest_cpu_config_host_passthrough_aarch64(self):
|
||||
def test_get_guest_cpu_config_automatic(self):
|
||||
expected = {
|
||||
fields.Architecture.X86_64: "host-model",
|
||||
fields.Architecture.I686: "host-model",
|
||||
|
@ -7758,34 +7717,32 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
self.assertIsInstance(conf.cpu, vconfig.LibvirtConfigGuestCPU)
|
||||
self.assertEqual(conf.cpu.mode, expect_mode)
|
||||
|
||||
def test_get_guest_cpu_config_host_model(self):
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
def test_get_guest_cpu_config_manual(self):
|
||||
for mode in ('host-passthrough', 'host-model'):
|
||||
self.flags(cpu_mode=mode, group='libvirt')
|
||||
|
||||
self.flags(cpu_mode="host-model", group='libvirt')
|
||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||
instance_ref,
|
||||
image_meta)
|
||||
conf = drvr._get_guest_config(instance_ref,
|
||||
_fake_network_info(self),
|
||||
image_meta, disk_info)
|
||||
self.assertIsInstance(conf.cpu,
|
||||
vconfig.LibvirtConfigGuestCPU)
|
||||
self.assertEqual(conf.cpu.mode, "host-model")
|
||||
self.assertIsNone(conf.cpu.model)
|
||||
self.assertEqual(conf.cpu.sockets, instance_ref.flavor.vcpus)
|
||||
self.assertEqual(conf.cpu.cores, 1)
|
||||
self.assertEqual(conf.cpu.threads, 1)
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
|
||||
disk_info = blockinfo.get_disk_info(
|
||||
CONF.libvirt.virt_type, instance_ref, image_meta)
|
||||
conf = drvr._get_guest_config(
|
||||
instance_ref, _fake_network_info(self), image_meta, disk_info)
|
||||
self.assertIsInstance(conf.cpu, vconfig.LibvirtConfigGuestCPU)
|
||||
self.assertEqual(conf.cpu.mode, mode)
|
||||
self.assertIsNone(conf.cpu.model)
|
||||
self.assertEqual(conf.cpu.sockets, instance_ref.flavor.vcpus)
|
||||
self.assertEqual(conf.cpu.cores, 1)
|
||||
self.assertEqual(conf.cpu.threads, 1)
|
||||
|
||||
def test_get_guest_cpu_config_custom(self):
|
||||
self.flags(cpu_mode="custom", cpu_models=["Penryn"], group='libvirt')
|
||||
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
|
||||
self.flags(cpu_mode="custom",
|
||||
cpu_models=["Penryn"],
|
||||
group='libvirt')
|
||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||
instance_ref,
|
||||
image_meta)
|
||||
|
@ -16298,7 +16255,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
drvr._host._get_domain = mock.Mock(return_value=mock_domain)
|
||||
drvr._has_uefi_support = mock.Mock(return_value=False)
|
||||
drvr.delete_instance_files = mock.Mock(return_value=None)
|
||||
drvr.get_info = mock.Mock(return_value=
|
||||
hardware.InstanceInfo(state=power_state.SHUTDOWN, internal_id=-1)
|
||||
|
@ -16321,7 +16277,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
drvr._host._get_domain = mock.Mock(return_value=mock_domain)
|
||||
drvr._has_uefi_support = mock.Mock(return_value=False)
|
||||
drvr.delete_instance_files = mock.Mock(return_value=None)
|
||||
drvr.get_info = mock.Mock(return_value=
|
||||
hardware.InstanceInfo(state=power_state.SHUTDOWN, internal_id=-1)
|
||||
|
@ -16347,7 +16302,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
drvr._host._get_domain = mock.Mock(return_value=mock_domain)
|
||||
drvr._has_uefi_support = mock.Mock(return_value=False)
|
||||
drvr.delete_instance_files = mock.Mock(return_value=None)
|
||||
drvr.get_info = mock.Mock(return_value=
|
||||
hardware.InstanceInfo(state=power_state.SHUTDOWN, internal_id=-1)
|
||||
|
@ -16373,7 +16327,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
drvr._host._get_domain = mock.Mock(return_value=mock_domain)
|
||||
drvr._has_uefi_support = mock.Mock(return_value=True)
|
||||
drvr.delete_instance_files = mock.Mock(return_value=None)
|
||||
drvr.get_info = mock.Mock(return_value=hardware.InstanceInfo(
|
||||
state=power_state.SHUTDOWN, internal_id=-1))
|
||||
|
@ -16402,7 +16355,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
drvr._host._get_domain = mock.Mock(return_value=mock_domain)
|
||||
drvr._has_uefi_support = mock.Mock(return_value=True)
|
||||
drvr.delete_instance_files = mock.Mock(return_value=None)
|
||||
drvr.get_info = mock.Mock(return_value=hardware.InstanceInfo(
|
||||
state=power_state.SHUTDOWN, internal_id=-1))
|
||||
|
|
|
@ -84,6 +84,9 @@ class LibvirtConfigObject(object):
|
|||
pretty_print=pretty_print)
|
||||
return xml_str
|
||||
|
||||
def __repr__(self):
|
||||
return self.to_xml(pretty_print=False)
|
||||
|
||||
|
||||
class LibvirtConfigCaps(LibvirtConfigObject):
|
||||
|
||||
|
@ -2784,6 +2787,8 @@ class LibvirtConfigGuest(LibvirtConfigObject):
|
|||
self.os_firmware = None
|
||||
self.os_loader_type = None
|
||||
self.os_loader_secure = None
|
||||
self.os_nvram = None
|
||||
self.os_nvram_template = None
|
||||
self.os_kernel = None
|
||||
self.os_initrd = None
|
||||
self.os_cmdline = None
|
||||
|
@ -2841,20 +2846,28 @@ class LibvirtConfigGuest(LibvirtConfigObject):
|
|||
if self.os_kernel is not None:
|
||||
os.append(self._text_node("kernel", self.os_kernel))
|
||||
|
||||
# Generate XML nodes for UEFI boot.
|
||||
if (
|
||||
self.os_loader is not None or
|
||||
self.os_loader_type is not None or
|
||||
self.os_loader_secure is not None
|
||||
):
|
||||
loader = self._text_node("loader", self.os_loader)
|
||||
if self.os_loader_type is not None:
|
||||
loader.set("type", "pflash")
|
||||
loader.set("type", self.os_loader_type)
|
||||
loader.set("readonly", "yes")
|
||||
if self.os_loader_secure is not None:
|
||||
loader.set(
|
||||
"secure", self.get_yes_no_str(self.os_loader_secure))
|
||||
os.append(loader)
|
||||
|
||||
if (
|
||||
self.os_nvram is not None or
|
||||
self.os_nvram_template is not None
|
||||
):
|
||||
nvram = self._text_node("nvram", self.os_nvram)
|
||||
nvram.set("template", self.os_nvram_template)
|
||||
os.append(nvram)
|
||||
|
||||
if self.os_initrd is not None:
|
||||
os.append(self._text_node("initrd", self.os_initrd))
|
||||
if self.os_cmdline is not None:
|
||||
|
|
|
@ -140,14 +140,6 @@ LOG = logging.getLogger(__name__)
|
|||
|
||||
CONF = nova.conf.CONF
|
||||
|
||||
DEFAULT_UEFI_LOADER_PATH = {
|
||||
"x86_64": ['/usr/share/OVMF/OVMF_CODE.fd',
|
||||
'/usr/share/OVMF/OVMF_CODE.secboot.fd',
|
||||
'/usr/share/qemu/ovmf-x86_64-code.bin'],
|
||||
"aarch64": ['/usr/share/AAVMF/AAVMF_CODE.fd',
|
||||
'/usr/share/qemu/aavmf-aarch64-code.bin']
|
||||
}
|
||||
|
||||
MAX_CONSOLE_BYTES = 100 * units.Ki
|
||||
VALID_DISK_CACHEMODES = [
|
||||
"default", "none", "writethrough", "writeback", "directsync", "unsafe",
|
||||
|
@ -5823,40 +5815,12 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
return flavor
|
||||
return instance.flavor
|
||||
|
||||
def _has_uefi_support(self):
|
||||
# This means that the host can support UEFI booting for guests
|
||||
supported_archs = [fields.Architecture.X86_64,
|
||||
fields.Architecture.AARCH64]
|
||||
caps = self._host.get_capabilities()
|
||||
# TODO(dmllr, kchamart): Get rid of probing the OVMF binary file
|
||||
# paths, it is not robust, because nothing but the binary's
|
||||
# filename is reported, which means you have to detect its
|
||||
# architecture and features by other means. To solve this,
|
||||
# query the libvirt's getDomainCapabilities() to get the
|
||||
# firmware paths (as reported in the 'loader' value). Nova now
|
||||
# has a wrapper method for this, get_domain_capabilities().
|
||||
# This is a more reliable way to detect UEFI boot support.
|
||||
#
|
||||
# Further, with libvirt 5.3 onwards, support for UEFI boot is
|
||||
# much more simplified by the "firmware auto-selection" feature.
|
||||
# When using this, Nova doesn't need to query OVMF file paths at
|
||||
# all; libvirt will take care of it. This is done by taking
|
||||
# advantage of the so-called firmware "descriptor files" --
|
||||
# small JSON files (which will be shipped by Linux
|
||||
# distributions) that describe a UEFI firmware binary's
|
||||
# "characteristics", such as the binary's file path, its
|
||||
# features, architecture, supported machine type, NVRAM template
|
||||
# and so forth.
|
||||
|
||||
return ((caps.host.cpu.arch in supported_archs) and
|
||||
any((os.path.exists(p)
|
||||
for p in DEFAULT_UEFI_LOADER_PATH[caps.host.cpu.arch])))
|
||||
|
||||
def _check_uefi_support(self, hw_firmware_type):
|
||||
caps = self._host.get_capabilities()
|
||||
return (self._has_uefi_support() and
|
||||
(hw_firmware_type == fields.FirmwareType.UEFI or
|
||||
caps.host.cpu.arch == fields.Architecture.AARCH64))
|
||||
return self._host.supports_uefi and (
|
||||
hw_firmware_type == fields.FirmwareType.UEFI or
|
||||
caps.host.cpu.arch == fields.Architecture.AARCH64
|
||||
)
|
||||
|
||||
def _get_supported_perf_events(self):
|
||||
if not len(CONF.libvirt.enabled_perf_events):
|
||||
|
@ -5895,6 +5859,9 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
guest.sysinfo = self._get_guest_config_sysinfo(instance)
|
||||
guest.os_smbios = vconfig.LibvirtConfigGuestSMBIOS()
|
||||
|
||||
mach_type = libvirt_utils.get_machine_type(image_meta)
|
||||
guest.os_mach_type = mach_type
|
||||
|
||||
hw_firmware_type = image_meta.properties.get('hw_firmware_type')
|
||||
|
||||
if arch == fields.Architecture.AARCH64:
|
||||
|
@ -5902,22 +5869,30 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
hw_firmware_type = fields.FirmwareType.UEFI
|
||||
|
||||
if hw_firmware_type == fields.FirmwareType.UEFI:
|
||||
if self._has_uefi_support():
|
||||
global uefi_logged
|
||||
if not uefi_logged:
|
||||
LOG.warning("uefi support is without some kind of "
|
||||
"functional testing and therefore "
|
||||
"considered experimental.")
|
||||
uefi_logged = True
|
||||
for lpath in DEFAULT_UEFI_LOADER_PATH[arch]:
|
||||
if os.path.exists(lpath):
|
||||
guest.os_loader = lpath
|
||||
guest.os_loader_type = "pflash"
|
||||
else:
|
||||
global uefi_logged
|
||||
if not uefi_logged:
|
||||
LOG.warning("uefi support is without some kind of "
|
||||
"functional testing and therefore "
|
||||
"considered experimental.")
|
||||
uefi_logged = True
|
||||
|
||||
if not self._host.supports_uefi:
|
||||
raise exception.UEFINotSupported()
|
||||
|
||||
mtype = libvirt_utils.get_machine_type(image_meta)
|
||||
guest.os_mach_type = mtype
|
||||
# TODO(stephenfin): Drop this when we drop support for legacy
|
||||
# architectures
|
||||
if not mach_type:
|
||||
# loaders are specific to arch and machine type - if we
|
||||
# don't have a machine type here, we're on a legacy
|
||||
# architecture that we have no default machine type for
|
||||
raise exception.UEFINotSupported()
|
||||
|
||||
loader, nvram_template = self._host.get_loader(
|
||||
arch, mach_type, has_secure_boot=False)
|
||||
|
||||
guest.os_loader = loader
|
||||
guest.os_loader_type = 'pflash'
|
||||
guest.os_nvram_template = nvram_template
|
||||
|
||||
# NOTE(lyarwood): If the machine type isn't recorded in the stashed
|
||||
# image metadata then record it through the system metadata table.
|
||||
|
@ -5929,7 +5904,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
# nova.objects.ImageMeta.from_instance and the
|
||||
# nova.utils.get_image_from_system_metadata function.
|
||||
if image_meta.properties.get('hw_machine_type') is None:
|
||||
instance.system_metadata['image_hw_machine_type'] = mtype
|
||||
instance.system_metadata['image_hw_machine_type'] = mach_type
|
||||
|
||||
if image_meta.properties.get('hw_boot_menu') is None:
|
||||
guest.os_bootmenu = strutils.bool_from_string(
|
||||
|
|
Loading…
Reference in New Issue