Test Kitchenで自作Ohaiプラグインを使う

前回のエントリでTest KitchenとDocker、Serverspecの設定手順を書きました。
今回は自作Ohaiプラグインを使ったレシピのテストを行う方法です。


何もせずにTest Kitchenで自作Ohaiプラグインを使おうとするとエラーになります。
具体的には自作Ohai変数をテンプレートに埋め込んでいる場合値が空になってしまいます。

色々試行錯誤してみたところ、以下のような設定でうまくいきました。

前提

まず、自作Ohaiプラグインファイルを以下ディレクトリに配置します。

/root/chef/repo/site-cookbooks/centos6/files/default/plugins

/root/chef/repo/site-cookbooks/centos6/までは
筆者のクックブックのパスなのでご自身のパスに読み替えてください。
files/default/plugins以下に配置しておきます。

Test Kitchen設定ファイルの修正

次にTest Kitchenの設定ファイルの修正です。
この.kitchen.ymlファイルは
/root/chef/repo/site-cookbooks/centos6/.kitchen.yml
に配置してあります。ここも適宜読み替えてください。

---
driver:
  name: docker

provisioner:
  name: chef_solo
  solo_rb:
    Ohai::Config[:plugin_path] << : /tmp/kitchen/cookbooks/centos6/files/default/plugins


solo.rb

Ohai::Config[:plugin_path] << : /tmp/kitchen/cookbooks/centos6/files/default/plugins
と追記します。

こうすることでTest Kitchenによって起動したインスタンス内のsolo.rbファイルに
Ohai::Config[:plugin_path] << "/tmp/kitchen/cookbooks/centos6/files/default/plugins"
と追記されます。

確認

実際にTest Kitchenによって起動されたインスタンスにログインを行い状態を確認してみます。

もう一度kitchenコマンドを実行します。

今度は以下のようなオプションを付けます。

kitchen test --destroy=never

通常はテスト後dockerインスタンスは破棄(destroy)されますが
このオプションを付けると破棄されずインスタンスが起動し続けます。


インスタンスの起動状態は

kitchen list

で確認出来ます。

表示例

[root@test centos6]$ kitchen list
Instance           Driver  Provisioner  Last Action
default-centos-65  Docker  ChefSolo     Verified
[root@test centos6]# 



さてインスタンスにログインしてみます。

kitchen login

を実行します。


インスタンスにkitchenユーザでログインすることになります。
パスワードを聞かれますが、ユーザ名と同じkitchenです。

[root@test centos6]# kitchen login
kitchen@localhost's password:

Last login: Thu Jul 31 13:31:11 2014 from 172.17.42.1
[kitchen@7dd079c23c0d ~]$

無事ログイン出来ました。


いよいよsolo.rbを見てみます。
以下のように最終行に追記されていることが確認出来ます。

/tmp/kitchen/solo.rb

node_name "default-centos-65"
checksum_path "/tmp/kitchen/checksums"
file_cache_path "/tmp/kitchen/cache"
file_backup_path "/tmp/kitchen/backup"
cookbook_path ["/tmp/kitchen/cookbooks", "/tmp/kitchen/site-cookbooks"]
data_bag_path "/tmp/kitchen/data_bags"
environment_path "/tmp/kitchen/environments"
node_path "/tmp/kitchen/nodes"
role_path "/tmp/kitchen/roles"
client_path "/tmp/kitchen/clients"
user_path "/tmp/kitchen/users"
validation_key "/tmp/kitchen/validation.pem"
client_key "/tmp/kitchen/client.pem"
chef_server_url "http://127.0.0.1:8889"
encrypted_data_bag_secret "/tmp/kitchen/encrypted_data_bag_secret"
Ohai::Config[:plugin_path] << "/tmp/kitchen/cookbooks/centos6/files/default/plugins"

Test KitchenでDockerとServerspecを使ってChefのレシピをテストする

概要

Test Kitchenの役割

以下を自動でやってくれます。

  1. Dockerコンテナ起動
  2. 起動したDockerコンテナにChefレシピを適用
  3. その後Serverspec実行
  4. Dockerコンテナ破棄


環境

OS

CentOS 6.5

このホストでTest KichenやDockerを動かします。


関連ミドルウェア
事前にインストールしておきます。
バージョンは以下のものを使用しました。

