scout 2.0.7 → 4.0.0
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/CHANGELOG +15 -0
- data/Rakefile +14 -59
- data/data/cacert.pem +3154 -0
- data/data/gpl-2.0.txt +339 -0
- data/data/lgpl-2.1.txt +504 -0
- data/lib/scout.rb +4 -4
- data/lib/scout/command.rb +9 -0
- data/lib/scout/command/test.rb +8 -6
- data/lib/scout/plugin.rb +17 -6
- data/lib/scout/server.rb +127 -123
- data/vendor/json_pure/CHANGES +119 -0
- data/vendor/json_pure/GPL +340 -0
- data/vendor/json_pure/README +78 -0
- data/vendor/json_pure/RUBY +58 -0
- data/vendor/json_pure/Rakefile +270 -0
- data/vendor/json_pure/TODO +1 -0
- data/vendor/json_pure/VERSION +1 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkComparison.log +52 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast-autocorrelation.dat +1000 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast.dat +1001 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty-autocorrelation.dat +900 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty.dat +901 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe-autocorrelation.dat +1000 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe.dat +1001 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt.log +261 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast-autocorrelation.dat +1000 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast.dat +1001 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty-autocorrelation.dat +1000 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty.dat +1001 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe-autocorrelation.dat +1000 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe.dat +1001 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure.log +262 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator-autocorrelation.dat +1000 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator.dat +1001 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails.log +82 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkComparison.log +34 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser-autocorrelation.dat +900 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser.dat +901 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt.log +81 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser-autocorrelation.dat +1000 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser.dat +1001 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure.log +82 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser-autocorrelation.dat +1000 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser.dat +1001 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails.log +82 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser-autocorrelation.dat +1000 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser.dat +1001 -0
- data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML.log +82 -0
- data/vendor/json_pure/benchmarks/generator_benchmark.rb +165 -0
- data/vendor/json_pure/benchmarks/parser_benchmark.rb +197 -0
- data/vendor/json_pure/bin/edit_json.rb +9 -0
- data/vendor/json_pure/bin/prettify_json.rb +75 -0
- data/vendor/json_pure/data/example.json +1 -0
- data/vendor/json_pure/data/index.html +38 -0
- data/vendor/json_pure/data/prototype.js +4184 -0
- data/vendor/json_pure/doc-templates/main.txt +283 -0
- data/vendor/json_pure/ext/json/ext/generator/extconf.rb +11 -0
- data/vendor/json_pure/ext/json/ext/generator/generator.c +919 -0
- data/vendor/json_pure/ext/json/ext/generator/unicode.c +182 -0
- data/vendor/json_pure/ext/json/ext/generator/unicode.h +53 -0
- data/vendor/json_pure/ext/json/ext/parser/extconf.rb +11 -0
- data/vendor/json_pure/ext/json/ext/parser/parser.c +1829 -0
- data/vendor/json_pure/ext/json/ext/parser/parser.rl +686 -0
- data/vendor/json_pure/ext/json/ext/parser/unicode.c +154 -0
- data/vendor/json_pure/ext/json/ext/parser/unicode.h +58 -0
- data/vendor/json_pure/install.rb +26 -0
- data/vendor/json_pure/lib/json.rb +10 -0
- data/vendor/json_pure/lib/json/Array.xpm +21 -0
- data/vendor/json_pure/lib/json/FalseClass.xpm +21 -0
- data/vendor/json_pure/lib/json/Hash.xpm +21 -0
- data/vendor/json_pure/lib/json/Key.xpm +73 -0
- data/vendor/json_pure/lib/json/NilClass.xpm +21 -0
- data/vendor/json_pure/lib/json/Numeric.xpm +28 -0
- data/vendor/json_pure/lib/json/String.xpm +96 -0
- data/vendor/json_pure/lib/json/TrueClass.xpm +21 -0
- data/vendor/json_pure/lib/json/add/core.rb +135 -0
- data/vendor/json_pure/lib/json/add/rails.rb +58 -0
- data/vendor/json_pure/lib/json/common.rb +354 -0
- data/vendor/json_pure/lib/json/editor.rb +1371 -0
- data/vendor/json_pure/lib/json/ext.rb +15 -0
- data/vendor/json_pure/lib/json/json.xpm +1499 -0
- data/vendor/json_pure/lib/json/pure.rb +77 -0
- data/vendor/json_pure/lib/json/pure/generator.rb +430 -0
- data/vendor/json_pure/lib/json/pure/parser.rb +269 -0
- data/vendor/json_pure/lib/json/version.rb +8 -0
- data/vendor/json_pure/tests/fixtures/fail1.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail10.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail11.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail12.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail13.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail14.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail18.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail19.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail2.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail20.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail21.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail22.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail23.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail24.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail25.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail27.json +2 -0
- data/vendor/json_pure/tests/fixtures/fail28.json +2 -0
- data/vendor/json_pure/tests/fixtures/fail3.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail4.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail5.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail6.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail7.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail8.json +1 -0
- data/vendor/json_pure/tests/fixtures/fail9.json +1 -0
- data/vendor/json_pure/tests/fixtures/pass1.json +56 -0
- data/vendor/json_pure/tests/fixtures/pass15.json +1 -0
- data/vendor/json_pure/tests/fixtures/pass16.json +1 -0
- data/vendor/json_pure/tests/fixtures/pass17.json +1 -0
- data/vendor/json_pure/tests/fixtures/pass2.json +1 -0
- data/vendor/json_pure/tests/fixtures/pass26.json +1 -0
- data/vendor/json_pure/tests/fixtures/pass3.json +6 -0
- data/vendor/json_pure/tests/test_json.rb +312 -0
- data/vendor/json_pure/tests/test_json_addition.rb +164 -0
- data/vendor/json_pure/tests/test_json_fixtures.rb +34 -0
- data/vendor/json_pure/tests/test_json_generate.rb +106 -0
- data/vendor/json_pure/tests/test_json_rails.rb +146 -0
- data/vendor/json_pure/tests/test_json_unicode.rb +62 -0
- data/vendor/json_pure/tools/fuzz.rb +139 -0
- data/vendor/json_pure/tools/server.rb +61 -0
- metadata +120 -6
- data/lib/scout/command/clone.rb +0 -21
- data/setup.rb +0 -1360
- data/test/scout_test.rb +0 -91
data/lib/scout.rb
CHANGED
data/lib/scout/command.rb
CHANGED
|
@@ -199,6 +199,15 @@ module Scout
|
|
|
199
199
|
running = true
|
|
200
200
|
begin
|
|
201
201
|
Process.kill(0, pid)
|
|
202
|
+
if stat = File.stat(pid_file)
|
|
203
|
+
if mtime = stat.mtime
|
|
204
|
+
if Time.now - mtime > 25 * 60 # assume process is hung after 25m
|
|
205
|
+
log.info "Trying to KILL an old process..." if log
|
|
206
|
+
Process.kill("KILL", pid)
|
|
207
|
+
running = false
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
202
211
|
rescue Errno::ESRCH
|
|
203
212
|
running = false
|
|
204
213
|
rescue
|
data/lib/scout/command/test.rb
CHANGED
|
@@ -25,12 +25,14 @@ module Scout
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
Scout::Server.new(nil, nil, history, log) do |scout|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
scout.prepare_checkin
|
|
29
|
+
scout.process_plugin( 'interval' => 0,
|
|
30
|
+
'plugin_id' => 1,
|
|
31
|
+
'name' => "Local Plugin",
|
|
32
|
+
'code' => plugin_code,
|
|
33
|
+
'options' => plugin_options,
|
|
34
|
+
'path' => plugin )
|
|
35
|
+
scout.show_checkin(:pp)
|
|
34
36
|
end
|
|
35
37
|
end
|
|
36
38
|
end
|
data/lib/scout/plugin.rb
CHANGED
|
@@ -69,22 +69,33 @@ module Scout
|
|
|
69
69
|
# add_error(:subject => "subject", :body => "body")
|
|
70
70
|
#
|
|
71
71
|
def data_for_server
|
|
72
|
-
@data_for_server ||= { :reports
|
|
73
|
-
:alerts
|
|
74
|
-
:errors
|
|
72
|
+
@data_for_server ||= { :reports => [ ],
|
|
73
|
+
:alerts => [ ],
|
|
74
|
+
:errors => [ ],
|
|
75
|
+
:summaries => [ ],
|
|
75
76
|
:memory => { } }
|
|
76
77
|
end
|
|
77
78
|
|
|
78
|
-
%w[report alert error].each do |kind|
|
|
79
|
+
%w[report alert error summary].each do |kind|
|
|
79
80
|
class_eval <<-END
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
if "#{kind}" == "summary"
|
|
82
|
+
def summaries
|
|
83
|
+
data_for_server[:summaries]
|
|
84
|
+
end
|
|
85
|
+
else
|
|
86
|
+
def #{kind}s
|
|
87
|
+
data_for_server[:#{kind}s]
|
|
88
|
+
end
|
|
82
89
|
end
|
|
83
90
|
|
|
84
91
|
if "#{kind}" == "report"
|
|
85
92
|
def report(new_entry)
|
|
86
93
|
reports << new_entry
|
|
87
94
|
end
|
|
95
|
+
elsif "#{kind}" == "summary"
|
|
96
|
+
def summary(new_entry)
|
|
97
|
+
summaries << new_entry
|
|
98
|
+
end
|
|
88
99
|
else
|
|
89
100
|
def #{kind}(*fields)
|
|
90
101
|
#{kind}s << ( fields.first.is_a?(Hash) ?
|
data/lib/scout/server.rb
CHANGED
|
@@ -4,6 +4,12 @@ require "net/https"
|
|
|
4
4
|
require "uri"
|
|
5
5
|
require "yaml"
|
|
6
6
|
require "timeout"
|
|
7
|
+
require "stringio"
|
|
8
|
+
require "zlib"
|
|
9
|
+
require "socket"
|
|
10
|
+
|
|
11
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), *%w[.. .. vendor json_pure lib])
|
|
12
|
+
require "json"
|
|
7
13
|
|
|
8
14
|
module Scout
|
|
9
15
|
class Server
|
|
@@ -12,18 +18,17 @@ module Scout
|
|
|
12
18
|
# A new class for API Timeout errors.
|
|
13
19
|
class APITimeoutError < RuntimeError; end
|
|
14
20
|
|
|
15
|
-
#
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
:clone => "/clients/CLIENT_KEY/clone_from?version=CLIENT_VERSION" }
|
|
21
|
-
|
|
21
|
+
# Headers passed up with all API requests.
|
|
22
|
+
HTTP_HEADERS = { "CLIENT_VERSION" => Scout::VERSION,
|
|
23
|
+
"CLIENT_HOSTNAME" => Socket.gethostname,
|
|
24
|
+
"ACCEPT_ENCODING" => "gzip" }
|
|
25
|
+
|
|
22
26
|
#
|
|
23
|
-
# A plugin cannot take more than
|
|
24
|
-
# otherwise, a timeout error is generated.
|
|
27
|
+
# A plugin cannot take more than DEFAULT_PLUGIN_TIMEOUT seconds to execute,
|
|
28
|
+
# otherwise, a timeout error is generated. This can be overriden by
|
|
29
|
+
# individual plugins.
|
|
25
30
|
#
|
|
26
|
-
|
|
31
|
+
DEFAULT_PLUGIN_TIMEOUT = 60
|
|
27
32
|
#
|
|
28
33
|
# A fuzzy range of seconds in which it is okay to rerun a plugin.
|
|
29
34
|
# We consider the interval close enough at this point.
|
|
@@ -45,6 +50,18 @@ module Scout
|
|
|
45
50
|
end
|
|
46
51
|
end
|
|
47
52
|
|
|
53
|
+
# Prepares a check-in data structure to hold Plugin generated data.
|
|
54
|
+
def prepare_checkin
|
|
55
|
+
@checkin = { :reports => Array.new,
|
|
56
|
+
:alerts => Array.new,
|
|
57
|
+
:errors => Array.new,
|
|
58
|
+
:summaries => Array.new }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def show_checkin(printer = :p)
|
|
62
|
+
send(printer, @checkin)
|
|
63
|
+
end
|
|
64
|
+
|
|
48
65
|
#
|
|
49
66
|
# Loads the history file from disk. If the file does not exist,
|
|
50
67
|
# it creates one.
|
|
@@ -72,7 +89,9 @@ module Scout
|
|
|
72
89
|
# Runs all plugins from a given plan. Calls process_plugin on each plugin.
|
|
73
90
|
def run_plugins_by_plan
|
|
74
91
|
plan do |plugin|
|
|
92
|
+
prepare_checkin
|
|
75
93
|
process_plugin(plugin)
|
|
94
|
+
checkin
|
|
76
95
|
end
|
|
77
96
|
end
|
|
78
97
|
|
|
@@ -86,17 +105,23 @@ module Scout
|
|
|
86
105
|
# set memory and last_run information in the history file.
|
|
87
106
|
#
|
|
88
107
|
def process_plugin(plugin)
|
|
89
|
-
info "Processing the #{plugin[
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
108
|
+
info "Processing the #{plugin['name']} plugin:"
|
|
109
|
+
id_and_name = "#{plugin['id']}-#{plugin['name']}".sub(/\A-/, "")
|
|
110
|
+
last_run = @history["last_runs"][id_and_name] ||
|
|
111
|
+
@history["last_runs"][plugin['name']]
|
|
112
|
+
memory = @history["memory"][id_and_name] ||
|
|
113
|
+
@history["memory"][plugin['name']]
|
|
114
|
+
run_time = Time.now
|
|
115
|
+
delta = last_run.nil? ? nil : run_time -
|
|
116
|
+
(last_run + plugin['interval'] * 60)
|
|
94
117
|
if last_run.nil? or delta.between?(-RUN_DELTA, 0) or delta >= 0
|
|
95
118
|
debug "Plugin is past interval and needs to be run. " +
|
|
96
119
|
"(last run: #{last_run || 'nil'})"
|
|
97
120
|
debug "Compiling plugin..."
|
|
98
121
|
begin
|
|
99
|
-
eval(plugin[
|
|
122
|
+
eval( plugin['code'],
|
|
123
|
+
TOPLEVEL_BINDING,
|
|
124
|
+
plugin['path'] || plugin['name'] )
|
|
100
125
|
info "Plugin compiled."
|
|
101
126
|
rescue Exception
|
|
102
127
|
raise if $!.is_a? SystemExit
|
|
@@ -105,12 +130,14 @@ module Scout
|
|
|
105
130
|
end
|
|
106
131
|
debug "Loading plugin..."
|
|
107
132
|
if job = Plugin.last_defined.load( last_run, (memory || Hash.new),
|
|
108
|
-
plugin[
|
|
133
|
+
plugin['options'] || Hash.new )
|
|
109
134
|
info "Plugin loaded."
|
|
110
135
|
debug "Running plugin..."
|
|
111
136
|
begin
|
|
112
|
-
data
|
|
113
|
-
|
|
137
|
+
data = {}
|
|
138
|
+
timeout = plugin['timeout'].to_i
|
|
139
|
+
timeout = DEFAULT_PLUGIN_TIMEOUT unless timeout > 0
|
|
140
|
+
Timeout.timeout(timeout, PluginTimeoutError) do
|
|
114
141
|
data = job.run
|
|
115
142
|
end
|
|
116
143
|
rescue Timeout::Error
|
|
@@ -118,30 +145,27 @@ module Scout
|
|
|
118
145
|
return
|
|
119
146
|
rescue Exception
|
|
120
147
|
raise if $!.is_a? SystemExit
|
|
121
|
-
error "Plugin failed to run: #{$!.class}: #{
|
|
148
|
+
error "Plugin failed to run: #{$!.class}: #{$!.message}\n" +
|
|
149
|
+
"#{$!.backtrace.join("\n")}"
|
|
122
150
|
end
|
|
123
151
|
info "Plugin completed its run."
|
|
124
152
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
# handle single alert or array of alerts
|
|
131
|
-
send_alert(data[:alert], plugin[:plugin_id]) if data[:alert]
|
|
132
|
-
if data[:alerts] and not data[:alerts].empty?
|
|
133
|
-
data[:alerts].each { |a| send_alert(a, plugin[:plugin_id]) }
|
|
134
|
-
end
|
|
135
|
-
# handle single error or array of errors
|
|
136
|
-
send_error(data[:error], plugin[:plugin_id]) if data[:error]
|
|
137
|
-
if data[:errors] and not data[:errors].empty?
|
|
138
|
-
data[:errors].each { |e| send_error(e, plugin[:plugin_id]) }
|
|
153
|
+
%w[report alert error summary].each do |type|
|
|
154
|
+
plural = "#{type}s".sub(/ys\z/, "ies").to_sym
|
|
155
|
+
(Array(data[type.to_sym]) + Array(data[plural])).each do |fields|
|
|
156
|
+
@checkin[plural] << build_report(plugin['id'], fields)
|
|
157
|
+
end
|
|
139
158
|
end
|
|
140
159
|
|
|
141
|
-
@history["last_runs"]
|
|
142
|
-
@history["memory"]
|
|
160
|
+
@history["last_runs"].delete(plugin['name'])
|
|
161
|
+
@history["memory"].delete(plugin['name'])
|
|
162
|
+
@history["last_runs"][id_and_name] = run_time
|
|
163
|
+
@history["memory"][id_and_name] = data[:memory]
|
|
143
164
|
else
|
|
144
|
-
|
|
165
|
+
@checkin[:errors] << build_report(
|
|
166
|
+
plugin_id['id'],
|
|
167
|
+
:subject => "Plugin would not load."
|
|
168
|
+
)
|
|
145
169
|
end
|
|
146
170
|
else
|
|
147
171
|
debug "Plugin does not need to be run at this time. " +
|
|
@@ -160,7 +184,7 @@ module Scout
|
|
|
160
184
|
error "Unable to remove plugin."
|
|
161
185
|
end
|
|
162
186
|
end
|
|
163
|
-
info "Plugin #{plugin[
|
|
187
|
+
info "Plugin #{plugin['name']} processing complete."
|
|
164
188
|
end
|
|
165
189
|
|
|
166
190
|
#
|
|
@@ -170,118 +194,80 @@ module Scout
|
|
|
170
194
|
def plan
|
|
171
195
|
url = urlify(:plan)
|
|
172
196
|
info "Loading plan from #{url}..."
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
197
|
+
headers = Hash.new
|
|
198
|
+
if @history["last_modified_for_plugins"] and @history["old_plugins"]
|
|
199
|
+
headers["If-Modified-Since"] = @history["last_modified_for_plugins"]
|
|
200
|
+
end
|
|
201
|
+
get(url, "Could not retrieve plan from server.", headers) do |res|
|
|
202
|
+
if res.is_a? Net::HTTPNotModified
|
|
203
|
+
info "Plan not modified. Reusing saved plan."
|
|
204
|
+
plugin_execution_plan = Array(@history["old_plugins"])
|
|
205
|
+
else
|
|
206
|
+
begin
|
|
207
|
+
body = res.body
|
|
208
|
+
if res["Content-Encoding"] == "gzip" and body and not body.empty?
|
|
209
|
+
body = Zlib::GzipReader.new(StringIO.new(body)).read
|
|
210
|
+
end
|
|
211
|
+
plugin_execution_plan = Array(JSON.parse(body)["plugins"])
|
|
212
|
+
if res["Last-Modified"]
|
|
213
|
+
@history["last_modified_for_plugins"] = res["last-modified"]
|
|
214
|
+
@history["old_plugins"] = plugin_execution_plan
|
|
215
|
+
end
|
|
216
|
+
info "Plan loaded. (#{plugin_execution_plan.size} plugins: " +
|
|
217
|
+
"#{plugin_execution_plan.map { |p| p['name'] }.join(', ')})"
|
|
218
|
+
rescue Exception
|
|
219
|
+
fatal "Plan from server was malformed."
|
|
220
|
+
exit
|
|
221
|
+
end
|
|
182
222
|
end
|
|
183
223
|
plugin_execution_plan.each do |plugin|
|
|
184
224
|
begin
|
|
185
225
|
yield plugin if block_given?
|
|
186
226
|
rescue RuntimeError
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
227
|
+
@checkin[:errors] << build_report(
|
|
228
|
+
plugin_id['id'],
|
|
229
|
+
:subject => "Exception: #{$!.message}.",
|
|
230
|
+
:body => $!.backtrace
|
|
231
|
+
)
|
|
190
232
|
end
|
|
191
233
|
end
|
|
192
234
|
end
|
|
193
235
|
end
|
|
194
236
|
alias_method :test, :plan
|
|
195
|
-
|
|
196
|
-
# Sends report data to the Scout Server.
|
|
197
|
-
def send_report(data, plugin_id)
|
|
198
|
-
url = urlify(:report, :plugin_id => plugin_id)
|
|
199
|
-
report_hash = {:data => data, :plugin_id => plugin_id}
|
|
200
|
-
|
|
201
|
-
# add in any special fields
|
|
202
|
-
if time = ( data.delete(:scout_time) || data.delete("scout_time") )
|
|
203
|
-
report_hash[:time] = time
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
debug "Sending report to #{url} (#{data.inspect})..."
|
|
207
|
-
post url,
|
|
208
|
-
"Unable to send report to server.",
|
|
209
|
-
:report => report_hash
|
|
210
|
-
info "Report sent."
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
# Sends an alert to the Scout Server.
|
|
214
|
-
def send_alert(data, plugin_id)
|
|
215
|
-
url = urlify(:alert, :plugin_id => plugin_id)
|
|
216
|
-
debug "Sending alert to #{url} (subject: #{data[:subject]})..."
|
|
217
|
-
post url,
|
|
218
|
-
"Unable to send alert to server.",
|
|
219
|
-
:alert => data.merge(:plugin_id => plugin_id)
|
|
220
|
-
info "Alert sent."
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
# Sends an error to the Scout Server.
|
|
224
|
-
def send_error(data, plugin_id)
|
|
225
|
-
url = urlify(:error, :plugin_id => plugin_id)
|
|
226
|
-
debug "Sending error to #{url} (subject: #{data[:subject]})..."
|
|
227
|
-
post url,
|
|
228
|
-
"Unable to log error on server.",
|
|
229
|
-
:error => data.merge(:plugin_id => plugin_id)
|
|
230
|
-
info "Error sent."
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
def clone_client(new_name, success_output)
|
|
234
|
-
url = urlify(:clone)
|
|
235
|
-
debug "Sending clone request to #{url}..."
|
|
236
|
-
post( url,
|
|
237
|
-
"Unable to send clone request to server.",
|
|
238
|
-
"client[name]" => new_name ) do |response|
|
|
239
|
-
case server_reply = response.body
|
|
240
|
-
when /\AError:/i
|
|
241
|
-
fatal "Clone error."
|
|
242
|
-
abort server_reply
|
|
243
|
-
else
|
|
244
|
-
info "Client cloned."
|
|
245
|
-
puts success_output.gsub(/\bCLIENT_KEY\b/, server_reply.strip)
|
|
246
|
-
end
|
|
247
|
-
end
|
|
248
|
-
end
|
|
249
237
|
|
|
250
238
|
private
|
|
239
|
+
|
|
240
|
+
def build_report(plugin_id, fields)
|
|
241
|
+
{ :plugin_id => plugin_id,
|
|
242
|
+
:created_at => Time.now.utc.strftime("%Y-%m-%d %H:%M:%S"),
|
|
243
|
+
:fields => fields }
|
|
244
|
+
end
|
|
251
245
|
|
|
252
246
|
def urlify(url_name, options = Hash.new)
|
|
253
247
|
return unless @server
|
|
254
248
|
options.merge!(:client_version => Scout::VERSION)
|
|
255
249
|
URI.join( @server,
|
|
256
|
-
|
|
250
|
+
"/clients/CLIENT_KEY/#{url_name}.scout".
|
|
257
251
|
gsub(/\bCLIENT_KEY\b/, @client_key).
|
|
258
252
|
gsub(/\b[A-Z_]+\b/) { |k| options[k.downcase.to_sym] || k } )
|
|
259
253
|
end
|
|
260
|
-
|
|
261
|
-
def paramify(params, prefix = nil)
|
|
262
|
-
params.inject(Hash.new) do |all, (key, value)|
|
|
263
|
-
parent = prefix ? "#{prefix}[#{key}]" : String(key)
|
|
264
|
-
if value.is_a? Hash
|
|
265
|
-
all.merge(paramify(value, parent))
|
|
266
|
-
else
|
|
267
|
-
all.merge(parent => String(value))
|
|
268
|
-
end
|
|
269
|
-
end
|
|
270
|
-
end
|
|
271
254
|
|
|
272
|
-
def post(url, error,
|
|
255
|
+
def post(url, error, body, headers = Hash.new, &response_handler)
|
|
273
256
|
return unless url
|
|
274
257
|
request(url, response_handler, error) do |connection|
|
|
275
|
-
post = Net::HTTP::Post.new(url.path +
|
|
276
|
-
|
|
258
|
+
post = Net::HTTP::Post.new( url.path +
|
|
259
|
+
(url.query ? ('?' + url.query) : ''),
|
|
260
|
+
HTTP_HEADERS.merge(headers) )
|
|
261
|
+
post.body = body
|
|
277
262
|
connection.request(post)
|
|
278
263
|
end
|
|
279
264
|
end
|
|
280
265
|
|
|
281
|
-
def get(url, error,
|
|
266
|
+
def get(url, error, headers = Hash.new, &response_handler)
|
|
282
267
|
return unless url
|
|
283
268
|
request(url, response_handler, error) do |connection|
|
|
284
|
-
connection.get(url.path + (url.query ? ('?' + url.query) : '')
|
|
269
|
+
connection.get( url.path + (url.query ? ('?' + url.query) : ''),
|
|
270
|
+
HTTP_HEADERS.merge(headers) )
|
|
285
271
|
end
|
|
286
272
|
end
|
|
287
273
|
|
|
@@ -291,12 +277,15 @@ module Scout
|
|
|
291
277
|
http = Net::HTTP.new(url.host, url.port)
|
|
292
278
|
if url.is_a? URI::HTTPS
|
|
293
279
|
http.use_ssl = true
|
|
294
|
-
http.
|
|
280
|
+
http.ca_file = File.join( File.dirname(__FILE__),
|
|
281
|
+
*%w[.. .. data cacert.pem] )
|
|
282
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER |
|
|
283
|
+
OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
|
295
284
|
end
|
|
296
285
|
response = no_warnings { http.start(&connector) }
|
|
297
286
|
end
|
|
298
287
|
case response
|
|
299
|
-
when Net::HTTPSuccess
|
|
288
|
+
when Net::HTTPSuccess, Net::HTTPNotModified
|
|
300
289
|
response_handler[response] unless response_handler.nil?
|
|
301
290
|
else
|
|
302
291
|
fatal error
|
|
@@ -311,6 +300,21 @@ module Scout
|
|
|
311
300
|
exit
|
|
312
301
|
end
|
|
313
302
|
|
|
303
|
+
def checkin
|
|
304
|
+
io = StringIO.new
|
|
305
|
+
gzip = Zlib::GzipWriter.new(io)
|
|
306
|
+
gzip << @checkin.to_json
|
|
307
|
+
gzip.close
|
|
308
|
+
post( urlify(:checkin),
|
|
309
|
+
"Unable to check in with the server.",
|
|
310
|
+
io.string,
|
|
311
|
+
"Content-Type" => "application/json",
|
|
312
|
+
"CONTENT_ENCODING" => "gzip" )
|
|
313
|
+
rescue Exception
|
|
314
|
+
error "Unable to check in with the server."
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
|
|
314
318
|
def no_warnings
|
|
315
319
|
old_verbose = $VERBOSE
|
|
316
320
|
$VERBOSE = false
|