Use instance.project_id when creating request specs for old instances

The online data migration routine to create request specs for old
instances is using an admin context, which doesn't have a project_id
set, which means the request spec that gets created doesn't have
a project_id set, which matters when the FilterScheduler tries to
claim resources (create allocations in Placement) using said
request spec's project_id (PUT /allocations requires a non-null
project_id).

This fixes the online data migration by creating the request spec
using the instance's project_id rather than that from the context.

Conflicts:
      nova/objects/request_spec.py

NOTE(mriedem): The conflict is due to
b26ef56807 which is not
in Newton nor is it needed.

Change-Id: I214a44f0eee7d90be5cd89f32f6e0017b19a3fd6
Partial-Bug: #1739318
(cherry picked from commit a148e638dd)
(cherry picked from commit c86db10feb)
(cherry picked from commit ff2231f583)
This commit is contained in:
Matt Riedemann 2017-12-19 18:31:27 -05:00
parent e4e7b8da56
commit 99b9cff2e4
2 changed files with 11 additions and 5 deletions

View File

@ -365,7 +365,7 @@ class RequestSpec(base.NovaObject):
@classmethod
def from_components(cls, context, instance_uuid, image, flavor,
numa_topology, pci_requests, filter_properties, instance_group,
availability_zone):
availability_zone, project_id=None):
"""Returns a new RequestSpec object hydrated by various components.
This helper is useful in creating the RequestSpec from the various
@ -382,6 +382,8 @@ class RequestSpec(base.NovaObject):
:param filter_properties: a dict of properties for scheduling
:param instance_group: None or an instance group NovaObject
:param availability_zone: an availability_zone string
:param project_id: The project_id for the requestspec (should match
the instance project_id).
"""
spec_obj = cls(context)
spec_obj.num_instances = 1
@ -389,7 +391,7 @@ class RequestSpec(base.NovaObject):
spec_obj.instance_group = instance_group
if spec_obj.instance_group is None and filter_properties:
spec_obj._populate_group_info(filter_properties)
spec_obj.project_id = context.project_id
spec_obj.project_id = project_id or context.project_id
spec_obj._image_meta_from_image(image)
spec_obj._from_flavor(flavor)
spec_obj._from_instance_pci_requests(pci_requests)
@ -555,7 +557,8 @@ def _create_minimal_request_spec(context, instance):
context, instance.uuid, image,
instance.flavor, instance.numa_topology,
instance.pci_requests,
filter_properties, None, instance.availability_zone
filter_properties, None, instance.availability_zone,
project_id=instance.project_id
)
request_spec.create()

View File

@ -138,9 +138,12 @@ class RequestSpecInstanceMigrationTestCase(
self.assertEqual(0, done)
# Make sure all instances have now a related RequestSpec
for uuid in [instance.uuid for instance in self.instances]:
for instance in self.instances:
uuid = instance.uuid
try:
objects.RequestSpec.get_by_instance_uuid(self.context, uuid)
spec = objects.RequestSpec.get_by_instance_uuid(
self.context, uuid)
self.assertEqual(instance.project_id, spec.project_id)
except exception.RequestSpecNotFound:
self.fail("RequestSpec not found for instance UUID :%s ", uuid)