156 lines
4.9 KiB
Python
156 lines
4.9 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# Copyright 2010 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 logging
|
|
|
|
from webob import exc
|
|
|
|
from nova import compute
|
|
from nova import flags
|
|
from nova import utils
|
|
from nova import wsgi
|
|
import nova.api.openstack
|
|
from nova.api.openstack import common
|
|
from nova.api.openstack import faults
|
|
import nova.image.service
|
|
|
|
|
|
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)
|
|
|
|
|
|
def _convert_image_id_to_hash(image):
|
|
image_id = abs(hash(image['imageId']))
|
|
image['imageId'] = image_id
|
|
image['id'] = image_id
|
|
|
|
|
|
class Controller(wsgi.Controller):
|
|
|
|
_serialization_metadata = {
|
|
'application/xml': {
|
|
"attributes": {
|
|
"image": ["id", "name", "updated", "created", "status",
|
|
"serverId", "progress"]}}}
|
|
|
|
def __init__(self):
|
|
self._service = utils.import_object(FLAGS.image_service)
|
|
|
|
def index(self, req):
|
|
"""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"""
|
|
try:
|
|
items = self._service.detail(req.environ['nova.context'])
|
|
except NotImplementedError:
|
|
items = self._service.index(req.environ['nova.context'])
|
|
for image in items:
|
|
_convert_image_id_to_hash(image)
|
|
|
|
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"""
|
|
image_id = common.get_image_id_from_image_hash(self._service,
|
|
req.environ['nova.context'], id)
|
|
|
|
image = self._service.show(req.environ['nova.context'], image_id)
|
|
_convert_image_id_to_hash(image)
|
|
return dict(image=image)
|
|
|
|
def delete(self, req, id):
|
|
# Only public images are supported for now.
|
|
raise faults.Fault(exc.HTTPNotFound())
|
|
|
|
def create(self, req):
|
|
context = req.environ['nova.context']
|
|
env = self._deserialize(req.body, req)
|
|
instance_id = env["image"]["serverId"]
|
|
name = env["image"]["name"]
|
|
return compute.API().snapshot(context, instance_id, name)
|
|
|
|
def update(self, req, id):
|
|
# Users may not modify public images, and that's all that
|
|
# we support for now.
|
|
raise faults.Fault(exc.HTTPNotFound())
|