From a71815df4e4599f97364f2e1ef360dc14e3e1fbb Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 10 Mar 2010 13:49:52 -0800 Subject: [PATCH] Additional shared folders can now be configured through the `config.vm.share_folder` method --- lib/vagrant/actions/vm/boot.rb | 9 ++- lib/vagrant/actions/vm/provision.rb | 8 +-- lib/vagrant/actions/vm/shared_folders.rb | 52 +++++++++-------- lib/vagrant/config.rb | 9 +++ lib/vagrant/vm.rb | 4 ++ test/vagrant/actions/vm/boot_test.rb | 14 ++--- test/vagrant/actions/vm/provision_test.rb | 3 +- .../vagrant/actions/vm/shared_folders_test.rb | 57 ++++++++++++++++--- test/vagrant/vm_test.rb | 10 ++++ 9 files changed, 118 insertions(+), 48 deletions(-) diff --git a/lib/vagrant/actions/vm/boot.rb b/lib/vagrant/actions/vm/boot.rb index 494b9b81e..b0ff0d3ab 100644 --- a/lib/vagrant/actions/vm/boot.rb +++ b/lib/vagrant/actions/vm/boot.rb @@ -2,6 +2,10 @@ module Vagrant module Actions module VM class Boot < Base + def prepare + Vagrant.config.vm.share_folder("vagrant-root", Vagrant.config.vm.project_directory, Env.root_path) + end + def execute! @runner.invoke_around_callback(:boot) do # Startup the VM @@ -17,11 +21,6 @@ error end end - def collect_shared_folders - # The root shared folder for the project - ["vagrant-root", Env.root_path, Vagrant.config.vm.project_directory] - end - def boot logger.info "Booting VM..." @runner.vm.start(:headless, true) diff --git a/lib/vagrant/actions/vm/provision.rb b/lib/vagrant/actions/vm/provision.rb index b9f8c0995..3750fb21a 100644 --- a/lib/vagrant/actions/vm/provision.rb +++ b/lib/vagrant/actions/vm/provision.rb @@ -2,6 +2,10 @@ module Vagrant module Actions module VM class Provision < Base + def prepare + Vagrant.config.vm.share_folder("vagrant-provisioning", cookbooks_path, File.expand_path(Vagrant.config.chef.cookbooks_path, Env.root_path)) + end + def execute! chown_provisioning_folder setup_json @@ -61,10 +65,6 @@ solo def cookbooks_path File.join(Vagrant.config.chef.provisioning_path, "cookbooks") end - - def collect_shared_folders - ["vagrant-provisioning", File.expand_path(Vagrant.config.chef.cookbooks_path, Env.root_path), cookbooks_path] - end end end end diff --git a/lib/vagrant/actions/vm/shared_folders.rb b/lib/vagrant/actions/vm/shared_folders.rb index a45167db7..1ca54d525 100644 --- a/lib/vagrant/actions/vm/shared_folders.rb +++ b/lib/vagrant/actions/vm/shared_folders.rb @@ -3,32 +3,15 @@ module Vagrant module VM class SharedFolders < Base def shared_folders - shared_folders = @runner.invoke_callback(:collect_shared_folders) - - # Basic filtering of shared folders. Basically only verifies that - # the result is an array of 3 elements. In the future this should - # also verify that the host path exists, the name is valid, - # and that the guest path is valid. - shared_folders.collect do |folder| - if folder.is_a?(Array) && folder.length == 3 - folder - else - nil - end - end.compact + Vagrant.config.vm.shared_folders.inject([]) do |acc, data| + name, value = data + acc << [name, File.expand_path(value[:hostpath]), value[:guestpath]] + end end def before_boot - logger.info "Creating shared folders metadata..." - - shared_folders.each do |name, hostpath, guestpath| - folder = VirtualBox::SharedFolder.new - folder.name = name - folder.hostpath = hostpath - @runner.vm.shared_folders << folder - end - - @runner.vm.save(true) + clear_shared_folders + create_metadata end def after_boot @@ -44,6 +27,29 @@ module Vagrant end end + def clear_shared_folders + logger.info "Clearing previously set shared folders..." + + @runner.vm.shared_folders.each do |shared_folder| + shared_folder.destroy + end + + @runner.reload! + end + + def create_metadata + logger.info "Creating shared folders metadata..." + + shared_folders.each do |name, hostpath, guestpath| + folder = VirtualBox::SharedFolder.new + folder.name = name + folder.hostpath = hostpath + @runner.vm.shared_folders << folder + end + + @runner.vm.save(true) + end + def mount_folder(ssh, name, guestpath, sleeptime=5) # Note: This method seems pretty OS-specific and could also use # some configuration options. For now its duct tape and "works" diff --git a/lib/vagrant/config.rb b/lib/vagrant/config.rb index baa3fcc9c..0b6459536 100644 --- a/lib/vagrant/config.rb +++ b/lib/vagrant/config.rb @@ -72,12 +72,14 @@ module Vagrant attr_accessor :base_mac attr_accessor :project_directory attr_reader :forwarded_ports + attr_reader :shared_folders attr_accessor :hd_location attr_accessor :disk_image_format def initialize @forwarded_ports = {} + @shared_folders = {} end def forward_port(name, guestport, hostport, protocol="TCP") @@ -88,6 +90,13 @@ module Vagrant } end + def share_folder(name, guestpath, hostpath) + @shared_folders[name] = { + :guestpath => guestpath, + :hostpath => hostpath + } + end + def hd_location=(val) raise Exception.new "disk_storage must be set to a directory" unless File.directory?(val) @hd_location=val diff --git a/lib/vagrant/vm.rb b/lib/vagrant/vm.rb index df4bab42d..56a0d6b84 100644 --- a/lib/vagrant/vm.rb +++ b/lib/vagrant/vm.rb @@ -19,6 +19,10 @@ module Vagrant @vm = vm end + def reload! + @vm = VirtualBox::VM.find(@vm.uuid) + end + def package(out_path, include_files=[]) add_action(Actions::VM::Export) add_action(Actions::VM::Package, out_path, include_files) diff --git a/test/vagrant/actions/vm/boot_test.rb b/test/vagrant/actions/vm/boot_test.rb index 729426854..52c2cef28 100644 --- a/test/vagrant/actions/vm/boot_test.rb +++ b/test/vagrant/actions/vm/boot_test.rb @@ -7,6 +7,13 @@ class BootActionTest < Test::Unit::TestCase mock_config end + context "preparing" do + should "add the root shared folder" do + Vagrant.config.vm.expects(:share_folder).with("vagrant-root", Vagrant.config.vm.project_directory, Vagrant::Env.root_path).once + @action.prepare + end + end + context "execution" do should "invoke the 'boot' around callback" do boot_seq = sequence("boot_seq") @@ -45,11 +52,4 @@ class BootActionTest < Test::Unit::TestCase assert !@action.wait_for_boot(0) end end - - context "callbacks" do - should "setup the root directory shared folder" do - expected = ["vagrant-root", Vagrant::Env.root_path, Vagrant.config.vm.project_directory] - assert_equal expected, @action.collect_shared_folders - end - end end diff --git a/test/vagrant/actions/vm/provision_test.rb b/test/vagrant/actions/vm/provision_test.rb index 9322d799f..64e6b808c 100644 --- a/test/vagrant/actions/vm/provision_test.rb +++ b/test/vagrant/actions/vm/provision_test.rb @@ -14,7 +14,8 @@ class ProvisionActionTest < Test::Unit::TestCase should "setup shared folder on VM for the cookbooks" do File.expects(:expand_path).with(Vagrant.config.chef.cookbooks_path, Vagrant::Env.root_path).returns("foo") @action.expects(:cookbooks_path).returns("bar") - assert_equal ["vagrant-provisioning", "foo", "bar"], @action.collect_shared_folders + Vagrant.config.vm.expects(:share_folder).with("vagrant-provisioning", "bar", "foo").once + @action.prepare end end diff --git a/test/vagrant/actions/vm/shared_folders_test.rb b/test/vagrant/actions/vm/shared_folders_test.rb index dadd0b031..5de4e8764 100644 --- a/test/vagrant/actions/vm/shared_folders_test.rb +++ b/test/vagrant/actions/vm/shared_folders_test.rb @@ -12,17 +12,58 @@ class SharedFoldersActionTest < Test::Unit::TestCase folders end + context "before boot" do + should "clear folders and create metadata, in order" do + before_seq = sequence("before") + @action.expects(:clear_shared_folders).once.in_sequence(before_seq) + @action.expects(:create_metadata).once.in_sequence(before_seq) + @action.before_boot + end + end + context "collecting shared folders" do - should "return the arrays that the callback returns" do - result = [[1,2,3],[4,5,6]] - @mock_vm.expects(:invoke_callback).with(:collect_shared_folders).once.returns(result) + setup do + File.stubs(:expand_path).returns("baz") + end + + should "convert the vagrant config values into an array" do + mock_config do |config| + config.vm.shared_folders.clear + config.vm.share_folder("foo", "bar", "baz") + end + + result = [["foo", "baz", "bar"]] assert_equal result, @action.shared_folders end - should "filter out invalid results" do - result = [[1,2,3],[4,5]] - @mock_vm.expects(:invoke_callback).with(:collect_shared_folders).once.returns(result) - assert_equal [[1,2,3]], @action.shared_folders + should "expand the path of the host folder" do + File.expects(:expand_path).with("baz").once.returns("expanded_baz") + + mock_config do |config| + config.vm.shared_folders.clear + config.vm.share_folder("foo", "bar", "baz") + end + + result = [["foo", "expanded_baz", "bar"]] + assert_equal result, @action.shared_folders + end + end + + context "clearing shared folders" do + setup do + @shared_folder = mock("shared_folder") + @shared_folders = [@shared_folder] + @vm.stubs(:shared_folders).returns(@shared_folders) + end + + should "call destroy on each shared folder then reload" do + destroy_seq = sequence("destroy") + @shared_folders.each do |sf| + sf.expects(:destroy).once.in_sequence(destroy_seq) + end + + @mock_vm.expects(:reload!).once.in_sequence(destroy_seq) + @action.clear_shared_folders end end @@ -39,7 +80,7 @@ class SharedFoldersActionTest < Test::Unit::TestCase @vm.stubs(:shared_folders).returns(shared_folders) @vm.expects(:save).with(true).once - @action.before_boot + @action.create_metadata end end diff --git a/test/vagrant/vm_test.rb b/test/vagrant/vm_test.rb index 94c48de0b..623acd16c 100644 --- a/test/vagrant/vm_test.rb +++ b/test/vagrant/vm_test.rb @@ -35,6 +35,16 @@ class VMTest < Test::Unit::TestCase context "vagrant VM instance" do setup do @vm = Vagrant::VM.new(@mock_vm) + @mock_vm.stubs(:uuid).returns("foo") + end + + context "reloading" do + should "load the same VM and set it" do + new_vm = mock("vm") + VirtualBox::VM.expects(:find).with(@mock_vm.uuid).returns(new_vm) + @vm.reload! + assert_equal new_vm, @vm.vm + end end context "packaging" do