vagrant-unbundled 2.2.9.0 → 2.2.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -0
  3. data/README.md +5 -5
  4. data/contrib/README.md +1 -0
  5. data/contrib/sudoers/linux-suse +2 -2
  6. data/contrib/zsh/_vagrant +736 -0
  7. data/contrib/zsh/generate_zsh_completion.rb +166 -0
  8. data/lib/vagrant/action.rb +3 -0
  9. data/lib/vagrant/action/builder.rb +52 -18
  10. data/lib/vagrant/action/builtin/box_add.rb +6 -5
  11. data/lib/vagrant/action/builtin/cloud_init_setup.rb +127 -0
  12. data/lib/vagrant/action/builtin/cloud_init_wait.rb +30 -0
  13. data/lib/vagrant/action/builtin/handle_box.rb +1 -1
  14. data/lib/vagrant/action/builtin/handle_forwarded_port_collisions.rb +13 -13
  15. data/lib/vagrant/action/builtin/has_provisioner.rb +36 -0
  16. data/lib/vagrant/action/builtin/mixin_provisioners.rb +1 -0
  17. data/lib/vagrant/action/builtin/mixin_synced_folders.rb +20 -21
  18. data/lib/vagrant/action/builtin/set_hostname.rb +5 -1
  19. data/lib/vagrant/action/builtin/synced_folders.rb +10 -0
  20. data/lib/vagrant/action/builtin/trigger.rb +3 -2
  21. data/lib/vagrant/action/hook.rb +59 -24
  22. data/lib/vagrant/action/warden.rb +25 -5
  23. data/lib/vagrant/box.rb +5 -4
  24. data/lib/vagrant/bundler.rb +6 -1
  25. data/lib/vagrant/errors.rb +37 -1
  26. data/lib/vagrant/machine.rb +47 -0
  27. data/lib/vagrant/machine_index.rb +27 -1
  28. data/lib/vagrant/plugin/v2/command.rb +5 -1
  29. data/lib/vagrant/plugin/v2/components.rb +6 -0
  30. data/lib/vagrant/plugin/v2/manager.rb +14 -0
  31. data/lib/vagrant/plugin/v2/plugin.rb +12 -0
  32. data/lib/vagrant/plugin/v2/synced_folder.rb +50 -0
  33. data/lib/vagrant/plugin/v2/trigger.rb +6 -5
  34. data/lib/vagrant/ui.rb +1 -1
  35. data/lib/vagrant/util/ansi_escape_code_remover.rb +1 -1
  36. data/lib/vagrant/util/caps.rb +48 -0
  37. data/lib/vagrant/util/credential_scrubber.rb +1 -1
  38. data/lib/vagrant/util/directory.rb +19 -0
  39. data/lib/vagrant/util/downloader.rb +3 -3
  40. data/lib/vagrant/util/guest_hosts.rb +68 -0
  41. data/lib/vagrant/util/install_cli_autocomplete.rb +118 -0
  42. data/lib/vagrant/util/ipv4_interfaces.rb +15 -0
  43. data/lib/vagrant/util/is_port_open.rb +8 -19
  44. data/lib/vagrant/util/network_ip.rb +11 -1
  45. data/lib/vagrant/util/powershell.rb +1 -1
  46. data/lib/vagrant/util/subprocess.rb +9 -1
  47. data/lib/vagrant/vagrantfile.rb +1 -1
  48. data/plugins/commands/autocomplete/command/install.rb +49 -0
  49. data/plugins/commands/autocomplete/command/root.rb +64 -0
  50. data/plugins/commands/autocomplete/plugin.rb +18 -0
  51. data/plugins/commands/destroy/command.rb +6 -2
  52. data/plugins/communicators/ssh/communicator.rb +7 -1
  53. data/plugins/communicators/winrm/helper.rb +1 -1
  54. data/plugins/communicators/winssh/communicator.rb +1 -1
  55. data/plugins/guests/alpine/cap/change_host_name.rb +10 -11
  56. data/plugins/guests/alt/cap/change_host_name.rb +40 -53
  57. data/plugins/guests/arch/cap/change_host_name.rb +5 -14
  58. data/plugins/guests/arch/cap/configure_networks.rb +27 -10
  59. data/plugins/guests/atomic/cap/change_host_name.rb +5 -14
  60. data/plugins/guests/darwin/cap/change_host_name.rb +10 -6
  61. data/plugins/guests/debian/cap/change_host_name.rb +11 -11
  62. data/plugins/guests/esxi/cap/public_key.rb +3 -1
  63. data/plugins/guests/freebsd/cap/change_host_name.rb +10 -6
  64. data/plugins/guests/gentoo/cap/change_host_name.rb +14 -22
  65. data/plugins/guests/haiku/cap/rsync.rb +19 -0
  66. data/plugins/guests/haiku/plugin.rb +15 -0
  67. data/plugins/guests/linux/cap/change_host_name.rb +46 -0
  68. data/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb +4 -11
  69. data/plugins/guests/linux/cap/persist_mount_shared_folder.rb +62 -0
  70. data/plugins/guests/linux/plugin.rb +10 -0
  71. data/plugins/guests/omnios/cap/change_host_name.rb +10 -16
  72. data/plugins/guests/openbsd/cap/change_host_name.rb +10 -6
  73. data/plugins/guests/photon/cap/change_host_name.rb +9 -15
  74. data/plugins/guests/pld/cap/change_host_name.rb +11 -17
  75. data/plugins/guests/redhat/cap/change_host_name.rb +10 -5
  76. data/plugins/guests/slackware/cap/change_host_name.rb +11 -17
  77. data/plugins/guests/solaris11/plugin.rb +5 -0
  78. data/plugins/guests/suse/cap/change_host_name.rb +12 -11
  79. data/plugins/hosts/darwin/cap/fs_iso.rb +49 -0
  80. data/plugins/hosts/darwin/plugin.rb +10 -0
  81. data/plugins/hosts/linux/cap/fs_iso.rb +49 -0
  82. data/plugins/hosts/linux/cap/rdp.rb +1 -1
  83. data/plugins/hosts/linux/plugin.rb +10 -0
  84. data/plugins/hosts/windows/cap/fs_iso.rb +48 -0
  85. data/plugins/hosts/windows/cap/rdp.rb +1 -1
  86. data/plugins/hosts/windows/plugin.rb +15 -0
  87. data/plugins/kernel_v2/config/cloud_init.rb +126 -0
  88. data/plugins/kernel_v2/config/disk.rb +40 -18
  89. data/plugins/kernel_v2/config/vm.rb +122 -13
  90. data/plugins/kernel_v2/config/vm_provisioner.rb +13 -2
  91. data/plugins/kernel_v2/config/vm_trigger.rb +5 -1
  92. data/plugins/providers/docker/action.rb +8 -17
  93. data/plugins/providers/docker/action/forwarded_ports.rb +2 -0
  94. data/plugins/providers/docker/action/prepare_forwarded_port_collision_params.rb +61 -0
  95. data/plugins/providers/docker/cap/has_communicator.rb +11 -0
  96. data/plugins/providers/docker/communicator.rb +1 -1
  97. data/plugins/providers/docker/driver.rb +35 -0
  98. data/plugins/providers/docker/plugin.rb +5 -0
  99. data/plugins/providers/hyperv/action.rb +2 -0
  100. data/plugins/providers/hyperv/action/configure.rb +8 -0
  101. data/plugins/providers/hyperv/cap/cleanup_disks.rb +54 -0
  102. data/plugins/providers/hyperv/cap/configure_disks.rb +200 -0
  103. data/plugins/providers/hyperv/cap/validate_disk_ext.rb +34 -0
  104. data/plugins/providers/hyperv/config.rb +5 -0
  105. data/plugins/providers/hyperv/driver.rb +80 -0
  106. data/plugins/providers/hyperv/plugin.rb +25 -0
  107. data/plugins/providers/hyperv/scripts/attach_disk_drive.ps1 +28 -0
  108. data/plugins/providers/hyperv/scripts/dismount_vhd.ps1 +13 -0
  109. data/plugins/providers/hyperv/scripts/get_vhd.ps1 +16 -0
  110. data/plugins/providers/hyperv/scripts/get_vm_status.ps1 +1 -1
  111. data/plugins/providers/hyperv/scripts/list_hdds.ps1 +17 -0
  112. data/plugins/providers/hyperv/scripts/new_vhd.ps1 +31 -0
  113. data/plugins/providers/hyperv/scripts/remove_disk_drive.ps1 +25 -0
  114. data/plugins/providers/hyperv/scripts/resize_disk_drive.ps1 +18 -0
  115. data/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 +24 -0
  116. data/plugins/providers/hyperv/scripts/utils/VagrantVM/VagrantVM.psm1 +8 -0
  117. data/plugins/providers/virtualbox/action.rb +12 -1
  118. data/plugins/providers/virtualbox/action/forward_ports.rb +2 -2
  119. data/plugins/providers/virtualbox/cap/cleanup_disks.rb +40 -9
  120. data/plugins/providers/virtualbox/cap/configure_disks.rb +230 -77
  121. data/plugins/providers/virtualbox/cap/mount_options.rb +35 -0
  122. data/plugins/providers/virtualbox/cap/validate_disk_ext.rb +10 -3
  123. data/plugins/providers/virtualbox/driver/meta.rb +3 -0
  124. data/plugins/providers/virtualbox/driver/version_5_0.rb +96 -21
  125. data/plugins/providers/virtualbox/model/storage_controller.rb +135 -0
  126. data/plugins/providers/virtualbox/model/storage_controller_array.rb +100 -0
  127. data/plugins/providers/virtualbox/plugin.rb +18 -1
  128. data/plugins/providers/virtualbox/synced_folder.rb +1 -0
  129. data/plugins/provisioners/container/client.rb +1 -1
  130. data/plugins/provisioners/shell/provisioner.rb +15 -9
  131. data/plugins/synced_folders/nfs/synced_folder.rb +3 -1
  132. data/plugins/synced_folders/smb/cap/default_fstab_modification.rb +11 -0
  133. data/plugins/synced_folders/smb/cap/mount_options.rb +36 -0
  134. data/plugins/synced_folders/smb/plugin.rb +10 -0
  135. data/plugins/synced_folders/smb/synced_folder.rb +1 -1
  136. data/plugins/synced_folders/unix_mount_helpers.rb +14 -0
  137. data/templates/guests/arch/{network_dhcp.erb → default_network/network_dhcp.erb} +0 -0
  138. data/templates/guests/arch/{network_static.erb → default_network/network_static.erb} +0 -0
  139. data/templates/guests/arch/{network_static6.erb → default_network/network_static6.erb} +0 -0
  140. data/templates/guests/arch/systemd_networkd/network_dhcp.erb +6 -0
  141. data/templates/guests/arch/systemd_networkd/network_static.erb +9 -0
  142. data/templates/guests/arch/systemd_networkd/network_static6.erb +9 -0
  143. data/templates/guests/linux/etc_fstab.erb +6 -0
  144. data/templates/locales/en.yml +121 -11
  145. data/templates/locales/providers_docker.yml +4 -0
  146. data/vagrant.gemspec +8 -7
  147. data/version.txt +1 -1
  148. metadata +1492 -1309
