Browse Source

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

changes/19/679519/1
Zuul 3 weeks ago
parent
commit
7cc65270cb
3 changed files with 47 additions and 3 deletions
  1. 17
    2
      nova/compute/rpcapi.py
  2. 4
    1
      nova/conf/database.py
  3. 26
    0
      nova/tests/unit/compute/test_rpcapi.py

+ 17
- 2
nova/compute/rpcapi.py View File

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

+ 4
- 1
nova/conf/database.py View File

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

+ 26
- 0
nova/tests/unit/compute/test_rpcapi.py View File

@@ -614,3 +614,29 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
614 614
         compute_rpcapi.ComputeAPI()
615 615
         mock_allcells.assert_called_once_with(mock.ANY, ['nova-compute'])
616 616
         mock_minver.assert_not_called()
617
+
618
+    @mock.patch('nova.compute.rpcapi.LOG.error')
619
+    @mock.patch('nova.objects.Service.get_minimum_version')
620
+    @mock.patch('nova.objects.service.get_minimum_version_all_cells',
621
+                side_effect=exception.DBNotAllowed(binary='nova-compute'))
622
+    def test_version_cap_all_cells_no_access(self, mock_allcells, mock_minver,
623
+                                             mock_log_error):
624
+        """Tests a scenario where nova-compute is configured with a connection
625
+        to the API database and fails trying to get the minium nova-compute
626
+        service version across all cells because nova-compute is configured to
627
+        not allow direct database access.
628
+        """
629
+        self.flags(connection='sqlite:///', group='api_database')
630
+        compute_rpcapi.LAST_VERSION = None
631
+        self.assertRaises(exception.DBNotAllowed,
632
+                          compute_rpcapi.ComputeAPI()._determine_version_cap,
633
+                          mock.Mock())
634
+        mock_allcells.assert_called_once_with(mock.ANY, ['nova-compute'])
635
+        mock_minver.assert_not_called()
636
+        # Make sure the expected error was logged.
637
+        mock_log_error.assert_called_once_with(
638
+            'This service is configured for access to the '
639
+            'API database but is not allowed to directly '
640
+            'access the database. You should run this '
641
+            'service without the [api_database]/connection '
642
+            'config option.')

Loading…
Cancel
Save