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
@@ -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,
|