diff --git a/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb b/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb index 87efb8c82..abbf917d2 100644 --- a/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb +++ b/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb @@ -6,15 +6,14 @@ module VagrantPlugins class MountVirtualBoxSharedFolder extend SyncedFolder::UnixMountHelpers - VB_MOUNT_TYPE = "vboxsf".freeze - def self.mount_virtualbox_shared_folder(machine, name, guestpath, options) guest_path = Shellwords.escape(guestpath) + mount_type = machine.synced_folders.types[:virtualbox].capability(:mount_type) @@logger.debug("Mounting #{name} (#{options[:hostpath]} to #{guestpath})") - builtin_mount_type = "-cit #{VB_MOUNT_TYPE}" - addon_mount_type = "-t #{VB_MOUNT_TYPE}" + builtin_mount_type = "-cit #{mount_type}" + addon_mount_type = "-t #{mount_type}" mount_options, mount_uid, mount_gid = machine.synced_folders.types[:virtualbox].capability(:mount_options, name, guest_path, options) mount_command = "mount #{addon_mount_type} -o #{mount_options} #{name} #{guest_path}" diff --git a/plugins/guests/linux/cap/persist_mount_shared_folder.rb b/plugins/guests/linux/cap/persist_mount_shared_folder.rb index 3a0445f97..78f187b86 100644 --- a/plugins/guests/linux/cap/persist_mount_shared_folder.rb +++ b/plugins/guests/linux/cap/persist_mount_shared_folder.rb @@ -28,11 +28,12 @@ module VagrantPlugins guest_path = Shellwords.escape(data[:guestpath]) mount_options, _, _ = machine.synced_folders.types[type].capability( :mount_options, name, guest_path, data) + mount_type = machine.synced_folders.types[type].capability(:mount_type) mount_options = "#{mount_options},nofail" { name: name, mount_point: guest_path, - mount_type: type, + mount_type: mount_type, mount_options: mount_options, } } diff --git a/plugins/providers/virtualbox/cap/mount_options.rb b/plugins/providers/virtualbox/cap/mount_options.rb index 1639ba8e9..3f0824ef8 100644 --- a/plugins/providers/virtualbox/cap/mount_options.rb +++ b/plugins/providers/virtualbox/cap/mount_options.rb @@ -6,6 +6,14 @@ module VagrantPlugins module MountOptions extend VagrantPlugins::SyncedFolder::UnixMountHelpers + VB_MOUNT_TYPE = "vboxsf".freeze + + # Returns mount options for a virual box synced folder + # + # @param [Machine] machine + # @param [String] name of mount + # @param [String] path of mount on guest + # @param [Hash] hash of mount options def self.mount_options(machine, name, guest_path, options) mount_options = options.fetch(:mount_options, []) detected_ids = detect_owner_group_ids(machine, guest_path, mount_options, options) @@ -17,6 +25,10 @@ module VagrantPlugins mount_options = mount_options.join(',') return mount_options, mount_uid, mount_gid end + + def self.mount_type(machine) + return VB_MOUNT_TYPE + end end end end diff --git a/plugins/providers/virtualbox/plugin.rb b/plugins/providers/virtualbox/plugin.rb index e193040ca..ad48bd083 100644 --- a/plugins/providers/virtualbox/plugin.rb +++ b/plugins/providers/virtualbox/plugin.rb @@ -73,6 +73,11 @@ module VagrantPlugins require_relative "cap/mount_options" Cap::MountOptions end + + synced_folder_capability(:virtualbox, "mount_type") do + require_relative "cap/mount_options" + Cap::MountOptions + end end autoload :Action, File.expand_path("../action", __FILE__) diff --git a/test/unit/plugins/guests/linux/cap/mount_virtual_box_shared_folder_test.rb b/test/unit/plugins/guests/linux/cap/mount_virtual_box_shared_folder_test.rb index dd9e05bc1..3e8662f78 100644 --- a/test/unit/plugins/guests/linux/cap/mount_virtual_box_shared_folder_test.rb +++ b/test/unit/plugins/guests/linux/cap/mount_virtual_box_shared_folder_test.rb @@ -43,12 +43,14 @@ describe "VagrantPlugins::GuestLinux::Cap::MountVirtualBoxSharedFolder" do it "generates the expected default mount command" do expect(mount_options_cap).to receive(:capability).with(:mount_options, mount_name, mount_guest_path, folder_options).and_return(["uid=#{mount_uid},gid=#{mount_gid}", mount_uid, mount_gid]) + expect(mount_options_cap).to receive(:capability).with(:mount_type).and_return("vboxsf") expect(comm).to receive(:sudo).with("mount -t vboxsf -o uid=#{mount_uid},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything) cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options) end it "automatically chown's the mounted directory on guest" do expect(mount_options_cap).to receive(:capability).with(:mount_options, mount_name, mount_guest_path, folder_options).and_return(["uid=#{mount_uid},gid=#{mount_gid}", mount_uid, mount_gid]) + expect(mount_options_cap).to receive(:capability).with(:mount_type).and_return("vboxsf") expect(comm).to receive(:sudo).with("mount -t vboxsf -o uid=#{mount_uid},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything) expect(comm).to receive(:sudo).with("chown #{mount_uid}:#{mount_gid} #{mount_guest_path}") cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options) @@ -58,6 +60,7 @@ describe "VagrantPlugins::GuestLinux::Cap::MountVirtualBoxSharedFolder" do it "emits mount event" do expect(comm).to receive(:sudo).with(/initctl emit/) + expect(mount_options_cap).to receive(:capability).with(:mount_type).and_return("vboxsf") expect(mount_options_cap).to receive(:capability).with(:mount_options, mount_name, mount_guest_path, folder_options).and_return(["uid=#{mount_uid},gid=#{mount_gid}", mount_uid, mount_gid]) cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options) end @@ -72,6 +75,7 @@ EOF } it "should perform guest mount using builtin module" do expect(mount_options_cap).to receive(:capability).with(:mount_options, mount_name, mount_guest_path, folder_options).and_return(["uid=#{mount_uid},gid=#{mount_gid}", mount_uid, mount_gid]) + expect(mount_options_cap).to receive(:capability).with(:mount_type).and_return("vboxsf") expect(comm).to receive(:sudo).with(/mount -t vboxsf/, any_args).and_yield(:stderr, vbox_stderr).and_return(1) expect(comm).to receive(:sudo).with(/mount -cit/, any_args) cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options) diff --git a/test/unit/plugins/guests/linux/cap/persist_mount_shared_folder_test.rb b/test/unit/plugins/guests/linux/cap/persist_mount_shared_folder_test.rb index b607bc044..030134529 100644 --- a/test/unit/plugins/guests/linux/cap/persist_mount_shared_folder_test.rb +++ b/test/unit/plugins/guests/linux/cap/persist_mount_shared_folder_test.rb @@ -13,11 +13,23 @@ describe "VagrantPlugins::GuestLinux::Cap::PersistMountSharedFolder" do let(:options_uid){ '1234' } let(:cap){ caps.get(:persist_mount_shared_folder) } let(:mount_options_cap){ double("opts") } + let(:ssh_info) {{ + :username => "vagrant" + }} + let (:fstab_folders) { { + "test1" => {:guestpath=>"/test1", :hostpath=>"/my/host/path", :disabled=>false, :__vagrantfile=>true, :owner=>"vagrant", :group=>"vagrant", :mount_options=>["uid=1234", "gid=1234"]}, + "vagrant" => {:guestpath=>"/vagrant", :hostpath=>"/my/host/vagrant", :disabled=>false, :__vagrantfile=>true, :owner=>"vagrant", :group=>"vagrant", :mount_options=>["uid=1234", "gid=1234"]} + }} + let (:folders) { { + :virtualbox => fstab_folders + } } before do allow(machine).to receive(:communicate).and_return(comm) + allow(machine).to receive(:ssh_info).and_return(ssh_info) allow(machine).to receive_message_chain(:synced_folders, :types).and_return( { :virtualbox => mount_options_cap } ) allow(mount_options_cap).to receive(:capability).with(:mount_options, any_args).and_return(["uid=#{options_uid},gid=#{options_gid}", options_uid, options_gid]) + allow(mount_options_cap).to receive(:capability).with(:mount_type).and_return("vboxsf") end after do @@ -44,12 +56,12 @@ describe "VagrantPlugins::GuestLinux::Cap::PersistMountSharedFolder" do expected_entry_test = "test1 /test1 vboxsf uid=#{options_uid},gid=#{options_gid},nofail 0 0" expect(cap).to receive(:remove_vagrant_managed_fstab) expect(comm).to receive(:sudo).with(/#{expected_entry_test}\n#{expected_entry_vagrant}/) - cap.persist_mount_shared_folder(machine, fstab_folders, "vboxsf") + cap.persist_mount_shared_folder(machine, folders) end it "does not insert an empty set of folders" do expect(cap).to receive(:remove_vagrant_managed_fstab) - cap.persist_mount_shared_folder(machine, [], "type") + cap.persist_mount_shared_folder(machine, nil) end end end diff --git a/test/unit/plugins/providers/virtualbox/synced_folder_test.rb b/test/unit/plugins/providers/virtualbox/synced_folder_test.rb index 9ea631ea9..28e8d9511 100644 --- a/test/unit/plugins/providers/virtualbox/synced_folder_test.rb +++ b/test/unit/plugins/providers/virtualbox/synced_folder_test.rb @@ -78,30 +78,6 @@ describe VagrantPlugins::ProviderVirtualBox::SyncedFolder do allow(machine).to receive(:ssh_info).and_return({:username => "test"}) allow(machine).to receive(:guest).and_return(guest) end - - it "should mount and persist all folders with a guest path" do - expect(guest).to receive(:capability).with(:mount_virtualbox_shared_folder, "folder", any_args) - expect(guest).not_to receive(:capability).with(:mount_virtualbox_shared_folder, "no_guestpath_folder", any_args) - expect(guest).to receive(:capability?).with(:persist_mount_shared_folder).and_return(true) - expect(guest).to receive(:capability).with(:persist_mount_shared_folder, any_args) - test_folders = folders.merge(no_guestpath_folder) - subject.enable(machine, test_folders, nil) - end - - context "fstab modification disabled" do - before do - allow(vm_config).to receive(:allow_fstab_modification).and_return(false) - end - - it "should not persist folders" do - expect(guest).to receive(:capability).with(:mount_virtualbox_shared_folder, "folder", any_args) - expect(guest).not_to receive(:capability).with(:mount_virtualbox_shared_folder, "no_guestpath_folder", any_args) - expect(guest).to receive(:capability?).with(:persist_mount_shared_folder).and_return(true) - expect(guest).to receive(:capability).with(:persist_mount_shared_folder, [], "vboxsf") - test_folders = folders.merge(no_guestpath_folder) - subject.enable(machine, test_folders, nil) - end - end end describe "#prepare" do diff --git a/test/unit/vagrant/action/builtin/synced_folders_test.rb b/test/unit/vagrant/action/builtin/synced_folders_test.rb index d168cd332..7d8357c27 100644 --- a/test/unit/vagrant/action/builtin/synced_folders_test.rb +++ b/test/unit/vagrant/action/builtin/synced_folders_test.rb @@ -45,6 +45,7 @@ describe Vagrant::Action::Builtin::SyncedFolders do allow(subject).to receive(:plugins).and_return(plugins) allow(subject).to receive(:synced_folders).and_return(synced_folders) allow(subject).to receive(:save_synced_folders) + allow(machine).to receive_message_chain(:guest, :capability?).with(:persist_mount_shared_folder).and_return(false) end after do @@ -228,5 +229,31 @@ describe Vagrant::Action::Builtin::SyncedFolders do subject.call(env) end end + + context "with guest capability to persist synced folders" do + it "persists folders" do + synced_folders["default"] = { + "root" => { + hostpath: "foo", + }, + + "other" => { + hostpath: "bar", + create: true, + } + } + allow(machine).to receive_message_chain(:guest, :capability?).with(:persist_mount_shared_folder).and_return(true) + expect(vm_config).to receive(:allow_fstab_modification).and_return(true) + expect(machine).to receive_message_chain(:guest, :capability).with(:persist_mount_shared_folder, synced_folders) + subject.call(env) + end + + it "does not persists folders if configured to not do so" do + allow(machine).to receive_message_chain(:guest, :capability?).with(:persist_mount_shared_folder).and_return(true) + expect(vm_config).to receive(:allow_fstab_modification).and_return(false) + expect(machine).to receive_message_chain(:guest, :capability).with(:persist_mount_shared_folder, nil) + subject.call(env) + end + end end end