test-kitchen 3.7.2 → 3.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2d5084681fcdd3347fff64203a6a4a01e005297e2da8da4a19268e862c015f78
4
- data.tar.gz: a97d9c95641aef0c507f775dbf8164e73acc712bd5efed94324209c8b7a5d725
3
+ metadata.gz: b2b9e6d594b61d9e569f8051f34251c4c1c4c531618c70d382558f34c2b4fbdb
4
+ data.tar.gz: 6703f8a68a196806e858011fdc1a7695e5e48c936a8e86c550ce8369aba82174
5
5
  SHA512:
6
- metadata.gz: a1c90dbec6701faa9b16472fea3b46bff2e5743fb08db95d44a305dcfa7bdcea5c92961a5c82d9758e199f128dfbf746474414db8ec1cc910b99e6471b9e5ec0
7
- data.tar.gz: 698c4e4f6a617799ac5930da2ab8e4e934a5cbc523cb7515bc241117e3544166acf81a8fcc8b716c58fa0319b41b78e51a1dbc2846faaa442435d0937764521e
6
+ metadata.gz: 36e39c93bc5d66d0d46b790f927ee54c412c6467fd61c72a981721511814c1681925232851a437013a1a4c3ee250cc73ae251b057931db9024dab20596c31db9
7
+ data.tar.gz: 930266c1bc9c86e98def9eb3e78cf9bde2d8106a13fa831f1f56a88a3ca3d9b48f2c9508df077a4e414add79ef792b47255870c0ff7a12351f238501cdb138f8
data/Gemfile CHANGED
@@ -7,7 +7,7 @@ group :test do
7
7
  gem "rb-readline"
8
8
  gem "aruba", ">= 0.11", "< 3.0"
9
9
  gem "countloc", "~> 0.4"
10
- gem "cucumber", ">= 9.2", "< 10"
10
+ gem "cucumber", ">= 9.2", "< 11"
11
11
  gem "fakefs", "~> 3.0"
12
12
  gem "maruku", "~> 0.6"
13
13
  gem "minitest", "~> 5.3", "< 6.0"
@@ -70,20 +70,39 @@ module Kitchen
70
70
  # rubocop:disable Metrics/AbcSize
71
71
  def call(state)
72
72
  create_sandbox
73
+ prepare_install_script
73
74
 
74
75
  instance.transport.connection(state) do |conn|
75
76
  config[:uploads].to_h.each do |locals, remote|
76
77
  debug("Uploading #{Array(locals).join(", ")} to #{remote}")
77
78
  conn.upload(locals.to_s, remote)
78
79
  end
79
- conn.execute(install_command)
80
+
81
+ # Run the init command to create the kitchen tmp directory
82
+ conn.execute(init_command)
83
+
84
+ # Upload the install script instead of directly executing the command
85
+ if install_command
86
+ script_filename = windows_os? ? "install_script.ps1" : "install_script"
87
+ remote_script_path = remote_path_join(resolve_remote_path(config[:root_path]), script_filename)
88
+ if install_script_path
89
+ debug("Uploading install script to #{remote_script_path}")
90
+ conn.upload(install_script_path, remote_script_path)
91
+ # Make script executable on remote host
92
+ conn.execute(make_executable_command(remote_script_path))
93
+ # Execute the uploaded script
94
+ conn.execute(run_script_command(remote_script_path))
95
+ end
96
+ end
97
+
98
+ # The install script will remove the kitchen tmp directory, hence creating it again.
80
99
  conn.execute(init_command)
81
100
  info("Transferring files to #{instance.to_str}")
82
- conn.upload(sandbox_dirs, config[:root_path])
101
+ conn.upload(sandbox_dirs, resolve_remote_path(config[:root_path]))
83
102
  debug("Transfer complete")
84
103
  conn.execute(prepare_command)
