Current Series Release Notes

In Development - Unreleased

New Features

  • Redfish inspection now discovers subsystem and subsystem_vendor for network interfaces.

  • Redfish inspection now discovers vendor, product, and pci_address for network interfaces when available.

  • The ironic-manage utility has a new inspection-rules check command that evaluates inspection rules against captured hardware data, showing which rules match and what actions would be executed without touching any real node. The rules file is passed with --rules, and the hardware data either as a single --node/--inventory file pair or as a directory tree of test cases with --data-dir.

  • Updates the known accelerators list with recent NVIDIA and AMD GPUs.

  • Adds a new configuration option [vnc]kubernetes_namespace to allow operators to specify the Kubernetes namespace in which console pods and secrets are created when using the kubernetes console container provider. The default value is openstack to maintain backward compatibility. This setting only applies when using the default template; custom templates must handle namespace configuration themselves.

  • The standalone ironic-networking service can now configure switch-port MTUs through networking-generic-switch. MTUs may be supplied in port.extra.switchport or in the network configuration string. MTU management is enabled automatically when the installed networking-generic-switch version and selected switch driver expose MTU support. Older builds leave switch MTUs unchanged.

  • Trait Based Networking filter expressions can now use the vif.id, vif.name and vif.tags variables, which match against the neutron port supplied as the VIF. vif.tags is a collection and supports the same ==, != and =~ semantics as network.tags.

Upgrade Notes

  • The new [ansible]enforce_playbooks_path option defaults to False. While disabled, a per-node ansible_playbooks_path that resolves outside [ansible]playbooks_path or [ansible]playbooks_path_allowlist is permitted but logs a warning. This default is expected to change to True in a future release. Operators who rely on custom per-node playbook directories should review conductor logs for these warnings and add the affected directories to [ansible]playbooks_path_allowlist before enforcement is enabled.

  • The default value of [deploy]image_server_auth_permit_unknown_hosts has changed from True to False. Operators who have configured [deploy]image_server_auth_strategy to http_basic must now also configure [deploy]image_server_auth_hosts for credentials to be sent. Deployments using the default noauth strategy are not affected.

  • The minimum required version of sushy is now 5.14.0. It reports the outcome of each Dell Lifecycle Controller job, so a Redfish firmware update on Dell iDRAC now always fails when the job applying the firmware fails, instead of assuming that a finished job succeeded.

  • The redfish-virtual-media boot interface has been enabled for Dell iDRAC10 BMCs.

  • The [ansible]enforce_playbooks_path option now defaults to True. Operators who point individual nodes at custom playbook directories via the ansible_playbooks_path driver_info value must list those directories in [ansible]playbooks_path_allowlist or those nodes will fail validation. Setting [ansible]enforce_playbooks_path to False restores the previous non-enforcing behaviour.

  • The standalone tools/inspection_rules/tester.py script has been removed. Use the new ironic-manage inspection-rules check command instead.

Deprecation Notes

  • Overriding the Ansible python interpreter per node via the ansible_python_interpreter field in driver_info is deprecated. Use the [ansible]default_python_interpreter configuration option instead. The per-node override can be disabled with the new [ansible]allow_node_python_interpreter_override option, whose default is expected to change to False in a future release.

  • When using Redfish inspection, the new device field should be used instead of product for network interfaces. The product field remains available for compatibility with IPA, but will eventually be removed.

