Merge pull request #12570 from chrisroberts/darwin-nfs

Fix NFS host paths on darwin
This commit is contained in:
Chris Roberts 2021-11-03 11:06:27 -07:00 committed by GitHub
commit 69ddf98607
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 123 additions and 4 deletions

View File

@ -356,6 +356,10 @@ module Vagrant
error_key(:darwin_mount_failed)
end
class DarwinVersionFailed < VagrantError
error_key(:darwin_version_failed)
end
class DestroyRequiresForce < VagrantError
error_key(:destroy_requires_force)
end

View File

@ -29,9 +29,12 @@ module VagrantPlugins
"//#{options[:smb_username]}:#{smb_password}@#{options[:smb_host]}/#{name} " +
"#{expanded_guest_path}"
retryable(on: Vagrant::Errors::DarwinMountFailed, tries: 10, sleep: 2) do
machine.communicate.execute(
mount_command,
error_class: Vagrant::Errors::DarwinMountFailed)
result = machine.communicate.execute(mount_command)
if result.exit_code != 0
raise Vagrant::Errors::DarwinMountFailed,
command: mount_command,
output: result.stderr
end
end
end
end

View File

@ -6,6 +6,7 @@ module VagrantPlugins
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
@ -15,6 +16,9 @@ module VagrantPlugins
# @return [String] resolved path
def self.resolve_host_path(env, path)
path = File.expand_path(path)
# Only expand firmlink paths on Catalina
return path if !CATALINA_CONSTRAINT.satisfied_by?(Cap::Version.version(env))
firmlink = firmlink_map.detect do |mount_path, data_path|
path.start_with?(mount_path)
end

View File

@ -0,0 +1,23 @@
module VagrantPlugins
module HostDarwin
module Cap
class Version
def self.version(env)
r = Vagrant::Util::Subprocess.execute("sw_vers", "-productVersion")
if r.exit_code != 0
raise Vagrant::Errors::DarwinVersionFailed,
version: r.stdout,
error: r.stderr
end
begin
Gem::Version.new(r.stdout)
rescue => err
raise Vagrant::Errors::DarwinVersionFailed,
version: r.stdout,
error: err.message
end
end
end
end
end
end

View File

@ -70,6 +70,11 @@ module VagrantPlugins
require_relative "cap/nfs"
Cap::NFS
end
host_capability("darwin", "version") do
require_relative "cap/version"
Cap::Version
end
end
end
end

View File

@ -845,6 +845,19 @@ en:
create_iso_host_cap_not_found: |-
Vagrant cannot create an iso due to the host capability for creating isos not existing.
Vagrant will now exit.
darwin_mount_failed: |-
Failed to mount folders in Darwin guest. The command attempted was:
%{command}
The error output from the last command was:
%{output}
darwin_version_failed: |-
Failed to determine macOS version.
Version string: %{version}
Error information: %{error}
destroy_requires_force: |-
Destroy doesn't have a TTY to ask for confirmation. Please pass the
`--force` flag to force a destroy, otherwise attach a TTY so that

View File

@ -1,13 +1,21 @@
require_relative "../../../../base"
require_relative "../../../../../../plugins/hosts/darwin/cap/path"
require_relative "../../../../../../plugins/hosts/darwin/cap/version"
describe VagrantPlugins::HostDarwin::Cap::Path do
describe ".resolve_host_path" do
let(:env) { double("environment") }
let(:path) { "/test/vagrant/path" }
let(:firmlink_map) { {} }
let(:macos_version) { Gem::Version.new("10.15.1") }
before { allow(described_class).to receive(:firmlink_map).and_return(firmlink_map) }
before do
allow(VagrantPlugins::HostDarwin::Cap::Version).to receive(:version).
with(anything).
and_return(macos_version)
allow(described_class).to receive(:firmlink_map).
and_return(firmlink_map)
end
it "should not change the path when no firmlinks are defined" do
expect(described_class.resolve_host_path(env, path)).to eq(path)
@ -48,6 +56,18 @@ describe VagrantPlugins::HostDarwin::Cap::Path do
expect(described_class.resolve_host_path(env, path)).to include("other")
end
end
context "when macos version is later than catalina" do
let(:macos_version) { Gem::Version.new("10.16.1") }
it "should not update the path" do
expect(described_class.resolve_host_path(env, path)).to eq(path)
end
it "should not prefix the path with the defined data path" do
expect(described_class.resolve_host_path(env, path)).not_to start_with(described_class.const_get(:FIRMLINK_DATA_PATH))
end
end
end
describe ".firmlink_map" do

View File

@ -0,0 +1,47 @@
require_relative "../../../../base"
require_relative "../../../../../../plugins/hosts/darwin/cap/version"
describe VagrantPlugins::HostDarwin::Cap::Version do
describe ".version" do
let(:product_version) { "10.5.1" }
let(:env) { double(:env) }
let(:exit_code) { 0 }
let(:stderr) { "" }
let(:stdout) { product_version }
let(:result) {
Vagrant::Util::Subprocess::Result.new(exit_code, stdout, stderr)
}
before do
allow(Vagrant::Util::Subprocess).to receive(:execute).
with("sw_vers", "-productVersion").
and_return(result)
end
it "should return a Gem::Version" do
expect(described_class.version(env)).to be_a(Gem::Version)
end
it "should equal the defined version" do
expect(described_class.version(env)).to eq(Gem::Version.new(product_version))
end
context "when version cannot be parsed" do
let(:product_version) { "invalid" }
it "should raise a failure error" do
expect { described_class.version(env) }.
to raise_error(Vagrant::Errors::DarwinVersionFailed)
end
end
context "when command execution fails" do
let(:exit_code) { 1 }
it "should raise a failure error" do
expect { described_class.version(env) }.
to raise_error(Vagrant::Errors::DarwinVersionFailed)
end
end
end
end