diff options
| author | Brian Lamar <brian.lamar@rackspace.com> | 2011-04-12 10:19:37 -0400 |
|---|---|---|
| committer | Brian Lamar <brian.lamar@rackspace.com> | 2011-04-12 10:19:37 -0400 |
| commit | cebc98176926f57016a508d5c59b11f55dfcf2b3 (patch) | |
| tree | 0bbcbbf0b94e0b54a3afc62b89e63ce0e920757b /nova | |
| parent | ae30b0a83469b15d1986fdbbef4f1dee52d68c17 (diff) | |
Commit for merge of metadata_quotas preq.
Diffstat (limited to 'nova')
| -rw-r--r-- | nova/api/openstack/servers.py | 103 | ||||
| -rw-r--r-- | nova/compute/api.py | 20 | ||||
| -rw-r--r-- | nova/tests/api/openstack/test_servers.py | 1 |
3 files changed, 90 insertions, 34 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 diff --git a/nova/compute/api.py b/nova/compute/api.py index 5ec88adbd..e5065c3a5 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -497,10 +497,11 @@ class API(base.Base): """Reboot the given instance.""" self._cast_compute_message('reboot_instance', context, instance_id) - def rebuild(self, context, instance_id, image_id, metadata=None): + def rebuild(self, context, instance_id, image_id, metadata=None, + files_to_inject=None): """Rebuild the given instance with the provided metadata.""" - instance = db.api.instance_get(context, instance_id) + if instance["state"] == power_state.BUILDING: msg = _("Instance already building") raise exception.BuildInProgress(msg) @@ -509,11 +510,22 @@ class API(base.Base): self._check_metadata_quota(context, metadata) self._check_metadata_item_length(context, metadata) - self._cast_compute_message('rebuild_instance', context, - instance_id, params={"image_id": image_id}) + files_to_inject = files_to_inject or [] + self._check_injected_file_quota(context, files_to_inject) + self._check_injected_file_format(context, files_to_inject) self.db.instance_update(context, instance_id, {"metadata": metadata}) + rebuild_params = { + "image_id": image_id, + "injected_files": files_to_inject, + } + + self._cast_compute_message('rebuild_instance', + context, + instance_id, + params=rebuild_params) + def revert_resize(self, context, instance_id): """Reverts a resize, deleting the 'new' instance in the process""" context = context.elevated() diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index 424ed2ec6..ccbdc4b38 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -981,6 +981,7 @@ class ServersTest(test.TestCase): res = req.get_response(fakes.wsgi_app()) self.assertEqual(res.status_int, 202) + self.assertEqual(res.body, "") def test_server_rebuild_rejected_when_building(self): body = { |
