2012-04-19 04:53:19 +00:00
|
|
|
require 'pathname'
|
2014-08-06 17:24:05 +00:00
|
|
|
|
|
|
|
require 'vagrant'
|
2015-11-23 23:14:32 +00:00
|
|
|
require 'vagrant/util/presence'
|
2013-08-29 18:26:21 +00:00
|
|
|
require 'vagrant/util/subprocess'
|
2012-04-19 04:53:19 +00:00
|
|
|
|
2014-10-30 15:21:56 +00:00
|
|
|
require_relative "base"
|
2012-04-19 04:53:19 +00:00
|
|
|
|
|
|
|
module VagrantPlugins
|
|
|
|
module Chef
|
|
|
|
module Provisioner
|
|
|
|
# This class implements provisioning via chef-client, allowing provisioning
|
|
|
|
# with a chef server.
|
|
|
|
class ChefClient < Base
|
2015-11-23 23:14:32 +00:00
|
|
|
include Vagrant::Util::Presence
|
|
|
|
|
2013-01-14 00:41:32 +00:00
|
|
|
def configure(root_config)
|
|
|
|
raise ChefError, :server_validation_key_required if @config.validation_key_path.nil?
|
2012-04-19 04:53:19 +00:00
|
|
|
raise ChefError, :server_validation_key_doesnt_exist if !File.file?(validation_key_path)
|
2013-01-14 00:41:32 +00:00
|
|
|
raise ChefError, :server_url_required if @config.chef_server_url.nil?
|
2012-04-19 04:53:19 +00:00
|
|
|
end
|
|
|
|
|
2013-01-14 00:51:16 +00:00
|
|
|
def provision
|
2014-10-31 20:06:05 +00:00
|
|
|
install_chef
|
2012-04-19 04:53:19 +00:00
|
|
|
verify_binary(chef_binary_path("chef-client"))
|
|
|
|
chown_provisioning_folder
|
|
|
|
create_client_key_folder
|
|
|
|
upload_validation_key
|
2014-01-17 02:03:38 +00:00
|
|
|
upload_encrypted_data_bag_secret
|
2012-04-19 04:53:19 +00:00
|
|
|
setup_json
|
|
|
|
setup_server_config
|
|
|
|
run_chef_client
|
2014-01-17 02:03:38 +00:00
|
|
|
delete_encrypted_data_bag_secret
|
2012-04-19 04:53:19 +00:00
|
|
|
end
|
|
|
|
|
2013-08-29 18:13:43 +00:00
|
|
|
def cleanup
|
2015-11-19 19:25:34 +00:00
|
|
|
if @config.delete_node
|
|
|
|
delete_from_chef_server("node")
|
|
|
|
end
|
|
|
|
|
|
|
|
if @config.delete_client
|
|
|
|
delete_from_chef_server("client")
|
|
|
|
end
|
2013-08-29 18:13:43 +00:00
|
|
|
end
|
|
|
|
|
2012-04-19 04:53:19 +00:00
|
|
|
def create_client_key_folder
|
2014-04-19 06:48:05 +00:00
|
|
|
@machine.ui.info I18n.t("vagrant.provisioners.chef.client_key_folder")
|
2015-07-09 22:55:55 +00:00
|
|
|
path = Pathname.new(guest_client_key_path)
|
2012-04-19 04:53:19 +00:00
|
|
|
|
2015-05-02 14:47:11 +00:00
|
|
|
if windows?
|
|
|
|
@machine.communicate.sudo("mkdir ""#{path.dirname}"" -f")
|
|
|
|
else
|
|
|
|
@machine.communicate.sudo("mkdir -p #{path.dirname}")
|
|
|
|
end
|
2012-04-19 04:53:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def upload_validation_key
|
2014-04-19 06:48:05 +00:00
|
|
|
@machine.ui.info I18n.t("vagrant.provisioners.chef.upload_validation_key")
|
2013-01-14 00:41:32 +00:00
|
|
|
@machine.communicate.upload(validation_key_path, guest_validation_key_path)
|
2012-04-19 04:53:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def setup_server_config
|
|
|
|
setup_config("provisioners/chef_client/client", "client.rb", {
|
2014-05-22 16:35:12 +00:00
|
|
|
chef_server_url: @config.chef_server_url,
|
|
|
|
validation_client_name: @config.validation_client_name,
|
|
|
|
validation_key: guest_validation_key_path,
|
2015-07-09 22:55:55 +00:00
|
|
|
client_key: guest_client_key_path,
|
2012-04-19 04:53:19 +00:00
|
|
|
})
|
|
|
|
end
|
|
|
|
|
|
|
|
def run_chef_client
|
2013-04-19 16:11:43 +00:00
|
|
|
if @config.run_list && @config.run_list.empty?
|
|
|
|
@machine.ui.warn(I18n.t("vagrant.chef_run_list_empty"))
|
|
|
|
end
|
|
|
|
|
2015-07-10 03:23:42 +00:00
|
|
|
command = CommandBuilder.command(:client, @config,
|
|
|
|
windows: windows?,
|
|
|
|
colored: @machine.env.ui.color?,
|
|
|
|
)
|
2017-08-10 10:39:41 +00:00
|
|
|
|
|
|
|
still_active = 259 #provisioner has asked chef to reboot
|
|
|
|
|
2013-01-14 00:41:32 +00:00
|
|
|
@config.attempts.times do |attempt|
|
2017-08-10 10:39:41 +00:00
|
|
|
exit_status = 0
|
|
|
|
while exit_status == 0 || exit_status == still_active
|
|
|
|
if @machine.guest.capability?(:wait_for_reboot)
|
|
|
|
@machine.guest.capability(:wait_for_reboot)
|
|
|
|
elsif attempt > 0
|
|
|
|
sleep 10
|
|
|
|
@machine.communicate.wait_for_ready(@machine.config.vm.boot_timeout)
|
|
|
|
end
|
|
|
|
if attempt == 0
|
|
|
|
@machine.ui.info I18n.t("vagrant.provisioners.chef.running_client")
|
|
|
|
else
|
|
|
|
@machine.ui.info I18n.t("vagrant.provisioners.chef.running_client_again")
|
|
|
|
end
|
|
|
|
|
|
|
|
opts = { error_check: false, elevated: true }
|
|
|
|
exit_status = @machine.communicate.sudo(command, opts) do |type, data|
|
|
|
|
# Output the data with the proper color based on the stream.
|
|
|
|
color = type == :stdout ? :green : :red
|
|
|
|
|
|
|
|
data = data.chomp
|
|
|
|
next if data.empty?
|
|
|
|
|
|
|
|
@machine.ui.info(data, color: color)
|
|
|
|
end
|
|
|
|
|
|
|
|
# There is no need to run Chef again if it converges
|
|
|
|
return if exit_status == 0
|
2012-04-19 04:53:19 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# If we reached this point then Chef never converged! Error.
|
|
|
|
raise ChefError, :no_convergence
|
|
|
|
end
|
|
|
|
|
|
|
|
def validation_key_path
|
2013-01-14 00:41:32 +00:00
|
|
|
File.expand_path(@config.validation_key_path, @machine.env.root_path)
|
2012-04-19 04:53:19 +00:00
|
|
|
end
|
|
|
|
|
2015-07-09 22:55:55 +00:00
|
|
|
def guest_client_key_path
|
|
|
|
if !@config.client_key_path.nil?
|
|
|
|
return @config.client_key_path
|
|
|
|
end
|
|
|
|
|
|
|
|
if windows?
|
|
|
|
"C:/chef/client.pem"
|
|
|
|
else
|
|
|
|
"/etc/chef/client.pem"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-11-19 02:28:33 +00:00
|
|
|
def guest_client_rb_path
|
|
|
|
File.join(guest_provisioning_path, "client.rb")
|
|
|
|
end
|
|
|
|
|
2012-04-19 04:53:19 +00:00
|
|
|
def guest_validation_key_path
|
2015-07-09 22:55:55 +00:00
|
|
|
File.join(guest_provisioning_path, "validation.pem")
|
2012-04-19 04:53:19 +00:00
|
|
|
end
|
2012-12-17 16:49:27 +00:00
|
|
|
|
|
|
|
def delete_from_chef_server(deletable)
|
2016-03-18 01:15:11 +00:00
|
|
|
node_name = @config.node_name
|
2015-11-19 00:55:37 +00:00
|
|
|
|
2015-11-23 23:14:32 +00:00
|
|
|
if !present?(node_name)
|
2015-11-19 00:55:37 +00:00
|
|
|
@machine.ui.warn(I18n.t("vagrant.provisioners.chef.missing_node_name",
|
|
|
|
deletable: deletable,
|
|
|
|
))
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2015-11-19 02:28:33 +00:00
|
|
|
@machine.ui.info(I18n.t("vagrant.provisioners.chef.deleting_from_server",
|
2013-08-29 18:13:43 +00:00
|
|
|
deletable: deletable, name: node_name))
|
2013-08-29 18:26:21 +00:00
|
|
|
|
2015-11-19 02:28:33 +00:00
|
|
|
command = "knife #{deletable} delete #{node_name}"
|
|
|
|
command << " --config '#{guest_client_rb_path}'"
|
|
|
|
command << " --yes"
|
2015-11-19 22:55:46 +00:00
|
|
|
|
|
|
|
output = []
|
|
|
|
result = @machine.communicate.sudo(command, error_check: false) do |_, data|
|
|
|
|
output << data
|
|
|
|
end
|
|
|
|
|
|
|
|
if result != 0
|
|
|
|
@machine.ui.error("There were errors removing the #{deletable} from the Chef Server:")
|
|
|
|
@machine.ui.error("")
|
|
|
|
@machine.ui.error(output.join("\n"))
|
|
|
|
@machine.ui.error("")
|
|
|
|
@machine.ui.error("Vagrant will continue destroying the virtual machine, but you may need")
|
|
|
|
@machine.ui.error("to manually delete the #{deletable} from the Chef Server!")
|
|
|
|
end
|
2012-12-17 16:49:27 +00:00
|
|
|
end
|
2012-04-19 04:53:19 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|