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 +4 -4
- data/lib/cloud/vsphere.rb +1 -0
- data/lib/cloud/vsphere/agent_env.rb +2 -2
- data/lib/cloud/vsphere/client.rb +2 -12
- data/lib/cloud/vsphere/cloud.rb +33 -20
- data/lib/cloud/vsphere/cloud_searcher.rb +3 -3
- data/lib/cloud/vsphere/disk_provider.rb +12 -1
- data/lib/cloud/vsphere/file_provider.rb +2 -2
- data/lib/cloud/vsphere/fixed_cluster_placer.rb +7 -0
- data/lib/cloud/vsphere/object_stringifier.rb +15 -0
- data/lib/cloud/vsphere/resources.rb +4 -2
- data/lib/cloud/vsphere/resources/cluster.rb +14 -4
- data/lib/cloud/vsphere/resources/cluster_provider.rb +2 -2
- data/lib/cloud/vsphere/resources/datacenter.rb +16 -9
- data/lib/cloud/vsphere/resources/datastore.rb +2 -0
- data/lib/cloud/vsphere/resources/disk/ephemeral_disk.rb +2 -1
- data/lib/cloud/vsphere/resources/folder.rb +1 -1
- data/lib/cloud/vsphere/resources/vm.rb +10 -2
- data/lib/cloud/vsphere/vm_creator.rb +9 -4
- data/lib/cloud/vsphere/vm_provider.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60b9ea302efbf07e91dd0adc105f975ec8dcacd8
|
4
|
+
data.tar.gz: 1c8ef64cfb700603dd0a14f8c3e4179461225e2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c86a93bead968a65f17b37c63b03110ec6a41d4ec8a6507796243a6d4a2da4e4327c41fb314e6deeeb4ee513d3c3321133fb45cd0cf7cbda8e4fba2132aa654
|
7
|
+
data.tar.gz: 07864ca78d8e30f593e91f031d24248eedacdb93472d20654e3409f79fd2aa746d844dd75f54b7f018eb797c0108b9906faae4f58f17d4b20a92d2efc5d5fc0a
|
data/lib/cloud/vsphere.rb
CHANGED
@@ -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(
|
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(
|
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
|
data/lib/cloud/vsphere/client.rb
CHANGED
@@ -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
|
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
|
data/lib/cloud/vsphere/cloud.rb
CHANGED
@@ -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
|
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
|
-
|
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
|
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
|
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
|
-
|
390
|
-
|
391
|
-
raise "Could not find stemcell
|
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
|
-
|
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 =
|
497
|
-
ephemeral_disks.
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
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 "
|
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
|
-
|
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
|
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
|
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
|
-
|
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
|
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
|
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
|
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
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
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
|
@@ -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}
|
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
|
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
|
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}
|
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
|
-
|
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
|
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.
|
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-
|
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
|