fog-vsphere 1.7.0.1 → 1.7.1

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 (73) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -2
  3. data/.travis.yml +7 -6
  4. data/CHANGELOG.md +13 -2
  5. data/CONTRIBUTORS.md +0 -8
  6. data/Rakefile +1 -10
  7. data/gemfiles/Gemfile.1.9.2+ +9 -0
  8. data/lib/fog/vsphere/compute.rb +2 -0
  9. data/lib/fog/vsphere/models/compute/scsicontroller.rb +6 -1
  10. data/lib/fog/vsphere/models/compute/server.rb +37 -8
  11. data/lib/fog/vsphere/models/compute/volume.rb +62 -28
  12. data/lib/fog/vsphere/models/compute/volumes.rb +1 -1
  13. data/lib/fog/vsphere/requests/compute/create_vm.rb +32 -44
  14. data/lib/fog/vsphere/requests/compute/list_vm_scsi_controllers.rb +4 -11
  15. data/lib/fog/vsphere/requests/compute/list_vm_volumes.rb +2 -1
  16. data/lib/fog/vsphere/requests/compute/modify_vm_controller.rb +2 -14
  17. data/lib/fog/vsphere/requests/compute/modify_vm_volume.rb +3 -3
  18. data/lib/fog/vsphere/requests/compute/vm_clone.rb +2 -2
  19. data/lib/fog/vsphere/requests/compute/vm_migrate.rb +1 -0
  20. data/lib/fog/vsphere/requests/compute/vm_reconfig_volumes.rb +26 -15
  21. data/lib/fog/vsphere/version.rb +1 -1
  22. data/tests/class_from_string_tests.rb +3 -3
  23. data/tests/compute_tests.rb +17 -16
  24. data/tests/helpers/mock_helper.rb +3 -3
  25. data/tests/models/compute/cluster_tests.rb +5 -4
  26. data/tests/models/compute/hosts_tests.rb +4 -2
  27. data/tests/models/compute/rules_tests.rb +16 -10
  28. data/tests/models/compute/server_tests.rb +29 -33
  29. data/tests/models/compute/servers_tests.rb +4 -2
  30. data/tests/requests/compute/current_time_tests.rb +4 -2
  31. data/tests/requests/compute/folder_destroy_tests.rb +7 -5
  32. data/tests/requests/compute/get_network_tests.rb +22 -18
  33. data/tests/requests/compute/list_child_snapshots_tests.rb +2 -1
  34. data/tests/requests/compute/list_clusters_tests.rb +6 -5
  35. data/tests/requests/compute/list_datastores_tests.rb +7 -6
  36. data/tests/requests/compute/list_hosts_tests.rb +4 -3
  37. data/tests/requests/compute/list_networks_tests.rb +7 -6
  38. data/tests/requests/compute/list_storage_pods_test.rb +4 -3
  39. data/tests/requests/compute/list_virtual_machines_tests.rb +20 -16
  40. data/tests/requests/compute/list_vm_cdroms_tests.rb +2 -1
  41. data/tests/requests/compute/list_vm_snapshots_tests.rb +2 -1
  42. data/tests/requests/compute/modify_vm_cdrom_tests.rb +4 -3
  43. data/tests/requests/compute/revert_to_snapshot_tests.rb +4 -2
  44. data/tests/requests/compute/set_vm_customvalue_tests.rb +2 -0
  45. data/tests/requests/compute/vm_clone_tests.rb +20 -20
  46. data/tests/requests/compute/vm_config_vnc_tests.rb +4 -3
  47. data/tests/requests/compute/vm_destroy_tests.rb +4 -1
  48. data/tests/requests/compute/vm_migrate_tests.rb +2 -1
  49. data/tests/requests/compute/vm_power_off_tests.rb +4 -2
  50. data/tests/requests/compute/vm_power_on_tests.rb +3 -1
  51. data/tests/requests/compute/vm_reboot_tests.rb +4 -2
  52. data/tests/requests/compute/vm_reconfig_cdrom_tests.rb +3 -2
  53. data/tests/requests/compute/vm_reconfig_cpus_tests.rb +3 -1
  54. data/tests/requests/compute/vm_reconfig_hardware_tests.rb +4 -2
  55. data/tests/requests/compute/vm_reconfig_memory_tests.rb +3 -1
  56. data/tests/requests/compute/vm_take_snapshot_tests.rb +3 -1
  57. metadata +4 -22
  58. data/.rubocop.yml +0 -8
  59. data/.rubocop_todo.yml +0 -217
  60. data/lib/fog/vsphere/models/compute/ticket.rb +0 -16
  61. data/lib/fog/vsphere/models/compute/tickets.rb +0 -25
  62. data/lib/fog/vsphere/requests/compute/host_finish_maintenance.rb +0 -14
  63. data/lib/fog/vsphere/requests/compute/host_shutdown.rb +0 -14
  64. data/lib/fog/vsphere/requests/compute/host_start_maintenance.rb +0 -14
  65. data/lib/fog/vsphere/requests/compute/vm_acquire_ticket.rb +0 -34
  66. data/lib/fog/vsphere/requests/compute/vm_relocate.rb +0 -54
  67. data/lib/fog/vsphere/requests/compute/vm_remove_snapshot.rb +0 -29
  68. data/lib/fog/vsphere/requests/compute/vm_rename.rb +0 -24
  69. data/lib/fog/vsphere/requests/compute/vm_revert_snapshot.rb +0 -29
  70. data/lib/fog/vsphere/requests/compute/vm_suspend.rb +0 -54
  71. data/tests/models/compute/ticket_tests.rb +0 -12
  72. data/tests/models/compute/tickets_tests.rb +0 -8
  73. data/tests/requests/compute/vm_suspend_tests.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 95375060abd33bf28937dfdc793ecbfcefb1a612d4a639456c0a304ac7641a25
