HackToday Walk Blog


  • Home

  • Tags

  • Archives

  • Search

ubuntu 14.04 运行devstack

Posted on 2014-05-16

前段时间的ubuntu的14.04的发布,可谓一直就想试试新的用户体验,软件工程师要有尝试新鲜事物的精神是吧,不是“神精”

下载iso,挂载virtualbox的新创建的虚拟机上,

  1. 下载代码
1
git clone https://github.com/openstack-dev/devstack.git

这个是master的branch就是针对openstack Juno的分支

  1. 配置 (根据自己的环境配置相应的***地方)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[[local|localrc]]
ENABLED_SERVICES="$ENABLED_SERVICES,-rabbit,-zeromq,qpid"
ENABLED_SERVICES="$ENABLED_SERVICES,-n-net,q-svc,q-agt,q-dhcp,q-l3,q-meta,q-metering,neutron,tempest"
ADMIN_PASSWORD=***
MYSQL_PASSWORD=***
SERVICE_PASSWORD=$ADMIN_PASSWORD
LOGFILE=$DEST/logs/stack.sh.log
HOST_IP=*****
KEYSTONE_CATALOG_BACKEND=sql
SERVICE_TOKEN=***

QPID_USERNAME=***
QPID_PASSWORD=***

FLOATING_RANGE=***
FIXED_RANGE=***
FIXED_NETWORK_SIZE=**
FLAT_INTERFACE=eth1
NETWORK_GATEWAY=****
PUBLIC_NETWORK_GATEWAY=***
  1. 运行
1
./stack.sh
  1. 执行完毕,openstack的一切服务运行良好

虽然devstack的主页没写支持ubuntu 14.04,但细细想想ubuntu多年前押宝到openstack,作为社区广泛流行的支持OS LTS的版本自然要相当重视,
应该是ubuntu团队对devstack贡献了不少代码,保证发布的14.04完美支持吧

SQL6031N 在 db2nodes.cfg 文件的行号"1" 上出错

Posted on 2014-04-19

问题是来源,迁移云环境后,最初发现keystone的log里,都是SQL链接的错误,很明显是keystone和DB2的通信出现了一点问题,
于是切换到DB2下,发现db2无法正常执行一些简单的命令比如stop,报错

1
SQL6031N 在 db2nodes.cfg 文件的行号 "1" 上出错....

显然错误的原因很明显,那就研究一下这个db2nodes.cfg

查了一下 DB2的官方文档,http://pic.dhe.ibm.com/infocenter/db2luw/v9r7/index.jsp?topic=%2Fcom.ibm.db2.luw.qb.server.doc%2Fdoc%2Fr0006351.html

这里面涉及到了一个hostname配置,也就是说你要是主机名修改了,这个地方原来的配置hostname就会有实效的问题,
这篇blog http://blog.csdn.net/kimmking/article/details/1613430也提到了类似的问题

修改成主机新的hostname后,就没有问题了,如果改成localhost,似乎不行,/etc/hosts 有解析, 不太清楚localhost的问题,改天再研究一下。

追踪无法umount的来源

Posted on 2014-04-19

前段时间执行一个cookbook,发现节点执行完后,每次总是有个路径没有正常umount,于是我就陷入深深的郁闷中,
可是工程师的职责就是解决问题的,别人不帮你解决,那就得自己搞定。

首先,要让完整的异常信息给抛出来,到底是什么原因导致的无法umount
如果你查看过 chef 的代码说明 https://github.com/opscode/chef/blob/master/lib/chef/mixin/shell_out.rb

1
2
shell_out 可是对错误不报警的
shell_out! 绝对不容忍命令执行错误,绝对抛出异常

使用shell_out!, cookbook执行后,把错误面目暴露出来了, device is busy
很显然是某个进程使用这个设备

然后,我们就需要找到哪个进程在用这个device, fuser 或者lsof 就是干这事的,做调查的比如fuser

1
sh -c fuser -m  /tmp/mytest ; ps aux

将上面的命令输出结果在cookbook执行时,打印出来,就可以抓到进程了

最后,上一步既然获得了进程也知道是chef-client在用,那就是cookbook中存在使用目录的情况,后面的就简单了,
一般就是打开文件,没有关闭,或者进入到了要卸载的目录 grep 找到open file的地方,发现有一个地方没有close,就是它了。

Fix问题后,重新运行cookbook,发现所有umoun就顺利完成了,问题就解决了。

不同console下的vim之间的copy

Posted on 2014-04-13

以前都是一个vim下的tabnew或者vsp之前的操作,因为是一个vim实例,所以快捷键copy和cut,paste是没有问题
今天发现不同console下的vim如果按照老套路是不能工作的,也就是说我们需要解决不同vim之间的内容如何copy,cut,paste呢 ?

