test-kitchen 2.8.0 → 2.11.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 +4 -10
- data/Rakefile +0 -22
- data/lib/kitchen/chef_utils_wiring.rb +40 -0
- data/lib/kitchen/cli.rb +2 -2
- data/lib/kitchen/config.rb +7 -4
- data/lib/kitchen/lifecycle_hook/base.rb +78 -0
- data/lib/kitchen/lifecycle_hook/local.rb +53 -0
- data/lib/kitchen/lifecycle_hook/remote.rb +33 -0
- data/lib/kitchen/lifecycle_hooks.rb +26 -78
- data/lib/kitchen/loader/yaml.rb +1 -0
- data/lib/kitchen/logger.rb +2 -2
- data/lib/kitchen/provisioner/base.rb +5 -0
- data/lib/kitchen/provisioner/chef/policyfile.rb +31 -39
- data/lib/kitchen/transport/ssh.rb +8 -10
- data/lib/kitchen/transport/winrm.rb +10 -6
- data/lib/kitchen/util.rb +10 -0
- data/lib/kitchen/verifier/shell.rb +1 -0
- data/lib/kitchen/version.rb +1 -1
- data/lib/kitchen/which.rb +26 -0
- data/test-kitchen.gemspec +2 -1
- metadata +22 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 50a5869d9e42e825114235ba5906b29590610fae29325445d10f36c17b2c25c5
         | 
| 4 | 
            +
              data.tar.gz: 2fa37f0832ddf1890a50be2fef7611dace27df7c5e9915e9245855cc4d497772
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 17a6a5c8c0aa1162ce1ca4f9913fbe0825a845fa64ed5ec15afee5a6cca6238e12a8abc8a87d5c256b893dde007dafcba4c146ba81e3580eac1162b1db8a9c98
         | 
| 7 | 
            +
              data.tar.gz: c99f2570b910d6d839048aa692c5cf371ac887c38980ebb28b90d6fd0c57524b099a286392c714387e7ed0d1f0a6caf1c93f59874efd2611c941f819b69ab43f
         | 
    
        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,10 +10,6 @@ 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 14 | 
             
              gem "pry"
         | 
| 17 15 | 
             
              gem "pry-byebug"
         | 
| @@ -19,9 +17,5 @@ group :debug do | |
| 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", "1.7.2"
         | 
| 21 | 
            +
            end
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -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
    
    | @@ -16,7 +16,7 @@ | |
| 16 16 | 
             
            # limitations under the License.
         | 
| 17 17 |  | 
| 18 18 | 
             
            # CI tests fail without an explicit unconditional require of Thor
         | 
| 19 | 
            -
            require "thor" # rubocop:disable  | 
| 19 | 
            +
            require "thor" # rubocop:disable Chef/Ruby/UnlessDefinedRequire
         | 
| 20 20 |  | 
| 21 21 | 
             
            require_relative "../kitchen"
         | 
| 22 22 | 
             
            require_relative "generator/init"
         | 
| @@ -162,7 +162,7 @@ module Kitchen | |
| 162 162 | 
             
                  long_desc <<-DESC
         | 
| 163 163 | 
             
                    The instance states are in order: destroy, create, converge, setup, verify, destroy.
         | 
| 164 164 | 
             
                    Change one or more instances from the current state to the #{action} state. Actions for all
         | 
| 165 | 
            -
                    intermediate states will be executed. See  | 
| 165 | 
            +
                    intermediate states will be executed. See https://kitchen.ci/ for further explanation.
         | 
| 166 166 | 
             
                  DESC
         | 
| 167 167 | 
             
                  method_option :concurrency,
         | 
| 168 168 | 
             
                    aliases: "-c",
         | 
    
        data/lib/kitchen/config.rb
    CHANGED
    
    | @@ -244,16 +244,18 @@ module Kitchen | |
| 244 244 | 
             
                # @return [Instance] a new Instance object
         | 
| 245 245 | 
             
                # @api private
         | 
| 246 246 | 
             
                def new_instance(suite, platform, index)
         | 
| 247 | 
            +
                  sf = new_state_file(suite, platform)
         | 
| 248 | 
            +
             | 
