Mark port as ready after enabling dhcp at agent

When subnet is created and network is scheduled to dhcp agent, the
dhcp agent will request neutron server to create dhcp port.

Neutron server will create and mark port as BUILD and wait for the
ready signal from dhcp agent.

dhcp agent will create 'real' dhcp port after getting response from
neutron server. But after that, dhcp agent will not tell neutron server
that the dhcp port is ready. So, the reported bug can be observed.

If ports are created before dhcp is enabled for network, dhcp agent will
not mark ports as 'ready' as there is no network cache. This patch also
marks all ports in network as ready, in case that happens.

Change-Id: I363d8727f7ef6e6e08be4b0022c6464d51692b85
Closes-bug: #1588906
This commit is contained in:
Hong Hui Xiao 2016-06-08 12:18:53 +00:00
parent d3b9977e1c
commit 5b0ea03202
3 changed files with 28 additions and 0 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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,