bosh_vsphere_cpi 2.2.1 → 2.2.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4395e6dd0db3e79ecccc8d4475dfca0aebac8684
4
- data.tar.gz: 48fe6a81c8586522b8040cbc45c03d32d5305fa1
3
+ metadata.gz: 8cf26eed256c7480a429cb3d09eaf357656adb64
4
+ data.tar.gz: 66f4347df33381995b727d84370de31160acd7cd
5
5
  SHA512:
6
- metadata.gz: 07c5278031cb259efb6dbd019db122a2cf06365eddd31a19a7fc7a7a377ea290fee62f6a43ab6ac514eb51173350d3e5def2829544351b1e5e02fc33ce1760ff
7
- data.tar.gz: 8cdc7000a67cced611bc18859ecb4390f292b081e669fe03209ba38dfd563e9bc8c0ebf8e23e335d0142bb535082fa58f710bb0db4550b03ca8af6423bbcbeef
6
+ metadata.gz: d29158bac673485edb46eea81b1678482774e05d38114c97dfa8210460b6fd33fa0b8d2e737b963f3eaf73d1fc3bb646420868e4db92b8e59b5b88fe9bfddfc8
7
+ data.tar.gz: 09c56e204697cb410e700f5cd3510067d069dae5ea17f3b2775e127d338d09d3b32d9ec58387de82f9f048e6b4192fe364f0c8797afcb2fb2da244dc3f878118
@@ -304,7 +304,7 @@ module VSphereCloud
304
304
 
305
305
  datastore_path = "[#{datastore.name}] #{disk_folder}"
306
306
  @logger.debug("Trying to find disk in : #{datastore_path}")
307
- vm_disk_infos = wait_for_task(datastore.mob.browser.search(datastore_path, search_spec)).file
307
+ vm_disk_infos = wait_for_task(datastore.mob.browser.search("[#{datastore.name}] #{disk_folder}", search_spec)).file
308
308
  return nil if vm_disk_infos.empty?
309
309
 
310
310
  vm_disk_infos.first.capacity_kb / 1024
@@ -312,26 +312,13 @@ module VSphereCloud
312
312
  nil
313
313
  end
314
314
 
315
- def disk_path_exists?(vm_mob, disk_path)
316
- match = /\[(.+)\] (.+)\/(.+\.vmdk)/.match(disk_path)
317
- search_spec_details = VimSdk::Vim::Host::DatastoreBrowser::FileInfo::Details.new
318
- search_spec_details.file_type = true # actually return VmDiskInfos not FileInfos
319
-
320
- search_spec = VimSdk::Vim::Host::DatastoreBrowser::SearchSpec.new
321
- search_spec.details = search_spec_details
322
- search_spec.match_pattern = [match[3]]
323
-
324
- datastore_path = "[#{match[1]}] #{match[2]}"
325
- @logger.debug("Trying to find disk in : #{datastore_path}")
326
- vm_disk_infos = wait_for_task(vm_mob.environment_browser.datastore_browser.search(datastore_path, search_spec)).file
327
- return false if vm_disk_infos.empty?
315
+ def add_persistent_disk_property_to_vm(vm, disk)
316
+ vm_config = Vim::Vm::ConfigSpec.new
317
+ v_app_config_spec = VimSdk::Vim::VApp::VmConfigSpec.new
328
318
 
329
- true
330
- rescue VimSdk::SoapError, FileNotFoundException
331
- false
332
- end
319
+ v_app_property_spec = VimSdk::Vim::VApp::PropertySpec.new
320
+ v_app_property_info = VimSdk::Vim::VApp::PropertyInfo.new
333
321
 
334
- def add_persistent_disk_property_to_vm(vm, disk)
335
322
  vm_disk = vm.disk_by_cid(disk.cid)
336
323
  disk_device_key = vm_disk.key
337
324
 
@@ -340,7 +327,6 @@ module VSphereCloud
340
327
  return
341
328
  end
