test-kitchen 2.10.0 → 3.0.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: 51ed51940914e0c4ffb30d1e11be2e3554289833261e0b418eaa2ebdb674cab9
4
- data.tar.gz: c3c9be7593e1c0c333102168228c84e217244c5071da0bfb2ba543edca7581ba
3
+ metadata.gz: 7cff7935683511121e07b20e636078776ae80c20fc007b5b08a922ce76e0ce94
4
+ data.tar.gz: 8207e168e7faf42b8239438753c58f2a9a37fc4f4f2dcd9728948f67b4a5afb9
5
5
  SHA512:
6
- metadata.gz: 59633a6df2c274542ee3d4c649c55f8632077a98476ee655a1f59c0b39d42fad9077294b0e615d8e7f697feef4cbb027a9df7be81708832760d45eee72fbf159
7
- data.tar.gz: 34164cc7046bb2aa507fa33373c928d94be84284a99ba629562c585614c1818d032a42a1b2b83ab0b95382e984841be63a2dc32a05412dbf8d60a15839325146
6
+ metadata.gz: 46356119baf46a5ec115cc036c81778e8f17ac2dca6a21733d7bb4ef8779d7d23724ef295cd1f0557083abe577578ff28eec2bb5d9a4596359d8c5c34ea0379b
7
+ data.tar.gz: 7770f0e415279795ecf2106a6005f7b1514bd692be9a5839d24e992ad4e03dcbbe33dd86892904b1dd87a73473a3484d3f44518f7b87211d1c340c3f94abd6a3
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
1
  source "https://rubygems.org"
2
+
3
+ # Specify your gem"s dependencies in test-kitchen.gemspec
2
4
  gemspec
3
5
 
4
6
  group :integration do
@@ -8,20 +10,12 @@ group :integration do
8
10
  gem "kitchen-vagrant"
9
11
  end
10
12
 
11
- group :changelog do
12
- gem "github_changelog_generator", "1.15.2"
13
- end
14
-
15
13
  group :debug do
16
- gem "pry"
14
+ gem "pry", "~>0.12"
17
15
  gem "pry-byebug"
18
16
  gem "pry-stack_explorer"
19
17
  end
20
18
 
21
19
  group :chefstyle do
22
- gem "chefstyle"
23
- end
24
-
25
- group :docs do
26
- gem "yard"
27
- end
20
+ gem "chefstyle", "2.0.5"
21
+ end
data/Rakefile CHANGED
@@ -11,7 +11,7 @@ begin
11
11
  require "cucumber"
12
12
  require "cucumber/rake/task"
13
13
  Cucumber::Rake::Task.new(:features) do |t|
14
- t.cucumber_opts = ["features", "-x", "--format progress", "--no-color", "--tags ~@ignore"]
14
+ t.cucumber_opts = ["features", "-x", "--format progress", "--no-color", "--tags 'not @ignore'"]
15
15
  end
16
16
  rescue LoadError
17
17
  puts "cucumber is not available. (sudo) gem install cucumber to run tests."
@@ -41,30 +41,8 @@ end
41
41
  desc "Run all quality tasks"
42
42
  task quality: %i{style stats}
43
43
 
44
- begin
45
- require "yard" unless defined?(YARD)
46
- YARD::Rake::YardocTask.new
47
- rescue LoadError
48
- puts "yard is not available. (sudo) gem install yard to generate yard documentation."
49
- end
50
-
51
44
  task default: %i{test quality}
52
45
 
53
- begin
54
- require "github_changelog_generator/task"
55
- require "kitchen/version"
56
-
57
- GitHubChangelogGenerator::RakeTask.new :changelog do |config|
58
- config.future_release = "v#{Kitchen::VERSION}"
59
- config.enhancement_labels = "enhancement,Enhancement,New Feature,Feature,Improvement".split(",")
60
- config.bug_labels = "bug,Bug".split(",")
61
- config.exclude_labels = %w{Duplicate Question Discussion No_Changelog}
62
- end
63
- rescue LoadError
64
- puts "github_changelog_generator is not available." \
65
- " (sudo) gem install github_changelog_generator to generate changelogs"
66
- end
67
-
68
46
  namespace :docs do
69
47
  desc "Deploy docs"
70
48
  task :deploy do
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright:: Copyright (c) Chef Software Inc.
4
+ # License:: Apache License, Version 2.0
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
+
19
+ module Kitchen
20
+ # Common Dependency Injection wiring for ChefUtils-related modules
21
+ module ChefUtilsWiring
22
+ private
23
+
24
+ def __config
25
+ # this would need to be some kind of Chef::Config looking thing, which probably requires
26
+ # a translation object from t-k config to Chef::Config layout if that ever becomes necessary.
27
+ # this ISNT the t-k config.
28
+ {}
29
+ end
30
+
31
+ def __log
32
+ @logger
33
+ end
34
+
35
+ def __transport_connection
36
+ # this could be wired up to train at some point, but need to be careful because about local vs. remote
37
+ # uses of helpers with test-kitchen, right now we're using it for local.
38
+ end
39
+ end
40
+ end
data/lib/kitchen/cli.rb CHANGED
@@ -285,7 +285,7 @@ module Kitchen
285
285
  perform("exec", "exec", args)
