-
Notifications
You must be signed in to change notification settings - Fork 4.4k
/
synced_folder.rb
153 lines (126 loc) · 4.89 KB
/
synced_folder.rb
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: BUSL-1.1
require "fileutils"
require "vagrant/util/platform"
module VagrantPlugins
module ProviderVirtualBox
class SyncedFolder < Vagrant.plugin("2", :synced_folder)
def usable?(machine, raise_errors=false)
# These synced folders only work if the provider if VirtualBox
return false if machine.provider_name != :virtualbox
# This only happens with `vagrant package --base`. Sigh.
return true if !machine.provider_config
machine.provider_config.functional_vboxsf
end
def prepare(machine, folders, _opts)
share_folders(machine, folders, false)
end
def enable(machine, folders, _opts)
share_folders(machine, folders, true)
# short guestpaths first, so we don't step on ourselves
folders = folders.sort_by do |id, data|
if data[:guestpath]
data[:guestpath].length
else
# A long enough path to just do this at the end.
10000
end
end
# Go through each folder and mount
machine.ui.output(I18n.t("vagrant.actions.vm.share_folders.mounting"))
fstab_folders = []
folders.each do |id, data|
if data[:guestpath]
# Guest path specified, so mount the folder to specified point
machine.ui.detail(I18n.t("vagrant.actions.vm.share_folders.mounting_entry",
guestpath: data[:guestpath],
hostpath: data[:hostpath]))
# Dup the data so we can pass it to the guest API
data = data.dup
# Calculate the owner and group
ssh_info = machine.ssh_info
data[:owner] ||= ssh_info[:username]
data[:group] ||= ssh_info[:username]
# Mount the actual folder
machine.guest.capability(
:mount_virtualbox_shared_folder,
os_friendly_id(id), data[:guestpath], data)
else
# If no guest path is specified, then automounting is disabled
machine.ui.detail(I18n.t("vagrant.actions.vm.share_folders.nomount_entry",
hostpath: data[:hostpath]))
end
end
end
def disable(machine, folders, _opts)
if machine.guest.capability?(:unmount_virtualbox_shared_folder)
folders.each do |id, data|
machine.guest.capability(
:unmount_virtualbox_shared_folder,
data[:guestpath], data)
end
end
# Remove the shared folders from the VM metadata
names = folders.map { |id, _data| os_friendly_id(id) }
driver(machine).unshare_folders(names)
end
def cleanup(machine, opts)
driver(machine).clear_shared_folders if machine.id && machine.id != ""
end
protected
# This is here so that we can stub it for tests
def driver(machine)
machine.provider.driver
end
def os_friendly_id(id)
id.gsub(/[\s\/\\]/,'_').sub(/^_/, '')
end
# share_folders sets up the shared folder definitions on the
# VirtualBox VM.
#
# The transient parameter determines if we're FORCING transient
# or not. If this is false, then any shared folders will be
# shared as non-transient unless they've specifically asked for
# transient.
def share_folders(machine, folders, transient)
defs = []
warn_user_symlink = false
folders.each do |id, data|
hostpath = data[:hostpath]
if !data[:hostpath_exact]
hostpath = Vagrant::Util::Platform.cygwin_windows_path(hostpath)
end
enable_symlink_create = true
if ENV['VAGRANT_DISABLE_VBOXSYMLINKCREATE']
enable_symlink_create = false
end
unless data[:SharedFoldersEnableSymlinksCreate].nil?
enable_symlink_create = data[:SharedFoldersEnableSymlinksCreate]
end
warn_user_symlink ||= enable_symlink_create
# Only setup the shared folders that match our transient level
if (!!data[:transient]) == transient
defs << {
name: os_friendly_id(id),
hostpath: hostpath.to_s,
transient: transient,
SharedFoldersEnableSymlinksCreate: enable_symlink_create,
automount: !!data[:automount]
}
end
end
if warn_user_symlink
display_symlink_create_warning(machine.env)
end
driver(machine).share_folders(defs)
end
def display_symlink_create_warning(env)
d_file = env.data_dir.join("vbox_symlink_create_warning")
if !d_file.exist?
FileUtils.touch(d_file.to_path)
env.ui.warn(I18n.t("vagrant.virtualbox.warning.shared_folder_symlink_create"))
end
end
end
end
end