use 127.0.0.1 for DRb to avoid IPv6 problems
[god.git] / bin / god
blob0e96c9bc90a00b6ceed19d1aafd02c306f221fef
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 stop <watch or group name>
18 monitor <watch or group name>
19 unmonitor <watch or group name>
20 load <file>
21 log <watch name>
22 status
23 terminate
25 Options:
26 EOF
28 opts.on("-cCONFIG", "--config-file CONFIG", "Configuration file") do |x|
29 options[:config] = x
30 end
32 opts.on("-pPORT", "--port PORT", "Communications port") do |x|
33 options[:port] = x
34 end
36 opts.on("-PFILE", "--pid FILE", "Where to write the PID file") do |x|
37 options[:pid] = x
38 end
40 opts.on("-lFILE", "--log FILE", "Where to write the log file") do |x|
41 options[:log] = x
42 end
44 opts.on("-D", "--no-daemonize", "Don't daemonize") do
45 options[:daemonize] = false
46 end
48 opts.on("-v", "--version", "Print the version number and exit") do
49 options[:version] = true
50 end
52 opts.on("-V", "Print extended version and build information") do
53 options[:info] = true
54 end
55 end.parse!
57 if options[:version]
58 require 'god'
60 # print version
61 puts "Version #{God::VERSION}"
62 exit!(0)
63 elsif options[:info]
64 require 'god'
66 puts "Version: #{God::VERSION}"
67 puts "Polls: enabled"
68 puts "Events: " + God::EventHandler.event_system
70 exit!(0)
71 elsif command = ARGV[0]
72 require 'god'
74 # a command was specified
76 # connect to remote drb
77 DRb.start_service
78 server = DRbObject.new nil, "druby://127.0.0.1:#{options[:port]}"
80 begin
81 server.ping
82 rescue DRb::DRbConnError
83 puts "The server is not available (or you do not have permissions to access it)"
84 exit!
85 rescue => e
86 puts e.message
87 puts e.backtrace.join("\n")
88 exit!
89 end
91 if command == 'load'
92 file = ARGV[1]
94 puts "Sending '#{command}' command"
96 code = File.read(file)
98 watches = server.running_load(code)
100 # output response
101 puts 'The following watches were affected:'
102 watches.each do |w|
103 puts ' ' + w.name
106 puts "Done"
107 elsif command == 'status'
108 puts server.status
109 elsif command == 'log'
110 begin
111 Signal.trap('INT') { exit!(0) }
112 name = ARGV[1]
113 t = Time.at(0)
114 loop do
115 print server.running_log(name, t)
116 t = Time.now
117 sleep 1
119 rescue God::NoSuchWatchError
120 puts "No such watch"
121 rescue DRb::DRbConnError
122 puts "The server went away"
123 rescue => e
124 puts e.message
125 puts e.backtrace.join("\n")
126 ensure
127 exit!(0)
129 elsif command == 'terminate'
130 if server.stop_all
131 puts 'Stopped all watches'
132 else
133 puts 'Could not stop all watches within 10 seconds'
136 begin
137 server.terminate
138 abort 'Could not stop god'
139 rescue DRb::DRbConnError
140 puts 'Stopped god'
141 exit!(0)
143 else
144 # get the name of the watch/group
145 name = ARGV[1]
147 begin
148 puts "Sending '#{command}' command"
150 # send command
151 watches = server.control(name, command)
153 # output response
154 puts 'The following watches were affected:'
155 watches.each do |w|
156 puts ' ' + w.name
158 rescue God::InvalidCommandError
159 abort "Command '#{command}' is not valid. Run 'god --help' for usage"
163 exit!(0)
164 else
165 # start god
166 if !options[:daemonize]
167 require 'god'
169 if options[:port]
170 God.port = options[:port]
173 load File.expand_path(options[:config])
174 else
175 pid = fork do
176 begin
177 require 'god'
179 log_file = options[:log] || "/dev/null"
181 STDIN.reopen "/dev/null"
182 STDOUT.reopen(log_file, "a")
183 STDERR.reopen STDOUT
185 puts "Starting god"
187 unless God::EventHandler.loaded?
188 puts
189 puts "***********************************************************************"
190 puts "*"
191 puts "* Event conditions are not available for your installation of god."
192 puts "* You may still use and write custom conditions using the poll system"
193 puts "*"
194 puts "***********************************************************************"
195 puts
198 puts "Resetting file descriptors"
200 puts "Loading config"
202 if options[:port]
203 God.port = options[:port]
206 load File.expand_path(options[:config])
208 Signal.trap('HUP') {}
209 rescue => e
210 File.open('god.log', 'a') { |f| f.puts e.message + "\n" + e.backtrace }
211 abort "!!! ERROR - See god.log !!!"
215 if options[:pid]
216 File.open(options[:pid], 'w') { |f| f.write pid }
219 ::Process.detach pid
221 exit!(0)