前言:

最近在重写公司的Cinder Driver,我们driver是按照OpenStack的要求,依赖一个叫oslo_config的一个包。这个包的作用就是让driver申明所依赖的选项(可以来自文件,也可以来自命令行),oslo_config负责读取文件,并加载。

具体的使用可以参考:

http://www.giantflyingsaucer.com/blog/?p=4822

或者:

http://docs.openstack.org/developer/oslo.config/cfg.html

安装oslo_config:

sudo pip install oslo_config

问题:

重写是把新的代码放到与原来代码的文件和目录里面,所以在一段时间内是,两份代码都会在Cinder的目录里面。新的driver所有option是不变的,于是我把原来的代码拷贝过来,然后小改了下,注意这里的小改,后面会debug我一天的时间!!!

首先,重构前的代码是这样的:

 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”去掉,其实保持不变,因为我觉得比较冗余...

改成了

 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

oslo_config中的DuplicateOptError坑的更多相关文章

  1. 整理iOS9适配中出现的坑(图文)

    原文: http://www.cnblogs.com/dsxniubility/p/4821184.html 整理iOS9适配中出现的坑(图文)   本文主要是说一些iOS9适配中出现的坑,如果只是要 ...

  2. Nancy总结(二)记一次Nancy 框架中遇到的坑

    记一次Nancy 框架中遇到的坑 前几天,公司一个项目运行很久的Nancy框架的网站,遇到了一个很诡异的问题.Session 对象跳转到另外一个页面的时候,session对象被清空了,导致用户登录不上 ...

  3. 整理 iOS 9 适配中出现的坑(图文)(转)

    作者:董铂然 本文主要是说一些iOS9适配中出现的坑,如果只是要单纯的了解iOS9新特性可以看瞄神的开发者所需要知道的 iOS 9 SDK 新特性.9月17日凌晨,苹果给用户推送了iOS9正式版,随着 ...

  4. 整理 iOS 9 适配中出现的坑

    本文主要是说一些iOS9适配中出现的坑,如果只是要单纯的了解iOS9新特性可以看瞄神的开发者所需要知道的 iOS 9 SDK 新特性.9月17日凌晨,苹果给用户推送了iOS9正式版,随着有用户陆续升级 ...

  5. 整理 iOS 9 适配中出现的坑(图文)

    作者:董铂然 授权本站转载. 本文主要是说一些iOS9适配中出现的坑,如果只是要单纯的了解iOS9新特性可以看瞄神的开发者所需要知道的 iOS 9 SDK 新特性.9月17日凌晨,苹果给用户推送了iO ...

  6. iOS内购(IAP)中的那些坑

    公司的公共库原来并没有这部分的代码,以前做内购是用两个比较有名的github上的第三方库.一个叫MKStoreKit,另一个叫IAPManager,我看了一下写的都很辣鸡,使用起来很不方便,而且写的还 ...

  7. jquery 的 each 方法中 return 的坑

    jquery 的 each 方法中 return 的坑 Chapter 0 在项目中使用 jquery 的 each 方法时想在 each 的循环中返回一个布尔类型的值于是掉进一个坑中... Chap ...

  8. rabbitmq在ios中实战采坑

    1. rabbitmq在ios中实战采坑 1.1. 问题 ios使用rabbitmq连接,没过多久就断开,并报错.且用android做相同的步骤并不会报错,错误如下 Received connecti ...

  9. python中的这些坑,早看早避免。

    python中的这些坑,早看早避免. 说一说python中遇到的坑,躲坑看这一篇就够了 传递参数时候不要使用列表 def foo(num,age=[]): age.append(num) print( ...

随机推荐

  1. java 字符串大小比较

    //java 字符串大小比较 String a="b123"; String b="b124"; String d="b122"; Stri ...

  2. enum 用法

    public enum WeekDay { SUN(, "Sunday", "SUN"), MON(, "Monday", "MO ...

  3. .net core中加载lua脚本的类库: MoonSharp

    前言 MoonSharp是一个支持C#调用lua脚本的类库,支持.net, .net core, mono, unity,因此在.net core中也能够使用,而且加载和调用lua也很方便简单: 官网 ...

  4. MySQL千万级多表关联SQL语句调优

    本文不涉及复杂的底层数据结构,通过explain解释SQL,并根据可能出现的情况,来做具体的优化.   需要优化的查询:使用explain      出现了Using temporary:       ...

  5. vue.js 常用语法总结(一)

    作者:曾萍,目前就职于京东商城. 概述 2016年已经结束了.你是否会思考一下,自己在过去的一年里是否错过一些重要的东西?不用担心,我们正在回顾那些流行的趋势.通过比较过去12个月里Github所增加 ...

  6. 完成OSS.Http底层HttpClient重构封装 支持标准库

    OSS.Http项目对于.Net Standard标准库的支持已经迁移完毕,OSS开源系列两个最底层的类库已经具备跨运行时支持的能力.由于OSS.Http类库是几年前我参照RestSharp的思路,完 ...

  7. 网站SEO,HTTP请求的关键数字----6

    客户端浏览器向服务器请求一个网页素材. 那么网页素材是通过什么方式,什么顺序被下载下来的呢. 我今天做了个简单的测试. 首先,准备测试文件 写一个网页,网页中引用若干的资源文件. 同一文件的不同的参数 ...

  8. Java初学练习答案(循环)

    /* 题目如下: 1 (for 循环)*编程找出四位整数abcd 中满足下述关系的数. (ab+cd)(ab+cd)=abcd 2 (循环)*读入一个整数n,输出如下图形 n = 3 * *** ** ...

  9. FastDFS+Nginx部署详细教程

    本例使用到的所有tar和zip包地址:http://download.csdn.net/detail/corey_jk/9758664 本例中使用CentOS1.CentOS2两台机器实现. 1 GC ...

  10. 使用Python实现子区域数据分类统计

    目录 前言 geopandas简介 子区域数据分类统计 总结 一.前言        最近碰到一个需求,需要统计某省内的所有市的某数据分布情况信息.现有该省的数据分布情况以及该省的行政区划数据.我通过 ...