342
329
 
343
- v_app_property_info = VimSdk::Vim::VApp::PropertyInfo.new
344
330
  v_app_property_info.key = disk_device_key
345
331
  v_app_property_info.id = disk.cid
346
332
  v_app_property_info.label = disk.cid
@@ -350,36 +336,58 @@ module VSphereCloud
350
336
  v_app_property_info.description = 'Used by BOSH to track persistent disks. Change at your own risk.'
351
337
  v_app_property_info.user_configurable = true
352
338
 
353
- v_app_property_spec = VimSdk::Vim::VApp::PropertySpec.new
354
339
  v_app_property_spec.info = v_app_property_info
355
340
  v_app_property_spec.operation = VimSdk::Vim::Option::ArrayUpdateSpec::Operation::ADD
356
-
357
- v_app_config_spec = VimSdk::Vim::VApp::VmConfigSpec.new
358
341
  v_app_config_spec.property << v_app_property_spec
359
342
 
360
- vm_config = Vim::Vm::ConfigSpec.new
361
343
  vm_config.v_app_config = v_app_config_spec
362
344
 
363
345
  reconfig_vm(vm.mob, vm_config)
364
346
  end
365
347
 
366
- def delete_persistent_disk_property_from_vm(vm, disk_device_key)
367
- if vm.get_vapp_property_by_key(disk_device_key).nil?
368
- @logger.debug("Disk property[#{disk_device_key}] does not exist on vm '#{vm.cid}'")
369
- return
370
- end
348
+ def set_custom_field(mob, name, value)
349
+ @fields_manager ||= @service_content.custom_fields_manager
350
+ name = name.to_s
351
+ value = value.to_s
352
+ field = nil
371
353
 
372
- v_app_property_spec = VimSdk::Vim::VApp::PropertySpec.new
373
- v_app_property_spec.remove_key = disk_device_key
374
- v_app_property_spec.operation = VimSdk::Vim::Option::ArrayUpdateSpec::Operation::REMOVE
375
-
376
- v_app_config_spec = VimSdk::Vim::VApp::VmConfigSpec.new
377
- v_app_config_spec.property << v_app_property_spec
354
+ begin
355
+ field = @fields_manager.add_field_definition(name, mob.class, nil, nil)
356
+ rescue SoapError => e
357
+ if e.fault.kind_of?(Vim::Fault::NoPermission)
358
+ @logger.warn("Can't create custom field definition due to lack of permission: #{e.message}")
359
+ elsif e.fault.kind_of?(Vim::Fault::DuplicateName)
360
+ @logger.warn("Custom field definition already exists: #{e.message}")
361
+ custom_fields = @fields_manager.field
362
+ field = custom_fields.find do |field|
363
+ field.name == name && field.managed_object_type == mob.class
364
+ end
365
+ else
366
+ raise e
367
+ end
368
+ end
378
369
 
379
- vm_config = Vim::Vm::ConfigSpec.new
380
- vm_config.v_app_config = v_app_config_spec
370
+ unless field.nil?
371
+ begin
372
+ @fields_manager.set_field(mob, field.key, value)
373
+ rescue SoapError => e
374
+ if e.fault.kind_of?(Vim::Fault::NoPermission)
375
+ @logger.warn("Can't set custom fields due to lack of permission: #{e.message}")
376
+ end
377
+ end
378
+ end
379
+ end
381
380
 
382
- reconfig_vm(vm.mob, vm_config)
381
+ def remove_custom_field_def(name, mob_type)
382
+ @fields_manager ||= @service_content.custom_fields_manager
383
+ name = name.to_s
384
+ custom_fields = @fields_manager.field
385
+ field = custom_fields.find do |field|
386
+ field.name == name && field.managed_object_type == mob_type
387
+ end
388
+ unless field.nil?
389
+ @fields_manager.remove_field_definition(field.key)
390
+ end
383
391
  end
384
392
 
385
393
  private
