3

ノード属性の値を確認したいのですが。このcaseステートメントは私がこれまでに持っているものであり、それは機能します:

case node[:languages][:ruby][:host_cpu]
   when "x86_64"
   ...
   when "i686"
   ...
end

私がやりたいのは、if代わりにステートメントを使用することです。これは私が試したものです:

if node[:languages][:ruby][:host_cpu]?("X86_64")
   ...
end

これは、うまくいった以下に基づいています。

if platform?("ubuntu")
    ...
end

しかし、私の試みはうまくいきませんでした。if予期しないものがあり、予期\nされていたという構文エラーが発生しました$end

を実行するには2種類の方法があることがわかりましたif。1つ目は、上記で示したもので、(明らかに)リソースでのみ機能しif_only、ノードで機能します。そのようです

if_only {node[:languages]} 

これは、ノードの存在をチェックするために、そしてdoコンテキスト内でのみ機能するようです。

ifステートメントを使用してノードの値を確認するにはどうすればよいですか?1つの方法は値をチェックしますが、リソースのみをチェックし、他の方法はノードをチェックしますが、それらの存在のみをチェックし、値はチェックしません。

4

1 に答える 1

8

条件の多くの異なるバリアントを混同していますが、そのほとんどは Ruby ではなく Chef の一部です。さまざまなオプションを 1 つずつ説明してみましょう。

一般に、acaseは一連のifandelsifステートメントにほぼ匹敵します。あなたのcase

case node[:languages][:ruby][:host_cpu]
   when "x86_64"
   ...
   when "i686"
   ...
end

したがって、ほぼ同等です

if node[:languages][:ruby][:host_cpu] == "x86_64"
  ...
elsif node[:languages][:ruby][:host_cpu] == "i686"
  ...
end

余談ですが、case実際には===可換ではないがより強力な演算子を使用しています。単純な比較では、同じように機能し==ます。これらのバリアントは両方とも、クックブックを作成する Ruby 言語の一部です。

あなたが言及した他のオプションは、実際には Chef が Ruby の上に定義した API の一部です。これはしばしば Chef DSL と呼ばれます (これは Domain Specific Language の略です。つまり、言語の拡張または適応であり、この場合は特定の使用ドメイン用の Ruby、この場合は構成管理用です)。

メソッドは、現在platform?のプラットフォームが渡された値の 1 つであるかどうかをチェックする Chef によって定義されたメソッドです。あなたはそれについてもっと読むことができます(そして同様の方法、例えば一般的なレシピplatform_family?のためのシェフのドキュメントで現在推奨されている方法といくつかのよく使われるルビーイディオム.

余談ですが、Ruby ではメソッド名の末尾に?および文字を使用できるという事実に驚かれるかもしれません。これにより、Ruby はこの点で類似の言語の中でも非常にユニークなものになっています。!これらの文字は単にメソッド名の一部であり、言語にとって特別な意味はありません。これらは、メソッドの目的をより適切に識別するために、プログラマーへの慣例によってのみ使用されます。メソッド?の末尾に a がある場合、それは何らかの条件をチェックするために使用され、真または偽の値を返すことが期待されます。!末尾に a を持つメソッドは、多くの場合、潜在的に危険な操作を実行します。たとえば、オブジェクトをその場で変更する、何かを削除するなどです。

あなたが言及した最後のオプションであるonly_ifand by extensionnot_ifは、特定の条件が true の場合 (または false の場合は を使用するnot_if場合) にのみ実行されるように、Chef リソースの条件を定義するために使用されます。これらの属性は Chef リソースでのみ使用されるため、必然的に Chef によっても定義されます。

なぜそれらが役立つのかを理解するには、Chef の実行がどのように機能するかを理解する必要があります。詳細は、Chef Run の解剖学の説明にあります。重要なのは、基本的にリソースのコンパイルと収束という 2 つの実行フェーズがあることです。最初のステップでは、リソースを定義する実際のコードが実行されます。caseここでは、ステートメント内のコードも実行されます。すべてのレシピがロードされ、すべてのリソースが定義された後、Chef は 2 番目のフェーズである収束フェーズに入ります。そこで、変更を実行するリソースの実際の実装 (ファイルとディレクトリの作成、ストール パッケージなど) が実行されます。このフェーズでのみ、only_ifおよびnot_if条件がチェックされます。

実際、次の違いを観察できます。

file "/tmp/helloworld"
  action :create
  content "hello world"
end   

if File.exist?("/tmp/helloworld")
  file "/tmp/foobar"
    action :create
    content "foobar"
  end
end

file "/tmp/helloworld"
  action :create
  content "hello world"
end   

file "/tmp/foobar"
  action :create
  content "foobar"
  only_if{ File.exist?("/tmp/helloworld") }
end

最初のバリアントでは、/tmp/foobarリソースのコンパイル中に条件が存在するかどうかがチェックされます。現時点では、実際に/tmp/helloworldファイルを作成するコードは実行されていません。変換ステップでのみ実行されるためです。したがって、最初の実行時には、/tmp/foobarファイルは作成されません。

ただし、2 番目のバリアントでは、only_if変換中に評価されるチェックが行われます。ここで、最初の実行で両方のファイルが作成されることがわかります。

条件の定義が Ruby の観点からどのように機能するかについてもう少し詳しく読みたい場合は (必ずそうすべきです)、後で実行するために渡すことができる多かれ少なかれコードの断片であるRuby ブロックについて読むことができます。

于 2013-01-05T11:39:16.453 に答える