Skip to content

Commit fc1b42c

Browse files
committed
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: stackhpc/ansible-role-libvirt-vm#83 Depends-On: stackhpc/ansible-role-libvirt-host#50 Depends-On: https://review.opendev.org/c/openstack/kayobe/+/827486 Change-Id: Ifaf95ecfd4f6e925d3c69d4b324fdf2cd6b0ca52
1 parent 7c6e87e commit fc1b42c

File tree

12 files changed

+99
-29
lines changed

12 files changed

+99
-29
lines changed

ansible/filter_plugins/tenks.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def filters(self):
4545
'set_libvirt_interfaces': set_libvirt_interfaces,
4646
'set_libvirt_start_params': set_libvirt_start_params,
4747
'set_libvirt_volume_pool': set_libvirt_volume_pool,
48+
'set_libvirt_boot_firmware': set_libvirt_boot_firmware,
4849

4950
# Miscellaneous filters.
5051
'size_string_to_gb': size_string_to_gb,
@@ -89,6 +90,54 @@ def set_libvirt_volume_pool(context, node):
8990
return node
9091

9192

93+
# The following function has been adapted from Ironic:
94+
# https://opendev.org/openstack/ironic/src/commit/5f6d753b2c334e4f404818d5e94a145b60244736/ironic/drivers/utils.py#L229
95+
96+
def _capabilities_to_dict(capabilities):
97+
"""Parse the capabilities string into a dictionary
98+
99+
:param capabilities: the capabilities of the node as a formatted string.
100+
:raises: InvalidParameterValue if capabilities is not an string or has a
101+
malformed value
102+
"""
103+
capabilities_dict = {}
104+
if capabilities:
105+
if not isinstance(capabilities, str):
106+
raise AnsibleFilterError(
107+
"Value of 'capabilities' must be string. Got %s"
108+
% type(capabilities))
109+
try:
110+
for capability in capabilities.split(','):
111+
key, value = capability.split(':')
112+
capabilities_dict[key] = value
113+
except ValueError:
114+
raise AnsibleFilterError(
115+
"Malformed capabilities value: %s" % capability
116+
)
117+
118+
return capabilities_dict
119+
120+
121+
@contextfilter
122+
def set_libvirt_boot_firmware(context, node):
123+
"""Set the boot firmware for a node."""
124+
default_boot_mode = _get_hostvar(context, 'default_boot_mode',
125+
inventory_hostname='localhost')
126+
properties = node.get('ironic_config', {}).get('properties', {})
127+
caps = properties.get('capabilities', '')
128+
caps_dict = _capabilities_to_dict(caps)
129+
boot_mode = caps_dict.get('boot_mode', default_boot_mode)
130+
if boot_mode not in ['bios', 'uefi']:
131+
raise AnsibleFilterError(
132+
"Unexpected boot firmware. Must be one of 'bios' or 'uefi'. Got "
133+
"'%s'" % boot_mode
134+
)
135+
boot_mode_to_firmware = {'uefi': 'efi', 'bios': 'bios'}
136+
node['boot_firmware'] = boot_mode_to_firmware[boot_mode]
137+
138+
return node
139+
140+
92141
def set_libvirt_start_params(node):
93142
"""Set the Libvirt start and autostart parameters.
94143

ansible/host_setup.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@
3838
libvirt_host_uri: "{{ libvirt_local_uri }}"
3939
libvirt_host_socket_dir: "{{ libvirt_custom_socket_path }}"
4040
libvirt_host_pid_path: "{{ libvirt_custom_pid_path }}"
41+
libvirt_host_enable_efi_support: >-
42+
{{ hostvars.localhost.tenks_state[inventory_hostname].nodes |
43+
default([]) |
44+
map('set_libvirt_boot_firmware') |
45+
selectattr('boot_firmware', 'equalto', 'efi') |
46+
list |
47+
length > 0 }}
4148
4249
- name: Set up Virtual BMC daemon
4350
include_role:

ansible/host_vars/localhost

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ state_file_path: >-
111111
# The default Ironic driver of a node. Can be overridden per-node.
112112
default_ironic_driver: ipmi
113113

114+
# The default boot mode of a node. One of 'bios' or 'uefi'. Can be
115+
# overridden per-node via properties.capabilities.boot_mode.
116+
default_boot_mode: bios
117+
114118
# Maps Ironic drivers to the BMC emulation tool they support.
115119
bmc_emulators:
116120
agent_ipmitool: virtualbmc

ansible/node_instantiation.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,5 @@
3030
{{ nodes | map('set_libvirt_interfaces')
3131
| map('set_libvirt_volume_pool')
3232
| map('set_libvirt_start_params')
33+
| map('set_libvirt_boot_firmware')
3334
| list }}

ansible/roles/ironic-enrolment/tasks/node.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,11 @@
102102
cpus: "{{ node.vcpus }}"
103103
memory_mb: "{{ node.memory_mb }}"
104104
local_gb: "{{ node.volumes[0].capacity | size_string_to_gb if node.volumes | length > 0 else 0 }}"
105-
# Since we currently only support legacy BIOS boot mode, set it
106-
# explicitly here. This is especially important since Ironic changed
107-
# the default boot mode to UEFI in Yoga. If the capabilities field is
108-
# provided, the boot_mode should be set explicitly.
109-
capabilities: "boot_mode:bios"
105+
# Set the boot mode explicitly here, since we cannot rely on a stable
106+
# default in Ironic (it changed from legacy BIOS to UEFI in Yoga).
107+
# If the capabilities field is provided, the boot_mode should be set
108+
# explicitly.
109+
capabilities: "boot_mode:{{ default_boot_mode }}"
110110

111111
- name: Add Ironic node traits
112112
command: >-

doc/source/configuration.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ Another variable that may be useful is ``bridge_type``. This may be either
5454
created by Tenks. This may be different from the type of interfaces or bridges
5555
in ``physnet_mappings``.
5656

57+
The default boot mode is legacy BIOS. This may be changed to UEFI by setting
58+
``default_boot_mode`` to ``uefi`` in a variable file. The boot mode for nodes
59+
may be set individually via ``ironic_config.properties.capabilities.boot_mode``
60+
in the ``specs`` list.
61+
5762
Standalone Ironic
5863
-----------------
5964

doc/source/development.rst

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,6 @@ to be implemented in future.
4747
``ansible-playbook`` invocation with multiple parameters. It would be less
4848
clunky to introduce a simple CLI wrapper encapsulating some default commands.
4949

50-
* **Configurable boot modes**. Support for boot modes other than legacy BIOS
51-
(for example, UEFI) would be useful. OpenStack Ironic supports configuration
52-
of boot modes with the `boot_mode` parameter for certain drivers. The
53-
Libvirt/QEMU/KVM stack supports UEFI boot with the `OVMF project
54-
<http://www.linux-kvm.org/downloads/lersek/ovmf-whitepaper-c770f8c.txt>`__
55-
5650
Contribution
5751
------------
5852

playbooks/tenks-deploy-teardown/templates/tenks-overrides.yml.j2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ specs:
2121
- type: type0
2222
count: 2
2323

24+
default_boot_mode: {{ boot_mode }}
25+
2426
nova_flavors: []
2527

2628
physnet_mappings:
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
features:
3+
- |
4+
Adds support for UEFI boot mode. The default boot mode may be set via
5+
``default_boot_mode``. The default boot mode remains legacy BIOS, although
6+
this may change.

zuul.d/base.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@
2323
- ^tox.ini$
2424

2525
- job:
26-
name: tenks-deploy-teardown-ovs-base
26+
name: tenks-deploy-teardown-ovs-bios-base
2727
parent: tenks-deploy-teardown-base
2828
vars:
2929
bridge_type: openvswitch
30+
boot_mode: bios
3031

3132
- job:
32-
name: tenks-deploy-teardown-linuxbridge-base
33+
name: tenks-deploy-teardown-linuxbridge-uefi-base
3334
parent: tenks-deploy-teardown-base
3435
vars:
3536
bridge_type: linuxbridge
37+
boot_mode: uefi

0 commit comments

Comments
 (0)