LoginSignup
11
11

More than 5 years have passed since last update.

ぼくのかんがえたCHEF-3694たいさく

Posted at

chefを使っていて地味に困るのはCHEF-3694、同一リソースを複数回いじったときのこの警告です。

もちろん、同じリソースを何の考えもなしに複数回いじるのは問題がありますが、意図的に複数回いじる必要があることもあります。そんなときには、この警告は邪魔者以外の何物でも無い。

というわけで、自分がやっているCHEF-3694対策についてまとめます

2度目だとわかってて実行するとき

途中までの設定を反映するためにサービス再起動が必要だったりとか、意図的に2回実行したい事があります。こういう時のやりかた。

execute_twice
service "httpd" do
  action :restart
end

# いろいろ処理して…

log "httpd-restart-again" do
  level :info
  notifies :restart, "service[httpd]", :immediately
  # notifies(action, resource, timing=:delayed)
end

chefのresourceからは基本的にnotifiesで別のアクションを呼ぶことが出来ます。なので、無害なアクションからnotifiesで呼べば問題なく実行できます。デフォルトのタイミングは:delayedなので、最後でもよい場合は3つめの引数は省略できますが、その場で実行したい場合は:immediatelyをつけます。

過去にやっているか定かではないけど、決まった処理を実行したいとき

主に複数cookbookを実行する場合だと思いますが、apacheのwelcome.confを削除する等、そのリソースに対する処理が決まりきっていて、とにかく1回実行しちゃえば問題ない時にやるやり方。

execute_once_without_warning
resources("file[/tmp/gomi]") rescue file "/tmp/gomi" do
  action :delete
end

notifiesで指定するとき同様に、あるはずのresourceを指定します。このとき、resources()は指定されたものが見つからないと例外が送出されるので、つまり、みつからなかったらここでresourceを定義すれば良いです。

上記のコードだとすっきりしない、もしくはもうちょっといろいろやりたい場合は、Chef::Exceptions::ResourceNotFoundに対して処理をすればOKです。

begin-rescue
service "rsyslog" do
  action :start
end

begin
  resources("service[rsyslog]").nil?
  Chef::Log::info("rsyslog found")
rescue Chef::Exceptions::ResourceNotFound
  Chef::Log::info("rsyslog not found")
end
# output "rsyslog found"

begin
  resources("service[no-such-resource]").nil?
  Chef::Log::info("no-such-resource found")
rescue Chef::Exceptions::ResourceNotFound
  Chef::Log::info("no-such-resource not found")
end
# output "no-such-resource not found"

このやり方だと「xxxを実行済みの場合は、yyyに切り替える」のような処理分岐も出来るようになります。

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