Browse Source

Fix an error when generating a host ID

When instance action events are created by periodic tasks,
the project IDs of them become null (None).
It causes an error when 'hostId' is generated
in the "Show Server Action Details"
(GET /servers/{server_id}/os-instance-actions/{request_id})
API.

Fix the issue by using the project ID of the server
if the project ID of the event is None.

Change-Id: Iac07fcddd4cc3321c6efe702066eb8af6a875418
Closes-Bug: #1817542
tags/19.0.0.0rc1
Takashi NATSUME 6 months ago
parent
commit
31fe7c7600

+ 8
- 1
nova/api/openstack/compute/instance_actions.py View File

@@ -175,8 +175,15 @@ class InstanceActionsController(wsgi.Controller):
175 175
         if show_events:
176 176
             events_raw = self.action_api.action_events_get(context, instance,
177 177
                                                            action_id)
178
+            # NOTE(takashin): The project IDs of instance action events
179
+            # become null (None) when instance action events are created
180
+            # by periodic tasks. If the project ID is null (None),
181
+            # it causes an error when 'hostId' is generated.
182
+            # If the project ID is null (None), pass the project ID of
183
+            # the server instead of that of instance action events.
178 184
             action['events'] = [self._format_event(
179
-                evt, action['project_id'], show_traceback=show_traceback,
185
+                evt, action['project_id'] or instance.project_id,
186
+                show_traceback=show_traceback,
180 187
                 show_host=show_host, show_hostid=show_hostid
181 188
             ) for evt in events_raw]
182 189
         return {'instanceAction': action}

+ 60
- 1
nova/tests/unit/api/openstack/compute/test_instance_actions.py View File

@@ -34,6 +34,7 @@ from nova import test
34 34
 from nova.tests.unit.api.openstack import fakes
35 35
 from nova.tests.unit import fake_instance
36 36
 from nova.tests.unit import fake_server_actions
37
+from nova import utils
37 38
 
38 39
 
39 40
 FAKE_UUID = fake_server_actions.FAKE_UUID
@@ -329,10 +330,68 @@ class InstanceActionsTestV258(InstanceActionsTestV251):
329 330
                       six.text_type(ex))
330 331
 
331 332
 
332
-class InstanceActionsTestV262(InstanceActionsTestV251):
333
+class InstanceActionsTestV262(InstanceActionsTestV258):
333 334
     wsgi_api_version = "2.62"
334 335
     expect_event_hostId = True
335 336
     expect_event_host = True
337
+    instance_project_id = '26cde4489f6749a08834741678df3c4a'
338
+
339
+    def fake_get(self, context, instance_uuid, expected_attrs=None,
340
+                 cell_down_support=False):
341
+        return objects.Instance(uuid=instance_uuid,
342
+                                project_id=self.instance_project_id)
343
+
344
+    @mock.patch.object(compute_api.InstanceActionAPI, 'action_events_get')
345
+    @mock.patch.object(compute_api.InstanceActionAPI,
346
+                       'action_get_by_request_id')
347
+    def test_get_action_with_events_project_id_none(self, mock_action_get,
348
+                                                    mock_action_events):
349
+        fake_request_id = 'req-%s' % uuids.req1
350
+
351
+        mock_action_get.return_value = objects.InstanceAction(
352
+            id=789,
353
+            action='stop',
354
+            instance_uuid=uuids.instance,
355
+            request_id=fake_request_id,
356
+            user_id=None,
357
+            project_id=None,
358
+            start_time=datetime.datetime(2019, 2, 28, 14, 28, 0, 0),
359
+            finish_time=None,
360
+            message='',
361
+            created_at=None,
362
+            updated_at=None,
363
+            deleted_at=None,
364
+            deleted=False)
365
+
366
+        mock_action_events.return_value = [
367
+            objects.InstanceActionEvent(
368
+                id=5,
369
+                action_id=789,
370
+                event='compute_stop_instance',
371
+                start_time=datetime.datetime(2019, 2, 28, 14, 28, 0, 0),
372
+                finish_time=datetime.datetime(2019, 2, 28, 14, 30, 0, 0),
373
+                result='Success',
374
+                traceback='',
375
+                created_at=None,
376
+                updated_at=None,
377
+                deleted_at=None,
378
+                deleted=False,
379
+                host='host2')]
380
+
381
+        req = self._get_http_req('os-instance-actions/1',
382
+                                 use_admin_context=True)
383
+        res_dict = self.controller.show(req, uuids.instance, fake_request_id)
384
+
385
+        # Assert that 'project_id' is null (None) in the response
386
+        self.assertIsNone(res_dict['instanceAction']['project_id'])
387
+        self.assertEqual('host2',
388
+                         res_dict['instanceAction']['events'][0]['host'])
389
+        # Assert that the 'hostId' is based on 'host' and the project ID
390
+        # of the server
391
+        self.assertEqual(utils.generate_hostid(
392
+            res_dict['instanceAction']['events'][0]['host'],
393
+            self.instance_project_id),
394
+            res_dict['instanceAction']['events'][0]['hostId'])
336 395
 
337 396
 
338 397
 class InstanceActionsTestV266(InstanceActionsTestV258):

Loading…
Cancel
Save