bluepill 0.0.36 → 0.0.37
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +7 -0
- data/VERSION +1 -1
- data/bluepill.gemspec +4 -3
- data/lib/bluepill/application.rb +9 -4
- data/lib/bluepill/dsl.rb +17 -13
- data/lib/bluepill/group.rb +7 -1
- data/lib/bluepill/logger.rb +11 -6
- data/lib/bluepill/process.rb +27 -30
- data/lib/bluepill/version.rb +1 -1
- data/lib/example.rb +5 -2
- data/lib/runit_example.rb +24 -0
- metadata +3 -2
data/README.md
CHANGED
@@ -211,6 +211,13 @@ By default, bluepill uses syslog local6 facility as described in the installatio
|
|
211
211
|
|
212
212
|
Keep in mind that you still need to set up log rotation (described in the installation section) to keep the log file from growing huge.
|
213
213
|
|
214
|
+
### Extra options
|
215
|
+
You can run bluepill in the foreground:
|
216
|
+
|
217
|
+
Bluepill.application("app_name", :foreground => true) do |app|
|
218
|
+
# ...
|
219
|
+
end
|
220
|
+
|
214
221
|
## Links
|
215
222
|
Code: [http://github.com/arya/bluepill](http://github.com/arya/bluepill)
|
216
223
|
Bugs/Features: [http://github.com/arya/bluepill/issues](http://github.com/arya/bluepill/issues)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.37
|
data/bluepill.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bluepill}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.37"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Arya Asemanfar", "Gary Tsang", "Rohith Ravi"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-03-14}
|
13
13
|
s.default_executable = %q{bluepill}
|
14
14
|
s.description = %q{Bluepill keeps your daemons up while taking up as little resources as possible. After all you probably want the resources of your server to be used by whatever daemons you are running rather than the thing that's supposed to make sure they are brought back up, should they die or misbehave.}
|
15
15
|
s.email = %q{entombedvirus@gmail.com}
|
@@ -50,7 +50,8 @@ Gem::Specification.new do |s|
|
|
50
50
|
"lib/bluepill/triggers/flapping.rb",
|
51
51
|
"lib/bluepill/util/rotational_array.rb",
|
52
52
|
"lib/bluepill/version.rb",
|
53
|
-
"lib/example.rb"
|
53
|
+
"lib/example.rb",
|
54
|
+
"lib/runit_example.rb"
|
54
55
|
]
|
55
56
|
s.homepage = %q{http://github.com/arya/bluepill}
|
56
57
|
s.rdoc_options = ["--charset=UTF-8"]
|
data/lib/bluepill/application.rb
CHANGED
@@ -11,6 +11,7 @@ module Bluepill
|
|
11
11
|
def initialize(name, options = {})
|
12
12
|
self.name = name
|
13
13
|
|
14
|
+
@foreground = options[:foreground]
|
14
15
|
self.log_file = options[:log_file]
|
15
16
|
self.base_dir = options[:base_dir] || '/var/bluepill'
|
16
17
|
self.pid_file = File.join(self.base_dir, 'pids', self.name + ".pid")
|
@@ -18,7 +19,7 @@ module Bluepill
|
|
18
19
|
|
19
20
|
self.groups = {}
|
20
21
|
|
21
|
-
self.logger = Bluepill::Logger.new(:log_file => self.log_file).prefix_with(self.name)
|
22
|
+
self.logger = Bluepill::Logger.new(:log_file => self.log_file, :stdout => foreground?).prefix_with(self.name)
|
22
23
|
|
23
24
|
self.setup_signal_traps
|
24
25
|
self.setup_pids_dir
|
@@ -26,6 +27,10 @@ module Bluepill
|
|
26
27
|
@mutex = Mutex.new
|
27
28
|
end
|
28
29
|
|
30
|
+
def foreground?
|
31
|
+
!!@foreground
|
32
|
+
end
|
33
|
+
|
29
34
|
def mutex(&b)
|
30
35
|
@mutex.synchronize(&b)
|
31
36
|
end
|
@@ -109,13 +114,13 @@ module Bluepill
|
|
109
114
|
def start_server
|
110
115
|
self.kill_previous_bluepill
|
111
116
|
|
112
|
-
Daemonize.daemonize
|
117
|
+
Daemonize.daemonize unless foreground?
|
113
118
|
|
114
119
|
self.logger.reopen
|
115
120
|
|
116
121
|
$0 = "bluepilld: #{self.name}"
|
117
122
|
|
118
|
-
self.groups.each {|_, group| group.
|
123
|
+
self.groups.each {|_, group| group.determine_initial_state }
|
119
124
|
|
120
125
|
|
121
126
|
self.write_pid_file
|
@@ -192,4 +197,4 @@ module Bluepill
|
|
192
197
|
File.open(self.pid_file, 'w') { |x| x.write(::Process.pid) }
|
193
198
|
end
|
194
199
|
end
|
195
|
-
end
|
200
|
+
end
|
data/lib/bluepill/dsl.rb
CHANGED
@@ -38,19 +38,21 @@ module Bluepill
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
+
def create_child_process_template
|
42
|
+
if @child_process_block
|
43
|
+
child_proxy = self.class.new
|
44
|
+
# Children inherit some properties of the parent
|
45
|
+
[:start_grace_time, :stop_grace_time, :restart_grace_time].each do |attribute|
|
46
|
+
child_proxy.send("#{attributes}=", @attributes[attribute]) if @attributes.key?(attribute)
|
47
|
+
end
|
48
|
+
@child_process_block.call(child_proxy)
|
49
|
+
validate_child_process(child_proxy)
|
50
|
+
@attributes[:child_process_template] = child_proxy.to_process(nil)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
41
54
|
def monitor_children(&child_process_block)
|
42
|
-
|
43
|
-
|
44
|
-
# Children inherit some properties of the parent
|
45
|
-
child_proxy.start_grace_time = @attributes[:start_grace_time]
|
46
|
-
child_proxy.stop_grace_time = @attributes[:stop_grace_time]
|
47
|
-
child_proxy.restart_grace_time = @attributes[:restart_grace_time]
|
48
|
-
|
49
|
-
child_process_block.call(child_proxy)
|
50
|
-
validate_child_process(child_proxy)
|
51
|
-
|
52
|
-
@attributes[:child_process_template] = child_proxy.to_process(nil)
|
53
|
-
# @attributes[:child_process_template].freeze
|
55
|
+
@child_process_block = child_process_block
|
54
56
|
@attributes[:monitor_children] = true
|
55
57
|
end
|
56
58
|
|
@@ -108,13 +110,15 @@ module Bluepill
|
|
108
110
|
def process(process_name, &process_block)
|
109
111
|
process_proxy = @@process_proxy.new(process_name)
|
110
112
|
process_block.call(process_proxy)
|
113
|
+
process_proxy.create_child_process_template
|
114
|
+
|
111
115
|
set_app_wide_attributes(process_proxy)
|
112
116
|
|
113
117
|
assign_default_pid_file(process_proxy, process_name)
|
114
118
|
|
115
119
|
validate_process(process_proxy, process_name)
|
116
120
|
|
117
|
-
group = process_proxy.attributes.delete(:group)
|
121
|
+
group = process_proxy.attributes.delete(:group)
|
118
122
|
process = process_proxy.to_process(process_name)
|
119
123
|
|
120
124
|
|
data/lib/bluepill/group.rb
CHANGED
@@ -19,9 +19,15 @@ module Bluepill
|
|
19
19
|
process.tick
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
def determine_initial_state
|
24
|
+
self.processes.each do |process|
|
25
|
+
process.determine_initial_state
|
26
|
+
end
|
27
|
+
end
|
22
28
|
|
23
29
|
# proxied events
|
24
|
-
[:start, :unmonitor, :stop, :restart
|
30
|
+
[:start, :unmonitor, :stop, :restart].each do |event|
|
25
31
|
class_eval <<-END
|
26
32
|
def #{event}(process_name = nil)
|
27
33
|
threads = []
|
data/lib/bluepill/logger.rb
CHANGED
@@ -3,9 +3,10 @@ module Bluepill
|
|
3
3
|
LOG_METHODS = [:emerg, :alert, :crit, :err, :warning, :notice, :info, :debug]
|
4
4
|
|
5
5
|
def initialize(options = {})
|
6
|
-
@options
|
7
|
-
@logger
|
8
|
-
@prefix
|
6
|
+
@options = options
|
7
|
+
@logger = options[:logger] || self.create_logger
|
8
|
+
@prefix = options[:prefix]
|
9
|
+
@stdout = options[:stdout]
|
9
10
|
@prefixes = {}
|
10
11
|
end
|
11
12
|
|
@@ -15,8 +16,12 @@ module Bluepill
|
|
15
16
|
if @logger.is_a?(self.class)
|
16
17
|
@logger.#{method}(msg, [@prefix] + prefix)
|
17
18
|
else
|
18
|
-
|
19
|
-
@
|
19
|
+
s_prefix = prefix.size > 0 ? "[\#{prefix.compact.join(':')}] " : ""
|
20
|
+
if @stdout
|
21
|
+
$stdout.puts("[#{method}]: \#{s_prefix}\#{msg}")
|
22
|
+
$stdout.flush
|
23
|
+
end
|
24
|
+
@logger.#{method}("\#{s_prefix}\#{msg}")
|
20
25
|
end
|
21
26
|
end
|
22
27
|
END
|
@@ -54,4 +59,4 @@ module Bluepill
|
|
54
59
|
end
|
55
60
|
end
|
56
61
|
end
|
57
|
-
end
|
62
|
+
end
|
data/lib/bluepill/process.rb
CHANGED
@@ -93,18 +93,16 @@ module Bluepill
|
|
93
93
|
@children = []
|
94
94
|
@statistics = ProcessStatistics.new
|
95
95
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
instance_variable_set("@#{grace}", options[grace.to_sym] || 3)
|
100
|
-
end
|
96
|
+
# These defaults are overriden below if it's configured to be something else.
|
97
|
+
@monitor_children = false
|
98
|
+
@start_grace_time = @stop_grace_time = @restart_grace_time = 3
|
101
99
|
|
102
100
|
CONFIGURABLE_ATTRIBUTES.each do |attribute_name|
|
103
101
|
self.send("#{attribute_name}=", options[attribute_name]) if options.has_key?(attribute_name)
|
104
102
|
end
|
105
|
-
|
103
|
+
|
106
104
|
# Let state_machine do its initialization stuff
|
107
|
-
super()
|
105
|
+
super() # no arguments intentional
|
108
106
|
end
|
109
107
|
|
110
108
|
def tick
|
@@ -118,9 +116,9 @@ module Bluepill
|
|
118
116
|
super
|
119
117
|
|
120
118
|
if self.up?
|
121
|
-
run_watches
|
119
|
+
self.run_watches
|
122
120
|
|
123
|
-
if monitor_children?
|
121
|
+
if self.monitor_children?
|
124
122
|
refresh_children!
|
125
123
|
children.each {|child| child.tick}
|
126
124
|
end
|
@@ -194,31 +192,28 @@ module Bluepill
|
|
194
192
|
end
|
195
193
|
end
|
196
194
|
|
195
|
+
def determine_initial_state
|
196
|
+
if self.process_running?(true)
|
197
|
+
self.state = 'up'
|
198
|
+
else
|
199
|
+
# TODO: or "unmonitored" if bluepill was started in no auto-start mode.
|
200
|
+
self.state = 'down'
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
197
204
|
def handle_user_command(cmd)
|
198
205
|
case cmd
|
199
|
-
when "boot"
|
200
|
-
# This is only called when bluepill is initially starting up
|
201
|
-
if process_running?(true)
|
202
|
-
# process was running even before bluepill was
|
203
|
-
self.state = 'up'
|
204
|
-
else
|
205
|
-
self.state = 'starting'
|
206
|
-
end
|
207
|
-
|
208
206
|
when "start"
|
209
|
-
if process_running?(true)
|
210
|
-
logger.warning("Refusing to re-run start command on an
|
211
|
-
|
207
|
+
if self.process_running?(true)
|
208
|
+
logger.warning("Refusing to re-run start command on an already running process.")
|
209
|
+
else
|
210
|
+
dispatch!(:start, "user initiated")
|
212
211
|
end
|
213
|
-
dispatch!(:start, "user initiated")
|
214
|
-
|
215
212
|
when "stop"
|
216
213
|
stop_process
|
217
214
|
dispatch!(:unmonitor, "user initiated")
|
218
|
-
|
219
215
|
when "restart"
|
220
216
|
restart_process
|
221
|
-
|
222
217
|
when "unmonitor"
|
223
218
|
# When the user issues an unmonitor cmd, reset any triggers so that
|
224
219
|
# scheduled events gets cleared
|
@@ -229,8 +224,10 @@ module Bluepill
|
|
229
224
|
|
230
225
|
# System Process Methods
|
231
226
|
def process_running?(force = false)
|
232
|
-
@process_running = nil if force
|
227
|
+
@process_running = nil if force # clear existing state if forced
|
228
|
+
|
233
229
|
@process_running ||= signal_process(0)
|
230
|
+
# the process isn't running, so we should clear the PID
|
234
231
|
self.clear_pid unless @process_running
|
235
232
|
@process_running
|
236
233
|
end
|
@@ -258,7 +255,7 @@ module Bluepill
|
|
258
255
|
|
259
256
|
def stop_process
|
260
257
|
if stop_command
|
261
|
-
cmd =
|
258
|
+
cmd = self.prepare_command(stop_command)
|
262
259
|
logger.warning "Executing stop command: #{cmd}"
|
263
260
|
|
264
261
|
with_timeout(stop_grace_time) do
|
@@ -281,7 +278,7 @@ module Bluepill
|
|
281
278
|
|
282
279
|
def restart_process
|
283
280
|
if restart_command
|
284
|
-
cmd =
|
281
|
+
cmd = self.prepare_command(restart_command)
|
285
282
|
|
286
283
|
logger.warning "Executing restart command: #{cmd}"
|
287
284
|
|
@@ -384,8 +381,8 @@ module Bluepill
|
|
384
381
|
Marshal.load(Marshal.dump(self))
|
385
382
|
end
|
386
383
|
|
387
|
-
def
|
388
|
-
|
384
|
+
def prepare_command(command)
|
385
|
+
command.to_s.gsub("{{PID}}", actual_pid.to_s)
|
389
386
|
end
|
390
387
|
|
391
388
|
def system_command_options
|
data/lib/bluepill/version.rb
CHANGED
data/lib/example.rb
CHANGED
@@ -15,7 +15,7 @@ end
|
|
15
15
|
|
16
16
|
# Watch with
|
17
17
|
# watch -n0.2 'ps axu | egrep "(CPU|forking|bluepill|sleep)" | grep -v grep | sort'
|
18
|
-
Bluepill.application(:sample_app) do |app|
|
18
|
+
Bluepill.application(:sample_app, :foreground => true) do |app|
|
19
19
|
0.times do |i|
|
20
20
|
app.process("process_#{i}") do |process|
|
21
21
|
process.pid_file = "#{ROOT_DIR}/pids/process_#{i}.pid"
|
@@ -70,7 +70,7 @@ Bluepill.application(:sample_app) do |app|
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
-
|
73
|
+
1.times do |i|
|
74
74
|
app.process("group_process_#{i}") do |process|
|
75
75
|
# process.uid = "deploy"
|
76
76
|
# process.gid = "deploy"
|
@@ -79,6 +79,9 @@ Bluepill.application(:sample_app) do |app|
|
|
79
79
|
# process.stdout = "/tmp/err.log"
|
80
80
|
|
81
81
|
# process.group = "grouped"
|
82
|
+
process.monitor_children do |child_process|
|
83
|
+
child_process.stop_command = "kill -QUIT {{PID}}"
|
84
|
+
end
|
82
85
|
|
83
86
|
process.start_command = "ruby /tmp/foo.rb"
|
84
87
|
process.stop_command = "kill {{PID}}"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bluepill'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
# ATTENTION:
|
6
|
+
# You must declare only one application per config when foreground mode specified
|
7
|
+
|
8
|
+
# Watch with
|
9
|
+
# watch -n0.2 'ps axu | egrep "(CPU|forking|bluepill|sleep)" | grep -v grep | sort'
|
10
|
+
Bluepill.application(:opscode_agent, :foreground => true) do |app|
|
11
|
+
app.process("opscode_agent") do |process|
|
12
|
+
process.pid_file = "/etc/service/opscode-agent/supervise/pid"
|
13
|
+
|
14
|
+
process.start_command = "sv start opscode-agent"
|
15
|
+
process.stop_command = "sv stop opscode-agent"
|
16
|
+
|
17
|
+
process.start_grace_time = 1.seconds
|
18
|
+
process.restart_grace_time = 7.seconds
|
19
|
+
process.stop_grace_time = 7.seconds
|
20
|
+
|
21
|
+
# process.checks :cpu_usage, :every => 10, :below => 0.5, :times => [5, 5]
|
22
|
+
process.checks :flapping, :times => 2, :within => 30.seconds, :retry_in => 7.seconds
|
23
|
+
end
|
24
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bluepill
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.37
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arya Asemanfar
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2010-
|
14
|
+
date: 2010-03-14 00:00:00 -08:00
|
15
15
|
default_executable: bluepill
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
@@ -96,6 +96,7 @@ files:
|
|
96
96
|
- lib/bluepill/util/rotational_array.rb
|
97
97
|
- lib/bluepill/version.rb
|
98
98
|
- lib/example.rb
|
99
|
+
- lib/runit_example.rb
|
99
100
|
has_rdoc: true
|
100
101
|
homepage: http://github.com/arya/bluepill
|
101
102
|
licenses: []
|