parent
294812fb13
commit
4b1847acf3
|
@ -1,52 +1,66 @@
|
||||||
module VagrantPlugins
|
module VagrantPlugins
|
||||||
module Chef
|
module Chef
|
||||||
class CommandBuilder
|
class CommandBuilder
|
||||||
def initialize(config, client_type, is_windows = false, is_ui_colored = false)
|
def self.command(type, config, options = {})
|
||||||
@client_type = client_type
|
new(type, config, options).command
|
||||||
@config = config
|
end
|
||||||
@is_windows = is_windows
|
|
||||||
@is_ui_colored = is_ui_colored
|
|
||||||
|
|
||||||
if client_type != :solo && client_type != :client
|
attr_reader :type
|
||||||
raise 'Invalid client_type, expected solo or client'
|
attr_reader :config
|
||||||
|
attr_reader :options
|
||||||
|
|
||||||
|
def initialize(type, config, options = {})
|
||||||
|
@type = type
|
||||||
|
@config = config
|
||||||
|
@options = options.dup
|
||||||
|
|
||||||
|
if type != :client && type != :solo
|
||||||
|
raise "Unknown type `#{type.inspect}'!"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_command
|
def command
|
||||||
"#{command_env}#{chef_binary_path} #{chef_arguments}"
|
if config.binary_env
|
||||||
|
"#{config.binary_env} #{binary_path} #{args}"
|
||||||
|
else
|
||||||
|
"#{binary_path} #{args}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def command_env
|
def binary_path
|
||||||
@config.binary_env ? "#{@config.binary_env} " : ""
|
binary_path = "chef-#{type}"
|
||||||
end
|
|
||||||
|
|
||||||
def chef_binary_path
|
if config.binary_path
|
||||||
binary_path = "chef-#{@client_type}"
|
binary_path = File.join(config.binary_path, binary_path)
|
||||||
if @config.binary_path
|
|
||||||
binary_path = File.join(@config.binary_path, binary_path)
|
|
||||||
if windows?
|
if windows?
|
||||||
binary_path = windows_friendly_path(binary_path)
|
binary_path = windows_friendly_path(binary_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
binary_path
|
binary_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def chef_arguments
|
def args
|
||||||
chef_arguments = "-c #{provisioning_path("#{@client_type}.rb")}"
|
args = ""
|
||||||
chef_arguments << " -j #{provisioning_path("dna.json")}"
|
args << " --config #{provisioning_path("#{type}.rb")}"
|
||||||
chef_arguments << " #{@config.arguments}" if @config.arguments
|
args << " --json-attributes #{provisioning_path("dna.json")}"
|
||||||
chef_arguments << " --no-color" unless color?
|
args << " --local-mode" if options[:local_mode]
|
||||||
chef_arguments.strip
|
args << " --log_level #{config.log_level}" if config.log_level
|
||||||
|
args << " --force-formatter"
|
||||||
|
args << " --no-color" if !options[:colored]
|
||||||
|
args << " #{config.arguments.strip}" if config.arguments
|
||||||
|
|
||||||
|
args.strip
|
||||||
end
|
end
|
||||||
|
|
||||||
def provisioning_path(file)
|
def provisioning_path(file)
|
||||||
if windows?
|
if windows?
|
||||||
path = @config.provisioning_path || "C:/vagrant-chef"
|
path = config.provisioning_path || "C:/vagrant-chef"
|
||||||
return windows_friendly_path(File.join(path, file))
|
return windows_friendly_path(File.join(path, file))
|
||||||
else
|
else
|
||||||
path = @config.provisioning_path || "/tmp/vagrant-chef"
|
path = config.provisioning_path || "/tmp/vagrant-chef"
|
||||||
return File.join(path, file)
|
return File.join(path, file)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -58,11 +72,7 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
|
|
||||||
def windows?
|
def windows?
|
||||||
!!@is_windows
|
!!options[:windows]
|
||||||
end
|
|
||||||
|
|
||||||
def color?
|
|
||||||
!!@is_ui_colored
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -51,13 +51,6 @@ module VagrantPlugins
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# This returns the command to run Chef for the given client
|
|
||||||
# type.
|
|
||||||
def build_command(client)
|
|
||||||
builder = CommandBuilder.new(@config, client, windows?, @machine.env.ui.color?)
|
|
||||||
return builder.build_command
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns the path to the Chef binary, taking into account the
|
# Returns the path to the Chef binary, taking into account the
|
||||||
# `binary_path` configuration option.
|
# `binary_path` configuration option.
|
||||||
def chef_binary_path(binary)
|
def chef_binary_path(binary)
|
||||||
|
|
|
@ -69,7 +69,10 @@ module VagrantPlugins
|
||||||
@machine.guest.capability(:wait_for_reboot)
|
@machine.guest.capability(:wait_for_reboot)
|
||||||
end
|
end
|
||||||
|
|
||||||
command = build_command(:client)
|
command = CommandBuilder.command(:client, @config,
|
||||||
|
windows: windows?,
|
||||||
|
colored: @machine.env.ui.color?,
|
||||||
|
)
|
||||||
|
|
||||||
@config.attempts.times do |attempt|
|
@config.attempts.times do |attempt|
|
||||||
if attempt == 0
|
if attempt == 0
|
||||||
|
|
|
@ -41,7 +41,7 @@ module VagrantPlugins
|
||||||
share_folders(root_config, "cse", @environments_folders, existing)
|
share_folders(root_config, "cse", @environments_folders, existing)
|
||||||
end
|
end
|
||||||
|
|
||||||
def provision(mode = :solo)
|
def provision
|
||||||
install_chef
|
install_chef
|
||||||
# Verify that the proper shared folders exist.
|
# Verify that the proper shared folders exist.
|
||||||
check = []
|
check = []
|
||||||
|
@ -58,7 +58,7 @@ module VagrantPlugins
|
||||||
upload_encrypted_data_bag_secret
|
upload_encrypted_data_bag_secret
|
||||||
setup_json
|
setup_json
|
||||||
setup_solo_config
|
setup_solo_config
|
||||||
run_chef(mode)
|
run_chef_solo
|
||||||
delete_encrypted_data_bag_secret
|
delete_encrypted_data_bag_secret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ module VagrantPlugins
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def run_chef(mode)
|
def run_chef_solo
|
||||||
if @config.run_list && @config.run_list.empty?
|
if @config.run_list && @config.run_list.empty?
|
||||||
@machine.ui.warn(I18n.t("vagrant.chef_run_list_empty"))
|
@machine.ui.warn(I18n.t("vagrant.chef_run_list_empty"))
|
||||||
end
|
end
|
||||||
|
@ -173,13 +173,16 @@ module VagrantPlugins
|
||||||
@machine.guest.capability(:wait_for_reboot)
|
@machine.guest.capability(:wait_for_reboot)
|
||||||
end
|
end
|
||||||
|
|
||||||
command = build_command(:solo)
|
command = CommandBuilder.command(:solo, @config,
|
||||||
|
windows: windows?,
|
||||||
|
colored: @machine.env.ui.color?,
|
||||||
|
)
|
||||||
|
|
||||||
@config.attempts.times do |attempt|
|
@config.attempts.times do |attempt|
|
||||||
if attempt == 0
|
if attempt == 0
|
||||||
@machine.ui.info I18n.t("vagrant.provisioners.chef.running_#{mode}")
|
@machine.ui.info I18n.t("vagrant.provisioners.chef.running_solo")
|
||||||
else
|
else
|
||||||
@machine.ui.info I18n.t("vagrant.provisioners.chef.running_#{mode}_again")
|
@machine.ui.info I18n.t("vagrant.provisioners.chef.running_solo_again")
|
||||||
end
|
end
|
||||||
|
|
||||||
opts = { error_check: false, elevated: true }
|
opts = { error_check: false, elevated: true }
|
||||||
|
|
|
@ -6,42 +6,19 @@ require "log4r"
|
||||||
|
|
||||||
require "vagrant/util/counter"
|
require "vagrant/util/counter"
|
||||||
|
|
||||||
require_relative "base"
|
require_relative "chef_solo"
|
||||||
|
|
||||||
module VagrantPlugins
|
module VagrantPlugins
|
||||||
module Chef
|
module Chef
|
||||||
module Provisioner
|
module Provisioner
|
||||||
# This class implements provisioning via chef-zero.
|
# This class implements provisioning via chef-zero.
|
||||||
class ChefZero < Base
|
class ChefZero < ChefSolo
|
||||||
extend Vagrant::Util::Counter
|
|
||||||
include Vagrant::Util::Counter
|
|
||||||
include Vagrant::Action::Builtin::MixinSyncedFolders
|
|
||||||
|
|
||||||
attr_reader :environments_folders
|
|
||||||
attr_reader :cookbook_folders
|
|
||||||
attr_reader :role_folders
|
|
||||||
attr_reader :data_bags_folders
|
|
||||||
|
|
||||||
def initialize(machine, config)
|
def initialize(machine, config)
|
||||||
super
|
super
|
||||||
@logger = Log4r::Logger.new("vagrant::provisioners::chef_zero")
|
@logger = Log4r::Logger.new("vagrant::provisioners::chef_zero")
|
||||||
@shared_folders = []
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def configure(root_config)
|
def provision
|
||||||
@cookbook_folders = expanded_folders(@config.cookbooks_path, "cookbooks")
|
|
||||||
@role_folders = expanded_folders(@config.roles_path, "roles")
|
|
||||||
@data_bags_folders = expanded_folders(@config.data_bags_path, "data_bags")
|
|
||||||
@environments_folders = expanded_folders(@config.environments_path, "environments")
|
|
||||||
|
|
||||||
existing = synced_folders(@machine, cached: true)
|
|
||||||
share_folders(root_config, "csc", @cookbook_folders, existing)
|
|
||||||
share_folders(root_config, "csr", @role_folders, existing)
|
|
||||||
share_folders(root_config, "csdb", @data_bags_folders, existing)
|
|
||||||
share_folders(root_config, "cse", @environments_folders, existing)
|
|
||||||
end
|
|
||||||
|
|
||||||
def provision(mode = :client)
|
|
||||||
install_chef
|
install_chef
|
||||||
# Verify that the proper shared folders exist.
|
# Verify that the proper shared folders exist.
|
||||||
check = []
|
check = []
|
||||||
|
@ -58,99 +35,10 @@ module VagrantPlugins
|
||||||
upload_encrypted_data_bag_secret
|
upload_encrypted_data_bag_secret
|
||||||
setup_json
|
setup_json
|
||||||
setup_zero_config
|
setup_zero_config
|
||||||
run_chef(mode)
|
run_chef_zero
|
||||||
delete_encrypted_data_bag_secret
|
delete_encrypted_data_bag_secret
|
||||||
end
|
end
|
||||||
|
|
||||||
# Converts paths to a list of properly expanded paths with types.
|
|
||||||
def expanded_folders(paths, appended_folder=nil)
|
|
||||||
# Convert the path to an array if it is a string or just a single
|
|
||||||
# path element which contains the folder location (:host or :vm)
|
|
||||||
paths = [paths] if paths.is_a?(String) || paths.first.is_a?(Symbol)
|
|
||||||
|
|
||||||
results = []
|
|
||||||
paths.each do |type, path|
|
|
||||||
# Create the local/remote path based on whether this is a host
|
|
||||||
# or VM path.
|
|
||||||
local_path = nil
|
|
||||||
remote_path = nil
|
|
||||||
if type == :host
|
|
||||||
# Get the expanded path that the host path points to
|
|
||||||
local_path = File.expand_path(path, @machine.env.root_path)
|
|
||||||
|
|
||||||
if File.exist?(local_path)
|
|
||||||
# Path exists on the host, setup the remote path. We use
|
|
||||||
# the MD5 of the local path so that it is predictable.
|
|
||||||
key = Digest::MD5.hexdigest(local_path)
|
|
||||||
remote_path = "#{guest_provisioning_path}/#{key}"
|
|
||||||
else
|
|
||||||
@machine.ui.warn(I18n.t(
|
|
||||||
"vagrant.provisioners.chef.cookbook_folder_not_found_warning",
|
|
||||||
path: local_path.to_s))
|
|
||||||
next
|
|
||||||
end
|
|
||||||
else
|
|
||||||
# Path already exists on the virtual machine. Expand it
|
|
||||||
# relative to where we're provisioning.
|
|
||||||
remote_path = File.expand_path(path, guest_provisioning_path)
|
|
||||||
|
|
||||||
# Remove drive letter if running on a windows host. This is a bit
|
|
||||||
# of a hack but is the most portable way I can think of at the moment
|
|
||||||
# to achieve this. Otherwise, Vagrant attempts to share at some crazy
|
|
||||||
# path like /home/vagrant/c:/foo/bar
|
|
||||||
remote_path = remote_path.gsub(/^[a-zA-Z]:/, "")
|
|
||||||
end
|
|
||||||
|
|
||||||
# If we have specified a folder name to append then append it
|
|
||||||
remote_path += "/#{appended_folder}" if appended_folder
|
|
||||||
|
|
||||||
# Append the result
|
|
||||||
results << [type, local_path, remote_path]
|
|
||||||
end
|
|
||||||
|
|
||||||
results
|
|
||||||
end
|
|
||||||
|
|
||||||
# Shares the given folders with the given prefix. The folders should
|
|
||||||
# be of the structure resulting from the `expanded_folders` function.
|
|
||||||
def share_folders(root_config, prefix, folders, existing=nil)
|
|
||||||
existing_set = Set.new
|
|
||||||
(existing || []).each do |_, fs|
|
|
||||||
fs.each do |id, data|
|
|
||||||
existing_set.add(data[:guestpath])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
folders.each do |type, local_path, remote_path|
|
|
||||||
next if type != :host
|
|
||||||
|
|
||||||
# If this folder already exists, then we don't share it, it means
|
|
||||||
# it was already put down on disk.
|
|
||||||
#
|
|
||||||
# NOTE: This is currently commented out because it was causing
|
|
||||||
# major bugs (GH-5199). We will investigate why this is in more
|
|
||||||
# detail for 1.8.0, but we wanted to fix this in a patch release
|
|
||||||
# and this was the hammer that did that.
|
|
||||||
=begin
|
|
||||||
if existing_set.include?(remote_path)
|
|
||||||
@logger.debug("Not sharing #{local_path}, exists as #{remote_path}")
|
|
||||||
next
|
|
||||||
end
|
|
||||||
=end
|
|
||||||
|
|
||||||
key = Digest::MD5.hexdigest(remote_path)
|
|
||||||
key = key[0..8]
|
|
||||||
|
|
||||||
opts = {}
|
|
||||||
opts[:id] = "v-#{prefix}-#{key}"
|
|
||||||
opts[:type] = @config.synced_folder_type if @config.synced_folder_type
|
|
||||||
|
|
||||||
root_config.vm.synced_folder(local_path, remote_path, opts)
|
|
||||||
end
|
|
||||||
|
|
||||||
@shared_folders += folders
|
|
||||||
end
|
|
||||||
|
|
||||||
def setup_zero_config
|
def setup_zero_config
|
||||||
setup_config("provisioners/chef_zero/zero", "client.rb", {
|
setup_config("provisioners/chef_zero/zero", "client.rb", {
|
||||||
local_mode: true,
|
local_mode: true,
|
||||||
|
@ -162,7 +50,7 @@ module VagrantPlugins
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
def run_chef(mode)
|
def run_chef_zero
|
||||||
if @config.run_list && @config.run_list.empty?
|
if @config.run_list && @config.run_list.empty?
|
||||||
@machine.ui.warn(I18n.t("vagrant.chef_run_list_empty"))
|
@machine.ui.warn(I18n.t("vagrant.chef_run_list_empty"))
|
||||||
end
|
end
|
||||||
|
@ -171,13 +59,17 @@ module VagrantPlugins
|
||||||
@machine.guest.capability(:wait_for_reboot)
|
@machine.guest.capability(:wait_for_reboot)
|
||||||
end
|
end
|
||||||
|
|
||||||
command = build_command(:client)
|
command = CommandBuilder.command(:client, @config,
|
||||||
|
windows: windows?,
|
||||||
|
colored: @machine.env.ui.color?,
|
||||||
|
local_mode: true,
|
||||||
|
)
|
||||||
|
|
||||||
@config.attempts.times do |attempt|
|
@config.attempts.times do |attempt|
|
||||||
if attempt == 0
|
if attempt == 0
|
||||||
@machine.ui.info I18n.t("vagrant.provisioners.chef.running_#{mode}")
|
@machine.ui.info I18n.t("vagrant.provisioners.chef.running_zero")
|
||||||
else
|
else
|
||||||
@machine.ui.info I18n.t("vagrant.provisioners.chef.running_#{mode}_again")
|
@machine.ui.info I18n.t("vagrant.provisioners.chef.running_zero_again")
|
||||||
end
|
end
|
||||||
|
|
||||||
opts = { error_check: false, elevated: true }
|
opts = { error_check: false, elevated: true }
|
||||||
|
|
|
@ -1849,8 +1849,8 @@ en:
|
||||||
running_apply: "Running chef-apply..."
|
running_apply: "Running chef-apply..."
|
||||||
running_solo: "Running chef-solo..."
|
running_solo: "Running chef-solo..."
|
||||||
running_solo_again: "Running chef-solo again (failed to converge)..."
|
running_solo_again: "Running chef-solo again (failed to converge)..."
|
||||||
running_zero: "Running chef-zero..."
|
running_zero: "Running chef-client (local-mode)..."
|
||||||
running_zero_again: "Running chef-zero again (failed to converge)..."
|
running_zero_again: "Running chef-client (local-mode) again (failed to converge)..."
|
||||||
missing_shared_folders: |-
|
missing_shared_folders: |-
|
||||||
Shared folders that Chef requires are missing on the virtual machine.
|
Shared folders that Chef requires are missing on the virtual machine.
|
||||||
This is usually due to configuration changing after already booting the
|
This is usually due to configuration changing after already booting the
|
||||||
|
|
Loading…
Reference in New Issue