OpenKeel: the sovereign French Cloud solution of the inherent group, with a European reach Discover inherent

Reverse-spec · Services

ironic — Change history

Change history — ironic — branch stable/2026.2

Branch stable/2026.2 @ 39ce09ec3b0d — range 752100ac7ff8..39ce09ec3b0d (merge-base with origin/master, where stable/2026.2 left it; 22 non-merge commits) — target: none (no carry-over target given) — analysed on 2026-10-29

Raw facts: _inventory/history_stable-2026.2.{md,json} (history.py). The branch was cut after 39.0.0; its 22 commits are backports. Correcting the automatic categories after reading the diffs: commits 3 to 9 only edit release notes (the script classified them from the note section they touch: feature/security/deprecation), and commit 15 is a fix. 9 functional changes remain: 2 security fixes with CVEs, 1 secret-leak fix in logs, 1 database fix, 5 fixes of the new Trait Based Networking (TBN) feature.

#CommitDateCategory (corrected)ChangeBugImpactIn target
164b234a311462026-09-21maintenance.gitreview for the branch—nonen/a
2763b5b6de2c32026-09-21maintenancetox constraints URL—nonen/a
3–9eebc97a29445 … 10410bed35c02026-09-22maintenance (release notes)typo, link and formatting fixes in seven release notes—nonen/a
10da1f19cdd95f2026-10-02fixTBN: VIF attach no longer fails with 500 on nodes that have port groups2168550POST /v1/nodes/{id}/vifs with TBNn/a
11595ceaa0a8822026-09-25fixTBN: a missing attribute reads as "" instead of raising2168550removes exception TBNAttributeRetrievalExceptionn/a
126024fc3363b42026-10-02fixTBN: comparisons against unset variables never match2168550VIF attach planningn/a
132986ca5df6682026-10-06fixneutron network interface: every port/port group carrying a tenant VIF must be plugged2169761deploy step switch_to_tenant_networkn/a
14639ccbb2d1072026-10-05fixTBN: execute only the first matching action on VIF attach2169647POST …/vifsn/a
156df69f9a7f3c2026-01-23fixTBN universal port/network constructors—TBN plannern/a
1605c88ec304ae2026-10-15securitysecret step arguments masked in conductor logs—logs, step error messagesn/a
172d0188bbe6682026-10-16fixGET /v1/allocations?node= for project-scoped users no longer 5002171179allocations listn/a
1800ffedff8c4e2026-10-05fixTBN: unhandled action raises NetworkError instead of silently not attaching2169647POST …/vifsn/a
19–2098d7937892c9, a9b3de60c9ef2026-10-07maintenance (docs)TBN documentation—nonen/a
21993565f27fdc2026-09-17securityRedfish vendor passthru validates BMC subscription ids (CVE-2026-90458)2166507* /v1/nodes/{id}/vendor_passthru?method=get_subscription|delete_subscriptionn/a
2239ce09ec3b0d2026-09-08securityPATCH /v1/nodes/{id} on /maintenance now needs baremetal:node:set_maintenance (CVE-2026-98419)2166510node update policyn/a

Change specifications

10. TBN port groups have no vendor — fix

  • Commit: da1f19cdd95ffea85311385d403f303c8e333b0e — review https://review.opendev.org/q/Iffc792719530ff688be2920cd57bb9edc02bb821 — related bug 2168550 — backport of 29fdb86db31d.
  • Before / after: with Trait Based Networking enabled, any VIF attach on a node that had port groups failed with HTTP 500 ("'Portgroup' object has no attribute 'vendor'") while building the plan. Now port groups are planned with vendor = None (ironic/common/trait_based_networking/base.py:479).
  • Impact on the specification: 01 § 4.5 VIFs; no new error code.
  • Upgrade / operations: none.
  • Carrying it over: standalone; tests in ironic/tests/unit/common/trait_based_networking/test_base.py.

11. Missing TBN attributes read as empty — fix

  • Commit: 595ceaa0a882e2a25c2c30b22c357e48da5c7877 — closes bug 2168550 — double backport (940617bbc37e, 13597c70d368).
  • Before / after: _retrieve_attribute raised TBNAttributeRetrievalException when an attribute was None; it now returns "" (ironic/common/trait_based_networking/base.py:155). The exception class is removed from ironic/common/exception.py.
  • Impact: the error catalogue loses one class; filter expressions on missing fields evaluate instead of failing the attach.
  • Carrying it over: before 12 (same file).

