How to read a cookbook file while compiling a recipe?

Similar things are commonly found in chef recipes:

%w{foo bar baz}.each do |x| file "#{x}" do content "whatever" end end 

But I want to read the elements that need to be sorted out from a file that is stored in the cookbook, for example:

 File.open('files/default/blah.txt').each do |x| file "#{x}" do content "whatever" end end 

This works if I give the full path to blah.txt , where the cache client performs caching, but it is not portable. This does not work if I write it, as in the example, β€œhoping” that the current directory is the root of the cookbook. Is there a way to get the root directory of a cookbook when compiling recipes?

+6
source share
3 answers

In Chef 11, you can become smarter and use Dir globbing to achieve your desired behavior:

  • Disable lazy asset loading. When lazy asset loading is enabled, Chef will retrieve assets (for example, cookbook files, templates, etc.), since they are requested at the time the Chef Client starts. In your use case, you need these assets to exist on the server before the recipe starts. Add the following to client.rb :

     no_lazy_load true 
  • Find the path to the cookbook cache on disk. This is a bit of magic and experimentation, but:

     "#{Chef::Config[:file_cache_path]}/cookbooks/NAME" 
  • Get the correct file:

     path = "#{Chef::Config[:file_cache_path]}/cookbooks/NAME/files/default/blah.txt" File.readlines(path).each do |line| name = line.strip # Whatever chef execution here... end 

You can also see Cookbook.preferred_filename_on_disk if you want to use file specification handlers.

+4
source

Another solution for those who do not need the contents of the file before merging, but which does not require any modifications to client.rb, is to use the cookbook_file file to read the resource in file_cache_path and then lazily load it. Here is an example where I read in a groovy script that should be embedded in an xml template.

 script_file = "#{Chef::Config['file_cache_path']}/bootstrap-machine.groovy" cookbook_file script_file do source 'bootstrap-machine.groovy' end config_xml = "#{Chef::Config['file_cache_path']}/bootstrap-machine-job.xml" template config_xml do source 'bootstrap-machine-job.xml.erb' variables(lazy {{ :groovy_script => File.open(script_file).read }}) end 
+4
source

For accuracy, I like to use a combination of File.join() and the variable "cookbook_name".

 File.join( Chef::Config[:file_cache_path], 'cookbooks', cookbook_name, 'path/to/blah.txt' ) 
0
source

All Articles