Merge "Add useful error log when _determine_version_cap raises DBNotAllowed" into stable/stein

This commit is contained in:
Zuul 2019-08-29 13:52:15 +00:00 committed by Gerrit Code Review
commit 7cc65270cb
3 changed files with 47 additions and 3 deletions

View File

@ -18,6 +18,7 @@ Client side of the compute RPC API.
from oslo_log import log as logging
import oslo_messaging as messaging
from oslo_serialization import jsonutils
from oslo_utils import excutils
import nova.conf
from nova import context
@ -393,8 +394,22 @@ class ComputeAPI(object):
# NOTE(danms): If we have a connection to the api database,
# we should iterate all cells. If not, we must only look locally.
if CONF.api_database.connection:
service_version = service_obj.get_minimum_version_all_cells(
context.get_admin_context(), ['nova-compute'])
try:
service_version = service_obj.get_minimum_version_all_cells(
context.get_admin_context(), ['nova-compute'])
except exception.DBNotAllowed:
# This most likely means we are in a nova-compute service
# configured with [upgrade_levels]/compute=auto and a
# connection to the API database. We should not be attempting
# to "get out" of our cell to look at the minimum versions of
# nova-compute services in other cells, so DBNotAllowed was
# raised. Log a user-friendly message and re-raise the error.
with excutils.save_and_reraise_exception():
LOG.error('This service is configured for access to the '
'API database but is not allowed to directly '
'access the database. You should run this '
'service without the [api_database]/connection '
'config option.')
else:
service_version = objects.Service.get_minimum_version(
context.get_admin_context(), 'nova-compute')

View File

@ -36,13 +36,16 @@ api_db_group = cfg.OptGroup('api_database',
The *Nova API Database* is a separate database which is used for information
which is used across *cells*. This database is mandatory since the Mitaka
release (13.0.0).
This group should **not** be configured for the ``nova-compute`` service.
""")
api_db_opts = [
# TODO(markus_z): This should probably have a required=True attribute
cfg.StrOpt('connection',
secret=True,
help=''),
# This help gets appended to the oslo.db help so prefix with a space.
help=' Do not set this for the ``nova-compute`` service.'),
cfg.StrOpt('connection_parameters',
default='',
help=''),

View File

@ -614,3 +614,29 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
compute_rpcapi.ComputeAPI()
mock_allcells.assert_called_once_with(mock.ANY, ['nova-compute'])
mock_minver.assert_not_called()
@mock.patch('nova.compute.rpcapi.LOG.error')
@mock.patch('nova.objects.Service.get_minimum_version')
@mock.patch('nova.objects.service.get_minimum_version_all_cells',
side_effect=exception.DBNotAllowed(binary='nova-compute'))
def test_version_cap_all_cells_no_access(self, mock_allcells, mock_minver,
mock_log_error):
"""Tests a scenario where nova-compute is configured with a connection
to the API database and fails trying to get the minium nova-compute
service version across all cells because nova-compute is configured to
not allow direct database access.
"""
self.flags(connection='sqlite:///', group='api_database')
compute_rpcapi.LAST_VERSION = None
self.assertRaises(exception.DBNotAllowed,
compute_rpcapi.ComputeAPI()._determine_version_cap,
mock.Mock())
mock_allcells.assert_called_once_with(mock.ANY, ['nova-compute'])
mock_minver.assert_not_called()
# Make sure the expected error was logged.
mock_log_error.assert_called_once_with(
'This service is configured for access to the '
'API database but is not allowed to directly '
'access the database. You should run this '
'service without the [api_database]/connection '
'config option.')