117 lines
4.2 KiB
Ruby
117 lines
4.2 KiB
Ruby
require 'pathname'
|
|
require 'vagrant/util/subprocess'
|
|
|
|
require File.expand_path("../base", __FILE__)
|
|
|
|
module VagrantPlugins
|
|
module Chef
|
|
module Provisioner
|
|
# This class implements provisioning via chef-client, allowing provisioning
|
|
# with a chef server.
|
|
class ChefClient < Base
|
|
def configure(root_config)
|
|
raise ChefError, :server_validation_key_required if @config.validation_key_path.nil?
|
|
raise ChefError, :server_validation_key_doesnt_exist if !File.file?(validation_key_path)
|
|
raise ChefError, :server_url_required if @config.chef_server_url.nil?
|
|
end
|
|
|
|
def provision
|
|
verify_binary(chef_binary_path("chef-client"))
|
|
chown_provisioning_folder
|
|
create_client_key_folder
|
|
upload_validation_key
|
|
upload_encrypted_data_bag_secret
|
|
setup_json
|
|
setup_server_config
|
|
run_chef_client
|
|
delete_encrypted_data_bag_secret
|
|
end
|
|
|
|
def cleanup
|
|
delete_from_chef_server('client') if @config.delete_client
|
|
delete_from_chef_server('node') if @config.delete_node
|
|
end
|
|
|
|
def create_client_key_folder
|
|
@machine.env.ui.info I18n.t("vagrant.provisioners.chef.client_key_folder")
|
|
path = Pathname.new(@config.client_key_path)
|
|
|
|
@machine.communicate.sudo("mkdir -p #{path.dirname}")
|
|
end
|
|
|
|
def upload_validation_key
|
|
@machine.env.ui.info I18n.t("vagrant.provisioners.chef.upload_validation_key")
|
|
@machine.communicate.upload(validation_key_path, guest_validation_key_path)
|
|
end
|
|
|
|
def setup_server_config
|
|
setup_config("provisioners/chef_client/client", "client.rb", {
|
|
:chef_server_url => @config.chef_server_url,
|
|
:validation_client_name => @config.validation_client_name,
|
|
:validation_key => guest_validation_key_path,
|
|
:client_key => @config.client_key_path,
|
|
})
|
|
end
|
|
|
|
def run_chef_client
|
|
if @config.run_list && @config.run_list.empty?
|
|
@machine.ui.warn(I18n.t("vagrant.chef_run_list_empty"))
|
|
end
|
|
|
|
command_env = @config.binary_env ? "#{@config.binary_env} " : ""
|
|
command_args = @config.arguments ? " #{@config.arguments}" : ""
|
|
command = "#{command_env}#{chef_binary_path("chef-client")} " +
|
|
"-c #{@config.provisioning_path}/client.rb " +
|
|
"-j #{@config.provisioning_path}/dna.json #{command_args}"
|
|
|
|
@config.attempts.times do |attempt|
|
|
if attempt == 0
|
|
@machine.env.ui.info I18n.t("vagrant.provisioners.chef.running_client")
|
|
else
|
|
@machine.env.ui.info I18n.t("vagrant.provisioners.chef.running_client_again")
|
|
end
|
|
|
|
exit_status = @machine.communicate.sudo(command, :error_check => false) do |type, data|
|
|
# Output the data with the proper color based on the stream.
|
|
color = type == :stdout ? :green : :red
|
|
@machine.env.ui.info(
|
|
data, :color => color, :new_line => false, :prefix => false)
|
|
end
|
|
|
|
# There is no need to run Chef again if it converges
|
|
return if exit_status == 0
|
|
end
|
|
|
|
# If we reached this point then Chef never converged! Error.
|
|
raise ChefError, :no_convergence
|
|
end
|
|
|
|
def validation_key_path
|
|
File.expand_path(@config.validation_key_path, @machine.env.root_path)
|
|
end
|
|
|
|
def guest_validation_key_path
|
|
File.join(@config.provisioning_path, "validation.pem")
|
|
end
|
|
|
|
def delete_from_chef_server(deletable)
|
|
node_name = @config.node_name || @machine.config.vm.hostname
|
|
@machine.env.ui.info(I18n.t(
|
|
"vagrant.provisioners.chef.deleting_from_server",
|
|
deletable: deletable, name: node_name))
|
|
|
|
command = ["knife", deletable, "delete", "--yes", node_name]
|
|
r = Vagrant::Util::Subprocess.execute(*command)
|
|
if r.exit_code != 0
|
|
@machine.env.ui.error(I18n.t(
|
|
"vagrant.chef_client_cleanup_failed",
|
|
deletable: deletable,
|
|
stdout: r.stdout,
|
|
stderr: r.stderr))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|