keystone在httpd的入口执行文件为/usr/bin/keystone-wsgi-public

查看文件/usr/bin/keystone-wsgi-public,根据代码,看到主要是这几行代码对keystone的服务进行了初始化,keystone服务通过wsgiref.simple_server与httpd进行交互,初始化函数为initialize_public_application

 from keystone.server.wsgi import initialize_public_application

 if __name__ == "__main__":
......
import wsgiref.simple_server as wss ...... server = wss.make_server(args.host, args.port, initialize_public_application()) .......
server.serve_forever()

查看initialize_public_application

 from keystone.server.flask import core as flask_core
def initialize_public_application():
return flask_core.initialize_application(name='public', config_files=flask_core._get_config_files())
initialize_admin_application = initialize_public_application

从这里可以看到在Rocky版本的keystone中,admin和public已经合并在了一起,不再区分admin和public,flask_core.initialize_application接受三个参数,原型如下

 def initialize_application(name, post_log_configured_function=lambda: None,
config_files=None):
possible_topdir = os.path.normpath(os.path.join(
os.path.abspath(__file__),
os.pardir,
os.pardir,
os.pardir,
os.pardir)) dev_conf = os.path.join(possible_topdir,
'etc',
'keystone.conf')
if not config_files:
config_files = None
if os.path.exists(dev_conf):
config_files = [dev_conf] keystone.server.configure(config_files=config_files) if CONF.debug:
CONF.log_opt_values(log.getLogger(CONF.prog), log.DEBUG) post_log_configured_function() def loadapp():
app = application.application_factory(name)
return app _unused, app = keystone.server.setup_backends(
startup_application_fn=loadapp) profiler.setup(name) return setup_app_middleware(app)
name 这个不需要讲,但是name必须是public或者admin,在后面的初始化过程中有限制
post_log_configured_function   接收一个函数,会在initialize_application这个函数中调用,但是具体是什么作用,还没有领悟出来,但是这个函数应该是可以做一些类似于初始化等等作用的
config_files 在开发模式下可以自定义keystone.conf,如果自己定义了keyston.conf这个文件,那么就会完全的替代/etc/keystone/keystone.conf中定义的一些配置参数,关于配置参数,后续会介绍

接着往下看这个函数
keystone.server.configure这个函数对keystone进行了一些配置
 def configure(version=None, config_files=None,
pre_setup_logging_fn=lambda: None):
keystone.conf.configure()
sql.initialize()
keystone.conf.set_config_defaults() CONF(project='keystone', version=version,
default_config_files=config_files) pre_setup_logging_fn()
keystone.conf.setup_logging() if CONF.insecure_debug:
LOG.warning(
'insecure_debug is enabled so responses may include sensitive '
'information.')
keystone.conf.configure()这个函数添加了几个参数,
standard-threads 可以自定义多少个线程
pydev-debug-host以及pydev-debug-port是对远程debug的机器和port进行了定义,并在conf中注册了它们三个参数
 def configure(conf=None):
if conf is None:
conf = CONF conf.register_cli_opt(
cfg.BoolOpt('standard-threads', default=False,
help='Do not monkey-patch threading system modules.'))
conf.register_cli_opt(
cfg.StrOpt('pydev-debug-host',
help='Host to connect to for remote debugger.'))
conf.register_cli_opt(
cfg.PortOpt('pydev-debug-port',
help='Port to connect to for remote debugger.')) for module in conf_modules:
module.register_opts(conf) # register any non-default auth methods here (used by extensions, etc)
auth.setup_authentication() # add oslo.cache related config options
cache.configure(conf)
auth.setup_authentication(),配置了几种认证方式,password,token等等,跟上述参数一样,先定义,后注册到conf中
cache.configure(conf),对cache进行了定义和注册,主要涉及到各种cache的定义等等

回到 keystone.server.configure
sql.initialize() 这个函数主要是对数据库进行了初始化,导入配置文件中的参数
keystone.conf.set_config_defaults()   采用默认值对keystone的设置进行初始化
CONF(project='keystone', version=version, default_config_files=config_files) 这块比较难理解,先说第三个参数,第三个参数采用指定的config_files对默认参数进行复写

