vagrant-unbundled 2.2.7.0 → 2.2.16.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 (282) hide show
  1. checksums.yaml +4 -4
  2. data/.hashibot.hcl +2 -0
  3. data/CHANGELOG.md +228 -0
  4. data/Gemfile +1 -1
  5. data/README.md +9 -51
  6. data/RELEASE.md +1 -1
  7. data/bin/vagrant +50 -1
  8. data/contrib/README.md +1 -0
  9. data/contrib/sudoers/linux-suse +2 -2
  10. data/contrib/zsh/_vagrant +738 -0
  11. data/contrib/zsh/generate_zsh_completion.rb +165 -0
  12. data/lib/vagrant.rb +28 -5
  13. data/lib/vagrant/action.rb +7 -0
  14. data/lib/vagrant/action/builder.rb +184 -38
  15. data/lib/vagrant/action/builtin/box_add.rb +24 -8
  16. data/lib/vagrant/action/builtin/box_check_outdated.rb +2 -1
  17. data/lib/vagrant/action/builtin/cleanup_disks.rb +56 -0
  18. data/lib/vagrant/action/builtin/cloud_init_setup.rb +122 -0
  19. data/lib/vagrant/action/builtin/cloud_init_wait.rb +30 -0
  20. data/lib/vagrant/action/builtin/delayed.rb +26 -0
  21. data/lib/vagrant/action/builtin/disk.rb +14 -1
  22. data/lib/vagrant/action/builtin/handle_box.rb +3 -1
  23. data/lib/vagrant/action/builtin/handle_forwarded_port_collisions.rb +28 -9
  24. data/lib/vagrant/action/builtin/has_provisioner.rb +36 -0
  25. data/lib/vagrant/action/builtin/mixin_provisioners.rb +1 -0
  26. data/lib/vagrant/action/builtin/mixin_synced_folders.rb +20 -21
  27. data/lib/vagrant/action/builtin/set_hostname.rb +5 -1
  28. data/lib/vagrant/action/builtin/synced_folders.rb +16 -0
  29. data/lib/vagrant/action/builtin/trigger.rb +37 -0
  30. data/lib/vagrant/action/hook.rb +76 -23
  31. data/lib/vagrant/action/runner.rb +12 -27
  32. data/lib/vagrant/action/warden.rb +28 -31
  33. data/lib/vagrant/box.rb +11 -4
  34. data/lib/vagrant/box_collection.rb +1 -1
  35. data/lib/vagrant/bundler.rb +310 -61
  36. data/lib/vagrant/cli.rb +4 -2
  37. data/lib/vagrant/environment.rb +1 -0
  38. data/lib/vagrant/errors.rb +69 -1
  39. data/lib/vagrant/machine.rb +64 -11
  40. data/lib/vagrant/machine_index.rb +28 -1
  41. data/lib/vagrant/patches/net-ssh.rb +186 -0
  42. data/lib/vagrant/plugin/manager.rb +45 -16
  43. data/lib/vagrant/plugin/v2/command.rb +7 -2
  44. data/lib/vagrant/plugin/v2/components.rb +6 -0
  45. data/lib/vagrant/plugin/v2/manager.rb +67 -0
  46. data/lib/vagrant/plugin/v2/plugin.rb +13 -0
  47. data/lib/vagrant/plugin/v2/synced_folder.rb +50 -0
  48. data/lib/vagrant/plugin/v2/trigger.rb +64 -25
  49. data/lib/vagrant/shared_helpers.rb +36 -0
  50. data/lib/vagrant/ui.rb +43 -2
  51. data/lib/vagrant/util.rb +2 -0
  52. data/lib/vagrant/util/ansi_escape_code_remover.rb +1 -1
  53. data/lib/vagrant/util/caps.rb +48 -0
  54. data/lib/vagrant/util/credential_scrubber.rb +1 -1
  55. data/lib/vagrant/util/curl_helper.rb +12 -8
  56. data/lib/vagrant/util/directory.rb +19 -0
  57. data/lib/vagrant/util/downloader.rb +10 -5
  58. data/lib/vagrant/util/guest_hosts.rb +68 -0
  59. data/lib/vagrant/util/guest_inspection.rb +9 -1
  60. data/lib/vagrant/util/install_cli_autocomplete.rb +118 -0
  61. data/lib/vagrant/util/io.rb +7 -27
  62. data/lib/vagrant/util/ipv4_interfaces.rb +15 -0
  63. data/lib/vagrant/util/is_port_open.rb +8 -19
  64. data/lib/vagrant/util/map_command_options.rb +33 -0
  65. data/lib/vagrant/util/mime.rb +92 -0
  66. data/lib/vagrant/util/network_ip.rb +11 -1
  67. data/lib/vagrant/util/numeric.rb +28 -0
  68. data/lib/vagrant/util/platform.rb +10 -2
  69. data/lib/vagrant/util/powershell.rb +31 -15
  70. data/lib/vagrant/util/subprocess.rb +9 -1
  71. data/lib/vagrant/util/template_renderer.rb +2 -2
  72. data/lib/vagrant/util/uploader.rb +7 -4
  73. data/lib/vagrant/vagrantfile.rb +2 -2
  74. data/plugins/commands/autocomplete/command/install.rb +49 -0
  75. data/plugins/commands/autocomplete/command/root.rb +64 -0
  76. data/plugins/commands/autocomplete/plugin.rb +18 -0
  77. data/plugins/commands/cap/command.rb +5 -1
  78. data/plugins/commands/cloud/auth/login.rb +20 -23
  79. data/plugins/commands/cloud/auth/logout.rb +2 -10
  80. data/plugins/commands/cloud/auth/middleware/add_authentication.rb +60 -31
  81. data/plugins/commands/cloud/auth/middleware/add_downloader_authentication.rb +64 -0
  82. data/plugins/commands/cloud/auth/whoami.rb +18 -20
  83. data/plugins/commands/cloud/box/create.rb +33 -29
  84. data/plugins/commands/cloud/box/delete.rb +30 -24
  85. data/plugins/commands/cloud/box/show.rb +41 -31
  86. data/plugins/commands/cloud/box/update.rb +34 -26
  87. data/plugins/commands/cloud/client/client.rb +55 -79
  88. data/plugins/commands/cloud/list.rb +3 -4
  89. data/plugins/commands/cloud/locales/en.yml +15 -11
  90. data/plugins/commands/cloud/plugin.rb +10 -0
  91. data/plugins/commands/cloud/provider/create.rb +38 -28
  92. data/plugins/commands/cloud/provider/delete.rb +39 -29
  93. data/plugins/commands/cloud/provider/update.rb +37 -28
  94. data/plugins/commands/cloud/provider/upload.rb +53 -33
  95. data/plugins/commands/cloud/publish.rb +193 -106
  96. data/plugins/commands/cloud/search.rb +34 -21
  97. data/plugins/commands/cloud/util.rb +273 -161
  98. data/plugins/commands/cloud/version/create.rb +33 -28
  99. data/plugins/commands/cloud/version/delete.rb +35 -28
  100. data/plugins/commands/cloud/version/release.rb +35 -29
  101. data/plugins/commands/cloud/version/revoke.rb +36 -29
  102. data/plugins/commands/cloud/version/update.rb +29 -25
  103. data/plugins/commands/destroy/command.rb +7 -7
  104. data/plugins/commands/login/plugin.rb +0 -13
  105. data/plugins/commands/ssh_config/command.rb +1 -1
  106. data/plugins/communicators/ssh/communicator.rb +25 -24
  107. data/plugins/communicators/winrm/config.rb +1 -1
  108. data/plugins/communicators/winrm/helper.rb +1 -1
  109. data/plugins/communicators/winrm/shell.rb +1 -1
  110. data/plugins/communicators/winssh/communicator.rb +126 -38
  111. data/plugins/communicators/winssh/config.rb +3 -7
  112. data/plugins/guests/alpine/cap/change_host_name.rb +10 -11
  113. data/plugins/guests/alpine/cap/configure_networks.rb +1 -1
  114. data/plugins/guests/alt/cap/change_host_name.rb +40 -53
  115. data/plugins/guests/arch/cap/change_host_name.rb +5 -14
  116. data/plugins/guests/arch/cap/configure_networks.rb +27 -10
  117. data/plugins/guests/arch/cap/smb.rb +1 -1
  118. data/plugins/guests/atomic/cap/change_host_name.rb +5 -14
  119. data/plugins/guests/centos/cap/flavor.rb +24 -0
  120. data/plugins/guests/centos/guest.rb +9 -0
  121. data/plugins/guests/centos/plugin.rb +20 -0
  122. data/plugins/guests/darwin/cap/change_host_name.rb +10 -6
  123. data/plugins/guests/darwin/cap/darwin_version.rb +40 -0
  124. data/plugins/guests/darwin/cap/mount_smb_shared_folder.rb +1 -1
  125. data/plugins/guests/darwin/cap/mount_vmware_shared_folder.rb +33 -10
  126. data/plugins/guests/darwin/plugin.rb +15 -0
  127. data/plugins/guests/debian/cap/change_host_name.rb +12 -11
  128. data/plugins/guests/debian/cap/configure_networks.rb +14 -6
  129. data/plugins/guests/esxi/cap/public_key.rb +3 -1
  130. data/plugins/guests/fedora/guest.rb +4 -4
  131. data/plugins/guests/freebsd/cap/change_host_name.rb +10 -6
  132. data/plugins/guests/gentoo/cap/change_host_name.rb +14 -22
  133. data/plugins/guests/haiku/cap/rsync.rb +19 -0
  134. data/plugins/guests/haiku/plugin.rb +15 -0
  135. data/plugins/guests/linux/cap/change_host_name.rb +46 -0
  136. data/plugins/guests/linux/cap/halt.rb +9 -1
  137. data/plugins/guests/linux/cap/mount_smb_shared_folder.rb +25 -34
  138. data/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb +10 -11
  139. data/plugins/guests/linux/cap/persist_mount_shared_folder.rb +74 -0
  140. data/plugins/guests/linux/cap/reboot.rb +36 -7
  141. data/plugins/guests/linux/plugin.rb +10 -0
  142. data/plugins/guests/omnios/cap/change_host_name.rb +10 -16
  143. data/plugins/guests/openbsd/cap/change_host_name.rb +10 -6
  144. data/plugins/guests/openwrt/cap/change_host_name.rb +19 -0
  145. data/plugins/guests/openwrt/cap/halt.rb +16 -0
  146. data/plugins/guests/openwrt/cap/insert_public_key.rb +20 -0
  147. data/plugins/guests/openwrt/cap/remove_public_key.rb +22 -0
  148. data/plugins/guests/openwrt/cap/rsync.rb +35 -0
  149. data/plugins/guests/openwrt/guest.rb +23 -0
  150. data/plugins/guests/openwrt/plugin.rb +61 -0
  151. data/plugins/guests/photon/cap/change_host_name.rb +9 -15
  152. data/plugins/guests/pld/cap/change_host_name.rb +11 -17
  153. data/plugins/guests/redhat/cap/change_host_name.rb +14 -5
  154. data/plugins/guests/redhat/cap/flavor.rb +3 -1
  155. data/plugins/guests/redhat/cap/smb.rb +20 -0
  156. data/plugins/guests/redhat/plugin.rb +5 -0
  157. data/plugins/guests/slackware/cap/change_host_name.rb +11 -17
  158. data/plugins/guests/solaris11/plugin.rb +5 -0
  159. data/plugins/guests/suse/cap/change_host_name.rb +31 -9
  160. data/plugins/guests/windows/cap/public_key.rb +3 -3
  161. data/plugins/guests/windows/cap/reboot.rb +10 -5
  162. data/plugins/hosts/darwin/cap/fs_iso.rb +49 -0
  163. data/plugins/hosts/darwin/plugin.rb +10 -0
  164. data/plugins/hosts/linux/cap/fs_iso.rb +49 -0
  165. data/plugins/hosts/linux/cap/nfs.rb +1 -0
  166. data/plugins/hosts/linux/cap/rdp.rb +1 -1
  167. data/plugins/hosts/linux/plugin.rb +10 -0
  168. data/plugins/hosts/windows/cap/fs_iso.rb +48 -0
  169. data/plugins/hosts/windows/cap/rdp.rb +1 -1
  170. data/plugins/hosts/windows/plugin.rb +15 -0
  171. data/plugins/kernel_v2/config/cloud_init.rb +133 -0
  172. data/plugins/kernel_v2/config/disk.rb +67 -14
  173. data/plugins/kernel_v2/config/ssh_connect.rb +24 -0
  174. data/plugins/kernel_v2/config/vm.rb +155 -21
  175. data/plugins/kernel_v2/config/vm_provisioner.rb +13 -2
  176. data/plugins/kernel_v2/config/vm_trigger.rb +6 -5
  177. data/plugins/providers/docker/action.rb +8 -17
  178. data/plugins/providers/docker/action/forwarded_ports.rb +2 -0
  179. data/plugins/providers/docker/action/prepare_forwarded_port_collision_params.rb +61 -0
  180. data/plugins/providers/docker/cap/has_communicator.rb +11 -0
  181. data/plugins/providers/docker/communicator.rb +1 -1
  182. data/plugins/providers/docker/driver.rb +58 -7
  183. data/plugins/providers/docker/plugin.rb +5 -0
  184. data/plugins/providers/hyperv/action.rb +3 -1
  185. data/plugins/providers/hyperv/action/configure.rb +8 -0
  186. data/plugins/providers/hyperv/action/export.rb +4 -2
  187. data/plugins/providers/hyperv/cap/cleanup_disks.rb +54 -0
  188. data/plugins/providers/hyperv/cap/configure_disks.rb +200 -0
  189. data/plugins/providers/hyperv/cap/validate_disk_ext.rb +34 -0
  190. data/plugins/providers/hyperv/config.rb +5 -0
  191. data/plugins/providers/hyperv/driver.rb +90 -9
  192. data/plugins/providers/hyperv/plugin.rb +25 -0
  193. data/plugins/providers/hyperv/scripts/attach_disk_drive.ps1 +28 -0
  194. data/plugins/providers/hyperv/scripts/dismount_vhd.ps1 +13 -0
  195. data/plugins/providers/hyperv/scripts/get_vhd.ps1 +16 -0
  196. data/plugins/providers/hyperv/scripts/get_vm_status.ps1 +1 -1
  197. data/plugins/providers/hyperv/scripts/list_hdds.ps1 +17 -0
  198. data/plugins/providers/hyperv/scripts/new_vhd.ps1 +31 -0
  199. data/plugins/providers/hyperv/scripts/remove_disk_drive.ps1 +25 -0
  200. data/plugins/providers/hyperv/scripts/resize_disk_drive.ps1 +18 -0
  201. data/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 +24 -0
  202. data/plugins/providers/hyperv/scripts/set_vm_integration_services.ps1 +3 -3
  203. data/plugins/providers/hyperv/scripts/utils/VagrantVM/VagrantVM.psm1 +14 -6
  204. data/plugins/providers/virtualbox/action.rb +13 -1
  205. data/plugins/providers/virtualbox/action/export.rb +4 -2
  206. data/plugins/providers/virtualbox/action/forward_ports.rb +2 -2
  207. data/plugins/providers/virtualbox/action/import.rb +8 -4
  208. data/plugins/providers/virtualbox/action/network.rb +12 -5
  209. data/plugins/providers/virtualbox/action/prepare_clone_snapshot.rb +4 -2
  210. data/plugins/providers/virtualbox/action/snapshot_delete.rb +4 -2
  211. data/plugins/providers/virtualbox/action/snapshot_restore.rb +4 -2
  212. data/plugins/providers/virtualbox/cap/cleanup_disks.rb +85 -0
  213. data/plugins/providers/virtualbox/cap/configure_disks.rb +440 -0
  214. data/plugins/providers/virtualbox/cap/mount_options.rb +40 -0
  215. data/plugins/providers/virtualbox/cap/validate_disk_ext.rb +34 -0
  216. data/plugins/providers/virtualbox/driver/base.rb +15 -0
  217. data/plugins/providers/virtualbox/driver/meta.rb +16 -2
  218. data/plugins/providers/virtualbox/driver/version_5_0.rb +217 -2
  219. data/plugins/providers/virtualbox/driver/version_6_1.rb +23 -0
  220. data/plugins/providers/virtualbox/model/storage_controller.rb +135 -0
  221. data/plugins/providers/virtualbox/model/storage_controller_array.rb +98 -0
  222. data/plugins/providers/virtualbox/plugin.rb +42 -0
  223. data/plugins/providers/virtualbox/provider.rb +2 -1
  224. data/plugins/providers/virtualbox/synced_folder.rb +1 -0
  225. data/plugins/provisioners/ansible/cap/guest/alpine/ansible_install.rb +44 -0
  226. data/plugins/provisioners/ansible/cap/guest/freebsd/ansible_install.rb +1 -1
  227. data/plugins/provisioners/ansible/plugin.rb +5 -0
  228. data/plugins/provisioners/ansible/provisioner/base.rb +1 -1
  229. data/plugins/provisioners/container/client.rb +203 -0
  230. data/plugins/provisioners/container/config.rb +83 -0
  231. data/plugins/provisioners/container/installer.rb +13 -0
  232. data/plugins/provisioners/container/plugin.rb +23 -0
  233. data/plugins/provisioners/container/provisioner.rb +28 -0
  234. data/plugins/provisioners/docker/cap/{redhat → centos}/docker_install.rb +10 -7
  235. data/plugins/provisioners/docker/cap/centos/docker_start_service.rb +24 -0
  236. data/plugins/provisioners/docker/client.rb +4 -175
  237. data/plugins/provisioners/docker/config.rb +2 -72
  238. data/plugins/provisioners/docker/installer.rb +3 -5
  239. data/plugins/provisioners/docker/plugin.rb +6 -6
  240. data/plugins/provisioners/docker/provisioner.rb +4 -10
  241. data/plugins/provisioners/podman/cap/centos/podman_install.rb +35 -0
  242. data/plugins/provisioners/podman/cap/linux/podman_installed.rb +13 -0
  243. data/plugins/provisioners/podman/cap/redhat/podman_install.rb +26 -0
  244. data/plugins/provisioners/podman/client.rb +12 -0
  245. data/plugins/provisioners/podman/config.rb +28 -0
  246. data/plugins/provisioners/podman/installer.rb +33 -0
  247. data/plugins/provisioners/podman/plugin.rb +38 -0
  248. data/plugins/provisioners/podman/provisioner.rb +52 -0
  249. data/plugins/provisioners/salt/bootstrap-salt.sh +7 -4
  250. data/plugins/provisioners/salt/provisioner.rb +4 -0
  251. data/plugins/provisioners/shell/config.rb +1 -6
  252. data/plugins/provisioners/shell/provisioner.rb +61 -26
  253. data/plugins/synced_folders/nfs/synced_folder.rb +3 -1
  254. data/plugins/synced_folders/smb/cap/default_fstab_modification.rb +11 -0
  255. data/plugins/synced_folders/smb/cap/mount_options.rb +56 -0
  256. data/plugins/synced_folders/smb/plugin.rb +20 -0
  257. data/plugins/synced_folders/smb/synced_folder.rb +2 -2
  258. data/plugins/synced_folders/unix_mount_helpers.rb +14 -0
  259. data/scripts/website_push_www.sh +1 -1
  260. data/templates/commands/init/Vagrantfile.min.erb +3 -0
  261. data/templates/guests/arch/{network_dhcp.erb → default_network/network_dhcp.erb} +0 -0
  262. data/templates/guests/arch/{network_static.erb → default_network/network_static.erb} +0 -0
  263. data/templates/guests/arch/{network_static6.erb → default_network/network_static6.erb} +0 -0
  264. data/templates/guests/arch/systemd_networkd/network_dhcp.erb +6 -0
  265. data/templates/guests/arch/systemd_networkd/network_static.erb +9 -0
  266. data/templates/guests/arch/systemd_networkd/network_static6.erb +9 -0
  267. data/templates/guests/linux/etc_fstab.erb +6 -0
  268. data/templates/guests/nixos/network.erb +5 -6
  269. data/templates/locales/en.yml +221 -5
  270. data/templates/locales/providers_docker.yml +4 -0
  271. data/templates/nfs/exports_darwin.erb +1 -1
  272. data/vagrant.gemspec +14 -20
  273. data/version.txt +1 -1
  274. metadata +5092 -8978
  275. data/lib/vagrant/action/builtin/after_trigger.rb +0 -31
  276. data/lib/vagrant/action/builtin/before_trigger.rb +0 -28
  277. data/plugins/commands/login/client.rb +0 -253
  278. data/plugins/commands/login/command.rb +0 -137
  279. data/plugins/commands/login/errors.rb +0 -24
  280. data/plugins/commands/login/locales/en.yml +0 -49
  281. data/plugins/provisioners/docker/cap/redhat/docker_start_service.rb +0 -16
  282. data/scripts/website_push_docs.sh +0 -40