其实vim的教程里说明了这一点,需要系统剪切板的支持,但是普通的vim,一般系统默认装的可能并不支持,

1
vim --version | grep clipboard

如果输出有:

1
-xterm_clipboard

那么说明你的vim有点弱,需要增强版的vim,
那么可以安装vim-gnome或者vim-gtk
安装后,vim –version, 就会有+xterm_clipboard

那么就尽情的享用快捷命令吧:

“+2yy – copy two lines to X11 clipboard
“+dd – cut line to X11 clipboard
“+p – paste X11 clipboard

具体更多参考:

http://vim.wikia.com/wiki/Accessing_the_system_clipboard

vim来浏览markdown文档

Posted on 2014-04-11

如果没有vim安装相应的插件,看markdown文档会遇到一些高亮无法正常显示的现象,比如引号识别

https://github.com/tpope/vim-markdown/issues/29

这个讨论的了这个问题

要想解决这个问题,就使用 http://calefy.org/2012/03/01/set-vim-markdown-syntax-highlight.html
安装相应的插件

cookbook 引发的 undefined method for {} Hash

Posted on 2014-04-01

在写cookbook的时候,发现strainer test 一直有问题
undefined method `<<’ for {}:Hash

比如network的cookbook在havana中spec_helper.rb是

1
2
# README(galstrom21): This will remove any coverage warnings from dependent cookbooks
ChefSpec::Coverage.filters << '*/openstack-network'

出错的地方,是filters这个地方

调查发现,原来社区的cookbook在icehouse将chefspec的version升级到3.4了
而havana是使用的3.1.4

查看chefspec的ruby class 说明:
chefspec 3.1.4 资料[1]

1
2
3
4
5
# File 'lib/chefspec/coverage.rb', line 16
def initialize
@collection = {}
@filters = []
end

这个是array

chefspec 3.4 资料[2]

1
2
3
4
5
# File 'lib/chefspec/coverage.rb', line 28
def initialize
@collection = {}
@filters = {}
end

已经变为hash了,所以显然如果仅仅更新GemFile,还是基于havana的spec_helper直接运行,那么就会报上面的错误,所以社区已经修改使用了如下的调用

1
ChefSpec::Coverage.start! { add_filter 'openstack-network' }

更多参考可以看社区的 blueprint

  1. http://rubydoc.info/gems/chefspec/3.1.4/frames
  2. http://rubydoc.info/gems/chefspec/ChefSpec/Coverage#filters-instance_method
  3. https://review.openstack.org/#/c/83712/
  4. https://launchpad.net/openstack-chef

ruby的warning: already initialized constant问题

Posted on 2014-03-30

如果使用1.8的ruby,项目编译运行经常会遇到如下的警告

1
warning: already initialized constant

这个就是因为load多次造成,为什么会load多次呢?

http://stackoverflow.com/questions/4532405/what-is-the-right-way-to-initialize-a-constant-in-ruby 给了解释。
比如下面这个测试程序(比如命名machine.rb,这个文件在~/test目录下)

1
2
3
module MyWork
IPADDR = 0x16df
end

我们在另外一个主rb文件(mytestmod.rb,和machine.rb在同一目录下)需要用到上面模块中的常量

1
2
3
4
5
6
7
8
9
10
11
12
require './machine'
require '../test/machine'
class Book
attr_reader :name, :price
def initialize(name, price)
@name = name
@price = price
end

end
book = Book.new('hello world', 120)
puts book.name

注意上面的例子,我们对同一个文件require了两次,如果使用ruby1.8,就会有

1
2
../test/machine.rb:4: warning: already initialized constant IPADDR
hello world

但是ruby1.9,不会出现这个问题

1
hello world

rubocop的规则和rspec的打架和解

Posted on 2014-03-30

rubocop是根据社区流行的ruby编码规范写的一个静态代码分析工具,
rpsec是ruby界流行的BDD测试工具

rpsec里有类似断言的关键字,expect,比如
1)判定某个变量等于123
expect(actual).to eq(123)
2)判断某个boolean值为true
expect(actual).to be true

expect还支持raise,throw错误的断言,采用block方式,如下

1
expect { dosomething }.to  raise_error

介绍了这么多,我们的问题是什么,rubocop里默认有个multi-line规则,就是代码里如果有block 方式 { …},

1
2
3
4
[1, 2, 3].each { |i|
puts i.to_s
...
}

rubocop 会提示上面的例子{.. }的warning,推荐你采用single-line 或者 do .. end的block方式, 采用do.. end 为例

1
2
3
4
[1, 2, 3].each do |i|
puts i.to_s
...
end

但是,实际测试expect断言的block中,很可能长度有超过80字符的长度的时候,那么,就得采取几种方法,避过可恶的rubocop警告

方法1: 在.rubocop.yml文件禁掉Blocks,因为默认的是

1
2
3
4
5
Blocks: 



Enabled: true

这个方法显然是有点过了,因为它会将这个检查对整个代码都生效了,所以不是很好

方法2:使用其他block方式,绕过{}, 比如

1
2
3
4
5
expected = expect do
...
...
end
expected.to raise_error

或者

1
2
3
4
expect do
...
...
end.to raise_error

参考资料:

  1. https://github.com/bbatsov/rubocop#configuration
  2. https://github.com/bbatsov/rubocop/blob/master/config/enabled.yml
  3. http://stackoverflow.com/questions/13274708/how-to-format-multiline-rspec-expect-to-change

chef的文件传输

Posted on 2014-03-23

chef有两类resource支持文件传输,一个是remote_file, 还有一个是cookbook_file,这两个的区别是

如果要传输的文件是放在cookbooks中的file目录下的,那么需要使用cookbook_file,顾名思义,就是文件放在cookbook里
如果要传输的文件是在放在远程的一个地方,那么使用remote_file, 其实这里的远程比较广,支持

1
2
The location (URI) of the source file.
This value may also specify HTTP (http://), FTP (ftp://), or local (file://) source file locations

我们举个简单的使用场景,
比如,你要对机房管理的机器,安装一个软件包,由于内网限制或者没有软件配置源,我们提前把要安装的软件包下载到本地,
然后使用cookbook功能完成传输文件,然后安装, 简单的一个recipe 比如:

1
2
3
4
5
6
7
8
9
10
11
12
cookbook_file "/tmp/test.gem" do
mode 0644
owner 'root'
group 'root'
action :create
end

gem_package "test" do
gem_binary("/opt/chef/embedded/bin/gem")
source "/tmp/test.gem"
action :install
end

如果remote_file,就是需要制定相应的uri,但是需要保证node是可以访问对应的资源的,都算可行的方法

ruby和python的ini纠纷

Posted on 2014-03-09

ruby有两个gem在ini文件的解析处理上用的比较多,一个是inifile,还有另外一个扩展的iniparse

根据 [1]介绍,iniparse相比inifile主要有三个优点
(1) 支持重复option项,这个在一些开源项目的ini文件可以看到
(2)ini 文件写的时候保留空格和缩进行
(3)保持对section和option的顺序

如果你不需要这些功能,iniparse建议你还是inifile吧。

其实 iniparse和inifile在对ini文件的解析上的不同还在约定上有点区别,
(1) = 的区别
比如下面的一个section

1
2
[MYWORK]
test = nice=3

上面的这个形式,iniparse是支持的,会认为 option是test对应的value是, nice=3,
但是inifile就会报错,不支持上面的解析格式

为什么会提到这种写法呢, 这时因为有些ini文件配置的数据库地址
connection = mysql://*?charset=utf-8

显然inifile爱莫能助,因为它的解析中,

1
2
3
4
5
6
7
8
9
10
...

elsif scanner.scan(%r/#{@param}/)
if property.empty?
property = string.strip
string.slice!(0, string.length)
else
parse_error
end
....

第一次, property赋值connection,但是往后解析再次遇到=,他会认为,有两个property存在,所以就parse_error了

(2)对于奇葩的ini混合式写法, ruby的ini解析都有问题
比如,有些python的ini文件,这样写

1
2
3
[composite:metadata]
use = egg:Paste#urlmap
/: meta

采用的是混合式写法,:和=都可以作为分隔符

inifile和iniparse搞不定这个(也许我没找到正确的调用方式,不过inifile的源码好像不支持)
pyhton的ConfigParser可以搞定上面的混合式写法的解析处理

(3)inifile的调用的可选参数

1
2
3
4
5
6
7
8
9
def initialize( content = nil, opts = {} )
opts, content = content, nil if Hash === content
@content = content
@comment = opts.fetch(:comment, ';#')
@param = opts.fetch(:parameter, '=')
@encoding = opts.fetch(:encoding, nil)
@escape = opts.fetch(:escape, true)
@default = opts.fetch(:default, 'global')
@filename = opts.fetch(:filename, nil)

可以看到,默认的comment的是;=两种,所以一些ini文件
比如

1
2
[composite:metadata]
use = egg:Paste#urlmap

如果你不传入 {:comment => ‘;’}, 就会将#urlmap作为注释了
综上,可见ruby和python的ini解析还有有不少坑的

参考资料:

  1. http://www.ruby-doc.org/gems/docs/i/iniparse-1.1.5/README_rdoc.html
  2. http://docs.python.org/2.7/library/configparser.html
1…111213…26

Kai Qiang Wu

This is a place for thinking and writing

253 posts
32 tags
GitHub
© 2020 Kai Qiang Wu
Powered by Hexo
|
Theme — NexT.Gemini v5.1.4
Visitor Total Visit