Change history — ironic — branch stable/2026.2
Branch
stable/2026.2@39ce09ec3b0d— range752100ac7ff8..39ce09ec3b0d(merge-base withorigin/master, wherestable/2026.2left 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.
| # | Commit | Date | Category (corrected) | Change | Bug | Impact | In target |
|---|---|---|---|---|---|---|---|
| 1 | 64b234a31146 | 2026-09-21 | maintenance | .gitreview for the branch | — | none | n/a |
| 2 | 763b5b6de2c3 | 2026-09-21 | maintenance | tox constraints URL | — | none | n/a |
| 3–9 | eebc97a29445 … 10410bed35c0 | 2026-09-22 | maintenance (release notes) | typo, link and formatting fixes in seven release notes | — | none | n/a |
| 10 | da1f19cdd95f | 2026-10-02 | fix | TBN: VIF attach no longer fails with 500 on nodes that have port groups | 2168550 | POST /v1/nodes/{id}/vifs with TBN | n/a |
| 11 | 595ceaa0a882 | 2026-09-25 | fix | TBN: a missing attribute reads as "" instead of raising | 2168550 | removes exception TBNAttributeRetrievalException | n/a |
| 12 | 6024fc3363b4 | 2026-10-02 | fix | TBN: comparisons against unset variables never match | 2168550 | VIF attach planning | n/a |
| 13 | 2986ca5df668 | 2026-10-06 | fix | neutron network interface: every port/port group carrying a tenant VIF must be plugged | 2169761 | deploy step switch_to_tenant_network | n/a |
| 14 | 639ccbb2d107 | 2026-10-05 | fix | TBN: execute only the first matching action on VIF attach | 2169647 | POST …/vifs | n/a |
| 15 | 6df69f9a7f3c | 2026-01-23 | fix | TBN universal port/network constructors | — | TBN planner | n/a |
| 16 | 05c88ec304ae | 2026-10-15 | security | secret step arguments masked in conductor logs | — | logs, step error messages | n/a |
| 17 | 2d0188bbe668 | 2026-10-16 | fix | GET /v1/allocations?node= for project-scoped users no longer 500 | 2171179 | allocations list | n/a |
| 18 | 00ffedff8c4e | 2026-10-05 | fix | TBN: unhandled action raises NetworkError instead of silently not attaching | 2169647 | POST …/vifs | n/a |
| 19–20 | 98d7937892c9, a9b3de60c9ef | 2026-10-07 | maintenance (docs) | TBN documentation | — | none | n/a |
| 21 | 993565f27fdc | 2026-09-17 | security | Redfish vendor passthru validates BMC subscription ids (CVE-2026-90458) | 2166507 | * /v1/nodes/{id}/vendor_passthru?method=get_subscription|delete_subscription | n/a |
| 22 | 39ce09ec3b0d | 2026-09-08 | security | PATCH /v1/nodes/{id} on /maintenance now needs baremetal:node:set_maintenance (CVE-2026-98419) | 2166510 | node update policy | n/a |
Change specifications
10. TBN port groups have no vendor — fix
- Commit:
da1f19cdd95ffea85311385d403f303c8e333b0e— review https://review.opendev.org/q/Iffc792719530ff688be2920cd57bb9edc02bb821 — related bug 2168550 — backport of29fdb86db31d. - 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_attributeraisedTBNAttributeRetrievalExceptionwhen an attribute wasNone; it now returns""(ironic/common/trait_based_networking/base.py:155). The exception class is removed fromironic/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.vendorof a port group,port.categoryunset) raisedTypeErroror 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_networksof theneutroninterface skipped ports belonging to a port group and succeeded if any port could be plugged, countingVifNotAttached. Now it selects up front the ports and port groups that have a tenant VIF ininternal_info, including member ports, and every one must be plugged; anyNetworkErrorfails 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_portgroupandattach_portmatched; Ironic bound the VIF twice and the second binding failed the wholevif_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()raisedTypeError(missing dataclass fields) andNetwork.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 of8a772ff67f80. - 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. Nowsanitize_steps()returns a masked copy for logs and error messages (ironic/conductor/utils.py:2206), also used bylog_step_flow_history(ironic/conductor/utils.py:2224). - Impact:
last_errortexts 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>joinsnodes; the project filterfilter_by(owner=…)became ambiguous and answered 500 to project-scoped users. Filters now nameAllocationcolumns 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 withTypeErrorbuildingNotImplementedAction. Nowvif_attachfails withNetworkError"…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_subscriptionanddelete_subscriptionput the user-suppliedidinto 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 400InvalidParameterValue(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/maintenanceor/maintenance_reasononly needed the generic update policy, bypassingbaremetal:node:set_maintenancethat guardsPUT …/maintenance. Both paths are now mapped to that policy (ironic/api/controllers/v1/node.py:3165); 52 new RBAC cases inironic/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
| Commit | Subject | Why it is usually not carried over |
|---|---|---|
64b234a31146 | Update .gitreview for stable/2026.2 | branch plumbing |
763b5b6de2c3 | Update TOX_CONSTRAINTS_FILE for stable/2026.2 | CI |
eebc97a29445, 887cbbaefe5a, ffdd38e0a1cd, e38b203fed14, e1e9389338fe, 29a3bb3457fa, 10410bed35c0 | release-note fixes (bug links, typos, code quoting) | documentation of changes already in 39.0.0 |
98d7937892c9, a9b3de60c9ef | TBN documentation | documentation |
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.