生命太过短暂,今日放弃了明天不必须能得到。
随着OpenStack项目的不断发展与完善,OpenStack社区将所有组件中的具有共性的组件剥离出来,并统一放在oslo组件下。oslo中的组件不仅可以在OpenStack项目中使用,也可以单独作为第三方工具包供其他项目使用。oslo.config项目是oslo组件中用于OpenStack配置文件的一个项目。本文首先以Nova项目为例,介绍了oslo.config的用法;然后,根据源码详细分析了其实现原理。
oslo.config用法
定义配置项
本小节以nova组件为例介绍oslo.config组件的用法。首先,要使用oslo.config需要导入该模块,一般地,直接导入oslo.config中的cfg即可。
1 | from oslo_config import cfg |
导入cfg后,需要新建一个表示配置组的OptGroup类,如在Nova中添加api相关配置时可以添加一个api_group类。
1 | api_group = cfg.OptGroup('api', |
api_group表示了一组关于api的配置项,其中,api表示该配置组的名称;title描述了该配置组的标题;help则详细描述了该配置组的作用。
创建了配置组类之后,则需要创建所有的配置项,如在Nova中添加关于api权限相关的配置参数。
1 | auth_opts = [ |
auth_opts配置了一组与api权限等相关的配置项,其中有String和Bool类型的配置项,通过分别创建StrOpt对象和BoolOpt对象设置参数的类型。
创建配置项之后,则需要将所有配置项都注册到配置组中,如在Nova中将auth_opts等配置项注册到api_group配置组中。
1 | API_OPTS = (auth_opts + |
其中,调用register_opts(API_OPTS, group=api_group)表示将与api相关的配置项注册到api_group配置组中;register_group(api_group)表示将api_group配置组与具体的配置文件相关联;而register_opts(deprecated_opts)则将一些不再支持的配置项单独配置。
读取配置文件并使用配置参数
一般,OpenStack组件在启动服务时便加载了配置文件,读取了各配置项;因此如果想要修改的配置信息被应用到服务中需要重启服务。如Nova启动nova-api服务时,会调用nova/cmd/api.py中的main()函数,在main()函数中,首先便会进行读取文件的操作。
1 | config.parse_args(sys.argv) |
而parse_args()函数通过sys.argv中指定的配置项和配置文件中的配置项,读取api相关的配置参数。
1 | def parse_args(argv, default_config_files=None, configure_db=True, |
nova通过导入nova.conf模块,此时会调用nova.conf的init.py文件中的各个register_opt()函数注册所有配置项。然后,调用了Config中的CongifOpts类的call()方法通过命令行参数和配置文件将配置项缓存到配置对象CONF中。之后,只需要在需要用到配置参数的文件中导入CONF对象即可使用其中的配置项。如在Nova中可以使用CONF.api.enable_instance_password读取配置文件中是否允许配置实例密码的配置项。
oslo.config实现原理
本节结合oslo.config的用法详细介绍oslo.config的实现原理。oslo.config项目相对比较简单,其中主要设计到oslo_config目录下的cfg.py和types.py等文件。其中,cfg.py定义了配置类的数据结构和方法等;types.py则封装了OpenStack中各配置项的类型。
要使用oslo.config最重要的便是ConfigOpts类,所以本文首先介绍ConfigOpts类。ConfigOpts类是一个用来提供注册配置组和配置项的配置项管理类,其中包含几个重要的属性,_opts表示所有的配置项,_cli_opts表示所有的命令行配置项,_groups表示所有的配置组,_namespace表示各服务的命名空间;OpenStack服务启动后所有的配置参数都会通过这四个参数保存到内存中。
上面提到启动服务时,会调用ConfigOpts类的call()方法将服务的所有配置项缓存到内存中,其定义如下:
1 | def __call__(self, |
在该方法中,首先将所有配置项清空,然后根据项目名称和版本等信息获取配置文件路径,然后根据命令行参数和配置文件读取服务所有配置信息,并进行合法性校验。
除此之外,ConfigOpts类还定义了register_opt()方法,register_cli_opt()方法和register_group()方法等分别实现注册配置文件或命令行参数的配置项和注册配置组的操作。另外,也提供了unregister_opt()等方法卸载配置项,添加了clear()方法清空ConfigOpts对象中的配置信息。
在ConfigOpts类定义的属性和方法中,用到了两个重要的类:Opt类和OptGroup类。其中,Opt类定义了一个配置项的模板,主要属性包括配置项名称name,配置项类型type,关联的ConfigOpts对象dest,默认值default和帮助信息help等。为了更好的封装配置项,oslo.config针对具体的配置参数类型为Opt继承了一系列子类,包括StrOpt、BoolOpt、IntOpt、FloatOpt、ListOpt、DictOpt、IPOpt、PortOpt、HostnameOpt、HostAddressOpt、URIOpt、MultiOpt、MultiStrOpt、SubCommandOpt、_ConfigFileOpt、_ConfigDirOpt等。OptGroup类则定义了一个配置组的模板,其主要属性包括配置组名称name,配置组描述title,配置组帮助信息help等。ConfigOpts类利用Opt和OptGroup辅助完成配置项的注册和读取等。
在读取配置文件时,oslo.config还定义了ConfigParser类将配置文件中的所有配置项封装为Json数据包便于处理。
最后,oslo.config将所有配置项的数据类型使用ConfigType类进行了封装,定义了各数据类型的类型名称、格式、最大值、最小值、最大长度等;这些数据类型主要包括String、MultiString、Boolean、Number、Integer、Float、Port、List、Range、Dict、IPAddress、Hostname、HostAddress、URI等。在使用时,可以调用call()方法校验读取的参数是否符合类型要求,也可以调用_formatter()方法对配置参数进行格式化操作。
原文链接:https://blog.csdn.net/Bill_Xiang_/article/details/78392616