2013-04-04 06:01:43 +00:00
|
|
|
module VagrantPlugins
|
|
|
|
module GuestLinux
|
|
|
|
module Cap
|
|
|
|
class MountVirtualBoxSharedFolder
|
|
|
|
def self.mount_virtualbox_shared_folder(machine, name, guestpath, options)
|
|
|
|
expanded_guest_path = machine.guest.capability(
|
|
|
|
:shell_expand_guest_path, guestpath)
|
|
|
|
|
2013-09-17 03:51:09 +00:00
|
|
|
mount_commands = []
|
|
|
|
|
2013-10-18 02:40:21 +00:00
|
|
|
if options[:owner].is_a? Integer
|
|
|
|
mount_uid = options[:owner]
|
|
|
|
else
|
|
|
|
mount_uid = "`id -u #{options[:owner]}`"
|
|
|
|
end
|
|
|
|
|
|
|
|
if options[:group].is_a? Integer
|
|
|
|
mount_gid = options[:group]
|
|
|
|
mount_gid_old = options[:group]
|
|
|
|
else
|
|
|
|
mount_gid = "`getent group #{options[:group]} | cut -d: -f3`"
|
|
|
|
mount_gid_old = "`id -g #{options[:group]}`"
|
|
|
|
end
|
|
|
|
|
2013-09-17 03:51:09 +00:00
|
|
|
# First mount command uses getent to get the group
|
2013-10-18 02:40:21 +00:00
|
|
|
mount_options = "-o uid=#{mount_uid},gid=#{mount_gid}"
|
2013-09-17 03:51:09 +00:00
|
|
|
mount_options += ",#{options[:mount_options].join(",")}" if options[:mount_options]
|
|
|
|
mount_commands << "mount -t vboxsf #{mount_options} #{name} #{expanded_guest_path}"
|
2013-09-01 19:25:21 +00:00
|
|
|
|
2013-09-17 03:51:09 +00:00
|
|
|
# Second mount command uses the old style `id -g`
|
2013-10-18 02:40:21 +00:00
|
|
|
mount_options = "-o uid=#{mount_uid},gid=#{mount_gid_old}"
|
2013-09-17 03:51:09 +00:00
|
|
|
mount_options += ",#{options[:mount_options].join(",")}" if options[:mount_options]
|
|
|
|
mount_commands << "mount -t vboxsf #{mount_options} #{name} #{expanded_guest_path}"
|
2013-04-04 06:01:43 +00:00
|
|
|
|
|
|
|
# Create the guest path if it doesn't exist
|
|
|
|
machine.communicate.sudo("mkdir -p #{expanded_guest_path}")
|
|
|
|
|
|
|
|
# Attempt to mount the folder. We retry here a few times because
|
|
|
|
# it can fail early on.
|
|
|
|
attempts = 0
|
|
|
|
while true
|
|
|
|
success = true
|
2013-09-17 03:51:09 +00:00
|
|
|
|
2014-08-29 15:27:48 +00:00
|
|
|
stderr = ""
|
2013-09-17 03:51:09 +00:00
|
|
|
mount_commands.each do |command|
|
2013-09-21 00:50:29 +00:00
|
|
|
no_such_device = false
|
2014-08-29 15:27:48 +00:00
|
|
|
stderr = ""
|
2013-09-21 00:50:29 +00:00
|
|
|
status = machine.communicate.sudo(command, error_check: false) do |type, data|
|
2014-08-29 15:27:48 +00:00
|
|
|
if type == :stderr
|
|
|
|
no_such_device = true if data =~ /No such device/i
|
|
|
|
stderr += data.to_s
|
|
|
|
end
|
2013-09-17 03:51:09 +00:00
|
|
|
end
|
|
|
|
|
2013-09-21 00:50:29 +00:00
|
|
|
success = status == 0 && !no_such_device
|
2013-09-17 03:51:09 +00:00
|
|
|
break if success
|
2013-04-04 06:01:43 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
break if success
|
|
|
|
|
|
|
|
attempts += 1
|
2013-09-21 00:52:36 +00:00
|
|
|
if attempts > 10
|
|
|
|
raise Vagrant::Errors::LinuxMountFailed,
|
2014-08-29 15:27:48 +00:00
|
|
|
command: mount_commands.join("\n"),
|
|
|
|
output: stderr
|
2013-09-21 00:52:36 +00:00
|
|
|
end
|
|
|
|
|
2014-08-29 16:47:34 +00:00
|
|
|
sleep(2*attempts)
|
2013-04-04 06:01:43 +00:00
|
|
|
end
|
|
|
|
|
2014-02-04 15:01:14 +00:00
|
|
|
# Chown the directory to the proper user. We skip this if the
|
|
|
|
# mount options contained a readonly flag, because it won't work.
|
2014-02-08 00:04:36 +00:00
|
|
|
if !options[:mount_options] || !options[:mount_options].include?("ro")
|
2014-02-04 15:01:14 +00:00
|
|
|
chown_commands = []
|
|
|
|
chown_commands << "chown #{mount_uid}:#{mount_gid} #{expanded_guest_path}"
|
|
|
|
chown_commands << "chown #{mount_uid}:#{mount_gid_old} #{expanded_guest_path}"
|
2013-09-17 03:51:09 +00:00
|
|
|
|
2014-02-04 15:01:14 +00:00
|
|
|
exit_status = machine.communicate.sudo(chown_commands[0], error_check: false)
|
|
|
|
machine.communicate.sudo(chown_commands[1]) if exit_status != 0
|
|
|
|
end
|
2013-11-25 19:31:15 +00:00
|
|
|
|
|
|
|
# Emit an upstart event if we can
|
2015-11-19 00:18:29 +00:00
|
|
|
machine.communicate.sudo <<-SCRIPT
|
|
|
|
if command -v /sbin/init &>/dev/null && /sbin/init --version | grep upstart &>/dev/null; then
|
|
|
|
/sbin/initctl emit --no-wait vagrant-mounted MOUNTPOINT='#{expanded_guest_path}'
|
|
|
|
fi
|
|
|
|
SCRIPT
|
2013-04-04 06:01:43 +00:00
|
|
|
end
|
2014-04-16 21:59:23 +00:00
|
|
|
|
|
|
|
def self.unmount_virtualbox_shared_folder(machine, guestpath, options)
|
|
|
|
result = machine.communicate.sudo(
|
|
|
|
"umount #{guestpath}", error_check: false)
|
|
|
|
if result == 0
|
2014-04-20 15:36:52 +00:00
|
|
|
machine.communicate.sudo("rmdir #{guestpath}", error_check: false)
|
2014-04-16 21:59:23 +00:00
|
|
|
end
|
|
|
|
end
|
2013-04-04 06:01:43 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|