OpenStack開發基礎-oslo.config


The cfg Module

cfg Module來自於OpenStack中的重要的基礎組件oslo.config,通過cfg Module能夠用來通過命令行或者是配置文件來配置一些options,對於每個選項使用Opt類或者其子類來定義。首先我們來看一個定義option的樣例:

example1:
#!/usr/bin/env python
# encoding: utf-8

from oslo_config import cfg
from oslo_config import types

# 定義了一個類型和范圍
PortType = types.Integer(1,65535)

# 定義一組選項
common_opts = [
    #定義了一個Str類型的選項,名字是bind_host。默認值是0.0.0.0,還有幫助信息
    #用的是Opt的子類來定義的,所以無需指定類類型,由於類型已經定下來了就是Str類型
    cfg.StrOpt('bind_host',default='0.0.0.0',
               help='IP address to listen on.'),
    #使用Opt類來定義一個選項,由於用的是基類。類型能夠是隨意的,所以需要使用type字段明白其類型
    #使用這樣的方式的優點我認為就是能夠定制類型的值范圍
    cfg.Opt('bind_port',
            type=PortType,
            default=9292,
            help="Port number to listen on.")
]

Opt是父類,其下有非常多特定類型的子類。以下是cfg Module支持的一些類型

oslo_config.types.String    
oslo_config.types.Boolean
oslo_config.types.Integer
oslo_config.types.Float
oslo_config.types.List
oslo_config.types.Dict
oslo_config.types.IPAddress

這些類型能夠用於在傳遞給Opt類,定義選型的類型信息,cfg也給我們提供了一系列的特定類型的選項類。能夠直接使用這些類來定義相應類型的選項

oslo_config.cfg.StrOpt
oslo_config.cfg.BoolOpt
oslo_config.cfg.IntOpt
oslo_config.cfg.PortOpt
oslo_config.cfg.FloatOpt
oslo_config.cfg.ListOpt
oslo_config.cfg.DictOpt
oslo_config.cfg.IPOpt

我相信一眼就能夠看出貓膩,所以這里就不解釋了。


cfg Module相同也支持具有多個值的選項。使用oslo_config.cfg.MultiOpt來定義,和oslo_config.cfg.Opt是相對的,前者是支持多個值的選項,后者是支持單個值的在使用MultiOpt類的時候通過設置item_type參數來設置選項的類型。為了方面MultiOpt相同也又很多能夠創建特定類型的子類。請看以下這個樣例:

example2:
#!/usr/bin/env python
# encoding: utf-8

from oslo_config import cfg
from oslo_config import types

DEFAULT_EXTENSIONS = [
    'nova.api.openstack.compute.contrib.standard_extensions'
]

# cfg.MultiOpt的子類用來定義一個多值的選項。值的類型是str
osapi_compute_extension_opt = cfg.MultiStrOpt('osapi_compute_extension',default=DEFAULT_EXTENSIONS)

個人感覺這個和oslo_config.cfg.ListOpt功能差點兒相同。詳細細節咱就不多說了。繼續往下看吧。

Registering Options

上文中定義了非常多的選項。可是離真正使用還差一步,那就是注冊。以下的樣例演示了怎樣去注冊選項和使用選項

example3:
#!/usr/bin/env python
# encoding: utf-8

from oslo_config import cfg
from oslo_config import types

PortType = types.Integer(1, 65535)
#定義一組選項
common_opts = [
    cfg.StrOpt('bind_host',
               default='0.0.0.0',
               help='IP address to listen on.'),
    cfg.Opt('bind_port',
            type=PortType,
            default=9292,
            help='Port number to listen on.')
]
#注冊選項
def add_common_opts(conf):
        conf.register_opts(common_opts)
#使用選項
def get_bind_host(conf):
        return conf.bind_host

def get_bind_port(conf):
        return conf.bind_port

#創建配置類
cf = cfg.CONF
#開始注冊
add_common_opts(cf)
print(get_bind_host(cf))

就是這么簡單。看起來不錯把,也沒有想象中的那么復雜,畢竟僅僅是一個配置類,搞的太復雜誰還用啊,功能再強大我也不會用的。

基於命令行配置選項

上面說了那么多。通過Opt類平配置了選項,設置選項的類型,默認值。然后通過CONF類來注冊選項,最后通過CONF類使用注冊的選項,讀者有沒有認為非常雞肋這不就是定義一個變量,賦值然后使用嘛,這哪是配置選項啊,文章的開頭說了,cfg Module是能夠通過命令行來傳遞配置選項的值,還能夠通過配置文件了來傳遞配置選項的值的,好吧我承認。上面說了那么多事實上都是在講基礎,真正的還沒開始呢,首先還是來分析下cfg Module怎樣通過命令行來配置選項。看以下這個樣例:

example4:
#!/usr/bin/env python
# encoding: utf-8

import sys
from oslo_config import cfg
from oslo_config import types
cli_opts = [
    cfg.BoolOpt('verbose',
                short='v',
                default=False,
                help='Print more verbose output.'),
    cfg.BoolOpt('debug',
                short='d',
                default=False,
                help='Print debugging output.'),
]