85
104
  conn.execute_with_retry(
86
- run_command,
105
+ encode_for_powershell(run_command),
87
106
  config[:retry_on_exit_code],
88
107
  config[:max_retries],
89
108
  config[:wait_for_retry]
@@ -195,6 +214,7 @@ module Kitchen
195
214
  return if sandbox_path.nil?
196
215
 
197
216
  debug("Cleaning up local sandbox in #{sandbox_path}")
217
+ @install_script_path = nil
198
218
  FileUtils.rmtree(sandbox_path)
199
219
  end
200
220
 
@@ -270,6 +290,102 @@ module Kitchen
270
290
  def prefix_command(script)
271
291
  config[:command_prefix] ? "#{config[:command_prefix]} #{script}" : script
272
292
  end
293
+
294
+ def encode_for_powershell(script)
295
+ return script unless windows_os?
296
+
297
+ utf16le = script.encode(Encoding::UTF_16LE)
298
+ encoded = [utf16le].pack("m0")
299
+
300
+ "powershell -NoProfile -NonInteractive -NoLogo -ExecutionPolicy Bypass -EncodedCommand #{encoded}"
301
+ end
302
+
303
+ # Writes the install command to a file that will be uploaded to the instance
304
+ # and executed.
305
+ #
306
+ # @api private
307
+ def prepare_install_script
308
+ command = install_command
309
+ return if command.nil? || command.empty?
310
+
311
+ info("Preparing install script")
312
+ script_filename = windows_os? ? "install_script.ps1" : "install_script"
313
+ @install_script_path = File.join(sandbox_path, script_filename)
314
+
315
+ debug("Creating install script at #{@install_script_path}")
316
+ File.open(@install_script_path, "wb") do |file|
317
+ unless windows_os?
318
+ file.write("#!/bin/sh\n")
319
+ end
320
+ file.write(command)
321
+ end
322
+
323
+ # Make script executable locally
324
+ FileUtils.chmod(0755, @install_script_path) unless windows_os?
325
+ end
326
+
327
+ def install_script_path
328
+ @install_script_path
329
+ end
330
+
331
+ # Returns a command to make a script executable on the remote host.
332
+ #
333
+ # @param script_path [String] path to the script on the remote host
334
+ # @return [String] command to make the script executable
335
+ # @api private
336
+ def make_executable_command(script_path)
337
+ debug "echo Making script executable"
338
+ return if windows_os?
339
+
340
+ prefix_command(wrap_shell_code(sudo("chmod +x #{script_path}")))
341
+ end
342
+
343
+ # Returns a command to execute a script on the remote host.
344
+ #
345
+ # @param script_path [String] path to the script on the remote host
346
+ # @return [String] command to execute the script
347
+ # @api private
348
+ def run_script_command(script_path)
349
+ if windows_os?
350
+ # Use parameters to suppress PowerShell formatting and control characters
351
+ # that can interfere with console output over SSH
352
+ "powershell -NoProfile -NonInteractive -NoLogo -ExecutionPolicy Bypass -File #{script_path}"
353
+ else
354
+ prefix_command(wrap_shell_code(sudo(script_path)))
355
+ end
356
+ end
357
+
358
+ # Resolves PowerShell environment variables in remote paths to actual paths
359
+ # for use with net/scp and other transport operations that can't handle
360
+ # PowerShell variables like $env:TEMP.
361
+ #
362
+ # @param path [String] the remote path that may contain PowerShell env vars
363
+ # @return [String] the resolved path
364
+ # @api private
365
+ def resolve_remote_path(path)
366
+ return path unless windows_os?
367
+
368
+ # For Windows, resolve common PowerShell environment variables
369
+ resolved_path = path.dup
370
+
371
+ # Replace $env:TEMP with the actual Windows temp directory based on the transport username
372
+ if resolved_path.include?("$env:TEMP")
373
+ # Try to get username from transport configuration
374
+ # For Windows systems, fallback to "Administrator" if not found
375
+ username = begin
376
+ instance.transport[:username]
377
+ rescue
378
+ nil
379
+ end
380
+ username ||= "Administrator"
381
+
382
+ temp_path = "C:/Users/#{username}/AppData/Local/Temp"
383
+ resolved_path = resolved_path.gsub("$env:TEMP", temp_path)
384
+ end
385
+
386
+ # Convert backslashes to forward slashes for cross-platform compatibility
387
+ resolved_path.tr("\\", "/")
388
+ end
273
389
  end
274
390
  end
275
391
  end
@@ -322,7 +322,7 @@ module Kitchen
322
322
  init_command_vars_for_bourne(dirs)
323
323
  end
324
324
 
325
- prefix_command(shell_code_from_file(vars, "chef_base_init_command"))
325
+ encode_for_powershell(prefix_command(shell_code_from_file(vars, "chef_base_init_command")))
326
326
  end
327
327
 
328
328
  # (see Base#install_command)
@@ -364,7 +364,9 @@ module Kitchen
364
364
  logger.debug(masked_string)
365
365
  yield
366
366
  rescue *RESCUE_EXCEPTIONS_ON_ESTABLISH => e
367
- if (opts[:retries] -= 1) > 0
367
+ retries_left = opts[:retries] - 1
368
+ if retries_left > 0
369
+ opts[:retries] = retries_left
368
370
  message = if opts[:message]
369
371
  logger.debug("[SSH] connection failed (#{e.inspect})")
370
372
  opts[:message]
@@ -16,5 +16,5 @@
16
16
  # limitations under the License.
17
17
 
18
18
  module Kitchen
19
- VERSION = "3.7.2".freeze
19
+ VERSION = "3.8.0".freeze
20
20
  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: 3.7.2
4
+ version: 3.8.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: 2025-07-03 00:00:00.000000000 Z
11
+ date: 2025-07-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bcrypt_pbkdf