change status interface to return hash instead of string
[god.git] / bin / god
blobbfd370c1df9aa47a6f214df74af0380d52abcaa7
1 #!/usr/bin/env ruby
3 $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
5 require 'rubygems'
6 require 'optparse'
7 require 'drb'
9 options = {:daemonize => true, :port => 17165}
11 OptionParser.new do |opts|
12 opts.banner = <<-EOF
13 Usage: god [command] [options]
15 Commands:
16 start <watch or group name>
17 restart <watch or group name>
18 stop <watch or group name>
19 monitor <watch or group name>
20 unmonitor <watch or group name>
21 load <file>
22 log <watch name>
23 status
24 terminate
26 Options:
27 EOF
29 opts.on("-cCONFIG", "--config-file CONFIG", "Configuration file") do |x|
30 options[:config] = x
31 end
33 opts.on("-pPORT", "--port PORT", "Communications port") do |x|
34 options[:port] = x
35 end
37 opts.on("-PFILE", "--pid FILE", "Where to write the PID file") do |x|
38 options[:pid] = x
39 end
41 opts.on("-lFILE", "--log FILE", "Where to write the log file") do |x|
42 options[:log] = x
43 end
45 opts.on("-D", "--no-daemonize", "Don't daemonize") do
46 options[:daemonize] = false
47 end
49 opts.on("-v", "--version", "Print the version number and exit") do
50 options[:version] = true
51 end
53 opts.on("-V", "Print extended version and build information") do
54 options[:info] = true
55 end
56 end.parse!
58 if options[:version]
59 require 'god'
61 # print version
62 puts "Version #{God::VERSION}"
63 exit!(0)
64 elsif options[:info]
65 require 'god'
67 puts "Version: #{God::VERSION}"
68 puts "Polls: enabled"
69 puts "Events: " + God::EventHandler.event_system
71 exit!(0)
72 elsif command = ARGV[0]
73 require 'god'
75 # a command was specified
77 # connect to remote drb
78 DRb.start_service
79 server = DRbObject.new nil, "druby://127.0.0.1:#{options[:port]}"
81 begin
82 server.ping
83 rescue DRb::DRbConnError
84 puts "The server is not available (or you do not have permissions to access it)"
85 exit!
86 rescue => e
87 puts e.message
88 puts e.backtrace.join("\n")
89 exit!
90 end
92 if command == 'load'
93 file = ARGV[1]
95 puts "Sending '#{command}' command"
97 code = File.read(file)
99 watches = server.running_load(code)
101 # output response
102 puts 'The following watches were affected:'
103 watches.each do |w|
104 puts ' ' + w.name
107 puts "Done"
108 elsif command == 'status'
109 watches = server.status
110 watches.keys.sort.each do |name|
111 state = watches[name][:state]
112 puts "#{name}: #{state}"
114 elsif command == 'log'
115 begin
116 Signal.trap('INT') { exit!(0) }
117 name = ARGV[1]
118 t = Time.at(0)
119 loop do
120 print server.running_log(name, t)
121 t = Time.now
122 sleep 1
124 rescue God::NoSuchWatchError
125 puts "No such watch"
126 rescue DRb::DRbConnError
127 puts "The server went away"
128 rescue => e
129 puts e.message
130 puts e.backtrace.join("\n")
131 ensure
132 exit!(0)
134 elsif command == 'terminate'
135 if server.stop_all
136 puts 'Stopped all watches'
137 else
138 puts 'Could not stop all watches within 10 seconds'
141 begin
142 server.terminate
143 abort 'Could not stop god'
144 rescue DRb::DRbConnError
145 puts 'Stopped god'
146 exit!(0)
148 else
149 # get the name of the watch/group
150 name = ARGV[1]
152 begin
153 puts "Sending '#{command}' command"
154 puts "This may take a few seconds depending on the grace periods assigned to your watches"
156 # send command
157 watches = server.control(name, command)
159 # output response
160 puts 'The following watches were affected:'
161 watches.each do |w|
162 puts ' ' + w.name
164 rescue God::InvalidCommandError
165 abort "Command '#{command}' is not valid. Run 'god --help' for usage"
169 exit!(0)
170 else
171 # start god
172 if !options[:daemonize]
173 require 'god'
175 if options[:port]
176 God.port = options[:port]
179 load File.expand_path(options[:config])
180 else
181 pid = fork do
182 begin
183 require 'god'
185 log_file = options[:log] || "/dev/null"
187 STDIN.reopen "/dev/null"
188 STDOUT.reopen(log_file, "a")
189 STDERR.reopen STDOUT
191 puts "Starting god"
193 unless God::EventHandler.loaded?
194 puts
195 puts "***********************************************************************"
196 puts "*"
197 puts "* Event conditions are not available for your installation of god."
198 puts "* You may still use and write custom conditions using the poll system"
199 puts "*"
200 puts "***********************************************************************"
201 puts
204 puts "Resetting file descriptors"
206 puts "Loading config"
208 if options[:port]
209 God.port = options[:port]
212 load File.expand_path(options[:config])
214 Signal.trap('HUP') {}
215 rescue => e
216 File.open('god.log', 'a') { |f| f.puts e.message + "\n" + e.backtrace }
217 abort "!!! ERROR - See god.log !!!"
221 if options[:pid]
222 File.open(options[:pid], 'w') { |f| f.write pid }
225 ::Process.detach pid
227 exit!(0)