Understanding rubygems 'require' in sudo vs rvmsudo

367 views Asked by At

I'm using Ubuntu 12.04.4 TLS

I wrote a simple shell script in /home/abdo/sample_serv.sh that executes a Ruby file:

#!/bin/bash
/home/abdo/.rvm/rubies/ruby-2.1.0/bin/ruby /home/abdo/sample_serv.rb

and /home/abdo/sample_serv.rb containing the code below:

puts $:

require 'sinatra'

set :port, 8084

get '/' do
  %{ <html><body>Hello from Abdo</body></html> }
end

Executing rvmsudo ./home/abdo/sample_serv.sh works just fine but I would like to get sudo ./home/abdo/sample_serv.sh to work by passing the necessary environment variables because I am having issues with upstart.

The issue arises in my /etc/init/foo.conf

description "webserver test"

start on runlevel [23]
stop on shutdown

pre-start script
  exec >> /var/log/unicorn_test.log 2>&1
  echo starting
end script

script
  exec >> /var/log/unicorn_test.log 2>&1

  /bin/bash /home/abdo/.rvm/bin/rvmsudo /home/abdo/sample_serv.sh
  echo started
end script

When the line /bin/bash /home/abdo/.rvm/bin/rvmsudo /home/abdo/sample_serv.sh is reached, I get

/home/abdo/.rvm/rubies/ruby-2.1.0/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in 
`require': cannot load such file -- sinatra (LoadError)

I was able to get the same ruby -v as that of my user but it looks like the GEM_PATH (even if I set it inside the upstart config file), is not helping.

Basically, if I can understand how (and where -- gem env is not helping since gem is not a command when I do sudo) rubygems looks for a file being required, I should be able to move forward.

1

There are 1 answers

4
Uri Agassi On

When you run under sudo you run in a different environment, where gem is not installed, the $PATH is different, so things may not run smoothly.

You may want to try this:

Changing sudo's strict defaults

There are 3 things needed to mitigate this situation if you encounter it:

  • the user that is invoking sudo must have export rvmsudo_secure_path=0 set on his shell environment (think .bashrc, .bash_profile or .zshrc)
  • comment out Defaults secure_path=... on /etc/sudoers
  • add Defaults env_keep +="rvm_bin_path GEM_HOME IRBRC MY_RUBY_HOME rvm_path rvm_prefix rvm_version GEM_PATH rvmsudo_secure_path RUBY_VERSION rvm_ruby_string rvm_delete_flag" to /etc/sudoers in rare cases it is required to add more variables - they should be reported by first run of rvmsudo.

After these changes, you should be able to use rvmsudo preserving the same password/no-password directives as "normal" sudo calls.

Edit

If you don't want to change the defaults, you can try to synchronize the values of the environment values stated above (rvm_bin_path GEM_HOME IRBRC MY_RUBY_HOME rvm_path rvm_prefix rvm_version GEM_PATH rvmsudo_secure_path RUBY_VERSION rvm_ruby_string rvm_delete_flag) to your root user.

If that doesn't work, you can try installing rvm as root, and using that environment (instead of /home/abdo/.rvm/bin/rvm) to run your code.