Creating uuid -> id mapping for S3 Image Service

This creates a mapping of Glance uuids to preserve the
EC2-specific image id format. This adds a lazily generated
mapping layer that is stored in the database.

This also fixes bug 882658

Change-Id: I64bf6c7297b97f206b967781a28791aa3874ca81
This commit is contained in:
Brian Waldon 2011-10-19 15:02:48 -04:00
parent 5b8133a839
commit c13e7f79e5
24 changed files with 470 additions and 191 deletions

View File

@ -1091,17 +1091,19 @@ class CloudController(object):
'status': volume['attach_status'],
'volumeId': ec2utils.id_to_ec2_vol_id(volume_id)}
def _format_kernel_id(self, instance_ref, result, key):
kernel_id = instance_ref['kernel_id']
if kernel_id is None:
def _format_kernel_id(self, context, instance_ref, result, key):
kernel_uuid = instance_ref['kernel_id']
if kernel_uuid is None or kernel_uuid == '':
return
result[key] = self.image_ec2_id(instance_ref['kernel_id'], 'aki')
kernel_id = self._get_image_id(context, kernel_uuid)
result[key] = self.image_ec2_id(kernel_id, 'aki')
def _format_ramdisk_id(self, instance_ref, result, key):
ramdisk_id = instance_ref['ramdisk_id']
if ramdisk_id is None:
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
result[key] = self.image_ec2_id(instance_ref['ramdisk_id'], 'ari')
ramdisk_id = self._get_image_id(context, ramdisk_uuid)
result[key] = self.image_ec2_id(ramdisk_id, 'ari')
@staticmethod
def _format_user_data(instance_ref):
@ -1140,10 +1142,10 @@ class CloudController(object):
self._format_instance_type(instance, result)
def _format_attr_kernel(instance, result):
self._format_kernel_id(instance, result, 'kernel')
self._format_kernel_id(context, instance, result, 'kernel')
def _format_attr_ramdisk(instance, result):
self._format_ramdisk_id(instance, result, 'ramdisk')
self._format_ramdisk_id(context, instance, result, 'ramdisk')
def _format_attr_root_device_name(instance, result):
self._format_instance_root_device_name(instance, result)
@ -1285,9 +1287,11 @@ class CloudController(object):
instance_id = instance['id']
ec2_id = ec2utils.id_to_ec2_id(instance_id)
i['instanceId'] = ec2_id
i['imageId'] = self.image_ec2_id(instance['image_ref'])
self._format_kernel_id(instance, i, 'kernelId')
self._format_ramdisk_id(instance, i, 'ramdiskId')
image_uuid = instance['image_ref']
image_id = self._get_image_id(context, image_uuid)
i['imageId'] = self.image_ec2_id(image_id)
self._format_kernel_id(context, instance, i, 'kernelId')
self._format_ramdisk_id(context, instance, i, 'ramdiskId')
i['instanceState'] = {
'code': instance['power_state'],
'name': state_description_from_vm_state(instance['vm_state'])}
@ -1399,14 +1403,16 @@ 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'] = kernel['id']
kwargs['kernel_id'] = self._get_image_uuid(context, kernel['id'])
if kwargs.get('ramdisk_id'):
ramdisk = self._get_image(context, kwargs['ramdisk_id'])
kwargs['ramdisk_id'] = ramdisk['id']
kwargs['ramdisk_id'] = self._get_image_uuid(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'])
if image:
image_state = self._get_image_state(image)
@ -1419,7 +1425,7 @@ class CloudController(object):
(instances, resv_id) = self.compute_api.create(context,
instance_type=instance_types.get_instance_type_by_name(
kwargs.get('instance_type', None)),
image_href=self._get_image(context, kwargs['image_id'])['id'],
image_href=image_uuid,
min_count=int(kwargs.get('min_count', max_count)),
max_count=max_count,
kernel_id=kwargs.get('kernel_id'),
@ -1516,7 +1522,7 @@ class CloudController(object):
"""Returns image ec2_id using id and three letter type."""
template = image_type + '-%08x'
try:
return ec2utils.id_to_ec2_id(int(image_id), template=template)
return ec2utils.id_to_ec2_id(image_id, template=template)
except ValueError:
#TODO(wwolf): once we have ec2_id -> glance_id mapping
# in place, this wont be necessary
@ -1536,6 +1542,15 @@ 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 = {}

View File

@ -31,7 +31,7 @@ def ec2_id_to_id(ec2_id):
def id_to_ec2_id(instance_id, template='i-%08x'):
"""Convert an instance ID (int) to an ec2 ID (i-[base 16 number])"""
return template % instance_id
return template % int(instance_id)
def id_to_ec2_snap_id(instance_id):

View File

@ -354,12 +354,12 @@ class ComputeManager(manager.SchedulerDependentManager):
allowed_size_bytes = allowed_size_gb * 1024 * 1024 * 1024
LOG.debug(_("image_id=%(image_id)d, image_size_bytes="
LOG.debug(_("image_id=%(image_id)s, image_size_bytes="
"%(size_bytes)d, allowed_size_bytes="
"%(allowed_size_bytes)d") % locals())
if size_bytes > allowed_size_bytes:
LOG.info(_("Image '%(image_id)d' size %(size_bytes)d exceeded"
LOG.info(_("Image '%(image_id)s' size %(size_bytes)d exceeded"
" instance_type allowed size "
"%(allowed_size_bytes)d")
% locals())
@ -798,7 +798,7 @@ class ComputeManager(manager.SchedulerDependentManager):
for i in xrange(excess):
image = images.pop()
image_id = image['id']
LOG.debug(_("Deleting image %d" % image_id))
LOG.debug(_("Deleting image %s" % image_id))
image_service.delete(context, image_id)
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())

View File

@ -1593,3 +1593,21 @@ def vsa_get_all(context):
def vsa_get_all_by_project(context, project_id):
"""Get all Virtual Storage Array records by project ID."""
return IMPL.vsa_get_all_by_project(context, project_id)
###################
def s3_image_get(context, image_id):
"""Find local s3 image represented by the provided id"""
return IMPL.s3_image_get(context, image_id)
def s3_image_get_by_uuid(context, image_uuid):
"""Find local s3 image represented by the provided uuid"""
return IMPL.s3_image_get_by_uuid(context, image_uuid)
def s3_image_create(context, image_uuid):
"""Create local s3 image represented by provided uuid"""
return IMPL.s3_image_create(context, image_uuid)

View File

@ -4017,4 +4017,42 @@ def vsa_get_all_by_project(context, project_id):
all()
####################
####################
def s3_image_get(context, image_id):
"""Find local s3 image represented by the provided id"""
session = get_session()
res = session.query(models.S3Image)\
.filter_by(id=image_id)\
.first()
if not res:
raise exception.ImageNotFound(image_id=image_id)
return res
def s3_image_get_by_uuid(context, image_uuid):
"""Find local s3 image represented by the provided uuid"""
session = get_session()
res = session.query(models.S3Image)\
.filter_by(uuid=image_uuid)\
.first()
if not res:
raise exception.ImageNotFound(image_id=image_uuid)
return res
def s3_image_create(context, image_uuid):
"""Create local s3 image represented by provided uuid"""
try:
s3_image_ref = models.S3Image()
s3_image_ref.update({'uuid': image_uuid})
s3_image_ref.save()
except Exception, e:
raise exception.DBError(e)
return s3_image_ref

View File

@ -0,0 +1,57 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 OpenStack LLC.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import sqlalchemy
from nova import log as logging
meta = sqlalchemy.MetaData()
s3_images = sqlalchemy.Table('s3_images', meta,
sqlalchemy.Column('created_at',
sqlalchemy.DateTime(timezone=False)),
sqlalchemy.Column('updated_at',
sqlalchemy.DateTime(timezone=False)),
sqlalchemy.Column('deleted_at',
sqlalchemy.DateTime(timezone=False)),
sqlalchemy.Column('deleted',
sqlalchemy.Boolean(create_constraint=True, name=None)),
sqlalchemy.Column('id', sqlalchemy.Integer(),
primary_key=True,
nullable=False,
autoincrement=True),
sqlalchemy.Column('uuid', sqlalchemy.String(36),
nullable=False))
def upgrade(migrate_engine):
meta.bind = migrate_engine
try:
s3_images.create()
except Exception:
logging.exception("Exception while creating table 's3_images'")
meta.drop_all(tables=[s3_images])
raise
def downgrade(migrate_engine):
meta.bind = migrate_engine
s3_images.drop()

View File

@ -873,6 +873,13 @@ class BandwidthUsage(BASE, NovaBase):
bw_out = Column(BigInteger)
class S3Image(BASE, NovaBase):
"""Compatibility layer for the S3 image service talking to Glance"""
__tablename__ = 's3_images'
id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
uuid = Column(String(36), nullable=False)
def register_models():
"""Register Models and create metadata.

View File

@ -362,7 +362,7 @@ DEFINE_string('null_kernel', 'nokernel',
'kernel image that indicates not to use a kernel,'
' but to use a raw disk image instead')
DEFINE_integer('vpn_image_id', 0, 'integer id for cloudpipe vpn server')
DEFINE_string('vpn_image_id', '0', 'image id for cloudpipe vpn server')
DEFINE_string('vpn_key_suffix',
'-vpn',
'Suffix to add to project name for vpn key and secgroups')

View File

@ -40,10 +40,12 @@ def get_image_service(context, image_href):
:returns: a tuple of the form (image_service, image_id)
"""
image_href = image_href or 0
if str(image_href).isdigit():
return (get_default_image_service(), int(image_href))
# check if this is not a uri
if '/' not in str(image_href):
return (get_default_image_service(), image_href)
(glance_client, image_id) = glance.get_glance_client(context, image_href)
image_service = nova.image.glance.GlanceImageService(glance_client)
return (image_service, image_id)
else:
(glance_client, image_id) = glance.get_glance_client(context,
image_href)
image_service = nova.image.glance.GlanceImageService(glance_client)
return (image_service, image_id)

View File

@ -24,6 +24,7 @@ import random
from nova import exception
from nova import flags
from nova import log as logging
from nova import utils
LOG = logging.getLogger('nova.image.fake')
@ -40,7 +41,9 @@ class _FakeImageService(object):
# NOTE(justinsb): The OpenStack API can't upload an image?
# So, make sure we've got one..
timestamp = datetime.datetime(2011, 01, 01, 01, 02, 03)
image1 = {'id': '123456',
# NOTE(bcwaldon): was image '123456'
image1 = {'id': '155d900f-4e14-4e4c-a73d-069cbf4541e6',
'name': 'fakeimage123456',
'created_at': timestamp,
'updated_at': timestamp,
@ -54,7 +57,8 @@ class _FakeImageService(object):
'ramdisk_id': FLAGS.null_kernel,
'architecture': 'x86_64'}}
image2 = {'id': 'fake',
# NOTE(bcwaldon): was image 'fake'
image2 = {'id': 'a2459075-d96c-40d5-893e-577ff92e721c',
'name': 'fakeimage123456',
'created_at': timestamp,
'updated_at': timestamp,
@ -67,7 +71,8 @@ class _FakeImageService(object):
'properties': {'kernel_id': FLAGS.null_kernel,
'ramdisk_id': FLAGS.null_kernel}}
image3 = {'id': '2',
# NOTE(bcwaldon): was image '2'
image3 = {'id': '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6',
'name': 'fakeimage123456',
'created_at': timestamp,
'updated_at': timestamp,
@ -80,7 +85,8 @@ class _FakeImageService(object):
'properties': {'kernel_id': FLAGS.null_kernel,
'ramdisk_id': FLAGS.null_kernel}}
image4 = {'id': '1',
# NOTE(bcwaldon): was image '1'
image4 = {'id': 'cedef40a-ed67-4d10-800e-17455edce175',
'name': 'fakeimage123456',
'created_at': timestamp,
'updated_at': timestamp,
@ -93,7 +99,8 @@ class _FakeImageService(object):
'properties': {'kernel_id': FLAGS.null_kernel,
'ramdisk_id': FLAGS.null_kernel}}
image5 = {'id': '3',
# NOTE(bcwaldon): was image '3'
image5 = {'id': 'c905cedb-7281-47e4-8a62-f26bc5fc4c77',
'name': 'fakeimage123456',
'created_at': timestamp,
'updated_at': timestamp,
@ -152,20 +159,10 @@ class _FakeImageService(object):
:raises: Duplicate if the image already exist.
"""
try:
image_id = metadata['id']
except KeyError:
while True:
image_id = random.randint(0, 2 ** 31 - 1)
if not self.images.get(str(image_id)):
break
image_id = str(image_id)
if self.images.get(image_id):
raise exception.Duplicate()
image_id = str(metadata.get('id', utils.gen_uuid()))
metadata['id'] = image_id
if image_id in self.images:
raise exception.Duplicate()
self.images[image_id] = copy.deepcopy(metadata)
return self.images[image_id]

View File

@ -54,7 +54,7 @@ def _parse_image_ref(image_href):
o = urlparse(image_href)
port = o.port or 80
host = o.netloc.split(':', 1)[0]
image_id = int(o.path.split('/')[-1])
image_id = o.path.split('/')[-1]
return (image_id, host, port)
@ -99,20 +99,25 @@ def get_glance_client(context, image_href):
:returns: a tuple of the form (glance_client, image_id)
"""
image_href = image_href or 0
glance_host, glance_port = pick_glance_api_server()
if str(image_href).isdigit():
glance_client = _create_glance_client(context, glance_host,
# check if this is an id
if '/' not in str(image_href):
glance_client = _create_glance_client(context,
glance_host,
glance_port)
return (glance_client, int(image_href))
return (glance_client, image_href)
try:
(image_id, host, port) = _parse_image_ref(image_href)
except ValueError:
raise exception.InvalidImageRef(image_href=image_href)
glance_client = _create_glance_client(context, glance_host, glance_port)
return (glance_client, image_id)
else:
try:
(image_id, host, port) = _parse_image_ref(image_href)
except ValueError:
raise exception.InvalidImageRef(image_href=image_href)
glance_client = _create_glance_client(context,
glance_host,
glance_port)
return (glance_client, image_id)
class GlanceImageService(object):

View File

@ -29,6 +29,7 @@ import boto.s3.connection
import eventlet
from nova import crypto
import nova.db.api
from nova import exception
from nova import flags
from nova import image
@ -54,6 +55,44 @@ 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):
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']
except KeyError:
pass
else:
image_copy['id'] = _find_or_create(image_copy['id'])
for prop in ['kernel_id', 'ramdisk_id']:
try:
image_uuid = image_copy['properties'][prop]
except (KeyError, ValueError):
pass
else:
image_copy['properties'][prop] = _find_or_create(image_uuid)
return image_copy
def create(self, context, metadata, data=None):
"""Create an image.
@ -64,23 +103,38 @@ class S3ImageService(object):
return image
def delete(self, context, image_id):
self.service.delete(context, image_id)
image_uuid = self.get_image_uuid(context, image_id)
self.service.delete(context, image_uuid)
def update(self, context, image_id, metadata, data=None):
image = self.service.update(context, image_id, metadata, data)
return image
image_uuid = self.get_image_uuid(context, image_id)
image = self.service.update(context, image_uuid, metadata, data)
return self._translate_uuid_to_id(context, image)
def index(self, context):
return self.service.index(context)
#NOTE(bcwaldon): sort asc to make sure we assign lower ids
# to older images
images = self.service.index(context, sort_dir='asc')
return self._translate_uuids_to_ids(context, images)
def detail(self, context):
return self.service.detail(context)
#NOTE(bcwaldon): sort asc to make sure we assign lower ids
# to older images
images = self.service.detail(context, sort_dir='asc')
return self._translate_uuids_to_ids(context, images)
def show(self, context, image_id):
return self.service.show(context, image_id)
image_uuid = self.get_image_uuid(context, image_id)
image = self.service.show(context, image_uuid)
return self._translate_uuid_to_id(context, image)
def show_by_name(self, context, name):
return self.service.show_by_name(context, name)
image = self.service.show_by_name(context, name)
return self._translate_uuid_to_id(context, image)
def get(self, context, image_id):
image_uuid = self.get_image_uuid(context, image_id)
return self.get(self, context, image_uuid)
@staticmethod
def _conn(context):
@ -158,10 +212,14 @@ class S3ImageService(object):
properties['architecture'] = arch
if kernel_id:
properties['kernel_id'] = ec2utils.ec2_id_to_id(kernel_id)
kernel_id = ec2_utils.ec2_id_to_id(kernel_id)
kernel_uuid = self._get_image_uuid(context, kernel_id)
properties['kernel_id'] = kernel_uuid
if ramdisk_id:
properties['ramdisk_id'] = ec2utils.ec2_id_to_id(ramdisk_id)
ramdisk_id = ec2utils.ec2_id_to_id(ramdisk_id)
ramdisk_uuid = self._get_image_uuid(context, ramdisk_id)
properties['ramdisk_id'] = ramdisk_uuid
if mappings:
properties['mappings'] = mappings
@ -172,8 +230,19 @@ class S3ImageService(object):
'is_public': False,
'properties': properties})
metadata['properties']['image_state'] = 'pending'
#TODO(bcwaldon): right now, this removes user-defined ids.
# We need to re-enable this.
image_id = metadata.pop('id', None)
image = self.service.create(context, metadata)
return manifest, image
# 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)
# return image_uuid so the caller can still make use of image_service
return manifest, image, image_uuid
def _s3_create(self, context, metadata):
"""Gets a manifext from s3 and makes an image."""
@ -187,15 +256,16 @@ class S3ImageService(object):
key = bucket.get_key(manifest_path)
manifest = key.get_contents_as_string()
manifest, image = self._s3_parse_manifest(context, metadata, manifest)
image_id = image['id']
manifest, image, image_uuid = self._s3_parse_manifest(context,
metadata,
manifest)
def delayed_create():
"""This handles the fetching and decrypting of the part files."""
log_vars = {'image_location': image_location,
'image_path': image_path}
metadata['properties']['image_state'] = 'downloading'
self.service.update(context, image_id, metadata)
self.service.update(context, image_uuid, metadata)
try:
parts = []
@ -217,11 +287,11 @@ class S3ImageService(object):
LOG.exception(_("Failed to download %(image_location)s "
"to %(image_path)s"), log_vars)
metadata['properties']['image_state'] = 'failed_download'
self.service.update(context, image_id, metadata)
self.service.update(context, image_uuid, metadata)
return
metadata['properties']['image_state'] = 'decrypting'
self.service.update(context, image_id, metadata)
self.service.update(context, image_uuid, metadata)
try:
hex_key = manifest.find('image/ec2_encrypted_key').text
@ -241,11 +311,11 @@ class S3ImageService(object):
LOG.exception(_("Failed to decrypt %(image_location)s "
"to %(image_path)s"), log_vars)
metadata['properties']['image_state'] = 'failed_decrypt'
self.service.update(context, image_id, metadata)
self.service.update(context, image_uuid, metadata)
return
metadata['properties']['image_state'] = 'untarring'
self.service.update(context, image_id, metadata)
self.service.update(context, image_uuid, metadata)
try:
unz_filename = self._untarzip_image(image_path, dec_filename)
@ -253,25 +323,25 @@ class S3ImageService(object):
LOG.exception(_("Failed to untar %(image_location)s "
"to %(image_path)s"), log_vars)
metadata['properties']['image_state'] = 'failed_untar'
self.service.update(context, image_id, metadata)
self.service.update(context, image_uuid, metadata)
return
metadata['properties']['image_state'] = 'uploading'
self.service.update(context, image_id, metadata)
self.service.update(context, image_uuid, metadata)
try:
with open(unz_filename) as image_file:
self.service.update(context, image_id,
self.service.update(context, image_uuid,
metadata, image_file)
except Exception:
LOG.exception(_("Failed to upload %(image_location)s "
"to %(image_path)s"), log_vars)
metadata['properties']['image_state'] = 'failed_upload'
self.service.update(context, image_id, metadata)
self.service.update(context, image_uuid, metadata)
return
metadata['properties']['image_state'] = 'available'
metadata['status'] = 'active'
self.service.update(context, image_id, metadata)
self.service.update(context, image_uuid, metadata)
shutil.rmtree(image_path)

View File

@ -17,6 +17,7 @@
# under the License.
import base64
import copy
import functools
import os
@ -110,9 +111,13 @@ class CloudTestCase(test.TestCase):
True)
def fake_show(meh, context, id):
return {'id': 1, 'container_format': 'ami',
'properties': {'kernel_id': 1, 'ramdisk_id': 1,
'type': 'machine', 'image_state': 'available'}}
return {'id': id,
'container_format': 'ami',
'properties': {
'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'ramdisk_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'type': 'machine',
'image_state': 'available'}}
self.stubs.Set(fake._FakeImageService, 'show', fake_show)
self.stubs.Set(fake._FakeImageService, 'show_by_name', fake_show)
@ -121,6 +126,12 @@ class CloudTestCase(test.TestCase):
# ensure that operations complete
self.stubs.Set(rpc, 'cast', rpc.call)
# make sure we can map ami-00000001/2 to a uuid in FakeImageService
db.api.s3_image_create(self.context,
'cedef40a-ed67-4d10-800e-17455edce175')
db.api.s3_image_create(self.context,
'76fa36fc-c930-4bf3-8c8a-ea2a2420deb6')
def _stub_instance_get_with_fixed_ips(self, func_name):
orig_func = getattr(self.cloud.compute_api, func_name)
@ -540,13 +551,14 @@ class CloudTestCase(test.TestCase):
self._stub_instance_get_with_fixed_ips('get_all')
self._stub_instance_get_with_fixed_ips('get')
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
inst1 = db.instance_create(self.context, {'reservation_id': 'a',
'image_ref': 1,
'image_ref': image_uuid,
'instance_type_id': 1,
'host': 'host1',
'vm_state': 'active'})
inst2 = db.instance_create(self.context, {'reservation_id': 'a',
'image_ref': 1,
'image_ref': image_uuid,
'instance_type_id': 1,
'host': 'host2',
'vm_state': 'active'})
@ -589,8 +601,9 @@ class CloudTestCase(test.TestCase):
self._stub_instance_get_with_fixed_ips('get_all')
self._stub_instance_get_with_fixed_ips('get')
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
inst1 = db.instance_create(self.context, {'reservation_id': 'a',
'image_ref': 1,
'image_ref': image_uuid,
'instance_type_id': 1,
'vm_state': 'active'})
comp1 = db.service_create(self.context, {'host': 'host1',
@ -611,14 +624,15 @@ class CloudTestCase(test.TestCase):
db.service_destroy(self.context, comp1['id'])
def test_describe_instances_deleted(self):
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
args1 = {'reservation_id': 'a',
'image_ref': 1,
'image_ref': image_uuid,
'instance_type_id': 1,
'host': 'host1',
'vm_state': 'active'}
inst1 = db.instance_create(self.context, args1)
args2 = {'reservation_id': 'b',
'image_ref': 1,
'image_ref': image_uuid,
'instance_type_id': 1,
'host': 'host1',
'vm_state': 'active'}
@ -649,12 +663,13 @@ class CloudTestCase(test.TestCase):
return volumes
def _setUpBlockDeviceMapping(self):
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
inst1 = db.instance_create(self.context,
{'image_ref': 1,
{'image_ref': image_uuid,
'instance_type_id': 1,
'root_device_name': '/dev/sdb1'})
inst2 = db.instance_create(self.context,
{'image_ref': 2,
{'image_ref': image_uuid,
'instance_type_id': 1,
'root_device_name': '/dev/sdc1'})
@ -814,9 +829,12 @@ class CloudTestCase(test.TestCase):
def test_describe_images(self):
describe_images = self.cloud.describe_images
def fake_detail(meh, context):
return [{'id': 1, 'container_format': 'ami',
'properties': {'kernel_id': 1, 'ramdisk_id': 1,
def fake_detail(meh, context, **kwargs):
return [{'id': 'cedef40a-ed67-4d10-800e-17455edce175',
'container_format': 'ami',
'properties': {
'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'ramdisk_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'type': 'machine'}}]
def fake_show_none(meh, context, id):
@ -876,9 +894,9 @@ class CloudTestCase(test.TestCase):
{'device_name': '/dev/sdc3', 'virtual_name': 'ephemeral6'},
{'device_name': '/dev/sdc4', 'no_device': True}]
image1 = {
'id': 1,
'id': 'cedef40a-ed67-4d10-800e-17455edce175',
'properties': {
'kernel_id': 1,
'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'type': 'machine',
'image_state': 'available',
'mappings': mappings1,
@ -890,22 +908,23 @@ class CloudTestCase(test.TestCase):
block_device_mapping2 = [{'device_name': '/dev/sdb1',
'snapshot_id': 01234567}]
image2 = {
'id': 2,
'id': '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6',
'properties': {
'kernel_id': 2,
'kernel_id': '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6',
'type': 'machine',
'root_device_name': '/dev/sdb1',
'mappings': mappings2,
'block_device_mapping': block_device_mapping2}}
def fake_show(meh, context, image_id):
for i in [image1, image2]:
if i['id'] == image_id:
_images = [copy.deepcopy(image1), copy.deepcopy(image2)]
for i in _images:
if str(i['id']) == str(image_id):
return i
raise exception.ImageNotFound(image_id=image_id)
def fake_detail(meh, context):
return [image1, image2]
return [copy.deepcopy(image1), copy.deepcopy(image2)]
self.stubs.Set(fake._FakeImageService, 'show', fake_show)
self.stubs.Set(fake._FakeImageService, 'detail', fake_detail)
@ -1000,8 +1019,12 @@ class CloudTestCase(test.TestCase):
describe_image_attribute = self.cloud.describe_image_attribute
def fake_show(meh, context, id):
return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1,
'type': 'machine'}, 'container_format': 'ami',
return {'id': 'cedef40a-ed67-4d10-800e-17455edce175',
'properties': {
'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'ramdisk_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'type': 'machine'},
'container_format': 'ami',
'is_public': True}
self.stubs.Set(fake._FakeImageService, 'show', fake_show)
@ -1039,9 +1062,14 @@ class CloudTestCase(test.TestCase):
def test_modify_image_attribute(self):
modify_image_attribute = self.cloud.modify_image_attribute
fake_metadata = {'id': 1, 'container_format': 'ami',
'properties': {'kernel_id': 1, 'ramdisk_id': 1,
'type': 'machine'}, 'is_public': False}
fake_metadata = {
'id': 1,
'container_format': 'ami',
'properties': {
'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'ramdisk_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'type': 'machine'},
'is_public': False}
def fake_show(meh, context, id):
return fake_metadata
@ -1173,10 +1201,22 @@ class CloudTestCase(test.TestCase):
self.cloud.delete_key_pair(self.context, 'test')
def test_run_instances(self):
kwargs = {'image_id': FLAGS.default_image,
kwargs = {'image_id': 'ami-00000001',
'instance_type': FLAGS.default_instance_type,
'max_count': 1}
run_instances = self.cloud.run_instances
def fake_show(self, context, id):
return {'id': 'cedef40a-ed67-4d10-800e-17455edce175',
'properties': {
'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'type': 'machine'},
'container_format': 'ami',
'status': 'active'}
self.stubs.UnsetAll()
self.stubs.Set(fake._FakeImageService, 'show', fake_show)
result = run_instances(self.context, **kwargs)
instance = result['instancesSet'][0]
self.assertEqual(instance['imageId'], 'ami-00000001')
@ -1186,13 +1226,16 @@ class CloudTestCase(test.TestCase):
self.assertEqual(instance['instanceType'], 'm1.small')
def test_run_instances_image_state_none(self):
kwargs = {'image_id': FLAGS.default_image,
kwargs = {'image_id': 'ami-00000001',
'instance_type': FLAGS.default_instance_type,
'max_count': 1}
run_instances = self.cloud.run_instances
def fake_show_no_state(self, context, id):
return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1,
return {'id': 'cedef40a-ed67-4d10-800e-17455edce175',
'properties': {
'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'ramdisk_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'type': 'machine'}, 'container_format': 'ami'}
self.stubs.UnsetAll()
@ -1201,14 +1244,17 @@ class CloudTestCase(test.TestCase):
self.context, **kwargs)
def test_run_instances_image_state_invalid(self):
kwargs = {'image_id': FLAGS.default_image,
kwargs = {'image_id': 'ami-00000001',
'instance_type': FLAGS.default_instance_type,
'max_count': 1}
run_instances = self.cloud.run_instances
def fake_show_decrypt(self, context, id):
return {'id': 1, 'container_format': 'ami',
'properties': {'kernel_id': 1, 'ramdisk_id': 1,
return {'id': 'cedef40a-ed67-4d10-800e-17455edce175',
'container_format': 'ami',
'properties': {
'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'ramdisk_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'type': 'machine', 'image_state': 'decrypting'}}
self.stubs.UnsetAll()
@ -1223,9 +1269,13 @@ class CloudTestCase(test.TestCase):
run_instances = self.cloud.run_instances
def fake_show_stat_active(self, context, id):
return {'id': 1, 'container_format': 'ami',
'properties': {'kernel_id': 1, 'ramdisk_id': 1,
'type': 'machine'}, 'status': 'active'}
return {'id': 'cedef40a-ed67-4d10-800e-17455edce175',
'container_format': 'ami',
'properties': {
'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'ramdisk_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'type': 'machine'},
'status': 'active'}
self.stubs.Set(fake._FakeImageService, 'show', fake_show_stat_active)
@ -1648,8 +1698,8 @@ class CloudTestCase(test.TestCase):
'security_groups': [{'name': 'fake0'}, {'name': 'fake1'}],
'vm_state': vm_states.STOPPED,
'instance_type': {'name': 'fake_type'},
'kernel_id': 1,
'ramdisk_id': 2,
'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
'ramdisk_id': '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6',
'user_data': 'fake-user data',
}
self.stubs.Set(self.cloud.compute_api, 'get', fake_get)

View File

@ -138,10 +138,11 @@ class CreateserverextTest(test.TestCase):
compute_api = MockComputeAPI()
self.stubs.Set(nova.compute, 'API',
self._make_stub_method(compute_api))
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
self.stubs.Set(
nova.api.openstack.servers.Controller,
'_get_kernel_ramdisk_from_image',
self._make_stub_method((1, 1)))
self._make_stub_method((image_uuid, image_uuid)))
return compute_api
def _setup_mock_network_api(self):
@ -150,7 +151,7 @@ class CreateserverextTest(test.TestCase):
def _create_security_group_request_dict(self, security_groups):
server = {}
server['name'] = 'new-server-test'
server['imageRef'] = 1
server['imageRef'] = 'cedef40a-ed67-4d10-800e-17455edce175'
server['flavorRef'] = 1
if security_groups is not None:
sg_list = []
@ -162,7 +163,7 @@ class CreateserverextTest(test.TestCase):
def _create_networks_request_dict(self, networks):
server = {}
server['name'] = 'new-server-test'
server['imageRef'] = 1
server['imageRef'] = 'cedef40a-ed67-4d10-800e-17455edce175'
server['flavorRef'] = 1
if networks is not None:
network_list = []
@ -174,7 +175,7 @@ class CreateserverextTest(test.TestCase):
def _create_user_data_request_dict(self, user_data):
server = {}
server['name'] = 'new-server-test'
server['imageRef'] = 1
server['imageRef'] = 'cedef40a-ed67-4d10-800e-17455edce175'
server['flavorRef'] = 1
server['user_data'] = user_data
return {'server': server}

View File

@ -28,6 +28,7 @@ FLAGS = flags.FLAGS
FAKE_UUID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
IMAGE_UUID = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
def fake_compute_api_create(cls, context, instance_type, image_href, **kwargs):
@ -42,7 +43,7 @@ def fake_compute_api_create(cls, context, instance_type, image_href, **kwargs):
'instance_type': dict(inst_type),
'access_ip_v4': '1.2.3.4',
'access_ip_v6': 'fead::1234',
'image_ref': 3,
'image_ref': IMAGE_UUID,
'user_id': 'fake',
'project_id': 'fake',
'created_at': datetime.datetime(2010, 10, 10, 12, 0, 0),
@ -61,7 +62,7 @@ class BootFromVolumeTest(test.TestCase):
def test_create_root_volume(self):
body = dict(server=dict(
name='test_server', imageRef=3,
name='test_server', imageRef=IMAGE_UUID,
flavorRef=2, min_count=1, max_count=1,
block_device_mapping=[dict(
volume_id=1,
@ -82,7 +83,7 @@ class BootFromVolumeTest(test.TestCase):
self.assertEqual(FAKE_UUID, server['id'])
self.assertEqual(2, int(server['flavor']['id']))
self.assertEqual(u'test_server', server['name'])
self.assertEqual(3, int(server['image']['id']))
self.assertEqual(IMAGE_UUID, server['image']['id'])
self.assertEqual(FLAGS.password_length, len(server['adminPass']))
self.assertEqual(len(_block_device_mapping_seen), 1)
self.assertEqual(_block_device_mapping_seen[0]['volume_id'], 1)

View File

@ -1349,7 +1349,8 @@ class ServersControllerCreateTest(test.TestCase):
def instance_create(context, inst):
inst_type = instance_types.get_instance_type_by_flavor_id(3)
image_ref = 'http://localhost/images/2'
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
def_image_ref = 'http://localhost/images/%s' % image_uuid
self.instance_cache_num += 1
instance = {
'id': self.instance_cache_num,
@ -1358,7 +1359,7 @@ class ServersControllerCreateTest(test.TestCase):
'instance_type': dict(inst_type),
'access_ip_v4': '1.2.3.4',
'access_ip_v6': 'fead::1234',
'image_ref': image_ref,
'image_ref': inst.get('image_ref', def_image_ref),
'user_id': 'fake',
'project_id': 'fake',
'reservation_id': inst['reservation_id'],
@ -1402,10 +1403,8 @@ class ServersControllerCreateTest(test.TestCase):
return 'network_topic'
def kernel_ramdisk_mapping(*args, **kwargs):
return (1, 1)
def image_id_from_hash(*args, **kwargs):
return 2
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
return (image_uuid, image_uuid)
fakes.stub_out_networking(self.stubs)
fakes.stub_out_rate_limiting(self.stubs)
@ -1430,8 +1429,9 @@ class ServersControllerCreateTest(test.TestCase):
self.stubs.Set(nova.compute.api.API, "_find_host", find_host)
def _test_create_instance(self):
image_uuid = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
body = dict(server=dict(
name='server_test', imageRef=3, flavorRef=2,
name='server_test', imageRef=image_uuid, flavorRef=2,
metadata={'hello': 'world', 'open': 'stack'},
personality={}))
req = fakes.HTTPRequest.blank('/v1.1/fake/servers')
@ -1444,13 +1444,13 @@ class ServersControllerCreateTest(test.TestCase):
self.assertEqual('server_test', server['name'])
self.assertEqual(FAKE_UUID, server['id'])
self.assertEqual('2', server['flavor']['id'])
self.assertEqual('3', server['image']['id'])
self.assertEqual(image_uuid, server['image']['id'])
def test_create_multiple_instances(self):
"""Test creating multiple instances but not asking for
reservation_id
"""
image_href = 'http://localhost/v1.1/123/images/2'
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
flavor_ref = 'http://localhost/123/flavors/3'
body = {
'server': {
@ -1476,7 +1476,7 @@ class ServersControllerCreateTest(test.TestCase):
"""Test creating multiple instances with asking for
reservation_id
"""
image_href = 'http://localhost/v1.1/123/images/2'
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
flavor_ref = 'http://localhost/123/flavors/3'
body = {
'server': {
@ -1504,7 +1504,7 @@ class ServersControllerCreateTest(test.TestCase):
def test_create_instance_with_user_supplied_reservation_id(self):
"""Non-admin supplied reservation_id should be ignored."""
image_href = 'http://localhost/v1.1/123/images/2'
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
flavor_ref = 'http://localhost/123/flavors/3'
body = {
'server': {
@ -1530,7 +1530,7 @@ class ServersControllerCreateTest(test.TestCase):
def test_create_instance_with_admin_supplied_reservation_id(self):
"""Admin supplied reservation_id should be honored."""
image_href = 'http://localhost/v1.1/123/images/2'
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
flavor_ref = 'http://localhost/123/flavors/3'
body = {
'server': {
@ -1561,7 +1561,8 @@ class ServersControllerCreateTest(test.TestCase):
def test_create_instance_with_access_ip(self):
# proper local hrefs must start with 'http://localhost/v1.1/'
image_href = 'http://localhost/v1.1/fake/images/2'
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
image_href = 'http://localhost/v1.1/fake/images/%s' % image_uuid
flavor_ref = 'http://localhost/fake/flavors/3'
access_ipv4 = '1.2.3.4'
access_ipv6 = 'fead::1234'
@ -1575,11 +1576,11 @@ class ServersControllerCreateTest(test.TestCase):
],
}
expected_image = {
"id": "2",
"id": image_uuid,
"links": [
{
"rel": "bookmark",
"href": 'http://localhost/fake/images/2',
"href": 'http://localhost/fake/images/%s' % image_uuid,
},
],
}
@ -1621,7 +1622,8 @@ class ServersControllerCreateTest(test.TestCase):
def test_create_instance(self):
# proper local hrefs must start with 'http://localhost/v1.1/'
image_href = 'http://localhost/v1.1/images/2'
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
image_href = 'http://localhost/v1.1/images/%s' % image_uuid
flavor_ref = 'http://localhost/123/flavors/3'
expected_flavor = {
"id": "3",
@ -1633,11 +1635,11 @@ class ServersControllerCreateTest(test.TestCase):
],
}
expected_image = {
"id": "2",
"id": image_uuid,
"links": [
{
"rel": "bookmark",
"href": 'http://localhost/fake/images/2',
"href": 'http://localhost/fake/images/%s' % image_uuid,
},
],
}
@ -1691,7 +1693,7 @@ class ServersControllerCreateTest(test.TestCase):
self.controller.create, req, body)
def test_create_instance_valid_key_name(self):
image_href = 'http://localhost/v1.1/images/2'
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
flavor_ref = 'http://localhost/flavors/3'
body = dict(server=dict(
name='server_test', imageRef=image_href, flavorRef=flavor_ref,
@ -1751,7 +1753,7 @@ class ServersControllerCreateTest(test.TestCase):
def test_create_instance_with_config_drive(self):
self.config_drive = True
image_href = 'http://localhost/v1.1/123/images/2'
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
flavor_ref = 'http://localhost/v1.1/123/flavors/3'
body = {
'server': {
@ -1779,7 +1781,7 @@ class ServersControllerCreateTest(test.TestCase):
def test_create_instance_with_config_drive_as_id(self):
self.config_drive = 2
image_href = 'http://localhost/v1.1/123/images/2'
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
flavor_ref = 'http://localhost/v1.1/123/flavors/3'
body = {
'server': {
@ -1791,7 +1793,7 @@ class ServersControllerCreateTest(test.TestCase):
'open': 'stack',
},
'personality': {},
'config_drive': 2,
'config_drive': image_href,
},
}
@ -1808,7 +1810,7 @@ class ServersControllerCreateTest(test.TestCase):
def test_create_instance_with_bad_config_drive(self):
self.config_drive = "asdf"
image_href = 'http://localhost/v1.1/123/images/2'
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
flavor_ref = 'http://localhost/v1.1/123/flavors/3'
body = {
'server': {
@ -1833,7 +1835,7 @@ class ServersControllerCreateTest(test.TestCase):
self.controller.create, req, body)
def test_create_instance_without_config_drive(self):
image_href = 'http://localhost/v1.1/123/images/2'
image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
flavor_ref = 'http://localhost/v1.1/123/flavors/3'
body = {
'server': {
@ -1860,7 +1862,7 @@ class ServersControllerCreateTest(test.TestCase):
self.assertFalse(server['config_drive'])
def test_create_instance_bad_href(self):
image_href = 'http://localhost/v1.1/images/asdf'
image_href = 'asdf'
flavor_ref = 'http://localhost/v1.1/flavors/3'
body = dict(server=dict(
name='server_test', imageRef=image_href, flavorRef=flavor_ref,
@ -1875,7 +1877,7 @@ class ServersControllerCreateTest(test.TestCase):
self.controller.create, req, body)
def test_create_instance_local_href(self):
image_id = "2"
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
flavor_ref = 'http://localhost/v1.1/flavors/3'
expected_flavor = {
"id": "3",
@ -1887,18 +1889,18 @@ class ServersControllerCreateTest(test.TestCase):
],
}
expected_image = {
"id": "2",
"id": image_uuid,
"links": [
{
"rel": "bookmark",
"href": 'http://localhost/fake/images/2',
"href": 'http://localhost/fake/images/%s' % image_uuid,
},
],
}
body = {
'server': {
'name': 'server_test',
'imageRef': image_id,
'imageRef': image_uuid,
'flavorRef': flavor_ref,
},
}
@ -1914,12 +1916,11 @@ class ServersControllerCreateTest(test.TestCase):
self.assertEqual(expected_image, server['image'])
def test_create_instance_admin_pass(self):
image_href = 'http://localhost/v1.1/images/2'
flavor_ref = 'http://localhost/v1.1/flavors/3'
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
body = {
'server': {
'name': 'server_test',
'imageRef': 3,
'imageRef': image_uuid,
'flavorRef': 3,
'adminPass': 'testpass',
},

View File

@ -61,20 +61,24 @@ class UrlmapTest(test.TestCase):
def test_path_content_type(self):
"""Test URL path specifying JSON returns JSON content."""
req = webob.Request.blank('/v1.1/foobar/images/1.json')
url = '/v1.1/foobar/images/cedef40a-ed67-4d10-800e-17455edce175.json'
req = webob.Request.blank(url)
req.accept = "application/xml"
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 200)
self.assertEqual(res.content_type, "application/json")
body = json.loads(res.body)
self.assertEqual(body['image']['id'], '1')
self.assertEqual(body['image']['id'],
'cedef40a-ed67-4d10-800e-17455edce175')
def test_accept_content_type(self):
"""Test Accept header specifying JSON returns JSON content."""
req = webob.Request.blank('/v1.1/foobar/images/1')
url = '/v1.1/foobar/images/cedef40a-ed67-4d10-800e-17455edce175'
req = webob.Request.blank(url)
req.accept = "application/xml;q=0.8, application/json"
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 200)
self.assertEqual(res.content_type, "application/json")
body = json.loads(res.body)
self.assertEqual(body['image']['id'], '1')
self.assertEqual(body['image']['id'],
'cedef40a-ed67-4d10-800e-17455edce175')

View File

@ -541,18 +541,11 @@ class TestGlanceImageService(test.TestCase):
fixture = self._make_fixture(name='test image')
image_id = self.service.create(self.context, fixture)['id']
client, same_id = glance.get_glance_client(self.context, image_id)
self.assertEquals(same_id, int(image_id))
self.assertEquals(same_id, image_id)
def test_glance_client_image_ref(self):
fixture = self._make_fixture(name='test image')
image_id = self.service.create(self.context, fixture)['id']
image_url = 'http://foo/%s' % image_id
client, same_id = glance.get_glance_client(self.context, image_url)
self.assertEquals(same_id, int(image_id))
def test_glance_client_invalid_image_ref(self):
fixture = self._make_fixture(name='test image')
image_id = self.service.create(self.context, fixture)['id']
image_url = 'khan'
self.assertRaises(exception.InvalidImageRef, glance.get_glance_client,
self.context, 'khan')
self.assertEquals(same_id, image_id)

View File

@ -16,6 +16,8 @@
# under the License.
from nova import context
import nova.db.api
from nova import exception
from nova import test
from nova.image import s3
@ -60,6 +62,10 @@ class TestS3ImageService(test.TestCase):
self.image_service = s3.S3ImageService()
self.context = context.RequestContext(None, None)
# set up one fixture to test shows, should have id '1'
nova.db.api.s3_image_create(self.context,
'155d900f-4e14-4e4c-a73d-069cbf4541e6')
def _assertEqualList(self, list0, list1, keys):
self.assertEqual(len(list0), len(list1))
key = keys[0]
@ -72,6 +78,14 @@ class TestS3ImageService(test.TestCase):
for k in keys:
self.assertEqual(x[k], y[k])
def test_show_cannot_use_uuid(self):
self.assertRaises(exception.ImageNotFound,
self.image_service.show, self.context,
'155d900f-4e14-4e4c-a73d-069cbf4541e6')
def test_show_translates_correctly(self):
image = self.image_service.show(self.context, '1')
def test_s3_create(self):
metadata = {'properties': {
'root_device_name': '/dev/sda1',
@ -83,11 +97,10 @@ class TestS3ImageService(test.TestCase):
'virutal_name': 'ephemeral0'},
{'device_name': '/dev/sdb0',
'no_device': True}]}}
_manifest, image = self.image_service._s3_parse_manifest(
_manifest, image, image_uuid = self.image_service._s3_parse_manifest(
self.context, metadata, ami_manifest_xml)
image_id = image['id']
ret_image = self.image_service.show(self.context, image_id)
ret_image = self.image_service.show(self.context, image['id'])
self.assertTrue('properties' in ret_image)
properties = ret_image['properties']

View File

@ -22,11 +22,12 @@ Provides common functionality for integrated unit tests
import random
import string
from nova import service
from nova import test # For the flags
import nova.image.glance
from nova.log import logging
from nova import service
from nova import test # For the flags
from nova.tests.integrated.api import client
from nova import utils
LOG = logging.getLogger('nova.tests.integrated')
@ -65,7 +66,7 @@ class _IntegratedTestBase(test.TestCase):
self.flags(verbose=True)
def fake_get_image_service(context, image_href):
image_id = int(str(image_href).split('/')[-1])
image_id = str(image_href).split('/')[-1]
return (nova.image.fake.FakeImageService(), image_id)
self.stubs.Set(nova.image, 'get_image_service', fake_get_image_service)
@ -103,9 +104,7 @@ class _IntegratedTestBase(test.TestCase):
return generate_new_element(server_names, 'server')
def get_invalid_image(self):
images = self.api.get_images()
image_ids = [image['id'] for image in images]
return generate_new_element(image_ids, '', numeric=True)
return str(utils.gen_uuid())
def _build_minimal_create_server_request(self):
server = {}

View File

@ -336,7 +336,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase):
# rebuild the server with metadata
post = {}
post['rebuild'] = {
"imageRef": "https://localhost/v1.1/32278/images/3",
"imageRef": "c905cedb-7281-47e4-8a62-f26bc5fc4c77",
"name": "blah",
}
@ -348,7 +348,8 @@ class ServersTest(integrated_helpers._IntegratedTestBase):
self.assertEqual(created_server_id, found_server['id'])
self.assertEqual({}, found_server.get('metadata'))
self.assertEqual('blah', found_server.get('name'))
self.assertEqual('3', found_server.get('image')['id'])
self.assertEqual(post['rebuild']['imageRef'],
found_server.get('image')['id'])
# Cleanup
self._delete_server(created_server_id)
@ -370,7 +371,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase):
# rebuild the server with metadata
post = {}
post['rebuild'] = {
"imageRef": "https://localhost/v1.1/32278/images/2",
"imageRef": "76fa36fc-c930-4bf3-8c8a-ea2a2420deb6",
"name": "blah",
}
@ -416,7 +417,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase):
# rebuild the server with metadata
post = {}
post['rebuild'] = {
"imageRef": "https://localhost/v1.1/32278/images/2",
"imageRef": "76fa36fc-c930-4bf3-8c8a-ea2a2420deb6",
"name": "blah",
}

View File

@ -61,7 +61,7 @@ def _create_instance_dict(**kwargs):
inst = {}
# NOTE(jk0): If an integer is passed as the image_ref, the image
# service will use the default image service (in this case, the fake).
inst['image_ref'] = '1'
inst['image_ref'] = 'cedef40a-ed67-4d10-800e-17455edce175'
inst['reservation_id'] = 'r-fakeres'
inst['user_id'] = kwargs.get('user_id', 'admin')
inst['project_id'] = kwargs.get('project_id', 'fake')

View File

@ -72,7 +72,7 @@ class QuotaTestCase(test.TestCase):
def _create_instance(self, cores=2):
"""Create a test instance"""
inst = {}
inst['image_id'] = 1
inst['image_id'] = 'cedef40a-ed67-4d10-800e-17455edce175'
inst['reservation_id'] = 'r-fakeres'
inst['user_id'] = self.user_id
inst['project_id'] = self.project_id
@ -218,12 +218,13 @@ class QuotaTestCase(test.TestCase):
instance_id = self._create_instance()
instance_ids.append(instance_id)
inst_type = instance_types.get_instance_type_by_name('m1.small')
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
self.assertRaises(quota.QuotaError, compute.API().create,
self.context,
min_count=1,
max_count=1,
instance_type=inst_type,
image_href=1)
image_href=image_uuid)
for instance_id in instance_ids:
db.instance_destroy(self.context, instance_id)
@ -232,12 +233,13 @@ class QuotaTestCase(test.TestCase):
instance_id = self._create_instance(cores=4)
instance_ids.append(instance_id)
inst_type = instance_types.get_instance_type_by_name('m1.small')
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
self.assertRaises(quota.QuotaError, compute.API().create,
self.context,
min_count=1,
max_count=1,
instance_type=inst_type,
image_href=1)
image_href=image_uuid)
for instance_id in instance_ids:
db.instance_destroy(self.context, instance_id)
@ -286,12 +288,13 @@ class QuotaTestCase(test.TestCase):
for i in range(FLAGS.quota_metadata_items + 1):
metadata['key%s' % i] = 'value%s' % i
inst_type = instance_types.get_instance_type_by_name('m1.small')
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
self.assertRaises(quota.QuotaError, compute.API().create,
self.context,
min_count=1,
max_count=1,
instance_type=inst_type,
image_href='fake',
image_href=image_uuid,
metadata=metadata)
def test_default_allowed_injected_files(self):
@ -340,15 +343,19 @@ class QuotaTestCase(test.TestCase):
self.flags(image_service='nova.image.fake.FakeImageService')
api = compute.API(image_service=self.StubImageService())
inst_type = instance_types.get_instance_type_by_name('m1.small')
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
api.create(self.context, min_count=1, max_count=1,
instance_type=inst_type, image_href='3',
instance_type=inst_type, image_href=image_uuid,
injected_files=files)
def test_no_injected_files(self):
self.flags(image_service='nova.image.fake.FakeImageService')
api = compute.API(image_service=self.StubImageService())
inst_type = instance_types.get_instance_type_by_name('m1.small')
api.create(self.context, instance_type=inst_type, image_href='3')
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
api.create(self.context,
instance_type=inst_type,
image_href=image_uuid)
def test_max_injected_files(self):
files = []

View File

@ -872,7 +872,7 @@ class LibvirtConnection(driver.ComputeDriver):
'ramdisk_id': inst['ramdisk_id']}
if disk_images['kernel_id']:
fname = '%08x' % int(disk_images['kernel_id'])
fname = disk_images['kernel_id']
self._cache_image(fn=self._fetch_image,
context=context,
target=basepath('kernel'),
@ -881,7 +881,7 @@ class LibvirtConnection(driver.ComputeDriver):
user_id=inst['user_id'],
project_id=inst['project_id'])
if disk_images['ramdisk_id']:
fname = '%08x' % int(disk_images['ramdisk_id'])
fname = disk_images['ramdisk_id']
self._cache_image(fn=self._fetch_image,
context=context,
target=basepath('ramdisk'),
@ -966,7 +966,7 @@ class LibvirtConnection(driver.ComputeDriver):
target_partition = None
if config_drive_id:
fname = '%08x' % int(config_drive_id)
fname = config_drive_id
self._cache_image(fn=self._fetch_image,
target=basepath('disk.config'),
fname=fname,