Fix migration of legacy router to DVR

We have to ensure ML2's create_port method is not called
in a transaction.

This adds a temporary hack to set an attribute on the context
to skip this check to accomodate an L3 code-path that has a port
creation entangled in a transaction.  This attribute will
ultimately be removed once this path is refactored.

Change-Id: I9c41a7848b22c437bedcdd7eb57f7c9da873b06d
Closes-bug: #1619312
This commit is contained in:
Brian Haley 2016-09-14 16:52:07 -04:00
parent f276be704e
commit 25e65df797
2 changed files with 37 additions and 0 deletions

View File

@ -139,6 +139,8 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
# router, make sure to create corresponding
# snat interface ports that are to be consumed by
# the Service Node.
# TODO(haleyb): move this out of transaction
setattr(context, 'GUARD_TRANSACTION', False)
if not self._create_snat_intf_ports_if_not_exists(
context.elevated(), router_db):
LOG.debug("SNAT interface ports not created: %s",

View File

@ -1532,3 +1532,38 @@ class L3DvrTestCase(ml2_test_base.ML2TestFramework):
self.context, router['id'])
self.assertEqual(1, len(agents['agents']))
self.assertEqual(self.l3_agent['id'], agents['agents'][0]['id'])
class L3DvrTestCaseMigration(L3DvrTestCase):
def test_update_router_db_centralized_to_distributed_with_ports(self):
with self.subnet() as subnet1:
kwargs = {'arg_list': (external_net.EXTERNAL,),
external_net.EXTERNAL: True}
with self.network(**kwargs) as ext_net, \
self.subnet(network=ext_net,
cidr='30.0.0.0/24'):
router = self._create_router(distributed=False)
self.l3_plugin.add_router_interface(
self.context, router['id'],
{'subnet_id': subnet1['subnet']['id']})
self.l3_plugin._update_router_gw_info(
self.context, router['id'],
{'network_id': ext_net['network']['id']})
self.assertEqual(
0, len(self.l3_plugin._get_snat_sync_interfaces(
self.context, [router['id']])))
# router needs to be in admin state down in order to be
# upgraded to DVR
self.l3_plugin.update_router(
self.context, router['id'],
{'router': {'admin_state_up': False}})
self.assertFalse(router['distributed'])
self.l3_plugin.update_router(
self.context, router['id'],
{'router': {'distributed': True}})
router = self.l3_plugin.get_router(self.context, router['id'])
self.assertTrue(router['distributed'])
self.assertEqual(
1, len(self.l3_plugin._get_snat_sync_interfaces(
self.context, [router['id']])))