Merge "[OVN] Handle OVN agents when "Chassis" register is deleted"

This commit is contained in:
Zuul 2022-04-21 18:01:26 +00:00 committed by Gerrit Code Review
commit aaec167c1c
2 changed files with 46 additions and 7 deletions

View File

@ -23,6 +23,12 @@ from neutron.common.ovn import utils as ovn_utils
from neutron.common import utils
class DeletedChassis(object):
external_ids = {}
hostname = '("Chassis" register deleted)'
name = '("Chassis" register deleted)'
class NeutronAgent(abc.ABC):
types = {}
@ -45,9 +51,12 @@ class NeutronAgent(abc.ABC):
def chassis_from_private(chassis_private):
try:
return chassis_private.chassis[0]
except (AttributeError, IndexError):
except AttributeError:
# No Chassis_Private support, just use Chassis
return chassis_private
except IndexError:
# Chassis register has been deleted but not Chassis_Private.
return DeletedChassis
@property
def chassis(self):

View File

@ -997,9 +997,9 @@ class AgentWaitEvent(event.WaitEvent):
ONETIME = False
def __init__(self, driver, chassis_names):
def __init__(self, driver, chassis_names, events=None):
table = driver.agent_chassis_table
events = (self.ROW_CREATE,)
events = events or (self.ROW_CREATE,)
self.chassis_names = chassis_names
super().__init__(events, table, None)
self.event_name = "AgentWaitEvent"
@ -1059,11 +1059,41 @@ class TestAgentApi(base.TestOVNFunctionalBase):
self.context, filters={'host': self.host})]
self.assertCountEqual(list(self.agent_types.values()), agent_ids)
# "ovn-controller" ends without deleting "Chassis" and
# "Chassis_Private" registers. If "Chassis" register is deleted,
# then Chassis_Private.chassis = []; both metadata and controller
# agents will still be present in the agent list.
agent_event = AgentWaitEvent(self.mech_driver, [self.chassis],
events=(event.RowEvent.ROW_UPDATE,))
self.sb_api.idl.notify_handler.watch_event(agent_event)
self.sb_api.chassis_del(self.chassis).execute(check_error=True)
self.assertTrue(agent_event.wait())
agent_ids = [a['id'] for a in self.plugin.get_agents(
self.context, filters={'host': self.host})]
self.assertCountEqual(list(self.agent_types.values()), agent_ids)
def test_agent_delete(self):
for agent_id in self.agent_types.values():
self.plugin.delete_agent(self.context, agent_id)
self.assertRaises(agent_exc.AgentNotFound, self.plugin.get_agent,
self.context, agent_id)
# Non OVN agent deletion.
agent_id = self.agent_types[self.TEST_AGENT]
self.plugin.delete_agent(self.context, agent_id)
self.assertRaises(agent_exc.AgentNotFound, self.plugin.get_agent,
self.context, agent_id)
# OVN controller agent deletion, that triggers the "Chassis" register
# deletion. The "Chassis" register deletion triggers the host OVN
# agents deletion, both controller and metadata if present.
controller_id = self.agent_types[ovn_const.OVN_CONTROLLER_AGENT]
metadata_id = self.agent_types[ovn_const.OVN_METADATA_AGENT]
self.plugin.delete_agent(self.context, controller_id)
self.assertRaises(agent_exc.AgentNotFound, self.plugin.get_agent,
self.context, controller_id)
self.assertEqual(
metadata_id,
self.plugin.get_agent(self.context, metadata_id)['id'])
self.plugin.delete_agent(self.context, metadata_id)
self.assertRaises(agent_exc.AgentNotFound, self.plugin.get_agent,
self.context, metadata_id)
class ConnectionInactivityProbeSetEvent(event.WaitEvent):