2012-04-19 04:53:19 +00:00
|
|
|
require 'tempfile'
|
|
|
|
|
2015-11-23 23:14:32 +00:00
|
|
|
require "vagrant/util/presence"
|
2012-06-28 15:29:48 +00:00
|
|
|
require "vagrant/util/template_renderer"
|
|
|
|
|
2014-10-31 20:06:05 +00:00
|
|
|
require_relative "../installer"
|
|
|
|
|
2012-04-19 04:53:19 +00:00
|
|
|
module VagrantPlugins
|
|
|
|
module Chef
|
|
|
|
module Provisioner
|
|
|
|
# This class is a base class where the common functionality shared between
|
|
|
|
# chef-solo and chef-client provisioning are stored. This is **not an actual
|
|
|
|
# provisioner**. Instead, {ChefSolo} or {ChefServer} should be used.
|
2012-11-07 05:21:36 +00:00
|
|
|
class Base < Vagrant.plugin("2", :provisioner)
|
2015-11-23 23:14:32 +00:00
|
|
|
include Vagrant::Util::Presence
|
|
|
|
|
2013-01-14 00:41:32 +00:00
|
|
|
class ChefError < Vagrant::Errors::VagrantError
|
|
|
|
error_namespace("vagrant.provisioners.chef")
|
|
|
|
end
|
|
|
|
|
2014-10-31 20:06:05 +00:00
|
|
|
def initialize(machine, config)
|
|
|
|
super
|
|
|
|
|
|
|
|
@logger = Log4r::Logger.new("vagrant::provisioners::chef")
|
2015-11-19 19:25:34 +00:00
|
|
|
|
2015-11-23 23:14:32 +00:00
|
|
|
if !present?(@config.node_name)
|
2016-03-18 01:15:11 +00:00
|
|
|
# First attempt to get the node name from the hostname, and if that
|
|
|
|
# is not present, generate/retrieve a random hostname.
|
|
|
|
hostname = @machine.config.vm.hostname
|
|
|
|
if present?(hostname)
|
|
|
|
@machine.ui.info I18n.t("vagrant.provisioners.chef.using_hostname_node_name",
|
|
|
|
hostname: hostname,
|
|
|
|
)
|
|
|
|
@config.node_name = hostname
|
|
|
|
else
|
|
|
|
cache = @machine.data_dir.join("chef_node_name")
|
|
|
|
if !cache.exist?
|
|
|
|
@machine.ui.info I18n.t("vagrant.provisioners.chef.generating_node_name")
|
|
|
|
cache.open("w+") do |f|
|
|
|
|
f.write("vagrant-#{SecureRandom.hex(4)}")
|
|
|
|
end
|
2015-11-19 19:25:34 +00:00
|
|
|
end
|
|
|
|
|
2016-03-18 01:15:11 +00:00
|
|
|
if cache.file?
|
|
|
|
@logger.info("Loading cached node_name...")
|
|
|
|
@config.node_name = cache.read.strip
|
|
|
|
end
|
2015-11-19 19:25:34 +00:00
|
|
|
end
|
|
|
|
end
|
2014-10-31 20:06:05 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def install_chef
|
|
|
|
return if !config.install
|
|
|
|
|
|
|
|
@logger.info("Checking for Chef installation...")
|
|
|
|
installer = Installer.new(@machine,
|
2015-11-19 22:57:01 +00:00
|
|
|
product: config.product,
|
|
|
|
channel: config.channel,
|
|
|
|
version: config.version,
|
|
|
|
force: config.install == :force,
|
2014-12-16 23:48:34 +00:00
|
|
|
download_path: config.installer_download_path
|
2014-10-31 20:06:05 +00:00
|
|
|
)
|
|
|
|
installer.ensure_installed
|
|
|
|
end
|
|
|
|
|
2012-04-19 04:53:19 +00:00
|
|
|
def verify_binary(binary)
|
|
|
|
# Checks for the existence of chef binary and error if it
|
|
|
|
# doesn't exist.
|
2015-05-02 14:47:11 +00:00
|
|
|
if windows?
|
|
|
|
command = "if ((&'#{binary}' -v) -Match 'Chef: *'){ exit 0 } else { exit 1 }"
|
|
|
|
else
|
|
|
|
command = "sh -c 'command -v #{binary}'"
|
|
|
|
end
|
|
|
|
|
2013-01-14 00:41:32 +00:00
|
|
|
@machine.communicate.sudo(
|
2015-05-02 14:47:11 +00:00
|
|
|
command,
|
2014-05-22 16:35:12 +00:00
|
|
|
error_class: ChefError,
|
|
|
|
error_key: :chef_not_detected,
|
2014-10-31 20:06:05 +00:00
|
|
|
binary: binary,
|
|
|
|
)
|
2012-04-19 04:53:19 +00:00
|
|
|
end
|
2014-04-12 22:00:28 +00:00
|
|
|
|
2012-04-19 04:53:19 +00:00
|
|
|
# Returns the path to the Chef binary, taking into account the
|
|
|
|
# `binary_path` configuration option.
|
|
|
|
def chef_binary_path(binary)
|
2013-01-14 00:41:32 +00:00
|
|
|
return binary if !@config.binary_path
|
|
|
|
return File.join(@config.binary_path, binary)
|
2012-04-19 04:53:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def chown_provisioning_folder
|
2015-07-09 22:55:55 +00:00
|
|
|
paths = [
|
|
|
|
guest_provisioning_path,
|
|
|
|
guest_file_backup_path,
|
|
|
|
guest_file_cache_path,
|
|
|
|
]
|
2013-12-04 19:51:05 +00:00
|
|
|
|
2013-01-14 00:41:32 +00:00
|
|
|
@machine.communicate.tap do |comm|
|
2013-12-04 19:51:05 +00:00
|
|
|
paths.each do |path|
|
2015-05-02 14:47:11 +00:00
|
|
|
if windows?
|
|
|
|
comm.sudo("mkdir ""#{path}"" -f")
|
|
|
|
else
|
|
|
|
comm.sudo("mkdir -p #{path}")
|
|
|
|
comm.sudo("chown -h #{@machine.ssh_info[:username]} #{path}")
|
|
|
|
end
|
2013-12-04 19:51:05 +00:00
|
|
|
end
|
2012-08-21 23:57:17 +00:00
|
|
|
end
|
2012-04-19 04:53:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def setup_config(template, filename, template_vars)
|
2013-07-11 02:31:52 +00:00
|
|
|
# If we have custom configuration, upload it
|
|
|
|
remote_custom_config_path = nil
|
|
|
|
if @config.custom_config_path
|
|
|
|
expanded = File.expand_path(
|
|
|
|
@config.custom_config_path, @machine.env.root_path)
|
|
|
|
remote_custom_config_path = File.join(
|
2015-07-09 22:55:55 +00:00
|
|
|
guest_provisioning_path, "custom-config.rb")
|
2013-07-11 02:31:52 +00:00
|
|
|
|
|
|
|
@machine.communicate.upload(expanded, remote_custom_config_path)
|
|
|
|
end
|
|
|
|
|
2012-06-28 15:29:48 +00:00
|
|
|
config_file = Vagrant::Util::TemplateRenderer.render(template, {
|
2014-05-22 16:35:12 +00:00
|
|
|
custom_configuration: remote_custom_config_path,
|
|
|
|
encrypted_data_bag_secret: guest_encrypted_data_bag_secret_key_path,
|
|
|
|
environment: @config.environment,
|
2015-07-09 23:01:36 +00:00
|
|
|
file_cache_path: guest_file_cache_path,
|
|
|
|
file_backup_path: guest_file_backup_path,
|
2014-05-22 16:35:12 +00:00
|
|
|
log_level: @config.log_level.to_sym,
|
|
|
|
node_name: @config.node_name,
|
|
|
|
verbose_logging: @config.verbose_logging,
|
2015-02-14 21:28:32 +00:00
|
|
|
enable_reporting: @config.enable_reporting,
|
2014-05-22 16:35:12 +00:00
|
|
|
http_proxy: @config.http_proxy,
|
|
|
|
http_proxy_user: @config.http_proxy_user,
|
|
|
|
http_proxy_pass: @config.http_proxy_pass,
|
|
|
|
https_proxy: @config.https_proxy,
|
|
|
|
https_proxy_user: @config.https_proxy_user,
|
|
|
|
https_proxy_pass: @config.https_proxy_pass,
|
|
|
|
no_proxy: @config.no_proxy,
|
|
|
|
formatter: @config.formatter
|
2012-04-19 04:53:19 +00:00
|
|
|
}.merge(template_vars))
|
|
|
|
|
|
|
|
# Create a temporary file to store the data so we
|
|
|
|
# can upload it
|
|
|
|
temp = Tempfile.new("vagrant")
|
|
|
|
temp.write(config_file)
|
|
|
|
temp.close
|
|
|
|
|
2015-07-09 22:55:55 +00:00
|
|
|
remote_file = File.join(guest_provisioning_path, filename)
|
2013-01-14 00:41:32 +00:00
|
|
|
@machine.communicate.tap do |comm|
|
2014-05-22 16:35:12 +00:00
|
|
|
comm.sudo("rm -f #{remote_file}", error_check: false)
|
2012-08-21 23:57:17 +00:00
|
|
|
comm.upload(temp.path, remote_file)
|
|
|
|
end
|
2012-04-19 04:53:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def setup_json
|
2015-11-19 19:25:34 +00:00
|
|
|
@machine.ui.info I18n.t("vagrant.provisioners.chef.json")
|
2012-04-19 04:53:19 +00:00
|
|
|
|
2012-05-02 05:03:54 +00:00
|
|
|
# Get the JSON that we're going to expose to Chef
|
2013-04-16 20:23:00 +00:00
|
|
|
json = @config.json
|
2015-07-06 00:30:29 +00:00
|
|
|
json[:run_list] = @config.run_list if @config.run_list &&
|
|
|
|
!@config.run_list.empty?
|
2013-04-16 20:23:00 +00:00
|
|
|
json = JSON.pretty_generate(json)
|
2012-04-19 04:53:19 +00:00
|
|
|
|
|
|
|
# Create a temporary file to store the data so we
|
|
|
|
# can upload it
|
|
|
|
temp = Tempfile.new("vagrant")
|
|
|
|
temp.write(json)
|
|
|
|
temp.close
|
|
|
|
|
2015-07-09 22:55:55 +00:00
|
|
|
remote_file = File.join(guest_provisioning_path, "dna.json")
|
2013-07-11 03:26:53 +00:00
|
|
|
@machine.communicate.tap do |comm|
|
2015-05-02 14:47:11 +00:00
|
|
|
if windows?
|
|
|
|
command = "if (test-path '#{remote_file}') {rm '#{remote_file}' -force -recurse}"
|
|
|
|
else
|
|
|
|
command = "rm -f #{remote_file}"
|
|
|
|
end
|
|
|
|
|
|
|
|
comm.sudo(command, error_check: false)
|
2013-07-11 03:26:53 +00:00
|
|
|
comm.upload(temp.path, remote_file)
|
|
|
|
end
|
2012-04-19 04:53:19 +00:00
|
|
|
end
|
2014-01-17 02:03:38 +00:00
|
|
|
|
|
|
|
def upload_encrypted_data_bag_secret
|
2014-02-16 21:14:56 +00:00
|
|
|
remote_file = guest_encrypted_data_bag_secret_key_path
|
|
|
|
return if !remote_file
|
2014-01-17 02:03:38 +00:00
|
|
|
|
2015-11-19 19:25:34 +00:00
|
|
|
@machine.ui.info I18n.t(
|
2014-01-17 02:03:38 +00:00
|
|
|
"vagrant.provisioners.chef.upload_encrypted_data_bag_secret_key")
|
|
|
|
|
|
|
|
@machine.communicate.tap do |comm|
|
2015-05-02 14:47:11 +00:00
|
|
|
if windows?
|
|
|
|
command = "if (test-path ""#{remote_file}"") {rm ""#{remote_file}"" -force -recurse}"
|
|
|
|
else
|
|
|
|
command = "rm -f #{remote_file}"
|
|
|
|
end
|
|
|
|
|
|
|
|
comm.sudo(command, error_check: false)
|
2014-01-17 02:03:38 +00:00
|
|
|
comm.upload(encrypted_data_bag_secret_key_path, remote_file)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def delete_encrypted_data_bag_secret
|
2014-02-16 21:14:56 +00:00
|
|
|
remote_file = guest_encrypted_data_bag_secret_key_path
|
|
|
|
if remote_file
|
2015-05-02 14:47:11 +00:00
|
|
|
if windows?
|
|
|
|
command = "if (test-path ""#{remote_file}"") {rm ""#{remote_file}"" -force -recurse}"
|
|
|
|
else
|
|
|
|
command = "rm -f #{remote_file}"
|
|
|
|
end
|
|
|
|
|
|
|
|
@machine.communicate.sudo(command, error_check: false)
|
2014-02-16 21:14:56 +00:00
|
|
|
end
|
2014-01-17 02:03:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def encrypted_data_bag_secret_key_path
|
|
|
|
File.expand_path(@config.encrypted_data_bag_secret_key_path,
|
|
|
|
@machine.env.root_path)
|
|
|
|
end
|
|
|
|
|
|
|
|
def guest_encrypted_data_bag_secret_key_path
|
2014-02-16 21:14:56 +00:00
|
|
|
if @config.encrypted_data_bag_secret_key_path
|
2015-07-09 22:55:55 +00:00
|
|
|
File.join(guest_provisioning_path, "encrypted_data_bag_secret_key")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def guest_provisioning_path
|
|
|
|
if !@config.provisioning_path.nil?
|
|
|
|
return @config.provisioning_path
|
|
|
|
end
|
|
|
|
|
|
|
|
if windows?
|
|
|
|
"C:/vagrant-chef"
|
|
|
|
else
|
|
|
|
"/tmp/vagrant-chef"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def guest_file_backup_path
|
|
|
|
if !@config.file_backup_path.nil?
|
|
|
|
return @config.file_backup_path
|
|
|
|
end
|
|
|
|
|
|
|
|
if windows?
|
|
|
|
"C:/chef/backup"
|
|
|
|
else
|
|
|
|
"/var/chef/backup"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def guest_file_cache_path
|
|
|
|
if !@config.file_cache_path.nil?
|
|
|
|
return @config.file_cache_path
|
|
|
|
end
|
|
|
|
|
|
|
|
if windows?
|
|
|
|
"C:/chef/cache"
|
|
|
|
else
|
|
|
|
"/var/chef/cache"
|
2014-02-16 21:14:56 +00:00
|
|
|
end
|
2014-01-17 02:03:38 +00:00
|
|
|
end
|
2014-04-12 21:46:57 +00:00
|
|
|
|
|
|
|
def windows?
|
|
|
|
@machine.config.vm.communicator == :winrm
|
|
|
|
end
|
2012-04-19 04:53:19 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|