summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/servers.py103
1 files changed, 73 insertions, 30 deletions
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index c9f0e1b1c..61e08211d 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -606,22 +606,32 @@ class ControllerV10(Controller):
except exception.TimeoutException:
return exc.HTTPRequestTimeout()
- def _action_rebuild(self, input_dict, req, id):
- context = req.environ['nova.context']
- if (not 'rebuild' in input_dict
- or not 'imageId' in input_dict['rebuild']):
- msg = _("No imageId was specified")
- return faults.Fault(exc.HTTPBadRequest(msg))
+ def _action_rebuild(self, info, request, instance_id):
+ context = request.environ['nova.context']
+ instance_id = int(instance_id)
- image_id = input_dict['rebuild']['imageId']
+ try:
+ image_id = info["rebuild"]["imageId"]
+ except (KeyError, TypeError):
+ msg = _("Could not parse imageId from request.")
+ LOG.debug(msg)
+ return faults.Fault(exc.HTTPBadRequest(explanation=msg))
try:
- self.compute_api.rebuild(context, id, image_id)
+ self.compute_api.rebuild(context, instance_id, image_id)
except exception.BuildInProgress:
- msg = _("Unable to rebuild server that is being rebuilt")
+ msg = _("Instance %d is currently being rebuilt.") % instance_id
+ LOG.debug(msg)
return faults.Fault(exc.HTTPConflict(explanation=msg))
+ except exception.Error as ex:
+ msg = _("Error encountered attempting to rebuild instance "
+ "%(instance_id): %(ex)") % locals()
+ LOG.error(msg)
+ raise
- return exc.HTTPAccepted()
+ response = exc.HTTPAccepted()
+ response.empty_body = True
+ return response
class ControllerV11(Controller):
@@ -662,33 +672,66 @@ class ControllerV11(Controller):
def _limit_items(self, items, req):
return common.limited_by_marker(items, req)
- def _action_rebuild(self, input_dict, req, id):
- context = req.environ['nova.context']
- if (not 'rebuild' in input_dict
- or not 'imageRef' in input_dict['rebuild']):
- msg = _("No imageRef was specified")
- return faults.Fault(exc.HTTPBadRequest(msg))
-
- image_ref = input_dict['rebuild']['imageRef']
- image_id = common.get_id_from_href(image_ref)
+ def _check_metadata(self, metadata):
+ """Ensure that the metadata given is of the correct type."""
+ try:
+ metadata.iteritems()
+ except AttributeError as ex:
+ msg = _("Unable to parse metadata key/value pairs.")
+ LOG.debug(msg)
+ raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
+
+ def _check_personalities(self, personalities):
+ """Ensure the given personalities have valid paths and contents."""
+ for personality in personalities:
+ try:
+ path = personality["path"]
+ contents = personality["contents"]
+ except (KeyError, TypeError):
+ msg = _("Unable to parse personality path/contents.")
+ LOG.info(msg)
+ raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
- metadata = []
- if 'metadata' in input_dict['rebuild']:
try:
- for k, v in input_dict['rebuild']['metadata'].items():
- metadata.append({'key': k, 'value': v})
+ base64.b64decode(contents)
+ except TypeError:
+ msg = _("Personality content could not be Base64 decoded.")
+ LOG.info(msg)
+ raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
+
+ def _action_rebuild(self, info, request, instance_id):
+ context = request.environ['nova.context']
+ instance_id = int(instance_id)
+
+ try:
+ image_ref = info["rebuild"]["imageRef"]
+ except (KeyError, TypeError):
+ msg = _("Could not parse imageRef from request.")
+ return faults.Fault(exc.HTTPBadRequest(explanation=msg))
- except Exception:
- msg = _("Improperly formatted metadata provided")
- return exc.HTTPBadRequest(msg)
+ image_id = common.get_id_from_href(image_ref)
+ personalities = info["rebuild"].get("personality", [])
+ metadata = info["rebuild"].get("metadata", {})
+
+ self._check_metadata(metadata)
+ self._check_personalities(personalities)
try:
- self.compute_api.rebuild(context, id, image_id, metadata)
+ args = [context, instance_id, image_id, metadata, personalities]
+ self.compute_api.rebuild(*args)
except exception.BuildInProgress:
- msg = _("Unable to rebuild server that is being rebuilt")
+ msg = _("Instance %d is currently being rebuilt.") % instance_id
+ LOG.debug(msg)
return faults.Fault(exc.HTTPConflict(explanation=msg))
-
- return exc.HTTPAccepted()
+ except exception.Error as ex:
+ msg = _("Error encountered attempting to rebuild instance "
+ "%(instance_id): %(ex)") % locals()
+ LOG.error(msg)
+ raise
+
+ response = exc.HTTPAccepted()
+ response.empty_body = True
+ return response
def get_default_xmlns(self, req):
return common.XML_NS_V11