[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 551ba73aa4
)
This commit is contained in:
parent
08a6168a07
commit
1529c0a297
|
@ -11,6 +11,8 @@
|
|||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import collections
|
||||
from collections import abc
|
||||
|
||||
from oslo_utils import timeutils
|
||||
from ovsdbapp.backend.ovs_idl import command
|
||||
|
@ -922,3 +924,35 @@ class UnsetLSwitchPortToVirtualTypeCommand(command.BaseCommand):
|
|||
virtual_parents)
|
||||
|
||||
setattr(lsp, 'options', options)
|
||||
|
||||
|
||||
class DbSetCommand(command.BaseCommand):
|
||||
def __init__(self, api, table, record, *col_values, if_exists=False,
|
||||
**columns):
|
||||
super().__init__(api)
|
||||
self.table = table
|
||||
self.record = record
|
||||
self.col_values = col_values or columns.items()
|
||||
self.if_exists = if_exists
|
||||
|
||||
def run_idl(self, txn):
|
||||
try:
|
||||
record = self.api.lookup(self.table, self.record)
|
||||
except idlutils.RowNotFound:
|
||||
if self.if_exists:
|
||||
return
|
||||
raise
|
||||
|
||||
for col, val in self.col_values:
|
||||
if isinstance(val, abc.Mapping):
|
||||
if isinstance(val, collections.OrderedDict):
|
||||
val = dict(val)
|
||||
existing = getattr(record, col, {})
|
||||
existing.update(val)
|
||||
val = existing
|
||||
# Since we are updating certain keys and leaving existing keys
|
||||
# but rewriting the whole external_ids column, we must verify()
|
||||
record.verify(col)
|
||||
# For non-map columns, we unconditionally overwrite the values that
|
||||
# exist, so prior state doesn't matter and we don't need verify()
|
||||
self.set_column(record, col, val)
|
||||
|
|
|
@ -828,6 +828,10 @@ class OvsdbNbOvnIdl(nb_impl_idl.OvnNbApiIdlImpl, Backend):
|
|||
def update_lb_external_ids(self, lb_name, values, if_exists=True):
|
||||
return cmd.UpdateLbExternalIds(self, lb_name, values, if_exists)
|
||||
|
||||
def db_set(self, table, record, *col_values, if_exists=True, **columns):
|
||||
return cmd.DbSetCommand(self, table, record, *col_values,
|
||||
if_exists=if_exists, **columns)
|
||||
|
||||
|
||||
class OvsdbSbOvnIdl(sb_impl_idl.OvnSbApiIdlImpl, Backend):
|
||||
def __init__(self, connection):
|
||||
|
@ -948,3 +952,7 @@ class OvsdbSbOvnIdl(sb_impl_idl.OvnSbApiIdlImpl, Backend):
|
|||
# and just start using chassis objects so db_find_rows could be used
|
||||
rows = self.db_list_rows('Port_Binding').execute(check_error=True)
|
||||
return [r for r in rows if r.chassis and r.chassis[0].name == chassis]
|
||||
|
||||
def db_set(self, table, record, *col_values, if_exists=True, **columns):
|
||||
return cmd.DbSetCommand(self, table, record, *col_values,
|
||||
if_exists=if_exists, **columns)
|
||||
|
|
Loading…
Reference in New Issue