@@ -0,0 +1,35 @@
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 virual 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 = mount_options.join(',')
26
+ return mount_options, mount_uid, mount_gid
27
+ end
28
+
29
+ def self.mount_type(machine)
30
+ return VB_MOUNT_TYPE
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -7,18 +7,25 @@ module VagrantPlugins
7
7
  LOGGER = Log4r::Logger.new("vagrant::plugins::virtualbox::validate_disk_ext")
8
8
 
9
9
  # The default set of disk formats that VirtualBox supports
10
- DEFAULT_DISK_EXT = ["vdi", "vmdk", "vhd"].map(&:freeze).freeze
10
+ DEFAULT_DISK_EXT_LIST = ["vdi", "vmdk", "vhd"].map(&:freeze).freeze
11
+ DEFAULT_DISK_EXT = "vdi".freeze
11
12
 
12
13
  # @param [Vagrant::Machine] machine
13
14
  # @param [String] disk_ext
14
15
  # @return [Bool]
15
16
  def self.validate_disk_ext(machine, disk_ext)
16
- DEFAULT_DISK_EXT.include?(disk_ext)
17
+ DEFAULT_DISK_EXT_LIST.include?(disk_ext)
17
18
  end
18
19
 
19
20
  # @param [Vagrant::Machine] machine
