bosh_vsphere_cpi 0.6.0 → 1.5.0.pre.1100

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/bin/vsphere_cpi_console +35 -0
  2. data/db/migrations/20120123235022_initial.rb +5 -0
  3. data/lib/cloud/vsphere/client.rb +4 -5
  4. data/lib/cloud/vsphere/cloud.rb +245 -226
  5. data/lib/cloud/vsphere/config.rb +0 -4
  6. data/lib/cloud/vsphere/models/disk.rb +3 -0
  7. data/lib/cloud/vsphere/path_finder.rb +12 -0
  8. data/lib/cloud/vsphere/resources.rb +0 -2
  9. data/lib/cloud/vsphere/version.rb +1 -1
  10. data/lib/cloud/vsphere.rb +5 -3
  11. data/lib/ruby_vim_sdk/base_type.rb +15 -0
  12. data/lib/ruby_vim_sdk/const.rb +32 -0
  13. data/lib/ruby_vim_sdk/core_types.rb +68 -0
  14. data/lib/ruby_vim_sdk/data_type.rb +14 -0
  15. data/lib/ruby_vim_sdk/enum_type.rb +12 -0
  16. data/lib/ruby_vim_sdk/ext.rb +9 -0
  17. data/lib/ruby_vim_sdk/managed_type.rb +12 -0
  18. data/lib/ruby_vim_sdk/method.rb +37 -0
  19. data/lib/ruby_vim_sdk/missing_types.rb +11 -0
  20. data/lib/ruby_vim_sdk/property.rb +49 -0
  21. data/lib/ruby_vim_sdk/server_objects.rb +2718 -0
  22. data/lib/ruby_vim_sdk/soap/deserializer.rb +301 -0
  23. data/lib/ruby_vim_sdk/soap/serializer.rb +225 -0
  24. data/lib/ruby_vim_sdk/soap/stub_adapter.rb +123 -0
  25. data/lib/ruby_vim_sdk/soap_exception.rb +12 -0
  26. data/lib/ruby_vim_sdk/typed_array.rb +9 -0
  27. data/lib/ruby_vim_sdk/types.rb +22 -0
  28. data/lib/ruby_vim_sdk/version.rb +5 -0
  29. data/lib/ruby_vim_sdk/vmodl/data_object.rb +102 -0
  30. data/lib/ruby_vim_sdk/vmodl/managed_object.rb +78 -0
  31. data/lib/ruby_vim_sdk/vmodl/method_name.rb +7 -0
  32. data/lib/ruby_vim_sdk/vmodl/property_path.rb +7 -0
  33. data/lib/ruby_vim_sdk/vmodl/type_name.rb +7 -0
  34. data/lib/ruby_vim_sdk/vmodl_helper.rb +33 -0
  35. data/lib/ruby_vim_sdk/vmomi_support.rb +280 -0
  36. data/lib/ruby_vim_sdk.rb +45 -0
  37. metadata +65 -53
  38. data/Rakefile +0 -50
  39. data/spec/spec_helper.rb +0 -33
  40. data/spec/unit/cloud/vsphere/resources/cluster_spec.rb +0 -383
  41. data/spec/unit/cloud/vsphere/resources/datacenter_spec.rb +0 -72
  42. data/spec/unit/cloud/vsphere/resources/datastore_spec.rb +0 -43
  43. data/spec/unit/cloud/vsphere/resources/folder_spec.rb +0 -63
  44. data/spec/unit/cloud/vsphere/resources/resource_pool_spec.rb +0 -42
  45. data/spec/unit/cloud/vsphere/resources/scorer_spec.rb +0 -73
  46. data/spec/unit/cloud/vsphere/resources/util_spec.rb +0 -35
  47. data/spec/unit/cloud/vsphere/resources_spec.rb +0 -216
@@ -1,26 +1,27 @@
1
- require "rubygems"
2
- require "membrane"
3
- require "ruby_vim_sdk"
4
-
5
- require "cloud/vsphere/client"
6
- require "cloud/vsphere/config"
7
- require "cloud/vsphere/lease_updater"
8
- require "cloud/vsphere/resources"
9
- require "cloud/vsphere/resources/cluster"
10
- require "cloud/vsphere/resources/datacenter"
11
- require "cloud/vsphere/resources/datastore"
12
- require "cloud/vsphere/resources/folder"
13
- require "cloud/vsphere/resources/resource_pool"
14
- require "cloud/vsphere/resources/scorer"
15
- require "cloud/vsphere/resources/util"
16
- require "cloud/vsphere/models/disk"
1
+ require 'json'
2
+ require 'membrane'
3
+ require 'ruby_vim_sdk'
4
+ require 'cloud/vsphere/client'
5
+ require 'cloud/vsphere/config'
6
+ require 'cloud/vsphere/lease_updater'
7
+ require 'cloud/vsphere/resources'
8
+ require 'cloud/vsphere/resources/cluster'
9
+ require 'cloud/vsphere/resources/datacenter'
10
+ require 'cloud/vsphere/resources/datastore'
11
+ require 'cloud/vsphere/resources/folder'
12
+ require 'cloud/vsphere/resources/resource_pool'
13
+ require 'cloud/vsphere/resources/scorer'
14
+ require 'cloud/vsphere/resources/util'
15
+ require 'cloud/vsphere/models/disk'
16
+ require 'cloud/vsphere/path_finder'
17
17
 
18
18
  module VSphereCloud
19
19
 
20
20
  class Cloud < Bosh::Cloud
21
21
  include VimSdk
22
22
 
23
- class TimeoutException < StandardError; end
23
+ class TimeoutException < StandardError;
24
+ end
24
25
 
25
26
  attr_accessor :client
26
27
 
@@ -47,10 +48,21 @@ module VSphereCloud
47
48
  end
48
49
  end
49
50
 
51
+ setup_at_exit
52
+ end
53
+
54
+ def setup_at_exit
50
55
  # HACK: finalizer not getting called, so we'll rely on at_exit
51
56
  at_exit { @client.logout }
52
57
  end
53
58
 
59
+ def has_vm?(vm_cid)
60
+ get_vm_by_cid(vm_cid)
61
+ true
62
+ rescue Bosh::Clouds::VMNotFound
63
+ false
64
+ end
65
+
54
66
  def create_stemcell(image, _)
55
67
  with_thread_name("create_stemcell(#{image}, _)") do
56
68
  result = nil
@@ -59,14 +71,13 @@ module VSphereCloud
59
71
  output = `tar -C #{temp_dir} -xzf #{image} 2>&1`
60
72
  raise "Corrupt image, tar exit status: #{$?.exitstatus} output: #{output}" if $?.exitstatus != 0
61
73
 
62
- ovf_file = Dir.entries(temp_dir).find { |entry| File.extname(entry) == ".ovf" }
63
- raise "Missing OVF" if ovf_file.nil?
74
+ ovf_file = Dir.entries(temp_dir).find { |entry| File.extname(entry) == '.ovf' }
75
+ raise 'Missing OVF' if ovf_file.nil?
64
76
  ovf_file = File.join(temp_dir, ovf_file)
65
77
 
66
78
  name = "sc-#{generate_unique_name}"
67
79
  @logger.info("Generated name: #{name}")
68
80
 
69
- # TODO: make stemcell friendly version of the calls below
70
81
  stemcell_size = File.size(image) / (1024 * 1024)
71
82
  cluster, datastore = @resources.place(0, stemcell_size, [])
72
83
  @logger.info("Deploying to: #{cluster.mob} / #{datastore.mob}")