@@ -195,7 +195,34 @@ module VSphereCloud
195
195
 
196
196
  persistent_disks = vm.persistent_disks
197
197
  unless persistent_disks.empty?
198
- vm.detach_disks(persistent_disks)
198
+ disks_to_move = []
199
+ @logger.info("Found #{persistent_disks.size} persistent disk(s)")
200
+ config = Vim::Vm::ConfigSpec.new
201
+ config.device_change = []
202
+
203
+ persistent_disks.each do |virtual_disk|
204
+ @logger.info("Detaching: #{virtual_disk.backing.file_name}")
205
+ config.device_change << Resources::VM.create_delete_device_spec(virtual_disk)
206
+
207
+ if vm.has_persistent_disk_property_mismatch?(virtual_disk)
208
+ @logger.info("Property Mismatch")
209
+ disks_to_move << virtual_disk
210
+ end
211
+ end
212
+ retry_block { client.reconfig_vm(vm.mob, config) }
213
+ @logger.info("Detached #{persistent_disks.size} persistent disk(s)")
214
+
215
+ @logger.info("Renaming #{disks_to_move.size} persistent disk(s)")
216
+ disks_to_move.each do |disk|
217
+ current_path = disk.backing.file_name
218
+
219
+ current_datastore = current_path.split(" ").first
220
+ original_disk_path = vm.get_old_disk_filepath(disk.key)
221
+ dest_filename = original_disk_path.split(" ").last
222
+ dest_path = "#{current_datastore} #{dest_filename}"
223
+
224
+ @datacenter.move_disk(current_path, dest_path)
225
+ end
199
226
  end
200
227
 
201
228
  # Delete env.iso and VM specific files managed by the director
@@ -232,35 +259,9 @@ module VSphereCloud
232
259
 
233
260
  def set_vm_metadata(vm_cid, metadata)
234
261
  with_thread_name("set_vm_metadata(#{vm_cid}, ...)") do
235
- begin
236
- fields_manager = client.service_content.custom_fields_manager
237
- custom_fields = fields_manager.field
238
- name_to_key_id = {}
239
-
240
- metadata.each_key do |name|
241
- field = custom_fields.find { |field| field.name == name.to_s &&
242
- field.managed_object_type == Vim::VirtualMachine }
243
- unless field
244
- field = fields_manager.add_field_definition(name.to_s, Vim::VirtualMachine, nil, nil)
245
- end
246
- name_to_key_id[name] = field.key
247
- end
248
-
249
- vm = vm_provider.find(vm_cid)
250
-
251
- metadata.each do |name, value|
252
- value = '' if value.nil? # value is required
253
- fields_manager.set_field(vm.mob, name_to_key_id[name], value)
254
- end
255
- rescue SoapError => e
256
- if e.fault.kind_of?(Vim::Fault::NoPermission)
257
- @logger.warn("Can't set custom fields due to lack of " +
258
- "permission: #{e.message}")
259
- elsif e.fault.kind_of?(Vim::Fault::DuplicateName)
260
- @logger.warn("Can't add custom field definition that already exists: #{e.message}")
261
- else
262
- raise e
263
- end
262
+ vm = vm_provider.find(vm_cid)
263
+ metadata.each do |name, value|
264
+ client.set_custom_field(vm.mob, name, value)
264
265
  end
265
266
  end
266
267
  end
@@ -326,12 +327,11 @@ module VSphereCloud
326
327
  with_thread_name("detach_disk(#{vm_cid}, #{disk_cid})") do
327
328
  @logger.info("Detaching disk: #{disk_cid} from vm: #{vm_cid}")
328
329
 
330
+ disk = @datacenter.find_disk(disk_cid)
329
331
  vm = vm_provider.find(vm_cid)
330
- disk = vm.disk_by_original_cid(disk_cid)
331
- raise Bosh::Clouds::DiskNotAttached.new(true), "Disk '#{disk_cid}' is not attached to VM '#{vm_cid}'" if disk.nil?
332
332
 
