diff --git a/neutron/agent/dhcp/agent.py b/neutron/agent/dhcp/agent.py index 38cb6717723..15e0289a7c3 100644 --- a/neutron/agent/dhcp/agent.py +++ b/neutron/agent/dhcp/agent.py @@ -162,7 +162,8 @@ class DhcpAgent(manager.Manager): if (isinstance(e, oslo_messaging.RemoteError) and e.exc_type == 'NetworkNotFound' or isinstance(e, exceptions.NetworkNotFound)): - LOG.debug("Network %s has been deleted.", network.id) + LOG.debug("Network %s has been removed from the agent " + "or deleted from DB.", network.id) else: LOG.exception('Unable to %(action)s dhcp for %(net_id)s.', {'net_id': network.id, 'action': action}) diff --git a/neutron/agent/linux/dhcp.py b/neutron/agent/linux/dhcp.py index 91c366f43bd..744cc48d934 100644 --- a/neutron/agent/linux/dhcp.py +++ b/neutron/agent/linux/dhcp.py @@ -26,7 +26,6 @@ from neutron_lib import constants from neutron_lib import exceptions from neutron_lib.utils import file as file_utils from oslo_log import log as logging -import oslo_messaging from oslo_utils import excutils from oslo_utils import fileutils from oslo_utils import uuidutils @@ -1368,16 +1367,9 @@ class DeviceManager(object): for port in network.ports: port_device_id = getattr(port, 'device_id', None) if port_device_id == constants.DEVICE_ID_RESERVED_DHCP_PORT: - try: - port = self.plugin.update_dhcp_port( - port.id, {'port': {'network_id': network.id, - 'device_id': device_id}}) - except oslo_messaging.RemoteError as e: - if e.exc_type == 'DhcpPortInUse': - LOG.info("Skipping DHCP port %s as it is " - "already in use", port.id) - continue - raise + port = self.plugin.update_dhcp_port( + port.id, {'port': {'network_id': network.id, + 'device_id': device_id}}) if port: return port diff --git a/neutron/api/rpc/handlers/dhcp_rpc.py b/neutron/api/rpc/handlers/dhcp_rpc.py index 19080534da9..cf000598d08 100644 --- a/neutron/api/rpc/handlers/dhcp_rpc.py +++ b/neutron/api/rpc/handlers/dhcp_rpc.py @@ -33,7 +33,6 @@ from oslo_utils import excutils from neutron._i18n import _ from neutron.common import constants as n_const -from neutron.common import exceptions as n_exc from neutron.common import utils from neutron.db import provisioning_blocks from neutron.extensions import segment as segment_ext @@ -280,6 +279,7 @@ class DhcpRpcCallback(object): hosts=[host]) return len(agents) != 0 + @oslo_messaging.expected_exceptions(exceptions.NetworkNotFound) @oslo_messaging.expected_exceptions(exceptions.IpAddressGenerationFailure) @db_api.retry_db_errors def update_dhcp_port(self, context, **kwargs): @@ -295,10 +295,14 @@ class DhcpRpcCallback(object): if (old_port['device_id'] != constants.DEVICE_ID_RESERVED_DHCP_PORT and old_port['device_id'] != - utils.get_dhcp_agent_device_id(network_id, host) or - not self._is_dhcp_agent_hosting_network(plugin, context, host, - network_id)): - raise n_exc.DhcpPortInUse(port_id=port['id']) + utils.get_dhcp_agent_device_id(network_id, host)): + return + if not self._is_dhcp_agent_hosting_network(plugin, context, host, + network_id): + LOG.warning("The DHCP agent on %(host)s does not host the " + "network %(net_id)s.", {"host": host, + "net_id": network_id}) + raise exceptions.NetworkNotFound(net_id=network_id) LOG.debug('Update dhcp port %(port)s ' 'from %(host)s.', {'port': port, @@ -308,7 +312,6 @@ class DhcpRpcCallback(object): LOG.debug('Host %(host)s tried to update port ' '%(port_id)s which no longer exists.', {'host': host, 'port_id': port['id']}) - return None @db_api.retry_db_errors def dhcp_ready_on_ports(self, context, port_ids): diff --git a/neutron/tests/unit/agent/linux/test_dhcp.py b/neutron/tests/unit/agent/linux/test_dhcp.py index 2b4139fb58a..8495998ceec 100644 --- a/neutron/tests/unit/agent/linux/test_dhcp.py +++ b/neutron/tests/unit/agent/linux/test_dhcp.py @@ -2949,8 +2949,7 @@ class TestDeviceManager(TestConfBase): def test__setup_reserved_dhcp_port_with_fake_remote_error(self): """Test scenario where a fake_network has two reserved ports, and - update_dhcp_port fails for the first of those with a RemoteError - different than DhcpPortInUse. + update_dhcp_port fails for the first of those with a RemoteError. """ # Setup with a reserved DHCP port. fake_network = FakeDualNetworkReserved2() @@ -2967,31 +2966,6 @@ class TestDeviceManager(TestConfBase): with testtools.ExpectedException(oslo_messaging.RemoteError): dh.setup_dhcp_port(fake_network) - def test__setup_reserved_dhcp_port_with_known_remote_error(self): - """Test scenario where a fake_network has two reserved ports, and - update_dhcp_port fails for the first of those with a DhcpPortInUse - RemoteError. - """ - # Setup with a reserved DHCP port. - fake_network = FakeDualNetworkReserved2() - fake_network.tenant_id = 'Tenant A' - reserved_port_1 = fake_network.ports[-2] - reserved_port_2 = fake_network.ports[-1] - - mock_plugin = mock.Mock() - dh = dhcp.DeviceManager(cfg.CONF, mock_plugin) - messaging_error = oslo_messaging.RemoteError(exc_type='DhcpPortInUse') - mock_plugin.update_dhcp_port.side_effect = [messaging_error, - reserved_port_2] - - with mock.patch.object(dhcp.LOG, 'info') as log: - dh.setup_dhcp_port(fake_network) - self.assertEqual(1, log.call_count) - expected_calls = [mock.call(reserved_port_1.id, mock.ANY), - mock.call(reserved_port_2.id, mock.ANY)] - self.assertEqual(expected_calls, - mock_plugin.update_dhcp_port.call_args_list) - class TestDictModel(base.BaseTestCase): diff --git a/neutron/tests/unit/api/rpc/handlers/test_dhcp_rpc.py b/neutron/tests/unit/api/rpc/handlers/test_dhcp_rpc.py index d3b4ff0a0d8..dc3204afd67 100644 --- a/neutron/tests/unit/api/rpc/handlers/test_dhcp_rpc.py +++ b/neutron/tests/unit/api/rpc/handlers/test_dhcp_rpc.py @@ -21,9 +21,9 @@ from neutron_lib import exceptions as n_exc from neutron_lib.plugins import constants as plugin_constants from neutron_lib.plugins import directory from oslo_db import exception as db_exc +from oslo_messaging.rpc import dispatcher as rpc_dispatcher from neutron.api.rpc.handlers import dhcp_rpc -from neutron.common import exceptions from neutron.common import utils from neutron.db import provisioning_blocks from neutron.tests import base @@ -304,12 +304,9 @@ class TestDhcpRpcCallback(base.BaseTestCase): self.plugin.get_port.return_value = { 'device_id': 'other_id'} - self.assertRaises(exceptions.DhcpPortInUse, - self.callbacks.update_dhcp_port, - mock.Mock(), - host='foo_host', - port_id='foo_port_id', - port=port) + res = self.callbacks.update_dhcp_port(mock.Mock(), host='foo_host', + port_id='foo_port_id', port=port) + self.assertIsNone(res) def test_update_dhcp_port(self): port = {'port': {'network_id': 'foo_network_id', @@ -340,7 +337,7 @@ class TestDhcpRpcCallback(base.BaseTestCase): self.plugin.get_port.return_value = { 'device_id': constants.DEVICE_ID_RESERVED_DHCP_PORT} self.mock_agent_hosting_network.return_value = False - self.assertRaises(exceptions.DhcpPortInUse, + self.assertRaises(rpc_dispatcher.ExpectedException, self.callbacks.update_dhcp_port, mock.Mock(), host='foo_host',