Security Issues

  • Adds the [ansible]allow_node_python_interpreter_override configuration option to the ansible deploy interface. The per-node ansible_python_interpreter value set in a node’s driver_info is passed to Ansible as a global extra-var, which means it also selects the interpreter used for the configdrive cleanup task that is delegated to the conductor and executed under the ironic-conductor service account. A caller able to update driver_info (for example a project owner under the default policy) could therefore influence which binary the conductor executes on its own host. Setting this option to False causes a per-node value to be rejected with a validation error, so that only the conductor-configured [ansible]default_python_interpreter is used, removing the caller’s ability to steer the conductor-side interpreter. The option defaults to True to preserve existing behavior; the default is expected to change to False in a future release. Operators that do not require per-node interpreter selection are encouraged to set it to False.

  • The ansible deploy interface now validates the per-node ansible_playbooks_path value found in driver_info. This value selects the directory on the conductor from which the playbook and inventory handed to ansible-playbook are loaded, and it was previously accepted without any constraint. The path is now checked to ensure it resolves to a location within [ansible]playbooks_path or one of the directories listed in the new [ansible]playbooks_path_allowlist option. Symlinks and relative (..) segments in the per-node value are resolved before the check so containment cannot be bypassed. Entries in [ansible]playbooks_path_allowlist are validated as explicit absolute paths and are rejected if they contain path traversal mechanisms, such as ... Whether a value outside the permitted directories is rejected or merely logged is controlled by the new [ansible]enforce_playbooks_path option.

  • Ironic now refuses to start when [deploy]image_server_password is configured without either [deploy]image_server_auth_hosts or [deploy]image_server_auth_permit_unknown_hosts. This prevents image server credentials from being silently sent to untrusted, potentially user-supplied, hosts. See bug 2162816 for details.

  • Fixes an issue where an Ironic conductor could experience a memory or disk exhaustion condition when a tenant provides a gzip bomb instead of a valid configdrive. Any tenant authorized to deploy machines could trigger this by supplying a base64-encoded gzip payload that Ironic decompresses while preparing the configdrive for deployment.

    This affected deployments using the Anaconda deploy interface, the redfish-virtual-media boot interface, and deployments where Ironic updates network metadata (network_data.json).

    Now, Ironic decompresses configdrives in bounded chunks and rejects any configdrive that expands to more than 64MiB – the same limit enforced by Ironic Python Agent (and the size of the partition it creates).

    This security issue is tracked as CVE-2026-115638.

  • Fixes an issue where issuing a PATCH to /v1/nodes containing /maintenance would bypass the more specific baremetal:node:set_maintenance policy and instead be evaluated as baremetal:node:update. For clouds running default Ironic policy, this means someone with member role in the project indicated in node.lessee could change the maintenance state of the node unexpectedly.

    This security fix is tracked in OSSA-2026-048 and CVE-2026-89419.

  • The [ansible]enforce_playbooks_path option now defaults to True. A per-node ansible_playbooks_path in driver_info that resolves outside [ansible]playbooks_path or [ansible]playbooks_path_allowlist is now rejected rather than merely logged.

  • Sensitive step arguments, such as passwords and tokens, are now masked when the conductor logs a step or a list of steps, and in step error messages. Previously the steps were logged with all of their arguments.

  • Hardens the OCI container registry client against credential disclosure to hosts other than the registry being queried, in response to bug 2170228. Tag list pagination now refuses to follow a next link which points anywhere other than the registry being queried, unless the destination is a host matched by the [oci]secure_cdn_registries trust check. Host matching for redirects and pagination links is now performed by exact hostname or a proper subdomain of a configured entry, so look-alike domain names such as docker.io.bad.example.com are no longer treated as trusted docker.io endpoints.

  • The ansible deploy interface no longer writes the configuration drive to a predictable path ([DEFAULT]tempdir/<node UUID>.cndrive) on the conductor. The configuration drive is now written into a private per-node directory created with 0700 permissions and an unpredictable name. This prevents other local users on the conductor from reading the configuration drive contents, which may include secrets, and prevents a local user from pre-creating or symlinking the predictable path before the conductor writes to it. The directory is removed when the deployment environment is cleaned up.

  • Add validation for BMC subscription IDs used to get or delete BMC subscriptions via redfish vendor passthru. Note that there’s no explicit specification for what constitutes a valid or invalid BMC subscription ID, therefore validation consists of forbidding illegal characters and substrings. Addresses CVE-2026-90458.

