Chef
廚師:如何修改自動生成的文件
我必鬚根據一些條件修改自動生成的 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::read
Chef 複製的文件,但由於 Chef 的 compile-then-converge 模型,您將嘗試在收斂複製文件之前讀取文件。