serverspecに手を出してみた
※2014/4/15 追記
ヒアドキュメントによる複数行比較(擬似diff)についてはtagomorisさんの下記がマージされれば使えるようになるはず。
https://github.com/serverspec/serverspec/pull/387
ホストを同じ構成で複数台、且つ構築時期が微妙に違うというものがあるのでそろそろ設定チェック方式を決めないとなあという事情があったのでずっと使おう使おう思ってた、serverspecを使うことにしました。
とりあえずテストを流す上での核となるRakefile/spec_helper.rbをメモ。
1回作るとありがたみをすごく感じます。mizzy さんの素晴らしいツールに感謝しきりです。
OS部分のテストも大体できたので、今後はOracleの設定部分を作っていく予定。
- 参考
http://serverspec.org/
http://rubydoc.info/gems/rspec-core/RSpec/Core/RakeTask#fail_on_error-instance_method
- 試したバージョン
CentOS release 6.5
ruby 1.9.3p545 (2014-02-24 revision 45159) [x86_64-linux] ※2系にあげないとな…
specinfra (0.8.0)
serverspec (0.15.5)
- Rake構成
IPアドレスなどの可変部分を外出ししたかったので、http://serverspec.org/advanced_tips.html の「How to use host specific properties」を基本にしました。
- properties.yml
仮テストなので適当です。
vora: :roles: - ntp - account - network :mngip: 192.168.xxx.xxx
サンプルほぼそのままですが「t.fail_on_error = false」入れて、rspec が failed になっても次のホストに進めるようにしています。
require 'rake' require 'rspec/core/rake_task' require 'yaml' properties = YAML.load_file('properties.yml') desc "Run serverspec to all hosts" task :spec => 'serverspec:all' namespace :serverspec do task :all => properties.keys.map {|key| 'serverspec:' + key.split('.')[0] } properties.keys.each do |key| desc "Run serverspec to #{key}" RSpec::Core::RakeTask.new(key.split('.')[0].to_sym) do |t| ENV['TARGET_HOST'] = key t.fail_on_error = false t.pattern = 'spec/{' + properties[key][:roles].join(',') + '}/*_spec.rb' end end end
- spec_helper.rb
これもサンプルほぼそのままですが、パスワード入力でのsshログインさせる方向のため、ASK_LOGIN_PASSWORD 周りを入れています。
require 'serverspec' require 'pathname' require 'net/ssh' require 'highline/import' require 'yaml' include Serverspec::Helper::Ssh include Serverspec::Helper::DetectOS include Serverspec::Helper::Properties properties = YAML.load_file('properties.yml') if ENV['ASK_LOGIN_PASSWORD'] inputpassword = ask("\nEnter login password: ") { |q| q.echo = false } else inputpassword = ENV['LOGIN_PASSWORD'] end RSpec.configure do |c| c.host = ENV['TARGET_HOST'] set_property properties[c.host] options = Net::SSH::Config.for(c.host) options[:password] = inputpassword user = options[:user] || Etc.getlogin c.ssh = Net::SSH.start(c.host, user, options) c.os = backend.check_os end
- はじめてやる上でハマったことやその他やったことのまとめ
・ファイルの内容を全比較する場合、match_~checksumがベースと思われるがレポートにファイル内容を出すにはファイルの内容をdiffするような形にしたい。its(:content)にガツっと書くのがいいのかな?
・複数テストを用意したときに failed になった場合でも先に進めるようにするにはどーすれば?
→RSpecの「fail_on_error = false」で対応。たどり着くまでずいぶん時間がかかったorz
・Service resource typeで意図的に無効にしたサービスをテストするためにbe_disabledが欲しいと思った
→it { should_not be_enabled } でできる。
が、OSによってはbe_enabledの実装次第で不適切になる可能性はあるので、その時は be_disabled を実装したほうがよいかもしれない。redhat/solarisは実装もすぐできた。
・Rake/RSpec周りがはじめてだったので色々調べながらで手間取った。けど、少しだけRake/RSpecの理解も進んで良かった。…けどまだまだ知らないことばかり。1回Railsアプリ作るしかないか?