Tags

By year

  1. 2014 (28)

Specinfra を試してみる

Specinfra Serverspec Docker

Posted on Apr 30


はじめに

Serverspec について改めて調査していたら Specinfra という Serverspec のバックエンドで実行しているコマンド群を抜き出した(という認識)ツールを知った。

かなり今更感が否めないが…こちらの資料を拝見して…

OS / ディストリビュージョン毎のコマンドの差異これらを吸収してくれるフレームワーク

という一文(スライドでは二枚分)に「おおっ」と思ったのでとりあえず手を動かすことにした。



参考



Specinfra とは

作者の @gosukenator さんのこちらの記事によると Serverspecconfigspec を作る際に共通する以下の処理を別の gem にしたのが Specinfra のようだ。

  1. ローカルホストの場合は exec リモートホストの場合は SSH 等の実行形式を抽象化した backend と呼ばれているレイヤー
  2. OS ごとに OS に適したコマンドを返す commands と呼ばれているレイヤー
  3. propertiesconfiguration というヘルパーメソッド

3 つ目のヘルパーメソッドについては実行環境に応じた必要な設定を行ってくれる(足りないものがあればエラーとなって注意してくれる)メソッドという認識。(例えば include SpecInfra::Helper::Lxc とすれば lxcgem の有無をチェックしてくれたりと…もちろん、それだけでは無いと思うが)



やってみよー

こちらに倣って試してみたいと思う。


インストール

インストールした環境は MacOS X 10.9 Marvericks に今更の Boxen 経由(!)でインストール。

  ruby::gem { "specinfra for 2.0.0-p247":
    gem     => 'specinfra',
    ruby    => '2.0.0-p247'
  }

上記のように specinfra をインストールするマニフェストを書く。gem install specinfra でもぜんぜんオッケー。


pry から利用してみる

インストールが終わったら早速 pry を起動して Specinfra を利用してみる。

チュートリアルはありませんが、serverspecのソースといつものspec_helper.rbを見れば大体つかめます。

@sawanoboly さんが上記のように書かれているので、手元の serverspec で生成した spec_helper.rb を見てみると SpecInfra の文字が見える。これが Serverspec がバックエンドで Specinfra が動いている証。

require 'serverspec'

include SpecInfra::Helper::Exec
include SpecInfra::Helper::DetectOS

require 'serverspec' とあるが serverspec.rb 内部で requier 'specinfra' とされているのも serverspec のソースから読み取れた。ということで、pry を起動して以下を実行して Specinfra を利用する準備を行う。

準備も整ったところで backend のメソッド達を呼び出してみる。

backend.methods

以下のようにズラズラーと backend で利用出来るメソッド達が表示される。

おお。

では、メソッドの中から run_command なんか試してみたりする。

backend.run_command('pwd')

以下のように pwd コマンドの実行結果を含んだ結果が出力された。

ついでに、先ほどの backend.methods から commands というメソッドを利用して、さらに…

backend.commands.check_running('httpd')

としてみると…以下のように backend.check_running('httpd') を実行する際に裏で実行される OS のコマンドが表示された。

ああ、これが各 OS のコマンドを抽象化しているということなのかな。



私的応用

横領ではなくて応用。まだまだちゃんと Specinfra の事は知らないけど pry から触っていて色々とやりたくなってきたので簡単に試してみた。


ミニマムな私的 Serverspec

適当に構築した Docker コンテナホストに対して Serverspec 的なことを実行してみる。

以下のスクリプトは見ての通り、

  • httpd
  • sshd
  • ntpd

それぞれのプロセスが起動しているかをチェックするもの。

#!/usr/bin/env ruby

require 'specinfra'
require 'net/ssh'

include SpecInfra::Helper::Ssh
include SpecInfra::Helper::DetectOS

SpecInfra.configuration.ssh = Net::SSH.start('localhost', 'sshuser', {:port => '49156', :password => 'sshuser'})

PROCESSES=['httpd','sshd','ntpd']
PROCESSES.each do |process|
  c = backend.check_running("#{process}")
  if "#{c}" == "true"
    puts "#{process} is running"
  else
    puts "#{process} is not running"
  end
end

実行結果は下記の通り。

おお、やっていることはまさに Serverspec そのもの!Serverspec も裏側ではこのようなことが行われている…という認識を持てた。


Backend として docker が使えるようなので…

SpecinfraBackend として以下のような環境が利用出来る。(他にもある)

  • ssh
  • lxc
  • docker
  • shellscript

ということで…試してみた。尚、Backend として docker を利用する場合には docker-apigem が必要になるのでインストールする。

sudo gem install docker-api --no-ri --no-rdoc -V

インストールが終わったら、例のごとく pry ではじめてみる。

require 'specinfra'
require 'docker'

を実行すると…

ふむ。次にヘルパーメソッド(と呼ぶのかな?)を include する。

include SpecInfra::Helper::Docker
include SpecInfra::Helper::RedHat

を実行すると…

次に Docker APIURL を指定してからコンテナイメージを指定する。

Docker.url = 'http://127.0.0.1:4243'
SpecInfra.configuration.docker_image = 'centos'

この状態から backend.methods を叩くと…

ほうほう。では run_command あたりを。

backend.run_command ('ls')

以下のように centos コンテナ内で ls を実行した結果が返ってきた。

おお、今度は install ('httpd') あたりを。

backend.install ('httpd')

以下のようにコンテナ内で Apacheyum install httpd でインストールした結果が返ってきた。

ファンタスティック!

上記のように Specinfra 内で抽象化されたコマンドで Docker コンテナ内に Apache をインストールすることが出来るのを確認した。



さいごに

  • OS のコマンドの違いを抽象化するという考え方にとても共感出来るし、Specinfra はその方法論の一つを具現化したものだと思う
  • Specinfra を触ることで Serverspec が裏側でどんなことをやっているかが少し解った
  • 自分の Ruby 力の低さから用語の使い方や認識に誤りがあると思われるが…も少し触ってみる



2014 かっぱのほげふが