nova 组件的wsgi详细工作流程

虽然是英文的,但是很值得review哦!!

At the heart of the OpenStack cloud framework is the Nova API Service (Ken Pepple, 2011). This API Service makes command and control of the Nova Compute programmatically available to users in realization

of the definition of cloud computing. The API endpoints are basic http web services which handle authentication, authorization, and basic command and control functions using the Openstack API interface. 

By default, nova-api listens on port 8774 for the OpenStack API. To accept and fulfill API requests, nova-api initiates most of the orchestration activities (such as boot servers and create flavors), and also enforces 

some policies (mostly authentication, authorization, and quota checks). For some requests, it will fulfill the entire request itself by querying the database and then returning the answer. For more complicated 

requests, it will pass messages to other daemons through a combination of writing information to the database and adding messages to the queue.

  

WSGI and Middleware

WSGI, an interface specification, specifies both server and application side interfaces. If an application is written to the WSGI spec then it will run on any server written to that spec (Phillip J. Eby, 2003).

These WSGI applications can be stacked. Middleware (those in the middle of the stack) must implement both sides of the WSGI interface, application and server. For the application on top of it it'll behave as a

 server whereas it'll behave as an application for the application below.

The WSGI server's only job is to receive the request from the client, pass it to the application and then send the response provided by the application to the client – nothing else. The finer details must be supplied 

by the application or middleware.

 

Webob, Routes, and Paste

Routes is a Python re-implementation of the Rails routes system for mapping URLs to application actions, and conversely to generate URLs. Routes makes it easy to create pretty and concise URLs that are
RESTful with little effort (Routes Documentation).
 
Webob is a Python library that provides wrappers around the WSGI request environment, and an object to help create WSGI responses. The objects map much of the specified behavior of HTTP, including header
parsing, content negotiation and correct handling of conditional and range requests (Webob).
 
Paste Deployment is a system for finding and configuring WSGI applications and servers. For WSGI application consumers it provides a single, simple function (loadapp) for loading a WSGI application from a
configuration file or a Python Egg. For WSGI application providers it only asks for a single, simple entry point to your application, so that application users don’t need to be exposed to the implementation details of
your application (Paste Deployment).

Nova API Architecture

 

<a '="" href="https://www.ibm.com/developerworks/mydeveloperworks/blogs/e93514d3-c4f0-4aa0-8844-497f370090f5/resource/BLOGS_UPLOADED_IMAGES/novaapiarchitecture.jpeg" target="_blank" style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: inherit; vertical-align: baseline; color: rgb(25, 112, 176); text-decoration: none;">image

 
nova.wsgi.Server serves as an embedded web server in every Nova API worker processes. It encapsulates and manages an eventlet greened version of WSGI server which runs on a self managed green 
thread pool(size configurable) and a supplied socket with customized configuration(port number to listen & maximum number of queued connections). 
 
Instead of directly feeding in a WSGI application to the server mentioned above, nova.api.openstack.compute.APIRouter is introduced to allow attaching multiple WSGI applications to a single WSGI server, which 
is the reason why every core APIs and extension resources are themselves independent WSGI applications.
 
nova.wsgi.Router, super class of nova.api.openstack.compute.APIRouter, uses routes.middleware.RoutesMiddleware internally to map incoming requests to these WSGI applications. 
nova.api.openstack.wsgi.Resource (implementation of nova.Application) is the one which actually defines the webob wrapped wsgi application entrance point and handles incoming requests. All core and 
extension APIs are essentially controllers of nova.api.openstack.wsgi.Resource which is also responsible for its controller methods dispatching.
 

Extension API

There two ways to extend openstack API - creating new WSGI resources or extending controllers of existing WSGI resources. Both ways require writing a new module to declare controller classes to handle 

requests and implement extensions.ExtensionDescriptor to register the newly created resource or controller extensions. Multiply resources and/or controller extensions can be defined in a single API module.

 

Security Policy

Security policies are enforced by nova.openstack.common.policy. Each API can have their own policies defined for every of its operations or on the whole API in nova/policy.json. 
Note, rules definition will be interpreted recursively until the last one is resolved, and roles will be tested against the user's credentials. 
 

Nova API Service Initialization

 
image
 
 
nova.wsgi.Server is not hard coded to load a nova.api.openstack.APIRouter implementation - instead how the router, along with some other filters, are deployed to the WSGI server is done by paste and 
configured through paste configuration file. For instance, user authentication and rate limit are achieved by these filters. The name of the paste configuration file is api-paste.ini, and it's typically located 
under /etc/nova. 
 

Extension API Loading

Based on the osapi_compute_extension configuration, ExtensionManager will either load standard or selected extensions. The entry points for loading these extensions are defined in contrib package init 