| 247 249 | 
             
                  Instance.new(
         | 
| 248 250 | 
             
                    driver: new_driver(suite, platform),
         | 
| 249 | 
            -
                    lifecycle_hooks: new_lifecycle_hooks(suite, platform),
         | 
| 251 | 
            +
                    lifecycle_hooks: new_lifecycle_hooks(suite, platform, sf),
         | 
| 250 252 | 
             
                    logger: new_instance_logger(suite, platform, index),
         | 
| 251 253 | 
             
                    suite: suite,
         | 
| 252 254 | 
             
                    platform: platform,
         | 
| 253 255 | 
             
                    provisioner: new_provisioner(suite, platform),
         | 
| 254 256 | 
             
                    transport: new_transport(suite, platform),
         | 
| 255 257 | 
             
                    verifier: new_verifier(suite, platform),
         | 
| 256 | 
            -
                    state_file:  | 
| 258 | 
            +
                    state_file: sf
         | 
| 257 259 | 
             
                  )
         | 
| 258 260 | 
             
                end
         | 
| 259 261 |  | 
| @@ -284,11 +286,12 @@ module Kitchen | |
| 284 286 | 
             
                #
         | 
| 285 287 | 
             
                # @param suite [Suite,#name] a Suite
         | 
| 286 288 | 
             
                # @param platform [Platform,#name] a Platform
         | 
| 289 | 
            +
                # @param state_file [Kitchen::StateFile] a SateFile
         | 
| 287 290 | 
             
                # @return [LifecycleHooks] a new LifecycleHooks object
         | 
| 288 291 | 
             
                # @api private
         | 
| 289 | 
            -
                def new_lifecycle_hooks(suite, platform)
         | 
| 292 | 
            +
                def new_lifecycle_hooks(suite, platform, state_file)
         | 
| 290 293 | 
             
                  lhdata = data.lifecycle_hooks_data_for(suite.name, platform.name)
         | 
| 291 | 
            -
                  LifecycleHooks.new(lhdata)
         | 
| 294 | 
            +
                  LifecycleHooks.new(lhdata, state_file)
         | 
| 292 295 | 
             
                end
         | 
| 293 296 |  | 
| 294 297 | 
             
                # Builds a newly configured Provisioner object, for a given Suite and
         | 
| @@ -0,0 +1,78 @@ | |
| 1 | 
            +
            module Kitchen
         | 
| 2 | 
            +
              class LifecycleHook
         | 
| 3 | 
            +
                class Base
         | 
| 4 | 
            +
                  # @return [Kitchen::LifecycleHooks]
         | 
| 5 | 
            +
                  attr_reader :lifecycle_hooks
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  # return [String]
         | 
| 8 | 
            +
                  attr_reader :phase
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  # return [Hash]
         | 
| 11 | 
            +
                  attr_reader :hook
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  # @param lifecycle_hooks [Kitchen::LifecycleHooks]
         | 
| 14 | 
            +
                  # @param phase [String]
         | 
| 15 | 
            +
                  # @param hook [Hash]
         | 
| 16 | 
            +
                  def initialize(lifecycle_hooks, phase, hook)
         | 
| 17 | 
            +
                    @lifecycle_hooks = lifecycle_hooks
         | 
| 18 | 
            +
                    @phase = phase
         | 
| 19 | 
            +
                    @hook = hook
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  # return [void]
         | 
| 23 | 
            +
                  def run
         | 
| 24 | 
            +
                    raise NotImplementedError
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  # @return [TrueClass, FalseClass]
         | 
| 28 | 
            +
                  def should_run?
         | 
| 29 | 
            +
                    if !includes.empty?
         | 
| 30 | 
            +
                      includes.include?(platform_name)
         | 
| 31 | 
            +
                    elsif !excludes.empty?
         | 
| 32 | 
            +
                      !excludes.include?(platform_name)
         | 
| 33 | 
            +
                    else
         | 
| 34 | 
            +
                      true
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  # @return [Logger] the lifecycle hooks's logger
         | 
| 39 | 
            +
                  #   otherwise
         | 
| 40 | 
            +
                  # @api private
         | 
| 41 | 
            +
                  def logger
         | 
| 42 | 
            +
                    lifecycle_hooks.send(:logger)
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  private
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  # @return [Kitchen::Instance]
         | 
| 48 | 
            +
                  def instance
         | 
| 49 | 
            +
                    lifecycle_hooks.instance
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  # @return [Hash]
         | 
| 53 | 
            +
                  def config
         | 
| 54 | 
            +
                    lifecycle_hooks.send(:config)
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  # @return [Kitchen::StateFile]
         | 
| 58 | 
            +
                  def state_file
         | 
| 59 | 
            +
                    lifecycle_hooks.state_file
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                  # @return [Array<String>] names of excluded platforms
         | 
| 63 | 
            +
                  def excludes
         | 
| 64 | 
            +
                    @excludes ||= hook.fetch(:excludes, [])
         | 
