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

feature #2911: Add correct actions for vCenter, solve many bugs

This commit is contained in:
Tino Vazquez 2014-09-24 17:16:38 +02:00
parent e832d7fd7a
commit b6560a5ed6
13 changed files with 196 additions and 103 deletions

View File

@ -224,7 +224,11 @@ module OpenNebula
def deploy(host_id, enforce=false, ds_id=-1)
enforce ||= false
ds_id ||= -1
return call(VM_METHODS[:deploy], @pe_id, host_id.to_i, enforce, ds_id.to_i)
return call(VM_METHODS[:deploy],
@pe_id,
host_id.to_i,
enforce,
ds_id.to_i)
end
# Shutdowns an already deployed VM
@ -587,6 +591,11 @@ module OpenNebula
self['GID'].to_i
end
# Returns the deploy_id of the VirtualMachine (numeric value)
def deploy_id
self['DEPLOY_ID']
end
private
def action(name)
return Error.new('ID not defined') if !@pe_id

View File

@ -25,6 +25,6 @@ fi
LOCAL_ACTIONS="deploy,shutdown,reboot,cancel,save,restore,migrate,poll,pre"
LOCAL_ACTIONS="${LOCAL_ACTIONS},post,clean"
LOCAL_ACTIONS="${LOCAL_ACTIONS},snapshotcreate,snapshotrevert,snapshotdelete"
LOCAL_ACTIONS="${LOCAL_ACTIONS},attach_nic,detach_nic"
LOCAL_ACTIONS="${LOCAL_ACTIONS},attach_nic,detach_nic,reset"
exec $MAD_LOCATION/one_vmm_exec -l $LOCAL_ACTIONS $*

View File

@ -31,11 +31,17 @@ require 'vcenter_driver'
deploy_id = ARGV[0]
host = ARGV[1]
vm_id = ARGV[-2]
vm = OpenNebula::VirtualMachine.new_with_id(vm_id, OpenNebula::Client.new)
vm.info
lcm_state = vm.lcm_state_str
begin
puts VCenterDriver::VCenterVm.cancel(deploy_id, host)
exit 0
puts VCenterDriver::VCenterVm.cancel(deploy_id, host, lcm_state)
rescue Exception => e
STDERR.puts "Cancel of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -28,16 +28,26 @@ $: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
require 'opennebula'
dfile = ARGV[0]
host = ARGV[1]
id = ARGV[2]
vm_id = ARGV[2]
vm = OpenNebula::VirtualMachine.new_with_id(vm_id, OpenNebula::Client.new)
vm.info
lcm_state = vm.lcm_state_str
deploy_id = vm.deploy_id
begin
puts VCenterDriver::VCenterVm.deploy File.read(dfile)
exit 0
puts VCenterDriver::VCenterVm.deploy(File.read(dfile),
lcm_state,
deploy_id,
host)
rescue Exception => e
STDERR.puts "Deploy of VM #{id} on host #{host} with #{dfile} failed " +
STDERR.puts "Deploy of VM #{vm_id} on host #{host} with #{dfile} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -33,9 +33,9 @@ deploy_id = ARGV[0]
host = ARGV[1]
begin
puts VCenterDriver::VCenterVm.reboot(deploy_id, host)
exit 0
VCenterDriver::VCenterVm.reboot(deploy_id, host)
rescue Exception => e
STDERR.puts "Guest reboot of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -27,15 +27,15 @@ end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vmware_driver'
require 'vcenter_driver'
deploy_id = ARGV[0]
host = ARGV[1]
begin
puts VCenterDriver::VCenterVm.reset(deploy_id, host)
exit 0
VCenterDriver::VCenterVm.reset(deploy_id, host)
rescue Exception => e
STDERR.puts "Reset of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -33,9 +33,9 @@ host = ARGV[-1]
deploy_id = ARGV[2]
begin
puts VCenterDriver::VCenterVm.resume(deploy_id, host)
exit 0
VCenterDriver::VCenterVm.resume(deploy_id, host)
rescue Exception => e
STDERR.puts "Restore of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -34,11 +34,11 @@ snapshot_name = ARGV[1]
host = ARGV[3]
begin
puts VCenterDriver::VCenterVm.revert_snapshot(deploy_id,
host,
snapshot_name)
exit 0
VCenterDriver::VCenterVm.revert_snapshot(deploy_id,
host,
snapshot_name)
rescue Exception => e
STDERR.puts "Snapshot of VM #{deploy_id} on host #{host} could not be " +
"reverted due to \"#{e.message}\""
exit -1
end