@@ -74,16 +85,16 @@ module VSphereCloud
74
85
  import_spec_result = import_ovf(name, ovf_file, cluster.resource_pool.mob, datastore.mob)
75
86
  lease = obtain_nfc_lease(cluster.resource_pool.mob, import_spec_result.import_spec,
76
87
  cluster.datacenter.template_folder.mob)
77
- @logger.info("Waiting for NFC lease")
88
+ @logger.info('Waiting for NFC lease')
78
89
  state = wait_for_nfc_lease(lease)
79
- raise "Could not acquire HTTP NFC lease" unless state == Vim::HttpNfcLease::State::READY
90
+ raise "Could not acquire HTTP NFC lease (state is: #{state})" unless state == Vim::HttpNfcLease::State::READY
80
91
 
81
- @logger.info("Uploading")
92
+ @logger.info('Uploading')
82
93
  vm = upload_ovf(ovf_file, lease, import_spec_result.file_item)
83
94
  result = name
84
95
 
85
- @logger.info("Removing NICs")
86
- devices = client.get_property(vm, Vim::VirtualMachine, "config.hardware.device", :ensure_all => true)
96
+ @logger.info('Removing NICs')
97
+ devices = client.get_property(vm, Vim::VirtualMachine, 'config.hardware.device', ensure_all: true)
87
98
  config = Vim::Vm::ConfigSpec.new
88
99
  config.device_change = []
89
100
 
@@ -94,8 +105,11 @@ module VSphereCloud
94
105
  end
95
106
  client.reconfig_vm(vm, config)
96
107
 
97
- @logger.info("Taking initial snapshot")
98
- task = take_snapshot(vm, "initial")
108
+ @logger.info('Taking initial snapshot')
109
+
110
+ # Despite the naming, this has nothing to do with the Cloud notion of a disk snapshot
111
+ # (which comes from AWS). This is a vm snapshot.
112
+ task = vm.create_snapshot('initial', nil, false, false)
99
113
  client.wait_for_task(task)
100
114
  end
101
115
  result
@@ -104,14 +118,14 @@ module VSphereCloud
104
118
 
105
119
  def delete_stemcell(stemcell)
106
120
  with_thread_name("delete_stemcell(#{stemcell})") do
107
- Bosh::ThreadPool.new(:max_threads => 32, :logger => @logger).wrap do |pool|
121
+ Bosh::ThreadPool.new(max_threads: 32, logger: @logger).wrap do |pool|
108
122
  @resources.datacenters.each_value do |datacenter|
109
123
  @logger.info("Looking for stemcell replicas in: #{datacenter.name}")
110
- templates = client.get_property(datacenter.template_folder.mob, Vim::Folder, "childEntity", :ensure_all => true)
111
- template_properties = client.get_properties(templates, Vim::VirtualMachine, ["name"])
124
+ templates = client.get_property(datacenter.template_folder.mob, Vim::Folder, 'childEntity', ensure_all: true)
125
+ template_properties = client.get_properties(templates, Vim::VirtualMachine, ['name'])
112
126
  template_properties.each_value do |properties|
113
- template_name = properties["name"].gsub("%2f", "/")
114
- if template_name.split("/").first.strip == stemcell
127
+ template_name = properties['name'].gsub('%2f', '/')
128
+ if template_name.split('/').first.strip == stemcell
115
129
  @logger.info("Found: #{template_name}")
116
130
  pool.process do
117
131
  @logger.info("Deleting: #{template_name}")
@@ -129,11 +143,11 @@ module VSphereCloud
129
143
  disks = []
130
144
  if persistent_disks
131
145
  persistent_disks.each do |disk_cid|
132
- disk = Models::Disk.first(:uuid => disk_cid)
146
+ disk = Models::Disk.first(uuid: disk_cid)
133
147
  disks << {
134
- :size => disk.size,
135
- :dc_name => disk.datacenter,
136
- :ds_name => disk.datastore
148
+ size: disk.size,
149
+ dc_name: disk.datacenter,
150
+ ds_name: disk.datastore
137
151
  }
138
152
  end
139
153
  end
@@ -142,15 +156,14 @@ module VSphereCloud
142
156
 
143
157
  def stemcell_vm(name)
144
158
  dc = @resources.datacenters.values.first
145
- client.find_by_inventory_path(
146
- [dc.name, "vm", dc.template_folder.name, name])
159
+ client.find_by_inventory_path([dc.name, 'vm', dc.template_folder.name, name])
147
160
  end
148
161
 
149
162
  def create_vm(agent_id, stemcell, resource_pool, networks, disk_locality = nil, environment = nil)
150
163
  with_thread_name("create_vm(#{agent_id}, ...)") do
151
- memory = resource_pool["ram"]
152
- disk = resource_pool["disk"]
153
- cpu = resource_pool["cpu"]
164
+ memory = resource_pool['ram']
165
+ disk = resource_pool['disk']
166
+ cpu = resource_pool['cpu']
154
167
 
155
168
  # Make sure number of cores is a power of 2. kb.vmware.com/kb/2003484
156
169
  if cpu & cpu - 1 != 0
@@ -160,9 +173,8 @@ module VSphereCloud
160
173
  stemcell_vm = stemcell_vm(stemcell)
161
174
  raise "Could not find stemcell: #{stemcell}" if stemcell_vm.nil?
162
175
 
163
- stemcell_size = client.get_property(
164
- stemcell_vm, Vim::VirtualMachine, "summary.storage.committed",
165
- :ensure_all => true)
176
+ stemcell_size =
177
+ client.get_property(stemcell_vm, Vim::VirtualMachine, 'summary.storage.committed', ensure_all: true)
166
178
  stemcell_size /= 1024 * 1024
167
179
 
168
180
  disks = disk_spec(disk_locality)
@@ -175,27 +187,27 @@ module VSphereCloud
175
187
 
176
188
  replicated_stemcell_vm = replicate_stemcell(cluster, datastore, stemcell)
177
189
  replicated_stemcell_properties = client.get_properties(replicated_stemcell_vm, Vim::VirtualMachine,
178
- ["config.hardware.device", "snapshot"],
179
- :ensure_all => true)
190
+ ['config.hardware.device', 'snapshot'],
191
+ ensure_all: true)
180
192
 
181
- devices = replicated_stemcell_properties["config.hardware.device"]
182
- snapshot = replicated_stemcell_properties["snapshot"]
193
+ devices = replicated_stemcell_properties['config.hardware.device']
194
+ snapshot = replicated_stemcell_properties['snapshot']
183
195
 
184
- config = Vim::Vm::ConfigSpec.new(:memory_mb => memory, :num_cpus => cpu)
196
+ config = Vim::Vm::ConfigSpec.new(memory_mb: memory, num_cpus: cpu)
185
197
  config.device_change = []
186
198
 
187
199
  system_disk = devices.find { |device| device.kind_of?(Vim::Vm::Device::VirtualDisk) }
188
200
  pci_controller = devices.find { |device| device.kind_of?(Vim::Vm::Device::VirtualPCIController) }
189
201
 
190
202
  file_name = "[#{datastore.name}] #{name}/ephemeral_disk.vmdk"
191
- ephemeral_disk_config = create_disk_config_spec(datastore.mob, file_name, system_disk.controller_key, disk,
192
- :create => true)
203
+ ephemeral_disk_config =
204
+ create_disk_config_spec(datastore.mob, file_name, system_disk.controller_key, disk, create: true)
193
205
  config.device_change << ephemeral_disk_config
194
206
 
195
207
  dvs_index = {}
196
208
  networks.each_value do |network|