docker-io-1.0.0-6
test-kitchen-1.2.1-1
kitchen-docker-1.5.0-1
serverspec-1.11.0-1



テストするレシピ
CentOS6系のサーバーに適用するレシピです。
/root/chef/repo/site-cookbooks/centos6/recipes/httpd.rb

  • httpdのインストール
  • デーモン起動
  • 自動起動設定

これらを行うレシピをDockerとServerspecでテストします。


事前準備(Test Kitchen)

Test Kitchenを動かすホストで
visudoを実行して以下のように変更します。

Defaults requiretty

Defaults !requiretty

セキュリティ上良くないけどレシピ適用テスト専用ホストだからひとまずよしとする。
これ以外対処法が分からなかった。

これをやらないと、後に実行することになるkitchen testでエラーが出る。

-----> Starting Kitchen (v1.2.1)
>>>>>> ------Exception-------
>>>>>> Class: Kitchen::UserError
>>>>>> Message: You must first install the Docker CLI tool http://www.docker.io/gettingstarted/
>>>>>> ----------------------
>>>>>> Please see .kitchen/logs/kitchen.log for more details
>>>>>> Also try running `kitchen diagnose --all` for configuration

こんなエラー。

.kichen.ymlの作成

テストを行うレシピが入っているクックブックのディレクトリへ移動します。

cd /root/chef/repo/site-cookbooks/centos6/


ディレクトリ移動後、設定ファイルを作成します。
今回はDockerを使用しますのでドライバにkitchen-dockerを指定します。

kitchen init --driver=kitchen-docker


デフォルトで作成される.kichen.yml

---
driver:
  name: docker

provisioner:
  name: chef_solo

platforms:
  - name: ubuntu-12.04
  - name: centos-6.4

suites:
  - name: default
    run_list:
    attributes:


これを今回テストする環境に合わせて修正します。

---
driver:
  name: docker

provisioner:
  name: chef_solo

platforms:
  - name: centos-6.5

suites:
  - name: default
    run_list:
      - recipe[centos6::httpd]
    attributes:


事前準備(Serverspec)

Serverspecのspecファイルを決められたディレクトリに配置します。
こんな感じで置きました。

/root/chef/repo/site-cookbooks/centos6/test/integration/default/serverspec/localhost/httpd_spec.rb


それぞれのディレクトリ名の説明
Chefリポジトリに存在しない場合はmkdirコマンドで作成してください。

/root/chef/repo/site-cookbooks/centos6/
└── test
    └── integration
        └── default
            └── serverspec
                └── localhost
                    ├── httpd_spec.rb

/root/chef/repo/site-cookbooks/centos6/
これは筆者のChefリポジトリファイルを保存しているディレクトリ名なので適宜読み替えてください。


test/integration/
これはデフォルトでこのディレクトリ名が決まっています。


default/
これは先程作成した.kichen.ymlファイルの

suites:
  - name: default

ここと合わせてください。


serverspec/
これはテストライブラリ名と合わせてください。
今回はServerspecを使用するのでserverspecとしています。


最後にhttpd_spec.rbです。
specファイル名は何でもいいのですが、ファイル名は必ず_spec.rbで終わるようにする必要があります。


Serverspecのファイルは以下のようなものを準備しておきます。

require 'serverspec'
include Serverspec::Helper::Exec
include Serverspec::Helper::DetectOS

describe package('httpd') do
  it { should be_installed }
end

describe service('httpd') do
  it { should be_enabled   }
  it { should be_running   }
end

describe port(80) do
  it { should be_listening }
end


Test Kitchen実行

準備が完了したらいよいよテストの実行です。

kitchen test

テストを実行するとコンテナが起動してChefの適用、Serverspecが実行されます。


テストが無事通ると以下のような表示になります。

-----> Starting Kitchen (v1.2.1)
-----> Cleaning up any prior instances of <default-centos-65>
-----> Destroying <default-centos-65>...
(略)
       Finished destroying <default-centos-65> (0m2.43s).
       Finished testing <default-centos-65> (4m39.76s).
-----> Kitchen is finished. (4m39.86s)


これでテスト環境が作成できました!
今後はGitのhookでJenkins経由の実行などを試してみようと思います。