Support UEFI boot mode

Adds support for using UEFI boot mode for nodes. This is done via node
capabilities, as it is in Ironic.

The default boot mode is now configurable via the default_boot_mode
variable. The default boot mode remains legacy BIOS for now, although
this may change.

Updates the existing CI jobs, with the OVS jobs using BIOS boot mode,
and the linuxbridge jobs using UEFI boot mode.

Depends-On: https://github.com/stackhpc/ansible-role-libvirt-vm/pull/83
Depends-On: https://github.com/stackhpc/ansible-role-libvirt-host/pull/50
Depends-On: https://review.opendev.org/c/openstack/kayobe/+/827486

Change-Id: Ifaf95ecfd4f6e925d3c69d4b324fdf2cd6b0ca52
This commit is contained in:
Mark Goddard 2022-02-02 11:17:57 +00:00
parent 7c6e87e598
commit fc1b42c60d
12 changed files with 99 additions and 29 deletions

View File

@ -45,6 +45,7 @@ class FilterModule(object):
'set_libvirt_interfaces': set_libvirt_interfaces, 'set_libvirt_interfaces': set_libvirt_interfaces,
'set_libvirt_start_params': set_libvirt_start_params, 'set_libvirt_start_params': set_libvirt_start_params,
'set_libvirt_volume_pool': set_libvirt_volume_pool, 'set_libvirt_volume_pool': set_libvirt_volume_pool,
'set_libvirt_boot_firmware': set_libvirt_boot_firmware,
# Miscellaneous filters. # Miscellaneous filters.
'size_string_to_gb': size_string_to_gb, 'size_string_to_gb': size_string_to_gb,
@ -89,6 +90,54 @@ def set_libvirt_volume_pool(context, node):
return node return node
# The following function has been adapted from Ironic:
# https://opendev.org/openstack/ironic/src/commit/5f6d753b2c334e4f404818d5e94a145b60244736/ironic/drivers/utils.py#L229
def _capabilities_to_dict(capabilities):
"""Parse the capabilities string into a dictionary
:param capabilities: the capabilities of the node as a formatted string.
:raises: InvalidParameterValue if capabilities is not an string or has a
malformed value
"""
capabilities_dict = {}
if capabilities:
if not isinstance(capabilities, str):
raise AnsibleFilterError(
"Value of 'capabilities' must be string. Got %s"
% type(capabilities))
try:
for capability in capabilities.split(','):
key, value = capability.split(':')
capabilities_dict[key] = value
except ValueError:
raise AnsibleFilterError(
"Malformed capabilities value: %s" % capability
)
return capabilities_dict
@contextfilter
def set_libvirt_boot_firmware(context, node):
"""Set the boot firmware for a node."""
default_boot_mode = _get_hostvar(context, 'default_boot_mode',
inventory_hostname='localhost')
properties = node.get('ironic_config', {}).get('properties', {})
caps = properties.get('capabilities', '')
caps_dict = _capabilities_to_dict(caps)
boot_mode = caps_dict.get('boot_mode', default_boot_mode)
if boot_mode not in ['bios', 'uefi']:
raise AnsibleFilterError(
"Unexpected boot firmware. Must be one of 'bios' or 'uefi'. Got "
"'%s'" % boot_mode
)
boot_mode_to_firmware = {'uefi': 'efi', 'bios': 'bios'}
node['boot_firmware'] = boot_mode_to_firmware[boot_mode]
return node
def set_libvirt_start_params(node): def set_libvirt_start_params(node):
"""Set the Libvirt start and autostart parameters. """Set the Libvirt start and autostart parameters.

View File

@ -38,6 +38,13 @@
libvirt_host_uri: "{{ libvirt_local_uri }}" libvirt_host_uri: "{{ libvirt_local_uri }}"
libvirt_host_socket_dir: "{{ libvirt_custom_socket_path }}" libvirt_host_socket_dir: "{{ libvirt_custom_socket_path }}"
libvirt_host_pid_path: "{{ libvirt_custom_pid_path }}" libvirt_host_pid_path: "{{ libvirt_custom_pid_path }}"
libvirt_host_enable_efi_support: >-
{{ hostvars.localhost.tenks_state[inventory_hostname].nodes |
default([]) |
map('set_libvirt_boot_firmware') |
selectattr('boot_firmware', 'equalto', 'efi') |
list |
length > 0 }}
- name: Set up Virtual BMC daemon - name: Set up Virtual BMC daemon
include_role: include_role:

