ruby-on-railsrvmcapistranobluepill

Bluepill - installed in user RVM - project specific gemset - how to run with sudo without password?


I have Bluepill setup to monitor my delayed_job processes.

On my production server, I use RVM installed in the user's home folder (username is deploy). My app's gems are installed in its own project-specific gemset. So, the bluepill gem and its corresponding binary are installed within the ~/.rvm/.... folder.

When I deploy my app using capistrano, I want bluepill to be stopped and started, so my DJs get restarted. I am looking at the instructions for the capistrano recipe here.

I think my RVM-compliant bluepill tasks have to be like the following:

# Bluepill related tasks
after 'deploy:start', 'bluepill:start'
after 'deploy:stop', 'bluepill:quit'
after 'deploy:restart', 'bluepill:quit', 'bluepill:start'

namespace :bluepill do
  desc 'Stop processes that bluepill is monitoring and quit bluepill'
  task :quit, :roles => [:app] do
    run "cd #{current_path}; sudo bluepill #{application}_#{rails_env} stop"
    run "cd #{current_path}; sudo bluepill #{application}_#{rails_env} quit"
    sleep 5
  end

  desc 'Load bluepill configuration and start it'
  task :start, :roles => [:app] do
    run "cd #{current_path}; sudo bluepill load #{current_path}/config/server/#{rails_env}/delayed_job.bluepill"
  end

  desc 'Prints bluepills monitored processes statuses'
  task :status, :roles => [:app] do
    run "cd #{current_path}; sudo bluepill #{application}_#{rails_env} status"
  end
end

I haven't tested the above yet.

What I am wondering is: what should I put in my sudoers file to allow the deploy user run just these bluepill related commands as root without a password? On this page they have mentioned this:

deploy ALL=(ALL) NOPASSWD: /usr/local/bin/bluepill

But the path to the bluepill binary would be different in my case. And it would be different for different projects, because of project-specific gemsets. Should I be mentioning each of the binary paths or is there a better way of handling this?


Solution

  • use wrappers and aliases:

    namespace :bluepill do
      task :setup do
        run "rvm alias create #{application} #{rvm_ruby_name_evaluated}"
        run "rvm wrappers #{application} --no-links bluepill"
      end
    end
    

    so after this task bluepill is available via #{rvm_path}/wrappers/#{application}/bluepill which will be always the same even if you change ruby version, so it can be added to sudoers for preserving path:

    deploy ALL=(ALL) NOPASSWD: /home/my_user/.rvm/wrappers/my_app/bluepill
    

    and then the tasks can use:

    sudo #{rvm_path}/wrappers/#{application}/bluepill ...
    

    it is important to note here that the wrapper takes care of loading rvm environment because it was lost by invocation of sudo ... but this is just a detail ;)