chef:如何修改自动生成的文件

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”食谱。如果我使用 line cookbook - 如何在 nginx cookbook 配方中使用它?

感谢您的回答。

所以,我需要对自动生成的文件执行此逻辑:

    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

答案1

Chef 对于如何做到这一点有自己的看法。您应该在 Chef 中管理整个文件,并将逻辑放在模板中或传递到模板的数据中。无论如何,“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 的编译然后收敛模型,您将尝试在收敛复制之前读取文件。

相关内容