333
- delete_disk_from_agent_env(vm, disk_cid)
334
- vm.detach_disks([disk])
333
+ delete_disk_from_agent_env(vm, disk)
334
+ vm.detach_disk(disk)
335
335
  end
336
336
  end
337
337
 
@@ -647,13 +647,13 @@ module VSphereCloud
647
647
  @logger.info("Updated agent env to: #{env.pretty_inspect}")
648
648
  end
649
649
 
650
- def delete_disk_from_agent_env(vm, disk_cid)
650
+ def delete_disk_from_agent_env(vm, disk)
651
651
  vm_mob = vm.mob
652
652
  location = get_vm_location(vm_mob)
653
653
  env = @agent_env.get_current_env(vm_mob, location[:datacenter])
654
654
  @logger.info("Reading current agent env: #{env.pretty_inspect}")
655
- if env['disks']['persistent'][disk_cid]
656
- env['disks']['persistent'].delete(disk_cid)
655
+ if env['disks']['persistent'][disk.cid]
656
+ env['disks']['persistent'].delete(disk.cid)
657
657
  @logger.info("Updating agent env to: #{env.pretty_inspect}")
658
658
 
659
659
  @agent_env.set_env(vm_mob, location, env)
@@ -60,7 +60,7 @@ module VSphereCloud
60
60
  end
61
61
 
62
62
  def persistent_disks
63
- devices.select do |device|
63
+ devices.select do |device|
64
64
  device.kind_of?(Vim::Vm::Device::VirtualDisk) &&
65
65
  device.backing.disk_mode == Vim::Vm::Device::VirtualDiskOption::DiskMode::INDEPENDENT_PERSISTENT
66
66
  end
@@ -77,7 +77,7 @@ module VSphereCloud
77
77
  end
78
78
 
79
79
  def fix_device_unit_numbers(device_changes)
80
- controllers_available_unit_numbers = Hash.new { |h, k| h[k] = (0..15).to_a }
80
+ controllers_available_unit_numbers = Hash.new { |h,k| h[k] = (0..15).to_a }
81
81
  devices.each do |device|
82
82
  if device.controller_key
83
83
  available_unit_numbers = controllers_available_unit_numbers[device.controller_key]
@@ -117,7 +117,7 @@ module VSphereCloud
117
117
  if question
118
118
  choices = question.choice
119
119
  @logger.info("VM is blocked on a question: #{question.text}, " +
120
- "providing default answer: #{choices.choice_info[choices.default_index].label}")
120
+ "providing default answer: #{choices.choice_info[choices.default_index].label}")
121
121
  @client.answer_vm(@mob, question.id, choices.choice_info[choices.default_index].key)
122
122
  power_state = cloud_searcher.get_property(@mob, Vim::VirtualMachine, 'runtime.powerState')
123
123
  else
@@ -138,21 +138,6 @@ module VSphereCloud
138
138
  end
139
139
  end
140
140
 
141
- def disk_by_original_cid(disk_cid)
142
- devices.each do |d|
143
- if d.kind_of?(Vim::Vm::Device::VirtualDisk)
144
- found_property = get_vapp_property_by_key(d.key)
145
- unless found_property.nil?
146
- if verify_persistent_disk_property?(found_property) && found_property.label == disk_cid
147
- return d
148
- end
149
- end
150
- end
151
- end
152
-
153
- nil
154
- end
155
-
156
141
  def reboot
157
142
  @mob.reboot_guest
158
143
  end
@@ -189,8 +174,8 @@ module VSphereCloud
189
174
  return false if found_property.nil? || !verify_persistent_disk_property?(found_property)
190
175
 
191
176
  # get full path without a datastore
