eye 0.3.1 → 0.3.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.travis.yml +1 -0
- data/CHANGES.md +19 -0
- data/Gemfile +1 -0
- data/README.md +10 -8
- data/bin/eye +30 -45
- data/examples/notify.eye +3 -2
- data/examples/puma.eye +2 -2
- data/examples/rbenv.eye +2 -2
- data/examples/sidekiq.eye +2 -2
- data/examples/thin-farm.eye +1 -0
- data/examples/unicorn.eye +1 -1
- data/eye.gemspec +1 -1
- data/lib/eye.rb +1 -1
- data/lib/eye/application.rb +1 -1
- data/lib/eye/checker.rb +10 -0
- data/lib/eye/controller/commands.rb +0 -5
- data/lib/eye/controller/helpers.rb +15 -1
- data/lib/eye/controller/load.rb +3 -0
- data/lib/eye/controller/send_command.rb +44 -14
- data/lib/eye/controller/status.rb +3 -8
- data/lib/eye/dsl/application_opts.rb +6 -2
- data/lib/eye/dsl/group_opts.rb +7 -6
- data/lib/eye/dsl/main.rb +1 -1
- data/lib/eye/dsl/opts.rb +22 -15
- data/lib/eye/dsl/process_opts.rb +3 -6
- data/lib/eye/dsl/pure_opts.rb +12 -1
- data/lib/eye/group.rb +1 -1
- data/lib/eye/logger.rb +4 -4
- data/lib/eye/process/scheduler.rb +4 -0
- data/lib/eye/process/validate.rb +9 -1
- data/lib/eye/process/watchers.rb +3 -3
- data/lib/eye/settings.rb +17 -5
- data/lib/eye/system.rb +9 -0
- data/lib/eye/utils/alive_array.rb +23 -1
- metadata +16 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f91b36c9b73d802f079d62a345bbf29fcb929768
|
|
4
|
+
data.tar.gz: 2953436d9e587ff52b0a2ee146c2ac52434e1662
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1569dabc95b8e86f63eaf7b3d921758638cd2183ea403610400f437f6824fe0d18d0b763c3ce2752ab6d2a63641d2755affd51137d134f6cf3adf2e6caa10869
|
|
7
|
+
data.tar.gz: 1e9d50a96ae0cc44d2ab218d45933ec4b3a49ec5686875351de2f6b5be10deaaa2e1843431bb88b89eb783c59a0c1f76d1ccda46ad915d11fc4e5da2c27640f1
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGES.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
0.3.3.dev
|
|
2
|
+
---------
|
|
3
|
+
|
|
4
|
+
0.3.2
|
|
5
|
+
---------
|
|
6
|
+
* improve matching targers
|
|
7
|
+
* possibility to add many checkers with the same type per process (ex: checks :http_2, ...)
|
|
8
|
+
* add uid,gid options (only for ruby 2.0)
|
|
9
|
+
|
|
10
|
+
0.3.1
|
|
11
|
+
-----
|
|
12
|
+
* load multiple configs (folder,...) now not breaks on first error (each config loads separately)
|
|
13
|
+
* load ~/.eyeconfig with first eye load
|
|
14
|
+
* some concurrency fixes
|
|
15
|
+
* custom checker
|
|
16
|
+
|
|
17
|
+
0.3
|
|
18
|
+
---
|
|
19
|
+
* stable version
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
Eye
|
|
1
|
+
Eye
|
|
2
2
|
===
|
|
3
|
+
[](http://rubygems.org/gems/eye)
|
|
4
|
+
[](http://travis-ci.org/kostya/eye)
|
|
5
|
+
[](https://coveralls.io/r/kostya/eye?branch=master)
|
|
3
6
|
|
|
4
7
|
Process monitoring tool. An alternative to God and Bluepill. With Bluepill like config syntax. Requires MRI Ruby >= 1.9.3-p194. Uses Celluloid and Celluloid::IO.
|
|
5
8
|
|
|
@@ -150,6 +153,10 @@ Check config syntax:
|
|
|
150
153
|
|
|
151
154
|
$ eye c(heck) examples/test.eye
|
|
152
155
|
|
|
156
|
+
Config explain (for debug):
|
|
157
|
+
|
|
158
|
+
$ eye e(xplain) examples/test.eye
|
|
159
|
+
|
|
153
160
|
Log tracing:
|
|
154
161
|
|
|
155
162
|
$ eye trace
|
|
@@ -160,11 +167,6 @@ Quit monitoring:
|
|
|
160
167
|
|
|
161
168
|
$ eye q(uit)
|
|
162
169
|
|
|
163
|
-
Config
|
|
164
|
-
|
|
165
|
-
$ eye explain examples/test.eye
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
### Config api:
|
|
170
|
+
### Config options:
|
|
169
171
|
|
|
170
|
-
Waiting for pull requests ..., until that you can read `examples` and `spec/dsl` folders.
|
|
172
|
+
Waiting for pull requests here..., until that you can read `examples` and `spec/dsl` folders.
|
data/bin/eye
CHANGED
|
@@ -10,9 +10,7 @@ class Cli < Thor
|
|
|
10
10
|
|
|
11
11
|
desc "info [MASK]", "show process statuses"
|
|
12
12
|
def info(mask = nil)
|
|
13
|
-
|
|
14
|
-
puts res if res && !res.empty?
|
|
15
|
-
puts
|
|
13
|
+
print cmd(:info, mask)
|
|
16
14
|
end
|
|
17
15
|
|
|
18
16
|
desc "status ", "show process statuses"
|
|
@@ -25,31 +23,22 @@ class Cli < Thor
|
|
|
25
23
|
method_option :config, :type => :boolean, :aliases => "-c"
|
|
26
24
|
method_option :show_processes, :type => :boolean, :aliases => "-p"
|
|
27
25
|
def xinfo
|
|
28
|
-
|
|
29
|
-
puts res if res && !res.empty?
|
|
30
|
-
puts
|
|
26
|
+
print cmd(:xinfo, options[:config], options[:show_processes])
|
|
31
27
|
end
|
|
32
28
|
|
|
33
29
|
desc "oinfo", "onelined info"
|
|
34
30
|
def oinfo
|
|
35
|
-
|
|
36
|
-
puts res if res && !res.empty?
|
|
37
|
-
puts
|
|
31
|
+
print cmd(:oinfo)
|
|
38
32
|
end
|
|
39
33
|
|
|
40
34
|
desc "load [CONF, ...]", "load config (and start server if needed) (-f for foregraund start)"
|
|
41
35
|
method_option :foregraund, :type => :boolean, :aliases => "-f"
|
|
42
|
-
method_option :logger, :type => :string, :aliases => "-l"
|
|
43
36
|
def load(*configs)
|
|
44
37
|
configs.map!{ |c| File.expand_path(c) } if !configs.empty?
|
|
45
38
|
|
|
46
39
|
if options[:foregraund]
|
|
47
40
|
# in foregraund we stop another server, and run just 1 current config version
|
|
48
|
-
if configs.size != 1
|
|
49
|
-
say "foregraund expected only one config", :red
|
|
50
|
-
exit 1
|
|
51
|
-
end
|
|
52
|
-
|
|
41
|
+
error!("foregraund expected only one config") if configs.size != 1
|
|
53
42
|
server_start_foregraund(configs.first)
|
|
54
43
|
|
|
55
44
|
elsif server_started?
|
|
@@ -90,9 +79,7 @@ class Cli < Thor
|
|
|
90
79
|
|
|
91
80
|
desc "history TARGET[,...]", "show process states history"
|
|
92
81
|
def history(*targets)
|
|
93
|
-
|
|
94
|
-
puts res if res && !res.empty?
|
|
95
|
-
puts
|
|
82
|
+
print cmd(:history, *targets)
|
|
96
83
|
end
|
|
97
84
|
|
|
98
85
|
desc "trace [TARGET]", "tracing log for app,group or process"
|
|
@@ -146,6 +133,16 @@ class Cli < Thor
|
|
|
146
133
|
|
|
147
134
|
private
|
|
148
135
|
|
|
136
|
+
def error!(msg)
|
|
137
|
+
say msg, :red
|
|
138
|
+
exit 1
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def print(msg, new_line = true)
|
|
142
|
+
say msg if msg && !msg.empty?
|
|
143
|
+
say if new_line
|
|
144
|
+
end
|
|
145
|
+
|
|
149
146
|
def client
|
|
150
147
|
@client ||= Eye::Client.new(Eye::Settings.socket_path)
|
|
151
148
|
end
|
|
@@ -160,11 +157,9 @@ private
|
|
|
160
157
|
res = _cmd(cmd, *args)
|
|
161
158
|
|
|
162
159
|
if res == :not_started
|
|
163
|
-
|
|
164
|
-
exit 1
|
|
160
|
+
error! "eye monitoring not found, did you start it?"
|
|
165
161
|
elsif res == :timeouted
|
|
166
|
-
|
|
167
|
-
exit 1
|
|
162
|
+
error! "eye does not answer, timeouted..."
|
|
168
163
|
end
|
|
169
164
|
|
|
170
165
|
res
|
|
@@ -175,18 +170,12 @@ private
|
|
|
175
170
|
end
|
|
176
171
|
|
|
177
172
|
def say_load_result(res = {}, opts = {})
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
say_filename = (res.size > 1)
|
|
185
|
-
say "eye started!", :green if opts[:started]
|
|
186
|
-
res.each do |filename, _res|
|
|
187
|
-
say "#{filename}: ", nil, true if say_filename
|
|
188
|
-
show_load_message(_res, opts)
|
|
189
|
-
end
|
|
173
|
+
error!(res) unless res.is_a?(Hash)
|
|
174
|
+
say_filename = (res.size > 1)
|
|
175
|
+
say "eye started!", :green if opts[:started]
|
|
176
|
+
res.each do |filename, _res|
|
|
177
|
+
say "#{filename}: ", nil, true if say_filename
|
|
178
|
+
show_load_message(_res, opts)
|
|
190
179
|
end
|
|
191
180
|
end
|
|
192
181
|
|
|
@@ -212,11 +201,11 @@ private
|
|
|
212
201
|
def send_command(_cmd, *args)
|
|
213
202
|
res = cmd(_cmd, *args)
|
|
214
203
|
if res == :unknown_command
|
|
215
|
-
|
|
204
|
+
error! "unknown command :#{_cmd}"
|
|
216
205
|
elsif res == :corrupred_marshal
|
|
217
|
-
|
|
206
|
+
error! "something crazy wrong, check eye logs!"
|
|
218
207
|
elsif res == []
|
|
219
|
-
|
|
208
|
+
error! "command :#{_cmd}, targets not found!"
|
|
220
209
|
else
|
|
221
210
|
say "command :#{_cmd} sended to [#{res * ", "}]"
|
|
222
211
|
end
|
|
@@ -227,7 +216,7 @@ private
|
|
|
227
216
|
if log_file && File.exists?(log_file)
|
|
228
217
|
Process.exec "tail -n 100 -f #{log_file} | grep '#{tag}'"
|
|
229
218
|
else
|
|
230
|
-
|
|
219
|
+
error! "log file not found #{log_file.inspect}"
|
|
231
220
|
end
|
|
232
221
|
end
|
|
233
222
|
|
|
@@ -250,8 +239,7 @@ private
|
|
|
250
239
|
|
|
251
240
|
def ensure_loader_path
|
|
252
241
|
unless loader_path
|
|
253
|
-
|
|
254
|
-
exit 1
|
|
242
|
+
error! "start monitoring needs to run under ruby with installed gem 'eye'"
|
|
255
243
|
end
|
|
256
244
|
end
|
|
257
245
|
|
|
@@ -275,18 +263,15 @@ private
|
|
|
275
263
|
Eye::Settings.ensure_eye_dir
|
|
276
264
|
|
|
277
265
|
ensure_stop_previous_server
|
|
278
|
-
|
|
279
|
-
args = []
|
|
280
|
-
args += ['-l', options[:logger]] if options[:logger]
|
|
281
266
|
|
|
267
|
+
args = []
|
|
282
268
|
pid = Process.spawn(ruby_path, loader_path, *args, :out => '/dev/null', :err => '/dev/null', :in => '/dev/null',
|
|
283
269
|
:chdir => '/', :pgroup => true)
|
|
284
270
|
Process.detach(pid)
|
|
285
271
|
File.open(Eye::Settings.pid_path, 'w'){|f| f.write(pid) }
|
|
286
272
|
|
|
287
273
|
unless wait_server
|
|
288
|
-
|
|
289
|
-
exit 1
|
|
274
|
+
error! "server not runned in 15 seconds, something crazy wrong"
|
|
290
275
|
end
|
|
291
276
|
|
|
292
277
|
configs.unshift(Eye::Settings.eyeconfig) if File.exists?(Eye::Settings.eyeconfig)
|
data/examples/notify.eye
CHANGED
data/examples/puma.eye
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
RUBY = '/usr/local/ruby/1.9.3-p392/bin/ruby'
|
|
2
2
|
RAILS_ENV = 'production'
|
|
3
|
-
ROOT =
|
|
3
|
+
ROOT = File.expand_path(File.join(File.dirname(__FILE__), %w[ processes ]))
|
|
4
4
|
CURRENT = File.expand_path(File.join(ROOT, %w{current}))
|
|
5
5
|
LOGS = File.expand_path(File.join(ROOT, %w{shared log}))
|
|
6
6
|
PIDS = File.expand_path(File.join(ROOT, %w{shared pids}))
|
|
@@ -12,7 +12,7 @@ end
|
|
|
12
12
|
|
|
13
13
|
Eye.application :super_app do
|
|
14
14
|
env 'RAILS_ENV' => RAILS_ENV
|
|
15
|
-
working_dir
|
|
15
|
+
working_dir ROOT
|
|
16
16
|
triggers :flapping, :times => 10, :within => 1.minute
|
|
17
17
|
|
|
18
18
|
process :puma do
|
data/examples/rbenv.eye
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Eye.application "rbenv_example" do
|
|
2
2
|
env 'RBENV_ROOT' => '/usr/local/rbenv', 'PATH' => "/usr/local/rbenv/shims:/usr/local/rbenv/bin:#{ENV['PATH']}"
|
|
3
|
-
working_dir
|
|
3
|
+
working_dir File.expand_path(File.join(File.dirname(__FILE__), %w[ processes ]))
|
|
4
4
|
|
|
5
5
|
process "some_process" do
|
|
6
6
|
pid_file "some.pid"
|
|
@@ -8,4 +8,4 @@ Eye.application "rbenv_example" do
|
|
|
8
8
|
daemonize true
|
|
9
9
|
stdall "some.log"
|
|
10
10
|
end
|
|
11
|
-
end
|
|
11
|
+
end
|
data/examples/sidekiq.eye
CHANGED
|
@@ -16,8 +16,8 @@ def sidekiq_process(proxy, name)
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
Eye.application :sidekiq_test do
|
|
19
|
-
working_dir
|
|
19
|
+
working_dir File.expand_path(File.join(File.dirname(__FILE__), %w[ processes ]))
|
|
20
20
|
env "RAILS_ENV" => 'production'
|
|
21
21
|
|
|
22
22
|
sidekiq_process self, :sidekiq
|
|
23
|
-
end
|
|
23
|
+
end
|
data/examples/thin-farm.eye
CHANGED
data/examples/unicorn.eye
CHANGED
|
@@ -5,7 +5,7 @@ RAILS_ENV = 'production'
|
|
|
5
5
|
|
|
6
6
|
Eye.application "rails_unicorn" do
|
|
7
7
|
env "RAILS_ENV" => RAILS_ENV, "PATH" => "#{File.dirname(RUBY)}:#{ENV['PATH']}"
|
|
8
|
-
working_dir
|
|
8
|
+
working_dir File.expand_path(File.join(File.dirname(__FILE__), %w[ processes ]))
|
|
9
9
|
|
|
10
10
|
process("unicorn") do
|
|
11
11
|
pid_file "tmp/pids/unicorn.pid"
|
data/eye.gemspec
CHANGED
|
@@ -27,7 +27,6 @@ Gem::Specification.new do |gem|
|
|
|
27
27
|
|
|
28
28
|
gem.add_development_dependency 'rake'
|
|
29
29
|
gem.add_development_dependency 'rspec'
|
|
30
|
-
gem.add_development_dependency 'simplecov'
|
|
31
30
|
gem.add_development_dependency 'rr'
|
|
32
31
|
gem.add_development_dependency 'ruby-graphviz'
|
|
33
32
|
gem.add_development_dependency 'forking'
|
|
@@ -36,4 +35,5 @@ Gem::Specification.new do |gem|
|
|
|
36
35
|
gem.add_development_dependency 'sinatra'
|
|
37
36
|
gem.add_development_dependency 'thin'
|
|
38
37
|
gem.add_development_dependency 'xmpp4r'
|
|
38
|
+
gem.add_development_dependency 'coveralls'
|
|
39
39
|
end
|
data/lib/eye.rb
CHANGED
data/lib/eye/application.rb
CHANGED
data/lib/eye/checker.rb
CHANGED
|
@@ -13,6 +13,16 @@ class Eye::Checker
|
|
|
13
13
|
|
|
14
14
|
attr_accessor :value, :values, :options, :pid, :type, :check_count
|
|
15
15
|
|
|
16
|
+
def self.name_and_class(type)
|
|
17
|
+
type = type.to_sym
|
|
18
|
+
return {:name => type, :type => type} if TYPES[type]
|
|
19
|
+
|
|
20
|
+
if type =~ /\A(.*?)_?[0-9]+\z/
|
|
21
|
+
ctype = $1.to_sym
|
|
22
|
+
return {:name => type, :type => ctype} if TYPES[ctype]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
16
26
|
def self.get_class(type)
|
|
17
27
|
klass = eval("Eye::Checker::#{TYPES[type]}") rescue nil
|
|
18
28
|
raise "Unknown checker #{type}" unless klass
|
|
@@ -6,10 +6,24 @@ module Eye::Controller::Helpers
|
|
|
6
6
|
$0 = str
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
+
def save_cache
|
|
10
|
+
File.open(Eye::Settings.cache_path, 'w') { |f| f.write(cache_str) }
|
|
11
|
+
rescue => ex
|
|
12
|
+
warn "save cache crashed with #{ex.message}"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def cache_str
|
|
16
|
+
all_processes.map{ |p| "#{p.full_name}=#{p.state}" } * "\n"
|
|
17
|
+
end
|
|
18
|
+
|
|
9
19
|
def process_by_name(name)
|
|
10
20
|
all_processes.detect{|c| c.name == name}
|
|
11
21
|
end
|
|
12
22
|
|
|
23
|
+
def process_by_full_name(name)
|
|
24
|
+
all_processes.detect{|c| c.full_name == name }
|
|
25
|
+
end
|
|
26
|
+
|
|
13
27
|
def group_by_name(name)
|
|
14
28
|
all_groups.detect{|c| c.name == name}
|
|
15
29
|
end
|
|
@@ -58,4 +72,4 @@ module Eye::Controller::Helpers
|
|
|
58
72
|
res
|
|
59
73
|
end
|
|
60
74
|
|
|
61
|
-
end
|
|
75
|
+
end
|
data/lib/eye/controller/load.rb
CHANGED
|
@@ -22,6 +22,7 @@ module Eye::Controller::Load
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
set_proc_line
|
|
25
|
+
save_cache
|
|
25
26
|
|
|
26
27
|
res
|
|
27
28
|
end
|
|
@@ -35,6 +36,8 @@ private
|
|
|
35
36
|
{ :error => false, :config => yield }
|
|
36
37
|
|
|
37
38
|
rescue Eye::Dsl::Error, Exception, NoMethodError => ex
|
|
39
|
+
raise if ex.class.to_s.include?('RR') # skip RR exceptions
|
|
40
|
+
|
|
38
41
|
error "load: config error <#{filename}>: #{ex.message}"
|
|
39
42
|
|
|
40
43
|
# filter backtrace for user output
|
|
@@ -4,7 +4,9 @@ module Eye::Controller::SendCommand
|
|
|
4
4
|
matched_objects(*obj_strs) do |obj|
|
|
5
5
|
if command.to_sym == :delete
|
|
6
6
|
remove_object_from_tree(obj)
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
set_proc_line
|
|
9
|
+
save_cache
|
|
8
10
|
end
|
|
9
11
|
|
|
10
12
|
obj.send_command(command)
|
|
@@ -61,32 +63,44 @@ private
|
|
|
61
63
|
return [] if obj_strs.blank?
|
|
62
64
|
return @applications.dup if obj_strs.size == 1 && (obj_strs[0].strip == 'all' || obj_strs[0].strip == '*')
|
|
63
65
|
|
|
64
|
-
res =
|
|
66
|
+
res = Eye::Utils::AliveArray.new
|
|
65
67
|
obj_strs.map{|c| c.split(",")}.flatten.each do |mask|
|
|
66
|
-
res += find_objects_by_mask(mask)
|
|
68
|
+
res += find_objects_by_mask(mask.to_s.strip)
|
|
67
69
|
end
|
|
70
|
+
res
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def find_objects_by_mask(mask)
|
|
74
|
+
res = find_all_objects_by_mask(mask)
|
|
68
75
|
|
|
69
76
|
if res.size > 1
|
|
70
|
-
|
|
77
|
+
final = Eye::Utils::AliveArray.new
|
|
71
78
|
|
|
72
|
-
|
|
79
|
+
if mask[-1] != '*'
|
|
80
|
+
# try to find exactly matched
|
|
81
|
+
r = right_regexp(mask)
|
|
82
|
+
res.each do |obj|
|
|
83
|
+
final << obj if obj.full_name =~ r
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
return final if final.present?
|
|
88
|
+
|
|
89
|
+
# remove inherited targets
|
|
73
90
|
res.each do |obj|
|
|
74
91
|
sub_object = res.any?{|a| a.sub_object?(obj) }
|
|
75
92
|
final << obj unless sub_object
|
|
76
93
|
end
|
|
77
94
|
|
|
78
95
|
res = final
|
|
79
|
-
end
|
|
96
|
+
end
|
|
80
97
|
|
|
81
|
-
res
|
|
98
|
+
res
|
|
82
99
|
end
|
|
83
100
|
|
|
84
|
-
def
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
res = []
|
|
88
|
-
str = Regexp.escape(mask).gsub('\*', '.*?')
|
|
89
|
-
r = %r{\A#{str}}
|
|
101
|
+
def find_all_objects_by_mask(mask)
|
|
102
|
+
res = Eye::Utils::AliveArray
|
|
103
|
+
r = left_regexp(mask)
|
|
90
104
|
|
|
91
105
|
# find app
|
|
92
106
|
res = @applications.select{|a| a.name =~ r || a.full_name =~ r }
|
|
@@ -102,9 +116,16 @@ private
|
|
|
102
116
|
gr.processes.each do |p|
|
|
103
117
|
res << p if p.name =~ r || p.full_name =~ r
|
|
104
118
|
|
|
119
|
+
# child matching
|
|
105
120
|
if p.childs.present?
|
|
106
|
-
|
|
121
|
+
childs = p.childs.values
|
|
122
|
+
res += childs.select do |ch|
|
|
123
|
+
name = ch.name rescue ''
|
|
124
|
+
full_name = ch.full_name rescue ''
|
|
125
|
+
name =~ r || full_name =~ r
|
|
126
|
+
end
|
|
107
127
|
end
|
|
128
|
+
|
|
108
129
|
end
|
|
109
130
|
end
|
|
110
131
|
end
|
|
@@ -112,4 +133,13 @@ private
|
|
|
112
133
|
res
|
|
113
134
|
end
|
|
114
135
|
|
|
136
|
+
def left_regexp(mask)
|
|
137
|
+
str = Regexp.escape(mask).gsub('\*', '.*?')
|
|
138
|
+
%r|\A#{str}|
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def right_regexp(mask)
|
|
142
|
+
str = Regexp.escape(mask).gsub('\*', '.*?')
|
|
143
|
+
%r|#{str}\z|
|
|
144
|
+
end
|
|
115
145
|
end
|
|
@@ -28,7 +28,7 @@ module Eye::Controller::Status
|
|
|
28
28
|
|
|
29
29
|
str = <<-S
|
|
30
30
|
About: #{Eye::ABOUT}
|
|
31
|
-
Info: #{resources_str(Eye::SystemResources.resources($$)
|
|
31
|
+
Info: #{resources_str(Eye::SystemResources.resources($$))}
|
|
32
32
|
Ruby: #{RUBY_DESCRIPTION}
|
|
33
33
|
Logger: #{Eye::Logger.dev}
|
|
34
34
|
Socket: #{Eye::Settings::socket_path}
|
|
@@ -98,16 +98,11 @@ private
|
|
|
98
98
|
end
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
def resources_str(r
|
|
101
|
+
def resources_str(r)
|
|
102
102
|
return '' if r.blank?
|
|
103
103
|
|
|
104
104
|
res = "#{r[:start_time]}, #{r[:cpu]}%"
|
|
105
|
-
|
|
106
|
-
if r[:memory]
|
|
107
|
-
mem = mb ? "#{r[:memory] / 1024}Mb" : "#{r[:memory]}Kb"
|
|
108
|
-
res += ", #{mem}"
|
|
109
|
-
end
|
|
110
|
-
|
|
105
|
+
res += ", #{r[:memory] / 1024}Mb" if r[:memory]
|
|
111
106
|
res += ", <#{r[:pid]}>"
|
|
112
107
|
|
|
113
108
|
res
|
|
@@ -6,6 +6,10 @@ class Eye::Dsl::ApplicationOpts < Eye::Dsl::Opts
|
|
|
6
6
|
[:pid_file, :start_command]
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
+
def not_seed_options
|
|
10
|
+
[:groups]
|
|
11
|
+
end
|
|
12
|
+
|
|
9
13
|
def group(name, &block)
|
|
10
14
|
Eye::Dsl.debug "=> group #{name}"
|
|
11
15
|
|
|
@@ -28,6 +32,6 @@ class Eye::Dsl::ApplicationOpts < Eye::Dsl::Opts
|
|
|
28
32
|
group("__default__"){ process(name.to_s, &block) }
|
|
29
33
|
end
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
alias xgroup nop
|
|
36
|
+
alias xprocess nop
|
|
33
37
|
end
|
data/lib/eye/dsl/group_opts.rb
CHANGED
|
@@ -6,6 +6,10 @@ class Eye::Dsl::GroupOpts < Eye::Dsl::Opts
|
|
|
6
6
|
[:pid_file, :start_command]
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
+
def not_seed_options
|
|
10
|
+
[:processes, :chain]
|
|
11
|
+
end
|
|
12
|
+
|
|
9
13
|
def process(name, &block)
|
|
10
14
|
Eye::Dsl.debug "=> process #{name}"
|
|
11
15
|
|
|
@@ -17,11 +21,8 @@ class Eye::Dsl::GroupOpts < Eye::Dsl::Opts
|
|
|
17
21
|
Eye::Dsl.debug "<= process #{name}"
|
|
18
22
|
end
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
parent
|
|
24
|
-
end
|
|
25
|
-
alias :app :application
|
|
24
|
+
alias xprocess nop
|
|
25
|
+
alias application parent
|
|
26
|
+
alias app application
|
|
26
27
|
|
|
27
28
|
end
|
data/lib/eye/dsl/main.rb
CHANGED
data/lib/eye/dsl/opts.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
class Eye::Dsl::Opts < Eye::Dsl::PureOpts
|
|
2
2
|
|
|
3
3
|
STR_OPTIONS = [ :pid_file, :working_dir, :stdout, :stderr, :stdall, :start_command,
|
|
4
|
-
:stop_command, :restart_command ]
|
|
4
|
+
:stop_command, :restart_command, :uid, :gid ]
|
|
5
5
|
create_options_methods(STR_OPTIONS, String)
|
|
6
6
|
|
|
7
7
|
BOOL_OPTIONS = [ :daemonize, :keep_alive, :control_pid, :auto_start, :stop_on_delete]
|
|
@@ -11,17 +11,14 @@ class Eye::Dsl::Opts < Eye::Dsl::PureOpts
|
|
|
11
11
|
:restart_grace, :stop_grace, :childs_update_period ]
|
|
12
12
|
create_options_methods(INTERVAL_OPTIONS, [Fixnum, Float])
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
create_options_methods(
|
|
14
|
+
create_options_methods([:environment], Hash)
|
|
15
|
+
create_options_methods([:stop_signals], Array)
|
|
16
|
+
create_options_methods([:umask], Fixnum)
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
def initialize(name = nil, parent = nil)
|
|
19
20
|
super(name, parent)
|
|
20
21
|
|
|
21
|
-
# ensure delete subobjects which can appears from parent config
|
|
22
|
-
@config.delete :groups
|
|
23
|
-
@config.delete :processes
|
|
24
|
-
|
|
25
22
|
@config[:application] = parent.name if parent.is_a?(Eye::Dsl::ApplicationOpts)
|
|
26
23
|
@config[:group] = parent.name if parent.is_a?(Eye::Dsl::GroupOpts)
|
|
27
24
|
|
|
@@ -30,14 +27,14 @@ class Eye::Dsl::Opts < Eye::Dsl::PureOpts
|
|
|
30
27
|
end
|
|
31
28
|
|
|
32
29
|
def checks(type, opts = {})
|
|
33
|
-
|
|
34
|
-
raise Eye::Dsl::Error, "unknown checker type #{type}" unless
|
|
30
|
+
nac = Eye::Checker.name_and_class(type.to_sym)
|
|
31
|
+
raise Eye::Dsl::Error, "unknown checker type #{type}" unless nac
|
|
35
32
|
|
|
36
|
-
opts.merge!(:type => type)
|
|
33
|
+
opts.merge!(:type => nac[:type])
|
|
37
34
|
Eye::Checker.validate!(opts)
|
|
38
35
|
|
|
39
36
|
@config[:checks] ||= {}
|
|
40
|
-
@config[:checks][
|
|
37
|
+
@config[:checks][nac[:name]] = opts
|
|
41
38
|
end
|
|
42
39
|
|
|
43
40
|
def triggers(type, opts = {})
|
|
@@ -53,9 +50,9 @@ class Eye::Dsl::Opts < Eye::Dsl::PureOpts
|
|
|
53
50
|
|
|
54
51
|
# clear checks from parent
|
|
55
52
|
def nochecks(type)
|
|
56
|
-
|
|
57
|
-
raise Eye::Dsl::Error, "unknown checker type #{type}" unless
|
|
58
|
-
@config[:checks].try :delete,
|
|
53
|
+
nac = Eye::Checker.name_and_class(type.to_sym)
|
|
54
|
+
raise Eye::Dsl::Error, "unknown checker type #{type}" unless nac
|
|
55
|
+
@config[:checks].try :delete, nac[:name]
|
|
59
56
|
end
|
|
60
57
|
|
|
61
58
|
# clear triggers from parent
|
|
@@ -85,7 +82,7 @@ class Eye::Dsl::Opts < Eye::Dsl::PureOpts
|
|
|
85
82
|
@config[:environment].merge!(value)
|
|
86
83
|
end
|
|
87
84
|
|
|
88
|
-
alias
|
|
85
|
+
alias env environment
|
|
89
86
|
|
|
90
87
|
def set_stdall(value)
|
|
91
88
|
super
|
|
@@ -94,6 +91,16 @@ class Eye::Dsl::Opts < Eye::Dsl::PureOpts
|
|
|
94
91
|
set_stderr value
|
|
95
92
|
end
|
|
96
93
|
|
|
94
|
+
def set_uid(value)
|
|
95
|
+
raise Eye::Dsl::Error, ":uid not supported by ruby (needed 2.0)" unless Eye::Settings.supported_setsid?
|
|
96
|
+
super
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def set_gid(value)
|
|
100
|
+
raise Eye::Dsl::Error, ":gid not supported by ruby (needed 2.0)" unless Eye::Settings.supported_setsid?
|
|
101
|
+
super
|
|
102
|
+
end
|
|
103
|
+
|
|
97
104
|
def scoped(&block)
|
|
98
105
|
h = self.class.new(self.name, self)
|
|
99
106
|
h.instance_eval(&block)
|
data/lib/eye/dsl/process_opts.rb
CHANGED
|
@@ -7,15 +7,12 @@ class Eye::Dsl::ProcessOpts < Eye::Dsl::Opts
|
|
|
7
7
|
@config[:monitor_children].merge!(opts.config)
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
alias xmonitor_children nop
|
|
11
11
|
|
|
12
12
|
def application
|
|
13
13
|
parent.try(:parent)
|
|
14
14
|
end
|
|
15
|
-
alias
|
|
16
|
-
|
|
17
|
-
def group
|
|
18
|
-
parent
|
|
19
|
-
end
|
|
15
|
+
alias app application
|
|
16
|
+
alias group parent
|
|
20
17
|
|
|
21
18
|
end
|
data/lib/eye/dsl/pure_opts.rb
CHANGED
|
@@ -49,7 +49,12 @@ class Eye::Dsl::PureOpts
|
|
|
49
49
|
|
|
50
50
|
if parent
|
|
51
51
|
@parent = parent
|
|
52
|
-
|
|
52
|
+
if merge_parent_config
|
|
53
|
+
@config = Eye::Utils::deep_clone(parent.config)
|
|
54
|
+
parent.not_seed_options.each { |opt| @config.delete(opt) }
|
|
55
|
+
else
|
|
56
|
+
@config = {}
|
|
57
|
+
end
|
|
53
58
|
@full_name = "#{parent.full_name}:#{@full_name}"
|
|
54
59
|
else
|
|
55
60
|
@config = {}
|
|
@@ -66,6 +71,10 @@ class Eye::Dsl::PureOpts
|
|
|
66
71
|
[]
|
|
67
72
|
end
|
|
68
73
|
|
|
74
|
+
def not_seed_options
|
|
75
|
+
[]
|
|
76
|
+
end
|
|
77
|
+
|
|
69
78
|
def with_condition(cond = true, &block)
|
|
70
79
|
self.instance_eval(&block) if cond && block
|
|
71
80
|
end
|
|
@@ -90,6 +99,8 @@ class Eye::Dsl::PureOpts
|
|
|
90
99
|
end
|
|
91
100
|
end
|
|
92
101
|
|
|
102
|
+
def nop(*args, &block); end
|
|
103
|
+
|
|
93
104
|
private
|
|
94
105
|
|
|
95
106
|
def self.with_parsed_file(file_name)
|
data/lib/eye/group.rb
CHANGED
data/lib/eye/logger.rb
CHANGED
|
@@ -42,11 +42,11 @@ class Eye::Logger
|
|
|
42
42
|
attr_reader :dev, :log_level
|
|
43
43
|
|
|
44
44
|
def link_logger(dev)
|
|
45
|
-
@dev = dev ? dev.to_s
|
|
45
|
+
@dev = dev ? dev.to_s : nil
|
|
46
46
|
@dev_fd = @dev
|
|
47
47
|
|
|
48
|
-
@dev_fd = STDOUT if @dev == 'stdout'
|
|
49
|
-
@dev_fd = STDERR if @dev == 'stderr'
|
|
48
|
+
@dev_fd = STDOUT if @dev.to_s.downcase == 'stdout'
|
|
49
|
+
@dev_fd = STDERR if @dev.to_s.downcase == 'stderr'
|
|
50
50
|
|
|
51
51
|
@inner_logger = InnerLogger.new(@dev_fd)
|
|
52
52
|
@inner_logger.level = self.log_level || Logger::INFO
|
|
@@ -77,4 +77,4 @@ private
|
|
|
77
77
|
end
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
-
end
|
|
80
|
+
end
|
|
@@ -53,6 +53,10 @@ module Eye::Process::Scheduler
|
|
|
53
53
|
def scheduler_actions_list
|
|
54
54
|
scheduler.list.map{|c| c[:args].first rescue nil }.compact
|
|
55
55
|
end
|
|
56
|
+
|
|
57
|
+
def scheduler_clear_pending_list
|
|
58
|
+
scheduler.clear_pending_list
|
|
59
|
+
end
|
|
56
60
|
|
|
57
61
|
def self.included(base)
|
|
58
62
|
base.finalizer :remove_scheduler
|
data/lib/eye/process/validate.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'shellwords'
|
|
2
|
+
require 'etc'
|
|
2
3
|
|
|
3
4
|
module Eye::Process::Validate
|
|
4
5
|
|
|
@@ -18,6 +19,13 @@ module Eye::Process::Validate
|
|
|
18
19
|
|
|
19
20
|
Shellwords.shellwords(config[:stop_command]) if config[:stop_command]
|
|
20
21
|
Shellwords.shellwords(config[:restart_command]) if config[:restart_command]
|
|
22
|
+
|
|
23
|
+
Etc.getpwnam(config[:uid]) if config[:uid]
|
|
24
|
+
Etc.getpwnam(config[:gid]) if config[:gid]
|
|
25
|
+
|
|
26
|
+
if config[:working_dir]
|
|
27
|
+
raise Error, "working_dir '#{config[:working_dir]}' is invalid" unless File.directory?(config[:working_dir])
|
|
28
|
+
end
|
|
21
29
|
end
|
|
22
30
|
|
|
23
|
-
end
|
|
31
|
+
end
|
data/lib/eye/process/watchers.rb
CHANGED
|
@@ -46,14 +46,14 @@ private
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def start_checkers
|
|
49
|
-
self[:checks].each{|
|
|
49
|
+
self[:checks].each{|name, cfg| start_checker(name, cfg) }
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
def start_checker(cfg)
|
|
52
|
+
def start_checker(name, cfg)
|
|
53
53
|
subject = Eye::Checker.create(pid, cfg, logger.prefix)
|
|
54
54
|
|
|
55
55
|
# ex: {:type => :memory, :every => 5.seconds, :below => 100.megabytes, :times => [3,5]}
|
|
56
|
-
add_watcher("check_#{
|
|
56
|
+
add_watcher("check_#{name}".to_sym, subject.every, subject, &method(:watcher_tick).to_proc)
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def watcher_tick(subject)
|
data/lib/eye/settings.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Eye::Settings
|
|
|
4
4
|
module_function
|
|
5
5
|
|
|
6
6
|
def dir
|
|
7
|
-
if
|
|
7
|
+
if root?
|
|
8
8
|
'/var/run/eye'
|
|
9
9
|
else
|
|
10
10
|
File.expand_path(File.join(home, '.eye'))
|
|
@@ -12,13 +12,17 @@ module Eye::Settings
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def eyeconfig
|
|
15
|
-
if
|
|
15
|
+
if root?
|
|
16
16
|
'/etc/eye.conf'
|
|
17
17
|
else
|
|
18
18
|
File.expand_path(File.join(home, '.eyeconfig'))
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
def root?
|
|
23
|
+
Process::UID.eid == 0
|
|
24
|
+
end
|
|
25
|
+
|
|
22
26
|
def home
|
|
23
27
|
ENV['EYE_HOME'] || ENV['HOME']
|
|
24
28
|
end
|
|
@@ -32,15 +36,23 @@ module Eye::Settings
|
|
|
32
36
|
end
|
|
33
37
|
|
|
34
38
|
def socket_path
|
|
35
|
-
path('sock')
|
|
39
|
+
path(ENV['EYE_SOCK'] || "sock#{ENV['EYE_V']}")
|
|
36
40
|
end
|
|
37
41
|
|
|
38
42
|
def pid_path
|
|
39
|
-
path('pid')
|
|
43
|
+
path(ENV['EYE_PID'] || "pid#{ENV['EYE_V']}")
|
|
40
44
|
end
|
|
41
45
|
|
|
46
|
+
def cache_path
|
|
47
|
+
path("processes#{ENV['EYE_V']}.cache")
|
|
48
|
+
end
|
|
49
|
+
|
|
42
50
|
def client_timeout
|
|
43
51
|
5
|
|
44
52
|
end
|
|
45
53
|
|
|
46
|
-
|
|
54
|
+
def supported_setsid?
|
|
55
|
+
RUBY_VERSION >= '2.0'
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
data/lib/eye/system.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'shellwords'
|
|
2
2
|
require 'pathname'
|
|
3
|
+
require 'etc'
|
|
3
4
|
|
|
4
5
|
module Eye::System
|
|
5
6
|
class << self
|
|
@@ -134,6 +135,14 @@ module Eye::System
|
|
|
134
135
|
o.update(out: [config[:stdout], 'a']) if config[:stdout]
|
|
135
136
|
o.update(err: [config[:stderr], 'a']) if config[:stderr]
|
|
136
137
|
o.update(in: config[:stdin]) if config[:stdin]
|
|
138
|
+
|
|
139
|
+
if Eye::Settings.root?
|
|
140
|
+
o.update(uid: Etc.getpwnam(config[:uid]).uid) if config[:uid]
|
|
141
|
+
o.update(gid: Etc.getpwnam(config[:gid]).gid) if config[:gid]
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
o.update(umask: config[:umask]) if config[:umask]
|
|
145
|
+
|
|
137
146
|
o
|
|
138
147
|
end
|
|
139
148
|
|
|
@@ -2,7 +2,8 @@ class Eye::Utils::AliveArray
|
|
|
2
2
|
extend Forwardable
|
|
3
3
|
include Enumerable
|
|
4
4
|
|
|
5
|
-
def_delegators :@arr, :[], :<<, :clear, :delete, :size, :empty?, :push,
|
|
5
|
+
def_delegators :@arr, :[], :<<, :clear, :delete, :size, :empty?, :push,
|
|
6
|
+
:flatten, :present?, :uniq!
|
|
6
7
|
|
|
7
8
|
def initialize(arr = [])
|
|
8
9
|
@arr = arr
|
|
@@ -28,4 +29,25 @@ class Eye::Utils::AliveArray
|
|
|
28
29
|
self.class.new super
|
|
29
30
|
end
|
|
30
31
|
|
|
32
|
+
def +(other)
|
|
33
|
+
if other.is_a?(Eye::Utils::AliveArray)
|
|
34
|
+
@arr += other.pure
|
|
35
|
+
elsif other.is_a?(Array)
|
|
36
|
+
@arr += other
|
|
37
|
+
else
|
|
38
|
+
raise "Unexpected + #{other}"
|
|
39
|
+
end
|
|
40
|
+
self
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def ==(other)
|
|
44
|
+
if other.is_a?(Eye::Utils::AliveArray)
|
|
45
|
+
@arr == other.pure
|
|
46
|
+
elsif other.is_a?(Array)
|
|
47
|
+
@arr == other
|
|
48
|
+
else
|
|
49
|
+
raise "Unexpected == #{other}"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
31
53
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: eye
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Konstantin Makarchev
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2013-
|
|
11
|
+
date: 2013-07-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: celluloid
|
|
@@ -109,7 +109,7 @@ dependencies:
|
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
110
|
version: '0'
|
|
111
111
|
- !ruby/object:Gem::Dependency
|
|
112
|
-
name:
|
|
112
|
+
name: rr
|
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
|
114
114
|
requirements:
|
|
115
115
|
- - '>='
|
|
@@ -123,7 +123,7 @@ dependencies:
|
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
124
|
version: '0'
|
|
125
125
|
- !ruby/object:Gem::Dependency
|
|
126
|
-
name:
|
|
126
|
+
name: ruby-graphviz
|
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
|
128
128
|
requirements:
|
|
129
129
|
- - '>='
|
|
@@ -137,7 +137,7 @@ dependencies:
|
|
|
137
137
|
- !ruby/object:Gem::Version
|
|
138
138
|
version: '0'
|
|
139
139
|
- !ruby/object:Gem::Dependency
|
|
140
|
-
name:
|
|
140
|
+
name: forking
|
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
|
142
142
|
requirements:
|
|
143
143
|
- - '>='
|
|
@@ -151,7 +151,7 @@ dependencies:
|
|
|
151
151
|
- !ruby/object:Gem::Version
|
|
152
152
|
version: '0'
|
|
153
153
|
- !ruby/object:Gem::Dependency
|
|
154
|
-
name:
|
|
154
|
+
name: fakeweb
|
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
|
156
156
|
requirements:
|
|
157
157
|
- - '>='
|
|
@@ -165,35 +165,35 @@ dependencies:
|
|
|
165
165
|
- !ruby/object:Gem::Version
|
|
166
166
|
version: '0'
|
|
167
167
|
- !ruby/object:Gem::Dependency
|
|
168
|
-
name:
|
|
168
|
+
name: eventmachine
|
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
|
170
170
|
requirements:
|
|
171
171
|
- - '>='
|
|
172
172
|
- !ruby/object:Gem::Version
|
|
173
|
-
version:
|
|
173
|
+
version: 1.0.3
|
|
174
174
|
type: :development
|
|
175
175
|
prerelease: false
|
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
|
177
177
|
requirements:
|
|
178
178
|
- - '>='
|
|
179
179
|
- !ruby/object:Gem::Version
|
|
180
|
-
version:
|
|
180
|
+
version: 1.0.3
|
|
181
181
|
- !ruby/object:Gem::Dependency
|
|
182
|
-
name:
|
|
182
|
+
name: sinatra
|
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
|
184
184
|
requirements:
|
|
185
185
|
- - '>='
|
|
186
186
|
- !ruby/object:Gem::Version
|
|
187
|
-
version:
|
|
187
|
+
version: '0'
|
|
188
188
|
type: :development
|
|
189
189
|
prerelease: false
|
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
|
191
191
|
requirements:
|
|
192
192
|
- - '>='
|
|
193
193
|
- !ruby/object:Gem::Version
|
|
194
|
-
version:
|
|
194
|
+
version: '0'
|
|
195
195
|
- !ruby/object:Gem::Dependency
|
|
196
|
-
name:
|
|
196
|
+
name: thin
|
|
197
197
|
requirement: !ruby/object:Gem::Requirement
|
|
198
198
|
requirements:
|
|
199
199
|
- - '>='
|
|
@@ -207,7 +207,7 @@ dependencies:
|
|
|
207
207
|
- !ruby/object:Gem::Version
|
|
208
208
|
version: '0'
|
|
209
209
|
- !ruby/object:Gem::Dependency
|
|
210
|
-
name:
|
|
210
|
+
name: xmpp4r
|
|
211
211
|
requirement: !ruby/object:Gem::Requirement
|
|
212
212
|
requirements:
|
|
213
213
|
- - '>='
|
|
@@ -221,7 +221,7 @@ dependencies:
|
|
|
221
221
|
- !ruby/object:Gem::Version
|
|
222
222
|
version: '0'
|
|
223
223
|
- !ruby/object:Gem::Dependency
|
|
224
|
-
name:
|
|
224
|
+
name: coveralls
|
|
225
225
|
requirement: !ruby/object:Gem::Requirement
|
|
226
226
|
requirements:
|
|
227
227
|
- - '>='
|
|
@@ -246,6 +246,7 @@ files:
|
|
|
246
246
|
- .gitignore
|
|
247
247
|
- .rspec
|
|
248
248
|
- .travis.yml
|
|
249
|
+
- CHANGES.md
|
|
249
250
|
- Gemfile
|
|
250
251
|
- LICENSE
|
|
251
252
|
- README.md
|