ztk 0.3.1 → 1.0.0.rc.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/.travis.yml +7 -5
- data/.yardopts +2 -0
- data/README.md +3 -3
- data/Rakefile +39 -0
- data/lib/ztk/background.rb +14 -6
- data/lib/ztk/base.rb +20 -5
- data/lib/ztk/benchmark.rb +33 -1
- data/lib/ztk/command.rb +24 -14
- data/lib/ztk/config.rb +0 -1
- data/lib/ztk/dsl/base.rb +76 -0
- data/lib/ztk/dsl/core/actions/find.rb +49 -0
- data/lib/ztk/dsl/core/actions/timestamps.rb +47 -0
- data/lib/ztk/dsl/core/actions.rb +34 -0
- data/lib/ztk/dsl/core/attributes.rb +53 -0
- data/lib/ztk/dsl/core/dataset.rb +66 -0
- data/lib/ztk/dsl/core/io.rb +41 -0
- data/lib/ztk/dsl/core/relations/belongs_to.rb +135 -0
- data/lib/ztk/dsl/core/relations/has_many.rb +105 -0
- data/lib/ztk/dsl/core/relations.rb +45 -0
- data/lib/ztk/dsl/core.rb +77 -0
- data/lib/ztk/dsl.rb +34 -0
- data/lib/ztk/logger.rb +14 -1
- data/lib/ztk/parallel.rb +2 -2
- data/lib/ztk/report.rb +43 -1
- data/lib/ztk/rescue_retry.rb +39 -1
- data/lib/ztk/spinner.rb +27 -8
- data/lib/ztk/ssh.rb +29 -28
- data/lib/ztk/tcp_socket_check.rb +1 -2
- data/lib/ztk/template.rb +0 -1
- data/lib/ztk/ui.rb +47 -0
- data/lib/ztk/version.rb +4 -1
- data/lib/ztk.rb +20 -14
- data/spec/ztk/background_spec.rb +60 -0
- data/spec/ztk/dsl_spec.rb +635 -0
- data/ztk.gemspec +4 -2
- metadata +38 -9
data/lib/ztk/spinner.rb
CHANGED
@@ -17,7 +17,6 @@
|
|
17
17
|
# limitations under the License.
|
18
18
|
#
|
19
19
|
################################################################################
|
20
|
-
|
21
20
|
require "ostruct"
|
22
21
|
|
23
22
|
module ZTK
|
@@ -25,33 +24,53 @@ module ZTK
|
|
25
24
|
# ZTK::Spinner Error Class
|
26
25
|
#
|
27
26
|
# @author Zachary Patten <zachary@jovelabs.net>
|
28
|
-
# @author Stephen Nelson-Smith <stephen@atalanta-systems.com>
|
29
27
|
class SpinnerError < Error; end
|
30
28
|
|
31
|
-
# Spinner Class
|
29
|
+
# ZTK Spinner Class
|
30
|
+
#
|
31
|
+
# This class can be used to display an "activity indicator" to a user while
|
32
|
+
# a task is executed in the supplied block. This indicator takes the form
|
33
|
+
# of a spinner.
|
32
34
|
#
|
33
35
|
# @author Zachary Patten <zachary@jovelabs.net>
|
34
|
-
# @author Stephen Nelson-Smith <stephen@atalanta-systems.com>
|
35
36
|
class Spinner
|
36
37
|
|
37
38
|
class << self
|
38
39
|
|
40
|
+
# Spinner Character Set
|
41
|
+
CHARSET = %w( | / - \\ )
|
42
|
+
|
43
|
+
# UI Spinner
|
44
|
+
#
|
45
|
+
# Displays a "spinner" while executing the supplied block. It is
|
46
|
+
# advisable that no output is sent to the console during this time.
|
47
|
+
#
|
48
|
+
# @param [Hash] options Configuration options hash.
|
49
|
+
# @option options [Float,Integer] :step (0.1) How long to sleep for in
|
50
|
+
# between cycles, while cycling through the *CHARSET*.
|
51
|
+
#
|
52
|
+
# @yield Block should execute the tasks for which they wish the user to
|
53
|
+
# have a false sense of security in the fact that something is actually
|
54
|
+
# taking place "behind the scenes".
|
55
|
+
# @return [Object] The return value of the block.
|
56
|
+
#
|
57
|
+
# @author Zachary Patten <zachary@jovelabs.net>
|
58
|
+
# @author Stephen Nelson-Smith <stephen@atalanta-systems.com>
|
39
59
|
def spin(options={}, &block)
|
40
60
|
options = Base.build_config({
|
41
|
-
:
|
61
|
+
:step => 0.1
|
42
62
|
}.merge(options))
|
43
63
|
options.logger.debug { "options(#{options.send(:table).inspect})" }
|
44
64
|
|
45
65
|
!block_given? and Base.log_and_raise(options.logger, SpinnerError, "You must supply a block!")
|
46
66
|
|
47
|
-
charset = %w( | / - \\ )
|
48
67
|
count = 0
|
49
68
|
spinner = Thread.new do
|
50
69
|
while count do
|
51
|
-
options.stdout.print(
|
70
|
+
options.stdout.print(CHARSET[(count += 1) % CHARSET.length])
|
52
71
|
options.stdout.print("\b")
|
53
72
|
options.stdout.respond_to?(:flush) and options.stdout.flush
|
54
|
-
sleep(options.
|
73
|
+
sleep(options.step)
|
55
74
|
end
|
56
75
|
end
|
57
76
|
yield.tap do
|
data/lib/ztk/ssh.rb
CHANGED
@@ -17,7 +17,6 @@
|
|
17
17
|
# limitations under the License.
|
18
18
|
#
|
19
19
|
################################################################################
|
20
|
-
|
21
20
|
require "ostruct"
|
22
21
|
require "net/ssh"
|
23
22
|
require "net/ssh/proxy/command"
|
@@ -85,6 +84,7 @@ module ZTK
|
|
85
84
|
# @author Zachary Patten <zachary@jovelabs.net>
|
86
85
|
class SSH < ZTK::Base
|
87
86
|
|
87
|
+
# Exit Signal Mappings
|
88
88
|
EXIT_SIGNALS = {
|
89
89
|
1 => "SIGHUP",
|
90
90
|
2 => "SIGINT",
|
@@ -115,7 +115,7 @@ module ZTK
|
|
115
115
|
27 => "SIGPROF"
|
116
116
|
}
|
117
117
|
|
118
|
-
# @param [Hash]
|
118
|
+
# @param [Hash] configuration Configuration options hash.
|
119
119
|
# @option config [String] :host_name Server hostname to connect to.
|
120
120
|
# @option config [String] :user Username to use for authentication.
|
121
121
|
# @option config [String, Array<String>] :keys A single or series of
|
@@ -142,23 +142,6 @@ module ZTK
|
|
142
142
|
config.logger.debug { "config=#{config.send(:table).inspect}" }
|
143
143
|
end
|
144
144
|
|
145
|
-
def inspect
|
146
|
-
tags = Array.new
|
147
|
-
|
148
|
-
if config.proxy_host_name
|
149
|
-
proxy_user_host = "#{config.proxy_user}@#{config.proxy_host_name}"
|
150
|
-
proxy_port = (config.proxy_port ? ":#{config.proxy_port}" : nil)
|
151
|
-
tags << [proxy_user_host, proxy_port].compact.join
|
152
|
-
tags << " >>> "
|
153
|
-
end
|
154
|
-
|
155
|
-
user_host = "#{config.user}@#{config.host_name}"
|
156
|
-
port = (config.port ? ":#{config.port}" : nil)
|
157
|
-
tags << [user_host, port].compact.join
|
158
|
-
|
159
|
-
tags.join.strip
|
160
|
-
end
|
161
|
-
|
162
145
|
# Starts an SSH session. Can also be used to get the Net::SSH object.
|
163
146
|
#
|
164
147
|
# Primarily used internally.
|
@@ -166,7 +149,7 @@ module ZTK
|
|
166
149
|
@ssh ||= Net::SSH.start(config.host_name, config.user, ssh_options)
|
167
150
|
end
|
168
151
|
|
169
|
-
# Starts an SFTP session. Can also be used to get the Net::
|
152
|
+
# Starts an SFTP session. Can also be used to get the Net::SFTP object.
|
170
153
|
#
|
171
154
|
# Primarily used internally.
|
172
155
|
def sftp
|
@@ -219,14 +202,6 @@ module ZTK
|
|
219
202
|
# end
|
220
203
|
# puts ssh.exec("hostname -f").inspect
|
221
204
|
def exec(command, options={})
|
222
|
-
|
223
|
-
def log_header(tag)
|
224
|
-
count = 8
|
225
|
-
sep = ("=" * count)
|
226
|
-
header = [sep, "[ #{tag} ]", sep, "[ #{self.inspect} ]", sep, "[ #{tag} ]", sep].join
|
227
|
-
"#{header}\n"
|
228
|
-
end
|
229
|
-
|
230
205
|
options = OpenStruct.new({ :exit_code => 0, :silence => false }.merge(options))
|
231
206
|
|
232
207
|
config.logger.debug { "config=#{config.send(:table).inspect}" }
|
@@ -470,6 +445,32 @@ module ZTK
|
|
470
445
|
options
|
471
446
|
end
|
472
447
|
|
448
|
+
# Builds a human readable tag about our connection. Used for internal
|
449
|
+
# logging purposes.
|
450
|
+
def tag
|
451
|
+
tags = Array.new
|
452
|
+
|
453
|
+
if config.proxy_host_name
|
454
|
+
proxy_user_host = "#{config.proxy_user}@#{config.proxy_host_name}"
|
455
|
+
proxy_port = (config.proxy_port ? ":#{config.proxy_port}" : nil)
|
456
|
+
tags << [proxy_user_host, proxy_port].compact.join
|
457
|
+
tags << " >>> "
|
458
|
+
end
|
459
|
+
|
460
|
+
user_host = "#{config.user}@#{config.host_name}"
|
461
|
+
port = (config.port ? ":#{config.port}" : nil)
|
462
|
+
tags << [user_host, port].compact.join
|
463
|
+
|
464
|
+
tags.join.strip
|
465
|
+
end
|
466
|
+
|
467
|
+
def log_header(what)
|
468
|
+
count = 8
|
469
|
+
sep = ("=" * count)
|
470
|
+
header = [sep, "[ #{what} ]", sep, "[ #{tag} ]", sep, "[ #{what} ]", sep].join
|
471
|
+
"#{header}\n"
|
472
|
+
end
|
473
|
+
|
473
474
|
end
|
474
475
|
|
475
476
|
end
|
data/lib/ztk/tcp_socket_check.rb
CHANGED
@@ -17,7 +17,6 @@
|
|
17
17
|
# limitations under the License.
|
18
18
|
#
|
19
19
|
################################################################################
|
20
|
-
|
21
20
|
require 'socket'
|
22
21
|
require 'timeout'
|
23
22
|
|
@@ -83,7 +82,7 @@ module ZTK
|
|
83
82
|
# @author Zachary Patten <zachary@jovelabs.net>
|
84
83
|
class TCPSocketCheck < ZTK::Base
|
85
84
|
|
86
|
-
# @param [Hash]
|
85
|
+
# @param [Hash] configuration Configuration options hash.
|
87
86
|
# @option config [String] :host Host to connect to.
|
88
87
|
# @option config [Integer, String] :port Port to connect to.
|
89
88
|
# @option config [String] :data Data to send to host to provoke a response.
|
data/lib/ztk/template.rb
CHANGED
data/lib/ztk/ui.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Zachary Patten <zachary@jovelabs.net>
|
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 "base64"
|
22
|
+
|
23
|
+
module ZTK
|
24
|
+
|
25
|
+
# ZTK::Ui Error Class
|
26
|
+
#
|
27
|
+
# @author Zachary Patten <zachary@jovelabs.net>
|
28
|
+
class UIError < Error; end
|
29
|
+
|
30
|
+
# @author Zachary Patten <zachary@jovelabs.net>
|
31
|
+
class UI < ZTK::Base
|
32
|
+
|
33
|
+
attr_accessor :stdout, :stderr, :stdin, :logger
|
34
|
+
|
35
|
+
def initialize(configuration={})
|
36
|
+
super({
|
37
|
+
:stdout => $stdout,
|
38
|
+
:stderr => $stderr,
|
39
|
+
:stdin => $stdin,
|
40
|
+
:logger => $logger
|
41
|
+
}.merge(configuration))
|
42
|
+
config.logger.debug { "config=#{config.send(:table).inspect}" }
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
data/lib/ztk/version.rb
CHANGED
data/lib/ztk.rb
CHANGED
@@ -18,10 +18,14 @@
|
|
18
18
|
#
|
19
19
|
################################################################################
|
20
20
|
|
21
|
-
require
|
21
|
+
require "ztk/version"
|
22
22
|
|
23
23
|
# Main ZTK module
|
24
24
|
#
|
25
|
+
# ZTK is a general purpose utility library. It definately has devops activities
|
26
|
+
# in mind. It provides several classes that ease SSH and SFTP, templating,
|
27
|
+
# and a myraid of other activities.
|
28
|
+
#
|
25
29
|
# @author Zachary Patten <zachary@jovelabs.net>
|
26
30
|
module ZTK
|
27
31
|
|
@@ -30,19 +34,21 @@ module ZTK
|
|
30
34
|
# @author Zachary Patten <zachary@jovelabs.net>
|
31
35
|
class Error < StandardError; end
|
32
36
|
|
33
|
-
autoload :Base,
|
37
|
+
autoload :Base, "ztk/base"
|
38
|
+
autoload :DSL, "ztk/dsl"
|
34
39
|
|
35
|
-
autoload :Background,
|
36
|
-
autoload :Benchmark,
|
37
|
-
autoload :Command,
|
38
|
-
autoload :Config,
|
39
|
-
autoload :Logger,
|
40
|
-
autoload :Parallel,
|
41
|
-
autoload :Report,
|
42
|
-
autoload :RescueRetry,
|
43
|
-
autoload :Spinner,
|
44
|
-
autoload :SSH,
|
45
|
-
autoload :TCPSocketCheck,
|
46
|
-
autoload :Template,
|
40
|
+
autoload :Background, "ztk/background"
|
41
|
+
autoload :Benchmark, "ztk/benchmark"
|
42
|
+
autoload :Command, "ztk/command"
|
43
|
+
autoload :Config, "ztk/config"
|
44
|
+
autoload :Logger, "ztk/logger"
|
45
|
+
autoload :Parallel, "ztk/parallel"
|
46
|
+
autoload :Report, "ztk/report"
|
47
|
+
autoload :RescueRetry, "ztk/rescue_retry"
|
48
|
+
autoload :Spinner, "ztk/spinner"
|
49
|
+
autoload :SSH, "ztk/ssh"
|
50
|
+
autoload :TCPSocketCheck, "ztk/tcp_socket_check"
|
51
|
+
autoload :Template, "ztk/template"
|
52
|
+
autoload :UI, "ztk/ui"
|
47
53
|
|
48
54
|
end
|
data/spec/ztk/background_spec.rb
CHANGED
@@ -74,7 +74,67 @@ describe ZTK::Background do
|
|
74
74
|
subject.process do
|
75
75
|
Process.pid
|
76
76
|
end
|
77
|
+
|
78
|
+
subject.wait
|
79
|
+
subject.result.should be_kind_of Integer
|
80
|
+
subject.result.should > 0
|
81
|
+
subject.result.should_not == Process.pid
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "alive?" do
|
87
|
+
|
88
|
+
it "should respond true when the process is still running" do
|
89
|
+
subject.process do
|
90
|
+
sleep(WAIT_SMALL)
|
91
|
+
end
|
92
|
+
subject.alive?.should be true
|
93
|
+
|
94
|
+
subject.wait
|
95
|
+
subject.result.should be_kind_of Integer
|
96
|
+
subject.result.should > 0
|
97
|
+
subject.result.should == WAIT_SMALL
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should respond false when the process is no longer running" do
|
101
|
+
subject.process do
|
102
|
+
Process.pid
|
103
|
+
end
|
104
|
+
subject.wait
|
105
|
+
sleep(WAIT_SMALL)
|
106
|
+
|
107
|
+
subject.alive?.should be false
|
108
|
+
|
109
|
+
subject.result.should be_kind_of Integer
|
110
|
+
subject.result.should > 0
|
111
|
+
subject.result.should_not == Process.pid
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "dead?" do
|
117
|
+
|
118
|
+
it "should respond false when the process is still running" do
|
119
|
+
subject.process do
|
120
|
+
sleep(WAIT_SMALL)
|
121
|
+
end
|
122
|
+
subject.dead?.should be false
|
123
|
+
|
77
124
|
subject.wait
|
125
|
+
subject.result.should be_kind_of Integer
|
126
|
+
subject.result.should > 0
|
127
|
+
subject.result.should == WAIT_SMALL
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should respond true when the process is no longer running" do
|
131
|
+
subject.process do
|
132
|
+
Process.pid
|
133
|
+
end
|
134
|
+
subject.wait
|
135
|
+
sleep(WAIT_SMALL)
|
136
|
+
|
137
|
+
subject.dead?.should be true
|
78
138
|
|
79
139
|
subject.result.should be_kind_of Integer
|
80
140
|
subject.result.should > 0
|