View File

@ -111,6 +111,10 @@ state_file_path: >-
# The default Ironic driver of a node. Can be overridden per-node. # The default Ironic driver of a node. Can be overridden per-node.
default_ironic_driver: ipmi default_ironic_driver: ipmi
# The default boot mode of a node. One of 'bios' or 'uefi'. Can be
# overridden per-node via properties.capabilities.boot_mode.
default_boot_mode: bios
# Maps Ironic drivers to the BMC emulation tool they support. # Maps Ironic drivers to the BMC emulation tool they support.
bmc_emulators: bmc_emulators:
agent_ipmitool: virtualbmc agent_ipmitool: virtualbmc

View File

@ -30,4 +30,5 @@
{{ nodes | map('set_libvirt_interfaces') {{ nodes | map('set_libvirt_interfaces')
| map('set_libvirt_volume_pool') | map('set_libvirt_volume_pool')
| map('set_libvirt_start_params') | map('set_libvirt_start_params')
| map('set_libvirt_boot_firmware')
| list }} | list }}

View File

@ -102,11 +102,11 @@
cpus: "{{ node.vcpus }}" cpus: "{{ node.vcpus }}"
memory_mb: "{{ node.memory_mb }}" memory_mb: "{{ node.memory_mb }}"
local_gb: "{{ node.volumes[0].capacity | size_string_to_gb if node.volumes | length > 0 else 0 }}" local_gb: "{{ node.volumes[0].capacity | size_string_to_gb if node.volumes | length > 0 else 0 }}"
# Since we currently only support legacy BIOS boot mode, set it # Set the boot mode explicitly here, since we cannot rely on a stable
# explicitly here. This is especially important since Ironic changed # default in Ironic (it changed from legacy BIOS to UEFI in Yoga).
# the default boot mode to UEFI in Yoga. If the capabilities field is # If the capabilities field is provided, the boot_mode should be set
# provided, the boot_mode should be set explicitly. # explicitly.
capabilities: "boot_mode:bios" capabilities: "boot_mode:{{ default_boot_mode }}"
- name: Add Ironic node traits - name: Add Ironic node traits
command: >- command: >-

View File

@ -54,6 +54,11 @@ Another variable that may be useful is ``bridge_type``. This may be either
created by Tenks. This may be different from the type of interfaces or bridges created by Tenks. This may be different from the type of interfaces or bridges
in ``physnet_mappings``. in ``physnet_mappings``.
The default boot mode is legacy BIOS. This may be changed to UEFI by setting
``default_boot_mode`` to ``uefi`` in a variable file. The boot mode for nodes
may be set individually via ``ironic_config.properties.capabilities.boot_mode``
in the ``specs`` list.
Standalone Ironic Standalone Ironic
----------------- -----------------

View File

@ -47,12 +47,6 @@ to be implemented in future.
``ansible-playbook`` invocation with multiple parameters. It would be less ``ansible-playbook`` invocation with multiple parameters. It would be less
clunky to introduce a simple CLI wrapper encapsulating some default commands. clunky to introduce a simple CLI wrapper encapsulating some default commands.
* **Configurable boot modes**. Support for boot modes other than legacy BIOS
(for example, UEFI) would be useful. OpenStack Ironic supports configuration
of boot modes with the `boot_mode` parameter for certain drivers. The
Libvirt/QEMU/KVM stack supports UEFI boot with the `OVMF project
<http://www.linux-kvm.org/downloads/lersek/ovmf-whitepaper-c770f8c.txt>`__
Contribution Contribution
------------ ------------

View File

@ -21,6 +21,8 @@ specs:
- type: type0 - type: type0
count: 2 count: 2
default_boot_mode: {{ boot_mode }}
nova_flavors: [] nova_flavors: []
physnet_mappings: physnet_mappings:

View File

@ -0,0 +1,6 @@
---
features:
- |
Adds support for UEFI boot mode. The default boot mode may be set via
``default_boot_mode``. The default boot mode remains legacy BIOS, although
this may change.

View File

