Puppet provisioner can mount/configure module paths from local directory

This commit is contained in:
Mitchell Hashimoto 2011-01-13 21:02:26 -08:00
parent 28a2167dda
commit 302f9ff0bb
4 changed files with 105 additions and 14 deletions

View File

@ -1,10 +1,8 @@
## 0.7.0 (unreleased)
The 0.7.0 betas will be merged into this one section upon final release.
I don't expect many changes.
## 0.7.0.beta2 (January 13, 2010)
- VirtualBox 4.0 support. Support for VirtualBox 3.2 is _dropped_, since
the API is so different. Stay with the 0.6.x series if you have VirtualBox
3.2.x.
- Puppet server provisioner. [GH-262]
- Use numeric uid/gid in mounting shared folders to increase portability. [GH-252]
- HTTP downloading follows redirects. [GH-163]
@ -28,17 +26,13 @@ I don't expect many changes.
change is not backwards compatible. [GH-265]
- Provisioners are now RVM-friendly, meaning if you installed chef or puppet
with an RVM managed Ruby, Vagrant now finds then. [GH-254]
## 0.7.0.beta (December 24, 2010)
- VirtualBox 4.0 support. Support for VirtualBox 3.2 is _dropped_, since
the API is so different. Stay with the 0.6.x series if you have VirtualBox
3.2.x.
- Changed the unused host only network destroy mechanism to check for
uselessness after the VM is destroyed. This should result in more accurate
checks.
- Networks are no longer disabled upon halt/destroy. With the above
change, its unnecessary.
- Puppet supports `module_path` configuration to mount local modules directory
as a shared folder and configure puppet with it. [GH-270]
## 0.6.9 (December 21, 2010)

View File

@ -10,12 +10,14 @@ module Vagrant
class Config < Vagrant::Config::Base
attr_accessor :manifest_file
attr_accessor :manifests_path
attr_accessor :module_path
attr_accessor :pp_path
attr_accessor :options
def initialize
@manifest_file = nil
@manifests_path = "manifests"
@module_path = nil
@pp_path = "/tmp/vagrant-puppet"
@options = []
end
@ -32,20 +34,45 @@ module Vagrant
manifest_file || "#{top.vm.box}.pp"
end
# Returns the module paths as an array of paths expanded relative to the
# root path.
def expanded_module_paths
return [] if !module_path
# Get all the paths and expand them relative to the root path, returning
# the array of expanded paths
paths = module_path
paths = [paths] if !paths.is_a?(Array)
paths.map do |path|
Pathname.new(path).expand_path(env.root_path)
end
end
def validate(errors)
super
# Manifests path/file validation
if !expanded_manifests_path.directory?
errors.add(I18n.t("vagrant.provisioners.puppet.manifests_path_missing", :path => expanded_manifests_path))
return
else
if !expanded_manifests_path.join(computed_manifest_file).file?
errors.add(I18n.t("vagrant.provisioners.puppet.manifest_missing", :manifest => computed_manifest_file))
end
end
errors.add(I18n.t("vagrant.provisioners.puppet.manifest_missing", :manifest => computed_manifest_file)) if !expanded_manifests_path.join(computed_manifest_file).file?
# Module paths validation
expanded_module_paths.each do |path|
if !path.directory?
errors.add(I18n.t("vagrant.provisioners.puppet.module_path_missing", :path => path))
end
end
end
end
def prepare
set_module_paths
share_manifests
share_module_paths
end
def provision!
@ -58,6 +85,23 @@ module Vagrant
env.config.vm.share_folder("manifests", config.pp_path, config.manifests_path)
end
def share_module_paths
count = 0
@module_paths.each do |from, to|
# Sorry for the cryptic key here, but VirtualBox has a strange limit on
# maximum size for it and its something small (around 10)
env.config.vm.share_folder("v-pp-m#{count}", to, from)
count += 1
end
end
def set_module_paths
@module_paths = {}
config.expanded_module_paths.each_with_index do |path, i|
@module_paths[path] = File.join(config.pp_path, "modules-#{i}")
end
end
def verify_binary(binary)
vm.ssh.execute do |ssh|
ssh.exec!("sudo -i which #{binary}", :error_class => PuppetError, :_key => :puppet_not_detected, :binary => binary)
@ -73,6 +117,7 @@ module Vagrant
def run_puppet_client
options = [config.options].flatten
options << "--modulepath '#{@module_paths.values.join(':')}'" if !@module_paths.empty?
options << config.computed_manifest_file
options = options.join(" ")

