1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-21 14:50:08 +03:00

F #2944: get_key method, attach_disk writes on vCenter metadata

F #2944: deploy writes metadata about managed disks

F #2944: Some fixes, detach disk delete proper metadata

F #2944: Some changes, query disk now gets managed keys
This commit is contained in:
sergio semedi 2019-02-14 16:56:20 +01:00
parent b100436f1d
commit e778335bf6
4 changed files with 104 additions and 39 deletions

View File

@ -93,9 +93,9 @@ begin
else
@error_message = "Error unregistering vm #{vmid} (#{vm_ref})."
vm.poweroff_hard if vm.is_powered_on?
vm.remove_all_snapshots if vm.has_snapshots?
if vm.instantiated_as_persistent?
vm.remove_all_snapshots if vm.has_snapshots?
vm.convert_to_template
else
vm.destroy

View File

@ -267,7 +267,13 @@ class VirtualMachine < VCenterDriver::Template
config = {}
if action == :delete
config[:key] = "opennebula.disk.#{@id}"
if managed?
key = "opennebula.mdisk.#{@id}"
else
key = "opennebula.disk.#{@id}"
end
config[:key] = key
config[:value] = ""
elsif action == :resize
if new_size
@ -544,13 +550,14 @@ class VirtualMachine < VCenterDriver::Template
@vi_client.vim.serviceContent.about.instanceUuid
end
def get_unmanaged_keys
def get_disk_keys
unmanaged_keys = {}
@item.config.extraConfig.each do |val|
if val[:key].include?("opennebula.disk")
unmanaged_keys[val[:key]] = val[:value]
end
u = val[:key].include?("opennebula.disk")
m = val[:key].include?("opennebula.mdisk")
unmanaged_keys[val[:key]] = val[:value] if u || m
end
return unmanaged_keys
end
@ -988,13 +995,25 @@ class VirtualMachine < VCenterDriver::Template
#
# @return [vCenter_disk] the proper disk
def query_disk(one_disk, keys, vc_disks)
index = one_disk['DISK_ID']
cloned = one_disk["CLONE"].nil? || one_disk["CLONE"] == "YES"
index = one_disk['DISK_ID']
cloned = one_disk["CLONE"].nil? || one_disk["CLONE"] == "YES"
unmanaged = "opennebula.disk.#{index}"
managed = "opennebula.mdisk.#{index}"
if keys["opennebula.disk.#{index}"]
key = keys["opennebula.disk.#{index}"].to_i
if keys[managed]
key = keys[managed].to_i
elsif keys[unmanaged]
key = keys[unmanaged].to_i
end
if key
query = vc_disks.select {|dev| key == dev[:key]}
else
error = 'disk metadata is corrupted and you have snapshots'
if has_snapshots?
raise error
end
path = !cloned ? one_disk['SOURCE'] : disk_real_path(one_disk, index)
query = vc_disks.select {|dev| path == dev[:path_wo_ds]}
end
@ -1062,7 +1081,7 @@ class VirtualMachine < VCenterDriver::Template
def info_disks
@disks = {}
keys = get_unmanaged_keys
keys = get_disk_keys
vc_disks = get_vcenter_disks
one_disks = get_one_disks
@ -1135,7 +1154,7 @@ class VirtualMachine < VCenterDriver::Template
raise "disk #{index} not found" unless one_disk
keys = opts[:keys].nil? ? get_unmanaged_keys : opts[:keys]
keys = opts[:keys].nil? ? get_disk_keys : opts[:keys]
vc_disks = opts[:disks].nil? ? get_vcenter_disks : opts[:disks]
vc_disk = query_disk(one_disk, keys, vc_disks)
@ -1418,7 +1437,6 @@ class VirtualMachine < VCenterDriver::Template
boot_opts = set_boot_order(deploy[:boot])
end
# changes from sync_disks
device_change += disks[:deviceChange] if disks[:deviceChange]
extraconfig += disks[:extraConfig] if disks[:extraConfig]
@ -1749,10 +1767,12 @@ class VirtualMachine < VCenterDriver::Template
# try to get specs for new attached disks
# using disk_each method with :no_exists? condition
def attach_disks_specs()
attach_disk_array = []
attach_spod_array = []
attach_disk_array = []
extraconfig = []
attach_spod_array = []
attach_spod_disk_info = {}
pos = {:ide => 0, :scsi => 0}
disks_each(:no_exists?) do |disk|
k = disk.one_item['TYPE'] == 'CDROM' ? :ide : :scsi
@ -1763,14 +1783,23 @@ class VirtualMachine < VCenterDriver::Template
unit_ctrl = "#{spec[:device].controllerKey}-#{spec[:device].unitNumber}"
attach_spod_disk_info[unit_ctrl] = disk.id
else
attach_disk_array << calculate_add_disk_spec(disk.one_item, pos[k])
aspec = calculate_add_disk_spec(disk.one_item, pos[k])
extra_key = "opennebula.mdisk.#{disk.one_item["DISK_ID"]}"
extra_value = "#{aspec[:device].key}"
attach_disk_array << aspec
extraconfig << {key: extra_key, value: extra_value }
end
pos[k]+=1
end
return attach_disk_array, attach_spod_array, attach_spod_disk_info
{ disks: attach_disk_array,
spods: attach_spod_array,
spod_info: attach_spod_disk_info,
extraconfig: extraconfig
}
end
# try to get specs for detached disks
@ -1778,10 +1807,10 @@ class VirtualMachine < VCenterDriver::Template
def detach_disks_specs()
detach_disk_array = []
extra_config = []
keys = get_unmanaged_keys.invert
keys = get_disk_keys.invert
ipool = VCenterDriver::VIHelper.one_pool(OpenNebula::ImagePool)
disks_each(:detached?) do |d|
key = d.key
key = d.key.to_s
source = VCenterDriver::FileHelper.escape_path(d.path)
persistent = VCenterDriver::VIHelper.find_persistent_image_by_source(source, ipool)
@ -1811,7 +1840,6 @@ class VirtualMachine < VCenterDriver::Template
spec_hash = {}
device_change = []
extra_config = []
if option == :all
detach_op = {}
@ -1820,13 +1848,16 @@ class VirtualMachine < VCenterDriver::Template
@item.ReconfigVM_Task(:spec => detach_op).wait_for_completion if perform
end
device_change, device_change_spod, device_change_spod_ids = attach_disks_specs
a_specs = attach_disks_specs
if !device_change_spod.empty?
spec_hash[:extraConfig] = create_storagedrs_disks(device_change_spod, device_change_spod_ids)
if !a_specs[:spods].empty?
spec_hash[:extraConfig] = create_storagedrs_disks(a_specs[:spods], a_specs[:spod_info])
end
spec_hash[:deviceChange] = device_change unless device_change.empty?
if !a_specs[:disks].empty?
spec_hash[:deviceChange] = a_specs[:disks]
spec_hash[:extraConfig] = a_specs[:extraconfig]
end
return spec_hash unless execute
@ -1837,18 +1868,14 @@ class VirtualMachine < VCenterDriver::Template
end
# Attach DISK to VM (hotplug)
def attach_disk
spec_hash = {}
disk = nil
def attach_disk(disk)
spec_hash = {}
device_change = []
# Extract unmanaged_keys
unmanaged_keys = get_unmanaged_keys
unmanaged_keys = get_disk_keys
vc_disks = get_vcenter_disks
# Extract disk from driver action
disk = one_item.retrieve_xmlelements("TEMPLATE/DISK[ATTACH='YES']").first
# Check if we're dealing with a StoragePod SYSTEM ds
storpod = disk["VCENTER_DS_REF"].start_with?('group-')
@ -1856,10 +1883,15 @@ class VirtualMachine < VCenterDriver::Template
raise "DISK is already connected to VM" if disk_attached_to_vm(disk, unmanaged_keys, vc_disks)
# Generate vCenter spec and reconfigure VM
device_change << calculate_add_disk_spec(disk)
add_spec = calculate_add_disk_spec(disk)
device_change << add_spec
raise "Could not generate DISK spec" if device_change.empty?
extra_key = "opennebula.mdisk.#{disk["DISK_ID"]}"
extra_value = "#{add_spec[:device].key}"
spec_hash[:deviceChange] = device_change
spec_hash[:extraConfig] = [{key: extra_key, value: extra_value }]
spec = RbVmomi::VIM.VirtualMachineConfigSpec(spec_hash)
begin
@ -1961,7 +1993,7 @@ class VirtualMachine < VCenterDriver::Template
return unless disk.exists?
spec_hash = {}
spec_hash[:extraConfig] = [disk.config(:delete)] unless disk.managed?
spec_hash[:extraConfig] = [disk.config(:delete)]
spec_hash[:deviceChange] = [{
:operation => :remove,
:device => disk.device
@ -2016,6 +2048,34 @@ class VirtualMachine < VCenterDriver::Template
return device_found
end
def get_key(type)
@used_keys = [] unless @used_keys
if type == "CDROM"
bound = "is_cdrom?"
key = 3000
else
bound = "is_disk?"
key = 2000
end
used = @used_keys
@item.config.hardware.device.each do |dev|
used << dev.key
next unless send(bound, dev)
key = dev.key
end
loop do
break if !used.include?(key)
key+=1
end
@used_keys << key
key
end
def calculate_add_disk_spec(disk, position=0)
img_name_escaped = VCenterDriver::FileHelper.get_img_name(
disk,
@ -2049,7 +2109,7 @@ class VirtualMachine < VCenterDriver::Template
device = RbVmomi::VIM::VirtualCdrom(
:backing => vmdk_backing,
:key => -1,
:key => get_key(type),
:controllerKey => controller.key,
:unitNumber => unit_number,
@ -2067,7 +2127,6 @@ class VirtualMachine < VCenterDriver::Template
else
# TYPE is regular disk (not CDROM)
controller, unit_number = find_free_controller(position)
storpod = disk["VCENTER_DS_REF"].start_with?('group-')
@ -2090,7 +2149,7 @@ class VirtualMachine < VCenterDriver::Template
:backing => vmdk_backing,
:capacityInKB => size_kb,
:controllerKey => controller.key,
:key => (-1 - position),
:key => get_key(type),
:unitNumber => unit_number
)
@ -2512,8 +2571,9 @@ class VirtualMachine < VCenterDriver::Template
@item.PowerOffVM_Task.wait_for_completion
end
def remove_all_snapshots
@item.RemoveAllSnapshots_Task.wait_for_completion
def remove_all_snapshots(consolidate = true)
@item.RemoveAllSnapshots_Task({consolidate: consolidate}).wait_for_completion
info_disks
end
def vm_tools?

View File

@ -790,6 +790,10 @@ class Template
!(device.class.ancestors.index(RbVmomi::VIM::VirtualDisk)).nil?
end
def is_cdrom?(device)
device.backing.is_a? RbVmomi::VIM::VirtualCdromIsoBackingInfo
end
# Checks if a RbVmomi::VIM::VirtualDevice is a network interface
def is_nic?(device)
!device.class.ancestors.index(RbVmomi::VIM::VirtualEthernetCard).nil?

View File

@ -46,9 +46,10 @@ begin
# Setting one_item with info with the vm_xml including DISK to be added
one_item = drv_action.retrieve_xmlelements('VM').first
disk = one_item.retrieve_xmlelements("TEMPLATE/DISK[ATTACH='YES']").first
vm = VCenterDriver::VirtualMachine.new_one(vi_client, vm_ref, one_item)
vm.attach_disk
vm.attach_disk(disk)
rescue StandardError => e
message = "Attach image for VM #{vm_ref} on vCenter cluster" \
"#{vc_cluster_name} failed due to \"#{e.message}\"\n"