Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 8th, 2012  |  syntax: None  |  size: 3.31 KB  |  hits: 15  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #!/usr/bin/env ruby
  2. require 'pathname'
  3. =begin
  4. Script to manage rails projects with unicorn server.
  5. Makes some assumptions:
  6. 1. Each project has corresponging system user.
  7. 2. Project deployed into $HOME/deploy with standard capistrano layout
  8. 3. Unicorn config lives in $HOME/deploy/current/config/unicorn.rb
  9. 4. Unicorn pid file lives in $HOME/deploy/shared/pids/unicorn.pid
  10. Tweak to your need by changing following configuration variables:
  11. RAILS_ENV - rails environment to run unicorns in
  12. BASE_DIR - homes for project users live here
  13. BUNDLE - full path to bundle command. By default script uses bundler installed with 'gem install' on debian system
  14. =end
  15. class ProjectRunningException < StandardError
  16.   def initialize(name)
  17.     super "Project #{name} already running"
  18.   end
  19. end
  20.  
  21. class Project
  22.   RAILS_ENV = "production"
  23.   BASE_DIR = "/srv/sites"
  24.   RVM_SHELL = "/usr/local/rvm/bin/rvm-shell"
  25.   BUNDLE = "/var/lib/gems/1.8/bin/bundle"
  26.  
  27.   @@projects = (Dir.entries(BASE_DIR) - ['.', '..']).select {|i|
  28.     File.exists?(File.join(BASE_DIR, i, 'deploy', 'current', 'config', 'unicorn.rb'))
  29.   }.sort
  30.  
  31.   attr_reader :name
  32.  
  33.   def initialize(name=nil)
  34.     raise "No project specified" if name.nil?
  35.     raise "Project not found. Use 'list' command for a list of project" unless @@projects.include? name
  36.  
  37.     @name = name
  38.     @current_path = File.join(BASE_DIR, @name, 'deploy', 'current')
  39.     @unicorn_conf = "#{@current_path}/config/unicorn.rb"
  40.     @pid_file = File.join(BASE_DIR, @name, 'deploy', 'shared', 'pids', 'unicorn.pid')
  41.     @user = name
  42.   end
  43.  
  44.   def start
  45.     #raise ProjectRunningException, @name if running?
  46.     puts "Starting project #{@name}"
  47.     rvm_ruby_string = Pathname(@current_path).join("config", "deploy.rb").open.grep(/rvm_ruby_string/).first
  48.     if rvm_ruby_string
  49.       ruby_version = rvm_ruby_string.split[2].gsub /['"]/, ''
  50.       cmd = %Q(su #{@user} -c "#{RVM_SHELL} #{ruby_version} -c 'cd #{@current_path} && bundle exec unicorn_rails -c #{@unicorn_conf} -E #{RAILS_ENV} -D'")
  51.     else
  52.       cmd = %Q(su #{@user} -c "rvm-shell -c cd #{@current_path} && #{BUNDLE} exec unicorn_rails -c #{@unicorn_conf} -E #{RAILS_ENV} -D")
  53.     end
  54.     system cmd
  55.   end
  56.  
  57.   def stop
  58.     raise "Pid file does not exist for project #{@name}" unless File.exists? @pid_file
  59.  
  60.     pid = open(@pid_file).readline
  61.     system("kill -QUIT #{pid}")
  62.   end
  63.  
  64.   def running?
  65.     system("ps ax | grep unicorn_rails | grep #{@name} | grep -v grep > /dev/null")
  66.   end
  67.  
  68.   def stale?
  69.     File.exists?(@pid_file) && !running?
  70.   end
  71.  
  72.   def self.list
  73.     @@projects.each do |name|
  74.       project = new(name)
  75.       prop = []
  76.  
  77.       if project.running?
  78.         prop.push "[running]"
  79.       elsif project.stale?
  80.         prop.push "[stale]"
  81.       end
  82.  
  83.       puts "#{project.name} #{prop.join ' '}"
  84.     end
  85.   end
  86.  
  87.   def self.start_all
  88.     @@projects.each do |name|
  89.       begin
  90.         new(name).start
  91.       rescue ProjectRunningException => e
  92.         puts e
  93.         next
  94.       end
  95.     end
  96.   end
  97. end
  98.  
  99.  
  100. abort "Only root can run this program" if Process.uid != 0
  101.  
  102. begin
  103.   case ARGV.shift
  104.   when "list"
  105.     Project.list
  106.   when "start"
  107.     Project.new(ARGV.shift).start
  108.   when "stop"
  109.     Project.new(ARGV.shift).stop
  110.   when "start_all"
  111.     Project.start_all
  112.   else
  113.     raise
  114.   end
  115. rescue Exception => e
  116.   puts e unless e.message.empty?
  117.   puts <<EOF
  118. Usage: #{__FILE__} list | start <project> | stop <project> | start_all
  119. EOF
  120. end