diff --git a/CHANGELOG.md b/CHANGELOG.md index 66d0c00d1..ec6de52f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,22 @@ FEATURES: +- providers/virtualbox: Virtualbox 5.2 support [GH-8955] + IMPROVEMENTS: +- core: Clear POSIXLY_CORRECT when using optparse [GH-8685] +- docs: Add auto_start_action and auto_stop_action to docs. [GH-9029] +- provisioners/chef: Handle chef provisioner reboot request [GH-8874] +- provisioners/shell: Use ui.detail for displaying output [GH-8983] + BUG FIXES: +- core: Rescue more exceptions when checking if port is open [GH-8517] +- guests/windows: Split out cygwin path helper for msys2/cygwin paths and ensure cygpath exists [GH-8972] +- providers/hyper-v: Properly invoke Auto stop action [GH-9000] +- virtualbox/synced_folders: Allow synced folders to contain spaces in the guest path [GH-8995] + ## 2.0.0 (September 7, 2017) IMPROVEMENTS: diff --git a/README.md b/README.md index cedba5568..bdbca438f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Vagrant * Website: [https://www.vagrantup.com/](https://www.vagrantup.com/) -* Source: [https://github.com/mitchellh/vagrant](https://github.com/mitchellh/vagrant) +* Source: [https://github.com/hashicorp/vagrant](https://github.com/hashicorp/vagrant) * [![Gitter chat](https://badges.gitter.im/mitchellh/vagrant.png)](https://gitter.im/mitchellh/vagrant) * Mailing list: [Google Groups](https://groups.google.com/group/vagrant-up) @@ -49,7 +49,7 @@ and you're welcome to give it a shot. Please review the installation page [here] ## Contributing to Vagrant -To install Vagrant from source, please [follow the guide in the Wiki](https://github.com/mitchellh/vagrant/wiki/Installing-Vagrant-from-Source). +To install Vagrant from source, please [follow the guide in the Wiki](https://github.com/hashicorp/vagrant/wiki/Installing-Vagrant-from-Source). You can run the test suite with: diff --git a/contrib/sudoers/linux-suse b/contrib/sudoers/linux-suse index 30658af3f..2620138a4 100644 --- a/contrib/sudoers/linux-suse +++ b/contrib/sudoers/linux-suse @@ -1,7 +1,6 @@ -Cmnd_Alias VAGRANT_EXPORTS_ADD = /usr/bin/tee -a /etc/exports -Cmnd_Alias VAGRANT_NFSD_CHECK = /sbin/service nfsserver status -Cmnd_Alias VAGRANT_NFSD_START = /sbin/service nfsserver start -Cmnd_Alias VAGRANT_NFSD_APPLY = /usr/sbin/exportfs -ar -Cmnd_Alias VAGRANT_EXPORTS_REMOVE = /usr/bin/sed -r -e * d -ibak /*/exports -Cmnd_Alias VAGRANT_EXPORTS_REMOVE_2 = /usr/bin/cp /*/exports /etc/exports -%vagrant ALL=(root) NOPASSWD: VAGRANT_EXPORTS_ADD, VAGRANT_NFSD_CHECK, VAGRANT_NFSD_START, VAGRANT_NFSD_APPLY, VAGRANT_EXPORTS_REMOVE, VAGRANT_EXPORTS_REMOVE_2 +Cmnd_Alias VAGRANT_CHOWN = /usr/bin/chown 0\:0 /tmp/vagrant[a-z0-9-]* +Cmnd_Alias VAGRANT_MV = /usr/bin/mv -f /tmp/vagrant[a-z0-9-]* /etc/exports +Cmnd_Alias VAGRANT_START = /sbin/service nfsserver start +Cmnd_Alias VAGRANT_STATUS = /sbin/service nfsserver status +Cmnd_Alias VAGRANT_APPLY = /usr/sbin/exportfs -ar +%vagrant ALL=(root) NOPASSWD: VAGRANT_CHOWN, VAGRANT_MV, VAGRANT_START, VAGRANT_STATUS, VAGRANT_APPLY diff --git a/lib/vagrant/plugin/v2/command.rb b/lib/vagrant/plugin/v2/command.rb index f0b6c4415..94e554dc5 100644 --- a/lib/vagrant/plugin/v2/command.rb +++ b/lib/vagrant/plugin/v2/command.rb @@ -43,6 +43,9 @@ module Vagrant # If this method returns `nil`, then you should assume that help # was printed and parsing failed. def parse_options(opts=nil) + # make sure optparse doesn't use POSIXLY_CORRECT parsing + ENV["POSIXLY_CORRECT"] = nil + # Creating a shallow copy of the arguments so the OptionParser # doesn't destroy the originals. argv = @argv.dup diff --git a/lib/vagrant/util/is_port_open.rb b/lib/vagrant/util/is_port_open.rb index b51a01ecd..a0a79b4f7 100644 --- a/lib/vagrant/util/is_port_open.rb +++ b/lib/vagrant/util/is_port_open.rb @@ -30,7 +30,8 @@ module Vagrant return true end rescue Timeout::Error, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, \ - Errno::ENETUNREACH, Errno::EACCES, Errno::ENOTCONN + Errno::ENETUNREACH, Errno::EACCES, Errno::ENOTCONN, \ + Errno::EADDRNOTAVAIL # Any of the above exceptions signal that the port is closed. return false end diff --git a/lib/vagrant/util/platform.rb b/lib/vagrant/util/platform.rb index 778f3a7ab..8eeecfbac 100644 --- a/lib/vagrant/util/platform.rb +++ b/lib/vagrant/util/platform.rb @@ -98,21 +98,20 @@ module Vagrant end # This takes any path and converts it from a Windows path to a - # Cygwin or msys style path. + # Cygwin style path. # # @param [String] path # @return [String] def cygwin_path(path) begin - # We have to revert to the old env - # path here, otherwise it looks like - # msys2 ends up using the wrong cygpath - # binary and ends up with a `/cygdrive` - # when it doesn't exist in msys2 - original_path_env = ENV['PATH'] - ENV['PATH'] = ENV['VAGRANT_OLD_ENV_PATH'] cygpath = Vagrant::Util::Which.which("cygpath") - cygpath.gsub!("/", '\\') + if cygpath.nil? + # If Which can't find it, just attempt to invoke it directly + cygpath = "cygpath" + else + cygpath.gsub!("/", '\\') + end + process = Subprocess.execute( cygpath, "-u", "-a", path.to_s) return process.stdout.chomp @@ -125,14 +124,29 @@ module Vagrant "--norc", "-c", "cd #{Shellwords.escape(path)} && pwd") return process.stdout.chomp + end + end + + # This takes any path and converts it from a Windows path to a + # msys style path. + # + # @param [String] path + # @return [String] + def msys_path(path) + begin + # We have to revert to the old env + # path here, otherwise it looks like + # msys2 ends up using the wrong cygpath + # binary and ends up with a `/cygdrive` + # when it doesn't exist in msys2 + original_path_env = ENV['PATH'] + ENV['PATH'] = ENV['VAGRANT_OLD_ENV_PATH'] + cygwin_path(path) ensure ENV['PATH'] = original_path_env end end - # Identical to cygwin_path for now - alias_method :msys_path, :cygwin_path - # This takes any path and converts it to a full-length Windows # path on Windows machines in Cygwin. # diff --git a/plugins/guests/windows/scripts/reboot_detect.ps1 b/plugins/guests/windows/scripts/reboot_detect.ps1 index fa2e84ffe..93688ad73 100644 --- a/plugins/guests/windows/scripts/reboot_detect.ps1 +++ b/plugins/guests/windows/scripts/reboot_detect.ps1 @@ -32,6 +32,11 @@ if (ShuttingDown) { exit 2 } + if ($LASTEXITCODE -eq 1115) { + # A system shutdown is in progress + exit 2 + } + # Remove the pending reboot we just created above if ($LASTEXITCODE -eq 0) { . shutdown.exe -a diff --git a/plugins/providers/hyperv/scripts/import_vm_vmcx.ps1 b/plugins/providers/hyperv/scripts/import_vm_vmcx.ps1 index f93230193..1bc175270 100644 --- a/plugins/providers/hyperv/scripts/import_vm_vmcx.ps1 +++ b/plugins/providers/hyperv/scripts/import_vm_vmcx.ps1 @@ -115,7 +115,7 @@ if ($auto_start_action) { } if ($auto_stop_action) { - Set-VM -VM $vmConfig.VM -AutomaticStartAction $auto_stop_action + Set-VM -VM $vmConfig.VM -AutomaticStopAction $auto_stop_action } # Only set EFI secure boot for Gen 2 machines, not gen 1 diff --git a/plugins/providers/virtualbox/driver/meta.rb b/plugins/providers/virtualbox/driver/meta.rb index 0dd186d8c..ec457a866 100644 --- a/plugins/providers/virtualbox/driver/meta.rb +++ b/plugins/providers/virtualbox/driver/meta.rb @@ -62,6 +62,7 @@ module VagrantPlugins "4.3" => Version_4_3, "5.0" => Version_5_0, "5.1" => Version_5_1, + "5.2" => Version_5_2, } if @@version.start_with?("4.2.14") diff --git a/plugins/providers/virtualbox/driver/version_5_2.rb b/plugins/providers/virtualbox/driver/version_5_2.rb new file mode 100644 index 000000000..cd6c0b6c5 --- /dev/null +++ b/plugins/providers/virtualbox/driver/version_5_2.rb @@ -0,0 +1,16 @@ +require File.expand_path("../version_5_1", __FILE__) + +module VagrantPlugins + module ProviderVirtualBox + module Driver + # Driver for VirtualBox 5.2.x + class Version_5_2 < Version_5_1 + def initialize(uuid) + super + + @logger = Log4r::Logger.new("vagrant::provider::virtualbox_5_2") + end + end + end + end +end diff --git a/plugins/providers/virtualbox/plugin.rb b/plugins/providers/virtualbox/plugin.rb index 399747a6a..090bc5061 100644 --- a/plugins/providers/virtualbox/plugin.rb +++ b/plugins/providers/virtualbox/plugin.rb @@ -57,6 +57,7 @@ module VagrantPlugins autoload :Version_4_3, File.expand_path("../driver/version_4_3", __FILE__) autoload :Version_5_0, File.expand_path("../driver/version_5_0", __FILE__) autoload :Version_5_1, File.expand_path("../driver/version_5_1", __FILE__) + autoload :Version_5_2, File.expand_path("../driver/version_5_2", __FILE__) end module Model diff --git a/plugins/providers/virtualbox/synced_folder.rb b/plugins/providers/virtualbox/synced_folder.rb index 2ce0f82c1..a3eff1f29 100644 --- a/plugins/providers/virtualbox/synced_folder.rb +++ b/plugins/providers/virtualbox/synced_folder.rb @@ -85,7 +85,7 @@ module VagrantPlugins end def os_friendly_id(id) - id.gsub(/[\/\\]/,'_').sub(/^_/, '') + id.gsub(/[\s\/\\]/,'_').sub(/^_/, '') end # share_folders sets up the shared folder definitions on the diff --git a/plugins/provisioners/chef/provisioner/chef_client.rb b/plugins/provisioners/chef/provisioner/chef_client.rb index 1d7dc5420..10d890176 100644 --- a/plugins/provisioners/chef/provisioner/chef_client.rb +++ b/plugins/provisioners/chef/provisioner/chef_client.rb @@ -73,35 +73,42 @@ module VagrantPlugins @machine.ui.warn(I18n.t("vagrant.chef_run_list_empty")) end - if @machine.guest.capability?(:wait_for_reboot) - @machine.guest.capability(:wait_for_reboot) - end - command = CommandBuilder.command(:client, @config, windows: windows?, colored: @machine.env.ui.color?, ) - + + still_active = 259 #provisioner has asked chef to reboot + @config.attempts.times do |attempt| - if attempt == 0 - @machine.ui.info I18n.t("vagrant.provisioners.chef.running_client") - else - @machine.ui.info I18n.t("vagrant.provisioners.chef.running_client_again") + exit_status = 0 + while exit_status == 0 || exit_status == still_active + if @machine.guest.capability?(:wait_for_reboot) + @machine.guest.capability(:wait_for_reboot) + elsif attempt > 0 + sleep 10 + @machine.communicate.wait_for_ready(@machine.config.vm.boot_timeout) + end + if attempt == 0 + @machine.ui.info I18n.t("vagrant.provisioners.chef.running_client") + else + @machine.ui.info I18n.t("vagrant.provisioners.chef.running_client_again") + end + + opts = { error_check: false, elevated: true } + exit_status = @machine.communicate.sudo(command, opts) do |type, data| + # Output the data with the proper color based on the stream. + color = type == :stdout ? :green : :red + + data = data.chomp + next if data.empty? + + @machine.ui.info(data, color: color) + end + + # There is no need to run Chef again if it converges + return if exit_status == 0 end - - opts = { error_check: false, elevated: true } - exit_status = @machine.communicate.sudo(command, opts) do |type, data| - # Output the data with the proper color based on the stream. - color = type == :stdout ? :green : :red - - data = data.chomp - next if data.empty? - - @machine.ui.info(data, color: color) - end - - # There is no need to run Chef again if it converges - return if exit_status == 0 end # If we reached this point then Chef never converged! Error. diff --git a/plugins/provisioners/chef/provisioner/chef_solo.rb b/plugins/provisioners/chef/provisioner/chef_solo.rb index cc613af8a..754ace11c 100644 --- a/plugins/provisioners/chef/provisioner/chef_solo.rb +++ b/plugins/provisioners/chef/provisioner/chef_solo.rb @@ -176,36 +176,43 @@ module VagrantPlugins @machine.ui.warn(I18n.t("vagrant.chef_run_list_empty")) end - if @machine.guest.capability?(:wait_for_reboot) - @machine.guest.capability(:wait_for_reboot) - end - command = CommandBuilder.command(:solo, @config, windows: windows?, colored: @machine.env.ui.color?, legacy_mode: @config.legacy_mode, ) + still_active = 259 #provisioner has asked chef to reboot + @config.attempts.times do |attempt| - if attempt == 0 - @machine.ui.info I18n.t("vagrant.provisioners.chef.running_solo") - else - @machine.ui.info I18n.t("vagrant.provisioners.chef.running_solo_again") + exit_status = 0 + while exit_status == 0 || exit_status == still_active + if @machine.guest.capability?(:wait_for_reboot) + @machine.guest.capability(:wait_for_reboot) + elsif attempt > 0 + sleep 10 + @machine.communicate.wait_for_ready(@machine.config.vm.boot_timeout) + end + if attempt == 0 + @machine.ui.info I18n.t("vagrant.provisioners.chef.running_solo") + else + @machine.ui.info I18n.t("vagrant.provisioners.chef.running_solo_again") + end + + opts = { error_check: false, elevated: true } + exit_status = @machine.communicate.sudo(command, opts) do |type, data| + # Output the data with the proper color based on the stream. + color = type == :stdout ? :green : :red + + data = data.chomp + next if data.empty? + + @machine.ui.info(data, color: color) + end + + # There is no need to run Chef again if it converges + return if exit_status == 0 end - - opts = { error_check: false, elevated: true } - exit_status = @machine.communicate.sudo(command, opts) do |type, data| - # Output the data with the proper color based on the stream. - color = type == :stdout ? :green : :red - - data = data.chomp - next if data.empty? - - @machine.ui.info(data, color: color) - end - - # There is no need to run Chef again if it converges - return if exit_status == 0 end # If we reached this point then Chef never converged! Error. diff --git a/plugins/provisioners/chef/provisioner/chef_zero.rb b/plugins/provisioners/chef/provisioner/chef_zero.rb index 70fff6854..afb79e8ea 100644 --- a/plugins/provisioners/chef/provisioner/chef_zero.rb +++ b/plugins/provisioners/chef/provisioner/chef_zero.rb @@ -56,36 +56,43 @@ module VagrantPlugins @machine.ui.warn(I18n.t("vagrant.chef_run_list_empty")) end - if @machine.guest.capability?(:wait_for_reboot) - @machine.guest.capability(:wait_for_reboot) - end - command = CommandBuilder.command(:client, @config, windows: windows?, colored: @machine.env.ui.color?, local_mode: true, ) + still_active = 259 #provisioner has asked chef to reboot + @config.attempts.times do |attempt| - if attempt == 0 - @machine.ui.info I18n.t("vagrant.provisioners.chef.running_zero") - else - @machine.ui.info I18n.t("vagrant.provisioners.chef.running_zero_again") + exit_status = 0 + while exit_status == 0 || exit_status == still_active + if @machine.guest.capability?(:wait_for_reboot) + @machine.guest.capability(:wait_for_reboot) + elsif attempt > 0 + sleep 10 + @machine.communicate.wait_for_ready(@machine.config.vm.boot_timeout) + end + if attempt == 0 + @machine.ui.info I18n.t("vagrant.provisioners.chef.running_zero") + else + @machine.ui.info I18n.t("vagrant.provisioners.chef.running_zero_again") + end + + opts = { error_check: false, elevated: true } + exit_status = @machine.communicate.sudo(command, opts) do |type, data| + # Output the data with the proper color based on the stream. + color = type == :stdout ? :green : :red + + data = data.chomp + next if data.empty? + + @machine.ui.info(data, color: color) + end + + # There is no need to run Chef again if it converges + return if exit_status == 0 end - - opts = { error_check: false, elevated: true } - exit_status = @machine.communicate.sudo(command, opts) do |type, data| - # Output the data with the proper color based on the stream. - color = type == :stdout ? :green : :red - - data = data.chomp - next if data.empty? - - @machine.ui.info(data, color: color) - end - - # There is no need to run Chef again if it converges - return if exit_status == 0 end # If we reached this point then Chef never converged! Error. diff --git a/plugins/provisioners/shell/provisioner.rb b/plugins/provisioners/shell/provisioner.rb index 6c54e5a0b..3964c0a82 100644 --- a/plugins/provisioners/shell/provisioner.rb +++ b/plugins/provisioners/shell/provisioner.rb @@ -43,7 +43,7 @@ module VagrantPlugins options = {} options[:color] = color if !config.keep_color - @machine.ui.info(data.chomp, options) + @machine.ui.detail(data.chomp, options) end end diff --git a/test/unit/plugins/providers/virtualbox/synced_folder_test.rb b/test/unit/plugins/providers/virtualbox/synced_folder_test.rb index 1cbb51edd..0e898991c 100644 --- a/test/unit/plugins/providers/virtualbox/synced_folder_test.rb +++ b/test/unit/plugins/providers/virtualbox/synced_folder_test.rb @@ -44,4 +44,30 @@ describe VagrantPlugins::ProviderVirtualBox::SyncedFolder do it "should share the folders" end + + describe "os_friendly_id" do + it "should not replace normal chars" do + expect(subject.send(:os_friendly_id, 'perfectly_valid0_name')).to eq('perfectly_valid0_name') + end + + it "should replace spaces" do + expect(subject.send(:os_friendly_id, 'Program Files')).to eq('Program_Files') + end + + it "should replace leading underscore" do + expect(subject.send(:os_friendly_id, '_vagrant')).to eq('vagrant') + end + + it "should replace slash" do + expect(subject.send(:os_friendly_id, 'va/grant')).to eq('va_grant') + end + + it "should replace leading underscore and slash" do + expect(subject.send(:os_friendly_id, '/vagrant')).to eq('vagrant') + end + + it "should replace backslash" do + expect(subject.send(:os_friendly_id, 'foo\\bar')).to eq('foo_bar') + end + end end diff --git a/test/unit/vagrant/util/platform_test.rb b/test/unit/vagrant/util/platform_test.rb index b97f11ff9..88171ddae 100644 --- a/test/unit/vagrant/util/platform_test.rb +++ b/test/unit/vagrant/util/platform_test.rb @@ -22,10 +22,36 @@ describe Vagrant::Util::Platform do allow(Vagrant::Util::Which).to receive(:which).and_return("C:/msys2/cygpath") allow(Vagrant::Util::Subprocess).to receive(:execute).and_return(subprocess_result) + expect(Vagrant::Util::Subprocess).to receive(:execute).with("C:\\msys2\\cygpath", "-u", "-a", "C:\\msys2\\home\\vagrant") + expect(subject.cygwin_path(path)).to eq("/home/vagrant") end end + describe "#msys_path" do + let(:updated_path) { "/home/vagrant" } + let(:subprocess_result) do + double("subprocess_result").tap do |result| + allow(result).to receive(:exit_code).and_return(0) + allow(result).to receive(:stdout).and_return(updated_path) + end + end + let(:old_path) { "/old/path/bin:/usr/local/bin:/usr/bin" } + + it "takes a windows path and returns a formatted path" do + path = ENV["PATH"] + allow(Vagrant::Util::Which).to receive(:which).and_return("C:/msys2/cygpath") + allow(Vagrant::Util::Subprocess).to receive(:execute).and_return(subprocess_result) + allow(ENV).to receive(:[]).with("PATH").and_return(path) + allow(ENV).to receive(:[]).with("VAGRANT_OLD_ENV_PATH").and_return(old_path) + + expect(Vagrant::Util::Subprocess).to receive(:execute).with("C:\\msys2\\cygpath", "-u", "-a", path) + + expect(subject.msys_path(path)).to eq("/home/vagrant") + expect(ENV["PATH"]).to eq(path) + end + end + describe "#cygwin?" do before do allow(subject).to receive(:platform).and_return("test") diff --git a/website/source/docs/boxes/base.html.md b/website/source/docs/boxes/base.html.md index 371e40eee..0ef8a98ec 100644 --- a/website/source/docs/boxes/base.html.md +++ b/website/source/docs/boxes/base.html.md @@ -71,7 +71,7 @@ Provider-specific guides for creating base boxes are linked below: We strongly recommend using [Packer](https://www.packer.io) to create reproducible builds for your base boxes, as well as automating the builds with [Atlas](https://atlas.hashicorp.com). Read more about -[Creating Vagrant Boxes with Packer](https://atlas.hashicorp.com/help/packer/artifacts/creating-vagrant-boxes) +[Creating Vagrant Boxes with Packer](https://www.terraform.io/docs/enterprise/packer/artifacts/creating-vagrant-boxes.html) in the Atlas documentation. ### Disk Space diff --git a/website/source/docs/hyperv/configuration.html.md b/website/source/docs/hyperv/configuration.html.md index f1d51a45a..47a0211df 100644 --- a/website/source/docs/hyperv/configuration.html.md +++ b/website/source/docs/hyperv/configuration.html.md @@ -32,6 +32,8 @@ you may set. A complete reference is shown below: * `enable_virtualization_extensions` (boolean) - Enable virtualization extensions for the virtual CPUs. This allows Hyper-V to be nested and run inside another Hyper-VM VM. It requires Windows 10 - 1511 (build 10586) or newer. Default is not defined. This will be disabled if not set. + * `auto_start_action` (Nothing, StartIfRunning, Start) - Action on automatic start of VM when booting OS + * `auto_stop_action` (ShutDown, TurnOff, Save) - Action on automatic stop of VM when shutting down OS. * `vm_integration_services` (Hash) - Hash to set the state of integration services. Example: @@ -47,6 +49,4 @@ you may set. A complete reference is shown below: vss: true } end - ``` - - \ No newline at end of file + ``` \ No newline at end of file diff --git a/website/source/docs/vagrantfile/ssh_settings.html.md b/website/source/docs/vagrantfile/ssh_settings.html.md index 929502e7b..f5ce75c16 100644 --- a/website/source/docs/vagrantfile/ssh_settings.html.md +++ b/website/source/docs/vagrantfile/ssh_settings.html.md @@ -63,7 +63,7 @@ the machine, but replace it with perhaps a more secure key later.
`config.ssh.keys_only` - Only use Vagrant-provided SSH private keys (do not use -any keys stored in ssh-agent). The default value is `true`.` +any keys stored in ssh-agent). The default value is `true`.