"Fossies" - the Fresh Open Source Software Archive 
Member "vagrant-2.2.14/plugins/guests/darwin/cap/mount_vmware_shared_folder.rb" (20 Nov 2020, 5101 Bytes) of package /linux/misc/vagrant-2.2.14.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Ruby source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
See also the latest
Fossies "Diffs" side-by-side code changes report for "mount_vmware_shared_folder.rb":
2.2.13_vs_2.2.14.
1 require "securerandom"
2
3 module VagrantPlugins
4 module GuestDarwin
5 module Cap
6 class MountVmwareSharedFolder
7
8 MACOS_BIGSUR_DARWIN_VERSION = 20.freeze
9
10 # Entry point for hook to called delayed actions
11 # which finalizing the synced folders setup on
12 # the guest
13 def self.write_apfs_firmlinks(env)
14 if env && env[:machine] && delayed = apfs_firmlinks_delayed.delete(env[:machine].id)
15 delayed.call
16 end
17 end
18
19 # @return [Hash] storage location for delayed actions
20 def self.apfs_firmlinks_delayed
21 if !@_apfs_firmlinks
22 @_apfs_firmlinks = {}
23 end
24 @_apfs_firmlinks
25 end
26
27 # we seem to be unable to ask 'mount -t vmhgfs' to mount the roots
28 # of specific shares, so instead we symlink from what is already
29 # mounted by the guest tools
30 # (ie. the behaviour of the VMware_fusion provider prior to 0.8.x)
31
32 def self.mount_vmware_shared_folder(machine, name, guestpath, options)
33 # Use this variable to determine which machines
34 # have been registered with after hook
35 @apply_firmlinks ||= Hash.new{ |h, k| h[k] = {bootstrap: false, content: []} }
36
37 machine.communicate.tap do |comm|
38 # check if we are dealing with an APFS root container
39 if comm.test("test -d /System/Volumes/Data")
40 parts = Pathname.new(guestpath).descend.to_a
41 firmlink = parts[1].to_s
42 firmlink.slice!(0, 1) if firmlink.start_with?("/")
43 if parts.size > 2
44 guestpath = File.join("/System/Volumes/Data", guestpath)
45 else
46 guestpath = nil
47 end
48 end
49
50 # Remove existing symlink or directory if defined
51 if guestpath
52 if comm.test("test -L \"#{guestpath}\"")
53 comm.sudo("rm -f \"#{guestpath}\"")
54 elsif comm.test("test -d \"#{guestpath}\"")
55 comm.sudo("rm -Rf \"#{guestpath}\"")
56 end
57
58 # create intermediate directories if needed
59 intermediate_dir = File.dirname(guestpath)
60 if intermediate_dir != "/"
61 comm.sudo("mkdir -p \"#{intermediate_dir}\"")
62 end
63
64 comm.sudo("ln -s \"/Volumes/VMware Shared Folders/#{name}\" \"#{guestpath}\"")
65 end
66
67 if firmlink && !system_firmlink?(firmlink)
68 if guestpath.nil?
69 guestpath = "/Volumes/VMware Shared Folders/#{name}"
70 else
71 guestpath = File.join("/System/Volumes/Data", firmlink)
72 end
73
74 share_line = "#{firmlink}\t#{guestpath}"
75
76 # Check if the line is already defined. If so, bail since we are done
77 if !comm.test("[[ \"$(</etc/synthetic.conf)\" = *\"#{share_line}\"* ]]")
78 @apply_firmlinks[machine.id][:bootstrap] = true
79 end
80
81 # If we haven't already added our hook to apply firmlinks, do it now
82 if @apply_firmlinks[machine.id][:content].empty?
83 apfs_firmlinks_delayed[machine.id] = proc do
84 content = @apply_firmlinks[machine.id][:content].join("\n")
85 # Write out the synthetic file
86 comm.sudo("echo -e #{content.inspect} > /etc/synthetic.conf")
87 if @apply_firmlinks[machine.id][:bootstrap]
88 if machine.guest.capability("darwin_major_version").to_i < MACOS_BIGSUR_DARWIN_VERSION
89 apfs_bootstrap_flag = "-B"
90 expected_rc = 0
91 else
92 apfs_bootstrap_flag = "-t"
93 expected_rc = 253
94 end
95 # Re-bootstrap the root container to pick up firmlink updates
96 comm.sudo("/System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util #{apfs_bootstrap_flag}", good_exit: [expected_rc])
97 end
98 end
99 end
100 @apply_firmlinks[machine.id][:content] << share_line
101 end
102 end
103 end
104
105 # Check if firmlink is provided by the system
106 #
107 # @param [String] firmlink Firmlink path
108 # @return [Boolean]
109 def self.system_firmlink?(firmlink)
110 if !@_firmlinks
111 if File.exist?("/usr/share/firmlinks")
112 @_firmlinks = File.readlines("/usr/share/firmlinks").map do |line|
113 line.split.first
114 end
115 else
116 @_firmlinks = []
117 end
118 end
119 firmlink = "/#{firmlink}" if !firmlink.start_with?("/")
120 @_firmlinks.include?(firmlink)
121 end
122
123 # @private
124 # Reset the cached values for capability. This is not considered a public
125 # API and should only be used for testing.
126 def self.reset!
127 instance_variables.each(&method(:remove_instance_variable))
128 end
129 end
130 end
131 end
132 end