How can I change a file with Chef?

↘锁芯ラ 提交于 2019-11-27 03:50:34
StephenKing

By design, you don't modify files with Chef. Instead you put placeholders (<%= ..%>) into the file templates, which are then replaced with the dynamic values (so called attributes).

Konzulic

Chef actually allows and uses this. You can find an example in the opscode's

cookbooks/chef-server/recipes/default.rb:

ruby_block "ensure node can resolve API FQDN" do
  block do
    fe = Chef::Util::FileEdit.new("/etc/hosts")
    fe.insert_line_if_no_match(/#{node['chef-server']['api_fqdn']}/,
                               "127.0.0.1 #{node['chef-server']['api_fqdn']}")
    fe.write_file
  end
  not_if { Resolv.getaddress(node['chef-server']['api_fqdn']) rescue false }
end

Here's the use-case. After the installation from source I had to uncomment lines in some created configuration file that hadn't been the same in all versions of software, therefore use of templates hadn't been appropriate. The methods I used were:

  • (Object) search_file_replace(regex, replace)
  • (Object) search_file_replace_line(regex, newline)

You may find the full documentation here:

TO STRESS: This method is to be used only when using templates and partials is inappropriate. As @StephenKing already said, templates are common way of doing this.

Stuart Pook

Here is an example of how you can use Chef to uncomment a line in a configuration file. The ruby_block is protected with a ::File::grep. The test for Debian is just for fun.

pam_config = "/etc/pam.d/su"
commented_limits = /^#\s+(session\s+\w+\s+pam_limits\.so)\b/m

ruby_block "add pam_limits to su" do
  block do
    sed = Chef::Util::FileEdit.new(pam_config)
    sed.search_file_replace(commented_limits, '\1')
    sed.write_file
  end
  only_if { ::File.readlines(pam_config).grep(commented_limits).any? }
end if platform_family?('debian')
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!