test-kitchen-rsync 3.0.0.pre.1
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.
- checksums.yaml +7 -0
- data/Gemfile +21 -0
- data/LICENSE +15 -0
- data/Rakefile +53 -0
- data/bin/zl-kitchen +11 -0
- data/lib/kitchen/base64_stream.rb +48 -0
- data/lib/kitchen/chef_utils_wiring.rb +40 -0
- data/lib/kitchen/cli.rb +413 -0
- data/lib/kitchen/collection.rb +52 -0
- data/lib/kitchen/color.rb +63 -0
- data/lib/kitchen/command/action.rb +41 -0
- data/lib/kitchen/command/console.rb +54 -0
- data/lib/kitchen/command/diagnose.rb +84 -0
- data/lib/kitchen/command/doctor.rb +39 -0
- data/lib/kitchen/command/exec.rb +37 -0
- data/lib/kitchen/command/list.rb +148 -0
- data/lib/kitchen/command/login.rb +39 -0
- data/lib/kitchen/command/package.rb +32 -0
- data/lib/kitchen/command/sink.rb +50 -0
- data/lib/kitchen/command/test.rb +47 -0
- data/lib/kitchen/command.rb +207 -0
- data/lib/kitchen/config.rb +344 -0
- data/lib/kitchen/configurable.rb +616 -0
- data/lib/kitchen/data_munger.rb +1024 -0
- data/lib/kitchen/diagnostic.rb +138 -0
- data/lib/kitchen/driver/base.rb +133 -0
- data/lib/kitchen/driver/dummy.rb +105 -0
- data/lib/kitchen/driver/exec.rb +70 -0
- data/lib/kitchen/driver/proxy.rb +70 -0
- data/lib/kitchen/driver/ssh_base.rb +351 -0
- data/lib/kitchen/driver.rb +40 -0
- data/lib/kitchen/errors.rb +243 -0
- data/lib/kitchen/generator/init.rb +254 -0
- data/lib/kitchen/instance.rb +726 -0
- data/lib/kitchen/lazy_hash.rb +148 -0
- data/lib/kitchen/lifecycle_hook/base.rb +78 -0
- data/lib/kitchen/lifecycle_hook/local.rb +53 -0
- data/lib/kitchen/lifecycle_hook/remote.rb +39 -0
- data/lib/kitchen/lifecycle_hooks.rb +92 -0
- data/lib/kitchen/loader/yaml.rb +377 -0
- data/lib/kitchen/logger.rb +422 -0
- data/lib/kitchen/logging.rb +52 -0
- data/lib/kitchen/login_command.rb +49 -0
- data/lib/kitchen/metadata_chopper.rb +49 -0
- data/lib/kitchen/platform.rb +64 -0
- data/lib/kitchen/plugin.rb +76 -0
- data/lib/kitchen/plugin_base.rb +60 -0
- data/lib/kitchen/provisioner/base.rb +269 -0
- data/lib/kitchen/provisioner/chef/berkshelf.rb +116 -0
- data/lib/kitchen/provisioner/chef/common_sandbox.rb +350 -0
- data/lib/kitchen/provisioner/chef/policyfile.rb +163 -0
- data/lib/kitchen/provisioner/chef_apply.rb +121 -0
- data/lib/kitchen/provisioner/chef_base.rb +705 -0
- data/lib/kitchen/provisioner/chef_infra.rb +167 -0
- data/lib/kitchen/provisioner/chef_solo.rb +82 -0
- data/lib/kitchen/provisioner/chef_zero.rb +12 -0
- data/lib/kitchen/provisioner/dummy.rb +75 -0
- data/lib/kitchen/provisioner/shell.rb +157 -0
- data/lib/kitchen/provisioner.rb +42 -0
- data/lib/kitchen/rake_tasks.rb +80 -0
- data/lib/kitchen/shell_out.rb +90 -0
- data/lib/kitchen/ssh.rb +289 -0
- data/lib/kitchen/state_file.rb +112 -0
- data/lib/kitchen/suite.rb +48 -0
- data/lib/kitchen/thor_tasks.rb +63 -0
- data/lib/kitchen/transport/base.rb +236 -0
- data/lib/kitchen/transport/dummy.rb +78 -0
- data/lib/kitchen/transport/exec.rb +145 -0
- data/lib/kitchen/transport/ssh.rb +579 -0
- data/lib/kitchen/transport/winrm.rb +546 -0
- data/lib/kitchen/transport.rb +40 -0
- data/lib/kitchen/util.rb +229 -0
- data/lib/kitchen/verifier/base.rb +243 -0
- data/lib/kitchen/verifier/busser.rb +275 -0
- data/lib/kitchen/verifier/dummy.rb +75 -0
- data/lib/kitchen/verifier/shell.rb +99 -0
- data/lib/kitchen/verifier.rb +39 -0
- data/lib/kitchen/version.rb +20 -0
- data/lib/kitchen/which.rb +26 -0
- data/lib/kitchen.rb +152 -0
- data/lib/vendor/hash_recursive_merge.rb +79 -0
- data/support/busser_install_command.ps1 +14 -0
- data/support/busser_install_command.sh +21 -0
- data/support/chef-client-fail-if-update-handler.rb +15 -0
- data/support/chef_base_init_command.ps1 +18 -0
- data/support/chef_base_init_command.sh +1 -0
- data/support/chef_base_install_command.ps1 +85 -0
- data/support/chef_base_install_command.sh +229 -0
- data/support/download_helpers.sh +109 -0
- data/support/dummy-validation.pem +27 -0
- data/templates/driver/CHANGELOG.md.erb +3 -0
- data/templates/driver/Gemfile.erb +3 -0
- data/templates/driver/README.md.erb +64 -0
- data/templates/driver/Rakefile.erb +21 -0
- data/templates/driver/driver.rb.erb +23 -0
- data/templates/driver/gemspec.erb +29 -0
- data/templates/driver/gitignore.erb +17 -0
- data/templates/driver/license_apachev2.erb +15 -0
- data/templates/driver/license_lgplv3.erb +16 -0
- data/templates/driver/license_mit.erb +22 -0
- data/templates/driver/license_reserved.erb +5 -0
- data/templates/driver/tailor.erb +4 -0
- data/templates/driver/travis.yml.erb +11 -0
- data/templates/driver/version.rb.erb +12 -0
- data/templates/init/chefignore.erb +2 -0
- data/templates/init/kitchen.yml.erb +18 -0
- data/test-kitchen.gemspec +52 -0
- metadata +528 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2013, Fletcher Nichol
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
|
|
18
|
+
require "fileutils" unless defined?(FileUtils)
|
|
19
|
+
require "logger"
|
|
20
|
+
|
|
21
|
+
module Kitchen
|
|
22
|
+
# Logging implementation for Kitchen. By default the console/stdout output
|
|
23
|
+
# will be displayed differently than the file log output. Therefor, this
|
|
24
|
+
# class wraps multiple loggers that conform to the stdlib `Logger` class
|
|
25
|
+
# behavior.
|
|
26
|
+
#
|
|
27
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
28
|
+
class Logger
|
|
29
|
+
include ::Logger::Severity
|
|
30
|
+
|
|
31
|
+
# @return [IO] the log device
|
|
32
|
+
attr_reader :logdev
|
|
33
|
+
|
|
34
|
+
# @return [Boolean] whether logger is configured for
|
|
35
|
+
# overwriting
|
|
36
|
+
attr_reader :log_overwrite
|
|
37
|
+
|
|
38
|
+
# Constructs a new logger.
|
|
39
|
+
#
|
|
40
|
+
# @param options [Hash] configuration for a new logger
|
|
41
|
+
# @option options [Symbol] :color color to use when when outputting
|
|
42
|
+
# messages
|
|
43
|
+
# @option options [Integer] :level the logging severity threshold
|
|
44
|
+
# (default: `Kitchen::DEFAULT_LOG_LEVEL`)
|
|
45
|
+
# @option options [Boolean] whether to overwrite the log
|
|
46
|
+
# when Test Kitchen runs. Only applies if the :logdev is a String.
|
|
47
|
+
# (default: `Kitchen::DEFAULT_LOG_OVERWRITE`)
|
|
48
|
+
# @option options [String,IO] :logdev filepath String or IO object to be
|
|
49
|
+
# used for logging (default: `nil`)
|
|
50
|
+
# @option options [String] :progname program name to include in log
|
|
51
|
+
# messages (default: `"Kitchen"`)
|
|
52
|
+
# @option options [IO] :stdout a standard out IO object to use
|
|
53
|
+
# (default: `$stdout`)
|
|
54
|
+
# @option options [Boolean] :colorize whether to colorize output
|
|
55
|
+
# when Test Kitchen runs.
|
|
56
|
+
# (default: `$stdout.tty?`)
|
|
57
|
+
def initialize(options = {})
|
|
58
|
+
@log_overwrite = if options[:log_overwrite].nil?
|
|
59
|
+
default_log_overwrite
|
|
60
|
+
else
|
|
61
|
+
options[:log_overwrite]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
@logdev = logdev_logger(options[:logdev], log_overwrite) if options[:logdev]
|
|
65
|
+
|
|
66
|
+
populate_loggers(options)
|
|
67
|
+
|
|
68
|
+
# These setters cannot be called until @loggers are populated because
|
|
69
|
+
# they are delegated
|
|
70
|
+
self.progname = options[:progname] || "Kitchen"
|
|
71
|
+
self.level = options[:level] || default_log_level
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Pulled out for Rubocop complexity issues
|
|
75
|
+
#
|
|
76
|
+
# @api private
|
|
77
|
+
def populate_loggers(options)
|
|
78
|
+
@loggers = []
|
|
79
|
+
@loggers << logdev unless logdev.nil?
|
|
80
|
+
@loggers << stdout_logger(options[:stdout], options[:color], options[:colorize]) if
|
|
81
|
+
options[:stdout]
|
|
82
|
+
@loggers << stdout_logger($stdout, options[:color], options[:colorize]) if
|
|
83
|
+
@loggers.empty?
|
|
84
|
+
end
|
|
85
|
+
private :populate_loggers
|
|
86
|
+
|
|
87
|
+
class << self
|
|
88
|
+
private
|
|
89
|
+
|
|
90
|
+
# @api private
|
|
91
|
+
# @!macro delegate_to_first_logger
|
|
92
|
+
# @method $1()
|
|
93
|
+
def delegate_to_first_logger(meth)
|
|
94
|
+
define_method(meth) { |*args| @loggers.first.public_send(meth, *args) }
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# @api private
|
|
98
|
+
# @!macro delegate_to_all_loggers
|
|
99
|
+
# @method $1()
|
|
100
|
+
def delegate_to_all_loggers(meth)
|
|
101
|
+
define_method(meth) do |*args|
|
|
102
|
+
result = nil
|
|
103
|
+
@loggers.each { |l| result = l.public_send(meth, *args) }
|
|
104
|
+
result
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# @return [Integer] the logging severity threshold
|
|
110
|
+
# @see http://is.gd/Okuy5p
|
|
111
|
+
delegate_to_first_logger :level
|
|
112
|
+
|
|
113
|
+
# Sets the logging severity threshold.
|
|
114
|
+
#
|
|
115
|
+
# @param level [Integer] the logging severity threshold
|
|
116
|
+
# @see http://is.gd/H1VBFH
|
|
117
|
+
delegate_to_all_loggers :level=
|
|
118
|
+
|
|
119
|
+
# @return [String] program name to include in log messages
|
|
120
|
+
# @see http://is.gd/5uHGK0
|
|
121
|
+
delegate_to_first_logger :progname
|
|
122
|
+
|
|
123
|
+
# Sets the program name to include in log messages.
|
|
124
|
+
#
|
|
125
|
+
# @param progname [String] the program name to include in log messages
|
|
126
|
+
# @see http://is.gd/f2U5Xj
|
|
127
|
+
delegate_to_all_loggers :progname=
|
|
128
|
+
|
|
129
|
+
# @return [String] the date format being used
|
|
130
|
+
# @see http://is.gd/btmFWJ
|
|
131
|
+
delegate_to_first_logger :datetime_format
|
|
132
|
+
|
|
133
|
+
# Sets the date format being used.
|
|
134
|
+
#
|
|
135
|
+
# @param format [String] the date format
|
|
136
|
+
# @see http://is.gd/M36ml8
|
|
137
|
+
delegate_to_all_loggers :datetime_format=
|
|
138
|
+
|
|
139
|
+
# Log a message if the given severity is high enough.
|
|
140
|
+
#
|
|
141
|
+
# @see http://is.gd/5opBW0
|
|
142
|
+
delegate_to_all_loggers :add
|
|
143
|
+
|
|
144
|
+
# Dump one or more messages to info.
|
|
145
|
+
#
|
|
146
|
+
# @param message [#to_s] the message to log
|
|
147
|
+
# @see http://is.gd/BCp5KV
|
|
148
|
+
delegate_to_all_loggers :<<
|
|
149
|
+
|
|
150
|
+
# Log a message with severity of banner (high level).
|
|
151
|
+
#
|
|
152
|
+
# @param message_or_progname [#to_s] the message to log. In the block
|
|
153
|
+
# form, this is the progname to use in the log message.
|
|
154
|
+
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
155
|
+
# logger's level is sufficient to log the message. This allows you to
|
|
156
|
+
# create potentially expensive logging messages that are only called when
|
|
157
|
+
# the logger is configured to show them.
|
|
158
|
+
# @return [nil,true] when the given severity is not high enough (for this
|
|
159
|
+
# particular logger), log no message, and return true
|
|
160
|
+
# @see http://is.gd/pYUCYU
|
|
161
|
+
delegate_to_all_loggers :banner
|
|
162
|
+
|
|
163
|
+
# Log a message with severity of debug.
|
|
164
|
+
#
|
|
165
|
+
# @param message_or_progname [#to_s] the message to log. In the block
|
|
166
|
+
# form, this is the progname to use in the log message.
|
|
167
|
+
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
168
|
+
# logger's level is sufficient to log the message. This allows you to
|
|
169
|
+
# create potentially expensive logging messages that are only called when
|
|
170
|
+
# the logger is configured to show them.
|
|
171
|
+
# @return [nil,true] when the given severity is not high enough (for this
|
|
172
|
+
# particular logger), log no message, and return true
|
|
173
|
+
# @see http://is.gd/Re97Zp
|
|
174
|
+
delegate_to_all_loggers :debug
|
|
175
|
+
|
|
176
|
+
# @return [true,false] whether or not the current severity level
|
|
177
|
+
# allows for the printing of debug messages
|
|
178
|
+
# @see http://is.gd/Iq08xB
|
|
179
|
+
delegate_to_first_logger :debug?
|
|
180
|
+
|
|
181
|
+
# Log a message with severity of info.
|
|
182
|
+
#
|
|
183
|
+
# @param message_or_progname [#to_s] the message to log. In the block
|
|
184
|
+
# form, this is the progname to use in the log message.
|
|
185
|
+
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
186
|
+
# logger's level is sufficient to log the message. This allows you to
|
|
187
|
+
# create potentially expensive logging messages that are only called when
|
|
188
|
+
# the logger is configured to show them.
|
|
189
|
+
# @return [nil,true] when the given severity is not high enough (for this
|
|
190
|
+
# particular logger), log no message, and return true
|
|
191
|
+
# @see http://is.gd/pYUCYU
|
|
192
|
+
delegate_to_all_loggers :info
|
|
193
|
+
|
|
194
|
+
# @return [true,false] whether or not the current severity level
|
|
195
|
+
# allows for the printing of info messages
|
|
196
|
+
# @see http://is.gd/lBtJkT
|
|
197
|
+
delegate_to_first_logger :info?
|
|
198
|
+
|
|
199
|
+
# Log a message with severity of error.
|
|
200
|
+
#
|
|
201
|
+
# @param message_or_progname [#to_s] the message to log. In the block
|
|
202
|
+
# form, this is the progname to use in the log message.
|
|
203
|
+
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
204
|
+
# logger's level is sufficient to log the message. This allows you to
|
|
205
|
+
# create potentially expensive logging messages that are only called when
|
|
206
|
+
# the logger is configured to show them.
|
|
207
|
+
# @return [nil,true] when the given severity is not high enough (for this
|
|
208
|
+
# particular logger), log no message, and return true
|
|
209
|
+
# @see http://is.gd/mLwYMl
|
|
210
|
+
delegate_to_all_loggers :error
|
|
211
|
+
|
|
212
|
+
# @return [true,false] whether or not the current severity level
|
|
213
|
+
# allows for the printing of error messages
|
|
214
|
+
# @see http://is.gd/QY19JL
|
|
215
|
+
delegate_to_first_logger :error?
|
|
216
|
+
|
|
217
|
+
# Log a message with severity of warn.
|
|
218
|
+
#
|
|
219
|
+
# @param message_or_progname [#to_s] the message to log. In the block
|
|
220
|
+
# form, this is the progname to use in the log message.
|
|
221
|
+
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
222
|
+
# logger's level is sufficient to log the message. This allows you to
|
|
223
|
+
# create potentially expensive logging messages that are only called when
|
|
224
|
+
# the logger is configured to show them.
|
|
225
|
+
# @return [nil,true] when the given severity is not high enough (for this
|
|
226
|
+
# particular logger), log no message, and return true
|
|
227
|
+
# @see http://is.gd/PX9AIS
|
|
228
|
+
delegate_to_all_loggers :warn
|
|
229
|
+
|
|
230
|
+
# @return [true,false] whether or not the current severity level
|
|
231
|
+
# allows for the printing of warn messages
|
|
232
|
+
# @see http://is.gd/Gdr4lD
|
|
233
|
+
delegate_to_first_logger :warn?
|
|
234
|
+
|
|
235
|
+
# Log a message with severity of fatal.
|
|
236
|
+
#
|
|
237
|
+
# @param message_or_progname [#to_s] the message to log. In the block
|
|
238
|
+
# form, this is the progname to use in the log message.
|
|
239
|
+
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
240
|
+
# logger's level is sufficient to log the message. This allows you to
|
|
241
|
+
# create potentially expensive logging messages that are only called when
|
|
242
|
+
# the logger is configured to show them.
|
|
243
|
+
# @return [nil,true] when the given severity is not high enough (for this
|
|
244
|
+
# particular logger), log no message, and return true
|
|
245
|
+
# @see http://is.gd/5ElFPK
|
|
246
|
+
delegate_to_all_loggers :fatal
|
|
247
|
+
|
|
248
|
+
# @return [true,false] whether or not the current severity level
|
|
249
|
+
# allows for the printing of fatal messages
|
|
250
|
+
# @see http://is.gd/7PgwRl
|
|
251
|
+
delegate_to_first_logger :fatal?
|
|
252
|
+
|
|
253
|
+
# Log a message with severity of unknown.
|
|
254
|
+
#
|
|
255
|
+
# @param message_or_progname [#to_s] the message to log. In the block
|
|
256
|
+
# form, this is the progname to use in the log message.
|
|
257
|
+
# @yield evaluates to the message to log. This is not evaluated unless the
|
|
258
|
+
# logger's level is sufficient to log the message. This allows you to
|
|
259
|
+
# create potentially expensive logging messages that are only called when
|
|
260
|
+
# the logger is configured to show them.
|
|
261
|
+
# @return [nil,true] when the given severity is not high enough (for this
|
|
262
|
+
# particular logger), log no message, and return true
|
|
263
|
+
# @see http://is.gd/Y4hqpf
|
|
264
|
+
delegate_to_all_loggers :unknown
|
|
265
|
+
|
|
266
|
+
# Close the logging devices.
|
|
267
|
+
#
|
|
268
|
+
# @see http://is.gd/b13cVn
|
|
269
|
+
delegate_to_all_loggers :close
|
|
270
|
+
|
|
271
|
+
private
|
|
272
|
+
|
|
273
|
+
# @return [Integer] the default logger level
|
|
274
|
+
# @api private
|
|
275
|
+
def default_log_level
|
|
276
|
+
Util.to_logger_level(Kitchen::DEFAULT_LOG_LEVEL)
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
# @return [Boolean] whether to overwrite logs by default
|
|
280
|
+
# @api private
|
|
281
|
+
def default_log_overwrite
|
|
282
|
+
Kitchen::DEFAULT_LOG_OVERWRITE
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
# Construct a new standard out logger.
|
|
286
|
+
#
|
|
287
|
+
# @param stdout [IO] the IO object that represents stdout (or similar)
|
|
288
|
+
# @param color [Symbol] color to use when outputing messages
|
|
289
|
+
# @param colorize [Boolean] whether to enable color
|
|
290
|
+
# @return [StdoutLogger] a new logger
|
|
291
|
+
# @api private
|
|
292
|
+
def stdout_logger(stdout, color, colorize)
|
|
293
|
+
logger = StdoutLogger.new(stdout)
|
|
294
|
+
if colorize
|
|
295
|
+
logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
|
296
|
+
Color.colorize(msg.dup.to_s, color).concat("\n")
|
|
297
|
+
end
|
|
298
|
+
else
|
|
299
|
+
logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
|
300
|
+
msg.dup.concat("\n")
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
logger
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# Construct a new logdev logger.
|
|
307
|
+
#
|
|
308
|
+
# @param filepath_or_logdev [String,IO] a filepath String or IO object
|
|
309
|
+
# @param log_overwrite [Boolean] apply log overwriting
|
|
310
|
+
# if filepath_or_logdev is a file path
|
|
311
|
+
# @return [LogdevLogger] a new logger
|
|
312
|
+
# @api private
|
|
313
|
+
def logdev_logger(filepath_or_logdev, log_overwrite)
|
|
314
|
+
LogdevLogger.new(resolve_logdev(filepath_or_logdev, log_overwrite))
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
# Return an IO object from a filepath String or the IO object itself.
|
|
318
|
+
#
|
|
319
|
+
# @param filepath_or_logdev [String,IO] a filepath String or IO object
|
|
320
|
+
# @param log_overwrite [Boolean] apply log overwriting
|
|
321
|
+
# if filepath_or_logdev is a file path
|
|
322
|
+
# @return [IO] an IO object
|
|
323
|
+
# @api private
|
|
324
|
+
def resolve_logdev(filepath_or_logdev, log_overwrite)
|
|
325
|
+
if filepath_or_logdev.is_a? String
|
|
326
|
+
mode = log_overwrite ? "wb" : "ab"
|
|
327
|
+
FileUtils.mkdir_p(File.dirname(filepath_or_logdev))
|
|
328
|
+
file = File.open(File.expand_path(filepath_or_logdev), mode)
|
|
329
|
+
file.sync = true
|
|
330
|
+
file
|
|
331
|
+
else
|
|
332
|
+
filepath_or_logdev
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
# Internal class which adds a #banner method call that displays the
|
|
337
|
+
# message with a callout arrow.
|
|
338
|
+
class LogdevLogger < ::Logger
|
|
339
|
+
alias super_info info
|
|
340
|
+
|
|
341
|
+
# Dump one or more messages to info.
|
|
342
|
+
#
|
|
343
|
+
# @param msg [String] a message
|
|
344
|
+
def <<(msg)
|
|
345
|
+
@buffer ||= ""
|
|
346
|
+
@buffer += msg
|
|
347
|
+
while (i = @buffer.index("\n"))
|
|
348
|
+
format_line(@buffer[0, i].chomp)
|
|
349
|
+
@buffer[0, i + 1] = ""
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
# Log a banner message.
|
|
354
|
+
#
|
|
355
|
+
# @param msg [String] a message
|
|
356
|
+
def banner(msg = nil, &block)
|
|
357
|
+
super_info("-----> #{msg}", &block)
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
private
|
|
361
|
+
|
|
362
|
+
# Reformat a line if it already contains log formatting.
|
|
363
|
+
#
|
|
364
|
+
# @param line [String] a message line
|
|
365
|
+
# @api private
|
|
366
|
+
def format_line(line)
|
|
367
|
+
case line
|
|
368
|
+
when /^-----> / then banner(line.gsub(/^[ >-]{6} /, ""))
|
|
369
|
+
when /^>>>>>> / then error(line.gsub(/^[ >-]{6} /, ""))
|
|
370
|
+
when /^ / then info(line.gsub(/^[ >-]{6} /, ""))
|
|
371
|
+
else info(line)
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
# Internal class which reformats logging methods for display as console
|
|
377
|
+
# output.
|
|
378
|
+
class StdoutLogger < LogdevLogger
|
|
379
|
+
# Log a debug message
|
|
380
|
+
#
|
|
381
|
+
# @param msg [String] a message
|
|
382
|
+
def debug(msg = nil, &block)
|
|
383
|
+
super("D #{msg}", &block)
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
# Log an info message
|
|
387
|
+
#
|
|
388
|
+
# @param msg [String] a message
|
|
389
|
+
def info(msg = nil, &block)
|
|
390
|
+
super(" #{msg}", &block)
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
# Log a warn message
|
|
394
|
+
#
|
|
395
|
+
# @param msg [String] a message
|
|
396
|
+
def warn(msg = nil, &block)
|
|
397
|
+
super("$$$$$$ #{msg}", &block)
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
# Log an error message
|
|
401
|
+
#
|
|
402
|
+
# @param msg [String] a message
|
|
403
|
+
def error(msg = nil, &block)
|
|
404
|
+
super(">>>>>> #{msg}", &block)
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
# Log a fatal message
|
|
408
|
+
#
|
|
409
|
+
# @param msg [String] a message
|
|
410
|
+
def fatal(msg = nil, &block)
|
|
411
|
+
super("!!!!!! #{msg}", &block)
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
# Log an unknown message
|
|
415
|
+
#
|
|
416
|
+
# @param msg [String] a message
|
|
417
|
+
def unknown(msg = nil, &block)
|
|
418
|
+
super("?????? #{msg}", &block)
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2013, Fletcher Nichol
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
|
|
18
|
+
module Kitchen
|
|
19
|
+
# Mixin module that delegates logging methods to a local `#logger`.
|
|
20
|
+
#
|
|
21
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
22
|
+
module Logging
|
|
23
|
+
class << self
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
# @api private
|
|
27
|
+
# @!macro logger_method
|
|
28
|
+
# @method $1($2)
|
|
29
|
+
# Log a message with severity of $1
|
|
30
|
+
# @param message_or_progname [#to_s] the message to log. In the block
|
|
31
|
+
# form, this is the progname to use in the log message.
|
|
32
|
+
# @yield evaluates to the message to log. This is not evaluated unless
|
|
33
|
+
# the logger's level is sufficient to log the message. This allows
|
|
34
|
+
# you to create potentially expensive logging messages that are
|
|
35
|
+
# only called when the logger is configured to show them.
|
|
36
|
+
# @return [nil,true] when the given severity is not high enough (for
|
|
37
|
+
# this particular logger), log no message, and return true
|
|
38
|
+
def logger_method(meth)
|
|
39
|
+
define_method(meth) do |*args|
|
|
40
|
+
logger.public_send(meth, *args)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
logger_method :banner
|
|
46
|
+
logger_method :debug
|
|
47
|
+
logger_method :info
|
|
48
|
+
logger_method :warn
|
|
49
|
+
logger_method :error
|
|
50
|
+
logger_method :fatal
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2013, Fletcher Nichol
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
|
|
18
|
+
module Kitchen
|
|
19
|
+
# Value object to track a shell command that will be passed to Kernel.exec
|
|
20
|
+
# for execution.
|
|
21
|
+
#
|
|
22
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
23
|
+
class LoginCommand
|
|
24
|
+
# @return [String] login command
|
|
25
|
+
attr_reader :command
|
|
26
|
+
|
|
27
|
+
# @return [Array] array of arguments to the command
|
|
28
|
+
attr_reader :arguments
|
|
29
|
+
|
|
30
|
+
# @return [Hash] options hash, passed to `Kernel#exec`
|
|
31
|
+
attr_reader :options
|
|
32
|
+
|
|
33
|
+
# Constructs a new LoginCommand instance.
|
|
34
|
+
#
|
|
35
|
+
# @param command [String] command
|
|
36
|
+
# @param arguments [Array] array of arguments to the command
|
|
37
|
+
# @param options [Hash] options hash, passed to `Kernel#exec`
|
|
38
|
+
# @see http://www.ruby-doc.org/core-2.1.2/Kernel.html#method-i-exec
|
|
39
|
+
def initialize(command, arguments, options = {})
|
|
40
|
+
@command = command
|
|
41
|
+
@arguments = Array(arguments)
|
|
42
|
+
@options = options
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def exec_args
|
|
46
|
+
[command, *arguments, options]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2012, Fletcher Nichol
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
|
|
18
|
+
module Kitchen
|
|
19
|
+
# A rather insane and questionable class to quickly consume a metadata.rb
|
|
20
|
+
# file and return the cookbook name and version attributes.
|
|
21
|
+
#
|
|
22
|
+
# @see https://twitter.com/fnichol/status/281650077901144064
|
|
23
|
+
# @see https://gist.github.com/4343327
|
|
24
|
+
class MetadataChopper < Hash
|
|
25
|
+
# Return an Array containing the cookbook name and version attributes,
|
|
26
|
+
# or nil values if they could not be parsed.
|
|
27
|
+
#
|
|
28
|
+
# @param metadata_file [String] path to a metadata.rb file
|
|
29
|
+
# @return [Array<String>] array containing the cookbook name and version
|
|
30
|
+
# attributes or nil values if they could not be determined
|
|
31
|
+
def self.extract(metadata_file)
|
|
32
|
+
mc = new(File.expand_path(metadata_file))
|
|
33
|
+
[mc[:name], mc[:version]]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Creates a new instances and loads in the contents of the metdata.rb
|
|
37
|
+
# file. If you value your life, you may want to avoid reading the
|
|
38
|
+
# implementation.
|
|
39
|
+
#
|
|
40
|
+
# @param metadata_file [String] path to a metadata.rb file
|
|
41
|
+
def initialize(metadata_file)
|
|
42
|
+
instance_eval(IO.read(metadata_file), metadata_file)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def method_missing(meth, *args, &_block)
|
|
46
|
+
self[meth] = args.first
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2012, Fletcher Nichol
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
|
|
18
|
+
module Kitchen
|
|
19
|
+
# A target operating system environment in which convergence integration
|
|
20
|
+
# will take place. This may represent a specific operating system, version,
|
|
21
|
+
# and machine architecture.
|
|
22
|
+
#
|
|
23
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
24
|
+
class Platform
|
|
25
|
+
# @return [String] logical name of this platform
|
|
26
|
+
attr_reader :name
|
|
27
|
+
|
|
28
|
+
# @return [String] operating system type hint (default: `"unix"`)
|
|
29
|
+
attr_reader :os_type
|
|
30
|
+
|
|
31
|
+
# @return [String] shell command flavor hint (default: `"bourne"`)
|
|
32
|
+
attr_reader :shell_type
|
|
33
|
+
|
|
34
|
+
# Constructs a new platform.
|
|
35
|
+
#
|
|
36
|
+
# @param [Hash] options configuration for a new platform
|
|
37
|
+
# @option options [String] :name logical name of this platform
|
|
38
|
+
# (**Required**)
|
|
39
|
+
def initialize(options = {})
|
|
40
|
+
@name = options.fetch(:name) do
|
|
41
|
+
raise ClientError, "Platform#new requires option :name"
|
|
42
|
+
end
|
|
43
|
+
@os_type = options.fetch(:os_type) do
|
|
44
|
+
windows?(options) ? "windows" : "unix"
|
|
45
|
+
end
|
|
46
|
+
@shell_type = options.fetch(:shell_type) do
|
|
47
|
+
windows?(options) ? "powershell" : "bourne"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def windows?(options)
|
|
52
|
+
@name.downcase =~ /^win/ || (
|
|
53
|
+
!options[:transport].nil? && options[:transport][:name] == "winrm"
|
|
54
|
+
)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Returns a Hash of configuration and other useful diagnostic information.
|
|
58
|
+
#
|
|
59
|
+
# @return [Hash] a diagnostic hash
|
|
60
|
+
def diagnose
|
|
61
|
+
{ os_type: os_type, shell_type: shell_type }
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|