diff options
Diffstat (limited to 'nova/conductor/manager.py')
-rw-r--r-- | nova/conductor/manager.py | 79 |
1 files changed, 62 insertions, 17 deletions
diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py index dc2b844496..1c644cf299 100644 --- a/nova/conductor/manager.py +++ b/nova/conductor/manager.py @@ -1307,8 +1307,37 @@ class ComputeTaskManager(base.Base): updates = {'vm_state': vm_states.ERROR, 'task_state': None} for instance in instances_by_uuid.values(): + + inst_mapping = None + try: + # We don't need the cell0-targeted context here because the + # instance mapping is in the API DB. + inst_mapping = \ + objects.InstanceMapping.get_by_instance_uuid( + context, instance.uuid) + except exception.InstanceMappingNotFound: + # The API created the instance mapping record so it should + # definitely be here. Log an error but continue to create the + # instance in the cell0 database. + LOG.error('While burying instance in cell0, no instance ' + 'mapping was found.', instance=instance) + + # Perform a final sanity check that the instance is not mapped + # to some other cell already because of maybe some crazy + # clustered message queue weirdness. + if inst_mapping and inst_mapping.cell_mapping is not None: + LOG.error('When attempting to bury instance in cell0, the ' + 'instance is already mapped to cell %s. Ignoring ' + 'bury in cell0 attempt.', + inst_mapping.cell_mapping.identity, + instance=instance) + continue + with obj_target_cell(instance, cell0) as cctxt: instance.create() + if inst_mapping: + inst_mapping.cell_mapping = cell0 + inst_mapping.save() # Record an instance action with a failed event. self._create_instance_action_for_cell0( @@ -1328,16 +1357,6 @@ class ComputeTaskManager(base.Base): self._set_vm_state_and_notify( cctxt, instance.uuid, 'build_instances', updates, exc, request_spec) - try: - # We don't need the cell0-targeted context here because the - # instance mapping is in the API DB. - inst_mapping = \ - objects.InstanceMapping.get_by_instance_uuid( - context, instance.uuid) - inst_mapping.cell_mapping = cell0 - inst_mapping.save() - except exception.InstanceMappingNotFound: - pass for build_request in build_requests: try: @@ -1506,13 +1525,8 @@ class ComputeTaskManager(base.Base): instance.tags = instance_tags if instance_tags \ else objects.TagList() - # Update mapping for instance. Normally this check is guarded by - # a try/except but if we're here we know that a newer nova-api - # handled the build process and would have created the mapping - inst_mapping = objects.InstanceMapping.get_by_instance_uuid( - context, instance.uuid) - inst_mapping.cell_mapping = cell - inst_mapping.save() + # Update mapping for instance. + self._map_instance_to_cell(context, instance, cell) if not self._delete_build_request( context, build_request, instance, cell, instance_bdms, @@ -1540,6 +1554,37 @@ class ComputeTaskManager(base.Base): host=host.service_host, node=host.nodename, limits=host.limits, host_list=host_list) + @staticmethod + def _map_instance_to_cell(context, instance, cell): + """Update the instance mapping to point at the given cell. + + During initial scheduling once a host and cell is selected in which + to build the instance this method is used to update the instance + mapping to point at that cell. + + :param context: nova auth RequestContext + :param instance: Instance object being built + :param cell: CellMapping representing the cell in which the instance + was created and is being built. + :returns: InstanceMapping object that was updated. + """ + inst_mapping = objects.InstanceMapping.get_by_instance_uuid( + context, instance.uuid) + # Perform a final sanity check that the instance is not mapped + # to some other cell already because of maybe some crazy + # clustered message queue weirdness. + if inst_mapping.cell_mapping is not None: + LOG.error('During scheduling instance is already mapped to ' + 'another cell: %s. This should not happen and is an ' + 'indication of bigger problems. If you see this you ' + 'should report it to the nova team. Overwriting ' + 'the mapping to point at cell %s.', + inst_mapping.cell_mapping.identity, cell.identity, + instance=instance) + inst_mapping.cell_mapping = cell + inst_mapping.save() + return inst_mapping + def _cleanup_build_artifacts(self, context, exc, instances, build_requests, request_specs, block_device_mappings, tags, cell_mapping_cache): |