ztk 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +0 -1
- data/WIKI.md +264 -6
- data/lib/ztk.rb +3 -0
- data/lib/ztk/base.rb +72 -0
- data/lib/ztk/logger.rb +8 -0
- data/lib/ztk/parallel.rb +24 -31
- data/lib/ztk/ssh.rb +34 -27
- data/lib/ztk/tcp_socket_check.rb +103 -0
- data/lib/ztk/template.rb +71 -0
- data/lib/ztk/version.rb +1 -1
- data/spec/support/test-template.txt.erb +1 -0
- data/spec/ztk/logger_spec.rb +6 -2
- data/spec/ztk/parallel_spec.rb +31 -11
- data/spec/ztk/ssh_spec.rb +84 -0
- data/spec/ztk/tcp_socket_check_spec.rb +115 -0
- data/spec/ztk/template_spec.rb +46 -0
- data/ztk.gemspec +1 -0
- metadata +30 -3
data/Gemfile
CHANGED
data/WIKI.md
CHANGED
@@ -8,7 +8,7 @@ Zachary's Tool Kit is a general purpose utility gem, featuring a collection of c
|
|
8
8
|
|
9
9
|
Add this line to your application's Gemfile:
|
10
10
|
|
11
|
-
gem
|
11
|
+
gem "ztk"
|
12
12
|
|
13
13
|
And then execute:
|
14
14
|
|
@@ -20,13 +20,18 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
|
23
|
+
## Console
|
24
|
+
|
25
|
+
bundle install
|
26
|
+
bundle exec ztk
|
27
|
+
|
28
|
+
## ZTK::Parallel
|
24
29
|
|
25
30
|
Parallel Processing Class
|
26
31
|
|
27
32
|
This class can be used to easily run iterative and linear processes in a parallel manner.
|
28
33
|
|
29
|
-
Example Ruby Code
|
34
|
+
### ZTK::Parallel Example Ruby Code
|
30
35
|
|
31
36
|
$logger = ZTK::Logger.new(STDOUT)
|
32
37
|
a_callback = Proc.new do |pid|
|
@@ -48,7 +53,7 @@ Example Ruby Code:
|
|
48
53
|
parallel.waitall
|
49
54
|
parallel.results
|
50
55
|
|
51
|
-
Example Code Pry Run
|
56
|
+
### ZTK::Parallel Example Code Pry Run
|
52
57
|
|
53
58
|
[1] pry(main)> $logger = ZTK::Logger.new(STDOUT)
|
54
59
|
=> #<ZTK::Logger:0x0000000204d498
|
@@ -129,8 +134,7 @@ Default Config Values for ZTK::Parallel:
|
|
129
134
|
:before_fork => nil,
|
130
135
|
:after_fork => nil
|
131
136
|
|
132
|
-
|
133
|
-
### ZTK::Logger
|
137
|
+
## ZTK::Logger
|
134
138
|
|
135
139
|
Logging Class
|
136
140
|
|
@@ -146,6 +150,260 @@ Example:
|
|
146
150
|
$logger.error { "This is a error message!" }
|
147
151
|
$logger.fatal { "This is a fatal message!" }
|
148
152
|
|
153
|
+
Example Output:
|
154
|
+
|
155
|
+
2012-09-01|21:34:45.216262|23603|FATAL|logger_spec.rb:122:block (5 levels) in <top (required)>|This is a test fatal message
|
156
|
+
|
157
|
+
## ZTK::SSH
|
158
|
+
|
159
|
+
SSH Class
|
160
|
+
|
161
|
+
Simplified SSH class; it provides for remote execute of commands and returning of command output. Additionally it allows for uploading and downloading of files.
|
162
|
+
|
163
|
+
### ZTK::SSH Example Ruby Code
|
164
|
+
|
165
|
+
$logger = ZTK::Logger.new(STDOUT)
|
166
|
+
ssh = ZTK::SSH.new
|
167
|
+
ssh.config do |config|
|
168
|
+
config.ssh.user = ENV["USER"]
|
169
|
+
config.ssh.host = "127.0.0.1"
|
170
|
+
end
|
171
|
+
puts ssh.exec("hostname -f")
|
172
|
+
local = File.expand_path(File.join("/tmp", "id_rsa.pub"))
|
173
|
+
remote = File.expand_path(File.join(ENV["HOME"], ".ssh", "id_rsa.pub"))
|
174
|
+
ssh.download(remote, local)
|
175
|
+
|
176
|
+
### ZTK::SSH Example Code Pry Run
|
177
|
+
|
178
|
+
[1] pry(main)> $logger = ZTK::Logger.new(STDOUT)
|
179
|
+
=> #<ZTK::Logger:0x000000025f2c18
|
180
|
+
@default_formatter=#<Logger::Formatter:0x000000025f2ab0 @datetime_format=nil>,
|
181
|
+
@formatter=nil,
|
182
|
+
@level=1,
|
183
|
+
@logdev=
|
184
|
+
#<Logger::LogDevice:0x000000025fcc18
|
185
|
+
@dev=#<IO:<STDOUT>>,
|
186
|
+
@filename=nil,
|
187
|
+
@mutex=
|
188
|
+
#<Logger::LogDevice::LogDeviceMutex:0x000000025fcbf0
|
189
|
+
@mon_count=0,
|
190
|
+
@mon_mutex=#<Mutex:0x000000025fc9e8>,
|
191
|
+
@mon_owner=nil>,
|
192
|
+
@shift_age=nil,
|
193
|
+
@shift_size=nil>,
|
194
|
+
@progname=nil>
|
195
|
+
[2] pry(main)> ssh = ZTK::SSH.new
|
196
|
+
=> #<ZTK::SSH:0x00000002c317c8
|
197
|
+
@config=
|
198
|
+
#<OpenStruct stdout=#<IO:<STDOUT>>, stderr=#<IO:<STDERR>>, stdin=#<IO:<STDIN>>, logger=#<ZTK::Logger:0x000000025f2c18 @progname=nil, @level=1, @default_formatter=#<Logger::Formatter:0x000000025f2ab0 @datetime_format=nil>, @formatter=nil, @logdev=#<Logger::LogDevice:0x000000025fcc18 @shift_size=nil, @shift_age=nil, @filename=nil, @dev=#<IO:<STDOUT>>, @mutex=#<Logger::LogDevice::LogDeviceMutex:0x000000025fcbf0 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0x000000025fc9e8>>>>, ssh=#<OpenStruct>>>
|
199
|
+
[3] pry(main)> ssh.config do |config|
|
200
|
+
[3] pry(main)* config.ssh.user = ENV["USER"]
|
201
|
+
[3] pry(main)* config.ssh.host = "127.0.0.1"
|
202
|
+
[3] pry(main)* end
|
203
|
+
=> "127.0.0.1"
|
204
|
+
[4] pry(main)> puts ssh.exec("hostname -f")
|
205
|
+
2012-09-01|04:49:47.723411|25709| INFO|ssh.rb:76:exec|command(hostname -f)
|
206
|
+
staging.jovelabs.net
|
207
|
+
staging.jovelabs.net
|
208
|
+
=> nil
|
209
|
+
[5] pry(main)> local = File.expand_path(File.join("/tmp", "id_rsa.pub"))
|
210
|
+
=> "/tmp/id_rsa.pub"
|
211
|
+
[6] pry(main)> remote = File.expand_path(File.join(ENV["HOME"], ".ssh", "id_rsa.pub"))
|
212
|
+
=> "/home/zpatten/.ssh/id_rsa.pub"
|
213
|
+
[7] pry(main)> ssh.download(remote, local)
|
214
|
+
2012-09-01|04:49:48.153389|25709| INFO|ssh.rb:133:download|parameters(/home/zpatten/.ssh/id_rsa.pub,/tmp/id_rsa.pub)
|
215
|
+
2012-09-01|04:49:48.153536|25709| INFO|ssh.rb:137:block in download|download(/home/zpatten/.ssh/id_rsa.pub -> /tmp/id_rsa.pub)
|
216
|
+
2012-09-01|04:49:48.156243|25709| INFO|ssh.rb:145:block in download|finish
|
217
|
+
=> true
|
218
|
+
|
219
|
+
### ZTK::SSH Config
|
220
|
+
|
221
|
+
To proxy through another host, for example SSH to 192.168.1.1 through 192.168.0.1:
|
222
|
+
|
223
|
+
ssh.config do |config|
|
224
|
+
config.ssh.user = ENV["USER"]
|
225
|
+
config.ssh.host = "192.168.1.1"
|
226
|
+
config.ssh.proxy_user = ENV["USER"]
|
227
|
+
config.ssh.proxy_host = "192.168.0.1"
|
228
|
+
end
|
229
|
+
|
230
|
+
Specify an identity file:
|
231
|
+
|
232
|
+
ssh.config do |config|
|
233
|
+
config.ssh.identify_file = File.expand_path(File.join(ENV["HOME"], ".ssh", "id_rsa"))
|
234
|
+
config.ssh.proxy_identify_file = File.expand_path(File.join(ENV["HOME"], ".ssh", "id_rsa"))
|
235
|
+
end
|
236
|
+
|
237
|
+
Specify a timeout:
|
238
|
+
|
239
|
+
ssh.config do |config|
|
240
|
+
config.ssh.timeout = 30
|
241
|
+
end
|
242
|
+
|
243
|
+
Specify a password:
|
244
|
+
|
245
|
+
ssh.config do |config|
|
246
|
+
config.ssh.password = "p@$$w0rd"
|
247
|
+
end
|
248
|
+
|
249
|
+
Check host keys, the default is false (off):
|
250
|
+
|
251
|
+
ssh.config do |config|
|
252
|
+
config.ssh.host_key_verify = true
|
253
|
+
end
|
254
|
+
|
255
|
+
### ZTK::SSH Core Methods
|
256
|
+
|
257
|
+
#### Execute A Command
|
258
|
+
|
259
|
+
ssh.exec(command, options={})
|
260
|
+
|
261
|
+
Where `command` is a command (i.e. `String`) to execute on the remote host (i.e. "hostname -f"). You can optionally pass `:silence => true` into `options` to suppress session output from going to STDOUT and STDERR.
|
262
|
+
|
263
|
+
#### Upload A File
|
264
|
+
|
265
|
+
ssh.upload(local, remote)
|
266
|
+
|
267
|
+
Where `local` is the local file/path you wish to upload on the local host to the `remote` file/path on the remote host.
|
268
|
+
|
269
|
+
#### Download A File
|
270
|
+
|
271
|
+
ssh.download(remote, local)
|
272
|
+
|
273
|
+
Where `remote` is the remote file/path you wish to download on the remote host to the `local` file/path on the local host.
|
274
|
+
|
275
|
+
## ZTK::Template
|
276
|
+
|
277
|
+
Erubis Templating
|
278
|
+
|
279
|
+
### ZTK::Template Example Ruby Code
|
280
|
+
|
281
|
+
template_file = File.expand_path(File.join(File.dirname(__FILE__), "spec", "support", "test-template.txt.erb"))
|
282
|
+
IO.read(template_file)
|
283
|
+
context = { :test_variable => "Hello World" }
|
284
|
+
ZTK::Template.render(template_file, context)
|
285
|
+
|
286
|
+
### ZTK::Template Example Code Pry Run
|
287
|
+
|
288
|
+
[1] pry(main)> template_file = File.expand_path(File.join(File.dirname(__FILE__), "spec", "support", "test-template.txt.erb"))
|
289
|
+
=> "/home/zpatten/Dropbox/code/ztk/spec/support/test-template.txt.erb"
|
290
|
+
[2] pry(main)> IO.read(template_file)
|
291
|
+
=> "<%= @test_variable %>\n"
|
292
|
+
[3] pry(main)> context = { :test_variable => "Hello World" }
|
293
|
+
=> {:test_variable=>"Hello World"}
|
294
|
+
[4] pry(main)> ZTK::Template.render(template_file, context)
|
295
|
+
=> "Hello World"
|
296
|
+
|
297
|
+
## ZTK::TCPSocketCheck
|
298
|
+
|
299
|
+
Check TCP Sockets
|
300
|
+
|
301
|
+
This class has two basic modes of operation:
|
302
|
+
|
303
|
+
* Read Test
|
304
|
+
|
305
|
+
By default we will perform a read test against the host and port specified. In this mode we will attempt to connect to the host and port supplied and if we can read any amount of data, regardless of the content we view this as success.
|
306
|
+
|
307
|
+
* Write Test
|
308
|
+
|
309
|
+
If `data` is supplied via the configuration, this will change the mode of operation to a write test. Certain services, such as HTTP don't send any data unless you send something first. In this mode we will attempt to connect to the host and port supplied, once connected we will write the supplied `data` to the socket and then attempt to read from the socket. If we can read any amount of data, reagardless of the conent we view this as success.
|
310
|
+
|
311
|
+
### ZTK::TCPSocketCheck Example Ruby Code
|
312
|
+
|
313
|
+
tcp_check = ZTK::TCPSocketCheck.new(:host => "github.com", :port => 22)
|
314
|
+
tcp_check.wait
|
315
|
+
tcp_check.ready?
|
316
|
+
|
317
|
+
### ZTK::TCPSocketCheck Example Code Pry Run
|
318
|
+
|
319
|
+
[1] pry(main)> tcp_check = ZTK::TCPSocketCheck.new(:host => "github.com", :port => 22)
|
320
|
+
=> #<ZTK::TCPSocketCheck:0x00000001890d18
|
321
|
+
@config=
|
322
|
+
#<OpenStruct stdout=#<IO:<STDOUT>>, stderr=#<IO:<STDERR>>, stdin=#<IO:<STDIN>>, logger=nil, host="github.com", port=22, data=nil, timeout=5>>
|
323
|
+
[2] pry(main)> tcp_check.wait
|
324
|
+
=> nil
|
325
|
+
[3] pry(main)> tcp_check.ready?
|
326
|
+
=> true
|
327
|
+
|
328
|
+
### ZTK::TCPSocketCheck Config
|
329
|
+
|
330
|
+
Here is an example TCPSocketCheck configuration. The `timeout` and `wait` values shown are the defaults if omitted.
|
331
|
+
|
332
|
+
tcp_check = ZTK::TCPSocketCheck.new
|
333
|
+
tcp_check.config do |config|
|
334
|
+
config.host = "www.google.com"
|
335
|
+
config.port = 80
|
336
|
+
config.data = "GET"
|
337
|
+
config.timeout = 5
|
338
|
+
config.wait = 60
|
339
|
+
end
|
340
|
+
|
341
|
+
Specify the host and port (required):
|
342
|
+
|
343
|
+
tcp_check = ZTK::TCPSocketCheck.new
|
344
|
+
tcp_check.config do |config|
|
345
|
+
config.host = "www.google.com"
|
346
|
+
config.port = 80
|
347
|
+
end
|
348
|
+
|
349
|
+
Specify data to write (switches to a write mode test if this is supplied):
|
350
|
+
|
351
|
+
tcp_check = ZTK::TCPSocketCheck.new
|
352
|
+
tcp_check.config do |config|
|
353
|
+
config.host = "www.google.com"
|
354
|
+
config.port = 80
|
355
|
+
config.data = "GET"
|
356
|
+
end
|
357
|
+
|
358
|
+
Override the `timeout` and `wait` values:
|
359
|
+
|
360
|
+
tcp_check = ZTK::TCPSocketCheck.new
|
361
|
+
tcp_check.config do |config|
|
362
|
+
config.host = "www.google.com"
|
363
|
+
config.port = 80
|
364
|
+
config.data = "GET"
|
365
|
+
config.timeout = 3
|
366
|
+
config.wait = 5
|
367
|
+
end
|
368
|
+
|
369
|
+
### ZTK::TCPSocketCheck Core Methods
|
370
|
+
|
371
|
+
#### Socket Ready?
|
372
|
+
|
373
|
+
We can use the `ready?` method to test if the socket is ready in a one off manner. This operations runtime is bound by the `timeout` configuration value.
|
374
|
+
|
375
|
+
tcp_check = ZTK::TCPSocketCheck.new
|
376
|
+
tcp_check.config do |config|
|
377
|
+
config.host = "www.google.com"
|
378
|
+
config.port = 80
|
379
|
+
config.data = "GET"
|
380
|
+
end
|
381
|
+
if tcp_check.ready? == true
|
382
|
+
puts "The Socket Is Ready!"
|
383
|
+
else
|
384
|
+
puts "Looks like no one is home!"
|
385
|
+
end
|
386
|
+
|
387
|
+
#### Socket Wait
|
388
|
+
|
389
|
+
We can use the `wait` method to block on the socket's `ready?` state. The method will return only if the socket becomes ready or a timeout occurs. This operations runtime is bound by the `wait` configuration value.
|
390
|
+
|
391
|
+
tcp_check = ZTK::TCPSocketCheck.new
|
392
|
+
tcp_check.config do |config|
|
393
|
+
config.host = "www.google.com"
|
394
|
+
config.port = 80
|
395
|
+
config.data = "GET"
|
396
|
+
end
|
397
|
+
if tcp_check.wait == true
|
398
|
+
puts "The Socket Is Ready!"
|
399
|
+
else
|
400
|
+
puts "We timed out or got no answer!"
|
401
|
+
end
|
402
|
+
|
403
|
+
## ZTK::Command
|
404
|
+
|
405
|
+
A class to execute commands locally.
|
406
|
+
|
149
407
|
# RESOURCES
|
150
408
|
|
151
409
|
Source:
|
data/lib/ztk.rb
CHANGED
@@ -23,7 +23,10 @@ require "ztk/version"
|
|
23
23
|
module ZTK
|
24
24
|
class Error < StandardError; end
|
25
25
|
|
26
|
+
autoload :Base, "ztk/base"
|
26
27
|
autoload :Logger, "ztk/logger"
|
27
28
|
autoload :Parallel, "ztk/parallel"
|
28
29
|
autoload :SSH, "ztk/ssh"
|
30
|
+
autoload :TCPSocketCheck, "ztk/tcp_socket_check"
|
31
|
+
autoload :Template, "ztk/template"
|
29
32
|
end
|
data/lib/ztk/base.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
4
|
+
# Copyright: Copyright (c) Jove Labs
|
5
|
+
# License: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
################################################################################
|
20
|
+
|
21
|
+
require "ostruct"
|
22
|
+
|
23
|
+
################################################################################
|
24
|
+
|
25
|
+
module ZTK
|
26
|
+
|
27
|
+
################################################################################
|
28
|
+
|
29
|
+
class BaseError < Error; end
|
30
|
+
|
31
|
+
################################################################################
|
32
|
+
|
33
|
+
class Base
|
34
|
+
|
35
|
+
################################################################################
|
36
|
+
|
37
|
+
def initialize(config={})
|
38
|
+
defined?(Rails) and rails_logger = Rails.logger
|
39
|
+
@config = OpenStruct.new({
|
40
|
+
:stdout => $stdout,
|
41
|
+
:stderr => $stderr,
|
42
|
+
:stdin => $stdin,
|
43
|
+
:logger => (rails_logger || $logger)
|
44
|
+
}.merge(config))
|
45
|
+
|
46
|
+
@config.stdout.respond_to?(:sync=) and @config.stdout.sync = true
|
47
|
+
@config.stderr.respond_to?(:sync=) and @config.stderr.sync = true
|
48
|
+
@config.stdin.respond_to?(:sync=) and @config.stdin.sync = true
|
49
|
+
@config.logger.respond_to?(:sync=) and @config.logger.sync = true
|
50
|
+
|
51
|
+
@config.logger and @config.logger.debug{ "config(#{@config.inspect})" }
|
52
|
+
end
|
53
|
+
|
54
|
+
################################################################################
|
55
|
+
|
56
|
+
def config(&block)
|
57
|
+
if block_given?
|
58
|
+
block.call(@config)
|
59
|
+
else
|
60
|
+
@config
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
################################################################################
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
################################################################################
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
################################################################################
|
data/lib/ztk/logger.rb
CHANGED
@@ -20,7 +20,12 @@
|
|
20
20
|
|
21
21
|
require "logger"
|
22
22
|
|
23
|
+
################################################################################
|
24
|
+
|
23
25
|
module ZTK
|
26
|
+
|
27
|
+
################################################################################
|
28
|
+
|
24
29
|
class Logger < ::Logger
|
25
30
|
|
26
31
|
################################################################################
|
@@ -74,6 +79,9 @@ module ZTK
|
|
74
79
|
################################################################################
|
75
80
|
|
76
81
|
end
|
82
|
+
|
83
|
+
################################################################################
|
84
|
+
|
77
85
|
end
|
78
86
|
|
79
87
|
################################################################################
|
data/lib/ztk/parallel.rb
CHANGED
@@ -17,55 +17,43 @@
|
|
17
17
|
# limitat::IOns under the License.
|
18
18
|
#
|
19
19
|
################################################################################
|
20
|
+
|
20
21
|
require "base64"
|
21
|
-
|
22
|
+
|
23
|
+
################################################################################
|
22
24
|
|
23
25
|
module ZTK
|
24
|
-
class Parallel
|
25
26
|
|
26
27
|
################################################################################
|
27
28
|
|
28
|
-
|
29
|
+
class Parallel < ::ZTK::Base
|
30
|
+
|
31
|
+
################################################################################
|
32
|
+
|
33
|
+
attr_accessor :results
|
29
34
|
|
30
35
|
################################################################################
|
31
36
|
|
32
37
|
def initialize(config={})
|
33
|
-
|
34
|
-
:
|
35
|
-
:stderr => $stderr,
|
36
|
-
:stdin => $stdin,
|
37
|
-
:logger => $logger,
|
38
|
-
:max_forks => `grep -c processor /proc/cpuinfo`.chomp.to_i,
|
39
|
-
:one_shot => false,
|
38
|
+
super({
|
39
|
+
:max_forks => %x( grep -c processor /proc/cpuinfo ).chomp.to_i,
|
40
40
|
:before_fork => nil,
|
41
41
|
:after_fork => nil
|
42
42
|
}.merge(config))
|
43
|
-
@config.stdout.sync = true if @config.stdout.respond_to?(:sync=)
|
44
|
-
@config.stderr.sync = true if @config.stderr.respond_to?(:sync=)
|
45
|
-
@config.stdin.sync = true if @config.stdin.respond_to?(:sync=)
|
46
|
-
@config.logger.sync = true if @config.logger.respond_to?(:sync=)
|
47
43
|
|
48
44
|
@forks = ::Array.new
|
49
45
|
@results = ::Array.new
|
50
46
|
::GC.respond_to?(:copy_on_write_friendly=) and ::GC.copy_on_write_friendly = true
|
51
47
|
end
|
52
48
|
|
53
|
-
################################################################################
|
54
|
-
|
55
|
-
def config(&block)
|
56
|
-
if block_given?
|
57
|
-
yield(@config)
|
58
|
-
else
|
59
|
-
@config
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
49
|
################################################################################
|
64
50
|
|
65
51
|
def process(*args)
|
66
|
-
@config.logger.debug{ "
|
67
|
-
|
68
|
-
|
52
|
+
@config.logger and @config.logger.debug{ "forks(#{@forks.inspect})" }
|
53
|
+
|
54
|
+
while (@forks.count >= @config.max_forks) do
|
55
|
+
wait
|
56
|
+
end
|
69
57
|
|
70
58
|
child_reader, parent_writer = ::IO.pipe
|
71
59
|
parent_reader, child_writer = ::IO.pipe
|
@@ -78,7 +66,7 @@ module ZTK
|
|
78
66
|
parent_reader.close
|
79
67
|
|
80
68
|
if !(data = yield).nil?
|
81
|
-
@config.logger.debug{ "
|
69
|
+
@config.logger and @config.logger.debug{ "write(#{data.inspect})" }
|
82
70
|
child_writer.write(::Base64.encode64(::Marshal.dump(data)))
|
83
71
|
end
|
84
72
|
|
@@ -100,18 +88,19 @@ module ZTK
|
|
100
88
|
################################################################################
|
101
89
|
|
102
90
|
def wait
|
103
|
-
@config.logger.debug{ "
|
91
|
+
@config.logger and @config.logger.debug{ "forks(#{@forks.inspect})" }
|
104
92
|
pid, status = (::Process.wait2(-1, ::Process::WNOHANG) rescue nil)
|
105
93
|
if !pid.nil? && !status.nil? && !(fork = @forks.select{ |f| f[:pid] == pid }.first).nil?
|
106
94
|
data = (::Marshal.load(::Base64.decode64(fork[:reader].read.to_s)) rescue nil)
|
107
|
-
@config.logger.debug{ "
|
108
|
-
|
95
|
+
@config.logger and @config.logger.debug{ "read(#{data.inspect})" }
|
96
|
+
!data.nil? and @results.push(data)
|
109
97
|
fork[:reader].close
|
110
98
|
fork[:writer].close
|
111
99
|
|
112
100
|
@forks -= [fork]
|
113
101
|
return [pid, status, data]
|
114
102
|
end
|
103
|
+
sleep(1)
|
115
104
|
nil
|
116
105
|
end
|
117
106
|
|
@@ -128,12 +117,16 @@ module ZTK
|
|
128
117
|
################################################################################
|
129
118
|
|
130
119
|
def count
|
120
|
+
@config.logger and @config.logger.debug{ "count(#{@forks.count})" }
|
131
121
|
@forks.count
|
132
122
|
end
|
133
123
|
|
134
124
|
################################################################################
|
135
125
|
|
136
126
|
end
|
127
|
+
|
128
|
+
################################################################################
|
129
|
+
|
137
130
|
end
|
138
131
|
|
139
132
|
################################################################################
|
data/lib/ztk/ssh.rb
CHANGED
@@ -17,30 +17,30 @@
|
|
17
17
|
# limitations under the License.
|
18
18
|
#
|
19
19
|
################################################################################
|
20
|
+
|
20
21
|
require "ostruct"
|
22
|
+
require "net/ssh"
|
23
|
+
require "net/ssh/proxy/command"
|
24
|
+
require "net/sftp"
|
25
|
+
|
26
|
+
################################################################################
|
21
27
|
|
22
28
|
module ZTK
|
29
|
+
|
30
|
+
################################################################################
|
31
|
+
|
23
32
|
class SSHError < Error; end
|
24
|
-
class SSH
|
25
33
|
|
26
34
|
################################################################################
|
27
35
|
|
28
|
-
|
36
|
+
class SSH < ::ZTK::Base
|
29
37
|
|
30
38
|
################################################################################
|
31
39
|
|
32
40
|
def initialize(config={})
|
33
|
-
|
34
|
-
:
|
35
|
-
:stderr => $stderr,
|
36
|
-
:stdin => $stdin,
|
37
|
-
:logger => $logger,
|
38
|
-
:ssh => Hash.new(nil)
|
41
|
+
super({
|
42
|
+
:ssh => ::OpenStruct.new
|
39
43
|
}.merge(config))
|
40
|
-
@config.stdout.sync = true if @config.stdout.respond_to?(:sync=)
|
41
|
-
@config.stderr.sync = true if @config.stderr.respond_to?(:sync=)
|
42
|
-
@config.stdin.sync = true if @config.stdin.respond_to?(:sync=)
|
43
|
-
@config.logger.sync = true if @config.logger.respond_to?(:sync=)
|
44
44
|
end
|
45
45
|
|
46
46
|
################################################################################
|
@@ -54,18 +54,18 @@ module ZTK
|
|
54
54
|
command << [ "-o", "StrictHostKeyChecking=no" ]
|
55
55
|
command << [ "-o", "KeepAlive=yes" ]
|
56
56
|
command << [ "-o", "ServerAliveInterval=60" ]
|
57
|
-
command << [ "-i", @config.ssh
|
58
|
-
command << [ "-o", "ProxyCommand=\"#{proxy_command}\"" ] if @config.ssh
|
59
|
-
command << "#{@config.ssh
|
57
|
+
command << [ "-i", @config.ssh.identity_file ] if @config.ssh.identity_file
|
58
|
+
command << [ "-o", "ProxyCommand=\"#{proxy_command}\"" ] if @config.ssh.proxy
|
59
|
+
command << "#{@config.ssh.user}@#{@config.ssh.host}"
|
60
60
|
command = command.flatten.compact.join(" ")
|
61
61
|
@config.logger and @config.logger.info { "command(#{command})" }
|
62
|
-
Kernel.exec(command)
|
62
|
+
::Kernel.exec(command)
|
63
63
|
end
|
64
64
|
|
65
65
|
################################################################################
|
66
66
|
|
67
67
|
def exec(command, options={})
|
68
|
-
@ssh ||= Net::SSH.start(@config.ssh
|
68
|
+
@ssh ||= ::Net::SSH.start(@config.ssh.host, @config.ssh.user, ssh_options)
|
69
69
|
|
70
70
|
options = { :silence => false }.merge(options)
|
71
71
|
silence = options[:silence]
|
@@ -102,7 +102,7 @@ module ZTK
|
|
102
102
|
################################################################################
|
103
103
|
|
104
104
|
def upload(local, remote)
|
105
|
-
@sftp ||= Net::SFTP.start(@config.ssh
|
105
|
+
@sftp ||= ::Net::SFTP.start(@config.ssh.host, @config.ssh.user, ssh_options)
|
106
106
|
|
107
107
|
@config.logger and @config.logger.debug { "config(#{@config.ssh.inspect})" }
|
108
108
|
@config.logger and @config.logger.info { "parameters(#{local},#{remote})" }
|
@@ -120,12 +120,14 @@ module ZTK
|
|
120
120
|
@config.logger and @config.logger.info { "finish" }
|
121
121
|
end
|
122
122
|
end
|
123
|
+
|
124
|
+
true
|
123
125
|
end
|
124
126
|
|
125
127
|
################################################################################
|
126
128
|
|
127
129
|
def download(remote, local)
|
128
|
-
@sftp ||= Net::SFTP.start(@config.ssh
|
130
|
+
@sftp ||= ::Net::SFTP.start(@config.ssh.host, @config.ssh.user, ssh_options)
|
129
131
|
|
130
132
|
@config.logger and @config.logger.debug { "config(#{@config.ssh.inspect})" }
|
131
133
|
@config.logger and @config.logger.info { "parameters(#{remote},#{local})" }
|
@@ -143,6 +145,8 @@ module ZTK
|
|
143
145
|
@config.logger and @config.logger.info { "finish" }
|
144
146
|
end
|
145
147
|
end
|
148
|
+
|
149
|
+
true
|
146
150
|
end
|
147
151
|
|
148
152
|
|
@@ -153,7 +157,7 @@ module ZTK
|
|
153
157
|
def proxy_command
|
154
158
|
@config.logger and @config.logger.debug { "config(#{@config.ssh.inspect})" }
|
155
159
|
|
156
|
-
if !@config.ssh
|
160
|
+
if !@config.ssh.identity_file
|
157
161
|
message = "You must specify an identity file in order to SSH proxy."
|
158
162
|
@config.logger and @config.logger.fatal { message }
|
159
163
|
raise SSHError, message
|
@@ -165,8 +169,8 @@ module ZTK
|
|
165
169
|
command << [ "-o", "StrictHostKeyChecking=no" ]
|
166
170
|
command << [ "-o", "KeepAlive=yes" ]
|
167
171
|
command << [ "-o", "ServerAliveInterval=60" ]
|
168
|
-
command << [ "-i", @config.ssh
|
169
|
-
command << "#{@config.ssh
|
172
|
+
command << [ "-i", @config.ssh.proxy_identity_file ] if @config.ssh.proxy_identity_file
|
173
|
+
command << "#{@config.ssh.proxy_user}@#{@config.ssh.proxy_host}"
|
170
174
|
command << "nc %h %p"
|
171
175
|
command = command.flatten.compact.join(" ")
|
172
176
|
@config.logger and @config.logger.debug { "command(#{command})" }
|
@@ -178,11 +182,11 @@ module ZTK
|
|
178
182
|
def ssh_options
|
179
183
|
@config.logger and @config.logger.debug { "config(#{@config.ssh.inspect})" }
|
180
184
|
options = {}
|
181
|
-
options.merge!(:password => @config.ssh
|
182
|
-
options.merge!(:keys => @config.ssh
|
183
|
-
options.merge!(:timeout => @config.ssh
|
184
|
-
options.merge!(:user_known_hosts_file => '/dev/null') if !@config.ssh
|
185
|
-
options.merge!(:proxy => Net::SSH::Proxy::Command.new(proxy_command)) if @config.ssh
|
185
|
+
options.merge!(:password => @config.ssh.password) if @config.ssh.password
|
186
|
+
options.merge!(:keys => @config.ssh.identity_file) if @config.ssh.identity_file
|
187
|
+
options.merge!(:timeout => @config.ssh.timeout) if @config.ssh.timeout
|
188
|
+
options.merge!(:user_known_hosts_file => '/dev/null') if !@config.ssh.host_key_verify
|
189
|
+
options.merge!(:proxy => ::Net::SSH::Proxy::Command.new(proxy_command)) if @config.ssh.proxy
|
186
190
|
@config.logger and @config.logger.debug { "options(#{options.inspect})" }
|
187
191
|
options
|
188
192
|
end
|
@@ -190,6 +194,9 @@ module ZTK
|
|
190
194
|
################################################################################
|
191
195
|
|
192
196
|
end
|
197
|
+
|
198
|
+
################################################################################
|
199
|
+
|
193
200
|
end
|
194
201
|
|
195
202
|
################################################################################
|
@@ -0,0 +1,103 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
4
|
+
# Copyright: Copyright (c) Jove Labs
|
5
|
+
# License: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
################################################################################
|
20
|
+
|
21
|
+
require "socket"
|
22
|
+
|
23
|
+
################################################################################
|
24
|
+
|
25
|
+
module ZTK
|
26
|
+
|
27
|
+
################################################################################
|
28
|
+
|
29
|
+
class TCPSocketCheckError < Error; end
|
30
|
+
|
31
|
+
################################################################################
|
32
|
+
|
33
|
+
class TCPSocketCheck < Base
|
34
|
+
|
35
|
+
################################################################################
|
36
|
+
|
37
|
+
def initialize(config={})
|
38
|
+
super({
|
39
|
+
:host => nil,
|
40
|
+
:port => nil,
|
41
|
+
:data => nil,
|
42
|
+
:timeout => 5,
|
43
|
+
:wait => 60
|
44
|
+
}.merge(config))
|
45
|
+
end
|
46
|
+
|
47
|
+
################################################################################
|
48
|
+
|
49
|
+
def ready?
|
50
|
+
if @config.host.nil?
|
51
|
+
message = "You must supply a host!"
|
52
|
+
@config.logger and @config.logger.fatal { message }
|
53
|
+
raise TCPSocketCheckError, message
|
54
|
+
end
|
55
|
+
|
56
|
+
if @config.port.nil?
|
57
|
+
message = "You must supply a port!"
|
58
|
+
@config.logger and @config.logger.fatal { message }
|
59
|
+
raise TCPSocketCheckError, message
|
60
|
+
end
|
61
|
+
|
62
|
+
socket = ::TCPSocket.new(@config.host, @config.port)
|
63
|
+
|
64
|
+
if @config.data.nil?
|
65
|
+
@config.logger and @config.logger.debug { "read(#{@config.host}:#{@config.port})" }
|
66
|
+
((::IO.select([socket], nil, nil, @config.timeout) && socket.gets) ? true : false)
|
67
|
+
else
|
68
|
+
@config.logger and @config.logger.debug { "write(#{@config.host}:#{@config.port}, '#{@config.data}')" }
|
69
|
+
((::IO.select(nil, [socket], nil, @config.timeout) && socket.write(@config.data)) ? true : false)
|
70
|
+
end
|
71
|
+
|
72
|
+
rescue Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::EHOSTUNREACH => e
|
73
|
+
@config.logger and @config.logger.debug { "#{@config.host}:#{@config.port} - #{e.message}" }
|
74
|
+
false
|
75
|
+
ensure
|
76
|
+
(socket && socket.close)
|
77
|
+
end
|
78
|
+
|
79
|
+
################################################################################
|
80
|
+
|
81
|
+
def wait
|
82
|
+
@config.logger and @config.logger.debug{ "waiting for socket to become available; timeout after #{@config.wait} seconds" }
|
83
|
+
Timeout.timeout(@config.wait) do
|
84
|
+
until ready?
|
85
|
+
@config.logger and @config.logger.debug{ "sleeping 1 second" }
|
86
|
+
sleep(1)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
true
|
90
|
+
rescue Timeout::Error => e
|
91
|
+
@config.logger and @config.logger.warn{ "socket(#{@config.host}:#{@config.port}) timeout!" }
|
92
|
+
false
|
93
|
+
end
|
94
|
+
|
95
|
+
################################################################################
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
################################################################################
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
################################################################################
|
data/lib/ztk/template.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
4
|
+
# Copyright: Copyright (c) Jove Labs
|
5
|
+
# License: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
################################################################################
|
20
|
+
|
21
|
+
require "erubis"
|
22
|
+
|
23
|
+
################################################################################
|
24
|
+
|
25
|
+
module ZTK
|
26
|
+
|
27
|
+
################################################################################
|
28
|
+
|
29
|
+
class TemplateError < Error; end
|
30
|
+
|
31
|
+
################################################################################
|
32
|
+
|
33
|
+
class Template
|
34
|
+
|
35
|
+
################################################################################
|
36
|
+
|
37
|
+
class << self
|
38
|
+
|
39
|
+
################################################################################
|
40
|
+
|
41
|
+
def render(template, context=nil)
|
42
|
+
render_template(load_template(template), context)
|
43
|
+
end
|
44
|
+
|
45
|
+
################################################################################
|
46
|
+
private
|
47
|
+
################################################################################
|
48
|
+
|
49
|
+
def load_template(template)
|
50
|
+
::IO.read(template).chomp
|
51
|
+
end
|
52
|
+
|
53
|
+
################################################################################
|
54
|
+
|
55
|
+
def render_template(template, context={})
|
56
|
+
::Erubis::Eruby.new(template).evaluate(context)
|
57
|
+
end
|
58
|
+
|
59
|
+
################################################################################
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
################################################################################
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
################################################################################
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
################################################################################
|
data/lib/ztk/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
<%= @test_variable %>
|
data/spec/ztk/logger_spec.rb
CHANGED
@@ -37,8 +37,12 @@ describe ZTK::Logger do
|
|
37
37
|
|
38
38
|
subject { ZTK::Logger.new(@logfile) }
|
39
39
|
|
40
|
-
|
41
|
-
|
40
|
+
describe "class" do
|
41
|
+
|
42
|
+
it "should be an instance of ZTK::Logger" do
|
43
|
+
subject.should be_an_instance_of ZTK::Logger
|
44
|
+
end
|
45
|
+
|
42
46
|
end
|
43
47
|
|
44
48
|
describe "general logging functionality" do
|
data/spec/ztk/parallel_spec.rb
CHANGED
@@ -22,13 +22,38 @@ require "spec_helper"
|
|
22
22
|
|
23
23
|
describe ZTK::Parallel do
|
24
24
|
|
25
|
-
before(:all) do
|
26
|
-
end
|
27
|
-
|
28
25
|
subject { ZTK::Parallel.new }
|
29
26
|
|
30
|
-
|
31
|
-
|
27
|
+
describe "class" do
|
28
|
+
|
29
|
+
it "should be an instance of ZTK::Parallel" do
|
30
|
+
subject.should be_an_instance_of ZTK::Parallel
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "default config" do
|
34
|
+
|
35
|
+
it "should use $stdout as the default STDOUT" do
|
36
|
+
subject.config.stdout.should be_a_kind_of $stdout.class
|
37
|
+
subject.config.stdout.should == $stdout
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should use $stderr as the default STDERR" do
|
41
|
+
subject.config.stderr.should be_a_kind_of $stderr.class
|
42
|
+
subject.config.stderr.should == $stderr
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should use $stdin as the default STDIN" do
|
46
|
+
subject.config.stdin.should be_a_kind_of $stdin.class
|
47
|
+
subject.config.stdin.should == $stdin
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should use $logger as the default logger" do
|
51
|
+
subject.config.logger.should be_a_kind_of ZTK::Logger
|
52
|
+
subject.config.logger.should == $logger
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
32
57
|
end
|
33
58
|
|
34
59
|
it "should spawn multiple processes to handle each iteration" do
|
@@ -41,12 +66,7 @@ describe ZTK::Parallel do
|
|
41
66
|
puts subject.results.inspect
|
42
67
|
subject.results.all?{ |r| r.should be_kind_of Integer }
|
43
68
|
subject.results.all?{ |r| r.should > 0 }
|
44
|
-
|
45
|
-
# for some odd reason this is always -1 on travis-ci
|
46
|
-
subject.results.uniq.count.should == 2
|
47
|
-
else
|
48
|
-
subject.results.uniq.count.should == 3
|
49
|
-
end
|
69
|
+
subject.results.uniq.count.should == 3
|
50
70
|
subject.results.include?(Process.pid).should be false
|
51
71
|
end
|
52
72
|
|
@@ -0,0 +1,84 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
4
|
+
# Copyright: Copyright (c) Jove Labs
|
5
|
+
# License: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
################################################################################
|
20
|
+
|
21
|
+
require "spec_helper"
|
22
|
+
|
23
|
+
describe ZTK::SSH do
|
24
|
+
|
25
|
+
subject { ZTK::SSH.new }
|
26
|
+
|
27
|
+
describe "class" do
|
28
|
+
|
29
|
+
it "should be an instance of ZTK::SSH" do
|
30
|
+
subject.should be_an_instance_of ZTK::SSH
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "default config" do
|
34
|
+
|
35
|
+
it "should use $stdout as the default STDOUT" do
|
36
|
+
subject.config.stdout.should be_a_kind_of $stdout.class
|
37
|
+
subject.config.stdout.should == $stdout
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should use $stderr as the default STDERR" do
|
41
|
+
subject.config.stderr.should be_a_kind_of $stderr.class
|
42
|
+
subject.config.stderr.should == $stderr
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should use $stdin as the default STDIN" do
|
46
|
+
subject.config.stdin.should be_a_kind_of $stdin.class
|
47
|
+
subject.config.stdin.should == $stdin
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should use $logger as the default logger" do
|
51
|
+
subject.config.logger.should be_a_kind_of ZTK::Logger
|
52
|
+
subject.config.logger.should == $logger
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
# this stuff doesn't work as is under travis-ci
|
60
|
+
if !ENV['CI'] && !ENV['TRAVIS']
|
61
|
+
|
62
|
+
it "should be able to connect to 127.0.0.1 as the current user and execute a command (your key must be in ssh-agent)" do
|
63
|
+
subject.config do |config|
|
64
|
+
config.ssh.user = ENV["USER"]
|
65
|
+
config.ssh.host = "127.0.0.1"
|
66
|
+
end
|
67
|
+
hostname = %x( hostname -f ).chomp
|
68
|
+
subject.exec("hostname -f").chomp.should == hostname
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should be able to proxy through 127.0.0.1, connecting to 127.0.0.1 as the current user and execute a command (your key must be in ssh-agent)" do
|
72
|
+
subject.config do |config|
|
73
|
+
config.ssh.user = ENV["USER"]
|
74
|
+
config.ssh.host = "127.0.0.1"
|
75
|
+
config.ssh.proxy_user = ENV["USER"]
|
76
|
+
config.ssh.proxy_host = "127.0.0.1"
|
77
|
+
end
|
78
|
+
hostname = %x( hostname -f ).chomp
|
79
|
+
subject.exec("hostname -f").chomp.should == hostname
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
4
|
+
# Copyright: Copyright (c) Jove Labs
|
5
|
+
# License: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
################################################################################
|
20
|
+
|
21
|
+
require "spec_helper"
|
22
|
+
|
23
|
+
describe ZTK::TCPSocketCheck do
|
24
|
+
|
25
|
+
subject { ZTK::TCPSocketCheck }
|
26
|
+
|
27
|
+
describe "class" do
|
28
|
+
|
29
|
+
it "should be ZTK::TCPSocketCheck" do
|
30
|
+
subject.should be ZTK::TCPSocketCheck
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "config" do
|
34
|
+
|
35
|
+
it "should throw an exception if the host is not specified" do
|
36
|
+
lambda{ subject.new(:port => 22).ready? }.should raise_error ZTK::TCPSocketCheckError, "You must supply a host!"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should throw an exception if the port is not specified" do
|
40
|
+
lambda{ subject.new(:host => "127.0.0.1").ready? }.should raise_error ZTK::TCPSocketCheckError, "You must supply a port!"
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "behaviour" do
|
48
|
+
|
49
|
+
describe "ready?" do
|
50
|
+
|
51
|
+
describe "read check" do
|
52
|
+
|
53
|
+
it "should return true on a remote read check to github.com:22" do
|
54
|
+
tcp_check = subject.new(:host => "github.com", :port => 22)
|
55
|
+
tcp_check.ready?.should == true
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should return false on a remote read check to 127.0.0.1:1" do
|
59
|
+
tcp_check = subject.new(:host => "127.0.0.1", :port => 1, :timeout => 3)
|
60
|
+
tcp_check.ready?.should == false
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "write check" do
|
66
|
+
|
67
|
+
it "should return true on a remote write check to www.google.com:80" do
|
68
|
+
tcp_check = subject.new(:host => "www.google.com", :port => 80, :data => "GET")
|
69
|
+
tcp_check.ready?.should == true
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should return false on a remote write check to 127.0.0.1:1" do
|
73
|
+
tcp_check = subject.new(:host => "127.0.0.1", :port => 1, :data => "GET", :timeout => 3)
|
74
|
+
tcp_check.ready?.should == false
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "wait" do
|
82
|
+
|
83
|
+
describe "read check" do
|
84
|
+
|
85
|
+
it "should timeout and should return false on a read check to 127.0.0.1:1" do
|
86
|
+
tcp_check = subject.new(:host => "127.0.0.1", :port => 1, :wait => 3)
|
87
|
+
tcp_check.wait.should == false
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should not timeout and should return true on a read check to github.com:22" do
|
91
|
+
tcp_check = subject.new(:host => "github.com", :port => 22, :wait => 3)
|
92
|
+
tcp_check.wait.should == true
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "write check" do
|
98
|
+
|
99
|
+
it "should timeout and should return false on a write check to 127.0.0.1:1" do
|
100
|
+
tcp_check = subject.new(:host => "127.0.0.1", :port => 1, :data => "GET", :wait => 3)
|
101
|
+
tcp_check.wait.should == false
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should not timeout and should return true on a write check to www.google.com:80" do
|
105
|
+
tcp_check = subject.new(:host => "www.google.com", :port => 80, :data => "GET", :wait => 3)
|
106
|
+
tcp_check.wait.should == true
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
4
|
+
# Copyright: Copyright (c) Jove Labs
|
5
|
+
# License: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
################################################################################
|
20
|
+
|
21
|
+
require "spec_helper"
|
22
|
+
|
23
|
+
describe ZTK::Template do
|
24
|
+
|
25
|
+
subject { ZTK::Template }
|
26
|
+
|
27
|
+
describe "class" do
|
28
|
+
|
29
|
+
it "should be ZTK::Template" do
|
30
|
+
subject.should be ZTK::Template
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "behaviour" do
|
36
|
+
|
37
|
+
it "should render the template with the supplied context" do
|
38
|
+
template_file = File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "test-template.txt.erb"))
|
39
|
+
context = { :test_variable => "Hello World" }
|
40
|
+
output = subject.render(template_file, context)
|
41
|
+
output.should == "Hello World"
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
data/ztk.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ztk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,6 +11,22 @@ bindir: bin
|
|
11
11
|
cert_chain: []
|
12
12
|
date: 2012-09-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: erubis
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
14
30
|
- !ruby/object:Gem::Dependency
|
15
31
|
name: net-ssh
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -126,13 +142,20 @@ files:
|
|
126
142
|
- WIKI.md
|
127
143
|
- bin/ztk
|
128
144
|
- lib/ztk.rb
|
145
|
+
- lib/ztk/base.rb
|
129
146
|
- lib/ztk/logger.rb
|
130
147
|
- lib/ztk/parallel.rb
|
131
148
|
- lib/ztk/ssh.rb
|
149
|
+
- lib/ztk/tcp_socket_check.rb
|
150
|
+
- lib/ztk/template.rb
|
132
151
|
- lib/ztk/version.rb
|
133
152
|
- spec/spec_helper.rb
|
153
|
+
- spec/support/test-template.txt.erb
|
134
154
|
- spec/ztk/logger_spec.rb
|
135
155
|
- spec/ztk/parallel_spec.rb
|
156
|
+
- spec/ztk/ssh_spec.rb
|
157
|
+
- spec/ztk/tcp_socket_check_spec.rb
|
158
|
+
- spec/ztk/template_spec.rb
|
136
159
|
- ztk.gemspec
|
137
160
|
homepage: https://github.com/jovelabs/ztk
|
138
161
|
licenses: []
|
@@ -148,7 +171,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
148
171
|
version: '0'
|
149
172
|
segments:
|
150
173
|
- 0
|
151
|
-
hash: -
|
174
|
+
hash: -3563770214735056009
|
152
175
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
176
|
none: false
|
154
177
|
requirements:
|
@@ -157,7 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
180
|
version: '0'
|
158
181
|
segments:
|
159
182
|
- 0
|
160
|
-
hash: -
|
183
|
+
hash: -3563770214735056009
|
161
184
|
requirements: []
|
162
185
|
rubyforge_project:
|
163
186
|
rubygems_version: 1.8.24
|
@@ -166,5 +189,9 @@ specification_version: 3
|
|
166
189
|
summary: Contains various classes and utilities I find I regularly need.
|
167
190
|
test_files:
|
168
191
|
- spec/spec_helper.rb
|
192
|
+
- spec/support/test-template.txt.erb
|
169
193
|
- spec/ztk/logger_spec.rb
|
170
194
|
- spec/ztk/parallel_spec.rb
|
195
|
+
- spec/ztk/ssh_spec.rb
|
196
|
+
- spec/ztk/tcp_socket_check_spec.rb
|
197
|
+
- spec/ztk/template_spec.rb
|