4
- data.tar.gz: 7550cbe2aee4325dafaff388c2546470a82cd893aad7818f52302f4005f5df2f
2
+ SHA1:
3
+ metadata.gz: 63a4262cd25dd64e24bcf3d02231bc108a678e14
4
+ data.tar.gz: bae6e27a2c111effe8440ceb4b308fb15190a792
5
5
  SHA512:
6
- metadata.gz: 032576f8e9d1c11dee28a26625d72f23c4c50c60fce93480b3cacb97c0ad13c98c182357acbcf2106138eaa6edf39a83dfd70fa86939f367cf32d017ab44fc8c
7
- data.tar.gz: 215eb88241d55311ecfcd45f2e85a2fd3a6b52ed9806418d8bfc7767e82559390f0f5e71b623a5a8ffe62272f304d7c1fae5fec261ad43cab0fb5bebcc1514de
6
+ metadata.gz: 47dcd8b6aa212d64564beee1d2a22bd64d38529fceccd4752baff6bde4cced8130792fefe29a145201a5ba9695f65abbebd25e969e68f69e95b339c2526b7679
7
+ data.tar.gz: ff2a5bdb21167a04acd97a87fa756d25bf043009ade394c9cce5e8ea7934c429c39a956e4fa0fe6be881c6e94ad1cc7708024582dd35d2b0efd1bba69bbbcadc
data/.gitignore CHANGED
@@ -20,5 +20,4 @@ tmp
20
20
  *.o
21
21
  *.a
22
22
  mkmf.log
