56

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

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

4

5 に答える 5

117

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

Erik Hollensbeは、これが2013年にどのように機能するかについての優れたウォークスルーを書きました。

さて、答えは:

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

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

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

return if 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 platform?('windows')

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

おそらく、Windowsにパッケージマネージャーがあり、このパッケージをインストールする必要があります。レイズの結果、シェフは致命的に終了し、スタックトレースを取得します。

過去数年間、別のアプローチはChef::Application.fatal!、この回答で私が書いたように、を使用することでした。時間は変更されており、これは推奨されません。もうこれをしないでください。それを行っている場合は、に切り替えて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_itemChefサーバー上のデータバッグに対してHTTPリクエストを作成しNet::HTTPServerException、サーバーからの問題(404が見つからない、403が許可されていないなど)がある場合はを返します。再試行するか、他の処理を実行してから、にフォールバックする可能性がありraiseます。

エラーの報告

コマンドラインからChefを実行している場合は、単に終了してスタックトレースを破棄するだけで問題ありません。cronただし、数台、数十台、または数百台のマシンでデーモンとして実行している場合、これは問題が発生したときに健全性を維持するための優れた方法ではありません。

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

ドキュメントには、その書き方が記載されています。また、次のようなさまざまなサービスに使用できる利用可能なオープンソースハンドラーのリストも含まれています。

  • SMTP経由の電子メール
  • IRC
  • 黒鉛
  • HipChat

などなど。

于 2013-01-12T13:58:31.193 に答える
8

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

ruby_block "some tricky operation" do
  block do
    OperationFoo
    raise "Operation Foo Failed" if some_condition
  end
end
于 2013-01-12T04:59:50.713 に答える
2

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
于 2013-05-02T20:35:18.047 に答える
-2

chef何らかのアクションの後で終了したい場合は、以下のステートメントを使用してください。

throw :end_client_run_early

エラーなしで終了します。

于 2018-01-19T09:20:02.440 に答える
-5

chef-soloの実行中に汚れた出口を実行するには、次のことを試してください。

bash 'exit' do
    code 'killall -9 chef-solo'
end
于 2016-02-01T19:44:03.937 に答える