我必须修改自动生成的nginxconfiguration,基于一些条件:现在在配方我包括模板:
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
然后在模板中,我通过使用正则expression式更改我更改文件内容:
<% 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 %>
`
现在我需要添加另外两个if语句。 如果我这样做,结果文件包含3个相同的网站定义,每个修改不同的if语句。
使用现有文件的最佳方式是什么? 我尝试在文件模板中没有成功的ruby代码,发现“行”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
厨师对如何做到这一点颇有见地。 您应该pipe理Chef中的整个文件,并将逻辑放入模板或传入模板的数据中。 对于什么是值得的,“厨师的方式”将是pipe理整个文件和您调用的File::read
。
在你的情况下,逻辑变得有点复杂,所以我build议你提前计算你想要的,例如
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
然后在你的模板中,只要吐出那个String:
<%= included_sites %>
如果你不pipe理厨师的整个事情,你也可能遇到操作问题的顺序,例如,你要在由厨师复制的文件上调用File::read
,但是由于厨师的编译,那么-converge模型,你会试图在收敛之前读取一个文件。