197
- v_network_name = network["cloud_properties"]["name"]
198
- network_mob = client.find_by_inventory_path([cluster.datacenter.name, "network", v_network_name])
209
+ v_network_name = network['cloud_properties']['name']
210
+ network_mob = client.find_by_inventory_path([cluster.datacenter.name, 'network', v_network_name])
199
211
  nic_config = create_nic_config_spec(v_network_name, network_mob, pci_controller.key, dvs_index)
200
212
  config.device_change << nic_config
201
213
  end
@@ -210,16 +222,18 @@ module VSphereCloud
210
222
 
211
223
  @logger.info("Cloning vm: #{replicated_stemcell_vm} to #{name}")
212
224
 
213
- task = clone_vm(replicated_stemcell_vm, name, cluster.datacenter.vm_folder.mob, cluster.resource_pool.mob,
214
- :datastore => datastore.mob, :linked => true, :snapshot => snapshot.current_snapshot,
215
- :config => config)
225
+ task = clone_vm(replicated_stemcell_vm,
226
+ name,
227
+ cluster.datacenter.vm_folder.mob,
228
+ cluster.resource_pool.mob,
229
+ datastore: datastore.mob, linked: true, snapshot: snapshot.current_snapshot, config: config)
216
230
  vm = client.wait_for_task(task)
217
231
 
218
232
  begin
219
- upload_file(cluster.datacenter.name, datastore.name, "#{name}/env.iso", "")
233
+ upload_file(cluster.datacenter.name, datastore.name, "#{name}/env.iso", '')
220
234
 
221
- vm_properties = client.get_properties(vm, Vim::VirtualMachine, ["config.hardware.device"], :ensure_all => true)
222
- devices = vm_properties["config.hardware.device"]
235
+ vm_properties = client.get_properties(vm, Vim::VirtualMachine, ['config.hardware.device'], ensure_all: true)
236
+ devices = vm_properties['config.hardware.device']
223
237
 
224
238
  # Configure the ENV CDROM
225
239
  config = Vim::Vm::ConfigSpec.new
@@ -232,12 +246,11 @@ module VSphereCloud
232
246
  network_env = generate_network_env(devices, networks, dvs_index)
233
247
  disk_env = generate_disk_env(system_disk, ephemeral_disk_config.device)
234
248
  env = generate_agent_env(name, vm, agent_id, network_env, disk_env)
235
- env["env"] = environment
249
+ env['env'] = environment
236
250
  @logger.info("Setting VM env: #{env.pretty_inspect}")
237
251
 
238
- location = get_vm_location(vm, :datacenter => cluster.datacenter.name,
239
- :datastore => datastore.name,
240
- :vm => name)
252
+ location =
253
+ get_vm_location(vm, datacenter: cluster.datacenter.name, datastore: datastore.name, vm: name)
241
254
  set_agent_env(vm, location, env)
242
255
 
243
256
  @logger.info("Powering on VM: #{vm} (#{name})")
@@ -258,7 +271,7 @@ module VSphereCloud
258
271
  result = yield
259
272
  break
260
273
  rescue RuntimeError
261
- raise if i + 1 >= num
274
+ raise if i + 1 >= num
262
275
  end
263
276
  end
264
277
  result
@@ -270,20 +283,24 @@ module VSphereCloud
270
283
 
271
284
  vm = get_vm_by_cid(vm_cid)
272
285
  datacenter = client.find_parent(vm, Vim::Datacenter)
273
- properties = client.get_properties(vm, Vim::VirtualMachine, ["runtime.powerState", "runtime.question",
274
- "config.hardware.device", "name"],
275
- :ensure => ["config.hardware.device"])
286
+ properties =
287
+ client.get_properties(
288
+ vm,
289
+ Vim::VirtualMachine,
290
+ ['runtime.powerState', 'runtime.question', 'config.hardware.device', 'name'],
291
+ ensure: ['config.hardware.device']
292
+ )
276
293
 
277
294
  retry_block do
278
- question = properties["runtime.question"]
295
+ question = properties['runtime.question']
279
296
  if question
280
297
  choices = question.choice
281
298
  @logger.info("VM is blocked on a question: #{question.text}, " +
282
- "providing default answer: #{choices.choice_info[choices.default_index].label}")
299
+ "providing default answer: #{choices.choice_info[choices.default_index].label}")
283
300
  client.answer_vm(vm, question.id, choices.choice_info[choices.default_index].key)
284
- power_state = client.get_property(vm, Vim::VirtualMachine, "runtime.powerState")
301
+ power_state = client.get_property(vm, Vim::VirtualMachine, 'runtime.powerState')
285
302
  else
286
- power_state = properties["runtime.powerState"]
303
+ power_state = properties['runtime.powerState']
287
304
  end
288
305
 
289
306
  if power_state != Vim::VirtualMachine::PowerState::POWERED_OFF
@@ -293,9 +310,9 @@ module VSphereCloud
293
310
  end
294
311
 
295
312
  # Detach any persistent disks in case they were not detached from the instance
296
- devices = properties["config.hardware.device"]
313
+ devices = properties['config.hardware.device']
297
314
  persistent_disks = devices.select { |device| device.kind_of?(Vim::Vm::Device::VirtualDisk) &&
298
- device.backing.disk_mode == Vim::Vm::Device::VirtualDiskOption::DiskMode::INDEPENDENT_PERSISTENT }
315
+ device.backing.disk_mode == Vim::Vm::Device::VirtualDiskOption::DiskMode::INDEPENDENT_PERSISTENT }
299
316
 
300
317
  unless persistent_disks.empty?
301
318
  @logger.info("Found #{persistent_disks.size} persistent disk(s)")
@@ -315,19 +332,18 @@ module VSphereCloud
315
332
  # Delete env.iso and VM specific files managed by the director
316
333
  retry_block do
317
334
  datastore = get_primary_datastore(devices)
318
- datastore_name = client.get_property(datastore, Vim::Datastore, "name")
319
- vm_name = properties["name"]
335
+ datastore_name = client.get_property(datastore, Vim::Datastore, 'name')
336
+ vm_name = properties['name']
320
337
  client.delete_path(datacenter, "[#{datastore_name}] #{vm_name}")
321
338
  end
322
339
  end
323
340
  end
324
341
 
325
- # TODO add option to force hard/soft reboot
326
342
  def reboot_vm(vm_cid)
327
343
  with_thread_name("reboot_vm(#{vm_cid})") do
328
344
  vm = get_vm_by_cid(vm_cid)
329
345
  datacenter = client.find_parent(vm, Vim::Datacenter)
330
- power_state = client.get_property(vm, Vim::VirtualMachine, "runtime.powerState")
346
+ power_state = client.get_property(vm, Vim::VirtualMachine, 'runtime.powerState')
331
347
 
332
348
  @logger.info("Reboot vm = #{vm_cid}")
333
349
  if power_state != Vim::VirtualMachine::PowerState::POWERED_ON
@@ -337,7 +353,7 @@ module VSphereCloud
337
353
  vm.reboot_guest
338
354
  rescue => e
339
355
  @logger.error("Soft reboot failed #{e} -#{e.backtrace.join("\n")}")
340
- @logger.info("Try hard reboot")
356
+ @logger.info('Try hard reboot')
341
357
  # if we fail to perform a soft-reboot we force a hard-reboot
342
358
  if power_state == Vim::VirtualMachine::PowerState::POWERED_ON
343
359
  retry_block { client.power_off_vm(vm) }
@@ -356,10 +372,9 @@ module VSphereCloud
356
372
 