20
21
  # @return [Array]
21
- def self.get_default_disk_ext(machine)
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)
22
29
  DEFAULT_DISK_EXT
23
30
  end
24
31
  end
@@ -117,6 +117,7 @@ module VagrantPlugins
117
117
  :export,
118
118
  :forward_ports,
119
119
  :get_port_and_device,
120
+ :get_storage_controller,
120
121
  :halt,
121
122
  :import,
122
123
  :list_snapshots,
@@ -133,6 +134,7 @@ module VagrantPlugins
133
134
  :read_machine_folder,
134
135
  :read_network_interfaces,
135
136
  :read_state,
137
+ :read_storage_controllers,
136
138
  :read_used_ports,
137
139
  :read_vms,
138
140
  :reconfig_host_only,
@@ -144,6 +146,7 @@ module VagrantPlugins
144
146
  :set_mac_address,
145
147
  :set_name,
146
148
  :share_folders,
149
+ :show_medium_info,
147
150
  :ssh_port,
148
151
  :start,
149
152
  :suspend,
@@ -22,20 +22,22 @@ module VagrantPlugins
22
22
  # - Port: 0
23
23
  # - Device: 0
24
24
  #
25
+ # @param [String] controller_name - name of storage controller to attach disk to
25
26
  # @param [String] port - port on device to attach disk to
