[OVN] Handle OVN agents when "Chassis" register is deleted
If an "ovn-controller" ends not gracefully, the node "Chassis" and "Chassis_Private" registers will remain in the OVN SB database. Because there is no a mandatory procedure to delete the "Chassis" and "Chassis_Private" registers, the administrator can manually delete, from the OVN SB database, any register in any order. If the "Chassis" register is deleted and the Neutron server restarted, the updated "Chassis_Private" register will be read from the database. That won't contain the "Chassis" information as this register has been deleted. In this case, the ``NeutronAgent`` returns ``DeletedChassis``, an empty chassis register with no information. NOTE: the sequence of actions ("Chassis" register deletion, Neutron server restart) must be follow to reproduce this issue. If the "Chassis" register is deleted, the Neutron server OVN agent local cache won't update the stored information and will keep the previous value. It is when the Neutron server is restarted when the OVN agent local cache is retrieved again; at this time the "Chassis_Private" register won't have any related "Chassis" register. Closes-Bug: #1951149 Conflicts: neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py Change-Id: I17aa53cea6aba8ea83187c99102a6f25fd33cfff (cherry picked from commitf1a5511e90
) (cherry picked from commit29998538ce
)
This commit is contained in:
parent
8418c3e1ce
commit
494cd8ca5d
|
@ -20,6 +20,12 @@ from neutron.common.ovn import constants as ovn_const
|
|||
from neutron.common.ovn import utils as ovn_utils
|
||||
|
||||
|
||||
class DeletedChassis(object):
|
||||
external_ids = {}
|
||||
hostname = '("Chassis" register deleted)'
|
||||
name = '("Chassis" register deleted)'
|
||||
|
||||
|
||||
class NeutronAgent(abc.ABC):
|
||||
types = {}
|
||||
|
||||
|
@ -35,9 +41,12 @@ class NeutronAgent(abc.ABC):
|
|||
def get_chassis(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 updated_at(self):
|
||||
|
|
|
@ -846,12 +846,12 @@ class AgentWaitEvent(event.WaitEvent):
|
|||
|
||||
ONETIME = False
|
||||
|
||||
def __init__(self, driver, chassis_names):
|
||||
def __init__(self, driver, chassis_names, events=None, timeout=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'
|
||||
super().__init__(events, table, None, timeout=timeout)
|
||||
self.event_name = "AgentWaitEvent"
|
||||
|
||||
def match_fn(self, event, row, old):
|
||||
return row.name in self.chassis_names
|
||||
|
@ -909,6 +909,21 @@ 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,),
|
||||
timeout=1)
|
||||
self.sb_api.idl.notify_handler.watch_event(agent_event)
|
||||
self.sb_api.chassis_del(self.chassis, if_exists=True).execute(
|
||||
check_error=False)
|
||||
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)
|
||||
|
||||
|
||||
class ConnectionInactivityProbeSetEvent(event.WaitEvent):
|
||||
"""Wait for a Connection (NB/SB) to have the inactivity probe set"""
|
||||
|
|
Loading…
Reference in New Issue