Class: Kitchen::Provisioner::ChefTarget

Inherits:
ChefInfra show all
Defined in:
lib/kitchen/provisioner/chef_target.rb

Overview

Chef Target provisioner.

Author:

Defined Under Namespace

Classes: ChefClientNotFound, ChefVersionTooLow, RequireTrainTransport

Constant Summary collapse

MIN_VERSION_REQUIRED =
"19.0.0".freeze

Instance Attribute Summary

Attributes included from Configurable

#instance

Instance Method Summary collapse

Methods inherited from ChefInfra

#run_command

Methods inherited from ChefBase

#check_license, #doctor, #initialize, #license_acceptance_id, #product_version

Methods inherited from Base

#check_license, #cleanup_sandbox, #doctor, #initialize, kitchen_provisioner_api_version, #run_command, #sandbox_dirs, #sandbox_path

Methods included from Logging

#banner, #debug, #error, #fatal, #info, #warn

Methods included from Configurable

#[], #bourne_shell?, #calculate_path, #config_keys, #diagnose, #diagnose_plugin, #finalize_config!, included, #name, #powershell_shell?, #remote_path_join, #unix_os?, #verify_dependencies, #windows_os?

Methods inherited from Kitchen::Plugin::Base

no_parallel_for

Constructor Details

This class inherits a constructor from Kitchen::Provisioner::ChefBase

Instance Method Details

#call(state) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/kitchen/provisioner/chef_target.rb', line 99

def call(state)
  remote_connection = instance.transport.connection(state)

  config[:uploads].to_h.each do |locals, remote|
    debug("Uploading #{Array(locals).join(", ")} to #{remote}")
    remote_connection.upload(locals.to_s, remote)
  end

  # no installation
  create_sandbox
  # no prepare command

  # Stream output to logger
  require "open3"
  Open3.popen2e(run_command) do |_stdin, output, _thread|
    output.each { |line| logger << line }
  end

  info("Downloading files from #{instance.to_str}")
  config[:downloads].to_h.each do |remotes, local|
    debug("Downloading #{Array(remotes).join(", ")} to #{local}")
    remote_connection.download(remotes, local)
  end
  debug("Download complete")
rescue Kitchen::Transport::TransportFailed => ex
  raise ActionFailed, ex.message
ensure
  cleanup_sandbox
end

#check_local_chef_clientObject



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/kitchen/provisioner/chef_target.rb', line 66

def check_local_chef_client
  debug("Checking for chef-client version")

  begin
    client_version = `chef-client -v`.chop.split(":")[-1]
  rescue Errno::ENOENT => e
    error("Error determining Chef Infra version: #{e.exception.message}")
    raise ChefClientNotFound.new("Need chef-client installed locally")
  end

  minimum_version = Gem::Version.new(MIN_VERSION_REQUIRED)
  installed_version = Gem::Version.new(client_version)

  if installed_version < minimum_version
    error("Found Chef Infra version #{installed_version}, but require #{minimum_version} for Target Mode")
    raise ChefVersionTooLow.new("Need version #{MIN_VERSION_REQUIRED} or higher")
  end

  debug("Chef Infra found and version constraints match")
end

#check_transport(connection) ⇒ Object



55
56
57
58
59
60
61
62
63
64
# File 'lib/kitchen/provisioner/chef_target.rb', line 55

def check_transport(connection)
  debug("Checking for active transport")

  unless connection.respond_to? "train_uri"
    error("Chef Target Mode provisioner requires a Train-based transport like kitchen-transport-train")
    raise RequireTrainTransport.new("No Train transport")
  end

  debug("Kitchen transport responds to train_uri function call, as required")
end

#chef_args(client_rb_filename) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/kitchen/provisioner/chef_target.rb', line 38

def chef_args(client_rb_filename)
  # Dummy execution to initialize and test remote connection
  connection = instance.remote_exec("echo Connection established")

  check_transport(connection)
  check_local_chef_client

  instance_name = instance.name
  credentials_file = File.join(kitchen_basepath, ".kitchen", instance_name + ".ini")
  File.write(credentials_file, connection.credentials_file)

  super.concat([
    "--target #{instance_name}",
    "--credentials #{credentials_file}",
  ])
end

#create_sandboxObject



91
92
93
94
95
96
97
# File 'lib/kitchen/provisioner/chef_target.rb', line 91

def create_sandbox
  super

  # Change config.rb to point to the local sandbox path, not to /tmp/kitchen
  config[:root_path] = sandbox_path
  prepare_config_rb
end

#init_commandObject



35
# File 'lib/kitchen/provisioner/chef_target.rb', line 35

def init_command; ""; end

#install_commandObject



34
# File 'lib/kitchen/provisioner/chef_target.rb', line 34

def install_command; ""; end

#kitchen_basepathObject



87
88
89
# File 'lib/kitchen/provisioner/chef_target.rb', line 87

def kitchen_basepath
  instance.driver.config[:kitchen_root]
end

#prepare_commandObject



36
# File 'lib/kitchen/provisioner/chef_target.rb', line 36

def prepare_command; ""; end