Skip to content

Commit 509ae3a

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "[OVN] Handle OVN agents when "Chassis" register is deleted" into stable/yoga
2 parents 061a80d + 669d7cc commit 509ae3a

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323
from neutron.common import utils
2424

2525

26+
class DeletedChassis(object):
27+
external_ids = {}
28+
hostname = '("Chassis" register deleted)'
29+
name = '("Chassis" register deleted)'
30+
31+
2632
class NeutronAgent(abc.ABC):
2733
types = {}
2834

@@ -45,9 +51,12 @@ def update(self, chassis_private, updated_at=None, clear_down=False):
4551
def chassis_from_private(chassis_private):
4652
try:
4753
return chassis_private.chassis[0]
48-
except (AttributeError, IndexError):
54+
except AttributeError:
4955
# No Chassis_Private support, just use Chassis
5056
return chassis_private
57+
except IndexError:
58+
# Chassis register has been deleted but not Chassis_Private.
59+
return DeletedChassis
5160

5261
@property
5362
def chassis(self):

neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -997,9 +997,9 @@ class AgentWaitEvent(event.WaitEvent):
997997

998998
ONETIME = False
999999

1000-
def __init__(self, driver, chassis_names):
1000+
def __init__(self, driver, chassis_names, events=None):
10011001
table = driver.agent_chassis_table
1002-
events = (self.ROW_CREATE,)
1002+
events = events or (self.ROW_CREATE,)
10031003
self.chassis_names = chassis_names
10041004
super().__init__(events, table, None)
10051005
self.event_name = "AgentWaitEvent"
@@ -1059,11 +1059,41 @@ def test_agent_list(self):
10591059
self.context, filters={'host': self.host})]
10601060
self.assertCountEqual(list(self.agent_types.values()), agent_ids)
10611061

1062+
# "ovn-controller" ends without deleting "Chassis" and
1063+
# "Chassis_Private" registers. If "Chassis" register is deleted,
1064+
# then Chassis_Private.chassis = []; both metadata and controller
1065+
# agents will still be present in the agent list.
1066+
agent_event = AgentWaitEvent(self.mech_driver, [self.chassis],
1067+
events=(event.RowEvent.ROW_UPDATE,))
1068+
self.sb_api.idl.notify_handler.watch_event(agent_event)
1069+
self.sb_api.chassis_del(self.chassis).execute(check_error=True)
1070+
self.assertTrue(agent_event.wait())
1071+
agent_ids = [a['id'] for a in self.plugin.get_agents(
1072+
self.context, filters={'host': self.host})]
1073+
self.assertCountEqual(list(self.agent_types.values()), agent_ids)
1074+
10621075
def test_agent_delete(self):
1063-
for agent_id in self.agent_types.values():
1064-
self.plugin.delete_agent(self.context, agent_id)
1065-
self.assertRaises(agent_exc.AgentNotFound, self.plugin.get_agent,
1066-
self.context, agent_id)
1076+
# Non OVN agent deletion.
1077+
agent_id = self.agent_types[self.TEST_AGENT]
1078+
self.plugin.delete_agent(self.context, agent_id)
1079+
self.assertRaises(agent_exc.AgentNotFound, self.plugin.get_agent,
1080+
self.context, agent_id)
1081+
1082+
# OVN controller agent deletion, that triggers the "Chassis" register
1083+
# deletion. The "Chassis" register deletion triggers the host OVN
1084+
# agents deletion, both controller and metadata if present.
1085+
controller_id = self.agent_types[ovn_const.OVN_CONTROLLER_AGENT]
1086+
metadata_id = self.agent_types[ovn_const.OVN_METADATA_AGENT]
1087+
self.plugin.delete_agent(self.context, controller_id)
1088+
self.assertRaises(agent_exc.AgentNotFound, self.plugin.get_agent,
1089+
self.context, controller_id)
1090+
self.assertEqual(
1091+
metadata_id,
1092+
self.plugin.get_agent(self.context, metadata_id)['id'])
1093+
1094+
self.plugin.delete_agent(self.context, metadata_id)
1095+
self.assertRaises(agent_exc.AgentNotFound, self.plugin.get_agent,
1096+
self.context, metadata_id)
10671097

10681098

10691099
class ConnectionInactivityProbeSetEvent(event.WaitEvent):

0 commit comments

Comments
 (0)