diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-07-18 16:03:33 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-07-18 16:03:33 +0000 |
| commit | 2e9ed45806f9fa7d4bdaa73050b92ba5f9463203 (patch) | |
| tree | d369a08fb72f834f92f68cbc4d3aca0602fc5a7d /nova/api | |
| parent | 6dd53cf4970ffb08fe961e72b78a5c170c536b62 (diff) | |
| parent | 8600394ec4dd4f800d774e4ed0c24fe087d8e1d3 (diff) | |
Merge "Support EC2 CreateImage API for boot-from-volume"
Diffstat (limited to 'nova/api')
| -rw-r--r-- | nova/api/ec2/cloud.py | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 94302383c..af74e75b8 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -1449,6 +1449,7 @@ class CloudController(object): # NOTE(yamahata): name/description are ignored by register_image(), # do so here no_reboot = kwargs.get('no_reboot', False) + name = kwargs.get('name') validate_ec2_id(instance_id) ec2_instance_id = instance_id instance_id = ec2utils.ec2_id_to_id(ec2_instance_id) @@ -1481,14 +1482,22 @@ class CloudController(object): raise exception.EC2APIError( _('Couldn\'t stop instance with in %d sec') % timeout) - src_image = self._get_image(context, instance['image_ref']) - properties = src_image['properties'] + glance_uuid = instance['image_ref'] + ec2_image_id = ec2utils.glance_id_to_ec2_id(context, glance_uuid) + src_image = self._get_image(context, ec2_image_id) + new_image = dict(src_image) + properties = new_image['properties'] if instance['root_device_name']: properties['root_device_name'] = instance['root_device_name'] + # meaningful image name + name_map = dict(instance=instance['uuid'], now=timeutils.isotime()) + new_image['name'] = (name or + _('image of %(instance)s at %(now)s') % name_map) + mapping = [] bdms = db.block_device_mapping_get_all_by_instance(context, - instance_id) + instance['uuid']) for bdm in bdms: if bdm.no_device: continue @@ -1501,15 +1510,16 @@ class CloudController(object): m[attr] = val volume_id = m.get('volume_id') - if m.get('snapshot_id') and volume_id: + snapshot_id = m.get('snapshot_id') + if snapshot_id and volume_id: # create snapshot based on volume_id volume = self.volume_api.get(context, volume_id) # NOTE(yamahata): Should we wait for snapshot creation? # Linux LVM snapshot creation completes in # short time, it doesn't matter for now. + name = _('snapshot for %s') % new_image['name'] snapshot = self.volume_api.create_snapshot_force( - context, volume, volume['display_name'], - volume['display_description']) + context, volume, name, volume['display_description']) m['snapshot_id'] = snapshot['id'] del m['volume_id'] @@ -1536,14 +1546,30 @@ class CloudController(object): properties['block_device_mapping'] = mapping for attr in ('status', 'location', 'id'): - src_image.pop(attr, None) + new_image.pop(attr, None) + + # the new image is simply a bucket of properties (particularly the + # block device mapping, kernel and ramdisk IDs) with no image data, + # hence the zero size + new_image['size'] = 0 + + def _unmap_id_property(properties, name): + if properties[name]: + properties[name] = ec2utils.id_to_glance_id(context, + properties[name]) - image_id = self._register_image(context, src_image) + # ensure the ID properties are unmapped back to the glance UUID + _unmap_id_property(properties, 'kernel_id') + _unmap_id_property(properties, 'ramdisk_id') + + new_image = self.image_service.service.create(context, new_image, + data='') + ec2_id = ec2utils.glance_id_to_ec2_id(context, new_image['id']) if restart_instance: self.compute_api.start(context, instance_id=instance_id) - return {'imageId': image_id} + return {'imageId': ec2_id} class CloudSecurityGroupAPI(compute.api.SecurityGroupAPI): |
