--- daemon/cruise.sample | 13 ++++- daemon/daemon_helper.rb | 110 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 104 insertions(+), 19 deletions(-) diff --git a/daemon/cruise.sample b/daemon/cruise.sample index dff5f78..5fb5230 100755 --- a/daemon/cruise.sample +++ b/daemon/cruise.sample @@ -1,5 +1,8 @@ #!/usr/bin/env ruby - +# +# chkconfig: - 92 35 +# description: Starts and stops cruisecontrol. +# # Instructions to make cruise run as daemon (and work correctly on reboot): # 1. sudo cp CRUISE_HOME/daemon/cruise.sample /etc/init.d/cruise # 2. edit /etc/init.d/cruise to @@ -17,9 +20,13 @@ require CRUISE_HOME + "/daemon/daemon_helper" command = ARGV.shift case command when 'start' - start_cruise "cd #{CRUISE_HOME} && ./cruise start -d" + exit start_cruise "cd #{CRUISE_HOME} && ./cruise start -d" when 'stop' - stop_cruise + exit stop_cruise +when 'restart' + exit restart_cruise +when 'status' + exit status_cruise else p "Usage: #{File.dirname(__FILE__)} start|stop" exit 1 diff --git a/daemon/daemon_helper.rb b/daemon/daemon_helper.rb index 0265d5b..905acba 100644 --- a/daemon/daemon_helper.rb +++ b/daemon/daemon_helper.rb @@ -7,6 +7,7 @@ # * Ensures log files are owned by cruise user, not root require "fileutils" +require "etc" include FileUtils require "rubygems" @@ -18,42 +19,119 @@ rescue => e exit 1 end +cruise_user_uid = Etc.getpwnam(CRUISE_USER)['uid'] +cruise_user_gid = Etc.getpwnam(CRUISE_USER)['gid'] +if Process.euid != cruise_user_uid || Process.egid != cruise_user_gid + Process.egid=cruise_user_gid + Process.euid=cruise_user_uid + Process.gid=cruise_user_gid + Process.uid=cruise_user_uid +end + def log(log_suffix, output) init_log_cmd = "touch #{CRUISE_HOME}/log/cruise_daemon_#{log_suffix}.log" - system(su_if_needed(init_log_cmd)) + system(init_log_cmd) File.open("#{CRUISE_HOME}/log/cruise_daemon_#{log_suffix}.log", "a+"){|f| f << output + "\n\n"} end -def su_if_needed(cmd) - return "su - #{CRUISE_USER} -c '#{cmd}'" if CRUISE_USER != ENV['USER'] - cmd -end - def start_cruise(start_cmd = "cd #{CRUISE_HOME} && ./cruise start -d") log(:env, ENV.inspect) - output = `#{su_if_needed(start_cmd)} 2>&1` + output = `#{start_cmd} 2>&1` if $?.success? print output + "\n" - exit 0 + return 0 else log(:err, output) print output + "\n" - exit 1 + return 1 end end def stop_cruise failed = false - failed ||= !(system "mongrel_rails stop -P #{CRUISE_HOME}/tmp/pids/mongrel.pid") - Dir["#{CRUISE_HOME}/tmp/pids/builders/*.pid"].each do |pid_file| - pid = File.open(pid_file){|f| f.read } - failed ||= !(system "kill -9 #{pid}") - rm pid_file + cruise_pids.each do |f,p| + failed ||= !(system "mongrel_rails stop -P #{f}") end + + sleep 1 + + builder_pids.each do |f,p| + failed ||= kill_process(p) + rm f + end + if failed log(:err, "'stop' command failed") - exit 1 + return 1 else - exit 0 + return 0 end + end + +def status_cruise + ret=0 + pids=cruise_pids + running=[] + ret=1 if pids.empty? + pids.each do |f,p| + if process_alive?(p) + running.push(p) + else + ret = 1 + end + end + if ret == 0 then + puts "Cruisecontrol.rb active at pid(s): #{running.join(' ')}" + else + puts "Cruisecontrol.rb not active" + end + ret +end + +def restart_cruise + stop_cruise + sleep 2 + start_cruise +end + +def cruise_pids + pids=Hash.new + Dir["#{CRUISE_HOME}/tmp/pids/mongrel*.pid"].each do |pid_file| + pid = File.open(pid_file){|f| f.read } + pids[pid_file]=pid.to_i + end + pids +end + +def builder_pids + pids=Hash.new + Dir["#{CRUISE_HOME}/tmp/pids/builders/*.pid"].each do |pid_file| + pid = File.open(pid_file){|f| f.read } + pids[pid_file]=pid.to_i + end + pids +end + +def process_alive?(p) + begin + # if we get an error, we'll set ret=1 in the rescue + Process.kill(0, p) + ret = true + rescue => e + log(:err, "got error: '#{e}' on pid: #{p}") +# puts "#{e} on pid: #{p}" + ret = false + end + ret +end + +def kill_process(p) + if process_alive?(p) + Process.kill('TERM', p) + sleep 2 + Process.kill('TERM', p) if process_alive?(p) + end + ! process_alive?(p) +end + -- 1.5.5.1