Skip to content

Commit 6205158

Browse files
cubeekumago
authored andcommitted
ovn-metadata: Refactor events
The agent had multiple events matching the same event type and calling the same run() method. Also the same things as in match_fn() were checked later again in run() method. This patch squashes the events, as a result there are only Port Binding Update and Port Binding Delete events that either provision or teardown the resources. Related bug: #2036118 Change-Id: I13f4e95eacb3cbdd3170f9707b2310bfae13a2bc Signed-off-by: Jakub Libosvar <[email protected]> (cherry picked from commit 6801589)
1 parent d69d868 commit 6205158

File tree

2 files changed

+157
-158
lines changed

2 files changed

+157
-158
lines changed

neutron/agent/ovn/metadata/agent.py

Lines changed: 78 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@
4848

4949
NS_PREFIX = 'ovnmeta-'
5050
MAC_PATTERN = re.compile(r'([0-9A-F]{2}[:-]){5}([0-9A-F]{2})', re.I)
51-
OVN_VIF_PORT_TYPES = ("", "external", ovn_const.LSP_TYPE_LOCALPORT, )
51+
OVN_VIF_PORT_TYPES = (
52+
"", ovn_const.LSP_TYPE_EXTERNAL, ovn_const.LSP_TYPE_LOCALPORT)
5253

