版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处!
此篇有些凌乱,主要是服务的启动及web请求的调用跨越了多个模块,仅作为个人学习笔记分享,有任何问题欢迎交流!
nova-api提供了RESTful服务,它对来自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"""
"""Floating IPs support"""
name = "FloatingIps"
alias = "os-floating-ips" 别名
namespace = "http://docs.openstack.org/compute/ext/floating_ips/api/v1.1"
updated = "2011-06-16T00:00:00+00:00"
alias = "os-floating-ips" 别名
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