From fb0f06c3ce41ff0f5db8a9886052dbfb4b4cecec Mon Sep 17 00:00:00 2001 From: Joel May Date: Sat, 22 Jan 2022 16:20:48 -0800 Subject: [PATCH 01/36] Explain that 'nil' can disable dynamic memory --- website/content/docs/providers/hyperv/configuration.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/content/docs/providers/hyperv/configuration.mdx b/website/content/docs/providers/hyperv/configuration.mdx index 7bc4c8790..3fab824f2 100644 --- a/website/content/docs/providers/hyperv/configuration.mdx +++ b/website/content/docs/providers/hyperv/configuration.mdx @@ -22,7 +22,7 @@ you may set. A complete reference is shown below: - `ip_address_timeout` (integer) - Number of seconds to wait for the VM to report an IP address. Default: 120. - `linked_clone` (boolean) - Use differencing disk instead of cloning entire VHD. Default: false - `mac` (string) - MAC address for the guest network interface -- `maxmemory` (integer) - Maximum number of megabytes allowed to be allocated for the VM. When set Dynamic Memory Allocation will be enabled. +- `maxmemory` (integer) - Maximum number of megabytes allowed to be allocated for the VM. When set Dynamic Memory Allocation will be enabled. Set to `nil` to disable Dynamic Memory. - `memory` (integer) - Number of megabytes allocated to VM at startup. If `maxmemory` is set, this will be amount of memory allocated at startup. - `vlan_id` (integer) - VLAN ID for the guest network interface. - `vmname` (string) - Name of virtual machine as shown in Hyper-V manager. Default: Generated name. From 76ef7d3dc83db9587324fb768b79af69e98130e8 Mon Sep 17 00:00:00 2001 From: Moritz Heiber Date: Tue, 10 Jan 2023 14:05:44 +0100 Subject: [PATCH 02/36] Fix installing Ansible provisioner with version and pip --- .../cap/guest/posix/ansible_installed.rb | 4 ++-- .../provisioners/ansible/provisioner/guest.rb | 2 +- .../provisioners/ansible/provisioner/host.rb | 5 +++-- .../provisioners/ansible/provisioner_test.rb | 22 +++++++++++-------- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/plugins/provisioners/ansible/cap/guest/posix/ansible_installed.rb b/plugins/provisioners/ansible/cap/guest/posix/ansible_installed.rb index 329eab8a9..3c7f623de 100644 --- a/plugins/provisioners/ansible/cap/guest/posix/ansible_installed.rb +++ b/plugins/provisioners/ansible/cap/guest/posix/ansible_installed.rb @@ -10,8 +10,8 @@ module VagrantPlugins def self.ansible_installed(machine, version) command = 'test -x "$(command -v ansible)"' - if !version.empty? - command << "&& ansible --version | grep 'ansible #{version}'" + unless version.empty? + command << "&& [[ $(python -c \"import importlib.metadata; print(importlib.metadata.version('ansible'))\") == \"#{version}\" ]]" end machine.communicate.test command, sudo: false diff --git a/plugins/provisioners/ansible/provisioner/guest.rb b/plugins/provisioners/ansible/provisioner/guest.rb index 1474b837b..e81bceaf5 100644 --- a/plugins/provisioners/ansible/provisioner/guest.rb +++ b/plugins/provisioners/ansible/provisioner/guest.rb @@ -75,7 +75,7 @@ module VagrantPlugins raw_output = "" result = @machine.communicate.execute( - "ansible --version", + "python -c \"import importlib.metadata; print('ansible ' + importlib.metadata.version('ansible'))\"", error_class: Ansible::Errors::AnsibleNotFoundOnGuest, error_key: :ansible_not_found_on_guest) do |type, output| if type == :stdout && output.lines[0] diff --git a/plugins/provisioners/ansible/provisioner/host.rb b/plugins/provisioners/ansible/provisioner/host.rb index f2a57133c..c2b9ddea4 100644 --- a/plugins/provisioners/ansible/provisioner/host.rb +++ b/plugins/provisioners/ansible/provisioner/host.rb @@ -108,8 +108,9 @@ module VagrantPlugins end def gather_ansible_version - raw_output = "" - command = %w(ansible --version) + raw_output = '' + command = ['python', '-c', + "\"import importlib.metadata; print('ansible ' + importlib.metadata.version('ansible'))\""] command << { notify: [:stdout, :stderr] diff --git a/test/unit/plugins/provisioners/ansible/provisioner_test.rb b/test/unit/plugins/provisioners/ansible/provisioner_test.rb index fdf9aa67e..d41d52af9 100644 --- a/test/unit/plugins/provisioners/ansible/provisioner_test.rb +++ b/test/unit/plugins/provisioners/ansible/provisioner_test.rb @@ -71,12 +71,14 @@ VF # Class methods for code reuse across examples # - def self.it_should_check_ansible_version() - it "execute 'ansible --version' before executing 'ansible-playbook'" do - expect(Vagrant::Util::Subprocess).to receive(:execute). - once.with('ansible', '--version', { :notify => [:stdout, :stderr] }) - expect(Vagrant::Util::Subprocess).to receive(:execute). - once.with('ansible-playbook', any_args) + def self.it_should_check_ansible_version + it "execute 'Python ansible version check before executing 'ansible-playbook'" do + expect(Vagrant::Util::Subprocess).to receive(:execute) + .once.with('python', '-c', "\"import importlib.metadata; print('ansible ' + importlib.metadata.version('ansible'))\"", { notify: %i[ + stdout stderr + ] }) + expect(Vagrant::Util::Subprocess).to receive(:execute) + .once.with('ansible-playbook', any_args) end end @@ -326,6 +328,7 @@ VF "2.x.y.z": VagrantPlugins::Ansible::COMPATIBILITY_MODE_V2_0, "4.3.2.1": VagrantPlugins::Ansible::COMPATIBILITY_MODE_V2_0, "[core 2.11.0]": VagrantPlugins::Ansible::COMPATIBILITY_MODE_V2_0, + "7.1.0": VagrantPlugins::Ansible::COMPATIBILITY_MODE_V2_0 } valid_versions.each_pair do |ansible_version, mode| describe "and ansible version #{ansible_version}" do @@ -347,7 +350,7 @@ VF "2.9.2.1", ] invalid_versions.each do |unknown_ansible_version| - describe "and `ansible --version` returning '#{unknown_ansible_version}'" do + describe "and `ansible version check returning '#{unknown_ansible_version}'" do before do allow(subject).to receive(:gather_ansible_version).and_return(unknown_ansible_version) end @@ -1044,10 +1047,11 @@ VF expect {subject.provision}.to raise_error(VagrantPlugins::Ansible::Errors::AnsibleCommandFailed) end - it "execute three commands: ansible --version, ansible-galaxy, and ansible-playbook" do + it 'execute three commands: Python ansible version check, ansible-galaxy, and ansible-playbook' do expect(Vagrant::Util::Subprocess).to receive(:execute) .once - .with('ansible', '--version', { :notify => [:stdout, :stderr] }) + .with('python', '-c', + "\"import importlib.metadata; print('ansible ' + importlib.metadata.version('ansible'))\"", { notify: %i[stdout stderr] }) .and_return(default_execute_result) expect(Vagrant::Util::Subprocess).to receive(:execute) .once From 5f82adf122bedb91480a4f86421c2c0161827205 Mon Sep 17 00:00:00 2001 From: Moritz Heiber Date: Wed, 11 Jan 2023 11:01:55 +0100 Subject: [PATCH 03/36] Replace python with python3, which is a common convention (and Ansible only works with Python 3) --- plugins/provisioners/ansible/provisioner/guest.rb | 2 +- plugins/provisioners/ansible/provisioner/host.rb | 2 +- test/unit/plugins/provisioners/ansible/provisioner_test.rb | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/provisioners/ansible/provisioner/guest.rb b/plugins/provisioners/ansible/provisioner/guest.rb index e81bceaf5..2e800a999 100644 --- a/plugins/provisioners/ansible/provisioner/guest.rb +++ b/plugins/provisioners/ansible/provisioner/guest.rb @@ -75,7 +75,7 @@ module VagrantPlugins raw_output = "" result = @machine.communicate.execute( - "python -c \"import importlib.metadata; print('ansible ' + importlib.metadata.version('ansible'))\"", + "python3 -c \"import importlib.metadata; print('ansible ' + importlib.metadata.version('ansible'))\"", error_class: Ansible::Errors::AnsibleNotFoundOnGuest, error_key: :ansible_not_found_on_guest) do |type, output| if type == :stdout && output.lines[0] diff --git a/plugins/provisioners/ansible/provisioner/host.rb b/plugins/provisioners/ansible/provisioner/host.rb index c2b9ddea4..ef700f03a 100644 --- a/plugins/provisioners/ansible/provisioner/host.rb +++ b/plugins/provisioners/ansible/provisioner/host.rb @@ -109,7 +109,7 @@ module VagrantPlugins def gather_ansible_version raw_output = '' - command = ['python', '-c', + command = ['python3', '-c', "\"import importlib.metadata; print('ansible ' + importlib.metadata.version('ansible'))\""] command << { diff --git a/test/unit/plugins/provisioners/ansible/provisioner_test.rb b/test/unit/plugins/provisioners/ansible/provisioner_test.rb index d41d52af9..2cb9f7bce 100644 --- a/test/unit/plugins/provisioners/ansible/provisioner_test.rb +++ b/test/unit/plugins/provisioners/ansible/provisioner_test.rb @@ -74,7 +74,7 @@ VF def self.it_should_check_ansible_version it "execute 'Python ansible version check before executing 'ansible-playbook'" do expect(Vagrant::Util::Subprocess).to receive(:execute) - .once.with('python', '-c', "\"import importlib.metadata; print('ansible ' + importlib.metadata.version('ansible'))\"", { notify: %i[ + .once.with('python3', '-c', "\"import importlib.metadata; print('ansible ' + importlib.metadata.version('ansible'))\"", { notify: %i[ stdout stderr ] }) expect(Vagrant::Util::Subprocess).to receive(:execute) @@ -1050,7 +1050,7 @@ VF it 'execute three commands: Python ansible version check, ansible-galaxy, and ansible-playbook' do expect(Vagrant::Util::Subprocess).to receive(:execute) .once - .with('python', '-c', + .with('python3', '-c', "\"import importlib.metadata; print('ansible ' + importlib.metadata.version('ansible'))\"", { notify: %i[stdout stderr] }) .and_return(default_execute_result) expect(Vagrant::Util::Subprocess).to receive(:execute) From dfabbbb7fe664975508a2ad5455b7ece325f56f0 Mon Sep 17 00:00:00 2001 From: Moritz Heiber Date: Wed, 11 Jan 2023 12:54:42 +0100 Subject: [PATCH 04/36] Forgot one occurance of using the raw python vs. python3 --- .../provisioners/ansible/cap/guest/posix/ansible_installed.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/provisioners/ansible/cap/guest/posix/ansible_installed.rb b/plugins/provisioners/ansible/cap/guest/posix/ansible_installed.rb index 3c7f623de..ab171ee5d 100644 --- a/plugins/provisioners/ansible/cap/guest/posix/ansible_installed.rb +++ b/plugins/provisioners/ansible/cap/guest/posix/ansible_installed.rb @@ -11,7 +11,7 @@ module VagrantPlugins command = 'test -x "$(command -v ansible)"' unless version.empty? - command << "&& [[ $(python -c \"import importlib.metadata; print(importlib.metadata.version('ansible'))\") == \"#{version}\" ]]" + command << "&& [[ $(python3 -c \"import importlib.metadata; print(importlib.metadata.version('ansible'))\") == \"#{version}\" ]]" end machine.communicate.test command, sudo: false From bc03f21758b8825a0da22c4d1ab705975eb935b3 Mon Sep 17 00:00:00 2001 From: sophia Date: Thu, 12 Jan 2023 15:25:36 -0800 Subject: [PATCH 05/36] Add a file mutex when downloading box files. Box's are global to Vagrant. Multiple Vagrant process can all access the box directory for both downloading and extracting boxes. A file mutex will ensure that mulitple Vagrant process will not trample eachother if they are trying to download the same box. --- lib/vagrant/action/builtin/box_add.rb | 13 +++++++++++++ lib/vagrant/errors.rb | 4 ++++ templates/locales/en.yml | 6 ++++++ 3 files changed, 23 insertions(+) diff --git a/lib/vagrant/action/builtin/box_add.rb b/lib/vagrant/action/builtin/box_add.rb index c9307beea..ec8c04761 100644 --- a/lib/vagrant/action/builtin/box_add.rb +++ b/lib/vagrant/action/builtin/box_add.rb @@ -22,6 +22,10 @@ module Vagrant # file already exists. RESUME_DELAY = 24 * 60 * 60 + # When a box file is being downloaded, identify the download is in progress + # by Vagrant with a mutex file named . + MUTEX_SUFFIX = ".lock" + def initialize(app, env) @app = app @logger = Log4r::Logger.new("vagrant::action::builtin::box_add") @@ -478,13 +482,22 @@ module Vagrant end end + mutex_path = d.destination + MUTEX_SUFFIX + if File.file?(mutex_path) + raise Errors::DownloadAlreadyInProgress, + dest_path: d.destination + end + begin + File.write(mutex_path, "") d.download! rescue Errors::DownloaderInterrupted # The downloader was interrupted, so just return, because that # means we were interrupted as well. @download_interrupted = true env[:ui].info(I18n.t("vagrant.actions.box.download.interrupted")) + ensure + File.delete(mutex_path) end Pathname.new(d.destination) diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index 664da86e5..186de6865 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -376,6 +376,10 @@ module Vagrant error_key(:dotfile_upgrade_json_error) end + class DownloadAlreadyInProgress < VagrantError + error_key(:download_already_in_progress_error) + end + class DownloaderError < VagrantError error_key(:downloader_error) end diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 9e6d7ca16..a20c6ce79 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -895,6 +895,12 @@ en: support. State file path: %{state_file} + download_already_in_progress_error: |- + Download to global Vagrant location already in progress. This + may be caused by other Vagrant processes attempting to download + a file to the same location. + + Download path: %{dest_path} downloader_error: |- An error occurred while downloading the remote file. The error message, if any, is reproduced below. Please fix this error and try From 83efa09dfafe3ed26ea4c2321bd1af9f0ccd277b Mon Sep 17 00:00:00 2001 From: sophia Date: Thu, 12 Jan 2023 16:30:05 -0800 Subject: [PATCH 06/36] Test box download mutex --- .../vagrant/action/builtin/box_add_test.rb | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/test/unit/vagrant/action/builtin/box_add_test.rb b/test/unit/vagrant/action/builtin/box_add_test.rb index 67652d501..397ff1259 100644 --- a/test/unit/vagrant/action/builtin/box_add_test.rb +++ b/test/unit/vagrant/action/builtin/box_add_test.rb @@ -84,7 +84,47 @@ describe Vagrant::Action::Builtin::BoxAdd, :skip_windows, :bsdtar do allow(box_collection).to receive(:find).and_return(nil) end + context "the download location is locked" do + let(:box_path) { iso_env.box2_file(:virtualbox) } + + before do + mutex_path = env[:tmp_path].join("box" + Digest::SHA1.hexdigest("file://" + box_path.to_s) + ".lock").to_s + File.write(mutex_path, "") + end + + it "raises a download error" do + env[:box_name] = "foo" + env[:box_url] = box_path.to_s + + expect { subject.call(env) }. + to raise_error(Vagrant::Errors::DownloadAlreadyInProgress) + end + end + context "with box file directly" do + it "creates and cleans up a lock file" do + box_path = iso_env.box2_file(:virtualbox) + + env[:box_name] = "foo" + env[:box_url] = box_path.to_s + + + expect(box_collection).to receive(:add).with(any_args) { |path, name, version, opts| + expect(checksum(path)).to eq(checksum(box_path)) + expect(name).to eq("foo") + expect(version).to eq("0") + expect(opts[:metadata_url]).to be_nil + true + }.and_return(box) + + expect(app).to receive(:call).with(env) + + mutex_path = env[:tmp_path].join("box" + Digest::SHA1.hexdigest("file://" + box_path.to_s) + ".lock").to_s + expect(File).to receive(:write).with(mutex_path, "") + expect(File).to receive(:delete).with(mutex_path) + subject.call(env) + end + it "adds it" do box_path = iso_env.box2_file(:virtualbox) From 817fbdd2d132ab6636234387d67ae56ae1eee7d3 Mon Sep 17 00:00:00 2001 From: sophia Date: Thu, 12 Jan 2023 16:34:45 -0800 Subject: [PATCH 07/36] Add information about lock file path --- lib/vagrant/action/builtin/box_add.rb | 3 ++- templates/locales/en.yml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/vagrant/action/builtin/box_add.rb b/lib/vagrant/action/builtin/box_add.rb index ec8c04761..80d5b10ce 100644 --- a/lib/vagrant/action/builtin/box_add.rb +++ b/lib/vagrant/action/builtin/box_add.rb @@ -485,7 +485,8 @@ module Vagrant mutex_path = d.destination + MUTEX_SUFFIX if File.file?(mutex_path) raise Errors::DownloadAlreadyInProgress, - dest_path: d.destination + dest_path: d.destination, + lock_file_path: mutex_path end begin diff --git a/templates/locales/en.yml b/templates/locales/en.yml index a20c6ce79..095f83384 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -901,6 +901,7 @@ en: a file to the same location. Download path: %{dest_path} + Lock file path: %{lock_file_path} downloader_error: |- An error occurred while downloading the remote file. The error message, if any, is reproduced below. Please fix this error and try From b91a5d5576f9df54ab64365620ef412b60e5aba2 Mon Sep 17 00:00:00 2001 From: sophia Date: Fri, 13 Jan 2023 11:46:00 -0800 Subject: [PATCH 08/36] Add file mutex util module --- lib/vagrant/action/builtin/box_add.rb | 32 ++++++++++++--------------- lib/vagrant/errors.rb | 4 ++++ lib/vagrant/util.rb | 1 + lib/vagrant/util/file_mutex.rb | 29 ++++++++++++++++++++++++ templates/locales/en.yml | 5 +++++ 5 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 lib/vagrant/util/file_mutex.rb diff --git a/lib/vagrant/action/builtin/box_add.rb b/lib/vagrant/action/builtin/box_add.rb index 80d5b10ce..3b5624c4f 100644 --- a/lib/vagrant/action/builtin/box_add.rb +++ b/lib/vagrant/action/builtin/box_add.rb @@ -6,6 +6,7 @@ require "uri" require "vagrant/box_metadata" require "vagrant/util/downloader" require "vagrant/util/file_checksum" +require "vagrant/util/file_mutex" require "vagrant/util/platform" module Vagrant @@ -22,10 +23,6 @@ module Vagrant # file already exists. RESUME_DELAY = 24 * 60 * 60 - # When a box file is being downloaded, identify the download is in progress - # by Vagrant with a mutex file named . - MUTEX_SUFFIX = ".lock" - def initialize(app, env) @app = app @logger = Log4r::Logger.new("vagrant::action::builtin::box_add") @@ -482,25 +479,24 @@ module Vagrant end end - mutex_path = d.destination + MUTEX_SUFFIX - if File.file?(mutex_path) + begin + mutex_path = d.destination + ".lock" + Util::FileMutex.new(mutex_path).with_lock do + begin + d.download! + rescue Errors::DownloaderInterrupted + # The downloader was interrupted, so just return, because that + # means we were interrupted as well. + @download_interrupted = true + env[:ui].info(I18n.t("vagrant.actions.box.download.interrupted")) + end + end + rescue Errors::VagrantLocked raise Errors::DownloadAlreadyInProgress, dest_path: d.destination, lock_file_path: mutex_path end - begin - File.write(mutex_path, "") - d.download! - rescue Errors::DownloaderInterrupted - # The downloader was interrupted, so just return, because that - # means we were interrupted as well. - @download_interrupted = true - env[:ui].info(I18n.t("vagrant.actions.box.download.interrupted")) - ensure - File.delete(mutex_path) - end - Pathname.new(d.destination) end diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index 186de6865..8e6bb8989 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -924,6 +924,10 @@ module Vagrant error_key(:uploader_interrupted) end + class VagrantLocked < VagrantError + error_key(:vagrant_locked) + end + class VagrantInterrupt < VagrantError error_key(:interrupted) end diff --git a/lib/vagrant/util.rb b/lib/vagrant/util.rb index 4b3e0ff09..8e3cbd2af 100644 --- a/lib/vagrant/util.rb +++ b/lib/vagrant/util.rb @@ -20,6 +20,7 @@ module Vagrant autoload :Experimental, 'vagrant/util/experimental' autoload :FileChecksum, 'vagrant/util/file_checksum' autoload :FileMode, 'vagrant/util/file_mode' + autoload :FileMutex, 'vagrant/util/file_mutex' autoload :GuestHosts, 'vagrant/util/guest_hosts' autoload :GuestInspection, 'vagrant/util/guest_inspection' autoload :HashWithIndifferentAccess, 'vagrant/util/hash_with_indifferent_access' diff --git a/lib/vagrant/util/file_mutex.rb b/lib/vagrant/util/file_mutex.rb new file mode 100644 index 000000000..c005a23a6 --- /dev/null +++ b/lib/vagrant/util/file_mutex.rb @@ -0,0 +1,29 @@ +module Vagrant + module Util + class FileMutex + def initialize(mutex_path) + @mutex_path = mutex_path + end + + def with_lock(&block) + lock + block.call + ensure + unlock + end + + def lock + if File.file?(@mutex_path) + raise Errors::VagrantLocked, + lock_file_path: @mutex_path + end + + File.write(@mutex_path, "") + end + + def unlock + File.delete(@mutex_path) + end + end + end +end diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 095f83384..4a18ff7f6 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -1675,6 +1675,11 @@ en: uploader_interrupted: |- The upload was interrupted by an external signal. It did not complete. + vagrant_locked: |- + The requested Vagrant action is locked. This may be caused + by other Vagrant processes attempting to do a similar action. + + Lock file path: %{lock_file_path} vagrantfile_exists: |- `Vagrantfile` already exists in this directory. Remove it before running `vagrant init`. From f153996b2d7480feecfc2c98136b69dbc5f6978d Mon Sep 17 00:00:00 2001 From: sophia Date: Fri, 13 Jan 2023 13:27:48 -0800 Subject: [PATCH 09/36] Add tests for mutex util module --- lib/vagrant/util/file_mutex.rb | 2 +- .../vagrant/action/builtin/box_add_test.rb | 23 --------- test/unit/vagrant/util/file_mutex_test.rb | 49 +++++++++++++++++++ 3 files changed, 50 insertions(+), 24 deletions(-) create mode 100644 test/unit/vagrant/util/file_mutex_test.rb diff --git a/lib/vagrant/util/file_mutex.rb b/lib/vagrant/util/file_mutex.rb index c005a23a6..2489d1a47 100644 --- a/lib/vagrant/util/file_mutex.rb +++ b/lib/vagrant/util/file_mutex.rb @@ -22,7 +22,7 @@ module Vagrant end def unlock - File.delete(@mutex_path) + File.delete(@mutex_path) if File.file?(@mutex_path) end end end diff --git a/test/unit/vagrant/action/builtin/box_add_test.rb b/test/unit/vagrant/action/builtin/box_add_test.rb index 397ff1259..2b53a7f34 100644 --- a/test/unit/vagrant/action/builtin/box_add_test.rb +++ b/test/unit/vagrant/action/builtin/box_add_test.rb @@ -102,29 +102,6 @@ describe Vagrant::Action::Builtin::BoxAdd, :skip_windows, :bsdtar do end context "with box file directly" do - it "creates and cleans up a lock file" do - box_path = iso_env.box2_file(:virtualbox) - - env[:box_name] = "foo" - env[:box_url] = box_path.to_s - - - expect(box_collection).to receive(:add).with(any_args) { |path, name, version, opts| - expect(checksum(path)).to eq(checksum(box_path)) - expect(name).to eq("foo") - expect(version).to eq("0") - expect(opts[:metadata_url]).to be_nil - true - }.and_return(box) - - expect(app).to receive(:call).with(env) - - mutex_path = env[:tmp_path].join("box" + Digest::SHA1.hexdigest("file://" + box_path.to_s) + ".lock").to_s - expect(File).to receive(:write).with(mutex_path, "") - expect(File).to receive(:delete).with(mutex_path) - subject.call(env) - end - it "adds it" do box_path = iso_env.box2_file(:virtualbox) diff --git a/test/unit/vagrant/util/file_mutex_test.rb b/test/unit/vagrant/util/file_mutex_test.rb new file mode 100644 index 000000000..0a709f770 --- /dev/null +++ b/test/unit/vagrant/util/file_mutex_test.rb @@ -0,0 +1,49 @@ +require File.expand_path("../../../base", __FILE__) +require 'vagrant/util/file_mutex' + +describe Vagrant::Util::FileMutex do + include_context "unit" + + let(:temp_dir) { Dir.mktmpdir("vagrant-test-util-mutex_test") } + + after do + FileUtils.rm_rf(temp_dir) + end + + it "should create a lock file" do + mutex_path = temp_dir + "test.lock" + instance = described_class.new(mutex_path) + instance.lock + expect(File).to exist(mutex_path) + end + + it "should create and delete lock file" do + mutex_path = temp_dir + "test.lock" + instance = described_class.new(mutex_path) + instance.lock + instance.unlock + expect(File).to_not exist(mutex_path) + end + + it "should not raise an error if the lock file does not exist" do + mutex_path = temp_dir + "test.lock" + instance = described_class.new(mutex_path) + instance.unlock + expect(File).to_not exist(mutex_path) + end + + it "should run a function with a lock" do + mutex_path = temp_dir + "test.lock" + instance = described_class.new(mutex_path) + instance.with_lock { true } + expect(File).to_not exist(mutex_path) + end + + it "should fail running a function when locked" do + mutex_path = temp_dir + "test.lock" + instance = described_class.new(mutex_path) + instance.lock + expect {instance.with_lock { true }}. + to raise_error(Vagrant::Errors::VagrantLocked) + end +end From 0ee7eb338ff504a068b774851a565c74e365c846 Mon Sep 17 00:00:00 2001 From: Penaz Date: Fri, 20 Jan 2023 16:25:59 +0100 Subject: [PATCH 10/36] Ensure Arch Plugin doesn't detect Artix Linux Some Artix Linux Distributions may be "migrated" from Arch and contain the "/etc/arch-release" file, leading to an incorrect OS being detected. --- plugins/hosts/arch/host.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hosts/arch/host.rb b/plugins/hosts/arch/host.rb index 0384eb25e..01de7c33d 100644 --- a/plugins/hosts/arch/host.rb +++ b/plugins/hosts/arch/host.rb @@ -4,7 +4,7 @@ module VagrantPlugins module HostArch class Host < Vagrant.plugin("2", :host) def detect?(env) - File.exist?("/etc/arch-release") + File.exist?("/etc/arch-release") and not File.exist?("/etc/artix-release") end end end From 157a182ec70bade5ff55a5e0c333d5a8680b9f8b Mon Sep 17 00:00:00 2001 From: Daniele Penazzo Date: Tue, 24 Jan 2023 07:46:24 +0100 Subject: [PATCH 11/36] Update plugins/hosts/arch/host.rb Co-authored-by: Sophia Castellarin --- plugins/hosts/arch/host.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hosts/arch/host.rb b/plugins/hosts/arch/host.rb index 01de7c33d..ed6339689 100644 --- a/plugins/hosts/arch/host.rb +++ b/plugins/hosts/arch/host.rb @@ -4,7 +4,7 @@ module VagrantPlugins module HostArch class Host < Vagrant.plugin("2", :host) def detect?(env) - File.exist?("/etc/arch-release") and not File.exist?("/etc/artix-release") + File.exist?("/etc/arch-release") && !File.exist?("/etc/artix-release") end end end From 5f2ea0486ef582747052d1b3326ad41083444e14 Mon Sep 17 00:00:00 2001 From: sophia Date: Mon, 9 Jan 2023 13:08:11 -0800 Subject: [PATCH 12/36] Update connection settings when using a password to connect ssh When connecting over ssh using net-ssh use the non_interactive argument must be set when authenticating with a password. Add the keyboard-interactive default auth method ref: https://github.com/net-ssh/net-ssh/blob/8a176a6ea0db1b59a21834df806a257a0b76e943/lib/net/ssh/config.rb#L52 --- plugins/communicators/ssh/communicator.rb | 8 ++++++-- .../plugins/communicators/ssh/communicator_test.rb | 10 +++++----- .../plugins/communicators/winssh/communicator_test.rb | 8 ++++---- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/plugins/communicators/ssh/communicator.rb b/plugins/communicators/ssh/communicator.rb index 3e660710e..8835b94f2 100644 --- a/plugins/communicators/ssh/communicator.rb +++ b/plugins/communicators/ssh/communicator.rb @@ -404,7 +404,7 @@ module VagrantPlugins # Set some valid auth methods. We disable the auth methods that # we're not using if we don't have the right auth info. - auth_methods = ["none", "hostbased"] + auth_methods = ["none", "hostbased", "keyboard-interactive"] auth_methods << "publickey" if ssh_info[:private_key_path] auth_methods << "password" if ssh_info[:password] @@ -460,6 +460,10 @@ module VagrantPlugins connect_opts[:keepalive] = true connect_opts[:keepalive_interval] = 5 end + + if ssh_info[:password] + connect_opts[:non_interactive] = true + end @logger.info("Attempting to connect to SSH...") @logger.info(" - Host: #{ssh_info[:host]}") @@ -469,7 +473,7 @@ module VagrantPlugins @logger.info(" - Key Path: #{ssh_info[:private_key_path]}") @logger.debug(" - connect_opts: #{connect_opts}") - Net::SSH.start(ssh_info[:host], ssh_info[:username], connect_opts) + Net::SSH.start(ssh_info[:host], ssh_info[:username], **connect_opts) ensure # Make sure we output the connection log @logger.debug("== Net-SSH connection debug-level log START ==") diff --git a/test/unit/plugins/communicators/ssh/communicator_test.rb b/test/unit/plugins/communicators/ssh/communicator_test.rb index 314bceb66..90694923d 100644 --- a/test/unit/plugins/communicators/ssh/communicator_test.rb +++ b/test/unit/plugins/communicators/ssh/communicator_test.rb @@ -664,7 +664,7 @@ describe VagrantPlugins::CommunicatorSSH::Communicator do it "includes `none` and `hostbased` auth methods" do expect(Net::SSH).to receive(:start).with( nil, nil, hash_including( - auth_methods: ["none", "hostbased"] + auth_methods: ["none", "hostbased", "keyboard-interactive"] ) ).and_return(true) communicator.send(:connect) @@ -780,7 +780,7 @@ describe VagrantPlugins::CommunicatorSSH::Communicator do it "includes `publickey` auth method" do expect(Net::SSH).to receive(:start).with( anything, anything, hash_including( - auth_methods: ["none", "hostbased", "publickey"] + auth_methods: ["none", "hostbased", "keyboard-interactive", "publickey"] ) ).and_return(true) communicator.send(:connect) @@ -809,7 +809,7 @@ describe VagrantPlugins::CommunicatorSSH::Communicator do it "has password defined" do expect(Net::SSH).to receive(:start).with( anything, anything, hash_including( - password: 'vagrant' + password: 'vagrant', non_interactive: true ) ).and_return(true) communicator.send(:connect) @@ -818,7 +818,7 @@ describe VagrantPlugins::CommunicatorSSH::Communicator do it "includes `password` auth method" do expect(Net::SSH).to receive(:start).with( anything, anything, hash_including( - auth_methods: ["none", "hostbased", "password"] + auth_methods: ["none", "hostbased", "keyboard-interactive", "password"] ) ).and_return(true) communicator.send(:connect) @@ -860,7 +860,7 @@ describe VagrantPlugins::CommunicatorSSH::Communicator do it "includes `publickey` and `password` auth methods" do expect(Net::SSH).to receive(:start).with( anything, anything, hash_including( - auth_methods: ["none", "hostbased", "publickey", "password"] + auth_methods: ["none", "hostbased", "keyboard-interactive", "publickey", "password"] ) ).and_return(true) communicator.send(:connect) diff --git a/test/unit/plugins/communicators/winssh/communicator_test.rb b/test/unit/plugins/communicators/winssh/communicator_test.rb index b0c189f4a..e71e474df 100644 --- a/test/unit/plugins/communicators/winssh/communicator_test.rb +++ b/test/unit/plugins/communicators/winssh/communicator_test.rb @@ -328,7 +328,7 @@ describe VagrantPlugins::CommunicatorWinSSH::Communicator do it "includes `none` and `hostbased` auth methods" do expect(Net::SSH).to receive(:start).with( nil, nil, hash_including( - auth_methods: ["none", "hostbased"] + auth_methods: ["none", "hostbased", "keyboard-interactive"] ) ).and_return(connection) communicator.send(:connect) @@ -420,7 +420,7 @@ describe VagrantPlugins::CommunicatorWinSSH::Communicator do it "includes `publickey` auth method" do expect(Net::SSH).to receive(:start).with( anything, anything, hash_including( - auth_methods: ["none", "hostbased", "publickey"] + auth_methods: ["none", "hostbased", "keyboard-interactive", "publickey"] ) ).and_return(connection) communicator.send(:connect) @@ -458,7 +458,7 @@ describe VagrantPlugins::CommunicatorWinSSH::Communicator do it "includes `password` auth method" do expect(Net::SSH).to receive(:start).with( anything, anything, hash_including( - auth_methods: ["none", "hostbased", "password"] + auth_methods: ["none", "hostbased", "keyboard-interactive", "password"] ) ).and_return(connection) communicator.send(:connect) @@ -500,7 +500,7 @@ describe VagrantPlugins::CommunicatorWinSSH::Communicator do it "includes `publickey` and `password` auth methods" do expect(Net::SSH).to receive(:start).with( anything, anything, hash_including( - auth_methods: ["none", "hostbased", "publickey", "password"] + auth_methods: ["none", "hostbased", "keyboard-interactive", "publickey", "password"] ) ).and_return(connection) communicator.send(:connect) From 0867fbd9d813691647b3c4d2e8e8db5925f47e41 Mon Sep 17 00:00:00 2001 From: RudiMT <69203001+RudiMT@users.noreply.github.com> Date: Tue, 2 Mar 2021 20:43:08 +0100 Subject: [PATCH 13/36] Add check if EnhancedSessionTransportType is supported by the current version of HyperV --- .../scripts/set_enhanced_session_transport_type.ps1 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 b/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 index 29191db37..fe9fad130 100644 --- a/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 +++ b/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 @@ -17,8 +17,14 @@ try { } try { - Hyper-V\Set-VM -VM $VM -EnhancedSessionTransportType $Type + # HyperV 1.1 (Windows Server 2012R2) crashes on this call. Vagrantfiles before 2.2.10 do break without skipping this. + $present = Get-Command Hyper-V\Set-VM -ParameterName EnhancedSessionTransportType -ErrorAction SilentlyContinue + if($present) { + Hyper-V\Set-VM -VM $VM -EnhancedSessionTransportType $Type + }else{ + Write-OutputMessage "This version of HyperV does not support EnhancedSessionTransportType, ignoring." + } } catch { - Write-ErrorMessage "Failed to assign EnhancedSessionTransportType to ${Type}: ${PSItem}" + Write-ErrorMessage "Failed to assign EnhancedSessionTransportType to ${Type}:${PSItem}" exit 1 } From e14aa1e43073bc367b3851b18f2e602da4f6fb7b Mon Sep 17 00:00:00 2001 From: RudiMT <69203001+RudiMT@users.noreply.github.com> Date: Tue, 6 Apr 2021 13:11:42 +0200 Subject: [PATCH 14/36] Formatting as in main --- .../hyperv/scripts/set_enhanced_session_transport_type.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 b/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 index fe9fad130..3f1a198b2 100644 --- a/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 +++ b/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 @@ -25,6 +25,6 @@ try { Write-OutputMessage "This version of HyperV does not support EnhancedSessionTransportType, ignoring." } } catch { - Write-ErrorMessage "Failed to assign EnhancedSessionTransportType to ${Type}:${PSItem}" + Write-ErrorMessage "Failed to assign EnhancedSessionTransportType to ${Type}: ${PSItem}" exit 1 } From ba562f273bb6f2f69326a83ce406202c8593c43a Mon Sep 17 00:00:00 2001 From: RudiMT <69203001+RudiMT@users.noreply.github.com> Date: Tue, 2 Mar 2021 20:43:08 +0100 Subject: [PATCH 15/36] Add check if EnhancedSessionTransportType is supported by the current version of HyperV --- .../hyperv/scripts/set_enhanced_session_transport_type.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 b/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 index 3f1a198b2..fe9fad130 100644 --- a/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 +++ b/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 @@ -25,6 +25,6 @@ try { Write-OutputMessage "This version of HyperV does not support EnhancedSessionTransportType, ignoring." } } catch { - Write-ErrorMessage "Failed to assign EnhancedSessionTransportType to ${Type}: ${PSItem}" + Write-ErrorMessage "Failed to assign EnhancedSessionTransportType to ${Type}:${PSItem}" exit 1 } From 431d91593a32c08a48219c7f989cc6cd50cf8e8d Mon Sep 17 00:00:00 2001 From: RudiMT <69203001+RudiMT@users.noreply.github.com> Date: Fri, 20 Jan 2023 18:51:00 +0100 Subject: [PATCH 16/36] Output message in json Would limit new console output to systems that do not already support EnhancedSessionTransportType. The vast majority of systems supports it and should not print additional messages. --- .../hyperv/scripts/set_enhanced_session_transport_type.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 b/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 index fe9fad130..6a591816f 100644 --- a/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 +++ b/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 @@ -22,7 +22,10 @@ try { if($present) { Hyper-V\Set-VM -VM $VM -EnhancedSessionTransportType $Type }else{ - Write-OutputMessage "This version of HyperV does not support EnhancedSessionTransportType, ignoring." + $message = @{ + "EnhancedSessionTransportTypeSupportPresent"=$false; + } | ConvertTo-Json + Write-OutputMessage $message } } catch { Write-ErrorMessage "Failed to assign EnhancedSessionTransportType to ${Type}:${PSItem}" From 2e7116cfc3dc8c7c830eba6e99fd5726e85ff1a1 Mon Sep 17 00:00:00 2001 From: sophia Date: Tue, 14 Feb 2023 15:49:37 -0800 Subject: [PATCH 17/36] Log ignoring of EnhancedSessionTransportType for debugging --- plugins/providers/hyperv/driver.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/providers/hyperv/driver.rb b/plugins/providers/hyperv/driver.rb index 50b2aa842..8fa6e8dd4 100644 --- a/plugins/providers/hyperv/driver.rb +++ b/plugins/providers/hyperv/driver.rb @@ -1,4 +1,5 @@ require "json" +require "log4r" require "vagrant/util/powershell" @@ -26,6 +27,7 @@ module VagrantPlugins def initialize(id) @vm_id = id + @logger = Log4r::Logger.new("vagrant::hyperv::driver") end # @return [Boolean] Supports VMCX @@ -294,7 +296,10 @@ module VagrantPlugins # @param [String] enhanced session transport type of the VM # @return [nil] def set_enhanced_session_transport_type(transport_type) - execute(:set_enhanced_session_transport_type, VmID: vm_id, type: transport_type) + result = execute(:set_enhanced_session_transport_type, VmID: vm_id, type: transport_type) + if !result.nil? + @logger.debug("EnhancedSessionTransportType is not supported by this version of hyperv, ignoring") + end end protected From 30fd6a32a2590fad0e06493cd505e45ae507f418 Mon Sep 17 00:00:00 2001 From: sophia Date: Tue, 14 Feb 2023 16:05:00 -0800 Subject: [PATCH 18/36] Update curl download options docs --- website/content/docs/vagrantfile/machine_settings.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/content/docs/vagrantfile/machine_settings.mdx b/website/content/docs/vagrantfile/machine_settings.mdx index 4a437f03c..4a59d81ea 100644 --- a/website/content/docs/vagrantfile/machine_settings.mdx +++ b/website/content/docs/vagrantfile/machine_settings.mdx @@ -76,7 +76,9 @@ the name of the synced folder plugin. to pass to the downloader. For example, a path to a key that the downloader should use could be specified as `{key: ""}`. The keys should be options supported by `curl` using the unshortened form of the flag. For - example, use `append` instead of `a`. + example, use `append` instead of `a`. To pass a curl option that does not + accept a value, include the option in the map with the value `true`. For + example specify the `--fail` flag as `{fail: true}`. - `config.vm.box_download_insecure` (boolean) - If true, then SSL certificates from the server will not be verified. By default, if the URL is an HTTPS From fbd90b1965974dc1ac300568d3cc583f3a86b1d8 Mon Sep 17 00:00:00 2001 From: sophia Date: Tue, 14 Feb 2023 16:17:42 -0800 Subject: [PATCH 19/36] Clarify file provisioning docs --- website/content/docs/provisioning/file.mdx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/website/content/docs/provisioning/file.mdx b/website/content/docs/provisioning/file.mdx index aae5e7fd3..a49309d91 100644 --- a/website/content/docs/provisioning/file.mdx +++ b/website/content/docs/provisioning/file.mdx @@ -27,10 +27,11 @@ end ``` If you want to upload a folder to your guest system, it can be accomplished by -using a file provisioner seen below. When copied, the resulting folder on the guest will -replace `folder` as `newfolder` and place its on the guest machine. Note that if -you'd like the same folder name on your guest machine, make sure that the destination -path has the same name as the folder on your host. +using a file provisioner seen below. This will copy the your local `folder` +(specified as the `source`) to the the `newfolder` on the guest machine +(specified as the `destination`). Note that if you'd like the same folder name +on your guest machine, make sure that the destination path has the same name as +the folder on your host. ```ruby Vagrant.configure("2") do |config| From 37540664c707fef5d689e693b9525665220f2d67 Mon Sep 17 00:00:00 2001 From: sophia Date: Wed, 15 Feb 2023 10:09:49 -0800 Subject: [PATCH 20/36] Add another example for finding ip --- website/content/docs/networking/private_network.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/content/docs/networking/private_network.mdx b/website/content/docs/networking/private_network.mdx index f52b06cbe..79770e5c9 100644 --- a/website/content/docs/networking/private_network.mdx +++ b/website/content/docs/networking/private_network.mdx @@ -40,7 +40,7 @@ end This will automatically assign an IP address from the reserved address space. The IP address can be determined by using `vagrant ssh` to SSH into the machine and using the appropriate command line tool to find the IP, -such as `ifconfig`. +such as `ifconfig` or `ip addr show`. ## Static IP From 1c72132914e14cc7145bb9deca242489036f0cb6 Mon Sep 17 00:00:00 2001 From: Mike Pennisi Date: Thu, 7 Apr 2022 18:08:17 -0400 Subject: [PATCH 21/36] Document Box requirement for "vagrant" group By default, the `vagrant rsync` command assumes that the SSH user belongs to a group of the same name [1]: # Folder options opts[:owner] ||= ssh_info[:username] opts[:group] ||= ssh_info[:username] Although consumers can override this behavior, Vagrant Boxes which follow this convention will provide a more seamless experience. Document the convention in the instructions for Vagrant Box authors. [1] https://github.com/hashicorp/vagrant/blob/3d68e16f1b5d616f879d24f48dac2598acac0a38/plugins/synced_folders/rsync/helper.rb#L73-L75 --- website/content/docs/boxes/base.mdx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/website/content/docs/boxes/base.mdx b/website/content/docs/boxes/base.mdx index f6d352757..c32f50b5e 100644 --- a/website/content/docs/boxes/base.mdx +++ b/website/content/docs/boxes/base.mdx @@ -116,10 +116,11 @@ users, passwords, private keys, etc.). By default, Vagrant expects a "vagrant" user to SSH into the machine as. This user should be setup with the [insecure keypair](https://github.com/hashicorp/vagrant/tree/main/keys) -that Vagrant uses as a default to attempt to SSH. Also, even though -Vagrant uses key-based authentication by default, it is a general convention -to set the password for the "vagrant" user to "vagrant". This lets people -login as that user manually if they need to. +that Vagrant uses as a default to attempt to SSH. It should belong to a +group named "vagrant". Also, even though Vagrant uses key-based +authentication by default, it is a general convention to set the +password for the "vagrant" user to "vagrant". This lets people login as +that user manually if they need to. To configure SSH access with the insecure keypair, place the public key into the `~/.ssh/authorized_keys` file for the "vagrant" user. Note From fa24dc82376faedded652d32bba80431b3637e9d Mon Sep 17 00:00:00 2001 From: Ryan Gerstenkorn Date: Mon, 30 Nov 2020 01:50:26 -0600 Subject: [PATCH 22/36] Add example config to disable default share When you use the default share the guest has access to the Vagrantfile on the host. Disabling the default share and using sharing another subfolder is an easy way to work around this. --- templates/commands/init/Vagrantfile.erb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/templates/commands/init/Vagrantfile.erb b/templates/commands/init/Vagrantfile.erb index 5b9bff115..a9b33125d 100644 --- a/templates/commands/init/Vagrantfile.erb +++ b/templates/commands/init/Vagrantfile.erb @@ -54,6 +54,13 @@ Vagrant.configure("2") do |config| # argument is a set of non-required options. # config.vm.synced_folder "../data", "/vagrant_data" + # Disable the default share of the current code directory. Doing this + # provides improved isolation between the vagrant box and your host + # by making sure your Vagrantfile isn't accessable to the vagrant box. + # If you use this you may want to enable additional shared subfolders as + # shown above. + # config.vm.synced_folder ".", "/vagrant", disabled: true + # Provider-specific configuration so you can fine-tune various # backing providers for Vagrant. These expose provider-specific options. # Example for VirtualBox: From d0ff2886daf8da89a7779792c0adda95ebccf2d5 Mon Sep 17 00:00:00 2001 From: sophia Date: Wed, 15 Feb 2023 16:07:04 -0800 Subject: [PATCH 23/36] Add linux command for uuids ref: https://github.com/hashicorp/vagrant/pull/12015 --- website/content/docs/cli/package.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/content/docs/cli/package.mdx b/website/content/docs/cli/package.mdx index c93362d3d..1bae2dfcf 100644 --- a/website/content/docs/cli/package.mdx +++ b/website/content/docs/cli/package.mdx @@ -20,7 +20,9 @@ and if the provider supports it. - `--base NAME` - Instead of packaging a VirtualBox machine that Vagrant manages, this will package a VirtualBox machine that VirtualBox manages. `NAME` should be the name or UUID of the machine from the VirtualBox GUI. - Currently this option is only available for VirtualBox. + Currently this option is only available for VirtualBox. + **In a multi-machine environment, the UUID is required.** This info can be + gathered in two different ways `ls -l ~/VirtualBox\ VMs` or `vboxmanage list vms`. - `--output NAME` - The resulting package will be saved as `NAME`. By default, it will be saved as `package.box`. From b0a41098459431e5924e094fb5ac1194751faee7 Mon Sep 17 00:00:00 2001 From: lyderX05 <69924216+lyderX05@users.noreply.github.com> Date: Thu, 1 Oct 2020 16:11:10 +0530 Subject: [PATCH 24/36] Fixes the issue of Vagrant is unable to execute Get-WindowsOptionalFeature Command. Fixes #11932 --- lib/vagrant/util/platform.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/vagrant/util/platform.rb b/lib/vagrant/util/platform.rb index c8658e185..b160f1bd9 100644 --- a/lib/vagrant/util/platform.rb +++ b/lib/vagrant/util/platform.rb @@ -139,8 +139,13 @@ module Vagrant return @_windows_hyperv_enabled if defined?(@_windows_hyperv_enabled) @_windows_hyperv_enabled = -> { - ["Get-WindowsOptionalFeature", "Get-WindowsFeature"].each do |cmd_name| - ps_cmd = "$(#{cmd_name} -FeatureName Microsoft-Hyper-V-Hypervisor).State" + {:"Get-WindowsOptionalFeature" => ["-Online"], :"Get-WindowsFeature" => []}.each do |cmd_name, arguments| + parameters = arguments.join " " + if cmd_name == "Get-WindowsFeature" + ps_cmd = "if (Get-Command #{cmd_name} -ErrorAction SilentlyContinue){ $(#{cmd_name} -FeatureName Microsoft-Hyper-V-Hypervisor #{parameters}).State } else { 'Disabled' }" + else + ps_cmd = "$(#{cmd_name} -FeatureName Microsoft-Hyper-V-Hypervisor #{parameters}).State" + end begin output = Vagrant::Util::PowerShell.execute_cmd(ps_cmd) return true if output == "Enabled" From 88c5e17c5ce301451712dca5195ce7a32ac0ead5 Mon Sep 17 00:00:00 2001 From: lyderX05 <69924216+lyderX05@users.noreply.github.com> Date: Thu, 1 Oct 2020 16:14:48 +0530 Subject: [PATCH 25/36] Fixes the issue of Vagrant is unable to execute Get-WindowsOptionalFeature Command changes 2 Fixes #11932 --- lib/vagrant/util/platform.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/vagrant/util/platform.rb b/lib/vagrant/util/platform.rb index b160f1bd9..b213add0e 100644 --- a/lib/vagrant/util/platform.rb +++ b/lib/vagrant/util/platform.rb @@ -141,10 +141,9 @@ module Vagrant @_windows_hyperv_enabled = -> { {:"Get-WindowsOptionalFeature" => ["-Online"], :"Get-WindowsFeature" => []}.each do |cmd_name, arguments| parameters = arguments.join " " + ps_cmd = "$(#{cmd_name} -FeatureName Microsoft-Hyper-V-Hypervisor #{parameters}).State" if cmd_name == "Get-WindowsFeature" ps_cmd = "if (Get-Command #{cmd_name} -ErrorAction SilentlyContinue){ $(#{cmd_name} -FeatureName Microsoft-Hyper-V-Hypervisor #{parameters}).State } else { 'Disabled' }" - else - ps_cmd = "$(#{cmd_name} -FeatureName Microsoft-Hyper-V-Hypervisor #{parameters}).State" end begin output = Vagrant::Util::PowerShell.execute_cmd(ps_cmd) From a7d87498ed4fb0101522f59ef97b06fc367e1692 Mon Sep 17 00:00:00 2001 From: lyderX05 <69924216+lyderX05@users.noreply.github.com> Date: Wed, 14 Oct 2020 00:49:48 +0530 Subject: [PATCH 26/36] Requested Changes Updated on Fixes Fixes the issue of Vagrant is unable to execute Get-WindowsOptionalFeature Command changes 2 Fixes #11932 --- lib/vagrant/util/platform.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/vagrant/util/platform.rb b/lib/vagrant/util/platform.rb index b213add0e..6091d84dd 100644 --- a/lib/vagrant/util/platform.rb +++ b/lib/vagrant/util/platform.rb @@ -139,18 +139,20 @@ module Vagrant return @_windows_hyperv_enabled if defined?(@_windows_hyperv_enabled) @_windows_hyperv_enabled = -> { - {:"Get-WindowsOptionalFeature" => ["-Online"], :"Get-WindowsFeature" => []}.each do |cmd_name, arguments| - parameters = arguments.join " " - ps_cmd = "$(#{cmd_name} -FeatureName Microsoft-Hyper-V-Hypervisor #{parameters}).State" - if cmd_name == "Get-WindowsFeature" - ps_cmd = "if (Get-Command #{cmd_name} -ErrorAction SilentlyContinue){ $(#{cmd_name} -FeatureName Microsoft-Hyper-V-Hypervisor #{parameters}).State } else { 'Disabled' }" - end + check_commands = Array.new.tap do |c| + c << "(Get-WindowsOptionalFeature -FeatureName Microsoft-Hyper-V-Hypervisor -Online).State" + c << "(Get-WindowsFeature -FeatureName Microsoft-Hyper-V-Hypervisor).State" + end + check_commands.each do |ps_cmd| begin output = Vagrant::Util::PowerShell.execute_cmd(ps_cmd) return true if output == "Enabled" rescue Errors::PowerShellInvalidVersion logger.warn("Invalid PowerShell version detected during Hyper-V enable check") return false + rescue Errors::PowerShellError + logger.warn("Powershell command not found or error on execution of command") + return false end end return false From 38e6e86d804f0826c4abcad8ceae387ac1301acb Mon Sep 17 00:00:00 2001 From: sophia Date: Fri, 17 Feb 2023 11:38:28 -0800 Subject: [PATCH 27/36] Removes check for hyperv being enabled when verifying virtualbox is usable on windows. Virtualbox has supported running with hyperv since version 6.0.0 https://www.virtualbox.org/wiki/Changelog-6.0. (Virtualbox 6.0 is currently EOL) So, this check is no longer required. --- plugins/providers/virtualbox/action/check_virtualbox.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/plugins/providers/virtualbox/action/check_virtualbox.rb b/plugins/providers/virtualbox/action/check_virtualbox.rb index 800852c2a..1ae3eee30 100644 --- a/plugins/providers/virtualbox/action/check_virtualbox.rb +++ b/plugins/providers/virtualbox/action/check_virtualbox.rb @@ -16,12 +16,6 @@ module VagrantPlugins # which will break us out of execution of the middleware sequence. Driver::Meta.new.verify! - if Vagrant::Util::Platform.windows? && Vagrant::Util::Platform.windows_hyperv_enabled? - @logger.error("Virtualbox and Hyper-V cannot be used together at the same time on Windows and will result in a system crash.") - - raise Vagrant::Errors::HypervVirtualBoxError - end - # Carry on. @app.call(env) end From c32109b39dfd3a3c36961fcee10bdd48a96d6037 Mon Sep 17 00:00:00 2001 From: sophia Date: Tue, 21 Feb 2023 16:48:29 -0800 Subject: [PATCH 28/36] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8aa3bf1f4..375ea3e50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ IMPROVEMENTS: BUG FIXES: - provider/virtualbox: De-duplicate machine port forward info [GH-13056] +- provider/hyperv: Check for hyper-v feature "EnhancedSessionTransportType" [GH-12280] - communicator/ssh: Use netssh builtin keep alive functionality [GH-13069] - synced_folders/rsync: allow rsync-auto to also ignore relative paths [GH-13066] From e1d0940a684cf6e2b2395b5bff6f6edc348b6270 Mon Sep 17 00:00:00 2001 From: sophia Date: Tue, 21 Feb 2023 16:51:33 -0800 Subject: [PATCH 29/36] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 375ea3e50..6eb4f4c21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,10 @@ IMPROVEMENTS: BUG FIXES: +- communicator/ssh: Use netssh builtin keep alive functionality [GH-13069] +- guest/arch: Support differentiating between Artix and Arch Linux [GH-13055] - provider/virtualbox: De-duplicate machine port forward info [GH-13056] - provider/hyperv: Check for hyper-v feature "EnhancedSessionTransportType" [GH-12280] -- communicator/ssh: Use netssh builtin keep alive functionality [GH-13069] - synced_folders/rsync: allow rsync-auto to also ignore relative paths [GH-13066] VAGRANT-GO: From 457ecc50a14b172edad8d82412ff7e13db5bb997 Mon Sep 17 00:00:00 2001 From: sophia Date: Tue, 21 Feb 2023 17:13:12 -0800 Subject: [PATCH 30/36] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6eb4f4c21..dfb10f722 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ BUG FIXES: - guest/arch: Support differentiating between Artix and Arch Linux [GH-13055] - provider/virtualbox: De-duplicate machine port forward info [GH-13056] - provider/hyperv: Check for hyper-v feature "EnhancedSessionTransportType" [GH-12280] +- provisioner/ansible: Fix installing Ansible provisioner with version and pip [GH-13054] - synced_folders/rsync: allow rsync-auto to also ignore relative paths [GH-13066] VAGRANT-GO: From 9f666f8f61a846376002933427ddfc7562e1cceb Mon Sep 17 00:00:00 2001 From: sophia Date: Tue, 21 Feb 2023 17:15:55 -0800 Subject: [PATCH 31/36] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfb10f722..5256a8f5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ BUG FIXES: - communicator/ssh: Use netssh builtin keep alive functionality [GH-13069] - guest/arch: Support differentiating between Artix and Arch Linux [GH-13055] +- host/windows: Get state of Windows feature "Microsoft-Hyper-V-Hypervisor" [GH-11933] - provider/virtualbox: De-duplicate machine port forward info [GH-13056] - provider/hyperv: Check for hyper-v feature "EnhancedSessionTransportType" [GH-12280] - provisioner/ansible: Fix installing Ansible provisioner with version and pip [GH-13054] From 456aac73860b460b4b17271133de01e07f4ab493 Mon Sep 17 00:00:00 2001 From: sophia Date: Tue, 21 Feb 2023 17:18:38 -0800 Subject: [PATCH 32/36] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5256a8f5e..5fe0e2380 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ BUG FIXES: - guest/arch: Support differentiating between Artix and Arch Linux [GH-13055] - host/windows: Get state of Windows feature "Microsoft-Hyper-V-Hypervisor" [GH-11933] - provider/virtualbox: De-duplicate machine port forward info [GH-13056] +- provider/virtualbox: Remove check for hyperv being enabled when verifying virtualbox is usable on windows [GH-13090] - provider/hyperv: Check for hyper-v feature "EnhancedSessionTransportType" [GH-12280] - provisioner/ansible: Fix installing Ansible provisioner with version and pip [GH-13054] - synced_folders/rsync: allow rsync-auto to also ignore relative paths [GH-13066] From 1074f19fa351727bb34ccc01454ff91d1c84878e Mon Sep 17 00:00:00 2001 From: kaitlincart Date: Wed, 22 Feb 2023 10:46:59 -0800 Subject: [PATCH 33/36] fixes links in headers --- website/content/docs/provisioning/ansible_intro.mdx | 8 ++++++-- website/content/vagrant-cloud/organizations/index.mdx | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/website/content/docs/provisioning/ansible_intro.mdx b/website/content/docs/provisioning/ansible_intro.mdx index 0c834840d..326a2b9a2 100644 --- a/website/content/docs/provisioning/ansible_intro.mdx +++ b/website/content/docs/provisioning/ansible_intro.mdx @@ -89,7 +89,9 @@ When using Ansible, it needs to know on which machines a given playbook should r The first and simplest option is to not provide one to Vagrant at all. Vagrant will generate an inventory file encompassing all of the virtual machines it manages, and use it for provisioning machines. -#### Example with the [`ansible`](/vagrant/docs/provisioning/ansible) provisioner +#### Ansible provisioner example + +Example with the [`ansible`](/vagrant/docs/provisioning/ansible) provisioner. ```text # Generated by Vagrant @@ -100,7 +102,9 @@ default ansible_host=127.0.0.1 ansible_port=2200 ansible_user='vagrant' ansible_ Note that the generated inventory file is stored as part of your local Vagrant environment in `.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory`. -#### Example with the [`ansible_local`](/vagrant/docs/provisioning/ansible_local) provisioner +#### Ansible local provision + +Example with the [`ansible_local`](/vagrant/docs/provisioning/ansible_local) provisioner ```text # Generated by Vagrant diff --git a/website/content/vagrant-cloud/organizations/index.mdx b/website/content/vagrant-cloud/organizations/index.mdx index 2856a08f6..3f7194426 100755 --- a/website/content/vagrant-cloud/organizations/index.mdx +++ b/website/content/vagrant-cloud/organizations/index.mdx @@ -1,6 +1,6 @@ --- layout: vagrant-cloud -page_page_title: Organizations in Vagrant Cloud +page_title: Organizations in Vagrant Cloud --- ## Organizations in Vagrant Cloud From 6277591c24985f24f8a9ac4999dcd852260e8c93 Mon Sep 17 00:00:00 2001 From: sophia Date: Wed, 22 Feb 2023 14:16:50 -0800 Subject: [PATCH 34/36] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fe0e2380..6f87ff880 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ IMPROVEMENTS: BUG FIXES: - communicator/ssh: Use netssh builtin keep alive functionality [GH-13069] +- communicator/ssh: Update connection settings when using a password to connect ssh [GH-13052] - guest/arch: Support differentiating between Artix and Arch Linux [GH-13055] - host/windows: Get state of Windows feature "Microsoft-Hyper-V-Hypervisor" [GH-11933] - provider/virtualbox: De-duplicate machine port forward info [GH-13056] From 4551b8b2ad84bd1293b06d6731414f585959d7e7 Mon Sep 17 00:00:00 2001 From: sophia Date: Thu, 2 Feb 2023 16:42:24 -0800 Subject: [PATCH 35/36] Use file locks to avoid file existance checking race conditions --- lib/vagrant/util/file_mutex.rb | 18 +++++----- .../vagrant/action/builtin/box_add_test.rb | 10 ++++-- test/unit/vagrant/util/file_mutex_test.rb | 34 ++++++++++++++++++- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/lib/vagrant/util/file_mutex.rb b/lib/vagrant/util/file_mutex.rb index 2489d1a47..0844726dd 100644 --- a/lib/vagrant/util/file_mutex.rb +++ b/lib/vagrant/util/file_mutex.rb @@ -7,18 +7,20 @@ module Vagrant def with_lock(&block) lock - block.call - ensure - unlock + begin + block.call + rescue => e + raise e + ensure + unlock + end end def lock - if File.file?(@mutex_path) - raise Errors::VagrantLocked, - lock_file_path: @mutex_path + f = File.open(@mutex_path, "w+") + if f.flock(File::LOCK_EX|File::LOCK_NB) === false + raise Errors::VagrantLocked, lock_file_path: @mutex_path end - - File.write(@mutex_path, "") end def unlock diff --git a/test/unit/vagrant/action/builtin/box_add_test.rb b/test/unit/vagrant/action/builtin/box_add_test.rb index 2b53a7f34..a28bcb16a 100644 --- a/test/unit/vagrant/action/builtin/box_add_test.rb +++ b/test/unit/vagrant/action/builtin/box_add_test.rb @@ -86,12 +86,16 @@ describe Vagrant::Action::Builtin::BoxAdd, :skip_windows, :bsdtar do context "the download location is locked" do let(:box_path) { iso_env.box2_file(:virtualbox) } + let(:mutex_path) { env[:tmp_path].join("box" + Digest::SHA1.hexdigest("file://" + box_path.to_s) + ".lock").to_s } before do - mutex_path = env[:tmp_path].join("box" + Digest::SHA1.hexdigest("file://" + box_path.to_s) + ".lock").to_s - File.write(mutex_path, "") + # Lock file + @f = File.open(mutex_path, "w+") + @f.flock(File::LOCK_EX|File::LOCK_NB) end - + + after { @f.close } + it "raises a download error" do env[:box_name] = "foo" env[:box_url] = box_path.to_s diff --git a/test/unit/vagrant/util/file_mutex_test.rb b/test/unit/vagrant/util/file_mutex_test.rb index 0a709f770..eacbd9ffd 100644 --- a/test/unit/vagrant/util/file_mutex_test.rb +++ b/test/unit/vagrant/util/file_mutex_test.rb @@ -21,6 +21,7 @@ describe Vagrant::Util::FileMutex do mutex_path = temp_dir + "test.lock" instance = described_class.new(mutex_path) instance.lock + expect(File).to exist(mutex_path) instance.unlock expect(File).to_not exist(mutex_path) end @@ -41,9 +42,40 @@ describe Vagrant::Util::FileMutex do it "should fail running a function when locked" do mutex_path = temp_dir + "test.lock" + # create a lock instance = described_class.new(mutex_path) instance.lock - expect {instance.with_lock { true }}. + # create a new lock that will run a function + instance2 = described_class.new(mutex_path) + # lock should persist for multiple runs + expect {instance2.with_lock { true }}. to raise_error(Vagrant::Errors::VagrantLocked) + expect {instance2.with_lock { true }}. + to raise_error(Vagrant::Errors::VagrantLocked) + # mutex should exist until its unlocked + expect(File).to exist(mutex_path) + instance.unlock + expect(File).to_not exist(mutex_path) + end + + it "should fail running a function within a locked" do + mutex_path = temp_dir + "test.lock" + # create a lock + instance = described_class.new(mutex_path) + # create a new lock that will run a function + instance2 = described_class.new(mutex_path) + expect { + instance.with_lock { instance2.with_lock{true} } + }.to raise_error(Vagrant::Errors::VagrantLocked) + expect(File).to_not exist(mutex_path) + end + + it "should delete the lock even when the function fails" do + mutex_path = temp_dir + "test.lock" + instance = described_class.new(mutex_path) + expect { + instance.with_lock { raise Vagrant::Errors::VagrantError.new } + }.to raise_error(Vagrant::Errors::VagrantError) + expect(File).to_not exist(mutex_path) end end From 3ce2b7ecc8e7cc70247dface553456db114734bc Mon Sep 17 00:00:00 2001 From: sophia Date: Wed, 22 Feb 2023 15:03:01 -0800 Subject: [PATCH 36/36] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f87ff880..13b35157f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ BUG FIXES: - communicator/ssh: Use netssh builtin keep alive functionality [GH-13069] - communicator/ssh: Update connection settings when using a password to connect ssh [GH-13052] +- core: Add a file mutex when downloading box files [GH-13057] - guest/arch: Support differentiating between Artix and Arch Linux [GH-13055] - host/windows: Get state of Windows feature "Microsoft-Hyper-V-Hypervisor" [GH-11933] - provider/virtualbox: De-duplicate machine port forward info [GH-13056]