diff options
author | Maru Newby <mnewby@internap.com> | 2012-03-12 23:19:16 -0700 |
---|---|---|
committer | Brian Waldon <bcwaldon@gmail.com> | 2012-03-13 10:09:12 -0700 |
commit | 0929e3a289af39fc38b46c4a55db06b8888e671e (patch) | |
tree | e7c90b6bfd014b06a4cc612b1c91e18a247e6111 /nova | |
parent | 094985ea657f590936906829486829846a558f05 (diff) | |
download | nova-0929e3a289af39fc38b46c4a55db06b8888e671e.tar.gz nova-0929e3a289af39fc38b46c4a55db06b8888e671e.tar.xz nova-0929e3a289af39fc38b46c4a55db06b8888e671e.zip |
Refactor glance id<->internal id conversion for s3
* Moves nova.image.s3.S3ImageService functions for converting
between glance ('image_uuid') and internal (db) ids to ec2utils:
get_image_id => ec2utils.glance_id_to_id
get_image_uuid => ec2utils.id_to_glance_id
* Refactors ec2utils.glance_id_to_id to create a new S3Image
object associating a glance id to an internal id if such a
mapping does not already exist. Previously, only calls to
nova.api.ec2.cloud.CloudController.describe_images would
add new mappings, but now any attempt to convert a glance id
to an internal id will succeed, resolving bug 948286.
* Adds 2 convenience methods to ec2utils, as per bcwaldon:
ec2_id_to_glance_id
glance_id_to_ec2_id
* Since this is a strict refactor and only streamlines existing
well-tested functionality, this change includes no new tests.
Change-Id: I810afe05223228df1bcc20a0ac688d8c62c472b4
Diffstat (limited to 'nova')
-rw-r--r-- | nova/api/ec2/cloud.py | 28 | ||||
-rw-r--r-- | nova/api/ec2/ec2utils.py | 26 | ||||
-rw-r--r-- | nova/image/s3.py | 40 |
3 files changed, 46 insertions, 48 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 81f0c9a7e..a95a0324f 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -967,15 +967,14 @@ class CloudController(object): kernel_uuid = instance_ref['kernel_id'] if kernel_uuid is None or kernel_uuid == '': return - kernel_id = self._get_image_id(context, kernel_uuid) - result[key] = ec2utils.image_ec2_id(kernel_id, 'aki') + result[key] = ec2utils.glance_id_to_ec2_id(context, kernel_uuid, 'aki') def _format_ramdisk_id(self, context, instance_ref, result, key): ramdisk_uuid = instance_ref['ramdisk_id'] if ramdisk_uuid is None or ramdisk_uuid == '': return - ramdisk_id = self._get_image_id(context, ramdisk_uuid) - result[key] = ec2utils.image_ec2_id(ramdisk_id, 'ari') + result[key] = ec2utils.glance_id_to_ec2_id(context, ramdisk_uuid, + 'ari') def describe_instance_attribute(self, context, instance_id, attribute, **kwargs): @@ -1173,8 +1172,7 @@ class CloudController(object): ec2_id = ec2utils.id_to_ec2_id(instance_id) i['instanceId'] = ec2_id image_uuid = instance['image_ref'] - image_id = self._get_image_id(context, image_uuid) - i['imageId'] = ec2utils.image_ec2_id(image_id) + i['imageId'] = ec2utils.glance_id_to_ec2_id(context, image_uuid) self._format_kernel_id(context, instance, i, 'kernelId') self._format_ramdisk_id(context, instance, i, 'ramdiskId') i['instanceState'] = _state_description( @@ -1287,16 +1285,17 @@ class CloudController(object): max_count = int(kwargs.get('max_count', 1)) if kwargs.get('kernel_id'): kernel = self._get_image(context, kwargs['kernel_id']) - kwargs['kernel_id'] = self._get_image_uuid(context, kernel['id']) + kwargs['kernel_id'] = ec2utils.id_to_glance_id(context, + kernel['id']) if kwargs.get('ramdisk_id'): ramdisk = self._get_image(context, kwargs['ramdisk_id']) - kwargs['ramdisk_id'] = self._get_image_uuid(context, - ramdisk['id']) + kwargs['ramdisk_id'] = ec2utils.id_to_glance_id(context, + ramdisk['id']) for bdm in kwargs.get('block_device_mapping', []): _parse_block_device_mapping(bdm) image = self._get_image(context, kwargs['image_id']) - image_uuid = self._get_image_uuid(context, image['id']) + image_uuid = ec2utils.id_to_glance_id(context, image['id']) if image: image_state = self._get_image_state(image) @@ -1383,15 +1382,6 @@ class CloudController(object): raise exception.ImageNotFound(image_id=ec2_id) return image - # NOTE(bcwaldon): We need access to the image uuid since we directly - # call the compute api from this class - def _get_image_uuid(self, context, internal_id): - return self.image_service.get_image_uuid(context, internal_id) - - # NOTE(bcwaldon): We also need to be able to map image uuids to integers - def _get_image_id(self, context, image_uuid): - return self.image_service.get_image_id(context, image_uuid) - def _format_image(self, image): """Convert from format defined by GlanceImageService to S3 format.""" i = {} diff --git a/nova/api/ec2/ec2utils.py b/nova/api/ec2/ec2utils.py index e44ae287e..1a6bb96bd 100644 --- a/nova/api/ec2/ec2utils.py +++ b/nova/api/ec2/ec2utils.py @@ -18,6 +18,7 @@ import re +from nova import db from nova import exception from nova import flags from nova import log as logging @@ -46,6 +47,31 @@ def image_type(image_type): return image_type +def id_to_glance_id(context, image_id): + """Convert an internal (db) id to a glance id.""" + return db.s3_image_get(context, image_id)['uuid'] + + +def glance_id_to_id(context, glance_id): + """Convert a glance id to an internal (db) id.""" + if glance_id is None: + return + try: + return db.s3_image_get_by_uuid(context, glance_id)['id'] + except exception.NotFound: + return db.s3_image_create(context, glance_id)['id'] + + +def ec2_id_to_glance_id(context, ec2_id): + image_id = ec2_id_to_id(ec2_id) + return id_to_glance_id(context, image_id) + + +def glance_id_to_ec2_id(context, glance_id, image_type='ami'): + image_id = glance_id_to_id(context, glance_id) + return image_ec2_id(image_id, image_type=image_type) + + def ec2_id_to_id(ec2_id): """Convert an ec2 ID (i-[base 16 number]) to an instance id (int)""" try: diff --git a/nova/image/s3.py b/nova/image/s3.py index bd5ee0462..a0aafe849 100644 --- a/nova/image/s3.py +++ b/nova/image/s3.py @@ -30,7 +30,6 @@ import boto.s3.connection import eventlet from nova import rpc -import nova.db.api from nova import exception from nova import flags from nova import image @@ -65,35 +64,18 @@ class S3ImageService(object): self.service = service or image.get_default_image_service() self.service.__init__(*args, **kwargs) - def get_image_uuid(self, context, image_id): - return nova.db.api.s3_image_get(context, image_id)['uuid'] - - def get_image_id(self, context, image_uuid): - return nova.db.api.s3_image_get_by_uuid(context, image_uuid)['id'] - - def _create_image_id(self, context, image_uuid): - return nova.db.api.s3_image_create(context, image_uuid)['id'] - def _translate_uuids_to_ids(self, context, images): return [self._translate_uuid_to_id(context, img) for img in images] def _translate_uuid_to_id(self, context, image): - def _find_or_create(image_uuid): - if image_uuid is None: - return - try: - return self.get_image_id(context, image_uuid) - except exception.NotFound: - return self._create_image_id(context, image_uuid) - image_copy = image.copy() try: - image_id = image_copy['id'] + image_uuid = image_copy['id'] except KeyError: pass else: - image_copy['id'] = _find_or_create(image_id) + image_copy['id'] = ec2utils.glance_id_to_id(context, image_uuid) for prop in ['kernel_id', 'ramdisk_id']: try: @@ -101,7 +83,8 @@ class S3ImageService(object): except (KeyError, ValueError): pass else: - image_copy['properties'][prop] = _find_or_create(image_uuid) + image_id = ec2utils.glance_id_to_id(context, image_uuid) + image_copy['properties'][prop] = image_id return image_copy @@ -113,7 +96,7 @@ class S3ImageService(object): except KeyError: pass else: - image_copy['id'] = self.get_image_uuid(context, image_id) + image_copy['id'] = ec2utils.id_to_glance_id(context, image_id) for prop in ['kernel_id', 'ramdisk_id']: try: @@ -121,7 +104,7 @@ class S3ImageService(object): except (KeyError, ValueError): pass else: - image_uuid = self.get_image_uuid(context, image_id) + image_uuid = ec2utils.id_to_glance_id(context, image_id) image_copy['properties'][prop] = image_uuid return image_copy @@ -136,11 +119,11 @@ class S3ImageService(object): return image def delete(self, context, image_id): - image_uuid = self.get_image_uuid(context, image_id) + image_uuid = ec2utils.id_to_glance_id(context, image_id) self.service.delete(context, image_uuid) def update(self, context, image_id, metadata, data=None): - image_uuid = self.get_image_uuid(context, image_id) + image_uuid = ec2utils.id_to_glance_id(context, image_id) metadata = self._translate_id_to_uuid(context, metadata) image = self.service.update(context, image_uuid, metadata, data) return self._translate_uuid_to_id(context, image) @@ -158,7 +141,7 @@ class S3ImageService(object): return self._translate_uuids_to_ids(context, images) def show(self, context, image_id): - image_uuid = self.get_image_uuid(context, image_id) + image_uuid = ec2utils.id_to_glance_id(context, image_id) image = self.service.show(context, image_uuid) return self._translate_uuid_to_id(context, image) @@ -241,8 +224,7 @@ class S3ImageService(object): properties['architecture'] = arch def _translate_dependent_image_id(image_key, image_id): - image_id = ec2utils.ec2_id_to_id(image_id) - image_uuid = self.get_image_uuid(context, image_id) + image_uuid = ec2utils.ec2_id_to_glance_id(context, image_id) properties[image_key] = image_uuid if kernel_id: @@ -269,7 +251,7 @@ class S3ImageService(object): # extract the new uuid and generate an int id to present back to user image_uuid = image['id'] - image['id'] = self._create_image_id(context, image_uuid) + image['id'] = ec2utils.glance_id_to_id(context, image_uuid) # return image_uuid so the caller can still make use of image_service return manifest, image, image_uuid |