diff --git a/CHANGELOG.md b/CHANGELOG.md index ff4f5d3fb..c8d8e8415 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## 0.5.1 (unreleased) + - Added `config.chef.recipe_url` which allows you to specify a URL to + a gzipped tar file for chef solo to download cookbooks. See the + [chef-solo docs](http://wiki.opscode.com/display/chef/Chef+Solo#ChefSolo-RunningfromaURL) for more information. - Added `vagrant box repackage` which repackages boxes which have been added. This is useful in case you want to redistribute a base box you have but may have lost the actual "box" file. diff --git a/lib/vagrant/provisioners/chef.rb b/lib/vagrant/provisioners/chef.rb index 22996e51d..9606caaba 100644 --- a/lib/vagrant/provisioners/chef.rb +++ b/lib/vagrant/provisioners/chef.rb @@ -16,6 +16,7 @@ module Vagrant # Chef solo specific config attr_accessor :cookbooks_path attr_accessor :roles_path + attr_accessor :recipe_url # Shared config attr_accessor :provisioning_path diff --git a/lib/vagrant/provisioners/chef_solo.rb b/lib/vagrant/provisioners/chef_solo.rb index 0a12c0d8d..962d96f85 100644 --- a/lib/vagrant/provisioners/chef_solo.rb +++ b/lib/vagrant/provisioners/chef_solo.rb @@ -32,7 +32,8 @@ module Vagrant :node_name => env.config.chef.node_name, :provisioning_path => env.config.chef.provisioning_path, :cookbooks_path => cookbooks_path, - :roles_path => roles_path + :recipe_url => env.config.chef.recipe_url, + :roles_path => roles_path, }) end @@ -65,7 +66,7 @@ module Vagrant # 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 + result end def host_cookbook_paths @@ -85,11 +86,14 @@ module Vagrant end def cookbooks_path - folders_path(host_cookbook_paths, "cookbooks") + result = folders_path(host_cookbook_paths, "cookbooks") + result = [result, File.join(env.config.chef.provisioning_path, "cookbooks")].flatten if env.config.chef.recipe_url + + result.to_json end def roles_path - folders_path(host_role_paths, "roles") + folders_path(host_role_paths, "roles").to_json end end end diff --git a/templates/chef_solo_solo.erb b/templates/chef_solo_solo.erb index b8557272a..80124ced5 100644 --- a/templates/chef_solo_solo.erb +++ b/templates/chef_solo_solo.erb @@ -3,3 +3,7 @@ file_cache_path "<%= provisioning_path %>" cookbook_path <%= cookbooks_path %> role_path <%= roles_path %> log_level <%= log_level.inspect %> + +<% if recipe_url %> +recipe_url "<%= recipe_url %>" +<% end %> \ No newline at end of file diff --git a/test/test_helper.rb b/test/test_helper.rb index 090c92fe2..76f7bd316 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -53,6 +53,7 @@ class Test::Unit::TestCase config.chef.validation_key_path = "validation.pem" config.chef.client_key_path = "/zoo/foo/bar.pem" config.chef.node_name = "baz" + config.chef.recipe_url = nil config.chef.cookbooks_path = "cookbooks" config.chef.provisioning_path = "/tmp/vagrant-chef" config.chef.log_level = :info diff --git a/test/vagrant/provisioners/chef_solo_test.rb b/test/vagrant/provisioners/chef_solo_test.rb index 35c000ede..71467a84a 100644 --- a/test/vagrant/provisioners/chef_solo_test.rb +++ b/test/vagrant/provisioners/chef_solo_test.rb @@ -111,14 +111,14 @@ class ChefSoloProvisionerTest < Test::Unit::TestCase acc << @action.cookbook_path(i) end - assert_equal @cookbooks.to_json, @action.folders_path(@folders, "cookbooks") + assert_equal @cookbooks, @action.folders_path(@folders, "cookbooks") end should "return a single string representation if folder paths is single" do @folder = "cookbooks" @cookbooks = @action.folder_path(@folder, 0) - assert_equal @cookbooks.to_json, @action.folders_path([0], @folder) + assert_equal @cookbooks, @action.folders_path([0], @folder) end end @@ -129,10 +129,17 @@ class ChefSoloProvisionerTest < Test::Unit::TestCase end should "properly call folders path and return result" do - result = mock("result") - @action.stubs(:host_cookbook_paths).returns([]) + result = [:a, :b, :c] @action.expects(:folders_path).with(@action.host_cookbook_paths, "cookbooks").once.returns(result) - assert_equal result, @action.cookbooks_path + assert_equal result.to_json, @action.cookbooks_path + end + + should "append a bare cookbooks path to the cookbooks path for recipe URL" do + @env.config.chef.recipe_url = "foo" + @action.stubs(:folders_path).returns([]) + result = @action.cookbooks_path + assert result + assert result =~ /\/cookbooks"\]$/ end end @@ -143,16 +150,17 @@ class ChefSoloProvisionerTest < Test::Unit::TestCase end should "properly call folders path and return result" do - result = mock("result") - @action.stubs(:host_role_paths).returns([]) + result = [:a, :b, :c] @action.expects(:folders_path).with(@action.host_role_paths, "roles").once.returns(result) - assert_equal result, @action.roles_path + assert_equal result.to_json, @action.roles_path end end context "generating and uploading chef solo configuration file" do setup do @vm.ssh.stubs(:upload!) + + @env.config.chef.recipe_url = "foo/bar/baz" end should "call setup_config with proper variables" do @@ -160,6 +168,7 @@ class ChefSoloProvisionerTest < Test::Unit::TestCase :node_name => @env.config.chef.node_name, :provisioning_path => @env.config.chef.provisioning_path, :cookbooks_path => @action.cookbooks_path, + :recipe_url => @env.config.chef.recipe_url, :roles_path => @action.roles_path })