Help us understand the problem. What is going on with this article?

Chef の only_if / not_if でハマった。

More than 5 years have passed since last update.

よくよく考えてみると当たり前なのですが、案外ハマる可能性があるかと思ったので共有しておきます。

Chef では、execute リソースや script リソースなどで、どうしても独自でスクリプトを動かしたいときがあると思います。その場合、冪等性は保証されないので、自分でがんばる必要があります。

たとえば、/tmp/to_be_appended/etc/whatever.cfg に追記するという処理をレシピに入れたいとします。実行するたびに追記されたら困るので、追記した内容のうち目印となる文字列を grep してなければ追加する、という条件をいれます。ここでは、追記するファイルに # ADDED があるとします。そこで、最初、私はこういう書き方をしました。

execute "Add a content of /tmp/to_be_appended to /etc/whatever.cfg" do
   command "cat /tmp/to_be_appended >> /etc/whatever.cfg"
   not_if { "grep '# ADDED' /etc/whatever.cfg" }
end

これが動かなくてハマりました。先に答えを言いますと、

execute "Add a content of /tmp/to_be_appended to /etc/whatever.cfg" do
   command "cat /tmp/to_be_appended >> /etc/whatever.cfg"
   not_if "grep '# ADDED' /etc/whatever.cfg"
end

が正解となります。 大事なのはnot_if の後ろの{}です。 only_ifnot_if はブロックも文字列も引数としてとることができます。しかし当然のことながら動きが違うわけです。整理しますと、

  • ブロックの場合は、中身を評価した結果
  • 文字列の場合は、文字列をシェルで実行してその結果(0が成功、それ以外が失敗)

が渡されます。ですので、

    only_if { File.exists?("/path/to/must_exist") }

    only_if "grep httpd /etc/password"

のように使うのが正しい使い方です。

ですので、一番最初に書いたような

    only_if { "grep something /path/to" }

としてしまうと、ブロック内は文字列であるため常に true となってしまいます。これをやってしまうと、only_if だと常に実行され、not_if だと全く実行されません。気をつけましょう。

ああ恥ずかしい。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away