-
Notifications
You must be signed in to change notification settings - Fork 899
/
reconfigure.rb
196 lines (172 loc) · 6.67 KB
/
reconfigure.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
module ManageIQ::Providers::Vmware::InfraManager::Vm::Reconfigure
# Show Reconfigure VM task
def reconfigurable?
true
end
def max_total_vcpus
[host.hardware.cpu_total_cores, max_total_vcpus_by_version].min
end
def max_total_vcpus_by_version
case hardware.virtual_hw_version
when "04" then 4
when "07" then 8
when "08" then 32
when "09", "10" then 64
when "11" then 128
else
_log.warn("Add support for new hardware version [#{hardware.virtual_hw_version}].")
128
end
end
def max_cpu_cores_per_socket(_total_vcpus = nil)
case hardware.virtual_hw_version
when "04" then 1
when "07" then 8
when "08" then 32
when "09", "10" then 64
when "11" then 128
else
_log.warn("Add support for new hardware version [#{hardware.virtual_hw_version}].")
128
end
end
def max_vcpus
max_total_vcpus
end
def max_memory_mb
case hardware.virtual_hw_version
when "04" then 64.gigabyte / 1.megabyte
when "07" then 255.gigabyte / 1.megabyte
when "08", "09", "10" then 1011.gigabyte / 1.megabyte
when "11" then 4.terabyte / 1.megabyte
else
_log.warn("Add support for new hardware version [#{hardware.virtual_hw_version}].")
4.terabyte / 1.megabyte
end
end
def build_config_spec(options)
VimHash.new("VirtualMachineConfigSpec") do |vmcs|
case hardware.virtual_hw_version
when "07"
ec = VimArray.new('ArrayOfOptionValue')
ec << VimHash.new('OptionValue') do |ov|
ov.key = "cpuid.coresPerSocket"
ov.value = VimString.new(options[:cores_per_socket].to_s, nil, "xsd:string")
end
vmcs.extraConfig = ec
else
set_spec_option(vmcs, :numCoresPerSocket, options[:cores_per_socket], :to_i)
end
set_spec_option(vmcs, :memoryMB, options[:vm_memory], :to_i)
set_spec_option(vmcs, :numCPUs, options[:number_of_cpus], :to_i)
if options[:disk_remove] || options[:disk_add]
with_provider_object do |vim_obj|
options[:disk_remove].each { |d| remove_disk_config_spec(vim_obj, vmcs, d) } if options[:disk_remove]
add_disks(vim_obj, vmcs, options[:disk_add]) if options[:disk_add]
end
end
end
end
def add_disks(vim_obj, vmcs, disks)
controller_key, unit_number = vim_obj.send(:getScsiCandU)
# if there is no scsi controller
if controller_key.blank?
controller_key, unit_number = [-99, 0]
add_scsi_controller(vmcs, 0, controller_key)
end
disks.each do |d|
d[:controller_key] = controller_key
d[:unit_number] = unit_number
add_disk_config_spec(vmcs, d)
unit_number += 1
end
end
def add_scsi_controller(vmcs, bus_number, dev_key)
device_type = 'VirtualLsiLogicController'
add_device_config_spec(vmcs, VirtualDeviceConfigSpecOperation::Add) do |vdcs|
vdcs.device = VimHash.new(device_type) do |dev|
dev.sharedBus = VimString.new('noSharing', 'VirtualSCSISharing')
dev.busNumber = bus_number
dev.key = dev_key
end
end
end
def backing_filename
# create the new disk in the same datastore as the primary disk or the VM's config file
datastore = hardware.disks.order(:location).find_by(:device_type => 'disk').try(:storage) || storage
"[#{datastore.name}]"
end
def disk_mode(dependent, persistent)
if dependent
persistent ? VirtualDiskMode::Persistent : VirtualDiskMode::Nonpersistent
else
persistent ? VirtualDiskMode::Independent_persistent : VirtualDiskMode::Independent_nonpersistent
end
end
def add_disk_config_spec(vmcs, options)
raise "#{__method__}: Disk size is required to add a new disk." unless options[:disk_size_in_mb]
options.reverse_merge!(:thin_provisioned => true, :dependent => true, :persistent => true)
add_device_config_spec(vmcs, VirtualDeviceConfigSpecOperation::Add) do |vdcs|
vdcs.fileOperation = VirtualDeviceConfigSpecFileOperation::Create
vdcs.device = VimHash.new("VirtualDisk") do |dev|
dev.key = -100 * options[:unit_number] # temp key for creation
dev.capacityInKB = options[:disk_size_in_mb].to_i * 1024
dev.controllerKey = options[:controller_key]
dev.unitNumber = options[:unit_number]
dev.connectable = VimHash.new("VirtualDeviceConnectInfo") do |con|
con.allowGuestControl = "false"
con.startConnected = "true"
con.connected = "true"
end
dev.backing = VimHash.new("VirtualDiskFlatVer2BackingInfo") do |bck|
bck.diskMode = disk_mode(options[:dependent], options[:persistent])
bck.thinProvisioned = options[:thin_provisioned]
bck.fileName = backing_filename
end
end
end
end
def remove_disk_config_spec(vim_obj, vmcs, options)
raise "remove_disk_config_spec: disk filename is required." unless options[:disk_name]
options.reverse_merge!(:delete_backing => false)
controller_key, key = vim_obj.send(:getDeviceKeysByBacking, options[:disk_name])
raise "remove_disk_config_spec: no virtual device associated with: #{options[:disk_name]}" unless key
add_device_config_spec(vmcs, VirtualDeviceConfigSpecOperation::Remove) do |vdcs|
vdcs.fileOperation = VirtualDeviceConfigSpecFileOperation::Destroy if options[:delete_backing]
vdcs.device = VimHash.new("VirtualDisk") do |dev|
dev.key = key
dev.capacityInKB = 0
dev.controllerKey = controller_key
dev.connectable = VimHash.new("VirtualDeviceConnectInfo") do |con|
con.allowGuestControl = "false"
con.startConnected = "true"
con.connected = "true"
end
end
end
end
def add_device_config_spec(vmcs, operation)
vmcs_vca = vmcs.deviceChange ||= VimArray.new('ArrayOfVirtualDeviceConfigSpec')
vmcs_vca << VimHash.new('VirtualDeviceConfigSpec') do |vdcs|
vdcs.operation = operation
yield(vdcs)
end
end
# Set the value if it is not nil
def set_spec_option(obj, property, value, modifier = nil)
unless value.nil?
# Modifier is a method like :to_s or :to_i
value = value.to_s if [true, false].include?(value)
value = value.send(modifier) unless modifier.nil?
_log.info "#{property} was set to #{value} (#{value.class})"
obj.send("#{property}=", value)
else
value = obj.send("#{property}")
if value.nil?
_log.info "#{property} was NOT set due to nil"
else
_log.info "#{property} inheriting value from spec: #{value} (#{value.class})"
end
end
end
end