26
27
  # @param [String] device - device on controller for disk
27
- # @param [String] file - disk file path
28
28
  # @param [String] type - type of disk to attach
29
+ # @param [String] file - disk file path
29
30
  # @param [Hash] opts - additional options
30
- def attach_disk(port, device, file, type="hdd", **opts)
31
- # Maybe only support SATA Controller for `:disk`???
32
- controller = "SATA Controller"
33
-
31
+ def attach_disk(controller_name, port, device, type, file, **opts)
34
32
  comment = "This disk is managed externally by Vagrant. Removing or adjusting settings could potentially cause issues with Vagrant."
35
33
 
36
- execute('storageattach', @uuid, '--storagectl', controller, '--port',
37
- port.to_s, '--device', device.to_s, '--type', type, '--medium',
38
- file, '--comment', comment)
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)
39
41
  end
40
42
 
41
43
  def clear_forwarded_ports
@@ -224,12 +226,15 @@ module VagrantPlugins
224
226
  raise
225
227
  end
226
228
 
229
+ # @param [String] controller_name - controller name to remove disk from
227
230
  # @param [String] port - port on device to attach disk to
228
231
  # @param [String] device - device on controller for disk
229
- # @param [Hash] opts - additional options
230
- def remove_disk(port, device)
231
- controller = "SATA Controller"
232
- execute('storageattach', @uuid, '--storagectl', controller, '--port', port.to_s, '--device', device.to_s, '--medium', "none")
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")
233
238
  end
234
239
 
235
240
  # @param [String] disk_file
@@ -388,20 +393,21 @@ module VagrantPlugins
388
393
  # Returns port and device for an attached disk given a disk uuid. Returns
389
394
  # empty hash if disk is not attachd to guest
390
395
  #
391
- # @param [Hash] vm_info - A guests information from vboxmanage
392
396
  # @param [String] disk_uuid - the UUID for the disk we are searching for
393
397
  # @return [Hash] disk_info - Contains a device and port number
394
398
  def get_port_and_device(disk_uuid)
395
- vm_info = show_vm_info
396
-
397
399
  disk = {}
398
- disk_info_key = vm_info.key(disk_uuid)
399
- return disk if !disk_info_key
400
400
 
401
- disk_info = disk_info_key.split("-")
402
-
403
- disk[:port] = disk_info[2]
404
- disk[:device] = disk_info[3]
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
405
411
 
406
412
  return disk
407
413
  end
@@ -802,6 +808,26 @@ module VagrantPlugins
802
808
  end
803
809
  end
804
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
+
805
831
  def ssh_port(expected_port)
806
832
  @logger.debug("Searching for SSH port: #{expected_port.inspect}")
807
833
 
@@ -923,6 +949,55 @@ module VagrantPlugins
923
949
  destination
924
950
  end
925
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
+
926
1001
  protected
927
1002
 
928
1003
  def valid_ip_address?(ip)
