fog-vsphere 1.7.0.1 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
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