最近在重寫公司的Cinder Driver,咱們driver是按照OpenStack的要求,依賴一個叫oslo_config的一個包。這個包的做用就是讓driver申明所依賴的選項(能夠來自文件,也能夠來自命令行),oslo_config負責讀取文件,並加載。html
具體的使用能夠參考:python
http://www.giantflyingsaucer.com/blog/?p=4822git
或者:github
http://docs.openstack.org/developer/oslo.config/cfg.html測試
安裝oslo_config: ui
sudo pip install oslo_config
重寫是把新的代碼放到與原來代碼的文件和目錄裏面,因此在一段時間內是,兩份代碼都會在Cinder的目錄裏面。新的driver全部option是不變的,因而我把原來的代碼拷貝過來,而後小改了下,注意這裏的小改,後面會debug我一天的時間!!!spa
首先,重構前的代碼是這樣的:命令行
cfg.StrOpt('storage_vnx_pool_names', deprecated_name='storage_vnx_pool_name', help='Comma-separated list of storage pool names to be used.'),
改動的地方是把「to be used」去掉,其實保持不變,由於我以爲比較冗餘...debug
改爲了code
cfg.StrOpt('storage_vnx_pool_names', deprecated_name='storage_vnx_pool_name', help='Comma-separated list of storage pool names.'),
而後個人悲劇就開始了:
跑UT的時候 一直報:
oslo_config.cfg.DuplicateOptError: duplicate option: storage_vnx_pool_names
通過不斷的分析,發現oslo_config是重寫了 __eq__和__ne__來判斷兩個選項是否同樣,以下:
# oslo_config/cfg.py def _is_opt_registered(opts, opt): """Check whether an opt with the same name is already registered. The same opt may be registered multiple times, with only the first registration having any effect. However, it is an error to attempt to register a different opt with the same name. :param opts: the set of opts already registered :param opt: the opt to be registered :returns: True if the opt was previously registered, False otherwise :raises: DuplicateOptError if a naming conflict is detected """ if opt.dest in opts: if opts[opt.dest]['opt'] != opt: raise DuplicateOptError(opt.name) return True else: return False
紅色就是拋出這個ERROR的地方
# oslo_config/cfg.py class Opt(object): ...
def __ne__(self, another): return vars(self) != vars(another)
def __eq__(self, another):
return vars(self) == vars(another)
我寫了一個測試(代碼在github 上)vars是如何進行比較的,dump下的數據以下:
(Pdb) print vars(self) {'deprecated_for_removal': False, 'short': None, 'name': 'enable', 'dest': 'enable', 'required': False, '_logged_deprecation': False, 'sample_default': None, 'deprecated_opts': [], 'positional': False, 'default': False, 'secret': False, 'deprecated_reason': None, 'mutable': False, 'type': Boolean, 'metavar': None, 'help': 'True enables, False disables'} (Pdb) print vars(another) {'deprecated_for_removal': False, 'short': None, 'name': 'enable', 'dest': 'enable', 'required': False, '_logged_deprecation': False, 'sample_default': None, 'deprecated_opts': [], 'positional': False, 'default': False, 'secret': False, 'deprecated_reason': None, 'mutable': False, 'type': Boolean, 'metavar': None, 'help': 'True enables, False disables.'}
注意紅色的東西,下面的少了一個句號,因而會返回不相等. 我就是由於改了help裏面的東西,因此oslo_config直接認爲我在兩個不一樣的option使用了同一個名字.
如今拋出這個錯誤的緣由也很明確了,把兩個地方的cfg.StrOpt改爲徹底同樣的就能夠了。
http://docs.openstack.org/developer/oslo.config/cfg.html
http://www.giantflyingsaucer.com/blog/?p=4822