From 26aa01094a79939320d58f2fe2d5731f169987b1 Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Wed, 20 Mar 2013 18:13:05 +0000 Subject: Change arguments to volume_detach() Most compute API calls accept an instance object. To be compatible with cells, volume_detach() should as well. Also change it to accept the volume object, instead of just a volume ID. This lets us proxy the volume object to child cells a bit more easily. This removes 2 skipTests that we have related to volumes and cells. Fixes bug 1157408 There was also a check that if instance_get_by_uuid() returned no instance, it VolumeUnattached should be raised. However, this check would never work as InstanceNotFound would have been raised. This patch also corrects that. Change-Id: Ide35ad5d8e147f6bd21b5840b901363dab0eae38 --- nova/api/ec2/cloud.py | 12 +++++++++++- nova/api/openstack/compute/contrib/volumes.py | 15 +++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index a35460576..206a72679 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -897,14 +897,24 @@ class CloudController(object): 'status': volume['attach_status'], 'volumeId': ec2utils.id_to_ec2_vol_id(volume_id)} + def _get_instance_from_volume(self, context, volume): + if volume['instance_uuid']: + try: + return db.instance_get_by_uuid(context, + volume['instance_uuid']) + except exception.InstanceNotFound: + pass + raise exception.VolumeUnattached(volume_id=volume['id']) + def detach_volume(self, context, volume_id, **kwargs): validate_ec2_id(volume_id) volume_id = ec2utils.ec2_vol_id_to_uuid(volume_id) LOG.audit(_("Detach volume %s"), volume_id, context=context) volume = self.volume_api.get(context, volume_id) + instance = self._get_instance_from_volume(context, volume) try: - self.compute_api.detach_volume(context, volume_id=volume_id) + self.compute_api.detach_volume(context, instance, volume) except exception.InvalidVolume: raise exception.EC2APIError(_('Detach Volume Failed.')) diff --git a/nova/api/openstack/compute/contrib/volumes.py b/nova/api/openstack/compute/contrib/volumes.py index b16d61852..27f5e4050 100644 --- a/nova/api/openstack/compute/contrib/volumes.py +++ b/nova/api/openstack/compute/contrib/volumes.py @@ -326,6 +326,7 @@ class VolumeAttachmentController(wsgi.Controller): def __init__(self): self.compute_api = compute.API() + self.volume_api = volume.API() super(VolumeAttachmentController, self).__init__() @wsgi.serializers(xml=VolumeAttachmentsTemplate) @@ -442,8 +443,9 @@ class VolumeAttachmentController(wsgi.Controller): except exception.NotFound: raise exc.HTTPNotFound() - bdms = self.compute_api.get_instance_bdms(context, instance) + volume = self.volume_api.get(context, volume_id) + bdms = self.compute_api.get_instance_bdms(context, instance) if not bdms: LOG.debug(_("Instance %s is not attached."), server_id) raise exc.HTTPNotFound() @@ -451,11 +453,16 @@ class VolumeAttachmentController(wsgi.Controller): found = False try: for bdm in bdms: - if bdm['volume_id'] == volume_id: - self.compute_api.detach_volume(context, - volume_id=volume_id) + if bdm['volume_id'] != volume_id: + continue + try: + self.compute_api.detach_volume(context, instance, volume) found = True break + except exception.VolumeUnattached: + # The volume is not attached. Treat it as NotFound + # by falling through. + pass except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state(state_error, 'detach_volume') -- cgit