bosh_vsphere_cpi 2.0.0 → 2.1.0

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: 0a34eef018c05343002743fbf10d259455c34ebe
4
- data.tar.gz: 268febe0f8b3d79243d7edcd2749c2bf2c989935
3
+ metadata.gz: 60b9ea302efbf07e91dd0adc105f975ec8dcacd8
4
+ data.tar.gz: 1c8ef64cfb700603dd0a14f8c3e4179461225e2d
5
5
  SHA512:
6
- metadata.gz: 3c65dc3f129c698aeaed6bea1fd597e40b8d7b90a5fddb7933cad41a70af2e3db50509366dc834c1e857f7c690ca5497086c66c8c6ca6ddb3134cbe4157a6a35
7
- data.tar.gz: 6161c9e5cec6d4c97f94421bcac212c577a913140d566701ac2bf039edf6fc8bfaab455d5756b7d3c30b4f1013a336485535f66e0b447a3b9cefec5d5c34c1fb
6
+ metadata.gz: 6c86a93bead968a65f17b37c63b03110ec6a41d4ec8a6507796243a6d4a2da4e4327c41fb314e6deeeb4ee513d3c3321133fb45cd0cf7cbda8e4fba2132aa654
7
+ data.tar.gz: 07864ca78d8e30f593e91f031d24248eedacdb93472d20654e3409f79fd2aa746d844dd75f54b7f018eb797c0108b9906faae4f58f17d4b20a92d2efc5d5fc0a
@@ -5,6 +5,7 @@ require 'common/thread_formatter'
5
5
  require 'ruby_vim_sdk'
6
6
 
7
7
  require 'cloud/vsphere/retry_block'
8
+ require 'cloud/vsphere/object_stringifier'
8
9
  require 'cloud/vsphere/agent_env'
9
10
  require 'cloud/vsphere/client'
10
11
  require 'cloud/vsphere/cloud'
@@ -17,11 +17,11 @@ module VSphereCloud
17
17
  datastore_name = cdrom.backing.datastore.name
18
18
  datastore_pattern = Regexp.escape(datastore_name)
