Merge "Metadata: handle process exceptions" into stable/xena

This commit is contained in:
Zuul 2024-01-03 12:40:46 +00:00 committed by Gerrit Code Review
commit 9540c9c251
5 changed files with 90 additions and 14 deletions

View File

@ -294,7 +294,13 @@ class MetadataDriver(object):
pm = cls._get_metadata_proxy_process_manager(uuid, conf,
ns_name=ns_name,
callback=callback)
pm.enable()
try:
pm.enable()
except exceptions.ProcessExecutionError as exec_err:
LOG.error("Encountered process execution error %(err)s while "
"starting process in namespace %(ns)s",
{"err": exec_err, "ns": ns_name})
return
monitor.register(uuid, METADATA_SERVICE_NAME, pm)
cls.monitors[router_id] = pm

View File

@ -197,7 +197,13 @@ class MetadataDriver(object):
pm = cls._get_metadata_proxy_process_manager(uuid, conf,
ns_name=ns_name,
callback=callback)
pm.enable()
try:
pm.enable()
except exceptions.ProcessExecutionError as exec_err:
LOG.error("Encountered process execution error %(err)s while "
"starting process in namespace %(ns)s",
{"err": exec_err, "ns": ns_name})
return
monitor.register(uuid, METADATA_SERVICE_NAME, pm)
cls.monitors[router_id] = pm

View File

@ -833,23 +833,37 @@ class TestDhcpAgentEventHandler(base.BaseTestCase):
def _enable_dhcp_helper(self, network, enable_isolated_metadata=False,
is_isolated_network=False, is_ovn_network=False):
self.dhcp._process_monitor = mock.Mock()
# The disable() call
gmppm_expected_calls = [mock.call(FAKE_NETWORK_UUID, cfg.CONF,
ns_name=FAKE_NETWORK_DHCP_NS)]
if enable_isolated_metadata:
cfg.CONF.set_override('enable_isolated_metadata', True)
if is_isolated_network:
# The enable() call
gmppm_expected_calls.append(
mock.call(FAKE_NETWORK_UUID, cfg.CONF,
ns_name=FAKE_NETWORK_DHCP_NS,
callback=mock.ANY))
self.plugin.get_network_info.return_value = network
self.dhcp.enable_dhcp_helper(network.id)
process_instance = mock.Mock(active=False)
with mock.patch.object(metadata_driver.MetadataDriver,
'_get_metadata_proxy_process_manager',
return_value=process_instance) as gmppm:
self.dhcp.enable_dhcp_helper(network.id)
gmppm.assert_has_calls(gmppm_expected_calls)
self.plugin.assert_has_calls([
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 and enable_isolated_metadata and not
is_ovn_network):
self.external_process.assert_has_calls([
self._process_manager_constructor_call(),
mock.call().enable()], any_order=True)
process_instance.assert_has_calls([
mock.call.disable(sig=str(int(signal.SIGTERM))),
mock.call.get_pid_file_name(),
mock.call.enable()])
else:
self.external_process.assert_has_calls([
self._process_manager_constructor_call(),
mock.call().disable(sig=str(int(signal.SIGTERM)))])
process_instance.assert_has_calls([
mock.call.disable(sig=str(int(signal.SIGTERM)))])
def test_enable_dhcp_helper_enable_metadata_isolated_network(self):
self._enable_dhcp_helper(isolated_network,
@ -1023,11 +1037,16 @@ class TestDhcpAgentEventHandler(base.BaseTestCase):
def test_enable_isolated_metadata_proxy(self):
self.dhcp._process_monitor = mock.Mock()
self.dhcp.enable_isolated_metadata_proxy(fake_network)
self.external_process.assert_has_calls([
self._process_manager_constructor_call(),
mock.call().enable()
], any_order=True)
process_instance = mock.Mock(active=False)
with mock.patch.object(metadata_driver.MetadataDriver,
'_get_metadata_proxy_process_manager',
return_value=process_instance) as gmppm:
self.dhcp.enable_isolated_metadata_proxy(fake_network)
gmppm.assert_called_with(FAKE_NETWORK_UUID,
cfg.CONF,
ns_name=FAKE_NETWORK_DHCP_NS,
callback=mock.ANY)
process_instance.enable.assert_called_once()
def test_disable_isolated_metadata_proxy(self):
method_path = ('neutron.agent.metadata.driver.MetadataDriver'

View File

@ -18,6 +18,7 @@ import signal
from unittest import mock
from neutron_lib import constants
from neutron_lib import exceptions as lib_exceptions
from neutron_lib import fixture as lib_fixtures
from oslo_config import cfg
from oslo_utils import uuidutils
@ -235,6 +236,26 @@ class TestMetadataDriverProcess(base.BaseTestCase):
def test_spawn_metadata_proxy_dad_failed(self):
self._test_spawn_metadata_proxy(dad_failed=True)
@mock.patch.object(metadata_driver.LOG, 'error')
def test_spawn_metadata_proxy_handles_process_exception(self, error_log):
process_instance = mock.Mock(active=False)
process_instance.enable.side_effect = (
lib_exceptions.ProcessExecutionError('Something happened', -1))
with mock.patch.object(metadata_driver.MetadataDriver,
'_get_metadata_proxy_process_manager',
return_value=process_instance):
process_monitor = mock.Mock()
network_id = 123456
metadata_driver.MetadataDriver.spawn_monitored_metadata_proxy(
process_monitor,
'dummy_namespace',
self.METADATA_PORT,
cfg.CONF,
network_id=network_id)
error_log.assert_called_once()
process_monitor.register.assert_not_called()
self.assertNotIn(network_id, metadata_driver.MetadataDriver.monitors)
def test_create_config_file_wrong_user(self):
with mock.patch('pwd.getpwnam', side_effect=KeyError):
config = metadata_driver.HaproxyConfigurator(_uuid(),

View File

@ -16,6 +16,7 @@
import os
from unittest import mock
from neutron_lib import exceptions as lib_exceptions
from neutron_lib import fixture as lib_fixtures
from oslo_config import cfg
from oslo_utils import uuidutils
@ -108,6 +109,29 @@ class TestMetadataDriverProcess(base.BaseTestCase):
run_as_root=True)
])
@mock.patch.object(metadata_driver.LOG, 'error')
def test_spawn_metadata_proxy_handles_process_exception(self, error_log):
process_instance = mock.Mock(active=False)
process_instance.enable.side_effect = (
lib_exceptions.ProcessExecutionError('Something happened', -1))
with mock.patch.object(metadata_driver.MetadataDriver,
'_get_metadata_proxy_process_manager',
return_value=process_instance):
process_monitor = mock.Mock()
network_id = 123456
metadata_driver.MetadataDriver.spawn_monitored_metadata_proxy(
process_monitor,
'dummy_namespace',
self.METADATA_PORT,
cfg.CONF,
network_id=network_id)
error_log.assert_called_once()
process_monitor.register.assert_not_called()
self.assertNotIn(network_id, metadata_driver.MetadataDriver.monitors)
def test_create_config_file_wrong_user(self):
with mock.patch('pwd.getpwnam', side_effect=KeyError):
config = metadata_driver.HaproxyConfigurator(mock.ANY, mock.ANY,