| 65 | 
            +
                  end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                  # @return [Array<String>] names of only included platforms
         | 
| 68 | 
            +
                  def includes
         | 
| 69 | 
            +
                    @includes ||= hook.fetch(:includes, [])
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  # @return [String]
         | 
| 73 | 
            +
                  def platform_name
         | 
| 74 | 
            +
                    instance.platform.name
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
            end
         | 
| @@ -0,0 +1,53 @@ | |
| 1 | 
            +
            require_relative "base"
         | 
| 2 | 
            +
            require_relative "../shell_out"
         | 
| 3 | 
            +
            require_relative "../logging"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Kitchen
         | 
| 6 | 
            +
              class LifecycleHook
         | 
| 7 | 
            +
                class Local < Base
         | 
| 8 | 
            +
                  include ShellOut
         | 
| 9 | 
            +
                  include Logging
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  # Execute a specific local command hook.
         | 
| 12 | 
            +
                  #
         | 
| 13 | 
            +
                  # @return [void]
         | 
| 14 | 
            +
                  def run
         | 
| 15 | 
            +
                    state = state_file.read
         | 
| 16 | 
            +
                    # set up empty user variable
         | 
| 17 | 
            +
                    user = {}
         | 
| 18 | 
            +
                    # Set up some environment variables with instance info.
         | 
| 19 | 
            +
                    environment = {
         | 
| 20 | 
            +
                      "KITCHEN_INSTANCE_NAME" => instance.name,
         | 
| 21 | 
            +
                      "KITCHEN_SUITE_NAME" => instance.suite.name,
         | 
| 22 | 
            +
                      "KITCHEN_PLATFORM_NAME" => instance.platform.name,
         | 
| 23 | 
            +
                      "KITCHEN_INSTANCE_HOSTNAME" => state[:hostname].to_s,
         | 
| 24 | 
            +
                    }
         | 
| 25 | 
            +
                    # If the user specified env vars too, fix them up because symbol keys
         | 
| 26 | 
            +
                    # make mixlib-shellout sad.
         | 
| 27 | 
            +
                    hook[:environment]&.each do |k, v|
         | 
| 28 | 
            +
                      environment[k.to_s] = v.to_s
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    # add user to user hash for later merging
         | 
| 32 | 
            +
                    user[:user] = hook[:user] if hook[:user]
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    # Default the cwd to the kitchen root and resolve a relative input cwd against that.
         | 
| 35 | 
            +
                    cwd = if hook[:cwd]
         | 
| 36 | 
            +
                            File.expand_path(hook[:cwd], config[:kitchen_root])
         | 
| 37 | 
            +
                          else
         | 
| 38 | 
            +
                            config[:kitchen_root]
         | 
| 39 | 
            +
                          end
         | 
| 40 | 
            +
                    # Build the options for mixlib-shellout.
         | 
| 41 | 
            +
                    opts = {}.merge(user).merge(cwd: cwd, environment: environment)
         | 
| 42 | 
            +
                    run_command(command, opts)
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  private
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  # @return [String]
         | 
| 48 | 
            +
                  def command
         | 
| 49 | 
            +
                    hook.fetch(:local)
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
            end
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            require_relative "base"
         | 
| 2 | 
            +
            require_relative "../errors"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Kitchen
         | 
| 5 | 
            +
              class LifecycleHook
         | 
| 6 | 
            +
                class Remote < Base
         | 
| 7 | 
            +
                  # Execute a specific remote command hook.
         | 
| 8 | 
            +
                  #
         | 
| 9 | 
            +
                  # @return [void]
         | 
| 10 | 
            +
                  def run
         | 
| 11 | 
            +
                    # Check if we're in a state that makes sense to even try.
         | 
| 12 | 
            +
                    unless instance.last_action
         | 
| 13 | 
            +
                      if hook[:skippable]
         | 
| 14 | 
            +
                        # Just not even trying.
         | 
| 15 | 
            +
                        return
         | 
| 16 | 
            +
                      else
         | 
| 17 | 
            +
                        raise UserError, "Cannot use remote lifecycle hooks during phases when the instance is not available"
         | 
| 18 | 
            +
                      end
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    conn = instance.transport.connection(state_file.read)
         | 
| 22 | 
            +
                    conn.execute(command)
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  private
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  # return [String]
         | 
| 28 | 
            +
                  def command
         | 
| 29 | 
            +
                    hook.fetch(:remote)
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
| @@ -15,8 +15,11 @@ | |
| 15 15 | 
             
            # See the License for the specific language governing permissions and
         | 