CONF的原型是 keystone.conf.CONF, 它采用了从文件中直接导入的方式,构造了一个单例的configure配置类 CONF = ConfigOpts()

CONF()调用了ConfigOpts.__call__()这个方法
pre_setup_logging_fn()这个和前文的post_log_configured_function是相似的,都是完成一些自定义的动作
keystone.conf.setup_logging()这个参数是对log进行配置

回到initialize_application
keystone.server.setup_backend(startup_application_fn=loadapp)
 def setup_backends(load_extra_backends_fn=lambda: {},
startup_application_fn=lambda: None):
drivers = backends.load_backends()
drivers.update(load_extra_backends_fn())
res = startup_application_fn()
return drivers, res
     def loadapp():
app = application.application_factory(name)
return app

这两段代码中,setup_backends首先导入一些driver,导入方法主要是用stevedore的DriverManager类对一些方法进行导入,并将这些driver注册到provider_api中,供后续调用

load_app采用了flask.application的工厂模式方法构造

 def application_factory(name='public'):
if name not in ('admin', 'public'):
raise RuntimeError('Application name (for base_url lookup) must be '
'either `admin` or `public`.') app = flask.Flask(name)
app.after_request(_add_vary_x_auth_token_header) app.config.update(PROPAGATE_EXCEPTIONS=True) # TODO(morgan): Convert Subsystems over to Flask-Native, for now, we simply
dispatch_map = collections.OrderedDict() hc_app = healthcheck.Healthcheck.app_factory(
{}, oslo_config_project='keystone')
dispatch_map['/healthcheck'] = hc_app
_routers = []
sub_routers = []
mapper = routes.Mapper()
for api_routers in ALL_API_ROUTERS:
moved_found = [pfx for
pfx in getattr(api_routers, '_path_prefixes', [])
if pfx in _MOVED_API_PREFIXES]
if moved_found:
raise RuntimeError('An API Router is trying to register path '
'prefix(s) `%(pfx)s` that is handled by the '
'native Flask app. Keystone cannot '
'start.' %
{'pfx': ', '.join([p for p in moved_found])}) routers_instance = api_routers.Routers()
_routers.append(routers_instance)
routers_instance.append_v3_routers(mapper, sub_routers) keystone.api.discovery.register_version('v3')
for api in keystone.api.__apis__:
for api_bp in api.APIs:
api_bp.instantiate_and_register_to_app(app)
sub_routers.append(_ComposibleRouterStub(_routers))
legacy_dispatcher = keystone_wsgi.ComposingRouter(mapper, sub_routers) for pfx in itertools.chain(*[rtr.Routers._path_prefixes for
rtr in ALL_API_ROUTERS]):
dispatch_map['/v3/%s' % pfx] = legacy_dispatcher app.wsgi_app = KeystoneDispatcherMiddleware(
app.wsgi_app,
dispatch_map)
return app

这块限定了name只能是public or admin,这个函数主要是为keystone的请求添加路由的mapper以及中间件的调用,先由这个函数对请求的API的路径进行解析, 最后KeystoneDispatcherMiddleware完成对路径API的访问,同样是调用了__call__()方法

profiler.setup(name)是对信息的采集,对性能统计有作用
setup_app_middleware()同样是通过stevedore.DriverManager进行中间件的导入

到此基本上整个keystone便启动了~

