diff options
| author | Brian Lamar <brian.lamar@rackspace.com> | 2011-05-03 18:02:19 +0000 |
|---|---|---|
| committer | Tarmac <> | 2011-05-03 18:02:19 +0000 |
| commit | 95052ace83860ee3bdc5420f3d7f5096f6f4bede (patch) | |
| tree | 16686a1a73c5c110edf01ed2656d909513d78ebd /nova/api | |
| parent | ce019de9ca633218f031077f6317edb373f1ea88 (diff) | |
| parent | 29e9aa173ea20a7d5cb816ce7478d6c0c2c38b80 (diff) | |
Adding support for server rebuild to v1.0 and v1.1 of the Openstack API
Diffstat (limited to 'nova/api')
| -rw-r--r-- | nova/api/openstack/servers.py | 83 | ||||
| -rw-r--r-- | nova/api/openstack/views/servers.py | 4 |
2 files changed, 82 insertions, 5 deletions
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 8505c3f71..3cf78e32c 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -317,10 +317,6 @@ class Controller(common.OpenstackController): return faults.Fault(exc.HTTPBadRequest()) return exc.HTTPAccepted() - def _action_rebuild(self, input_dict, req, id): - LOG.debug(_("Rebuild server action is not implemented")) - return faults.Fault(exc.HTTPNotImplemented()) - def _action_resize(self, input_dict, req, id): """ Resizes a given instance to the flavor size requested """ try: @@ -603,6 +599,28 @@ class ControllerV10(Controller): except exception.TimeoutException: return exc.HTTPRequestTimeout() + def _action_rebuild(self, info, request, instance_id): + context = request.environ['nova.context'] + instance_id = int(instance_id) + + 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, instance_id, image_id) + except exception.BuildInProgress: + msg = _("Instance %d is currently being rebuilt.") % instance_id + LOG.debug(msg) + return faults.Fault(exc.HTTPConflict(explanation=msg)) + + response = exc.HTTPAccepted() + response.empty_body = True + return response + class ControllerV11(Controller): def _image_id_from_req_data(self, data): @@ -639,6 +657,63 @@ class ControllerV11(Controller): def _limit_items(self, items, req): return common.limited_by_marker(items, req) + def _validate_metadata(self, metadata): + """Ensure that we can work with the metadata given.""" + 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 _decode_personalities(self, personalities): + """Decode the Base64-encoded personalities.""" + 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)) + + try: + personality["contents"] = 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.") + LOG.debug(msg) + return faults.Fault(exc.HTTPBadRequest(explanation=msg)) + + image_id = common.get_id_from_href(image_ref) + personalities = info["rebuild"].get("personality", []) + metadata = info["rebuild"].get("metadata", {}) + + self._validate_metadata(metadata) + self._decode_personalities(personalities) + + try: + self.compute_api.rebuild(context, instance_id, image_id, metadata, + personalities) + except exception.BuildInProgress: + msg = _("Instance %d is currently being rebuilt.") % instance_id + LOG.debug(msg) + return faults.Fault(exc.HTTPConflict(explanation=msg)) + + response = exc.HTTPAccepted() + response.empty_body = True + return response + def _get_server_admin_password(self, server): """ Determine the admin password for a server on creation """ password = server.get('adminPass') diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index bdc85f4a1..0be468edc 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -66,7 +66,9 @@ class ViewBuilder(object): power_state.SHUTDOWN: 'SHUTDOWN', power_state.SHUTOFF: 'SHUTOFF', power_state.CRASHED: 'ERROR', - power_state.FAILED: 'ERROR'} + power_state.FAILED: 'ERROR', + power_state.BUILDING: 'BUILD', + } inst_dict = { 'id': int(inst['id']), |
