最近在重写公司的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