diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/backports.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/backports.py new file mode 100644 index 00000000000..e31750683ef --- /dev/null +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/backports.py @@ -0,0 +1,64 @@ +# Copyright 2021 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +# We don't technically require ovs 2.10 or ovsdbapp that has these fixes so +# just include them here for stable releases +try: + from ovs.db import custom_index + + IndexEntryClass = custom_index.IndexEntryClass +except ImportError: + import collections + + from ovs.db import data + + def IndexEntryClass(table): + def defaults_uuid_to_row(atom, base): + return atom.value + + columns = ['uuid'] + list(table.columns.keys()) + cls = collections.namedtuple(table.name, columns) + cls._table = table + cls.__new__.__defaults__ = (None,) + tuple( + data.Datum.default(c.type).to_python(defaults_uuid_to_row) + for c in table.columns.values()) + return cls + + +try: + from ovsdbapp.backend.ovs_idl import idlutils + + frozen_row = idlutils.frozen_row +except AttributeError: + def frozen_row(row): + try: + IndexEntry = row._table.rows.IndexEntry + except AttributeError: + row._table.rows = IndexEntryClass(row._table) + return IndexEntry( + uuid=row.uuid, + **{col: getattr(row, col) + for col in row._table.columns if hasattr(row, col)}) + + +try: + from ovsdbapp.backend.ovs_idl import event as row_event + from ovsdbapp import event as ovsdb_event + + RowEventHandler = row_event.RowEventHandler +except AttributeError: + class RowEventHandler(ovsdb_event.RowEventHandler): + def notify(self, event, row, updates=None): + row = frozen_row(row) + super().notify(event, row, updates) diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovsdb_monitor.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovsdb_monitor.py index 71ba96a2b3b..5a170c4c5d2 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovsdb_monitor.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovsdb_monitor.py @@ -26,7 +26,6 @@ from ovs.stream import Stream from ovsdbapp.backend.ovs_idl import connection from ovsdbapp.backend.ovs_idl import event as row_event from ovsdbapp.backend.ovs_idl import idlutils -from ovsdbapp import event from neutron.common.ovn import constants as ovn_const from neutron.common.ovn import exceptions @@ -34,6 +33,7 @@ from neutron.common.ovn import hash_ring_manager from neutron.common.ovn import utils from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf from neutron.db import ovn_hash_ring_db +from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import backports CONF = cfg.CONF @@ -346,7 +346,7 @@ class FIPAddDeleteEvent(row_event.RowEvent): self.driver.delete_mac_binding_entries(row.external_ip) -class OvnDbNotifyHandler(event.RowEventHandler): +class OvnDbNotifyHandler(backports.RowEventHandler): def __init__(self, driver): super(OvnDbNotifyHandler, self).__init__() self.driver = driver @@ -362,7 +362,7 @@ class Ml2OvnIdlBase(connection.OvsdbIdl): class BaseOvnIdl(Ml2OvnIdlBase): def __init__(self, remote, schema): - self.notify_handler = event.RowEventHandler() + self.notify_handler = backports.RowEventHandler() super(BaseOvnIdl, self).__init__(remote, schema) @classmethod