64 lines
2.1 KiB
Ruby

module VagrantPlugins
module HostDarwin
module Cap
class Path
@@logger = Log4r::Logger.new("vagrant::host::darwin::path")
FIRMLINK_DEFS = "/usr/share/firmlinks".freeze
FIRMLINK_DATA_PATH = "/System/Volumes/Data".freeze
CATALINA_CONSTRAINT = Gem::Requirement.new("~> 10.15")
# Resolve the given host path to the actual
# usable system path by detecting firmlinks
# if available on the current system
#
# @param [String] path Host system path
# @return [String] resolved path
def self.resolve_host_path(env, path)
path = File.expand_path(path)
# Only expand firmlink paths on Catalina
host_version = env.host.capability(:version)
return path if !CATALINA_CONSTRAINT.satisfied_by?(host_version)
firmlink = firmlink_map.detect do |mount_path, data_path|
path.start_with?(mount_path)
end
return path if firmlink.nil?
current_prefix, new_suffix = firmlink
new_prefix = File.join(FIRMLINK_DATA_PATH, new_suffix)
new_path = path.sub(current_prefix, new_prefix)
@@logger.debug("Resolved given path `#{path}` to `#{new_path}`")
new_path
end
# Generate mapping of firmlinks if available on the host
#
# @return [Hash<String,String>]
def self.firmlink_map
if !@firmlink_map
return @firmlink_map = {} if !File.exist?(FIRMLINK_DEFS)
begin
@firmlink_map = Hash[
File.readlines(FIRMLINK_DEFS).map { |d|
d.strip.split(/\s+/, 2)
}
]
rescue => err
@@logger.warn("Failed to parse firmlink definitions: #{err}")
@firmlink_map = {}
end
end
@firmlink_map
end
# @private
# Reset the cached values for capability. This is not considered a public
# API and should only be used for testing.
def self.reset!
instance_variables.each(&method(:remove_instance_variable))
end
end
end
end
end