daemons 1.1.9 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|