File: mount_virtualbox_shared_folder.rb

package info (click to toggle)
vagrant 2.2.14%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 9,800 kB
  • sloc: ruby: 97,301; sh: 375; makefile: 16; lisp: 1
file content (75 lines) | stat: -rw-r--r-- 2,970 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
require_relative "../../../synced_folders/unix_mount_helpers"

module VagrantPlugins
  module GuestLinux
    module Cap
      class MountVirtualBoxSharedFolder
        extend SyncedFolder::UnixMountHelpers

        # Mounts and virtualbox folder on linux guest
        #
        # @param [Machine] machine
        # @param [String] name of mount
        # @param [String] path of mount on guest
        # @param [Hash] hash of mount options 
        def self.mount_virtualbox_shared_folder(machine, name, guestpath, options)
          guest_path = Shellwords.escape(guestpath)
          mount_type = options[:plugin].capability(:mount_type)

          @@logger.debug("Mounting #{name} (#{options[:hostpath]} to #{guestpath})")

          builtin_mount_type = "-cit #{mount_type}"
          addon_mount_type = "-t #{mount_type}"

          mount_options, mount_uid, mount_gid = options[:plugin].capability(:mount_options, name, guest_path, options)
          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 vboxsf 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