summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorChris Behrens <cbehrens@codestud.com>2011-06-29 12:26:04 -0700
committerChris Behrens <cbehrens@codestud.com>2011-06-29 12:26:04 -0700
commit097e25f69a3ce4fe29addf93e4f92fa861aa54dc (patch)
tree31692c181fc854c4e9842b87e99d1559d7337ed8 /nova/api
parent851802e772095b646a7570bf0cc0c6d32be4643c (diff)
parent17d08b9644080265f6feb4d55825de8e4049c991 (diff)
downloadnova-097e25f69a3ce4fe29addf93e4f92fa861aa54dc.tar.gz
nova-097e25f69a3ce4fe29addf93e4f92fa861aa54dc.tar.xz
nova-097e25f69a3ce4fe29addf93e4f92fa861aa54dc.zip
Merged trunk
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/common.py37
-rw-r--r--nova/api/openstack/images.py58
2 files changed, 64 insertions, 31 deletions
diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py
index 4da7ec0ef..aa8911b62 100644
--- a/nova/api/openstack/common.py
+++ b/nova/api/openstack/common.py
@@ -45,23 +45,20 @@ def get_pagination_params(request):
exc.HTTPBadRequest() exceptions to be raised.
"""
- try:
- marker = int(request.GET.get('marker', 0))
- except ValueError:
- raise webob.exc.HTTPBadRequest(_('marker param must be an integer'))
-
- try:
- limit = int(request.GET.get('limit', 0))
- except ValueError:
- raise webob.exc.HTTPBadRequest(_('limit param must be an integer'))
-
- if limit < 0:
- raise webob.exc.HTTPBadRequest(_('limit param must be positive'))
-
- if marker < 0:
- raise webob.exc.HTTPBadRequest(_('marker param must be positive'))
-
- return(marker, limit)
+ params = {}
+ for param in ['marker', 'limit']:
+ if not param in request.GET:
+ continue
+ try:
+ params[param] = int(request.GET[param])
+ except ValueError:
+ msg = _('%s param must be an integer') % param
+ raise webob.exc.HTTPBadRequest(msg)
+ if params[param] < 0:
+ msg = _('%s param must be positive') % param
+ raise webob.exc.HTTPBadRequest(msg)
+
+ return params
def limited(items, request, max_limit=FLAGS.osapi_max_limit):
@@ -100,10 +97,10 @@ def limited(items, request, max_limit=FLAGS.osapi_max_limit):
def limited_by_marker(items, request, max_limit=FLAGS.osapi_max_limit):
"""Return a slice of items according to the requested marker and limit."""
- (marker, limit) = get_pagination_params(request)
+ params = get_pagination_params(request)
- if limit == 0:
- limit = max_limit
+ limit = params.get('limit', max_limit)
+ marker = params.get('marker')
limit = min(max_limit, limit)
start_index = 0
diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py
index d43340e10..0ab764199 100644
--- a/nova/api/openstack/images.py
+++ b/nova/api/openstack/images.py
@@ -90,31 +90,67 @@ class Controller(object):
return webob.exc.HTTPNoContent()
def create(self, req, body):
- """Snapshot a server instance and save the image.
+ """Snapshot or backup a server instance and save the image.
+
+ Images now have an `image_type` associated with them, which can be
+ 'snapshot' or the backup type, like 'daily' or 'weekly'.
+
+ If the image_type is backup-like, then the rotation factor can be
+ included and that will cause the oldest backups that exceed the
+ rotation factor to be deleted.
:param req: `wsgi.Request` object
"""
+ def get_param(param):
+ try:
+ return body["image"][param]
+ except KeyError:
+ raise webob.exc.HTTPBadRequest(explanation="Missing required "
+ "param: %s" % param)
+
context = req.environ['nova.context']
content_type = req.get_content_type()
if not body:
raise webob.exc.HTTPBadRequest()
+ image_type = body["image"].get("image_type", "snapshot")
+
try:
server_id = self._server_id_from_req(req, body)
- image_name = body["image"]["name"]
except KeyError:
raise webob.exc.HTTPBadRequest()
+ image_name = get_param("name")
props = self._get_extra_properties(req, body)
- image = self._compute_service.snapshot(context, server_id,
- image_name, props)
+ if image_type == "snapshot":
+ image = self._compute_service.snapshot(
+ context, server_id, image_name,
+ extra_properties=props)
+ elif image_type == "backup":
+ # NOTE(sirp): Unlike snapshot, backup is not a customer facing
+ # API call; rather, it's used by the internal backup scheduler
+ if not FLAGS.allow_admin_api:
+ raise webob.exc.HTTPBadRequest(
+ explanation="Admin API Required")
+
+ backup_type = get_param("backup_type")
+ rotation = int(get_param("rotation"))
+
+ image = self._compute_service.backup(
+ context, server_id, image_name,
+ backup_type, rotation, extra_properties=props)
+ else:
+ LOG.error(_("Invalid image_type '%s' passed") % image_type)
+ raise webob.exc.HTTPBadRequest(explanation="Invalue image_type: "
+ "%s" % image_type)
+
return dict(image=self.get_builder(req).build(image, detail=True))
def get_builder(self, request):
"""Indicates that you must use a Controller subclass."""
- raise NotImplementedError
+ raise NotImplementedError()
def _server_id_from_req(self, req, data):
raise NotImplementedError()
@@ -181,9 +217,9 @@ class ControllerV11(Controller):
"""
context = req.environ['nova.context']
filters = self._get_filters(req)
- (marker, limit) = common.get_pagination_params(req)
- images = self._image_service.index(
- context, filters=filters, marker=marker, limit=limit)
+ page_params = common.get_pagination_params(req)
+ images = self._image_service.index(context, filters=filters,
+ **page_params)
builder = self.get_builder(req).build
return dict(images=[builder(image, detail=False) for image in images])
@@ -195,9 +231,9 @@ class ControllerV11(Controller):
"""
context = req.environ['nova.context']
filters = self._get_filters(req)
- (marker, limit) = common.get_pagination_params(req)
- images = self._image_service.detail(
- context, filters=filters, marker=marker, limit=limit)
+ page_params = common.get_pagination_params(req)
+ images = self._image_service.detail(context, filters=filters,
+ **page_params)
builder = self.get_builder(req).build
return dict(images=[builder(image, detail=True) for image in images])