James Shubin d4c76d1bcf Do not prepend default path because it can override modules.
It is common for Puppet to manage itself. If the puppet code you are
deploying pushes files to /etc/puppet/modules/, then prepending this
path can break deployment because it will override the module path if
the deployment code is changing. There is no good reason to include this
path. Puppet has built in defaults for this reason.
2013-12-17 14:29:54 -05:00

156 lines
5.0 KiB
Ruby

require "log4r"
module VagrantPlugins
module Puppet
module Provisioner
class PuppetError < Vagrant::Errors::VagrantError
error_namespace("vagrant.provisioners.puppet")
end
class Puppet < Vagrant.plugin("2", :provisioner)
def initialize(machine, config)
super
@logger = Log4r::Logger.new("vagrant::provisioners::puppet")
end
def configure(root_config)
# Calculate the paths we're going to use based on the environment
root_path = @machine.env.root_path
@expanded_module_paths = @config.expanded_module_paths(root_path)
@manifest_file = File.join(manifests_guest_path, @config.manifest_file)
# Setup the module paths
@module_paths = []
@expanded_module_paths.each_with_index do |path, i|
@module_paths << [path, File.join(config.temp_dir, "modules-#{i}")]
end
folder_opts = {}
folder_opts[:nfs] = true if @config.nfs
folder_opts[:owner] = "root" if !folder_opts[:nfs]
# Share the manifests directory with the guest
if @config.manifests_path[0].to_sym == :host
root_config.vm.synced_folder(
File.expand_path(@config.manifests_path[1], root_path),
manifests_guest_path, folder_opts)
end
# Share the module paths
@module_paths.each do |from, to|
root_config.vm.synced_folder(from, to, folder_opts)
end
end
def provision
# Check that the shared folders are properly shared
check = []
if @config.manifests_path[0] == :host
check << manifests_guest_path
end
@module_paths.each do |host_path, guest_path|
check << guest_path
end
# Make sure the temporary directory is properly set up
@machine.communicate.tap do |comm|
comm.sudo("mkdir -p #{config.temp_dir}")
comm.sudo("chmod 0777 #{config.temp_dir}")
end
verify_shared_folders(check)
# Verify Puppet is installed and run it
verify_binary("puppet")
# Upload Hiera configuration if we have it
@hiera_config_path = nil
if config.hiera_config_path
local_hiera_path = File.expand_path(config.hiera_config_path,
@machine.env.root_path)
@hiera_config_path = File.join(config.temp_dir, "hiera.yaml")
@machine.communicate.upload(local_hiera_path, @hiera_config_path)
end
run_puppet_apply
end
def manifests_guest_path
if config.manifests_path[0] == :host
# The path is on the host, so point to where it is shared
File.join(config.temp_dir, "manifests")
else
# The path is on the VM, so just point directly to it
config.manifests_path[1]
end
end
def verify_binary(binary)
@machine.communicate.sudo(
"which #{binary}",
:error_class => PuppetError,
:error_key => :not_detected,
:binary => binary)
end
def run_puppet_apply
options = [config.options].flatten
module_paths = @module_paths.map { |_, to| to }
if !@module_paths.empty?
# Add the command line switch to add the module path
options << "--modulepath '#{module_paths.join(':')}'"
end
if @hiera_config_path
options << "--hiera_config=#{@hiera_config_path}"
end
if !@machine.env.ui.is_a?(Vagrant::UI::Colored)
options << "--color=false"
end
options << "--manifestdir #{manifests_guest_path}"
options << "--detailed-exitcodes"
options << @manifest_file
options = options.join(" ")
# Build up the custom facts if we have any
facter = ""
if !config.facter.empty?
facts = []
config.facter.each do |key, value|
facts << "FACTER_#{key}='#{value}'"
end
facter = "#{facts.join(" ")} "
end
command = "#{facter}puppet apply #{options} || [ $? -eq 2 ]"
if config.working_directory
command = "cd #{config.working_directory} && #{command}"
end
@machine.env.ui.info I18n.t("vagrant.provisioners.puppet.running_puppet",
:manifest => config.manifest_file)
@machine.communicate.sudo(command) do |type, data|
if !data.empty?
@machine.env.ui.info(data, :new_line => false, :prefix => false)
end
end
end
def verify_shared_folders(folders)
folders.each do |folder|
@logger.debug("Checking for shared folder: #{folder}")
if !@machine.communicate.test("test -d #{folder}", sudo: true)
raise PuppetError, :missing_shared_folders
end
end
end
end
end
end
end