bannister 0.0.1 → 0.0.2
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.
- data/Rakefile +10 -1
- data/lib/bannister/apache.rb +8 -1
- data/lib/bannister/recurse.rb +20 -8
- data/lib/bannister/version.rb +1 -1
- data/lib/bannister.rb +74 -1
- metadata +21 -8
data/Rakefile
CHANGED
@@ -3,6 +3,8 @@ CLEAN << ".yardoc"
|
|
3
3
|
CLEAN << FileList["*.gem"]
|
4
4
|
CLEAN << "doc"
|
5
5
|
|
6
|
+
DOC_FILES=Dir['*.md']
|
7
|
+
|
6
8
|
desc "Build the gem"
|
7
9
|
task :gem do
|
8
10
|
system "gem build bannister.gemspec"
|
@@ -10,5 +12,12 @@ end
|
|
10
12
|
|
11
13
|
desc "Build the YARD docs"
|
12
14
|
task :docs do
|
13
|
-
system "yardoc"
|
15
|
+
system "yardoc --files #{DOC_FILES.join(",")}"
|
16
|
+
end
|
17
|
+
|
18
|
+
task :doc => :docs
|
19
|
+
|
20
|
+
desc "Build the YARD developer docs, including private methods"
|
21
|
+
task :dev_docs do
|
22
|
+
system "yardoc --private --files #{DOC_FILES.join(",")}"
|
14
23
|
end
|
data/lib/bannister/apache.rb
CHANGED
@@ -27,10 +27,13 @@ module Bannister
|
|
27
27
|
catch :done do
|
28
28
|
20.times do
|
29
29
|
sleep(0.1)
|
30
|
+
# No need to trap error messages here, because `kill`
|
31
|
+
# gives us a meaningful error code
|
30
32
|
next if system "kill -0 #{pid} 2> /dev/null"
|
31
33
|
throw :done
|
32
34
|
end
|
33
|
-
|
35
|
+
|
36
|
+
raise "Apache2 (pid=#{pid}) failed to stop!"
|
34
37
|
end
|
35
38
|
end
|
36
39
|
end
|
@@ -80,6 +83,10 @@ module Bannister
|
|
80
83
|
|
81
84
|
private
|
82
85
|
|
86
|
+
# Read apache2's pid from {PidFilename}.
|
87
|
+
#
|
88
|
+
# @return [Integer] Apache's process id.
|
89
|
+
# @return nil if it's not there.
|
83
90
|
def read_pid()
|
84
91
|
if File.file?(PidFilename)
|
85
92
|
return Integer(File.read(PidFilename).strip)
|
data/lib/bannister/recurse.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Bannister
|
2
2
|
|
3
|
-
# Use the Recurse class to launch other
|
3
|
+
# Use the Recurse class to launch other apps with a runner script.
|
4
4
|
class Recurse
|
5
5
|
|
6
6
|
# @param [String] dir Directory to chdir to before running bannister
|
@@ -10,25 +10,37 @@ module Bannister
|
|
10
10
|
@dir=dir
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
# Run "
|
13
|
+
|
14
|
+
# Run "runner stop" and exit.
|
15
15
|
def stop
|
16
|
-
system "
|
16
|
+
system "./runner stop"
|
17
17
|
exit(0)
|
18
18
|
end
|
19
19
|
|
20
20
|
|
21
|
-
# If foreground is true, exec
|
22
|
-
#
|
21
|
+
# Run the application's runner. If foreground is true, exec
|
22
|
+
# "runner run" in @dir. Otherwise set up traps for the right
|
23
|
+
# signals to a backgrounded "runner start" process.
|
24
|
+
#
|
25
|
+
# @param [Boolean] foreground Pass true to run in the foreground, false
|
26
|
+
# otherwise.
|
23
27
|
def start(foreground=false)
|
24
28
|
Dir.chdir(@dir) do
|
25
29
|
if foreground
|
26
|
-
|
30
|
+
# We're replacing the current process with the child, so we want
|
31
|
+
# std* to go to the console
|
32
|
+
exec "./runner run"
|
27
33
|
else
|
28
34
|
trap("TERM"){stop()}
|
29
35
|
trap("HUP"){stop()}
|
30
36
|
|
31
|
-
|
37
|
+
# This ignores stdout and stderr. Since the child process expects to
|
38
|
+
# running in the background anyway, we expect it to make its own
|
39
|
+
# arrangements.
|
40
|
+
#
|
41
|
+
# Yes, this is lazy, but there's not a lot more we can do at this
|
42
|
+
# point without a higher-level error-handling facility.
|
43
|
+
system "./runner start &"
|
32
44
|
|
33
45
|
sleep()
|
34
46
|
end
|
data/lib/bannister/version.rb
CHANGED
data/lib/bannister.rb
CHANGED
@@ -3,8 +3,17 @@ require 'fileutils'
|
|
3
3
|
module Bannister
|
4
4
|
|
5
5
|
|
6
|
+
# List of scripts in script/startup sorted asciibetically. This is the order
|
7
|
+
# they will be launched in, but there is no further dependency checking
|
8
|
+
# between the scripts.
|
6
9
|
SCRIPTS = Dir['script/startup/*'].sort
|
10
|
+
|
11
|
+
# A list of pids of the started scripts. These will be sent TERM signals when
|
12
|
+
# bannister is stopped.
|
7
13
|
LAUNCHED_PIDS = []
|
14
|
+
|
15
|
+
# The location of the pidfile for the master process. This will be
|
16
|
+
# de-hard-coded in a future release.
|
8
17
|
PID_FILENAME = "pids/bannister.pid"
|
9
18
|
|
10
19
|
|
@@ -42,7 +51,6 @@ module Bannister
|
|
42
51
|
else # create it. The easiest way to do this is to write
|
43
52
|
# out a screenrc containing the relevant commands and
|
44
53
|
# let screen launch them
|
45
|
-
|
46
54
|
begin
|
47
55
|
write_screenrc(screenrc_filename)
|
48
56
|
|
@@ -90,18 +98,37 @@ module Bannister
|
|
90
98
|
end
|
91
99
|
|
92
100
|
|
101
|
+
|
93
102
|
private
|
103
|
+
# Method to see whether a bannister process for the current application
|
104
|
+
# is running or not.
|
105
|
+
#
|
106
|
+
# @return [Boolean] true if PID_FILENAME exists, false otherwise.
|
94
107
|
def running?
|
95
108
|
return File.exists?(PID_FILENAME)
|
96
109
|
end
|
97
110
|
|
98
111
|
|
112
|
+
# Generate the screen command for the passed script filename. Since this
|
113
|
+
# will only ever be called when running in the foreground, we append -X
|
114
|
+
# to the command. A title for the screen window is also generated based
|
115
|
+
# on the current directory name and the script filename.
|
116
|
+
#
|
117
|
+
# @param [String] script the filename of a script to run.
|
118
|
+
# @return [String] the screen command to run the script.
|
99
119
|
def command_for_script(script)
|
100
120
|
title = File.basename(FileUtils.pwd)+':'+File.basename(script)
|
101
121
|
return "screen -t '#{title}' #{script} -X"
|
102
122
|
end
|
103
123
|
|
104
124
|
|
125
|
+
# Generate a screen config file and save it to the passed screenrc_filename.
|
126
|
+
# Screen is set up to allow restarting of dead processes with the 'r' key,
|
127
|
+
# and to give each script a meaningful title in the status line.
|
128
|
+
#
|
129
|
+
# @param [String] screenrc_filename the filename to save the
|
130
|
+
# generated config file to.
|
131
|
+
# @return [NilClass] nil.
|
105
132
|
def write_screenrc(screenrc_filename)
|
106
133
|
File.open(screenrc_filename, "wb") do |f|
|
107
134
|
f.write <<-SCREENRC
|
@@ -113,10 +140,18 @@ SCREENRC
|
|
113
140
|
f.puts( command_for_script(script) )
|
114
141
|
end
|
115
142
|
end
|
143
|
+
|
144
|
+
return nil
|
116
145
|
end
|
117
146
|
|
118
147
|
|
119
148
|
|
149
|
+
# Daemonize the bannister process and yield. Used when running in
|
150
|
+
# the background. This is a slightly different daemonize method to
|
151
|
+
# the usual, in that we need to be sure that the script filenames in
|
152
|
+
# SCRIPT don't lose their relative location, so we chdir to '/'
|
153
|
+
# *after* kicking them off. It's each individual script's
|
154
|
+
# responsibility to daemonise properly.
|
120
155
|
def daemonize()
|
121
156
|
exit!(0) if fork
|
122
157
|
Process::setsid
|
@@ -132,25 +167,43 @@ SCREENRC
|
|
132
167
|
# and if any of them rely on relative paths, they won't get
|
133
168
|
# broken
|
134
169
|
Dir::chdir("/")
|
170
|
+
|
171
|
+
return nil
|
135
172
|
end
|
136
173
|
|
137
174
|
|
175
|
+
# Set up our environment and launch everything in the background.
|
138
176
|
def do_start()
|
139
177
|
set_name()
|
140
178
|
drop_pid()
|
141
179
|
launch_all()
|
142
180
|
end
|
143
181
|
|
182
|
+
# Set the process name to something meaningful. In this case,
|
183
|
+
# "something meaningful" means "bannister:" + the name of the
|
184
|
+
# directory we're in. This makes it easy to see which bannister pids
|
185
|
+
# are responsible for which applications.
|
186
|
+
#
|
187
|
+
# @return [NilClass] nil.
|
144
188
|
def set_name
|
145
189
|
$0 = "bannister:"+File.basename(FileUtils.pwd)
|
190
|
+
|
191
|
+
return nil
|
146
192
|
end
|
147
193
|
|
194
|
+
# Record the current pid somewhere it can be found later
|
148
195
|
def drop_pid
|
149
196
|
system "mkdir -p #{File.dirname PID_FILENAME}"
|
150
197
|
File.open(PID_FILENAME, "w"){|f| f.write $$.to_s}
|
198
|
+
|
199
|
+
return nil
|
151
200
|
end
|
152
201
|
|
153
202
|
|
203
|
+
# Read the pid from where drop_pid left it, or nil if it's not there.
|
204
|
+
#
|
205
|
+
# @return [Fixnum] pid as integer if it exists
|
206
|
+
# @return [NilClass] nil otherwise.
|
154
207
|
def read_pid
|
155
208
|
if File.exists?(PID_FILENAME)
|
156
209
|
return Integer(File.read(PID_FILENAME).strip)
|
@@ -160,31 +213,51 @@ SCREENRC
|
|
160
213
|
end
|
161
214
|
|
162
215
|
|
216
|
+
# Clear the pid that drop_pid left behind.
|
217
|
+
#
|
218
|
+
# @return [NilClass] nil.
|
163
219
|
def remove_pid
|
164
220
|
FileUtils.rm_f(PID_FILENAME)
|
221
|
+
|
222
|
+
return nil
|
165
223
|
end
|
166
224
|
|
167
225
|
|
226
|
+
# Fork and exec each of SCRIPTS.
|
227
|
+
#
|
228
|
+
# @return [NilClass] nil.
|
168
229
|
def launch_all()
|
169
230
|
SCRIPTS.each do |script|
|
170
231
|
LAUNCHED_PIDS << fork do
|
171
232
|
exec script
|
172
233
|
end
|
173
234
|
end
|
235
|
+
|
236
|
+
return nil
|
174
237
|
end
|
175
238
|
|
176
239
|
|
240
|
+
# Call Process.waitpid on each process launched by launch_all.
|
241
|
+
#
|
242
|
+
# @return [NilClass] nil.
|
177
243
|
def wait_for_all()
|
178
244
|
LAUNCHED_PIDS.each do |pid|
|
179
245
|
Process.waitpid(pid)
|
180
246
|
end
|
247
|
+
|
248
|
+
return nil
|
181
249
|
end
|
182
250
|
|
183
251
|
|
252
|
+
# Send the TERM signal to each process launched by launch_all.
|
253
|
+
#
|
254
|
+
# @return [NilClass] nil.
|
184
255
|
def kill_all()
|
185
256
|
LAUNCHED_PIDS.each do |pid|
|
186
257
|
system "kill -15 #{pid}"
|
187
258
|
end
|
259
|
+
|
260
|
+
return nil
|
188
261
|
end
|
189
262
|
|
190
263
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bannister
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Alex Young
|
@@ -15,10 +15,23 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-10-13 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: bluecloth
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
22
35
|
description: |
|
23
36
|
An application launcher which maintains a tree of processes to keep background
|
24
37
|
processes tied to the launcher.
|
@@ -33,9 +46,9 @@ extra_rdoc_files: []
|
|
33
46
|
|
34
47
|
files:
|
35
48
|
- bin/bannister
|
36
|
-
- lib/bannister/apache.rb
|
37
|
-
- lib/bannister/recurse.rb
|
38
49
|
- lib/bannister/version.rb
|
50
|
+
- lib/bannister/recurse.rb
|
51
|
+
- lib/bannister/apache.rb
|
39
52
|
- lib/bannister.rb
|
40
53
|
- README.md
|
41
54
|
- Rakefile
|