summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorMaru Newby <mnewby@internap.com>2012-03-12 23:19:16 -0700
committerBrian Waldon <bcwaldon@gmail.com>2012-03-13 10:09:12 -0700
commit0929e3a289af39fc38b46c4a55db06b8888e671e (patch)
treee7c90b6bfd014b06a4cc612b1c91e18a247e6111 /nova
parent094985ea657f590936906829486829846a558f05 (diff)
downloadnova-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.py28
-rw-r--r--nova/api/ec2/ec2utils.py26
-rw-r--r--nova/image/s3.py40
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