23
- gemfiles/*.lock
24
- .*.swp
23
+ gemfiles/*.lock
data/.travis.yml CHANGED
@@ -6,19 +6,20 @@ matrix:
6
6
  - rvm: jruby-head
7
7
  fast_finish: true
8
8
  include:
9
+ - rvm: 1.9.3
10
+ gemfile: gemfiles/Gemfile.1.9.2+
9
11
  - rvm: 2.0.0
10
12
  gemfile: Gemfile
11
- - rvm: 2.1.10
13
+ - rvm: 2.1.0
12
14
  gemfile: Gemfile
13
- - rvm: 2.2.6
15
+ - rvm: 2.1.1
14
16
  gemfile: Gemfile
15
- - rvm: 2.3.3
16
- gemfile: Gemfile
17
- - rvm: 2.4.0
17
+ - rvm: 2.2.0
18
18
  gemfile: Gemfile
19
+ - rvm: jruby-19mode
20
+ gemfile: gemfiles/Gemfile.1.9.2+
19
21
  - rvm: jruby-head
20
22
  gemfile: Gemfile
21
- script: bundle exec rake travis:ci
22
23
  notifications:
23
24
  email: false
24
25
  addons:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
+ ## v1.7.1
2
+
3
+ * Send all options to VM migrate request
4
+ * Fix VM clone with resource pool
5
+ * Remove obsolete index argument to create_disk call
6
+ * Fix error when creating volume using the wrong key name
7
+
1
8
  ## v1.7.0
2
9
 
10
+ * Update volumes when `save` is called on Server
11
+ * Add the ability to update the size of attached virtual disks
3
12
  * Improve mocks for folders and networks
4
13
 
5
14
  ## v1.6.0
@@ -12,15 +21,17 @@
12
21
 
13
22
  ## v1.5.1
14
23
 
15
- * Removed for hotfix
24
+ * Move volume key generation to volume model
25
+ * Set defaults more reliably for SCSI
16
26
 
17
27
  ## v1.5.0
18
28
 
19
29
  * Rename the get_spec method in create_rule to get_group_spec
30
+ * Change modify_vm_controller to follow changes made to create_controller
20
31
 
21
32
  ## v1.4.0
22
33
 
23
- * Removed for hotfix
34
+ * Add ability for VMs to have multiple SCSI controllers
24
35
 
25
36
  ## v1.3.0
26
37
 
data/CONTRIBUTORS.md CHANGED
@@ -4,13 +4,11 @@
4
4
  * Ben Talbot - btalbot <ben_t48@hotmail.com>
5
5
  * Carl Caum <carl@carlcaum.com>
6
6
  * Carlos Sanchez <csanchez@maestrodev.com>
7
- * Chris Roberts <chrobert@redhat.com>
8
7
  * Chris Thompson <chris.thompson@govdelivery.com>
9
8
  * Chris Thompson <teaforthecat@gmail.com>
10
9
  * Christopher Oliver <coliver@datapipe.com>
11
10
  * Cyrus Team <cyrusteam@cyruslists.com>
12
11
  * Darren Foo <stonith@users.noreply.github.com>
13
- * Derek Wright <derekmwright@users.noreply.github.com>
14
12
  * Dominic Cleal <dcleal@redhat.com>
15
13
  * Eric Stonfer <ericstonfer@yahoo.com>
16
14
  * Ewoud Kohl van Wijngaarden <ewoud@kohlvanwijngaarden.nl>
@@ -38,7 +36,6 @@
38
36
  * Lukas Zapletal <lzap+git@redhat.com>
39
37
  * Marc Grimme <grimme@atix.de>
40
38
  * Marc Grimme <marc.grimme@googlemail.com>
41
- * Marek Hulan <mhulan@redhat.com>
42
39
  * Martin Matuska <martin@matuska.org>
43
40
  * Matt Darby <matt.darby@rackspace.com>
44
41
  * Matthew Black <matthew.black@sap.com>
@@ -63,10 +60,8 @@
63
60
  * Shlomi Zadok <shlomi@ben-hanna.com>
64
61
  * Simon Josi <me@yokto.net>
65
62
  * Tejas Ravindra Mandke <tejas@identified.com>
66
- * Timo Goebel <mail@timogoebel.name>
67
63
  * Timo Goebel <timo.goebel@dm.de>
68
64
  * Timur Alperovich <timur@maginatics.com>
69
- * Tyler Gregory <01100010011001010110010101110000@users.noreply.github.com>
70
65
  * Wesley Beary <geemus+github@gmail.com>
71
66
  * Wesley Beary <geemus@gmail.com>
72
67
  * Xavier Fontrodona <xavier.fontrodona@safelayer.com>
@@ -77,8 +72,5 @@
77
72
  * karmab <karimboumedhel@gmail.com>
78
73
  * karimb <karimboumedhel@gmail.com>
79
74
  * milo_cheung <milo.cheung@appcara.com>
80
- * scottd018 <scottd018@users.noreply.github.com>
81
75
  * slivik <jakub.sliva@gmail.com>
82
- * theOpenBit <theopenbit@users.noreply.github.com>
83
76
  * tipt0e <topo-2@charter.net>
84
- * wiad <adam.winberg@gmail.com>
data/Rakefile CHANGED
@@ -1,17 +1,8 @@
1
1
  require 'bundler/gem_tasks'
2
- require 'rubocop/rake_task'
3
-
4
- desc 'Run Ruby style checks'
5
- RuboCop::RakeTask.new(:style)
6
-
7
- namespace :travis do
8
- desc 'Run tests on Travis'
9
- task ci: %w(style test)
10
- end
11
2
 
12
3
  mock = ENV['FOG_MOCK'] || 'true'
13
4
  task :test do
14
5
  sh("export FOG_MOCK=#{mock} && bundle exec shindont")
15
6
  end
16
7
 
17
- task(default: [:test])
8
+ task(:default => [:test])
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'codeclimate-test-reporter', '~> 1.0', group: :test, require: nil
4
+ gem 'json', '~> 1.8.0'
5
+ gem 'net-ssh', '~> 2.9'
6
+ gem 'rubocop', '~> 0.41.0'
7
+ gem 'simplecov', '~> 0.12.0'
8
+
9
+ gemspec :path => '..'
@@ -89,6 +89,7 @@ module Fog
89
89
  request :get_virtual_machine
90
90
  request :vm_reconfig_hardware
91
91
  request :vm_reconfig_memory
92
+ request :vm_reconfig_volumes
92
93
  request :vm_reconfig_cpus
93
94
  request :vm_reconfig_cdrom
94
95
  request :vm_config_vnc
@@ -100,6 +101,7 @@ module Fog
100
101
  request :list_vm_customvalues
101
102
  request :list_customfields
102
103
  request :get_vm_first_scsi_controller
104
+ request :list_vm_scsi_controllers
103
105
  request :set_vm_customvalue
104
106
  request :vm_take_snapshot
105
107
  request :list_vm_snapshots
@@ -5,9 +5,14 @@ module Fog
5
5
  attribute :shared_bus
6
6
  attribute :type
7
7
  attribute :unit_number
8
- attribute :key
8
+ attribute :key, :type => :integer
9
9
  attribute :server_id
10
10
 
11
+ def initialize(attributes = {})
12
+ super
13
+ self.key ||= 1000
14
+ end
15
+
11
16
  def to_s
12
17
  "#{type} ##{key}: shared: #{shared_bus}, unit_number: #{unit_number}"
13
18
  end
@@ -6,6 +6,7 @@ module Fog
6
6
  class Server < Fog::Compute::Server
7
7
  extend Fog::Deprecation
8
8
  deprecate(:ipaddress, :public_ip_address)
9
+ deprecate(:scsi_controller, :scsi_controllers)
9
10
 
10
11
  # This will be the instance uuid which is globally unique across
11
12
  # a vSphere deployment.
@@ -45,7 +46,7 @@ module Fog
45
46
  attribute :instance_uuid # move this --> id
46
47
  attribute :guest_id
47
48
  attribute :hardware_version
48
- attribute :scsi_controller # this is the first scsi controller. Right now no more of them can be used.
49
+ attribute :scsi_controllers, :type => :array
49
50
  attribute :cpuHotAddEnabled
50
51
  attribute :memoryHotAddEnabled
51
52
  attribute :firmware
@@ -57,7 +58,7 @@ module Fog
57
58
  initialize_interfaces
58
59
  initialize_volumes
59
60
  initialize_customvalues
60
- initialize_scsi_controller
61
+ initialize_scsi_controllers
61
62
  end
62
63
 
63
64
  # Lazy Loaded Attributes
@@ -79,6 +80,11 @@ module Fog
79
80
  service.vm_reconfig_cpus('instance_uuid' => instance_uuid, 'cpus' => cpus, 'corespersocket' => corespersocket)
80
81
  end
81
82
 
83
+ def vm_reconfig_volumes(options = {})
84
+ requires :instance_uuid, :volumes
85
+ service.vm_reconfig_volumes('instance_uuid' => instance_uuid, 'volumes' => volumes)
86
+ end
87
+
82
88
  def vm_reconfig_hardware(hardware_spec, options = {})
83
89
  requires :instance_uuid
84
90
  service.vm_reconfig_hardware('instance_uuid' => instance_uuid, 'hardware_spec' => hardware_spec)
@@ -114,7 +120,14 @@ module Fog
114
120
  def migrate(options = {})
115
121
  options = { :priority => 'defaultPriority' }.merge(options)
116
122
  requires :instance_uuid
117
- service.vm_migrate('instance_uuid' => instance_uuid, 'priority' => options[:priority])
123
+
124
+ # Convert symbols to strings
125
+ req_options = options.reduce({}) { |hsh, (k,v)| hsh[k.to_s] = v; hsh }
126
+ req_options['cluster'] ||= cluster
127
+ req_options['datacenter'] = "#{datacenter}"
128
+ req_options['instance_uuid'] = instance_uuid
129
+
130
+ service.vm_migrate(req_options)
118
131
  end
119
132
 
120
133
  # Clone from a server object
@@ -255,8 +268,12 @@ module Fog
255
268
  attributes[:customvalues] ||= id.nil? ? [] : service.customvalues( :vm => self )
256
269
  end
257
270
 
271
+ def scsi_controllers
272
+ self.attributes[:scsi_controllers] ||= service.list_vm_scsi_controllers(id)
273
+ end
274
+
258
275
  def scsi_controller
259
- self.attributes[:scsi_controller] ||= service.get_vm_first_scsi_controller(id)
276
+ scsi_controllers.first
260
277
  end
261
278
 
262
279
  def folder
@@ -269,6 +286,7 @@ module Fog
269
286
  if persisted?
270
287
  vm_reconfig_cpus if attribute_changed?(:cpus) || attribute_changed?(:corespersocket)
271
288
  vm_reconfig_memory if attribute_changed?(:memory_mb)
289
+ vm_reconfig_volumes if attribute_changed?(:volumes)
272
290
  else
273
291
  self.id = service.create_vm(attributes)
274
292
  end
@@ -314,7 +332,7 @@ module Fog
314
332
 
315
333
  def initialize_volumes
316
334
  if attributes[:volumes] and attributes[:volumes].is_a?(Array)
317
- self.attributes[:volumes].map! { |vol| vol.is_a?(Hash) ? service.volumes.new(vol) : vol }
335
+ self.attributes[:volumes].map! { |vol| vol.is_a?(Hash) ? service.volumes.new({:server => self}.merge(vol)) : vol }
318
336
  end
319
337
  end
320
338
 
@@ -324,9 +342,20 @@ module Fog
324
342
  end
325
343
  end
326
344
 
327
- def initialize_scsi_controller
328
- if attributes[:scsi_controller] and attributes[:scsi_controller].is_a?(Hash)
329
- Fog::Compute::Vsphere::SCSIController.new(self.attributes[:scsi_controller])
345
+ def initialize_scsi_controllers
346
+ if attributes[:scsi_controllers] && attributes[:scsi_controllers].is_a?(Array)
347
+ self.attributes[:scsi_controllers].map! do |controller|
348
+ controller.is_a?(Hash) ? Fog::Compute::Vsphere::SCSIController.new(controller) : controller
349
+ end
350
+ elsif attributes[:scsi_controller] && attributes[:scsi_controller].is_a?(Hash)
351
+ self.attributes[:scsi_controllers] = [
352
+ Fog::Compute::Vsphere::SCSIController.new(self.attributes[:scsi_controller])
353
+ ]
354
+ elsif attributes[:volumes] && attributes[:volumes].is_a?(Array) && !attributes[:volumes].empty?
355
+ # Create a default scsi controller if there are any disks but no controller defined
356
+ self.attributes[:scsi_controllers] = [
357
+ Fog::Compute::Vsphere::SCSIController.new
358
+ ]
330
359
  end
331
360
  end
332
361
 
@@ -5,6 +5,7 @@ module Fog
5
5
  DISK_SIZE_TO_GB = 1048576
6
6
  identity :id
7
7
 
8
+ has_one :server, Server
8
9
  attribute :datastore
9
10
  attribute :storage_pod
10
11
  attribute :mode
@@ -16,12 +17,9 @@ module Fog
16
17
  attribute :size_gb
17
18
  attribute :key
18
19
  attribute :unit_number
19
- attribute :server_id
20
-
21
- def initialize(attributes={} )
22
- # Assign server first to prevent race condition with persisted?
23
- self.server_id = attributes.delete(:server_id)
20
+ attribute :controller_key, :type => :integer
24
21
 
22
+ def initialize(attributes={})
25
23
  super defaults.merge(attributes)
26
24
  end
27
25
 
@@ -31,6 +29,7 @@ module Fog
31
29
 
32
30
  def size_gb= s
33
31
  attributes[:size] = s.to_i * DISK_SIZE_TO_GB if s
32
+ attributes[:size_gb] = s.to_i if s
34
33
  end
35
34
 
36
35
  def to_s
@@ -48,25 +47,7 @@ module Fog
48
47
  raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted?
49
48
  requires :server_id, :size, :datastore
50
49
 
51
- # When adding volumes to vsphere, if our unit_number is 7 or higher, vsphere will increment the unit_number
52
- # This is due to SCSI ID 7 being reserved for the pvscsi controller
53
- # When referring to a volume that already added using a unit_id of 7 or higher, we must refer to the actual SCSI ID
54
- if unit_number.nil?
55
- # Vsphere maps unit_numbers 7 and greater to a higher SCSI ID since the pvscsi driver reserves SCSI ID 7
56
- used_unit_numbers = server.volumes.map { |volume| volume.unit_number < 7 ? volume.unit_number : volume.unit_number - 1 }
57
- max_unit_number = used_unit_numbers.max
58
-
59
- if max_unit_number > server.volumes.size
60
- # If the max ID exceeds the number of volumes, there must be a hole in the range. Find a hole and use it.
61
- self.unit_number = max_unit_number.times.to_a.find { |i| used_unit_numbers.exclude?(i) }
62
- else
63
- self.unit_number = max_unit_number + 1
64
- end
65
- else
66
- if server.volumes.any? { |volume| volume.unit_number == self.unit_number && volume.id != self.id }
67
- raise "A volume already exists with that unit_number, so we can't save the new volume"
68
- end
69
- end
50
+ set_unit_number
70
51
 
71
52
  data = service.add_vm_volume(self)
72
53
 
@@ -78,8 +59,25 @@ module Fog
78
59
  # We have to query vSphere to get the volume attributes since the task handle doesn't include that info.
79
60
  created = server.volumes.all.find { |volume| volume.unit_number == self.unit_number }
80
61
 
62
+ # example of "created" =>
63
+ # <Fog::Compute::Vsphere::Volume
64
+ # id="6000C295-576f-0e2d-5b70-c778cd108b3a",
65
+ # datastore="datastore1",
66
+ # storage_pod=nil,
67
+ # mode="persistent",
68
+ # size=10485760,
69
+ # thin=true,
70
+ # eager_zero=nil,
71
+ # name="Hard disk 2",
72
+ # filename="[datastore1] testvm/testvm_2.vmdk",
73
+ # size_gb=10,
74
+ # key=2004,
75
+ # unit_number=2,
76
+ # controller_key=1000
77
+ # >
81
78
  self.id = created.id
82
79
  self.key = created.key
80
+ self.controller_key = created.controller_key
83
81
  self.filename = created.filename
84
82
 
85
83
  true
@@ -88,9 +86,33 @@ module Fog
88
86
  end
89
87
  end
90
88
 
91
- def server
92
- requires :server_id
93
- service.servers.get(server_id)
89
+ def server_id
90
+ requires :server
91
+ server.id
92
+ end
93
+
94
+ def set_unit_number
95
+ # When adding volumes to vsphere, if our unit_number is 7 or higher, vsphere will increment the unit_number
96
+ # This is due to SCSI ID 7 being reserved for the pvscsi controller
97
+ # When referring to a volume that already added using a unit_id of 7 or higher, we must refer to the actual SCSI ID
98
+ if unit_number.nil?
99
+ self.unit_number = calculate_free_unit_number
100
+ else
101
+ if server.volumes.select { |vol| vol.controller_key == controller_key }.any? { |volume| volume.unit_number == self.unit_number && volume.id != self.id }
102
+ raise "A volume already exists with that unit_number, so we can't save the new volume"
103
+ end
104
+ end
105
+ end
106
+
107
+ def set_key
108
+ requires :controller_key, :unit_number
109
+
110
+ return unless key.nil?
111
+
112
+ # controller key is based on 1000 + controller bus
113
+ # disk key is based on 2000 + the SCSI ID + the controller bus * 16
114
+ controller_bus = controller_key - 1000
115
+ self.key = 2000 + (controller_bus * 16) + unit_number
94
116
  end
95
117
 
96
118
  private
@@ -99,9 +121,21 @@ module Fog
99
121
  {
100
122
  :thin => true,
101
123
  :name => "Hard disk",
102
- :mode => "persistent"
124
+ :mode => "persistent",
125
+ :controller_key => 1000
103
126
  }
104
127
  end
128
+
129
+ def calculate_free_unit_number
130
+ requires :controller_key
131
+
132
+ # Vsphere maps unit_numbers 7 and greater to a higher SCSI ID since the pvscsi driver reserves SCSI ID 7
133
+ used_unit_numbers = server.volumes
134
+ .select { |vol| vol.unit_number && vol.controller_key == controller_key }.map(&:unit_number) + [7]
135
+ free_unit_numbers = (0..15).to_a - used_unit_numbers
136
+
137
+ free_unit_numbers.first
138
+ end
105
139
  end
106
140
  end
107
141
  end
@@ -20,7 +20,7 @@ module Fog
20
20
  raise 'volumes should have vm or template'
21
21
  end
22
22
 
23
- self.each { |volume| volume.server_id = server.id }
23
+ self.each { |volume| volume.server = server }
24
24
  self
25
25
  end
26
26