From bda9c0e49359fab5edf09d67dd79851740d337f9 Mon Sep 17 00:00:00 2001 From: Doug Goldstein Date: Tue, 15 Sep 2026 15:06:40 -0500 Subject: [PATCH 1/5] fix(neutron): pin networking-baremetal to stable/2026.1 The airship base image installs networking-baremetal from PyPI unpinned, so a rebuild picks up whatever is current. Today that is 8.1.0, from the series after 2026.1, whose CI only ever ran against master constraints. The 2026.1 series is 7.x, and stable/2026.1 is the only branch gated against the 2026.1 library set the image ships. Install it from git alongside neutron and neutron-lib so the version is deterministic and matches our release. --- containers/neutron/Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/containers/neutron/Dockerfile b/containers/neutron/Dockerfile index 0ef7b9c27..2500d28e0 100644 --- a/containers/neutron/Dockerfile +++ b/containers/neutron/Dockerfile @@ -15,6 +15,11 @@ ARG NEUTRON_LIB_GIT_REF=6d0367183cc92656ba449acefd830cb4e11f2f5b ADD --keep-git-dir=true https://github.com/rackerlabs/neutron-lib.git#${NEUTRON_LIB_GIT_REF} /src/neutron-lib RUN git -C /src/neutron-lib fetch --unshallow --tags +# renovate: name=openstack/networking-baremetal repo=https://github.com/openstack/networking-baremetal.git branch=stable/2026.1 +ARG NETWORKING_BAREMETAL_GIT_REF=e713f05659b1bf2794a462ab8aa13ee367ef4045 +ADD --keep-git-dir=true https://github.com/openstack/networking-baremetal.git#${NETWORKING_BAREMETAL_GIT_REF} /src/networking-baremetal +RUN git -C /src/networking-baremetal fetch --unshallow --tags + COPY python/neutron-understack /src/neutron-understack ARG OPENSTACK_VERSION="required_argument" @@ -32,6 +37,7 @@ RUN --mount=type=cache,target=/root/.cache/uv \ --constraint /upper-constraints.txt \ /src/neutron \ /src/neutron-lib \ + /src/networking-baremetal \ /src/neutron-understack ARG OPENSTACK_VERSION="required_argument" From 417e7670851c4c04d7525dc4061a3d583da9856f Mon Sep 17 00:00:00 2001 From: Doug Goldstein Date: Tue, 15 Sep 2026 15:06:51 -0500 Subject: [PATCH 2/5] fix(neutron): run the neutron RPC server neutron-server runs under uWSGI, which serves the API only, so the rpc_workers setting in neutron.conf is inert and nothing consumes the agent state report topic. neutron-ironic-agent therefore never registers as a baremetal agent: report_state is a cast, so the agent logs successful reports while every one of them is discarded. Enable the rpc-server deployment and drop the claim that it only sends requests to agents, which is what kept it off. secret_ks_etc is false here, so every component has to list its etcSources explicitly. neutron_rpc_server and neutron_periodic_worker were missing and would get an empty /etc/neutron/neutron.conf.d instead of the keystone, ironic, nova and placement service user credentials. Run two replicas so agent state reports survive a rollout or a drain. Assisted-by: Claude Opus 5 --- components/images-openstack.yaml | 2 ++ components/neutron/values.yaml | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/components/images-openstack.yaml b/components/images-openstack.yaml index 490161535..9db07b1f8 100644 --- a/components/images-openstack.yaml +++ b/components/images-openstack.yaml @@ -46,6 +46,8 @@ images: neutron_server: "ghcr.io/rackerlabs/understack/neutron:2026.1" neutron_rpc_server: "ghcr.io/rackerlabs/understack/neutron:2026.1" neutron_ovn_maintenance_worker: "ghcr.io/rackerlabs/understack/neutron:2026.1" + neutron_ironic_agent: "ghcr.io/rackerlabs/understack/neutron:2026.1" + neutron_ironic_agent_init: "ghcr.io/rackerlabs/understack/neutron:2026.1" neutron_bagpipe_bgp: "ghcr.io/rackerlabs/understack/neutron:2026.1" neutron_netns_cleanup_cron: "ghcr.io/rackerlabs/understack/neutron:2026.1" diff --git a/components/neutron/values.yaml b/components/neutron/values.yaml index fd8bf06e0..85f1135cf 100644 --- a/components/neutron/values.yaml +++ b/components/neutron/values.yaml @@ -136,11 +136,19 @@ pod: neutron_ovn_maintenance_worker: - secret: name: neutron-ks-etc + neutron_rpc_server: + - secret: + name: neutron-ks-etc + neutron_periodic_worker: + - secret: + name: neutron-ks-etc use_fqdn: neutron_agent: false replicas: server: 4 + # More than one so agent state reports survive a rollout or node drain. + rpc_server: 2 lifecycle: disruption_budget: server: @@ -255,14 +263,16 @@ manifests: # - neutron-metadata-agent # - neutron-ovs-agent # - neutron-sriov-agent - # - neutron-rpc-agent (this sends requests to the various agents) # https://docs.openstack.org/ironic/latest/admin/ovn-networking.html daemonset_dhcp_agent: false daemonset_l3_agent: false daemonset_lb_agent: false daemonset_metadata_agent: false daemonset_ovs_agent: false - deployment_rpc_server: false + # neutron-server runs under uWSGI, which serves the API only. The RPC + # server is what receives report_state and get_agents from agents, so + # neutron-ironic-agent cannot register without it. + deployment_rpc_server: true deployment_ovn_maintenance_worker: true # The janitor only needs the OVN maintenance worker. The chart enables the # generic periodic worker by default; disable it. From e8a0dd5b72c74f77cb633f35eddea70cf8bf6293 Mon Sep 17 00:00:00 2001 From: Doug Goldstein Date: Mon, 21 Sep 2026 09:47:21 -0500 Subject: [PATCH 3/5] fix(neutron): bump the neutron chart to 2026.1.45+5b923efb7 Picks up the ironic agent's ovn-neutron-init container and its --config-file /tmp/pod-shared/ovn.ini argument, so ironic-neutron-agent takes ovn_nb_connection from the chart instead of falling back to tcp:127.0.0.1:6641 with OVN event-driven reconciliation disabled. --- charts/argocd-understack/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/argocd-understack/values.yaml b/charts/argocd-understack/values.yaml index 1fbeb8ef1..21c72de3a 100644 --- a/charts/argocd-understack/values.yaml +++ b/charts/argocd-understack/values.yaml @@ -407,7 +407,7 @@ site: wave: 2 # -- Chart version for Neutron # renovate: datasource=helm depName=neutron registryUrl=https://tarballs.opendev.org/openstack/openstack-helm - chartVersion: 2026.1.41+7c81bea7c + chartVersion: 2026.1.47+6a45d0ecf # -- Placement (Placement Service) placement: From acb5a8800c2f9e30b2c97541dc6d1720f387f64e Mon Sep 17 00:00:00 2001 From: Doug Goldstein Date: Mon, 21 Sep 2026 10:40:51 -0500 Subject: [PATCH 4/5] feat(neutron): enable periodic worker The periodic worker can be used by flavor plugins like our router plugins to run operations like validations and cleanups out of band from API calls. Add the missing container reference and fix up the OVN metadata agent container as well. --- components/images-openstack.yaml | 3 ++- components/neutron/values.yaml | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/components/images-openstack.yaml b/components/images-openstack.yaml index 9db07b1f8..d86ccb51a 100644 --- a/components/images-openstack.yaml +++ b/components/images-openstack.yaml @@ -41,13 +41,14 @@ images: neutron_l2gw: "ghcr.io/rackerlabs/understack/neutron:2026.1" neutron_linuxbridge_agent: "ghcr.io/rackerlabs/understack/neutron:2026.1" neutron_metadata: "ghcr.io/rackerlabs/understack/neutron:2026.1" - neutron_ovn_metadata: "ghcr.io/rackerlabs/understack/neutron:2026.1" + neutron_ovn_metadata_agent: "ghcr.io/rackerlabs/understack/neutron:2026.1" neutron_openvswitch_agent: "ghcr.io/rackerlabs/understack/neutron:2026.1" neutron_server: "ghcr.io/rackerlabs/understack/neutron:2026.1" neutron_rpc_server: "ghcr.io/rackerlabs/understack/neutron:2026.1" neutron_ovn_maintenance_worker: "ghcr.io/rackerlabs/understack/neutron:2026.1" neutron_ironic_agent: "ghcr.io/rackerlabs/understack/neutron:2026.1" neutron_ironic_agent_init: "ghcr.io/rackerlabs/understack/neutron:2026.1" + neutron_periodic_worker: "ghcr.io/rackerlabs/understack/neutron:2026.1" neutron_bagpipe_bgp: "ghcr.io/rackerlabs/understack/neutron:2026.1" neutron_netns_cleanup_cron: "ghcr.io/rackerlabs/understack/neutron:2026.1" diff --git a/components/neutron/values.yaml b/components/neutron/values.yaml index 85f1135cf..e84715fd0 100644 --- a/components/neutron/values.yaml +++ b/components/neutron/values.yaml @@ -274,9 +274,6 @@ manifests: # neutron-ironic-agent cannot register without it. deployment_rpc_server: true deployment_ovn_maintenance_worker: true - # The janitor only needs the OVN maintenance worker. The chart enables the - # generic periodic worker by default; disable it. - deployment_periodic_worker: false daemonset_sriov_agent: false daemonset_l2gw_agent: false daemonset_bagpipe_bgp: false From be2a2cdae7f71f57a5718dc1074b5a14396d03f8 Mon Sep 17 00:00:00 2001 From: Doug Goldstein Date: Mon, 21 Sep 2026 16:18:53 -0500 Subject: [PATCH 5/5] fix(neutron): disable networking-baremetal l2vni trunk reconciler We are not using the networking-baremetal l2vni support yet so the trunk reconciler runs and attempts to recreate the anchor network and fails since we do not have geneve enabled by default. So disable it but also when we do go to enable it in the future, pre-emptively change to vxlan. --- components/neutron/values.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/components/neutron/values.yaml b/components/neutron/values.yaml index e84715fd0..f000c2acd 100644 --- a/components/neutron/values.yaml +++ b/components/neutron/values.yaml @@ -87,6 +87,20 @@ conf: default_availability_zones: "" # add 50 to the max MTU we want of 9000 to handle Neutron's -50 for VXLAN type global_physnet_mtu: 9050 + l2vni: + # networking-baremetal ships an L2VNI trunk reconciler that manages + # trunk subports for network nodes off OVN ha_chassis_group membership. + # We do not use it, neutron-understack owns baremetal VLAN binding here. + # Both flags have to be off: the agent initializes the trunk manager if + # either one is set, and the event-driven path reconciles on every OVN + # localnet port change regardless of the periodic flag. + enable_l2vni_trunk_reconciliation: false + enable_l2vni_trunk_reconciliation_events: false + # Only read when the reconciler above is turned back on. It defaults to + # 'geneve', which is not in our ml2 type_drivers, so creating the anchor + # networks fails outright instead of falling back. 'vxlan' is the only + # other accepted value. + l2vni_subport_anchor_network_type: "vxlan" oslo_messaging_notifications: driver: messagingv2 oslo_messaging_rabbit: