Fail to start nova-api if no APIs were able to be started

This helps to make it clear that either you specified no API services,
or you specified all bad ones, or that you fat-fingered the thing
entirely. If we can't start any, we shouldn't start the process acting
like we did and then wait for you to figure out the hard way that we
aren't actually listening for any requests.

Change-Id: I864486a58cf3fde35647ae3b8d2ad917c809ea54
Related-Bug: #1572495
(cherry picked from commit 9b2329d100)
This commit is contained in:
Dan Smith 2016-04-22 14:22:08 -07:00 committed by Matt Riedemann
parent 8ec57fb155
commit e80a873524
2 changed files with 30 additions and 1 deletions

View File

@ -29,7 +29,7 @@ import six
from nova import config
from nova import exception
from nova.i18n import _LW
from nova.i18n import _LE, _LW
from nova import objects
from nova import service
from nova import utils
@ -50,14 +50,21 @@ def main():
gmr.TextGuruMeditation.setup_autorun(version)
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(
_LW("%s. ``enabled_apis`` includes bad values. "
"Fix to remove this warning."), six.text_type(ex))
if started == 0:
log.error(_LE('No APIs were started. '
'Check the enabled_apis config option.'))
sys.exit(1)
launcher.wait()

View File

@ -65,3 +65,25 @@ class TestNovaAPI(test.NoDBTestCase):
launcher = mock_service.process_launcher.return_value
launcher.launch_service.assert_called_once_with(
fake_server, workers=123)
@mock.patch('sys.exit')
def test_fails_if_none_started(self, mock_exit):
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)
@mock.patch('sys.exit')
def test_fails_if_all_failed(self, mock_exit):
mock_exit.side_effect = test.TestingException
self.flags(enabled_apis=['foo', 'bar'])
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)