rv 2.991 → 3

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.
Files changed (4) hide show
  1. data/CHANGELOG +1 -1
  2. data/README +8 -5
  3. data/lib/rv.rb +55 -19
  4. metadata +2 -2
data/CHANGELOG CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- v2.991. Gem'd; RDoc documentation; automated setup scripts; cluster support. Incompatible changes. Pre-release.
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 is known to work; Gentoo should work; others should work with minor or no changes.
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 sudo /etc/init.d/rv start
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 su -c "</tt>' and the first '<tt>< /dev/null...</tt>') and try running it by hand. Make sure you're using the correct user. You can also check <tt>/var/log/rv.log</tt> as well as the application log.
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>'ruby'</tt> - a string used to start the Ruby interpreter.
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
- 'ruby' => '/usr/bin/env ruby',
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
- # Examine matching applications
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 = File.open(pid_file).readlines.first.chomp rescue nil
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 running
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 running
138
- system %[nohup su -c "kill -9 #{pid} #{options['null_stream']}" #{options['user']} #{options['log_stream']}]
139
- running = nil
140
- note "stopped"
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 "not running"
143
- File.delete pid_file
154
+ note "has already died"
155
+ File.delete pid_file
144
156
  else
145
- note "pid file #{pid_file.inspect} not found. Application was probably not running."
157
+ note "not running"
146
158
  end
147
159
  when "start"
148
- unless running
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
- system %[nohup su -c "#{env_variables} #{options['ruby']} #{options['harness']} #{options['null_stream']}" #{options['user']} #{options['log_stream']} &]
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
- end while tries < options['max_tries'] and !File.exist?(pid_file)
158
- if File.exist?(pid_file)
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: "2.991"
7
- date: 2007-08-07 00:00:00 -04:00
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