286
286
  end
287
287
 
288
- desc "version", "Print Kitchen's version information"
288
+ desc "version", "Print Test Kitchen's version information"
289
289
  def version
290
290
  puts "Test Kitchen version #{Kitchen::VERSION}"
291
291
  end
@@ -296,7 +296,7 @@ module Kitchen
296
296
  perform("sink", "sink")
297
297
  end
298
298
 
299
- desc "console", "Kitchen Console!"
299
+ desc "console", "Test Kitchen Console!"
300
300
  def console
301
301
  perform("console", "console")
302
302
  end
@@ -43,7 +43,7 @@ module Kitchen
43
43
  def prompt(char)
44
44
  proc do |target_self, nest_level, pry|
45
45
  [
46
- "[#{pry.input_array.size}] ",
46
+ "[#{pry.input_ring.size}] ",
47
47
  "kc(#{Pry.view_clip(target_self.class)})",
48
48
  "#{":#{nest_level}" unless nest_level == 0}#{char} ",
49
49
  ].join
@@ -149,7 +149,7 @@ module Kitchen
149
149
  # @return [String] joined path for instance's os_type
150
150
  def remote_path_join(*parts)
151
151
  path = File.join(*parts)
152
- windows_os? ? path.tr("/", '\\') : path.tr('\\', "/")
152
+ windows_os? ? path.tr("/", "\\") : path.tr("\\", "/")
153
153
  end
154
154
 
155
155
  # @return [TrueClass,FalseClass] true if `:os_type` is `"unix"` (or
@@ -720,12 +720,14 @@ module Kitchen
720
720
  move_data_to!(:provisioner, suite, :attributes)
721
721
  move_data_to!(:provisioner, suite, :run_list)
722
722
  move_data_to!(:provisioner, suite, :named_run_list)
723
+ move_data_to!(:provisioner, suite, :policy_group)
723
724
  end
724
725
 
725
726
  data.fetch(:platforms, []).each do |platform|
726
727
  move_data_to!(:provisioner, platform, :attributes)
727
728
  move_data_to!(:provisioner, platform, :run_list)
728
729
  move_data_to!(:provisioner, platform, :named_run_list)
730
+ move_data_to!(:provisioner, platform, :policy_group)
729
731
  end
730
732
  end
731
733
 
@@ -18,8 +18,14 @@ module Kitchen
18
18
  end
19
19
  end
20
20
 
21
- conn = instance.transport.connection(state_file.read)
22
- conn.execute(command)
21
+ begin
22
+ conn = instance.transport.connection(state_file.read)
23
+ conn.execute(command)
24
+ rescue Kitchen::Transport::SshFailed => e
25
+ return if hook[:skippable] && e.message.match(/^SSH exited \(\d{1,3}\) for command: \[.+\]$/)
26
+
27
+ raise
28
+ end
23
29
  end
24
30
 
25
31
  private
@@ -293,11 +293,11 @@ module Kitchen
293
293
  logger = StdoutLogger.new(stdout)
294
294
  if colorize
295
295
  logger.formatter = proc do |_severity, _datetime, _progname, msg|
296
- Color.colorize(msg.to_s, color).concat("\n")
296
+ Color.colorize(msg.dup.to_s, color).concat("\n")
297
297
  end
298
298
  else
299
299
  logger.formatter = proc do |_severity, _datetime, _progname, msg|
300
- msg.concat("\n")
300
+ msg.dup.concat("\n")
301
301
  end
302
302
  end
303
303
  logger
@@ -2,6 +2,7 @@
2
2
  # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
3
  #
4
4
  # Copyright (C) 2013, Fletcher Nichol
5
+ # Copyright (C) Chef Software Inc.
5
6
  #
6
7
  # Licensed under the Apache License, Version 2.0 (the "License");
7
8
  # you may not use this file except in compliance with the License.
@@ -25,7 +26,7 @@ module Kitchen
25
26
  # @author Fletcher Nichol <fnichol@nichol.ca>
26
27
  module Provisioner
27
28
  # Default provisioner to use
28
- DEFAULT_PLUGIN = "chef_solo".freeze
29
+ DEFAULT_PLUGIN = "chef_infra".freeze
29
30
 
30
31
  # Returns an instance of a provisioner given a plugin type string.
31
32
  #
@@ -34,6 +35,7 @@ module Kitchen
34
35
  # @return [Provisioner::Base] a provisioner instance
35
36
  # @raise [ClientError] if a provisioner instance could not be created
36
37
  def self.for_plugin(plugin, config)
38
+ plugin, config[:name] = "chef_infra", "chef_infra" if plugin == "chef_zero"
37
39
  Kitchen::Plugin.load(self, plugin, config)
38
40
  end
39
41
  end
@@ -74,7 +74,7 @@ module Kitchen
74
74
 
75
75
  instance.transport.connection(state) do |conn|
76
76
  config[:uploads].to_h.each do |locals, remote|
77
- debug("Uploading #{Array(locals).join(', ')} to #{remote}")
77
+ debug("Uploading #{Array(locals).join(", ")} to #{remote}")
78
78
  conn.upload(locals.to_s, remote)
79
79
  end
