From 2c7ef566af9bccbc565e0dc0259a8c456396153f Mon Sep 17 00:00:00 2001 From: Terry Wilson Date: Tue, 25 Oct 2016 01:05:24 -0500 Subject: [PATCH] Handle db_add in transaction for new objects The native interface chokes when doing db_add on an object that was created within the same transaction due to the column we are modifying not yet existing. This patch adds defaults for the column. Change-Id: I4386aa293f9b18d2e17b4a80d9c7da4b9b46f3c9 Closes-Bug: #1642764 --- neutron/agent/ovsdb/native/commands.py | 3 ++- neutron/tests/functional/agent/test_ovs_lib.py | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/neutron/agent/ovsdb/native/commands.py b/neutron/agent/ovsdb/native/commands.py index 8267fb59c06..8b0ebec8c57 100644 --- a/neutron/agent/ovsdb/native/commands.py +++ b/neutron/agent/ovsdb/native/commands.py @@ -223,16 +223,17 @@ class DbAddCommand(BaseCommand): def run_idl(self, txn): record = idlutils.row_by_record(self.api.idl, self.table, self.record) for value in self.values: - field = getattr(record, self.column) if isinstance(value, collections.Mapping): # We should be doing an add on a 'map' column. If the key is # already set, do nothing, otherwise set the key to the value + field = getattr(record, self.column, {}) for k, v in six.iteritems(value): if k in field: continue field[k] = v else: # We should be appending to a 'set' column. + field = getattr(record, self.column, []) field.append(value) record.verify(self.column) setattr(record, self.column, idlutils.db_replace_record(field)) diff --git a/neutron/tests/functional/agent/test_ovs_lib.py b/neutron/tests/functional/agent/test_ovs_lib.py index b16130cc0e3..c5b5b47e689 100644 --- a/neutron/tests/functional/agent/test_ovs_lib.py +++ b/neutron/tests/functional/agent/test_ovs_lib.py @@ -416,6 +416,15 @@ class OVSBridgeTestCase(OVSBridgeTestBase): self.assertIn(brname, self.ovs.get_bridges()) + def test_db_add_to_new_object(self): + ovsdb = self.ovs.ovsdb + brname = utils.get_rand_name(prefix=net_helpers.BR_PREFIX) + br = ovs_lib.OVSBridge(brname) # doesn't create + self.addCleanup(br.destroy) + with ovsdb.transaction(check_error=True) as txn: + txn.add(ovsdb.add_br(brname)) + txn.add(ovsdb.db_add('Bridge', brname, 'protocols', 'OpenFlow10')) + class OVSLibTestCase(base.BaseOVSLinuxTestCase):