cinder api启动过程源码分析
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启动过程源码分析的更多相关文章
- Spark(五十一):Spark On YARN(Yarn-Cluster模式)启动流程源码分析(二)
上篇<Spark(四十九):Spark On YARN启动流程源码分析(一)>我们讲到启动SparkContext初始化,ApplicationMaster启动资源中,讲解的内容明显不完整 ...
- Spark(四十九):Spark On YARN启动流程源码分析(一)
引导: 该篇章主要讲解执行spark-submit.sh提交到将任务提交给Yarn阶段代码分析. spark-submit的入口函数 一般提交一个spark作业的方式采用spark-submit来提交 ...
- Android系统默认Home应用程序(Launcher)的启动过程源码分析
在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还须要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应 ...
- Android Content Provider的启动过程源码分析
本文參考Android应用程序组件Content Provider的启动过程源码分析http://blog.csdn.net/luoshengyang/article/details/6963418和 ...
- Flume-NG启动过程源码分析(二)(原创)
在上一节中讲解了——Flume-NG启动过程源码分析(一)(原创) 本节分析配置文件的解析,即PollingPropertiesFileConfigurationProvider.FileWatch ...
- 10.4 android输入系统_框架、编写一个万能模拟输入驱动程序、reader/dispatcher线程启动过程源码分析
1. 输入系统框架 android输入系统官方文档 // 需FQhttp://source.android.com/devices/input/index.html <深入理解Android 卷 ...
- Activity启动过程源码分析(Android 8.0)
Activity启动过程源码分析 本文来Activity的启动流程,一般我们都是通过startActivity或startActivityForResult来启动目标activity,那么我们就由此出 ...
- Netty入门一:服务端应用搭建 & 启动过程源码分析
最近周末也没啥事就学学Netty,同时打算写一些博客记录一下(写的过程理解更加深刻了) 本文主要从三个方法来呈现:Netty核心组件简介.Netty服务端创建.Netty启动过程源码分析 如果你对Ne ...
- Spring启动过程源码分析基本概念
Spring启动过程源码分析基本概念 本文是通过AnnotationConfigApplicationContext读取配置类来一步一步去了解Spring的启动过程. 在看源码之前,我们要知道某些类的 ...
随机推荐
- Android复习准备
1. 四大组件是什么? Activity(活动):用于表现功能 Service(服务):后台运行服务,不提供界面呈现 BroadcastReceiver(广播接收器):用来接收广播 ContentPr ...
- spring 循环依赖的一次 理解
前言: 在看spring 循环依赖的问题中,知道原理,网上一堆的资料有讲原理. 但今天在看代码过程中,又产生了疑问. 疑问点如下: // 疑问点: 先进行 dependon 判断String[] de ...
- Entry基本用法
1.BooleanVar() 布尔类型 2.IntVar() 整数类型 3.DoubleVar() 浮点数类型 4.StringVar() 字符串类型 5.self.entry1 = Entry(se ...
- 使用 MySQLi 和 PDO 向 MySQL 插入多条数据
PHP MySQL 插入多条数据 使用 MySQLi 和 PDO 向 MySQL 插入多条数据 mysqli_multi_query() 函数可用来执行多条SQL语句. 以下实例向 "MyG ...
- Skill 扫描list中是否含有某元素
https://www.cnblogs.com/yeungchie/ code procedure(ycInListp(scan keylist) prog((times) times = 0 for ...
- CF R 633 div 1 1338 C. Perfect Triples 打表找规律
LINK:Perfect Triples 初看这道题 一脸懵逼.. 完全没有思路 最多就只是发现一点小规律 即. a<b<c. 且b的最大的二进制位一定严格大于a b的最大二进制位一定等于 ...
- 解析laravel之redis简单模块操作
入门级操作 普通 set / get 操作: set操作,如果键名存在,则会覆盖原有的值: $redis = app('redis.connection'); $redis->set('libr ...
- 10分钟了解js的宏任务和微任务
熟悉宏任务和微任务以及js(nodejs)事件循环机制,在写业务代码还是自己写库,或者看源码都是那么重要 看了部分文档,自己总结和实践了一下 js中同步任务.宏任务和微任务介绍 同步任务: 普通任务 ...
- Spring 自动装配机制
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w ...
- 符合AUTOSAR(AP&CP)的嵌入式系统和软件设计工具
AUTOSAR Builder功能介绍 AUTOSAR Builder 是达索旗下一种基于 Eclipse 的开放性.可扩展工具套件,用于设计和开发符合 AUTOSAR 标准的系统和软件.最新版本20 ...