From d7a5f74897549326fd325e5c4c835aa2de82207e Mon Sep 17 00:00:00 2001 From: Jeff Bonhag Date: Tue, 17 Dec 2019 12:41:12 -0500 Subject: [PATCH] Fixes #11128: Error if machine folder inaccessible (#11239) This commit catches the Errno::EPERM raised by the operating system if the machine folder is inaccessible and displays it as a more friendly error message. This can be an issue on macOS Catalina if virtual machine files are kept in a special directory (Documents/Downloads/Desktop) that Vagrant's embedded Ruby is not allowed to access. --- lib/vagrant/errors.rb | 4 +++ .../virtualbox/action/clean_machine_folder.rb | 11 ++++++- templates/locales/en.yml | 9 ++++++ .../action/clean_machine_folder_test.rb | 25 +++++++++++++++ .../source/docs/other/macos-catalina.html.md | 32 +++++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 test/unit/plugins/providers/virtualbox/action/clean_machine_folder_test.rb create mode 100644 website/source/docs/other/macos-catalina.html.md diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index 44bed4d4c..90e5c42c1 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -436,6 +436,10 @@ module Vagrant error_key(:machine_action_locked) end + class MachineFolderNotAccessible < VagrantError + error_key(:machine_folder_not_accessible) + end + class MachineGuestNotReady < VagrantError error_key(:machine_guest_not_ready) end diff --git a/plugins/providers/virtualbox/action/clean_machine_folder.rb b/plugins/providers/virtualbox/action/clean_machine_folder.rb index 3007cbd0f..d4fdf5203 100644 --- a/plugins/providers/virtualbox/action/clean_machine_folder.rb +++ b/plugins/providers/virtualbox/action/clean_machine_folder.rb @@ -13,7 +13,16 @@ module VagrantPlugins end def call(env) - clean_machine_folder(env[:machine].provider.driver.read_machine_folder) + machine_folder = env[:machine].provider.driver.read_machine_folder + + begin + clean_machine_folder(machine_folder) + rescue Errno::EPERM + raise Vagrant::Errors::MachineFolderNotAccessible, + name: env[:machine].name, + path: machine_folder + end + @app.call(env) end diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 333addb8a..72737a7b8 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -964,6 +964,15 @@ en: If you believe this message is in error, please check the process listing for any "ruby" or "vagrant" processes and kill them. Then try again. + machine_folder_not_accessible: |- + Vagrant attempted to clean the machine folder for the machine '%{name}' + but does not have permission to read the following path: + + %{path} + + Please ensure that Vagrant has the proper permissions to access the path + above. You may need to grant this permission to the terminal emulator + running Vagrant as well. machine_guest_not_ready: |- Guest-specific operations were attempted on a machine that is not ready for guest communication. This should not happen and a bug diff --git a/test/unit/plugins/providers/virtualbox/action/clean_machine_folder_test.rb b/test/unit/plugins/providers/virtualbox/action/clean_machine_folder_test.rb new file mode 100644 index 000000000..896c4842f --- /dev/null +++ b/test/unit/plugins/providers/virtualbox/action/clean_machine_folder_test.rb @@ -0,0 +1,25 @@ +require_relative '../base' + +describe VagrantPlugins::ProviderVirtualBox::Action::CleanMachineFolder do + let(:app) { double("app") } + let(:driver) { double("driver") } + let(:machine) { double("machine", provider: double("provider", driver: driver), name: "") } + let(:env) { + { machine: machine } + } + let(:subject) { described_class.new(app, env) } + + before do + allow(driver).to receive(:read_machine_folder) + end + + context "machine folder is not accessible" do + before do + allow(subject).to receive(:clean_machine_folder).and_raise(Errno::EPERM) + end + + it "raises an error" do + expect { subject.call(env) }.to raise_error(Vagrant::Errors::MachineFolderNotAccessible) + end + end +end diff --git a/website/source/docs/other/macos-catalina.html.md b/website/source/docs/other/macos-catalina.html.md new file mode 100644 index 000000000..5fdd9d81a --- /dev/null +++ b/website/source/docs/other/macos-catalina.html.md @@ -0,0 +1,32 @@ +--- +layout: "docs" +page_title: "Vagrant and macOS Catalina" +sidebar_current: "other-macos-catalina" +description: |- + An overview of using Vagrant on macOS Catalina. +--- + +# Vagrant and macOS Catalina + +The latest version of macOS (Catalina) includes security changes that prevent +applications from accessing data in your Documents, Desktop, and Downloads +folders without explicit permission. If you keep any virtual machine files in +these folders, you will need to allow access to these folders for your terminal +emulator. + +Initially when you try to access one of these folders from the command line, you +should see a popup that says something like: + +> “Terminal” would like to access files in your Documents folder. + +Click "OK" to grant those permissions. + +If you click "Don't Allow" and find that you need to grant access later on, you +can go to "System Preferences" -> "Security & Privacy" -> "Files and Folders" +and you should see your terminal emulator there. Click on the lock, and then +click on the checkbox next to the folder that contains the files that Vagrant +needs to access. + +Note that granting the `vagrant` binary "Full Disk Access" is not sufficient or +necessary. If Terminal (or iTerm2/Hyper/etc.) is granted access to a particular +folder, then Vagrant will also be able to access that folder.