web-dev-qa-db-ja.com

Chefの実行をどのように中止/終了しますか?

特定の条件下では、ゼロ以外のステータスコードでChefの実行を中止/終了する必要があります。このコードは、展開チェーンを介して伝播し、最終的にJenkinsに伝播して、大きく太い赤いボールになります。

これを行う最良の方法は何ですか?

52

Chefに馴染みがないかもしれないこの質問と回答に将来来る読者のために、Chefの実行はノードを「収束」させるか、実行中のレシピで宣言されたポリシーに合わせてノードをもたらします。これは「収束」とも呼ばれます。これには、「コンパイル」と「実行」の2つのフェーズがあります。コンパイルフェーズでは、シェフがレシピのRubyコードを評価(「コンパイル」)し、リソースコレクションに追加するリソースを探します。それが完了すると、各リソースのアクションを「実行」して、必要な状態にします。システムコマンドなどが実行されます.

Erik Hollensbeは、excellentウォークスルー 2013年の仕組み を書きました。

今、答えは:

ChefレシピはRubyコードであるため、実行方法に応じて、Chefの実行を終了またはChefレシピを終了する方法がいくつかあります。

条件に基づいてレシピの処理を停止し、残りの実行を続行することが目的の場合は、return Rubyキーワードを使用します。例えば:

file '/tmp/ponies' do
  action :create
end

return if node['platform'] == 'windows'

package 'bunnies-and-flowers' do
  action :install
end

システムがWindowsの場合、bunnies-and-flowersパッケージをインストールできるパッケージマネージャーがないため、元の場所から戻ると想定しています。

Chefの実行を完全に中止したい場合

Tl; dr:raiseを使用します。エラー状態の場合、Chefの実行を中止するのがベストプラクティスです。

つまり、実行中に未処理の例外が発生すると、chef-clientは終了します。たとえば、テンプレートリソースがそのソースファイルを見つけられない場合、またはchef-clientを実行しているユーザーがディレクトリを作成するなどの操作を行う権限を持っていない場合です。このため、raiseを使用しても実行を終了できます。

raiseを置く場所が重要です。 Ruby_blockリソースで使用すると、収束の実行段階でのみ発生します。上記のreturnの例のようなリソースの外部で使用すると、コンパイル段階で発生します。

file '/tmp/ponies' do
  action :create
end

raise if node['platform'] == 'windows'

package 'bunnies-and-flowers' do
  action :install
end

おそらくWindowsにパッケージマネージャーがあり、このパッケージをインストールする必要があります。このレイズにより、Chefは致命的に終了し、スタックトレースを提供します。

過去数年間、別のアプローチはChef::Application.fatal!を使用することでした-この答えで私が書いたように。時間が変更され、これはNOT RECOMMENDEDです。もうこれをしないでください。それをしている場合、raiseに切り替えて、前述のように、ニーズがより複雑な場合は独自の例外ハンドラを作成します(以下を参照)。

より優雅なエラー処理

レシピはRubyであるため、begin..rescueブロックを使用してエラー状態を適切に処理することもできます。

begin
  dater = data_bag_item(:basket, "flowers")
rescue Net::HTTPServerException
  # maybe some retry code here?
  raise "Couldn't find flowers in the basket, need those to continue!"
end

data_bag_itemは、Chef ServerでデータバッグのHTTPリクエストを作成し、サーバーに問題がある場合(404が見つからない、403が不正など)Net::HTTPServerExceptionを返します。再試行するか、他の処理を行ってから、raiseにフォールバックすることもできます。

エラーの報告

コマンドラインからChefを実行している場合は、単にスタックトレースを終了してトスするだけで十分です。ただし、cronで実行している場合、または数台、あるいは数十台または数百台のマシンでデーモンとして実行している場合、これは問題がある場合に正気を保つのに最適な方法ではありません。

シェフのレポート/例外ハンドラー機能 と入力します。 Chefの実行にハンドラーを使用できます。すべてのレポートハンドラーは、Chefの実行の最後に実行されます。例外ハンドラは、中断されたChef実行の最後に実行されます。実行のステータスは追跡され、ハンドラーで確認できるため、両方の種類の実行(成功/完了または失敗/中止)を処理するものを作成できます。

documentation は、その記述方法を示します。また、利用可能な オープンソースハンドラー のリストも含まれており、次のようなさまざまなサービスに使用できます。

  • SMTP経由のメール
  • IRC
  • 黒鉛
  • ヒップチャット

などなど。

108
jtimberman

Chefの実行を中止または編集する推奨方法は、例外を発生させることです。以下に例を示します。

Ruby_block "some tricky operation" do
  block do
    OperationFoo
    raise "Operation Foo Failed" if some_condition
  end
end
7

Chef :: Application.fatal!あなたが探していることをすべきです。これが参考になるコードベースの例を示します。

cipher = case key.length
    when 16 then "AES-128-ECB"
    when 24 then "AES-192-ECB"
    when 32 then "AES-256-ECB"
else
    Chef::Application.fatal!("AES Key must be 16, 24, or 32 characters in length but key #{key} has length of #{key.length}")
end
3
John T Dyer