357
373
  metadata.each_key do |name|
358
374
  field = custom_fields.find { |field| field.name == name.to_s &&
359
- field.managed_object_type == Vim::VirtualMachine }
375
+ field.managed_object_type == Vim::VirtualMachine }
360
376
  unless field
361
- field = fields_manager.add_field_definition(
362
- name.to_s, Vim::VirtualMachine, nil, nil)
377
+ field = fields_manager.add_field_definition(name.to_s, Vim::VirtualMachine, nil, nil)
363
378
  end
364
379
  name_to_key_id[name] = field.key
365
380
  end
@@ -367,13 +382,13 @@ module VSphereCloud
367
382
  vm = get_vm_by_cid(vm_cid)
368
383
 
369
384
  metadata.each do |name, value|
370
- value = "" if value.nil? # value is required
385
+ value = '' if value.nil? # value is required
371
386
  fields_manager.set_field(vm, name_to_key_id[name], value)
372
387
  end
373
388
  rescue SoapException => e
374
389
  if e.fault.kind_of?(Vim::Fault::NoPermission)
375
390
  @logger.warn("Can't set custom fields due to lack of " +
376
- "permission: #{e.message}")
391
+ "permission: #{e.message}")
377
392
  else
378
393
  raise e
379
394
  end
@@ -385,33 +400,32 @@ module VSphereCloud
385
400
  with_thread_name("configure_networks(#{vm_cid}, ...)") do
386
401
  vm = get_vm_by_cid(vm_cid)
387
402
 
388
- @logger.debug("Waiting for the VM to shutdown")
403
+ @logger.debug('Waiting for the VM to shutdown')
389
404
  state = :initial
390
405
  begin
391
406
  wait_until_off(vm, 30)
392
407
  rescue TimeoutException
393
408
  case state
394
409
  when :initial
395
- @logger.debug("The guest did not shutdown in time, requesting it to shutdown")
410
+ @logger.debug('The guest did not shutdown in time, requesting it to shutdown')
396
411
  begin
397
412
  vm.shutdown_guest
398
413
  rescue => e
399
- @logger.debug("Ignoring possible race condition when a VM has " +
400
- "powered off by the time we ask it to shutdown: #{e.message}")
414
+ @logger.debug("Ignoring possible race condition when a VM has powered off by the time we ask it to shutdown: #{e.message}")
401
415
  end
402
416
  state = :shutdown_guest
403
417
  retry
404
418
  else
405
- @logger.error("The guest did not shutdown in time, even after a request")
419
+ @logger.error('The guest did not shutdown in time, even after a request')
406
420
  raise
407
421
  end
408
422
  end
409
423
 
410
424
  @logger.info("Configuring: #{vm_cid} to use the following network settings: #{networks.pretty_inspect}")
411
425
  vm = get_vm_by_cid(vm_cid)
412
- devices = client.get_property(vm, Vim::VirtualMachine, "config.hardware.device", :ensure_all => true)
426
+ devices = client.get_property(vm, Vim::VirtualMachine, 'config.hardware.device', ensure_all: true)
413
427
  datacenter = client.find_parent(vm, Vim::Datacenter)
414
- datacenter_name = client.get_property(datacenter, Vim::Datacenter, "name")
428
+ datacenter_name = client.get_property(datacenter, Vim::Datacenter, 'name')
415
429
  pci_controller = devices.find { |device| device.kind_of?(Vim::Vm::Device::VirtualPCIController) }
416
430
 
417
431
  config = Vim::Vm::ConfigSpec.new
@@ -424,63 +438,61 @@ module VSphereCloud
424
438
 
425
439
  dvs_index = {}
426
440
  networks.each_value do |network|
427
- v_network_name = network["cloud_properties"]["name"]
428
- network_mob = client.find_by_inventory_path([datacenter_name, "network", v_network_name])
441
+ v_network_name = network['cloud_properties']['name']
442
+ network_mob = client.find_by_inventory_path([datacenter_name, 'network', v_network_name])
429
443
  nic_config = create_nic_config_spec(v_network_name, network_mob, pci_controller.key, dvs_index)
430
444
  config.device_change << nic_config
431
445
  end
432
446
 
433
447
  fix_device_unit_numbers(devices, config.device_change)
434
- @logger.debug("Reconfiguring the networks")
448
+ @logger.debug('Reconfiguring the networks')
435
449
  @client.reconfig_vm(vm, config)
436
450
 
437
- location = get_vm_location(vm, :datacenter => datacenter_name)
451
+ location = get_vm_location(vm, datacenter: datacenter_name)
438
452
  env = get_current_agent_env(location)
439
453
  @logger.debug("Reading current agent env: #{env.pretty_inspect}")
440
454
 
441
- devices = client.get_property(vm, Vim::VirtualMachine, "config.hardware.device", :ensure_all => true)
442
- env["networks"] = generate_network_env(devices, networks, dvs_index)
455
+ devices = client.get_property(vm, Vim::VirtualMachine, 'config.hardware.device', ensure_all: true)
456
+ env['networks'] = generate_network_env(devices, networks, dvs_index)
443
457
 
444
458
  @logger.debug("Updating agent env to: #{env.pretty_inspect}")
445
459
  set_agent_env(vm, location, env)
446
460
 
447
- @logger.debug("Powering the VM back on")
461
+ @logger.debug('Powering the VM back on')
448
462
  client.power_on_vm(datacenter, vm)
449
463
  end
450
464
  end
451
465
 
452
466
  def get_vm_host_info(vm_ref)
453
- vm = @client.get_properties(vm_ref, Vim::VirtualMachine, "runtime")
454
- vm_runtime = vm["runtime"]
467
+ vm = @client.get_properties(vm_ref, Vim::VirtualMachine, 'runtime')
468
+ vm_runtime = vm['runtime']
455
469
 
456
- properties = @client.get_properties(vm_runtime.host, Vim::HostSystem, ["datastore", "parent"],
457
- :ensure_all => true)
470
+ properties = @client.get_properties(vm_runtime.host, Vim::HostSystem, ['datastore', 'parent'], ensure_all: true)
458
471
 
459
472
  # Get the cluster that the vm's host belongs to.
460
- cluster = @client.get_properties(properties["parent"], Vim::ClusterComputeResource, "name")
473
+ cluster = @client.get_properties(properties['parent'], Vim::ClusterComputeResource, 'name')
461
474
 
462
475
  # Get the datastores that are accessible to the vm's host.
463
476
  datastores_accessible = []
464
- properties["datastore"].each { |store|
465
- ds = @client.get_properties(store, Vim::Datastore, "info", :ensure_all => true)
466
- datastores_accessible << ds["info"].name
467
- }
477
+ properties['datastore'].each do |store|
478
+ ds = @client.get_properties(store, Vim::Datastore, 'info', ensure_all: true)
479
+ datastores_accessible << ds['info'].name
480
+ end
468
481
 
469
- {"cluster" => cluster["name"], "datastores" => datastores_accessible}
482
+ { 'cluster' => cluster['name'], 'datastores' => datastores_accessible }
470
483
  end
471
484
 
472
485
  def find_persistent_datastore(datacenter_name, host_info, disk_size)
473
486
  # Find datastore
474
- datastore = @resources.place_persistent_datastore(
475
- datacenter_name, host_info["cluster"], disk_size)
487
+ datastore = @resources.place_persistent_datastore(datacenter_name, host_info['cluster'], disk_size)
476
488
 
477
489
  if datastore.nil?