Bug Fixes

  • Fixed an issue where setting the boot device would sometimes fail on Dell iDRAC BMCs with the message ‘The service is temporarily unavailable. Retry in 30 seconds.’ Retries are now attempted when that happens.

  • Fixes bug 2169173 to add validation that rejects Glance encrypted images during deployment validation. Ironic now checks for the cinder_encryption_key_id property in Glance images and raises a clear error message indicating that encrypted images are not supported for bare metal deployments. This prevents wasting deployment resources on images that cannot work with bare metal due to the fundamental architectural mismatch between encryption designed for virtualized environments and physical hardware access.

  • Improves Lifecycle Controller job checking on Dell iDRAC during Redfish firmware updates. When the Redfish task of a BIOS update disappears before Ironic can poll it, a job that ended in error is reported as a failed update, and a temporary failure to read the job queue is retried instead of triggering the reboot. If the job has disappeared before its outcome could be observed, Ironic treats the update as failed because it cannot establish whether firmware remains to be applied; inspect the BMC before retrying.

  • Fixes an issue where listing allocations filtered by node, for example baremetal allocation list --node <node>, failed with an HTTP 500 error (“Attribute name “owner” is ambiguous”) when the request was made with a project scoped token. bug 2171179.

  • Fixes an issue where a pre-shared OCI registry credential supplied in the documented docker config.json “auth” format (the base64 encoding of username:password) was sent to the registry as an HTTP Basic password with an empty username. When a bearer token is requested, such a credential is now decoded and sent as proper HTTP Basic credentials, allowing registries which expect basic authentication to authenticate successfully. Opaque bearer tokens conveyed via the password, which are not base64 encoded username:password values, continue to be sent unchanged, preserving the prior behavior. See bug 2168735.

  • Fixes bootc container deployments dropping the username when a raw username:password basic authentication credential was supplied as a pull secret. The credential is now reconstructed and transmitted to the agent so that both the username and password are available for authentication to the remote container registry. See bug 2168735.

  • Fixes inconsistent handling of the BootSourceOverrideEnabled parameter for vendors requiring full boot requests (American Megatrends International, ASRock Rack, and Redfish compatible systems). The enabled variable could be None when the desired persistence matched the current BMC state, which prevented the CONTINUOUS-to-ONCE fallback from triggering on these vendors.

  • Fixes an inconsistency where the cpu.frequency field in inspection data was reported as an integer by Redfish (out-of-band) inspection but as a string by in-band inspection (IPA). Redfish inspection now reports cpu.frequency as a string to match in-band inspection.

  • Fixed the error message of the Trait Based Networking TBNNoPortMatchesFound exception. A misspelled attribute caused the intended message to be ignored and a generic, uninformative message to be shown instead.

  • Fixed Trait Based Networking (TBN) failing with an HTTP 500 error ('Portgroup' object has no attribute 'vendor') when attaching a VIF to a node that has portgroups. Portgroups have no vendor field, so filter expressions that reference port.vendor no longer match portgroups.

  • Fixed Trait Based Networking (TBN) failing VIF attachment when more than one action matched, for example when a port is a member of a portgroup and matches both an attach_portgroup and an attach_port action. All matching actions were executed in the same vif_attach() call, so the second attempt to bind the VIF failed the whole operation. Only the first matching action is now executed. See bug 2169647 for details.

  • Fixed Trait Based Networking (TBN) failing with an internal TypeError when a trait used an action that is not yet implemented, such as bond_ports. VIF attachment now fails with a NetworkError that names the unhandled action, instead of logging a malformed warning.

  • Trait Based Networking (TBN) filter expressions that reference an unset value, such as port.vendor on a portgroup or port.category on a port without a category, now never match, regardless of comparator. Previously ordering comparators (<, <=, >, >=) and prefix match (=~) raised an error, and != matched.

  • Fixes the inspection rule plugin data actions (set-plugin-data, extend-plugin-data and unset-plugin-data) ignoring slash notation in path, so that they now accept the same dot or slash notation as the node attribute actions.

  • Fixes an issue where Lenovo servers in UEFI mode would get stuck in an infinite boot loop after Ironic provisioned RHCOS or other operating systems that require UEFI shim bootloaders when using custom deploy flows (e.g., OpenShift/Metal³ deployments with Redfish boot interfaces).

    After provisioning, when preparing the instance to boot from disk, the Redfish boot interfaces (redfish-virtual-media and redfish-https) set BootSourceOverrideTarget=Hdd which on Lenovo systems maps to a generic “Hard Disk” boot entry that bypasses the UEFI shim bootloader. The system would display a “Boot Option Restoration” screen and continuously reboot, requiring manual user intervention.

    The fix extends existing Lenovo UEFI handling from the agent deploy interface to the Redfish boot interfaces. During the prepare_instance phase, Ironic now skips setting the boot device for Lenovo UEFI systems, allowing the UEFI boot order (which has the shim bootloader first) to handle the boot process. This avoids triggering NVRAM changes that can be lost due to Lenovo’s NVRAM restore behavior.

    This change only affects Lenovo hardware in UEFI mode during instance preparation in the Redfish boot interfaces and does not affect legacy BIOS mode, other vendors, or other boot interfaces.

    For more details, see bug 2150628.

  • Fix an issue where the [neutron].fail_on_port_binding_failure option could cause us to not properly track and clean up ports if one port bound successfully and then the next port did not bind correctly because the ports were only recorded on success of all port binding. See bug 2148615 for details.

  • The pci-devices inspection hook now works with the Redfish inspection, which reports PCI devices in the inventory rather than in the plugin data.

  • Fixes an issue where the neutron network interface could attach only some of the tenant VIFs of a node. Every port or port group with a tenant VIF attached is now plugged when configuring tenant networks, and a failure to plug any one of them fails the operation. Ports that are members of a port group are no longer skipped, so a port group can be defined while its member ports are still plugged individually, and they are likewise unbound when tenant networks are unconfigured. See bug 2169761 for details.

  • The ironic-networking interface now skips ports without extra.switchport data when adding or removing provisioning, cleaning, rescue, inspection, and servicing networks. Previously, a network-level configuration could be applied to any port with a local_link_connection. See bug 2170129.

  • Fixes a file descriptor leak in Swift client connections. The SwiftAPI class was creating OpenStack SDK Connection objects without properly closing them, leading to file descriptor accumulation over time in deployments that use Swift for configdrive, firmware updates, or inspection data storage. All Swift client code now properly closes connections using context managers.

  • Trait Based Networking now looks up the neutron port and network of a VIF when attaching, so that network.name and network.tags are populated from the network the port is attached to.