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:
Hong Hui Xiao 2015-10-20 05:31:46 -04:00 committed by Ihar Hrachyshka
parent 36864b6a70
commit 0feecfe9dd
3 changed files with 57 additions and 3 deletions

View File

@ -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."""

View File

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

View File

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