首先,仍然以compute节点为例,看一下cfg服务的启动过程:
在compute节点的nova-compute服务启动时,调用nova.cmd.compute
中的main
方法。在此之前会执行模块内的CONF = nova.conf.CONF
,其返回的是oslo_config.cfg.ConfigOpts类的实例。
之后我们返回到nova.conf.__init__.py
中,模块初始化时服务把默认的配置项及配置组注册至cfg中,首先举例看conf中group即对应conf文件的section注册流程:
api.register_opts(CONF)
↓ `nova.conf.api`
def register_opts(conf):
conf.register_group(api_group)
conf.register_opts(API_OPTS, group=api_group)
conf.register_opts(deprecated_opts)
↓ `nova.conf.api`
api_group = cfg.OptGroup('api',
title='API options',
help=''
↓ `oslo_config.cfg`
class OptGroup(object):
def __init__(self, name, title=None, help=None):
self.name = name
self.title = "%s options" % name if title is None else title
self.help = help
self._opts = {} # dict of dicts of (opt:, override:, default:)
self._argparse_group = None
↓ `oslo_conf.cfg.ConfigOpts`
def register_group(self, group):
if group.name in self._groups:
return
self._groups[group.name] = copy.copy(group)
api_group
变量值为OptGroup类实例,定义了某option的集合,等同于conf中的 [] section。传入的name=’api’即为section的名称,即conf文件中的[api] section。- register_group(api_group)将api_group的name属性作为key,并copy(api_group)这个实例作为value,存入CONF的_groups字典中,完成此section的注册。
接下来,我们分析section中options的注册流程:
1.常用类型的option,包括string、int、bool、float等,均继承自oslo_config.cfg.Opt类。类初始化方法接受的参数为:
name:option的名称,对应conf文件section下各个option的名称;
type:option值的数据类型,必须是oslo_config.types模块下不同数据类型对应的类的实例。能够接收string,返回转换后且经过验证的值;
dest:CONF中相对应属性名;
short:命令行中option名称的单字母缩写;
default:option的默认值;
positional:是否为命令行中固定位置的argument;
metavar:--help中显示的argument信息;
help:此option的使用帮助信息;
secret:是否不在log中显示相关信息;
required:是否值不能为空;
deprecated_name:option注册时,将覆写的相关option的名称。类似别名;
deprecated_group:别名所在的section,如果不填则代表同option所在一样的section;
deprecated_opts: option注册时,将要覆写的别名信息列表,元素为oslo_config.cfg.DeprecatedOpt类实例;
deprecated_for_removal:标明是否在未来版本中,此项option将会被废弃;
deprecated_reason:对于此项option在未来版本中被废弃的解释;
deprecated_since:标明在哪个未来版本中此项option将会被废弃;
mutable:是否此option可以被重载;
advanced:是否此option是一个高级选项,默认不被大部分用户使用。
2.区分option不同的类型,由初始化中type参数,即oslo_config.types
模块中对应的不同类的实例来实现。在此举string类型的option为例说明:
cfg.StrOpt()
↓
class StrOpt(Opt):
def __init__(self, name, choices=None, quotes=None,
regex=None, ignore_case=None, max_length=None, **kwargs):
super(StrOpt, self).__init__(name,