BigSwitch: Create router ports synchronously
Since router ports are created as part of a long transaction with multiple REST calls, they need to be created sychronously. This is to prevent the async thread from deleting them from the backend if it can't find them in cases where they haven't been committed to the DB yet. Closes-Bug: #1305331 Change-Id: I2ab3c862dc6b1760199654bbd0969ac5efdbe704
This commit is contained in:
parent
ec82d2006b
commit
37e9ea249d
@ -664,7 +664,11 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base,
|
||||
with context.session.begin(subtransactions=True):
|
||||
self._ensure_default_security_group_on_port(context, port)
|
||||
sgids = self._get_security_groups_on_port(context, port)
|
||||
# set port status to pending. updated after rest call completes
|
||||
# non-router port status is set to pending. it is then updated
|
||||
# after the async rest call completes. router ports are synchronous
|
||||
if port['port']['device_owner'] == l3_db.DEVICE_OWNER_ROUTER_INTF:
|
||||
port['port']['status'] = const.PORT_STATUS_ACTIVE
|
||||
else:
|
||||
port['port']['status'] = const.PORT_STATUS_BUILD
|
||||
dhcp_opts = port['port'].get(edo_ext.EXTRADHCPOPTS, [])
|
||||
new_port = super(NeutronRestProxyV2, self).create_port(context,
|
||||
@ -691,6 +695,13 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base,
|
||||
|
||||
# create on network ctrl
|
||||
mapped_port = self._map_state_and_status(new_port)
|
||||
# ports have to be created synchronously when creating a router
|
||||
# port since adding router interfaces is a multi-call process
|
||||
if mapped_port['device_owner'] == l3_db.DEVICE_OWNER_ROUTER_INTF:
|
||||
self.servers.rest_create_port(net["tenant_id"],
|
||||
new_port["network_id"],
|
||||
mapped_port)
|
||||
else:
|
||||
self.evpool.spawn_n(self.async_port_create, net["tenant_id"],
|
||||
new_port["network_id"], mapped_port)
|
||||
self.notify_security_groups_member_updated(context, new_port)
|
||||
|
@ -20,6 +20,7 @@ import mock
|
||||
from oslo.config import cfg
|
||||
import webob.exc
|
||||
|
||||
from neutron.common import constants
|
||||
from neutron import context
|
||||
from neutron.extensions import portbindings
|
||||
from neutron.manager import NeutronManager
|
||||
@ -81,7 +82,21 @@ class TestBigSwitchProxyPortsV2(test_plugin.TestPortsV2,
|
||||
super(TestBigSwitchProxyPortsV2,
|
||||
self).setUp(self._plugin_name)
|
||||
|
||||
def test_router_port_status_active(self):
|
||||
# router ports screw up port auto-deletion so it has to be
|
||||
# disabled for this test
|
||||
with self.network(do_delete=False) as net:
|
||||
with self.subnet(network=net, do_delete=False) as sub:
|
||||
with self.port(
|
||||
subnet=sub,
|
||||
no_delete=True,
|
||||
device_owner=constants.DEVICE_OWNER_ROUTER_INTF
|
||||
) as port:
|
||||
# router ports should be immediately active
|
||||
self.assertEqual(port['port']['status'], 'ACTIVE')
|
||||
|
||||
def test_update_port_status_build(self):
|
||||
# normal ports go into the pending build state for async creation
|
||||
with self.port() as port:
|
||||
self.assertEqual(port['port']['status'], 'BUILD')
|
||||
self.assertEqual(self.port_create_status, 'BUILD')
|
||||
|
Loading…
Reference in New Issue
Block a user