def __init__(self): super(GridcentricServerControllerExtension, self).__init__() self.gridcentric_api = API() # Add the gridcentric-specific states to the state map common._STATE_MAP['blessed'] = {'default': 'BLESSED'}
class GridcentricServerControllerExtension(wsgi.Controller): """ The OpenStack Extension definition for the Gridcentric capabilities. Currently this includes: * Bless an existing virtual machine (creates a new server snapshot of the virtual machine and enables the user to launch new copies nearly instantaneously). * Launch new virtual machines from a blessed copy above. * Discard blessed VMs. """ _view_builder_class = views_servers.ViewBuilder def __init__(self): super(GridcentricServerControllerExtension, self).__init__() self.gridcentric_api = API() # Add the gridcentric-specific states to the state map common._STATE_MAP['blessed'] = {'default': 'BLESSED'} @wsgi.action('gc_bless') def _bless_instance(self, req, id, body): context = req.environ["nova.context"] result = self.gridcentric_api.bless_instance(context, id) return self._build_instance_list(req, [result]) @wsgi.action('gc_discard') def _discard_instance(self, req, id, body): context = req.environ["nova.context"] result = self.gridcentric_api.discard_instance(context, id) return webob.Response(status_int=200, body=json.dumps(result)) @wsgi.action('gc_launch') def _launch_instance(self, req, id, body): context = req.environ["nova.context"] try: params = body.get('gc_launch', {}) result = self.gridcentric_api.launch_instance(context, id, params=params) return self._build_instance_list(req, [result]) except novaexc.QuotaError as error: self._handle_quota_error(error) @wsgi.action('gc_migrate') def _migrate_instance(self, req, id, body): context = req.environ["nova.context"] try: dest = body['gc_migrate']['dest'] except: return webob.Response(status_int=401, body='Invalid destination') try: self.gridcentric_api.migrate_instance(context, id, dest) return webob.Response(status_int=200) except novaexc.QuotaError as error: self._handle_quota_error(error) @wsgi.action('gc_list_launched') def _list_launched_instances(self, req, id, body): context = req.environ["nova.context"] return self._build_instance_list(req, self.gridcentric_api.list_launched_instances(context, id)) @wsgi.action('gc_list_blessed') def _list_blessed_instances(self, req, id, body): context = req.environ["nova.context"] return self._build_instance_list(req, self.gridcentric_api.list_blessed_instances(context, id)) @wsgi.extends def delete(self, req, resp_obj, **kwargs): """ There is some clean up our extension needs to do when an instance is deleted. """ context = req.environ["nova.context"] instance_uuid = kwargs.get("id", None) if instance_uuid != None: self.gridcentric_api.cleanup_instance(context, instance_uuid) def _build_instance_list(self, req, instances): def _build_view(req, instance, is_detail=True): project_id = getattr(req.environ['nova.context'], 'project_id', '') base_url = req.application_url flavor_builder = nova.api.openstack.views.flavors.ViewBuilderV11( base_url, project_id) image_builder = nova.api.openstack.views.images.ViewBuilderV11( base_url, project_id) addresses_builder = nova.api.openstack.views.addresses.ViewBuilderV11() builder = nova.api.openstack.views.servers.ViewBuilderV11( addresses_builder, flavor_builder, image_builder, base_url, project_id) return builder.build(instance, is_detail=is_detail) instances = self._view_builder.detail(req, instances)['servers'] return webob.Response(status_int=200, body=json.dumps(instances)) ## Utility methods taken from nova core ## def _handle_quota_error(self, error): """ Reraise quota errors as api-specific http exceptions """ code_mappings = { "OnsetFileLimitExceeded": _("Personality file limit exceeded"), "OnsetFilePathLimitExceeded": _("Personality file path too long"), "OnsetFileContentLimitExceeded": _("Personality file content too long"), # NOTE(bcwaldon): expose the message generated below in order # to better explain how the quota was exceeded "InstanceLimitExceeded": error.message, } code = error.kwargs['code'] expl = code_mappings.get(code, error.message) % error.kwargs raise webob.exc.HTTPRequestEntityTooLarge(explanation=expl, headers={'Retry-After': 0})