From a6bd6f8581b9c03da9aceed7d87f4664410d0998 Mon Sep 17 00:00:00 2001 From: Michael Gundlach Date: Thu, 26 Aug 2010 14:09:14 -0400 Subject: work endpoint/images.py into an S3ImageService. The translation isn't perfect, but it's a start. --- nova/endpoint/images.py | 30 +++++------------------------- nova/image/service.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 25 deletions(-) diff --git a/nova/endpoint/images.py b/nova/endpoint/images.py index 2a88d66af..cfea4c20b 100644 --- a/nova/endpoint/images.py +++ b/nova/endpoint/images.py @@ -26,6 +26,7 @@ import urllib import boto.s3.connection +from nova import image from nova import flags from nova import utils from nova.auth import manager @@ -35,7 +36,7 @@ FLAGS = flags.FLAGS def modify(context, image_id, operation): - conn(context).make_request( + image.S3ImageService(context)._conn().make_request( method='POST', bucket='_images', query_args=qs({'image_id': image_id, 'operation': operation})) @@ -47,7 +48,7 @@ def register(context, image_location): """ rpc call to register a new image based from a manifest """ image_id = utils.generate_uid('ami') - conn(context).make_request( + image.S3ImageService(context)._conn().make_request( method='PUT', bucket='_images', query_args=qs({'image_location': image_location, @@ -61,12 +62,7 @@ def list(context, filter_list=[]): optionally filtered by a list of image_id """ - # FIXME: send along the list of only_images to check for - response = conn(context).make_request( - method='GET', - bucket='_images') - - result = json.loads(response.read()) + result = image.S3ImageService(context).index().values() if not filter_list is None: return [i for i in result if i['imageId'] in filter_list] return result @@ -74,23 +70,7 @@ def list(context, filter_list=[]): def deregister(context, image_id): """ unregister an image """ - conn(context).make_request( - method='DELETE', - bucket='_images', - query_args=qs({'image_id': image_id})) - - -def conn(context): - access = manager.AuthManager().get_access_key(context.user, - context.project) - secret = str(context.user.secret) - calling = boto.s3.connection.OrdinaryCallingFormat() - return boto.s3.connection.S3Connection(aws_access_key_id=access, - aws_secret_access_key=secret, - is_secure=False, - calling_format=calling, - port=FLAGS.s3_port, - host=FLAGS.s3_host) + image.S3ImageService(context).delete(image_id) def qs(params): diff --git a/nova/image/service.py b/nova/image/service.py index 1a7a258b7..25e4bb675 100644 --- a/nova/image/service.py +++ b/nova/image/service.py @@ -38,6 +38,8 @@ class ImageService(object): def show(self, id): """ Returns a dict containing image data for the given opaque image id. + + Returns None if the id does not exist. """ @@ -88,3 +90,46 @@ class LocalImageService(ImageService): Delete the given image. Raises OSError if the image does not exist. """ os.unlink(self._path_to(image_id)) + + +# TODO(gundlach): before this can be loaded dynamically in ImageService.load(), +# we'll have to make __init__() not require a context. Right now it +# is only used by the AWS API, which hard-codes it, so that's OK. +class S3ImageService(ImageService): + """Service that stores images in an S3 provider.""" + + def __init__(self, context): + self._context = context + + def index(self): + response = self._conn().make_request( + method='GET', + bucket='_images') + items = json.loads(response.read()) + return dict((item['imageId'], item) for item in items) + + def show(self, id): + response = self._conn().make_request( + method='GET', + bucket='_images', + query_args=qs({'image_id': image_id})) + return json.loads(response.read()) + + def delete(self, image_id): + self._conn().make_request( + method='DELETE', + bucket='_images', + query_args=qs({'image_id': image_id})) + + def _conn(self): + """Return a boto S3Connection to the S3 store.""" + access = manager.AuthManager().get_access_key(self._context.user, + self._context.project) + secret = str(self._context.user.secret) + calling = boto.s3.connection.OrdinaryCallingFormat() + return boto.s3.connection.S3Connection(aws_access_key_id=access, + aws_secret_access_key=secret, + is_secure=False, + calling_format=calling, + port=FLAGS.s3_port, + host=FLAGS.s3_host) -- cgit