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
@@ -0,0 +1,40 @@
1
+ require_relative "../../../synced_folders/unix_mount_helpers"
2
+
3
+ module VagrantPlugins
4
+ module ProviderVirtualBox
5
+ module Cap
6
+ module MountOptions
7
+ extend VagrantPlugins::SyncedFolder::UnixMountHelpers
8
+
9
+ VB_MOUNT_TYPE = "vboxsf".freeze
10
+
11
+ # Returns mount options for a virtual box synced folder
12
+ #
13
+ # @param [Machine] machine
14
+ # @param [String] name of mount
15
+ # @param [String] path of mount on guest
16
+ # @param [Hash] hash of mount options
17
+ def self.mount_options(machine, name, guest_path, options)
18
+ mount_options = options.fetch(:mount_options, [])
19
+ detected_ids = detect_owner_group_ids(machine, guest_path, mount_options, options)
20
+ mount_uid = detected_ids[:uid]
21
+ mount_gid = detected_ids[:gid]
22
+
23
+ mount_options << "uid=#{mount_uid}"
24
+ mount_options << "gid=#{mount_gid}"
25
+ mount_options << "_netdev"
26
+ mount_options = mount_options.join(',')
27
+ return mount_options, mount_uid, mount_gid
28
+ end
29
+
30
+ def self.mount_type(machine)
31
+ return VB_MOUNT_TYPE
32
+ end
33
+
34
+ def self.mount_name(machine, name, data)
35
+ name.gsub(/[\s\/\\]/,'_').sub(/^_/, '')
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,34 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module ProviderVirtualBox
5
+ module Cap
6
+ module ValidateDiskExt
7
+ LOGGER = Log4r::Logger.new("vagrant::plugins::virtualbox::validate_disk_ext")
8
+
9
+ # The default set of disk formats that VirtualBox supports
10
+ DEFAULT_DISK_EXT_LIST = ["vdi", "vmdk", "vhd"].map(&:freeze).freeze
11
+ DEFAULT_DISK_EXT = "vdi".freeze
12
+
13
+ # @param [Vagrant::Machine] machine
14
+ # @param [String] disk_ext
15
+ # @return [Bool]
16
+ def self.validate_disk_ext(machine, disk_ext)
17
+ DEFAULT_DISK_EXT_LIST.include?(disk_ext)
18
+ end
19
+
20
+ # @param [Vagrant::Machine] machine
21
+ # @return [Array]
22
+ def self.default_disk_exts(machine)
23
+ DEFAULT_DISK_EXT_LIST
24
+ end
25
+
26
+ # @param [Vagrant::Machine] machine
27
+ # @return [String]
28
+ def self.set_default_disk_ext(machine)
29
+ DEFAULT_DISK_EXT
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -368,6 +368,21 @@ module VagrantPlugins
368
368
  def vm_exists?(uuid)
369
369
  end
370
370
 
371
+ # Returns a hash of information about a given virtual machine
372
+ #
373
+ # @param [String] uuid
374
+ # @return [Hash] info
375
+ def show_vm_info
376
+ info = {}
377
+ execute('showvminfo', @uuid, '--machinereadable', retryable: true).split("\n").each do |line|
378
+ parts = line.partition('=')
379
+ key = parts.first.gsub('"', '')
380
+ value = parts.last.gsub('"', '')
381
+ info[key] = value
382
+ end
383
+ info
384
+ end
385
+
371
386
  # Execute the given subcommand for VBoxManage and return the output.
372
387
  def execute(*command, &block)
373
388
  # Get the options hash if it exists
@@ -97,10 +97,15 @@ module VagrantPlugins
97
97
  end
98
98
  end
99
99
 
100
- def_delegators :@driver, :clear_forwarded_ports,
100
+ def_delegators :@driver,
101
+ :attach_disk,
102
+ :clear_forwarded_ports,
101
103
  :clear_shared_folders,
104
+ :clone_disk,
102
105
  :clonevm,
106
+ :close_medium,
103
107
  :create_dhcp_server,
108
+ :create_disk,
104
109
  :create_host_only_network,
105
110
  :create_snapshot,
106
111
  :delete,
@@ -111,9 +116,12 @@ module VagrantPlugins
111
116
  :execute_command,
112
117
  :export,
113
118
  :forward_ports,
119
+ :get_port_and_device,
120
+ :get_storage_controller,
114
121
  :halt,
115
122
  :import,
116
123
  :list_snapshots,