80
80
  conn.execute(install_command)
@@ -177,11 +177,9 @@ module Kitchen
177
177
  # @raise [ClientError] if the sandbox directory has no yet been created
178
178
  # by calling `#create_sandbox`
179
179
  def sandbox_path
180
- @sandbox_path ||= begin
181
- raise ClientError, "Sandbox directory has not yet " \
180
+ @sandbox_path ||= raise ClientError, "Sandbox directory has not yet " \
182
181
  "been created. Please run #{self.class}#create_sandox before " \
183
182
  "trying to access the path."
184
- end
185
183
  end
186
184
 
187
185
  # Deletes the sandbox path. Without calling this method, the sandbox path
@@ -73,6 +73,10 @@ module Kitchen
73
73
  # @api private
74
74
  attr_reader :sandbox_path
75
75
 
76
+ # @return [String] name of the policy_group, nil results in "local"
77
+ # @api private
78
+ attr_reader :policy_group
79
+
76
80
  # Generates a list of all files in the cookbooks directory in the
77
81
  # sandbox path.
78
82
  #
@@ -281,19 +285,17 @@ module Kitchen
281
285
  end
282
286
 
283
287
  def update_dna_for_policyfile
284
- if !config[:run_list].nil? && !config[:run_list].empty?
285
- warn("You must set your run_list in your Policyfile instead of "\
286
- "kitchen config. The run_list in your config will be ignored.")
287
- warn("Ignored run_list: #{config[:run_list].inspect}")
288
- end
289
- policy = Chef::Policyfile.new(policyfile, sandbox_path,
288
+ policy = Chef::Policyfile.new(
289
+ policyfile, sandbox_path,
290
290
  logger: logger,
291
- always_update: config[:always_update_cookbooks])
291
+ always_update: config[:always_update_cookbooks],
292
+ policy_group: policy_group
293
+ )
292
294
  Kitchen.mutex.synchronize do
293
295
  policy.compile
294
296
  end
295
297
  policy_name = JSON.parse(IO.read(policy.lockfile))["name"]
296
- policy_group = "local"
298
+ policy_group = config[:policy_group] || "local"
297
299
  config[:attributes].merge(policy_name: policy_name, policy_group: policy_group)
298
300
  end
299
301
 
@@ -302,9 +304,12 @@ module Kitchen
302
304
  # @api private
303
305
  def resolve_with_policyfile
304
306
  Kitchen.mutex.synchronize do
305
- Chef::Policyfile.new(policyfile, sandbox_path,
307
+ Chef::Policyfile.new(
308
+ policyfile, sandbox_path,
306
309
  logger: logger,
307
- always_update: config[:always_update_cookbooks]).resolve
310
+ always_update: config[:always_update_cookbooks],
311
+ policy_group: config[:policy_group]
312
+ ).resolve
308
313
  end
309
314
  end
310
315
 
@@ -21,6 +21,7 @@ require "rbconfig" unless defined?(RbConfig)
21
21
  require_relative "../../errors"
22
22
  require_relative "../../logging"
23
23
  require_relative "../../shell_out"
24
+ require_relative "../../which"
24
25
 
25
26
  module Kitchen
26
27
  module Provisioner
@@ -31,6 +32,7 @@ module Kitchen
31
32
  class Policyfile
32
33
  include Logging
33
34
  include ShellOut
35
+ include Which
34
36
 
35
37
  # Creates a new cookbook resolver.
36
38
  #
@@ -39,11 +41,12 @@ module Kitchen
39
41
  # cookbooks
40
42
  # @param logger [Kitchen::Logger] a logger to use for output, defaults
41
43
  # to `Kitchen.logger`
42
- def initialize(policyfile, path, logger: Kitchen.logger, always_update: false)
43
- @policyfile = policyfile
44
- @path = path
45
- @logger = logger
44
+ def initialize(policyfile, path, logger: Kitchen.logger, always_update: false, policy_group: nil)
45
+ @policyfile = policyfile
46
+ @path = path
47
+ @logger = logger
46
48
  @always_update = always_update
49
+ @policy_group = policy_group
47
50
  end
48
51
 
49
52
  # Loads the library code required to use the resolver.
@@ -51,30 +54,34 @@ module Kitchen
51
54
  # @param logger [Kitchen::Logger] a logger to use for output, defaults
52
55
  # to `Kitchen.logger`
53
56
  def self.load!(logger: Kitchen.logger)
54
- detect_chef_command!(logger)
57
+ # intentionally left blank
55
58
  end
56
59
 
57
60
  # Performs the cookbook resolution and vendors the resulting cookbooks
58
61
  # in the desired path.
59
62
  def resolve
60
- info("Exporting cookbook dependencies from Policyfile #{path}...")
61
- run_command("chef export #{escape_path(policyfile)} #{escape_path(path)} --force")
63
+ if policy_group
64
+ 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
+ else
67
+ 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
+ end
62
70
  end
63
71
 
64
72
  # Runs `chef install` to determine the correct cookbook set and
65
73
  # generate the policyfile lock.
66
74
  def compile
67
75
  if File.exist?(lockfile)
68
- info("Installing cookbooks for Policyfile #{policyfile} using `chef install`")
76
+ info("Installing cookbooks for Policyfile #{policyfile} using `#{cli_path} install`")
69
77
  else