19
19
  result = env_iso_folder.match(/\[#{datastore_pattern}\] (.*)/)
20
- raise Bosh::Clouds::CloudError.new('Could not find matching datastore name') unless result
20
+ raise Bosh::Clouds::CloudError.new("Could not find matching datastore name '#{datastore_name}'") unless result
21
21
  env_path = result[1]
22
22
 
23
23
  contents = @file_provider.fetch_file(datacenter_name, datastore_name, "#{env_path}/env.json")
24
- raise Bosh::Clouds::CloudError.new('Unable to load env.json') unless contents
24
+ raise Bosh::Clouds::CloudError.new("Unable to load env.json from '#{env_path}/env.json'") unless contents
25
25
 
26
26
  JSON.load(contents)
27
27
  end
@@ -62,7 +62,7 @@ module VSphereCloud
62
62
  raise 'Recommendations were detected, you may be running in Manual DRS mode. Aborting.' if result.recommendations.any?
63
63
 
64
64
  if result.attempted.empty?
65
- raise "Could not power on VM: #{result.not_attempted.map(&:msg).join(', ')}"
65
+ raise "Could not power on VM '#{vm}': #{result.not_attempted.map(&:fault).map(&:msg).join(', ')}"
66
66
  else
67
67
  task = result.attempted.first.task
68
68
  wait_for_task(task)
@@ -120,16 +120,6 @@ module VSphereCloud
120
120
  @service_content.root_folder.create_folder(name)
121
121
  end
122
122
 
123
- def move_into_folder(folder, objects)
124
- task = folder.move_into(objects)
125
- wait_for_task(task)
126
- end
127
-
128
- def move_into_root_folder(objects)
129
- task = @service_content.root_folder.move_into(objects)
130
- wait_for_task(task)
131
- end
132
-
133
123
  def delete_folder(folder)
134
124
  task = folder.destroy
135
125
  wait_for_task(task)
@@ -152,7 +142,7 @@ module VSphereCloud
152
142
  )[task]
153
143
 
154
144
  duration = Time.now - started
155
- raise "Task taking too long" if duration > 3600 # 1 hour
145
+ raise "Task exceeded 60 minutes, task properties: #{properties}" if duration > 3600 # 1 hour
156
146
 
157
147
  # Update the polling interval based on task progress
158
148
  if properties["info.progress"] && properties["info.progress"] > 0
@@ -8,8 +8,16 @@ module VSphereCloud
8
8
  include RetryBlock
9
9
 
10
10
  class TimeoutException < StandardError; end
11
+ class NetworkException < StandardError
12
+ attr_accessor :vm_cid
13
+
14
+ def message
15
+ super + (vm_cid ? " for VM '#{vm_cid}'" : '')
16
+ end
17
+ end
11
18
 
12
19
  attr_accessor :client
20
+ attr_reader :datacenter
13
21
 
14
22
  def initialize(options)
15
23
  @config = Config.build(options)
@@ -71,10 +79,10 @@ module VSphereCloud
71
79
  Dir.mktmpdir do |temp_dir|
72
80
  @logger.info("Extracting stemcell to: #{temp_dir}")
73
81
  output = `tar -C #{temp_dir} -xzf #{image} 2>&1`
74
- raise "Corrupt image, tar exit status: #{$?.exitstatus} output: #{output}" if $?.exitstatus != 0
82
+ raise "Corrupt image '#{image}', tar exit status: #{$?.exitstatus}, output: #{output}" if $?.exitstatus != 0
75
83
 
76
84
  ovf_file = Dir.entries(temp_dir).find { |entry| File.extname(entry) == '.ovf' }
77
- raise 'Missing OVF' if ovf_file.nil?
85
+ raise "Missing OVF for stemcell '#{stemcell}'" if ovf_file.nil?
78
86
  ovf_file = File.join(temp_dir, ovf_file)
79
87
 
80
88
  name = "sc-#{SecureRandom.uuid}"
@@ -276,8 +284,12 @@ module VSphereCloud
276
284
  @logger.debug("Reading current agent env: #{env.pretty_inspect}")
277
285
 
278
286
  devices = @cloud_searcher.get_property(vm.mob, Vim::VirtualMachine, 'config.hardware.device', ensure_all: true)
279
- env['networks'] = generate_network_env(devices, networks, dvs_index)
280
-
287
+ begin
288
+ env['networks'] = generate_network_env(devices, networks, dvs_index)
289
+ rescue NetworkException => e
290
+ e.vm_cid = vm_cid
291
+ raise e
292
+ end
281
293
  @logger.debug("Updating agent env to: #{env.pretty_inspect}")
282
294
  location = get_vm_location(vm.mob, datacenter: @datacenter.name)
283
295
  @agent_env.set_env(vm.mob, location, env)
@@ -334,7 +346,7 @@ module VSphereCloud
334
346
 
335
347
  vm.reload
336
348
  virtual_disk = vm.disk_by_cid(disk.cid)
337
- raise Bosh::Clouds::DiskNotAttached.new(true), "Disk (#{disk.cid}) is not attached to VM (#{vm.cid})" if virtual_disk.nil?
349
+ raise Bosh::Clouds::DiskNotAttached.new(true), "Disk '#{disk.cid}' is not attached to VM '#{vm.cid}'" if virtual_disk.nil?
338
350
 
339
351
  config = Vim::Vm::ConfigSpec.new
340
352
  config.device_change = []
@@ -353,7 +365,7 @@ module VSphereCloud
353
365
  break if virtual_disk.nil?
354
366
  sleep(1.0)
355
367
  end
356
- raise "Failed to detach disk: #{disk.cid} from vm: #{vm.cid}" unless virtual_disk.nil?
368
+ raise "Failed to detach disk '#{disk.cid}' from vm '#{vm.cid}'" unless virtual_disk.nil?
357
369
 
358
370
  @logger.info('Finished detaching disk')
359
371
  end
@@ -386,9 +398,9 @@ module VSphereCloud
386
398
  end
387
399
 
388
400
  def replicate_stemcell(cluster, datastore, stemcell)
389
- stemcell_vm = client.find_by_inventory_path([cluster.datacenter.name, 'vm',
390
- cluster.datacenter.template_folder.path_components, stemcell])
391
- raise "Could not find stemcell: #{stemcell}" if stemcell_vm.nil?
401
+ stemcell_vm_path_components = [cluster.datacenter.name, 'vm', cluster.datacenter.template_folder.path_components, stemcell]
402
+ stemcell_vm = client.find_by_inventory_path(stemcell_vm_path_components)
403
+ raise "Could not find VM for stemcell '#{stemcell}' at path '#{stemcell_vm_path_components.join("/")}'" if stemcell_vm.nil?
392
404
  stemcell_datastore = @cloud_searcher.get_property(stemcell_vm, Vim::VirtualMachine, 'datastore', ensure_all: true)
393
405
 
394
406
  if stemcell_datastore != datastore.mob
@@ -435,7 +447,9 @@ module VSphereCloud
435
447
  networks.each do |network_name, network|
436
448
  network_entry = network.dup
437
449
  v_network_name = network['cloud_properties']['name']
438
- nic = nics[v_network_name].pop
450
+ network = nics[v_network_name]
451
+ raise NetworkException, "Could not find network '#{v_network_name}'" if network.nil?
452
+ nic = network.pop
439
453
  network_entry['mac'] = nic.mac_address
440
454
  network_env[network_name] = network_entry
441
455
  end
@@ -481,7 +495,7 @@ module VSphereCloud
481
495
 
482
496
  unless datastore_name
483
497
  devices = vm_properties['config.hardware.device']
484
- datastore = get_primary_datastore(devices)
498
+ datastore = get_primary_datastore(devices, vm_name)
485
499
  datastore_name = @cloud_searcher.get_property(datastore, Vim::Datastore, 'name')
486
500
  end
487
501
  end
@@ -489,17 +503,16 @@ module VSphereCloud
489
503
  { datacenter: datacenter_name, datastore: datastore_name, vm: vm_name }
490
504
  end
491
505
 
492
- def get_primary_datastore(devices)
506
+ def get_primary_datastore(devices, vm_name = nil)
493
507
  ephemeral_disks = devices.select { |device| device.kind_of?(Vim::Vm::Device::VirtualDisk) &&
494
508
  device.backing.disk_mode != Vim::Vm::Device::VirtualDiskOption::DiskMode::INDEPENDENT_PERSISTENT }
495
509
 
496
- datastore = nil
497
- ephemeral_disks.each do |disk|
498
- if datastore
499
- raise 'Ephemeral disks should all be on the same datastore.' unless datastore.eql?(disk.backing.datastore)
500
- else
501
- datastore = disk.backing.datastore
502
- end
510
+ datastore = ephemeral_disks.first.backing.datastore
511
+ disk_in_wrong_datastore = ephemeral_disks.find { |disk| !datastore.eql?(disk.backing.datastore) }
512
+ if disk_in_wrong_datastore
513
+ error_msg = vm_name ? "for VM '#{vm_name}'" : ""
514
+ raise "Ephemeral disks #{error_msg} should all be on the same datastore. " +
515
+ "Expected datastore '#{datastore}' to match datastore '#{disk_in_wrong_datastore.backing.datastore}'"
503
516
  end
504
517
 
505
518
  datastore
@@ -524,7 +537,7 @@ module VSphereCloud
524
537
  end
525
538
 
526
539
  def create_nic_config_spec(v_network_name, network, controller_key, dvs_index)
527
- raise "Can't find network: #{v_network_name}" if network.nil?
540
+ raise "Invalid network '#{v_network_name}'" if network.nil?
528
541
  if network.class == Vim::Dvs::DistributedVirtualPortgroup
529
542
  portgroup_properties = @cloud_searcher.get_properties(network,
530
543
  Vim::Dvs::DistributedVirtualPortgroup,
@@ -50,7 +50,7 @@ module VSphereCloud
50
50
  end
51
51
  end
52
52
  unless remaining_properties.empty?
53
- raise MissingPropertiesException.new("The object[s] #{obj} " +
53
+ raise MissingPropertiesException.new("The object[s] '#{obj}' " +
54
54
  "should have the following properties: #{properties.pretty_inspect}, " +
55
55
  "but they were missing these: #{remaining_properties.pretty_inspect}.")
56
56
  end
@@ -93,8 +93,8 @@ module VSphereCloud
93
93
 
94
94
  def get_managed_object(type, options)
95
95
  result = get_managed_objects(type, options)
96
- raise "Could not find #{type}: #{options.pretty_inspect}" if result.length == 0
97
- raise "Found more than one #{type}: #{options.pretty_inspect}" if result.length > 1
96
+ raise "Could not find '#{type}': #{options.pretty_inspect}" if result.length == 0
97
+ raise "Found more than one '#{type}': #{options.pretty_inspect}" if result.length > 1
98
98
  result.first
99
99
  end
100
100
 
@@ -26,7 +26,9 @@ module VSphereCloud
26
26
 
27
27
  def find_and_move(disk_cid, cluster, datacenter, accessible_datastores)
28
28
  disk = find(disk_cid)
29
- return disk if accessible_datastores.include?(disk.datastore.name)
29
+ disk_in_persistent_datastore = @datacenter.persistent_datastores.include?(disk.datastore.name)
30
+ disk_in_accessible_datastore = accessible_datastores.include?(disk.datastore.name)
31
+ return disk if disk_in_persistent_datastore && disk_in_accessible_datastore
30
32
 
31
33
  destination_datastore = @resources.pick_persistent_datastore_in_cluster(cluster.name, disk.size_in_mb)
32
34
 
@@ -46,6 +48,15 @@ module VSphereCloud
46
48
  @logger.debug("Looking for disk #{disk_cid} in datastores: #{persistent_datastores}")
47
49
  persistent_datastores.each do |_, datastore|
48
50
  disk = @client.find_disk(disk_cid, datastore, @disk_path)
51
+ @logger.debug("disk #{disk_cid} found in: #{datastore}") unless disk.nil?
52
+ return disk unless disk.nil?
53
+ end
54
+
55
+ other_datastores = @datacenter.all_datastores.reject{|datastore_name, _| persistent_datastores[datastore_name] }
56
+ @logger.debug("disk #{disk_cid} not found in filtered persistent datastores, trying other datastores: #{other_datastores}")
57
+ other_datastores.each do |_, datastore|
58
+ disk = @client.find_disk(disk_cid, datastore, @disk_path)
59
+ @logger.debug("disk #{disk_cid} found in: #{datastore}") unless disk.nil?
49
60
  return disk unless disk.nil?
50
61
  end
51
62
 
@@ -19,7 +19,7 @@ module VSphereCloud
19
19
  elsif response.code == 404
20
20
  nil
21
21
  else
22
- raise "Could not fetch file: #{url}, status code: #{response.code}"
22
+ raise "Could not fetch file '#{url}', received status code '#{response.code}'"
23
23
  end
24
24
  end
25
25
  end
@@ -35,7 +35,7 @@ module VSphereCloud
35
35
  { 'Content-Type' => 'application/octet-stream', 'Content-Length' => contents.length })
36
36
 
37
37
  unless response.code < 400
38
- raise "Could not upload file: #{url}, status code: #{response.code}"
38
+ raise "Could not upload file '#{url}', received status code '#{response.code}'"
39
39
  end
40
40
  end
41
41
  end
@@ -1,5 +1,8 @@
1
1
  module VSphereCloud
2
2
  class FixedClusterPlacer
3
+ include ObjectStringifier
4
+ stringify_with :cluster
5
+
3
6
  attr_reader :drs_rules
4
7
 
5
8
  def initialize(cluster, drs_rules)
@@ -21,5 +24,9 @@ module VSphereCloud
21
24
  def pick_persistent_datastore(_, _)
22
25
  raise NotImplementedError
23
26
  end
27
+
28
+ private
29
+
30
+ attr_reader :cluster
24
31
  end
25
32
  end
@@ -0,0 +1,15 @@
1
+ module VSphereCloud
2
+ module ObjectStringifier
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def stringify_with(*attributes)
9
+ define_method(:to_s) do
10
+ "(#{self.class.name} (#{attributes.map{|attr| "#{attr}=\"#{self.send(attr)}\""}.join(', ')}))"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -2,6 +2,8 @@ require 'cloud/vsphere/resources/datacenter'
2
2
 
3
3
  module VSphereCloud
4
4
  class Resources
5
+ include ObjectStringifier
6
+ stringify_with :datacenter
5
7
  MEMORY_HEADROOM = 128
6
8
  DISK_HEADROOM = 1024
7
9
  STALE_TIMEOUT = 60
@@ -28,7 +30,7 @@ module VSphereCloud
28
30
  @lock.synchronize do
29
31
  cluster = @datacenter.clusters[cluster_name]
30
32
  if cluster.nil?
31
- raise Bosh::Clouds::CloudError, "Couldn't find cluster '#{cluster_name}'. Found #{@datacenter.clusters.values.map(&:name)}"
33
+ raise Bosh::Clouds::CloudError, "Couldn't find cluster '#{cluster_name}'. Found: #{@datacenter.clusters.values.map(&:name)}"
32
34
  end
33
35
 
34
36
  datastore = cluster.pick_persistent(disk_size_in_mb)
@@ -122,7 +124,7 @@ module VSphereCloud
122
124
 
123
125
  private
124
126
 
125
- attr_reader :config
127
+ attr_reader :config, :datacenter
126
128
 
127
129
 
128
130
  class PersistentDiskIndex
@@ -4,6 +4,8 @@ module VSphereCloud
4
4
  class Resources
5
5
  class Cluster
6
6
  include VimSdk
7
+ include ObjectStringifier
8
+ stringify_with :name
7
9
 
8
10
  PROPERTIES = %w(name datastore resourcePool host)
9
11
  HOST_PROPERTIES = %w(hardware.memorySize runtime.inMaintenanceMode)
@@ -114,14 +116,22 @@ module VSphereCloud
114
116
  @persistent_datastores ||= select_datastores(@datacenter_persistent_datastore_pattern)
115
117
  end
116
118
 
119
+ def all_datastores
120
+ @all_datastores ||= Datastore.build_from_client(
121
+ @client,
122
+ properties['datastore']
123
+ ).inject({}) do |acc, datastore|
124
+ acc[datastore.name] = datastore
125
+ acc
126
+ end
127
+ end
128
+
117
129
  private
118
130
 
119
131
  attr_reader :config, :client, :properties, :logger
120
132
 
121
133
  def select_datastores(pattern)
122
- @datastores ||= Datastore.build_from_client(@client, properties['datastore'])
123
- matching_datastores = @datastores.select { |datastore| datastore.name =~ pattern }
124
- matching_datastores.inject({}) { |h, datastore| h[datastore.name] = datastore; h }
134
+ all_datastores.select { |name, datastore| name =~ pattern }
125
135
  end
126
136
 
127
137
  def pick_store(type, size)
@@ -204,7 +214,7 @@ module VSphereCloud
204
214
  # @return [void]
205
215
  def fetch_resource_pool_utilization
206
216
  properties = @client.cloud_searcher.get_properties(resource_pool.mob, Vim::ResourcePool, 'summary')
207
- raise "Failed to get utilization for resource pool #{resource_pool}" if properties.nil?
217
+ raise "Failed to get utilization for resource pool '#{resource_pool}'" if properties.nil?
208
218
 
209
219
  runtime_info = properties["summary"].runtime
210
220
 
@@ -9,13 +9,13 @@ module VSphereCloud
9
9
 
10
10
  def find(name, config)
11
11
  cluster_mob = cluster_mobs[name]
12
- raise "Can't find cluster: #{name}" if cluster_mob.nil?
12
+ raise "Can't find cluster '#{name}'" if cluster_mob.nil?
13
13
 
14
14
  cluster_properties = @client.cloud_searcher.get_properties(
15
15
  cluster_mob, VimSdk::Vim::ClusterComputeResource,
16
16
  Cluster::PROPERTIES, :ensure_all => true
17
17
  )
18
- raise "Can't find properties for cluster: #{name}" if cluster_properties.nil?
18
+ raise "Can't find properties for cluster '#{name}'" if cluster_properties.nil?
19
19
 
20
20
  Cluster.new(
21
21
  @datacenter,
@@ -4,6 +4,8 @@ module VSphereCloud
4
4
  class Resources
5
5
  class Datacenter
6
6
  include VimSdk
7
+ include ObjectStringifier
8
+ stringify_with :name
7
9
 
8
10
  attr_accessor :config
9
11
 
@@ -27,7 +29,7 @@ module VSphereCloud
27
29
 
28
30
  def mob
29
31
  mob = @client.find_by_inventory_path(name)
30
- raise "Datacenter: #{name} not found" if mob.nil?
32
+ raise "Datacenter '#{name}' not found" if mob.nil?
31
33
  mob
32
34
  end
33
35
 
@@ -70,17 +72,22 @@ module VSphereCloud
70
72
  @clusters.each do |cluster_name, cluster_config|
71
73
  clusters[cluster_name] = @cluster_provider.find(cluster_name, cluster_config)
72
74
  end
75
+ @logger.debug("All clusters provided: #{@clusters}")
73
76
  clusters
74
77
  end
75
78
 
76
79
  def persistent_datastores
77
- datastores = {}
78
- clusters.each do |_, cluster|
79
- cluster.persistent_datastores.each do |_, datastore|
80
- datastores[datastore.name] = datastore
81
- end
80
+ clusters.values.inject({}) do |acc, cluster|
81
+ acc.merge!(cluster.persistent_datastores)
82
+ acc
83
+ end
84
+ end
85
+
86
+ def all_datastores
87
+ clusters.values.inject({}) do |acc, cluster|
88
+ acc.merge!(cluster.all_datastores)
89
+ acc
82
90
  end
83
- datastores
84
91
  end
85
92
 
86
93
  def pick_persistent_datastore(size)
@@ -95,14 +102,14 @@ module VSphereCloud
95
102
  datastores = persistent_datastores.values
96
103
  available_datastores = datastores.reject { |datastore| datastore.free_space - size < DISK_HEADROOM }
97
104
 
98
- @logger.debug("Looking for a #{type} datastore with #{size}MB free space.")
105
+ @logger.debug("Looking for a '#{type}' datastore with #{size}MB free space.")
99
106
  @logger.debug("All datastores: #{datastores.map(&:debug_info)}")
100
107
  @logger.debug("Datastores with enough space: #{available_datastores.map(&:debug_info)}")
101
108
 
102
109
  selected_datastore = Util.weighted_random(available_datastores.map { |datastore| [datastore, datastore.free_space] })
103
110
 
104
111
  if selected_datastore.nil?
105
- raise Bosh::Clouds::NoDiskSpace.new(true), "Couldn't find a #{type} datastore with #{size}MB of free space. Found:\n #{datastores.map(&:debug_info).join("\n ")}\n"
112
+ raise Bosh::Clouds::NoDiskSpace.new(true), "Couldn't find a '#{type}' datastore with #{size}MB of free space. Found:\n #{datastores.map(&:debug_info).join("\n ")}\n"
106
113
  end
107
114
  selected_datastore
108
115
  end
@@ -4,6 +4,8 @@ module VSphereCloud
4
4
  class Resources
5
5
  class Datastore
6
6
  include VimSdk
7
+ include ObjectStringifier
8
+ stringify_with :name, :mob
7
9
  PROPERTIES = %w(summary.freeSpace summary.capacity name)
8
10
 
9
11
  def self.build_from_client(client, datastore_properties)
@@ -2,6 +2,7 @@ require 'cloud/vsphere/resources/disk/disk_config'
2
2
 
3
3
  module VSphereCloud
4
4
  class EphemeralDisk
5
+ DISK_NAME = 'ephemeral_disk'
5
6
  def initialize(size_in_mb, folder_name, datastore)
6
7
  @folder_name = folder_name
7
8
  @datastore = datastore
@@ -15,7 +16,7 @@ module VSphereCloud
15
16
  private
16
17
 
17
18
  def filename
18
- "[#{@datastore.name}] #{@folder_name}/ephemeral_disk.vmdk"
19
+ "[#{@datastore.name}] #{@folder_name}/#{DISK_NAME}.vmdk"
19
20
  end
20
21
  end
21
22
  end
@@ -18,7 +18,7 @@ module VSphereCloud
18
18
  def find_or_create_folder(path_components)
19
19
  if path_components.empty?
20
20
  folder = root_vm_folder
21
- raise "Root VM Folder not found: #{@datacenter_name}/vm" if folder.nil?
21
+ raise "Root VM Folder not found '#{@datacenter_name}/vm'" if folder.nil?
22
22
  return folder
23
23
  end
24
24
 
@@ -3,6 +3,8 @@ module VSphereCloud
3
3
  class VM
4
4
  include VimSdk
5
5
  include RetryBlock
6
+ include ObjectStringifier
7
+ stringify_with :cid
6
8
 
7
9
  attr_reader :mob, :cid
8
10
 
@@ -64,6 +66,12 @@ module VSphereCloud
64
66
  end
65
67
  end
66
68
 
69
+ def ephemeral_disk
70
+ devices.find do |device|
71
+ device.kind_of?(Vim::Vm::Device::VirtualDisk) && device.backing.file_name =~ /#{VSphereCloud::EphemeralDisk::DISK_NAME}.vmdk$/
72
+ end
73
+ end
74
+
67
75
  def pci_controller
68
76
  devices.find { |device| device.kind_of?(Vim::Vm::Device::VirtualPCIController) }
69
77
  end
@@ -157,12 +165,12 @@ module VSphereCloud
157
165
  end
158
166
  end
159
167
 
160
- private
161
-
162
168
  def power_state
163
169
  properties['runtime.powerState']
164
170
  end
165
171
 
172
+ private
173
+
166
174
  def properties
167
175
  @properties ||= cloud_searcher.get_properties(
168
176
  @mob,
@@ -19,7 +19,7 @@ module VSphereCloud
19
19
 
20
20
  def create(agent_id, stemcell_cid, networks, persistent_disk_cids, environment)
21
21
  stemcell_vm = @cpi.stemcell_vm(stemcell_cid)
22
- raise "Could not find stemcell: #{stemcell_cid}" if stemcell_vm.nil?
22
+ raise "Could not find VM for stemcell '#{stemcell_cid}'" if stemcell_vm.nil?
23
23
 
24
24
  stemcell_size =
25
25
  @cloud_searcher.get_property(stemcell_vm, VimSdk::Vim::VirtualMachine, 'summary.storage.committed', ensure_all: true)
@@ -94,13 +94,18 @@ module VSphereCloud
94
94
 
95
95
  @agent_env.set_env(created_vm.mob, location, env)
96
96
 
97
- @logger.info("Powering on VM: #{created_vm} (#{created_vm.cid})")
97
+ @logger.info("Powering on VM: #{created_vm}")
98
98
  created_vm.power_on
99
99
 
100
100
  create_drs_rules(created_vm.mob, cluster)
101
101
  rescue => e
102
+ e.vm_cid = vm_cid if e.instance_of?(Cloud::NetworkException)
102
103
  @logger.info("#{e} - #{e.backtrace.join("\n")}")
103
- created_vm.delete if created_vm
104
+ begin
105
+ created_vm.delete if created_vm
106
+ rescue => ex
107
+ @logger.info("Failed to delete vm '#{vm_cid}' with message: #{ex.inspect}")
108
+ end
104
109
  raise e
105
110
  end
106
111
 
@@ -118,7 +123,7 @@ module VSphereCloud
118
123
  rule_config = @placer.drs_rules.first
119
124
 
120
125
  if rule_config['type'] != 'separate_vms'
121
- raise "vSphere CPI only supports DRS rule of 'separate_vms' type"
126
+ raise "vSphere CPI only supports DRS rule of 'separate_vms' type, not '#{rule_config['type']}'"
122
127
  end
123
128
 
124
129
  drs_rule = VSphereCloud::DrsRule.new(
@@ -8,7 +8,7 @@ module VSphereCloud
8
8
 
9
9
  def find(vm_cid)
10
10
  vm_mob = @client.find_by_inventory_path(@datacenter.vm_path(vm_cid))
11
- raise Bosh::Clouds::VMNotFound, "VM `#{vm_cid}' not found" if vm_mob.nil?
11
+ raise Bosh::Clouds::VMNotFound, "VM '#{vm_cid}' not found at path '#{@datacenter.vm_path(vm_cid)}'" if vm_mob.nil?
12
12
 
13
13
  Resources::VM.new(vm_cid, vm_mob, @client, @logger)
14
14
  end
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.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - VMware
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-02 00:00:00.000000000 Z
11
+ date: 2015-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bosh_common
@@ -133,6 +133,7 @@ files:
133
133
  - lib/cloud/vsphere/fixed_cluster_placer.rb
134
134
  - lib/cloud/vsphere/lease_obtainer.rb
135
135
  - lib/cloud/vsphere/lease_updater.rb
136
+ - lib/cloud/vsphere/object_stringifier.rb
136
137
  - lib/cloud/vsphere/path_finder.rb
137
138
  - lib/cloud/vsphere/resources.rb
138
139
  - lib/cloud/vsphere/resources/cluster.rb