ztk 0.3.1 → 1.0.0.rc.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,41 @@
|
|
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
|
+
module ZTK::DSL::Core
|
22
|
+
module IO
|
23
|
+
|
24
|
+
def self.included(base)
|
25
|
+
base.class_eval do
|
26
|
+
base.send(:extend, ZTK::DSL::Core::IO::ClassMethods)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module ClassMethods
|
31
|
+
|
32
|
+
def load(rb_file)
|
33
|
+
new do
|
34
|
+
instance_eval(::IO.read(rb_file))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,135 @@
|
|
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
|
+
module ZTK::DSL::Core::Relations
|
22
|
+
module BelongsTo
|
23
|
+
|
24
|
+
def self.included(base)
|
25
|
+
base.class_eval do
|
26
|
+
base.add_relation(:belongs_to)
|
27
|
+
base.send(:extend, ZTK::DSL::Core::Relations::BelongsTo::ClassMethods)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def belongs_to_references
|
32
|
+
@belongs_to_references ||= {}
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_belongs_to_reference(key)
|
36
|
+
logger.debug { "key(#{key})" }
|
37
|
+
|
38
|
+
if belongs_to_references.key?(key)
|
39
|
+
logger.debug { "found key -> (#{key})" }
|
40
|
+
|
41
|
+
belongs_to_references[key]
|
42
|
+
else
|
43
|
+
logger.debug { "looking up key -> (#{key})" }
|
44
|
+
|
45
|
+
key_id = send("#{key}_id")
|
46
|
+
item = key.to_s.classify.constantize.find(key_id).first
|
47
|
+
belongs_to_references[key] = item
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def set_belongs_to_reference(key, value)
|
52
|
+
logger.debug { "key(#{key}), value(#{value})" }
|
53
|
+
|
54
|
+
belongs_to_references[key] = value
|
55
|
+
attributes.merge!("#{key}_id".to_sym => value.id)
|
56
|
+
|
57
|
+
klass = self.class.to_s.demodulize.downcase.pluralize
|
58
|
+
logger.debug { "send(#{klass})" }
|
59
|
+
many = value.send(klass)
|
60
|
+
many << self
|
61
|
+
many.uniq!
|
62
|
+
end
|
63
|
+
|
64
|
+
def save_belongs_to_references
|
65
|
+
belongs_to_references.each do |key, dataset|
|
66
|
+
dataset.each do |data|
|
67
|
+
# do something to store the data somewhere
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
module ClassMethods
|
73
|
+
|
74
|
+
def belongs_to(key, options={})
|
75
|
+
belongs_to_relations[key] = {
|
76
|
+
:class_name => key.to_s.classify,
|
77
|
+
:key => key
|
78
|
+
}.merge(options)
|
79
|
+
logger.debug { "key(#{key.inspect}), options(#{belongs_to_relations[key].inspect})" }
|
80
|
+
|
81
|
+
define_method(key) do |*args|
|
82
|
+
logger.debug { "*args(#{args.inspect})" }
|
83
|
+
|
84
|
+
if args.count == 0
|
85
|
+
get_belongs_to_reference(key)
|
86
|
+
else
|
87
|
+
send("#{key}=", *args)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
define_method("#{key}=") do |value|
|
92
|
+
logger.debug { "#{key}= value(#{value.inspect})" }
|
93
|
+
|
94
|
+
set_belongs_to_reference(key, value)
|
95
|
+
end
|
96
|
+
|
97
|
+
define_method("#{key}_id") do |*args|
|
98
|
+
logger.debug { "#{key}_id *args(#{args.inspect})" }
|
99
|
+
|
100
|
+
if args.count == 0
|
101
|
+
attributes["#{key}_id".to_sym]
|
102
|
+
else
|
103
|
+
send("#{key}_id=".to_sym, args.first)
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
define_method("#{key}_id=") do |value|
|
109
|
+
options = self.class.belongs_to_relations[key]
|
110
|
+
logger.debug { "#{key}_id= value(#{value.inspect}), options(#{options.inspect})" }
|
111
|
+
|
112
|
+
if value != attributes["#{key}_id".to_sym]
|
113
|
+
item = options[:class_name].constantize.find(value).first
|
114
|
+
set_belongs_to_reference(key, item)
|
115
|
+
else
|
116
|
+
value
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# define_method(singularize(key)) do |value|
|
121
|
+
# set_belongs_to_reference(key, value)
|
122
|
+
# end
|
123
|
+
|
124
|
+
# define_method(singularize(key)) do |&block|
|
125
|
+
# puts get_belongs_to_reference(key).inspect
|
126
|
+
# data = constantize(classify(key.to_s)).new(&block)
|
127
|
+
# get_belongs_to_reference(key) << data
|
128
|
+
# data
|
129
|
+
# end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,105 @@
|
|
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
|
+
module ZTK::DSL::Core::Relations
|
22
|
+
module HasMany
|
23
|
+
|
24
|
+
def self.included(base)
|
25
|
+
base.class_eval do
|
26
|
+
base.add_relation(:has_many)
|
27
|
+
base.send(:extend, ZTK::DSL::Core::Relations::HasMany::ClassMethods)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def has_many_references
|
32
|
+
@has_many_references ||= {}
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_has_many_reference(key)
|
36
|
+
logger.debug { "key(#{key})" }
|
37
|
+
|
38
|
+
if has_many_references.key?(key)
|
39
|
+
logger.debug { "found key -> (#{key})" }
|
40
|
+
|
41
|
+
has_many_references[key]
|
42
|
+
else
|
43
|
+
logger.debug { "looking up key -> (#{key})" }
|
44
|
+
|
45
|
+
has_many_references[key] ||= []
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def set_has_many_reference(key, value)
|
50
|
+
logger.debug { "key(#{key}), value(#{value})" }
|
51
|
+
|
52
|
+
dataset = get_has_many_reference(key)
|
53
|
+
dataset.clear
|
54
|
+
dataset.concat(value)
|
55
|
+
end
|
56
|
+
|
57
|
+
def save_has_many_references
|
58
|
+
has_many_references.each do |key, dataset|
|
59
|
+
dataset.each do |data|
|
60
|
+
# do something to store the data somewhere
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
module ClassMethods
|
66
|
+
|
67
|
+
def has_many(key, options={})
|
68
|
+
has_many_relations[key] = {
|
69
|
+
:class_name => key.to_s.classify,
|
70
|
+
:key => key
|
71
|
+
}.merge(options)
|
72
|
+
logger.debug { "key(#{key.inspect}), options(#{has_many_relations[key].inspect})" }
|
73
|
+
|
74
|
+
define_method(key) do |*args|
|
75
|
+
logger.debug { "#{key} *args(#{args.inspect})" }
|
76
|
+
|
77
|
+
if args.count == 0
|
78
|
+
get_has_many_reference(key)
|
79
|
+
else
|
80
|
+
send("#{key}=", *args)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
define_method("#{key}=") do |value|
|
85
|
+
logger.debug { "#{key}= value(#{value.inspect})" }
|
86
|
+
|
87
|
+
set_has_many_reference(key, value)
|
88
|
+
end
|
89
|
+
|
90
|
+
define_method(key.to_s.singularize) do |&block|
|
91
|
+
options = self.class.has_many_relations[key]
|
92
|
+
logger.debug { "#{key.to_s.singularize} block(#{block.inspect}), options(#{options.inspect})" }
|
93
|
+
data = options[:class_name].constantize.new(&block)
|
94
|
+
get_has_many_reference(key) << data
|
95
|
+
klass = self.class.to_s.demodulize.singularize.downcase
|
96
|
+
logger.debug { "send(#{klass})" }
|
97
|
+
data.send("#{klass}=", self)
|
98
|
+
data
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,45 @@
|
|
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
|
+
module ZTK::DSL::Core
|
22
|
+
module Relations
|
23
|
+
autoload :BelongsTo, "ztk/dsl/core/relations/belongs_to"
|
24
|
+
autoload :HasMany, "ztk/dsl/core/relations/has_many"
|
25
|
+
|
26
|
+
def self.included(base)
|
27
|
+
base.class_eval do
|
28
|
+
base.send(:extend, ZTK::DSL::Core::Relations::ClassMethods)
|
29
|
+
base.send(:include, ZTK::DSL::Core::Relations::BelongsTo)
|
30
|
+
base.send(:include, ZTK::DSL::Core::Relations::HasMany)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module ClassMethods
|
35
|
+
|
36
|
+
def add_relation(key)
|
37
|
+
relation_key = "#{key}_relations"
|
38
|
+
cattr_accessor relation_key
|
39
|
+
send(relation_key) || send("#{relation_key}=", {})
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
data/lib/ztk/dsl/core.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
module ZTK::DSL
|
2
|
+
module Core
|
3
|
+
autoload :Attributes, "ztk/dsl/core/attributes"
|
4
|
+
autoload :Actions, "ztk/dsl/core/actions"
|
5
|
+
autoload :Dataset, "ztk/dsl/core/dataset"
|
6
|
+
autoload :IO, "ztk/dsl/core/io"
|
7
|
+
autoload :Relations, "ztk/dsl/core/relations"
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.class_eval do
|
11
|
+
base.send(:extend, ZTK::DSL::Core::ClassMethods)
|
12
|
+
|
13
|
+
base.send(:extend, ZTK::DSL::Core::DualMethods)
|
14
|
+
base.send(:include, ZTK::DSL::Core::DualMethods)
|
15
|
+
|
16
|
+
base.send(:include, ZTK::DSL::Core::Attributes)
|
17
|
+
base.send(:include, ZTK::DSL::Core::Actions)
|
18
|
+
base.send(:include, ZTK::DSL::Core::Dataset)
|
19
|
+
base.send(:include, ZTK::DSL::Core::IO)
|
20
|
+
base.send(:include, ZTK::DSL::Core::Relations)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module DualMethods
|
25
|
+
|
26
|
+
def logger
|
27
|
+
unless defined?($logger)
|
28
|
+
$logger = ::ZTK::Logger.new("dsl.log")
|
29
|
+
$logger.info {"=" * 80}
|
30
|
+
$logger.info {"=" * 80}
|
31
|
+
$logger.info {"=" * 80}
|
32
|
+
end
|
33
|
+
$logger
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
module ClassMethods
|
39
|
+
|
40
|
+
def cattr_accessor(*args)
|
41
|
+
cattr_reader(*args)
|
42
|
+
cattr_writer(*args)
|
43
|
+
end
|
44
|
+
|
45
|
+
def cattr_reader(*args)
|
46
|
+
args.flatten.each do |arg|
|
47
|
+
next if arg.is_a?(Hash)
|
48
|
+
instance_eval %Q{
|
49
|
+
unless defined?(@@#{arg})
|
50
|
+
@@#{arg} = nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def #{arg}
|
54
|
+
@@#{arg}
|
55
|
+
end
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def cattr_writer(*args)
|
61
|
+
args.flatten.each do |arg|
|
62
|
+
next if arg.is_a?(Hash)
|
63
|
+
instance_eval %Q{
|
64
|
+
unless defined?(@@#{arg})
|
65
|
+
@@#{arg} = nil
|
66
|
+
end
|
67
|
+
|
68
|
+
def #{arg}=(value)
|
69
|
+
@@#{arg} = value
|
70
|
+
end
|
71
|
+
}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
data/lib/ztk/dsl.rb
ADDED
@@ -0,0 +1,34 @@
|
|
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 "active_support/inflector"
|
22
|
+
|
23
|
+
# @author Zachary Patten <zachary@jovelabs.net>
|
24
|
+
module ZTK
|
25
|
+
module DSL
|
26
|
+
|
27
|
+
# @author Zachary Patten <zachary@jovelabs.net>
|
28
|
+
class DSLError < Error; end
|
29
|
+
|
30
|
+
autoload :Base, "ztk/dsl/base"
|
31
|
+
autoload :Core, "ztk/dsl/core"
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
data/lib/ztk/logger.rb
CHANGED
@@ -17,7 +17,6 @@
|
|
17
17
|
# limitations under the License.
|
18
18
|
#
|
19
19
|
################################################################################
|
20
|
-
|
21
20
|
require "logger"
|
22
21
|
|
23
22
|
module ZTK
|
@@ -45,6 +44,7 @@ module ZTK
|
|
45
44
|
# @author Zachary Patten <zachary@jovelabs.net>
|
46
45
|
class Logger < ::Logger
|
47
46
|
|
47
|
+
# Log Levels
|
48
48
|
SEVERITIES = Severity.constants.inject([]) {|arr,c| arr[Severity.const_get(c)] = c; arr}
|
49
49
|
|
50
50
|
def initialize(*args)
|
@@ -52,15 +52,28 @@ module ZTK
|
|
52
52
|
set_log_level
|
53
53
|
end
|
54
54
|
|
55
|
+
# Provides access to the raw log device.
|
55
56
|
def logdev
|
56
57
|
self.instance_variable_get(:@logdev).instance_variable_get(:@dev)
|
57
58
|
end
|
58
59
|
|
60
|
+
# Specialized logging. Logs messages in the same format, except has the
|
61
|
+
# option to shift the caller_at position to exposed the proper calling
|
62
|
+
# method.
|
63
|
+
#
|
64
|
+
# Very useful in situations of class inheritence, for example, where you
|
65
|
+
# might have logging statements in a base class, which are inherited by
|
66
|
+
# another class. When calling the base class method via the inherited class
|
67
|
+
# the log messages will indicate the base class as the caller. While this
|
68
|
+
# is technically true it is not always what we want to see in the logs
|
69
|
+
# because it is ambigious and does not show us where the call truly
|
70
|
+
# originated from.
|
59
71
|
def shift(severity, shift=0, &block)
|
60
72
|
severity = ZTK::Logger.const_get(severity.to_s.upcase)
|
61
73
|
add(severity, nil, nil, shift, &block)
|
62
74
|
end
|
63
75
|
|
76
|
+
# Generates a human-readable string about the logger.
|
64
77
|
def inspect
|
65
78
|
"#<#{self.class} filename=#{@logdev.filename.inspect}>"
|
66
79
|
end
|
data/lib/ztk/parallel.rb
CHANGED
@@ -17,7 +17,6 @@
|
|
17
17
|
# limitatIOns under the License.
|
18
18
|
#
|
19
19
|
################################################################################
|
20
|
-
|
21
20
|
require "base64"
|
22
21
|
|
23
22
|
module ZTK
|
@@ -62,6 +61,7 @@ module ZTK
|
|
62
61
|
# @author Zachary Patten <zachary@jovelabs.net>
|
63
62
|
class Parallel < ZTK::Base
|
64
63
|
|
64
|
+
# Default Maximum Number of Forks
|
65
65
|
MAX_FORKS = case RUBY_PLATFORM
|
66
66
|
when /darwin/ then
|
67
67
|
%x( sysctl hw.ncpu ).chomp.split(':').last.strip.to_i
|
@@ -72,7 +72,7 @@ module ZTK
|
|
72
72
|
# Result Set
|
73
73
|
attr_accessor :results
|
74
74
|
|
75
|
-
# @param [Hash]
|
75
|
+
# @param [Hash] configuration Configuration options hash.
|
76
76
|
# @option config [Integer] :max_forks Maximum number of forks to use.
|
77
77
|
# @option config [Proc] :before_fork (nil) Proc to call before forking.
|
78
78
|
# @option config [Proc] :after_fork (nil) Proc to call after forking.
|
data/lib/ztk/report.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
|
|
@@ -28,6 +27,15 @@ module ZTK
|
|
28
27
|
# @author Zachary Patten <zachary@jovelabs.net>
|
29
28
|
class ReportError < Error; end
|
30
29
|
|
30
|
+
# ZTK Report Class
|
31
|
+
#
|
32
|
+
# This class contains tools for generating spreadsheet or key-value list
|
33
|
+
# styled output. Report methods are currently meant to be interchangeable;
|
34
|
+
# that is one should be able to just switch which method they are calling
|
35
|
+
# to change the output type.
|
36
|
+
#
|
37
|
+
# The idea here is that everything is auto-sized and simply displayed.
|
38
|
+
#
|
31
39
|
# @author Zachary Patten <zachary@jovelabs.net>
|
32
40
|
class Report < ZTK::Base
|
33
41
|
|
@@ -38,6 +46,21 @@ module ZTK
|
|
38
46
|
config.logger.debug { "config=#{config.send(:table).inspect}" }
|
39
47
|
end
|
40
48
|
|
49
|
+
# Displays data in a spreadsheet style.
|
50
|
+
#
|
51
|
+
# +-------------+-------+-------+--------+----------------+-------------------+--------------+---------+
|
52
|
+
# | NAME | ALIVE | ARCH | DISTRO | IP | MAC | CHEF VERSION | PERSIST |
|
53
|
+
# +-------------+-------+-------+--------+----------------+-------------------+--------------+---------+
|
54
|
+
# | sudo | false | amd64 | ubuntu | 192.168.99.110 | 00:00:5e:34:d6:aa | N/A | true |
|
55
|
+
# | timezone | false | amd64 | ubuntu | 192.168.122.47 | 00:00:5e:92:d7:f6 | N/A | true |
|
56
|
+
# | chef-client | false | amd64 | ubuntu | 192.168.159.98 | 00:00:5e:c7:ce:26 | N/A | true |
|
57
|
+
# | users | false | amd64 | ubuntu | 192.168.7.78 | 00:00:5e:89:f9:50 | N/A | true |
|
58
|
+
# +-------------+-------+-------+--------+----------------+-------------------+--------------+---------+
|
59
|
+
#
|
60
|
+
# @param [Array] dataset An array of items for which we want to generate a
|
61
|
+
# report
|
62
|
+
# @param [Array] headers An array of headers used for ordering the output.
|
63
|
+
# @return [OpenStruct]
|
41
64
|
def spreadsheet(dataset, headers, &block)
|
42
65
|
!block_given? and log_and_raise(ReportError, "You must supply a block!")
|
43
66
|
headers.nil? and log_and_raise(ReportError, "Headers can not be nil!")
|
@@ -80,6 +103,25 @@ module ZTK
|
|
80
103
|
OpenStruct.new(:rows => rows, :max_lengths => max_lengths, :width => width)
|
81
104
|
end
|
82
105
|
|
106
|
+
# Displays data in a key-value list style.
|
107
|
+
#
|
108
|
+
# +-------------------------------------------------------------------+
|
109
|
+
# | PROVIDER: Cucumber::Chef::Provider::Vagrant |
|
110
|
+
# | ID: default |
|
111
|
+
# | STATE: aborted |
|
112
|
+
# | USERNAME: vagrant |
|
113
|
+
# | IP ADDRESS: 127.0.0.1 |
|
114
|
+
# | PORT: 2222 |
|
115
|
+
# | CHEF-SERVER API: http://127.0.0.1:4000 |
|
116
|
+
# | CHEF-SERVER WEBUI: http://127.0.0.1:4040 |
|
117
|
+
# | CHEF-SERVER DEFAULT USER: admin |
|
118
|
+
# | CHEF-SERVER DEFAULT PASSWORD: p@ssw0rd1 |
|
119
|
+
# +-------------------------------------------------------------------+
|
120
|
+
#
|
121
|
+
# @param [Array] dataset An array of items for which we want to generate a
|
122
|
+
# report
|
123
|
+
# @param [Array] headers An array of headers used for ordering the output.
|
124
|
+
# @return [OpenStruct]
|
83
125
|
def list(dataset, headers, &block)
|
84
126
|
!block_given? and log_and_raise(ReportError, "You must supply a block!")
|
85
127
|
headers.nil? and log_and_raise(ReportError, "Headers can not be nil!")
|
data/lib/ztk/rescue_retry.rb
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
# limitations under the License.
|
18
18
|
#
|
19
19
|
################################################################################
|
20
|
+
|
20
21
|
module ZTK
|
21
22
|
|
22
23
|
# ZTK::RescueRetry Error Class
|
@@ -24,13 +25,50 @@ module ZTK
|
|
24
25
|
# @author Zachary Patten <zachary@jovelabs.net>
|
25
26
|
class RescueRetryError < Error; end
|
26
27
|
|
27
|
-
# RescueRetry Class
|
28
|
+
# ZTK RescueRetry Class
|
29
|
+
#
|
30
|
+
# This class contains an exception handling tool, which will allowing retry
|
31
|
+
# of all or specific *Exceptions* based on a set number of attempts to make.
|
32
|
+
#
|
33
|
+
# The block is yielded and if a valid exception occurs the block will be
|
34
|
+
# re-executed for the set number of attempts.
|
35
|
+
#
|
36
|
+
# For example, from the ZTK SSH class:
|
37
|
+
#
|
38
|
+
# ZTK::RescueRetry.try(:tries => 3, :on => EOFError) do
|
39
|
+
# @ssh = Net::SSH.start(config.host_name, config.user, ssh_options)
|
40
|
+
# ...
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# If an SSH connection drops on the other side and we go to write to it, we
|
44
|
+
# will get this error. Wrapping the SSH code in *RescueRetry* allows us to
|
45
|
+
# retry the connection in the event this happens. If we have no luck after
|
46
|
+
# 3 attempts at executing the block, *RescueRetry* surfaces the exception.
|
28
47
|
#
|
29
48
|
# @author Zachary Patten <zachary@jovelabs.net>
|
30
49
|
class RescueRetry
|
31
50
|
|
32
51
|
class << self
|
33
52
|
|
53
|
+
# Rescue and Retry the supplied block.
|
54
|
+
#
|
55
|
+
# When no options are supplied, if an *Exception* is encounter it is
|
56
|
+
# surfaced immediately and no retry is performed.
|
57
|
+
#
|
58
|
+
# It is advisable to at least leave the *delay* option at 1. You could
|
59
|
+
# optionally set this to 0, but this is generally a bad idea.
|
60
|
+
#
|
61
|
+
# @param [Hash] options Configuration options hash.
|
62
|
+
# @option options [String] :tries (1) How many attempts at executing the
|
63
|
+
# block before we give up and surface the *Exception*.
|
64
|
+
# @option options [String] :on (Exception) Watch for a specific exception
|
65
|
+
# instead of performing retry on all exceptions.
|
66
|
+
# @option options [Float,Integer] :delay (1) How long to sleep for between
|
67
|
+
# each retry.
|
68
|
+
#
|
69
|
+
# @yield Block should execute the tasks to be rescued and retried if
|
70
|
+
# needed.
|
71
|
+
# @return [Object] The return value of the block.
|
34
72
|
def try(options={}, &block)
|
35
73
|
options = Base.build_config({
|
36
74
|
:tries => 1,
|