stage (standard_extensions and select_extensions). standard extension will load extension modules under given location (the contrib package for Compute and Volume APIs) complying with the standard 

extension naming convention (a class inside a module has the same name as the module with initial capitalized), while selective extension loads the ones configured in nova configuration file.

 
The exact loading process consists of two stage: extension module loading and extension API setup, as illustrated in the following diagram: 
 
image
 
An incoming request will first arrive at the nova.api.openstack.APIRouter instance and be handed over to its internally managed routes.middleware. RoutesMiddleware
instance where the request will be further routed to its destined WSGI resource according to the route mapping setup during the initialization phase. After a  
WSGI resource (a core or extension API resource) receives the request, nova.api.openstack.wsgi.Resource multiplexes the incoming request to a request handling 
method (index, create, delete... or other custom actions) which is the final place where a request is served.

How to write a core API

  
  
  • write a controller to implement the standard actions (e.g. index, create, delete ......) and possibly other custom actions for the new RESTful resource
  • set up the RESTful resource in APIRouter implementation, e.g. nova.api.openstack.compute.APIRouter for Compute

How to write an extension API

1. write a controller(s) to implement the standard actions (e.g. index, create, delete .....) and possibly other custom actions for the new RESTful resource(s) 
or an existing one(s)
2. define a subclass of extensions.ExtensionDescriptor with concrete implementations of get_resources or/and get_controller_extensions methods to set up the new 
resources or/and controller extensions, depending on whether it's requeired to register new RESTful resources, extend the controllers of existing RESTful 
resources, or both.
3. put the controller(s) and the extensions descriptor class into a module which has the same name as the extensions descriptor with the initial in lower case in 
order to let nova.api.openstack.extensions.load_standard_extensions recognize it when the system is configured to load standard extension. 4. place the module under a package where it can be loaded, this is typically the contrib package 5. supply a custom_routes_fn when creating resource extension (extensions.ResourceExtension) to set up a custom resource if desired, for example getting rid off 
the {tenent_id} route component 
 
Below is an simple extension API definition named “Documents”. The controller implementation defines the five basic operations (CRUD and List) to this Documents collection and its member resource. class DocumentController(object):     “””the Document s API controller deceleration”””       def index(self,req):      “””return a list of documents “””         pass     def create(self,req, body):    “””create a document “””         pass     def show(self,req, id):    “”” read the details of a document given its id”””         pass    def update(self, req, id, body):       “””updates a document given its id and content “””          pass     def delete(self,req, id):     “””removes a document given its id”””         pass     class Documents(extensions.ExtensionDescriptor):       “”“ExtensionDescriptor implementation”””         name = "document"         alias ="os-documents"         namespace ="......"         updated = "......"         def get_resources(self):   “”” register the new Documents RESTful resource ”””             resources = [extensions.ResourceExtension('os-documents',DocumentController())]             return resources
  
  
 
These operations can be invoked as follows, GET v2/{tenant_id}/ os-documents POST v2/{tenant_id}/ os-documents GET v2/{tenant_id}/ os-documents/{document_id} PUT v2/{tenant_id}/ os-documents/{document_id} DELETE v2/{tenant_id}/ os-documents/{document_id}
 

How to debug Nova API in Pydev

 
1. avoid eventlet blindly greening everything (I suspect the monkey patch would make the debugger not able to block the thread execution.) change eventlet.monkey_patch(os=False) to eventlet.monkey_patch(all=False,socket=True,select=True) in nova/bin/nova-api 2. make sure pydevd.py module is included in your python path e.g. PYTHONPATH=/usr/share/eclipse/dropins/pydev/eclipse/plugins/org.python.pydev_2.6 3. insert  import pydevd;  pydevd.settrace() to where you want to start debugging  4. start debug server, and switch to debug perspective in eclipse, click on Pydev menu and select start debug server on the pull down list run the remote program i.e. nova/bin/nova-api for nova API the program should be associated to the debug server then
 
Note:

    
    
  • The reason why we cannot simply right click on nova-api and go Debug As--> Python Run in eclipse is that this will attach the debugger to the parent process 
while its child processes are actually the ones that accept and serve incoming requests.
  • Only one process can be associated to the debugger at a time.
 
 
 
 
 

References:

Ken, Pepple. (2011). Deploying Openstack. : O'Reilly Media.Phillip J. Eby. (07 Dec 2003). Python Web Server Gateway Interface. In PEP 333. Retrieved 29 Sep. 2012, from http://www.python.org/dev/peps/pep-0333/Routes Documentation. Retrieved 25 Sep. 2012, from http://routes.readthedocs.org/en/latest/Webob WSGI request and response objects. In Webob.org. Retrieved 25 Sep. 2012, from http://webob.org/Paste Deployment. In Python Paste. Retrieved 25 Sep. 2012, from http://pythonpaste.org/deploy/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值