2013-04-04 43 views
6

我對廚師非常陌生,並試圖找出模板(看起來很酷)。在我舊的部署結構中,我有一個我只是想複製的目錄。它有許多配置參數分散在目錄中的所有文件中。我已經提前嘗試將這些參數抽象爲一個屬性文件(非常乾淨),但是無法與Chef一起安裝。我修改了ERB中所有文件的擴展名,以.erb結尾(我來自Rails背景,所以這對我來說很自然)。例如,我有一個名爲run.conf的文件,它現在名爲run.conf.erb。具有遞歸目錄的廚師模板

理想我想有一個模板塊中剛剛超過目錄中的所有文件拷貝和更新這些.erb文件(去除.erb擴展名)與我公司提供的變量的配方。下面是我在迄今爲止其中一個例子:

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 

我已經把下模板/默認調用服務器文件夾,該文件夾中包含我想模板文件。 #{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 
+0

貴公司的所有文件需要的參數模板或只是幾個? – cmur2 2013-04-04 20:50:39

+0

目前只有幾個,但理想情況下我希望將它們放在一起(那些需要模板化和不需要的模板),因此在將來添加/刪除文件非常容易。 – Jon 2013-04-04 20:52:31

+0

您可能可以使用ruby獲取模板目錄中相對於配方的所有文件。然後,您只需使用'files.each'塊內的'template'資源。 – cassianoleal 2013-04-05 00:16:30

回答

2

你可以定義template_dirruby_block內,而不是在頂部LEVEL-,將工作就好了。

find是Ruby標準庫的一部分,並通過目錄將遞歸走。使用它會導致一些輕微清潔:

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而不是把它變成你的食譜中。兩階段編譯/執行的事情會導致很多不直觀的行爲(比如塊無法查找template_dir),並且因爲編寫LWRP可以讓您驗證輸入,編寫測試,並且更好地確保冪等性。

此外,我對你有'服務器'字符串有點困惑 - 我不知道在什麼環境下,將解決你的templates目錄。在任何情況下,如果你想在你的食譜訪問的所有模板的列表,還有一個陣列可以在這裏找到:run_context.cookbook_collection[cookbook_name].template_filenames