LoginSignup
6
6

More than 5 years have passed since last update.

Test-Kitchenで成果物を作ってローカル保存

Last updated at Posted at 2014-08-13

この記事は最終更新から1年以上経過しています。 気をつけてね。

Test KitchenはChefのCookbookをテストする用途に使うのが一般的です。
が、実際やっていることを要素として抜き出すと次の通りです。

  • テンポラリなインスタンスをつくる
  • プロビジョナで何かする
  • 好きなテストスイート(主にRubyの)でテストする

ということで、『プロビジョナで何かする』のフェーズでパッケージをビルドしてみましょう。

ちなみにChef社が依存ライブラリ込みパッケージのクロスビルド用に保守しているOmnibusも、(便宜上の)バージョン3から内部ではTest-Kitchenを使っています。

サンプルの概要

この記事で使われているコードのリポジトリはこちら: https://github.com/OpsRockin/kitchen-build-example

次表のとおり作ってみました。

対象 余談
導入するプロダクト jemalloc(3.6.0) 手軽だったのでチョイス。(※Ubuntuにはlibjemallocがパッケージであるのは気にしないで。)
ビルドするパッケージ debとrpm Ubuntu14.04とCentOS6.5上で、checkinstallを用いて作成
プロビジョナ Ansible たまには私もAnsible。 (※Chef以外を使うことで、選べるプロビジョナを演出)
テストスイート Serverspec デファクトスタンダード

Ansibleでjemallocのパッケージをビルドして、ついでにインストールしてみた後にServerspecでテストするというのをTest-Kitchenでやってみましょうかと。

解説

この記事で使われているコードのリポジトリはこちら: https://github.com/OpsRockin/kitchen-build-example

まずはGemfileです。

Gemfile
# A sample Gemfile
source "https://rubygems.org"

gem 'test-kitchen'
gem 'kitchen-ansible'
gem 'kitchen-vagrant'

group :integration do
  gem 'serverspec'
end

プロビジョナとしてAnsibleを使うため、kitchen-ansibleが入っています。使い方は割愛、kitchen-ansibleのGithubリポジトリ入門Ansibleあたりを見れば良いと思います。

.kitchen.ymlはこんな感じです、リポジトリには無いけども、コメントを入れておきます。

.kitchen.yml
---
driver:
  name: vagrant
  synced_folders:
    - ["pkg", "/opt/pkg"]  ## ローカルのMacなりと共有するディレクトリ

provisioner:
  name: ansible_playbook   ## kitchen-ansibleを使う設定
  hosts: all
  ansible_verbose: true
  extra_vars:
    build_name: jemalloc
    build_vers: 3.6.0  ## group_varsの内容をここでも上書きOK

platforms:
  - name: ubuntu-14.04
  - name: centos-6.5

suites:
  - name: build  ## パッケージをビルドするだけのSuite、デフォルトのsite.ymlが使われる。
  - name: test   ## パッケージをインストールしてみて、Serverspecを流すSuite
    provisioner:
      playbook: test.yml

この.kitchen.ymlで、VagrantによってVirtualBoxにVMがが作られ、使いたいPlaybookが実行されるという塩梅です。

実行

buildと名前をつけたSuiteを実行するため、kitchen converge buildします。Ubuntu14.04とCentOS6.5でそれぞれ実行されます。

$ kitchen converge build
-----> Starting Kitchen (v1.2.1)
-----> Creating <build-ubuntu-1404>...

-- sinp --

PLAY [all] ********************************************************************        

GATHERING FACTS ***************************************************************        
ok: [localhost]       

TASK: [prepare | debug ] ******************************************************        
ok: [localhost] => {       
    "item": "",        
    "msg": "Hello Ubuntu"       
}       

TASK: [prepare | file path={{build_dir}} state=directory] *********************        
changed: [localhost] => {"changed": true, "gid": 0, "group": "root", "item": "", "mode": "0755", "owner": "root", "path": "/opt/jemalloc", "size": 4096, "state": "directory", "uid": 0}       

TASK: [prepare | apt name=] ***************************************************        
changed: [localhost] => (省略)       

TASK: [prepare | file path=/root/rpmbuild state=directory] ********************        
skipping: [localhost]       

TASK: [prepare | file path=/root/rpmbuild/SOURCES state=directory] ************        
skipping: [localhost]       

TASK: [prepare | yum name=] ***************************************************        
skipping: [localhost]       

       TASK: [jemalloc | get_url url={{source_url}} dest={{build_dir}}/{{source_file}}] *** 
changed: [localhost] => {"changed": true, "dest": "/opt/jemalloc/jemalloc-3.6.0.tar.bz2", "gid": 0, "group": "root", "item": "", "md5sum": "e76665b63a8fddf4c9f26d2fa67afdf2", "mode": "0644", "msg": "OK (338964 bytes)", "owner": "root", "sha256sum": "", "size": 338964, "src": "/tmp/tmp6Lqcyg", "state": "file", "uid": 0, "url": "http://www.canonware.com/download/jemalloc/jemalloc-3.6.0.tar.bz2"}       

TASK: [jemalloc | command tar xaf {{source_file}} chdir={{build_dir}} creates={{build_name}}-{{build_vers}}] ***        
changed: [localhost] => {"changed": true, "cmd": ["tar", "xaf", "jemalloc-3.6.0.tar.bz2"], "delta": "0:00:00.085939", "end": "2014-08-13 15:34:41.330784", "item": "", "rc": 0, "start": "2014-08-13 15:34:41.244845", "stderr": "", "stdout": ""}       

TASK: [jemalloc | command ./configure] ****************************************        
changed: [localhost] => {省略}

TASK: [jemalloc | command make] ***********************************************        
changed: [localhost] => {省略}       

TASK: [jemalloc | command checkinstall -y --nodoc --pakdir={{pkg_dir}}] *******        
changed: [localhost] => {省略}       

PLAY RECAP ********************************************************************        
localhost                  : ok=9    changed=7    unreachable=0    failed=0          

       Finished converging <build-ubuntu-1404> (2m57.43s).

## ここからCnetOS

-----> Creating <build-centos-65>...

-- snip --

       PLAY [all] ******************************************************************** 

       GATHERING FACTS *************************************************************** 
       ok: [localhost]

       TASK: [prepare | debug ] ****************************************************** 
       ok: [localhost] => {
           "msg": "Hello CentOS"
       }

       TASK: [prepare | file path={{build_dir}} state=directory] ********************* 
       changed: [localhost] => {"changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/opt/jemalloc", "size": 4096, "state": "directory", "uid": 0}

       TASK: [prepare | apt name={{item}}] ******************************************* 
       skipping: [localhost]

       TASK: [prepare | file path=/root/rpmbuild state=directory] ******************** 
       changed: [localhost] => {"changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/root/rpmbuild", "size": 4096, "state": "directory", "uid": 0}

       TASK: [prepare | file path=/root/rpmbuild/SOURCES state=directory] ************ 
       changed: [localhost] => {"changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/root/rpmbuild/SOURCES", "size": 4096, "state": "directory", "uid": 0}

       TASK: [prepare | yum name={{item}}] ******************************************* 
       changed: [localhost] => (省略}

       TASK: [jemalloc | get_url url={{source_url}} dest={{build_dir}}/{{source_file}}] *** 
       changed: [localhost] => {"changed": true, "dest": "/opt/jemalloc/jemalloc-3.6.0.tar.bz2", "gid": 0, "group": "root", "md5sum": "e76665b63a8fddf4c9f26d2fa67afdf2", "mode": "0644", "msg": "OK (338964 bytes)", "owner": "root", "sha256sum": "", "size": 338964, "src": "/tmp/tmpcUAwXP", "state": "file", "uid": 0, "url": "http://www.canonware.com/download/jemalloc/jemalloc-3.6.0.tar.bz2"}

       TASK: [jemalloc | command tar xaf {{source_file}} chdir={{build_dir}} creates={{build_name}}-{{build_vers}}] *** 
       changed: [localhost] => {"changed": true, "cmd": ["tar", "xaf", "jemalloc-3.6.0.tar.bz2"], "delta": "0:00:00.097923", "end": "2014-08-13 15:38:54.325594", "rc": 0, "start": "2014-08-13 15:38:54.227671", "stderr": "", "stdout": ""}

       TASK: [jemalloc | command ./configure] **************************************** 
changed: [localhost] => {省略}

       TASK: [jemalloc | command make] *********************************************** 
changed: [localhost] => {省略}

       TASK: [jemalloc | command checkinstall -y --nodoc --pakdir={{pkg_dir}}] ******* 
       changed: [localhost] => {省略}

       PLAY RECAP ******************************************************************** 
       localhost                  : ok=11   changed=9    unreachable=0    failed=0   

       Finished converging <build-centos-65> (3m15.34s).
-----> Kitchen is finished. (7m43.64s)

kitchenコマンドを実行したホストのpkg/にはcheckinstallで作成したパッケージができています。

$ ls pkg/
jemalloc-3.6.0-1.x86_64.rpm jemalloc_3.6.0-1_amd64.deb

Serverspecでテスト

Test-KitchenのVerifyフェーズで、test/以下の内容を実行することができます。ちなみにconverge(Provisioning)とtestと、作る順番はどちらが先でも構いません。

  • 事前のタスクとして、作成済みのパッケージをインストール(rpm or deb)する。
    • これもPlaybookで。
  • パッケージのインストール後に確かめておきたい内容をServerspecで。

スイートtestで実行するPlaybookはこのように直接記述しました。

test.yml
---
- hosts: all
  sudo: yes
  tasks:
    - shell: "ls -1 {{ pkg_dir }}/*.deb | sort -r | head -n 1"
      register: deb_file
      when: ansible_distribution == "Ubuntu"
    - command: dpkg -i {{ deb_file.stdout }}
      when: ansible_distribution == "Ubuntu"
    - shell: "ls -1 {{ pkg_dir }}/*.rpm | sort -r | head -n 1"
      register: rpm_file
      when: ansible_distribution == "CentOS"
    - yum: name={{ rpm_file.stdout }}
      when: ansible_distribution == "CentOS"

で、パッケージインストール後のspecを簡単に記述してみます。

jemalloc_spec.rb
require 'spec_helper'

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

describe command('/usr/local/bin/jemalloc.sh env') do
  it { should return_stdout /^LD_PRELOAD=.+libjemalloc.+/ }
end

そうしたらあとはkitchen verifyです。

$ kitchen verify test
-----> Starting Kitchen (v1.2.1)
-----> Creating <test-ubuntu-1404>...

-- snip --

## Ubuntuで
-----> Running serverspec test suite       
/opt/chef/embedded/bin/ruby -I/tmp/busser/suites/serverspec -S /opt/chef/embedded/bin/rspec /tmp/busser/suites/serverspec/localhost/jemalloc_spec.rb --color --format documentation       

Package "jemalloc"       
  should be installed       

Command "/usr/local/bin/jemalloc.sh env"       
  should return stdout /^LD_PRELOAD=.+libjemalloc.+/       

Finished in 0.08954 seconds       
2 examples, 0 failures       
       Finished verifying <test-ubuntu-1404> (0m1.78s).


## CentOSで

-----> Creating <test-centos-65>...

-- snip --

-----> Running serverspec test suite
       /opt/chef/embedded/bin/ruby -I/tmp/busser/suites/serverspec -S /opt/chef/embedded/bin/rspec /tmp/busser/suites/serverspec/localhost/jemalloc_spec.rb --color --format documentation

       Package "jemalloc"
         should be installed

       Command "/usr/local/bin/jemalloc.sh env"
         should return stdout /^LD_PRELOAD=.+libjemalloc.+/

       Finished in 0.08964 seconds
       2 examples, 0 failures
       Finished verifying <test-centos-65> (0m1.75s).


-----> Kitchen is finished. (9m16.28s)

Ubuntu(deb)、CentOS(rpm)のどちらも、2 examples, 0 failuresと望んだ結果になっていることが確認できました。
これでこのパッケージは期待通りの動きをしてくれそうな気がします。

さいごに

このサンプルではcheckinstallを軽めに扱っているので、そのまま再利用というわけにもいかないでしょう、そのへんは各自の知見の活用しどころだと思います。

例えばこういう形のtest-KitchenをCIなどで自動実行するようにして、作ったパッケージをしれっとpackagecloud.ioなどでホストすれば、自前パッケージのデリバリも楽になるかもしれないですね。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6