vagrant-unbundled 2.2.0.0 → 2.2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -4
  3. data/CHANGELOG.md +49 -0
  4. data/lib/vagrant/action/builtin/box_check_outdated.rb +1 -0
  5. data/lib/vagrant/action/builtin/config_validate.rb +1 -1
  6. data/lib/vagrant/box.rb +27 -0
  7. data/lib/vagrant/bundler.rb +7 -2
  8. data/lib/vagrant/cli.rb +4 -0
  9. data/lib/vagrant/config/v2/root.rb +6 -2
  10. data/lib/vagrant/plugin/v2/communicator.rb +7 -0
  11. data/lib/vagrant/plugin/v2/trigger.rb +5 -1
  12. data/lib/vagrant/util/network_ip.rb +1 -26
  13. data/lib/vagrant/util/platform.rb +19 -7
  14. data/lib/vagrant/util/powershell.rb +23 -25
  15. data/lib/vagrant/util/ssh.rb +18 -5
  16. data/lib/vagrant/vagrantfile.rb +13 -2
  17. data/plugins/commands/login/plugin.rb +0 -1
  18. data/plugins/commands/validate/command.rb +17 -2
  19. data/plugins/communicators/ssh/communicator.rb +22 -12
  20. data/plugins/communicators/winrm/communicator.rb +5 -1
  21. data/plugins/communicators/winrm/shell.rb +25 -1
  22. data/plugins/guests/debian/cap/change_host_name.rb +66 -10
  23. data/plugins/guests/windows/cap/change_host_name.rb +4 -12
  24. data/plugins/guests/windows/cap/reboot.rb +36 -6
  25. data/plugins/guests/windows/plugin.rb +5 -0
  26. data/plugins/kernel_v2/config/vm.rb +8 -4
  27. data/plugins/providers/docker/action/host_machine_sync_folders.rb +2 -3
  28. data/plugins/providers/hyperv/provider.rb +15 -3
  29. data/plugins/providers/hyperv/scripts/delete_vm.ps1 +3 -0
  30. data/plugins/providers/hyperv/scripts/get_network_config.ps1 +1 -1
  31. data/plugins/providers/hyperv/scripts/set_network_vlan.ps1 +0 -6
  32. data/plugins/providers/hyperv/scripts/utils/VagrantVM/VagrantVM.psm1 +1 -1
  33. data/plugins/providers/virtualbox/action.rb +2 -0
  34. data/plugins/providers/virtualbox/action/network.rb +33 -42
  35. data/plugins/providers/virtualbox/action/set_default_nic_type.rb +69 -0
  36. data/plugins/providers/virtualbox/config.rb +10 -0
  37. data/plugins/providers/virtualbox/driver/meta.rb +1 -0
  38. data/plugins/providers/virtualbox/driver/version_5_0.rb +17 -6
  39. data/plugins/providers/virtualbox/driver/version_5_2.rb +2 -2
  40. data/plugins/providers/virtualbox/driver/version_6_0.rb +105 -0
  41. data/plugins/providers/virtualbox/plugin.rb +1 -0
  42. data/plugins/providers/virtualbox/synced_folder.rb +2 -1
  43. data/plugins/provisioners/docker/cap/linux/docker_configure_vagrant_user.rb +1 -0
  44. data/plugins/provisioners/shell/config.rb +4 -1
  45. data/plugins/provisioners/shell/provisioner.rb +6 -0
  46. data/plugins/synced_folders/smb/synced_folder.rb +18 -5
  47. data/templates/locales/en.yml +19 -3
  48. data/vagrant.gemspec +3 -1
  49. data/version.txt +1 -1
  50. metadata +407 -12
@@ -9,6 +9,9 @@ $ErrorActionPreference = "Stop"
9
9
 
