特定の条件下では、ゼロ以外のステータスコードでChefの実行を中止/終了する必要があります。このコードは、展開チェーンを介して伝播し、最終的にJenkinsに伝播して、大きく太い赤いボールになります。
これを行う最良の方法は何ですか?
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 は、その記述方法を示します。また、利用可能な オープンソースハンドラー のリストも含まれており、次のようなさまざまなサービスに使用できます。
などなど。
Chefの実行を中止または編集する推奨方法は、例外を発生させることです。以下に例を示します。
Ruby_block "some tricky operation" do
block do
OperationFoo
raise "Operation Foo Failed" if some_condition
end
end
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