diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ecd67de9..5a6f2acff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,12 @@ BUG FIXES: - core: push configurations are validated with global configs [GH-5130] - core: remove executable permissions on internal file [GH-5220] - core: check name and version in `has_plugin?` [GH-5218] + - core/cli: fix box checksum validation [GH-4665, GH-5221] - hosts/nfs: allow colons (`:`) in NFS IDs [GH-5222] - guests/funtoo: fix incorrect path in configure networks [GH-4812] - plugins/login: allow users to login with a token [GH-5145] - providers/hyperv: allow users to configure memory, cpu count, and vmname [GH-5183] + - providers/virtualbox: read netmask from dhcpservers [GH-5233] - provisioners/ansible: fix SSH settings to support more than 5 ssh keys [GH-5017] - provisioners/ansible: increase ansible connection timeout to 30 seconds [GH-5018] - provisioners/docker: use docker.com instead of docker.io [GH-5216] diff --git a/lib/vagrant/action/builtin/handle_box.rb b/lib/vagrant/action/builtin/handle_box.rb index a01e49d64..8cbdd413c 100644 --- a/lib/vagrant/action/builtin/handle_box.rb +++ b/lib/vagrant/action/builtin/handle_box.rb @@ -64,6 +64,8 @@ module Vagrant box_download_ca_path = machine.config.vm.box_download_ca_path box_download_client_cert = machine.config.vm.box_download_client_cert box_download_insecure = machine.config.vm.box_download_insecure + box_download_checksum_type = machine.config.vm.box_download_checksum_type + box_download_checksum = machine.config.vm.box_download_checksum box_formats = machine.provider_options[:box_format] || machine.provider_name @@ -86,6 +88,8 @@ module Vagrant box_download_ca_cert: box_download_ca_cert, box_download_ca_path: box_download_ca_path, box_download_insecure: box_download_insecure, + box_checksum_type: box_download_checksum_type, + box_checksum: box_download_checksum, })) rescue Errors::BoxAlreadyExists # Just ignore this, since it means the next part will succeed! diff --git a/lib/vagrant/action/runner.rb b/lib/vagrant/action/runner.rb index bfb187709..8799a8d7f 100644 --- a/lib/vagrant/action/runner.rb +++ b/lib/vagrant/action/runner.rb @@ -62,7 +62,7 @@ module Vagrant end # We place a process lock around every action that is called - @logger.info("Running action: #{callable_id}") + @logger.info("Running action: #{environment[:action_name]} #{callable_id}") Util::Busy.busy(int_callback) { callable.call(environment) } # Return the environment in case there are things in there that diff --git a/plugins/communicators/winrm/file_manager.rb b/plugins/communicators/winrm/file_manager.rb deleted file mode 100644 index 71586b811..000000000 --- a/plugins/communicators/winrm/file_manager.rb +++ /dev/null @@ -1,163 +0,0 @@ -require "log4r" - -module VagrantPlugins - module CommunicatorWinRM - # Manages the file system on the remote guest allowing for file tranfer - # between the guest and host. - class FileManager - def initialize(shell) - @logger = Log4r::Logger.new("vagrant::communication::filemanager") - @shell = shell - end - - # Uploads the given file or directory from the host to the guest (recursively). - # - # @param [String] The source file or directory path on the host - # @param [String] The destination file or directory path on the host - def upload(host_src_file_path, guest_dest_file_path) - @logger.debug("Upload: #{host_src_file_path} -> #{guest_dest_file_path}") - if File.directory?(host_src_file_path) - upload_directory(host_src_file_path, guest_dest_file_path) - else - upload_file(host_src_file_path, guest_dest_file_path) - end - end - - # Downloads the given file from the guest to the host. - # NOTE: This currently only supports single file download - # - # @param [String] The source file path on the guest - # @param [String] The destination file path on the host - def download(guest_src_file_path, host_dest_file_path) - @logger.debug("#{guest_src_file_path} -> #{host_dest_file_path}") - - output = @shell.powershell("[System.convert]::ToBase64String([System.IO.File]::ReadAllBytes(\"#{guest_src_file_path}\"))") - contents = output[:data].map!{|line| line[:stdout]}.join.gsub("\\n\\r", '') - out = Base64.decode64(contents) - IO.binwrite(host_dest_file_path, out) - end - - private - - # Recursively uploads the given directory from the host to the guest - # - # @param [String] The source file or directory path on the host - # @param [String] The destination file or directory path on the host - def upload_directory(host_src_file_path, guest_dest_file_path) - glob_patt = File.join(host_src_file_path, '**/*') - Dir.glob(glob_patt).select { |f| !File.directory?(f) }.each do |host_file_path| - guest_file_path = guest_file_path(host_src_file_path, guest_dest_file_path, host_file_path) - upload_file(host_file_path, guest_file_path) - end - end - - # Uploads the given file, but only if the target file doesn't exist - # or its MD5 checksum doens't match the host's source checksum. - # - # @param [String] The source file path on the host - # @param [String] The destination file path on the guest - def upload_file(host_src_file_path, guest_dest_file_path) - if should_upload_file?(host_src_file_path, guest_dest_file_path) - tmp_file_path = upload_to_temp_file(host_src_file_path) - decode_temp_file(tmp_file_path, guest_dest_file_path) - else - @logger.debug("Up to date: #{guest_dest_file_path}") - end - end - - # Uploads the given file to a new temp file on the guest - # - # @param [String] The source file path on the host - # @return [String] The temp file path on the guest - def upload_to_temp_file(host_src_file_path) - tmp_file_path = File.join(guest_temp_dir, "winrm-upload-#{rand()}") - @logger.debug("Uploading '#{host_src_file_path}' to temp file '#{tmp_file_path}'") - - base64_host_file = Base64.encode64(IO.binread(host_src_file_path)).gsub("\n",'') - base64_host_file.chars.to_a.each_slice(8000-tmp_file_path.size) do |chunk| - out = @shell.cmd("echo #{chunk.join} >> \"#{tmp_file_path}\"") - raise_upload_error_if_failed(out, host_src_file_path, tmp_file_path) - end - - tmp_file_path - end - - # Moves and decodes the given file temp file on the guest to its - # permanent location - # - # @param [String] The source base64 encoded temp file path on the guest - # @param [String] The destination file path on the guest - def decode_temp_file(guest_tmp_file_path, guest_dest_file_path) - @logger.debug("Decoding temp file '#{guest_tmp_file_path}' to '#{guest_dest_file_path}'") - out = @shell.powershell <<-EOH - $tmp_file_path = [System.IO.Path]::GetFullPath('#{guest_tmp_file_path}') - $dest_file_path = [System.IO.Path]::GetFullPath('#{guest_dest_file_path}') - - if (Test-Path $dest_file_path) { - rm $dest_file_path - } - else { - $dest_dir = ([System.IO.Path]::GetDirectoryName($dest_file_path)) - New-Item -ItemType directory -Force -Path $dest_dir - } - - $base64_string = Get-Content $tmp_file_path - $bytes = [System.Convert]::FromBase64String($base64_string) - [System.IO.File]::WriteAllBytes($dest_file_path, $bytes) - EOH - raise_upload_error_if_failed(out, guest_tmp_file_path, guest_dest_file_path) - end - - # Checks to see if the target file on the guest is missing or out of date. - # - # @param [String] The source file path on the host - # @param [String] The destination file path on the guest - # @return [Boolean] True if the file is missing or out of date - def should_upload_file?(host_src_file_path, guest_dest_file_path) - local_md5 = Digest::MD5.file(host_src_file_path).hexdigest - cmd = <<-EOH - $dest_file_path = [System.IO.Path]::GetFullPath('#{guest_dest_file_path}') - - if (Test-Path $dest_file_path) { - $crypto_provider = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider - try { - $file = [System.IO.File]::Open($dest_file_path, [System.IO.Filemode]::Open, [System.IO.FileAccess]::Read) - $guest_md5 = ([System.BitConverter]::ToString($crypto_provider.ComputeHash($file))).Replace("-","").ToLower() - } - finally { - $file.Dispose() - } - if ($guest_md5 -eq '#{local_md5}') { - exit 0 - } - } - Write-Host "should upload file $dest_file_path" - exit 1 - EOH - @shell.powershell(cmd)[:exitcode] == 1 - end - - # Creates a guest file path equivalent from a host file path - # - # @param [String] The base host directory we're going to copy from - # @param [String] The base guest directory we're going to copy to - # @param [String] A full path to a file on the host underneath host_base_dir - # @return [String] The guest file path equivalent - def guest_file_path(host_base_dir, guest_base_dir, host_file_path) - rel_path = File.dirname(host_file_path[host_base_dir.length, host_file_path.length]) - File.join(guest_base_dir, rel_path, File.basename(host_file_path)) - end - - def guest_temp_dir - @guest_temp ||= (@shell.cmd('echo %TEMP%'))[:data][0][:stdout].chomp - end - - def raise_upload_error_if_failed(out, from, to) - raise Errors::WinRMFileTransferError, - from: from, - to: to, - message: out.inspect if out[:exitcode] != 0 - end - end - end -end diff --git a/plugins/communicators/winrm/shell.rb b/plugins/communicators/winrm/shell.rb index 794c3135d..2e9c35d5a 100644 --- a/plugins/communicators/winrm/shell.rb +++ b/plugins/communicators/winrm/shell.rb @@ -9,7 +9,7 @@ Vagrant::Util::SilenceWarnings.silence! do require "winrm" end -require_relative "file_manager" +require "winrm-fs/file_manager" module VagrantPlugins module CommunicatorWinRM @@ -65,11 +65,13 @@ module VagrantPlugins end def upload(from, to) - FileManager.new(self).upload(from, to) + file_manager = WinRM::FS::FileManager.new(session) + file_manager.upload(from, to) end def download(from, to) - FileManager.new(self).download(from, to) + file_manager = WinRM::FS::FileManager.new(session) + file_manager.download(from, to) end protected diff --git a/plugins/providers/virtualbox/driver/version_4_0.rb b/plugins/providers/virtualbox/driver/version_4_0.rb index a29193842..53361bbbb 100644 --- a/plugins/providers/virtualbox/driver/version_4_0.rb +++ b/plugins/providers/virtualbox/driver/version_4_0.rb @@ -265,6 +265,8 @@ module VagrantPlugins info[:network_name] = "HostInterfaceNetworking-#{network}" elsif ip = line[/^IP:\s+(.+?)$/, 1] info[:ip] = ip + elsif netmask = line[/^NetworkMask:\s+(.+?)$/, 1] + info[:netmask] = netmask elsif lower = line[/^lowerIPAddress:\s+(.+?)$/, 1] info[:lower] = lower elsif upper = line[/^upperIPAddress:\s+(.+?)$/, 1] diff --git a/plugins/providers/virtualbox/driver/version_4_1.rb b/plugins/providers/virtualbox/driver/version_4_1.rb index c22042b6b..ae1830019 100644 --- a/plugins/providers/virtualbox/driver/version_4_1.rb +++ b/plugins/providers/virtualbox/driver/version_4_1.rb @@ -270,6 +270,8 @@ module VagrantPlugins info[:network_name] = "HostInterfaceNetworking-#{network}" elsif ip = line[/^IP:\s+(.+?)$/, 1] info[:ip] = ip + elsif netmask = line[/^NetworkMask:\s+(.+?)$/, 1] + info[:netmask] = netmask elsif lower = line[/^lowerIPAddress:\s+(.+?)$/, 1] info[:lower] = lower elsif upper = line[/^upperIPAddress:\s+(.+?)$/, 1] diff --git a/plugins/providers/virtualbox/driver/version_4_2.rb b/plugins/providers/virtualbox/driver/version_4_2.rb index d976d973c..dc7da430a 100644 --- a/plugins/providers/virtualbox/driver/version_4_2.rb +++ b/plugins/providers/virtualbox/driver/version_4_2.rb @@ -293,6 +293,8 @@ module VagrantPlugins info[:network_name] = "HostInterfaceNetworking-#{network}" elsif ip = line[/^IP:\s+(.+?)$/, 1] info[:ip] = ip + elsif netmask = line[/^NetworkMask:\s+(.+?)$/, 1] + info[:netmask] = netmask elsif lower = line[/^lowerIPAddress:\s+(.+?)$/, 1] info[:lower] = lower elsif upper = line[/^upperIPAddress:\s+(.+?)$/, 1] diff --git a/plugins/providers/virtualbox/driver/version_4_3.rb b/plugins/providers/virtualbox/driver/version_4_3.rb index 28e6539d4..2d257a8c1 100644 --- a/plugins/providers/virtualbox/driver/version_4_3.rb +++ b/plugins/providers/virtualbox/driver/version_4_3.rb @@ -302,6 +302,8 @@ module VagrantPlugins info[:network_name] = "HostInterfaceNetworking-#{network}" elsif ip = line[/^IP:\s+(.+?)$/, 1] info[:ip] = ip + elsif netmask = line[/^NetworkMask:\s+(.+?)$/, 1] + info[:netmask] = netmask elsif lower = line[/^lowerIPAddress:\s+(.+?)$/, 1] info[:lower] = lower elsif upper = line[/^upperIPAddress:\s+(.+?)$/, 1] diff --git a/test/unit/plugins/providers/virtualbox/support/shared/virtualbox_driver_version_4_x_examples.rb b/test/unit/plugins/providers/virtualbox/support/shared/virtualbox_driver_version_4_x_examples.rb index 513f065a7..88f199a82 100644 --- a/test/unit/plugins/providers/virtualbox/support/shared/virtualbox_driver_version_4_x_examples.rb +++ b/test/unit/plugins/providers/virtualbox/support/shared/virtualbox_driver_version_4_x_examples.rb @@ -37,6 +37,7 @@ shared_examples "a version 4.x virtualbox driver" do |options| network_name: 'HostInterfaceNetworking-vboxnet0', network: 'vboxnet0', ip: '172.28.128.2', + netmask: '255.255.255.0', lower: '172.28.128.3', upper: '172.28.128.254', }]) @@ -65,8 +66,8 @@ shared_examples "a version 4.x virtualbox driver" do |options| it "returns a list with one entry for each server" do expect(subject.read_dhcp_servers).to eq([ - {network_name: 'HostInterfaceNetworking-vboxnet0', network: 'vboxnet0', ip: '172.28.128.2', lower: '172.28.128.3', upper: '172.28.128.254'}, - {network_name: 'HostInterfaceNetworking-vboxnet1', network: 'vboxnet1', ip: '10.0.0.2', lower: '10.0.0.3', upper: '10.0.0.254'}, + {network_name: 'HostInterfaceNetworking-vboxnet0', network: 'vboxnet0', ip: '172.28.128.2', netmask: '255.255.255.0', lower: '172.28.128.3', upper: '172.28.128.254'}, + {network_name: 'HostInterfaceNetworking-vboxnet1', network: 'vboxnet1', ip: '10.0.0.2', netmask: '255.255.255.0', lower: '10.0.0.3', upper: '10.0.0.254'}, ]) end end diff --git a/test/unit/vagrant/action/builtin/handle_box_test.rb b/test/unit/vagrant/action/builtin/handle_box_test.rb index 6b7d85818..17f32563f 100644 --- a/test/unit/vagrant/action/builtin/handle_box_test.rb +++ b/test/unit/vagrant/action/builtin/handle_box_test.rb @@ -106,4 +106,31 @@ describe Vagrant::Action::Builtin::HandleBox do subject.call(env) end end + + context "with a box with a checksum set" do + before do + machine.stub(box: nil) + + machine.config.vm.box = "foo" + machine.config.vm.box_url = "bar" + machine.config.vm.box_download_checksum_type = "sha256" + machine.config.vm.box_download_checksum = "1f42ac2decf0169c4af02b2d8c77143ce35f7ba87d5d844e19bf7cbb34fbe74e" + end + + it "adds a box that doesn't exist and maps checksum options correctly" do + expect(action_runner).to receive(:run).with { |action, opts| + expect(opts[:box_name]).to eq(machine.config.vm.box) + expect(opts[:box_url]).to eq(machine.config.vm.box_url) + expect(opts[:box_provider]).to eq(:dummy) + expect(opts[:box_version]).to eq(machine.config.vm.box_version) + expect(opts[:box_checksum_type]).to eq(machine.config.vm.box_download_checksum_type) + expect(opts[:box_checksum]).to eq(machine.config.vm.box_download_checksum) + true + } + + expect(app).to receive(:call).with(env) + + subject.call(env) + end + end end diff --git a/vagrant.gemspec b/vagrant.gemspec index 3fb550b26..8fa73e7ea 100644 --- a/vagrant.gemspec +++ b/vagrant.gemspec @@ -28,7 +28,8 @@ Gem::Specification.new do |s| s.add_dependency "rb-kqueue", "~> 0.2.0" s.add_dependency "rest-client", ">= 1.6.0", "< 2.0" s.add_dependency "wdm", "~> 0.1.0" - s.add_dependency "winrm", "~> 1.3" + s.add_dependency "winrm", "~> 1.3.0" + s.add_dependency "winrm-fs", "~> 0.1.0" # We lock this down to avoid compilation issues. s.add_dependency "nokogiri", "= 1.6.3.1" diff --git a/website/docs/config.rb b/website/docs/config.rb index 40a858875..132037bb8 100644 --- a/website/docs/config.rb +++ b/website/docs/config.rb @@ -59,13 +59,6 @@ set :markdown, fenced_code_blocks: true configure :build do activate :asset_hash activate :minify_css - activate :minify_html do |html| - html.remove_quotes = false - html.remove_script_attributes = false - html.remove_multi_spaces = false - html.remove_http_protocol = false - html.remove_https_protocol = false - end activate :minify_javascript # Enable cache buster diff --git a/website/docs/source/v2/provisioning/shell.html.md b/website/docs/source/v2/provisioning/shell.html.md index ffc9580c7..e46d0ad52 100644 --- a/website/docs/source/v2/provisioning/shell.html.md +++ b/website/docs/source/v2/provisioning/shell.html.md @@ -136,6 +136,16 @@ that the external path has the proper extension (".bat" or ".ps1"), because Windows uses this to determine what kind fo file it is to execute. If you exclude this extension, it likely won't work. +To run a script already available on the guest you can use an inline script to +invoke the remote script on the guest. + +```ruby +Vagrant.configure("2") do |config| + config.vm.provision "shell", + inline: "/bin/sh /path/to/the/script/already/on/the/guest.sh" +end +``` + ## Script Arguments You can parameterize your scripts as well like any normal shell script. diff --git a/website/docs/source/v2/synced-folders/basic_usage.html.md b/website/docs/source/v2/synced-folders/basic_usage.html.md index 5a1f7dcd5..dc8ee00aa 100644 --- a/website/docs/source/v2/synced-folders/basic_usage.html.md +++ b/website/docs/source/v2/synced-folders/basic_usage.html.md @@ -27,9 +27,10 @@ if it doesn't exist. ## Options -As an optional third parameter to configuring synced folders, you may specify -some options. These options are listed below. More detailed examples of using -some of these options are shown below this section. +You may also specify additional optional parameters when configuring +synced folders. These options are listed below. More detailed examples of using +some of these options are shown below this section, note the owner/group example +supplies two additional options separated by commas. In addition to these options, the specific synced folder type might allow more options. See the documentation for your specific synced folder diff --git a/website/www/config.rb b/website/www/config.rb index d8ea935b6..d30b7bd51 100644 --- a/website/www/config.rb +++ b/website/www/config.rb @@ -33,12 +33,5 @@ end configure :build do activate :asset_hash activate :minify_css - activate :minify_html do |html| - html.remove_quotes = false - html.remove_script_attributes = false - html.remove_multi_spaces = false - html.remove_http_protocol = false - html.remove_https_protocol = false - end activate :minify_javascript end diff --git a/website/www/source/vmware/index.html.erb b/website/www/source/vmware/index.html.erb index 9d1b8b8fb..26d738b07 100644 --- a/website/www/source/vmware/index.html.erb +++ b/website/www/source/vmware/index.html.erb @@ -177,7 +177,7 @@ page_title: "VMware Vagrant Environments" software, which must be purchased separately. If you're buying over 100 licenses, contact sales@hashicorp.com for volume pricing.
- Previous plugin versions may not support the latest VMware products. Please visit the license upgrade center to check if your license requires an upgrade before you upgrade your VMware products. + Previous plugin versions may not support the latest VMware products. Please visit the license upgrade center to check if your license requires an upgrade before you upgrade your VMware products.
For reseller information, click here.