Delete metadata_proxy for network if it is not needed
Currently, once the metadata_process is created for the network,
it will never be eliminated unless the network is deleted. Even if
user disable the metadata for network and restart dhcp agent, the
metdata proxy for network will still be there. This will waste the
resource of neutron host. This patch will let the dhcp-agent
delete useless metadata_proxy at startup.
Additional functional tests are added to for related scenario.
Change-Id: Id867b211fe7c01a11ba73a5ebc275c595933becf
Closes-Bug: #1507950
(cherry picked from commit dc0c7b5588
)
This commit is contained in:
parent
36864b6a70
commit
0feecfe9dd
|
@ -245,6 +245,12 @@ class DhcpAgent(manager.Manager):
|
|||
if subnet.ip_version == 4 and subnet.enable_dhcp:
|
||||
self.enable_isolated_metadata_proxy(network)
|
||||
break
|
||||
elif (self.conf.use_namespaces and not self.conf.force_metadata and
|
||||
not self.conf.enable_isolated_metadata):
|
||||
# In the case that the dhcp agent ran with metadata enabled,
|
||||
# and dhcp agent now starts with metadata disabled, check and
|
||||
# delete any metadata_proxy.
|
||||
self.disable_isolated_metadata_proxy(network)
|
||||
|
||||
def disable_dhcp_helper(self, network_id):
|
||||
"""Disable DHCP for a network known to the agent."""
|
||||
|
|
|
@ -27,6 +27,7 @@ from neutron.agent.common import ovs_lib
|
|||
from neutron.agent.dhcp import agent
|
||||
from neutron.agent import dhcp_agent
|
||||
from neutron.agent.linux import dhcp
|
||||
from neutron.agent.linux import external_process
|
||||
from neutron.agent.linux import interface
|
||||
from neutron.agent.linux import ip_lib
|
||||
from neutron.agent.linux import utils
|
||||
|
@ -80,6 +81,8 @@ class DHCPAgentOVSTestFramework(base.BaseSudoTestCase):
|
|||
|
||||
self.ovs_driver = interface.OVSInterfaceDriver(self.conf)
|
||||
|
||||
self.conf.set_override('check_child_processes_interval', 1, 'AGENT')
|
||||
|
||||
def network_dict_for_dhcp(self, dhcp_enabled=True, ip_version=4):
|
||||
net_id = uuidutils.generate_uuid()
|
||||
subnet_dict = self.create_subnet_dict(
|
||||
|
@ -232,6 +235,12 @@ class DHCPAgentOVSTestFramework(base.BaseSudoTestCase):
|
|||
self.addCleanup(proc.wait)
|
||||
self.addCleanup(proc.kill)
|
||||
|
||||
def _get_metadata_proxy_process(self, network):
|
||||
return external_process.ProcessManager(
|
||||
self.conf,
|
||||
network.id,
|
||||
network.namespace)
|
||||
|
||||
|
||||
class DHCPAgentOVSTestCase(DHCPAgentOVSTestFramework):
|
||||
|
||||
|
@ -260,3 +269,38 @@ class DHCPAgentOVSTestCase(DHCPAgentOVSTestFramework):
|
|||
port.mac_address = str(bad_mac_address)
|
||||
self._plug_port_for_dhcp_request(network, port)
|
||||
self.assert_bad_allocation_for_port(network, port)
|
||||
|
||||
def _spawn_network_metadata_proxy(self):
|
||||
network = self.network_dict_for_dhcp()
|
||||
self.conf.set_override('enable_isolated_metadata', True)
|
||||
self.addCleanup(self.agent.disable_isolated_metadata_proxy, network)
|
||||
self.configure_dhcp_for_network(network=network)
|
||||
pm = self._get_metadata_proxy_process(network)
|
||||
utils.wait_until_true(
|
||||
lambda: pm.active,
|
||||
timeout=5,
|
||||
sleep=0.01,
|
||||
exception=RuntimeError("Metadata proxy didn't spawn"))
|
||||
return (pm, network)
|
||||
|
||||
def test_metadata_proxy_respawned(self):
|
||||
pm, network = self._spawn_network_metadata_proxy()
|
||||
old_pid = pm.pid
|
||||
|
||||
utils.execute(['kill', '-9', old_pid], run_as_root=True)
|
||||
utils.wait_until_true(
|
||||
lambda: pm.active and pm.pid != old_pid,
|
||||
timeout=5,
|
||||
sleep=0.1,
|
||||
exception=RuntimeError("Metadata proxy didn't respawn"))
|
||||
|
||||
def test_stale_metadata_proxy_killed(self):
|
||||
pm, network = self._spawn_network_metadata_proxy()
|
||||
|
||||
self.conf.set_override('enable_isolated_metadata', False)
|
||||
self.configure_dhcp_for_network(network=network)
|
||||
utils.wait_until_true(
|
||||
lambda: not pm.active,
|
||||
timeout=5,
|
||||
sleep=0.1,
|
||||
exception=RuntimeError("Stale metadata proxy didn't get killed"))
|
||||
|
|
|
@ -617,11 +617,14 @@ class TestDhcpAgentEventHandler(base.BaseTestCase):
|
|||
mock.call.get_network_info(network.id)])
|
||||
self.call_driver.assert_called_once_with('enable', network)
|
||||
self.cache.assert_has_calls([mock.call.put(network)])
|
||||
if is_isolated_network:
|
||||
if is_isolated_network and enable_isolated_metadata:
|
||||
self.external_process.assert_has_calls([
|
||||
self._process_manager_constructor_call(),
|
||||
mock.call().enable()
|
||||
])
|
||||
mock.call().enable()])
|
||||
elif not enable_isolated_metadata:
|
||||
self.external_process.assert_has_calls([
|
||||
self._process_manager_constructor_call(ns=None),
|
||||
mock.call().disable()])
|
||||
else:
|
||||
self.assertFalse(self.external_process.call_count)
|
||||
|
||||
|
@ -723,6 +726,7 @@ class TestDhcpAgentEventHandler(base.BaseTestCase):
|
|||
def test_enable_dhcp_helper_driver_failure(self):
|
||||
self.plugin.get_network_info.return_value = fake_network
|
||||
self.call_driver.return_value = False
|
||||
cfg.CONF.set_override('enable_isolated_metadata', True)
|
||||
self.dhcp.enable_dhcp_helper(fake_network.id)
|
||||
self.plugin.assert_has_calls(
|
||||
[mock.call.get_network_info(fake_network.id)])
|
||||
|
|
Loading…
Reference in New Issue