使用Chef配方将多行附加到配置文件

时间:2013-06-02 03:22:13

标签: linux chef chef-recipe

我正在尝试创建一个Chef配方,将多行(20-30)附加到特定的配置文件中。

我知道推荐的模式是change entire config files,而不仅仅是附加到文件,但我出于多种原因不喜欢这种方法。

到目前为止,我找到的唯一解决方案是使用cookbook_file,然后使用bash资源执行:

cat lines_to_append >> /path/configfile

显然这不会正常工作,因为每次你运行chef-client时它会反复追加文件。我必须首先创建一个小的bash脚本来检查特定的字符串,然后,如果找不到,则附加到该文件。

但这似乎打败了使用Chef的目的。必须有更好的方法。

一个有希望的解决方案是来自OpsCode社区的line cookbook。它旨在解决这个确切的问题。不幸的是,功能不完整,错误,代码只是一个快速的黑客。远非一个坚实的解决方案。

我评估的另一个选项是augeas。看起来非常强大,但它还为系统添加了另一层抽象。在我的情况下,矫枉过正。

鉴于这是任何系统管理员最明显的任务之一,有什么简单而美观的解决方案与Chef没有见过吗?


编辑:到目前为止,我正在解决这个问题:

 cookbook_file "/tmp/parms_to_append.conf" do
   source "parms_to_append.conf"
 end

 bash "append_to_config" do
   user "root"
   code <<-EOF
      cat /tmp/parms_to_append.conf >> /etc/config
      rm /tmp/parms_to_append.conf
   EOF
   not_if "grep -q MY_IDENTIFIER /etc/config"
 end

它有效,但不确定这是推荐的Chef模式。

5 个答案:

答案 0 :(得分:11)

正如您自己所说,推荐的Chef模式是管理整个文件。

如果您正在使用Chef 11,那么您可能会使用partials来实现您想要实现的目标。

还有更多信息here以及此example cookbook

只要您有权访问原始配置模板,只需将<%= render "original_config.erb" %>添加到parms_to_append.conf模板的顶部即可。

答案 1 :(得分:9)

如前所述,使用模板和partials是常见的方法,但是厨师允许附加文件,甚至更改(编辑)文件行。使用以下函数执行Appendind:

  • insert_line_after_match(regex,newline);
  • insert_line_if_no_match(正则表达式,换行符)

您可以在stackoverflow上找到并示例here,以及rubydoc.info上的完整文档

请谨慎使用,并且仅在部分和模板不合适的情况下使用。

答案 2 :(得分:4)

我做了类似的事情:

monit_overwrites /模板/默认/ monitrc.erb:

#---FLOWDOCK-START
set mail-format { from: monit@ourservice.com }
#---FLOWDOCK-END

在我的食谱中我做到了:

monit_overwrites /食谱/ default.rb:

execute "Clean up monitrc from earlier runs" do
  user "root"
  command "sed '/#---FLOWDOCK-START/,/#---FLOWDOCK-END/d' > /etc/monitrc"
end

template "/tmp/monitrc_append.conf" do
  source "monitrc_append.erb"
end

execute "Setup monit to push notifications into flowdock" do
  user "root"
  command "cat /tmp/monitrc_append.conf >> /etc/monitrc"
end

execute "Remove monitrc_append" do
  command "rm /tmp/monitrc_append.conf"
end

答案 3 :(得分:1)

解决这个问题的最简单方法是创建一个字符串并将其传递给内容。当然bash块工作......但我认为文件资源很优雅。

lines = ""
File.open('input file') do |f|
   f.lines.each do |line|
      lines = lines  + line + "\n"
   end
end
file "file path"  do
   content line
end

答案 4 :(得分:0)

以下是在匹配后插入2行新代码的示例ruby块:

ruby_block "insert_lines" do
  block do
    file = Chef::Util::FileEdit.new("/etc/nginx/nginx.conf")
    file.insert_line_after_match("worker_rlimit_nofile", "load_module 1")
    file.insert_line_after_match("pid", "load_module 2")
    file.write_file
  end
end

insert_line_after_match搜索正则表达式/字符串,它将在匹配项之后插入值。