From: Ivar Lazzaro Date: Tue, 18 Aug 2015 00:17:42 +0000 (-0700) Subject: handle gw_info outside of the db transaction on router creation X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=622dea818d851224a43d5276a81d5ce8a6eebb76;p=openstack-build%2Fneutron-build.git handle gw_info outside of the db transaction on router creation Move the gateway interface creation outside the DB transaction to avoid lock timeout. Change-Id: I5a78d7f32e8ca912016978105221d5f34618af19 Closes-bug: 1485809 --- diff --git a/neutron/db/l3_db.py b/neutron/db/l3_db.py index ebd7465e8..a803dcb61 100644 --- a/neutron/db/l3_db.py +++ b/neutron/db/l3_db.py @@ -174,11 +174,17 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase): r = router['router'] gw_info = r.pop(EXTERNAL_GW_INFO, None) tenant_id = self._get_tenant_id_for_create(context, r) - with context.session.begin(subtransactions=True): - router_db = self._create_router_db(context, r, tenant_id) + router_db = self._create_router_db(context, r, tenant_id) + try: if gw_info: self._update_router_gw_info(context, router_db['id'], gw_info, router=router_db) + except Exception: + with excutils.save_and_reraise_exception(): + LOG.exception(_LE("An exception occurred while creating " + "the router: %s"), router) + self.delete_router(context, router_db.id) + return self._make_router_dict(router_db) def _update_router_db(self, context, router_id, data, gw_info): diff --git a/neutron/tests/unit/extensions/test_l3.py b/neutron/tests/unit/extensions/test_l3.py index 77e55682b..7c6f47cad 100644 --- a/neutron/tests/unit/extensions/test_l3.py +++ b/neutron/tests/unit/extensions/test_l3.py @@ -2477,6 +2477,23 @@ class L3NatTestCaseBase(L3NatTestCaseMixin): fip['floatingip']['floating_ip_address']) self.assertEqual(floating_ip.version, 4) + def test_create_router_gateway_fails(self): + # Force _update_router_gw_info failure + plugin = manager.NeutronManager.get_service_plugins()[ + service_constants.L3_ROUTER_NAT] + ctx = context.Context('', 'foo') + plugin._update_router_gw_info = mock.Mock( + side_effect=n_exc.NeutronException) + data = {'router': { + 'name': 'router1', 'admin_state_up': True, + 'external_gateway_info': {'network_id': 'some_uuid'}}} + + # Verify router doesn't persist on failure + self.assertRaises(n_exc.NeutronException, + plugin.create_router, ctx, data) + routers = plugin.get_routers(ctx) + self.assertEqual(0, len(routers)) + class L3AgentDbTestCaseBase(L3NatTestCaseMixin):