daemons 1.1.9 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +1 -1
- data/README.md +207 -0
- data/Releases +85 -24
- data/examples/call/call.rb +13 -16
- data/examples/call/call_monitor.rb +13 -17
- data/examples/daemonize/daemonize.rb +4 -8
- data/examples/run/ctrl_crash.rb +0 -1
- data/examples/run/ctrl_custom_logfiles.rb +18 -0
- data/examples/run/ctrl_exec.rb +0 -1
- data/examples/run/ctrl_exit.rb +0 -1
- data/examples/run/ctrl_keep_pid_files.rb +1 -3
- data/examples/run/ctrl_monitor.rb +0 -1
- data/examples/run/ctrl_monitor_multiple.rb +17 -0
- data/examples/run/ctrl_monitor_nocrash.rb +15 -0
- data/examples/run/ctrl_multiple.rb +0 -1
- data/examples/run/ctrl_ontop.rb +0 -1
- data/examples/run/ctrl_optionparser.rb +5 -7
- data/examples/run/ctrl_proc.rb +8 -9
- data/examples/run/ctrl_proc_multiple.rb +4 -6
- data/examples/run/ctrl_proc_rand.rb +2 -4
- data/examples/run/ctrl_proc_simple.rb +0 -1
- data/examples/run/myserver.rb +0 -1
- data/examples/run/myserver_crashing.rb +5 -5
- data/examples/run/myserver_exiting.rb +2 -2
- data/examples/run/myserver_hanging.rb +4 -5
- data/examples/run/myserver_slowstop.rb +5 -6
- data/lib/daemons/application.rb +235 -229
- data/lib/daemons/application_group.rb +115 -100
- data/lib/daemons/change_privilege.rb +2 -4
- data/lib/daemons/cmdline.rb +75 -62
- data/lib/daemons/controller.rb +36 -54
- data/lib/daemons/daemonize.rb +74 -75
- data/lib/daemons/etc_extension.rb +3 -4
- data/lib/daemons/exceptions.rb +11 -13
- data/lib/daemons/monitor.rb +57 -77
- data/lib/daemons/pid.rb +26 -56
- data/lib/daemons/pidfile.rb +49 -44
- data/lib/daemons/pidmem.rb +5 -9
- data/lib/daemons/reporter.rb +54 -0
- data/lib/daemons/syslogio.rb +240 -0
- data/lib/daemons/version.rb +3 -0
- data/lib/daemons.rb +87 -77
- metadata +111 -46
- data/README +0 -214
- data/Rakefile +0 -90
- data/TODO +0 -2
- data/setup.rb +0 -1360
@@ -1,65 +1,63 @@
|
|
1
1
|
|
2
2
|
module Daemons
|
3
3
|
class ApplicationGroup
|
4
|
-
|
5
4
|
attr_reader :app_name
|
6
5
|
attr_reader :script
|
7
|
-
|
6
|
+
|
8
7
|
attr_reader :monitor
|
9
|
-
|
10
|
-
#attr_reader :controller
|
11
|
-
|
8
|
+
|
12
9
|
attr_reader :options
|
13
|
-
|
10
|
+
|
14
11
|
attr_reader :applications
|
15
|
-
|
12
|
+
|
16
13
|
attr_accessor :controller_argv
|
17
14
|
attr_accessor :app_argv
|
18
|
-
|
15
|
+
|
19
16
|
attr_accessor :dir_mode
|
20
17
|
attr_accessor :dir
|
21
|
-
|
18
|
+
|
22
19
|
# true if the application is supposed to run in multiple instances
|
23
20
|
attr_reader :multiple
|
24
|
-
|
25
|
-
|
21
|
+
|
26
22
|
def initialize(app_name, options = {})
|
27
23
|
@app_name = app_name
|
28
24
|
@options = options
|
29
|
-
|
30
|
-
if options[:script]
|
31
|
-
@script = File.expand_path(options[:script])
|
25
|
+
|
26
|
+
if @options[:script]
|
27
|
+
@script = File.expand_path(@options[:script])
|
32
28
|
end
|
33
|
-
|
34
|
-
#@controller = controller
|
29
|
+
|
35
30
|
@monitor = nil
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
@
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
@
|
46
|
-
|
47
|
-
|
31
|
+
|
32
|
+
@multiple = @options[:multiple] || false
|
33
|
+
|
34
|
+
@dir_mode = @options[:dir_mode] || :script
|
35
|
+
['dir'].each do |k|
|
36
|
+
@options[k] = File.expand_path(@options[k]) if @options.key?(k)
|
37
|
+
end
|
38
|
+
@dir = @options[:dir] || ''
|
39
|
+
|
40
|
+
@keep_pid_files = @options[:keep_pid_files] || false
|
41
|
+
|
42
|
+
@no_pidfiles = @options[:no_pidfiles] || false
|
43
|
+
|
44
|
+
@pid_delimiter = @options[:pid_delimiter]
|
45
|
+
|
48
46
|
@applications = []
|
49
47
|
end
|
50
|
-
|
48
|
+
|
51
49
|
# Setup the application group.
|
52
50
|
# Currently this functions calls <tt>find_applications</tt> which finds
|
53
51
|
# all running instances of the application and populates the application array.
|
54
52
|
#
|
55
53
|
def setup
|
56
|
-
@applications = find_applications(pidfile_dir
|
54
|
+
@applications = find_applications(pidfile_dir)
|
57
55
|
end
|
58
|
-
|
56
|
+
|
59
57
|
def pidfile_dir
|
60
58
|
PidFile.dir(@dir_mode, @dir, script)
|
61
|
-
end
|
62
|
-
|
59
|
+
end
|
60
|
+
|
63
61
|
def find_applications(dir)
|
64
62
|
if @no_pidfiles
|
65
63
|
return find_applications_by_app_name(app_name)
|
@@ -67,128 +65,145 @@ module Daemons
|
|
67
65
|
return find_applications_by_pidfiles(dir)
|
68
66
|
end
|
69
67
|
end
|
70
|
-
|
68
|
+
|
71
69
|
# TODO: identifiy the monitor process
|
72
70
|
def find_applications_by_app_name(app_name)
|
73
71
|
pids = []
|
74
|
-
|
72
|
+
|
75
73
|
begin
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
74
|
+
x = `ps auxw | grep -v grep | awk '{print $2, $11, $12}' | grep #{app_name}`
|
75
|
+
if x && x.chomp!
|
76
|
+
processes = x.split(/\n/).compact
|
77
|
+
processes = processes.delete_if do |p|
|
78
|
+
_pid, name, add = p.split(/\s/)
|
79
|
+
# We want to make sure that the first part of the process name matches
|
80
|
+
# so that app_name matches app_name_22
|
81
|
+
|
82
|
+
app_name != name[0..(app_name.length - 1)] and not add.include?(app_name)
|
83
|
+
end
|
84
|
+
pids = processes.map { |p| p.split(/\s/)[0].to_i }
|
85
85
|
end
|
86
|
-
pids = processes.map {|p| p.split(/\s/)[0].to_i}
|
87
|
-
end
|
88
86
|
rescue ::Exception
|
89
87
|
end
|
90
|
-
|
91
|
-
|
88
|
+
|
89
|
+
pids.map do |f|
|
92
90
|
app = Application.new(self, {}, PidMem.existing(f))
|
93
91
|
setup_app(app)
|
94
92
|
app
|
95
|
-
|
93
|
+
end
|
96
94
|
end
|
97
|
-
|
95
|
+
|
98
96
|
def find_applications_by_pidfiles(dir)
|
99
|
-
pid_files = PidFile.find_files(dir, app_name, ! @keep_pid_files)
|
100
|
-
|
101
|
-
#pp pid_files
|
102
|
-
|
103
97
|
@monitor = Monitor.find(dir, app_name + '_monitor')
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
98
|
+
|
99
|
+
reporter = Reporter.new(options)
|
100
|
+
pid_files = PidFile.find_files(dir, app_name, ! @keep_pid_files, @pid_delimiter) do |pid, file|
|
101
|
+
reporter.deleted_found_pidfile(pid, file)
|
102
|
+
end
|
103
|
+
|
104
|
+
pid_files.map do |f|
|
108
105
|
app = Application.new(self, {}, PidFile.existing(f))
|
109
106
|
setup_app(app)
|
110
107
|
app
|
111
|
-
|
108
|
+
end
|
112
109
|
end
|
113
|
-
|
110
|
+
|
114
111
|
def new_application(add_options = {})
|
115
|
-
if @applications.size > 0
|
112
|
+
if @applications.size > 0 && !@multiple
|
116
113
|
if options[:force]
|
117
|
-
@applications.delete_if
|
114
|
+
@applications.delete_if do |a|
|
118
115
|
unless a.running?
|
119
116
|
a.zap
|
120
117
|
true
|
121
118
|
end
|
122
|
-
|
119
|
+
end
|
123
120
|
end
|
124
|
-
|
125
|
-
|
121
|
+
|
122
|
+
fail RuntimeException.new('there is already one or more instance(s) of the program running') unless @applications.empty?
|
126
123
|
end
|
127
|
-
|
124
|
+
|
128
125
|
app = Application.new(self, add_options)
|
129
|
-
|
126
|
+
|
130
127
|
setup_app(app)
|
131
|
-
|
128
|
+
|
132
129
|
@applications << app
|
133
|
-
|
134
|
-
|
130
|
+
|
131
|
+
app
|
135
132
|
end
|
136
|
-
|
133
|
+
|
137
134
|
def setup_app(app)
|
138
135
|
app.controller_argv = @controller_argv
|
139
136
|
app.app_argv = @app_argv
|
137
|
+
if @options[:show_status_callback]
|
138
|
+
app.show_status_callback = @options[:show_status_callback]
|
139
|
+
end
|
140
140
|
end
|
141
141
|
private :setup_app
|
142
|
-
|
142
|
+
|
143
143
|
def create_monitor(an_app)
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
144
|
+
if @monitor && options[:monitor]
|
145
|
+
@monitor.stop
|
146
|
+
@monitor = nil
|
147
|
+
end
|
148
148
|
|
149
|
-
|
149
|
+
if options[:monitor]
|
150
|
+
opt = {}
|
151
|
+
opt[:monitor_interval] = options[:monitor_interval] if options[:monitor_interval]
|
152
|
+
@monitor = Monitor.new(an_app, opt)
|
153
|
+
@monitor.start(self)
|
150
154
|
end
|
151
155
|
end
|
152
|
-
|
156
|
+
|
153
157
|
def start_all
|
154
158
|
@monitor.stop if @monitor
|
155
159
|
@monitor = nil
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
160
|
+
|
161
|
+
pids = []
|
162
|
+
@applications.each do |a|
|
163
|
+
pids << fork do
|
164
|
+
a.start
|
165
|
+
end
|
166
|
+
end
|
167
|
+
pids.each { |pid| Process.waitpid(pid) }
|
162
168
|
end
|
163
|
-
|
169
|
+
|
164
170
|
def stop_all(no_wait = false)
|
165
|
-
|
166
|
-
|
171
|
+
if @monitor
|
172
|
+
@monitor.stop
|
173
|
+
@monitor = nil
|
174
|
+
setup
|
175
|
+
end
|
176
|
+
|
167
177
|
threads = []
|
168
|
-
|
169
|
-
@applications.each
|
178
|
+
|
179
|
+
@applications.each do |a|
|
170
180
|
threads << Thread.new do
|
171
181
|
a.stop(no_wait)
|
172
182
|
end
|
173
|
-
|
174
|
-
|
175
|
-
threads.each {|t| t.join}
|
183
|
+
end
|
184
|
+
|
185
|
+
threads.each { |t| t.join }
|
176
186
|
end
|
177
|
-
|
187
|
+
|
178
188
|
def reload_all
|
179
|
-
@applications.each {|a| a.reload}
|
189
|
+
@applications.each { |a| a.reload }
|
180
190
|
end
|
181
191
|
|
182
192
|
def zap_all
|
183
193
|
@monitor.stop if @monitor
|
184
|
-
|
185
|
-
@applications.each {|a| a.zap}
|
194
|
+
|
195
|
+
@applications.each { |a| a.zap }
|
186
196
|
end
|
187
|
-
|
197
|
+
|
188
198
|
def show_status
|
189
|
-
@applications.each {|a| a.show_status}
|
199
|
+
@applications.each { |a| a.show_status }
|
190
200
|
end
|
191
|
-
|
192
|
-
end
|
193
201
|
|
202
|
+
# Check whether at least one of the applications in the group is running. If yes, return true.
|
203
|
+
def running?
|
204
|
+
@applications.each { |a| return true if a.running? }
|
205
|
+
return false
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
194
209
|
end
|
@@ -1,9 +1,7 @@
|
|
1
1
|
require 'daemons/etc_extension'
|
2
2
|
|
3
3
|
class CurrentProcess
|
4
|
-
def self.change_privilege(user, group=user)
|
5
|
-
puts "Changing process privilege to #{user}:#{group}"
|
6
|
-
|
4
|
+
def self.change_privilege(user, group = user)
|
7
5
|
uid, gid = Process.euid, Process.egid
|
8
6
|
target_uid = Etc.getpwnam(user).uid
|
9
7
|
target_gid = Etc.getgrnam(group).gid
|
@@ -16,4 +14,4 @@ class CurrentProcess
|
|
16
14
|
rescue Errno::EPERM => e
|
17
15
|
raise "Couldn't change user and group to #{user}:#{group}: #{e}"
|
18
16
|
end
|
19
|
-
end
|
17
|
+
end
|
data/lib/daemons/cmdline.rb
CHANGED
@@ -1,56 +1,78 @@
|
|
1
|
-
|
2
1
|
module Daemons
|
3
|
-
|
4
2
|
class Optparse
|
5
|
-
|
6
3
|
attr_reader :usage
|
7
4
|
|
8
5
|
def initialize(controller)
|
9
6
|
@controller = controller
|
10
7
|
@options = {}
|
11
|
-
|
8
|
+
|
12
9
|
@opts = OptionParser.new do |opts|
|
13
|
-
opts.banner =
|
14
|
-
|
15
|
-
|
16
|
-
# @options[:verbose] = v
|
17
|
-
# end
|
18
|
-
|
19
|
-
opts.on("-t", "--ontop", "Stay on top (does not daemonize)") do |t|
|
10
|
+
opts.banner = ''
|
11
|
+
|
12
|
+
opts.on('-t', '--ontop', 'Stay on top (does not daemonize)') do |t|
|
20
13
|
@options[:ontop] = t
|
21
14
|
end
|
22
|
-
|
23
|
-
opts.on(
|
15
|
+
|
16
|
+
opts.on('-s', '--shush', 'Silent mode (no output to the terminal)') do |t|
|
17
|
+
@options[:shush] = t
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on('-f', '--force', 'Force operation') do |t|
|
24
21
|
@options[:force] = t
|
25
22
|
end
|
26
|
-
|
27
|
-
opts.on(
|
23
|
+
|
24
|
+
opts.on('-n', '--no_wait', 'Do not wait for processes to stop') do |t|
|
28
25
|
@options[:no_wait] = t
|
29
26
|
end
|
30
|
-
|
31
|
-
#opts.separator ""
|
32
|
-
#opts.separator "Specific options:"
|
33
27
|
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
opts.on('-w', '--force_kill_waittime SECONDS', Integer, 'Maximum time to wait for processes to stop before force-killing') do |t|
|
29
|
+
@options[:force_kill_waittime] = t
|
30
|
+
end
|
31
|
+
opts.on('--signals_and_waits STRING', String, 'which signal to use to stop and how long to wait e.g. TERM:20|KILL:20') do |t|
|
32
|
+
@options[:signals_and_waits] = t
|
33
|
+
end
|
34
|
+
|
35
|
+
opts.on('--pid_delimiter STRING', 'Text used to separate process number in full process name and pid-file name') do |value|
|
36
|
+
@options[:pid_delimiter] = value
|
37
|
+
end
|
38
|
+
|
39
|
+
opts.separator ''
|
40
|
+
opts.separator 'Common options:'
|
41
|
+
|
42
|
+
opts.on('-l', '--log_output', 'Enable input/output stream redirection') do |value|
|
43
|
+
@options[:log_output] = value
|
44
|
+
end
|
45
|
+
|
46
|
+
opts.on('--logfilename FILE', String, 'Custom log file name for exceptions') do |value|
|
47
|
+
@options[:logfilename] = value
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.on('--output_logfilename FILE', String, 'Custom file name for input/output stream redirection log') do |value|
|
51
|
+
@options[:output_logfilename] = value
|
52
|
+
end
|
53
|
+
|
54
|
+
opts.on('--log_dir DIR', String, 'Directory for log files') do |value|
|
55
|
+
@options[:log_dir] = value
|
56
|
+
end
|
57
|
+
|
58
|
+
opts.on('--syslog', 'Enable output redirction into SYSLOG instead of a file') do |value|
|
59
|
+
@options[:log_output_syslog] = value
|
60
|
+
end
|
37
61
|
|
38
62
|
# No argument, shows at tail. This will print an options summary
|
39
|
-
opts.on_tail(
|
40
|
-
|
41
|
-
|
42
|
-
controller.print_usage()
|
43
|
-
|
63
|
+
opts.on_tail('-h', '--help', 'Show this message') do
|
64
|
+
controller.print_usage
|
65
|
+
|
44
66
|
exit
|
45
67
|
end
|
46
68
|
|
47
69
|
# Switch to print the version.
|
48
|
-
opts.on_tail(
|
70
|
+
opts.on_tail('--version', 'Show version') do
|
49
71
|
puts "daemons version #{Daemons::VERSION}"
|
50
72
|
exit
|
51
73
|
end
|
52
|
-
end
|
53
|
-
|
74
|
+
end
|
75
|
+
|
54
76
|
begin
|
55
77
|
@usage = @opts.to_s
|
56
78
|
rescue ::Exception # work around a bug in ruby 1.9
|
@@ -65,57 +87,48 @@ module Daemons
|
|
65
87
|
END
|
66
88
|
end
|
67
89
|
end
|
68
|
-
|
69
|
-
|
70
|
-
#
|
90
|
+
|
71
91
|
# Return a hash describing the options.
|
72
92
|
#
|
73
93
|
def parse(args)
|
74
94
|
# The options specified on the command line will be collected in *options*.
|
75
95
|
# We set default values here.
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
##pp args
|
96
|
+
|
80
97
|
@opts.parse(args)
|
81
|
-
|
82
|
-
return @options
|
83
|
-
end
|
84
98
|
|
99
|
+
@options
|
100
|
+
end
|
85
101
|
end
|
86
|
-
|
87
|
-
|
102
|
+
|
88
103
|
class Controller
|
89
|
-
|
90
104
|
def print_usage
|
91
|
-
puts
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
+
puts <<-USAGE.gsub(/^ {6}/, '')
|
106
|
+
Usage: #{@app_name} <command> <options> -- <application options>
|
107
|
+
|
108
|
+
* where <command> is one of:
|
109
|
+
start start an instance of the application
|
110
|
+
stop stop all instances of the application
|
111
|
+
restart stop all instances and restart them afterwards
|
112
|
+
reload send a SIGHUP to all instances of the application
|
113
|
+
run run the application in the foreground (same as start -t)
|
114
|
+
zap set the application to a stopped state
|
115
|
+
status show status (PID) of application instances
|
116
|
+
|
117
|
+
* and where <options> may contain several of the following:
|
118
|
+
#{@optparse.usage}
|
119
|
+
USAGE
|
105
120
|
end
|
106
|
-
|
121
|
+
|
107
122
|
def catch_exceptions(&block)
|
108
123
|
begin
|
109
124
|
block.call
|
110
125
|
rescue CmdException, OptionParser::ParseError => e
|
111
|
-
puts "ERROR: #{e
|
126
|
+
puts "ERROR: #{e}"
|
112
127
|
puts
|
113
|
-
print_usage
|
128
|
+
print_usage
|
114
129
|
rescue RuntimeException => e
|
115
|
-
puts "ERROR: #{e
|
130
|
+
puts "ERROR: #{e}"
|
116
131
|
end
|
117
132
|
end
|
118
|
-
|
119
133
|
end
|
120
|
-
|
121
134
|
end
|
data/lib/daemons/controller.rb
CHANGED
@@ -1,70 +1,56 @@
|
|
1
1
|
|
2
2
|
module Daemons
|
3
3
|
class Controller
|
4
|
-
|
5
4
|
attr_reader :app_name
|
6
|
-
|
5
|
+
|
7
6
|
attr_reader :group
|
8
|
-
|
7
|
+
|
9
8
|
attr_reader :options
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
'start',
|
14
|
-
'stop',
|
15
|
-
'restart',
|
16
|
-
'run',
|
17
|
-
'zap',
|
18
|
-
'reload',
|
19
|
-
'status'
|
20
|
-
]
|
21
|
-
|
9
|
+
|
10
|
+
COMMANDS = %w(start stop restart run zap reload status)
|
11
|
+
|
22
12
|
def initialize(options = {}, argv = [])
|
23
13
|
@options = options
|
24
14
|
@argv = argv
|
25
|
-
|
15
|
+
|
26
16
|
# Allow an app_name to be specified. If not specified use the
|
27
17
|
# basename of the script.
|
28
18
|
@app_name = options[:app_name]
|
29
|
-
|
19
|
+
|
30
20
|
if options[:script]
|
31
21
|
@script = File.expand_path(options[:script])
|
32
|
-
|
22
|
+
|
33
23
|
@app_name ||= File.split(@script)[1]
|
34
24
|
end
|
35
|
-
|
25
|
+
|
36
26
|
@app_name ||= 'unknown_application'
|
37
|
-
|
27
|
+
|
38
28
|
@command, @controller_part, @app_part = Controller.split_argv(argv)
|
39
|
-
|
40
|
-
|
41
|
-
|
29
|
+
|
30
|
+
# @options[:dir_mode] ||= :script
|
31
|
+
|
42
32
|
@optparse = Optparse.new(self)
|
43
33
|
end
|
44
|
-
|
45
|
-
|
34
|
+
|
46
35
|
# This function is used to do a final update of the options passed to the application
|
47
36
|
# before they are really used.
|
48
37
|
#
|
49
38
|
# Note that this function should only update <tt>@options</tt> and no other variables.
|
50
39
|
#
|
51
40
|
def setup_options
|
52
|
-
#@options[:ontop] ||= true
|
53
41
|
end
|
54
|
-
|
42
|
+
|
55
43
|
def run
|
56
|
-
@options.update @optparse.parse(@controller_part).delete_if {|k,v| !v}
|
57
|
-
|
58
|
-
setup_options
|
59
|
-
|
60
|
-
#pp @options
|
44
|
+
@options.update @optparse.parse(@controller_part).delete_if { |k, v| !v }
|
45
|
+
|
46
|
+
setup_options
|
61
47
|
|
62
48
|
@group = ApplicationGroup.new(@app_name, @options)
|
63
49
|
@group.controller_argv = @controller_part
|
64
50
|
@group.app_argv = @app_part
|
65
|
-
|
51
|
+
|
66
52
|
@group.setup
|
67
|
-
|
53
|
+
|
68
54
|
case @command
|
69
55
|
when 'start'
|
70
56
|
@group.new_application.start
|
@@ -75,11 +61,11 @@ module Daemons
|
|
75
61
|
@group.stop_all(@options[:no_wait])
|
76
62
|
when 'restart'
|
77
63
|
unless @group.applications.empty?
|
78
|
-
@group.stop_all
|
64
|
+
@group.stop_all(@options[:no_wait])
|
79
65
|
sleep(1)
|
80
66
|
@group.start_all
|
81
67
|
else
|
82
|
-
puts "
|
68
|
+
$stderr.puts "#{@group.app_name}: warning: no instances running. Starting..."
|
83
69
|
@group.new_application.start
|
84
70
|
end
|
85
71
|
when 'reload'
|
@@ -89,21 +75,18 @@ module Daemons
|
|
89
75
|
when 'status'
|
90
76
|
unless @group.applications.empty?
|
91
77
|
@group.show_status
|
78
|
+
exit 3 if not @group.running? # exit with status 3 to indicate that no apps are running
|
92
79
|
else
|
93
|
-
puts "#{@group.app_name}: no instances running"
|
80
|
+
$stderr.puts "#{@group.app_name}: no instances running"
|
81
|
+
exit 3 # exit with status 3 to indicate that no apps are running
|
94
82
|
end
|
95
83
|
when nil
|
96
|
-
|
97
|
-
#puts "ERROR: No command given"; puts
|
98
|
-
|
99
|
-
#print_usage()
|
100
|
-
#raise('usage function not implemented')
|
84
|
+
fail CmdException.new('no command given')
|
101
85
|
else
|
102
|
-
|
86
|
+
fail Error.new("command '#{@command}' not implemented")
|
103
87
|
end
|
104
88
|
end
|
105
|
-
|
106
|
-
|
89
|
+
|
107
90
|
# Split an _argv_ array.
|
108
91
|
# +argv+ is assumed to be in the following format:
|
109
92
|
# ['command', 'controller option 1', 'controller option 2', ..., '--', 'app option 1', ...]
|
@@ -113,28 +96,27 @@ module Daemons
|
|
113
96
|
# *Returns*: the command as a string, the controller options as an array, the appliation options
|
114
97
|
# as an array
|
115
98
|
#
|
116
|
-
def
|
99
|
+
def self.split_argv(argv)
|
117
100
|
argv = argv.dup
|
118
|
-
|
101
|
+
|
119
102
|
command = nil
|
120
103
|
controller_part = []
|
121
104
|
app_part = []
|
122
|
-
|
105
|
+
|
123
106
|
if COMMANDS.include? argv[0]
|
124
107
|
command = argv.shift
|
125
108
|
end
|
126
|
-
|
109
|
+
|
127
110
|
if i = argv.index('--')
|
128
111
|
# Handle the case where no controller options are given, just
|
129
112
|
# options after "--" as well (i == 0)
|
130
|
-
controller_part = (i == 0 ? [] : argv[0..i-1])
|
131
|
-
app_part = argv[i+1..-1]
|
113
|
+
controller_part = (i == 0 ? [] : argv[0..i - 1])
|
114
|
+
app_part = argv[i + 1..-1]
|
132
115
|
else
|
133
116
|
controller_part = argv[0..-1]
|
134
117
|
end
|
135
|
-
|
136
|
-
|
118
|
+
|
119
|
+
[command, controller_part, app_part]
|
137
120
|
end
|
138
121
|
end
|
139
|
-
|
140
122
|
end
|