View File

@ -475,6 +475,7 @@ en:
running_puppet: "Running Puppet with %{manifest}..."
manifest_missing: "The Puppet %{manifest} manifest is missing. You cannot configure this box."
manifests_path_missing: "The manifests path specified for Puppet does not exist: %{path}"
module_path_missing: "The configured module path doesn't exist: %{path}"
puppet_server:
not_detected: |-

View File

@ -41,6 +41,20 @@ class PuppetProvisionerTest < Test::Unit::TestCase
assert_equal "woot.pp", @config.computed_manifest_file
end
should "return an empty array if no module path is set" do
@config.module_path = nil
assert_equal [], @config.expanded_module_paths
end
should "return array of module paths expanded relative to root path" do
@config.module_path = "foo"
result = @config.expanded_module_paths
assert result.is_a?(Array)
assert_equal 1, result.length
assert_equal File.expand_path(@config.module_path, @env.root_path), result[0].to_s
end
should "be valid" do
@config.validate(@errors)
assert @errors.errors.empty?
@ -63,11 +77,27 @@ class PuppetProvisionerTest < Test::Unit::TestCase
@config.validate(@errors)
assert !@errors.errors.empty?
end
should "be invalid if a specified module path doesn't exist" do
@config.module_path = "foo"
@config.validate(@errors)
assert !@errors.errors.empty?
end
should "be valid if all module paths exist" do
@config.module_path = "foo"
@config.expanded_module_paths.first.mkdir
@config.validate(@errors)
assert @errors.errors.empty?
end
end
context "preparing" do
should "share manifests" do
@action.expects(:share_manifests).once
pre_seq = sequence("prepare")
@action.expects(:set_module_paths).once.in_sequence(pre_seq)
@action.expects(:share_manifests).once.in_sequence(pre_seq)
@action.expects(:share_module_paths).once.in_sequence(pre_seq)
@action.prepare
end
end
@ -96,6 +126,18 @@ class PuppetProvisionerTest < Test::Unit::TestCase
end
end
context "sharing module paths" do
should "share all the module paths" do
@config.module_path = ["foo", "bar"]
@config.expanded_module_paths.each_with_index do |path, i|
@env.config.vm.expects(:share_folder).with("v-pp-m#{i}", File.join(@config.pp_path, "modules-#{i}"), path)
end
@action.set_module_paths
@action.share_module_paths
end
end
context "verifying binary" do
setup do
@ssh = mock("ssh")
@ -124,6 +166,7 @@ class PuppetProvisionerTest < Test::Unit::TestCase
setup do
@ssh = mock("ssh")
@vm.ssh.stubs(:execute).yields(@ssh)
@action.set_module_paths
end
def expect_puppet_command(command)
@ -146,5 +189,13 @@ class PuppetProvisionerTest < Test::Unit::TestCase
expect_puppet_command("puppet --modulepath modules --verbose #{@config.computed_manifest_file}")
@action.run_puppet_client
end
should "cd into the pp_path and run puppet with module paths if set" do
@config.module_path = "foo"
expect_puppet_command("puppet --modulepath '#{File.join(@config.pp_path, 'modules-0')}' #{@config.computed_manifest_file}")
@action.set_module_paths
@action.run_puppet_client
end
end
end