summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjaypipes@gmail.com <>2010-10-01 16:06:14 -0400
committerjaypipes@gmail.com <>2010-10-01 16:06:14 -0400
commit0ef621d47eeea421820a2191de53dee9e83d8c44 (patch)
tree1b686e54d75a6c48810cbb3c97d8727f2283f7f1
parentbf22bbd2d4f4364255a306e024d1a7d316b89014 (diff)
downloadnova-0ef621d47eeea421820a2191de53dee9e83d8c44.tar.gz
nova-0ef621d47eeea421820a2191de53dee9e83d8c44.tar.xz
nova-0ef621d47eeea421820a2191de53dee9e83d8c44.zip
Adds BaseImageService and flag to control image service loading. Adds unit test for local image service.
-rw-r--r--nova/api/rackspace/images.py7
-rw-r--r--nova/flags.py4
-rw-r--r--nova/image/service.py114
-rw-r--r--nova/tests/api/rackspace/test_images.py102
4 files changed, 206 insertions, 21 deletions
diff --git a/nova/api/rackspace/images.py b/nova/api/rackspace/images.py
index 4a7dd489c..d4ab8ce3c 100644
--- a/nova/api/rackspace/images.py
+++ b/nova/api/rackspace/images.py
@@ -17,12 +17,17 @@
from webob import exc
+from nova import flags
+from nova import utils
from nova import wsgi
from nova.api.rackspace import _id_translator
import nova.api.rackspace
import nova.image.service
from nova.api.rackspace import faults
+
+FLAGS = flags.FLAGS
+
class Controller(wsgi.Controller):
_serialization_metadata = {
@@ -35,7 +40,7 @@ class Controller(wsgi.Controller):
}
def __init__(self):
- self._service = nova.image.service.ImageService.load()
+ self._service = utils.import_object(FLAGS.image_service)
self._id_translator = _id_translator.RackspaceAPIIdTranslator(
"image", self._service.__class__.__name__)
diff --git a/nova/flags.py b/nova/flags.py
index c32cdd7a4..ab80e83fb 100644
--- a/nova/flags.py
+++ b/nova/flags.py
@@ -222,6 +222,10 @@ DEFINE_string('volume_manager', 'nova.volume.manager.AOEManager',
DEFINE_string('scheduler_manager', 'nova.scheduler.manager.SchedulerManager',
'Manager for scheduler')
+# The service to use for image search and retrieval
+DEFINE_string('image_service', 'nova.image.service.LocalImageService',
+ 'The service to use for retrieving and searching for images.')
+
DEFINE_string('host', socket.gethostname(),
'name of this node')
diff --git a/nova/image/service.py b/nova/image/service.py
index 1a7a258b7..4bceab6ee 100644
--- a/nova/image/service.py
+++ b/nova/image/service.py
@@ -20,34 +20,117 @@ import os.path
import random
import string
-class ImageService(object):
- """Provides storage and retrieval of disk image objects."""
+from nova import utils
+from nova import flags
- @staticmethod
- def load():
- """Factory method to return image service."""
- #TODO(gundlach): read from config.
- class_ = LocalImageService
- return class_()
+
+FLAGS = flags.FLAGS
+
+
+flags.DEFINE_string('glance_teller_address', '127.0.0.1',
+ 'IP address or URL where Glance\'s Teller service resides')
+flags.DEFINE_string('glance_teller_port', '9191',
+ 'Port for Glance\'s Teller service')
+flags.DEFINE_string('glance_parallax_address', '127.0.0.1',
+ 'IP address or URL where Glance\'s Parallax service resides')
+flags.DEFINE_string('glance_parallax_port', '9191',
+ 'Port for Glance\'s Parallax service')
+
+
+class BaseImageService(object):
+
+ """Base class for providing image search and retrieval services"""
def index(self):
"""
Return a dict from opaque image id to image data.
"""
+ raise NotImplementedError
def show(self, id):
"""
Returns a dict containing image data for the given opaque image id.
"""
+ raise NotImplementedError
+
+ def create(self, data):
+ """
+ Store the image data and return the new image id.
+
+ :raises AlreadyExists if the image already exist.
+ """
+ raise NotImplementedError
+
+ def update(self, image_id, data):
+ """Replace the contents of the given image with the new data.
-class GlanceImageService(ImageService):
+ :raises NotFound if the image does not exist.
+
+ """
+ raise NotImplementedError
+
+ def delete(self, image_id):
+ """
+ Delete the given image.
+
+ :raises NotFound if the image does not exist.
+
+ """
+ raise NotImplementedError
+
+
+class GlanceImageService(BaseImageService):
+
"""Provides storage and retrieval of disk image objects within Glance."""
- # TODO(gundlach): once Glance has an API, build this.
- pass
+ def index(self):
+ """
+ Calls out to Parallax for a list of images available
+ """
+ raise NotImplementedError
+
+ def show(self, id):
+ """
+ Returns a dict containing image data for the given opaque image id.
+ """
+ raise NotImplementedError
+
+ def create(self, data):
+ """
+ Store the image data and return the new image id.
+
+ :raises AlreadyExists if the image already exist.
+
+ """
+ raise NotImplementedError
+
+ def update(self, image_id, data):
+ """Replace the contents of the given image with the new data.
+
+ :raises NotFound if the image does not exist.
+
+ """
+ raise NotImplementedError
+
+ def delete(self, image_id):
+ """
+ Delete the given image.
+
+ :raises NotFound if the image does not exist.
+
+ """
+ raise NotImplementedError
+
+ def delete_all(self):
+ """
+ Clears out all images
+ """
+ pass
+
+
+class LocalImageService(BaseImageService):
-class LocalImageService(ImageService):
"""Image service storing images to local disk."""
def __init__(self):
@@ -88,3 +171,10 @@ class LocalImageService(ImageService):
Delete the given image. Raises OSError if the image does not exist.
"""
os.unlink(self._path_to(image_id))
+
+ def delete_all(self):
+ """
+ Clears out all images in local directory
+ """
+ for f in os.listdir(self._path):
+ os.unlink(self._path_to(f))
diff --git a/nova/tests/api/rackspace/test_images.py b/nova/tests/api/rackspace/test_images.py
index 489e35052..21dad7648 100644
--- a/nova/tests/api/rackspace/test_images.py
+++ b/nova/tests/api/rackspace/test_images.py
@@ -15,25 +15,111 @@
# License for the specific language governing permissions and limitations
# under the License.
+import logging
import unittest
import stubout
+from nova import utils
from nova.api.rackspace import images
-class ImagesTest(unittest.TestCase):
+#{ Fixtures
+
+
+fixture_images = [
+ {
+ 'name': 'image #1',
+ 'updated': None,
+ 'created': None,
+ 'status': None,
+ 'serverId': None,
+ 'progress': None},
+ {
+ 'name': 'image #2',
+ 'updated': None,
+ 'created': None,
+ 'status': None,
+ 'serverId': None,
+ 'progress': None},
+ {
+ 'name': 'image #3',
+ 'updated': None,
+ 'created': None,
+ 'status': None,
+ 'serverId': None,
+ 'progress': None}]
+
+
+#}
+
+
+class BaseImageServiceTests():
+
+ """Tasks to test for all image services"""
+
+ def test_create_and_index(self):
+ for i in fixture_images:
+ self.service.create(i)
+
+ self.assertEquals(len(fixture_images), len(self.service.index()))
+
+ def test_create_and_update(self):
+ ids = {}
+ temp = 0
+ for i in fixture_images:
+ ids[self.service.create(i)] = temp
+ temp += 1
+
+ self.assertEquals(len(fixture_images), len(self.service.index()))
+
+ for image_id, num in ids.iteritems():
+ new_data = fixture_images[num]
+ new_data['updated'] = 'test' + str(num)
+ self.service.update(image_id, new_data)
+
+ images = self.service.index()
+
+ for i in images:
+ self.assertEquals('test' + str(ids[i['id']]),
+ i['updated'])
+
+ def test_create_and_show(self):
+ ids = {}
+ temp = 0
+ for i in fixture_images:
+ ids[self.service.create(i)] = temp
+ temp += 1
+
+ for i in fixture_images:
+ image = self.service.show(i['id'])
+ index = ids[i['id']]
+ self.assertEquals(image, fixture_images[index])
+
+
+class LocalImageServiceTest(unittest.TestCase,
+ BaseImageServiceTests):
+
+ """Tests the local image service"""
+
def setUp(self):
self.stubs = stubout.StubOutForTesting()
+ self.service = utils.import_object('nova.image.service.LocalImageService')
def tearDown(self):
+ self.service.delete_all()
self.stubs.UnsetAll()
- def test_get_image_list(self):
- pass
- def test_delete_image(self):
- pass
-
- def test_create_image(self):
- pass
+#class GlanceImageServiceTest(unittest.TestCase,
+# BaseImageServiceTests):
+#
+# """Tests the local image service"""
+#
+# def setUp(self):
+# self.stubs = stubout.StubOutForTesting()
+# self.service = utils.import_object('nova.image.service.GlanceImageService')
+#
+# def tearDown(self):
+# self.service.delete_all()
+# self.stubs.UnsetAll()