test-kitchen 3.8.2 → 3.9.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 +4 -4
- data/Gemfile +3 -5
- data/lib/kitchen/driver/exec.rb +2 -2
- data/lib/kitchen/generator/init.rb +1 -1
- data/lib/kitchen/instance.rb +1 -0
- data/lib/kitchen/loader/yaml.rb +1 -1
- data/lib/kitchen/provisioner/base.rb +23 -37
- data/lib/kitchen/transport/ssh.rb +23 -2
- data/lib/kitchen/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afc726dab92d4107edf13980480047c6286dbc816001eb61597206806e279644
|
4
|
+
data.tar.gz: 8cb0615335e7b7239e717bc4fac1c60ee0d4da202607be641542633fd0152f6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: afc342581e2d0b242bae26f23d5b872610c24cc78c160405ae7b7a56c9c45b595ab4a55ef88c6bb153a302e3a8aaa42cdb0218d2e6c98827ab04b5ecbf7eb47f
|
7
|
+
data.tar.gz: 5ece9c33f5ce95f94ff35f52d3a66b34c67da743f4ea296f89879c35da1c0bd97f503bdb94e3050ac588ade627bc3b65342d9bafa747cacfa0889982989b760e
|
data/Gemfile
CHANGED
@@ -6,21 +6,19 @@ group :test do
|
|
6
6
|
gem "rake"
|
7
7
|
gem "rb-readline"
|
8
8
|
gem "aruba", ">= 0.11", "< 3.0"
|
9
|
+
gem "chef-cli"
|
9
10
|
gem "countloc", "~> 0.4"
|
10
11
|
gem "cucumber", ">= 9.2", "< 11"
|
11
12
|
gem "fakefs", "~> 3.0"
|
12
|
-
gem "
|
13
|
+
gem "kitchen-inspec"
|
14
|
+
gem "maruku", "~> 0.7"
|
13
15
|
gem "minitest", "~> 5.3", "< 6.0"
|
14
16
|
gem "mocha", "~> 2.0"
|
15
17
|
end
|
16
18
|
|
17
19
|
group :integration do
|
18
|
-
gem "chef-cli"
|
19
20
|
gem "kitchen-dokken"
|
20
|
-
gem "kitchen-inspec"
|
21
21
|
gem "kitchen-vagrant"
|
22
|
-
gem "inspec", "~> 5.22" # Fix dependency conflicts for ruby < 3.4
|
23
|
-
gem "train", "~> 3.10" # Fix dependency conflicts for ruby < 3.4
|
24
22
|
end
|
25
23
|
|
26
24
|
group :linting do
|
data/lib/kitchen/driver/exec.rb
CHANGED
@@ -53,8 +53,8 @@ module Kitchen
|
|
53
53
|
|
54
54
|
private
|
55
55
|
|
56
|
-
# Resets the non-Kitchen managed instance
|
57
|
-
#
|
56
|
+
# Resets the non-Kitchen managed instance by issuing a command
|
57
|
+
# locally.
|
58
58
|
#
|
59
59
|
# @param state [Hash] the state hash
|
60
60
|
# @api private
|
data/lib/kitchen/instance.rb
CHANGED
data/lib/kitchen/loader/yaml.rb
CHANGED
@@ -70,7 +70,6 @@ module Kitchen
|
|
70
70
|
# rubocop:disable Metrics/AbcSize
|
71
71
|
def call(state)
|
72
72
|
create_sandbox
|
73
|
-
prepare_install_script
|
74
73
|
|
75
74
|
instance.transport.connection(state) do |conn|
|
76
75
|
config[:uploads].to_h.each do |locals, remote|
|
@@ -78,21 +77,24 @@ module Kitchen
|
|
78
77
|
conn.upload(locals.to_s, remote)
|
79
78
|
end
|
80
79
|
|
81
|
-
#
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
80
|
+
# Check if we need to upload script (for Windows SSH or other scenarios requiring script upload)
|
81
|
+
transport_config = instance.transport.instance_variable_get(:@config)
|
82
|
+
debug("Windows OS: #{windows_os?} and Transport config: #{transport_config.inspect}")
|
83
|
+
if windows_os? && transport_config && transport_config[:name] == "ssh"
|
84
|
+
prepare_install_script
|
85
|
+
# Run the init command to create the kitchen tmp directory
|
86
|
+
conn.execute(encode_for_powershell(init_command))
|
87
|
+
remote_script_path = remote_path_join(resolve_remote_path(config[:root_path]), "install_script.ps1")
|
88
88
|
if install_script_path
|
89
89
|
debug("Uploading install script to #{remote_script_path}")
|
90
90
|
conn.upload(install_script_path, remote_script_path)
|
91
|
-
|
92
|
-
conn.execute(make_executable_command(remote_script_path))
|
93
|
-
# Execute the uploaded script
|
91
|
+
debug("Executing install script with #{run_script_command(remote_script_path)}")
|
94
92
|
conn.execute(run_script_command(remote_script_path))
|
95
93
|
end
|
94
|
+
else
|
95
|
+
# For all other scenarios, execute install command directly
|
96
|
+
debug("Executing install command: #{install_command}")
|
97
|
+
conn.execute(install_command)
|
96
98
|
end
|
97
99
|
|
98
100
|
# The install script will remove the kitchen tmp directory, hence creating it again.
|
@@ -100,7 +102,9 @@ module Kitchen
|
|
100
102
|
info("Transferring files to #{instance.to_str}")
|
101
103
|
conn.upload(sandbox_dirs, resolve_remote_path(config[:root_path]))
|
102
104
|
debug("Transfer complete")
|
105
|
+
debug("Executing prepare command: #{prepare_command}")
|
103
106
|
conn.execute(prepare_command)
|
107
|
+
debug("Executing run command: #{run_command}")
|
104
108
|
conn.execute_with_retry(
|
105
109
|
encode_for_powershell(run_command),
|
106
110
|
config[:retry_on_exit_code],
|
@@ -292,8 +296,8 @@ module Kitchen
|
|
292
296
|
end
|
293
297
|
|
294
298
|
def encode_for_powershell(script)
|
295
|
-
return script unless windows_os?
|
296
299
|
return script if script.nil? || script.empty?
|
300
|
+
return script unless windows_os? && instance.transport.instance_variable_get(:@config)[:name] == "ssh"
|
297
301
|
|
298
302
|
utf16le = script.encode(Encoding::UTF_16LE)
|
299
303
|
encoded = [utf16le].pack("m0")
|
@@ -306,18 +310,16 @@ module Kitchen
|
|
306
310
|
#
|
307
311
|
# @api private
|
308
312
|
def prepare_install_script
|
313
|
+
return unless windows_os?
|
314
|
+
|
309
315
|
command = install_command
|
310
316
|
return if command.nil? || command.empty?
|
311
317
|
|
312
318
|
info("Preparing install script")
|
313
|
-
|
314
|
-
@install_script_path = File.join(sandbox_path, script_filename)
|
319
|
+
@install_script_path = File.join(sandbox_path, "install_script.ps1")
|
315
320
|
|
316
321
|
debug("Creating install script at #{@install_script_path}")
|
317
322
|
File.open(@install_script_path, "wb") do |file|
|
318
|
-
unless windows_os?
|
319
|
-
file.write("#!/bin/sh\n")
|
320
|
-
end
|
321
323
|
file.write(command)
|
322
324
|
end
|
323
325
|
|
@@ -329,31 +331,15 @@ module Kitchen
|
|
329
331
|
@install_script_path
|
330
332
|
end
|
331
333
|
|
332
|
-
# Returns a command to make a script executable on the remote host.
|
333
|
-
#
|
334
|
-
# @param script_path [String] path to the script on the remote host
|
335
|
-
# @return [String] command to make the script executable
|
336
|
-
# @api private
|
337
|
-
def make_executable_command(script_path)
|
338
|
-
debug "echo Making script executable"
|
339
|
-
return if windows_os?
|
340
|
-
|
341
|
-
prefix_command(wrap_shell_code(sudo("chmod +x #{script_path}")))
|
342
|
-
end
|
343
|
-
|
344
334
|
# Returns a command to execute a script on the remote host.
|
345
335
|
#
|
346
336
|
# @param script_path [String] path to the script on the remote host
|
347
337
|
# @return [String] command to execute the script
|
348
338
|
# @api private
|
349
339
|
def run_script_command(script_path)
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
"powershell -NoProfile -NonInteractive -NoLogo -ExecutionPolicy Bypass -File #{script_path}"
|
354
|
-
else
|
355
|
-
prefix_command(wrap_shell_code(sudo(script_path)))
|
356
|
-
end
|
340
|
+
# Use parameters to suppress PowerShell formatting and control characters
|
341
|
+
# that can interfere with console output over SSH
|
342
|
+
"powershell -NoProfile -NonInteractive -NoLogo -ExecutionPolicy Bypass -File #{script_path}"
|
357
343
|
end
|
358
344
|
|
359
345
|
# Resolves PowerShell environment variables in remote paths to actual paths
|
@@ -364,7 +350,7 @@ module Kitchen
|
|
364
350
|
# @return [String] the resolved path
|
365
351
|
# @api private
|
366
352
|
def resolve_remote_path(path)
|
367
|
-
return path unless windows_os?
|
353
|
+
return path unless windows_os? && instance.transport.instance_variable_get(:@config)[:name] == "ssh"
|
368
354
|
|
369
355
|
# For Windows, resolve common PowerShell environment variables
|
370
356
|
resolved_path = path.dup
|
@@ -22,6 +22,7 @@ require "fileutils" unless defined?(FileUtils)
|
|
22
22
|
require "net/ssh" unless defined?(Net::SSH)
|
23
23
|
require "net/ssh/gateway"
|
24
24
|
require "net/ssh/proxy/http"
|
25
|
+
require "net/ssh/proxy/command"
|
25
26
|
require "net/scp"
|
26
27
|
require "timeout" unless defined?(Timeout)
|
27
28
|
require "benchmark" unless defined?(Benchmark)
|
@@ -63,6 +64,8 @@ module Kitchen
|
|
63
64
|
default_config :ssh_http_proxy_user, nil
|
64
65
|
default_config :ssh_http_proxy_password, nil
|
65
66
|
|
67
|
+
default_config :ssh_proxy_command, nil
|
68
|
+
|
66
69
|
default_config :ssh_key, nil
|
67
70
|
expand_path_for :ssh_key
|
68
71
|
|
@@ -164,7 +167,9 @@ module Kitchen
|
|
164
167
|
if options.key?(:forward_agent)
|
165
168
|
args += %W{ -o ForwardAgent=#{options[:forward_agent] ? "yes" : "no"} }
|
166
169
|
end
|
167
|
-
if
|
170
|
+
if ssh_proxy_command
|
171
|
+
args += %W{ -o ProxyCommand=#{ssh_proxy_command} }
|
172
|
+
elsif ssh_gateway
|
168
173
|
gateway_command = "ssh -q #{ssh_gateway_username}@#{ssh_gateway} nc #{hostname} #{port}"
|
169
174
|
args += %W{ -o ProxyCommand=#{gateway_command} -p #{ssh_gateway_port} }
|
170
175
|
end
|
@@ -309,6 +314,11 @@ module Kitchen
|
|
309
314
|
# @api private
|
310
315
|
attr_reader :ssh_http_proxy_password
|
311
316
|
|
317
|
+
# @return [String] The ProxyCommand to use when connecting to the
|
318
|
+
# remote SSH host
|
319
|
+
# @api private
|
320
|
+
attr_reader :ssh_proxy_command
|
321
|
+
|
312
322
|
# Establish an SSH session on the remote host using a gateway host.
|
313
323
|
#
|
314
324
|
# @param opts [Hash] retry options
|
@@ -341,7 +351,13 @@ module Kitchen
|
|
341
351
|
# @api private
|
342
352
|
def establish_connection(opts)
|
343
353
|
retry_connection(opts) do
|
344
|
-
|
354
|
+
# Handle proxy command creation at connection time
|
355
|
+
connection_options = options.dup
|
356
|
+
if connection_options[:ssh_proxy_command_string]
|
357
|
+
proxy_command = connection_options.delete(:ssh_proxy_command_string)
|
358
|
+
connection_options[:proxy] = Net::SSH::Proxy::Command.new(proxy_command)
|
359
|
+
end
|
360
|
+
Net::SSH.start(hostname, username, connection_options)
|
345
361
|
end
|
346
362
|
end
|
347
363
|
|
@@ -428,6 +444,7 @@ module Kitchen
|
|
428
444
|
@ssh_http_proxy_user = @options.delete(:ssh_http_proxy_user)
|
429
445
|
@ssh_http_proxy_password = @options.delete(:ssh_http_proxy_password)
|
430
446
|
@ssh_http_proxy_port = @options.delete(:ssh_http_proxy_port)
|
447
|
+
@ssh_proxy_command = @options.delete(:ssh_proxy_command)
|
431
448
|
end
|
432
449
|
|
433
450
|
# Returns a connection session, or establishes one when invoked the
|
@@ -488,6 +505,7 @@ module Kitchen
|
|
488
505
|
ssh_gateway: data[:ssh_gateway],
|
489
506
|
ssh_gateway_username: data[:ssh_gateway_username],
|
490
507
|
ssh_gateway_port: data[:ssh_gateway_port],
|
508
|
+
ssh_proxy_command: data[:ssh_proxy_command],
|
491
509
|
}
|
492
510
|
|
493
511
|
if data[:ssh_key] && !data[:password]
|
@@ -501,6 +519,9 @@ module Kitchen
|
|
501
519
|
options_http_proxy[:user] = data[:ssh_http_proxy_user]
|
502
520
|
options_http_proxy[:password] = data[:ssh_http_proxy_password]
|
503
521
|
opts[:proxy] = Net::SSH::Proxy::HTTP.new(data[:ssh_http_proxy], data[:ssh_http_proxy_port], options_http_proxy)
|
522
|
+
elsif data[:ssh_proxy_command]
|
523
|
+
# Store the command string, create proxy object during connection
|
524
|
+
opts[:ssh_proxy_command_string] = data[:ssh_proxy_command]
|
504
525
|
end
|
505
526
|
|
506
527
|
if data[:ssh_key_only]
|
data/lib/kitchen/version.rb
CHANGED
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: 3.
|
4
|
+
version: 3.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fletcher Nichol
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bcrypt_pbkdf
|