前言:

最近在重写公司的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. 快速入门Http协议

    本节主要讲解http协议相关的内容,作为后期讲述的一个预备知识.深入了解Http协议,对你今后的JavaSE,JavaEE学习都大有裨益,本节难度不是很大,却很重要. 早期的Http协议是1.0版本的 ...

  2. shell编程其实真的很简单(四)

    上篇我们学习了shell中条件选择语句的用法.接下来本篇就来学习循环语句.在shell中,循环是通过for, while, until命令来实现的.下面就分别来看看吧. for for循环有两种形式: ...

  3. salesforce 零基础学习(六十四)页面初始化时实现DML操作

    有的时候我们往往会遇到此种类似的需求:用户在访问某个详细的记录时,需要记录一下什么时候哪个用户访问过此页面,也就是说进入此页面时,需要插入一条记录到表中,表有用户信息,record id,sObjec ...

  4. cordova StatusBar插件的使用(设置手机状态栏颜色和页面头部颜色一致),做出和原生一样的页面效果体验

    cordova StatusBar插件的使用(设置手机状态栏颜色和页面头部颜色一致),做出和原生一样的页面效果体验设置设备状态栏背景颜色StatusBar.backgroundColorByHexSt ...

  5. Android 如何保证service在后台不被kill

    Android 其实无法做多绝对的不被后台kill掉,我们只能尽量使用一些操作提升不被kill的机会. 一.onStartCommand方法,返回START_STICKY   START_STICKY ...

  6. 一个基于POI的通用excel导入导出工具类的简单实现及使用方法

    前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴. ...

  7. Ionic 2 中创建一个照片倾斜浏览组件

    内容简介 今天介绍一个新的UI元素,就是当我们改变设备的方向时,我们可以看到照片的不同部分,有一种身临其境的感觉,类似于360全景视图在移动设备上的应用. 倾斜照片浏览 Ionic 2 实例开发 新增 ...

  8. 《C++ Primer》读书笔记—第二章 变量和基本类型

    声明: 文中内容收集整理自<C++ Primer 中文版 (第5版)>,版权归原书所有. 学习一门程序设计语言最好的方法就是练习编程. 1.8比特的char类型计算机表示的实际范围是-12 ...

  9. [Hadoop] - Protocol Buffer安装

    Hadoop从2.x版本开始,底层的RPC远程调用使用ProtocolBuffer格式来传递数据,所以在编译Hadoop的过程中有可能出现提示缺少Protocol服务的异常信息,类似:'protoc ...

  10. Mysql删除表格之后,进行恢复

    一:存在在PHPmyAdmin下找到表格导出然后再导入 二:当没有备份时,使用binlog功能进行恢复 先进入到/etc/my.cnf文件中. 在文件中添加一句:log-bin=mysql-bin 然 ...