ra-bluepill 0.0.44 → 0.0.45
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/bin/bluepill +8 -3
- data/lib/bluepill/application.rb +1 -1
- data/lib/bluepill/controller.rb +16 -15
- data/lib/bluepill/process.rb +3 -1
- data/lib/bluepill/socket.rb +12 -1
- data/lib/bluepill/system.rb +3 -2
- data/lib/bluepill/trigger.rb +11 -2
- data/lib/bluepill/triggers/flapping.rb +4 -6
- data/ra-bluepill.gemspec +1 -1
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.45
|
data/bin/bluepill
CHANGED
@@ -6,7 +6,8 @@ require 'bluepill'
|
|
6
6
|
options = {
|
7
7
|
:log_file => "/var/log/bluepill.log",
|
8
8
|
:base_dir => "/var/bluepill",
|
9
|
-
:privileged => true
|
9
|
+
:privileged => true,
|
10
|
+
:timeout => 10
|
10
11
|
}
|
11
12
|
|
12
13
|
OptionParser.new do |opts|
|
@@ -28,6 +29,10 @@ OptionParser.new do |opts|
|
|
28
29
|
options[:privileged] = v
|
29
30
|
end
|
30
31
|
|
32
|
+
opts.on('-t', '--timeout Seconds', Integer, "Timeout for commands sent to the daemon, in seconds. Defaults to 10.") do |timeout|
|
33
|
+
options[:timeout] = timeout
|
34
|
+
end
|
35
|
+
|
31
36
|
help = proc do
|
32
37
|
puts opts
|
33
38
|
puts
|
@@ -57,7 +62,7 @@ end
|
|
57
62
|
|
58
63
|
APPLICATION_COMMANDS = %w(status start stop restart unmonitor quit log)
|
59
64
|
|
60
|
-
controller = Bluepill::Controller.new(options.slice(:base_dir, :log_file))
|
65
|
+
controller = Bluepill::Controller.new(options.slice(:base_dir, :log_file, :timeout))
|
61
66
|
|
62
67
|
if controller.running_applications.include?(File.basename($0)) && File.symlink?($0)
|
63
68
|
# bluepill was called as a symlink with the name of the target application
|
@@ -97,7 +102,7 @@ if options[:command] == "load"
|
|
97
102
|
file_path = File.expand_path(file)
|
98
103
|
|
99
104
|
exec(ruby, "-I#{load_path}", '-rbluepill', file_path)
|
100
|
-
|
105
|
+
|
101
106
|
else
|
102
107
|
$stderr.puts "Can't find file: #{file}"
|
103
108
|
end
|
data/lib/bluepill/application.rb
CHANGED
data/lib/bluepill/controller.rb
CHANGED
@@ -2,22 +2,23 @@ require 'fileutils'
|
|
2
2
|
|
3
3
|
module Bluepill
|
4
4
|
class Controller
|
5
|
-
attr_accessor :base_dir, :log_file, :sockets_dir, :pids_dir
|
6
|
-
|
5
|
+
attr_accessor :base_dir, :log_file, :sockets_dir, :pids_dir, :timeout
|
6
|
+
|
7
7
|
def initialize(options = {})
|
8
8
|
self.log_file = options[:log_file]
|
9
9
|
self.base_dir = options[:base_dir]
|
10
|
+
self.timeout = options[:timeout]
|
10
11
|
self.sockets_dir = File.join(base_dir, 'socks')
|
11
12
|
self.pids_dir = File.join(base_dir, 'pids')
|
12
|
-
|
13
|
+
|
13
14
|
setup_dir_structure
|
14
15
|
cleanup_bluepill_directory
|
15
16
|
end
|
16
|
-
|
17
|
+
|
17
18
|
def running_applications
|
18
19
|
Dir[File.join(sockets_dir, "*.sock")].map{|x| File.basename(x, ".sock")}
|
19
20
|
end
|
20
|
-
|
21
|
+
|
21
22
|
def handle_command(application, command, *args)
|
22
23
|
case command.to_sym
|
23
24
|
when :status
|
@@ -44,10 +45,10 @@ module Bluepill
|
|
44
45
|
when :log
|
45
46
|
log_file_location = self.send_to_daemon(application, :log_file)
|
46
47
|
log_file_location = self.log_file if log_file_location.to_s.strip.empty?
|
47
|
-
|
48
|
+
|
48
49
|
requested_pattern = args.first
|
49
50
|
grep_pattern = self.grep_pattern(application, requested_pattern)
|
50
|
-
|
51
|
+
|
51
52
|
tail = "tail -n 100 -f #{log_file_location} | grep -E '#{grep_pattern}'"
|
52
53
|
puts "Tailing log for #{requested_pattern}..."
|
53
54
|
Kernel.exec(tail)
|
@@ -56,13 +57,13 @@ module Bluepill
|
|
56
57
|
exit(1)
|
57
58
|
end
|
58
59
|
end
|
59
|
-
|
60
|
+
|
60
61
|
def send_to_daemon(application, command, *args)
|
61
62
|
begin
|
62
63
|
verify_version!(application)
|
63
64
|
|
64
65
|
command = ([command, *args]).join(":")
|
65
|
-
response = Socket.client_command(base_dir, application, command)
|
66
|
+
response = Socket.client_command(base_dir, application, command, timeout)
|
66
67
|
if response.is_a?(Exception)
|
67
68
|
$stderr.puts "Received error from server:"
|
68
69
|
$stderr.puts response.inspect
|
@@ -76,13 +77,13 @@ module Bluepill
|
|
76
77
|
abort("Connection Refused: Server is not running")
|
77
78
|
end
|
78
79
|
end
|
79
|
-
|
80
|
+
|
80
81
|
def grep_pattern(application, query = nil)
|
81
82
|
pattern = [application, query].compact.join(':')
|
82
83
|
['\[.*', Regexp.escape(pattern), '.*'].compact.join
|
83
84
|
end
|
84
85
|
private
|
85
|
-
|
86
|
+
|
86
87
|
def cleanup_bluepill_directory
|
87
88
|
self.running_applications.each do |app|
|
88
89
|
pid = pid_for(app)
|
@@ -94,21 +95,21 @@ module Bluepill
|
|
94
95
|
end
|
95
96
|
end
|
96
97
|
end
|
97
|
-
|
98
|
+
|
98
99
|
def pid_for(app)
|
99
100
|
pid_file = File.join(self.pids_dir, "#{app}.pid")
|
100
101
|
File.exists?(pid_file) && File.read(pid_file).to_i
|
101
102
|
end
|
102
|
-
|
103
|
+
|
103
104
|
def setup_dir_structure
|
104
105
|
[@sockets_dir, @pids_dir].each do |dir|
|
105
106
|
FileUtils.mkdir_p(dir) unless File.exists?(dir)
|
106
107
|
end
|
107
108
|
end
|
108
|
-
|
109
|
+
|
109
110
|
def verify_version!(application)
|
110
111
|
begin
|
111
|
-
version = Socket.client_command(base_dir, application, "version")
|
112
|
+
version = Socket.client_command(base_dir, application, "version", timeout)
|
112
113
|
if version != Bluepill::VERSION
|
113
114
|
abort("The running version of your daemon seems to be out of date.\nDaemon Version: #{version}, CLI Version: #{Bluepill::VERSION}")
|
114
115
|
end
|
data/lib/bluepill/process.rb
CHANGED
@@ -382,10 +382,12 @@ module Bluepill
|
|
382
382
|
def deep_copy
|
383
383
|
# TODO: This is a kludge. Ideally, process templates
|
384
384
|
# would be facotries, and not a template object.
|
385
|
-
mutex, @event_mutex = @event_mutex, nil
|
385
|
+
mutex, triggers, @event_mutex, @triggers = @event_mutex, @triggers, nil, nil
|
386
386
|
clone = Marshal.load(Marshal.dump(self))
|
387
387
|
clone.instance_variable_set("@event_mutex", Monitor.new)
|
388
|
+
clone.instance_variable_set("@triggers", triggers.collect{ |t| t.deep_copy })
|
388
389
|
@event_mutex = mutex
|
390
|
+
@triggers = triggers
|
389
391
|
clone
|
390
392
|
end
|
391
393
|
|
data/lib/bluepill/socket.rb
CHANGED
@@ -2,9 +2,12 @@ require 'socket'
|
|
2
2
|
|
3
3
|
module Bluepill
|
4
4
|
module Socket
|
5
|
+
<<<<<<< HEAD
|
5
6
|
TIMEOUT = 10
|
6
7
|
RETRY = 5
|
7
8
|
@@timeout = 0
|
9
|
+
=======
|
10
|
+
>>>>>>> akzhan
|
8
11
|
|
9
12
|
extend self
|
10
13
|
|
@@ -12,9 +15,13 @@ module Bluepill
|
|
12
15
|
UNIXSocket.open(socket_path(base_dir, name), &b)
|
13
16
|
end
|
14
17
|
|
18
|
+
<<<<<<< HEAD
|
15
19
|
def client_command(base_dir, name, command)
|
20
|
+
=======
|
21
|
+
def client_command(base_dir, name, command, timeout)
|
22
|
+
>>>>>>> akzhan
|
16
23
|
client(base_dir, name) do |socket|
|
17
|
-
Timeout.timeout(
|
24
|
+
Timeout.timeout(timeout) do
|
18
25
|
socket.puts command
|
19
26
|
Marshal.load(socket)
|
20
27
|
end
|
@@ -54,3 +61,7 @@ module Bluepill
|
|
54
61
|
end
|
55
62
|
end
|
56
63
|
end
|
64
|
+
<<<<<<< HEAD
|
65
|
+
=======
|
66
|
+
|
67
|
+
>>>>>>> akzhan
|
data/lib/bluepill/system.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'etc'
|
2
|
+
require "shellwords"
|
2
3
|
|
3
4
|
module Bluepill
|
4
5
|
# This class represents the system that bluepill is running on.. It's mainly used to memoize
|
@@ -72,7 +73,7 @@ module Bluepill
|
|
72
73
|
|
73
74
|
redirect_io(*options.values_at(:stdin, :stdout, :stderr))
|
74
75
|
|
75
|
-
::Kernel.exec(cmd)
|
76
|
+
::Kernel.exec(*Shellwords.shellwords(cmd))
|
76
77
|
exit
|
77
78
|
end
|
78
79
|
|
@@ -136,7 +137,7 @@ module Bluepill
|
|
136
137
|
cmd_err_write.close
|
137
138
|
|
138
139
|
# finally, replace grandchild with cmd
|
139
|
-
::Kernel.exec(cmd)
|
140
|
+
::Kernel.exec(*Shellwords.shellwords(cmd))
|
140
141
|
}
|
141
142
|
|
142
143
|
# we do not use these ends of the pipes in the child
|
data/lib/bluepill/trigger.rb
CHANGED
@@ -30,12 +30,21 @@ module Bluepill
|
|
30
30
|
self.process.dispatch!(event, self.class.name.split("::").last)
|
31
31
|
end
|
32
32
|
|
33
|
+
def deep_copy
|
34
|
+
# TODO: This is a kludge. Ideally, process templates
|
35
|
+
# would be facotries, and not a template object.
|
36
|
+
mutex, @mutex = @mutex, nil
|
37
|
+
clone = Marshal.load(Marshal.dump(self))
|
38
|
+
clone.instance_variable_set("@mutex", Monitor.new)
|
39
|
+
@mutex = mutex
|
40
|
+
clone
|
41
|
+
end
|
42
|
+
|
33
43
|
def schedule_event(event, delay)
|
34
44
|
# TODO: maybe wrap this in a ScheduledEvent class with methods like cancel
|
35
45
|
thread = Thread.new(self) do |trigger|
|
36
46
|
begin
|
37
47
|
sleep delay.to_f
|
38
|
-
trigger.logger.info("Retrying from flapping")
|
39
48
|
trigger.dispatch!(event)
|
40
49
|
trigger.mutex.synchronize do
|
41
50
|
trigger.scheduled_events.delete_if { |_, thread| thread == Thread.current }
|
@@ -57,4 +66,4 @@ module Bluepill
|
|
57
66
|
end
|
58
67
|
|
59
68
|
end
|
60
|
-
end
|
69
|
+
end
|
@@ -43,11 +43,9 @@ module Bluepill
|
|
43
43
|
if duration
|
44
44
|
self.logger.info "Flapping detected: retrying in #{self.retry_in} seconds"
|
45
45
|
|
46
|
-
self.schedule_event(:start, self.retry_in)
|
47
|
-
|
48
|
-
|
49
|
-
self.dispatch!(:unmonitor)
|
50
|
-
|
46
|
+
self.schedule_event(:start, self.retry_in) unless self.retry_in == 0 # retry_in zero means "do not retry, ever"
|
47
|
+
self.schedule_event(:unmonitor, 0)
|
48
|
+
|
51
49
|
@timeline.clear
|
52
50
|
|
53
51
|
# This will prevent a transition from happening in the process state_machine
|
@@ -56,4 +54,4 @@ module Bluepill
|
|
56
54
|
end
|
57
55
|
end
|
58
56
|
end
|
59
|
-
end
|
57
|
+
end
|
data/ra-bluepill.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ra-bluepill}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.45"
|
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"]
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ra-bluepill
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 69
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 45
|
10
|
+
version: 0.0.45
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Arya Asemanfar
|