0

I'm configuring a vagrant box using chef and then deploying my app using capistrano.

my chef recipe to install bundler is the following:

include_recipe "rbenv"

include_recipe "rbenv::ruby_build"

rbenv_ruby node[:rbenv][:ruby] do 
  global true
end

rbenv_gem "bundler" do
  ruby_version node[:rbenv][:ruby]
end

using the Riot rbenv cookbook

When I try using the bundle with capistrano I figured that the executed bundle is one that was preinstalled on the box, rather than the one installed by chef.

Here's the problem:

$ which bundle
/opt/rbenv/shims/bundle
$ sudo which bundle
/usr/bin/bundle
$ sudo su -
root# which bundle
/opt/rbenv/shims/bundle

Basically it appears that Capistrano runs the commands using the second form, were it uses the /usr/bin/bundle.

I've tried running:

$ sudo bundle
/usr/lib/ruby/vendor_ruby/bundler/rubygems_ext.rb:8:in `require': no such file to load -- rubygems (LoadError)
    from /usr/lib/ruby/vendor_ruby/bundler/rubygems_ext.rb:8
    from /usr/lib/ruby/vendor_ruby/bundler.rb:11:in `require'
    from /usr/lib/ruby/vendor_ruby/bundler.rb:11
    from /usr/bin/bundle:4:in `require'
    from /usr/bin/bundle:4

and I obtain exactly the same exception I see in Capistrano.

If I manually uninstall bundler then here's what I obtain:

$ bundle
Bundler::GemfileNotFound
$ sudo bundle
sudo: bundle: command not found
$ sudo su - 
root# bundle
Bundler::GemfileNotFound

UPDATE

I've figured that the whole ruby version is not available for sudoers:

$ ruby -v
ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-linux]
$ sudo ruby -v
ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]

even more troubles.

Can you help me ?

thanks.

cassianoleal
  • 2,556
  • 19
  • 22
Don Giulio
  • 2,946
  • 3
  • 43
  • 82

2 Answers2

3

The problem is not that the rbenv-managed Ruby is not available to sudoers. The problem is that the system Ruby is used by default, unless overridden by something else -- usually .bashrc or a /etc/profile.d/* or such.

Since capistrano doesn't source any of these files, it uses the system Ruby.

You should tell cap to use the rbenv bin paths before the system ones by adding:

set :default_environment, {
  'PATH' => "/opt/rbenv/shims:/opt/rbenv/bin:$PATH"
}

to your deploy.rb file.

Update

In Capistrano v3, the :default_environment has been renamed to :default_env.

Community
  • 1
  • 1
cassianoleal
  • 2,556
  • 19
  • 22
  • do you mean that this is normal because sudoers use the system version by default? I would guess for security reasons? – Don Giulio Nov 28 '13 at 12:11
  • 1
    Yes. By default, sudoers use the `secure_path` that's set on `/etc/sudoers`. – cassianoleal Nov 28 '13 at 12:31
  • thanks that's brilliant and makes sense, although setting the `default_environment` is not working for me: `DEBUG [6974ecca] Command: cd && /usr/bin/env echo $PATH INFO [6974ecca] Finished in 0.004 seconds with exit status 0 (successful). DEBUG [6974ecca] /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games` any clue? – Don Giulio Nov 28 '13 at 13:33
  • it feels like capistrano 3.x has lost the `default_environment`, there's no such string in its source code. – Don Giulio Nov 28 '13 at 13:42
  • ok, it seems that in capistrano 3 the `default_environment` is now called `default_env`. setting this last one worked. – Don Giulio Nov 28 '13 at 15:25
  • Apparently changing the `default_environment` is not the right solution, it led me to many other issues, and it appears that this is not the best practice. Though I'm still trying to figure out what is the best way. – Don Giulio Nov 29 '13 at 19:49
0

Apparently tweaking with the default_env is a possibility, but not the preferred way.

as:

set :default_environment, {
    'PATH' => "/opt/rbenv/shims:/opt/rbenv/bin:$PATH"
}

is not maintained by capistrano and probably even dangerous.

The preferred way is to look into the program one wants to run for a way to fix this.

In particular my problem: the RVM needs to be initialized upon shell startup, and any RVM installation tool will include your .bashrc with the call to the proper init script at the end of the file. Also at the beginning of .bashrc there's a command that exits the script when it's called on a non interactive shell.

Accidentally Capistrano runs the scripts on a non interactive shell, so when it calls RVM commands they are not initialized, in the non interactive shell.

The solution in my case was to edit the .bashrc file in chef so to call the RVM init script before exiting.

Don Giulio
  • 2,946
  • 3
  • 43
  • 82
  • Can you explain this a little more. I am having the exact same problem, and I am a bit confused. – moosilauke18 Dec 21 '13 at 06:24
  • So: the RVM needs to be initialized upon shell startup, and any RVM installation tool will include your `.bashrc` with the call to the proper init script at the end of the file. Also at the beginning of `.bashrc` there's a command that exits the script when it's called on a non interactive shell. Accidentally Capistrano runs the scripts on a non interactive shell, so when it calls RVM commands they are not initialized, in the non interactive shell. The solution in my case was to edit the `.bashrc` file in chef so to call the RVM init script before exiting. – Don Giulio Dec 23 '13 at 13:00