Skip to content

Commit

Permalink
validate specified volumes to boot from at the API layer
Browse files Browse the repository at this point in the history
This causes the create to fail fast instead of putting
the instance into error later in the process.

Related to bug: 1069904
Change-Id: I5f7c8d20d3ebf33ce1ce64bf0a8418bd2b5a6411
  • Loading branch information
vishvananda authored and Pádraig Brady committed Jan 29, 2013
1 parent 3ddd1ae commit 24fffd9
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
27 changes: 22 additions & 5 deletions nova/compute/api.py
Expand Up @@ -558,6 +558,11 @@ def _validate_and_provision_instance(self, context, instance_type,
security_group, block_device_mapping)
instances.append(instance)
instance_uuids.append(instance['uuid'])
self._validate_bdm(context, instance)
# send a state update notification for the initial create to
# show it going from non-existent to BUILDING
notifications.send_update_with_states(context, instance, None,
vm_states.BUILDING, None, None, service="api")

# In the case of any exceptions, attempt DB cleanup and rollback the
# quota reservations.
Expand Down Expand Up @@ -704,6 +709,23 @@ def _update_block_device_mapping(self, elevated_context,
self.db.block_device_mapping_update_or_create(elevated_context,
values)

def _validate_bdm(self, context, instance):
for bdm in self.db.block_device_mapping_get_all_by_instance(
context, instance['uuid']):
# NOTE(vish): For now, just make sure the volumes are accessible.
snapshot_id = bdm.get('snapshot_id')
volume_id = bdm.get('volume_id')
if volume_id is not None:
try:
self.volume_api.get(context, volume_id)
except Exception:
raise exception.InvalidBDMVolume(id=volume_id)
elif snapshot_id is not None:
try:
self.volume_api.get_snapshot(context, snapshot_id)
except Exception:
raise exception.InvalidBDMSnapshot(id=snapshot_id)

def _populate_instance_for_bdm(self, context, instance, instance_type,
image, block_device_mapping):
"""Populate instance block device mapping information."""
Expand Down Expand Up @@ -818,11 +840,6 @@ def create_db_entry_for_new_instance(self, context, instance_type, image,
self._populate_instance_for_bdm(context, instance,
instance_type, image, block_device_mapping)

# send a state update notification for the initial create to
# show it going from non-existent to BUILDING
notifications.send_update_with_states(context, instance, None,
vm_states.BUILDING, None, None, service="api")

return instance

def _check_create_policies(self, context, availability_zone,
Expand Down
14 changes: 14 additions & 0 deletions nova/exception.py
Expand Up @@ -226,6 +226,20 @@ class Invalid(NovaException):
code = 400


class InvalidBDM(Invalid):
message = _("Block Device Mapping is Invalid.")


class InvalidBDMSnapshot(InvalidBDM):
message = _("Block Device Mapping is Invalid: "
"failed to get snapshot %(id)s.")


class InvalidBDMVolume(InvalidBDM):
message = _("Block Device Mapping is Invalid: "
"failed to get volume %(id)s.")


class VolumeUnattached(Invalid):
message = _("Volume %(volume_id)s is not attached to anything")

Expand Down

0 comments on commit 24fffd9

Please sign in to comment.