Skip to content

Commit 1529c0a

Browse files
committed
[stable-only][ovn] Fix ovsdbapp db_set command for stable branches
The lack of an if_exists on the db_set function in ovsdbapp causes the network log object deletion to not be a asynchronous operation on the ML2/OVN plugin. The if_exists was recently added to ovsdbapp, but since that is an API change[0] it will not be backported to older branches, so this patch overrides the function. This way we avoid the possibility of getting errors when concurrently making operations with security groups and network log objects. Closes-bug: #2019887 [0] https://review.opendev.org/c/openstack/ovsdbapp/+/880687 Change-Id: I628591da75c1cc367076f5a3051ca3c1e131d216 (cherry picked from commit 551ba73)
1 parent 08a6168 commit 1529c0a

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/commands.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1212
# License for the specific language governing permissions and limitations
1313
# under the License.
14+
import collections
15+
from collections import abc
1416

1517
from oslo_utils import timeutils
1618
from ovsdbapp.backend.ovs_idl import command
@@ -922,3 +924,35 @@ def run_idl(self, txn):
922924
virtual_parents)
923925

924926
setattr(lsp, 'options', options)
927+
928+
929+
class DbSetCommand(command.BaseCommand):
930+
def __init__(self, api, table, record, *col_values, if_exists=False,
931+
**columns):
932+
super().__init__(api)
933+
self.table = table
934+
self.record = record
935+
self.col_values = col_values or columns.items()
936+
self.if_exists = if_exists
937+
938+
def run_idl(self, txn):
939+
try:
940+
record = self.api.lookup(self.table, self.record)
941+
except idlutils.RowNotFound:
942+
if self.if_exists:
943+
return
944+
raise
945+
946+
for col, val in self.col_values:
947+
if isinstance(val, abc.Mapping):
948+
if isinstance(val, collections.OrderedDict):
949+
val = dict(val)
950+
existing = getattr(record, col, {})
951+
existing.update(val)
952+
val = existing
953+
# Since we are updating certain keys and leaving existing keys
954+
# but rewriting the whole external_ids column, we must verify()
955+
record.verify(col)
956+
# For non-map columns, we unconditionally overwrite the values that
957+
# exist, so prior state doesn't matter and we don't need verify()
958+
self.set_column(record, col, val)

neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,10 @@ def unset_lswitch_port_to_virtual_type(self, lport_name,
828828
def update_lb_external_ids(self, lb_name, values, if_exists=True):
829829
return cmd.UpdateLbExternalIds(self, lb_name, values, if_exists)
830830

831+
def db_set(self, table, record, *col_values, if_exists=True, **columns):
832+
return cmd.DbSetCommand(self, table, record, *col_values,
833+
if_exists=if_exists, **columns)
834+
831835

832836
class OvsdbSbOvnIdl(sb_impl_idl.OvnSbApiIdlImpl, Backend):
833837
def __init__(self, connection):
@@ -948,3 +952,7 @@ def get_ports_on_chassis(self, chassis):
948952
# and just start using chassis objects so db_find_rows could be used
949953
rows = self.db_list_rows('Port_Binding').execute(check_error=True)
950954
return [r for r in rows if r.chassis and r.chassis[0].name == chassis]
955+
956+
def db_set(self, table, record, *col_values, if_exists=True, **columns):
957+
return cmd.DbSetCommand(self, table, record, *col_values,
958+
if_exists=if_exists, **columns)

0 commit comments

Comments
 (0)