test-kitchen 3.2.2 → 3.3.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/Gemfile +1 -1
- data/lib/kitchen/driver/ssh_base.rb +1 -1
- data/lib/kitchen/lifecycle_hook/base.rb +6 -4
- data/lib/kitchen/platform_filter.rb +72 -0
- data/lib/kitchen/provisioner/base.rb +7 -1
- data/lib/kitchen/provisioner/chef/common_sandbox.rb +4 -2
- data/lib/kitchen/provisioner/chef/policyfile.rb +11 -6
- data/lib/kitchen/ssh.rb +10 -3
- data/lib/kitchen/suite.rb +4 -2
- data/lib/kitchen/transport/base.rb +10 -6
- data/lib/kitchen/transport/ssh.rb +17 -6
- data/lib/kitchen/transport/winrm.rb +28 -4
- data/lib/kitchen/util.rb +13 -0
- data/lib/kitchen/verifier/base.rb +7 -1
- data/lib/kitchen/version.rb +1 -1
- data/templates/driver/README.md.erb +2 -2
- data/test-kitchen.gemspec +2 -2
- metadata +10 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0b2b5ae9a13717d2eb6e02314305d2ee451bdf5739a396ffd649eeb03bd2cbd1
|
|
4
|
+
data.tar.gz: 2552cb2ca280b5f696fc17ed7f1346c7b9c9320d6d0f8b5bd729bb7ee23bd480
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cd7e48cec7ae4a0a959dc58bdcb196549a432177b8338340d774c9b20165efa95306dcc3f5b1c4aebd8da225462165b5a3d0e5dadbdc1a8d07fd7f282046d0c8
|
|
7
|
+
data.tar.gz: cef3fceeb5cc11c249b814fc3681187207eaeadc92dd499f422555ce69992bc57ce8d9177e4e637e57433a6515cc5275b1dbeae60c78b8b10605fa4370980e41
|
data/Gemfile
CHANGED
|
@@ -70,7 +70,7 @@ module Kitchen
|
|
|
70
70
|
def converge(state) # rubocop:disable Metrics/AbcSize
|
|
71
71
|
provisioner = instance.provisioner
|
|
72
72
|
provisioner.create_sandbox
|
|
73
|
-
sandbox_dirs =
|
|
73
|
+
sandbox_dirs = provisioner.sandbox_dirs
|
|
74
74
|
|
|
75
75
|
instance.transport.connection(backcompat_merged_state(state)) do |conn|
|
|
76
76
|
conn.execute(env_cmd(provisioner.install_command))
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require_relative "../platform_filter"
|
|
2
|
+
|
|
1
3
|
module Kitchen
|
|
2
4
|
class LifecycleHook
|
|
3
5
|
class Base
|
|
@@ -59,14 +61,14 @@ module Kitchen
|
|
|
59
61
|
lifecycle_hooks.state_file
|
|
60
62
|
end
|
|
61
63
|
|
|
62
|
-
# @return [Array<
|
|
64
|
+
# @return [Array<PlatformFilter>] names of excluded platforms
|
|
63
65
|
def excludes
|
|
64
|
-
@excludes ||= hook.fetch(:excludes, [])
|
|
66
|
+
@excludes ||= PlatformFilter.convert(hook.fetch(:excludes, []))
|
|
65
67
|
end
|
|
66
68
|
|
|
67
|
-
# @return [Array<
|
|
69
|
+
# @return [Array<PlatformFilter>] names of only included platforms
|
|
68
70
|
def includes
|
|
69
|
-
@includes ||= hook.fetch(:includes, [])
|
|
71
|
+
@includes ||= PlatformFilter.convert(hook.fetch(:includes, []))
|
|
70
72
|
end
|
|
71
73
|
|
|
72
74
|
# @return [String]
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Baptiste Courtois (<b.courtois@criteo.com>)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2021, Baptiste Courtois
|
|
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
|
+
# http://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
|
+
module Kitchen
|
|
19
|
+
# A wrapper on Regexp and strings to mix them in platform filters.
|
|
20
|
+
#
|
|
21
|
+
# This should handle backward compatibility in most cases were
|
|
22
|
+
# platform are matched against a filters array using Array.include?
|
|
23
|
+
#
|
|
24
|
+
# This wrapper does not work if filters arrays are converted to Set.
|
|
25
|
+
#
|
|
26
|
+
# @author Baptiste Courtois <b.courtois@criteo.com>
|
|
27
|
+
class PlatformFilter
|
|
28
|
+
# Pattern used to determine whether a filter should be handled as a Regexp
|
|
29
|
+
REGEXP_LIKE_PATTERN = %r{^/(?<pattern>.*)/(?<options>[ix]*)$}.freeze
|
|
30
|
+
|
|
31
|
+
# Converts platform filters into an array of PlatformFilter handling both strings and Regexp.
|
|
32
|
+
# A string "looks-like" a regexp if it starts by / and end by / + Regexp options i or x
|
|
33
|
+
#
|
|
34
|
+
# @return [Array] filters with regexp-like string converted to PlatformRegexpFilter
|
|
35
|
+
def self.convert(filters)
|
|
36
|
+
::Kernel.Array(filters).map do |filter|
|
|
37
|
+
if (match = filter.match(REGEXP_LIKE_PATTERN))
|
|
38
|
+
options = match["options"].include?("i") ? ::Regexp::IGNORECASE : 0
|
|
39
|
+
options |= ::Regexp::EXTENDED if match["options"].include?("x")
|
|
40
|
+
filter = ::Regexp.new(match["pattern"], options)
|
|
41
|
+
end
|
|
42
|
+
new(filter)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @return [Regexp] value of this filter
|
|
47
|
+
attr_reader :value
|
|
48
|
+
|
|
49
|
+
# Constructs a new filter.
|
|
50
|
+
#
|
|
51
|
+
# @param [Regexp,String] value of the filter
|
|
52
|
+
def initialize(value)
|
|
53
|
+
raise ::ArgumentError, "PlatformFilter#new requires value to be a String or a Regexp" unless value.is_a?(::Regexp) || value.is_a?(::String)
|
|
54
|
+
|
|
55
|
+
@value = value
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Override of the equality operator to check whether the wrapped Regexp match the given object.
|
|
59
|
+
#
|
|
60
|
+
# @param [Object] other object to compare to
|
|
61
|
+
# @return [Boolean] whether the objects are equal or the wrapped Regexp matches the given string or symbol
|
|
62
|
+
def ==(other)
|
|
63
|
+
if @value.is_a?(::Regexp) && (other.is_a?(::String) || other.is_a?(::Symbol))
|
|
64
|
+
@value =~ other
|
|
65
|
+
else
|
|
66
|
+
other == @value
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
alias eq? ==
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -70,7 +70,6 @@ module Kitchen
|
|
|
70
70
|
# rubocop:disable Metrics/AbcSize
|
|
71
71
|
def call(state)
|
|
72
72
|
create_sandbox
|
|
73
|
-
sandbox_dirs = Util.list_directory(sandbox_path)
|
|
74
73
|
|
|
75
74
|
instance.transport.connection(state) do |conn|
|
|
76
75
|
config[:uploads].to_h.each do |locals, remote|
|
|
@@ -182,6 +181,13 @@ module Kitchen
|
|
|
182
181
|
"trying to access the path."
|
|
183
182
|
end
|
|
184
183
|
|
|
184
|
+
# Returns the list of items in the sandbox directory
|
|
185
|
+
#
|
|
186
|
+
# @return [String] path of items in the sandbox directory
|
|
187
|
+
def sandbox_dirs
|
|
188
|
+
Util.list_directory(sandbox_path)
|
|
189
|
+
end
|
|
190
|
+
|
|
185
191
|
# Deletes the sandbox path. Without calling this method, the sandbox path
|
|
186
192
|
# will persist after the process terminates. In other words, cleanup is
|
|
187
193
|
# explicit. This method is safe to call multiple times.
|
|
@@ -289,7 +289,8 @@ module Kitchen
|
|
|
289
289
|
policyfile, sandbox_path,
|
|
290
290
|
logger: logger,
|
|
291
291
|
always_update: config[:always_update_cookbooks],
|
|
292
|
-
policy_group: policy_group
|
|
292
|
+
policy_group: policy_group,
|
|
293
|
+
license: config[:chef_license]
|
|
293
294
|
)
|
|
294
295
|
Kitchen.mutex.synchronize do
|
|
295
296
|
policy.compile
|
|
@@ -308,7 +309,8 @@ module Kitchen
|
|
|
308
309
|
policyfile, sandbox_path,
|
|
309
310
|
logger: logger,
|
|
310
311
|
always_update: config[:always_update_cookbooks],
|
|
311
|
-
policy_group: config[:policy_group]
|
|
312
|
+
policy_group: config[:policy_group],
|
|
313
|
+
license: config[:chef_license]
|
|
312
314
|
).resolve
|
|
313
315
|
end
|
|
314
316
|
end
|
|
@@ -41,12 +41,13 @@ module Kitchen
|
|
|
41
41
|
# cookbooks
|
|
42
42
|
# @param logger [Kitchen::Logger] a logger to use for output, defaults
|
|
43
43
|
# to `Kitchen.logger`
|
|
44
|
-
def initialize(policyfile, path, logger: Kitchen.logger, always_update: false, policy_group: nil)
|
|
44
|
+
def initialize(policyfile, path, license: nil, logger: Kitchen.logger, always_update: false, policy_group: nil)
|
|
45
45
|
@policyfile = policyfile
|
|
46
46
|
@path = path
|
|
47
47
|
@logger = logger
|
|
48
48
|
@always_update = always_update
|
|
49
49
|
@policy_group = policy_group
|
|
50
|
+
@license = license
|
|
50
51
|
end
|
|
51
52
|
|
|
52
53
|
# Loads the library code required to use the resolver.
|
|
@@ -62,10 +63,10 @@ module Kitchen
|
|
|
62
63
|
def resolve
|
|
63
64
|
if policy_group
|
|
64
65
|
info("Exporting cookbook dependencies from Policyfile #{path} with policy_group #{policy_group} using `#{cli_path} export`...")
|
|
65
|
-
run_command("#{cli_path} export #{escape_path(policyfile)} #{escape_path(path)} --policy_group #{policy_group} --force")
|
|
66
|
+
run_command("#{cli_path} export #{escape_path(policyfile)} #{escape_path(path)} --policy_group #{policy_group} --force --chef-license #{license}")
|
|
66
67
|
else
|
|
67
68
|
info("Exporting cookbook dependencies from Policyfile #{path} using `#{cli_path} export`...")
|
|
68
|
-
run_command("#{cli_path} export #{escape_path(policyfile)} #{escape_path(path)} --force")
|
|
69
|
+
run_command("#{cli_path} export #{escape_path(policyfile)} #{escape_path(path)} --force --chef-license #{license}")
|
|
69
70
|
end
|
|
70
71
|
end
|
|
71
72
|
|
|
@@ -77,11 +78,11 @@ module Kitchen
|
|
|
77
78
|
else
|
|
78
79
|
info("Policy lock file doesn't exist, running `#{cli_path} install` for Policyfile #{policyfile}...")
|
|
79
80
|
end
|
|
80
|
-
run_command("#{cli_path} install #{escape_path(policyfile)}")
|
|
81
|
+
run_command("#{cli_path} install #{escape_path(policyfile)} --chef-license #{license}")
|
|
81
82
|
|
|
82
83
|
if always_update
|
|
83
84
|
info("Updating policy lock using `#{cli_path} update`")
|
|
84
|
-
run_command("#{cli_path} update #{escape_path(policyfile)}")
|
|
85
|
+
run_command("#{cli_path} update #{escape_path(policyfile)} --chef-license #{license}")
|
|
85
86
|
end
|
|
86
87
|
end
|
|
87
88
|
|
|
@@ -114,6 +115,10 @@ module Kitchen
|
|
|
114
115
|
# @api private
|
|
115
116
|
attr_reader :policy_group
|
|
116
117
|
|
|
118
|
+
# @return [String] name of the chef_license
|
|
119
|
+
# @api private
|
|
120
|
+
attr_reader :license
|
|
121
|
+
|
|
117
122
|
# Escape spaces in a path in way that works with both Sh (Unix) and
|
|
118
123
|
# Windows.
|
|
119
124
|
#
|
|
@@ -152,7 +157,7 @@ module Kitchen
|
|
|
152
157
|
def no_cli_found_error
|
|
153
158
|
@logger.fatal("The `chef` or `chef-cli` executables cannot be found in your " \
|
|
154
159
|
"PATH. Ensure you have installed Chef Workstation " \
|
|
155
|
-
"from https://
|
|
160
|
+
"from https://www.chef.io/downloads/ and that your PATH " \
|
|
156
161
|
"setting includes the path to the `chef` or `chef-cli` commands.")
|
|
157
162
|
raise UserError, "Could not find the chef or chef-cli executables in your PATH."
|
|
158
163
|
end
|
data/lib/kitchen/ssh.rb
CHANGED
|
@@ -23,6 +23,7 @@ require "socket" unless defined?(Socket)
|
|
|
23
23
|
|
|
24
24
|
require_relative "errors"
|
|
25
25
|
require_relative "login_command"
|
|
26
|
+
require_relative "util"
|
|
26
27
|
|
|
27
28
|
module Kitchen
|
|
28
29
|
# Wrapped exception for any internally raised SSH-related errors.
|
|
@@ -75,7 +76,9 @@ module Kitchen
|
|
|
75
76
|
# @param cmd [String] command string to execute
|
|
76
77
|
# @raise [SSHFailed] if the command does not exit with a 0 code
|
|
77
78
|
def exec(cmd)
|
|
78
|
-
|
|
79
|
+
string_to_mask = "[SSH] #{self} (#{cmd})"
|
|
80
|
+
masked_string = Util.mask_values(string_to_mask, %w{password ssh_http_proxy_password})
|
|
81
|
+
logger.debug(masked_string)
|
|
79
82
|
exit_code = exec_with_exit(cmd)
|
|
80
83
|
|
|
81
84
|
if exit_code != 0
|
|
@@ -137,7 +140,9 @@ module Kitchen
|
|
|
137
140
|
def shutdown
|
|
138
141
|
return if @session.nil?
|
|
139
142
|
|
|
140
|
-
|
|
143
|
+
string_to_mask = "[SSH] closing connection to #{self}"
|
|
144
|
+
masked_string = Util.mask_values(string_to_mask, %w{password ssh_http_proxy_password})
|
|
145
|
+
logger.debug(masked_string)
|
|
141
146
|
session.shutdown!
|
|
142
147
|
ensure
|
|
143
148
|
@session = nil
|
|
@@ -212,7 +217,9 @@ module Kitchen
|
|
|
212
217
|
retries = options[:ssh_retries] || 3
|
|
213
218
|
|
|
214
219
|
begin
|
|
215
|
-
|
|
220
|
+
string_to_mask = "[SSH] opening connection to #{self}"
|
|
221
|
+
masked_string = Util.mask_values(string_to_mask, %w{password ssh_http_proxy_password})
|
|
222
|
+
logger.debug(masked_string)
|
|
216
223
|
Net::SSH.start(hostname, username, options)
|
|
217
224
|
rescue *rescue_exceptions => e
|
|
218
225
|
retries -= 1
|
data/lib/kitchen/suite.rb
CHANGED
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
# See the License for the specific language governing permissions and
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
|
|
18
|
+
require_relative "platform_filter"
|
|
19
|
+
|
|
18
20
|
module Kitchen
|
|
19
21
|
# A logical configuration representing a test case or fixture that will be
|
|
20
22
|
# executed on a platform.
|
|
@@ -41,8 +43,8 @@ module Kitchen
|
|
|
41
43
|
@name = options.fetch(:name) do
|
|
42
44
|
raise ClientError, "Suite#new requires option :name"
|
|
43
45
|
end
|
|
44
|
-
@excludes = options.fetch(:excludes, [])
|
|
45
|
-
@includes = options.fetch(:includes, [])
|
|
46
|
+
@excludes = PlatformFilter.convert(options.fetch(:excludes, []))
|
|
47
|
+
@includes = PlatformFilter.convert(options.fetch(:includes, []))
|
|
46
48
|
end
|
|
47
49
|
end
|
|
48
50
|
end
|
|
@@ -128,8 +128,8 @@ module Kitchen
|
|
|
128
128
|
tries += 1
|
|
129
129
|
debug("Attempting to execute command - try #{tries} of #{max_retries}.")
|
|
130
130
|
execute(command)
|
|
131
|
-
rescue
|
|
132
|
-
if retry?(tries, max_retries, retryable_exit_codes, e
|
|
131
|
+
rescue Exception => e
|
|
132
|
+
if retry?(tries, max_retries, retryable_exit_codes, e)
|
|
133
133
|
close
|
|
134
134
|
sleep wait_time
|
|
135
135
|
retry
|
|
@@ -139,10 +139,14 @@ module Kitchen
|
|
|
139
139
|
end
|
|
140
140
|
end
|
|
141
141
|
|
|
142
|
-
def retry?(current_try, max_retries, retryable_exit_codes,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
142
|
+
def retry?(current_try, max_retries, retryable_exit_codes, exception)
|
|
143
|
+
if exception.is_a?(Kitchen::Transport::TransportFailed)
|
|
144
|
+
return current_try <= max_retries &&
|
|
145
|
+
!retryable_exit_codes.nil? &&
|
|
146
|
+
retryable_exit_codes.flatten.include?(exception.exit_code)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
false
|
|
146
150
|
end
|
|
147
151
|
|
|
148
152
|
# Builds a LoginCommand which can be used to open an interactive
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
|
|
18
18
|
require_relative "../../kitchen"
|
|
19
|
+
require_relative "../util"
|
|
19
20
|
|
|
20
21
|
require "fileutils" unless defined?(FileUtils)
|
|
21
22
|
require "net/ssh" unless defined?(Net::SSH)
|
|
@@ -102,7 +103,9 @@ module Kitchen
|
|
|
102
103
|
# (see Base#cleanup!)
|
|
103
104
|
def cleanup!
|
|
104
105
|
if @connection
|
|
105
|
-
|
|
106
|
+
string_to_mask = "[SSH] shutting previous connection #{@connection}"
|
|
107
|
+
masked_string = Util.mask_values(string_to_mask, %w{password ssh_http_proxy_password})
|
|
108
|
+
logger.debug(masked_string)
|
|
106
109
|
@connection.close
|
|
107
110
|
@connection = @connection_options = nil
|
|
108
111
|
end
|
|
@@ -125,7 +128,9 @@ module Kitchen
|
|
|
125
128
|
def close
|
|
126
129
|
return if @session.nil?
|
|
127
130
|
|
|
128
|
-
|
|
131
|
+
string_to_mask = "[SSH] closing connection to #{self}"
|
|
132
|
+
masked_string = Util.mask_values(string_to_mask, %w{password ssh_http_proxy_password})
|
|
133
|
+
logger.debug(masked_string)
|
|
129
134
|
session.close
|
|
130
135
|
ensure
|
|
131
136
|
@session = nil
|
|
@@ -135,7 +140,9 @@ module Kitchen
|
|
|
135
140
|
def execute(command)
|
|
136
141
|
return if command.nil?
|
|
137
142
|
|
|
138
|
-
|
|
143
|
+
string_to_mask = "[SSH] #{self} (#{command})"
|
|
144
|
+
masked_string = Util.mask_values(string_to_mask, %w{password ssh_http_proxy_password})
|
|
145
|
+
logger.debug(masked_string)
|
|
139
146
|
exit_code = execute_with_exit_code(command)
|
|
140
147
|
|
|
141
148
|
if exit_code != 0
|
|
@@ -352,7 +359,9 @@ module Kitchen
|
|
|
352
359
|
def retry_connection(opts)
|
|
353
360
|
log_msg = "[SSH] opening connection to #{self}"
|
|
354
361
|
log_msg += " via #{ssh_gateway_username}@#{ssh_gateway}:#{ssh_gateway_port}" if ssh_gateway
|
|
355
|
-
|
|
362
|
+
masked_string = Util.mask_values(log_msg, %w{password ssh_http_proxy_password})
|
|
363
|
+
|
|
364
|
+
logger.debug(masked_string)
|
|
356
365
|
yield
|
|
357
366
|
rescue *RESCUE_EXCEPTIONS_ON_ESTABLISH => e
|
|
358
367
|
if (opts[:retries] -= 1) > 0
|
|
@@ -541,7 +550,7 @@ module Kitchen
|
|
|
541
550
|
# Creates a new SSH Connection instance and save it for potential future
|
|
542
551
|
# reuse.
|
|
543
552
|
#
|
|
544
|
-
# @param options [Hash]
|
|
553
|
+
# @param options [Hash] connection options
|
|
545
554
|
# @return [Ssh::Connection] an SSH Connection instance
|
|
546
555
|
# @api private
|
|
547
556
|
def create_new_connection(options, &block)
|
|
@@ -555,7 +564,9 @@ module Kitchen
|
|
|
555
564
|
# @return [Ssh::Connection] an SSH Connection instance
|
|
556
565
|
# @api private
|
|
557
566
|
def reuse_connection
|
|
558
|
-
|
|
567
|
+
string_to_mask = "[SSH] reusing existing connection #{@connection}"
|
|
568
|
+
masked_string = Util.mask_values(string_to_mask, %w{password ssh_http_proxy_password})
|
|
569
|
+
logger.debug(masked_string)
|
|
559
570
|
yield @connection if block_given?
|
|
560
571
|
@connection
|
|
561
572
|
end
|
|
@@ -20,7 +20,9 @@
|
|
|
20
20
|
require "rbconfig" unless defined?(RbConfig)
|
|
21
21
|
require "uri" unless defined?(URI)
|
|
22
22
|
require_relative "../../kitchen"
|
|
23
|
+
require_relative "../util"
|
|
23
24
|
require "winrm" unless defined?(WinRM::Connection)
|
|
25
|
+
require "winrm/exceptions" unless defined?(WinRM::WinRMHTTPTransportError)
|
|
24
26
|
|
|
25
27
|
module Kitchen
|
|
26
28
|
module Transport
|
|
@@ -103,7 +105,9 @@ module Kitchen
|
|
|
103
105
|
def execute(command)
|
|
104
106
|
return if command.nil?
|
|
105
107
|
|
|
106
|
-
|
|
108
|
+
string_to_mask = "[WinRM] #{self} (#{command})"
|
|
109
|
+
masked_string = Util.mask_values(string_to_mask, %w{password ssh_http_proxy_password})
|
|
110
|
+
logger.debug(masked_string)
|
|
107
111
|
|
|
108
112
|
exit_code, stderr = execute_with_exit_code(command)
|
|
109
113
|
|
|
@@ -118,6 +122,22 @@ module Kitchen
|
|
|
118
122
|
end
|
|
119
123
|
end
|
|
120
124
|
|
|
125
|
+
def retry?(current_try, max_retries, retryable_exit_codes, exception)
|
|
126
|
+
# Avoid duplicating Kitchen::Transport::Base#retry?
|
|
127
|
+
result = super
|
|
128
|
+
return result if result == true
|
|
129
|
+
|
|
130
|
+
case exception
|
|
131
|
+
when WinRM::WinRMHTTPTransportError
|
|
132
|
+
return current_try <= max_retries &&
|
|
133
|
+
[400, 500].include?(exception.status_code)
|
|
134
|
+
when WinRM::WinRMWSManFault
|
|
135
|
+
return current_try <= max_retries
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
false
|
|
139
|
+
end
|
|
140
|
+
|
|
121
141
|
# (see Base::Connection#login_command)
|
|
122
142
|
def login_command
|
|
123
143
|
case RbConfig::CONFIG["host_os"]
|
|
@@ -477,12 +497,14 @@ module Kitchen
|
|
|
477
497
|
# Creates a new WinRM Connection instance and save it for potential
|
|
478
498
|
# future reuse.
|
|
479
499
|
#
|
|
480
|
-
# @param options [Hash]
|
|
500
|
+
# @param options [Hash] connection options
|
|
481
501
|
# @return [Ssh::Connection] a WinRM Connection instance
|
|
482
502
|
# @api private
|
|
483
503
|
def create_new_connection(options, &block)
|
|
484
504
|
if @connection
|
|
485
|
-
|
|
505
|
+
string_to_mask = "[WinRM] shutting previous connection #{@connection}"
|
|
506
|
+
masked_string = Util.mask_values(string_to_mask, %w{password ssh_http_proxy_password})
|
|
507
|
+
logger.debug(masked_string)
|
|
486
508
|
@connection.close
|
|
487
509
|
end
|
|
488
510
|
|
|
@@ -542,7 +564,9 @@ module Kitchen
|
|
|
542
564
|
# @return [Winrm::Connection] a WinRM Connection instance
|
|
543
565
|
# @api private
|
|
544
566
|
def reuse_connection
|
|
545
|
-
|
|
567
|
+
string_to_mask = "[WinRM] reusing existing connection #{@connection}"
|
|
568
|
+
masked_string = Util.mask_values(string_to_mask, %w{password ssh_http_proxy_password})
|
|
569
|
+
logger.debug(masked_string)
|
|
546
570
|
yield @connection if block_given?
|
|
547
571
|
@connection
|
|
548
572
|
end
|
data/lib/kitchen/util.rb
CHANGED
|
@@ -88,6 +88,19 @@ module Kitchen
|
|
|
88
88
|
end
|
|
89
89
|
end
|
|
90
90
|
|
|
91
|
+
# Returns a string with masked values for specified parameters.
|
|
92
|
+
#
|
|
93
|
+
# @param string_to_mask [String] the object whose string representation is parsed
|
|
94
|
+
# @param [Array] the list of keys whose values should be masked
|
|
95
|
+
# @return [String] the string representation of passed object with masked values
|
|
96
|
+
def self.mask_values(string_to_mask, keys)
|
|
97
|
+
masked_string = string_to_mask
|
|
98
|
+
keys.each do |key|
|
|
99
|
+
masked_string.gsub!(/:#{key}=>"([^"]*)"/, %{:#{key}=>"******"})
|
|
100
|
+
end
|
|
101
|
+
masked_string
|
|
102
|
+
end
|
|
103
|
+
|
|
91
104
|
# Returns a formatted string representing a duration in seconds.
|
|
92
105
|
#
|
|
93
106
|
# @param total [Integer] the total number of seconds
|
|
@@ -65,7 +65,6 @@ module Kitchen
|
|
|
65
65
|
# @raise [ActionFailed] if the action could not be completed
|
|
66
66
|
def call(state)
|
|
67
67
|
create_sandbox
|
|
68
|
-
sandbox_dirs = Util.list_directory(sandbox_path)
|
|
69
68
|
|
|
70
69
|
instance.transport.connection(state) do |conn|
|
|
71
70
|
conn.execute(install_command)
|
|
@@ -174,6 +173,13 @@ module Kitchen
|
|
|
174
173
|
"trying to access the path."
|
|
175
174
|
end
|
|
176
175
|
|
|
176
|
+
# Returns the list of items in the sandbox directory
|
|
177
|
+
#
|
|
178
|
+
# @return [String] the absolute path of sandbox directory files
|
|
179
|
+
def sandbox_dirs
|
|
180
|
+
Util.list_directory(sandbox_path)
|
|
181
|
+
end
|
|
182
|
+
|
|
177
183
|
# Sets the API version for this verifier. If the verifier does not set
|
|
178
184
|
# this value, then `nil` will be used and reported.
|
|
179
185
|
#
|
data/lib/kitchen/version.rb
CHANGED
|
@@ -58,7 +58,7 @@ Created and maintained by [<%= config[:author] %>][author] (<<%= config[:email]
|
|
|
58
58
|
|
|
59
59
|
[author]: https://github.com/enter-github-user
|
|
60
60
|
[issues]: https://github.com/enter-github-user/<%= config[:gem_name] %>/issues
|
|
61
|
-
[license]: https://github.com/enter-github-user/<%= config[:gem_name] %>/blob/
|
|
61
|
+
[license]: https://github.com/enter-github-user/<%= config[:gem_name] %>/blob/main/LICENSE
|
|
62
62
|
[repo]: https://github.com/enter-github-user/<%= config[:gem_name] %>
|
|
63
|
-
[driver_usage]:
|
|
63
|
+
[driver_usage]: https://kitchen.ci/docs/drivers/
|
|
64
64
|
[chef_omnibus_dl]: http://www.chef.io/chef/install/
|
data/test-kitchen.gemspec
CHANGED
|
@@ -42,9 +42,9 @@ Gem::Specification.new do |gem|
|
|
|
42
42
|
gem.add_development_dependency "bundler"
|
|
43
43
|
gem.add_development_dependency "rake"
|
|
44
44
|
|
|
45
|
-
gem.add_development_dependency "aruba", "
|
|
45
|
+
gem.add_development_dependency "aruba", ">= 0.11", "< 3.0"
|
|
46
46
|
gem.add_development_dependency "fakefs", "~> 1.0"
|
|
47
|
-
gem.add_development_dependency "minitest", "~> 5.3", "< 5.
|
|
47
|
+
gem.add_development_dependency "minitest", "~> 5.3", "< 5.16"
|
|
48
48
|
gem.add_development_dependency "mocha", "~> 1.1"
|
|
49
49
|
gem.add_development_dependency "cucumber", ">= 2.1", "< 8.0"
|
|
50
50
|
gem.add_development_dependency "countloc", "~> 0.4"
|
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.3.2
|
|
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: 2022-08-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: mixlib-shellout
|
|
@@ -274,22 +274,22 @@ dependencies:
|
|
|
274
274
|
name: aruba
|
|
275
275
|
requirement: !ruby/object:Gem::Requirement
|
|
276
276
|
requirements:
|
|
277
|
-
- - "
|
|
277
|
+
- - ">="
|
|
278
278
|
- !ruby/object:Gem::Version
|
|
279
279
|
version: '0.11'
|
|
280
280
|
- - "<"
|
|
281
281
|
- !ruby/object:Gem::Version
|
|
282
|
-
version: '
|
|
282
|
+
version: '3.0'
|
|
283
283
|
type: :development
|
|
284
284
|
prerelease: false
|
|
285
285
|
version_requirements: !ruby/object:Gem::Requirement
|
|
286
286
|
requirements:
|
|
287
|
-
- - "
|
|
287
|
+
- - ">="
|
|
288
288
|
- !ruby/object:Gem::Version
|
|
289
289
|
version: '0.11'
|
|
290
290
|
- - "<"
|
|
291
291
|
- !ruby/object:Gem::Version
|
|
292
|
-
version: '
|
|
292
|
+
version: '3.0'
|
|
293
293
|
- !ruby/object:Gem::Dependency
|
|
294
294
|
name: fakefs
|
|
295
295
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -313,7 +313,7 @@ dependencies:
|
|
|
313
313
|
version: '5.3'
|
|
314
314
|
- - "<"
|
|
315
315
|
- !ruby/object:Gem::Version
|
|
316
|
-
version: '5.
|
|
316
|
+
version: '5.16'
|
|
317
317
|
type: :development
|
|
318
318
|
prerelease: false
|
|
319
319
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -323,7 +323,7 @@ dependencies:
|
|
|
323
323
|
version: '5.3'
|
|
324
324
|
- - "<"
|
|
325
325
|
- !ruby/object:Gem::Version
|
|
326
|
-
version: '5.
|
|
326
|
+
version: '5.16'
|
|
327
327
|
- !ruby/object:Gem::Dependency
|
|
328
328
|
name: mocha
|
|
329
329
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -440,6 +440,7 @@ files:
|
|
|
440
440
|
- lib/kitchen/login_command.rb
|
|
441
441
|
- lib/kitchen/metadata_chopper.rb
|
|
442
442
|
- lib/kitchen/platform.rb
|
|
443
|
+
- lib/kitchen/platform_filter.rb
|
|
443
444
|
- lib/kitchen/plugin.rb
|
|
444
445
|
- lib/kitchen/plugin_base.rb
|
|
445
446
|
- lib/kitchen/provisioner.rb
|
|
@@ -520,7 +521,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
520
521
|
- !ruby/object:Gem::Version
|
|
521
522
|
version: '0'
|
|
522
523
|
requirements: []
|
|
523
|
-
rubygems_version: 3.2.
|
|
524
|
+
rubygems_version: 3.2.3
|
|
524
525
|
signing_key:
|
|
525
526
|
specification_version: 4
|
|
526
527
|
summary: Test Kitchen is an integration tool for developing and testing infrastructure
|