12. Unset variables never match — fix

  • Commit: 6024fc3363b408085e2f32f34de831e9713d936d — related bug 2168550.
  • Before / after: comparing an unset variable (port.vendor of a port group, port.category unset) raised TypeError or a prefix-match type error for ordering comparators, and != matched everything. Now an unset variable never matches, whatever the comparator (ironic/common/trait_based_networking/base.py:72).
  • Impact: TBN filter semantics (documented in doc/source/references/trait-based-networking/filter-expression-reference.rst); a rewrite of TBN must implement "None never matches".
  • Carrying it over: after 10 and 11.

13. Plug every port carrying a tenant VIF — fix

  • Commit: 2986ca5df668826053d90760e69871e51f860f22 — related bug 2169761.
  • Before / after: configure_tenant_networks of the neutron interface skipped ports belonging to a port group and succeeded if any port could be plugged, counting VifNotAttached. Now it selects up front the ports and port groups that have a tenant VIF in internal_info, including member ports, and every one must be plugged; any NetworkError fails the deploy (ironic/drivers/modules/network/neutron.py:181).
  • Impact on the specification: deploy step switch_to_tenant_network (05 § 3.2); failures are now reported instead of leaving a half-plugged node.
  • Upgrade / operations: deployments that relied on partial plugging now fail with "No neutron ports or portgroups are associated with node …" or a Neutron error.
  • Carrying it over: standalone; tests in ironic/tests/unit/drivers/modules/network/test_neutron.py.

14. First matching TBN action only — fix

  • Commit: 639ccbb2d1072aa11576d354de165636188f3512 — closes bug 2169647.
  • Before / after: when a port is in a port group both attach_portgroup and attach_port matched; Ironic bound the VIF twice and the second binding failed the whole vif_attach. Now only the first action runs (ironic/drivers/modules/network/common.py:731).
  • Carrying it over: prerequisite of 18.

15. TBN universal constructors — fix

  • Commit: 6df69f9a7f3c114b8be5beeba40bb8aa2d051bf0 (authored 2026-01-23, backported later).
  • Before / after: Port.universal_port() raised TypeError (missing dataclass fields) and Network.universal_network() used an integer id; both fixed (ironic/common/trait_based_networking/base.py:447, ironic/common/trait_based_networking/base.py:508). [inferred] Only reachable through TBN traits that target the universal port/network.

16. Mask secret step arguments in logs — security

  • Commit: 05c88ec304ae27dda0ecaea2525f1ca3911ecaa5, backport of 8a772ff67f80.
  • Before / after: the conductor logged the full step dictionaries (including arguments such as BMC or BIOS passwords passed to steps) when starting, listing and finishing clean/deploy/service steps, and put them in last_error. Now sanitize_steps() returns a masked copy for logs and error messages (ironic/conductor/utils.py:2206), also used by log_step_flow_history (ironic/conductor/utils.py:2224).
  • Impact: last_error texts for step failures now show masked arguments; 02 § 4.
  • Upgrade / operations: logs written before the fix may contain secrets: rotate them.
  • Carrying it over: touches ironic/conductor/cleaning.py, ironic/conductor/deployments.py, ironic/conductor/servicing.py, ironic/conductor/steps.py, ironic/conductor/utils.py; likely conflicts on a diverged conductor.

17. Ambiguous owner column when listing allocations by node — fix

  • Commit: 2d0188bbe6680ae0dbff609b3afdbf8094a22a52 — closes bug 2171179.
  • Before / after: GET /v1/allocations?node=<uuid> joins nodes; the project filter filter_by(owner=…) became ambiguous and answered 500 to project-scoped users. Filters now name Allocation columns explicitly (ironic/db/sqlalchemy/api.py:368, ironic/db/sqlalchemy/api.py:627).
  • Impact: 01 § 4.7; a rewrite must qualify columns in joined queries.

18. Unhandled TBN action is an error — fix

  • Commit: 00ffedff8c4ec5c232a65f6e360669c0601310ef — related bug 2169647.
  • Before / after: an action the driver cannot handle (e.g. bond_ports) only logged a malformed warning and the VIF stayed unattached; the planner also crashed with TypeError building NotImplementedAction. Now vif_attach fails with NetworkError "…Trait Based Networking selected an action which cannot be handled…" (ironic/drivers/modules/network/common.py:777, ironic/common/trait_based_networking/plan.py:114).
  • Carrying it over: after 14.