478
- raise Bosh::Clouds::NoDiskSpace.new(true), "Not enough persistent space on cluster #{host_info["cluster"]}, #{disk_size}"
490
+ raise Bosh::Clouds::NoDiskSpace.new(true), "Not enough persistent space on cluster #{host_info['cluster']}, #{disk_size}"
479
491
  end
480
492
 
481
493
  # Sanity check, verify that the vm's host can access this datastore
482
- unless host_info["datastores"].include?(datastore.name)
483
- raise "Datastore not accessible to host, #{datastore.name}, #{host_info["datastores"]}"
494
+ unless host_info['datastores'].include?(datastore.name)
495
+ raise "Datastore not accessible to host, #{datastore.name}, #{host_info['datastores']}"
484
496
  end
485
497
  datastore
486
498
  end
@@ -488,25 +500,29 @@ module VSphereCloud
488
500
  def attach_disk(vm_cid, disk_cid)
489
501
  with_thread_name("attach_disk(#{vm_cid}, #{disk_cid})") do
490
502
  @logger.info("Attaching disk: #{disk_cid} on vm: #{vm_cid}")
491
- disk = Models::Disk.first(:uuid => disk_cid)
503
+ disk = Models::Disk.first(uuid: disk_cid)
492
504
  raise "Disk not found: #{disk_cid}" if disk.nil?
493
505
 
494
506
  vm = get_vm_by_cid(vm_cid)
495
507
 
496
508
  datacenter = client.find_parent(vm, Vim::Datacenter)
497
- datacenter_name = client.get_property(datacenter, Vim::Datacenter, "name")
509
+ datacenter_name = client.get_property(datacenter, Vim::Datacenter, 'name')
498
510
 
499
- vm_properties = client.get_properties(vm, Vim::VirtualMachine, "config.hardware.device", :ensure_all => true)
511
+ vm_properties = client.get_properties(vm, Vim::VirtualMachine, 'config.hardware.device', ensure_all: true)
500
512
  host_info = get_vm_host_info(vm)
501
513
 
502
514
  create_disk = false
503
515
  if disk.path
504
- if disk.datacenter == datacenter_name &&
505
- @resources.validate_persistent_datastore(datacenter_name, disk.datastore) &&
506
- host_info["datastores"].include?(disk.datastore)
516
+
517
+ disk_in_correct_datacenter =
518
+ (disk.datacenter == datacenter_name &&
519
+ @resources.validate_persistent_datastore(datacenter_name, disk.datastore) &&
520
+ host_info['datastores'].include?(disk.datastore))
521
+
522
+ if disk_in_correct_datacenter
507
523
  @logger.info("Disk already in the right datastore #{datacenter_name} #{disk.datastore}")
508
- persistent_datastore = @resources.persistent_datastore(
509
- datacenter_name, host_info["cluster"], disk.datastore)
524
+ persistent_datastore =
525
+ @resources.persistent_datastore(datacenter_name, host_info['cluster'], disk.datastore)
510
526
  @logger.debug("Datastore: #{persistent_datastore}")
511
527
  else
512
528
  @logger.info("Disk needs to move from #{datacenter_name} #{disk.datastore}")
@@ -523,10 +539,10 @@ module VSphereCloud
523
539
 
524
540
  if Config.copy_disks
525
541
  client.copy_disk(source_datacenter, source_path, datacenter, destination_path)
526
- @logger.info("Copied disk successfully")
542
+ @logger.info('Copied disk successfully')
527
543
  else
528
544
  client.move_disk(source_datacenter, source_path, datacenter, destination_path)
529
- @logger.info("Moved disk successfully")
545
+ @logger.info('Moved disk successfully')
530
546
  end
531
547
 
532
548
  disk.datacenter = datacenter_name
@@ -535,7 +551,7 @@ module VSphereCloud
535
551
  disk.save
536
552
  end
537
553
  else
538
- @logger.info("Need to create disk")
554
+ @logger.info('Need to create disk')
539
555
 
540
556
  # Find the destination datastore
541
557
  persistent_datastore = find_persistent_datastore(datacenter_name, host_info, disk.size)
@@ -549,43 +565,47 @@ module VSphereCloud
549
565
  create_disk = true
550
566
  end
551
567
 
552
- devices = vm_properties["config.hardware.device"]
568
+ devices = vm_properties['config.hardware.device']
553
569
  system_disk = devices.find { |device| device.kind_of?(Vim::Vm::Device::VirtualDisk) }
554
570
 
555
571
  vmdk_path = "#{disk.path}.vmdk"
556
- attached_disk_config = create_disk_config_spec(persistent_datastore.mob, vmdk_path,
557
- system_disk.controller_key, disk.size.to_i,
558
- :create => create_disk, :independent => true)
572
+ attached_disk_config = create_disk_config_spec(persistent_datastore.mob,
573
+ vmdk_path,
574
+ system_disk.controller_key,
575
+ disk.size.to_i,
576
+ create: create_disk, independent: true)
559
577
  config = Vim::Vm::ConfigSpec.new
560
578
  config.device_change = []
561
579
  config.device_change << attached_disk_config
562
580
  fix_device_unit_numbers(devices, config.device_change)
563
581
 
564
- location = get_vm_location(vm, :datacenter => datacenter_name)
582
+ location = get_vm_location(vm, datacenter: datacenter_name)
565
583
  env = get_current_agent_env(location)
566
584
  @logger.info("Reading current agent env: #{env.pretty_inspect}")
567
- env["disks"]["persistent"][disk.uuid] = attached_disk_config.device.unit_number
585
+ env['disks']['persistent'][disk.uuid] = attached_disk_config.device.unit_number
568
586
  @logger.info("Updating agent env to: #{env.pretty_inspect}")
569
587
  set_agent_env(vm, location, env)
570
- @logger.info("Attaching disk")
588
+ @logger.info('Attaching disk')
571
589
  client.reconfig_vm(vm, config)
572
- @logger.info("Finished attaching disk")
590
+ @logger.info('Finished attaching disk')
573
591
  end
574
592
  end
575
593
 
576
594
  def detach_disk(vm_cid, disk_cid)
577
595
  with_thread_name("detach_disk(#{vm_cid}, #{disk_cid})") do
578
596
  @logger.info("Detaching disk: #{disk_cid} from vm: #{vm_cid}")
579
- disk = Models::Disk.first(:uuid => disk_cid)
597
+ disk = Models::Disk.first(uuid: disk_cid)
580
598
  raise "Disk not found: #{disk_cid}" if disk.nil?
581
599
 
582
600
  vm = get_vm_by_cid(vm_cid)
583
601
 
584
- devices = client.get_property(vm, Vim::VirtualMachine, "config.hardware.device", :ensure_all => true)
602
+ devices = client.get_property(vm, Vim::VirtualMachine, 'config.hardware.device', ensure_all: true)
585
603
 
586
604
  vmdk_path = "#{disk.path}.vmdk"
587
- virtual_disk = devices.find { |device| device.kind_of?(Vim::Vm::Device::VirtualDisk) &&
588
- device.backing.file_name == vmdk_path }
605
+ virtual_disk =
606
+ devices.find do |device|
607
+ device.kind_of?(Vim::Vm::Device::VirtualDisk) && device.backing.file_name == vmdk_path
608
+ end
589
609
  raise Bosh::Clouds::DiskNotAttached.new(true), "Disk (#{disk_cid}) is not attached to VM (#{vm_cid})" if virtual_disk.nil?
590
610
 
591
611
  config = Vim::Vm::ConfigSpec.new
@@ -595,10 +615,10 @@ module VSphereCloud
595
615
  location = get_vm_location(vm)
