test-kitchen 1.14.1 → 1.14.2
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/Berksfile +1 -1
- data/CHANGELOG.md +7 -0
- data/Gemfile +1 -1
- data/Guardfile +5 -5
- data/Rakefile +5 -5
- data/bin/kitchen +1 -1
- data/features/step_definitions/gem_steps.rb +6 -6
- data/features/support/env.rb +6 -7
- data/lib/kitchen.rb +5 -7
- data/lib/kitchen/base64_stream.rb +2 -8
- data/lib/kitchen/cli.rb +76 -80
- data/lib/kitchen/collection.rb +0 -2
- data/lib/kitchen/color.rb +7 -9
- data/lib/kitchen/command.rb +0 -4
- data/lib/kitchen/command/action.rb +0 -3
- data/lib/kitchen/command/console.rb +4 -7
- data/lib/kitchen/command/diagnose.rb +7 -14
- data/lib/kitchen/command/driver_discover.rb +1 -4
- data/lib/kitchen/command/exec.rb +0 -3
- data/lib/kitchen/command/list.rb +9 -12
- data/lib/kitchen/command/login.rb +0 -3
- data/lib/kitchen/command/package.rb +0 -3
- data/lib/kitchen/command/sink.rb +6 -9
- data/lib/kitchen/command/test.rb +1 -4
- data/lib/kitchen/config.rb +25 -27
- data/lib/kitchen/configurable.rb +26 -31
- data/lib/kitchen/data_munger.rb +34 -36
- data/lib/kitchen/diagnostic.rb +5 -7
- data/lib/kitchen/driver.rb +3 -5
- data/lib/kitchen/driver/base.rb +0 -3
- data/lib/kitchen/driver/dummy.rb +0 -3
- data/lib/kitchen/driver/proxy.rb +0 -3
- data/lib/kitchen/driver/ssh_base.rb +13 -16
- data/lib/kitchen/errors.rb +11 -16
- data/lib/kitchen/generator/driver_create.rb +18 -21
- data/lib/kitchen/generator/init.rb +21 -26
- data/lib/kitchen/instance.rb +19 -23
- data/lib/kitchen/lazy_hash.rb +1 -2
- data/lib/kitchen/loader/yaml.rb +22 -25
- data/lib/kitchen/logger.rb +9 -14
- data/lib/kitchen/logging.rb +0 -3
- data/lib/kitchen/login_command.rb +0 -2
- data/lib/kitchen/metadata_chopper.rb +0 -2
- data/lib/kitchen/platform.rb +1 -3
- data/lib/kitchen/provisioner.rb +3 -5
- data/lib/kitchen/provisioner/base.rb +2 -5
- data/lib/kitchen/provisioner/chef/berkshelf.rb +1 -5
- data/lib/kitchen/provisioner/chef/common_sandbox.rb +24 -29
- data/lib/kitchen/provisioner/chef/librarian.rb +2 -6
- data/lib/kitchen/provisioner/chef/policyfile.rb +4 -8
- data/lib/kitchen/provisioner/chef_apply.rb +14 -17
- data/lib/kitchen/provisioner/chef_base.rb +43 -46
- data/lib/kitchen/provisioner/chef_solo.rb +10 -13
- data/lib/kitchen/provisioner/chef_zero.rb +22 -29
- data/lib/kitchen/provisioner/dummy.rb +0 -3
- data/lib/kitchen/provisioner/shell.rb +6 -9
- data/lib/kitchen/rake_tasks.rb +4 -6
- data/lib/kitchen/shell_out.rb +3 -5
- data/lib/kitchen/ssh.rb +16 -22
- data/lib/kitchen/state_file.rb +3 -5
- data/lib/kitchen/suite.rb +0 -2
- data/lib/kitchen/thor_tasks.rb +2 -4
- data/lib/kitchen/transport.rb +3 -5
- data/lib/kitchen/transport/base.rb +1 -7
- data/lib/kitchen/transport/dummy.rb +0 -4
- data/lib/kitchen/transport/ssh.rb +41 -47
- data/lib/kitchen/transport/winrm.rb +41 -40
- data/lib/kitchen/util.rb +1 -3
- data/lib/kitchen/verifier.rb +3 -5
- data/lib/kitchen/verifier/base.rb +2 -5
- data/lib/kitchen/verifier/busser.rb +24 -24
- data/lib/kitchen/verifier/dummy.rb +0 -3
- data/lib/kitchen/verifier/shell.rb +1 -3
- data/lib/kitchen/version.rb +1 -1
- data/lib/vendor/hash_recursive_merge.rb +0 -2
- data/spec/kitchen/base64_stream_spec.rb +3 -6
- data/spec/kitchen/cli_spec.rb +0 -2
- data/spec/kitchen/collection_spec.rb +4 -8
- data/spec/kitchen/color_spec.rb +0 -3
- data/spec/kitchen/config_spec.rb +91 -106
- data/spec/kitchen/configurable_spec.rb +44 -76
- data/spec/kitchen/data_munger_spec.rb +1178 -1247
- data/spec/kitchen/diagnostic_spec.rb +37 -38
- data/spec/kitchen/driver/base_spec.rb +7 -14
- data/spec/kitchen/driver/dummy_spec.rb +1 -7
- data/spec/kitchen/driver/proxy_spec.rb +2 -7
- data/spec/kitchen/driver/ssh_base_spec.rb +128 -149
- data/spec/kitchen/driver_spec.rb +7 -13
- data/spec/kitchen/errors_spec.rb +50 -60
- data/spec/kitchen/instance_spec.rb +217 -294
- data/spec/kitchen/lazy_hash_spec.rb +14 -18
- data/spec/kitchen/loader/yaml_spec.rb +201 -227
- data/spec/kitchen/logger_spec.rb +7 -15
- data/spec/kitchen/logging_spec.rb +1 -4
- data/spec/kitchen/login_command_spec.rb +3 -4
- data/spec/kitchen/metadata_chopper_spec.rb +0 -3
- data/spec/kitchen/platform_spec.rb +31 -32
- data/spec/kitchen/provisioner/base_spec.rb +22 -41
- data/spec/kitchen/provisioner/chef/policyfile_spec.rb +15 -15
- data/spec/kitchen/provisioner/chef_apply_spec.rb +8 -13
- data/spec/kitchen/provisioner/chef_base_spec.rb +150 -182
- data/spec/kitchen/provisioner/chef_solo_spec.rb +58 -72
- data/spec/kitchen/provisioner/chef_zero_spec.rb +99 -125
- data/spec/kitchen/provisioner/dummy_spec.rb +8 -11
- data/spec/kitchen/provisioner/shell_spec.rb +86 -103
- data/spec/kitchen/provisioner_spec.rb +5 -11
- data/spec/kitchen/shell_out_spec.rb +15 -19
- data/spec/kitchen/ssh_spec.rb +16 -35
- data/spec/kitchen/state_file_spec.rb +6 -11
- data/spec/kitchen/suite_spec.rb +5 -6
- data/spec/kitchen/transport/base_spec.rb +6 -14
- data/spec/kitchen/transport/ssh_spec.rb +39 -64
- data/spec/kitchen/transport/winrm_spec.rb +99 -127
- data/spec/kitchen/transport_spec.rb +7 -13
- data/spec/kitchen/util_spec.rb +17 -26
- data/spec/kitchen/verifier/base_spec.rb +24 -40
- data/spec/kitchen/verifier/busser_spec.rb +38 -68
- data/spec/kitchen/verifier/dummy_spec.rb +8 -11
- data/spec/kitchen/verifier/shell_spec.rb +14 -17
- data/spec/kitchen/verifier_spec.rb +7 -13
- data/spec/kitchen_spec.rb +4 -6
- data/spec/spec_helper.rb +1 -1
- data/spec/support/powershell_max_size_spec.rb +1 -2
- data/support/chef-client-zero.rb +3 -4
- data/test-kitchen.gemspec +4 -6
- metadata +9 -9
|
@@ -19,9 +19,7 @@
|
|
|
19
19
|
require "kitchen"
|
|
20
20
|
|
|
21
21
|
module Kitchen
|
|
22
|
-
|
|
23
22
|
module Provisioner
|
|
24
|
-
|
|
25
23
|
# Dummy provisioner for Kitchen. This driver does nothing but report what
|
|
26
24
|
# would happen if this provisioner did anything of consequence. As a result
|
|
27
25
|
# it may be a useful provisioner to use when debugging or developing new
|
|
@@ -29,7 +27,6 @@ module Kitchen
|
|
|
29
27
|
#
|
|
30
28
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
31
29
|
class Dummy < Kitchen::Provisioner::Base
|
|
32
|
-
|
|
33
30
|
kitchen_provisioner_api_version 2
|
|
34
31
|
|
|
35
32
|
plugin_version Kitchen::VERSION
|
|
@@ -20,21 +20,18 @@ require "kitchen/provisioner/base"
|
|
|
20
20
|
require "kitchen/version"
|
|
21
21
|
|
|
22
22
|
module Kitchen
|
|
23
|
-
|
|
24
23
|
module Provisioner
|
|
25
|
-
|
|
26
24
|
# Basic shell provisioner.
|
|
27
25
|
#
|
|
28
26
|
# @author Chris Lundquist (<chris.ludnquist@github.com>)
|
|
29
27
|
class Shell < Base
|
|
30
|
-
|
|
31
28
|
kitchen_provisioner_api_version 2
|
|
32
29
|
|
|
33
30
|
plugin_version Kitchen::VERSION
|
|
34
31
|
|
|
35
32
|
default_config :script do |provisioner|
|
|
36
33
|
src = provisioner.powershell_shell? ? "bootstrap.ps1" : "bootstrap.sh"
|
|
37
|
-
provisioner.calculate_path(src, :
|
|
34
|
+
provisioner.calculate_path(src, type: :file)
|
|
38
35
|
end
|
|
39
36
|
expand_path_for :script
|
|
40
37
|
|
|
@@ -56,7 +53,7 @@ module Kitchen
|
|
|
56
53
|
data = remote_path_join(root, "data")
|
|
57
54
|
|
|
58
55
|
code = if powershell_shell?
|
|
59
|
-
|
|
56
|
+
Util.outdent!(<<-POWERSHELL)
|
|
60
57
|
if (Test-Path "#{data}") {
|
|
61
58
|
Remove-Item "#{data}" -Recurse -Force
|
|
62
59
|
}
|
|
@@ -64,9 +61,9 @@ module Kitchen
|
|
|
64
61
|
New-Item "#{root}" -ItemType directory | Out-Null
|
|
65
62
|
}
|
|
66
63
|
POWERSHELL
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
64
|
+
else
|
|
65
|
+
"#{sudo('rm')} -rf #{data} ; mkdir -p #{root}"
|
|
66
|
+
end
|
|
70
67
|
|
|
71
68
|
wrap_shell_code(code)
|
|
72
69
|
end
|
|
@@ -114,7 +111,7 @@ module Kitchen
|
|
|
114
111
|
end
|
|
115
112
|
|
|
116
113
|
FileUtils.chmod(0755,
|
|
117
|
-
|
|
114
|
+
File.join(sandbox_path, File.basename(config[:script])))
|
|
118
115
|
end
|
|
119
116
|
|
|
120
117
|
# Creates a minimal, no-op script in the sandbox path.
|
data/lib/kitchen/rake_tasks.rb
CHANGED
|
@@ -21,23 +21,21 @@ require "rake/tasklib"
|
|
|
21
21
|
require "kitchen"
|
|
22
22
|
|
|
23
23
|
module Kitchen
|
|
24
|
-
|
|
25
24
|
# Kitchen Rake task generator.
|
|
26
25
|
#
|
|
27
26
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
28
27
|
class RakeTasks < ::Rake::TaskLib
|
|
29
|
-
|
|
30
28
|
# Creates Kitchen Rake tasks and allows the callee to configure it.
|
|
31
29
|
#
|
|
32
30
|
# @yield [self] gives itself to the block
|
|
33
31
|
def initialize(cfg = {})
|
|
34
32
|
@loader = Kitchen::Loader::YAML.new(
|
|
35
|
-
:
|
|
36
|
-
:
|
|
37
|
-
:
|
|
33
|
+
project_config: ENV["KITCHEN_YAML"],
|
|
34
|
+
local_config: ENV["KITCHEN_LOCAL_YAML"],
|
|
35
|
+
global_config: ENV["KITCHEN_GLOBAL_YAML"]
|
|
38
36
|
)
|
|
39
37
|
@config = Kitchen::Config.new(
|
|
40
|
-
{ :
|
|
38
|
+
{ loader: @loader }.merge(cfg)
|
|
41
39
|
)
|
|
42
40
|
Kitchen.logger = Kitchen.default_file_logger(nil, false)
|
|
43
41
|
yield self if block_given?
|
data/lib/kitchen/shell_out.rb
CHANGED
|
@@ -19,13 +19,11 @@
|
|
|
19
19
|
require "mixlib/shellout"
|
|
20
20
|
|
|
21
21
|
module Kitchen
|
|
22
|
-
|
|
23
22
|
# Mixin that wraps a command shell out invocation, providing a #run_command
|
|
24
23
|
# method.
|
|
25
24
|
#
|
|
26
25
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
27
26
|
module ShellOut
|
|
28
|
-
|
|
29
27
|
# Wrapped exception for any interally raised shell out commands.
|
|
30
28
|
class ShellCommandFailed < TransientFailure; end
|
|
31
29
|
|
|
@@ -59,9 +57,9 @@ module Kitchen
|
|
|
59
57
|
# @raise [Error] for all other unexpected exceptions
|
|
60
58
|
def run_command(cmd, options = {})
|
|
61
59
|
if options.fetch(:use_sudo, false)
|
|
62
|
-
cmd = "#{options.fetch(:sudo_command,
|
|
60
|
+
cmd = "#{options.fetch(:sudo_command, 'sudo -E')} #{cmd}"
|
|
63
61
|
end
|
|
64
|
-
subject = "[#{options.fetch(:log_subject,
|
|
62
|
+
subject = "[#{options.fetch(:log_subject, 'local')} command]"
|
|
65
63
|
|
|
66
64
|
debug("#{subject} BEGIN (#{cmd})")
|
|
67
65
|
sh = Mixlib::ShellOut.new(cmd, shell_opts(options))
|
|
@@ -87,7 +85,7 @@ module Kitchen
|
|
|
87
85
|
filtered_opts = options.reject do |key, _value|
|
|
88
86
|
[:use_sudo, :sudo_command, :log_subject, :quiet].include?(key)
|
|
89
87
|
end
|
|
90
|
-
{ :
|
|
88
|
+
{ live_stream: logger, timeout: 60_000 }.merge(filtered_opts)
|
|
91
89
|
end
|
|
92
90
|
end
|
|
93
91
|
end
|
data/lib/kitchen/ssh.rb
CHANGED
|
@@ -25,7 +25,6 @@ require "kitchen/errors"
|
|
|
25
25
|
require "kitchen/login_command"
|
|
26
26
|
|
|
27
27
|
module Kitchen
|
|
28
|
-
|
|
29
28
|
# Wrapped exception for any internally raised SSH-related errors.
|
|
30
29
|
#
|
|
31
30
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
@@ -36,7 +35,6 @@ module Kitchen
|
|
|
36
35
|
#
|
|
37
36
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
38
37
|
class SSH
|
|
39
|
-
|
|
40
38
|
# Constructs a new SSH object.
|
|
41
39
|
#
|
|
42
40
|
# @example basic usage
|
|
@@ -94,11 +92,9 @@ module Kitchen
|
|
|
94
92
|
# @see http://net-ssh.github.io/net-scp/classes/Net/SCP.html#method-i-upload
|
|
95
93
|
def upload!(local, remote, options = {}, &progress)
|
|
96
94
|
if progress.nil?
|
|
97
|
-
progress = lambda
|
|
98
|
-
if sent == total
|
|
99
|
-
|
|
100
|
-
end
|
|
101
|
-
}
|
|
95
|
+
progress = lambda do |_ch, name, sent, total|
|
|
96
|
+
logger.debug("Uploaded #{name} (#{total} bytes)") if sent == total
|
|
97
|
+
end
|
|
102
98
|
end
|
|
103
99
|
|
|
104
100
|
session.scp.upload!(local, remote, options, &progress)
|
|
@@ -106,11 +102,11 @@ module Kitchen
|
|
|
106
102
|
|
|
107
103
|
def upload(local, remote, options = {}, &progress)
|
|
108
104
|
if progress.nil?
|
|
109
|
-
progress = lambda
|
|
105
|
+
progress = lambda do |_ch, name, sent, total|
|
|
110
106
|
if sent == total
|
|
111
107
|
logger.debug("Async Uploaded #{name} (#{total} bytes)")
|
|
112
108
|
end
|
|
113
|
-
|
|
109
|
+
end
|
|
114
110
|
end
|
|
115
111
|
|
|
116
112
|
session.scp.upload(local, remote, options, &progress)
|
|
@@ -125,13 +121,13 @@ module Kitchen
|
|
|
125
121
|
# @option options [true,false] :recursive recursive copy (default: `true`)
|
|
126
122
|
# @see http://net-ssh.github.io/net-scp/classes/Net/SCP.html#method-i-upload
|
|
127
123
|
def upload_path!(local, remote, options = {}, &progress)
|
|
128
|
-
options = { :
|
|
124
|
+
options = { recursive: true }.merge(options)
|
|
129
125
|
|
|
130
126
|
upload!(local, remote, options, &progress)
|
|
131
127
|
end
|
|
132
128
|
|
|
133
129
|
def upload_path(local, remote, options = {}, &progress)
|
|
134
|
-
options = { :
|
|
130
|
+
options = { recursive: true }.merge(options)
|
|
135
131
|
upload(local, remote, options, &progress)
|
|
136
132
|
end
|
|
137
133
|
|
|
@@ -155,16 +151,16 @@ module Kitchen
|
|
|
155
151
|
#
|
|
156
152
|
# @return [LoginCommand] the login command
|
|
157
153
|
def login_command
|
|
158
|
-
args = %
|
|
159
|
-
args += %
|
|
160
|
-
args += %
|
|
161
|
-
args += %W
|
|
154
|
+
args = %w{ -o UserKnownHostsFile=/dev/null }
|
|
155
|
+
args += %w{ -o StrictHostKeyChecking=no }
|
|
156
|
+
args += %w{ -o IdentitiesOnly=yes } if options[:keys]
|
|
157
|
+
args += %W{ -o LogLevel=#{logger.debug? ? 'VERBOSE' : 'ERROR'} }
|
|
162
158
|
if options.key?(:forward_agent)
|
|
163
|
-
args += %W
|
|
159
|
+
args += %W{ -o ForwardAgent=#{options[:forward_agent] ? 'yes' : 'no'} }
|
|
164
160
|
end
|
|
165
|
-
Array(options[:keys]).each { |ssh_key| args += %W
|
|
166
|
-
args += %W
|
|
167
|
-
args += %W
|
|
161
|
+
Array(options[:keys]).each { |ssh_key| args += %W{ -i #{ssh_key} } }
|
|
162
|
+
args += %W{ -p #{port} }
|
|
163
|
+
args += %W{ #{username}@#{hostname} }
|
|
168
164
|
|
|
169
165
|
LoginCommand.new("ssh", args)
|
|
170
166
|
end
|
|
@@ -175,7 +171,7 @@ module Kitchen
|
|
|
175
171
|
SOCKET_EXCEPTIONS = [
|
|
176
172
|
SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH,
|
|
177
173
|
Errno::ENETUNREACH, IOError
|
|
178
|
-
]
|
|
174
|
+
].freeze
|
|
179
175
|
|
|
180
176
|
# @return [String] the remote hostname
|
|
181
177
|
# @api private
|
|
@@ -251,11 +247,9 @@ module Kitchen
|
|
|
251
247
|
def exec_with_exit(cmd)
|
|
252
248
|
exit_code = nil
|
|
253
249
|
session.open_channel do |channel|
|
|
254
|
-
|
|
255
250
|
channel.request_pty
|
|
256
251
|
|
|
257
252
|
channel.exec(cmd) do |_ch, _success|
|
|
258
|
-
|
|
259
253
|
channel.on_data do |_ch, data|
|
|
260
254
|
logger << data
|
|
261
255
|
end
|
data/lib/kitchen/state_file.rb
CHANGED
|
@@ -24,7 +24,6 @@ end
|
|
|
24
24
|
require "safe_yaml/load"
|
|
25
25
|
|
|
26
26
|
module Kitchen
|
|
27
|
-
|
|
28
27
|
# Exception class for any exceptions raised when reading and parsing a state
|
|
29
28
|
# file from disk
|
|
30
29
|
class StateFileLoadError < StandardError; end
|
|
@@ -33,7 +32,6 @@ module Kitchen
|
|
|
33
32
|
#
|
|
34
33
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
35
34
|
class StateFile
|
|
36
|
-
|
|
37
35
|
# Constructs an new instance taking the kitchen root and instance name.
|
|
38
36
|
#
|
|
39
37
|
# @param kitchen_root [String] path to the Kitchen project's root directory
|
|
@@ -54,7 +52,7 @@ module Kitchen
|
|
|
54
52
|
if File.exist?(file_name) && !File.zero?(file_name)
|
|
55
53
|
Util.symbolized_hash(deserialize_string(read_file))
|
|
56
54
|
else
|
|
57
|
-
|
|
55
|
+
{}
|
|
58
56
|
end
|
|
59
57
|
end
|
|
60
58
|
|
|
@@ -65,7 +63,7 @@ module Kitchen
|
|
|
65
63
|
dir = File.dirname(file_name)
|
|
66
64
|
serialized_string = serialize_hash(Util.stringified_hash(state))
|
|
67
65
|
|
|
68
|
-
FileUtils.mkdir_p(dir)
|
|
66
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
|
69
67
|
File.open(file_name, "wb") { |f| f.write(serialized_string) }
|
|
70
68
|
end
|
|
71
69
|
|
|
@@ -79,7 +77,7 @@ module Kitchen
|
|
|
79
77
|
# @return [Hash] a diagnostic hash
|
|
80
78
|
def diagnose
|
|
81
79
|
raw = read
|
|
82
|
-
result =
|
|
80
|
+
result = {}
|
|
83
81
|
raw.keys.sort.each { |k| result[k] = raw[k] }
|
|
84
82
|
result
|
|
85
83
|
end
|
data/lib/kitchen/suite.rb
CHANGED
|
@@ -17,13 +17,11 @@
|
|
|
17
17
|
# limitations under the License.
|
|
18
18
|
|
|
19
19
|
module Kitchen
|
|
20
|
-
|
|
21
20
|
# A logical configuration representing a test case or fixture that will be
|
|
22
21
|
# executed on a platform.
|
|
23
22
|
#
|
|
24
23
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
25
24
|
class Suite
|
|
26
|
-
|
|
27
25
|
# @return [String] logical name of this suite
|
|
28
26
|
attr_reader :name
|
|
29
27
|
|
data/lib/kitchen/thor_tasks.rb
CHANGED
|
@@ -21,12 +21,10 @@ require "thor"
|
|
|
21
21
|
require "kitchen"
|
|
22
22
|
|
|
23
23
|
module Kitchen
|
|
24
|
-
|
|
25
24
|
# Kitchen Thor task generator.
|
|
26
25
|
#
|
|
27
26
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
28
27
|
class ThorTasks < Thor
|
|
29
|
-
|
|
30
28
|
namespace :kitchen
|
|
31
29
|
|
|
32
30
|
# Creates Kitchen Thor tasks and allows the callee to configure it.
|
|
@@ -52,14 +50,14 @@ module Kitchen
|
|
|
52
50
|
def define
|
|
53
51
|
config.instances.each do |instance|
|
|
54
52
|
self.class.desc instance.name, "Run #{instance.name} test instance"
|
|
55
|
-
self.class.send(:define_method, instance.name.
|
|
53
|
+
self.class.send(:define_method, instance.name.tr("-", "_")) do
|
|
56
54
|
instance.test(:always)
|
|
57
55
|
end
|
|
58
56
|
end
|
|
59
57
|
|
|
60
58
|
self.class.desc "all", "Run all test instances"
|
|
61
59
|
self.class.send(:define_method, :all) do
|
|
62
|
-
config.instances.each { |i| invoke i.name.
|
|
60
|
+
config.instances.each { |i| invoke i.name.tr("-", "_") }
|
|
63
61
|
end
|
|
64
62
|
end
|
|
65
63
|
end
|
data/lib/kitchen/transport.rb
CHANGED
|
@@ -19,14 +19,12 @@
|
|
|
19
19
|
require "thor/util"
|
|
20
20
|
|
|
21
21
|
module Kitchen
|
|
22
|
-
|
|
23
22
|
# A transport is responsible for the communication with an instance,
|
|
24
23
|
# that is remote comands and other actions such as file transfer,
|
|
25
24
|
# login, etc.
|
|
26
25
|
#
|
|
27
26
|
# @author Salim Afiune <salim@afiunemaya.com.mx>
|
|
28
27
|
module Transport
|
|
29
|
-
|
|
30
28
|
# Default transport to use
|
|
31
29
|
DEFAULT_PLUGIN = "ssh".freeze
|
|
32
30
|
|
|
@@ -46,9 +44,9 @@ module Kitchen
|
|
|
46
44
|
object
|
|
47
45
|
rescue LoadError, NameError
|
|
48
46
|
raise ClientError,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
"Could not load the '#{plugin}' transport from the load path." \
|
|
48
|
+
" Please ensure that your transport is installed as a gem or" \
|
|
49
|
+
" included in your Gemfile if using Bundler."
|
|
52
50
|
end
|
|
53
51
|
end
|
|
54
52
|
end
|
|
@@ -22,9 +22,7 @@ require "kitchen/lazy_hash"
|
|
|
22
22
|
require "kitchen/login_command"
|
|
23
23
|
|
|
24
24
|
module Kitchen
|
|
25
|
-
|
|
26
25
|
module Transport
|
|
27
|
-
|
|
28
26
|
# Wrapped exception for any internally raised Transport errors.
|
|
29
27
|
#
|
|
30
28
|
# @author Salim Afiune <salim@afiunemaya.com.mx>
|
|
@@ -42,7 +40,6 @@ module Kitchen
|
|
|
42
40
|
# @author Salim Afiune <salim@afiunemaya.com.mx>
|
|
43
41
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
44
42
|
class Base
|
|
45
|
-
|
|
46
43
|
include Configurable
|
|
47
44
|
include Logging
|
|
48
45
|
|
|
@@ -80,7 +77,6 @@ module Kitchen
|
|
|
80
77
|
#
|
|
81
78
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
82
79
|
class Connection
|
|
83
|
-
|
|
84
80
|
include Logging
|
|
85
81
|
|
|
86
82
|
# Create a new Connection instance.
|
|
@@ -90,9 +86,7 @@ module Kitchen
|
|
|
90
86
|
def initialize(options = {})
|
|
91
87
|
init_options(options)
|
|
92
88
|
|
|
93
|
-
if block_given?
|
|
94
|
-
yield self
|
|
95
|
-
end
|
|
89
|
+
yield self if block_given?
|
|
96
90
|
end
|
|
97
91
|
|
|
98
92
|
# Closes the session connection, if it is still active.
|
|
@@ -19,15 +19,12 @@
|
|
|
19
19
|
require "kitchen"
|
|
20
20
|
|
|
21
21
|
module Kitchen
|
|
22
|
-
|
|
23
22
|
module Transport
|
|
24
|
-
|
|
25
23
|
# Dummy transport for Kitchen. This transport does nothing but report what would
|
|
26
24
|
# happen if this transport did anything of consequence. As a result it may
|
|
27
25
|
# be a useful transport to use when debugging or developing new features or
|
|
28
26
|
# plugins.
|
|
29
27
|
class Dummy < Kitchen::Transport::Base
|
|
30
|
-
|
|
31
28
|
kitchen_transport_api_version 1
|
|
32
29
|
|
|
33
30
|
plugin_version Kitchen::VERSION
|
|
@@ -42,7 +39,6 @@ module Kitchen
|
|
|
42
39
|
|
|
43
40
|
# TODO: comment
|
|
44
41
|
class Connection < Kitchen::Transport::Base::Connection
|
|
45
|
-
|
|
46
42
|
# (see Base#execute)
|
|
47
43
|
def execute(command)
|
|
48
44
|
report(:execute, command)
|
|
@@ -25,9 +25,7 @@ require "timeout"
|
|
|
25
25
|
require "benchmark"
|
|
26
26
|
|
|
27
27
|
module Kitchen
|
|
28
|
-
|
|
29
28
|
module Transport
|
|
30
|
-
|
|
31
29
|
# Wrapped exception for any internally raised SSH-related errors.
|
|
32
30
|
#
|
|
33
31
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
@@ -38,7 +36,6 @@ module Kitchen
|
|
|
38
36
|
#
|
|
39
37
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
40
38
|
class Ssh < Kitchen::Transport::Base
|
|
41
|
-
|
|
42
39
|
kitchen_transport_api_version 1
|
|
43
40
|
|
|
44
41
|
plugin_version Kitchen::VERSION
|
|
@@ -110,7 +107,6 @@ module Kitchen
|
|
|
110
107
|
#
|
|
111
108
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
112
109
|
class Connection < Kitchen::Transport::Base::Connection
|
|
113
|
-
|
|
114
110
|
# (see Base::Connection#close)
|
|
115
111
|
def close
|
|
116
112
|
return if @session.nil?
|
|
@@ -139,21 +135,21 @@ module Kitchen
|
|
|
139
135
|
|
|
140
136
|
# (see Base::Connection#login_command)
|
|
141
137
|
def login_command
|
|
142
|
-
args = %
|
|
143
|
-
args += %
|
|
144
|
-
args += %
|
|
145
|
-
args += %W
|
|
138
|
+
args = %w{ -o UserKnownHostsFile=/dev/null }
|
|
139
|
+
args += %w{ -o StrictHostKeyChecking=no }
|
|
140
|
+
args += %w{ -o IdentitiesOnly=yes } if options[:keys]
|
|
141
|
+
args += %W{ -o LogLevel=#{logger.debug? ? 'VERBOSE' : 'ERROR'} }
|
|
146
142
|
if options.key?(:forward_agent)
|
|
147
|
-
args += %W
|
|
143
|
+
args += %W{ -o ForwardAgent=#{options[:forward_agent] ? 'yes' : 'no'} }
|
|
148
144
|
end
|
|
149
145
|
if ssh_gateway
|
|
150
146
|
gateway_command = "ssh -q #{ssh_gateway_username}@#{ssh_gateway} nc #{hostname} #{port}"
|
|
151
147
|
# Should support other ports than 22 for ssh gateways
|
|
152
|
-
args += %W
|
|
148
|
+
args += %W{ -o ProxyCommand=#{gateway_command} -p 22 }
|
|
153
149
|
end
|
|
154
|
-
Array(options[:keys]).each { |ssh_key| args += %W
|
|
155
|
-
args += %W
|
|
156
|
-
args += %W
|
|
150
|
+
Array(options[:keys]).each { |ssh_key| args += %W{ -i #{ssh_key} } }
|
|
151
|
+
args += %W{ -p #{port} }
|
|
152
|
+
args += %W{ #{username}@#{hostname} }
|
|
157
153
|
|
|
158
154
|
LoginCommand.new("ssh", args)
|
|
159
155
|
end
|
|
@@ -164,7 +160,7 @@ module Kitchen
|
|
|
164
160
|
elapsed = Benchmark.measure do
|
|
165
161
|
waits = []
|
|
166
162
|
Array(locals).map do |local|
|
|
167
|
-
opts = File.directory?(local) ? { :
|
|
163
|
+
opts = File.directory?(local) ? { recursive: true } : {}
|
|
168
164
|
|
|
169
165
|
waits.push session.scp.upload(local, remote, opts) do |_ch, name, sent, total|
|
|
170
166
|
logger.debug("Async Uploaded #{name} (#{total} bytes)") if sent == total
|
|
@@ -183,9 +179,9 @@ module Kitchen
|
|
|
183
179
|
def wait_until_ready
|
|
184
180
|
delay = 3
|
|
185
181
|
session(
|
|
186
|
-
:
|
|
187
|
-
:
|
|
188
|
-
:
|
|
182
|
+
retries: max_wait_until_ready / delay,
|
|
183
|
+
delay: delay,
|
|
184
|
+
message: "Waiting for SSH service on #{hostname}:#{port}, " \
|
|
189
185
|
"retrying in #{delay} seconds"
|
|
190
186
|
)
|
|
191
187
|
execute(PING_COMMAND.dup)
|
|
@@ -258,7 +254,7 @@ module Kitchen
|
|
|
258
254
|
def establish_connection_via_gateway(opts)
|
|
259
255
|
retry_connection(opts) do
|
|
260
256
|
Net::SSH::Gateway.new(ssh_gateway,
|
|
261
|
-
|
|
257
|
+
ssh_gateway_username, options).ssh(hostname, username, options)
|
|
262
258
|
end
|
|
263
259
|
end
|
|
264
260
|
|
|
@@ -298,12 +294,12 @@ module Kitchen
|
|
|
298
294
|
rescue *RESCUE_EXCEPTIONS_ON_ESTABLISH => e
|
|
299
295
|
if (opts[:retries] -= 1) > 0
|
|
300
296
|
message = if opts[:message]
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
297
|
+
logger.debug("[SSH] connection failed (#{e.inspect})")
|
|
298
|
+
opts[:message]
|
|
299
|
+
else
|
|
300
|
+
"[SSH] connection failed, retrying in #{opts[:delay]} seconds " \
|
|
301
|
+
"(#{e.inspect})"
|
|
302
|
+
end
|
|
307
303
|
logger.info(message)
|
|
308
304
|
sleep(opts[:delay])
|
|
309
305
|
retry
|
|
@@ -321,11 +317,9 @@ module Kitchen
|
|
|
321
317
|
def execute_with_exit_code(command)
|
|
322
318
|
exit_code = nil
|
|
323
319
|
session.open_channel do |channel|
|
|
324
|
-
|
|
325
320
|
channel.request_pty
|
|
326
321
|
|
|
327
322
|
channel.exec(command) do |_ch, _success|
|
|
328
|
-
|
|
329
323
|
channel.on_data do |_ch, data|
|
|
330
324
|
logger << data
|
|
331
325
|
end
|
|
@@ -366,13 +360,13 @@ module Kitchen
|
|
|
366
360
|
def session(retry_options = {})
|
|
367
361
|
if ssh_gateway
|
|
368
362
|
@session ||= establish_connection_via_gateway({
|
|
369
|
-
:
|
|
370
|
-
:
|
|
363
|
+
retries: connection_retries.to_i,
|
|
364
|
+
delay: connection_retry_sleep.to_i,
|
|
371
365
|
}.merge(retry_options))
|
|
372
366
|
else
|
|
373
367
|
@session ||= establish_connection({
|
|
374
|
-
:
|
|
375
|
-
:
|
|
368
|
+
retries: connection_retries.to_i,
|
|
369
|
+
delay: connection_retry_sleep.to_i,
|
|
376
370
|
}.merge(retry_options))
|
|
377
371
|
end
|
|
378
372
|
end
|
|
@@ -397,23 +391,23 @@ module Kitchen
|
|
|
397
391
|
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
398
392
|
def connection_options(data)
|
|
399
393
|
opts = {
|
|
400
|
-
:
|
|
401
|
-
:
|
|
402
|
-
:
|
|
403
|
-
:
|
|
404
|
-
:
|
|
405
|
-
:
|
|
406
|
-
:
|
|
407
|
-
:
|
|
408
|
-
:
|
|
409
|
-
:
|
|
410
|
-
:
|
|
411
|
-
:
|
|
412
|
-
:
|
|
413
|
-
:
|
|
414
|
-
:
|
|
415
|
-
:
|
|
416
|
-
:
|
|
394
|
+
logger: logger,
|
|
395
|
+
user_known_hosts_file: "/dev/null",
|
|
396
|
+
paranoid: false,
|
|
397
|
+
hostname: data[:hostname],
|
|
398
|
+
port: data[:port],
|
|
399
|
+
username: data[:username],
|
|
400
|
+
compression: data[:compression],
|
|
401
|
+
compression_level: data[:compression_level],
|
|
402
|
+
keepalive: data[:keepalive],
|
|
403
|
+
keepalive_interval: data[:keepalive_interval],
|
|
404
|
+
timeout: data[:connection_timeout],
|
|
405
|
+
connection_retries: data[:connection_retries],
|
|
406
|
+
connection_retry_sleep: data[:connection_retry_sleep],
|
|
407
|
+
max_ssh_sessions: data[:max_ssh_sessions],
|
|
408
|
+
max_wait_until_ready: data[:max_wait_until_ready],
|
|
409
|
+
ssh_gateway: data[:ssh_gateway],
|
|
410
|
+
ssh_gateway_username: data[:ssh_gateway_username],
|
|
417
411
|
}
|
|
418
412
|
|
|
419
413
|
if data[:ssh_key] && !data[:password]
|