Chef

廚師:如何修改自動生成的文件

  • September 9, 2015

我必鬚根據一些條件修改自動生成的 nginx 配置: 現在在配方中我包含模板:

   template "#{node['nginx']['dir']}/sites-available/#{node['fqdn']}" do
           source 'nginx-site.erb'
           owner  'root'
           group  node['root_group']
           mode   '0600'
           notifies :reload, 'service[nginx]'
   end

然後在模板中我使用正則表達式更改文件內容:

   <% node['nginx']['sites'].each do |site|
           if File::exist?(site['include_path'])
   %>
   <% if not node['nginx']['edperl'] %>
           <%= File::read(site['include_path']) %>
   <% else %>
   <%= File::read(site['include_path']).gsub(/(access_log.*?;)/, '\1' + "\n    set $pseclvl $seclvl;") %>
   <% end -%>
   <%    end
           end
   %>

`

現在我需要再添加 2 個 if 語句。如果我這樣做,結果文件包含 3 個相同的站點定義,每個定義都在不同的 if 語句中修改。

使用現有文件的最佳方法是什麼?我在文件模板中嘗試了沒有成功的 ruby​​ 程式碼,並找到了“line”cookbook。如果我使用 line cookbook - 如何在 nginx 食譜食譜中使用它?

謝謝你的回答。

所以,我需要對自動生成的文件執行此邏輯:

   if node['nginx']['attribute1']
           add to a file line1 after access_log statement
   end
   if node['nginx']['attribute2']
        add to a file line2 after access_log statement
   end
   if node['nginx']['attribute3']
        add to a file line3 after access_log statement
   end

廚師對如何做到這一點頗有意見。您應該在 Chef 中管理整個文件,並將邏輯放在模板中或傳入模板的數據中。對於它的價值,“廚師方式”將是管理整個文件您正在呼叫的文件File::read

在你的情況下,邏輯有點複雜,所以我建議你提前計算你想要的,例如

included_str = ''
node['nginx']['sites'].each do |site|
   next unless ::File::exist?(site['include_path'])

   if not node['nginx']['edperl']
       included_str << File::read(site['include_path'])
   else
       included_str << File::read(site['include_path']).gsub(/(access_log.*?;)/, '\1' + "\n    set $pseclvl $seclvl;") %>
   end

   included_str << "\n"
end

然後在渲染模板時,將其傳入:

template "#{node['nginx']['dir']}/sites-available/#{node['fqdn']}" do
   source 'nginx-site.erb'
   owner  'root'
   group  node['root_group']
   mode   '0600'
   notifies :reload, 'service[nginx]'
   variables(included_sites: included_str)
end

然後在你的模板中,吐出那個字元串:

<%= included_sites %>

如果您不在 Chef 中管理整個事情,您也可能會遇到操作順序問題,例如,您將呼叫File::readChef 複製的文件,但由於 Chef 的 compile-then-converge 模型,您將嘗試在收斂複製文件之前讀取文件。

引用自:https://serverfault.com/questions/720849