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
This commit is contained in:
parent
094985ea65
commit
0929e3a289
@ -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 = {}
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user