596
616
  env = get_current_agent_env(location)
597
617
  @logger.info("Reading current agent env: #{env.pretty_inspect}")
598
- env["disks"]["persistent"].delete(disk.uuid)
618
+ env['disks']['persistent'].delete(disk.uuid)
599
619
  @logger.info("Updating agent env to: #{env.pretty_inspect}")
600
620
  set_agent_env(vm, location, env)
601
- @logger.info("Detaching disk")
621
+ @logger.info('Detaching disk')
602
622
  client.reconfig_vm(vm, config)
603
623
 
604
624
  # detach-disk is async and task completion does not necessarily mean
@@ -606,15 +626,18 @@ module VSphereCloud
606
626
  # that the change has been applied. This is a known issue for vsphere 4.
607
627
  # Fixed in vsphere 5.
608
628
  5.times do
609
- devices = client.get_property(vm, Vim::VirtualMachine, "config.hardware.device", :ensure_all => true)
610
- virtual_disk = devices.find { |device| device.kind_of?(Vim::Vm::Device::VirtualDisk) &&
611
- device.backing.file_name == vmdk_path }
629
+ devices = client.get_property(vm, Vim::VirtualMachine, 'config.hardware.device', ensure_all: true)
630
+ virtual_disk =
631
+ devices.find do |device|
632
+ device.kind_of?(Vim::Vm::Device::VirtualDisk) &&
633
+ device.backing.file_name == vmdk_path
634
+ end
612
635
  break if virtual_disk.nil?
613
636
  sleep(1.0)
614
637
  end
615
638
  raise "Failed to detach disk: #{disk_cid} from vm: #{vm_cid}" unless virtual_disk.nil?
616
639
 
617
- @logger.info("Finished detaching disk")
640
+ @logger.info('Finished detaching disk')
618
641
  end
619
642
  end
620
643
 
@@ -633,7 +656,7 @@ module VSphereCloud
633
656
  def delete_disk(disk_cid)
634
657
  with_thread_name("delete_disk(#{disk_cid})") do
635
658
  @logger.info("Deleting disk: #{disk_cid}")
636
- disk = Models::Disk.first(:uuid => disk_cid)
659
+ disk = Models::Disk.first(uuid: disk_cid)
637
660
  if disk
638
661
  if disk.path
639
662
  datacenter = client.find_by_inventory_path(disk.datacenter)
@@ -642,7 +665,7 @@ module VSphereCloud
642
665
  client.delete_disk(datacenter, disk.path)
643
666
  end
644
667
  disk.destroy
645
- @logger.info("Finished deleting disk")
668
+ @logger.info('Finished deleting disk')
646
669
  else
647
670
  raise "Could not find disk: #{disk_cid}"
648
671
  end
@@ -650,32 +673,27 @@ module VSphereCloud
650
673
  end
651
674
 
652
675
  def validate_deployment(old_manifest, new_manifest)
653
- # TODO: still needed? what does it verify? cloud properties? should be replaced by normalize cloud properties?
654
676
  end
655
677
 
656
678
  def get_vm_by_cid(vm_cid)
657
679
  @resources.datacenters.each_value do |datacenter|
658
- vm = client.find_by_inventory_path(
659
- [datacenter.name, "vm", datacenter.vm_folder.name, vm_cid])
660
- unless vm.nil?
661
- return vm
662
- end
680
+ vm = client.find_by_inventory_path([datacenter.name, 'vm', datacenter.vm_folder.name, vm_cid])
681
+ return vm unless vm.nil?
663
682
  end
664
683
  raise Bosh::Clouds::VMNotFound, "VM `#{vm_cid}' not found"
665
684
  end
666
685
 
667
686
  def replicate_stemcell(cluster, datastore, stemcell)