21. Redfish subscription id validation — security (CVE-2026-90458)

  • Commit: 993565f27fdc0386781ecb6864054dbde99f7315 — closes bug 2166507.
  • Before / after: the Redfish vendor passthru methods get_subscription and delete_subscription put the user-supplied id into a BMC URL unchecked, letting a caller with vendor-passthru rights send arbitrary GET/DELETE requests to the BMC's Redfish tree with the conductor's BMC-admin credentials (path traversal). Now ids containing RFC 1738 unsafe characters or .. are refused with 400 InvalidParameterValue (ironic/common/validate.py:20, ironic/drivers/modules/redfish/vendor.py:214, ironic/drivers/modules/redfish/vendor.py:301).
  • Impact: 02 (new 400 situation); requirement for the Go Redfish layer: never build BMC URLs from unvalidated input.

22. Maintenance through PATCH needs the maintenance policy — security (CVE-2026-98419)

  • Commit: 39ce09ec3b0d4de31bb092f1507784a0240b7aaa — closes bug 2166510.
  • Before / after: PATCH /v1/nodes/{id} with /maintenance or /maintenance_reason only needed the generic update policy, bypassing baremetal:node:set_maintenance that guards PUT …/maintenance. Both paths are now mapped to that policy (ironic/api/controllers/v1/node.py:3165); 52 new RBAC cases in ironic/tests/unit/api/test_rbac_project_scoped.yaml (they are part of the replayed RBAC matrix, 07 § 7).
  • Points of attention: the commit message says CVE-2026-98419, the release note file name says cve-2026-89419: one of them is a typo.
  • Impact: 01 § 4.2 (per-path policies of PATCH): a rewrite must keep the per-field policy table including these two entries.

Maintenance-only changes

CommitSubjectWhy it is usually not carried over
64b234a31146Update .gitreview for stable/2026.2branch plumbing
763b5b6de2c3Update TOX_CONSTRAINTS_FILE for stable/2026.2CI
eebc97a29445, 887cbbaefe5a, ffdd38e0a1cd, e38b203fed14, e1e9389338fe, 29a3bb3457fa, 10410bed35c0release-note fixes (bug links, typos, code quoting)documentation of changes already in 39.0.0
98d7937892c9, a9b3de60c9efTBN documentationdocumentation

Carry-over plan

No target was given. For a fork of 39.0.0, in application order:

git cherry-pick -x 595ceaa0a882e2a25c2c30b22c357e48da5c7877   # TBN: missing attribute = "" (11)
git cherry-pick -x da1f19cdd95ffea85311385d403f303c8e333b0e   # TBN: portgroup vendor (10)
git cherry-pick -x 6024fc3363b408085e2f32f34de831e9713d936d   # TBN: unset never matches (12)
git cherry-pick -x 2986ca5df668826053d90760e69871e51f860f22   # neutron: plug all tenant VIFs (13)
git cherry-pick -x 639ccbb2d1072aa11576d354de165636188f3512   # TBN: first action only (14)
git cherry-pick -x 6df69f9a7f3c114b8be5beeba40bb8aa2d051bf0   # TBN: universal constructors (15)
git cherry-pick -x 05c88ec304ae27dda0ecaea2525f1ca3911ecaa5   # mask secrets in step logs (16)
git cherry-pick -x 2d0188bbe6680ae0dbff609b3afdbf8094a22a52   # allocation owner filter (17)
git cherry-pick -x 00ffedff8c4ec5c232a65f6e360669c0601310ef   # TBN: unhandled action error (18)
git cherry-pick -x 993565f27fdc0386781ecb6864054dbde99f7315   # CVE-2026-90458 (21)
git cherry-pick -x 39ce09ec3b0d4de31bb092f1507784a0240b7aaa   # CVE-2026-98419 (22)

For openkeel-ironic the list is a requirements list, not a patch list: items 16, 17, 21 and 22 apply to the Go rewrite (mask step secrets, qualified joins, validated BMC URL components, per-path PATCH policies); TBN items apply only if TBN is implemented.

Source: reverse-spec-ironic/06-change-history_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.