124
+ :list_hdds,
117
125
  :read_forwarded_ports,
118
126
  :read_bridged_interfaces,
119
127
  :read_dhcp_servers,
@@ -126,21 +134,27 @@ module VagrantPlugins
126
134
  :read_machine_folder,
127
135
  :read_network_interfaces,
128
136
  :read_state,
137
+ :read_storage_controllers,
129
138
  :read_used_ports,
130
139
  :read_vms,
131
140
  :reconfig_host_only,
132
141
  :remove_dhcp_server,
142
+ :remove_disk,
143
+ :resize_disk,
133
144
  :restore_snapshot,
134
145
  :resume,
135
146
  :set_mac_address,
136
147
  :set_name,
137
148
  :share_folders,
149
+ :show_medium_info,
138
150
  :ssh_port,
139
151
  :start,
140
152
  :suspend,
153
+ :vdi_to_vmdk,
141
154
  :verify!,
142
155
  :verify_image,
143
- :vm_exists?
156
+ :vm_exists?,
157
+ :vmdk_to_vdi
144
158
 
145
159
  protected
146
160
 
@@ -16,6 +16,30 @@ module VagrantPlugins
16
16
  @uuid = uuid
17
17
  end
18
18
 
19
+ # Controller-Port-Device looks like:
20
+ # SATA Controller-ImageUUID-0-0 (sub out ImageUUID)
21
+ # - Controller: SATA Controller
22
+ # - Port: 0
23
+ # - Device: 0
24
+ #
25
+ # @param [String] controller_name - name of storage controller to attach disk to
26
+ # @param [String] port - port on device to attach disk to
27
+ # @param [String] device - device on controller for disk
28
+ # @param [String] type - type of disk to attach
29
+ # @param [String] file - disk file path
30
+ # @param [Hash] opts - additional options
31
+ def attach_disk(controller_name, port, device, type, file, **opts)
32
+ comment = "This disk is managed externally by Vagrant. Removing or adjusting settings could potentially cause issues with Vagrant."
33
+
34
+ execute('storageattach', @uuid,
35
+ '--storagectl', controller_name,
36
+ '--port', port.to_s,
37
+ '--device', device.to_s,
38
+ '--type', type,
39
+ '--medium', file,
40
+ '--comment', comment)
41
+ end
42
+
19
43
  def clear_forwarded_ports
20
44
  retryable(on: Vagrant::Errors::VBoxManageError, tries: 3, sleep: 1) do
21
45
  args = []
@@ -38,6 +62,13 @@ module VagrantPlugins
38
62
  end
39
63
  end
40
64
 
65
+ # @param [String] source
66
+ # @param [String] destination
67
+ # @param [String] disk_format
68
+ def clone_disk(source, destination, disk_format, **opts)
69
+ execute("clonemedium", source, destination, '--format', disk_format)
70
+ end
71
+
41
72
  def clonevm(master_id, snapshot_name)
42
73
  machine_name = "temp_clone_#{(Time.now.to_f * 1000.0).to_i}_#{rand(100000)}"
43
74
  args = ["--register", "--name", machine_name]
@@ -49,6 +80,14 @@ module VagrantPlugins
49
80
  return get_machine_id(machine_name)
50
81
  end
51
82
 
83
+ # Removes a disk from the given virtual machine
84
+ #
85
+ # @param [String] disk_uuid or file path
86
+ # @param [Hash] opts - additional options
87
+ def close_medium(disk_uuid)
88
+ execute("closemedium", disk_uuid, '--delete')
89
+ end
90
+
52
91
  def create_dhcp_server(network, options)
53
92
  retryable(on: Vagrant::Errors::VBoxManageError, tries: 3, sleep: 1) do
54
93
  begin
@@ -65,6 +104,17 @@ module VagrantPlugins
65
104
  end
66
105
  end
67
106
 
107
+ # Creates a disk. Default format is VDI unless overridden
108
+ #
109
+ # @param [String] disk_file
110
+ # @param [Integer] disk_size - size in bytes
111
+ # @param [String] disk_format - format of disk, defaults to "VDI"
112
+ # @param [Hash] opts - additional options
113
+ def create_disk(disk_file, disk_size, disk_format="VDI", **opts)
114
+ execute("createmedium", '--filename', disk_file, '--sizebyte', disk_size.to_i.to_s, '--format', disk_format)
115
+ end
116
+
117
+
68
118
  def create_host_only_network(options)
69
119
  # Create the interface