192
- file_path = disk.backing.file_name[/([^\]]*)\.vmdk/, 1].strip
193
- original_file_path = found_property.value[/([^\]]*)\.vmdk/, 1].strip
177
+ file_path = disk.backing.file_name[/([^\]]*)\.vmdk/,1].strip
178
+ original_file_path =found_property.value[/([^\]]*)\.vmdk/,1].strip
194
179
  @logger.debug("Current file path is #{file_path}")
195
180
  @logger.debug("Original file path is #{original_file_path}")
196
181
 
@@ -231,51 +216,31 @@ module VSphereCloud
231
216
  return disk_config_spec
232
217
  end
233
218
 
234
- def detach_disks(virtual_disks)
219
+ def detach_disk(disk)
235
220
  reload
236
- disks_to_move = []
237
- @logger.info("Found #{virtual_disks.size} persistent disk(s)")
221
+ virtual_disk = disk_by_cid(disk.cid)
222
+ raise Bosh::Clouds::DiskNotAttached.new(true), "Disk '#{disk.cid}' is not attached to VM '#{@cid}'" if virtual_disk.nil?
223
+
238
224
  config = Vim::Vm::ConfigSpec.new
239
225
  config.device_change = []
240
-
241
- virtual_disks.each do |virtual_disk|
242
- @logger.info("Detaching: #{virtual_disk.backing.file_name}")
243
- config.device_change << Resources::VM.create_delete_device_spec(virtual_disk)
244
-
245
- disk_property = get_vapp_property_by_key(virtual_disk.key)
246
- unless disk_property.nil?
247
- if has_persistent_disk_property_mismatch?(virtual_disk) && !@client.disk_path_exists?(@mob, disk_property.value)
248
- @logger.info('Persistent disk was moved: moving disk to expected location')
249
- disks_to_move << virtual_disk
250
- end
251
- end
226
+ config.device_change << self.class.create_delete_device_spec(virtual_disk)
227
+
228
+ @logger.info('Detaching disk')
229
+ @client.reconfig_vm(@mob, config)
230
+
231
+ # detach-disk is async and task completion does not necessarily mean
232
+ # that changes have been applied to VC side. Query VC until we confirm
233
+ # that the change has been applied. This is a known issue for vsphere 4.
234
+ # Fixed in vsphere 5.
235
+ 5.times do
236
+ reload
237
+ virtual_disk = disk_by_cid(disk.cid)
238
+ break if virtual_disk.nil?
239
+ sleep(1.0)
252
240
  end
253
- retry_block { @client.reconfig_vm(@mob, config) }
254
- @logger.info("Detached #{virtual_disks.size} persistent disk(s)")
255
-
256
- move_disks_to_old_path(disks_to_move)
257
-
258
- @logger.info('Finished detaching disk(s)')
241
+ raise "Failed to detach disk '#{disk.cid}' from vm '#{@cid}'" unless virtual_disk.nil?
259
242
 
260
- virtual_disks.each do |disk|
261
- @logger.debug("Deleting persistent disk property #{disk.key} from vm '#{@cid}'")
262
- @client.delete_persistent_disk_property_from_vm(self, disk.key)
263
- end
264
- @logger.debug('Finished deleting persistent disk properties from vm')
265
- end
266
-
267
- def move_disks_to_old_path(disks_to_move)
268
- @logger.info("Renaming #{disks_to_move.size} persistent disk(s)")
269
- disks_to_move.each do |virtual_disk|
270
- current_path = virtual_disk.backing.file_name
271
-
272
- current_datastore = current_path.split(" ").first
273
- original_disk_path = get_old_disk_filepath(virtual_disk.key)
274
- dest_filename = original_disk_path.split(" ").last
275
- dest_path = "#{current_datastore} #{dest_filename}"
276
-
277
- @client.move_disk(datacenter, current_path, datacenter, dest_path)
278
- end
243
+ @logger.info('Finished detaching disk')
279
244
  end
280
245
 
281
246
  def self.create_delete_device_spec(device, options = {})
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh_vsphere_cpi
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - VMware
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-26 00:00:00.000000000 Z
11
+ date: 2016-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bosh_common