Only enable shared folder mounts on freebsd guests
Since the virtualbox guest additions seem to only be available for freeBSD, move the shared folder functionality over to freebsd guests rather than all BSD guests.
This commit is contained in:
parent
b2251d5bec
commit
2f0c66f832
|
@ -1,78 +1,14 @@
|
|||
require_relative "../../../synced_folders/unix_mount_helpers"
|
||||
|
||||
module VagrantPlugins
|
||||
module GuestBSD
|
||||
module Cap
|
||||
class VirtualBox
|
||||
extend SyncedFolder::UnixMountHelpers
|
||||
# BSD-based guests do not currently support VirtualBox synced folders.
|
||||
# Instead of raising an error about a missing capability, this defines
|
||||
# the capability and then provides a more detailed error message,
|
||||
# linking to sources on the Internet where the problem is
|
||||
# better-described.
|
||||
def self.mount_virtualbox_shared_folder(machine, name, guestpath, options)
|
||||
guest_path = Shellwords.escape(guestpath)
|
||||
|
||||
@@logger.debug("Mounting #{name} (#{options[:hostpath]} to #{guestpath})")
|
||||
|
||||
builtin_mount_type = "-cit vboxvfs"
|
||||
addon_mount_type = "-t vboxvfs"
|
||||
|
||||
mount_options = options.fetch(:mount_options, [])
|
||||
detected_ids = detect_owner_group_ids(machine, guest_path, mount_options, options)
|
||||
mount_uid = detected_ids[:uid]
|
||||
mount_gid = detected_ids[:gid]
|
||||
|
||||
mount_options << "uid=#{mount_uid}"
|
||||
mount_options << "gid=#{mount_gid}"
|
||||
mount_options = mount_options.join(',')
|
||||
mount_command = "mount #{addon_mount_type} -o #{mount_options} #{name} #{guest_path}"
|
||||
|
||||
# Create the guest path if it doesn't exist
|
||||
machine.communicate.sudo("mkdir -p #{guest_path}")
|
||||
|
||||
stderr = ""
|
||||
result = machine.communicate.sudo(mount_command, error_check: false) do |type, data|
|
||||
stderr << data if type == :stderr
|
||||
end
|
||||
|
||||
if result != 0
|
||||
if stderr.include?("-cit")
|
||||
@@logger.info("Detected builtin vboxvfs module, modifying mount command")
|
||||
mount_command.sub!(addon_mount_type, builtin_mount_type)
|
||||
end
|
||||
|
||||
# Attempt to mount the folder. We retry here a few times because
|
||||
# it can fail early on.
|
||||
stderr = ""
|
||||
retryable(on: Vagrant::Errors::VirtualBoxMountFailed, tries: 3, sleep: 5) do
|
||||
machine.communicate.sudo(mount_command,
|
||||
error_class: Vagrant::Errors::VirtualBoxMountFailed,
|
||||
error_key: :virtualbox_mount_failed,
|
||||
command: mount_command,
|
||||
output: stderr,
|
||||
) { |type, data| stderr = data if type == :stderr }
|
||||
end
|
||||
end
|
||||
|
||||
# Chown the directory to the proper user. We skip this if the
|
||||
# mount options contained a readonly flag, because it won't work.
|
||||
if !options[:mount_options] || !options[:mount_options].include?("ro")
|
||||
chown_command = "chown #{mount_uid}:#{mount_gid} #{guest_path}"
|
||||
machine.communicate.sudo(chown_command)
|
||||
end
|
||||
|
||||
emit_upstart_notification(machine, guest_path)
|
||||
end
|
||||
|
||||
|
||||
def self.unmount_virtualbox_shared_folder(machine, guestpath, options)
|
||||
guest_path = Shellwords.escape(guestpath)
|
||||
|
||||
result = machine.communicate.sudo("umount #{guest_path}", error_check: false)
|
||||
if result == 0
|
||||
machine.communicate.sudo("rmdir #{guest_path}", error_check: false)
|
||||
end
|
||||
raise Vagrant::Errors::VirtualBoxMountNotSupportedBSD
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
require_relative "../../../synced_folders/unix_mount_helpers"
|
||||
|
||||
module VagrantPlugins
|
||||
module GuestFreeBSD
|
||||
module Cap
|
||||
class VirtualBox
|
||||
extend SyncedFolder::UnixMountHelpers
|
||||
|
||||
def self.mount_virtualbox_shared_folder(machine, name, guestpath, options)
|
||||
guest_path = Shellwords.escape(guestpath)
|
||||
|
||||
@@logger.debug("Mounting #{name} (#{options[:hostpath]} to #{guestpath})")
|
||||
|
||||
builtin_mount_type = "-cit vboxvfs"
|
||||
addon_mount_type = "-t vboxvfs"
|
||||
|
||||
mount_options = options.fetch(:mount_options, [])
|
||||
detected_ids = detect_owner_group_ids(machine, guest_path, mount_options, options)
|
||||
mount_uid = detected_ids[:uid]
|
||||
mount_gid = detected_ids[:gid]
|
||||
|
||||
mount_options << "uid=#{mount_uid}"
|
||||
mount_options << "gid=#{mount_gid}"
|
||||
mount_options = mount_options.join(',')
|
||||
mount_command = "mount #{addon_mount_type} -o #{mount_options} #{name} #{guest_path}"
|
||||
|
||||
# Create the guest path if it doesn't exist
|
||||
machine.communicate.sudo("mkdir -p #{guest_path}")
|
||||
|
||||
stderr = ""
|
||||
result = machine.communicate.sudo(mount_command, error_check: false) do |type, data|
|
||||
stderr << data if type == :stderr
|
||||
end
|
||||
|
||||
if result != 0
|
||||
if stderr.include?("-cit")
|
||||
@@logger.info("Detected builtin vboxvfs module, modifying mount command")
|
||||
mount_command.sub!(addon_mount_type, builtin_mount_type)
|
||||
end
|
||||
|
||||
# Attempt to mount the folder. We retry here a few times because
|
||||
# it can fail early on.
|
||||
stderr = ""
|
||||
retryable(on: Vagrant::Errors::VirtualBoxMountFailed, tries: 3, sleep: 5) do
|
||||
machine.communicate.sudo(mount_command,
|
||||
error_class: Vagrant::Errors::VirtualBoxMountFailed,
|
||||
error_key: :virtualbox_mount_failed,
|
||||
command: mount_command,
|
||||
output: stderr,
|
||||
) { |type, data| stderr = data if type == :stderr }
|
||||
end
|
||||
end
|
||||
|
||||
# Chown the directory to the proper user. We skip this if the
|
||||
# mount options contained a readonly flag, because it won't work.
|
||||
if !options[:mount_options] || !options[:mount_options].include?("ro")
|
||||
chown_command = "chown #{mount_uid}:#{mount_gid} #{guest_path}"
|
||||
machine.communicate.sudo(chown_command)
|
||||
end
|
||||
|
||||
emit_upstart_notification(machine, guest_path)
|
||||
end
|
||||
|
||||
|
||||
def self.unmount_virtualbox_shared_folder(machine, guestpath, options)
|
||||
guest_path = Shellwords.escape(guestpath)
|
||||
|
||||
result = machine.communicate.sudo("umount #{guest_path}", error_check: false)
|
||||
if result == 0
|
||||
machine.communicate.sudo("rmdir #{guest_path}", error_check: false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -50,6 +50,11 @@ module VagrantPlugins
|
|||
require_relative "cap/shell_expand_guest_path"
|
||||
Cap::ShellExpandGuestPath
|
||||
end
|
||||
|
||||
guest_capability(:freebsd, :mount_virtualbox_shared_folder) do
|
||||
require_relative "cap/virtualbox"
|
||||
Cap::VirtualBox
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -33,193 +33,9 @@ describe "VagrantPlugins::GuestBSD::Cap::VirtualBox" do
|
|||
end
|
||||
|
||||
describe ".mount_virtualbox_shared_folder" do
|
||||
|
||||
before do
|
||||
allow(comm).to receive(:sudo).with(any_args)
|
||||
allow(comm).to receive(:execute).with(any_args)
|
||||
end
|
||||
|
||||
it "generates the expected default mount command" do
|
||||
expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:")
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -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(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:")
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -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)
|
||||
end
|
||||
|
||||
context "with owner user ID explicitly defined" do
|
||||
|
||||
before do
|
||||
expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:")
|
||||
end
|
||||
|
||||
context "with user ID provided as Integer" do
|
||||
let(:mount_owner){ 2000 }
|
||||
|
||||
it "generates the expected mount command using mount_owner directly" do
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o uid=#{mount_owner},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything)
|
||||
expect(comm).to receive(:sudo).with("chown #{mount_owner}:#{mount_gid} #{mount_guest_path}")
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options)
|
||||
end
|
||||
end
|
||||
|
||||
context "with user ID provided as String" do
|
||||
let(:mount_owner){ "2000" }
|
||||
|
||||
it "generates the expected mount command using mount_owner directly" do
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o uid=#{mount_owner},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything)
|
||||
expect(comm).to receive(:sudo).with("chown #{mount_owner}:#{mount_gid} #{mount_guest_path}")
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "with owner group ID explicitly defined" do
|
||||
|
||||
before do
|
||||
expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
end
|
||||
|
||||
context "with owner group ID provided as Integer" do
|
||||
let(:mount_group){ 2000 }
|
||||
|
||||
it "generates the expected mount command using mount_group directly" do
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o uid=#{mount_uid},gid=#{mount_group} #{mount_name} #{mount_guest_path}", anything)
|
||||
expect(comm).to receive(:sudo).with("chown #{mount_uid}:#{mount_group} #{mount_guest_path}")
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options)
|
||||
end
|
||||
end
|
||||
|
||||
context "with owner group ID provided as String" do
|
||||
let(:mount_group){ "2000" }
|
||||
|
||||
it "generates the expected mount command using mount_group directly" do
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o uid=#{mount_uid},gid=#{mount_group} #{mount_name} #{mount_guest_path}", anything)
|
||||
expect(comm).to receive(:sudo).with("chown #{mount_uid}:#{mount_group} #{mount_guest_path}")
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "with non-existent default owner group" do
|
||||
|
||||
it "fetches the effective group ID of the user" do
|
||||
expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_raise(Vagrant::Errors::VirtualBoxMountFailed, {command: '', output: ''})
|
||||
expect(comm).to receive(:execute).with("id -g #{mount_owner}", anything).and_yield(:stdout, "1").and_return(0)
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options)
|
||||
end
|
||||
end
|
||||
|
||||
context "with non-existent owner group" do
|
||||
|
||||
it "raises an error" do
|
||||
expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_raise(Vagrant::Errors::VirtualBoxMountFailed, {command: '', output: ''})
|
||||
expect do
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options)
|
||||
end.to raise_error Vagrant::Errors::VirtualBoxMountFailed
|
||||
end
|
||||
end
|
||||
|
||||
context "with read-only option defined" do
|
||||
|
||||
it "does not chown mounted guest directory" do
|
||||
expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:")
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o ro,uid=#{mount_uid},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything)
|
||||
expect(comm).not_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.merge(mount_options: ["ro"]))
|
||||
end
|
||||
end
|
||||
|
||||
context "with upstart init" do
|
||||
|
||||
it "emits mount event" do
|
||||
expect(comm).to receive(:sudo).with(/initctl emit/)
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options)
|
||||
end
|
||||
end
|
||||
|
||||
context "with custom mount options" do
|
||||
|
||||
let(:ui){ double(:ui) }
|
||||
before do
|
||||
allow(ui).to receive(:warn)
|
||||
allow(machine).to receive(:ui).and_return(ui)
|
||||
end
|
||||
|
||||
context "with uid defined" do
|
||||
let(:options_uid){ '1234' }
|
||||
|
||||
it "should only include uid defined within mount options" do
|
||||
expect(comm).not_to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:")
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o uid=#{options_uid},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything)
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options.merge(mount_options: ["uid=#{options_uid}"]))
|
||||
end
|
||||
end
|
||||
|
||||
context "with gid defined" do
|
||||
let(:options_gid){ '1234' }
|
||||
|
||||
it "should only include gid defined within mount options" do
|
||||
expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).not_to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:")
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o uid=#{mount_uid},gid=#{options_gid} #{mount_name} #{mount_guest_path}", anything)
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options.merge(mount_options: ["gid=#{options_gid}"]))
|
||||
end
|
||||
end
|
||||
|
||||
context "with uid and gid defined" do
|
||||
let(:options_gid){ '1234' }
|
||||
let(:options_uid){ '1234' }
|
||||
|
||||
it "should only include uid and gid defined within mount options" do
|
||||
expect(comm).not_to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).not_to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{options_gid}:")
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o uid=#{options_uid},gid=#{options_gid} #{mount_name} #{mount_guest_path}", anything)
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options.merge(mount_options: ["gid=#{options_gid}", "uid=#{options_uid}"]))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with guest builtin vboxvfs module" do
|
||||
let(:vbox_stderr){ <<-EOF
|
||||
mount.vboxvfs cannot be used with mainline vboxvfs; instead use:
|
||||
|
||||
mount -cit vboxvfs NAME MOUNTPOINT
|
||||
EOF
|
||||
}
|
||||
it "should perform guest mount using builtin module" do
|
||||
expect(comm).to receive(:sudo).with(/mount -t vboxvfs/, 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)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".unmount_virtualbox_shared_folder" do
|
||||
|
||||
after { cap.unmount_virtualbox_shared_folder(machine, mount_guest_path, folder_options) }
|
||||
|
||||
it "unmounts shared directory and deletes directory on guest" do
|
||||
expect(comm).to receive(:sudo).with("umount #{mount_guest_path}", anything).and_return(0)
|
||||
expect(comm).to receive(:sudo).with("rmdir #{mount_guest_path}", anything)
|
||||
end
|
||||
|
||||
it "does not delete guest directory if unmount fails" do
|
||||
expect(comm).to receive(:sudo).with("umount #{mount_guest_path}", anything).and_return(1)
|
||||
expect(comm).not_to receive(:sudo).with("rmdir #{mount_guest_path}", anything)
|
||||
it "raises an error as unsupported" do
|
||||
expect {cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options) }.
|
||||
to raise_error(Vagrant::Errors::VirtualBoxMountNotSupportedBSD)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,225 @@
|
|||
require_relative "../../../../base"
|
||||
|
||||
describe "VagrantPlugins::GuestFreeBSD::Cap::VirtualBox" do
|
||||
let(:caps) do
|
||||
VagrantPlugins::GuestFreeBSD::Plugin
|
||||
.components
|
||||
.guest_capabilities[:freebsd]
|
||||
end
|
||||
|
||||
let(:machine) { double("machine") }
|
||||
let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
|
||||
let(:mount_owner){ "vagrant" }
|
||||
let(:mount_group){ "vagrant" }
|
||||
let(:mount_uid){ "1000" }
|
||||
let(:mount_gid){ "1000" }
|
||||
let(:mount_name){ "vagrant" }
|
||||
let(:mount_guest_path){ "/vagrant" }
|
||||
let(:folder_options) do
|
||||
{
|
||||
owner: mount_owner,
|
||||
group: mount_group,
|
||||
hostpath: "/host/directory/path"
|
||||
}
|
||||
end
|
||||
let(:cap){ caps.get(:mount_virtualbox_shared_folder) }
|
||||
|
||||
before do
|
||||
allow(machine).to receive(:communicate).and_return(comm)
|
||||
end
|
||||
|
||||
after do
|
||||
comm.verify_expectations!
|
||||
end
|
||||
|
||||
describe ".mount_virtualbox_shared_folder" do
|
||||
|
||||
before do
|
||||
allow(comm).to receive(:sudo).with(any_args)
|
||||
allow(comm).to receive(:execute).with(any_args)
|
||||
end
|
||||
|
||||
it "generates the expected default mount command" do
|
||||
expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:")
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -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(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:")
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -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)
|
||||
end
|
||||
|
||||
context "with owner user ID explicitly defined" do
|
||||
|
||||
before do
|
||||
expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:")
|
||||
end
|
||||
|
||||
context "with user ID provided as Integer" do
|
||||
let(:mount_owner){ 2000 }
|
||||
|
||||
it "generates the expected mount command using mount_owner directly" do
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o uid=#{mount_owner},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything)
|
||||
expect(comm).to receive(:sudo).with("chown #{mount_owner}:#{mount_gid} #{mount_guest_path}")
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options)
|
||||
end
|
||||
end
|
||||
|
||||
context "with user ID provided as String" do
|
||||
let(:mount_owner){ "2000" }
|
||||
|
||||
it "generates the expected mount command using mount_owner directly" do
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o uid=#{mount_owner},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything)
|
||||
expect(comm).to receive(:sudo).with("chown #{mount_owner}:#{mount_gid} #{mount_guest_path}")
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "with owner group ID explicitly defined" do
|
||||
|
||||
before do
|
||||
expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
end
|
||||
|
||||
context "with owner group ID provided as Integer" do
|
||||
let(:mount_group){ 2000 }
|
||||
|
||||
it "generates the expected mount command using mount_group directly" do
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o uid=#{mount_uid},gid=#{mount_group} #{mount_name} #{mount_guest_path}", anything)
|
||||
expect(comm).to receive(:sudo).with("chown #{mount_uid}:#{mount_group} #{mount_guest_path}")
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options)
|
||||
end
|
||||
end
|
||||
|
||||
context "with owner group ID provided as String" do
|
||||
let(:mount_group){ "2000" }
|
||||
|
||||
it "generates the expected mount command using mount_group directly" do
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o uid=#{mount_uid},gid=#{mount_group} #{mount_name} #{mount_guest_path}", anything)
|
||||
expect(comm).to receive(:sudo).with("chown #{mount_uid}:#{mount_group} #{mount_guest_path}")
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "with non-existent default owner group" do
|
||||
|
||||
it "fetches the effective group ID of the user" do
|
||||
expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_raise(Vagrant::Errors::VirtualBoxMountFailed, {command: '', output: ''})
|
||||
expect(comm).to receive(:execute).with("id -g #{mount_owner}", anything).and_yield(:stdout, "1").and_return(0)
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options)
|
||||
end
|
||||
end
|
||||
|
||||
context "with non-existent owner group" do
|
||||
|
||||
it "raises an error" do
|
||||
expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_raise(Vagrant::Errors::VirtualBoxMountFailed, {command: '', output: ''})
|
||||
expect do
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options)
|
||||
end.to raise_error Vagrant::Errors::VirtualBoxMountFailed
|
||||
end
|
||||
end
|
||||
|
||||
context "with read-only option defined" do
|
||||
|
||||
it "does not chown mounted guest directory" do
|
||||
expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:")
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o ro,uid=#{mount_uid},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything)
|
||||
expect(comm).not_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.merge(mount_options: ["ro"]))
|
||||
end
|
||||
end
|
||||
|
||||
context "with upstart init" do
|
||||
|
||||
it "emits mount event" do
|
||||
expect(comm).to receive(:sudo).with(/initctl emit/)
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options)
|
||||
end
|
||||
end
|
||||
|
||||
context "with custom mount options" do
|
||||
|
||||
let(:ui){ double(:ui) }
|
||||
before do
|
||||
allow(ui).to receive(:warn)
|
||||
allow(machine).to receive(:ui).and_return(ui)
|
||||
end
|
||||
|
||||
context "with uid defined" do
|
||||
let(:options_uid){ '1234' }
|
||||
|
||||
it "should only include uid defined within mount options" do
|
||||
expect(comm).not_to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:")
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o uid=#{options_uid},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything)
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options.merge(mount_options: ["uid=#{options_uid}"]))
|
||||
end
|
||||
end
|
||||
|
||||
context "with gid defined" do
|
||||
let(:options_gid){ '1234' }
|
||||
|
||||
it "should only include gid defined within mount options" do
|
||||
expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).not_to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:")
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o uid=#{mount_uid},gid=#{options_gid} #{mount_name} #{mount_guest_path}", anything)
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options.merge(mount_options: ["gid=#{options_gid}"]))
|
||||
end
|
||||
end
|
||||
|
||||
context "with uid and gid defined" do
|
||||
let(:options_gid){ '1234' }
|
||||
let(:options_uid){ '1234' }
|
||||
|
||||
it "should only include uid and gid defined within mount options" do
|
||||
expect(comm).not_to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid)
|
||||
expect(comm).not_to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{options_gid}:")
|
||||
expect(comm).to receive(:sudo).with("mount -t vboxvfs -o uid=#{options_uid},gid=#{options_gid} #{mount_name} #{mount_guest_path}", anything)
|
||||
cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options.merge(mount_options: ["gid=#{options_gid}", "uid=#{options_uid}"]))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with guest builtin vboxvfs module" do
|
||||
let(:vbox_stderr){ <<-EOF
|
||||
mount.vboxvfs cannot be used with mainline vboxvfs; instead use:
|
||||
|
||||
mount -cit vboxvfs NAME MOUNTPOINT
|
||||
EOF
|
||||
}
|
||||
it "should perform guest mount using builtin module" do
|
||||
expect(comm).to receive(:sudo).with(/mount -t vboxvfs/, 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)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".unmount_virtualbox_shared_folder" do
|
||||
|
||||
after { cap.unmount_virtualbox_shared_folder(machine, mount_guest_path, folder_options) }
|
||||
|
||||
it "unmounts shared directory and deletes directory on guest" do
|
||||
expect(comm).to receive(:sudo).with("umount #{mount_guest_path}", anything).and_return(0)
|
||||
expect(comm).to receive(:sudo).with("rmdir #{mount_guest_path}", anything)
|
||||
end
|
||||
|
||||
it "does not delete guest directory if unmount fails" do
|
||||
expect(comm).to receive(:sudo).with("umount #{mount_guest_path}", anything).and_return(1)
|
||||
expect(comm).not_to receive(:sudo).with("rmdir #{mount_guest_path}", anything)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue