Merge pull request #5601 from benh57/environments_wip

Puppet 4 and Puppet environments support
This commit is contained in:
Seth Vargo 2015-05-30 21:04:48 -07:00
commit 042928db9f
4 changed files with 166 additions and 43 deletions

View File

@ -1,11 +1,18 @@
module VagrantPlugins
module Puppet
module Config
class Puppet < Vagrant.plugin("2", :config)
class Puppet < Vagrant.plugin("2", :config)
# The path to Puppet's bin/ directory.
# @return [String]
attr_accessor :binary_path
attr_accessor :facter
attr_accessor :hiera_config_path
attr_accessor :manifest_file
attr_accessor :manifests_path
attr_accessor :environment
attr_accessor :environment_path
attr_accessor :module_path
attr_accessor :options
attr_accessor :synced_folder_type
@ -15,15 +22,18 @@ module VagrantPlugins
def initialize
super
@hiera_config_path = UNSET_VALUE
@manifest_file = UNSET_VALUE
@manifests_path = UNSET_VALUE
@module_path = UNSET_VALUE
@options = []
@facter = {}
@binary_path = UNSET_VALUE
@hiera_config_path = UNSET_VALUE
@manifest_file = UNSET_VALUE
@manifests_path = UNSET_VALUE
@environment = UNSET_VALUE
@environment_path = UNSET_VALUE
@module_path = UNSET_VALUE
@options = []
@facter = {}
@synced_folder_type = UNSET_VALUE
@temp_dir = UNSET_VALUE
@working_directory = UNSET_VALUE
@temp_dir = UNSET_VALUE
@working_directory = UNSET_VALUE
end
def nfs=(value)
@ -41,28 +51,49 @@ module VagrantPlugins
def merge(other)
super.tap do |result|
result.facter = @facter.merge(other.facter)
result.environment_path = @facter.merge(other.environment_path)
result.environment = @facter.merge(other.environment)
end
end
def finalize!
super
if @manifests_path == UNSET_VALUE
if @environment_path == UNSET_VALUE && @manifests_path == UNSET_VALUE
#If both are unset, assume 'manifests' mode for now. TBD: Switch to environments by default?
@manifests_path = [:host, "manifests"]
end
if @manifests_path && !@manifests_path.is_a?(Array)
# If the paths are just strings, assume they are 'host' paths (rather than guest)
if @environment_path != UNSET_VALUE && !@environment_path.is_a?(Array)
@environment_path = [:host, @environment_path]
end
if @manifests_path != UNSET_VALUE && !@manifests_path.is_a?(Array)
@manifests_path = [:host, @manifests_path]
end
@manifests_path[0] = @manifests_path[0].to_sym
@hiera_config_path = nil if @hiera_config_path == UNSET_VALUE
@manifest_file = "default.pp" if @manifest_file == UNSET_VALUE
@module_path = nil if @module_path == UNSET_VALUE
@synced_folder_type = nil if @synced_folder_type == UNSET_VALUE
@temp_dir = "/tmp/vagrant-puppet" if @temp_dir == UNSET_VALUE
@working_directory = nil if @working_directory == UNSET_VALUE
if @environment_path == UNSET_VALUE
@manifests_path[0] = @manifests_path[0].to_sym
@environment_path = nil
@manifest_file = "default.pp" if @manifest_file == UNSET_VALUE
else
@environment_path[0] = @environment_path[0].to_sym
@environment = "production" if @environment == UNSET_VALUE
if @manifests_path == UNSET_VALUE
@manifests_path = nil
end
if @manifest_file == UNSET_VALUE
@manifest_file = nil
end
end
@binary_path = nil if @binary_path == UNSET_VALUE
@module_path = nil if @module_path == UNSET_VALUE
@synced_folder_type = nil if @synced_folder_type == UNSET_VALUE
@temp_dir = "/tmp/vagrant-puppet" if @temp_dir == UNSET_VALUE
@working_directory = nil if @working_directory == UNSET_VALUE
end
# Returns the module paths as an array of paths expanded relative to the
@ -86,7 +117,7 @@ module VagrantPlugins
this_expanded_module_paths = expanded_module_paths(machine.env.root_path)
# Manifests path/file validation
if manifests_path[0].to_sym == :host
if manifests_path != nil && manifests_path[0].to_sym == :host
expanded_path = Pathname.new(manifests_path[1]).
expand_path(machine.env.root_path)
if !expanded_path.directory?
@ -99,8 +130,27 @@ module VagrantPlugins
manifest: expanded_manifest_file.to_s)
end
end
elsif environment_path != nil && environment_path[0].to_sym == :host
# Environments path/file validation
expanded_path = Pathname.new(environment_path[1]).
expand_path(machine.env.root_path)
if !expanded_path.directory?
errors << I18n.t("vagrant.provisioners.puppet.environment_path_missing",
path: expanded_path.to_s)
else
expanded_environment_file = expanded_path.join(environment)
if !expanded_environment_file.file? && !expanded_environment_file.directory?
errors << I18n.t("vagrant.provisioners.puppet.environment_missing",
environment: environment.to_s,
environment_path: expanded_path.to_s)
end
end
end
if environment_path == nil && manifests_path == nil
errors << "Please specify either a Puppet environment_path + environment (preferred) or manifests_path (deprecated)."
end
# Module paths validation
this_expanded_module_paths.each do |path|
if !path.directory?
@ -108,7 +158,6 @@ module VagrantPlugins
path: path)
end
end
{ "puppet provisioner" => errors }
end
end

View File

@ -10,22 +10,22 @@ module VagrantPlugins
DESC
config(:puppet, :provisioner) do
require File.expand_path("../config/puppet", __FILE__)
require_relative "config/puppet"
Config::Puppet
end
config(:puppet_server, :provisioner) do
require File.expand_path("../config/puppet_server", __FILE__)
require_relative "config/puppet_server"
Config::PuppetServer
end
provisioner(:puppet) do
require File.expand_path("../provisioner/puppet", __FILE__)
require_relative "provisioner/puppet"
Provisioner::Puppet
end
provisioner(:puppet_server) do
require File.expand_path("../provisioner/puppet_server", __FILE__)
require_relative "provisioner/puppet_server"
Provisioner::PuppetServer
end
end

View File

@ -20,7 +20,6 @@ module VagrantPlugins
# 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 = []
@ -33,11 +32,22 @@ module VagrantPlugins
folder_opts[:type] = @config.synced_folder_type if @config.synced_folder_type
folder_opts[:owner] = "root" if !@config.synced_folder_type
# 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)
if @config.environment_path.is_a?(Array)
# Share the environments directory with the guest
if @config.environment_path[0].to_sym == :host
root_config.vm.synced_folder(
File.expand_path(@config.environment_path[1], root_path),
environments_guest_path, folder_opts)
end
end
if @config.manifest_file
@manifest_file = File.join(manifests_guest_path, @config.manifest_file)
# 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
end
# Share the module paths
@ -46,6 +56,24 @@ module VagrantPlugins
end
end
def parse_environment_metadata
# Parse out the environment manifest path since puppet apply doesnt do that for us.
environment_conf = File.join(environments_guest_path, @config.environment, "environment.conf")
if @machine.communicate.test("test -e #{environment_conf}", sudo: true)
conf = @machine.communicate.sudo("cat #{environment_conf}") do | type, data|
if type == :stdout
data.each_line do |line|
if line =~ /^\s*manifest\s+=\s+([^\s]+)/
@manifest_file = $1
@manifest_file.gsub! '$basemodulepath:', "#{environments_guest_path}/#{@config.environment}/"
@logger.debug("Using manifest from environment.conf: #{@manifest_file}")
end
end
end
end
end
end
def provision
# If the machine has a wait for reboot functionality, then
# do that (primarily Windows)
@ -53,11 +81,19 @@ module VagrantPlugins
@machine.guest.capability(:wait_for_reboot)
end
# In environment mode we still need to specify a manifest file, if its not, use the one from env config if specified.
if !@manifest_file
@manifest_file = "#{environments_guest_path}/#{@config.environment}/manifests/site.pp"
parse_environment_metadata
end
# Check that the shared folders are properly shared
check = []
if @config.manifests_path[0] == :host
if @config.manifests_path.is_a?(Array) && @config.manifests_path[0] == :host
check << manifests_guest_path
end
if @config.environment_path.is_a?(Array) && @config.environment_path[0] == :host
check << environments_guest_path
end
@module_paths.each do |host_path, guest_path|
check << guest_path
end
@ -71,7 +107,7 @@ module VagrantPlugins
verify_shared_folders(check)
# Verify Puppet is installed and run it
verify_binary("puppet")
verify_binary(puppet_binary_path("puppet"))
# Upload Hiera configuration if we have it
@hiera_config_path = nil
@ -96,12 +132,32 @@ module VagrantPlugins
end
end
def environments_guest_path
if config.environment_path[0] == :host
# The path is on the host, so point to where it is shared
File.join(config.temp_dir, "environments")
else
# The path is on the VM, so just point directly to it
config.environment_path[1]
end
end
# Returns the path to the Puppet binary, taking into account the
# `binary_path` configuration option.
def puppet_binary_path(binary)
return binary if !@config.binary_path
return File.join(@config.binary_path, binary)
end
def verify_binary(binary)
@machine.communicate.sudo(
"which #{binary}",
error_class: PuppetError,
error_key: :not_detected,
binary: binary)
if !machine.communicate.test("sh -c 'command -v #{binary}'")
@config.binary_path = "/opt/puppetlabs/bin/"
@machine.communicate.sudo(
"test -x /opt/puppetlabs/bin/#{binary}",
error_class: PuppetError,
error_key: :not_detected,
binary: binary)
end
end
def run_puppet_apply
@ -129,8 +185,14 @@ module VagrantPlugins
options << "--color=false"
end
options << "--manifestdir #{manifests_guest_path}"
options << "--detailed-exitcodes"
if config.environment_path
options << "--environmentpath #{environments_guest_path}/"
options << "--environment #{@config.environment}"
else
options << "--manifestdir #{manifests_guest_path}"
end
options << @manifest_file
options = options.join(" ")
@ -150,7 +212,7 @@ module VagrantPlugins
facter = "#{facts.join(" ")} "
end
command = "#{facter}puppet apply #{options}"
command = "#{facter} #{config.binary_path}puppet apply #{options}"
if config.working_directory
if windows?
command = "cd #{config.working_directory}; if (`$?) \{ #{command} \}"
@ -159,9 +221,15 @@ module VagrantPlugins
end
end
@machine.ui.info(I18n.t(
"vagrant.provisioners.puppet.running_puppet",
manifest: config.manifest_file))
if config.environment_path
@machine.ui.info(I18n.t(
"vagrant.provisioners.puppet.running_puppet_env",
environment: config.environment))
else
@machine.ui.info(I18n.t(
"vagrant.provisioners.puppet.running_puppet",
manifest: config.manifest_file))
end
opts = {
elevated: true,

View File

@ -1854,11 +1854,17 @@ en:
installed on this guest. Puppet provisioning can not continue without
Puppet properly installed.
running_puppet: "Running Puppet with %{manifest}..."
running_puppet_env: "Running Puppet with environment %{environment}..."
manifest_missing: |-
The configured Puppet manifest is missing. Please specify a path to an
existing manifest:
%{manifest}
environment_missing: |-
The configured Puppet environment folder %{environment} was not found in the
specified environmentpath %{environmentpath}.
Please specify a path to an existing Puppet directory environment.
environment_path_missing: "The environment path specified for Puppet does not exist: %{path}"
manifests_path_missing: "The manifests path specified for Puppet does not exist: %{path}"
missing_shared_folders: |-
Shared folders that Puppet requires are missing on the virtual machine.