Skip to content

Commit ece7d9c

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Metadata: handle process exceptions" into stable/2023.1
2 parents d30d295 + 63c1667 commit ece7d9c

File tree

5 files changed

+89
-14
lines changed

5 files changed

+89
-14
lines changed

neutron/agent/metadata/driver.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,13 @@ def spawn_monitored_metadata_proxy(cls, monitor, ns_name, port, conf,
269269
pm = cls._get_metadata_proxy_process_manager(uuid, conf,
270270
ns_name=ns_name,
271271
callback=callback)
272-
pm.enable()
272+
try:
273+
pm.enable()
274+
except exceptions.ProcessExecutionError as exec_err:
275+
LOG.error("Encountered process execution error %(err)s while "
276+
"starting process in namespace %(ns)s",
277+
{"err": exec_err, "ns": ns_name})
278+
return
273279
monitor.register(uuid, METADATA_SERVICE_NAME, pm)
274280
cls.monitors[router_id] = pm
275281

neutron/agent/ovn/metadata/driver.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,13 @@ def spawn_monitored_metadata_proxy(cls, monitor, ns_name, port, conf,
180180
pm = cls._get_metadata_proxy_process_manager(uuid, conf,
181181
ns_name=ns_name,
182182
callback=callback)
183-
pm.enable()
183+
try:
184+
pm.enable()
185+
except exceptions.ProcessExecutionError as exec_err:
186+
LOG.error("Encountered process execution error %(err)s while "
187+
"starting process in namespace %(ns)s",
188+
{"err": exec_err, "ns": ns_name})
189+
return
184190
monitor.register(uuid, METADATA_SERVICE_NAME, pm)
185191
cls.monitors[router_id] = pm
186192

neutron/tests/unit/agent/dhcp/test_agent.py

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -828,23 +828,36 @@ def _process_manager_constructor_call(self, ns=FAKE_NETWORK_DHCP_NS):
828828
def _enable_dhcp_helper(self, network, enable_isolated_metadata=False,
829829
is_isolated_network=False, is_ovn_network=False):
830830
self.dhcp._process_monitor = mock.Mock()
831+
# The disable() call
832+
gmppm_expected_calls = [mock.call(FAKE_NETWORK_UUID, cfg.CONF,
833+
ns_name=FAKE_NETWORK_DHCP_NS)]
831834
if enable_isolated_metadata:
832835
cfg.CONF.set_override('enable_isolated_metadata', True)
836+
if is_isolated_network:
837+
# The enable() call
838+
gmppm_expected_calls.append(
839+
mock.call(FAKE_NETWORK_UUID, cfg.CONF,
840+
ns_name=FAKE_NETWORK_DHCP_NS,
841+
callback=mock.ANY))
833842
self.plugin.get_network_info.return_value = network
834-
self.dhcp.enable_dhcp_helper(network.id)
843+
process_instance = mock.Mock(active=False)
844+
with mock.patch.object(metadata_driver.MetadataDriver,
845+
'_get_metadata_proxy_process_manager',
846+
return_value=process_instance) as gmppm:
847+
self.dhcp.enable_dhcp_helper(network.id)
848+
gmppm.assert_has_calls(gmppm_expected_calls)
835849
self.plugin.assert_has_calls([
836850
mock.call.get_network_info(network.id)])
837851
self.call_driver.assert_called_once_with('enable', network)
838852
self.cache.assert_has_calls([mock.call.put(network)])
839853
if (is_isolated_network and enable_isolated_metadata and not
840854
is_ovn_network):
841-
self.external_process.assert_has_calls([
842-
self._process_manager_constructor_call(),
843-
mock.call().enable()], any_order=True)
855+
process_instance.assert_has_calls([
856+
mock.call.disable(sig=str(int(signal.SIGTERM))),
857+
mock.call.enable()])
844858
else:
845-
self.external_process.assert_has_calls([
846-
self._process_manager_constructor_call(),
847-
mock.call().disable(sig=str(int(signal.SIGTERM)))])
859+
process_instance.assert_has_calls([
860+
mock.call.disable(sig=str(int(signal.SIGTERM)))])
848861

849862
def test_enable_dhcp_helper_enable_metadata_isolated_network(self):
850863
self._enable_dhcp_helper(isolated_network,
@@ -1018,11 +1031,16 @@ def test_disable_dhcp_helper_driver_failure(self):
10181031

10191032
def test_enable_isolated_metadata_proxy(self):
10201033
self.dhcp._process_monitor = mock.Mock()
1021-
self.dhcp.enable_isolated_metadata_proxy(fake_network)
1022-
self.external_process.assert_has_calls([
1023-
self._process_manager_constructor_call(),
1024-
mock.call().enable()
1025-
], any_order=True)
1034+
process_instance = mock.Mock(active=False)
1035+
with mock.patch.object(metadata_driver.MetadataDriver,
1036+
'_get_metadata_proxy_process_manager',
1037+
return_value=process_instance) as gmppm:
1038+
self.dhcp.enable_isolated_metadata_proxy(fake_network)
1039+
gmppm.assert_called_with(FAKE_NETWORK_UUID,
1040+
cfg.CONF,
1041+
ns_name=FAKE_NETWORK_DHCP_NS,
1042+
callback=mock.ANY)
1043+
process_instance.enable.assert_called_once()
10261044

10271045
def test_disable_isolated_metadata_proxy(self):
10281046
method_path = ('neutron.agent.metadata.driver.MetadataDriver'

neutron/tests/unit/agent/metadata/test_driver.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from unittest import mock
1919

2020
from neutron_lib import constants
21+
from neutron_lib import exceptions as lib_exceptions
2122
from neutron_lib import fixture as lib_fixtures
2223
from oslo_config import cfg
2324
from oslo_utils import uuidutils
@@ -248,6 +249,26 @@ def test_spawn_metadata_proxy(self):
248249
def test_spawn_metadata_proxy_dad_failed(self):
249250
self._test_spawn_metadata_proxy(dad_failed=True)
250251

252+
@mock.patch.object(metadata_driver.LOG, 'error')
253+
def test_spawn_metadata_proxy_handles_process_exception(self, error_log):
254+
process_instance = mock.Mock(active=False)
255+
process_instance.enable.side_effect = (
256+
lib_exceptions.ProcessExecutionError('Something happened', -1))
257+
with mock.patch.object(metadata_driver.MetadataDriver,
258+
'_get_metadata_proxy_process_manager',
259+
return_value=process_instance):
260+
process_monitor = mock.Mock()
261+
network_id = 123456
262+
metadata_driver.MetadataDriver.spawn_monitored_metadata_proxy(
263+
process_monitor,
264+
'dummy_namespace',
265+
self.METADATA_PORT,
266+
cfg.CONF,
267+
network_id=network_id)
268+
error_log.assert_called_once()
269+
process_monitor.register.assert_not_called()
270+
self.assertNotIn(network_id, metadata_driver.MetadataDriver.monitors)
271+
251272
def test_create_config_file_wrong_user(self):
252273
with mock.patch('pwd.getpwnam', side_effect=KeyError):
253274
config = metadata_driver.HaproxyConfigurator(_uuid(),

neutron/tests/unit/agent/ovn/metadata/test_driver.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import os
1717
from unittest import mock
1818

19+
from neutron_lib import exceptions as lib_exceptions
1920
from neutron_lib import fixture as lib_fixtures
2021
from oslo_config import cfg
2122
from oslo_utils import uuidutils
@@ -123,6 +124,29 @@ def test_spawn_metadata_proxy(self):
123124
self.delete_if_exists.assert_called_once_with(
124125
mock.ANY, run_as_root=True)
125126

127+
@mock.patch.object(metadata_driver.LOG, 'error')
128+
def test_spawn_metadata_proxy_handles_process_exception(self, error_log):
129+
process_instance = mock.Mock(active=False)
130+
process_instance.enable.side_effect = (
131+
lib_exceptions.ProcessExecutionError('Something happened', -1))
132+
133+
with mock.patch.object(metadata_driver.MetadataDriver,
134+
'_get_metadata_proxy_process_manager',
135+
return_value=process_instance):
136+
process_monitor = mock.Mock()
137+
network_id = 123456
138+
139+
metadata_driver.MetadataDriver.spawn_monitored_metadata_proxy(
140+
process_monitor,
141+
'dummy_namespace',
142+
self.METADATA_PORT,
143+
cfg.CONF,
144+
network_id=network_id)
145+
146+
error_log.assert_called_once()
147+
process_monitor.register.assert_not_called()
148+
self.assertNotIn(network_id, metadata_driver.MetadataDriver.monitors)
149+
126150
def test_create_config_file_wrong_user(self):
127151
with mock.patch('pwd.getpwnam', side_effect=KeyError):
128152
config = metadata_driver.HaproxyConfigurator(mock.ANY, mock.ANY,

0 commit comments

Comments
 (0)