refactor god binary
[god.git] / lib / god / cli / command.rb
blob55a296cc229badb53d9f35db507bb1016d9a7d45
1 module God
2   module CLI
3     
4     class Command
5       def initialize(command, options, args)
6         @command = command
7         @options = options
8         @args = args
9         
10         setup
11         dispatch
12       end
13       
14       def setup
15         # connect to drb unix socket
16         DRb.start_service
17         @server = DRbObject.new(nil, God::Socket.socket(@options[:port]))
18         
19         # ping server to ensure that it is responsive
20         begin
21           @server.ping
22         rescue DRb::DRbConnError
23           puts "The server is not available (or you do not have permissions to access it)"
24           abort
25         end
26       end
27       
28       def dispatch
29         if %w{load status log quit terminate}.include?(@command)
30           send("#{@command}_command")
31         elsif %w{start stop restart monitor unmonitor}.include?(@command)
32           lifecycle_command
33         else
34           puts "Command '#{@command}' is not valid. Run 'god --help' for usage"
35           abort
36         end
37       end
38       
39       def load_command
40         file = @args[1]
41           
42         puts "Sending '#{@command}' command"
43         puts
44         
45         unless File.exist?(file)
46           abort "File not found: #{file}"
47         end
48         
49         names, errors = *@server.running_load(File.read(file), File.expand_path(file))
50         
51         # output response
52         unless names.empty?
53           puts 'The following tasks were affected:'
54           names.each do |w|
55             puts '  ' + w
56           end
57         end
58         
59         unless errors.empty?
60           puts errors
61           exit(1)
62         end
63       end
64       
65       def status_command
66         watches = @server.status
67         watches.keys.sort.each do |name|
68           state = watches[name][:state]
69           puts "#{name}: #{state}"
70         end
71       end
72       
73       def log_command
74         begin
75           Signal.trap('INT') { exit }
76           name = @args[1]
77           t = Time.at(0)
78           loop do
79             print @server.running_log(name, t)
80             t = Time.now
81             sleep 1
82           end
83         rescue God::NoSuchWatchError
84           puts "No such watch"
85         rescue DRb::DRbConnError
86           puts "The server went away"
87         end
88       end
89       
90       def quit_command
91         begin
92           @server.terminate
93           abort 'Could not stop god'
94         rescue DRb::DRbConnError
95           puts 'Stopped god'
96         end
97       end
98       
99       def terminate_command
100         t = Thread.new { loop { STDOUT.print('.'); STDOUT.flush; sleep(1) } }
101         if @server.stop_all
102           t.kill; STDOUT.puts
103           puts 'Stopped all watches'
104         else
105           t.kill; STDOUT.puts
106           puts 'Could not stop all watches within 10 seconds'
107         end
108         
109         begin
110           @server.terminate
111           abort 'Could not stop god'
112         rescue DRb::DRbConnError
113           puts 'Stopped god'
114         end
115       end
116       
117       def lifecycle_command
118         # get the name of the watch/group
119         name = @args[1]
120         
121         puts "Sending '#{@command}' command"
122         
123         t = Thread.new { loop { sleep(1); STDOUT.print('.'); STDOUT.flush; sleep(1) } }
124         
125         # send @command
126         watches = @server.control(name, @command)
127         
128         # output response
129         t.kill; STDOUT.puts
130         unless watches.empty?
131           puts 'The following watches were affected:'
132           watches.each do |w|
133             puts '  ' + w
134           end
135         else
136           puts 'No matching task or group'
137         end
138       end
139     end # Command
140     
141   end