From 17e15f64ff9aa15c253bfd595abc4fb41f3ea550 Mon Sep 17 00:00:00 2001 From: "Carlos J. Herrera" Date: Mon, 10 Jan 2022 06:23:49 -0500 Subject: [PATCH] B #5660: Fix issue when import template as copy (#1691) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tino Vázquez (cherry picked from commit d76e0e2b9ce3641aa32c17815aec75e11da7dad7) --- .../ruby/opennebula/virtual_machine_ext.rb | 10 +- .../lib/vcenter_driver/virtual_machine.rb | 86 -------- .../remotes/lib/vcenter_driver/vm_template.rb | 208 ++++++++++++------ 3 files changed, 151 insertions(+), 153 deletions(-) diff --git a/src/oca/ruby/opennebula/virtual_machine_ext.rb b/src/oca/ruby/opennebula/virtual_machine_ext.rb index 83fee33fde..12078b84e2 100644 --- a/src/oca/ruby/opennebula/virtual_machine_ext.rb +++ b/src/oca/ruby/opennebula/virtual_machine_ext.rb @@ -116,11 +116,11 @@ module OpenNebula::VirtualMachineExt vm_id ) - return vm.save_as_linked_clones( - name, - deploy_id, - vi_client - ) + error, vm_template_ref = vm.save_as_linked_clones(name) + + raise error unless error.nil? + + return vm_template_ref end # -------------------------------------------------------------- diff --git a/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb b/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb index 5622b85c1e..8fca76b10f 100644 --- a/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb +++ b/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb @@ -579,8 +579,6 @@ end end end - dc = cluster.datacenter - vcenter_vm_folder = drv_action['USER_TEMPLATE/VCENTER_VM_FOLDER'] if !vcenter_vm_folder.nil? && !vcenter_vm_folder.empty? @@ -1864,90 +1862,6 @@ end end end - def save_as_linked_clones(name, deploy_id, vi_client) - vm = RbVmomi::VIM::VirtualMachine(vi_client.vim, deploy_id) - - disks = vm.config.hardware.device.grep( - RbVmomi::VIM::VirtualMachine - ) - disks.select {|x| x.backing.parent.nil? }.each do |disk| - spec = { - :deviceChange => [ - { - :operation => :remove, - :device => disk - }, - { - :operation => :add, - :fileOperation => :create, - :device => disk.dup.tap do |x| - x.backing = x.backing.dup - x.backing.fileName = - "[#{disk.backing.datastore.name}]" - x.backing.parent = disk.backing - end - } - ] - } - vm.ReconfigVM_Task( - :spec => spec - ).wait_for_completion - end - - relocateSpec = RbVmomi::VIM.VirtualMachineRelocateSpec( - :diskMoveType => :moveChildMostDiskBacking - ) - - spec = RbVmomi::VIM.VirtualMachineCloneSpec( - :location => relocateSpec, - :powerOn => false, - :template => true - ) - - new_template = vm.CloneVM_Task( - :folder => vm.parent, - :name => name, - :spec => spec - ).wait_for_completion - - new_vm_template_ref = new_template._ref - - one_client = OpenNebula::Client.new - importer = VCenterDriver::VmImporter.new( - one_client, - vi_client - ) - - importer.retrieve_resources({}) - importer.get_indexes(new_vm_template_ref) - - importer.process_import( - new_vm_template_ref, - { - new_vm_template_ref.to_s => { - :type => 'default', - :linked_clone => '1', - :copy => '0', - :name => '', - :folder => '' - } - } - ) - - begin - importer.output[:success][0][:id][0] - rescue StandardError => e - message = 'Creating linked clones template' \ - " failed due to \"#{e.message}\".\n" - - if VCenterDriver::CONFIG[:debug_information] - message += " #{e.backtrace}\n" - end - - raise message - end - end - # Returns an array of actions to be included in :deviceChange def calculate_add_nic_spec(nic, unumber = nil) mac = nic['MAC'] diff --git a/src/vmm_mad/remotes/lib/vcenter_driver/vm_template.rb b/src/vmm_mad/remotes/lib/vcenter_driver/vm_template.rb index 7950c2ad7a..c48047ce8a 100644 --- a/src/vmm_mad/remotes/lib/vcenter_driver/vm_template.rb +++ b/src/vmm_mad/remotes/lib/vcenter_driver/vm_template.rb @@ -96,6 +96,90 @@ module VCenterDriver @vi_client.vim.serviceContent.about.instanceUuid rescue nil end + def save_as_linked_clones(name) + error = nil + + disks = @item.config.hardware.device.grep( + RbVmomi::VIM::VirtualMachine + ) + disks.select {|x| x.backing.parent.nil? }.each do |disk| + spec = { + :deviceChange => [ + { + :operation => :remove, + :device => disk + }, + { + :operation => :add, + :fileOperation => :create, + :device => disk.dup.tap do |x| + x.backing = x.backing.dup + x.backing.fileName = + "[#{disk.backing.datastore.name}]" + x.backing.parent = disk.backing + end + } + ] + } + @item.ReconfigVM_Task( + :spec => spec + ).wait_for_completion + end + + relocateSpec = RbVmomi::VIM.VirtualMachineRelocateSpec( + :diskMoveType => :moveChildMostDiskBacking + ) + + spec = RbVmomi::VIM.VirtualMachineCloneSpec( + :location => relocateSpec, + :powerOn => false, + :template => true + ) + + new_template = @item.CloneVM_Task( + :folder => @item.parent, + :name => name, + :spec => spec + ).wait_for_completion + + new_vm_template_ref = new_template._ref + + one_client = OpenNebula::Client.new + importer = VCenterDriver::VmImporter.new( + one_client, + @vi_client + ) + + importer.retrieve_resources({}) + importer.get_indexes(new_vm_template_ref) + + importer.process_import( + new_vm_template_ref, + { + new_vm_template_ref.to_s => { + :type => 'default', + :linked_clone => '1', + :copy => '0', + :name => '', + :folder => '' + } + } + ) + + begin + importer.output[:success][0][:id][0] + rescue StandardError => e + error = 'Creating linked clone VM Template' \ + " failed due to \"#{e.message}\".\n" + + if VCenterDriver::CONFIG[:debug_information] + error += " #{e.backtrace}\n" + end + end + + [error, new_vm_template_ref] + end + def create_template_copy(template_name) error = nil template_ref = nil @@ -1835,10 +1919,8 @@ module VCenterDriver # the template if something go wrong if copy error, template_copy_ref = - selected[:template] - .create_template_copy( - opts[:name] - ) + selected[:template].save_as_linked_clones(opts[:name]) + unless template_copy_ref raise 'There is a problem creating ' \ "your copy: #{error}" @@ -1893,68 +1975,70 @@ module VCenterDriver working_template[:one] << "VCENTER_TEMPLATE_NAME=\"#{selected[:name]}\"\n" - create(working_template[:one]) do |one_object, id| - res[:id] << id + unless copy + create(working_template[:one]) do |one_object, id| + res[:id] << id - type = { :object => 'template', :id => id } - error, template_disks, allocated_images = - template - .import_vcenter_disks( - vc_uuid, - dpool, - ipool, - type + type = { :object => 'template', :id => id } + error, template_disks, allocated_images = + template + .import_vcenter_disks( + vc_uuid, + dpool, + ipool, + type + ) + + if allocated_images + # rollback stack + allocated_images.reverse.each do |i| + @rollback.unshift(Raction.new(i, :delete)) + end + end + raise error unless error.empty? + + working_template[:one] << template_disks + + if template_copy_ref + template_moref = template_copy_ref + else + template_moref = selected[:vcenter_ref] + end + + opts_nics = { + :vi_client => @vi_client, + :vc_uuid => vc_uuid, + :npool => npool, + :hpool => hpool, + :vcenter => vcenter, + :template_moref => template_moref, + :vm_object => nil + } + + error, template_nics, _ar_ids, allocated_nets = + template + .import_vcenter_nics( + opts_nics, + id, + dc + ) + + if allocated_nets + # rollback stack + allocated_nets.reverse.each do |n| + @rollback.unshift(Raction.new(n, :delete)) + end + end + raise error unless error.empty? + + working_template[:one] << template_nics + working_template[:one] << rp_opts( + opts[:type], + opts[:resourcepool] ) - if allocated_images - # rollback stack - allocated_images.reverse.each do |i| - @rollback.unshift(Raction.new(i, :delete)) - end + one_object.update(working_template[:one]) end - raise error unless error.empty? - - working_template[:one] << template_disks - - if template_copy_ref - template_moref = template_copy_ref - else - template_moref = selected[:vcenter_ref] - end - - opts_nics = { - :vi_client => @vi_client, - :vc_uuid => vc_uuid, - :npool => npool, - :hpool => hpool, - :vcenter => vcenter, - :template_moref => template_moref, - :vm_object => nil - } - - error, template_nics, _ar_ids, allocated_nets = - template - .import_vcenter_nics( - opts_nics, - id, - dc - ) - - if allocated_nets - # rollback stack - allocated_nets.reverse.each do |n| - @rollback.unshift(Raction.new(n, :delete)) - end - end - raise error unless error.empty? - - working_template[:one] << template_nics - working_template[:one] << rp_opts( - opts[:type], - opts[:resourcepool] - ) - - one_object.update(working_template[:one]) end res