@@ -0,0 +1,135 @@
1
+ module VagrantPlugins
2
+ module ProviderVirtualBox
3
+ module Model
4
+ # Represents a storage controller for VirtualBox. Storage controllers
5
+ # have a type, a name, and can have hard disks or optical drives attached.
6
+ class StorageController
7
+ IDE_CONTROLLER_TYPES = ["PIIX4", "PIIX3", "ICH6"].map(&:freeze).freeze
8
+ SATA_CONTROLLER_TYPES = ["IntelAhci"].map(&:freeze).freeze
9
+ SCSI_CONTROLLER_TYPES = [ "LsiLogic", "BusLogic"].map(&:freeze).freeze
10
+
11
+ IDE_DEVICES_PER_PORT = 2.freeze
12
+ SATA_DEVICES_PER_PORT = 1.freeze
13
+ SCSI_DEVICES_PER_PORT = 1.freeze
14
+
15
+ IDE_BOOT_PRIORITY = 1.freeze
16
+ SATA_BOOT_PRIORITY = 2.freeze
17
+ SCSI_BOOT_PRIORITY = 3.freeze
18
+
19
+ # The name of the storage controller.
20
+ #
21
+ # @return [String]
22
+ attr_reader :name
23
+
24
+ # The specific type of controller.
25
+ #
26
+ # @return [String]
27
+ attr_reader :type
28
+
29
+ # The maximum number of avilable ports for the storage controller.
30
+ #
31
+ # @return [Integer]
32
+ attr_reader :maxportcount
33
+
34
+ # The number of devices that can be attached to each port. For SATA
35
+ # controllers, this will usually be 1, and for IDE controllers this
36
+ # will usually be 2.
37
+ # @return [Integer]
38
+ attr_reader :devices_per_port
39
+
40
+ # The maximum number of individual disks that can be attached to the
41
+ # storage controller. For SATA controllers, this equals the maximum
42
+ # number of ports. For IDE controllers, this will be twice the max
43
+ # number of ports (primary/secondary).
44
+ #
45
+ # @return [Integer]
46
+ attr_reader :limit
47
+
48
+ # The boot priority of the storage controller. This does not seem to
49
+ # depend on the controller number returned by `showvminfo`.
50
+ # Experimentation has determined that VirtualBox will try to boot from
51
+ # the first controller it finds with a hard disk, in this order:
52
+ # IDE, SATA, SCSI
53
+ #
54
+ # @return [Integer]
55
+ attr_reader :boot_priority
56
+
57
+ # The list of disks/ISOs attached to each storage controller.
58
+ #
59
+ # @return [Array<Hash>]
60
+ attr_reader :attachments
61
+
62
+ def initialize(name, type, maxportcount, attachments)
63
+ @name = name
64
+ @type = type
65
+
66
+ @maxportcount = maxportcount.to_i
67
+
68
+ if IDE_CONTROLLER_TYPES.include?(@type)
69
+ @storage_bus = :ide
70
+ @devices_per_port = IDE_DEVICES_PER_PORT
71
+ @boot_priority = IDE_BOOT_PRIORITY
72
+ elsif SATA_CONTROLLER_TYPES.include?(@type)
73
+ @storage_bus = :sata
74
+ @devices_per_port = SATA_DEVICES_PER_PORT
75
+ @boot_priority = SATA_BOOT_PRIORITY
76
+ elsif SCSI_CONTROLLER_TYPES.include?(@type)
77
+ @storage_bus = :scsi
78
+ @devices_per_port = SCSI_DEVICES_PER_PORT
79
+ @boot_priority = SCSI_BOOT_PRIORITY
80
+ else
81
+ @storage_bus = :unknown
82
+ @devices_per_port = 1
83
+ end
84
+
85
+ @limit = @maxportcount * @devices_per_port
86
+
87
+ attachments ||= []
88
+ @attachments = attachments
89
+ end
90
+
91
+ # Get a single storage device, either by port/device address or by
92
+ # UUID.
93
+ #
94
+ # @param [Hash] opts - A hash of options to match
95
+ # @return [Hash] attachment - Attachment information
96
+ def get_attachment(opts = {})
97
+ if opts[:port] && opts[:device]
98
+ @attachments.detect { |a| a[:port] == opts[:port] &&
99
+ a[:device] == opts[:device] }
100
+ elsif opts[:uuid]
101
+ @attachments.detect { |a| a[:uuid] == opts[:uuid] }
102
+ end
103
+ end
104
+
105
+ # Returns true if the storage controller has a supported type.
106
+ #
107
+ # @return [Boolean]
108
+ def supported?
109
+ [:ide, :sata, :scsi].include?(@storage_bus)
110
+ end
111
+
112
+ # Returns true if the storage controller is a IDE type controller.
113
+ #
114
+ # @return [Boolean]
115
+ def ide?
116
+ @storage_bus == :ide
117
+ end
118
+
119
+ # Returns true if the storage controller is a SATA type controller.
120
+ #
121
+ # @return [Boolean]
122
+ def sata?
123
+ @storage_bus == :sata
124
+ end
125
+
126
+ # Returns true if the storage controller is a SCSI type controller.
127
+ #
128
+ # @return [Boolean]
129
+ def scsi?
130
+ @storage_bus == :scsi
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,100 @@
1
+ require_relative "../cap/validate_disk_ext"
2
+
3
+ module VagrantPlugins
4
+ module ProviderVirtualBox
5
+ module Model
6
+ # A collection of storage controllers. Includes finder methods to look
7
+ # up a storage controller by given attributes.
8
+ class StorageControllerArray < Array
9
+ # Returns a storage controller with the given name. Raises an
10
+ # exception if a matching controller can't be found.
11
+ #
12
+ # @param [String] name - The name of the storage controller
13
+ # @return [VagrantPlugins::ProviderVirtualBox::Model::StorageController]
14
+ def get_controller(name)
15
+ controller = detect { |c| c.name == name }
16
+ if !controller
17
+ raise Vagrant::Errors::VirtualBoxDisksControllerNotFound, name: name
18
+ end
19
+ controller
20
+ end
21
+
22
+ # Find the controller containing the primary disk (i.e. the boot
23
+ # disk). This is used to determine which controller virtual disks
24
+ # should be attached to.
25
+ #
26
+ # Raises an exception if no supported controllers are found.
27
+ #
28
+ # @return [VagrantPlugins::ProviderVirtualBox::Model::StorageController]
29
+ def get_primary_controller
30
+ ordered = sort { |a, b| a.boot_priority <=> b.boot_priority }
31
+ controller = ordered.detect do |c|
32
+ c.supported? && c.attachments.any? { |a| hdd?(a) }
33
+ end
34
+
35
+ if !controller
36
+ raise Vagrant::Errors::VirtualBoxDisksNoSupportedControllers,
37
+ supported_types: supported_types.join(" ,")
38
+ end
39
+
40
+ controller
41
+ end
42
+
43
+ # Find the attachment representing the primary disk (i.e. the boot
44
+ # disk). We can't rely on the order of #list_hdds, as they will not
45
+ # always come in port order, but primary is always Port 0 Device 0.
46
+ #
47
+ # @return [Hash] attachment - Primary disk attachment information
48
+ def get_primary_attachment
49
+ attachment = nil
50
+
51
+ controller = get_primary_controller
52
+ attachment = controller.get_attachment(port: "0", device: "0")
53
+ if !attachment
54
+ raise Vagrant::Errors::VirtualBoxDisksPrimaryNotFound
55
+ end
56
+
57
+ attachment
58
+ end
59
+
60
+ # Returns the first supported storage controller for attaching dvds.
61
+ # Will raise an exception if no suitable controller can be found.
62
+ #
63
+ # @return [VagrantPlugins::ProviderVirtualBox::Model::StorageController]
64
+ def get_dvd_controller
65
+ ordered = sort { |a, b| a.boot_priority <=> b.boot_priority }
66
+ controller = ordered.detect { |c| c.supported? }
67
+ if !controller
68
+ raise Vagrant::Errors::VirtualBoxDisksNoSupportedControllers,
69
+ supported_types: supported_types.join(" ,")
70
+ end
71
+
72
+ controller
73
+ end
74
+
75
+ private
76
+
77
+ # Determine whether the given attachment is a hard disk.
78
+ #
79
+ # @param [Hash] attachment - Attachment information
80
+ # @return [Boolean]
81
+ def hdd?(attachment)
82
+ if !attachment
83
+ false
84
+ else
85
+ ext = File.extname(attachment[:location].to_s).downcase.split('.').last
86
+ VagrantPlugins::ProviderVirtualBox::Cap::ValidateDiskExt.validate_disk_ext(nil, ext)
87
+ end
88
+ end
89
+
90
+ # Returns a list of all the supported controller types.
91
+ #
92
+ # @return [Array<String>]
93
+ def supported_types
94
+ StorageController::SATA_CONTROLLER_TYPES + StorageController::IDE_CONTROLLER_TYPES +
95
+ StorageController::SCSI_CONTROLLER_TYPES
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end