3

I'm new in chef and cookbook. I'm creating a cookbook, and I want to append at the end of file some contents (text). At the moment, I'm using:

file "#{node['dir']}/#{params[:name]}.txt" do
   content "my full text"
end

but I must always append in the "content" the old content because it will overwrite. Is there another way to append contents?

Thank you pasquy

pasquy73
  • 563
  • 3
  • 13
  • Note that simply appending text to a file is not considered good practice as it isn't [idempotent](http://en.wikipedia.org/wiki/Idempotence) (i.e. you can't run your recipe again and get the same end-result as before which most people consider rather crucial for recipes). Whenever possible, you should try to manage whole files with Chef as that is *much* easier to control than checking existing files and selectively adding content. – Holger Just Dec 13 '13 at 11:26
  • Ok, thank you Holger. FYI I'm working on subversion authorization and I need to append in the dav_svn.load apache file the text "LoadModule ... mod_authz_svn.so". – pasquy73 Dec 13 '13 at 11:48
  • Apache has the concept of config directories where it loads all the files that are in there (e.g. `/etc/httpd/config.d`). Just create a new file with your content in that directory (or a similar one depending on your OS, on debian/ubuntu its `/etc/apache2/mods-available` with a symlink in `/etc/apache2/mods-enabled`). – Holger Just Dec 13 '13 at 11:52
  • You are right, I thought to create a new conf file, but in my case, the authz_svn must be loaded before dav_svn module, and apache server reads all conf files in alphabetic order. I accept any suggestion. – pasquy73 Dec 13 '13 at 14:55
  • So? just create a file with a filename that comes alphabetically before the existing one. – Holger Just Dec 13 '13 at 14:56
  • Is this the right way? The module is named authz_svn. I can try to named this authz_svn module as dav_svn_authz; I'll let you know and thank you for your suggestion. – pasquy73 Dec 13 '13 at 15:04
  • If I want to use the apache_module.rb file (of the apache cookbook), I must add in the server.rb file this line: apache_module 'authz_svn' (to create the file within LoadModule ... mod_authz_svn.so) but the file is named mod_authz_svn. – pasquy73 Dec 13 '13 at 15:21
  • You can add the `filename` parameter to the `apache_module` resource like `apache_module "authz_svn" do; filename "mod_authz_svn.so"; end`. Have a look at the [definition](https://github.com/opscode-cookbooks/apache2/blob/master/definitions/apache_module.rb). – Holger Just Dec 13 '13 at 15:31
  • Thank you Holger, it works; these are the lines: `apache_module "dav_svn_authz" do; filename "mod_authz_svn.so"; identifier "authz_svn_module"; end`. so my new file is named dav_svn_authz.load – pasquy73 Dec 13 '13 at 16:34
  • Did any of the proposed solutions help? Please don't forget to mark an answer as correct! :) – sethvargo Jan 02 '14 at 01:17

3 Answers3

2

Please don't use direct Ruby to do this. There's a built-in class in Chef called FileEdit that will handle this for you. Specifically, you probably want insert_line_if_no_match.

sethvargo
  • 26,739
  • 10
  • 86
  • 156
1

You could you use direct ruby code if you wanted like

open('myfile.out', 'a') do |f|
f << "and again ...\n"
end

That could be done in a ruby_block provider if you wanted. This link describes how to use that type of block

Another alternative is to read in your files contents and then concatenate that with the updated string in your current block?

PatrickWalker
  • 550
  • 5
  • 19
1

If you only use ruby code, then chef will write contents at load time of your recipe BEFORE checking any dependencies. And definitely not during convergence.

A combination of ruby and chef will do the trick.

file = File.open(#{node['dir']}/#{params[:name]}.txt, "rb")
existingContents = file.read
newContents = existingContents + "my full text"

file "#{node['dir']}/#{params[:name]}.txt" do
   content newContents
end

So the idea is build the string at load time, pass that string to chef and let chef change the contents at right stage during convergence.

zainengineer
  • 13,289
  • 6
  • 38
  • 28