Question

I am trying to build a development box via Vagrant/Chef-solo, based on Centos 6.4 and using vagrant-omnibus (1.1.2) to ensure the box is using the latest Chef (while creating/putting together the cookbooks, then I'll probably freeze the version). Currently it installs 11.8.2.

One of the cookbooks is using ruby_build to install Ruby 2.0.0-p353 and then create symlinks under /usr/local/bin so that Ruby is available to all users after the chef run is complete. It also installs some gems which installation I want to enforce system-wide.

The thing is that using the gem_package resource after the ruby_build execution installs the gem in the embedded ruby from the Chef Omnibus installation. Until now I worked around that using the gem_binary option to force the detection of the system-wide Ruby environment but it got me thinking and so I checked which PATH is used during the Chef run (using a shell_out to print the PATH to a file) and found out it shows the following:

/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/opt/chef/embedded/bin:/opt/chef/embedded/bin:/usr/local/bin

Where does that come from? How/Why is /opt/chef/embedded/bin added before /usr/local/bin?

Was it helpful?

Solution

The answer is:

  1. Vagrant uses ssh to log in to the guest box as the 'vagrant' user. This adds the sshd_config secure path. In CentOS 6.4 that's:

    /sbin:/bin:/usr/sbin:/usr/bin

  2. Then it uses sudo to become the 'root' user. The profile get's sourced and in CentOS 6.4 that means sbin paths are prepended, while $HOME/bin is appended.

  3. Then chef-solo runs and path sanity is enforced. Path sanity appends all paths (if not part of the existing $PATH) at the end, starting with ruby_bindir and gem_bindir (which refer to the Chef Omnibus installation). Then, every other sane path is appended if not part of $PATH already, which is why /usr/local/bin is at the very end.

As Mark O'Connor mentioned, for gem_package the gem_binary option can be used to for a certain gem. For other resources the full path can be specified. For shell_out! though, if a command is to be executed as a user with a login shell first the environment needs to be emptied (enviroment: { 'PATH' => nil } and bash -l -c used to execute the desired command.

OTHER TIPS

I would recommend specifying the path to the gem command of the target ruby:

gem_package "mypackage" do
  gem_binary "/path/to/my/ruby/distro/bin/gem"
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top