From 7ca696c7355ba93dd89e69a76162c6d9a3429a2b Mon Sep 17 00:00:00 2001 From: armando-migliaccio Date: Fri, 19 Sep 2014 12:11:11 -0700 Subject: [PATCH] Fix foreign key constraint error on ml2_dvr_port_bindings Get the port before creating the DVR binding. This should guarantee that, if the port is found, no foreign key violation is triggered. Closes-bug: #1371696 Change-Id: I90c3d6460c14ef27823be95bc26aae38eba4879a --- neutron/plugins/ml2/plugin.py | 6 +++++- neutron/tests/unit/ml2/test_ml2_plugin.py | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index e6a8d9040..8547d18d8 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -890,10 +890,14 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, router_id != device_id) if update_required: with session.begin(subtransactions=True): + try: + orig_port = super(Ml2Plugin, self).get_port(context, id) + except exc.PortNotFound: + LOG.debug("DVR Port %s has been deleted concurrently", id) + return if not binding: binding = db.ensure_dvr_port_binding( session, id, host, router_id=device_id) - orig_port = super(Ml2Plugin, self).get_port(context, id) network = self.get_network(context, orig_port['network_id']) mech_context = driver_context.DvrPortContext(self, context, orig_port, network, diff --git a/neutron/tests/unit/ml2/test_ml2_plugin.py b/neutron/tests/unit/ml2/test_ml2_plugin.py index ca0a061f9..e70aa3c4a 100644 --- a/neutron/tests/unit/ml2/test_ml2_plugin.py +++ b/neutron/tests/unit/ml2/test_ml2_plugin.py @@ -377,6 +377,17 @@ class TestMl2PortBinding(Ml2PluginV2TestCase, mech_context._binding.router_id) self.assertEqual(host_id, mech_context._binding.host) + def test_update_dvr_port_binding_on_non_existent_port(self): + plugin = manager.NeutronManager.get_plugin() + port = { + 'id': 'foo_port_id', + 'binding:host_id': 'foo_host', + } + with mock.patch.object(ml2_db, 'ensure_dvr_port_binding') as mock_dvr: + plugin.update_dvr_port_binding( + self.context, 'foo_port_id', {'port': port}) + self.assertFalse(mock_dvr.called) + class TestMl2PortBindingNoSG(TestMl2PortBinding): HAS_PORT_FILTER = False -- 2.45.2