70
- info("Policy lock file doesn't exist, running `chef install` for "\
71
- "Policyfile #{policyfile}...")
78
+ info("Policy lock file doesn't exist, running `#{cli_path} install` for Policyfile #{policyfile}...")
72
79
  end
73
- run_command("chef install #{escape_path(policyfile)}")
80
+ run_command("#{cli_path} install #{escape_path(policyfile)}")
74
81
 
75
82
  if always_update
76
- info("Updating policy lock using `chef update`")
77
- run_command("chef update #{escape_path(policyfile)}")
83
+ info("Updating policy lock using `#{cli_path} update`")
84
+ run_command("#{cli_path} update #{escape_path(policyfile)}")
78
85
  end
79
86
  end
80
87
 
@@ -103,6 +110,10 @@ module Kitchen
103
110
  # @api private
104
111
  attr_reader :always_update
105
112
 
113
+ # @return [String] name of the policy_group, nil results in "local"
114
+ # @api private
115
+ attr_reader :policy_group
116
+
106
117
  # Escape spaces in a path in way that works with both Sh (Unix) and
107
118
  # Windows.
108
119
  #
@@ -117,7 +128,7 @@ module Kitchen
117
128
  # Windows command line parsing libraries. This covers the 99% case of
118
129
  # spaces in the path without breaking other stuff.
