Skip to content

Commit 99b712b

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 46aefeb commit 99b712b

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
@@ -894,3 +896,35 @@ def run_idl(self, txn):
894896
virtual_parents)
895897

896898
setattr(lsp, 'options', options)
899+
900+
901+
class DbSetCommand(command.BaseCommand):
902+
def __init__(self, api, table, record, *col_values, if_exists=False,
903+
**columns):
904+
super().__init__(api)
905+
self.table = table
906+
self.record = record
907+
self.col_values = col_values or columns.items()
908+
self.if_exists = if_exists
909+
910+
def run_idl(self, txn):
911+
try:
912+
record = self.api.lookup(self.table, self.record)
913+
except idlutils.RowNotFound:
914+
if self.if_exists:
915+
return
916+
raise
917+
918+
for col, val in self.col_values:
919+
if isinstance(val, abc.Mapping):
920+
if isinstance(val, collections.OrderedDict):
921+
val = dict(val)
922+
existing = getattr(record, col, {})
923+
existing.update(val)
924+
val = existing
925+
# Since we are updating certain keys and leaving existing keys
926+
# but rewriting the whole external_ids column, we must verify()
927+
record.verify(col)
928+
# For non-map columns, we unconditionally overwrite the values that
929+
# exist, so prior state doesn't matter and we don't need verify()
930+
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
@@ -811,6 +811,10 @@ def unset_lswitch_port_to_virtual_type(self, lport_name,
811811
def update_lb_external_ids(self, lb_name, values, if_exists=True):
812812
return cmd.UpdateLbExternalIds(self, lb_name, values, if_exists)
813813

814+
def db_set(self, table, record, *col_values, if_exists=True, **columns):
815+
return cmd.DbSetCommand(self, table, record, *col_values,
816+
if_exists=if_exists, **columns)
817+
814818

815819
class OvsdbSbOvnIdl(sb_impl_idl.OvnSbApiIdlImpl, Backend):
816820
def __init__(self, connection):
@@ -930,3 +934,7 @@ def get_ports_on_chassis(self, chassis):
930934
# and just start using chassis objects so db_find_rows could be used
931935
rows = self.db_list_rows('Port_Binding').execute(check_error=True)
932936
return [r for r in rows if r.chassis and r.chassis[0].name == chassis]
937+
938+
def db_set(self, table, record, *col_values, if_exists=True, **columns):
939+
return cmd.DbSetCommand(self, table, record, *col_values,
940+
if_exists=if_exists, **columns)

0 commit comments

Comments
 (0)