@@ -25,6 +25,7 @@ module Vagrant
25
25
  def initialize(app, env)
26
26
  @app = app
27
27
  @logger = Log4r::Logger.new("vagrant::action::builtin::box_add")
28
+ @parser = URI::RFC2396_Parser.new
28
29
  end
29
30
 
30
31
  def call(env)
@@ -44,7 +45,7 @@ module Vagrant
44
45
  u = u.gsub("\\", "/")
45
46
  if Util::Platform.windows? && u =~ /^[a-z]:/i
46
47
  # On Windows, we need to be careful about drive letters
47
- u = "file:///#{URI.escape(u)}"
48
+ u = "file:///#{@parser.escape(u)}"
48
49
  end
49
50
 
50
51
  if u =~ /^[a-z0-9]+:.*$/i && !u.start_with?("file://")
@@ -53,9 +54,9 @@ module Vagrant
53
54
  end
54
55
 
55
56
  # Expand the path and try to use that, if possible
56
- p = File.expand_path(URI.unescape(u.gsub(/^file:\/\//, "")))
57
+ p = File.expand_path(@parser.unescape(u.gsub(/^file:\/\//, "")))
57
58
  p = Util::Platform.cygwin_windows_path(p)
58
- next "file://#{URI.escape(p.gsub("\\", "/"))}" if File.file?(p)
59
+ next "file://#{@parser.escape(p.gsub("\\", "/"))}" if File.file?(p)
59
60
 
60
61
  u
61
62
  end
@@ -107,6 +108,14 @@ module Vagrant
107
108
  end
108
109
  end
109
110
 
111
+ is_error = is_metadata_results.find do |b|
112
+ b.is_a?(Errors::DownloaderError)
113
+ end
114
+ if is_error
115
+ raise Errors::BoxMetadataDownloadError,
116
+ message: is_error.extra_data[:message]
117
+ end
118
+
110
119
  is_metadata = is_metadata_results.any? { |b| b === true }
111
120
  if is_metadata && url.length > 1
112
121
  raise Errors::BoxAddMetadataMultiURL,
@@ -117,7 +126,7 @@ module Vagrant
117
126
  url = [url.first, authed_urls.first]
118
127
  add_from_metadata(url, env, expanded)
119
128
  else
120
- add_direct(url, env)
129
+ add_direct(authed_urls, env)
121
130
  end
122
131
 
123
132
  @app.call(env)
@@ -433,14 +442,18 @@ module Vagrant
433
442
  downloader_options[:headers] = ["Accept: application/json"] if opts[:json]
434
443
  downloader_options[:ui] = env[:ui] if opts[:ui]
435
444
  downloader_options[:location_trusted] = env[:box_download_location_trusted]
445
+ downloader_options[:box_extra_download_options] = env[:box_extra_download_options]
436
446
 
437
- Util::Downloader.new(url, temp_path, downloader_options)
447
+ d = Util::Downloader.new(url, temp_path, downloader_options)
448
+ env[:hook].call(:authenticate_box_downloader, downloader: d)
449
+ d
438
450
  end
439
451
 
440
452
  def download(url, env, **opts)
441
453
  opts[:ui] = true if !opts.key?(:ui)
442
454
 
443
455
  d = downloader(url, env, **opts)
456
+ env[:hook].call(:authenticate_box_downloader, downloader: d)
444
457
 
445
458
  # Download the box to a temporary path. We store the temporary
446
459
  # path as an instance variable so that the `#recover` method can
@@ -484,6 +497,7 @@ module Vagrant
484
497
  # @return [Boolean] true if metadata
485
498
  def metadata_url?(url, env)
486
499
  d = downloader(url, env, json: true, ui: false)
500
+ env[:hook].call(:authenticate_box_downloader, downloader: d)
487
501
 
488
502
  # If we're downloading a file, cURL just returns no
489
503
  # content-type (makes sense), so we just test if it is JSON
@@ -494,7 +508,7 @@ module Vagrant
494
508
  url ||= uri.opaque
495
509
  #7570 Strip leading slash left in front of drive letter by uri.path
496
510
  Util::Platform.windows? && url.gsub!(/^\/([a-zA-Z]:)/, '\1')
497
- url = URI.unescape(url)
511
+ url = @parser.unescape(url)
498
512
 
499
513
  begin
500
514
  File.open(url, "r") do |f|
@@ -532,11 +546,13 @@ module Vagrant
532
546
  !!(match.last.chomp =~ /application\/json/)
533
547
  end
534
548
 
535
- def validate_checksum(checksum_type, checksum, path)
549
+ def validate_checksum(checksum_type, _checksum, path)
550
+ checksum = _checksum.strip()
536
551
  @logger.info("Validating checksum with #{checksum_type}")
537
552
  @logger.info("Expected checksum: #{checksum}")
538
553
 
539
- actual = FileChecksum.new(path, checksum_type).checksum
554
+ _actual = FileChecksum.new(path, checksum_type).checksum
555
+ actual = _actual.strip()
540
556
  @logger.info("Actual checksum: #{actual}")
541
557
  if actual.casecmp(checksum) != 0
542
558
  raise Errors::BoxChecksumMismatch,
@@ -46,7 +46,8 @@ module Vagrant
46
46
  client_cert: env[:client_cert] ||
47
47
  machine.config.vm.box_download_client_cert,
48
48
  insecure: !env[:insecure].nil? ?
49
- env[:insecure] : machine.config.vm.box_download_insecure
49
+ env[:insecure] : machine.config.vm.box_download_insecure,
50
+ box_extra_download_options: env[:box_extra_download_options] || machine.config.vm.box_extra_download_options,
50
51
  }
51
52
 
52
53
  env[:ui].output(I18n.t(
@@ -0,0 +1,56 @@
1
+ require "json"
2
+
3
+ module Vagrant
4
+ module Action
5
+ module Builtin
6
+ class CleanupDisks
7
+ # Removes any attached disks no longer defined in a Vagrantfile config
8
+ def initialize(app, env)
9
+ @app = app
10
+ @logger = Log4r::Logger.new("vagrant::action::builtin::disk")
11
+ end
12
+
13
+ def call(env)
14
+ machine = env[:machine]
15
+ defined_disks = get_disks(machine, env)
16
+
17
+ # Call into providers machine implementation for disk management
18
+ disk_meta_file = read_disk_metadata(machine)
19
+
20
+ if !disk_meta_file.empty?
21
+ if machine.provider.capability?(:cleanup_disks)
22
+ machine.provider.capability(:cleanup_disks, defined_disks, disk_meta_file)
23
+ else
24
+ env[:ui].warn(I18n.t("vagrant.actions.disk.provider_unsupported",
25
+ provider: machine.provider_name))
26
+ end
27
+ end
28
+
29
+ # Continue On
30
+ @app.call(env)
31
+ end
32
+
33
+ def read_disk_metadata(machine)
34
+ meta_file = machine.data_dir.join("disk_meta")
35
+ if File.file?(meta_file)
36
+ disk_meta = JSON.parse(meta_file.read)
37
+ else
38
+ @logger.info("No previous disk_meta file defined for guest #{machine.name}")
39
+ disk_meta = {}
40
+ end
41
+
42
+ return disk_meta
43
+ end
44
+
45
+ def get_disks(machine, env)
46
+ return @_disks if @_disks
47
+
48
+ @_disks = []
49
+ @_disks = machine.config.vm.disks
50
+
51
+ @_disks
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,122 @@
1
+ require 'vagrant/util/mime'
2
+ require 'tmpdir'
3
+
4
+ module Vagrant
5
+ module Action
6
+ module Builtin
7
+ class CloudInitSetup
8
+ TEMP_PREFIX = "vagrant-cloud-init-iso-temp-".freeze
9
+
10
+ def initialize(app, env)
11
+ @app = app
12
+ @logger = Log4r::Logger.new("vagrant::action::builtin::cloudinit::setup")
13
+ end
14
+
15
+ def call(env)
16
+ machine = env[:machine]
17
+
18
+ user_data_configs = machine.config.vm.cloud_init_configs
19
+ .select { |c| c.type == :user_data }
20
+
21
+ if !user_data_configs.empty?
22
+ user_data = setup_user_data(machine, env, user_data_configs)
23
+ meta_data = { "instance-id" => "i-#{machine.id.split('-').join}" }
24
+
25
+ write_cfg_iso(machine, env, user_data, meta_data)
26
+ end
27
+
28
+ # Continue On
29
+ @app.call(env)
30
+ end
31
+
32
+ # @param [Vagrant::Machine] machine
33
+ # @param [Vagrant::Environment] env
34
+ # @param [Array<#VagrantPlugins::Kernel_V2::VagrantConfigCloudInit>] user_data_cfgs
35
+ # @return [Vagrant::Util::Mime::MultiPart] user_data
36
+ def setup_user_data(machine, env, user_data_cfgs)
37
+ machine.ui.info(I18n.t("vagrant.actions.vm.cloud_init_user_data_setup"))
38
+
39
+ text_cfgs = user_data_cfgs.map { |cfg| read_text_cfg(machine, cfg) }
40
+
41
+ user_data = generate_cfg_msg(machine, text_cfgs)
42
+ user_data
43
+ end
44
+
45
+ # Reads an individual cloud_init config and stores its contents and the
46
+ # content_type as a MIME text
47
+ #
48
+ # @param [Vagrant::Machine] machine
49
+ # @param [VagrantPlugins::Kernel_V2::VagrantConfigCloudInit] cfg
50
+ # @return [Vagrant::Util::Mime::Entity] text_msg
51
+ def read_text_cfg(machine, cfg)
52
+ if cfg.path
53
+ text = File.read(Pathname.new(cfg.path).expand_path(machine.env.root_path))
54
+ else
55
+ text = cfg.inline
56
+ end
57
+
58
+ text_msg = Vagrant::Util::Mime::Entity.new(text, cfg.content_type)
59
+ text_msg.disposition = "attachment; filename=\"#{File.basename(cfg.content_disposition_filename).gsub('"', '\"')}\"" if cfg.content_disposition_filename
60
+ text_msg
61
+ end
62
+
63
+ # Combines all known cloud_init configs into a multipart mixed MIME text
64
+ # message
65
+ #
66
+ # @param [Vagrant::Machine] machine
67
+ # @param [Array<Vagrant::Util::Mime::Entity>] text_msg - One or more text configs
68
+ # @return [Vagrant::Util::Mime::Multipart] msg
69
+ def generate_cfg_msg(machine, text_cfgs)
70
+ msg = Vagrant::Util::Mime::Multipart.new
71
+ msg.headers["MIME-Version"] = "1.0"
72
+
73
+ text_cfgs.each do |c|
74
+ msg.add(c)
75
+ end
76
+
77
+ msg
78
+ end
79
+
80
+ # Writes the contents of the guests cloud_init config to a tmp
81
+ # dir and passes that source directory along to the host cap to be
82
+ # written to an iso
83
+ #
84
+ # @param [Vagrant::Machine] machine
85
+ # @param [Vagrant::Util::Mime::Multipart] user_data
86
+ # @param [Hash] meta_data
87
+ def write_cfg_iso(machine, env, user_data, meta_data)
88
+ iso_path = nil
89
+
90
+ if env[:env].host.capability?(:create_iso)
91
+ begin
92
+ source_dir = Pathname.new(Dir.mktmpdir(TEMP_PREFIX))
93
+ File.open("#{source_dir}/user-data", 'w') { |file| file.write(user_data.to_s) }
94
+
95
+ File.open("#{source_dir}/meta-data", 'w') { |file| file.write(meta_data.to_yaml) }
96
+
97
+ iso_path = env[:env].host.capability(:create_iso,
98
+ source_dir, volume_id: "cidata")
99
+ attach_disk_config(machine, env, iso_path.to_path)
100
+ ensure
101
+ FileUtils.remove_entry(source_dir)
102
+ end
103
+ else
104
+ raise Errors::CreateIsoHostCapNotFound
105
+ end
106
+ end
107
+
108
+ # Adds a new :dvd disk config with the given iso_path to be attached
109
+ # to the guest later
110
+ #
111
+ # @param [Vagrant::Machine] machine
112
+ # @param [Vagrant::Environment] env
113
+ # @param [String] iso_path
114
+ def attach_disk_config(machine, env, iso_path)
115
+ @logger.info("Adding cloud_init iso '#{iso_path}' to disk config")
116
+ machine.config.vm.disk :dvd, file: iso_path, name: "vagrant-cloud_init-disk"
117
+ machine.config.vm.disks.each { |d| d.finalize! if d.type == :dvd && d.file == iso_path }
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,30 @@
1
+ module Vagrant
2
+ module Action
3
+ module Builtin
4
+ class CloudInitWait
5
+
6
+ def initialize(app, env)
7
+ @app = app
8
+ @logger = Log4r::Logger.new("vagrant::action::builtin::cloudinitwait")
9
+ end
10
+
11
+ def call(env)
12
+ machine = env[:machine]
13
+ cloud_init_wait_cmd = "cloud-init status --wait"
14
+ if !machine.config.vm.cloud_init_configs.empty?
15
+ if machine.communicate.test("command -v cloud-init")
16
+ env[:ui].output(I18n.t("vagrant.cloud_init_waiting"))
17
+ result = machine.communicate.sudo(cloud_init_wait_cmd, error_check: false)
18
+ if result != 0
19
+ raise Vagrant::Errors::CloudInitCommandFailed, cmd: cloud_init_wait_cmd, guest_name: machine.name
20
+ end
21
+ else
22
+ raise Vagrant::Errors::CloudInitNotFound, guest_name: machine.name
23
+ end
24
+ end
25
+ @app.call(env)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ module Vagrant
2
+ module Action
3
+ module Builtin
4
+ # This class is used to delay execution until the end of
5
+ # a configured stack
6
+ class Delayed
7
+ # @param [Object] callable The object to call (must respond to #call)
8
+ def initialize(app, env, callable)
9
+ if !callable.respond_to?(:call)
10
+ raise TypeError, "Callable argument is expected to respond to `#call`"
11
+ end
12
+ @app = app
13
+ @env = env
14
+ @callable = callable
15
+ end
16
+
17
+ def call(env)
18
+ # Allow the rest of the call stack to execute
19
+ @app.call(env)
20
+ # Now call our delayed stack
21
+ @callable.call(env)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,3 +1,5 @@
1
+ require "json"
2
+
1
3
  module Vagrant
2
4
  module Action
3
5
  module Builtin
@@ -12,19 +14,30 @@ module Vagrant
12
14
  defined_disks = get_disks(machine, env)
13
15
 
14
16
  # Call into providers machine implementation for disk management
17
+ configured_disks = {}
15
18
  if !defined_disks.empty?
16
19
  if machine.provider.capability?(:configure_disks)
17
- machine.provider.capability(:configure_disks, defined_disks)
20
+ configured_disks = machine.provider.capability(:configure_disks, defined_disks)
18
21
  else
19
22
  env[:ui].warn(I18n.t("vagrant.actions.disk.provider_unsupported",
20
23
  provider: machine.provider_name))
21
24
  end
22
25
  end
23
26
 
27
+ write_disk_metadata(machine, configured_disks) unless configured_disks.empty?
28
+
24
29
  # Continue On
25
30
  @app.call(env)
26
31
  end
27
32
 
33
+ def write_disk_metadata(machine, current_disks)
34
+ meta_file = machine.data_dir.join("disk_meta")
35
+ @logger.debug("Writing disk metadata file to #{meta_file}")
36
+ File.open(meta_file.to_s, "w+") do |file|
37
+ file.write(JSON.dump(current_disks))
38
+ end
39
+ end
40
+
28
41
  def get_disks(machine, env)
29
42
  return @_disks if @_disks
30
43
 
@@ -20,7 +20,7 @@ module Vagrant
20
20
  def call(env)
21
21
  machine = env[:machine]
22
22
 
23
- if !machine.config.vm.box
23
+ if !machine.config.vm.box || machine.config.vm.box.to_s.empty?
24
24
  @logger.info("Skipping HandleBox because no box is set")
25
25
  return @app.call(env)
26
26
  end
@@ -67,6 +67,7 @@ module Vagrant
67
67
  box_download_checksum_type = machine.config.vm.box_download_checksum_type
68
68
  box_download_checksum = machine.config.vm.box_download_checksum
69
69
  box_download_location_trusted = machine.config.vm.box_download_location_trusted
70
+ box_extra_download_options = machine.config.vm.box_extra_download_options
70
71
  box_formats = machine.provider_options[:box_format] ||
71
72
  machine.provider_name
72
73
 
@@ -92,6 +93,7 @@ module Vagrant
92
93
  box_checksum_type: box_download_checksum_type,
93
94
  box_checksum: box_download_checksum,
94
95
  box_download_location_trusted: box_download_location_trusted,
96
+ box_extra_download_options: box_extra_download_options,
95
97
  }))
96
98
  rescue Errors::BoxAlreadyExists
97
99
  # Just ignore this, since it means the next part will succeed!
@@ -1,8 +1,10 @@
1
1
  require "set"
2
2
 
3
3
  require "log4r"
4
+ require "socket"
4
5
 
5
6
  require "vagrant/util/is_port_open"
7
+ require "vagrant/util/ipv4_interfaces"
6
8
 
7
9
  module Vagrant
8
10
  module Action
@@ -25,6 +27,7 @@ module Vagrant
25
27
  #
26
28
  class HandleForwardedPortCollisions
27
29
  include Util::IsPortOpen
30
+ include Util::IPv4Interfaces
28
31
 
29
32
  def initialize(app, env)
30
33
  @app = app
@@ -120,6 +123,7 @@ module Vagrant
120
123
  in_use = is_forwarded_already(extra_in_use, host_port, host_ip) ||
121
124
  call_port_checker(port_checker, host_ip, host_port) ||
122
125
  lease_check(host_ip, host_port)
126
+
123
127
  if in_use
124
128
  if !repair || !options[:auto_correct]
125
129
  raise Errors::ForwardPortCollision,
@@ -243,18 +247,33 @@ module Vagrant
243
247
  end
244
248
 
245
249
  def port_check(host_ip, host_port)
246
- # If no host_ip is specified, intention taken to be list on all interfaces.
247
- # If platform is windows, default back to localhost only
250
+ self.class.port_check(@machine, host_ip, host_port)
251
+ end
252
+
253
+ def self.port_check(machine, host_ip, host_port)
254
+ @logger = Log4r::Logger.new("vagrant::action::builtin::handle_port_collisions")
255
+ # If no host_ip is specified, intention taken to be listen on all interfaces.
248
256
  test_host_ip = host_ip || "0.0.0.0"
249
- begin
250
- is_port_open?(test_host_ip, host_port)
251
- rescue Errno::EADDRNOTAVAIL
252
- if !host_ip && test_host_ip == "0.0.0.0"
253
- test_host_ip = "127.0.0.1"
254
- retry
257
+ if Util::Platform.windows? && test_host_ip == "0.0.0.0"
258
+ @logger.debug("Testing port #{host_port} on all IPv4 interfaces...")
259
+ available_interfaces = Vagrant::Util::IPv4Interfaces.ipv4_interfaces.select do |interface|
260
+ @logger.debug("Testing #{interface[0]} with IP address #{interface[1]}")
261
+ !Vagrant::Util::IsPortOpen.is_port_open?(interface[1], host_port)
262
+ end
263
+ if available_interfaces.empty?
264
+ @logger.debug("Cannot forward port #{host_port} on any interfaces.")
265
+ true
255
266
  else
256
- raise
267
+ @logger.debug("Port #{host_port} will forward to the guest on the following interfaces: #{available_interfaces}")
268
+ false
269
+ end
270
+ else
271
+ # Do a regular check
272
+ if test_host_ip != "0.0.0.0" && !Addrinfo.ip(test_host_ip).ipv4_loopback? &&
273
+ Vagrant::Util::IPv4Interfaces.ipv4_interfaces.none? { |iface| iface[1] == test_host_ip }
274
+ @logger.warn("host IP address is not local to this device host_ip=#{test_host_ip}")
257
275
  end
276
+ Vagrant::Util::IsPortOpen.is_port_open?(test_host_ip, host_port)
258
277
  end
259
278
  end
260
279