class Kitchen::Provisioner::ChefTarget
@author Thomas Heinen <thomas.heinen@gmail.com>
for enterprise Chef features.
or kitchen-cinc if they are installed, providing a seamless upgrade path
This provisioner will automatically detect and use kitchen-chef-enterprise
Chef Target provisioner with enterprise gem delegation support.
def self.new(config = {})
-
(ChefTarget)- provisioner instance
Parameters:
-
config(Hash) -- configuration hash
def self.new(config = {}) enterprise_gem = ChefBase.enterprise_gem_available? if enterprise_gem begin omnibus_chef_class = self require "#{enterprise_gem}/provisioner/chef_target" enterprise_class = Kitchen::Provisioner.const_get(:ChefTarget) if enterprise_class != omnibus_chef_class if config[:instance] && config[:instance].respond_to?(:logger) config[:instance].logger.info("Using #{enterprise_gem} implementation of ChefTarget provisioner") end return enterprise_class.allocate.tap { |instance| instance.send(:initialize, config) } end rescue LoadError, NameError => e if config[:instance] && config[:instance].respond_to?(:logger) config[:instance].logger.debug("Could not load enterprise provisioner, using kitchen-omnibus-chef: #{e.message}") end end end allocate.tap { |instance| instance.send(:initialize, config) } end
def call(state)
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
def check_local_chef_client
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
def check_transport(connection)
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
def chef_args(client_rb_filename)
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.push( "--target #{instance_name}", "--credentials #{credentials_file}" ) end
def create_sandbox
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
def init_command; ""; end
def init_command; ""; end
def install_command; ""; end
def install_command; ""; end
def kitchen_basepath
def kitchen_basepath instance.driver.config[:kitchen_root] end
def prepare_command; ""; end
def prepare_command; ""; end