10
10
  try {
11
11
  $VM = Hyper-V\Get-VM -Id $VmId
12
+ if((Get-Command Hyper-V\Set-VM).Parameters["AutomaticCheckpointsEnabled"] -ne $null) {
13
+ Hyper-V\Set-VM -VM $VM -AutomaticCheckpointsEnabled $false -ErrorAction SilentlyContinue
14
+ }
12
15
  Hyper-V\Remove-VM $VM -Force
13
16
  } catch {
14
17
  Write-ErrorMessage "Failed to delete VM: ${PSItem}"
@@ -35,7 +35,7 @@ try {
35
35
  foreach ($macaddr in $macaddresses) {
36
36
  $macaddress = $macaddr.MacAddress -replace '(.{2})(?!$)', '${1}-'
37
37
  $addr = Get-NetNeighbor -LinkLayerAddress $macaddress -ErrorAction SilentlyContinue | select IPAddress
38
- if ($ip_address) {
38
+ if ($addr) {
39
39
  $ip_address = $addr.IPAddress
40
40
  if ($ip_address.Contains(".")) {
41
41
  $ip4_address = $ip_address
@@ -7,12 +7,6 @@ param (
7
7
  [int]$VlanId
8
8
  )
9
9
 
10
- # Include the following modules
11
- $presentDir = Split-Path -parent $PSCommandPath
12
- $modules = @()
13
- $modules += $presentDir + "\utils\write_messages.ps1"
14
- forEach ($module in $modules) { . $module }
15
-
16
10
  try {
17
11
  $vm = Hyper-V\Get-VM -Id $VmId -ErrorAction "stop"
18
12
  Hyper-V\Set-VMNetworkAdapterVlan $vm -Access -Vlanid $VlanId
@@ -85,7 +85,7 @@ function New-VagrantVMVMCX {
85
85
  VhdDestinationPath = Join-Path $DataPath "Virtual Hard Disks";
86
86
  VirtualMachinePath = $DataPath;
87
87
  }
88
- $VMConfig = (Hyper-V\Compare-VM -Copy -GenerateNewID @NewVMConfig)
88
+ $VMConfig = (Hyper-V\Compare-VM -Copy -GenerateNewID @NewVMConfig -ErrorAction SilentlyContinue)
89
89
 
90
90
  # If the config is empty it means the import failed. Attempt to provide
91
91
  # context for failure
@@ -42,6 +42,7 @@ module VagrantPlugins
42
42
  autoload :PrepareForwardedPortCollisionParams, File.expand_path("../action/prepare_forwarded_port_collision_params", __FILE__)
43
43
  autoload :Resume, File.expand_path("../action/resume", __FILE__)
44
44
  autoload :SaneDefaults, File.expand_path("../action/sane_defaults", __FILE__)
45
+ autoload :SetDefaultNICType, File.expand_path("../action/set_default_nic_type", __FILE__)
45
46
  autoload :SetName, File.expand_path("../action/set_name", __FILE__)
46
47
  autoload :SnapshotDelete, File.expand_path("../action/snapshot_delete", __FILE__)
47
48
  autoload :SnapshotRestore, File.expand_path("../action/snapshot_restore", __FILE__)
@@ -71,6 +72,7 @@ module VagrantPlugins
71
72
  b.use SyncedFolderCleanup
72
73
  b.use SyncedFolders
73
74
  b.use PrepareNFSSettings
75
+ b.use SetDefaultNICType
74
76
  b.use ClearNetworkInterfaces
75
77
  b.use Network
76
78
  b.use NetworkFixIPv6
@@ -261,16 +261,26 @@ module VagrantPlugins
261
261
 
262
262
  begin
263
263
  ip = IPAddr.new(options[:ip])
264
- rescue IPAddr::InvalidAddressError => e
265
- raise Vagrant::Errors::NetworkAddressInvalid, :ip => options[:ip], :error_msg => e.message
266
- end
264
+ if ip.ipv4?
265
+ options[:netmask] ||= "255.255.255.0"
266
+ elsif ip.ipv6?
267
+ options[:netmask] ||= 64
267
268
 
268
- if ip.ipv4?
269
- options[:netmask] ||= "255.255.255.0"
269
+ # Append a 6 to the end of the type
270
+ options[:type] = "#{options[:type]}6".to_sym
271
+ else
272
+ raise IPAddr::AddressFamilyError, 'unknown address family'
273
+ end
270
274
 
271
275
  # Calculate our network address for the given IP/netmask
272
- netaddr = network_address(options[:ip], options[:netmask])
276
+ netaddr = IPAddr.new("#{options[:ip]}/#{options[:netmask]}")
277
+ rescue IPAddr::Error => e
278
+ raise Vagrant::Errors::NetworkAddressInvalid,
279
+ address: options[:ip], mask: options[:netmask],
280
+ error: e.message
281
+ end
273
282
 
283
+ if ip.ipv4?
274
284
  # Verify that a host-only network subnet would not collide
275
285
  # with a bridged networking interface.
276
286
  #
@@ -287,44 +297,24 @@ module VagrantPlugins
287
297
  interface_name: interface[:name]
288
298
  end
289
299
  end
290
-
291
- # Split the IP address into its components
292
- ip_parts = netaddr.split(".").map { |i| i.to_i }
293
-
294
- # Calculate the adapter IP, which we assume is the IP ".1" at
295
- # the end usually.
296
- adapter_ip = ip_parts.dup
297
- adapter_ip[3] += 1
298
- options[:adapter_ip] ||= adapter_ip.join(".")
299
- elsif ip.ipv6?
300
- # Default subnet prefix length
301
- options[:netmask] ||= 64
302
-
303
- # Set adapter IP to <prefix>::1
304
- options[:adapter_ip] ||= (ip.mask(options[:netmask].to_i) | 1).to_s
305
-
306
- # Append a 6 to the end of the type
307
- options[:type] = "#{options[:type]}6".to_sym
308
- else
309
- raise "BUG: Unknown IP type: #{ip.inspect}"
310
300
  end
311
301
 
302
+ # Calculate the adapter IP which is the network address with
303
+ # the final bit + 1. Usually it is "x.x.x.1" for IPv4 and
304
+ # "<prefix>::1" for IPv6
305
+ options[:adapter_ip] ||= (netaddr | 1).to_s
306
+
312
307
  dhcp_options = {}
313
308
  if options[:type] == :dhcp
314
- # Calculate the DHCP server IP, which is the network address
315
- # with the final octet + 2. So "172.28.0.0" turns into "172.28.0.2"
316
- dhcp_ip = ip_parts.dup
317
- dhcp_ip[3] += 2
318
- dhcp_options[:dhcp_ip] = options[:dhcp_ip] || dhcp_ip.join(".")
319
-
320
- # Calculate the lower and upper bound for the DHCP server
321
- dhcp_lower = ip_parts.dup
322
- dhcp_lower[3] += 3
323
- dhcp_options[:dhcp_lower] = options[:dhcp_lower] || dhcp_lower.join(".")
324
-
325
- dhcp_upper = ip_parts.dup
326
- dhcp_upper[3] = 254
327
- dhcp_options[:dhcp_upper] = options[:dhcp_upper] || dhcp_upper.join(".")
309
+ # Calculate the DHCP server IP and lower & upper bound
310
+ # Example: for "192.168.22.64/26" network range those are:
311
+ # dhcp_ip: "192.168.22.66",
312
+ # dhcp_lower: "192.168.22.67"
313
+ # dhcp_upper: "192.168.22.126"
314
+ ip_range = netaddr.to_range
315
+ dhcp_options[:dhcp_ip] = options[:dhcp_ip] || (ip_range.first | 2).to_s
316
+ dhcp_options[:dhcp_lower] = options[:dhcp_lower] || (ip_range.first | 3).to_s
317
+ dhcp_options[:dhcp_upper] = options[:dhcp_upper] || (ip_range.last(2).first).to_s
328
318
  end
329
319
 
330
320
  return {
@@ -413,15 +403,16 @@ module VagrantPlugins
413
403
  end
414
404
 
415
405
  def nat_config(options)
416
- return {
406
+ return options.merge(
417
407
  auto_config: false
418
- }
408
+ )
419
409
  end
420
410
 
421
411
  def nat_adapter(config)
422
412
  return {
423
413
  adapter: config[:adapter],
424
414
  type: :nat,
415
+ nic_type: config[:nic_type],
425
416
  }
426
417
  end
427
418
 
@@ -0,0 +1,69 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module ProviderVirtualBox
5
+ module Action
6
+ # This sets the default NIC type used for network adapters created
7
+ # on the guest. Also includes a check of NIC types in use and VirtualBox
8
+ # version to determine if E1000 NIC types are vulnerable.
9
+ #
10
+ # NOTE: Vulnerability was fixed here: https://www.virtualbox.org/changeset/75330/vbox
11
+ class SetDefaultNICType
12
+ # Defines versions of VirtualBox with susceptible implementation
13
+ # of the E1000 devices.
14
+ E1000_SUSCEPTIBLE = Gem::Requirement.new("<= 5.2.22").freeze
15
+
16
+ def initialize(app, env)
17
+ @logger = Log4r::Logger.new("vagrant::plugins::virtualbox::set_default_nic_type")
18
+ @app = app
19
+ end
20
+
21
+ def call(env)
22
+ default_nic_type = env[:machine].provider_config.default_nic_type
23
+
24
+ e1000_in_use = [
25
+ # simple check on default_nic_type
26
+ ->{ default_nic_type.nil? || default_nic_type.to_s.start_with?("8254") },
27
+ # check provider defined adapters
28
+ ->{ env[:machine].provider_config.network_adapters.values.detect{ |_, opts|
29
+ opts[:nic_type].to_s.start_with?("8254") } },
30
+ # finish with inspecting configured networks
31
+ ->{ env[:machine].config.vm.networks.detect{ |_, opts|
32
+ opts.fetch(:virtualbox__nic_type, opts[:nic_type]).to_s.start_with?("8254") } }
33
+ ]
34
+
35
+ # Check if VirtualBox E1000 implementation is vulnerable
36
+ if E1000_SUSCEPTIBLE.satisfied_by?(Gem::Version.new(env[:machine].provider.driver.version))
37
+ @logger.info("Detected VirtualBox version with susceptible E1000 implementation (`#{E1000_SUSCEPTIBLE}`)")
38
+ if e1000_in_use.any?(&:call)
39
+ env[:ui].warn I18n.t("vagrant.actions.vm.set_default_nic_type.e1000_warning")
40
+ end
41
+ end
42
+
43
+ if default_nic_type
44
+ @logger.info("Default NIC type for VirtualBox interfaces `#{default_nic_type}`")
45
+ # Update network adapters defined in provider configuration
46
+ env[:machine].provider_config.network_adapters.each do |slot, args|
47
+ _, opts = args
48
+ if opts && !opts.key?(:nic_type)
49
+ @logger.info("Setting default NIC type (`#{default_nic_type}`) adapter `#{slot}` - `#{args}`")
50
+ opts[:nic_type] = default_nic_type
51
+ end
52
+ end
53
+
54
+ # Update generally defined networks
55
+ env[:machine].config.vm.networks.each do |type, options|
56
+ next if !type.to_s.end_with?("_network")
57
+ if !options.key?(:nic_type) && !options.key?(:virtualbox__nic_type)
58
+ @logger.info("Setting default NIC type (`#{default_nic_type}`) for `#{type}` - `#{options}`")
59
+ options[:virtualbox__nic_type] = default_nic_type
60
+ end
61
+ end
62
+ end
63
+
64
+ @app.call(env)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -19,6 +19,13 @@ module VagrantPlugins
19
19
  # @return [Array]
20
20
  attr_reader :customizations
21
21
 
22
+ # Set the default type of NIC hardware to be used for network
23
+ # devices. By default this is `nil` and VirtualBox's default
24
+ # will be used.
25
+ #
26
+ # @return [String]
27
+ attr_accessor :default_nic_type
28
+
22
29
  # If true, unused network interfaces will automatically be deleted.
23
30
  # This defaults to false because the detection does not work across
24
31
  # multiple users, and because on Windows this operation requires
@@ -68,6 +75,7 @@ module VagrantPlugins
68
75
  @auto_nat_dns_proxy = UNSET_VALUE
69
76
  @check_guest_additions = UNSET_VALUE
70
77
  @customizations = []
78
+ @default_nic_type = UNSET_VALUE
71
79
  @destroy_unused_network_interfaces = UNSET_VALUE
72
80
  @functional_vboxsf = UNSET_VALUE
73
81
  @name = UNSET_VALUE
@@ -158,6 +166,8 @@ module VagrantPlugins
158
166
 
159
167
  # The default name is just nothing, and we default it
160
168
  @name = nil if @name == UNSET_VALUE
169
+
170
+ @default_nic_type = nil if @default_nic_type == UNSET_VALUE
161
171
  end
162
172
 
163
173
  def validate(machine)
@@ -63,6 +63,7 @@ module VagrantPlugins
63
63
  "5.0" => Version_5_0,
64
64
  "5.1" => Version_5_1,
65
65
  "5.2" => Version_5_2,
66
+ "6.0" => Version_6_0,
66
67
  }
67
68
 
68
69
  if @@version.start_with?("4.2.14")
@@ -674,6 +674,8 @@ module VagrantPlugins
674
674
  hostpath]
675
675
  args << "--transient" if folder.key?(:transient) && folder[:transient]
676
676
 
677
+ args << "--automount" if folder.key?(:automount) && folder[:automount]
678
+
677
679
  if folder[:SharedFoldersEnableSymlinksCreate]
678
680
  # Enable symlinks on the shared folder
679
681
  execute("setextradata", @uuid, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/#{folder[:name]}", "1", retryable: true)
@@ -687,12 +689,21 @@ module VagrantPlugins
687
689
  def ssh_port(expected_port)
688
690
  @logger.debug("Searching for SSH port: #{expected_port.inspect}")
689
691
 
690
- # Look for the forwarded port only by comparing the guest port
691
- read_forwarded_ports.each do |_, _, hostport, guestport|
692
- return hostport if guestport == expected_port
693
- end
694
-
695
- nil
692
+ # Look for the forwarded port. Valid based on the guest port, but will do
693
+ # scoring based matching to determine best value when multiple results are
694
+ # available.
695
+ matches = read_forwarded_ports.map do |_, name, hostport, guestport, host_ip|
696
+ next if guestport != expected_port
697
+ match = [0, hostport]
698
+ match[0] += 1 if name == "ssh"
699
+ match[0] += 1 if name.downcase == "ssh"
700
+ match[0] += 1 if host_ip == "127.0.0.1"
701
+ match
702
+ end.compact
703
+
704
+ result = matches.sort_by(&:first).last
705
+
706
+ result.last if result
696
707
  end
697
708
 
698
709
  def resume
@@ -1,10 +1,10 @@
1
- require File.expand_path("../version_5_1", __FILE__)
1
+ require File.expand_path("../version_5_0", __FILE__)
2
2
 
3
3
  module VagrantPlugins
4
4
  module ProviderVirtualBox
5
5
  module Driver
6
6
  # Driver for VirtualBox 5.2.x
7
- class Version_5_2 < Version_5_1
7
+ class Version_5_2 < Version_5_0
8
8
  def initialize(uuid)
9
9
  super
10
10
 
@@ -0,0 +1,105 @@
1
+ require File.expand_path("../version_5_0", __FILE__)
2
+
3
+ module VagrantPlugins
4
+ module ProviderVirtualBox
5
+ module Driver
6
+ # Driver for VirtualBox 6.0.x
7
+ class Version_6_0 < Version_5_0
8
+ def initialize(uuid)
9
+ super
10
+
11
+ @logger = Log4r::Logger.new("vagrant::provider::virtualbox_6_0")
12
+ end
13
+
14
+ def import(ovf)
15
+ ovf = Vagrant::Util::Platform.windows_path(ovf)
16
+
17
+ output = ""
18
+ total = ""
19
+ last = 0
20
+
21
+ # Dry-run the import to get the suggested name and path
22
+ @logger.debug("Doing dry-run import to determine parallel-safe name...")
23
+ output = execute("import", "-n", ovf)
24
+ result = /Suggested VM name "(.+?)"/.match(output)
25
+ if !result
26
+ raise Vagrant::Errors::VirtualBoxNoName, output: output
27
+ end
28
+ suggested_name = result[1].to_s
29
+
30
+ # Append millisecond plus a random to the path in case we're
31
+ # importing the same box elsewhere.
32
+ specified_name = "#{suggested_name}_#{(Time.now.to_f * 1000.0).to_i}_#{rand(100000)}"
33
+ @logger.debug("-- Parallel safe name: #{specified_name}")
34
+
35
+ # Build the specified name param list
36
+ name_params = [
37
+ "--vsys", "0",
38
+ "--vmname", specified_name,
39
+ ]
40
+
41
+ # Target path for disks is no longer a full path. Extract the path for the
42
+ # settings file to determine the base directory which we can then use to
43
+ # build the disk paths
44
+ result = /Suggested VM settings file name "(?<settings_path>.+?)"/.match(output)
45
+ if !result
46
+ @logger.warn("Failed to locate base path for disks. Using current working directory.")
47
+ base_path = "."
48
+ else
49
+ base_path = File.dirname(result[:settings_path])
50
+ end
51
+
52
+ @logger.info("Base path for disk import: #{base_path}")
53
+
54
+ # Extract the disks list and build the disk target params
55
+ disk_params = []
56
+ disks = output.scan(/(\d+): Hard disk image: source image=.+, target path=(.+),/)
57
+ disks.each do |unit_num, path|
58
+ path = File.join(base_path, File.basename(path))
59
+ disk_params << "--vsys"
60
+ disk_params << "0"
61
+ disk_params << "--unit"
62
+ disk_params << unit_num
63
+ disk_params << "--disk"
64
+ if Vagrant::Util::Platform.windows?
65
+ # we use the block form of sub here to ensure that if the specified_name happens to end with a number (which is fairly likely) then
66
+ # we won't end up having the character sequence of a \ followed by a number be interpreted as a back reference. For example, if
67
+ # specified_name were "abc123", then "\\abc123\\".reverse would be "\\321cba\\", and the \3 would be treated as a back reference by the sub
68
+ disk_params << path.reverse.sub("\\#{suggested_name}\\".reverse) { "\\#{specified_name}\\".reverse }.reverse # Replace only last occurrence
69
+ else
70
+ disk_params << path.reverse.sub("/#{suggested_name}/".reverse, "/#{specified_name}/".reverse).reverse # Replace only last occurrence
71
+ end
72
+ end
73
+
74
+ execute("import", ovf , *name_params, *disk_params, retryable: true) do |type, data|
75
+ if type == :stdout
76
+ # Keep track of the stdout so that we can get the VM name
77
+ output << data
78
+ elsif type == :stderr
79
+ # Append the data so we can see the full view
80
+ total << data.gsub("\r", "")
81
+
82
+ # Break up the lines. We can't get the progress until we see an "OK"
83
+ lines = total.split("\n")
84
+ if lines.include?("OK.")
85
+ # The progress of the import will be in the last line. Do a greedy
86
+ # regular expression to find what we're looking for.
87
+ match = /.+(\d{2})%/.match(lines.last)
88
+ if match
89
+ current = match[1].to_i
90
+ if current > last
91
+ last = current
92
+ yield current if block_given?
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ return get_machine_id specified_name
100
+ end
101
+
102
+ end
103
+ end
104
+ end
105
+ end
@@ -58,6 +58,7 @@ module VagrantPlugins
58
58
  autoload :Version_5_0, File.expand_path("../driver/version_5_0", __FILE__)
59
59
  autoload :Version_5_1, File.expand_path("../driver/version_5_1", __FILE__)
60
60
  autoload :Version_5_2, File.expand_path("../driver/version_5_2", __FILE__)
61
+ autoload :Version_6_0, File.expand_path("../driver/version_6_0", __FILE__)
61
62
  end
62
63
 
63
64
  module Model
@@ -124,7 +124,8 @@ module VagrantPlugins
124
124
  name: os_friendly_id(id),
125
125
  hostpath: hostpath.to_s,
126
126
  transient: transient,
127
- SharedFoldersEnableSymlinksCreate: enable_symlink_create
127
+ SharedFoldersEnableSymlinksCreate: enable_symlink_create,
128
+ automount: !!data[:automount]
128
129
  }
129
130
  end
130
131
  end