]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
handle gw_info outside of the db transaction on router creation
authorIvar Lazzaro <ivarlazzaro@gmail.com>
Tue, 18 Aug 2015 00:17:42 +0000 (17:17 -0700)
committerIvar Lazzaro <ivarlazzaro@gmail.com>
Fri, 28 Aug 2015 20:17:46 +0000 (20:17 +0000)
Move the gateway interface creation outside the DB transaction
to avoid lock timeout.

Change-Id: I5a78d7f32e8ca912016978105221d5f34618af19
Closes-bug: 1485809

neutron/db/l3_db.py
neutron/tests/unit/extensions/test_l3.py

index ebd7465e8b18cc3da4fd2e9fff830c0d337d63d6..a803dcb6143c4b4d7d3790bb5b113d0e6b7248b4 100644 (file)
@@ -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):
index 77e55682b9773d1d8af45696b6c31a9aeaab424d..7c6f47cad38e733c812f64540bc41c60abb0d4ec 100644 (file)
@@ -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):