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,275 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2012, 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 "base64" unless defined?(Base64)
|
|
19
|
+
require "digest" unless defined?(Digest)
|
|
20
|
+
|
|
21
|
+
require_relative "base"
|
|
22
|
+
|
|
23
|
+
module Kitchen
|
|
24
|
+
module Verifier
|
|
25
|
+
# Command string generator to interface with Busser. The commands that are
|
|
26
|
+
# generated are safe to pass to an SSH command or as an unix command
|
|
27
|
+
# argument (escaped in single quotes).
|
|
28
|
+
#
|
|
29
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
30
|
+
class Busser < Kitchen::Verifier::Base
|
|
31
|
+
kitchen_verifier_api_version 1
|
|
32
|
+
|
|
33
|
+
plugin_version Kitchen::VERSION
|
|
34
|
+
|
|
35
|
+
default_config :busser_bin do |verifier|
|
|
36
|
+
verifier
|
|
37
|
+
.remote_path_join(%W{#{verifier[:root_path]} bin busser})
|
|
38
|
+
.tap { |path| path.concat(".bat") if verifier.windows_os? }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
default_config :ruby_bindir do |verifier|
|
|
42
|
+
if verifier.windows_os?
|
|
43
|
+
'$env:systemdrive\\opscode\\chef\\embedded\\bin'
|
|
44
|
+
else
|
|
45
|
+
verifier.remote_path_join(%W{#{verifier[:chef_omnibus_root]} embedded bin})
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
default_config :version, "busser"
|
|
50
|
+
|
|
51
|
+
expand_path_for :test_base_path
|
|
52
|
+
|
|
53
|
+
# Creates a new Busser object using the provided configuration data
|
|
54
|
+
# which will be merged with any default configuration.
|
|
55
|
+
#
|
|
56
|
+
# @param config [Hash] provided driver configuration
|
|
57
|
+
def initialize(config = {})
|
|
58
|
+
init_config(config)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# (see Base#create_sandbox)
|
|
62
|
+
def create_sandbox
|
|
63
|
+
super
|
|
64
|
+
prepare_helpers
|
|
65
|
+
prepare_suites
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# (see Base#init_command)
|
|
69
|
+
def init_command
|
|
70
|
+
return if local_suite_files.empty?
|
|
71
|
+
|
|
72
|
+
cmd = sudo(config[:busser_bin]).dup
|
|
73
|
+
.tap { |str| str.insert(0, "& ") if powershell_shell? }
|
|
74
|
+
|
|
75
|
+
prefix_command(wrap_shell_code(Util.outdent!(<<-CMD)))
|
|
76
|
+
#{busser_env}
|
|
77
|
+
|
|
78
|
+
#{cmd} suite cleanup
|
|
79
|
+
CMD
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# (see Base#install_command)
|
|
83
|
+
def install_command
|
|
84
|
+
return if local_suite_files.empty?
|
|
85
|
+
|
|
86
|
+
vars = install_command_vars
|
|
87
|
+
|
|
88
|
+
prefix_command(shell_code_from_file(vars, "busser_install_command"))
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# (see Base#run_command)
|
|
92
|
+
def run_command
|
|
93
|
+
return if local_suite_files.empty?
|
|
94
|
+
|
|
95
|
+
cmd = sudo(config[:busser_bin]).dup
|
|
96
|
+
.tap { |str| str.insert(0, "& ") if powershell_shell? }
|
|
97
|
+
|
|
98
|
+
prefix_command(wrap_shell_code(Util.outdent!(<<-CMD)))
|
|
99
|
+
#{busser_env}
|
|
100
|
+
|
|
101
|
+
#{cmd} test #{plugins.join(" ").gsub!("busser-", "")}
|
|
102
|
+
CMD
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Legacy method stub for `#setup_cmd` which calls `#install_command`.
|
|
106
|
+
#
|
|
107
|
+
# @return [String] command string
|
|
108
|
+
# @deprecated When backwards compatibility for old Busser methods is
|
|
109
|
+
# removed, this method will no longer be available. Use
|
|
110
|
+
# `#install_command` in its place.
|
|
111
|
+
define_method(:setup_cmd) { install_command }
|
|
112
|
+
|
|
113
|
+
# Legacy method stub for `#run_cmd` which calls `#run_command`.
|
|
114
|
+
#
|
|
115
|
+
# @return [String] command string
|
|
116
|
+
# @deprecated When backwards compatibility for old Busser methods is
|
|
117
|
+
# removed, this method will no longer be available. Use
|
|
118
|
+
# `#run_command` in its place.
|
|
119
|
+
define_method(:run_cmd) { run_command }
|
|
120
|
+
|
|
121
|
+
# Legacy method stub for `#sync_cmd`.
|
|
122
|
+
#
|
|
123
|
+
# @deprecated When backwards compatibility for old Busser methods is
|
|
124
|
+
# removed, this method will no longer be available. Use
|
|
125
|
+
# `transport#upload` to transfer test files in its place.
|
|
126
|
+
def sync_cmd
|
|
127
|
+
warn("Legacy call to #sync_cmd cannot be preserved, meaning that " \
|
|
128
|
+
"test files will not be uploaded. " \
|
|
129
|
+
"Code that calls #sync_cmd can now use the transport#upload " \
|
|
130
|
+
"method to transfer files.")
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
private
|
|
134
|
+
|
|
135
|
+
# Returns a command string that sets appropriate environment variables for
|
|
136
|
+
# busser commands.
|
|
137
|
+
#
|
|
138
|
+
# @return [String] command string
|
|
139
|
+
# @api private
|
|
140
|
+
def busser_env
|
|
141
|
+
root = config[:root_path]
|
|
142
|
+
gem_home = gem_path = remote_path_join(root, "gems")
|
|
143
|
+
gem_cache = remote_path_join(gem_home, "cache")
|
|
144
|
+
|
|
145
|
+
[
|
|
146
|
+
shell_env_var("BUSSER_ROOT", root),
|
|
147
|
+
shell_env_var("GEM_HOME", gem_home),
|
|
148
|
+
shell_env_var("GEM_PATH", gem_path),
|
|
149
|
+
shell_env_var("GEM_CACHE", gem_cache),
|
|
150
|
+
].join("\n")
|
|
151
|
+
.tap { |str| str.insert(0, reload_ps1_path) if windows_os? }
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Determines whether or not a local workstation file exists under a
|
|
155
|
+
# Chef-related directory.
|
|
156
|
+
#
|
|
157
|
+
# @return [truthy,falsey] whether or not a given file is some kind of
|
|
158
|
+
# Chef-related file
|
|
159
|
+
# @api private
|
|
160
|
+
def chef_data_dir?(base, file)
|
|
161
|
+
file =~ %r{^#{base}/(data|data_bags|environments|nodes|roles)/}
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Returns arguments to a `gem install` command, suitable to install the
|
|
165
|
+
# Busser gem.
|
|
166
|
+
#
|
|
167
|
+
# @return [String] arguments string
|
|
168
|
+
# @api private
|
|
169
|
+
def gem_install_args
|
|
170
|
+
gem, version = config[:version].split("@")
|
|
171
|
+
if /^\d+\.\d+\.\d+/.match?(gem)
|
|
172
|
+
version = gem
|
|
173
|
+
gem = "busser"
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
root = config[:root_path]
|
|
177
|
+
gem_bin = remote_path_join(root, "bin")
|
|
178
|
+
|
|
179
|
+
# We don't want the gems to be installed in the home directory,
|
|
180
|
+
# this will force the bindir and the gem install location both
|
|
181
|
+
# to be under /tmp/verifier
|
|
182
|
+
args = gem
|
|
183
|
+
args += " --version #{version}" if version
|
|
184
|
+
args += " --no-document --no-format-executable -n #{gem_bin}"
|
|
185
|
+
args += " --no-user-install"
|
|
186
|
+
args
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Returns an Array of common helper filenames currently residing on the
|
|
190
|
+
# local workstation.
|
|
191
|
+
#
|
|
192
|
+
# @return [Array<String>] array of helper files
|
|
193
|
+
# @api private
|
|
194
|
+
def helper_files
|
|
195
|
+
glob = File.join("helpers", "*/**/*")
|
|
196
|
+
Util.safe_glob(config[:test_base_path], glob).reject { |f| File.directory?(f) }
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def install_command_vars
|
|
200
|
+
ruby = remote_path_join(config[:ruby_bindir], "ruby")
|
|
201
|
+
.tap { |path| path.concat(".exe") if windows_os? }
|
|
202
|
+
gem = remote_path_join(config[:ruby_bindir], "gem")
|
|
203
|
+
|
|
204
|
+
[
|
|
205
|
+
busser_env,
|
|
206
|
+
shell_var("ruby", ruby),
|
|
207
|
+
shell_var("gem", gem),
|
|
208
|
+
shell_var("version", config[:version]),
|
|
209
|
+
shell_var("gem_install_args", gem_install_args),
|
|
210
|
+
shell_var("busser", sudo(config[:busser_bin])),
|
|
211
|
+
shell_var("plugins", plugins.join(" ")),
|
|
212
|
+
].join("\n")
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Returns an Array of test suite filenames for the related suite currently
|
|
216
|
+
# residing on the local workstation. Any special provisioner-specific
|
|
217
|
+
# directories (such as a Chef roles/ directory) are excluded.
|
|
218
|
+
#
|
|
219
|
+
# @return [Array<String>] array of suite files
|
|
220
|
+
# @api private
|
|
221
|
+
def local_suite_files
|
|
222
|
+
base = File.join(config[:test_base_path], config[:suite_name])
|
|
223
|
+
Util.safe_glob(base, "*/**/*").reject do |f|
|
|
224
|
+
chef_data_dir?(base, f) || File.directory?(f)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Returns a uniquely sorted Array of Busser plugin gems that need to
|
|
229
|
+
# be installed for the related suite.
|
|
230
|
+
#
|
|
231
|
+
# @return [Array<String>] a lexically sorted, unique item array of Busser
|
|
232
|
+
# plugin gem names
|
|
233
|
+
# @api private
|
|
234
|
+
def plugins
|
|
235
|
+
non_suite_dirs = %w{data data_bags environments nodes roles}
|
|
236
|
+
Util.list_directory(File.join(config[:test_base_path], config[:suite_name])).reject do |d|
|
|
237
|
+
!File.directory?(d) || non_suite_dirs.include?(File.basename(d))
|
|
238
|
+
end.map { |d| "busser-#{File.basename(d)}" }.sort.uniq
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Copies all common testing helper files into the suites directory in
|
|
242
|
+
# the sandbox.
|
|
243
|
+
#
|
|
244
|
+
# @api private
|
|
245
|
+
def prepare_helpers
|
|
246
|
+
base = File.join(config[:test_base_path], "helpers")
|
|
247
|
+
|
|
248
|
+
helper_files.each do |src|
|
|
249
|
+
dest = File.join(sandbox_suites_dir, src.sub("#{base}/", ""))
|
|
250
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
|
251
|
+
FileUtils.cp(src, dest, preserve: true)
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Copies all test suite files into the suites directory in the sandbox.
|
|
256
|
+
#
|
|
257
|
+
# @api private
|
|
258
|
+
def prepare_suites
|
|
259
|
+
base = File.join(config[:test_base_path], config[:suite_name])
|
|
260
|
+
|
|
261
|
+
local_suite_files.each do |src|
|
|
262
|
+
dest = File.join(sandbox_suites_dir, src.sub("#{base}/", ""))
|
|
263
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
|
264
|
+
FileUtils.cp(src, dest, preserve: true)
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# @return [String] path to suites directory under sandbox path
|
|
269
|
+
# @api private
|
|
270
|
+
def sandbox_suites_dir
|
|
271
|
+
File.join(sandbox_path, "suites")
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2015, 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_relative "base"
|
|
19
|
+
|
|
20
|
+
module Kitchen
|
|
21
|
+
module Verifier
|
|
22
|
+
# Dummy verifier for Kitchen. This verifier does nothing but report what
|
|
23
|
+
# would happen if this verifier did anything of consequence. As a result
|
|
24
|
+
# it may be a useful verifier to use when debugging or developing new
|
|
25
|
+
# features or plugins.
|
|
26
|
+
#
|
|
27
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
28
|
+
class Dummy < Kitchen::Verifier::Base
|
|
29
|
+
kitchen_verifier_api_version 1
|
|
30
|
+
|
|
31
|
+
plugin_version Kitchen::VERSION
|
|
32
|
+
|
|
33
|
+
default_config :sleep, 0
|
|
34
|
+
default_config :random_failure, false
|
|
35
|
+
|
|
36
|
+
# (see Base#call)
|
|
37
|
+
def call(state)
|
|
38
|
+
info("[#{name}] Verify on instance=#{instance} with state=#{state}")
|
|
39
|
+
sleep_if_set
|
|
40
|
+
failure_if_set
|
|
41
|
+
debug("[#{name}] Verify completed (#{config[:sleep]}s).")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
# Sleep for a period of time, if a value is set in the config.
|
|
47
|
+
#
|
|
48
|
+
# @api private
|
|
49
|
+
def sleep_if_set
|
|
50
|
+
sleep(config[:sleep].to_f) if config[:sleep].to_f > 0.0
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Simulate a failure in an action, if set in the config.
|
|
54
|
+
#
|
|
55
|
+
# @api private
|
|
56
|
+
def failure_if_set
|
|
57
|
+
if config[:fail]
|
|
58
|
+
debug("Failure for Verifier #{name}.")
|
|
59
|
+
raise ActionFailed, "Action #verify failed for #{instance.to_str}."
|
|
60
|
+
elsif config[:random_failure] && randomly_fail?
|
|
61
|
+
debug("Random failure for Verifier #{name}.")
|
|
62
|
+
raise ActionFailed, "Action #verify failed for #{instance.to_str}."
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Determine whether or not to randomly fail.
|
|
67
|
+
#
|
|
68
|
+
# @return [true, false]
|
|
69
|
+
# @api private
|
|
70
|
+
def randomly_fail?
|
|
71
|
+
[true, false].sample
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: SAWANOBORI Yukihiko (<sawanoboriyu@higanworks.com>)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2015, HiganWorks LLC
|
|
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_relative "base"
|
|
19
|
+
|
|
20
|
+
module Kitchen
|
|
21
|
+
module Verifier
|
|
22
|
+
# Shell verifier for Kitchen. This verifier just execute shell command from local.
|
|
23
|
+
#
|
|
24
|
+
# @author SAWANOBORI Yukihiko (<sawanoboriyu@higanworks.com>)
|
|
25
|
+
class Shell < Kitchen::Verifier::Base
|
|
26
|
+
require "mixlib/shellout" unless defined?(Mixlib::ShellOut)
|
|
27
|
+
|
|
28
|
+
kitchen_verifier_api_version 1
|
|
29
|
+
|
|
30
|
+
plugin_version Kitchen::VERSION
|
|
31
|
+
|
|
32
|
+
default_config :sleep, 0
|
|
33
|
+
default_config :command, "true"
|
|
34
|
+
default_config :shellout_opts, {}
|
|
35
|
+
default_config :live_stream, $stdout
|
|
36
|
+
default_config :remote_exec, false
|
|
37
|
+
|
|
38
|
+
# (see Base#call)
|
|
39
|
+
def call(state)
|
|
40
|
+
info("[#{name}] Verify on instance #{instance.name} with state=#{state}")
|
|
41
|
+
sleep_if_set
|
|
42
|
+
merge_state_to_env(state)
|
|
43
|
+
if config[:remote_exec]
|
|
44
|
+
instance.transport.connection(state) do |conn|
|
|
45
|
+
conn.execute(config[:command])
|
|
46
|
+
end
|
|
47
|
+
else
|
|
48
|
+
shellout
|
|
49
|
+
end
|
|
50
|
+
debug("[#{name}] Verify completed.")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# for legacy drivers.
|
|
54
|
+
def run_command
|
|
55
|
+
if config[:remote_exec]
|
|
56
|
+
config[:command]
|
|
57
|
+
else
|
|
58
|
+
shellout
|
|
59
|
+
nil
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
# Sleep for a period of time, if a value is set in the config.
|
|
66
|
+
#
|
|
67
|
+
# @api private
|
|
68
|
+
def sleep_if_set
|
|
69
|
+
config[:sleep].to_i.times do
|
|
70
|
+
info(".")
|
|
71
|
+
sleep 1
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def shellout
|
|
76
|
+
cmd = Mixlib::ShellOut.new(config[:command], config[:shellout_opts])
|
|
77
|
+
cmd.live_stream = config[:live_stream]
|
|
78
|
+
cmd.run_command
|
|
79
|
+
begin
|
|
80
|
+
cmd.error!
|
|
81
|
+
rescue Mixlib::ShellOut::ShellCommandFailed
|
|
82
|
+
raise ActionFailed, "Action #verify failed for #{instance.to_str}."
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def merge_state_to_env(state)
|
|
87
|
+
env_state = { environment: {} }
|
|
88
|
+
env_state[:environment]["KITCHEN_INSTANCE"] = instance.name
|
|
89
|
+
env_state[:environment]["KITCHEN_PLATFORM"] = instance.platform.name
|
|
90
|
+
env_state[:environment]["KITCHEN_SUITE"] = instance.suite.name
|
|
91
|
+
env_state[:environment]["KITCHEN_USERNAME"] = instance.transport[:username] if instance.respond_to?(:transport)
|
|
92
|
+
state.each_pair do |key, value|
|
|
93
|
+
env_state[:environment]["KITCHEN_" + key.to_s.upcase] = value.to_s
|
|
94
|
+
end
|
|
95
|
+
config[:shellout_opts].merge!(env_state)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2015, 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_relative "plugin"
|
|
19
|
+
|
|
20
|
+
module Kitchen
|
|
21
|
+
# A verifier is responsible for running tests post-converge to confirm that
|
|
22
|
+
# the instance is in a known/consistent state.
|
|
23
|
+
#
|
|
24
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
25
|
+
module Verifier
|
|
26
|
+
# Default verifier to use
|
|
27
|
+
DEFAULT_PLUGIN = "busser".freeze
|
|
28
|
+
|
|
29
|
+
# Returns an instance of a verifier given a plugin type string.
|
|
30
|
+
#
|
|
31
|
+
# @param plugin [String] a verifier plugin type, to be constantized
|
|
32
|
+
# @param config [Hash] a configuration hash to initialize the verifier
|
|
33
|
+
# @return [Verifier::Base] a verifier instance
|
|
34
|
+
# @raise [ClientError] if a verifier instance could not be created
|
|
35
|
+
def self.for_plugin(plugin, config)
|
|
36
|
+
Kitchen::Plugin.load(self, plugin, config)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2012, 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
|
+
VERSION = "3.0.0-1".freeze
|
|
20
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
3
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
|
4
|
+
# License:: Apache License, Version 2.0
|
|
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 "chef-utils/dsl/which" unless defined?(ChefUtils::DSL::Which)
|
|
19
|
+
require_relative "chef_utils_wiring" unless defined?(Kitchen::ChefUtilsWiring)
|
|
20
|
+
|
|
21
|
+
module Kitchen
|
|
22
|
+
module Which
|
|
23
|
+
include ChefUtils::DSL::Which
|
|
24
|
+
include ChefUtilsWiring
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/kitchen.rb
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2012, 2013, 2014 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 "pathname" unless defined?(Pathname)
|
|
19
|
+
require_relative "kitchen/errors"
|
|
20
|
+
require_relative "kitchen/logger"
|
|
21
|
+
require_relative "kitchen/logging"
|
|
22
|
+
require_relative "kitchen/shell_out"
|
|
23
|
+
require_relative "kitchen/configurable"
|
|
24
|
+
require_relative "kitchen/util"
|
|
25
|
+
|
|
26
|
+
require_relative "kitchen/provisioner"
|
|
27
|
+
require_relative "kitchen/provisioner/base"
|
|
28
|
+
require_relative "kitchen/color"
|
|
29
|
+
require_relative "kitchen/collection"
|
|
30
|
+
require_relative "kitchen/config"
|
|
31
|
+
require_relative "kitchen/data_munger"
|
|
32
|
+
require_relative "kitchen/driver"
|
|
33
|
+
require_relative "kitchen/driver/base"
|
|
34
|
+
require_relative "kitchen/driver/ssh_base"
|
|
35
|
+
require_relative "kitchen/driver/proxy"
|
|
36
|
+
require_relative "kitchen/instance"
|
|
37
|
+
require_relative "kitchen/lifecycle_hooks"
|
|
38
|
+
require_relative "kitchen/transport"
|
|
39
|
+
require_relative "kitchen/transport/base"
|
|
40
|
+
require_relative "kitchen/loader/yaml"
|
|
41
|
+
require_relative "kitchen/metadata_chopper"
|
|
42
|
+
require_relative "kitchen/platform"
|
|
43
|
+
require_relative "kitchen/state_file"
|
|
44
|
+
require_relative "kitchen/ssh"
|
|
45
|
+
require_relative "kitchen/suite"
|
|
46
|
+
require_relative "kitchen/verifier"
|
|
47
|
+
require_relative "kitchen/verifier/base"
|
|
48
|
+
require_relative "kitchen/version"
|
|
49
|
+
|
|
50
|
+
# Test Kitchen base module.
|
|
51
|
+
#
|
|
52
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
53
|
+
module Kitchen
|
|
54
|
+
class << self
|
|
55
|
+
# @return [Logger] the common Kitchen logger
|
|
56
|
+
attr_accessor :logger
|
|
57
|
+
|
|
58
|
+
# @return [Mutex] a common mutex for global coordination
|
|
59
|
+
attr_accessor :mutex
|
|
60
|
+
|
|
61
|
+
# @return [Mutex] a mutex used for Dir.chdir coordination
|
|
62
|
+
attr_accessor :mutex_chdir
|
|
63
|
+
|
|
64
|
+
# Returns the root path of the Kitchen gem source code.
|
|
65
|
+
#
|
|
66
|
+
# @return [Pathname] root path of gem
|
|
67
|
+
def source_root
|
|
68
|
+
@source_root ||= Pathname.new(File.expand_path("..", __dir__))
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Returns a default logger which emits on standard output.
|
|
72
|
+
#
|
|
73
|
+
# @return [Logger] a logger
|
|
74
|
+
def default_logger
|
|
75
|
+
Logger.new(stdout: $stdout, level: Util.to_logger_level(env_log))
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Returns a default file logger which emits on standard output and to a
|
|
79
|
+
# log file.
|
|
80
|
+
#
|
|
81
|
+
# @param [Symbol] level logging level
|
|
82
|
+
# @param [Boolean] log_overwrite logging level
|
|
83
|
+
# @return [Logger] a logger
|
|
84
|
+
def default_file_logger(level = nil, log_overwrite = nil)
|
|
85
|
+
level ||= env_log
|
|
86
|
+
log_overwrite = log_overwrite.nil? ? env_log_overwrite : log_overwrite
|
|
87
|
+
log_location = File.expand_path(File.join(DEFAULT_LOG_DIR, "kitchen.log"))
|
|
88
|
+
log_location = log_location.to_s
|
|
89
|
+
|
|
90
|
+
Logger.new(
|
|
91
|
+
stdout: $stdout,
|
|
92
|
+
logdev: log_location,
|
|
93
|
+
level: Util.to_logger_level(level),
|
|
94
|
+
log_overwrite: log_overwrite
|
|
95
|
+
)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Returns whether or not standard output is associated with a terminal
|
|
99
|
+
# device (tty).
|
|
100
|
+
#
|
|
101
|
+
# @return [true,false] is there a tty?
|
|
102
|
+
def tty?
|
|
103
|
+
$stdout.tty?
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Determine the default log level from an environment variable, if it is
|
|
107
|
+
# set.
|
|
108
|
+
#
|
|
109
|
+
# @return [Symbol,nil] a log level or nil if not set
|
|
110
|
+
# @api private
|
|
111
|
+
def env_log
|
|
112
|
+
ENV["KITCHEN_LOG"] && ENV["KITCHEN_LOG"].downcase.to_sym
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Determine the log overwriting logic from an environment variable,
|
|
116
|
+
# if it is set.
|
|
117
|
+
#
|
|
118
|
+
# @return [Boolean,nil]
|
|
119
|
+
# @api private
|
|
120
|
+
def env_log_overwrite
|
|
121
|
+
case ENV["KITCHEN_LOG_OVERWRITE"] && ENV["KITCHEN_LOG_OVERWRITE"].downcase
|
|
122
|
+
when nil, ""
|
|
123
|
+
nil
|
|
124
|
+
when "false", "f", "no"
|
|
125
|
+
false
|
|
126
|
+
else
|
|
127
|
+
true
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Default log level verbosity
|
|
133
|
+
DEFAULT_LOG_LEVEL = :info
|
|
134
|
+
|
|
135
|
+
# Overwrite the log file when Test Kitchen runs
|
|
136
|
+
DEFAULT_LOG_OVERWRITE = true
|
|
137
|
+
|
|
138
|
+
# Default base directory for integration tests, fixtures, etc.
|
|
139
|
+
DEFAULT_TEST_DIR = "test/integration".freeze
|
|
140
|
+
|
|
141
|
+
# Default base directory for instance and common log files
|
|
142
|
+
DEFAULT_LOG_DIR = ".kitchen/logs".freeze
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Initialize the base logger
|
|
146
|
+
Kitchen.logger = Kitchen.default_logger
|
|
147
|
+
|
|
148
|
+
# Setup a collection of instance crash exceptions for error reporting
|
|
149
|
+
Kitchen.mutex = Mutex.new
|
|
150
|
+
|
|
151
|
+
# Initialize the mutex for Dir.chdir coordination
|
|
152
|
+
Kitchen.mutex_chdir = Mutex.new
|