668
- # TODO: support more than a single datacenter
669
- stemcell_vm = client.find_by_inventory_path([cluster.datacenter.name, "vm",
687
+ stemcell_vm = client.find_by_inventory_path([cluster.datacenter.name, 'vm',
670
688
  cluster.datacenter.template_folder.name, stemcell])
671
689
  raise "Could not find stemcell: #{stemcell}" if stemcell_vm.nil?
672
- stemcell_datastore = client.get_property(stemcell_vm, Vim::VirtualMachine, "datastore", :ensure_all => true)
690
+ stemcell_datastore = client.get_property(stemcell_vm, Vim::VirtualMachine, 'datastore', ensure_all: true)
673
691
 
674
692
  if stemcell_datastore != datastore.mob
675
693
  @logger.info("Stemcell lives on a different datastore, looking for a local copy of: #{stemcell}.")
676
- local_stemcell_name = "#{stemcell} / #{datastore.mob.__mo_id__}"
677
- local_stemcell_path = [cluster.datacenter.name, "vm", cluster.datacenter.template_folder.name,
678
- local_stemcell_name]
694
+ local_stemcell_name = "#{stemcell} %2f #{datastore.mob.__mo_id__}"
695
+ local_stemcell_path =
696
+ [cluster.datacenter.name, 'vm', cluster.datacenter.template_folder.name, local_stemcell_name]
679
697
  replicated_stemcell_vm = client.find_by_inventory_path(local_stemcell_path)
680
698
 
681
699
  if replicated_stemcell_vm.nil?
@@ -692,13 +710,17 @@ module VSphereCloud
692
710
  replicated_stemcell_vm = client.find_by_inventory_path(local_stemcell_path)
693
711
  if replicated_stemcell_vm.nil?
694
712
  @logger.info("Replicating #{stemcell} (#{stemcell_vm}) to #{local_stemcell_name}")
695
- task = clone_vm(stemcell_vm, local_stemcell_name, cluster.datacenter.template_folder.mob,
696
- cluster.resource_pool.mob, :datastore => datastore.mob)
713
+ task = clone_vm(stemcell_vm,
714
+ local_stemcell_name,
715
+ cluster.datacenter.template_folder.mob,
716
+ cluster.resource_pool.mob,
717
+ datastore: datastore.mob)
697
718
  replicated_stemcell_vm = client.wait_for_task(task)
698
- @logger.info("Replicated #{stemcell} (#{stemcell_vm}) to " +
699
- "#{local_stemcell_name} (#{replicated_stemcell_vm})")
719
+ @logger.info("Replicated #{stemcell} (#{stemcell_vm}) to #{local_stemcell_name} (#{replicated_stemcell_vm})")
700
720
  @logger.info("Creating initial snapshot for linked clones on #{replicated_stemcell_vm}")
701
- task = take_snapshot(replicated_stemcell_vm, "initial")
721
+ # Despite the naming, this has nothing to do with the Cloud notion of a disk snapshot
722
+ # (which comes from AWS). This is a vm snapshot.
723
+ task = replicated_stemcell_vm.create_snapshot('initial', nil, false, false)
702
724
  client.wait_for_task(task)
703
725
  @logger.info("Created initial snapshot for linked clones on #{replicated_stemcell_vm}")
704
726
  end
@@ -724,9 +746,9 @@ module VSphereCloud
724
746
  if device.kind_of?(Vim::Vm::Device::VirtualEthernetCard)
725
747
  backing = device.backing
726
748
  if backing.kind_of?(Vim::Vm::Device::VirtualEthernetCard::DistributedVirtualPortBackingInfo)
727
- v_network_name = dvs_index[device.backing.port.portgroup_key]
749
+ v_network_name = dvs_index[backing.port.portgroup_key]
728
750
  else
729
- v_network_name = device.backing.device_name
751
+ v_network_name = PathFinder.new.path(backing.network)
730
752
  end
731
753
  allocated_networks = nics[v_network_name] || []
732
754
  allocated_networks << device
@@ -737,9 +759,9 @@ module VSphereCloud
737
759
  network_env = {}
738
760
  networks.each do |network_name, network|
739
761
  network_entry = network.dup
740
- v_network_name = network["cloud_properties"]["name"]
762
+ v_network_name = network['cloud_properties']['name']
741
763
  nic = nics[v_network_name].pop
742
- network_entry["mac"] = nic.mac_address
764
+ network_entry['mac'] = nic.mac_address
743
765
  network_env[network_name] = network_entry
744
766
  end
745
767
  network_env
@@ -747,23 +769,23 @@ module VSphereCloud
747
769
 
748
770
  def generate_disk_env(system_disk, ephemeral_disk)
749
771
  {
750
- "system" => system_disk.unit_number,
751
- "ephemeral" => ephemeral_disk.unit_number,
752
- "persistent" => {}
772
+ 'system' => system_disk.unit_number,
773
+ 'ephemeral' => ephemeral_disk.unit_number,
774
+ 'persistent' => {}
753
775
  }
754
776
  end
755
777
 
756
778
  def generate_agent_env(name, vm, agent_id, networking_env, disk_env)
757
779
  vm_env = {
758
- "name" => name,
759
- "id" => vm.__mo_id__
780
+ 'name' => name,
781
+ 'id' => vm.__mo_id__
760
782
  }
761
783
 
762
784
  env = {}
763
- env["vm"] = vm_env
764
- env["agent_id"] = agent_id
765
- env["networks"] = networking_env
766
- env["disks"] = disk_env
785
+ env['vm'] = vm_env
786
+ env['agent_id'] = agent_id
787
+ env['networks'] = networking_env
788
+ env['disks'] = disk_env
767
789
  env.merge!(Config.agent)
768
790
  env
769
791
  end
@@ -775,32 +797,32 @@ module VSphereCloud
775
797
 
776
798
  unless datacenter_name
777
799
  datacenter = client.find_parent(vm, Vim::Datacenter)
778
- datacenter_name = client.get_property(datacenter, Vim::Datacenter, "name")
800
+ datacenter_name = client.get_property(datacenter, Vim::Datacenter, 'name')
779
801
  end
780
802
 
781
803
  if vm_name.nil? || datastore_name.nil?
782
- vm_properties = client.get_properties(vm, Vim::VirtualMachine, ["config.hardware.device", "name"],
783
- :ensure_all => true)
784
- vm_name = vm_properties["name"]
804
+ vm_properties =
805
+ client.get_properties(vm, Vim::VirtualMachine, ['config.hardware.device', 'name'], ensure_all: true)
806
+ vm_name = vm_properties['name']
785
807
 
786
808
  unless datastore_name
787
- devices = vm_properties["config.hardware.device"]
809
+ devices = vm_properties['config.hardware.device']
788
810
  datastore = get_primary_datastore(devices)
789
- datastore_name = client.get_property(datastore, Vim::Datastore, "name")
811
+ datastore_name = client.get_property(datastore, Vim::Datastore, 'name')
790
812
  end
791
813
  end
792
814
 
793
- {:datacenter => datacenter_name, :datastore => datastore_name, :vm => vm_name}
815
+ { datacenter: datacenter_name, datastore: datastore_name, vm: vm_name }
794
816
  end
795
817
 
796
818
  def get_primary_datastore(devices)
797
819
  ephemeral_disks = devices.select { |device| device.kind_of?(Vim::Vm::Device::VirtualDisk) &&
798
- device.backing.disk_mode != Vim::Vm::Device::VirtualDiskOption::DiskMode::INDEPENDENT_PERSISTENT }
820
+ device.backing.disk_mode != Vim::Vm::Device::VirtualDiskOption::DiskMode::INDEPENDENT_PERSISTENT }
799
821
 
800
822
  datastore = nil
801
823
  ephemeral_disks.each do |disk|
802
824
  if datastore
803
- raise "Ephemeral disks should all be on the same datastore." unless datastore.eql?(disk.backing.datastore)
825
+ raise 'Ephemeral disks should all be on the same datastore.' unless datastore.eql?(disk.backing.datastore)
804
826
  else
805
827
  datastore = disk.backing.datastore
806
828
  end
@@ -811,11 +833,11 @@ module VSphereCloud
811
833
 
812
834
  def get_current_agent_env(location)
813
835
  contents = fetch_file(location[:datacenter], location[:datastore], "#{location[:vm]}/env.json")
814
- contents ? Yajl::Parser.parse(contents) : nil
836
+ contents ? JSON.load(contents) : nil
815
837
  end
816
838
 
817
839
  def set_agent_env(vm, location, env)
818
- env_json = Yajl::Encoder.encode(env)
840
+ env_json = JSON.dump(env)
819
841
 
820
842
  connect_cdrom(vm, false)
821
843
  upload_file(location[:datacenter], location[:datastore], "#{location[:vm]}/env.json", env_json)
@@ -824,7 +846,7 @@ module VSphereCloud
824
846
  end
825
847
 
826
848
  def connect_cdrom(vm, connected = true)
827
- devices = client.get_property(vm, Vim::VirtualMachine, "config.hardware.device", :ensure_all => true)
849
+ devices = client.get_property(vm, Vim::VirtualMachine, 'config.hardware.device', ensure_all: true)
828
850
  cdrom = devices.find { |device| device.kind_of?(Vim::Vm::Device::VirtualCdrom) }
829
851
 
830
852
  if cdrom.connectable.connected != connected
@@ -868,19 +890,19 @@ module VSphereCloud
868
890
 
869
891
  def generate_env_iso(env)
870
892
  Dir.mktmpdir do |path|
871
- env_path = File.join(path, "env")
872
- iso_path = File.join(path, "env.iso")
873
- File.open(env_path, "w") { |f| f.write(env) }
893
+ env_path = File.join(path, 'env')
894
+ iso_path = File.join(path, 'env.iso')
895
+ File.open(env_path, 'w') { |f| f.write(env) }
874
896
  output = `#{genisoimage} -o #{iso_path} #{env_path} 2>&1`
875
897
  raise "#{$?.exitstatus} -#{output}" if $?.exitstatus != 0
876
- File.open(iso_path, "r") { |f| f.read }
898
+ File.open(iso_path, 'r') { |f| f.read }
877
899
  end
878
900
  end
879
901
 
880
902
  def fetch_file(datacenter_name, datastore_name, path)
881
903
  retry_block do
882
- url = "https://#{Config.vcenter.host}/folder/#{path}?dcPath=#{URI.escape(datacenter_name)}" +
883
- "&dsName=#{URI.escape(datastore_name)}"
904
+ url =
905
+ "https://#{Config.vcenter.host}/folder/#{path}?dcPath=#{URI.escape(datacenter_name)}&dsName=#{URI.escape(datastore_name)}"
884
906
 
885
907
  response = @rest_client.get(url)
886
908
 
@@ -896,17 +918,18 @@ module VSphereCloud
896
918
 
897
919
  def upload_file(datacenter_name, datastore_name, path, contents)
898
920
  retry_block do
899
- url = "https://#{Config.vcenter.host}/folder/#{path}?dcPath=#{URI.escape(datacenter_name)}" +
900
- "&dsName=#{URI.escape(datastore_name)}"
901
- response = @rest_client.put(url, contents, {"Content-Type" => "application/octet-stream",
902
- "Content-Length" => contents.length})
921
+ url =
922
+ "https://#{Config.vcenter.host}/folder/#{path}?dcPath=#{URI.escape(datacenter_name)}&dsName=#{URI.escape(datastore_name)}"
923
+ response = @rest_client.put(url,
924
+ contents,
925
+ { 'Content-Type' => 'application/octet-stream', 'Content-Length' => contents.length })
903
926
 
904
927
  raise "Could not upload file: #{url}, status code: #{response.code}" unless response.code < 400
905
928
  end
906
929
  end
907
930
 
908
931
  def clone_vm(vm, name, folder, resource_pool, options={})
909
- relocation_spec =Vim::Vm::RelocateSpec.new
932
+ relocation_spec = Vim::Vm::RelocateSpec.new
910
933
  relocation_spec.datastore = options[:datastore] if options[:datastore]
911
934
  if options[:linked]
912
935
  relocation_spec.disk_move_type = Vim::Vm::RelocateSpec::DiskMoveOptions::CREATE_NEW_CHILD_DISK_BACKING
@@ -923,12 +946,8 @@ module VSphereCloud
923
946
  vm.clone(folder, name, clone_spec)
924
947
  end
925
948
 
926
- def take_snapshot(vm, name)
927
- vm.create_snapshot(name, nil, false, false)
928
- end
929
-
930
949
  def generate_unique_name
931
- UUIDTools::UUID.random_create.to_s
950
+ SecureRandom.uuid
932
951
  end
933
952
 
934
953
  def create_disk_config_spec(datastore, file_name, controller_key, space, options = {})
@@ -959,16 +978,17 @@ module VSphereCloud
959
978
  def create_nic_config_spec(v_network_name, network, controller_key, dvs_index)
960
979
  raise "Can't find network: #{v_network_name}" if network.nil?
961
980
  if network.class == Vim::Dvs::DistributedVirtualPortgroup
962
- portgroup_properties = client.get_properties(network, Vim::Dvs::DistributedVirtualPortgroup,
963
- ["config.key", "config.distributedVirtualSwitch"],
964
- :ensure_all => true)
981
+ portgroup_properties = client.get_properties(network,
982
+ Vim::Dvs::DistributedVirtualPortgroup,
983
+ ['config.key', 'config.distributedVirtualSwitch'],
984
+ ensure_all: true)
965
985
 
966
- switch = portgroup_properties["config.distributedVirtualSwitch"]
967
- switch_uuid = client.get_property(switch, Vim::DistributedVirtualSwitch, "uuid", :ensure_all => true)
986
+ switch = portgroup_properties['config.distributedVirtualSwitch']
987
+ switch_uuid = client.get_property(switch, Vim::DistributedVirtualSwitch, 'uuid', ensure_all: true)
968
988
 
969
989
  port = Vim::Dvs::PortConnection.new
970
990
  port.switch_uuid = switch_uuid
971
- port.portgroup_key = portgroup_properties["config.key"]
991
+ port.portgroup_key = portgroup_properties['config.key']
972
992
 
973
993
  backing_info = Vim::Vm::Device::VirtualEthernetCard::DistributedVirtualPortBackingInfo.new
974
994
  backing_info.port = port
@@ -976,7 +996,7 @@ module VSphereCloud
976
996
  dvs_index[port.portgroup_key] = v_network_name
977
997
  else
978
998
  backing_info = Vim::Vm::Device::VirtualEthernetCard::NetworkBackingInfo.new
979
- backing_info.device_name = v_network_name
999
+ backing_info.device_name = network.name
980
1000
  backing_info.network = network
981
1001
  end
982
1002
 
@@ -1039,8 +1059,10 @@ module VSphereCloud
1039
1059
  ovf_descriptor = ovf_file.read
1040
1060
  ovf_file.close
1041
1061
 
1042
- @client.service_content.ovf_manager.create_import_spec(ovf_descriptor, resource_pool,
1043
- datastore, import_spec_params)
1062
+ @client.service_content.ovf_manager.create_import_spec(ovf_descriptor,
1063
+ resource_pool,
1064
+ datastore,
1065
+ import_spec_params)
1044
1066
  end
1045
1067
 
1046
1068
  def obtain_nfc_lease(resource_pool, import_spec, folder)
@@ -1049,16 +1071,14 @@ module VSphereCloud
1049
1071
 
1050
1072
  def wait_for_nfc_lease(lease)
1051
1073
  loop do
1052
- state = client.get_property(lease, Vim::HttpNfcLease, "state")
1053
- unless state == Vim::HttpNfcLease::State::INITIALIZING
1054
- return state
1055
- end
1074
+ state = client.get_property(lease, Vim::HttpNfcLease, 'state')
1075
+ return state unless state == Vim::HttpNfcLease::State::INITIALIZING
1056
1076
  sleep(1.0)
1057
1077
  end
1058
1078
  end
1059
1079
 
1060
1080
  def upload_ovf(ovf, lease, file_items)
1061
- info = client.get_property(lease, Vim::HttpNfcLease, "info", :ensure_all => true)
1081
+ info = client.get_property(lease, Vim::HttpNfcLease, 'info', ensure_all: true)
1062
1082
  lease_updater = LeaseUpdater.new(client, lease)
1063
1083
 
1064
1084
  info.device_url.each do |device_url|
@@ -1070,13 +1090,11 @@ module VSphereCloud
1070
1090
  http_client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
1071
1091
 
1072
1092
  disk_file_path = File.join(File.dirname(ovf), file_item.path)
1073
- # TODO; capture the error if file is not found a provide a more meaningful error
1074
1093
  disk_file = File.open(disk_file_path)
1075
1094
  disk_file_size = File.size(disk_file_path)
1076
1095
 
1077
1096
  progress_thread = Thread.new do
1078
1097
  loop do
1079
- # TODO: fix progress calculation to work across multiple disks
1080
1098
  lease_updater.progress = disk_file.pos * 100 / disk_file_size
1081
1099
  sleep(2)
1082
1100
  end
@@ -1084,8 +1102,9 @@ module VSphereCloud
1084
1102
 
1085
1103
  @logger.info("Uploading disk to: #{device_url.url}")
1086
1104
 
1087
- http_client.post(device_url.url, disk_file, {"Content-Type" => "application/x-vnd.vmware-streamVmdk",
1088
- "Content-Length" => disk_file_size})
1105
+ http_client.post(device_url.url,
1106
+ disk_file,
1107
+ { 'Content-Type' => 'application/x-vnd.vmware-streamVmdk', 'Content-Length' => disk_file_size })
1089
1108
 
1090
1109
  progress_thread.kill
1091
1110
  disk_file.close
@@ -1097,13 +1116,13 @@ module VSphereCloud
1097
1116
  end
1098
1117
 
1099
1118
  def wait_until_off(vm, timeout)
1100
- started = Time.now
1101
- loop do
1102
- power_state = client.get_property(vm, Vim::VirtualMachine, "runtime.powerState")
1103
- break if power_state == Vim::VirtualMachine::PowerState::POWERED_OFF
1104
- raise TimeoutException if Time.now - started > timeout
1105
- sleep(1.0)
1106
- end
1119
+ started = Time.now
1120
+ loop do
1121
+ power_state = client.get_property(vm, Vim::VirtualMachine, 'runtime.powerState')
1122
+ break if power_state == Vim::VirtualMachine::PowerState::POWERED_OFF
1123
+ raise TimeoutException if Time.now - started > timeout
1124
+ sleep(1.0)
1125
+ end
1107
1126
  end
1108
1127
  end
1109
1128
  end