Skip to content

Commit c8c7214

Browse files
fix(neutron): Fix for neutron+ovn chassis register deleted issue
1 parent 60d61ad commit c8c7214

3 files changed

Lines changed: 67 additions & 0 deletions

File tree

containers/neutron/Dockerfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ RUN --mount=type=cache,target=/root/.cache/uv \
2929
/src/neutron-lib \
3030
/src/neutron-understack
3131

32+
RUN apt-get update && \
33+
apt-get install -y --no-install-recommends \
34+
patch \
35+
quilt \
36+
&& apt-get clean && rm -rf /var/lib/apt/lists/*
37+
38+
COPY containers/neutron/patches /tmp/patches/
39+
RUN cd /var/lib/openstack/lib/python3.12/site-packages && \
40+
QUILT_PATCHES=/tmp/patches quilt push -a
41+
3242
ARG OPENSTACK_VERSION="required_argument"
3343
FROM quay.io/airshipit/neutron:${OPENSTACK_VERSION}-ubuntu_noble AS final
3444

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
Description: Prevent ghost OVN agents from orphaned Chassis_Private rows
2+
When a Chassis row is deleted but its Chassis_Private persists (e.g.
3+
ungraceful ovn-controller shutdown in containers), the ROW_CREATE path
4+
in ChassisAgentWriteEvent and ChassisOVNAgentWriteEvent would add an
5+
agent to the cache with the DeletedChassis sentinel hostname
6+
'("Chassis" register deleted)'. This patch gates ROW_CREATE on
7+
row.chassis being non-empty, consistent with the ROW_UPDATE path and
8+
the AgentCache.populate() method which already skips such rows.
9+
Author: Nicholas Kuechler
10+
11+
--- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovsdb_monitor.py
12+
+++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovsdb_monitor.py
13+
@@ -359,13 +359,17 @@
14+
class ChassisAgentWriteEvent(ChassisAgentEvent):
15+
events = (BaseEvent.ROW_CREATE, BaseEvent.ROW_UPDATE)
16+
17+
def match_fn(self, event, row, old=None):
18+
# On updates to Chassis_Private because the Chassis has been deleted,
19+
# don't update the AgentCache. We use chassis_private.chassis to return
20+
- # data about the agent.
21+
- return (event == self.ROW_CREATE or
22+
- (hasattr(old, 'nb_cfg') and row.chassis))
23+
+ # data about the agent. Require a valid chassis reference for all
24+
+ # events including ROW_CREATE: an orphaned Chassis_Private (where the
25+
+ # Chassis row was already deleted) must not create a ghost agent entry.
26+
+ if not row.chassis:
27+
+ return False
28+
+ return (event == self.ROW_CREATE or
29+
+ (hasattr(old, 'nb_cfg') and row.chassis))
30+
31+
def run(self, event, row, old):
32+
n_agent.AgentCache().update(ovn_const.OVN_CONTROLLER_AGENT, row,
33+
clear_down=event == self.ROW_CREATE)
34+
@@ -427,14 +431,15 @@
35+
def match_fn(self, event, row, old=None):
36+
if not self.agent_id(row):
37+
# Don't create a cached object with an agent_id of 'None'
38+
return False
39+
- if event == self.ROW_CREATE:
40+
- return True
41+
42+
- # On updates to Chassis_Private because the Chassis has been
43+
- # deleted, don't update the AgentCache. We use
44+
- # chassis_private.chassis to return data about the agent.
45+
+ # Require a valid chassis reference for all events including
46+
+ # ROW_CREATE: an orphaned Chassis_Private (where the Chassis row
47+
+ # was already deleted) must not create a ghost agent entry.
48+
if not getattr(row, 'chassis', None):
49+
return False
50+
51+
+ if event == self.ROW_CREATE:
52+
+ return True
53+
+
54+
# Check if both rows have external_ids before comparing nb_cfg
55+
if not (hasattr(old, 'external_ids') and row.external_ids):
56+
return False

containers/neutron/patches/series

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fix-ovn-ghost-chassis-agent.patch

0 commit comments

Comments
 (0)