test-kitchen 3.9.1 → 4.1.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 +8 -5
- data/lib/kitchen/cli.rb +33 -8
- data/lib/kitchen/collection.rb +1 -1
- data/lib/kitchen/command/list.rb +49 -9
- data/lib/kitchen/command/logs.rb +185 -0
- data/lib/kitchen/command/test.rb +2 -1
- data/lib/kitchen/command.rb +22 -9
- data/lib/kitchen/config.rb +8 -0
- data/lib/kitchen/configurable.rb +4 -4
- data/lib/kitchen/data_munger.rb +54 -21
- data/lib/kitchen/driver/base.rb +19 -0
- data/lib/kitchen/driver/dummy.rb +27 -0
- data/lib/kitchen/driver/proxy.rb +11 -6
- data/lib/kitchen/errors.rb +1 -0
- data/lib/kitchen/generator/init.rb +1 -1
- data/lib/kitchen/instance.rb +248 -182
- data/lib/kitchen/lazy_hash.rb +1 -1
- data/lib/kitchen/lifecycle_hook/remote.rb +5 -2
- data/lib/kitchen/logger.rb +407 -74
- data/lib/kitchen/logging.rb +2 -2
- data/lib/kitchen/metadata_chopper.rb +1 -1
- data/lib/kitchen/provisioner/base.rb +27 -35
- data/lib/kitchen/provisioner/external.rb +420 -0
- data/lib/kitchen/provisioner.rb +1 -2
- data/lib/kitchen/shell_out.rb +1 -1
- data/lib/kitchen/state_file.rb +12 -2
- data/lib/kitchen/transport/base.rb +1 -1
- data/lib/kitchen/transport/ssh.rb +5 -5
- data/lib/kitchen/transport/winrm.rb +8 -8
- data/lib/kitchen/util.rb +1 -1
- data/lib/kitchen/verifier/base.rb +17 -5
- data/lib/kitchen/version.rb +1 -1
- data/lib/kitchen.rb +21 -4
- data/lib/vendor/hash_recursive_merge.rb +2 -2
- data/templates/driver/driver.rb.erb +1 -1
- data/test-kitchen.gemspec +5 -7
- metadata +36 -41
- 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
data/lib/kitchen.rb
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
|
|
18
18
|
require "pathname" unless defined?(Pathname)
|
|
19
|
+
require "securerandom" unless defined?(SecureRandom)
|
|
19
20
|
require_relative "kitchen/errors"
|
|
20
21
|
require_relative "kitchen/logger"
|
|
21
22
|
require_relative "kitchen/logging"
|
|
@@ -31,7 +32,6 @@ require_relative "kitchen/config"
|
|
|
31
32
|
require_relative "kitchen/data_munger"
|
|
32
33
|
require_relative "kitchen/driver"
|
|
33
34
|
require_relative "kitchen/driver/base"
|
|
34
|
-
require_relative "kitchen/driver/ssh_base"
|
|
35
35
|
require_relative "kitchen/driver/proxy"
|
|
36
36
|
require_relative "kitchen/instance"
|
|
37
37
|
require_relative "kitchen/lifecycle_hooks"
|
|
@@ -41,7 +41,6 @@ require_relative "kitchen/loader/yaml"
|
|
|
41
41
|
require_relative "kitchen/metadata_chopper"
|
|
42
42
|
require_relative "kitchen/platform"
|
|
43
43
|
require_relative "kitchen/state_file"
|
|
44
|
-
require_relative "kitchen/ssh"
|
|
45
44
|
require_relative "kitchen/suite"
|
|
46
45
|
require_relative "kitchen/verifier"
|
|
47
46
|
require_relative "kitchen/verifier/base"
|
|
@@ -61,6 +60,9 @@ module Kitchen
|
|
|
61
60
|
# @return [Mutex] a mutex used for Dir.chdir coordination
|
|
62
61
|
attr_accessor :mutex_chdir
|
|
63
62
|
|
|
63
|
+
# @return [String] identifier for the current Kitchen process invocation
|
|
64
|
+
attr_writer :run_id
|
|
65
|
+
|
|
64
66
|
# Returns the root path of the Kitchen gem source code.
|
|
65
67
|
#
|
|
66
68
|
# @return [Pathname] root path of gem
|
|
@@ -72,7 +74,11 @@ module Kitchen
|
|
|
72
74
|
#
|
|
73
75
|
# @return [Logger] a logger
|
|
74
76
|
def default_logger
|
|
75
|
-
Logger.new(
|
|
77
|
+
Logger.new(
|
|
78
|
+
stdout: $stdout,
|
|
79
|
+
level: Util.to_logger_level(env_log),
|
|
80
|
+
metadata: { kitchen_run_id: run_id }
|
|
81
|
+
)
|
|
76
82
|
end
|
|
77
83
|
|
|
78
84
|
# Returns a default file logger which emits on standard output and to a
|
|
@@ -86,15 +92,26 @@ module Kitchen
|
|
|
86
92
|
log_overwrite = log_overwrite.nil? ? env_log_overwrite : log_overwrite
|
|
87
93
|
log_location = File.expand_path(File.join(DEFAULT_LOG_DIR, "kitchen.log"))
|
|
88
94
|
log_location = log_location.to_s
|
|
95
|
+
structured_log_location = File.expand_path(File.join(DEFAULT_LOG_DIR, "kitchen.ndjson"))
|
|
96
|
+
structured_log_location = structured_log_location.to_s
|
|
89
97
|
|
|
90
98
|
Logger.new(
|
|
91
99
|
stdout: $stdout,
|
|
92
100
|
logdev: log_location,
|
|
101
|
+
structured_logdev: structured_log_location,
|
|
93
102
|
level: Util.to_logger_level(level),
|
|
94
|
-
log_overwrite
|
|
103
|
+
log_overwrite:,
|
|
104
|
+
metadata: { kitchen_run_id: run_id }
|
|
95
105
|
)
|
|
96
106
|
end
|
|
97
107
|
|
|
108
|
+
# Returns the current Kitchen run identifier.
|
|
109
|
+
#
|
|
110
|
+
# @return [String] identifier for the current Kitchen process invocation
|
|
111
|
+
def run_id
|
|
112
|
+
@run_id ||= SecureRandom.uuid
|
|
113
|
+
end
|
|
114
|
+
|
|
98
115
|
# Returns whether or not standard output is associated with a terminal
|
|
99
116
|
# device (tty).
|
|
100
117
|
#
|
|
@@ -48,8 +48,8 @@ module HashRecursiveMerge
|
|
|
48
48
|
# When both +hsh+ and +other_hash+ contains an entry with the same key,
|
|
49
49
|
# it merges and returns the values from both arrays.
|
|
50
50
|
#
|
|
51
|
-
# Compared with Hash#merge, this method provides a different
|
|
52
|
-
# for merging
|
|
51
|
+
# Compared with Hash#merge, this method provides a different approach
|
|
52
|
+
# for merging nested hashes.
|
|
53
53
|
# If the value of a given key is an Hash and both +other_hash+ abd +hsh
|
|
54
54
|
# includes the same key, the value is merged instead replaced with
|
|
55
55
|
# +other_hash+ value.
|
|
@@ -11,7 +11,7 @@ module Kitchen
|
|
|
11
11
|
# <%= config[:klass_name] %> driver for Kitchen.
|
|
12
12
|
#
|
|
13
13
|
# @author <%= config[:author] %> <<%= config[:email] %>>
|
|
14
|
-
class <%= config[:klass_name] %> < Kitchen::Driver::
|
|
14
|
+
class <%= config[:klass_name] %> < Kitchen::Driver::Base
|
|
15
15
|
|
|
16
16
|
def create(state)
|
|
17
17
|
end
|
data/test-kitchen.gemspec
CHANGED
|
@@ -27,7 +27,7 @@ Gem::Specification.new do |gem|
|
|
|
27
27
|
gem.add_dependency "csv", "~> 3.3"
|
|
28
28
|
gem.add_dependency "ed25519", "~> 1.3" # ed25519 ssh key support
|
|
29
29
|
gem.add_dependency "irb", "~> 1.15"
|
|
30
|
-
gem.add_dependency "mixlib-install", "
|
|
30
|
+
gem.add_dependency "mixlib-install", ">= 3.6", "< 5.0" # allow Cinc's mixlib-install 4.x fork
|
|
31
31
|
gem.add_dependency "mixlib-shellout", ">= 1.2", "< 4.0"
|
|
32
32
|
gem.add_dependency "net-scp", ">= 1.1", "< 5.0" # pinning until we can confirm 4+ works
|
|
33
33
|
gem.add_dependency "net-ssh", ">= 2.9", "< 8.0" # pinning until we can confirm 8+ works
|
|
@@ -35,10 +35,8 @@ Gem::Specification.new do |gem|
|
|
|
35
35
|
gem.add_dependency "ostruct", "~> 0.6"
|
|
36
36
|
gem.add_dependency "syslog", "~> 0.3"
|
|
37
37
|
gem.add_dependency "thor", ">= 0.19", "< 2.0"
|
|
38
|
-
|
|
39
|
-
gem.add_dependency "winrm
|
|
40
|
-
gem.add_dependency "winrm-
|
|
41
|
-
|
|
42
|
-
# TK is not under Chef EULA
|
|
43
|
-
gem.add_dependency "license-acceptance", ">= 1.0.11", "< 3.0" # pinning until we can confirm 3+ works
|
|
38
|
+
# Chef Forked versions with additional fixes since no one is maintining them upstream
|
|
39
|
+
gem.add_dependency "chef-winrm", ">= 2.5.0", "< 3.0"
|
|
40
|
+
gem.add_dependency "chef-winrm-elevated", ">= 1.0", "< 2.0"
|
|
41
|
+
gem.add_dependency "chef-winrm-fs", ">= 1.0", "< 2.0"
|
|
44
42
|
end
|
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.1.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-07-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bcrypt_pbkdf
|
|
@@ -84,16 +84,22 @@ dependencies:
|
|
|
84
84
|
name: mixlib-install
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
|
-
- - "
|
|
87
|
+
- - ">="
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
89
|
version: '3.6'
|
|
90
|
+
- - "<"
|
|
91
|
+
- !ruby/object:Gem::Version
|
|
92
|
+
version: '5.0'
|
|
90
93
|
type: :runtime
|
|
91
94
|
prerelease: false
|
|
92
95
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
96
|
requirements:
|
|
94
|
-
- - "
|
|
97
|
+
- - ">="
|
|
95
98
|
- !ruby/object:Gem::Version
|
|
96
99
|
version: '3.6'
|
|
100
|
+
- - "<"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '5.0'
|
|
97
103
|
- !ruby/object:Gem::Dependency
|
|
98
104
|
name: mixlib-shellout
|
|
99
105
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -223,67 +229,65 @@ dependencies:
|
|
|
223
229
|
- !ruby/object:Gem::Version
|
|
224
230
|
version: '2.0'
|
|
225
231
|
- !ruby/object:Gem::Dependency
|
|
226
|
-
name: winrm
|
|
232
|
+
name: chef-winrm
|
|
227
233
|
requirement: !ruby/object:Gem::Requirement
|
|
228
234
|
requirements:
|
|
229
|
-
- - "
|
|
235
|
+
- - ">="
|
|
230
236
|
- !ruby/object:Gem::Version
|
|
231
|
-
version:
|
|
237
|
+
version: 2.5.0
|
|
238
|
+
- - "<"
|
|
239
|
+
- !ruby/object:Gem::Version
|
|
240
|
+
version: '3.0'
|
|
232
241
|
type: :runtime
|
|
233
242
|
prerelease: false
|
|
234
243
|
version_requirements: !ruby/object:Gem::Requirement
|
|
235
244
|
requirements:
|
|
236
|
-
- - "
|
|
245
|
+
- - ">="
|
|
237
246
|
- !ruby/object:Gem::Version
|
|
238
|
-
version:
|
|
247
|
+
version: 2.5.0
|
|
248
|
+
- - "<"
|
|
249
|
+
- !ruby/object:Gem::Version
|
|
250
|
+
version: '3.0'
|
|
239
251
|
- !ruby/object:Gem::Dependency
|
|
240
|
-
name: winrm-elevated
|
|
252
|
+
name: chef-winrm-elevated
|
|
241
253
|
requirement: !ruby/object:Gem::Requirement
|
|
242
254
|
requirements:
|
|
243
|
-
- - "
|
|
255
|
+
- - ">="
|
|
244
256
|
- !ruby/object:Gem::Version
|
|
245
257
|
version: '1.0'
|
|
258
|
+
- - "<"
|
|
259
|
+
- !ruby/object:Gem::Version
|
|
260
|
+
version: '2.0'
|
|
246
261
|
type: :runtime
|
|
247
262
|
prerelease: false
|
|
248
263
|
version_requirements: !ruby/object:Gem::Requirement
|
|
249
264
|
requirements:
|
|
250
|
-
- - "
|
|
265
|
+
- - ">="
|
|
251
266
|
- !ruby/object:Gem::Version
|
|
252
267
|
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
|
-
- - "~>"
|
|
268
|
+
- - "<"
|
|
265
269
|
- !ruby/object:Gem::Version
|
|
266
|
-
version: '
|
|
270
|
+
version: '2.0'
|
|
267
271
|
- !ruby/object:Gem::Dependency
|
|
268
|
-
name:
|
|
272
|
+
name: chef-winrm-fs
|
|
269
273
|
requirement: !ruby/object:Gem::Requirement
|
|
270
274
|
requirements:
|
|
271
275
|
- - ">="
|
|
272
276
|
- !ruby/object:Gem::Version
|
|
273
|
-
version: 1.0
|
|
277
|
+
version: '1.0'
|
|
274
278
|
- - "<"
|
|
275
279
|
- !ruby/object:Gem::Version
|
|
276
|
-
version: '
|
|
280
|
+
version: '2.0'
|
|
277
281
|
type: :runtime
|
|
278
282
|
prerelease: false
|
|
279
283
|
version_requirements: !ruby/object:Gem::Requirement
|
|
280
284
|
requirements:
|
|
281
285
|
- - ">="
|
|
282
286
|
- !ruby/object:Gem::Version
|
|
283
|
-
version: 1.0
|
|
287
|
+
version: '1.0'
|
|
284
288
|
- - "<"
|
|
285
289
|
- !ruby/object:Gem::Version
|
|
286
|
-
version: '
|
|
290
|
+
version: '2.0'
|
|
287
291
|
description: Test Kitchen is an integration tool for developing and testing infrastructure
|
|
288
292
|
code and software on isolated target platforms.
|
|
289
293
|
email:
|
|
@@ -311,6 +315,7 @@ files:
|
|
|
311
315
|
- lib/kitchen/command/exec.rb
|
|
312
316
|
- lib/kitchen/command/list.rb
|
|
313
317
|
- lib/kitchen/command/login.rb
|
|
318
|
+
- lib/kitchen/command/logs.rb
|
|
314
319
|
- lib/kitchen/command/package.rb
|
|
315
320
|
- lib/kitchen/command/sink.rb
|
|
316
321
|
- lib/kitchen/command/test.rb
|
|
@@ -323,7 +328,6 @@ files:
|
|
|
323
328
|
- lib/kitchen/driver/dummy.rb
|
|
324
329
|
- lib/kitchen/driver/exec.rb
|
|
325
330
|
- lib/kitchen/driver/proxy.rb
|
|
326
|
-
- lib/kitchen/driver/ssh_base.rb
|
|
327
331
|
- lib/kitchen/errors.rb
|
|
328
332
|
- lib/kitchen/generator/init.rb
|
|
329
333
|
- lib/kitchen/instance.rb
|
|
@@ -343,20 +347,11 @@ files:
|
|
|
343
347
|
- lib/kitchen/plugin_base.rb
|
|
344
348
|
- lib/kitchen/provisioner.rb
|
|
345
349
|
- 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
350
|
- lib/kitchen/provisioner/dummy.rb
|
|
351
|
+
- lib/kitchen/provisioner/external.rb
|
|
356
352
|
- lib/kitchen/provisioner/shell.rb
|
|
357
353
|
- lib/kitchen/rake_tasks.rb
|
|
358
354
|
- lib/kitchen/shell_out.rb
|
|
359
|
-
- lib/kitchen/ssh.rb
|
|
360
355
|
- lib/kitchen/state_file.rb
|
|
361
356
|
- lib/kitchen/suite.rb
|
|
362
357
|
- 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
|