diff --git a/lib/vagrant/provisioners/chef.rb b/lib/vagrant/provisioners/chef.rb index 09f38193d..35ba58d43 100644 --- a/lib/vagrant/provisioners/chef.rb +++ b/lib/vagrant/provisioners/chef.rb @@ -15,6 +15,7 @@ module Vagrant # Chef solo specific config attr_accessor :cookbooks_path + attr_accessor :roles_path # Shared config attr_accessor :provisioning_path @@ -27,6 +28,7 @@ module Vagrant @node_name = "client" @cookbooks_path = "cookbooks" + @roles_path = [] @provisioning_path = "/tmp/vagrant-chef" @log_level = :info @json = { diff --git a/lib/vagrant/provisioners/chef_solo.rb b/lib/vagrant/provisioners/chef_solo.rb index e3b905c56..b7d765ee2 100644 --- a/lib/vagrant/provisioners/chef_solo.rb +++ b/lib/vagrant/provisioners/chef_solo.rb @@ -4,6 +4,7 @@ module Vagrant class ChefSolo < Chef def prepare share_cookbook_folders + share_role_folders end def provision! @@ -18,11 +19,18 @@ module Vagrant env.config.vm.share_folder("vagrant-chef-solo-#{i}", cookbook_path(i), cookbook) end end + + def share_role_folders + host_role_paths.each_with_index do |role, i| + env.config.vm.share_folder("vagrant-chef-solo-#{i}", role_path(i), role) + end + end def setup_solo_config setup_config("chef_solo_solo", "solo.rb", { :provisioning_path => env.config.chef.provisioning_path, - :cookbooks_path => cookbooks_path + :cookbooks_path => cookbooks_path, + :roles_path => roles_path }) end @@ -43,10 +51,21 @@ module Vagrant cookbooks.collect! { |cookbook| File.expand_path(cookbook, env.root_path) } return cookbooks end + + def host_role_paths + roles = env.config.chef.roles_path + roles = [roles] unless roles.is_a?(Array) + roles.collect! { |role| File.expand_path(role, env.root_path) } + return roles + end def cookbook_path(i) File.join(env.config.chef.provisioning_path, "cookbooks-#{i}") end + + def role_path(i) + File.join(env.config.chef.provisioning_path, "roles-#{i}") + end def cookbooks_path result = [] @@ -59,6 +78,18 @@ module Vagrant result = result[0].to_s if result.length == 1 result.to_json end + + def roles_path + result = [] + host_role_paths.each_with_index do |host_path, i| + result << role_path(i) + end + + # We're lucky that ruby's string and array syntax for strings is the + # same as JSON, so we can just convert to JSON here and use that + result = result[0].to_s if result.length == 1 + result.to_json + end end end end diff --git a/templates/chef_solo_solo.erb b/templates/chef_solo_solo.erb index 55fbad275..407653c87 100644 --- a/templates/chef_solo_solo.erb +++ b/templates/chef_solo_solo.erb @@ -1,3 +1,4 @@ file_cache_path "<%= provisioning_path %>" cookbook_path <%= cookbooks_path %> +role_path <%= roles_path %> log_level <%= log_level.inspect %> \ No newline at end of file diff --git a/test/vagrant/provisioners/chef_solo_test.rb b/test/vagrant/provisioners/chef_solo_test.rb index bc3448d4b..bb1c81dee 100644 --- a/test/vagrant/provisioners/chef_solo_test.rb +++ b/test/vagrant/provisioners/chef_solo_test.rb @@ -11,6 +11,11 @@ class ChefSoloProvisionerTest < Test::Unit::TestCase @action.expects(:share_cookbook_folders).once @action.prepare end + + should "share role folders" do + @action.expects(:share_role_folders).once + @action.prepare + end end context "provisioning" do @@ -39,6 +44,22 @@ class ChefSoloProvisionerTest < Test::Unit::TestCase @action.share_cookbook_folders end end + + context "sharing role folders" do + setup do + @host_role_paths = ["foo", "bar"] + @action.stubs(:host_role_paths).returns(@host_role_paths) + end + + should "share each role folder" do + share_seq = sequence("share_seq") + @host_role_paths.each_with_index do |role, i| + @env.config.vm.expects(:share_folder).with("vagrant-chef-solo-#{i}", @action.role_path(i), role).in_sequence(share_seq) + end + + @action.share_role_folders + end + end context "host cookbooks paths" do should "return as an array if was originally a string" do @@ -58,6 +79,25 @@ class ChefSoloProvisionerTest < Test::Unit::TestCase assert_equal cookbooks, @action.host_cookbook_paths end end + + context "host roles paths" do + should "return as an array if was originally a string" do + File.stubs(:expand_path).returns("foo") + @env.config.chef.roles_path = "foo" + + assert_equal ["foo"], @action.host_role_paths + end + + should "return the array of roles if its an array" do + roles = ["foo", "bar"] + @env.config.chef.roles_path = roles + + expand_seq = sequence('expand_seq') + roles.collect! { |role| File.expand_path(role, @env.root_path) } + + assert_equal roles, @action.host_role_paths + end + end context "cookbooks path" do should "return a proper path to a single cookbook" do @@ -81,6 +121,29 @@ class ChefSoloProvisionerTest < Test::Unit::TestCase assert_equal @cookbooks.to_json, @action.cookbooks_path end end + + context "roles path" do + should "return a proper path to a single role" do + expected = File.join(@env.config.chef.provisioning_path, "roles-5") + assert_equal expected, @action.role_path(5) + end + + should "return array-representation of role paths if multiple" do + @roles = (0..5).inject([]) do |acc, i| + acc << @action.role_path(i) + end + + @env.config.chef.roles_path = @roles + assert_equal @roles.to_json, @action.roles_path + end + + should "return a single string representation if roles paths is single" do + @roles = @action.role_path(0) + + @env.config.chef.roles_path = @roles + assert_equal @roles.to_json, @action.roles_path + end + end context "generating and uploading chef solo configuration file" do setup do @@ -90,7 +153,8 @@ class ChefSoloProvisionerTest < Test::Unit::TestCase should "call setup_config with proper variables" do @action.expects(:setup_config).with("chef_solo_solo", "solo.rb", { :provisioning_path => @env.config.chef.provisioning_path, - :cookbooks_path => @action.cookbooks_path + :cookbooks_path => @action.cookbooks_path, + :roles_path => @action.roles_path }) @action.setup_solo_config