Remove eventlet based WSGI server entry points

Nova deprecated[1] running the API services under Eventlet in the Rocky
release 6 years ago. Now that we are trying to transition away from
Eventlet it is time to rip out these entry points fully.

[1] b53d81b03c

Change-Id: Ie758550c0b8fb02aeb398396961467d9f845fcc9
This commit is contained in:
Balazs Gibizer
2025-04-15 14:50:56 +02:00
parent 1ad11b1388
commit 05b219746f
6 changed files with 5 additions and 253 deletions

View File

@@ -1,71 +0,0 @@
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Starter script for Nova API.
Starts both the EC2 and OpenStack APIs in separate greenthreads.
"""
import sys
from oslo_log import log as logging
from oslo_reports import guru_meditation_report as gmr
from oslo_reports import opts as gmr_opts
import nova.conf
from nova.conf import remote_debug
from nova import config
from nova import exception
from nova import objects
from nova import service
from nova import version
CONF = nova.conf.CONF
remote_debug.register_cli_opts(CONF)
def main():
config.parse_args(sys.argv)
logging.setup(CONF, "nova")
objects.register_all()
gmr_opts.set_defaults(CONF)
if 'osapi_compute' in CONF.enabled_apis:
# NOTE(mriedem): This is needed for caching the nova-compute service
# version.
objects.Service.enable_min_version_cache()
log = logging.getLogger(__name__)
gmr.TextGuruMeditation.setup_autorun(version, conf=CONF)
launcher = service.process_launcher()
started = 0
for api in CONF.enabled_apis:
should_use_ssl = api in CONF.enabled_ssl_apis
try:
server = service.WSGIService(api, use_ssl=should_use_ssl)
launcher.launch_service(server, workers=server.workers or 1)
started += 1
except exception.PasteAppNotFound as ex:
log.warning("%s. ``enabled_apis`` includes bad values. "
"Fix to remove this warning.", ex)
if started == 0:
log.error('No APIs were started. '
'Check the enabled_apis config option.')
sys.exit(1)
launcher.wait()

View File

@@ -1,52 +0,0 @@
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Starter script for Nova Metadata API."""
import sys
from oslo_log import log as logging
from oslo_reports import guru_meditation_report as gmr
from oslo_reports import opts as gmr_opts
from nova.conductor import rpcapi as conductor_rpcapi
import nova.conf
from nova.conf import remote_debug
from nova import config
from nova import objects
from nova.objects import base as objects_base
from nova import service
from nova import version
CONF = nova.conf.CONF
remote_debug.register_cli_opts(CONF)
def main():
config.parse_args(sys.argv)
logging.setup(CONF, "nova")
objects.register_all()
gmr_opts.set_defaults(CONF)
gmr.TextGuruMeditation.setup_autorun(version, conf=CONF)
objects_base.NovaObject.indirection_api = conductor_rpcapi.ConductorAPI()
should_use_ssl = 'metadata' in CONF.enabled_ssl_apis
server = service.WSGIService('metadata', use_ssl=should_use_ssl)
service.serve(server, workers=server.workers)
service.wait()

View File

@@ -1,51 +0,0 @@
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Starter script for Nova OS API."""
import sys
from oslo_log import log as logging
from oslo_reports import guru_meditation_report as gmr
from oslo_reports import opts as gmr_opts
import nova.conf
from nova.conf import remote_debug
from nova import config
from nova import objects
from nova import service
from nova import version
CONF = nova.conf.CONF
remote_debug.register_cli_opts(CONF)
def main():
config.parse_args(sys.argv)
logging.setup(CONF, "nova")
objects.register_all()
gmr_opts.set_defaults(CONF)
# NOTE(mriedem): This is needed for caching the nova-compute service
# version.
objects.Service.enable_min_version_cache()
gmr.TextGuruMeditation.setup_autorun(version, conf=CONF)
should_use_ssl = 'osapi_compute' in CONF.enabled_ssl_apis
server = service.WSGIService('osapi_compute', use_ssl=should_use_ssl)
service.serve(server, workers=server.workers)
service.wait()

View File

@@ -1,76 +0,0 @@
# Copyright 2015 HPE, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from unittest import mock
from nova.cmd import api
from nova import config
from nova import exception
from nova import test
# required because otherwise oslo early parse_args dies
@mock.patch.object(config, 'parse_args', new=lambda *args, **kwargs: None)
# required so we don't set the global service version cache
@mock.patch('nova.objects.Service.enable_min_version_cache')
class TestNovaAPI(test.NoDBTestCase):
def test_continues_on_failure(self, version_cache):
count = [1]
fake_server = mock.MagicMock()
fake_server.workers = 123
def fake_service(api, **kw):
while count:
count.pop()
raise exception.PasteAppNotFound(name=api, path='/')
return fake_server
self.flags(enabled_apis=['osapi_compute', 'metadata'])
with mock.patch.object(api, 'service') as mock_service:
mock_service.WSGIService.side_effect = fake_service
api.main()
mock_service.WSGIService.assert_has_calls([
mock.call('osapi_compute', use_ssl=False),
mock.call('metadata', use_ssl=False),
])
launcher = mock_service.process_launcher.return_value
launcher.launch_service.assert_called_once_with(
fake_server, workers=123)
self.assertTrue(version_cache.called)
@mock.patch('sys.exit')
def test_fails_if_none_started(self, mock_exit, version_cache):
mock_exit.side_effect = test.TestingException
self.flags(enabled_apis=[])
with mock.patch.object(api, 'service') as mock_service:
self.assertRaises(test.TestingException, api.main)
mock_exit.assert_called_once_with(1)
launcher = mock_service.process_launcher.return_value
self.assertFalse(launcher.wait.called)
self.assertFalse(version_cache.called)
@mock.patch('sys.exit')
def test_fails_if_all_failed(self, mock_exit, version_cache):
mock_exit.side_effect = test.TestingException
self.flags(enabled_apis=['osapi_compute', 'metadata'])
with mock.patch.object(api, 'service') as mock_service:
mock_service.WSGIService.side_effect = exception.PasteAppNotFound(
name='foo', path='/')
self.assertRaises(test.TestingException, api.main)
mock_exit.assert_called_once_with(1)
launcher = mock_service.process_launcher.return_value
self.assertFalse(launcher.wait.called)
self.assertTrue(version_cache.called)

View File

@@ -0,0 +1,5 @@
---
upgrade:
- |
Running API services (nova-osapi_compute or nova-metadata) with eventlet
is removed. Deploy with a WSGI server such as uwsgi or mod_wsgi.

View File

@@ -74,9 +74,6 @@ nova.api.extra_spec_validators =
nova.compute.monitors.cpu =
virt_driver = nova.compute.monitors.cpu.virt_driver:Monitor
console_scripts =
nova-api = nova.cmd.api:main
nova-api-metadata = nova.cmd.api_metadata:main
nova-api-os-compute = nova.cmd.api_os_compute:main
nova-compute = nova.cmd.compute:main
nova-conductor = nova.cmd.conductor:main
nova-manage = nova.cmd.manage:main