rv 2.991 → 3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +1 -1
- data/README +8 -5
- data/lib/rv.rb +55 -19
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
v3. Gem'd; RDoc documentation; automated setup scripts; cluster support; accurate status reporting. Incompatible changes
|
3
3
|
|
4
4
|
v2. Mongrel static directory handler.
|
5
5
|
|
data/README
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
Rv
|
3
3
|
|
4
|
-
A little <tt>init.d</tt> system for running Camping apps.
|
4
|
+
A little <tt>init.d</tt> system for running Camping apps, for Linux.
|
5
5
|
|
6
6
|
== License
|
7
7
|
|
@@ -12,8 +12,11 @@ Copyright 2007 Cloudburst, LLC. See the included LICENSE file.
|
|
12
12
|
* cluster support
|
13
13
|
* custom database configuration
|
14
14
|
* interactive setup tasks
|
15
|
+
* logging
|
15
16
|
|
16
|
-
Linux is required. Ubuntu
|
17
|
+
Linux is required. Ubuntu and Gentoo are known to work.
|
18
|
+
|
19
|
+
Rv is designed for Camping, but it can actually manage any app for which you write a compatible Mongrel harness.
|
17
20
|
|
18
21
|
= Usage
|
19
22
|
|
@@ -46,10 +49,10 @@ The script also responds to <tt>status</tt>, <tt>restart</tt>, and <tt>stop</tt>
|
|
46
49
|
|
47
50
|
== Troubleshooting
|
48
51
|
|
49
|
-
If you're having problems, run:
|
50
|
-
RV_DEBUG=true
|
52
|
+
If you're having problems, first check <tt>/var/log/rv.log</tt>. If that doesn't help, run:
|
53
|
+
sudo env RV_DEBUG=true /etc/init.d/rv start
|
51
54
|
|
52
|
-
Copy out the inner command (between the '<tt>nohup
|
55
|
+
Copy out the inner command (between the '<tt>nohup sudo -u httpd</tt>' and the '<tt>< /dev/null</tt>') and try running it by hand. Make sure you're using the correct user.
|
53
56
|
|
54
57
|
== Apache configuration
|
55
58
|
|
data/lib/rv.rb
CHANGED
@@ -11,7 +11,8 @@ Available keys are:
|
|
11
11
|
* <tt>'user'</tt> - the system user used to start the apps.
|
12
12
|
* <tt>'max_tries'</tt> - the number of retries before giving up on an app (each try takes a half second).
|
13
13
|
* <tt>'log'</tt> - the path to Rv's own logfile.
|
14
|
-
* <tt>'
|
14
|
+
* <tt>'env'</tt> - the path to the <tt>env</tt> utility.
|
15
|
+
* <tt>'ruby'</tt> - the name of the Ruby interpreter.
|
15
16
|
|
16
17
|
=end
|
17
18
|
|
@@ -47,7 +48,8 @@ class Rv
|
|
47
48
|
|
48
49
|
DEFAULTS = {
|
49
50
|
'user' => 'httpd',
|
50
|
-
'
|
51
|
+
'env' => '/usr/bin/env',
|
52
|
+
'ruby' => 'ruby',
|
51
53
|
'conf_dir' => '/etc/rv',
|
52
54
|
'log' => '/var/log/rv.log',
|
53
55
|
'harness' => 'rv_harness.rb',
|
@@ -78,7 +80,6 @@ class Rv
|
|
78
80
|
end
|
79
81
|
system "chown #{options['user']} #{options['log']} #{options['null_stream']}"
|
80
82
|
system "chgrp #{options['user']} #{options['log']} #{options['null_stream']}"
|
81
|
-
|
82
83
|
end
|
83
84
|
|
84
85
|
# Perform any action in VALID_ACTIONS. Defaults to running against all applications. Pass a specific app name as <tt>match</tt> if this is not what you want.
|
@@ -89,6 +90,7 @@ class Rv
|
|
89
90
|
case action
|
90
91
|
when "restart"
|
91
92
|
daemon("stop", match)
|
93
|
+
sleep(5) # wait for the sockets to get released
|
92
94
|
daemon("start", match)
|
93
95
|
when "install"
|
94
96
|
install
|
@@ -105,9 +107,12 @@ class Rv
|
|
105
107
|
# Runs a daemon action. Only called from <tt>perform</tt>.
|
106
108
|
def daemon(action, match)
|
107
109
|
filenames = Dir["#{options['conf_dir']}/#{match}.yml"]
|
110
|
+
|
111
|
+
# sanity checks
|
108
112
|
exit_with("No applications found for '#{match}' in #{options['conf_dir']}/") if filenames.empty?
|
113
|
+
exit_with("Can't write to the log (#{options['log']})") unless check_log
|
109
114
|
|
110
|
-
#
|
115
|
+
# examine matching applications
|
111
116
|
filenames.each do |filename|
|
112
117
|
|
113
118
|
real_config = YAML.load_file(filename)
|
@@ -121,12 +126,11 @@ class Rv
|
|
121
126
|
@port = config['port'] += cluster_index
|
122
127
|
|
123
128
|
pid_file = Rv.pid_file(config['app'], config['port'])
|
124
|
-
pid =
|
125
|
-
running = pid ? `ps -p #{pid}`.split("\n")[1] : nil
|
129
|
+
pid = get_pid(pid_file)
|
126
130
|
|
127
131
|
case action
|
128
132
|
when "status"
|
129
|
-
if
|
133
|
+
if check_pid(pid)
|
130
134
|
note "running"
|
131
135
|
elsif pid
|
132
136
|
note "has died"
|
@@ -134,28 +138,38 @@ class Rv
|
|
134
138
|
note "not running"
|
135
139
|
end
|
136
140
|
when "stop"
|
137
|
-
if pid and
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
+
if pid and check_pid(pid)
|
142
|
+
# send a hard kill
|
143
|
+
run "kill -9 #{pid}"
|
144
|
+
# remove the pid file, since we didn't let mongrel to do it
|
145
|
+
sleep(0.5)
|
146
|
+
unless check_pid(pid)
|
147
|
+
File.delete(pid_file)
|
148
|
+
running = nil
|
149
|
+
note "stopped"
|
150
|
+
else
|
151
|
+
note "failed to stop"
|
152
|
+
end
|
141
153
|
elsif pid
|
142
|
-
note "
|
143
|
-
File.delete pid_file
|
154
|
+
note "has already died"
|
155
|
+
File.delete pid_file
|
144
156
|
else
|
145
|
-
note "
|
157
|
+
note "not running"
|
146
158
|
end
|
147
159
|
when "start"
|
148
|
-
unless
|
160
|
+
unless check_pid(pid)
|
161
|
+
# Gentoo requires the env variables to be set within the command, not before the sudo
|
149
162
|
env_variables = config.map {|key, value| "RV_#{key.upcase}=#{value}"}.join(" ")
|
150
|
-
|
151
|
-
|
163
|
+
run "#{options['env']} #{env_variables} #{options['ruby']} #{options['harness']}", true
|
152
164
|
# wait for the app to initialize
|
153
165
|
tries = 0
|
154
166
|
begin
|
155
167
|
sleep(0.5)
|
156
168
|
tries += 1
|
157
|
-
|
158
|
-
|
169
|
+
pid = get_pid(pid_file) # reset the pid
|
170
|
+
end while tries < options['max_tries'] and !(File.exist?(pid_file) and check_pid(pid))
|
171
|
+
|
172
|
+
if File.exist?(pid_file) and check_pid(pid)
|
159
173
|
note "started"
|
160
174
|
else
|
161
175
|
note "failed to start"
|
@@ -255,11 +269,33 @@ class Rv
|
|
255
269
|
puts msg
|
256
270
|
exit
|
257
271
|
end
|
272
|
+
|
273
|
+
# Makes sure the log is writeable.
|
274
|
+
def check_log
|
275
|
+
run "touch #{options['log']}"
|
276
|
+
end
|
277
|
+
|
278
|
+
# Reads a pid number from a pid_file.
|
279
|
+
def get_pid(pid_file)
|
280
|
+
File.open(pid_file).readlines.first.chomp rescue nil
|
281
|
+
end
|
258
282
|
|
283
|
+
# Checks if the process number <tt>pid</tt> is running.
|
284
|
+
def check_pid(pid = nil)
|
285
|
+
if pid
|
286
|
+
`ps -p #{pid}`.split("\n")[1]
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
259
290
|
# Prints a message along with the current port.
|
260
291
|
def note(msg)
|
261
292
|
puts " #{msg.capitalize} (#{@port})"
|
262
293
|
end
|
294
|
+
|
295
|
+
# Runs a command as the app user, with log redirects, in a way that doubly detaches from the terminal and doesn't require a shell.
|
296
|
+
def run(cmd, background = false)
|
297
|
+
system %[nohup sudo -u #{options['user']} #{cmd} #{options['log_stream']} #{'&' if background}]
|
298
|
+
end
|
263
299
|
|
264
300
|
# system() with debugging output
|
265
301
|
def system(string)
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: rv
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: "
|
7
|
-
date: 2007-08-
|
6
|
+
version: "3"
|
7
|
+
date: 2007-08-08 00:00:00 -04:00
|
8
8
|
summary: A little init.d system for running Camping apps.
|
9
9
|
require_paths:
|
10
10
|
- lib
|