この記事は最終更新から1年以上経過しています。 気をつけてね。
書き換えの対象はJoyent SmartOSでの固有情報を収集するために書いたプラグイン。Ohai本家にプルリクエストして、長い間放置していたもの。
コミットはこのツリー。
provides "joyent"
require_plugin "os"
require_plugin "platform"
if platform == "smartos" then
joyent Mash.new
# get uuid
status, stdout, stderr = run_command(:no_status_check => true, :command => "/usr/bin/zonename")
joyent[:sm_uuid] = stdout.chomp
# get zone id unless globalzone
status, stdout, stderr = run_command(:no_status_check => true, :command => "/usr/sbin/zoneadm list -p | awk -F: '{ print $1 }'")
joyent[:sm_id] = stdout.chomp unless joyent[:sm_uuid] == "global"
# retrieve image name and pkgsrc
if ::File.exist?("/etc/product") then
::File.open("/etc/product") do |file|
while line = file.gets
case line
when /^Image/
sm_image = line.split(" ")
joyent[:sm_image_id] = sm_image[1]
joyent[:sm_image_ver] = sm_image[2]
when /^Base Image/
sm_baseimage = line.split(" ")
joyent[:sm_baseimage_id] = sm_baseimage[2]
joyent[:sm_baseimage_ver] = sm_baseimage[3]
end
end
end
## retrieve pkgsrc
sm_pkgsrc = ::File.read("/opt/local/etc/pkg_install.conf").split("=")
joyent[:sm_pkgsrc] = sm_pkgsrc[1].chomp
end
end
チケットOHAI-458で色々指摘があったので、それも込みで上記のやつをそのままOhai7の書式に書きなおしたのがこちら。
Ohai.plugin(:Joyent) do
%w{ sm_uuid sm_id sm_image sm_image_id sm_image_ver sm_baseimage sm_baseimage_id sm_baseimage_ver sm_pkgsrc }.each do |info|
provides "joyent/#{info}"
end
provides 'virtualization/guest_id'
depends 'os', 'platform', 'virtualization'
def collect_solaris_guestid
command = '/usr/sbin/zoneadm list -p'
so = shell_out(command)
so.stdout.split(':').first
end
def collect_product_file
lines = []
if ::File.exists?("/etc/product")
::File.open("/etc/product") do |file|
while line = file.gets
lines << line
end
end
end
lines
end
def collect_pkgsrc
if File.exist?('/opt/local/etc/pkg_install.conf')
sm_pkgsrc = ::File.read("/opt/local/etc/pkg_install.conf").split("=")
sm_pkgsrc[1].chomp
else
nil
end
end
def is_smartos?
platform == 'smartos'
end
collect_data do
if is_smartos?
joyent Mash.new
# copy uuid
joyent[:sm_uuid] = virtualization[:guest_uuid]
# get zone id unless globalzone
unless joyent[:sm_uuid] == "global"
virtualization[:guest_id] = collect_solaris_guestid
joyent[:sm_id] = virtualization[:guest_id]
end
# retrieve image name and pkgsrc
collect_product_file.each do |line|
case line
when /^Image/
sm_image = line.split(" ")
joyent[:sm_image_id] = sm_image[1]
joyent[:sm_image_ver] = sm_image[2]
when /^Base Image/
sm_baseimage = line.split(" ")
joyent[:sm_baseimage_id] = sm_baseimage[2]
joyent[:sm_baseimage_ver] = sm_baseimage[3]
end
end
## retrieve pkgsrc
joyent[:sm_pkgsrc] = collect_pkgsrc if collect_pkgsrc
end
end
end
同じようでところどころ違いますね。カタマリ単位で再分配した感じ。
ピックアップ解説
require_plugin
はdepends
になった
これは見たままですね。
事前に依存をある程度解決するようになったのかな。
Ohai.plugin(:Joyent)
のブロックで囲んだ
Ohai7で作られたしきたり。とりあえず囲もう。
データ収集をcollect_data
ブロックで囲んだ
def
と明確に分けるのが目的っぽい。
Ohai.plugin
ブロック直下のdef
(メソッド定義)は、collect_data
の中でしか呼べなかった。
例えばif is_smartos?
は2行上ではNo Methodエラー
で動かないんですね。
その他、他のプラグインで収集済みのattributeも、def
内またはcollect_data
内でのみ使えるようです。
Ohai.plugin
直下で使えないのは、誤爆を防いだりするためでしょうかね。
環境依存がある所をメソッドにした
要はファイルや、コマンドラインで結果を取得するものをメソッドにしています。
これは7だからってわけではないのですが、テストの書きやすさに影響しています。この件は次の段落もどうぞ。
本家にPRするため、RSpec
Ohai6で見られた@ohai
を使ったテストが姿を潜め、軒並み@plugin
を使う形式に様変わりしています。
defを別にしたのはここでスタブしやすくするためでもあるようです。
結構ラクにモックを使ったテストができるようになりました。
require 'spec_helper'
describe Ohai::System, "plugin joyent" do
before(:each) do
@plugin = get_plugin('joyent')
end
describe "without joyent" do
before(:each) do
@plugin.stub(:is_smartos?).and_return(false)
end
it "should NOT create joyent" do
@plugin.run
@plugin[:joyent].should be_nil
end
end
describe "with joyent" do
before(:each) do
@plugin.stub(:is_smartos?).and_return(true)
@plugin[:virtualization] = Mash.new
@plugin[:virtualization][:guest_uuid] = "global"
end
it "should create joyent" do
@plugin.run
@plugin[:joyent].should_not be_nil
end
describe "under global zone" do
before(:each) do
@plugin.run
end
it "should ditect global zone" do
@plugin[:joyent][:sm_uuid].should eql 'global'
end
it "should NOT create sm_id" do
@plugin[:joyent][:sm_id].should be_nil
end
end
describe "under smartmachine" do
before(:each) do
@plugin[:virtualization][:guest_uuid] = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx'
@plugin.stub(:collect_solaris_guestid).and_return('30')
@plugin.stub(:collect_product_file).and_return(["Name: Joyent Instance", "Image: base64 13.4.2", "Documentation: http://wiki.joyent.com/jpc2/SmartMachine+Base"])
@plugin.stub(:collect_pkgsrc).and_return('http://pkgsrc.joyent.com/packages/SmartOS/2013Q4/x86_64/All')
@plugin.run
end
it "should retrive zone uuid" do
@plugin[:joyent][:sm_uuid].should eql 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx'
end
it "should collect sm_id" do
@plugin[:joyent][:sm_id].should eql '30'
end
it "should collect images" do
@plugin[:joyent][:sm_image].should_not nil
@plugin[:joyent][:sm_image_id].should_not nil
@plugin[:joyent][:sm_image_ver].should_not nil
end
it "should collect pkgsrc" do
@plugin[:joyent][:sm_pkgsrc].should eql 'http://pkgsrc.joyent.com/packages/SmartOS/2013Q4/x86_64/All'
end
end
end
end
テストもOK。
Ohai::System plugin joyent
without joyent
should NOT create joyent
with joyent
should create joyent
under global zone
should ditect global zone
should NOT create sm_id
under smartmachine
should retrive zone uuid
should collect sm_id
should collect images
should collect pkgsrc
Finished in 0.01159 seconds
8 examples, 0 failures
おわりに
だいたいこの辺を抑えておけば、7書式への移行もスムーズに行くんじゃないかと。