nova-api提供了WSGI服务,它对来自web的请求通过router方式转给各个service的具体方法,由这些service的具体方法完成服务的请求。
/usr/bin/nova-api
server = service.WSGIService(api)
/nova/service.py
self.loader = loader or wsgi.Loader()
self.app = self.loader.load_app(name)
/nova/wsgi.py
class Loader(object):load_app
加载 nova.api.openstack.compute:
APIRouter.factory
/nova/api/openstack/compute/__init__.py
class
APIRouter(nova.api.openstack.APIRouter)
ExtensionManager = extensions.ExtensionManager
def
_setup_routes(self, mapper, ext_mgr)
self.resources['xxxxxx'] =
xxxxxxx.create_resource()
/nova/api/openstack/__init__.py
class APIRouter(base_wsgi.Router)
def factory
def __init__
ext_mgr = self.
ExtensionManager()
mapper =
ProjectMapper()
self.
_setup_routes(mapper, ext_mgr)
self.
_setup_ext_routes(mapper, ext_mgr)
self.
_setup_extensions(ext_mgr)
super(APIRouter, self).__init__(mapper) 调用基类的初始化接口
/nova/wsgi.py
class Router(object) 为基类
方法 __init__
self.map = mapper
self._router = routes.middleware.RoutesMiddleware(self._dispatch, self.map)
@webob.dec.wsgify(RequestClass=
Request)
方法 __call__ WSGI服务请求调用接口,通过装饰后实际上是将此处__call__方法的返回值作为参数传入到webob.dec.wsgify装饰类,并调用该类的同名方法__call__, __call__方法又根据web请求调用app既Resource的__call__来完成具体的功能,每当有nova-api相关请求时均会进入到Resource的__call__方法以便进行请求的dispatch,所以下面的ExtensionsResource就主要是将各个功能类进行manage操作,以便完成服务请求。此处需要注意的是设计模式-
Decorator(装饰者模式)。
方法 def _dispatch(req): 转发web请求到具体的功能模块(extension加载的功能模块)
match = req.environ['wsgiorg.routing_args'][1]
retun app = match['controller']
分析ProjectMapper()
/nova/api/openstack/__init__.py
class ProjectMapper(APIMapper):
def resource
class APIMapper
def routematch
分析
_setup_ext_routes
/nova/api/openstack/__init__.py
def _setup_ext_routes(self, mapper, ext_mgr)
for resource in
ext_mgr.get_resources():
分析
ext_mgr.get_resources()
/nova/api/openstack/extensions.py
class ExtensionManager(object)
def get_resources(self):
resources.append(ResourceExtension('extensions',
ExtensionsResource(self)))
.....
分析
ExtensionsResource
/nova/api/openstack/extensions.py
class ExtensionsResource(
wsgi.Resource):
__init__
ext_data = {}
ext_data['name'] = ext.name
ext_data['alias'] = ext.alias
ext_data['description'] = ext.__doc__
......
return ext_data
通过该部分可以看出get_resources返回了extension加载的功能模块信息,以便在web请求路由时查找调用相应的功能方法
分析
wsgi.Resource
/nova/api/openstack/wsgi.py
class Resource(
wsgi.Application)
分析wsgi.Application
/nova/wsgi.py
分析extensions.ExtensionManager
/nova/api/openstack/compute/extensions.py
class ExtensionManager(base_extensions.ExtensionManager) 基类base_extensions.ExtensionManager
self.PluginManager = pluginmanager.PluginManager('nova','compute-extensions')
self.PluginManager.
load_plugins()
self.cls_list.append(self.PluginManager.
plugin_extension_factory)
......................
self.
_load_extensions()
/nova/api/openstack/extensions.py
class ExtensionManager(object)
self.cls_list = FLAGS.osapi_compute_extension既nova.api.openstack.compute.contrib.standard_extensions所指向的内容,形式如下:
nova.api.openstack.volume.contrib.volume_actions.Volume_actions
nova.api.openstack.volume.contrib.admin_actions.Admin_actions
nova.api.openstack.volume.contrib.image_create.Image_create
.........................
def _load_extensions(self)
def get_resources(self)
分析load_plugins()
/nova/openstack/common/plugin.py
class PluginManager(object)
def load_plugins(self):
for entrypoint in pkg_resources.iter_entry_points('%s.plugin' %self._project_name)
pluginclass = entrypoint.load()
plugin = pluginclass(self._service_name)
self.plugins.append(plugin)
分析plugin_extension_factory
/nova/openstack/common/plugin/pluginmanager.py
class ExtensionManager:
def plugin_extension_factory
ext_mgr.
load_extension(descriptor)
分析load_extension
/nova/api/openstack/extensions.py
class ExtensionManager:
def load_extension(self, ext_factory)
factory =
importutils.import_class(ext_factory)
分析_load_extensions
/nova/api/openstack/extensions.py
class ExtensionManager:
def load_extension(self)
extensions = list(
self.cls_list)
for ext_factory in extensions:
self.load_extension(ext_factory) 也是调用的load_extension
分析importutils.import_class
/nova/openstack/common/importutils.py
加载的既nova/api/openstack/compute/contrib:standard_extensions所指定的功能类,就是nova/api/openstack/compute/contrib目录下的内容
def import_class(import_str):
mod_str, _sep, class_str = import_str.rpartition('.')
__import__(mod_str)
getattr(sys.modules[mod_str], class_str)
以加载nova.api.openstack.volume.contrib.image_create.Floating_ips为例:
class Floating_ips(extensions.ExtensionDescriptor):
"""Floating IPs support"""
name = "FloatingIps"
alias = "os-floating-ips" 别名,web请求实际使用的就是别名,通过别名进行实际的功能入口查找
namespace = "http://docs.openstack.org/compute/ext/floating_ips/api/v1.1"
updated = "2011-06-16T00:00:00+00:00"
def get_resources
FloatingIPController()
def get_controller_extensions
controller =
FloatingIPActionController()
extension = extensions.ControllerExtension(self, 'servers', controller)
其中
FloatingIPController提供了show()、create()、delete()的方法以便对float IP进行操作
至此全部的extension功能模块都被加载完毕,再返回分析
create_resource
nova.api.openstack.compute import flavors