119
130
  if /[ \t\n\v"]/.match?(path)
120
- "\"#{path.gsub(/[ \t\n\v\"\\]/) { |m| '\\' + m[0] }}\""
131
+ "\"#{path.gsub(/[ \t\n\v\"\\]/) { |m| "\\" + m[0] }}\""
121
132
  else
122
133
  path
123
134
  end
@@ -126,33 +137,24 @@ module Kitchen
126
137
  end
127
138
  end
128
139
 
129
- class << self
130
- private
131
-
132
- # Ensure the `chef` command is in the path.
133
- #
134
- # @param logger [Kitchen::Logger] the logger to use
135
- # @raise [UserError] if the `chef` command is not in the PATH
136
- # @api private
137
- def detect_chef_command!(logger)
138
- unless ENV["PATH"].split(File::PATH_SEPARATOR).any? do |path|
139
- if /mswin|mingw/.match?(RbConfig::CONFIG["host_os"])
140
- # Windows could have different extentions: BAT, EXE or NONE
141
- %w{chef chef.exe chef.bat}.each do |bin|
142
- File.exist?(File.join(path, bin))
143
- end
144
- else
145
- File.exist?(File.join(path, "chef"))
146
- end
147
- end
148
- logger.fatal("The `chef` executable cannot be found in your " \
149
- "PATH. Ensure you have installed Chef Workstation " \
150
- "from https://downloads.chef.io and that your PATH " \
151
- "setting includes the path to the `chef` command.")
152
- raise UserError,
153
- "Could not find the chef executable in your PATH."
154
- end
155
- end
140
+ # Find the `chef` or `chef-cli` commands in the path or raise `chef` is present in
141
+ # ChefDK / Workstation releases, but is no longer shipped in any gems now that we
142
+ # use a Go based wrapper for the `chef` command in Workstation. The Ruby CLI has been
143
+ # renamed `chef-cli` under the hood and is shipped in the `chef-cli` gem.
144
+ #
145
+ # @api private
146
+ # @returns [String]
147
+ def cli_path
148
+ @cli_path ||= which("chef-cli") || which("chef") || no_cli_found_error
149
+ end
150
+
151
+ # @api private
152
+ def no_cli_found_error
153
+ @logger.fatal("The `chef` or `chef-cli` executables cannot be found in your " \
154
+ "PATH. Ensure you have installed Chef Workstation " \
155
+ "from https://downloads.chef.io and that your PATH " \
156
+ "setting includes the path to the `chef` or `chef-cli` commands.")
157
+ raise UserError, "Could not find the chef or chef-cli executables in your PATH."
156
158
  end
157
159
 
158
160
  end
@@ -46,6 +46,7 @@ module Kitchen
46
46
  default_config :chef_omnibus_install_options, nil
47
47
  default_config :chef_license, nil
48
48
  default_config :run_list, []
49
+ default_config :policy_group, nil
49
50
  default_config :attributes, {}
50
51
  default_config :config_path, nil
51
52
  default_config :log_file, nil
@@ -63,7 +64,7 @@ module Kitchen
63
64
  default_config :berksfile_path, nil
64
65
  # If set to true (which is the default from `chef generate`), try to update
65
66
  # backend cookbook downloader on every kitchen run.
66
- default_config :always_update_cookbooks, false
67
+ default_config :always_update_cookbooks, true
67
68
  default_config :cookbook_files_glob, %w(
68
69
  README.* VERSION metadata.{json,rb} attributes.rb recipe.rb
69
70
  attributes/**/* definitions/**/* files/**/* libraries/**/*
@@ -441,7 +442,7 @@ module Kitchen
441
442
  if obj.is_a?(String) && obj =~ /^:/
442
443
  obj
443
444
  elsif obj.is_a?(String)
444
- %{"#{obj.gsub(/\\/, '\\\\\\\\')}"}
445
+ %{"#{obj.gsub(/\\/, "\\\\\\\\")}"}
445
446
  elsif obj.is_a?(Array)
446
447
  %{[#{obj.map { |i| format_value(i) }.join(", ")}]}
447
448
  else
@@ -0,0 +1,167 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ #
4
+ # Copyright (C) 2013, Fletcher Nichol
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
+ require_relative "chef_base"
19
+
20
+ module Kitchen
21
+ module Provisioner
22
+ # Chef Zero provisioner.
23
+ #
24
+ # @author Fletcher Nichol <fnichol@nichol.ca>
25
+ class ChefInfra < ChefBase
26
+ kitchen_provisioner_api_version 2
27
+
28
+ plugin_version Kitchen::VERSION
29
+
30
+ default_config :client_rb, {}
31
+ default_config :named_run_list, {}
32
+ default_config :json_attributes, true
33
+ default_config :chef_zero_host, nil
34
+ default_config :chef_zero_port, 8889
35
+
36
+ default_config :chef_client_path do |provisioner|
37
+ provisioner
38
+ .remote_path_join(%W{#{provisioner[:chef_omnibus_root]} bin chef-client})
39
+ .tap { |path| path.concat(".bat") if provisioner.windows_os? }
40
+ end
41
+
42
+ default_config :ruby_bindir do |provisioner|
43
+ provisioner
44
+ .remote_path_join(%W{#{provisioner[:chef_omnibus_root]} embedded bin})
45
+ end
46
+
47
+ # (see Base#create_sandbox)
48
+ def create_sandbox
49
+ super
50
+ prepare_validation_pem
51
+ prepare_config_rb
52
+ end
53
+
54
+ def run_command
55
+ cmd = "#{sudo(config[:chef_client_path])} --local-mode".tap { |str| str.insert(0, "& ") if powershell_shell? }
56
+
57
+ chef_cmd(cmd)
58
+ end
59
+
60
+ private
61
+
62
+ # Adds optional flags to a chef-client command, depending on
63
+ # configuration data. Note that this method mutates the incoming Array.
64
+ #
65
+ # @param args [Array<String>] array of flags
66
+ # @api private
67
+ # rubocop:disable Metrics/CyclomaticComplexity
68
+ def add_optional_chef_client_args!(args)
69
+ if config[:json_attributes]
70
+ json = remote_path_join(config[:root_path], "dna.json")
71
+ args << "--json-attributes #{json}"
72
+ end
73
+
74
+ args << "--logfile #{config[:log_file]}" if config[:log_file]
75
+
76
+ # these flags are chef-client local mode only and will not work
77
+ # on older versions of chef-client
78
+ if config[:chef_zero_host]
79
+ args << "--chef-zero-host #{config[:chef_zero_host]}"
80
+ end
81
+
82
+ if config[:chef_zero_port]
83
+ args << "--chef-zero-port #{config[:chef_zero_port]}"
84
+ end
85
+
86
+ args << "--profile-ruby" if config[:profile_ruby]
87
+
88
+ if config[:slow_resource_report]
89
+ if config[:slow_resource_report].is_a?(Integer)
90
+ args << "--slow-report #{config[:slow_resource_report]}"
91
+ else
92
+ args << "--slow-report"
93
+ end
94
+ end
95
+ end
96
+ # rubocop:enable Metrics/CyclomaticComplexity
97
+
98
+ # Returns an Array of command line arguments for the chef client.
99
+ #
100
+ # @return [Array<String>] an array of command line arguments
101
+ # @api private
102
+ def chef_args(client_rb_filename)
103
+ level = config[:log_level]
104
+ args = [
105
+ "--config #{remote_path_join(config[:root_path], client_rb_filename)}",
106
+ "--log_level #{level}",
107
+ "--force-formatter",
108
+ "--no-color",
109
+ ]
110
+ add_optional_chef_client_args!(args)
111
+
112
+ args
113
+ end
114
+
115
+ # Generates a string of shell environment variables needed for the
116
+ # chef-client-zero.rb shim script to properly function.
117
+ #
118
+ # @return [String] a shell script string
119
+ # @api private
120
+ def chef_client_zero_env
121
+ root = config[:root_path]
122
+ gem_home = gem_path = remote_path_join(root, "chef-client-zero-gems")
123
+ gem_cache = remote_path_join(gem_home, "cache")
124
+
125
+ [
126
+ shell_env_var("CHEF_REPO_PATH", root),
127
+ shell_env_var("GEM_HOME", gem_home),
128
+ shell_env_var("GEM_PATH", gem_path),
129
+ shell_env_var("GEM_CACHE", gem_cache),
130
+ ].join("\n").concat("\n")
131
+ end
132
+
133
+ # Writes a fake (but valid) validation.pem into the sandbox directory.
134
+ #
135
+ # @api private
136
+ def prepare_validation_pem
137
+ info("Preparing validation.pem")
138
+ debug("Using a dummy validation.pem")
139
+
140
+ source = File.join(File.dirname(__FILE__),
141
+ %w{.. .. .. support dummy-validation.pem})
142
+ FileUtils.cp(source, File.join(sandbox_path, "validation.pem"))
143
+ end
144
+
145
+ # Returns the command that will run a backwards compatible shim script
146
+ # that approximates local mode in a modern chef-client run.
147
+ #
148
+ # @return [String] the command string
149
+ # @api private
150
+ def shim_command
151
+ ruby = remote_path_join(config[:ruby_bindir], "ruby")
152
+ .tap { |path| path.concat(".exe") if windows_os? }
153
+ shim = remote_path_join(config[:root_path], "chef-client-zero.rb")
154
+
155
+ "#{chef_client_zero_env}\n#{sudo(ruby)} #{shim}"
156
+ end
157
+
158
+ # This provisioner supports policyfiles, so override the default (which
159
+ # is false)
160
+ # @return [true] always returns true
161
+ # @api private
162
+ def supports_policyfile?
163
+ true
164
+ end
165
+ end
166
+ end
167
+ end
@@ -1,156 +1,12 @@
1
- #
2
- # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
- #
4
- # Copyright (C) 2013, Fletcher Nichol
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
- require_relative "chef_base"
1
+ # Deprecated AS PER THE PR - https://github.com/test-kitchen/test-kitchen/pull/1730
2
+ require_relative "chef_infra"
19
3
 
20
4
  module Kitchen
21
5
  module Provisioner
22
6
  # Chef Zero provisioner.
23
7
  #
24
8
  # @author Fletcher Nichol <fnichol@nichol.ca>
25
- class ChefZero < ChefBase
26
- kitchen_provisioner_api_version 2
27
-
28
- plugin_version Kitchen::VERSION
29
-
30
- default_config :client_rb, {}
31
- default_config :named_run_list, {}
32
- default_config :json_attributes, true
33
- default_config :chef_zero_host, nil
34
- default_config :chef_zero_port, 8889
35
-
36
- default_config :chef_client_path do |provisioner|
37
- provisioner
38
- .remote_path_join(%W{#{provisioner[:chef_omnibus_root]} bin chef-client})
39
- .tap { |path| path.concat(".bat") if provisioner.windows_os? }
40
- end
41
-
42
- default_config :ruby_bindir do |provisioner|
43
- provisioner
44
- .remote_path_join(%W{#{provisioner[:chef_omnibus_root]} embedded bin})
45
- end
46
-
47
- # (see Base#create_sandbox)
48
- def create_sandbox
49
- super
50
- prepare_validation_pem
51
- prepare_config_rb
52
- end
53
-
54
- def run_command
55
- cmd = "#{sudo(config[:chef_client_path])} --local-mode".tap { |str| str.insert(0, "& ") if powershell_shell? }
56
-
57
- chef_cmd(cmd)
58
- end
59
-
60
- private
61
-
62
- # Adds optional flags to a chef-client command, depending on
63
- # configuration data. Note that this method mutates the incoming Array.
64
- #
65
- # @param args [Array<String>] array of flags
66
- # @api private
67
- # rubocop:disable Metrics/CyclomaticComplexity
68
- def add_optional_chef_client_args!(args)
69
- if config[:json_attributes]
70
- json = remote_path_join(config[:root_path], "dna.json")
71
- args << "--json-attributes #{json}"
72
- end
73
- args << "--logfile #{config[:log_file]}" if config[:log_file]
74
-
75
- # these flags are chef-client local mode only and will not work
76
- # on older versions of chef-client
77
- if config[:chef_zero_host]
78
- args << "--chef-zero-host #{config[:chef_zero_host]}"
79
- end
80
- if config[:chef_zero_port]
81
- args << "--chef-zero-port #{config[:chef_zero_port]}"
82
- end
83
- args << "--profile-ruby" if config[:profile_ruby]
84
- end
85
- # rubocop:enable Metrics/CyclomaticComplexity
86
-
87
- # Returns an Array of command line arguments for the chef client.
88
- #
89
- # @return [Array<String>] an array of command line arguments
90
- # @api private
91
- def chef_args(client_rb_filename)
92
- level = config[:log_level]
93
- args = [
94
- "--config #{remote_path_join(config[:root_path], client_rb_filename)}",
95
- "--log_level #{level}",
96
- "--force-formatter",
97
- "--no-color",
98
- ]
99
- add_optional_chef_client_args!(args)
100
-
101
- args
102
- end
103
-
104
- # Generates a string of shell environment variables needed for the
105
- # chef-client-zero.rb shim script to properly function.
106
- #
107
- # @return [String] a shell script string
108
- # @api private
109
- def chef_client_zero_env
110
- root = config[:root_path]
111
- gem_home = gem_path = remote_path_join(root, "chef-client-zero-gems")
112
- gem_cache = remote_path_join(gem_home, "cache")
113
-
114
- [
115
- shell_env_var("CHEF_REPO_PATH", root),
116
- shell_env_var("GEM_HOME", gem_home),
117
- shell_env_var("GEM_PATH", gem_path),
118
- shell_env_var("GEM_CACHE", gem_cache),
119
- ].join("\n").concat("\n")
120
- end
121
-
122
- # Writes a fake (but valid) validation.pem into the sandbox directory.
123
- #
124
- # @api private
125
- def prepare_validation_pem
126
- info("Preparing validation.pem")
127
- debug("Using a dummy validation.pem")
128
-
129
- source = File.join(File.dirname(__FILE__),
130
- %w{.. .. .. support dummy-validation.pem})
131
- FileUtils.cp(source, File.join(sandbox_path, "validation.pem"))
132
- end
133
-
134
- # Returns the command that will run a backwards compatible shim script
135
- # that approximates local mode in a modern chef-client run.
136
- #
137
- # @return [String] the command string
138
- # @api private
139
- def shim_command
140
- ruby = remote_path_join(config[:ruby_bindir], "ruby")
141
- .tap { |path| path.concat(".exe") if windows_os? }
142
- shim = remote_path_join(config[:root_path], "chef-client-zero.rb")
143
-
144
- "#{chef_client_zero_env}\n#{sudo(ruby)} #{shim}"
145
- end
146
-
147
- # This provisioner supports policyfiles, so override the default (which
148
- # is false)
149
- # @return [true] always returns true
150
- # @api private
151
- def supports_policyfile?
152
- true
153
- end
9
+ class ChefZero < ChefInfra
154
10
  end
155
11
  end
156
12
  end
@@ -195,18 +195,16 @@ module Kitchen
195
195
  FileUtils.mkdir_p(File.dirname(local))
196
196
 
197
197
  Array(remotes).each do |file|
198
+ logger.debug("Attempting to download '#{file}' as file")
199
+ session.scp.download!(file, local)
200
+ rescue Net::SCP::Error
198
201
  begin
199
- logger.debug("Attempting to download '#{file}' as file")
200
- session.scp.download!(file, local)
202
+ logger.debug("Attempting to download '#{file}' as directory")
203
+ session.scp.download!(file, local, recursive: true)
201
204
  rescue Net::SCP::Error
202
- begin
203
- logger.debug("Attempting to download '#{file}' as directory")
204
- session.scp.download!(file, local, recursive: true)
205
- rescue Net::SCP::Error
206
- logger.warn(
207
- "SCP download failed for file or directory '#{file}', perhaps it does not exist?"
208
- )
209
- end
205
+ logger.warn(
206
+ "SCP download failed for file or directory '#{file}', perhaps it does not exist?"
207
+ )
210
208
  end
211
209
  end
212
210
  rescue Net::SSH::Exception => ex
@@ -365,11 +365,9 @@ module Kitchen
365
365
  # @return [Winrm::Shells::Elevated] the elevated shell
366
366
  # @api private
367
367
  def elevated_session(retry_options = {})
368
- @elevated_session ||= begin
369
- connection(retry_options).shell(:elevated).tap do |shell|
370
- shell.username = options[:elevated_username]
371
- shell.password = options[:elevated_password]
372
- end
368
+ @elevated_session ||= connection(retry_options).shell(:elevated).tap do |shell|
369
+ shell.username = options[:elevated_username]
370
+ shell.password = options[:elevated_password]
373
371
  end
374
372
  end
375
373
 
@@ -169,11 +169,9 @@ module Kitchen
169
169
  # @raise [ClientError] if the sandbox directory has no yet been created
170
170
  # by calling `#create_sandbox`
171
171
  def sandbox_path
172
- @sandbox_path ||= begin
173
- raise ClientError, "Sandbox directory has not yet " \
172
+ @sandbox_path ||= raise ClientError, "Sandbox directory has not yet " \
174
173
  "been created. Please run #{self.class}#create_sandox before " \
175
174
  "trying to access the path."
176
- end
177
175
  end
178
176
 
179
177
  # Sets the API version for this verifier. If the verifier does not set
@@ -88,6 +88,7 @@ module Kitchen
88
88
  env_state[:environment]["KITCHEN_INSTANCE"] = instance.name
89
89
  env_state[:environment]["KITCHEN_PLATFORM"] = instance.platform.name
90
90
  env_state[:environment]["KITCHEN_SUITE"] = instance.suite.name
91
+ env_state[:environment]["KITCHEN_USERNAME"] = instance.transport[:username] if instance.respond_to?(:transport)
91
92
  state.each_pair do |key, value|
92
93
  env_state[:environment]["KITCHEN_" + key.to_s.upcase] = value.to_s
93
94
  end
@@ -16,5 +16,5 @@
16
16
  # limitations under the License.
17
17
 
18
18
  module Kitchen
19
- VERSION = "2.10.0".freeze
19
+ VERSION = "3.0.0".freeze
20
20
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright:: Copyright (c) Chef Software Inc.
4
+ # License:: Apache License, Version 2.0
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
+ require "chef-utils/dsl/which" unless defined?(ChefUtils::DSL::Which)
19
+ require_relative "chef_utils_wiring" unless defined?(Kitchen::ChefUtilsWiring)
20
+
21
+ module Kitchen
22
+ module Which
23
+ include ChefUtils::DSL::Which
24
+ include ChefUtilsWiring
25
+ end
26
+ end
data/test-kitchen.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |gem|
20
20
  gem.executables = %w{kitchen}
21
21
  gem.require_paths = ["lib"]
22
22
 
23
- gem.required_ruby_version = ">= 2.4"
23
+ gem.required_ruby_version = ">= 2.5"
24
24
 
25
25
  gem.add_dependency "mixlib-shellout", ">= 1.2", "< 4.0"
26
26
  gem.add_dependency "net-scp", ">= 1.1", "< 4.0" # pinning until we can confirm 4+ works
@@ -33,6 +33,7 @@ Gem::Specification.new do |gem|
33
33
  gem.add_dependency "winrm", "~> 2.0"
34
34
  gem.add_dependency "winrm-elevated", "~> 1.0"
35
35
  gem.add_dependency "winrm-fs", "~> 1.1"
36
+ gem.add_dependency "chef-utils", ">= 16.4.35"
36
37
  # Required to run the Chef provisioner local license check for remote systems
37
38
  # TK is not under Chef EULA
38
39
  gem.add_dependency "license-acceptance", ">= 1.0.11", "< 3.0" # pinning until we can confirm 3+ works
@@ -43,7 +44,7 @@ Gem::Specification.new do |gem|
43
44
 
44
45
  gem.add_development_dependency "aruba", "~> 0.11", "< 1.0"
45
46
  gem.add_development_dependency "fakefs", "~> 1.0"
46
- gem.add_development_dependency "minitest", "~> 5.3", "< 5.12"
47
+ gem.add_development_dependency "minitest", "~> 5.3", "< 5.15"
47
48
  gem.add_development_dependency "mocha", "~> 1.1"
48
49
  gem.add_development_dependency "cucumber", ">= 2.1", "< 4.0" # we just need to validate 4.0 when it comes out
49
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: 2.10.0
4
+ version: 3.0.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: 2021-01-17 00:00:00.000000000 Z
11
+ date: 2021-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mixlib-shellout
@@ -194,6 +194,20 @@ dependencies:
194
194
  - - "~>"
195
195
  - !ruby/object:Gem::Version
196
196
  version: '1.1'
197
+ - !ruby/object:Gem::Dependency
198
+ name: chef-utils
199
+ requirement: !ruby/object:Gem::Requirement
200
+ requirements:
201
+ - - ">="
202
+ - !ruby/object:Gem::Version
203
+ version: 16.4.35
204
+ type: :runtime
205
+ prerelease: false
206
+ version_requirements: !ruby/object:Gem::Requirement
207
+ requirements:
208
+ - - ">="
209
+ - !ruby/object:Gem::Version
210
+ version: 16.4.35
197
211
  - !ruby/object:Gem::Dependency
198
212
  name: license-acceptance
199
213
  requirement: !ruby/object:Gem::Requirement
@@ -299,7 +313,7 @@ dependencies:
299
313
  version: '5.3'
300
314
  - - "<"
301
315
  - !ruby/object:Gem::Version
302
- version: '5.12'
316
+ version: '5.15'
303
317
  type: :development
304
318
  prerelease: false
305
319
  version_requirements: !ruby/object:Gem::Requirement
@@ -309,7 +323,7 @@ dependencies:
309
323
  version: '5.3'
310
324
  - - "<"
311
325
  - !ruby/object:Gem::Version
312
- version: '5.12'
326
+ version: '5.15'
313
327
  - !ruby/object:Gem::Dependency
314
328
  name: mocha
315
329
  requirement: !ruby/object:Gem::Requirement
@@ -387,6 +401,7 @@ files:
387
401
  - bin/kitchen
388
402
  - lib/kitchen.rb
389
403
  - lib/kitchen/base64_stream.rb
404
+ - lib/kitchen/chef_utils_wiring.rb
390
405
  - lib/kitchen/cli.rb
391
406
  - lib/kitchen/collection.rb
392
407
  - lib/kitchen/color.rb
@@ -434,6 +449,7 @@ files:
434
449
  - lib/kitchen/provisioner/chef/policyfile.rb
435
450
  - lib/kitchen/provisioner/chef_apply.rb
436
451
  - lib/kitchen/provisioner/chef_base.rb
452
+ - lib/kitchen/provisioner/chef_infra.rb
437
453
  - lib/kitchen/provisioner/chef_solo.rb
438
454
  - lib/kitchen/provisioner/chef_zero.rb
439
455
  - lib/kitchen/provisioner/dummy.rb
@@ -457,6 +473,7 @@ files:
457
473
  - lib/kitchen/verifier/dummy.rb
458
474
  - lib/kitchen/verifier/shell.rb
459
475
  - lib/kitchen/version.rb
476
+ - lib/kitchen/which.rb
460
477
  - lib/vendor/hash_recursive_merge.rb
461
478
  - support/busser_install_command.ps1
462
479
  - support/busser_install_command.sh
@@ -496,14 +513,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
496
513
  requirements:
497
514
  - - ">="
498
515
  - !ruby/object:Gem::Version
499
- version: '2.4'
516
+ version: '2.5'
500
517
  required_rubygems_version: !ruby/object:Gem::Requirement
501
518
  requirements:
502
519
  - - ">="
503
520
  - !ruby/object:Gem::Version
504
521
  version: '0'
505
522
  requirements: []
506
- rubygems_version: 3.1.4
523
+ rubygems_version: 3.2.15
507
524
  signing_key:
508
525
  specification_version: 4
509
526
  summary: Test Kitchen is an integration tool for developing and testing infrastructure