The HIRO Says

If you smell what The HIRO is cooking!!!

Test Kitchenが想定通り動作しない場合の解決方法

Chef実践入門 ~コードによるインフラ構成の自動化 (WEB+DB PRESS plus)

Chef実践入門 ~コードによるインフラ構成の自動化 (WEB+DB PRESS plus)

ChefとServerspecでテスト駆動開発を試したいと思い、こちらの書籍に記載のあったTest Kitchenを試してみたところ、想定通りに動作せずにハマりました。ハマった箇所2点とその原因および解決策を、下記にまとめます。


このエントリーの前提条件

ツール バージョン
OS Mac OS X 10.9.5
Chef-solo 12.3.0
Knife-solo 0.4.2
Ruby 2.0.0p0
Vagrant 1.7.2
Virtualbox 4.3.24

Provisioningは、Vagrantを経由してVirtualbox上のVMに対して行います。


課題1.CentOS 6.4/6.5でインスタンスが生成できない!

(1)問題
  • "kitchen init"コマンドで生成した".kitchen.yml"ファイルに最初から定義されている"centos-6.4"を使用しようとすると、後述のエラーが発生する。
  • CentOSバージョンを"centos-6.5"へ変更しても、同様のエラーが発生する。


".kitchen.yml"のデフォルト値(必要な箇所のみ)

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

suites:
  - name: default


インスタンス生成前

$ kitchen list
Instance           Driver   Provisioner  Verifier  Transport  Last Action
default-centos-64  Vagrant  ChefSolo     Busser    Ssh        


インスタンス生成時のエラーメッセージ

$ kitchen create default-centos-64
(中略)
Couldn't open file <ワーキングディレクトリ>/.kitchen/kitchen-vagrant/-default-centos-64/centos-6.4
>>>>>> ------Exception-------
>>>>>> Class: Kitchen::ActionFailed
>>>>>> Message: Failed to complete #create action: [Expected process to exit with [0], but received '1'
    ---- Begin output of vagrant up --no-provision --provider virtualbox ----
STDOUT: Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'centos-6.4' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
==> default: Adding box 'centos-6.4' (v0) for provider: virtualbox
    default: Downloading: centos-6.4

STDERR: An error occurred while downloading the remote file. The error message, if any, is reproduced below. Please fix this error and try again.

Couldn't open file <ワーキングディレクトリ>/.kitchen/kitchen-vagrant/-default-centos-64/centos-6.4
 ---- End output of vagrant up --no-provision --provider virtualbox ----
Ran vagrant up --no-provision --provider virtualbox returned 1]
>>>>>> ----------------------
>>>>>> Please see .kitchen/logs/kitchen.log for more details
>>>>>> Also try running `kitchen diagnose --all` for configuration
(2)原因

2015/08/25時点でBentoで配布されているboxは、"centos-6.6"centos-6.4/6.5は配布されていないためエラーとなる。
(参考)https://github.com/test-kitchen/test-kitchen/issues/663

(3)解決策

".kitchen.yml"ファイルのCentOSバージョンを、"centos-6.6"へ変更する。


".kitchen.yml"の修正後の値(必要な箇所のみ)

platforms:
  - name: centos-6.6

suites:
  - name: default


インスタンス生成前

$ kitchen list
Instance           Driver   Provisioner  Verifier  Transport  Last Action
default-centos-66  Vagrant  ChefSolo     Busser    Ssh        


インスタンス生成時(正常終了)

$ kitchen create default-centos-66
          • > Starting Kitchen (v1.4.1)
          • > Creating ...
Bringing machine 'default' up with 'virtualbox' provider... ==> default: VirtualBox VM is already running. [SSH] Established Vagrant instance created. Finished creating (0m4.44s).
          • > Kitchen is finished. (0m5.75s)


インスタンス生成後

$ kitchen list
Instance           Driver   Provisioner  Verifier  Transport  Last Action
default-centos-66  Vagrant  ChefSolo     Busser    Ssh        Created

課題2.Recipeが見つからない!

(1)問題
  • "kitchen converge <インスタンス名>"コマンドで、作成したRecipeを適用しようとすると、下記のエラーが発生する。
ERROR: Running exception handlers
Running handlers complete
ERROR: Exception handlers complete
Chef Client failed. 0 resources updated in 1.24109821 seconds
FATAL: Stacktrace dumped to /tmp/kitchen/cache/chef-stacktrace.out
ERROR: Cookbook  not found. If you're loading config from another cookbook, make sure you configure the dependency in your metadata
FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

Converge failed on instance .
Please see .kitchen/logs/default-centos-66.log for more details
 ------Exception-------
Class: Kitchen::ActionFailed
Message: SSH exited (1) for command: [sh -c '
sudo -E /opt/chef/bin/chef-solo --config /tmp/kitchen/solo.rb --log_level auto --force-formatter --no-color --json-attributes /tmp/kitchen/dna.json
']
(2)原因

Berkshelfが、Berksfileに未定義のcookbookをインスタンスにロードしないように振る舞うため。

インスタンス上のワークディレクトリである"/tmp/kitchen"には、cookbooksディレクトリはあるが、"site-cookbooks"ディレクトリはない。この挙動は、下記の実行時ログからも確認できる。
 INFO -- default-centos-66: Preparing dna.json
 INFO -- default-centos-66: Resolving cookbook dependencies with Berkshelf 3.3.0...
 INFO -- default-centos-66: Removing non-cookbook files before transfer
 INFO -- default-centos-66: Preparing data_bags
 INFO -- default-centos-66: Preparing environments
 INFO -- default-centos-66: Preparing nodes
 INFO -- default-centos-66: Preparing roles
 INFO -- default-centos-66: Preparing solo.rb

(3)解決策
  1. Berkshelfに、site-cookbooksを参照するRecipeの情報を追記する。
    1. (参考)cookbook 'config', path: './site-cookbooks/config'
  2. kitchen destroy -> kitchen create -> kitchen convergeをやり直す。
(4)補足

http://stackoverflow.com/questions/27687647/vagrant-chef-cookbook-not-found
こちらには、「vagrant-berkshelfプラグインが悪さをしているので、これを除去すればよい」との記述がある。しかし今回調査したところ、vagrant-berkshelfプラグインはインストールされていなかった。

$ vagrant plugin list
sahara (0.0.17)
vagrant-omnibus (1.4.1)
vagrant-share (1.1.4, system)

最後に

枯れていない技術に触れる一番の楽しさは、こうした問題の解決策を考え試して、実際に解決していくことにありますね。そのことを改めて痛感。