From 0d71f29583c68c2488d5917f3fdaa7b7011186a1 Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Tue, 13 Dec 2011 15:57:37 -0500 Subject: Expose Asynchronous Fault entity in the OSAPI Show latest instance fault in server update, show and detailed list Change-Id: I9719d696aa3aac6e9cbca4c9a102bcd5a33bf0b1 --- nova/api/openstack/v2/schemas/v1.1/server.rng | 34 ++++++++++++++--------- nova/api/openstack/v2/servers.py | 40 +++++++++++++++++++++------ nova/api/openstack/v2/views/servers.py | 26 ++++++++++++++--- 3 files changed, 74 insertions(+), 26 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/v2/schemas/v1.1/server.rng b/nova/api/openstack/v2/schemas/v1.1/server.rng index 2e86ccffe..07fa16daa 100644 --- a/nova/api/openstack/v2/schemas/v1.1/server.rng +++ b/nova/api/openstack/v2/schemas/v1.1/server.rng @@ -1,20 +1,20 @@ - - - - - - - - - - + + + + + + + + + + - + - + @@ -24,6 +24,14 @@ + + + + + + + + @@ -39,7 +47,7 @@ - + diff --git a/nova/api/openstack/v2/servers.py b/nova/api/openstack/v2/servers.py index b149c2cf9..049a17ef6 100644 --- a/nova/api/openstack/v2/servers.py +++ b/nova/api/openstack/v2/servers.py @@ -16,28 +16,21 @@ import base64 import os -import traceback -from lxml import etree from webob import exc import webob from xml.dom import minidom from nova.api.openstack import common from nova.api.openstack.v2 import ips -from nova.api.openstack.v2.views import addresses as views_addresses -from nova.api.openstack.v2.views import flavors as views_flavors -from nova.api.openstack.v2.views import images as views_images from nova.api.openstack.v2.views import servers as views_servers from nova.api.openstack import wsgi from nova.api.openstack import xmlutil from nova import compute from nova.compute import instance_types from nova import network -from nova import db from nova import exception from nova import flags -from nova import image from nova import log as logging from nova.rpc import common as rpc_common from nova.scheduler import api as scheduler_api @@ -92,6 +85,18 @@ class Controller(wsgi.Controller): """ return None + def _add_instance_faults(self, ctxt, instances): + faults = self.compute_api.get_instance_faults(ctxt, instances) + if faults is not None: + for instance in instances: + faults_list = faults.get(instance['uuid'], []) + try: + instance['fault'] = faults_list[0] + except IndexError: + pass + + return instances + def _get_servers(self, req, is_detail): """Returns a list of servers, taking into account any search options specified. @@ -142,6 +147,7 @@ class Controller(wsgi.Controller): limited_list = self._limit_items(instance_list, req) if is_detail: + self._add_instance_faults(context, limited_list) return self._view_builder.detail(req, limited_list) else: return self._view_builder.index(req, limited_list) @@ -297,8 +303,9 @@ class Controller(wsgi.Controller): def show(self, req, id): """ Returns server details by server id """ try: - instance = self.compute_api.routing_get( - req.environ['nova.context'], id) + context = req.environ['nova.context'] + instance = self.compute_api.routing_get(context, id) + self._add_instance_faults(context, [instance]) return self._view_builder.show(req, instance) except exception.NotFound: raise exc.HTTPNotFound() @@ -503,6 +510,7 @@ class Controller(wsgi.Controller): instance.update(update_dict) + self._add_instance_faults(ctxt, [instance]) return self._view_builder.show(req, instance) @exception.novaclient_converter @@ -796,6 +804,7 @@ class Controller(wsgi.Controller): raise exc.HTTPNotFound(explanation=msg) instance = self._get_server(context, instance_id) + self._add_instance_faults(context, [instance]) view = self._view_builder.show(request, instance) view['server']['adminPass'] = password @@ -882,6 +891,16 @@ class SecurityGroupsTemplateElement(xmlutil.TemplateElement): return 'security_groups' in datum +def make_fault(elem): + fault = xmlutil.SubTemplateElement(elem, 'fault', selector='fault') + fault.set('code') + fault.set('created') + msg = xmlutil.SubTemplateElement(fault, 'message') + msg.text = 'message' + det = xmlutil.SubTemplateElement(fault, 'details') + det.text = 'details' + + def make_server(elem, detailed=False): elem.set('name') elem.set('id') @@ -907,6 +926,9 @@ def make_server(elem, detailed=False): flavor.set('id') xmlutil.make_links(flavor, 'links') + # Attach fault node + make_fault(elem) + # Attach metadata node elem.append(common.MetadataTemplate()) diff --git a/nova/api/openstack/v2/views/servers.py b/nova/api/openstack/v2/views/servers.py index 979be930f..859bd48ab 100644 --- a/nova/api/openstack/v2/views/servers.py +++ b/nova/api/openstack/v2/views/servers.py @@ -42,6 +42,10 @@ class ViewBuilder(common.ViewBuilder): "VERIFY_RESIZE", ) + _fault_statuses = ( + "ERROR", + ) + def __init__(self): """Initialize view builder.""" super(ViewBuilder, self).__init__() @@ -101,6 +105,9 @@ class ViewBuilder(common.ViewBuilder): "links": self._get_links(request, instance["uuid"]), }, } + _inst_fault = self._get_fault(request, instance) + if server["server"]["status"] in self._fault_statuses and _inst_fault: + server['server']['fault'] = _inst_fault if server["server"]["status"] in self._progress_statuses: server["server"]["progress"] = instance.get("progress", 0) @@ -109,13 +116,11 @@ class ViewBuilder(common.ViewBuilder): def index(self, request, instances): """Show a list of servers without many details.""" - list_func = self.basic - return self._list_view(list_func, request, instances) + return self._list_view(self.basic, request, instances) def detail(self, request, instances): """Detailed view of a list of instance.""" - list_func = self.show - return self._list_view(list_func, request, instances) + return self._list_view(self.show, request, instances) def _list_view(self, func, request, servers): """Provide a view for a list of servers.""" @@ -173,3 +178,16 @@ class ViewBuilder(common.ViewBuilder): "href": flavor_bookmark, }], } + + def _get_fault(self, request, instance): + fault = instance.get("fault", None) + + if not fault: + return None + + return { + "code": fault["code"], + "created": utils.isotime(fault["created_at"]), + "message": fault["message"], + "details": fault["details"], + } -- cgit