fog-vsphere 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -4
- data/CHANGELOG.md +8 -0
- data/CONTRIBUTORS.md +6 -0
- data/fog-vsphere.gemspec +1 -1
- data/lib/fog/vsphere/compute.rb +47 -3
- data/lib/fog/vsphere/models/compute/cdrom.rb +65 -0
- data/lib/fog/vsphere/models/compute/cdroms.rb +18 -0
- data/lib/fog/vsphere/models/compute/datacenter.rb +4 -0
- data/lib/fog/vsphere/models/compute/folder.rb +4 -0
- data/lib/fog/vsphere/models/compute/server.rb +8 -0
- data/lib/fog/vsphere/models/compute/storage_pod.rb +19 -0
- data/lib/fog/vsphere/models/compute/storage_pods.rb +22 -0
- data/lib/fog/vsphere/models/compute/volume.rb +1 -0
- data/lib/fog/vsphere/requests/compute/create_folder.rb +10 -0
- data/lib/fog/vsphere/requests/compute/create_vm.rb +163 -4
- data/lib/fog/vsphere/requests/compute/folder_destroy.rb +26 -0
- data/lib/fog/vsphere/requests/compute/get_folder.rb +4 -2
- data/lib/fog/vsphere/requests/compute/get_storage_pod.rb +31 -0
- data/lib/fog/vsphere/requests/compute/list_datacenters.rb +1 -1
- data/lib/fog/vsphere/requests/compute/list_datastores.rb +2 -1
- data/lib/fog/vsphere/requests/compute/list_networks.rb +2 -1
- data/lib/fog/vsphere/requests/compute/list_storage_pods.rb +45 -0
- data/lib/fog/vsphere/requests/compute/list_virtual_machines.rb +8 -4
- data/lib/fog/vsphere/requests/compute/list_vm_cdroms.rb +30 -0
- data/lib/fog/vsphere/requests/compute/list_vm_interfaces.rb +34 -13
- data/lib/fog/vsphere/requests/compute/list_vm_snapshots.rb +5 -1
- data/lib/fog/vsphere/requests/compute/modify_vm_cdrom.rb +25 -0
- data/lib/fog/vsphere/requests/compute/modify_vm_interface.rb +19 -2
- data/lib/fog/vsphere/requests/compute/modify_vm_volume.rb +1 -1
- data/lib/fog/vsphere/requests/compute/upload_iso.rb +34 -0
- data/lib/fog/vsphere/requests/compute/vm_clone.rb +68 -25
- data/lib/fog/vsphere/requests/compute/vm_reconfig_cdrom.rb +68 -0
- data/lib/fog/vsphere/version.rb +1 -1
- data/tests/models/compute/servers_tests.rb +1 -1
- data/tests/requests/compute/folder_destroy_tests.rb +21 -0
- data/tests/requests/compute/list_storage_pods_test.rb +10 -0
- data/tests/requests/compute/list_vm_cdroms_tests.rb +10 -0
- data/tests/requests/compute/modify_vm_cdrom_tests.rb +21 -0
- data/tests/requests/compute/vm_reconfig_cdrom_tests.rb +15 -0
- metadata +28 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f0eaac527da91308fec5066b89407f48b10c7ec
|
4
|
+
data.tar.gz: 150e3dc5e72cb0c27d617bf65b2d7db259edb609
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c03d49413d12ba37d6a02365932583cafc87634cafaf55c8bceadc687ef08a9e0f9134b7928eb2aed94099ef01ee395340d5b10f76351e3870c0e7e409baec5a
|
7
|
+
data.tar.gz: 2d78b5e76edff6315f2601fc1830ae395c2419b3e159632a3ad0261d2309c7271d3a303c16ad1b5883fa40ef73e43bfa8958ec92c868d1e0c32d3e78e7124da1
|
data/.travis.yml
CHANGED
@@ -6,8 +6,6 @@ matrix:
|
|
6
6
|
- rvm: jruby-head
|
7
7
|
fast_finish: true
|
8
8
|
include:
|
9
|
-
- rvm: 1.8.7
|
10
|
-
gemfile: gemfiles/Gemfile.1.9.2-
|
11
9
|
- rvm: 1.9.3
|
12
10
|
gemfile: gemfiles/Gemfile.1.9.2+
|
13
11
|
- rvm: 2.0.0
|
@@ -18,8 +16,6 @@ matrix:
|
|
18
16
|
gemfile: Gemfile
|
19
17
|
- rvm: 2.2.0
|
20
18
|
gemfile: Gemfile
|
21
|
-
- rvm: jruby-18mode
|
22
|
-
gemfile: gemfiles/Gemfile.1.9.2-
|
23
19
|
- rvm: jruby-19mode
|
24
20
|
gemfile: gemfiles/Gemfile.1.9.2+
|
25
21
|
- rvm: jruby-head
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
* Fix update_vm_interface
|
2
|
+
* Add add folder.destroy
|
3
|
+
* Implement CD-ROM options
|
4
|
+
* Implement storage pods
|
5
|
+
* Fix nil error when snapshots is called on a VM without snapshots
|
6
|
+
* No longer support Ruby 1.8
|
7
|
+
* Allow setting of boot order when using api > 5.0
|
8
|
+
* Select the most recent API version instead of 4.1
|
data/CONTRIBUTORS.md
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
* Carlos Sanchez <csanchez@maestrodev.com>
|
5
5
|
* Chris Thompson <chris.thompson@govdelivery.com>
|
6
6
|
* Chris Thompson <teaforthecat@gmail.com>
|
7
|
+
* Christopher Oliver <coliver@datapipe.com>
|
7
8
|
* Cyrus Team <cyrusteam@cyruslists.com>
|
8
9
|
* Darren Foo <stonith@users.noreply.github.com>
|
9
10
|
* Dominic Cleal <dcleal@redhat.com>
|
@@ -14,6 +15,8 @@
|
|
14
15
|
* Francois Herbert <francois@herbert.org.nz>
|
15
16
|
* Ivan Nečas <inecas@redhat.com>
|
16
17
|
* Ivo Reznicek <ireznice@googlemail.com>
|
18
|
+
* J.R. Garcia <jr@garciaole.com>
|
19
|
+
* J.R. Garcia <jrg@vmware.com>
|
17
20
|
* James Herdman <james.herdman@me.com>
|
18
21
|
* Jeff McCune <jeff@puppetlabs.com>
|
19
22
|
* Justin Clayton <justin.clayton@gettyimages.com>
|
@@ -42,11 +45,14 @@
|
|
42
45
|
* Oscar Elfving <sofam84@gmail.com>
|
43
46
|
* Paul Thornthwaite <paul@brightbox.co.uk>
|
44
47
|
* Paul Thornthwaite <tokengeek@gmail.com>
|
48
|
+
* Paulo Henrique Lopes Ribeiro <plribeiro3000@gmail.com>
|
49
|
+
* Rich Daley <rdaley@williamhill.co.uk>
|
45
50
|
* Rich Lane <rlane@club.cc.cmu.edu>
|
46
51
|
* Samuel Keeley <samuel@dropbox.com>
|
47
52
|
* Shlomi Zadok <shlomi@ben-hanna.com>
|
48
53
|
* Simon Josi <me@yokto.net>
|
49
54
|
* Tejas Ravindra Mandke <tejas@identified.com>
|
55
|
+
* Timo Goebel <timo.goebel@dm.de>
|
50
56
|
* Timur Alperovich <timur@maginatics.com>
|
51
57
|
* Wesley Beary <geemus+github@gmail.com>
|
52
58
|
* Wesley Beary <geemus@gmail.com>
|
data/fog-vsphere.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.required_ruby_version = '>= 1.8.7'
|
23
23
|
|
24
|
-
spec.add_runtime_dependency 'fog-core'
|
24
|
+
spec.add_runtime_dependency 'fog-core'
|
25
25
|
spec.add_runtime_dependency 'rbvmomi', '~> 1.8'
|
26
26
|
|
27
27
|
spec.add_development_dependency 'bundler', '~> 1.10'
|
data/lib/fog/vsphere/compute.rb
CHANGED
@@ -33,6 +33,8 @@ module Fog
|
|
33
33
|
collection :networks
|
34
34
|
model :datastore
|
35
35
|
collection :datastores
|
36
|
+
model :storage_pod
|
37
|
+
collection :storage_pods
|
36
38
|
model :folder
|
37
39
|
collection :folders
|
38
40
|
model :customvalue
|
@@ -41,6 +43,8 @@ module Fog
|
|
41
43
|
collection :customfields
|
42
44
|
model :scsicontroller
|
43
45
|
model :process
|
46
|
+
model :cdrom
|
47
|
+
collection :cdroms
|
44
48
|
|
45
49
|
request_path 'fog/vsphere/requests/compute'
|
46
50
|
request :current_time
|
@@ -63,6 +67,8 @@ module Fog
|
|
63
67
|
request :get_network
|
64
68
|
request :list_datastores
|
65
69
|
request :get_datastore
|
70
|
+
request :list_storage_pods
|
71
|
+
request :get_storage_pod
|
66
72
|
request :list_compute_resources
|
67
73
|
request :get_compute_resource
|
68
74
|
request :list_templates
|
@@ -73,11 +79,14 @@ module Fog
|
|
73
79
|
request :list_vm_interfaces
|
74
80
|
request :modify_vm_interface
|
75
81
|
request :modify_vm_volume
|
82
|
+
request :modify_vm_cdrom
|
76
83
|
request :list_vm_volumes
|
84
|
+
request :list_vm_cdroms
|
77
85
|
request :get_virtual_machine
|
78
86
|
request :vm_reconfig_hardware
|
79
87
|
request :vm_reconfig_memory
|
80
88
|
request :vm_reconfig_cpus
|
89
|
+
request :vm_reconfig_cdrom
|
81
90
|
request :vm_config_vnc
|
82
91
|
request :create_folder
|
83
92
|
request :list_server_types
|
@@ -93,6 +102,8 @@ module Fog
|
|
93
102
|
request :list_child_snapshots
|
94
103
|
request :revert_to_snapshot
|
95
104
|
request :list_processes
|
105
|
+
request :upload_iso
|
106
|
+
request :folder_destroy
|
96
107
|
|
97
108
|
module Shared
|
98
109
|
attr_reader :vsphere_is_vcenter
|
@@ -237,6 +248,17 @@ module Fog
|
|
237
248
|
"status" => "ok",
|
238
249
|
"summary" => "VM Network",
|
239
250
|
}],
|
251
|
+
"cdroms" =>
|
252
|
+
[{
|
253
|
+
"name" => "CD-/DVD-Drive 1",
|
254
|
+
"filename" => nil,
|
255
|
+
"key" => 3000,
|
256
|
+
"controller_key" => 200,
|
257
|
+
"unit_number" => 0,
|
258
|
+
"start_connected" => false,
|
259
|
+
"allow_guest_control" => true,
|
260
|
+
"connected" => false,
|
261
|
+
}],
|
240
262
|
"hypervisor" => "gunab.puppetlabs.lan",
|
241
263
|
"guest_id" => "rhel6_64Guest",
|
242
264
|
"tools_state" => "toolsOk",
|
@@ -308,7 +330,7 @@ module Fog
|
|
308
330
|
"tools_state" => "toolsOk",
|
309
331
|
"name" => "jefftest",
|
310
332
|
"operatingsystem" => "Red Hat Enterprise Linux 6 (64-bit)",
|
311
|
-
"path" => "/",
|
333
|
+
"path" => "/Solutions/wibble",
|
312
334
|
"tools_version" => "guestToolsUnmanaged",
|
313
335
|
"ipaddress" => "192.168.100.187",
|
314
336
|
"uuid" => "42329da7-e8ab-29ec-1892-d6a4a964912a",
|
@@ -318,8 +340,30 @@ module Fog
|
|
318
340
|
}
|
319
341
|
},
|
320
342
|
:datacenters => {
|
321
|
-
"Solutions" => {:name => "Solutions", :status => "grey"}
|
343
|
+
"Solutions" => {:name => "Solutions", :status => "grey", :path => ['Solutions']}
|
344
|
+
},
|
345
|
+
:folders => {
|
346
|
+
'wibble' => {
|
347
|
+
'name' => 'wibble',
|
348
|
+
'datacenter' => 'Solutions',
|
349
|
+
'path' => '/Solutions/wibble',
|
350
|
+
'type' => 'vm'
|
351
|
+
},
|
352
|
+
'empty' => {
|
353
|
+
'name' => 'empty',
|
354
|
+
'datacenter' => 'Solutions',
|
355
|
+
'path' => '/Solutions/empty',
|
356
|
+
'type' => 'vm'
|
357
|
+
}
|
322
358
|
},
|
359
|
+
:storage_pods =>
|
360
|
+
[{:id => "group-p123456",
|
361
|
+
:name => "Datastore Cluster 1",
|
362
|
+
:freespace => "4856891834368",
|
363
|
+
:capacity => "7132061630464",
|
364
|
+
:datacenter => "Solutions",
|
365
|
+
},
|
366
|
+
],
|
323
367
|
:clusters =>
|
324
368
|
[{:id => "1d4d9a3f-e4e8-4c40-b7fc-263850068fa4",
|
325
369
|
:name => "Solutionscluster",
|
@@ -417,7 +461,7 @@ module Fog
|
|
417
461
|
# Negotiate the API revision
|
418
462
|
if not revision
|
419
463
|
rev = @connection.serviceContent.about.apiVersion
|
420
|
-
@connection.rev = [ rev, ENV['FOG_VSPHERE_REV'] || '4.1' ].
|
464
|
+
@connection.rev = [ rev, ENV['FOG_VSPHERE_REV'] || '4.1' ].max
|
421
465
|
end
|
422
466
|
|
423
467
|
@vsphere_is_vcenter = @connection.serviceContent.about.apiType == "VirtualCenter"
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Fog
|
2
|
+
module Compute
|
3
|
+
class Vsphere
|
4
|
+
class Cdrom < Fog::Model
|
5
|
+
identity :key
|
6
|
+
|
7
|
+
attribute :filename
|
8
|
+
attribute :name, :default => "CD-/DVD-ROM Drive"
|
9
|
+
attribute :controller_key
|
10
|
+
attribute :unit_number
|
11
|
+
attribute :start_connected
|
12
|
+
attribute :allow_guest_control
|
13
|
+
attribute :connected
|
14
|
+
|
15
|
+
has_one_identity :server, :servers, :aliases => :instance_uuid
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
name
|
19
|
+
end
|
20
|
+
|
21
|
+
def destroy
|
22
|
+
requires :instance_uuid, :key, :unit_number
|
23
|
+
|
24
|
+
service.destroy_vm_cdrom(self)
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
def save
|
29
|
+
requires :instance_uuid
|
30
|
+
|
31
|
+
if unit_number.nil?
|
32
|
+
used_unit_numbers = server.cdroms.map { |cdrom| cdrom.unit_number }
|
33
|
+
max_unit_number = used_unit_numbers.max
|
34
|
+
|
35
|
+
if max_unit_number > server.cdroms.size
|
36
|
+
# If the max ID exceeds the number of cdroms, there must be a hole in the range. Find a hole and use it.
|
37
|
+
self.unit_number = max_unit_number.times.to_a.find { |i| used_unit_numbers.exclude?(i) }
|
38
|
+
else
|
39
|
+
self.unit_number = max_unit_number + 1
|
40
|
+
end
|
41
|
+
else
|
42
|
+
if server.cdroms.any? { |cdrom| cdrom.unit_number == self.unit_number && cdrom.id != self.id }
|
43
|
+
raise "A cdrom already exists with that unit_number, so we can't save the new cdrom"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
data = service.add_vm_cdrom(self)
|
48
|
+
|
49
|
+
if data['task_state'] == 'success'
|
50
|
+
# We have to query vSphere to get the cdrom attributes since the task handle doesn't include that info.
|
51
|
+
created = server.cdroms.get(unit_number)
|
52
|
+
|
53
|
+
self.key = created.key
|
54
|
+
self.filename = created.filename
|
55
|
+
self.unit_number = created.unit_number
|
56
|
+
|
57
|
+
true
|
58
|
+
else
|
59
|
+
false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Fog
|
2
|
+
module Compute
|
3
|
+
class Vsphere
|
4
|
+
class Cdroms < Fog::Collection
|
5
|
+
attribute :instance_uuid, :alias => :server_id
|
6
|
+
model Fog::Compute::Vsphere::Cdrom
|
7
|
+
|
8
|
+
def all(filters = {})
|
9
|
+
load service.list_vm_cdroms(instance_uuid)
|
10
|
+
end
|
11
|
+
|
12
|
+
def get(unit_number)
|
13
|
+
all.find { |cdrom| cdrom.unit_number == unit_number }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -19,6 +19,10 @@ module Fog
|
|
19
19
|
service.datastores({ :datacenter => path.join("/") }.merge(filters))
|
20
20
|
end
|
21
21
|
|
22
|
+
def storage_pods filters = { }
|
23
|
+
service.storage_pods({ :datacenter => path.join("/") }.merge(filters))
|
24
|
+
end
|
25
|
+
|
22
26
|
def vm_folders filters = { }
|
23
27
|
service.folders({ :datacenter => path.join("/"), :type => :vm }.merge(filters))
|
24
28
|
end
|
@@ -237,6 +237,14 @@ module Fog
|
|
237
237
|
end
|
238
238
|
end
|
239
239
|
|
240
|
+
def cdroms(opts = {})
|
241
|
+
service.cdroms(:instance_uuid => self.id).all(opts)
|
242
|
+
end
|
243
|
+
|
244
|
+
def cdrom(key)
|
245
|
+
cdroms.get(key)
|
246
|
+
end
|
247
|
+
|
240
248
|
def guest_processes(opts = {})
|
241
249
|
fail 'VM tools must be running' unless tools_running?
|
242
250
|
service.list_processes(self.id, opts)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Fog
|
2
|
+
module Compute
|
3
|
+
class Vsphere
|
4
|
+
class StoragePod < Fog::Model
|
5
|
+
identity :id
|
6
|
+
|
7
|
+
attribute :name
|
8
|
+
attribute :datacenter
|
9
|
+
attribute :type
|
10
|
+
attribute :freespace
|
11
|
+
attribute :capacity
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
name
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'fog/core/collection'
|
2
|
+
require 'fog/vsphere/models/compute/storage_pod'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module Compute
|
6
|
+
class Vsphere
|
7
|
+
class StoragePods < Fog::Collection
|
8
|
+
model Fog::Compute::Vsphere::StoragePod
|
9
|
+
attribute :datacenter
|
10
|
+
|
11
|
+
def all(filters = {})
|
12
|
+
load service.list_storage_pods(filters.merge(datacenter: datacenter))
|
13
|
+
end
|
14
|
+
|
15
|
+
def get(id)
|
16
|
+
requires :datacenter
|
17
|
+
new service.get_storage_pod(id, datacenter)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -17,6 +17,16 @@ module Fog
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
20
|
+
class Mock
|
21
|
+
def create_folder(datacenter, path, name)
|
22
|
+
self.data[:folders][name] = {
|
23
|
+
'name' => name,
|
24
|
+
'datacenter' => datacenter,
|
25
|
+
'path' => "#{path}/#{name}",
|
26
|
+
'type' => 'vm'
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
20
30
|
end
|
21
31
|
end
|
22
32
|
end
|
@@ -19,13 +19,20 @@ module Fog
|
|
19
19
|
vm_cfg[:cpuHotAddEnabled] = attributes[:cpuHotAddEnabled] if attributes.key?(:cpuHotAddEnabled)
|
20
20
|
vm_cfg[:memoryHotAddEnabled] = attributes[:memoryHotAddEnabled] if attributes.key?(:memoryHotAddEnabled)
|
21
21
|
vm_cfg[:firmware] = attributes[:firmware] if attributes.key?(:firmware)
|
22
|
+
vm_cfg[:bootOptions] = boot_options(attributes) if attributes.key?(:boot_order)
|
22
23
|
resource_pool = if attributes[:resource_pool]
|
23
24
|
get_raw_resource_pool(attributes[:resource_pool], attributes[:cluster], attributes[:datacenter])
|
24
25
|
else
|
25
26
|
get_raw_cluster(attributes[:cluster], attributes[:datacenter]).resourcePool
|
26
27
|
end
|
27
28
|
vmFolder = get_raw_vmfolder(attributes[:path], attributes[:datacenter])
|
28
|
-
|
29
|
+
# if any volume has a storage_pod set, we deploy the vm on a storage pod instead of the defined datastores
|
30
|
+
pod = get_storage_pod(attributes)
|
31
|
+
if pod
|
32
|
+
vm = create_vm_on_storage_pod(pod, vm_cfg, vmFolder, resource_pool, attributes[:datacenter])
|
33
|
+
else
|
34
|
+
vm = create_vm_on_datastore(vm_cfg, vmFolder, resource_pool)
|
35
|
+
end
|
29
36
|
vm.config.instanceUuid
|
30
37
|
rescue => e
|
31
38
|
raise e, "failed to create vm: #{e}"
|
@@ -33,9 +40,47 @@ module Fog
|
|
33
40
|
|
34
41
|
private
|
35
42
|
|
43
|
+
def create_vm_on_datastore(vm_cfg, vmFolder, resource_pool)
|
44
|
+
vm = vmFolder.CreateVM_Task(:config => vm_cfg, :pool => resource_pool).wait_for_completion
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_vm_on_storage_pod(storage_pod, vm_cfg, vmFolder, resource_pool, datacenter)
|
48
|
+
pod_spec = RbVmomi::VIM::StorageDrsPodSelectionSpec.new(
|
49
|
+
:storagePod => get_raw_storage_pod(storage_pod, datacenter),
|
50
|
+
)
|
51
|
+
storage_spec = RbVmomi::VIM::StoragePlacementSpec.new(
|
52
|
+
:type => 'create',
|
53
|
+
:folder => vmFolder,
|
54
|
+
:resourcePool => resource_pool,
|
55
|
+
:podSelectionSpec => pod_spec,
|
56
|
+
:configSpec => vm_cfg,
|
57
|
+
)
|
58
|
+
srm = @connection.serviceContent.storageResourceManager
|
59
|
+
result = srm.RecommendDatastores(:storageSpec => storage_spec)
|
60
|
+
|
61
|
+
# if result array contains recommendation, we can apply it
|
62
|
+
if key = result.recommendations.first.key
|
63
|
+
result = srm.ApplyStorageDrsRecommendation_Task(:key => [key]).wait_for_completion
|
64
|
+
vm = result.vm
|
65
|
+
else
|
66
|
+
raise "Could not create vm on storage pod, did not get a storage recommendation"
|
67
|
+
end
|
68
|
+
vm
|
69
|
+
end
|
70
|
+
|
71
|
+
# check if a storage pool is set on any of the volumes and return the first result found or nil
|
72
|
+
# return early if vsphere revision is lower than 5 as this is not supported
|
73
|
+
def get_storage_pod attributes
|
74
|
+
return unless @vsphere_rev.to_f >= 5
|
75
|
+
volume = attributes[:volumes].detect {|volume| !( volume.storage_pod.nil? || volume.storage_pod.empty? ) }
|
76
|
+
volume.storage_pod if volume
|
77
|
+
end
|
78
|
+
|
36
79
|
# this methods defines where the vm config files would be located,
|
37
80
|
# by default we prefer to keep it at the same place the (first) vmdk is located
|
81
|
+
# if we deploy the vm on a storage pool, we have to return an empty string
|
38
82
|
def vm_path_name attributes
|
83
|
+
return '' if get_storage_pod(attributes)
|
39
84
|
datastore = attributes[:volumes].first.datastore unless attributes[:volumes].empty?
|
40
85
|
datastore ||= 'datastore1'
|
41
86
|
"[#{datastore}]"
|
@@ -49,11 +94,73 @@ module Fog
|
|
49
94
|
|
50
95
|
if (disks = attributes[:volumes])
|
51
96
|
devices << create_controller(attributes[:scsi_controller]||attributes["scsi_controller"]||{})
|
52
|
-
devices << disks.map { |disk| create_disk(disk, disks.index(disk)) }
|
97
|
+
devices << disks.map { |disk| create_disk(disk, disks.index(disk), :add, 1000, get_storage_pod(attributes)) }
|
98
|
+
end
|
99
|
+
|
100
|
+
if (cdroms = attributes[:cdroms])
|
101
|
+
devices << cdroms.map { |cdrom| create_cdrom(cdrom, cdroms.index(cdrom)) }
|
53
102
|
end
|
54
103
|
devices.flatten
|
55
104
|
end
|
56
105
|
|
106
|
+
def boot_options attributes
|
107
|
+
# NOTE: you must be using vsphere_rev 5.0 or greater to set boot_order
|
108
|
+
# e.g. Fog::Compute.new(provider: "vsphere", vsphere_rev: "5.5", etc)
|
109
|
+
return unless @vsphere_rev.to_f >= 5
|
110
|
+
RbVmomi::VIM::VirtualMachineBootOptions.new(
|
111
|
+
:bootOrder => boot_order(attributes)
|
112
|
+
)
|
113
|
+
end
|
114
|
+
|
115
|
+
def boot_order attributes
|
116
|
+
# attributes[:boot_order] may be an array like this ['network', 'disk']
|
117
|
+
# stating, that we want to prefer network boots over disk boots
|
118
|
+
boot_order = []
|
119
|
+
attributes[:boot_order].each do |boot_device|
|
120
|
+
case boot_device
|
121
|
+
when 'network'
|
122
|
+
if nics = attributes[:interfaces]
|
123
|
+
# key is based on 4000 + the interface index
|
124
|
+
# we allow booting from all network interfaces, the first interface has the highest priority
|
125
|
+
nics.each do |nic|
|
126
|
+
boot_order << RbVmomi::VIM::VirtualMachineBootOptionsBootableEthernetDevice.new(
|
127
|
+
:deviceKey => 4000 + nics.index(nic),
|
128
|
+
)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
when 'disk'
|
132
|
+
if disks = attributes[:volumes]
|
133
|
+
disks.each do |disk|
|
134
|
+
# we allow booting from all harddisks, the first disk has the highest priority
|
135
|
+
boot_order << RbVmomi::VIM::VirtualMachineBootOptionsBootableDiskDevice.new(
|
136
|
+
:deviceKey => disk.key || get_disk_device_key(disks.index(disk)),
|
137
|
+
)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
when 'cdrom'
|
141
|
+
boot_order << RbVmomi::VIM::VirtualMachineBootOptionsBootableCdromDevice.new()
|
142
|
+
when 'floppy'
|
143
|
+
boot_order << RbVmomi::VIM::VirtualMachineBootOptionsBootableFloppyDevice.new()
|
144
|
+
else
|
145
|
+
raise "failed to create boot device because \"#{boot_device}\" is unknown"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
boot_order
|
149
|
+
end
|
150
|
+
|
151
|
+
def get_disk_device_key(index)
|
152
|
+
# disk key is based on 2000 + the SCSI ID + the controller bus * 16
|
153
|
+
# the scsi host adapter appears as SCSI ID 7, so we have to skip that
|
154
|
+
# host adapter key is based on 1000 + bus id
|
155
|
+
# fog assumes that there is only a single scsi controller, see device_change()
|
156
|
+
if (index > 6) then
|
157
|
+
_index = index + 1
|
158
|
+
else
|
159
|
+
_index = index
|
160
|
+
end
|
161
|
+
2000 + _index
|
162
|
+
end
|
163
|
+
|
57
164
|
def create_nic_backing nic, attributes
|
58
165
|
raw_network = get_raw_network(nic.network, attributes[:datacenter], if nic.virtualswitch then nic.virtualswitch end)
|
59
166
|
|
@@ -121,19 +228,25 @@ module Fog
|
|
121
228
|
end
|
122
229
|
end
|
123
230
|
|
124
|
-
def create_disk disk, index = 0, operation = :add, controller_key = 1000
|
231
|
+
def create_disk disk, index = 0, operation = :add, controller_key = 1000, storage_pod = nil
|
125
232
|
if (index > 6) then
|
126
233
|
_index = index + 1
|
127
234
|
else
|
128
235
|
_index = index
|
129
236
|
end
|
237
|
+
# If we deploy the vm on a storage pod, datastore has to be an empty string
|
238
|
+
if storage_pod
|
239
|
+
datastore ''
|
240
|
+
else
|
241
|
+
datastore = "[#{disk.datastore}]"
|
242
|
+
end
|
130
243
|
payload = {
|
131
244
|
:operation => operation,
|
132
245
|
:fileOperation => operation == :add ? :create : :destroy,
|
133
246
|
:device => RbVmomi::VIM.VirtualDisk(
|
134
247
|
:key => disk.key || _index,
|
135
248
|
:backing => RbVmomi::VIM.VirtualDiskFlatVer2BackingInfo(
|
136
|
-
:fileName =>
|
249
|
+
:fileName => datastore,
|
137
250
|
:diskMode => disk.mode.to_sym,
|
138
251
|
:thinProvisioned => disk.thin
|
139
252
|
),
|
@@ -150,6 +263,22 @@ module Fog
|
|
150
263
|
payload
|
151
264
|
end
|
152
265
|
|
266
|
+
def create_cdrom cdrom, index = 0, operation = :add, controller_key = 200
|
267
|
+
{
|
268
|
+
:operation => operation,
|
269
|
+
:device => RbVmomi::VIM.VirtualCdrom(
|
270
|
+
:key => cdrom.key || index,
|
271
|
+
:backing => RbVmomi::VIM::VirtualCdromRemoteAtapiBackingInfo(deviceName: ''),
|
272
|
+
:controllerKey => controller_key,
|
273
|
+
connectable: RbVmomi::VIM::VirtualDeviceConnectInfo(
|
274
|
+
startConnected: false,
|
275
|
+
connected: false,
|
276
|
+
allowGuestControl: true,
|
277
|
+
),
|
278
|
+
)
|
279
|
+
}
|
280
|
+
end
|
281
|
+
|
153
282
|
def extra_config attributes
|
154
283
|
[
|
155
284
|
{
|
@@ -162,6 +291,36 @@ module Fog
|
|
162
291
|
|
163
292
|
class Mock
|
164
293
|
def create_vm attributes = { }
|
294
|
+
id = SecureRandom.uuid
|
295
|
+
vm = {
|
296
|
+
'id' => id,
|
297
|
+
'uuid' => id,
|
298
|
+
'instance_uuid' => id,
|
299
|
+
'mo_ref' => "vm-#{rand 99999}",
|
300
|
+
'datacenter' => attributes[:datacenter],
|
301
|
+
'name' => attributes[:name],
|
302
|
+
'interfaces' => attributes[:interfaces].map {{
|
303
|
+
'mac' => 'f2:b5:46:b5:d8:d7'
|
304
|
+
}}
|
305
|
+
}
|
306
|
+
self.data[:servers][id] = vm
|
307
|
+
id
|
308
|
+
end
|
309
|
+
|
310
|
+
def create_cdrom cdrom, index = 0, operation = :add, controller_key = 200
|
311
|
+
{
|
312
|
+
:operation => operation,
|
313
|
+
:device => {
|
314
|
+
:key => cdrom.key || index,
|
315
|
+
:backing => { deviceName: '' },
|
316
|
+
:controllerKey => controller_key,
|
317
|
+
connectable: {
|
318
|
+
startConnected: false,
|
319
|
+
connected: false,
|
320
|
+
allowGuestControl: true,
|
321
|
+
},
|
322
|
+
}
|
323
|
+
}
|
165
324
|
end
|
166
325
|
end
|
167
326
|
end
|