5354
MetadataPortInfo = collections.namedtuple('MetadataPortInfo', ['mac',
5455
'ip_addresses',
@@ -74,39 +75,31 @@ class ConfigException(Exception):
7475
"""
7576

7677

77-
class PortBindingChassisEvent(row_event.RowEvent):
78-
def __init__(self, metadata_agent, events):
78+
class PortBindingEvent(row_event.RowEvent):
79+
def __init__(self, metadata_agent):
7980
self.agent = metadata_agent
8081
table = 'Port_Binding'
81-
super(PortBindingChassisEvent, self).__init__(
82-
events, table, None)
82+
super().__init__((self.__class__.EVENT,), table, None)
8383
self.event_name = self.__class__.__name__
84+
self._log_msg = (
85+
"PortBindingEvent matched for logical port %s and network %s")
86+
87+
def log_row(self, row):
88+
net_name = ovn_utils.get_network_name_from_datapath(
89+
row.datapath)
90+
LOG.info(self._log_msg, row.logical_port, net_name)
91+
92+
def match_fn(self, event, row, old):
93+
return row.type in OVN_VIF_PORT_TYPES
8494

8595
def run(self, event, row, old):
8696
# Check if the port has been bound/unbound to our chassis and update
8797
# the metadata namespace accordingly.
8898
resync = False
89-
if row.type not in OVN_VIF_PORT_TYPES:
90-
return
91-
if row.type == ovn_const.LSP_TYPE_LOCALPORT:
92-
new_ext_ids = row.external_ids
93-
old_ext_ids = old.external_ids
94-
device_id = row.external_ids.get(
95-
ovn_const.OVN_DEVID_EXT_ID_KEY, "")
96-
if not device_id.startswith(NS_PREFIX):
97-
return
98-
new_cidrs = new_ext_ids.get(ovn_const.OVN_CIDRS_EXT_ID_KEY, "")
99-
old_cidrs = old_ext_ids.get(ovn_const.OVN_CIDRS_EXT_ID_KEY, "")
100-
# If old_cidrs is "", it is create event,
101-
# nothing needs to be done.
102-
# If old_cidrs equals new_cidrs, the ip does not change.
103-
if old_cidrs in ("", new_cidrs, ):
104-
return
99+
105100
with _SYNC_STATE_LOCK.read_lock():
101+
self.log_row(row)
106102
try:
107-
net_name = ovn_utils.get_network_name_from_datapath(
108-
row.datapath)
109-
LOG.info(self.LOG_MSG, row.logical_port, net_name)
110103
self.agent.provision_datapath(row.datapath)
111104
except ConfigException:
112105
# We're now in the reader lock mode, we need to exit the
@@ -116,63 +109,84 @@ def run(self, event, row, old):
116109
self.agent.resync()
117110

118111

119-
class PortBindingMetaPortUpdatedEvent(PortBindingChassisEvent):
120-
LOG_MSG = "Metadata Port %s in datapath %s updated."
112+
class PortBindingUpdatedEvent(PortBindingEvent):
113+
EVENT = PortBindingEvent.ROW_UPDATE
121114

122-
def __init__(self, metadata_agent):
123-
events = (self.ROW_UPDATE,)
124-
super(PortBindingMetaPortUpdatedEvent, self).__init__(
125-
metadata_agent, events)
115+
def __init__(self, *args, **kwargs):
116+
super().__init__(*args, **kwargs)
117+
self._match_checks = [
118+
self._is_localport_ext_ids_update,
119+
self._is_new_chassis_set,
120+
self._is_chassis_removed,
121+
]
126122

127123
def match_fn(self, event, row, old):
128-
if row.type == ovn_const.LSP_TYPE_LOCALPORT:
129-
if hasattr(row, 'external_ids') and hasattr(old, 'external_ids'):
130-
device_id = row.external_ids.get(
131-
ovn_const.OVN_DEVID_EXT_ID_KEY, "")
132-
if device_id.startswith(NS_PREFIX):
133-
return True
134-
return False
124+
if not super().match_fn(event, row, old):
125+
return False
126+
# if any of the check functions is true, the event should be triggered
127+
return any(check(row, old) for check in self._match_checks)
128+
129+
def _is_localport_ext_ids_update(self, row, old):
130+
if row.type != ovn_const.LSP_TYPE_LOCALPORT:
131+
return False
135132

133+
if not hasattr(old, 'external_ids'):
134+
return False
136135

137-
class PortBindingChassisCreatedEvent(PortBindingChassisEvent):
138-
LOG_MSG = "Port %s in datapath %s bound to our chassis"
136+
device_id = row.external_ids.get(
137+
ovn_const.OVN_DEVID_EXT_ID_KEY, "")
138+
if not device_id.startswith(NS_PREFIX):
139+
return False
139140

140-
def __init__(self, metadata_agent):
141-
events = (self.ROW_UPDATE,)
142-
super(PortBindingChassisCreatedEvent, self).__init__(
143-
metadata_agent, events)
141+
new_cidrs = row.external_ids.get(
142+
ovn_const.OVN_CIDRS_EXT_ID_KEY, "")
143+
old_cidrs = old.external_ids.get(
144+
ovn_const.OVN_CIDRS_EXT_ID_KEY, "")
145+
# If old_cidrs is "", it is create event,
146+
# nothing needs to be done.
147+
# If old_cidrs equals new_cidrs, the ip does not change.
148+
if old_cidrs not in ("", new_cidrs):
149+
self._log_msg = (
150+
"Metadata Port %s in datapath %s updated")
151+
return True
152+
return False
144153

145-
def match_fn(self, event, row, old):
154+
def _is_new_chassis_set(self, row, old):
155+
self._log_msg = "Port %s in datapath %s bound to our chassis"
146156
try:
147157
return (row.chassis[0].name == self.agent.chassis and
148158
not old.chassis)
149159
except (IndexError, AttributeError):
150160
return False
151161

162+
def _is_chassis_removed(self, row, old):
163+
self._log_msg = "Port %s in datapath %s unbound from our chassis"
164+
try:
165+
return (old.chassis[0].name == self.agent.chassis and
166+
not row.chassis)
167+
except (IndexError, AttributeError):
168+
return False
152169

153-
class PortBindingChassisDeletedEvent(PortBindingChassisEvent):
154-
LOG_MSG = "Port %s in datapath %s unbound from our chassis"
155170

156-
def __init__(self, metadata_agent):
157-
events = (self.ROW_UPDATE, self.ROW_DELETE)
158-
super(PortBindingChassisDeletedEvent, self).__init__(
159-
metadata_agent, events)
171+
class PortBindingDeletedEvent(PortBindingEvent):
172+
EVENT = PortBindingEvent.ROW_DELETE
160173

161174
def match_fn(self, event, row, old):
175+
if not super().match_fn(event, row, old):
176+
return False
162177
try:
163-
if event == self.ROW_UPDATE:
164-
return (old.chassis[0].name == self.agent.chassis and
165-
not row.chassis)
166-
else:
167-
if row.chassis[0].name == self.agent.chassis:
168-
if row.type != "external":
169-
LOG.warning(
170-
'Removing non-external type port %(port_id)s with '
171-
'type "%(type)s"',
172-
{"port_id": row.uuid, "type": row.type})
173-
return True
178+
if row.chassis[0].name != self.agent.chassis:
179+
return False
174180
except (IndexError, AttributeError):
175181
return False
182+
if row.type != ovn_const.LSP_TYPE_EXTERNAL:
183+
LOG.warning(
184+
'Removing non-external type port %(port_id)s with '
185+
'type "%(type)s"',
186+
{"port_id": row.uuid, "type": row.type})
187+
self._log_msg = (
188+
"Port %s in datapath %s unbound from our chassis")
189+
return True
176190

177191

178192
class ChassisCreateEventBase(row_event.RowEvent):
@@ -301,10 +315,10 @@ def start(self):
301315

302316
tables = ('Encap', 'Port_Binding', 'Datapath_Binding', 'SB_Global',
303317
'Chassis')
304-
events = (PortBindingChassisCreatedEvent(self),
305-
PortBindingChassisDeletedEvent(self),
318+
events = (PortBindingUpdatedEvent(self),
319+
PortBindingDeletedEvent(self),
306320
SbGlobalUpdateEvent(self),
307-
PortBindingMetaPortUpdatedEvent(self))
321+
)
308322

309323
# TODO(lucasagomes): Remove this in the future. Try to register
310324
# the Chassis_Private table, if not present, fallback to the normal

0 commit comments

Comments
 (0)