Назад | Перейти на главную страницу

шеф: Как изменить автоматически созданный файл

Мне нужно изменить автоматически сгенерированную конфигурацию 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.

Как лучше всего работать с существующим файлом? Я безуспешно пробую код рубина в шаблоне файла и нашел "строчную" поваренную книгу. Если я использую поваренную книгу line - как использовать ее в рецепте поваренной книги 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 "компиляция-затем-схождение" вы будете пытаться прочитать файл до того, как сходимость скопирует его.