diff --git a/src/oca/ruby/opennebula/virtual_machine.rb b/src/oca/ruby/opennebula/virtual_machine.rb index 549cacb2a8..4eae4a6dc5 100644 --- a/src/oca/ruby/opennebula/virtual_machine.rb +++ b/src/oca/ruby/opennebula/virtual_machine.rb @@ -702,6 +702,12 @@ module OpenNebula self['DEPLOY_ID'] end + # Returns the deploy_id of the VirtualMachine (numeric value) + def keep_disks? + !self['USER_TEMPLATE/KEEP_DISKS_ON_DONE'].nil? && + self['USER_TEMPLATE/KEEP_DISKS_ON_DONE'].downcase=="yes" + end + # Clones the VM's source Template, replacing the disks with live snapshots # of the current disks. The VM capacity and NICs are also preserved # diff --git a/src/vmm_mad/remotes/vcenter/cancel b/src/vmm_mad/remotes/vcenter/cancel index 283142a555..c7354f251a 100755 --- a/src/vmm_mad/remotes/vcenter/cancel +++ b/src/vmm_mad/remotes/vcenter/cancel @@ -36,10 +36,11 @@ vm_id = ARGV[-2] vm = OpenNebula::VirtualMachine.new_with_id(vm_id, OpenNebula::Client.new) vm.info -lcm_state = vm.lcm_state_str +lcm_state = vm.lcm_state_str +keep_disks = vm.keep_disks? begin - VCenterDriver::VCenterVm.cancel(deploy_id, host, lcm_state) + VCenterDriver::VCenterVm.cancel(deploy_id, host, lcm_state, keep_disks) rescue Exception => e STDERR.puts "Cancel of VM #{deploy_id} on host #{host} failed " + "due to \"#{e.message}\"" diff --git a/src/vmm_mad/remotes/vcenter/shutdown b/src/vmm_mad/remotes/vcenter/shutdown index 83d3cf069f..4f55288948 100755 --- a/src/vmm_mad/remotes/vcenter/shutdown +++ b/src/vmm_mad/remotes/vcenter/shutdown @@ -37,10 +37,11 @@ vm_id = ARGV[-2] vm = OpenNebula::VirtualMachine.new_with_id(vm_id, OpenNebula::Client.new) vm.info -lcm_state = vm.lcm_state_str +lcm_state = vm.lcm_state_str +keep_disks = vm.keep_disks? begin - VCenterDriver::VCenterVm.shutdown(deploy_id, host, lcm_state) + VCenterDriver::VCenterVm.shutdown(deploy_id, host, lcm_state, keep_disks) rescue Exception => e STDERR.puts "Shutdown of VM #{deploy_id} on host #{host} failed " + "due to \"#{e.message}\"" diff --git a/src/vmm_mad/remotes/vcenter/vcenter_driver.rb b/src/vmm_mad/remotes/vcenter/vcenter_driver.rb index 5937244459..b224b7ac4a 100644 --- a/src/vmm_mad/remotes/vcenter/vcenter_driver.rb +++ b/src/vmm_mad/remotes/vcenter/vcenter_driver.rb @@ -774,7 +774,7 @@ class VCenterVm # @param deploy_id vcenter identifier of the VM # @param hostname name of the host (equals the vCenter cluster) ############################################################################ - def self.cancel(deploy_id, hostname, lcm_state) + def self.cancel(deploy_id, hostname, lcm_state, keep_disks) case lcm_state when "SHUTDOWN_POWEROFF", "SHUTDOWN_UNDEPLOY" shutdown(deploy_id, hostname, lcm_state) @@ -789,6 +789,7 @@ class VCenterVm end rescue end + detach_all_disks(vm) if keep_disks vm.Destroy_Task.wait_for_completion end end @@ -857,7 +858,7 @@ class VCenterVm # @param deploy_id vcenter identifier of the VM # @param hostname name of the host (equals the vCenter cluster) ############################################################################ - def self.shutdown(deploy_id, hostname, lcm_state) + def self.shutdown(deploy_id, hostname, lcm_state, keep_disks) hid = VIClient::translate_hostname(hostname) connection = VIClient.new(hid) @@ -870,6 +871,7 @@ class VCenterVm rescue end vm.PowerOffVM_Task.wait_for_completion + detach_all_disks(vm) if keep_disks vm.Destroy_Task.wait_for_completion when "SHUTDOWN_POWEROFF", "SHUTDOWN_UNDEPLOY" begin @@ -1202,6 +1204,13 @@ private !device.class.ancestors.index(RbVmomi::VIM::VirtualEthernetCard).nil? end + ######################################################################## + # Checks if a RbVmomi::VIM::VirtualDevice is a disk + ######################################################################## + def self.is_disk?(device) + !device.class.ancestors.index(RbVmomi::VIM::VirtualDisk).nil? + end + ######################################################################## # Returns the spec to reconfig a VM and add a NIC ######################################################################## @@ -1411,5 +1420,25 @@ private return vm_uuid end + + ############################################################################ + # Detach all disks from a VM + ############################################################################ + def self.detach_all_disks(vm) + disks = vm.config.hardware.device.select { |d| is_disk?(d) } + + return if disks.nil? + + spec = { :deviceChange => [] } + + disks.each{|disk| + spec[:deviceChange] << { + :operation => :remove, + :device => disk + } + } + + vm.ReconfigVM_Task(:spec => spec).wait_for_completion + end end end