70
120
  execute("hostonlyif", "create", retryable: true) =~ /^Interface '(.+?)' was successfully created$/
@@ -130,6 +180,33 @@ module VagrantPlugins
130
180
  end
131
181
  end
132
182
 
183
+ # Lists all attached harddisks from a given virtual machine. Additionally,
184
+ # this method adds a new key "Disk Name" based on the disks file path from "Location"
185
+ #
186
+ # @return [Array] hdds An array of hashes of harddrive info for a guest
187
+ def list_hdds
188
+ hdds = []
189
+ tmp_drive = {}
190
+ execute('list', 'hdds', retryable: true).split("\n").each do |line|
191
+ if line == "" # separator between disks
192
+ hdds << tmp_drive
193
+ tmp_drive = {}
194
+ next
195
+ end
196
+ parts = line.partition(":")
197
+ key = parts.first.strip
198
+ value = parts.last.strip
199
+ tmp_drive[key] = value
200
+
201
+ if key == "Location"
202
+ tmp_drive["Disk Name"] = File.basename(value, ".*")
203
+ end
204
+ end
205
+ hdds << tmp_drive unless tmp_drive.empty?
206
+
207
+ hdds
208
+ end
209
+
133
210
  def list_snapshots(machine_id)
134
211
  output = execute(
135
212
  "snapshot", machine_id, "list", "--machinereadable",
@@ -149,6 +226,24 @@ module VagrantPlugins
149
226
  raise
150
227
  end
151
228
 
229
+ # @param [String] controller_name - controller name to remove disk from
230
+ # @param [String] port - port on device to attach disk to
231
+ # @param [String] device - device on controller for disk
232
+ def remove_disk(controller_name, port, device)
233
+ execute('storageattach', @uuid,
234
+ '--storagectl', controller_name,
235
+ '--port', port.to_s,
236
+ '--device', device.to_s,
237
+ '--medium', "none")
238
+ end
239
+
240
+ # @param [String] disk_file
241
+ # @param [Integer] disk_size in bytes
242
+ # @param [Hash] opts - additional options
243
+ def resize_disk(disk_file, disk_size, **opts)
244
+ execute("modifymedium", disk_file, '--resizebyte', disk_size.to_i.to_s)
245
+ end
246
+
152
247
  def restore_snapshot(machine_id, snapshot_name)
153
248
  # Start with 0%
154
249
  last = 0
@@ -295,6 +390,28 @@ module VagrantPlugins
295
390
  nil
296
391
  end
297
392
 
393
+ # Returns port and device for an attached disk given a disk uuid. Returns
394
+ # empty hash if disk is not attachd to guest
395
+ #
396
+ # @param [String] disk_uuid - the UUID for the disk we are searching for
397
+ # @return [Hash] disk_info - Contains a device and port number
398
+ def get_port_and_device(disk_uuid)
399
+ disk = {}
400
+
401
+ storage_controllers = read_storage_controllers
402
+ storage_controllers.each do |controller|
403
+ controller.attachments.each do |attachment|
404
+ if disk_uuid == attachment[:uuid]
405
+ disk[:port] = attachment[:port]
406
+ disk[:device] = attachment[:device]
407
+ return disk
408
+ end
409
+ end
410
+ end
411
+
412
+ return disk
413
+ end
414
+
298
415
  def halt
299
416
  execute("controlvm", @uuid, "poweroff", retryable: true)
300
417
  end
@@ -370,7 +487,7 @@ module VagrantPlugins
370
487
  end
371
488
  end
372
489
 
373
- return get_machine_id specified_name
490
+ return get_machine_id(specified_name)
374
491
  end
375
492
 
376
493
  def max_network_adapters
@@ -476,6 +593,11 @@ module VagrantPlugins
476
593
 
477
594
  def read_guest_ip(adapter_number)
478
595
  ip = read_guest_property("/VirtualBox/GuestInfo/Net/#{adapter_number}/V4/IP")
596
+ if ip.end_with?(".1")
597
+ @logger.warn("VBoxManage guest property returned: #{ip}. Result resembles IP of DHCP server and is being ignored.")
598
+ ip = nil
599
+ end
600
+
479
601
  if !valid_ip_address?(ip)
480
602
  raise Vagrant::Errors::VirtualBoxGuestPropertyNotFound,
481
603
  guest_property: "/VirtualBox/GuestInfo/Net/#{adapter_number}/V4/IP"
@@ -686,6 +808,26 @@ module VagrantPlugins
686
808
  end
687
809
  end
688
810
 
811
+ # Returns information for a given disk
812
+ #
813
+ # @param [String] disk_type - can be "disk", "dvd", or "floppy"
814
+ # @param [String] disk_uuid_or_file
815
+ # @return [Hash] disk
816
+ def show_medium_info(disk_type, disk_uuid_or_file)
817
+ disk = {}
818
+ execute('showmediuminfo', disk_type, disk_uuid_or_file, retryable: true).split("\n").each do |line|
819
+ parts = line.partition(":")
820
+ key = parts.first.strip
821
+ value = parts.last.strip
822
+ disk[key] = value
823
+
824
+ if key == "Location"
825
+ disk["Disk Name"] = File.basename(value, ".*")
826
+ end
827
+ end
828
+ disk
829
+ end
830
+
689
831
  def ssh_port(expected_port)
690
832
  @logger.debug("Searching for SSH port: #{expected_port.inspect}")
691
833
 
@@ -783,12 +925,85 @@ module VagrantPlugins
783
925
  return true
784
926
  end
785
927
 
928
+ # @param [VagrantPlugins::VirtualboxProvider::Driver] driver
929
+ # @param [String] defined_disk_path
930
+ # @return [String] destination - The cloned disk
931
+ def vmdk_to_vdi(defined_disk_path)
932
+ source = defined_disk_path
933
+ destination = File.join(File.dirname(source), File.basename(source, ".*")) + ".vdi"
934
+
935
+ clone_disk(source, destination, 'VDI')
936
+
937
+ destination
938
+ end
939
+
940
+ # @param [VagrantPlugins::VirtualboxProvider::Driver] driver
941
+ # @param [String] defined_disk_path
942
+ # @return [String] destination - The cloned disk
943
+ def vdi_to_vmdk(defined_disk_path)
944
+ source = defined_disk_path
945
+ destination = File.join(File.dirname(source), File.basename(source, ".*")) + ".vmdk"
946
+
947
+ clone_disk(source, destination, 'VMDK')
948
+
949
+ destination
950
+ end
951
+
952
+ # Helper method to get a list of storage controllers added to the
953
+ # current VM
954
+ #
955
+ # @return [VagrantPlugins::ProviderVirtualBox::Model::StorageControllerArray]
956
+ def read_storage_controllers
957
+ vm_info = show_vm_info
958
+ count = vm_info.count { |key, value| key.match(/^storagecontrollername\d+$/) }
959
+ all_disks = list_hdds
960
+
961
+ storage_controllers = Model::StorageControllerArray.new
962
+
963
+ (0..count - 1).each do |n|
964
+ # basic controller metadata
965
+ name = vm_info["storagecontrollername#{n}"]
966
+ type = vm_info["storagecontrollertype#{n}"]
967
+ maxportcount = vm_info["storagecontrollermaxportcount#{n}"].to_i
968
+
969
+ # build attachments array
970
+ attachments = []
971
+ vm_info.each do |k, v|
972
+ if /^#{name}-ImageUUID-(\d+)-(\d+)$/ =~ k
973
+ port = $1.to_s
974
+ device = $2.to_s
975
+ uuid = v
976
+ location = vm_info["#{name}-#{port}-#{device}"]
977
+
978
+ extra_disk_data = all_disks.detect { |d| d["UUID"] == uuid }
979
+
980
+ attachment = { port: port,
981
+ device: device,
982
+ uuid: uuid,
983
+ location: location }
984
+
985
+ extra_disk_data&.each do |dk,dv|
986
+ # NOTE: We convert the keys from VirtualBox to symbols
987
+ # to be consistent with the other keys
988
+ attachment[dk.downcase.gsub(' ', '_').to_sym] = dv
989
+ end
990
+
991
+ attachments << attachment
992
+ end
993
+ end
994
+
995
+ storage_controllers << Model::StorageController.new(name, type, maxportcount, attachments)
996
+ end
997
+
998
+ storage_controllers
999
+ end
1000
+
786
1001
  protected
787
1002
 
788
1003
  def valid_ip_address?(ip)
789
1004
  # Filter out invalid IP addresses
790
1005
  # GH-4658 VirtualBox can report an IP address of 0.0.0.0 for FreeBSD guests.
791
- if ip == "0.0.0.0"
1006
+ if ip == "0.0.0.0" || ip.nil?
792
1007
  return false
793
1008
  else
794
1009
  return true