Fix PortNotFound exception during sync_routers
This trace is observed when an L3 agent invokes sync_routers right about the same time a port interface is removed from a router. Related-bug: #1355409 Change-Id: I825b25080cbf054462318fc01248692b9e0e4ecb
This commit is contained in:
parent
c2dd30b0f7
commit
1f9dbabe1d
@ -16,6 +16,7 @@
|
||||
from oslo.config import cfg
|
||||
|
||||
from neutron.common import constants
|
||||
from neutron.common import exceptions
|
||||
from neutron.common import utils
|
||||
from neutron import context as neutron_context
|
||||
from neutron.extensions import l3
|
||||
@ -106,8 +107,13 @@ class L3RpcCallbackMixin(object):
|
||||
portbindings.VIF_TYPE_BINDING_FAILED)):
|
||||
# All ports, including ports created for SNAT'ing for
|
||||
# DVR are handled here
|
||||
self.plugin.update_port(context, port['id'],
|
||||
{'port': {portbindings.HOST_ID: host}})
|
||||
try:
|
||||
self.plugin.update_port(context, port['id'],
|
||||
{'port': {portbindings.HOST_ID: host}})
|
||||
except exceptions.PortNotFound:
|
||||
LOG.debug("Port %(port)s not found while updating "
|
||||
"agent binding for router %(router)s."
|
||||
% {"port": port['id'], "router": router_id})
|
||||
elif (port and
|
||||
port.get('device_owner') ==
|
||||
constants.DEVICE_OWNER_DVR_INTERFACE):
|
||||
|
@ -38,6 +38,7 @@ from neutron.db import l3_rpc_base
|
||||
from neutron.db import model_base
|
||||
from neutron.extensions import external_net
|
||||
from neutron.extensions import l3
|
||||
from neutron.extensions import portbindings
|
||||
from neutron import manager
|
||||
from neutron.openstack.common import importutils
|
||||
from neutron.openstack.common import log as logging
|
||||
@ -2048,6 +2049,41 @@ class L3NatDBIntAgentSchedulingTestCase(L3BaseForIntTests,
|
||||
expected_code=exc.HTTPBadRequest.code)
|
||||
|
||||
|
||||
class L3RpcCallbackMixinTestCase(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(L3RpcCallbackMixinTestCase, self).setUp()
|
||||
self.mock_plugin = mock.patch.object(
|
||||
l3_rpc_base.L3RpcCallbackMixin,
|
||||
'plugin', new_callable=mock.PropertyMock).start()
|
||||
self.mock_l3plugin = mock.patch.object(
|
||||
l3_rpc_base.L3RpcCallbackMixin,
|
||||
'l3plugin', new_callable=mock.PropertyMock).start()
|
||||
self.mixin = l3_rpc_base.L3RpcCallbackMixin()
|
||||
|
||||
def test__ensure_host_set_on_port_update_on_concurrent_delete(self):
|
||||
port_id = 'foo_port_id'
|
||||
port = {
|
||||
'id': port_id,
|
||||
'device_owner': 'compute:None',
|
||||
portbindings.HOST_ID: '',
|
||||
portbindings.VIF_TYPE: portbindings.VIF_TYPE_BINDING_FAILED
|
||||
}
|
||||
router_id = 'foo_router_id'
|
||||
self.mixin.plugin.update_port.side_effect = n_exc.PortNotFound(
|
||||
port_id=port_id)
|
||||
with mock.patch.object(l3_rpc_base.LOG, 'debug') as mock_log:
|
||||
self.mixin._ensure_host_set_on_port(
|
||||
mock.ANY, mock.ANY, port, router_id)
|
||||
self.mixin.plugin.update_port.assert_called_once_with(
|
||||
mock.ANY, port_id, {'port': {'binding:host_id': mock.ANY}})
|
||||
self.assertTrue(mock_log.call_count)
|
||||
expected_message = ('Port foo_port_id not found while updating '
|
||||
'agent binding for router foo_router_id.')
|
||||
actual_message = mock_log.call_args[0][0]
|
||||
self.assertEqual(expected_message, actual_message)
|
||||
|
||||
|
||||
class L3AgentDbIntTestCase(L3BaseForIntTests, L3AgentDbTestCaseBase):
|
||||
|
||||
"""Unit tests for methods called by the L3 agent for
|
||||
|
Loading…
x
Reference in New Issue
Block a user