3

私は現在、Chef レシピに取り組んでおり、コードの結果に応じた情報でデータ バッグを更新する必要があります。基本的に、データバッグを成功または失敗で更新する必要があります。

コードは次のようになります。

begin
     node[:fileDeploy].each do |f|
        if f[:deploy]
          cookbook_file "#{f[:subdirectory]}/#{f[:targetFilename]}" do
             owner users['tomcatUser']
             group users['tomcatGroup']
             mode "0755"
             cookbook node[:cookbookName]
             source "#{f[:sourceFilename]}"
          end
        end
     end
     # Update data bag: succeeded
rescue Chef::Exceptions::FileNotFound => e
     # Update data bag: failed
end

問題は、不足しているファイルがあってもレスキュー ブロックが実行されず、それに応じてデータ バッグが更新されないことです。そのため、サーバーでコマンド sudochef-client を実行すると、例外が発生しますが、ブロックChef::Exceptions::FileNotFoundによって処理されません。rescueそれは理にかなっていますか?何か助けはありますか?

4

1 に答える 1

6

例外を発生させるコードが例外ハンドラーのスコープ内で実行されないため、レスキュー ブロックは例外をキャッチしません。

コードでは、リソースを宣言しますcookbook_file。宣言は問題なく行われ、リソースは収束フェーズ中に実行されるようにスケジュールされます。レスキュー ブロックは、リソースが実際に実行されるときではなく、リソースの宣言中に発生する例外をキャッチする可能性があります。

シェフの実行の 2 つのフェーズ、つまりリソー​​ス コレクションの生成とその後の収束について詳しくは、chef-client の実行についてをご覧ください。

目的の結果を得るために、収束中にソース ファイルが存在するという条件を確認し、それに応じて決定することができます。

一般に、Chef ではエラーの処理はかなり困難です。これは設計によるものです。通常、システムは他の部分からかなり独立しているように設計する必要があるためです。したがって、ディレクトリまたはファイルが存在する必要がある場合は、適切なリソースを使用して明示的に作成する必要があります。次に、通知を使用して、現在のリソースが「変更」された場合に特定のアクションを実行するように他のリソースに通知できます (特定のリソースにとってそれが何を意味するかに関係なく)。

以下のコードは、あなたが望むものに似たものを達成しようとします。収束中に例外をキャッチすることはありませんが、最初から例外を発生させようとはしませんが、必要な条件をチェックして適切なリソースを実行します。

node[:fileDeploy].each do |f|
  if f[:deploy]
    cookbook_file "#{f[:subdirectory]}/#{f[:targetFilename]}" do
      owner users['tomcatUser']
      group users['tomcatGroup']
      mode "0755"
      cookbook node[:cookbookName]
      source f[:sourceFilename]
      only_if{ Dir.exist?(File.base_name(f[:sourceFilename]) }
      notifies :run, "execute[success #{f[:sourceFilename]}]", :immediately
    end

    # This one gets notified (and run) when the cookbook_file is successful
    execute "success #{f[:sourceFilename]}" do
      action :nothing
      command "do whatever you like"
    end

    # This one runs only if the created file doesn't exist by now
    execute "error #{f[:subdirectory]}/#{f[:targetFilename]}" do
      action :run
      command "do whatever you like"
      creates "#{f[:subdirectory]}/#{f[:targetFilename]}"
    end
  end
end
于 2013-08-23T17:22:15.697 に答える