| 16 16 | 
             
            # limitations under the License.
         | 
| 17 17 |  | 
| 18 | 
            +
            require_relative "configurable"
         | 
| 18 19 | 
             
            require_relative "errors"
         | 
| 19 | 
            -
            require_relative " | 
| 20 | 
            +
            require_relative "lifecycle_hook/local"
         | 
| 21 | 
            +
            require_relative "lifecycle_hook/remote"
         | 
| 22 | 
            +
            require_relative "logging"
         | 
| 20 23 |  | 
| 21 24 | 
             
            module Kitchen
         | 
| 22 25 | 
             
              # A helper object used by {Instance} to coordinate lifecycle hook calls from
         | 
| @@ -27,10 +30,10 @@ module Kitchen | |
| 27 30 | 
             
              class LifecycleHooks
         | 
| 28 31 | 
             
                include Configurable
         | 
| 29 32 | 
             
                include Logging
         | 
| 30 | 
            -
                include ShellOut
         | 
| 31 33 |  | 
| 32 | 
            -
                def initialize(config)
         | 
| 34 | 
            +
                def initialize(config, state_file)
         | 
| 33 35 | 
             
                  init_config(config)
         | 
| 36 | 
            +
                  @state_file = state_file
         | 
| 34 37 | 
             
                end
         | 
| 35 38 |  | 
| 36 39 | 
             
                # Run a lifecycle phase with the pre and post hooks.
         | 
| @@ -40,21 +43,22 @@ module Kitchen | |
| 40 43 | 
             
                # @param block [Proc] Block of code implementing the lifecycle phase.
         | 
| 41 44 | 
             
                # @return [void]
         | 
| 42 45 | 
             
                def run_with_hooks(phase, state_file, &block)
         | 
