diff options
| author | Michael Gundlach <michael.gundlach@rackspace.com> | 2010-08-23 12:07:20 -0400 |
|---|---|---|
| committer | Michael Gundlach <michael.gundlach@rackspace.com> | 2010-08-23 12:07:20 -0400 |
| commit | e3727d6d88a0631d3b896c4fcdcfec05510dad36 (patch) | |
| tree | 3fa9bc56c14e007ab3939ec1119f63c533889722 | |
| parent | d38f21e0fb382bd8f01cfbc79cb34ea8710cd639 (diff) | |
| download | nova-e3727d6d88a0631d3b896c4fcdcfec05510dad36.tar.gz nova-e3727d6d88a0631d3b896c4fcdcfec05510dad36.tar.xz nova-e3727d6d88a0631d3b896c4fcdcfec05510dad36.zip | |
Support opaque id to rs int id as well
| -rw-r--r-- | nova/api/rackspace/images.py | 42 | ||||
| -rw-r--r-- | nova/api/services/image.py | 8 |
2 files changed, 36 insertions, 14 deletions
diff --git a/nova/api/rackspace/images.py b/nova/api/rackspace/images.py index e29f737a5..c9cc8e85d 100644 --- a/nova/api/rackspace/images.py +++ b/nova/api/rackspace/images.py @@ -44,18 +44,24 @@ class Controller(base.Controller): strategy = self._svc.__class__.__name__ return self._id_xlator.to_rs_id(strategy, image_id) + def _from_rs_id(self, rs_image_id): + """ + Convert an image id from the Rackspace API format (an int) to the + format of our ImageService strategy. + """ + strategy = self._svc.__class__.__name__ + return self._id_xlator.from_rs_id(strategy, rs_image_id) + def index(self, req): """Return all public images.""" - data = self._svc.list() - for img in data: - img['id'] = self._to_rs_id(img['id']) - return dict(images=result) + data = dict((self._to_rs_id(id), val) + for id, val in self._svc.index().iteritems()) + return dict(images=data) def show(self, req, id): """Return data about the given image id.""" - img = self._svc.show(id) - img['id'] = self._to_rs_id(img['id']) - return dict(image=img) + opaque_id = self._from_rs_id(id) + return dict(image=self._svc.show(opaque_id)) def delete(self, req, id): # Only public images are supported for now. @@ -80,14 +86,30 @@ class RackspaceApiImageIdTranslator(object): def __init__(self): self._store = datastore.Redis.instance() + self._key_template = "rsapi.idstrategies.image.%s.%s" def to_rs_id(self, strategy_name, opaque_id): """Convert an id from a strategy-specific one to a Rackspace one.""" - key = "rsapi.idstrategies.image.%s" % strategy_name + key = self._key_template % (strategy_name, "fwd") result = self._store.hget(key, str(opaque_id)) if result: # we have a mapping from opaque to RS for this strategy return int(result) else: + # Store the mapping. nextid = self._store.incr("%s.lastid" % key) - self._store.hsetnx(key, str(opaque_id), nextid) - return nextid + if self._store.hsetnx(key, str(opaque_id), nextid): + # If someone else didn't beat us to it, store the reverse + # mapping as well. + key = self._key_template % (strategy_name, "rev") + self._store.hset(key, nextid, str(opaque_id)) + return nextid + else: + # Someone beat us to it; use their number instead, and + # discard nextid (which is OK -- we don't require that + # every int id be used.) + return int(self._store.hget(key, str(opaque_id))) + + def from_rs_id(self, strategy_name, rs_id): + """Convert a Rackspace id to a strategy-specific one.""" + key = self._key_template % (strategy_name, "rev") + return self._store.hget(key, rs_id) diff --git a/nova/api/services/image.py b/nova/api/services/image.py index bda50fc66..11e19804a 100644 --- a/nova/api/services/image.py +++ b/nova/api/services/image.py @@ -17,6 +17,7 @@ import cPickle as pickle import os.path +import random import string class ImageService(object): @@ -31,8 +32,7 @@ class ImageService(object): def index(self): """ - Return a list of image data dicts. Each dict will contain an - id key whose value is an opaque image id. + Return a dict from opaque image id to image data. """ def show(self, id): @@ -62,10 +62,10 @@ class LocalImageService(ImageService): def _ids(self): """The list of all image ids.""" - return os.path.listdir(self._path) + return os.listdir(self._path) def index(self): - return [ self.show(id) for id in self._ids() ] + return dict((id, self.show(id)) for id in self._ids()) def show(self, id): return pickle.load(open(self._path_to(id))) |
