diff options
| author | Cory Wright <cory.wright@rackspace.com> | 2010-12-28 10:50:18 -0500 |
|---|---|---|
| committer | Cory Wright <cory.wright@rackspace.com> | 2010-12-28 10:50:18 -0500 |
| commit | 3a3987d3acaa23a90131ab550e659f2611fed63a (patch) | |
| tree | 8269abe1ec96b4c93ca46900a4e58ef9b37b1ea9 /nova/api | |
| parent | 002bbfa7a648a1117e14713eab3ee3ee4b2b6d8e (diff) | |
| parent | 675ca7c5f38af0fa1150936e881482aa20fdaa45 (diff) | |
| download | nova-3a3987d3acaa23a90131ab550e659f2611fed63a.tar.gz nova-3a3987d3acaa23a90131ab550e659f2611fed63a.tar.xz nova-3a3987d3acaa23a90131ab550e659f2611fed63a.zip | |
merge trunk
Diffstat (limited to 'nova/api')
| -rw-r--r-- | nova/api/openstack/__init__.py | 2 | ||||
| -rw-r--r-- | nova/api/openstack/images.py | 85 | ||||
| -rw-r--r-- | nova/api/openstack/servers.py | 29 |
3 files changed, 100 insertions, 16 deletions
diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index c49399f28..bebcdc18c 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -93,6 +93,8 @@ class APIRouter(wsgi.Router): logging.debug("Including admin operations in API.") server_members['pause'] = 'POST' server_members['unpause'] = 'POST' + server_members['suspend'] = 'POST' + server_members['resume'] = 'POST' mapper.resource("server", "servers", controller=servers.Controller(), collection={'detail': 'GET'}, diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index d3312aba8..ba35fbc78 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -30,6 +30,65 @@ from nova.api.openstack import faults FLAGS = flags.FLAGS +def _translate_keys(item): + """ + Maps key names to Rackspace-like attributes for return + also pares down attributes to those we want + item is a dict + + Note: should be removed when the set of keys expected by the api + and the set of keys returned by the image service are equivalent + + """ + # TODO(tr3buchet): this map is specific to s3 object store, + # replace with a list of keys for _filter_keys later + mapped_keys = {'status': 'imageState', + 'id': 'imageId', + 'name': 'imageLocation'} + + mapped_item = {} + # TODO(tr3buchet): + # this chunk of code works with s3 and the local image service/glance + # when we switch to glance/local image service it can be replaced with + # a call to _filter_keys, and mapped_keys can be changed to a list + try: + for k, v in mapped_keys.iteritems(): + # map s3 fields + mapped_item[k] = item[v] + except KeyError: + # return only the fields api expects + mapped_item = _filter_keys(item, mapped_keys.keys()) + + return mapped_item + + +def _translate_status(item): + """ + Translates status of image to match current Rackspace api bindings + item is a dict + + Note: should be removed when the set of statuses expected by the api + and the set of statuses returned by the image service are equivalent + + """ + status_mapping = { + 'pending': 'queued', + 'decrypting': 'preparing', + 'untarring': 'saving', + 'available': 'active'} + item['status'] = status_mapping[item['status']] + return item + + +def _filter_keys(item, keys): + """ + Filters all model attributes except for keys + item is a dict + + """ + return dict((k, v) for k, v in item.iteritems() if k in keys) + + class Controller(wsgi.Controller): _serialization_metadata = { @@ -42,25 +101,25 @@ class Controller(wsgi.Controller): self._service = utils.import_object(FLAGS.image_service) def index(self, req): - """Return all public images in brief.""" - return dict(images=[dict(id=img['id'], name=img['name']) - for img in self.detail(req)['images']]) + """Return all public images in brief""" + items = self._service.index(req.environ['nova.context']) + items = common.limited(items, req) + items = [_filter_keys(item, ('id', 'name')) for item in items] + return dict(images=items) def detail(self, req): - """Return all public images in detail.""" + """Return all public images in detail""" try: - images = self._service.detail(req.environ['nova.context']) - images = common.limited(images, req) + items = self._service.detail(req.environ['nova.context']) except NotImplementedError: - # Emulate detail() using repeated calls to show() - ctxt = req.environ['nova.context'] - images = self._service.index(ctxt) - images = common.limited(images, req) - images = [self._service.show(ctxt, i['id']) for i in images] - return dict(images=images) + items = self._service.index(req.environ['nova.context']) + items = common.limited(items, req) + items = [_translate_keys(item) for item in items] + items = [_translate_status(item) for item in items] + return dict(images=items) def show(self, req, id): - """Return data about the given image id.""" + """Return data about the given image id""" return dict(image=self._service.show(req.environ['nova.context'], id)) def delete(self, req, id): diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 8d60e2cab..10c397384 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -46,7 +46,8 @@ def _entity_detail(inst): power_state.NOSTATE: 'build', power_state.RUNNING: 'active', power_state.BLOCKED: 'active', - power_state.PAUSED: 'suspended', + power_state.SUSPENDED: 'suspended', + power_state.PAUSED: 'error', power_state.SHUTDOWN: 'active', power_state.SHUTOFF: 'active', power_state.CRASHED: 'error'} @@ -182,7 +183,7 @@ class Controller(wsgi.Controller): self.compute_api.pause(ctxt, id) except: readable = traceback.format_exc() - logging.error("Compute.api::pause %s", readable) + logging.error(_("Compute.api::pause %s"), readable) return faults.Fault(exc.HTTPUnprocessableEntity()) return exc.HTTPAccepted() @@ -193,6 +194,28 @@ class Controller(wsgi.Controller): self.compute_api.unpause(ctxt, id) except: readable = traceback.format_exc() - logging.error("Compute.api::unpause %s", readable) + logging.error(_("Compute.api::unpause %s"), readable) + return faults.Fault(exc.HTTPUnprocessableEntity()) + return exc.HTTPAccepted() + + def suspend(self, req, id): + """permit admins to suspend the server""" + context = req.environ['nova.context'] + try: + self.compute_api.suspend(context, id) + except: + readable = traceback.format_exc() + logging.error(_("compute.api::suspend %s"), readable) + return faults.Fault(exc.HTTPUnprocessableEntity()) + return exc.HTTPAccepted() + + def resume(self, req, id): + """permit admins to resume the server from suspend""" + context = req.environ['nova.context'] + try: + self.compute_api.resume(context, id) + except: + readable = traceback.format_exc() + logging.error(_("compute.api::resume %s"), readable) return faults.Fault(exc.HTTPUnprocessableEntity()) return exc.HTTPAccepted() |
