test-kitchen 3.9.1 → 4.0.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.
- checksums.yaml +4 -4
- data/Gemfile +5 -4
- data/lib/kitchen/collection.rb +1 -1
- data/lib/kitchen/configurable.rb +4 -4
- data/lib/kitchen/data_munger.rb +7 -9
- data/lib/kitchen/driver/proxy.rb +11 -6
- data/lib/kitchen/generator/init.rb +1 -1
- data/lib/kitchen/instance.rb +6 -103
- data/lib/kitchen/lazy_hash.rb +1 -1
- data/lib/kitchen/logger.rb +1 -1
- data/lib/kitchen/metadata_chopper.rb +1 -1
- data/lib/kitchen/provisioner/base.rb +0 -18
- data/lib/kitchen/provisioner.rb +1 -2
- data/lib/kitchen/transport/winrm.rb +8 -8
- data/lib/kitchen/util.rb +1 -1
- data/lib/kitchen/version.rb +1 -1
- data/lib/kitchen.rb +0 -2
- data/lib/vendor/hash_recursive_merge.rb +2 -2
- data/templates/driver/driver.rb.erb +1 -1
- data/test-kitchen.gemspec +4 -6
- metadata +26 -39
- data/lib/kitchen/driver/ssh_base.rb +0 -346
- data/lib/kitchen/provisioner/chef/berkshelf.rb +0 -116
- data/lib/kitchen/provisioner/chef/common_sandbox.rb +0 -352
- data/lib/kitchen/provisioner/chef/policyfile.rb +0 -173
- data/lib/kitchen/provisioner/chef_apply.rb +0 -121
- data/lib/kitchen/provisioner/chef_base.rb +0 -723
- data/lib/kitchen/provisioner/chef_infra.rb +0 -167
- data/lib/kitchen/provisioner/chef_solo.rb +0 -82
- data/lib/kitchen/provisioner/chef_target.rb +0 -130
- data/lib/kitchen/provisioner/chef_zero.rb +0 -12
- data/lib/kitchen/ssh.rb +0 -296
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: test-kitchen
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 4.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Fletcher Nichol
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-01-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bcrypt_pbkdf
|
|
@@ -223,67 +223,65 @@ dependencies:
|
|
|
223
223
|
- !ruby/object:Gem::Version
|
|
224
224
|
version: '2.0'
|
|
225
225
|
- !ruby/object:Gem::Dependency
|
|
226
|
-
name: winrm
|
|
226
|
+
name: chef-winrm
|
|
227
227
|
requirement: !ruby/object:Gem::Requirement
|
|
228
228
|
requirements:
|
|
229
|
-
- - "
|
|
229
|
+
- - ">="
|
|
230
230
|
- !ruby/object:Gem::Version
|
|
231
|
-
version:
|
|
231
|
+
version: 2.5.0
|
|
232
|
+
- - "<"
|
|
233
|
+
- !ruby/object:Gem::Version
|
|
234
|
+
version: '3.0'
|
|
232
235
|
type: :runtime
|
|
233
236
|
prerelease: false
|
|
234
237
|
version_requirements: !ruby/object:Gem::Requirement
|
|
235
238
|
requirements:
|
|
236
|
-
- - "
|
|
239
|
+
- - ">="
|
|
237
240
|
- !ruby/object:Gem::Version
|
|
238
|
-
version:
|
|
241
|
+
version: 2.5.0
|
|
242
|
+
- - "<"
|
|
243
|
+
- !ruby/object:Gem::Version
|
|
244
|
+
version: '3.0'
|
|
239
245
|
- !ruby/object:Gem::Dependency
|
|
240
|
-
name: winrm-elevated
|
|
246
|
+
name: chef-winrm-elevated
|
|
241
247
|
requirement: !ruby/object:Gem::Requirement
|
|
242
248
|
requirements:
|
|
243
|
-
- - "
|
|
249
|
+
- - ">="
|
|
244
250
|
- !ruby/object:Gem::Version
|
|
245
251
|
version: '1.0'
|
|
252
|
+
- - "<"
|
|
253
|
+
- !ruby/object:Gem::Version
|
|
254
|
+
version: '2.0'
|
|
246
255
|
type: :runtime
|
|
247
256
|
prerelease: false
|
|
248
257
|
version_requirements: !ruby/object:Gem::Requirement
|
|
249
258
|
requirements:
|
|
250
|
-
- - "
|
|
259
|
+
- - ">="
|
|
251
260
|
- !ruby/object:Gem::Version
|
|
252
261
|
version: '1.0'
|
|
253
|
-
-
|
|
254
|
-
name: winrm-fs
|
|
255
|
-
requirement: !ruby/object:Gem::Requirement
|
|
256
|
-
requirements:
|
|
257
|
-
- - "~>"
|
|
258
|
-
- !ruby/object:Gem::Version
|
|
259
|
-
version: '1.1'
|
|
260
|
-
type: :runtime
|
|
261
|
-
prerelease: false
|
|
262
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
263
|
-
requirements:
|
|
264
|
-
- - "~>"
|
|
262
|
+
- - "<"
|
|
265
263
|
- !ruby/object:Gem::Version
|
|
266
|
-
version: '
|
|
264
|
+
version: '2.0'
|
|
267
265
|
- !ruby/object:Gem::Dependency
|
|
268
|
-
name:
|
|
266
|
+
name: chef-winrm-fs
|
|
269
267
|
requirement: !ruby/object:Gem::Requirement
|
|
270
268
|
requirements:
|
|
271
269
|
- - ">="
|
|
272
270
|
- !ruby/object:Gem::Version
|
|
273
|
-
version: 1.0
|
|
271
|
+
version: '1.0'
|
|
274
272
|
- - "<"
|
|
275
273
|
- !ruby/object:Gem::Version
|
|
276
|
-
version: '
|
|
274
|
+
version: '2.0'
|
|
277
275
|
type: :runtime
|
|
278
276
|
prerelease: false
|
|
279
277
|
version_requirements: !ruby/object:Gem::Requirement
|
|
280
278
|
requirements:
|
|
281
279
|
- - ">="
|
|
282
280
|
- !ruby/object:Gem::Version
|
|
283
|
-
version: 1.0
|
|
281
|
+
version: '1.0'
|
|
284
282
|
- - "<"
|
|
285
283
|
- !ruby/object:Gem::Version
|
|
286
|
-
version: '
|
|
284
|
+
version: '2.0'
|
|
287
285
|
description: Test Kitchen is an integration tool for developing and testing infrastructure
|
|
288
286
|
code and software on isolated target platforms.
|
|
289
287
|
email:
|
|
@@ -323,7 +321,6 @@ files:
|
|
|
323
321
|
- lib/kitchen/driver/dummy.rb
|
|
324
322
|
- lib/kitchen/driver/exec.rb
|
|
325
323
|
- lib/kitchen/driver/proxy.rb
|
|
326
|
-
- lib/kitchen/driver/ssh_base.rb
|
|
327
324
|
- lib/kitchen/errors.rb
|
|
328
325
|
- lib/kitchen/generator/init.rb
|
|
329
326
|
- lib/kitchen/instance.rb
|
|
@@ -343,20 +340,10 @@ files:
|
|
|
343
340
|
- lib/kitchen/plugin_base.rb
|
|
344
341
|
- lib/kitchen/provisioner.rb
|
|
345
342
|
- lib/kitchen/provisioner/base.rb
|
|
346
|
-
- lib/kitchen/provisioner/chef/berkshelf.rb
|
|
347
|
-
- lib/kitchen/provisioner/chef/common_sandbox.rb
|
|
348
|
-
- lib/kitchen/provisioner/chef/policyfile.rb
|
|
349
|
-
- lib/kitchen/provisioner/chef_apply.rb
|
|
350
|
-
- lib/kitchen/provisioner/chef_base.rb
|
|
351
|
-
- lib/kitchen/provisioner/chef_infra.rb
|
|
352
|
-
- lib/kitchen/provisioner/chef_solo.rb
|
|
353
|
-
- lib/kitchen/provisioner/chef_target.rb
|
|
354
|
-
- lib/kitchen/provisioner/chef_zero.rb
|
|
355
343
|
- lib/kitchen/provisioner/dummy.rb
|
|
356
344
|
- lib/kitchen/provisioner/shell.rb
|
|
357
345
|
- lib/kitchen/rake_tasks.rb
|
|
358
346
|
- lib/kitchen/shell_out.rb
|
|
359
|
-
- lib/kitchen/ssh.rb
|
|
360
347
|
- lib/kitchen/state_file.rb
|
|
361
348
|
- lib/kitchen/suite.rb
|
|
362
349
|
- lib/kitchen/thor_tasks.rb
|
|
@@ -1,346 +0,0 @@
|
|
|
1
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
2
|
-
# you may not use this file except in compliance with the License.
|
|
3
|
-
# You may obtain a copy of the License at
|
|
4
|
-
#
|
|
5
|
-
# https://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
-
#
|
|
7
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
8
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
-
# See the License for the specific language governing permissions and
|
|
11
|
-
# limitations under the License.
|
|
12
|
-
|
|
13
|
-
require "thor/util"
|
|
14
|
-
|
|
15
|
-
require_relative "../lazy_hash"
|
|
16
|
-
require_relative "../plugin_base"
|
|
17
|
-
require "benchmark" unless defined?(Benchmark)
|
|
18
|
-
|
|
19
|
-
module Kitchen
|
|
20
|
-
module Driver
|
|
21
|
-
# Legacy base class for a driver that uses SSH to communication with an
|
|
22
|
-
# instance. This class has been updated to use the Instance's Transport to
|
|
23
|
-
# issue commands and transfer files and no longer uses the `Kitchen:SSH`
|
|
24
|
-
# class directly.
|
|
25
|
-
#
|
|
26
|
-
# **NOTE:** Authors of new Drivers are encouraged to inherit from
|
|
27
|
-
# `Kitchen::Driver::Base` instead and existing Driver authors are
|
|
28
|
-
# encouraged to update their Driver class to inherit from
|
|
29
|
-
# `Kitchen::Driver::SSHBase`.
|
|
30
|
-
#
|
|
31
|
-
# A subclass must implement the following methods:
|
|
32
|
-
# * #create(state)
|
|
33
|
-
# * #destroy(state)
|
|
34
|
-
#
|
|
35
|
-
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
36
|
-
# @deprecated While all possible effort has been made to preserve the
|
|
37
|
-
# original behavior of this class, future improvements to the Driver,
|
|
38
|
-
# Transport, and Verifier subsystems may not be picked up in these
|
|
39
|
-
# Drivers. When legacy Driver::SSHBase support is removed, this class
|
|
40
|
-
# will no longer be available.
|
|
41
|
-
class SSHBase < Kitchen::Plugin::Base
|
|
42
|
-
include ShellOut
|
|
43
|
-
include Configurable
|
|
44
|
-
include Logging
|
|
45
|
-
|
|
46
|
-
default_config :sudo, true
|
|
47
|
-
default_config :port, 22
|
|
48
|
-
# needs to be one less than the configured sshd_config MaxSessions
|
|
49
|
-
default_config :max_ssh_sessions, 9
|
|
50
|
-
|
|
51
|
-
# Creates a new Driver object using the provided configuration data
|
|
52
|
-
# which will be merged with any default configuration.
|
|
53
|
-
#
|
|
54
|
-
# @param config [Hash] provided driver configuration
|
|
55
|
-
def initialize(config = {})
|
|
56
|
-
init_config(config)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# (see Base#create)
|
|
60
|
-
def create(state) # rubocop:disable Lint/UnusedMethodArgument
|
|
61
|
-
raise ClientError, "#{self.class}#create must be implemented"
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# (see Base#converge)
|
|
65
|
-
def converge(state) # rubocop:disable Metrics/AbcSize
|
|
66
|
-
provisioner = instance.provisioner
|
|
67
|
-
provisioner.create_sandbox
|
|
68
|
-
sandbox_dirs = provisioner.sandbox_dirs
|
|
69
|
-
|
|
70
|
-
instance.transport.connection(backcompat_merged_state(state)) do |conn|
|
|
71
|
-
conn.execute(env_cmd(provisioner.install_command))
|
|
72
|
-
conn.execute(env_cmd(provisioner.init_command))
|
|
73
|
-
info("Transferring files to #{instance.to_str}")
|
|
74
|
-
conn.upload(sandbox_dirs, provisioner[:root_path])
|
|
75
|
-
debug("Transfer complete")
|
|
76
|
-
conn.execute(env_cmd(provisioner.prepare_command))
|
|
77
|
-
conn.execute(env_cmd(provisioner.run_command))
|
|
78
|
-
info("Downloading files from #{instance.to_str}")
|
|
79
|
-
provisioner[:downloads].to_h.each do |remotes, local|
|
|
80
|
-
debug("Downloading #{Array(remotes).join(", ")} to #{local}")
|
|
81
|
-
conn.download(remotes, local)
|
|
82
|
-
end
|
|
83
|
-
debug("Download complete")
|
|
84
|
-
end
|
|
85
|
-
rescue Kitchen::Transport::TransportFailed => ex
|
|
86
|
-
raise ActionFailed, ex.message
|
|
87
|
-
ensure
|
|
88
|
-
instance.provisioner.cleanup_sandbox
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
# (see Base#setup)
|
|
92
|
-
def setup(state)
|
|
93
|
-
verifier = instance.verifier
|
|
94
|
-
|
|
95
|
-
instance.transport.connection(backcompat_merged_state(state)) do |conn|
|
|
96
|
-
conn.execute(env_cmd(verifier.install_command))
|
|
97
|
-
end
|
|
98
|
-
rescue Kitchen::Transport::TransportFailed => ex
|
|
99
|
-
raise ActionFailed, ex.message
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
# (see Base#verify)
|
|
103
|
-
def verify(state) # rubocop:disable Metrics/AbcSize
|
|
104
|
-
verifier = instance.verifier
|
|
105
|
-
verifier.create_sandbox
|
|
106
|
-
sandbox_dirs = Util.list_directory(verifier.sandbox_path)
|
|
107
|
-
|
|
108
|
-
instance.transport.connection(backcompat_merged_state(state)) do |conn|
|
|
109
|
-
conn.execute(env_cmd(verifier.init_command))
|
|
110
|
-
info("Transferring files to #{instance.to_str}")
|
|
111
|
-
conn.upload(sandbox_dirs, verifier[:root_path])
|
|
112
|
-
debug("Transfer complete")
|
|
113
|
-
conn.execute(env_cmd(verifier.prepare_command))
|
|
114
|
-
conn.execute(env_cmd(verifier.run_command))
|
|
115
|
-
end
|
|
116
|
-
rescue Kitchen::Transport::TransportFailed => ex
|
|
117
|
-
raise ActionFailed, ex.message
|
|
118
|
-
ensure
|
|
119
|
-
instance.verifier.cleanup_sandbox
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
# (see Base#destroy)
|
|
123
|
-
def destroy(state) # rubocop:disable Lint/UnusedMethodArgument
|
|
124
|
-
raise ClientError, "#{self.class}#destroy must be implemented"
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def legacy_state(state)
|
|
128
|
-
backcompat_merged_state(state)
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
# Package an instance.
|
|
132
|
-
#
|
|
133
|
-
# (see Base#package)
|
|
134
|
-
def package(state); end
|
|
135
|
-
|
|
136
|
-
# (see Base#login_command)
|
|
137
|
-
def login_command(state)
|
|
138
|
-
instance.transport.connection(backcompat_merged_state(state))
|
|
139
|
-
.login_command
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
# Executes an arbitrary command on an instance over an SSH connection.
|
|
143
|
-
#
|
|
144
|
-
# @param state [Hash] mutable instance and driver state
|
|
145
|
-
# @param command [String] the command to be executed
|
|
146
|
-
# @raise [ActionFailed] if the command could not be successfully completed
|
|
147
|
-
def remote_command(state, command)
|
|
148
|
-
instance.transport.connection(backcompat_merged_state(state)) do |conn|
|
|
149
|
-
conn.execute(env_cmd(command))
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
# **(Deprecated)** Executes a remote command over SSH.
|
|
154
|
-
#
|
|
155
|
-
# @param ssh_args [Array] ssh arguments
|
|
156
|
-
# @param command [String] remote command to invoke
|
|
157
|
-
# @deprecated This method should no longer be called directly and exists
|
|
158
|
-
# to support very old drivers. This will be removed in the future.
|
|
159
|
-
def ssh(ssh_args, command)
|
|
160
|
-
pseudo_state = { hostname: ssh_args[0], username: ssh_args[1] }
|
|
161
|
-
pseudo_state.merge!(ssh_args[2])
|
|
162
|
-
connection_state = backcompat_merged_state(pseudo_state)
|
|
163
|
-
|
|
164
|
-
instance.transport.connection(connection_state) do |conn|
|
|
165
|
-
conn.execute(env_cmd(command))
|
|
166
|
-
end
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
# Performs whatever tests that may be required to ensure that this driver
|
|
170
|
-
# will be able to function in the current environment. This may involve
|
|
171
|
-
# checking for the presence of certain directories, software installed,
|
|
172
|
-
# etc.
|
|
173
|
-
#
|
|
174
|
-
# @raise [UserError] if the driver will not be able to perform or if a
|
|
175
|
-
# documented dependency is missing from the system
|
|
176
|
-
def verify_dependencies; end
|
|
177
|
-
|
|
178
|
-
# Cache directory that a driver could implement to inform the provisioner
|
|
179
|
-
# that it can leverage it internally
|
|
180
|
-
#
|
|
181
|
-
# @return path [String] a path of the cache directory
|
|
182
|
-
def cache_directory; end
|
|
183
|
-
|
|
184
|
-
private
|
|
185
|
-
|
|
186
|
-
def backcompat_merged_state(state)
|
|
187
|
-
driver_ssh_keys = %w{
|
|
188
|
-
forward_agent hostname password port ssh_key username
|
|
189
|
-
}.map(&:to_sym)
|
|
190
|
-
config.select { |key, _| driver_ssh_keys.include?(key) }.rmerge(state)
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
# Builds arguments for constructing a `Kitchen::SSH` instance.
|
|
194
|
-
#
|
|
195
|
-
# @param state [Hash] state hash
|
|
196
|
-
# @return [Array] SSH constructor arguments
|
|
197
|
-
# @api private
|
|
198
|
-
def build_ssh_args(state)
|
|
199
|
-
combined = config.to_hash.merge(state)
|
|
200
|
-
|
|
201
|
-
opts = {}
|
|
202
|
-
opts[:user_known_hosts_file] = "/dev/null"
|
|
203
|
-
opts[:verify_host_key] = false
|
|
204
|
-
opts[:keys_only] = true if combined[:ssh_key]
|
|
205
|
-
opts[:password] = combined[:password] if combined[:password]
|
|
206
|
-
opts[:forward_agent] = combined[:forward_agent] if combined.key? :forward_agent
|
|
207
|
-
opts[:port] = combined[:port] if combined[:port]
|
|
208
|
-
opts[:keys] = Array(combined[:ssh_key]) if combined[:ssh_key]
|
|
209
|
-
opts[:logger] = logger
|
|
210
|
-
|
|
211
|
-
[combined[:hostname], combined[:username], opts]
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
# Adds http, https and ftp proxy environment variables to a command, if
|
|
215
|
-
# set in configuration data or on local workstation.
|
|
216
|
-
#
|
|
217
|
-
# @param cmd [String] command string
|
|
218
|
-
# @return [String] command string
|
|
219
|
-
# @api private
|
|
220
|
-
# rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/AbcSize
|
|
221
|
-
def env_cmd(cmd)
|
|
222
|
-
return if cmd.nil?
|
|
223
|
-
|
|
224
|
-
env = "env"
|
|
225
|
-
http_proxy = config[:http_proxy] || ENV["http_proxy"] ||
|
|
226
|
-
ENV["HTTP_PROXY"]
|
|
227
|
-
https_proxy = config[:https_proxy] || ENV["https_proxy"] ||
|
|
228
|
-
ENV["HTTPS_PROXY"]
|
|
229
|
-
ftp_proxy = config[:ftp_proxy] || ENV["ftp_proxy"] ||
|
|
230
|
-
ENV["FTP_PROXY"]
|
|
231
|
-
no_proxy = if (!config[:http_proxy] && http_proxy) ||
|
|
232
|
-
(!config[:https_proxy] && https_proxy) ||
|
|
233
|
-
(!config[:ftp_proxy] && ftp_proxy)
|
|
234
|
-
ENV["no_proxy"] || ENV["NO_PROXY"]
|
|
235
|
-
end
|
|
236
|
-
env << " http_proxy=#{http_proxy}" if http_proxy
|
|
237
|
-
env << " https_proxy=#{https_proxy}" if https_proxy
|
|
238
|
-
env << " ftp_proxy=#{ftp_proxy}" if ftp_proxy
|
|
239
|
-
env << " no_proxy=#{no_proxy}" if no_proxy
|
|
240
|
-
|
|
241
|
-
env == "env" ? cmd : "#{env} #{cmd}"
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
# Executes a remote command over SSH.
|
|
245
|
-
#
|
|
246
|
-
# @param command [String] remove command to run
|
|
247
|
-
# @param connection [Kitchen::SSH] an SSH connection
|
|
248
|
-
# @raise [ActionFailed] if an exception occurs
|
|
249
|
-
# @api private
|
|
250
|
-
def run_remote(command, connection)
|
|
251
|
-
return if command.nil?
|
|
252
|
-
|
|
253
|
-
connection.exec(env_cmd(command))
|
|
254
|
-
rescue SSHFailed, Net::SSH::Exception => ex
|
|
255
|
-
raise ActionFailed, ex.message
|
|
256
|
-
end
|
|
257
|
-
|
|
258
|
-
# Transfers one or more local paths over SSH.
|
|
259
|
-
#
|
|
260
|
-
# @param locals [Array<String>] array of local paths
|
|
261
|
-
# @param remote [String] remote destination path
|
|
262
|
-
# @param connection [Kitchen::SSH] an SSH connection
|
|
263
|
-
# @raise [ActionFailed] if an exception occurs
|
|
264
|
-
# @api private
|
|
265
|
-
def transfer_path(locals, remote, connection)
|
|
266
|
-
return if locals.nil? || Array(locals).empty?
|
|
267
|
-
|
|
268
|
-
info("Transferring files to #{instance.to_str}")
|
|
269
|
-
debug("TIMING: scp asynch upload (Kitchen::Driver::SSHBase)")
|
|
270
|
-
elapsed = Benchmark.measure do
|
|
271
|
-
transfer_path_async(locals, remote, connection)
|
|
272
|
-
end
|
|
273
|
-
delta = Util.duration(elapsed.real)
|
|
274
|
-
debug("TIMING: scp async upload (Kitchen::Driver::SSHBase) took #{delta}")
|
|
275
|
-
debug("Transfer complete")
|
|
276
|
-
rescue SSHFailed, Net::SSH::Exception => ex
|
|
277
|
-
raise ActionFailed, ex.message
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
def transfer_path_async(locals, remote, connection)
|
|
281
|
-
waits = []
|
|
282
|
-
locals.map do |local|
|
|
283
|
-
waits.push connection.upload_path(local, remote)
|
|
284
|
-
waits.shift.wait while waits.length >= config[:max_ssh_sessions]
|
|
285
|
-
end
|
|
286
|
-
waits.each(&:wait)
|
|
287
|
-
end
|
|
288
|
-
|
|
289
|
-
# Blocks until a TCP socket is available where a remote SSH server
|
|
290
|
-
# should be listening.
|
|
291
|
-
#
|
|
292
|
-
# @param hostname [String] remote SSH server host
|
|
293
|
-
# @param username [String] SSH username (default: `nil`)
|
|
294
|
-
# @param options [Hash] configuration hash (default: `{}`)
|
|
295
|
-
# @api private
|
|
296
|
-
def wait_for_sshd(hostname, username = nil, options = {})
|
|
297
|
-
pseudo_state = { hostname: }
|
|
298
|
-
pseudo_state[:username] = username if username
|
|
299
|
-
pseudo_state.merge!(options)
|
|
300
|
-
|
|
301
|
-
instance.transport.connection(**backcompat_merged_state(pseudo_state))
|
|
302
|
-
.wait_until_ready
|
|
303
|
-
end
|
|
304
|
-
|
|
305
|
-
# Intercepts any bare #puts calls in subclasses and issues an INFO log
|
|
306
|
-
# event instead.
|
|
307
|
-
#
|
|
308
|
-
# @param msg [String] message string
|
|
309
|
-
def puts(msg)
|
|
310
|
-
info(msg)
|
|
311
|
-
end
|
|
312
|
-
|
|
313
|
-
# Intercepts any bare #print calls in subclasses and issues an INFO log
|
|
314
|
-
# event instead.
|
|
315
|
-
#
|
|
316
|
-
# @param msg [String] message string
|
|
317
|
-
def print(msg)
|
|
318
|
-
info(msg)
|
|
319
|
-
end
|
|
320
|
-
|
|
321
|
-
# Delegates to Kitchen::ShellOut.run_command, overriding some default
|
|
322
|
-
# options:
|
|
323
|
-
#
|
|
324
|
-
# * `:use_sudo` defaults to the value of `config[:use_sudo]` in the
|
|
325
|
-
# Driver object
|
|
326
|
-
# * `:log_subject` defaults to a String representation of the Driver's
|
|
327
|
-
# class name
|
|
328
|
-
#
|
|
329
|
-
# @see ShellOut#run_command
|
|
330
|
-
def run_command(cmd, options = {})
|
|
331
|
-
base_options = {
|
|
332
|
-
use_sudo: config[:use_sudo],
|
|
333
|
-
log_subject: Thor::Util.snake_case(self.class.to_s),
|
|
334
|
-
}.merge(options)
|
|
335
|
-
super(cmd, base_options)
|
|
336
|
-
end
|
|
337
|
-
|
|
338
|
-
# Returns the Busser object associated with the driver.
|
|
339
|
-
#
|
|
340
|
-
# @return [Busser] a busser
|
|
341
|
-
def busser
|
|
342
|
-
instance.verifier
|
|
343
|
-
end
|
|
344
|
-
end
|
|
345
|
-
end
|
|
346
|
-
end
|
|
@@ -1,116 +0,0 @@
|
|
|
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
|
-
# https://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 "../../errors"
|
|
19
|
-
require_relative "../../logging"
|
|
20
|
-
|
|
21
|
-
module Kitchen
|
|
22
|
-
module Provisioner
|
|
23
|
-
module Chef
|
|
24
|
-
# Chef cookbook resolver that uses Berkshelf and a Berksfile to calculate
|
|
25
|
-
# dependencies.
|
|
26
|
-
#
|
|
27
|
-
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
28
|
-
class Berkshelf
|
|
29
|
-
include Logging
|
|
30
|
-
|
|
31
|
-
# Creates a new cookbook resolver.
|
|
32
|
-
#
|
|
33
|
-
# @param berksfile [String] path to a Berksfile
|
|
34
|
-
# @param path [String] path in which to vendor the resulting
|
|
35
|
-
# cookbooks
|
|
36
|
-
# @param logger [Kitchen::Logger] a logger to use for output, defaults
|
|
37
|
-
# to `Kitchen.logger`
|
|
38
|
-
def initialize(berksfile, path, logger: Kitchen.logger, always_update: false)
|
|
39
|
-
@berksfile = berksfile
|
|
40
|
-
@path = path
|
|
41
|
-
@logger = logger
|
|
42
|
-
@always_update = always_update
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Loads the library code required to use the resolver.
|
|
46
|
-
#
|
|
47
|
-
# @param logger [Kitchen::Logger] a logger to use for output, defaults
|
|
48
|
-
# to `Kitchen.logger`
|
|
49
|
-
def self.load!(logger: Kitchen.logger)
|
|
50
|
-
load_berkshelf!(logger)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
# Performs the cookbook resolution and vendors the resulting cookbooks
|
|
54
|
-
# in the desired path.
|
|
55
|
-
def resolve
|
|
56
|
-
version = ::Berkshelf::VERSION
|
|
57
|
-
info("Resolving cookbook dependencies with Berkshelf #{version}...")
|
|
58
|
-
debug("Using Berksfile from #{berksfile}")
|
|
59
|
-
|
|
60
|
-
::Berkshelf.ui.mute do
|
|
61
|
-
berksfile_obj = ::Berkshelf::Berksfile.from_file(berksfile)
|
|
62
|
-
berksfile_obj.update if always_update && berksfile_obj.lockfile.present?
|
|
63
|
-
# Berkshelf requires the directory to not exist
|
|
64
|
-
FileUtils.rm_rf(path)
|
|
65
|
-
berksfile_obj.vendor(path)
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
private
|
|
70
|
-
|
|
71
|
-
# @return [String] path to a Berksfile
|
|
72
|
-
# @api private
|
|
73
|
-
attr_reader :berksfile
|
|
74
|
-
|
|
75
|
-
# @return [String] path in which to vendor the resulting cookbooks
|
|
76
|
-
# @api private
|
|
77
|
-
attr_reader :path
|
|
78
|
-
|
|
79
|
-
# @return [Kitchen::Logger] a logger to use for output
|
|
80
|
-
# @api private
|
|
81
|
-
attr_reader :logger
|
|
82
|
-
|
|
83
|
-
# @return [Boolean] If true, always update cookbooks in Berkshelf.
|
|
84
|
-
# @api private
|
|
85
|
-
attr_reader :always_update
|
|
86
|
-
|
|
87
|
-
class << self
|
|
88
|
-
private
|
|
89
|
-
|
|
90
|
-
# Load the Berkshelf-specific library code.
|
|
91
|
-
#
|
|
92
|
-
# @param logger [Kitchen::Logger] the logger to use
|
|
93
|
-
# @raise [UserError] if the library couldn't be loaded
|
|
94
|
-
# @api private
|
|
95
|
-
def load_berkshelf!(logger)
|
|
96
|
-
first_load = require "berkshelf"
|
|
97
|
-
|
|
98
|
-
version = ::Berkshelf::VERSION
|
|
99
|
-
if first_load
|
|
100
|
-
logger.debug("Berkshelf #{version} library loaded")
|
|
101
|
-
else
|
|
102
|
-
logger.debug("Berkshelf #{version} previously loaded")
|
|
103
|
-
end
|
|
104
|
-
rescue LoadError => e
|
|
105
|
-
logger.fatal("The `berkshelf' gem is missing and must be installed" \
|
|
106
|
-
" or cannot be properly activated. Run" \
|
|
107
|
-
" `gem install berkshelf` or add the following to your" \
|
|
108
|
-
" Gemfile if you are using Bundler: `gem 'berkshelf'`.")
|
|
109
|
-
raise UserError,
|
|
110
|
-
"Could not load or activate Berkshelf (#{e.message})"
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
end
|