6

私はChefを初めて使用し、テンプレートを理解しようとしています(これは本当にクールです)。私の古い展開構造には、単純にコピーしたいディレクトリがありました。ディレクトリ内のファイル全体に散在する多くの構成パラメーターがありました。私は先に進んで、これらのパラメーターを属性ファイルに抽象化しようとしましたが (はるかにクリーン)、Chef でのインストールに問題があります。ERB を含むすべてのファイルの拡張子を .erb で終わるように変更しました (私は Rails のバックグラウンドを持っているので、これは自然なことのように思えます)。たとえば、run.conf という名前のファイルがあり、現在は run.conf.erb という名前になっています。

理想的には、ディレクトリ内のすべてのファイルをコピーし、それらの .erb ファイル (.erb 拡張子を削除) を私が提供する変数で更新するだけの 1 つのテンプレート ブロックをレシピに含めたいと考えています。これまでのところ、私がいる場所の例を次に示します。

template "#{node["dcm4chee"]["home"]}" do
  source "server/"
  variables(
    "java_mem_opts" => node["dcm4chee"]["java_mem_opts"],
    "db_username" => node["dcm4chee"]["admin"]["username"],
    "db_password" => node["dcm4chee"]["admin"]["password"],
    "db_hostname" => node["mysql"]["hostname"],
    "db_port" => node["mysql"]["port"]
)
end

template/default の下に server というフォルダーを配置しました。そのフォルダーには、テンプレート化するファイルが含まれています。#{node["dcm4chee"]["home"]} 変数は、ターゲット マシン上のファイルを配置する場所です。理想的には、レシピ内の特定のファイルに名前を付けずにこれを実行したいと考えています。これは、デプロイのためにサーバー ディレクトリの内容を変更する場合にレシピに触れる必要がないためです。

これは可能ですか?もしそうなら、私は何を間違っていますか?そうでない場合、私の代替手段は何ですか。

ありがとう

編集

これについて少し考えた後、カスタム Ruby コードを使用してこれを実行しようとしました。これは、ruby_block 内の最初の呼び出しから tempate_dir を参照する NoMethodError で失敗している私の現在の試みです。

def template_dir(file)
  Dir.foreach("server") do |file|
    if File.file?(file)
      template "#{node["dcm4chee"]["home"]}/#{file}" do
        source "server/#{file}"
          variables(
            "java_mem_opts" => node["dcm4chee"]["java_mem_opts"],
            "db_username" => node["dcm4chee"]["admin"]["username"],
            "db_password" => node["dcm4chee"]["admin"]["password"],
            "db_hostname" => node["mysql"]["hostname"],
           "db_port" => node["mysql"]["port"]
          )
      end
    else
      directory "#{node["dcm4chee"]["home"]}/#{file}" do
        action :create
      end
      template_dir(file)
    end
  end
end

ruby_block "template the whole server directory" do
  block do
    template_dir("server")
  end
end
4

1 に答える 1

2

template_dirトップレベルではなく、内部で定義することもできますruby_block-それはうまく機能します。

findRuby 標準ライブラリの一部であり、ディレクトリを再帰的にウォークスルーします。それを使用すると、少しきれいになります。

ruby_block "recursive templating" do
    block do
        require 'find'
        root = 'server'
        Find.find(root) do |file|
            if File.file?(file)
                template "#{node["dcm4chee"]["home"]}/#{file}" do
                    source file
                    variables(
                        "java_mem_opts" => node["dcm4chee"]["java_mem_opts"],
                        "db_username" => node["dcm4chee"]["admin"]["username"],
                        "db_password" => node["dcm4chee"]["admin"]["password"],
                        "db_hostname" => node["mysql"]["hostname"],
                        "db_port" => node["mysql"]["port"]
                    )
                end
            end
        end
    end
end

一般に、多少複雑なロジックを作成する場合は、レシピに組み込むのではなく、LWRP を作成することを検討する必要があります。2 フェーズのコンパイル/実行は、多くの非直感的な動作 (ブロックが参照できないという事実などtemplate_dir) を引き起こします。これは、LWRP を作成すると、入力を検証し、テストを作成し、冪等性を確保するためのより良い仕事を行うことができるためです。

templatesまた、あなたが持っている「サーバー」文字列について少し混乱しています-どの環境でディレクトリに解決されるかわかりません。いずれにせよ、クックブック内のすべてのテンプレートのリストにアクセスしたい場合は、ここで利用可能な配列があります:run_context.cookbook_collection[cookbook_name].template_filenames

于 2013-10-06T20:44:33.983 に答える