1、启动cinder-api服务

当你通过cinder-api命令(如:/usr/bin/cinder-api --config-file /etc/cinder/cinder.conf)启动api服务时,执行的实际上是
cinder/cmd/api.py/main()函数, 如下:

[root@xgto02n010027244133 ~]# cat /usr/bin/cinder-api
#!/usr/bin/python2
# PBR Generated from u'console_scripts'
import sys
from cinder.cmd.api import main
if __name__ == "__main__":
sys.exit(main())

cinder/cmd/api.py/main()函数,内容如下:

def main():

    objects.register_all() #加载辅助对象,封装与数据库相关的操作
gmr_opts.set_defaults(CONF) #oslo_reports模块,用于生成错误报告,如内存泄漏等
CONF(sys.argv[1:], project='cinder',
version=version.version_string())
config.set_middleware_defaults()
logging.setup(CONF, "cinder")
python_logging.captureWarnings(True)
utils.monkey_patch() # monkey-patch,替换库比如socket、thread等,不改变import的行为,改变的是操作的指向函数 gmr.TextGuruMeditation.setup_autorun(version, conf=CONF)
"""初始化rpc:
设置全局Transport和Notifier,Transport是
oslo_messaging/transport.py/Transport实例,我采用的是默认的
rpc_backend=rabbit,所以Transport采用的driver=oslo_messaging/
_drivers/impl_rabbit.py/RabbitDriver;Notifier是一个通知消息发
送器,它借助Transport将通知发送发送给ceilometer
"""
rpc.init(CONF)
#通过服务启动器启动WSGI服务(`osapi_volume`)并等待服务启动成功
#在初始化WSGI服务时,会设置路由映射以及加载WSGI应用程序
#在启动WSGI服务时,会启动http监听
launcher = service.process_launcher()
server = service.WSGIService('osapi_volume') #创建一个名为`osapi_volume`的`WSGIService`服务对象 ,2里面详解
launcher.launch_service(server, workers=server.workers)
launcher.wait()

2、创建 WSGIService 服务对象

