validate specified volumes to boot from at the API layer

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
This commit is contained in:
Vishvananda Ishaya
2013-01-24 10:07:33 +00:00
committed by Pádraig Brady
parent 3ddd1aeda6
commit 24fffd9d8b
2 changed files with 36 additions and 5 deletions

View File

@@ -558,6 +558,11 @@ class API(base.Base):
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.
@@ -704,6 +709,23 @@ class API(base.Base):
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."""
@@ -818,11 +840,6 @@ class API(base.Base):
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,

View File

@@ -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")