From bb970160e5c58f027af3d74a5814d0e96f655c3f Mon Sep 17 00:00:00 2001 From: Steve Keay Date: Wed, 13 May 2026 18:03:11 +0100 Subject: [PATCH] Update BIOS settings to disable SecureBoot We were previously deferring BIOS settings until after agent inspection. Most of the settings are to support PXE boot, and were not required for our virtual-media-based agent inspection. Setting of SecureBoot is actually important for virtual-media boot, so we now set BIOS settings ahead of every boot: 1) basic settings to support virtual-media boot, (disable SecureBoot) 2) once pxe_interface is known, we update BIOS settings a second time to configure that. --- .../tests/test_enroll_server.py | 2 +- .../understack_workflows/bmc_bios.py | 15 ++++++++++----- .../understack_workflows/main/enroll_server.py | 5 +++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/python/understack-workflows/tests/test_enroll_server.py b/python/understack-workflows/tests/test_enroll_server.py index bf596ee90..17507b224 100644 --- a/python/understack-workflows/tests/test_enroll_server.py +++ b/python/understack-workflows/tests/test_enroll_server.py @@ -251,7 +251,7 @@ def test_enrol_happy_path_uses_virtual_media_inspect_and_flips_back(mocker): bmc_set_hostname.assert_called_once_with(fake_bmc, "None", "Dell-ABC123") # BIOS settings configured exactly once, using pxe_enabled port BIOS names. - update_dell_bios_settings.assert_called_once_with( + update_dell_bios_settings.assert_any_call( fake_bmc, pxe_interface="NIC.Integrated.1-1", ) diff --git a/python/understack-workflows/understack_workflows/bmc_bios.py b/python/understack-workflows/understack_workflows/bmc_bios.py index c6c20b48a..2048531ba 100644 --- a/python/understack-workflows/understack_workflows/bmc_bios.py +++ b/python/understack-workflows/understack_workflows/bmc_bios.py @@ -6,9 +6,9 @@ logger = logging.getLogger(__name__) -def required_bios_settings(pxe_interface: str) -> dict[str, str]: +def required_bios_settings(pxe_interface: str | None) -> dict[str, str]: """Return Bios settings map for BMC.""" - return { + settings = { # at this time ironic conductor returns http URLs # when its serving data from its own http server "HttpDev1TlsMode": "None", @@ -22,15 +22,20 @@ def required_bios_settings(pxe_interface: str) -> dict[str, str]: "OS-BMC.1.AdminState": "Disabled", # This closes down IPMI, which we don't use anyhow: "IPMILan.1.Enable": "Disabled", + # We must disable secureboot for IPA to work + "SecureBoot": "Disabled", # PXE is enabled by default on DELL, but we don't use it: "PxeDev1EnDis": "Disabled", - # Configure exactly one HTTP port for booting: - "HttpDev1Interface": pxe_interface, "HttpDev1EnDis": "Enabled", "HttpDev2EnDis": "Disabled", "HttpDev3EnDis": "Disabled", "HttpDev4EnDis": "Disabled", } + if pxe_interface: + # Configure exactly one HTTP port for booting: + settings["HttpDev1Interface"] = pxe_interface + + return settings def required_change_for_bios_setting( @@ -77,7 +82,7 @@ def required_change_for_bios_setting( return required_value -def update_dell_bios_settings(bmc: Bmc, pxe_interface: str) -> dict: +def update_dell_bios_settings(bmc: Bmc, pxe_interface: str | None) -> dict: """Check and update BIOS settings to standard as required. Any changes take effect on next server reboot. diff --git a/python/understack-workflows/understack_workflows/main/enroll_server.py b/python/understack-workflows/understack_workflows/main/enroll_server.py index 27cc87d16..bff6865f5 100644 --- a/python/understack-workflows/understack_workflows/main/enroll_server.py +++ b/python/understack-workflows/understack_workflows/main/enroll_server.py @@ -112,8 +112,9 @@ def enroll( # port data is set up in a manner that suits the Neutron algorithm. If a # normal PXE/HTTP port is available then we use it instead: - virtual_media = not bool(ironic_node.pxe_enabled_bios_name(node)) - agent_inspection(node, virtual_media=virtual_media) + pxe_interface = ironic_node.pxe_enabled_bios_name(node) + update_dell_bios_settings(bmc, pxe_interface=pxe_interface) + agent_inspection(node, virtual_media=not pxe_interface) pxe_interface = ironic_node.pxe_enabled_bios_name(node) if not pxe_interface: