LoginSignup
13
13

More than 5 years have passed since last update.

Guardでchef-soloを継続実行

Last updated at Posted at 2013-04-22

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

Guardはファイルの変更をチェックして任意のタスクを実行するツール。

この手のものはテストを実行して開発・リファクタリングする用途に使うツールですが、chef-soloとレシピでやってもよいじゃないかと。

概要

さてこれから何をするか

  • Guardに attributes/recipes以下のdefault.rbを監視してもらう。
  • 対象のファイルに変更があったらchef-soloを実行する。
  • ついでにnode.jsonファイルも監視。

このTipを手軽に再現するためにgithubにコードを公開してます。

Guardのインストール

bundlerを使おう、guard-shellはシェルスクリプトを実行する雛形を作るためのプラグインだ。

Gemfile
Gemfile
source "https://rubygems.org"

gem 'chef'
gem 'guard'
gem 'guard-shell'

こんな感じでbundle.

Guard-shellの初期化

guardのサブコマンドで初期化する、shellオプションをつかう。

shell-out
$ guard init shell
14:37:52 - INFO - Guard here! It looks like your project has a Gemfile, yet you are running
14:37:52 - INFO - Writing new Guardfile to /root/github/guard_chefsolo_example/Guardfile
14:37:52 - INFO - shell guard added to Guardfile, feel free to edit it

初期化で作成されたGuardfileには監視対象と実行コマンドの例が書かれている。

Guardfile(sample)
# A sample Guardfile
# More info at https://github.com/guard/guard#readme

# Add files and commands to this file, like the example:
#   watch(%r{file/path}) { `command(s)` }
#
guard 'shell' do
  watch(/(.*).txt/) {|m| `tail #{m[0]}` }
end

ぱっと見で*.txtファイルが更新されたらtailを実行と分かるね。

Chef-soloの準備

chef-solo実行のため必要なファイルを用意します。

solo.rbとnode.json

solo.rb
cookbook_path [
  File.expand_path("../cookbooks", __FILE__)
]
node.json
{}

jsonはrun_listを並べたりattributesをoverrideするので空ですがひとまず作成。

Guardfileへの反映

適当なCookBookとしてsandboxというのを作ります、github参照。

Guardfile
guard 'shell' do
  watch('cookbooks/sandbox/attributes/default.rb') { `chef-solo -c solo.rb -j node.json` }
end

guard 'shell' do
  watch('cookbooks/sandbox/recipes/defaults.rb') { `chef-solo -c solo.rb -j node.json` }
end

guard 'shell' do
  watch('node.json') { `chef-solo -c solo.rb -j node.json` }
end
end

分かりやすさ重視で3つの単純なルールを作りました、watchのルールは正規表現などでもっと簡潔にかけます。

この時点のファイル状態を1_start@githubというブランチにしています。お試しはcheckoutでどうぞ。

Guard起動と動作チェック

ではguardコマンドを実行します、専用のプロンプトが起動するので別のShellセッションを開いてそちらで。

shell-out(guard)
$ guard 
15:08:01 - INFO - Guard here! It looks like your project has a Gemfile, yet you are running
15:08:01 - INFO - Guard uses NotifySend to send notifications.
15:08:01 - INFO - Guard uses TerminalTitle to send notifications.
15:08:01 - INFO - Guard is now watching at '/root/github/guard_chefsolo_example'
[Listen warning]:
  Listen will be polling for changes. Learn more at https://github.com/guard/listen#polling-fallback.

[1] guard(main)> 

ファイル監視の挙動は環境によります、ここではpollingが選択されました(joyent smartos)。

抜ける時はexitです。

shell-out(guard)
[1] guard(main)> exit
15:22:13 - INFO - Bye bye...

ファイル変更の検知とコマンド実行

早速監視対象のnode.jsonを更新します。

shell-out(main)
$ touch node.json

程なくタスクが実行されます。

shell-out(guard)
[2013-04-22T15:12:34+00:00] INFO: *** Chef 11.4.0 ***
[2013-04-22T15:12:36+00:00] INFO: Run List is []
[2013-04-22T15:12:36+00:00] INFO: Run List expands to []
[2013-04-22T15:12:36+00:00] INFO: Starting Chef Run for ipf_test
[2013-04-22T15:12:36+00:00] INFO: Running start handlers
[2013-04-22T15:12:36+00:00] INFO: Start handlers complete.
[2013-04-22T15:12:36+00:00] INFO: Chef Run complete in 0.005674519 seconds
[2013-04-22T15:12:36+00:00] INFO: Running report handlers
[2013-04-22T15:12:36+00:00] INFO: Report handlers complete
[1] guard(main)> 

node.jsonsandbox::defaultの実行を記述してみます。

node.json
{
  "run_list": [
    "sandbox::default"
  ]
}

エディタで開いて保存すると、またタスクが自動的に実行されます。

shell-out(guard)
[2013-04-22T15:19:33+00:00] INFO: *** Chef 11.4.0 ***
[2013-04-22T15:19:36+00:00] INFO: Setting the run_list to ["sandbox::default"] from JSON
[2013-04-22T15:19:36+00:00] INFO: Run List is [recipe[sandbox::default]]
[2013-04-22T15:19:36+00:00] INFO: Run List expands to [sandbox::default]
[2013-04-22T15:19:36+00:00] INFO: Starting Chef Run for ipf_test
[2013-04-22T15:19:36+00:00] INFO: Running start handlers
[2013-04-22T15:19:36+00:00] INFO: Start handlers complete.
[2013-04-22T15:19:36+00:00] INFO: Chef Run complete in 0.00620992 seconds
[2013-04-22T15:19:36+00:00] INFO: Running report handlers
[2013-04-22T15:19:36+00:00] INFO: Report handlers complete
[1] guard(main)> 

run_list["sandbox::default"]が加わっています。

そしてこの時点のファイル状態を2_run_guard@githubというブランチにしています。こちらもお試しはcheckoutでどうぞ。

Guardに追われるようにレシピを作成する

ではguardを起動させた状態でファイル保存=即コンバージョンという適度な緊張感のなかレシピを書いていきましょう。

この手法でのCookbook開発は危ないのでクラウドIaaSの適当なインスタンスでやりましょう。

fileを作成する

手軽な所でFileリソースをレシピに書いてみます。

cookbooks/sandbox/recipes/default.rb
file "/tmp/cha-ra.txt" do
  content "head-chara"
end

レシピを保存するとGuardによりchef-soloが実行されます。

shell-out(guard)
[2013-04-22T15:42:08+00:00] INFO: *** Chef 11.4.0 ***
-- snip --
[2013-04-22T15:42:10+00:00] INFO: Processing file[/tmp/cha-ra.txt] action create (sandbox::default line 11)
[2013-04-22T15:42:11+00:00] INFO: entered create
[2013-04-22T15:42:11+00:00] INFO: file[/tmp/cha-ra.txt] created file /tmp/cha-ra.txt
-- snip --
[1] guard(main)> 

ちょっとパーミッションを追加してみます。

cookbooks/sandbox/recipes/default.rb
file "/tmp/cha-ra.txt" do
  content "head-chara"
  mode "0600"
end

早速コンバージョンされます。

shell-out(guard)
[2013-04-22T15:45:11+00:00] INFO: *** Chef 11.4.0 ***
-- snip --
[2013-04-22T15:45:14+00:00] INFO: Processing file[/tmp/cha-ra.txt] action create (sandbox::default line 11)
[2013-04-22T15:45:14+00:00] INFO: file[/tmp/cha-ra.txt] mode changed to 600
[1] guard(main)> 
-- snip --

attributesを追加して、recpieに反映

ファイルのコンテンツをattributesで管理するため、attributes/default.rbを作ってみます。

cookbooks/sandbox/attributes/default.rb
default['text_contents'] = 'heno-kappa'

guardが目ざとくchef-soloを走らせますが先ほどと変更がないため何も起こりません。

shell-out(guard)
[2013-04-22T15:50:40+00:00] INFO: *** Chef 11.4.0 ***
-- snip --
[2013-04-22T15:50:43+00:00] INFO: Processing file[/tmp/cha-ra.txt] action create (sandbox::default line 11)
-- snip --
[1] guard(main)> 

ではレシピ側でattributesを使うように変更を入れます。

cookbooks/sandbox/recipes/default.rb
file "/tmp/cha-ra.txt" do
  content node['text_contents']
  mode "0600"
end

chef-soloが実行され、ファイルが更新されました。

shell-out(guard)
[2013-04-22T15:55:15+00:00] INFO: *** Chef 11.4.0 ***
-- snip --
[2013-04-22T15:55:17+00:00] INFO: Processing file[/tmp/cha-ra.txt] action create (sandbox::default line 11)
[2013-04-22T15:55:17+00:00] INFO: file[/tmp/cha-ra.txt] backed up to /var/chef/backup/tmp/cha-ra.txt.chef-20130422155517
[2013-04-22T15:55:17+00:00] INFO: file[/tmp/cha-ra.txt] contents updated
-- snip --
[1] guard(main)> 

最後の状態はmasterブランチです。

おわりに

通常guardwatchrというツールはRSpecChefspecを実行するようにしてテストの手間を減らすものです。

しかしサーバインスタンスの調達も簡単な今日ではOpsによるこのような強引なインフラ開発もいいんじゃないでしょうか。

ついでにこの手法は冪等を意識してレシピを書かないとサーバがどんどん壊れていくはずなのでChef勘が養える...かも。

13
13
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
13
13