@ -23,13 +23,15 @@
- ^tox.ini$ - ^tox.ini$
- job: - job:
name: tenks-deploy-teardown-ovs-base name: tenks-deploy-teardown-ovs-bios-base
parent: tenks-deploy-teardown-base parent: tenks-deploy-teardown-base
vars: vars:
bridge_type: openvswitch bridge_type: openvswitch
boot_mode: bios
- job: - job:
name: tenks-deploy-teardown-linuxbridge-base name: tenks-deploy-teardown-linuxbridge-uefi-base
parent: tenks-deploy-teardown-base parent: tenks-deploy-teardown-base
vars: vars:
bridge_type: linuxbridge bridge_type: linuxbridge
boot_mode: uefi

View File

@ -8,21 +8,21 @@
tox_envlist: alint tox_envlist: alint
- job: - job:
name: tenks-deploy-teardown-ovs-centos8s name: tenks-deploy-teardown-ovs-bios-centos8s
parent: tenks-deploy-teardown-ovs-base parent: tenks-deploy-teardown-ovs-bios-base
nodeset: centos-8-stream nodeset: centos-8-stream
- job: - job:
name: tenks-deploy-teardown-ovs-ubuntu name: tenks-deploy-teardown-ovs-bios-ubuntu
parent: tenks-deploy-teardown-ovs-base parent: tenks-deploy-teardown-ovs-bios-base
nodeset: ubuntu-bionic nodeset: ubuntu-bionic
- job: - job:
name: tenks-deploy-teardown-linuxbridge-centos8s name: tenks-deploy-teardown-linuxbridge-uefi-centos8s
parent: tenks-deploy-teardown-linuxbridge-base parent: tenks-deploy-teardown-linuxbridge-uefi-base
nodeset: centos-8-stream nodeset: centos-8-stream
- job: - job:
name: tenks-deploy-teardown-linuxbridge-ubuntu name: tenks-deploy-teardown-linuxbridge-uefi-ubuntu
parent: tenks-deploy-teardown-linuxbridge-base parent: tenks-deploy-teardown-linuxbridge-uefi-base
nodeset: ubuntu-bionic nodeset: ubuntu-bionic

View File

@ -13,10 +13,10 @@
- openstack-tox-py38 - openstack-tox-py38
- openstack-tox-py39 - openstack-tox-py39
- tenks-tox-ansible-lint - tenks-tox-ansible-lint
- tenks-deploy-teardown-ovs-centos8s - tenks-deploy-teardown-ovs-bios-centos8s
- tenks-deploy-teardown-ovs-ubuntu - tenks-deploy-teardown-ovs-bios-ubuntu
- tenks-deploy-teardown-linuxbridge-centos8s - tenks-deploy-teardown-linuxbridge-uefi-centos8s
- tenks-deploy-teardown-linuxbridge-ubuntu - tenks-deploy-teardown-linuxbridge-uefi-ubuntu
# Until we have ironic jobs using tenks, gate on the kayobe overcloud # Until we have ironic jobs using tenks, gate on the kayobe overcloud
# deploy job, which uses tenks to test bare metal compute provisioning. # deploy job, which uses tenks to test bare metal compute provisioning.
- kayobe-overcloud-centos8s - kayobe-overcloud-centos8s
@ -29,10 +29,10 @@
- openstack-tox-py38 - openstack-tox-py38
- openstack-tox-py39 - openstack-tox-py39
- tenks-tox-ansible-lint - tenks-tox-ansible-lint
- tenks-deploy-teardown-ovs-centos8s - tenks-deploy-teardown-ovs-bios-centos8s
- tenks-deploy-teardown-ovs-ubuntu - tenks-deploy-teardown-ovs-bios-ubuntu
- tenks-deploy-teardown-linuxbridge-centos8s - tenks-deploy-teardown-linuxbridge-uefi-centos8s
- tenks-deploy-teardown-linuxbridge-ubuntu - tenks-deploy-teardown-linuxbridge-uefi-ubuntu
# Until we have ironic jobs using tenks, gate on the kayobe overcloud # Until we have ironic jobs using tenks, gate on the kayobe overcloud
# deploy job, which uses tenks to test bare metal compute provisioning. # deploy job, which uses tenks to test bare metal compute provisioning.
- kayobe-overcloud-centos8s - kayobe-overcloud-centos8s