from oslo_service import wsgi
from cinder import service
cinder/service.py:class WSGIService(service.ServiceBase):
class WSGIService(service.ServiceBase):
"""Provides ability to launch API from a 'paste' configuration.""" def __init__(self, name, loader=None):
"""Initialize, but do not start the WSGI server.
初始化,但是并不启动wsgi server服务
:param name: The name of the WSGI server given to the loader.
:param loader: Loads the WSGI application using the given name.
:returns: None """
self.name = name #服务名`osapi_volume`
self.manager = self._get_manager() #加载名为(`osapi_volume_manager`)的管理器,返回值为None)
#创建WSGI应用加载器,并根据配置文件(`cinder.conf`)设置应用配置路径,config_path` = `/etc/cinder/api-paste.ini‘
self.loader = loader or wsgi.Loader(CONF) #该函数会寻找cinder.conf文件中 api_paste_config 参数对应的配置文件,并保存到变量中
self.app = self.loader.load_app(name) #加载WSGI应用并设置路由映射,return paste.urlmap.URLMap """
根据配置文件(`cinder.conf`)设置监听地址及工作线程数
如果未指定监听ip及端口就分别设置为`0.0.0.0`及`0`
如果为指定工作线程数就设置为cpu个数
如果设置的工作线程数小于1,则抛异常
"""
self.host = getattr(CONF, '%s_listen' % name, "0.0.0.0")
self.port = getattr(CONF, '%s_listen_port' % name, 0)
self.use_ssl = getattr(CONF, '%s_use_ssl' % name, False)
self.workers = (getattr(CONF, '%s_workers' % name, None) or
processutils.get_worker_count())
if self.workers and self.workers < 1:
worker_name = '%s_workers' % name
msg = (_("%(worker_name)s value of %(workers)d is invalid, "
"must be greater than 0.") %
{'worker_name': worker_name,
'workers': self.workers})
raise exception.InvalidInput(msg) """如果CONF.profiler.enabled = True就开启性能分析
创建一个类型为`Messaging`的通知器(`_notifier`),将性能数据发送给
ceilometer
"""
setup_profiler(name, self.host)
##创建WSGI服务器对象
self.server = wsgi.Server(CONF,
name,
self.app,
host=self.host,
port=self.port,
use_ssl=self.use_ssl)

在cinder.conf配置文件中与cinder api服务有关的参数
# File name for the paste.deploy config for api service (string value)
api_paste_config = /etc/cinder/api-paste.ini
在初始化WSGIService服务对象过程中,主要完成了如下操作:
1)加载WSGI Application(Python Paste Deployment)
2)设置路由映射(Python Routes)
3)创建WSGI服务器对象并完成初始化

2.1 对wsgi的使用

oslo_service/wsgi.py
class Loader(object):
"""Used to load WSGI applications from paste configurations.""" def __init__(self, conf):
"""Initialize the loader, and attempt to find the config.
:param conf: Application config
:returns: None
"""
conf.register_opts(_options.wsgi_opts)
self.config_path = None config_path = conf.api_paste_config
if not os.path.isabs(config_path):
self.config_path = conf.find_file(config_path)
elif os.path.exists(config_path):
self.config_path = config_path if not self.config_path:
raise ConfigNotFound(path=config_path) def load_app(self, name):
"""Return the paste URLMap wrapped WSGI application.
:param name: Name of the application to load.
:returns: Paste URLMap object wrapping the requested application.
:raises: PasteAppNotFound
"""
try:
LOG.debug("Loading app %(name)s from %(path)s",
{'name': name, 'path': self.config_path})
return deploy.loadapp("config:%s" % self.config_path, name=name)
except LookupError:
LOG.exception("Couldn't lookup app: %s", name)
raise PasteAppNotFound(name=name, path=self.config_path)

配置文件api-paste.ini内容如下

[composite:osapi_volume]
use = call:cinder.api:root_app_factory
/: apiversions
/v1: openstack_volume_api_v1
/v2: openstack_volume_api_v2
/v3: openstack_volume_api_v3 [composite:openstack_volume_api_v1]
use = call:cinder.api.middleware.auth:pipeline_factory
noauth = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler noauth apiv1
keystone = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv1
keystone_nolimit = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv1 [composite:openstack_volume_api_v2]
use = call:cinder.api.middleware.auth:pipeline_factory
noauth = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler noauth apiv2
keystone = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv2
keystone_nolimit = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv2 cinder.conf文件中的api启动的配置
这三个参数控制的是api 版本的控制
# DEPRECATED: Deploy v1 of the Cinder API. (boolean value)
# This option is deprecated for remoervice_down_timeal.
# Its value may be silently ignored in the future.
#enable_v1_api = false--------不加载v1对应的app # DEPRECATED: Deploy v2 of the Cinder API. (boolean value)
# This option is deprecated for removal.
# Its value may be silently ignored in the future.
#enable_v2_api = True------------加载v2对应的app # Deploy v3 of the Cinder API. (boolean value)
enable_v3_api = True-------------加载v3对应的app # The strategy to use for auth. Supports noauth or keystone. (string value)
# Allowed values: noauth, keystone
auth_strategy = keystone----------这个参数控制的api-paste.ini中选择哪一种认证方式

  

  

  

  

  

cinder api启动过程源码分析的更多相关文章

  1. Spark(五十一):Spark On YARN(Yarn-Cluster模式)启动流程源码分析(二)

    上篇<Spark(四十九):Spark On YARN启动流程源码分析(一)>我们讲到启动SparkContext初始化,ApplicationMaster启动资源中,讲解的内容明显不完整 ...

  2. Spark(四十九):Spark On YARN启动流程源码分析(一)

    引导: 该篇章主要讲解执行spark-submit.sh提交到将任务提交给Yarn阶段代码分析. spark-submit的入口函数 一般提交一个spark作业的方式采用spark-submit来提交 ...

  3. Android系统默认Home应用程序(Launcher)的启动过程源码分析

    在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还须要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应 ...

  4. Android Content Provider的启动过程源码分析

    本文參考Android应用程序组件Content Provider的启动过程源码分析http://blog.csdn.net/luoshengyang/article/details/6963418和 ...

  5. Flume-NG启动过程源码分析(二)(原创)

    在上一节中讲解了——Flume-NG启动过程源码分析(一)(原创)  本节分析配置文件的解析,即PollingPropertiesFileConfigurationProvider.FileWatch ...

  6. 10.4 android输入系统_框架、编写一个万能模拟输入驱动程序、reader/dispatcher线程启动过程源码分析

    1. 输入系统框架 android输入系统官方文档 // 需FQhttp://source.android.com/devices/input/index.html <深入理解Android 卷 ...

  7. Activity启动过程源码分析(Android 8.0)

    Activity启动过程源码分析 本文来Activity的启动流程,一般我们都是通过startActivity或startActivityForResult来启动目标activity,那么我们就由此出 ...

  8. Netty入门一:服务端应用搭建 & 启动过程源码分析

    最近周末也没啥事就学学Netty,同时打算写一些博客记录一下(写的过程理解更加深刻了) 本文主要从三个方法来呈现:Netty核心组件简介.Netty服务端创建.Netty启动过程源码分析 如果你对Ne ...

  9. Spring启动过程源码分析基本概念

    Spring启动过程源码分析基本概念 本文是通过AnnotationConfigApplicationContext读取配置类来一步一步去了解Spring的启动过程. 在看源码之前,我们要知道某些类的 ...

随机推荐

  1. apache配置Directory目录权限的一些配置

    可以使用<Directory 目录路径>和</Directory>这对语句为主目录或虚拟目录设置权限,它们是一对容器语句,必须成对出现,它们之间封装的是具体 的设置目录权限语句 ...

  2. 《HelloGitHub》第 52 期

    兴趣是最好的老师,HelloGitHub 就是帮你找到兴趣! 简介 分享 GitHub 上有趣.入门级的开源项目. 这是一个面向编程新手.热爱编程.对开源社区感兴趣 人群的月刊,月刊的内容包括:各种编 ...

  3. C++程序员容易走入性能优化误区!对此你怎么看呢?

    有些C++ 程序员,特别是只写C++ 没有写过 Python/PHP 等慢语言的程序员,容易对性能有心智负担,就像着了魔一样,每写3 行代码必有一行代码因为性能考虑而优化使得代码变形(复杂而晦涩). ...

  4. 7.11 NOI模拟赛 graph 生成函数 dp 多项式

    LINK:graph HDU题库里的原题 没做过自闭. 考虑dp 设\(f_{i,j}\)表示前i个点构成j个联通块是树的方案数. 对于一次询问答案即为\(\sum_{j}f_{n,j}j^k\) 考 ...

  5. luogu P1526 [NOI2003]智破连环阵 搜索+最大匹配+剪枝

    LINK:智破连环阵 考试的时候 题意没理解清楚 题目是指一个炸弹爆炸时间结束后再放另一个炸弹 而放完一个炸弹紧接另一个炸弹.题目中存在然后二字. 这样我们可以发现某个炸弹只会炸连续的一段. 但是 由 ...

  6. 用大白话的方式讲明白Java的StringBuilder、StringBuffer的扩容机制

    StringBuffer和StringBuilder,它们的底层char数组value默认的初始化容量是16,扩容只需要修改底层的char数组,两者的扩容最终都会调用到AbstractStringBu ...

  7. linux之shell基本认知操作和简单shell练习

    shell编程: 1.Shell的作用 命令解释器,“翻译官”.介于操作系统内核与用户之间,负责解释命令行. shell功能非常强大,除负责解释名另外,还可以将多个命令组合起来,完成复杂的任务,这就是 ...

  8. python6.3类的继承与多态

    class Animal(object): def __init__(self,color): self.color=color def eat(self): print("动物在吃!&qu ...

  9. 节点操作 - DOM编程

    1. 获取节点 1.1 直接获取节点 父子关系: element.parentNode element.firstChild/element.lastChild element.firstElemen ...

  10. 【工具】之002-Mac下常用工具

    写在前面 我很懒,,,不想敲一个命令一个命令敲... "偷懒是有前提的,不是之前,就是之后." 常用命令 测试端口是否畅通 nc -z 10.254.3.86 30003 查看端口 ...