View File

@ -28,15 +28,22 @@ $: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
require 'opennebula'
deploy_id = ARGV[0]
file = ARGV[1]
host = ARGV[2]
vm_id = ARGV[-2]
vm = OpenNebula::VirtualMachine.new_with_id(vm_id, OpenNebula::Client.new)
vm.info
lcm_state = vm.lcm_state_str
begin
puts VCenterDriver::VCenterVm.save(deploy_id, host)
exit 0
puts VCenterDriver::VCenterVm.save(deploy_id, host, lcm_state)
rescue Exception => e
STDERR.puts "Save of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -28,10 +28,21 @@ $: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
require 'opennebula'
deploy_id = ARGV[0]
host = ARGV[1]
vm_id = ARGV[-2]
vmware_drv = VMwareDriver.new(host)
vm = OpenNebula::VirtualMachine.new_with_id(vm_id, OpenNebula::Client.new)
vm.info
vmware_drv.shutdown(deploy_id)
lcm_state = vm.lcm_state_str
begin
VCenterDriver::VCenterVm.shutdown(deploy_id, host, lcm_state)
rescue Exception => e
STDERR.puts "Shutdown of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -34,11 +34,11 @@ snapshot_name = ARGV[1]
host = ARGV[3]
begin
puts VCenterDriver::VCenterVm.create_snapshot(deploy_id,
VCenterDriver::VCenterVm.create_snapshot(deploy_id,
host,
snapshot_name)
exit 0
rescue Exception => e
STDERR.puts "Snapshot of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -34,11 +34,11 @@ snapshot_name = ARGV[1]
host = ARGV[3]
begin
puts VCenterDriver::VCenterVm.delete_snapshot(deploy_id,
host,
snapshot_name)
exit 0
VCenterDriver::VCenterVm.delete_snapshot(deploy_id,
host,
snapshot_name)
rescue Exception => e
STDERR.puts "Snapshot of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -419,63 +419,16 @@ class VCenterVm
# Deploys a VM
# @xml_text XML repsentation of the VM
############################################################################
def self.deploy(xml_text)
xml = REXML::Document.new xml_text
pcs = xml.root.get_elements("//USER_TEMPLATE/PUBLIC_CLOUD")
raise "Cannot find VCenter element in VM template." if pcs.nil?
template = pcs.find { |t|
type = t.elements["TYPE"]
!type.nil? && type.text.downcase == "vcenter"
}
raise "Cannot find VCenter element in VM template." if template.nil?
uuid = template.elements["VM_TEMPLATE"]
raise "Cannot find VM_TEMPLATE in VCenter element." if uuid.nil?
uuid = uuid.text
vmid = xml.root.elements["/VM/ID"].text
hid = xml.root.elements["//HISTORY_RECORDS/HISTORY/HID"]
raise "Cannot find host id in deployment file history." if hid.nil?
connection = VIClient.new(hid)
vc_template = connection.find_vm_template(uuid)
relocate_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(
:diskMoveType => :moveChildMostDiskBacking,
:pool => connection.resource_pool)
clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(
:location => relocate_spec,
:powerOn => true,
:template => false)
rc = vc_template.CloneVM_Task(
:folder => vc_template.parent,
:name => "one-#{vmid}",
:spec => clone_spec).wait_for_completion
vm_uuid = rc.config.uuid
vnc_port = xml.root.elements["/VM/TEMPLATE/GRAPHICS/PORT"]
if vnc_port
spec = RbVmomi::VIM.VirtualMachineConfigSpec(:extraConfig =>
[{:key=>"remotedisplay.vnc.enabled", :value=>"TRUE"},
{:key=>"remotedisplay.vnc.port", :value=>vnc_port.text}])
rc.ReconfigVM_Task(:spec => spec).wait_for_completion
def self.deploy(xml_text, lcm_state, deploy_id, hostname)
if lcm_state == "BOOT"
return clone_vm(xml_text)
else
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
vm.PowerOnVM_Task.wait_for_completion
return vm.config.uuid
end
return vm_uuid
end
############################################################################
@ -483,14 +436,21 @@ 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)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
def self.cancel(deploy_id, hostname, lcm_state)
case lcm_state
when "SHUTDOWN_POWEROFF", "SHUTDOWN_UNDEPLOY"
shutdown(deploy_id, hostname, lcm_state)
when "CANCEL"
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
vm = connection.find_vm_template(deploy_id)
vm.PowerOffVM_Task.wait_for_completion
vm.Destroy_Task.wait_for_completion
begin
vm.PowerOffVM_Task.wait_for_completion
rescue
end
vm.Destroy_Task.wait_for_completion
end
end
############################################################################
@ -498,13 +458,17 @@ class VCenterVm
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
############################################################################
def self.save(deploy_id, hostname)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
def self.save(deploy_id, hostname, lcm_state)
case lcm_state
when "SAVE_MIGRATE"
raise "Migration between vCenters cluster not supported"
when "SAVE_SUSPEND", "SAVE_STOP"
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
vm = connection.find_vm_template(deploy_id)
vm.SuspendVM_Task.wait_for_completion
vm.SuspendVM_Task.wait_for_completion
end
end
############################################################################
@ -515,7 +479,6 @@ class VCenterVm
def self.resume(deploy_id, hostname)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
vm.PowerOnVM_Task.wait_for_completion
@ -554,14 +517,27 @@ 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)
def self.shutdown(deploy_id, hostname, lcm_state)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
vm.ShutdownGuest.wait_for_completion
vm.UnregisterVM.wait_for_completion
case lcm_state
when "SHUTDOWN"
begin
vm.ShutdownGuest.wait_for_completion
rescue
end
vm.PowerOffVM_Task.wait_for_completion
vm.Destroy_Task.wait_for_completion
when "SHUTDOWN_POWEROFF", "SHUTDOWN_UNDEPLOY"
begin
vm.ShutdownGuest.wait_for_completion
rescue
end
vm.PowerOffVM_Task.wait_for_completion
end
end
############################################################################
@ -696,7 +672,11 @@ class VCenterVm
" TYPE =\"vcenter\",\n"\
" VM_TEMPLATE =\"#{@vm.config.uuid}\"\n"\
"]\n"\
"SCHED_REQUIREMENTS=\"NAME=\\\"#{@vm.runtime.host.parent.name}\\\"\"\n"
"GRAPHICS = [\n"\
" TYPE =\"vnc\",\n"\
" LISTEN =\"0.0.0.0\"\n"\
"]\n"\
"SCHED_REQUIREMENTS=\"NAME=\\\"#{@vm.runtime.host.parent.name}\\\"\"\n"
end
private
@ -714,5 +694,75 @@ private
'd'
end
end
########################################################################
# Clone a vCenter VM Template and leaves it powered on
########################################################################
def self.clone_vm(xml_text)
xml = REXML::Document.new xml_text
pcs = xml.root.get_elements("//USER_TEMPLATE/PUBLIC_CLOUD")
raise "Cannot find VCenter element in VM template." if pcs.nil?
template = pcs.find { |t|
type = t.elements["TYPE"]
!type.nil? && type.text.downcase == "vcenter"
}
raise "Cannot find VCenter element in VM template." if template.nil?
uuid = template.elements["VM_TEMPLATE"]
raise "Cannot find VM_TEMPLATE in VCenter element." if uuid.nil?
uuid = uuid.text
vmid = xml.root.elements["/VM/ID"].text
hid = xml.root.elements["//HISTORY_RECORDS/HISTORY/HID"]
raise "Cannot find host id in deployment file history." if hid.nil?
connection = VIClient.new(hid)
vc_template = connection.find_vm_template(uuid)
relocate_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(
:diskMoveType => :moveChildMostDiskBacking,
:pool => connection.resource_pool)
clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(
:location => relocate_spec,
:powerOn => true,
:template => false)
rc = vc_template.CloneVM_Task(
:folder => vc_template.parent,
:name => "one-#{vmid}",
:spec => clone_spec).wait_for_completion
vm_uuid = rc.config.uuid
vnc_port = xml.root.elements["/VM/TEMPLATE/GRAPHICS/PORT"]
vnc_listen = xml.root.elements["/VM/TEMPLATE/GRAPHICS/LISTEN"]
if !vnc_listen
vnc_listen = "0.0.0.0"
else
vnc_listen = vnc_listen.text
end
if vnc_port
spec = RbVmomi::VIM.VirtualMachineConfigSpec(:extraConfig =>
[{:key=>"remotedisplay.vnc.enabled", :value=>"TRUE"},
{:key=>"remotedisplay.vnc.port", :value=>vnc_port.text},
{:key=>"remotedisplay.vnc.ip", :value=>vnc_listen}])
rc.ReconfigVM_Task(:spec => spec).wait_for_completion
end
return vm_uuid
end
end
end