分享

OpenStack中的Oslo.config笔记

xioaxu790 发表于 2014-10-14 21:19:38 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 3 10226
问题导读
1、oslo.config怎么使用呢?
2、如何利用oslo.config和rally模板写一个Python程序?
3、如何在其他project中使用oslo.config?





其实关于oslo.config的使用,在它代码库的oslo.config.cfg.py文件中有很详细的注释说明。但为了避免每次都去阅读一遍(而且有的用法确实不经常用),还是有选择的做一下笔记,以便查询使用。这个笔记不是关于oslo.config方法的全集,因为有些东西我认为没必要记录的就略去了。

因为oslo.config用了iniparser和argparse,所以最好是对它们有一些理解和掌握。

术语:
本篇对于英文中的options统一翻译成配置项

配置项支持的类型
strings, integers, floats, booleans, lists, 'multi strings' and 'key/value pairs' (dictionary)

配置项的定义
  1. def __init__(self, name, type=None, dest=None, short=None,
  2.              default=None, positional=False, metavar=None, help=None,
  3.              secret=False, required=False,
  4.              deprecated_name=None, deprecated_group=None,
  5.              deprecated_opts=None, sample_default=None):
  6.     """Construct an Opt object.
  7.     The only required parameter is the option's name. However, it is
  8.     common to also supply a default and help string for all options.
  9.     :param name: the option's name
  10.     :param type: the option's type. Must be a callable object that
  11.                  takes string and returns converted and validated value
  12.     :param dest: the name of the corresponding ConfigOpts property
  13.     :param short: a single character CLI option name
  14.     :param default: the default value of the option
  15.     :param positional: True if the option is a positional CLI argument
  16.     :param metavar: the option argument to show in --help
  17.     :param help: an explanation of how the option is used
  18.     :param secret: true iff the value should be obfuscated in log output
  19.     :param required: true iff a value must be supplied for this option
  20.     :param deprecated_name: deprecated name option.  Acts like an alias
  21.     :param deprecated_group: the group containing a deprecated alias
  22.     :param deprecated_opts: array of DeprecatedOpt(s)
  23.     :param sample_default: a default string for sample config files
复制代码



如何在其他project中使用oslo.config
配置项操作涉及‘定义’和‘指定’,‘定义’是指说明系统可以使用哪些配置项,一般是在模块开头处进行定义和注册;‘指定’就是确认配置项实际的值,一般是在配置文件或命令行中指定,后出现/解析的值会覆盖前面的值。

只有通过register_cli_opt注册的配置项才能通过命令行指定。

这里需要考虑一种特殊情况,我们需要解析配置文件获取配置项的值,但配置文件的位置在哪?要通过命令行指定,因此默认情况下,oslo自己注册了两个命令行配置项--config-file和--config-dir,这样在程序运行时,就可以直接解析命令行中的配置文件路径,进而解析配置文件中的配置项的值。

在其他project中使用oslo.config的用法如下:
  1. from oslo.config import cfg
  2. opts = [
  3.     cfg.StrOpt('bind_host', default='0.0.0.0'),
  4.     cfg.IntOpt('bind_port', default=9292),
  5. ]
  6. CONF = cfg.CONF
  7. CONF.register_opts(opts)
  8. def start(server, app):
  9.     server.start(app, CONF.bind_port, CONF.bind_host)
复制代码


开始解析(配置文件和命令行)是通过CONF(sys.argv[1:])完成。

配置项定义的特殊用法

不做解释,直接看示例即可:
  1. opts = [
  2.     cfg.StrOpt('state_path',
  3.                default=os.path.join(os.path.dirname(__file__), '../'),
  4.                help='Top-level directory for maintaining nova state.'),
  5.     cfg.StrOpt('sqlite_db',
  6.                default='nova.sqlite',
  7.                help='File name for SQLite.'),
  8.     cfg.StrOpt('sql_connection',
  9.                default='sqlite:///$state_path/$sqlite_db',
  10.                help='Connection string for SQL database.'),
  11.     cfg.StrOpt('service_name', required=True),
  12.     cfg.StrOpt('s3_store_access_key', secret=True),
  13. ]
复制代码



Sub-Parsers
其实Sub-Parsers是argparser中的概念,可以参见argparser的官方文档或我之前的一篇博客做一些了解。oslo.config中使用SubCommandOpt实现Sub-Parsers。
  1. >>> def add_parsers(subparsers):
  2. ...     list_action = subparsers.add_parser('list')
  3. ...     list_action.add_argument('id')
  4. ...
  5. >>> conf = ConfigOpts()
  6. >>> conf.register_cli_opt(SubCommandOpt('action', handler=add_parsers))
  7. True
  8. >>> conf(args=['list', '10'])
  9. >>> conf.action.name, conf.action.id
  10. ('list', '10')
复制代码



以Rally为例

rally最开始的使用仅限于命令行,现在在慢慢做成服务。也就是说,之前通过命令行使用时,每一次执行都会进行解析操作,效率是非常低的,所以现在在做成服务。

如果你自己用Python想写一个命令行程序,程序依赖于配置文件,程序提供多层次命令,你不用再费劲使用iniparser和argparser自己组装,oslo.config和rally无疑提供了一个很好的模板。
  1. from oslo.config import cfg
  2. CONF = cfg.CONF
  3. categories = {
  4.     'deployment': deployment.DeploymentCommands,
  5.     'info': info.InfoCommands,
  6.     'show': show.ShowCommands,
  7.     'task': task.TaskCommands,
  8.     'use': use.UseCommands,
  9.     'verify': verify.VerifyCommands
  10. }
  11. parser = lambda subparsers: _add_command_parsers(categories, subparsers)
  12. category_opt = cfg.SubCommandOpt('category',
  13.                                  title='Command categories',
  14.                                  help='Available categories',
  15.                                  handler=parser)
  16. CONF.register_cli_opt(category_opt)
  17. cfg.CONF(argv[1:], project='rally', version=version.version_string())
复制代码

解析时,首先是解析配置文件,然后解析命令行参数(就是category_opt)。

已有(3)人评论

跳转到指定楼层
sheldon 发表于 2015-1-21 11:37:51
opts = [
    cfg.StrOpt('bind_host', default='0.0.0.0'),
    cfg.IntOpt('bind_port', default=9292),
]
在这里定义的bind_host, bind_port,会被配置文件的设置覆盖掉,是吗?
回复

使用道具 举报

langke93 发表于 2015-1-21 12:11:51
sheldon 发表于 2015-1-21 11:37
opts = [
    cfg.StrOpt('bind_host', default='0.0.0.0'),
    cfg.IntOpt('bind_port', default=9292) ...
一般程序都有这么个规则,程序定义覆盖配置文件,不确定自己也可以坐下测试
回复

使用道具 举报

sheldon 发表于 2015-1-22 13:56:31
我的问题没有意义,我糊涂了。opts这个变量是定义的缺省值,配置文件里的定义,应该是要覆盖opts里的缺省值的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条