def add_common_opts(conf):
        conf.register_cli_opts(cli_opts)

cf = cfg.CONF
add_common_opts(cf);
cf(sys.argv[1:])  #將命令行參數傳遞給CONF類,argv[0]是程序名,所以從1開始

if cf.debug:
    print("開啟調試")
else:
    print("關閉調試")

完了,這個版本號最終不是雞肋了,能夠通過命令行參數來改變verbos和debug兩個選項的值,使用一下把。先help一把,輸出例如以下:

usage: example4.py [-h] [--config-dir DIR] [--config-file PATH] [--debug]
                 [--nodebug] [--noverbose] [--verbose] [--version]

optional arguments:
  -h, --help show this help message and exit
  --config-dir DIR Path to a config directory to pull *.conf files from.
                      This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. The default files used are: None. --debug, -d Print debugging output. --nodebug The inverse of --debug --noverbose The inverse of --verbose --verbose, -v Print more verbose output. --version show program's version number and exit 

尼瑪好多東西啊。事實上僅僅有倒數幾行是我們定義的選項,這里不解釋了,cfg Module幫我們做了非常多設置,比方提供了–nodebug接下來看看怎么設置選項的值把,由於我這里是bool類型,所以直接使用選項–debug就是debug=True。–nodebug就是debug=False。假設什么參數也沒有就是debug=False,簡單吧。

基於配置文件配置選項

事實上也非常easy了,代碼不變。依舊example4部分的代碼,相信有的讀者已經猜到了,由於上面在執行–help的時候出現了–config-file和–config-dir兩個命令行參數這兩個的功能就是用來從配置文件加載配置選項的,前者指定一個配置文件,后者則指定一個文件夾下的全部配置文件。這里提供一個配置文件,通過配置文件來執行一下example4中代碼:

example4.conf
[DEFAULT]
debug=True
verbose=False
通過以下的命令類加載配置
python example4.py --config-file=example4.conf

簡單吧,可是我認為還是有必要解釋一下,DEFAULT是一個默認組。默認情況下Opt定義的選項都是屬於這個組的。cfg Module給配置選項提供了組的概念。不同的組配置選項是能夠反復的。那么讓我們看看怎樣使用配置組吧。

Option Groups

先來一段代碼。看看怎樣使用配置組

#!/usr/bin/env python
# encoding: utf-8
#定義了一個名為rabbit的組,記住組的名字也非常重要,后面會用到
rabbit_group = cfg.OptGroup(name='rabbit',
                            title='RabbitMQ options')

#定義了兩個選項,和上文中說到的定義選項沒有不論什么差別
rabbit_host_opt = cfg.StrOpt('host',
                             default='localhost',
                             help='IP/hostname to listen on.'),
rabbit_port_opt = cfg.PortOpt('port',
                              default=5672,
                              help='Port number to listen on.')
def register_rabbit_opts(conf):
    #通過CONF類來注冊了一個組。(CONF類啥都要先注冊后使用。注冊事實上就是在CONF類內部做解析呢)
    conf.register_group(rabbit_group)
    # options can be registered under a group in either of these ways:
    #注冊選項的時候通過指定組來把選項加入到特定的組中,指定組能夠有例如以下兩種方式,一種就是直接使用OptGroup實例的方式
    #第二種就是使用配置組的名字這里是rabbit
    conf.register_opt(rabbit_host_opt, group=rabbit_group)
    conf.register_opt(rabbit_port_opt, group='rabbit')
#沒提供group就是默認組DEFAULT

之前僅僅有默認組的時候。在命令行使用–debug就會自己主動去DEFAULT組去找,那么如今加入了一個rabbit組,假設要找rabbit組中的host該怎么通過命令行來指定呢這也是非常方便的直接通過前綴來推斷比如–rabbit-host指的就是rabbit組中的host選項。

配置文件句不多說了,定義一個[rabbit]就能夠了,怎樣在代碼中訪問呢,也非常easy。直接使用conf.rabbit.host就能夠了。

Special Handling Instructions

說了這么多,是不是感覺cfg Module有點強大,我也這么認為的,這個部分介紹下cfg Module關於選項提供的一些處理指令吧.

  • 設置必需要輸入的選項值,假設用戶沒有提供就會拋出一個錯誤的異常
    通過在Opt類或者子類中加入required=True這個參數就能夠實現了。

  • 設置選型值不計入日志文件里
    cfg Module提供了一個LOG類。能夠用戶輸入的配置選項的值記錄到日志文件里,可是對於一些敏感的配置選項值還是不要記錄到日志中把。

    能夠通過在Opt類或者子類中加入secret=True這個參數就能夠實現了。

小結

cfg Module還有非常多細節在本篇文章還未涉及到,可是本文的初衷僅僅是由於作者我在分析OpenStack代碼的時候由於對非常多基礎庫不熟悉。導致分析的時候遇到了非常多困難因此有了本文。希望本文帶您入門,至少能夠看懂OpenStack中慣關於配置選項的大部分代碼,那么我認為本文的目的就達到了。

如要想知道很多其它關於oslo.config的知識請參考以下的鏈接。


oslo-config doc


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM