diff --git a/neutron/agent/dhcp/agent.py b/neutron/agent/dhcp/agent.py index 4602a3c4c53..c4b38885656 100644 --- a/neutron/agent/dhcp/agent.py +++ b/neutron/agent/dhcp/agent.py @@ -277,6 +277,10 @@ class DhcpAgent(manager.Manager): if self.call_driver('enable', network): dhcp_network_enabled = True self.cache.put(network) + # After enabling dhcp for network, mark all existing + # ports as ready. So that the status of ports which are + # created before enabling dhcp can be updated. + self.dhcp_ready_ports |= {p.id for p in network.ports} break if enable_metadata and dhcp_network_enabled: diff --git a/neutron/tests/functional/agent/test_dhcp_agent.py b/neutron/tests/functional/agent/test_dhcp_agent.py index 041367c6c5b..383102d2d6b 100644 --- a/neutron/tests/functional/agent/test_dhcp_agent.py +++ b/neutron/tests/functional/agent/test_dhcp_agent.py @@ -19,6 +19,7 @@ import eventlet import fixtures import mock import netaddr +from neutron_lib import constants as lib_const from oslo_config import fixture as fixture_config from oslo_utils import uuidutils @@ -313,3 +314,20 @@ class DHCPAgentOVSTestCase(DHCPAgentOVSTestFramework): timeout=5, sleep=0.1, exception=RuntimeError("Stale metadata proxy didn't get killed")) + + def test_notify_port_ready_after_enable_dhcp(self): + network = self.network_dict_for_dhcp() + dhcp_port = self.create_port_dict( + network.id, network.subnets[0].id, + '24:77:03:7d:00:4d', ip_address='192.168.10.11') + dhcp_port.device_owner = lib_const.DEVICE_OWNER_DHCP + network.ports.append(dhcp_port) + self.agent.start_ready_ports_loop() + self.configure_dhcp_for_network(network) + ports_to_send = {p.id for p in network.ports} + utils.wait_until_true( + lambda: self.mock_plugin_api.dhcp_ready_on_ports.called, + timeout=1, + sleep=0.1, + exception=RuntimeError("'dhcp_ready_on_ports' not be called")) + self.mock_plugin_api.dhcp_ready_on_ports.assert_called_with(ports_to_send) diff --git a/neutron/tests/unit/agent/dhcp/test_agent.py b/neutron/tests/unit/agent/dhcp/test_agent.py index 0cd5bb84157..4911df332df 100644 --- a/neutron/tests/unit/agent/dhcp/test_agent.py +++ b/neutron/tests/unit/agent/dhcp/test_agent.py @@ -467,6 +467,12 @@ class TestDhcpAgent(base.BaseTestCase): # should have been called with all ports again after the failure ready.assert_has_calls([mock.call(set(range(4)))] * 2) + def test_dhcp_ready_ports_updates_after_enable_dhcp(self): + dhcp = dhcp_agent.DhcpAgent(HOSTNAME) + self.assertEqual(set(), dhcp.dhcp_ready_ports) + dhcp.configure_dhcp_for_network(fake_network) + self.assertEqual({fake_port1.id}, dhcp.dhcp_ready_ports) + def test_report_state_revival_logic(self): dhcp = dhcp_agent.DhcpAgentWithStateReport(HOSTNAME) with mock.patch.object(dhcp.state_rpc,