| 43 | 
            -
                  run( | 
| 46 | 
            +
                  run(phase, :pre)
         | 
| 44 47 | 
             
                  yield
         | 
| 45 | 
            -
                  run( | 
| 48 | 
            +
                  run(phase, :post)
         | 
| 46 49 | 
             
                end
         | 
| 47 50 |  | 
| 51 | 
            +
                # @return [Kitchen::StateFile]
         | 
| 52 | 
            +
                attr_reader :state_file
         | 
| 53 | 
            +
             | 
| 48 54 | 
             
                private
         | 
| 49 55 |  | 
| 50 56 | 
             
                # Execute a specific lifecycle hook.
         | 
| 51 57 | 
             
                #
         | 
| 52 | 
            -
                # @param instance [Instance] The instance object to run against.
         | 
| 53 58 | 
             
                # @param phase [String] Lifecycle phase which is being executed.
         | 
| 54 | 
            -
                # @param state_file [StateFile] Instance state file object.
         | 
| 55 59 | 
             
                # @param hook_timing [Symbol] `:pre` or `:post` to indicate which hook to run.
         | 
| 56 60 | 
             
                # @return [void]
         | 
| 57 | 
            -
                def run( | 
| 61 | 
            +
                def run(phase, hook_timing)
         | 
| 58 62 | 
             
                  # Yes this has to be a symbol because of how data munger works.
         | 
| 59 63 | 
             
                  hook_key = :"#{hook_timing}_#{phase}"
         | 
| 60 64 | 
             
                  # No hooks? We're outta here.
         | 
| @@ -65,80 +69,24 @@ module Kitchen | |
| 65 69 | 
             
                    # Coerce the common case of a bare string to be a local command. This
         | 
| 66 70 | 
             
                    # is to match the behavior of the old `pre_create_command` semi-hook.
         | 
| 67 71 | 
             
                    hook = { local: hook } if hook.is_a?(String)
         | 
| 68 | 
            -
                     | 
| 69 | 
            -
             | 
| 70 | 
            -
                      run_local_hook(instance, state_file, hook)
         | 
| 71 | 
            -
                    elsif hook.include?(:remote)
         | 
| 72 | 
            -
                      # Remote command execution on the test instance.
         | 
| 73 | 
            -
                      run_remote_hook(instance, state_file, hook)
         | 
| 74 | 
            -
                    else
         | 
| 75 | 
            -
                      raise UserError, "Unknown lifecycle hook target #{hook.inspect}"
         | 
| 76 | 
            -
                    end
         | 
| 72 | 
            +
                    hook = generate_hook(phase, hook)
         | 
| 73 | 
            +
                    hook.run if hook.should_run?
         | 
| 77 74 | 
             
                  end
         | 
| 78 75 | 
             
                end
         | 
| 79 76 |  | 
| 80 | 
            -
                #  | 
| 81 | 
            -
                #
         | 
| 82 | 
            -
                # @ | 
| 83 | 
            -
                 | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
                   | 
| 88 | 
            -
             | 
| 89 | 
            -
             | 
| 90 | 
            -
                   | 
| 91 | 
            -
             | 
| 92 | 
            -
                  environment = {
         | 
| 93 | 
            -
                    "KITCHEN_INSTANCE_NAME" => instance.name,
         | 
| 94 | 
            -
                    "KITCHEN_SUITE_NAME" => instance.suite.name,
         | 
| 95 | 
            -
                    "KITCHEN_PLATFORM_NAME" => instance.platform.name,
         | 
| 96 | 
            -
                    "KITCHEN_INSTANCE_HOSTNAME" => state[:hostname].to_s,
         | 
| 97 | 
            -
                  }
         | 
| 98 | 
            -
                  # If the user specified env vars too, fix them up because symbol keys
         | 
| 99 | 
            -
                  # make mixlib-shellout sad.
         | 
| 100 | 
            -
                  if hook[:environment]
         | 
| 101 | 
            -
                    hook[:environment].each do |k, v|
         | 
| 102 | 
            -
                      environment[k.to_s] = v.to_s
         | 
| 103 | 
            -
                    end
         | 
| 104 | 
            -
                  end
         | 
| 105 | 
            -
             | 
| 106 | 
            -
                  # add user to user hash for later merging
         | 
| 107 | 
            -
                  if hook[:user]
         | 
| 108 | 
            -
                    user[:user] = hook[:user]
         | 
| 77 | 
            +
                # @param phase [String]
         | 
| 78 | 
            +
                # @param hook [Hash]
         | 
| 79 | 
            +
                # @return [Kitchen::LifecycleHook::Local, Kitchen::LifecycleHook::Remote]
         | 
| 80 | 
            +
                def generate_hook(phase, hook)
         | 
| 81 | 
            +
                  if hook.include?(:local)
         | 
| 82 | 
            +
                    # Local command execution on the workstation.
         | 
| 83 | 
            +
                    Kitchen::LifecycleHook::Local.new(self, phase, hook)
         | 
| 84 | 
            +
                  elsif hook.include?(:remote)
         | 
| 85 | 
            +
                    # Remote command execution on the test instance.
         | 
| 86 | 
            +
                    Kitchen::LifecycleHook::Remote.new(self, phase, hook)
         | 
| 87 | 
            +
                  else
         | 
| 88 | 
            +
                    raise UserError, "Unknown lifecycle hook target #{hook.inspect}"
         | 
| 109 89 | 
             
                  end
         | 
| 110 | 
            -
             | 
| 111 | 
            -
                  # Default the cwd to the kitchen root and resolve a relative input cwd against that.
         | 
| 112 | 
            -
                  cwd = if hook[:cwd]
         | 
| 113 | 
            -
                          File.expand_path(hook[:cwd], config[:kitchen_root])
         | 
| 114 | 
            -
                        else
         | 
| 115 | 
            -
                          config[:kitchen_root]
         | 
| 116 | 
            -
                        end
         | 
| 117 | 
            -
                  # Build the options for mixlib-shellout.
         | 
| 118 | 
            -
                  opts = {}.merge(user).merge(cwd: cwd, environment: environment)
         | 
| 119 | 
            -
                  run_command(cmd, opts)
         | 
| 120 | 
            -
                end
         | 
| 121 | 
            -
             | 
| 122 | 
            -
                # Execute a specific remote command hook.
         | 
| 123 | 
            -
                #
         | 
| 124 | 
            -
                # @param instance [Instance] The instance object to run against.
         | 
| 125 | 
            -
                # @param state_file [StateFile] Instance state file object.
         | 
| 126 | 
            -
                # @param hook [Hash] Hook configration to use.
         | 
| 127 | 
            -
                # @return [void]
         | 
| 128 | 
            -
                def run_remote_hook(instance, state_file, hook)
         | 
| 129 | 
            -
                  # Check if we're in a state that makes sense to even try.
         | 
| 130 | 
            -
                  unless instance.last_action
         | 
| 131 | 
            -
                    if hook[:skippable]
         | 
| 132 | 
            -
                      # Just not even trying.
         | 
| 133 | 
            -
                      return
         | 
| 134 | 
            -
                    else
         | 
| 135 | 
            -
                      raise UserError, "Cannot use remote lifecycle hooks during phases when the instance is not available"
         | 
| 136 | 
            -
                    end
         | 
| 137 | 
            -
                  end
         | 
| 138 | 
            -
             | 
| 139 | 
            -
                  cmd = hook.fetch(:remote)
         | 
| 140 | 
            -
                  conn = instance.transport.connection(state_file.read)
         | 
| 141 | 
            -
                  conn.execute(cmd)
         | 
| 142 90 | 
             
                end
         | 
| 143 91 | 
             
              end
         | 
| 144 92 | 
             
            end
         | 
    
        data/lib/kitchen/loader/yaml.rb
    CHANGED
    
    
    
        data/lib/kitchen/logger.rb
    CHANGED
    
    | @@ -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
         | 
| @@ -51,6 +51,7 @@ module Kitchen | |
| 51 51 |  | 
| 52 52 | 
             
                  default_config :command_prefix, nil
         | 
| 53 53 |  | 
| 54 | 
            +
                  default_config :uploads, {}
         | 
| 54 55 | 
             
                  default_config :downloads, {}
         | 
| 55 56 |  | 
| 56 57 | 
             
                  expand_path_for :test_base_path
         | 
| @@ -72,6 +73,10 @@ module Kitchen | |
| 72 73 | 
             
                    sandbox_dirs = Util.list_directory(sandbox_path)
         | 
| 73 74 |  | 
| 74 75 | 
             
                    instance.transport.connection(state) do |conn|
         | 
| 76 | 
            +
                      config[:uploads].to_h.each do |locals, remote|
         | 
| 77 | 
            +
                        debug("Uploading #{Array(locals).join(", ")} to #{remote}")
         | 
| 78 | 
            +
                        conn.upload(locals.to_s, remote)
         | 
| 79 | 
            +
                      end
         | 
| 75 80 | 
             
                      conn.execute(install_command)
         | 
| 76 81 | 
             
                      conn.execute(init_command)
         | 
| 77 82 | 
             
                      info("Transferring files to #{instance.to_str}")
         | 
| @@ -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 | 
             
                    #
         | 
| @@ -40,9 +42,9 @@ module Kitchen | |
| 40 42 | 
             
                    # @param logger [Kitchen::Logger] a logger to use for output, defaults
         | 
| 41 43 | 
             
                    #   to `Kitchen.logger`
         | 
| 42 44 | 
             
                    def initialize(policyfile, path, logger: Kitchen.logger, always_update: false)
         | 
| 43 | 
            -
                      @policyfile | 
| 44 | 
            -
                      @path | 
| 45 | 
            -
                      @logger | 
| 45 | 
            +
                      @policyfile    = policyfile
         | 
| 46 | 
            +
                      @path          = path
         | 
| 47 | 
            +
                      @logger        = logger
         | 
| 46 48 | 
             
                      @always_update = always_update
         | 
| 47 49 | 
             
                    end
         | 
| 48 50 |  | 
| @@ -51,30 +53,29 @@ module Kitchen | |
| 51 53 | 
             
                    # @param logger [Kitchen::Logger] a logger to use for output, defaults
         | 
| 52 54 | 
             
                    #   to `Kitchen.logger`
         | 
| 53 55 | 
             
                    def self.load!(logger: Kitchen.logger)
         | 
| 54 | 
            -
                       | 
| 56 | 
            +
                      # intentionally left blank
         | 
| 55 57 | 
             
                    end
         | 
| 56 58 |  | 
| 57 59 | 
             
                    # Performs the cookbook resolution and vendors the resulting cookbooks
         | 
| 58 60 | 
             
                    # in the desired path.
         | 
| 59 61 | 
             
                    def resolve
         | 
| 60 | 
            -
                      info("Exporting cookbook dependencies from Policyfile #{path} | 
| 61 | 
            -
                      run_command(" | 
| 62 | 
            +
                      info("Exporting cookbook dependencies from Policyfile #{path} using `#{cli_path} export`...")
         | 
| 63 | 
            +
                      run_command("#{cli_path} export #{escape_path(policyfile)} #{escape_path(path)} --force")
         | 
| 62 64 | 
             
                    end
         | 
| 63 65 |  | 
| 64 66 | 
             
                    # Runs `chef install` to determine the correct cookbook set and
         | 
| 65 67 | 
             
                    # generate the policyfile lock.
         | 
| 66 68 | 
             
                    def compile
         | 
| 67 69 | 
             
                      if File.exist?(lockfile)
         | 
| 68 | 
            -
                        info("Installing cookbooks for Policyfile #{policyfile} using  | 
| 70 | 
            +
                        info("Installing cookbooks for Policyfile #{policyfile} using `#{cli_path} install`")
         | 
| 69 71 | 
             
                      else
         | 
| 70 | 
            -
                        info("Policy lock file doesn't exist, running  | 
| 71 | 
            -
                             "Policyfile #{policyfile}...")
         | 
| 72 | 
            +
                        info("Policy lock file doesn't exist, running `#{cli_path} install` for Policyfile #{policyfile}...")
         | 
| 72 73 | 
             
                      end
         | 
| 73 | 
            -
                      run_command(" | 
| 74 | 
            +
                      run_command("#{cli_path} install #{escape_path(policyfile)}")
         | 
| 74 75 |  | 
| 75 76 | 
             
                      if always_update
         | 
| 76 | 
            -
                        info("Updating policy lock using  | 
| 77 | 
            -
                        run_command(" | 
| 77 | 
            +
                        info("Updating policy lock using `#{cli_path} update`")
         | 
| 78 | 
            +
                        run_command("#{cli_path} update #{escape_path(policyfile)}")
         | 
| 78 79 | 
             
                      end
         | 
| 79 80 | 
             
                    end
         | 
| 80 81 |  | 
| @@ -126,33 +127,24 @@ module Kitchen | |
| 126 127 | 
             
                      end
         | 
| 127 128 | 
             
                    end
         | 
| 128 129 |  | 
| 129 | 
            -
                     | 
| 130 | 
            -
             | 
| 131 | 
            -
             | 
| 132 | 
            -
             | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 135 | 
            -
             | 
| 136 | 
            -
             | 
| 137 | 
            -
                       | 
| 138 | 
            -
             | 
| 139 | 
            -
             | 
| 140 | 
            -
             | 
| 141 | 
            -
             | 
| 142 | 
            -
             | 
| 143 | 
            -
             | 
| 144 | 
            -
             | 
| 145 | 
            -
             | 
| 146 | 
            -
             | 
| 147 | 
            -
                        end
         | 
| 148 | 
            -
                          logger.fatal("The `chef` executable cannot be found in your " \
         | 
| 149 | 
            -
                                      "PATH. Ensure you have installed ChefDK or 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
         | 
| 130 | 
            +
                    # Find the `chef` or `chef-cli` commands in the path or raise `chef` is present in
         | 
| 131 | 
            +
                    # ChefDK / Workstation releases, but is no longer shipped in any gems now that we
         | 
| 132 | 
            +
                    # use a Go based wrapper for the `chef` command in Workstation. The Ruby CLI has been
         | 
| 133 | 
            +
                    # renamed `chef-cli` under the hood and is shipped in the `chef-cli` gem.
         | 
| 134 | 
            +
                    #
         | 
| 135 | 
            +
                    # @api private
         | 
| 136 | 
            +
                    # @returns [String]
         | 
| 137 | 
            +
                    def cli_path
         | 
| 138 | 
            +
                      @cli_path ||= which("chef-cli") || which("chef") || no_cli_found_error
         | 
| 139 | 
            +
                    end
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                    # @api private
         | 
| 142 | 
            +
                    def no_cli_found_error
         | 
| 143 | 
            +
                      @logger.fatal("The `chef` or `chef-cli` executables cannot be found in your " \
         | 
| 144 | 
            +
                                    "PATH. Ensure you have installed Chef Workstation " \
         | 
| 145 | 
            +
                                    "from https://downloads.chef.io and that your PATH " \
         | 
| 146 | 
            +
                                    "setting includes the path to the `chef` or `chef-cli` commands.")
         | 
| 147 | 
            +
                      raise UserError, "Could not find the chef or chef-cli executables in your PATH."
         | 
| 156 148 | 
             
                    end
         | 
| 157 149 |  | 
| 158 150 | 
             
                  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  | 
| 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 | 
            -
                           | 
| 203 | 
            -
                             | 
| 204 | 
            -
             | 
| 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
         | 
| @@ -308,16 +308,20 @@ module Kitchen | |
| 308 308 |  | 
| 309 309 | 
             
                    # Builds a `LoginCommand` for use by Linux-based platforms.
         | 
| 310 310 | 
             
                    #
         | 
| 311 | 
            -
                    # TODO: determine whether or not `desktop` exists
         | 
| 312 | 
            -
                    #
         | 
| 313 311 | 
             
                    # @return [LoginCommand] a login command
         | 
| 314 312 | 
             
                    # @api private
         | 
| 315 313 | 
             
                    def login_command_for_linux
         | 
| 316 | 
            -
                       | 
| 317 | 
            -
                       | 
| 318 | 
            -
             | 
| 314 | 
            +
                      xfreerdp = Util.command_exists? "xfreerdp"
         | 
| 315 | 
            +
                      unless xfreerdp
         | 
| 316 | 
            +
                        raise WinrmFailed, "xfreerdp binary not found. Please install freerdp2-x11 on Debian-based systems or freerdp on Redhat-based systems."
         | 
| 317 | 
            +
                      end
         | 
| 318 | 
            +
             | 
| 319 | 
            +
                      args  = %W{/u:#{options[:user]}}
         | 
| 320 | 
            +
                      args += %W{/p:#{options[:password]}} if options.key?(:password)
         | 
| 321 | 
            +
                      args += %W{/v:#{URI.parse(options[:endpoint]).host}:#{rdp_port}}
         | 
| 322 | 
            +
                      args += %W{/cert-tofu} # always accept certificate
         | 
| 319 323 |  | 
| 320 | 
            -
                      LoginCommand.new( | 
| 324 | 
            +
                      LoginCommand.new(xfreerdp, args)
         | 
| 321 325 | 
             
                    end
         | 
| 322 326 |  | 
| 323 327 | 
             
                    # Builds a `LoginCommand` for use by Mac-based platforms.
         | 
    
        data/lib/kitchen/util.rb
    CHANGED
    
    | @@ -215,5 +215,15 @@ module Kitchen | |
| 215 215 | 
             
                def self.snake_case(a_string)
         | 
| 216 216 | 
             
                  Thor::Util.snake_case(a_string)
         | 
| 217 217 | 
             
                end
         | 
| 218 | 
            +
             | 
| 219 | 
            +
                # Check if a cmd exists on the PATH
         | 
| 220 | 
            +
                def self.command_exists?(cmd)
         | 
| 221 | 
            +
                  paths = ENV["PATH"].split(File::PATH_SEPARATOR) + [ "/bin", "/usr/bin", "/sbin", "/usr/sbin" ]
         | 
| 222 | 
            +
                  paths.each do |path|
         | 
| 223 | 
            +
                    filename = File.join(path, cmd)
         | 
| 224 | 
            +
                    return filename if File.executable?(filename)
         | 
| 225 | 
            +
                  end
         | 
| 226 | 
            +
                  false
         | 
| 227 | 
            +
                end
         | 
| 218 228 | 
             
              end
         | 
| 219 229 | 
             
            end
         | 
| @@ -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
         | 
    
        data/lib/kitchen/version.rb
    CHANGED
    
    
| @@ -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. | 
| 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
         | 
    
        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. | 
| 4 | 
            +
              version: 2.11.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: 2021-03-25 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
         | 
| @@ -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
         | 
| @@ -415,6 +430,9 @@ files: | |
| 415 430 | 
             
            - lib/kitchen/generator/init.rb
         | 
| 416 431 | 
             
            - lib/kitchen/instance.rb
         | 
| 417 432 | 
             
            - lib/kitchen/lazy_hash.rb
         | 
| 433 | 
            +
            - lib/kitchen/lifecycle_hook/base.rb
         | 
| 434 | 
            +
            - lib/kitchen/lifecycle_hook/local.rb
         | 
| 435 | 
            +
            - lib/kitchen/lifecycle_hook/remote.rb
         | 
| 418 436 | 
             
            - lib/kitchen/lifecycle_hooks.rb
         | 
| 419 437 | 
             
            - lib/kitchen/loader/yaml.rb
         | 
| 420 438 | 
             
            - lib/kitchen/logger.rb
         | 
| @@ -454,6 +472,7 @@ files: | |
| 454 472 | 
             
            - lib/kitchen/verifier/dummy.rb
         | 
| 455 473 | 
             
            - lib/kitchen/verifier/shell.rb
         | 
| 456 474 | 
             
            - lib/kitchen/version.rb
         | 
| 475 | 
            +
            - lib/kitchen/which.rb
         | 
| 457 476 | 
             
            - lib/vendor/hash_recursive_merge.rb
         | 
| 458 477 | 
             
            - support/busser_install_command.ps1
         | 
| 459 478 | 
             
            - support/busser_install_command.sh
         | 
| @@ -493,7 +512,7 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 493 512 | 
             
              requirements:
         | 
| 494 513 | 
             
              - - ">="
         | 
| 495 514 | 
             
                - !ruby/object:Gem::Version
         | 
| 496 | 
            -
                  version: '2. | 
| 515 | 
            +
                  version: '2.5'
         | 
| 497 516 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 498 517 | 
             
              requirements:
         | 
| 499 518 | 
             
              - - ">="
         |