2
votes

I have a Chef (solo) recipe which generates a CSS file and puts it somewhere into web root directory (/vagrant/css on VM in my case). The problem is that the recipe needs to know an absolute path to vagrant synced directory on VM - it is a folder where Vagrantfile is, and by default it maps to /vagrant inside a VM.

I know how to set that path:

Vagrant.configure("2") do |config|
  config.vm.synced_folder ".", "/synced/dir/on/vm"
end

But the problem is how to let the recipe know that /synced/dir/on/vm.

Currently I use that:

Vagrant.configure("2") do |config|
  config.vm.provision :chef_solo do |chef|
    chef.json = {
      "base_directory" => "/vagrant" # THIS IS IT
    }
  end
end

It lets me use node["base_directory"] inside the recipe code, but there is a downside to that: if I was to write multiple recipes, it would be inconvinient to use node["base_directory"] in every recipe. It is much better that hardcoding the path, but it forces me to use same key on chef.json for every recipe.

Furthermore, if I'd wish to share my recipe, I would force users to use that "base_directory" => "/vagrant" key/value pair in their Vagrantfile.

Is there an API method to get this synched directory path on VM in the recipe code? Or more genarally: is there a way to get Vagrant-specific properties from Chef recipes?

I scoured Vagrant docs, but there seems to be just a single page on that topic, and because it is specific to Vagrant, there is no related information in Chef docs either.

1
I would love to know this too. It looks like there used to be some method of doing this, but it doesn't work anymore: github.com/aespinosa/workstation-vagrant/blob/master/… and github.com/xforty/chef-drupal/blob/master/recipes/…Alan Ivey
It's not really clear why you are putting the file generated on the VM back into a folder that is mounted from the host computer. If you just need to drop the file in a 'known' location, maybe use the Chef::Config[:file_cache_path].CAB
Another thought; if other recipes need to know where that specific CSS file ends up, add an attribute to the css recipe, like default[:cssrecipe][:cssdir] = "". In the Vagrantfile json attributes do this; chef.json = { :cssrecipe => { :cssdir => [ "/vagrant" ] }}. In the other recipes' attribute files do this; include_attribute "cssrecipe". within those recipes you can now use node[:cssrecipe][:cssdir]. This is no less burdensome on needing to use chef.json in each Vagrantfile, but it makes the relationship between recipes much more understandable.CAB
No. You will have to pass the values into the node objectsethvargo
Did you find a solution to this? Please don't forget to mark an answer as correct! :)sethvargo

1 Answers

2
votes

So it seems there's some disconnect on the understanding of how this is meant to work.

When writing a recipe, it's common to use node attributes to define where thing will end up - such as your web_root directory.

I can conceive of the recipe's attributes file containing:

default['base_directory'] = '/var/www/html'

Which would apply to many production servers out there.

Then, when writing your recipes, use this attribute to send the files where you want them to, e.g.:

cookbook_file "#{node['base_directory']/css/myfile.css" do
  owner "root"
  ...
end

When sharing your cookbook, anyone executing this on a server that has the /var/www/html directory will receive your file in the correct place.

In your Vagrantfile, in order to override the node's base_directory attribute to the synced directory, you can do something like this:

SYNCED_FOLDER = "/synced/dir/on/vm"

Vagrant.configure("2") do |config|

  config.vm.synced_folder ".", SYNCED_FOLDER

  config.vm.provision :chef_solo do |chef|
    chef.json = {
      "base_directory" => SYNCED_FOLDER
    }
  end
end

However, you mentioned that you didn't want to have to specify base_directory in your recipes, so I'd ask what node attribute you are using to drive the target location of your web root?

If you're using something like the apache2 cookbook from the Community site, then there's already an attribute for this: node['apache']['docroot_dir'], so using that you can control where thing are referenced.