openstack Rocky系列之keystone:(一)keystone的启动的更多相关文章

  1. openstack Rocky系列之keystone:(二)keystone中API注册

    主要说一下initialize_application中的application_factory def loadapp(): app = application.application_factor ...

  2. OpenStack实践系列②认证服务Keystone

    OpenStack实践系列②认证服务Keystone 三.实战OpenStack之控制节点3.1 CentOS7的时间同步服务器chrony 下载chrony # yum install -y chr ...

  3. OpenStack组件系列☞Keystone搭建

    一:版本信息 官网:http://docs.openstack.org/newton/install-guide-rdo/keystone.html 二:部署keystone 官网文档:http:// ...

  4. OpenStack组件系列☞Keystone

    Keystone(OpenStack Identity Service)是 OpenStack 框架中负责管理身份验证.服务规则和服务令牌功能的模块.用户访问资源需要验证用户的身份与权限,服务执行操作 ...

  5. openstack安装记录(二)keystone安装

    先决条件 在你配置 OpenStack 身份认证服务前,你必须创建一个数据库和管理员令牌. 完成下面的步骤以创建数据库: 用数据库连接客户端以 root 用户连接到数据库服务器: $ mysql -u ...

  6. openstack项目【day23】:keystone组件基础

    本节内容 一 什么是keystone 二 为何要有keystone 三 keystone的功能 四 keystone概念详解 五 keystone内包含的组件 六 keystone与openstack ...

  7. openstack项目【day24】:keystone部署及操作

    阅读目录 一 前言 二 版本信息 三 部署keystone 四 keystone操作 五 验证 六 创建脚本 七 keystone使用套路总结 一 前言 任何软件的部署都是没有技术含量的,任何就部署讲 ...

  8. [ Openstack ] OpenStack-Mitaka 高可用之 认证服务(keystone)

    目录 Openstack-Mitaka 高可用之 概述    Openstack-Mitaka 高可用之 环境初始化    Openstack-Mitaka 高可用之 Mariadb-Galera集群 ...

  9. OpenStack实践系列⑨云硬盘服务Cinder

    OpenStack实践系列⑨云硬盘服务Cinder八.cinder8.1存储的三大分类 块存储:硬盘,磁盘阵列DAS,SAN存储 文件存储:nfs,GluserFS,Ceph(PB级分布式文件系统), ...

随机推荐

  1. LoadRunner脚本编写之二

    LoadRunner脚本编写之二 编程基本语法必须要记牢.程序的思想也很重要. 下面来回顾一下嵌套循环例子. Action() {     int  i,j;   //生命两个变量     for ( ...

  2. 关于 About

    关于我 我是 Ivy,目前武汉大学 GIS 专业在读硕士研究生,业余渣程序媛. 写了一些不起眼的代码(参看我的 GitHub),做了一些不起眼的小研究(参看我的 ResearchGate). 关于本站 ...

  3. php文件夹上传下载控件分享

    用过浏览器的开发人员都对大文件上传与下载比较困扰,之前遇到了一个php文件夹上传下载的问题,无奈之下自己开发了一套文件上传控件,在这里分享一下.希望能对你有所帮助. 以下是实例的部分脚本文件 这里我先 ...

  4. 表视图为Group类型的注意问题

    使用group类型的tableview时,第一个section距离navigationbar的距离很大,不符合这边的设计图. 使用 myTableView . sectionHeaderHeight  ...

  5. IntelliJ IDEA 2018 for Mac专业使用技巧

    IntelliJ IDEA 2018 for Mac是一个综合性的Java编程环境,被许多开发人员和行业专家誉为市场上最好的IDE,它提供了一系列最实用的的工具组合:智能编码辅助和自动控制,支持J2E ...

  6. PHP常用的 五种设计模式及应用场景

    设计模式六大原则 开放封闭原则:一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 里氏替换原则:所有引用基类的地方必须能透明地使用其子类的对象. 依赖倒置原则:高层模块不应该依赖低层模块,二者 ...

  7. C# AE 通过要素类工作空间将shp路径string类型对象转换为IFeatureClass;

    IWorkspaceFactory pWorkspaceFactory = new ShapefileWorkspaceFactoryClass();//打开shapefile工作空间openFile ...

  8. SQLite扫描

    SQLite的扫盲 SQLite的是一种嵌入式数据库,它的数据库就是一个文件.由于SQLite的本身是Ç写的,而且体积很小,所以经常被集成到各种应用程序中,主要在手机的应用中使用. 之前没有遇到过关于 ...

  9. 【Linux开发】linux设备驱动归纳总结(四):5.多处理器下的竞态和并发

    linux设备驱动归纳总结(四):5.多处理器下的竞态和并发 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  10. mysql事件(event)

    [小结]简单案例 SET GLOBAL event_scheduler=1delimiter $$ create definer = current_user event `test`.`event_ ...