mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-12 08:58:17 +03:00
feature #1977: Refactor VIDriver class. Move datavmx to an element in metadata.
This commit is contained in:
parent
055869a5dc
commit
0e6f372732
@ -34,9 +34,9 @@ if !host
|
||||
exit -1
|
||||
end
|
||||
|
||||
vi_drv = VIDriver.new(host)
|
||||
VIDriver::initialize(host)
|
||||
|
||||
results = vi_drv.poll_host_and_vms
|
||||
results = VIDriver::poll_host_and_vms
|
||||
|
||||
if results != -1
|
||||
puts results
|
||||
|
@ -45,7 +45,7 @@ int LibVirtDriver::deployment_description_vmware(
|
||||
|
||||
string arch = "";
|
||||
string guestOS = "";
|
||||
string pciBridge = "";
|
||||
string pciBridge = "";
|
||||
|
||||
const VectorAttribute * disk;
|
||||
const VectorAttribute * context;
|
||||
@ -473,7 +473,7 @@ int LibVirtDriver::deployment_description_vmware(
|
||||
data_vmx = raw->vector_value("DATA_VMX");
|
||||
if ( !data_vmx.empty() )
|
||||
{
|
||||
metadata << data_vmx;
|
||||
metadata << "<datavmx>" << data_vmx << "</datavmx>";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -484,7 +484,7 @@ int LibVirtDriver::deployment_description_vmware(
|
||||
{
|
||||
file << "\t" << default_raw << endl;
|
||||
}
|
||||
|
||||
|
||||
if ( !metadata.str().empty() )
|
||||
{
|
||||
file << "\t<metadata>" << metadata.str() << "</metadata>" << endl;
|
||||
|
@ -35,6 +35,8 @@ bridge = ARGV[2]
|
||||
model = ARGV[3]
|
||||
host = ARGV[5]
|
||||
|
||||
vi_drv = VIDriver.new(host)
|
||||
VIDriver::initialize(host, false)
|
||||
|
||||
puts vi_drv.attach_nic(deploy_id, bridge, model, mac)
|
||||
vivm = VIDriver::VIVm.new(deploy_id, nil)
|
||||
|
||||
puts vivm.attach_nic(bridge, model, mac)
|
||||
|
@ -33,6 +33,9 @@ deploy_id = ARGV[0]
|
||||
mac = ARGV[1]
|
||||
host = ARGV[3]
|
||||
|
||||
vi_drv = VIDriver.new(host)
|
||||
|
||||
puts vi_drv.detach_nic(deploy_id, mac)
|
||||
VIDriver::initialize(host, false)
|
||||
|
||||
vivm = VIDriver::VIVm.new(deploy_id, nil)
|
||||
|
||||
puts vivm.detach_nic(mac)
|
||||
|
@ -31,8 +31,7 @@ else
|
||||
VAR_LOCATION = ONE_LOCATION + "/var/" if !defined?(VAR_LOCATION)
|
||||
end
|
||||
|
||||
CONF_FILE = ETC_LOCATION + "/vmwarerc"
|
||||
CHECKPOINT = VAR_LOCATION + "/remotes/vmm/vmware/checkpoint"
|
||||
|
||||
|
||||
ENV['LANG'] = 'C'
|
||||
|
||||
@ -41,348 +40,418 @@ $: << LIB_LOCATION+'/ruby/vendors/rbvmomi/lib'
|
||||
require 'rbvmomi'
|
||||
require 'yaml'
|
||||
|
||||
class VIDriver
|
||||
############################################################################
|
||||
# Public Methods - Class Interface #
|
||||
############################################################################
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Initialize the client for hypervisor connection #
|
||||
# -------------------------------------------------------------------------#
|
||||
def initialize(hostname)
|
||||
conf = YAML::load(File.read(CONF_FILE))
|
||||
module VIDriver
|
||||
|
||||
if conf[:password] and !conf[:password].empty?
|
||||
CONF_FILE = ETC_LOCATION + "/vmwarerc"
|
||||
CHECKPOINT = VAR_LOCATION + "/remotes/vmm/vmware/checkpoint"
|
||||
|
||||
############################################################################
|
||||
# Initialize the module by creating a VI connection and setting up
|
||||
# configuration attributes
|
||||
# @param hostname [String] to access the VI API and interact to
|
||||
# @param monitor [false, true] monitor the host on creation. Defaults true
|
||||
############################################################################
|
||||
def self.initialize(hostname, monitor = true )
|
||||
conf = YAML::load(File.read(CONF_FILE))
|
||||
|
||||
if conf[:password] and !conf[:password].empty?
|
||||
pass=conf[:password]
|
||||
else
|
||||
else
|
||||
pass="\"\""
|
||||
end
|
||||
end
|
||||
|
||||
@datacenter = conf[:datacenter]
|
||||
@vcenter = conf[:vcenter]
|
||||
begin
|
||||
@@client = RbVmomi::VIM.connect(:host => hostname,
|
||||
:user => conf[:username],
|
||||
:password => pass,
|
||||
:insecure => true)
|
||||
@@root = @@client.root
|
||||
@@host = VIHost.new(hostname)
|
||||
|
||||
begin
|
||||
@client = RbVmomi::VIM.connect(:host => hostname,
|
||||
:user => conf[:username],
|
||||
:password => pass,
|
||||
:insecure => true)
|
||||
@rootFolder = @client.serviceInstance.content.rootFolder
|
||||
@host = get_host(hostname)
|
||||
# Get values to be used in all of this class instantiations
|
||||
@cpuMhz = @host.summary.hardware.cpuMhz.to_f
|
||||
@numCpuCores = @host.summary.hardware.numCpuCores.to_f
|
||||
rescue Exception => e
|
||||
@@host.monitor if monitor
|
||||
|
||||
rescue Exception => e
|
||||
raise "Connection error to #{hostname}: " + e.message
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
############################################################################
|
||||
# Return the OpenNebula monitoring string for the given VM
|
||||
# @param deploy_id [String] OpenNebula VM ID, e.g. "one-237"
|
||||
############################################################################
|
||||
def self.poll_vm(deploy_id)
|
||||
begin
|
||||
vm = VIVm.new(deploy_id, nil)
|
||||
|
||||
vm.monitor
|
||||
str_info = vm.info
|
||||
|
||||
rescue Exception => e
|
||||
str_info = "STATE=d"
|
||||
STDERR.puts e.message
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Poll the monitoring information for a VM #
|
||||
# -------------------------------------------------------------------------#
|
||||
def poll_vm(deploy_id)
|
||||
begin
|
||||
vm = get_vm(deploy_id)[:vm]
|
||||
str_info = get_vm_info(vm)
|
||||
rescue Exception => e
|
||||
str_info = "STATE=d"
|
||||
STDERR.puts e.message
|
||||
end
|
||||
return str_info
|
||||
return str_info
|
||||
end
|
||||
|
||||
############################################################################
|
||||
# Return the OpenNebula monitoring string for the given host and the running
|
||||
# VMs in that host
|
||||
############################################################################
|
||||
def self.poll_host_and_vms
|
||||
begin
|
||||
str_info = @@host.info
|
||||
vms_info = @@host.all_vms_info
|
||||
|
||||
str_info << "\nVM_POLL=YES\n#{vms_info}" if !vms_info.empty?
|
||||
|
||||
rescue Exception => e
|
||||
STDERR.puts e.message
|
||||
str_info = ""
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Poll the monitoring information for a VM #
|
||||
# -------------------------------------------------------------------------#
|
||||
def poll_host_and_vms
|
||||
begin
|
||||
str_info = get_host_info
|
||||
vms_info = get_all_vms_info
|
||||
str_info += " " + vms_info if vms_info
|
||||
rescue Exception => e
|
||||
STDERR.puts e.message
|
||||
return -1
|
||||
end
|
||||
return str_info
|
||||
end
|
||||
return str_info
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Attach a NIC to deploy_id, linked to bridge, with mac and of type = model#
|
||||
# -------------------------------------------------------------------------#
|
||||
def attach_nic(deploy_id, bridge, model, mac)
|
||||
vm = get_vm(deploy_id)[:vm]
|
||||
card_num = 1 # start in one, we want the next avaiable id
|
||||
vm.config.hardware.device.each{ |dv|
|
||||
if dv.class.ancestors[1] == RbVmomi::VIM::VirtualEthernetCard
|
||||
card_num = card_num + 1
|
||||
############################################################################
|
||||
# The VIVm is a high level abstraction of a VI VirtualMachine class for
|
||||
# OpenNebula semantics. The VIDriver::initialize MUST be called before
|
||||
# instantiating this class
|
||||
############################################################################
|
||||
class VIVm
|
||||
|
||||
########################################################################
|
||||
# Creates a new VIVm using its name or a RbVmomi::VirtualMachine object
|
||||
# @param vmname [String] the OpenNebula vm deploy_id (e.g. "one-237")
|
||||
# @param vm_vi [RbVmomi::VirtualMachine] it will be used if not nil
|
||||
########################################################################
|
||||
def initialize(vmname, vm_vi)
|
||||
if vm_vi.nil?
|
||||
@vm = VIDriver::host.vm.find { |v|
|
||||
v.name == vmname
|
||||
}
|
||||
else
|
||||
@vm = vm_vi
|
||||
end
|
||||
}
|
||||
backing = RbVmomi::VIM.VirtualEthernetCardNetworkBackingInfo(:deviceName => bridge)
|
||||
device_spec = {:key => 0,
|
||||
:deviceInfo => {
|
||||
:label => "net" + card_num.to_s,
|
||||
:summary => bridge
|
||||
},
|
||||
:backing => backing,
|
||||
:addressType => 'manual',
|
||||
:macAddress => mac }
|
||||
|
||||
device = case model.downcase
|
||||
when 'pcnet32'
|
||||
RbVmomi::VIM.VirtualPCNet32(device_spec)
|
||||
when 'VirtualVmxnet'
|
||||
RbVmomi::VIM.VirtualVmxnet(device_spec)
|
||||
else # By default, assume E1000 model
|
||||
RbVmomi::VIM.VirtualE1000(device_spec)
|
||||
end
|
||||
spec = {:deviceChange => [:operation => :add, :device => device]}
|
||||
|
||||
vm.ReconfigVM_Task(:spec => spec).wait_for_completion
|
||||
raise "Cannot find VM #{vmname}" if @vm.nil?
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Detach a NIC with mac from deploy_id #
|
||||
# -------------------------------------------------------------------------#
|
||||
def detach_nic(deploy_id, mac)
|
||||
vm = get_vm(deploy_id)[:vm]
|
||||
nic_to_detach = nil
|
||||
vm.config.hardware.device.each{ |dv|
|
||||
if dv.class.ancestors[1] == RbVmomi::VIM::VirtualEthernetCard
|
||||
nic_to_detach = dv if dv.macAddress == mac
|
||||
end
|
||||
}
|
||||
|
||||
return -1 if !nic_to_detach
|
||||
|
||||
spec = {:deviceChange => [:operation => :remove,:device => nic_to_detach]}
|
||||
|
||||
vm.ReconfigVM_Task(:spec => spec).wait_for_completion
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Set the guest OS #
|
||||
# -------------------------------------------------------------------------#
|
||||
def set_guest_os(deploy_id, guest_os_id)
|
||||
vm = get_vm(deploy_id)[:vm]
|
||||
########################################################################
|
||||
# Set the guest OS
|
||||
########################################################################
|
||||
def set_guestos(guest_os_id)
|
||||
return if (guest_os_id.nil? || guest_os_id.empty? )
|
||||
|
||||
spec = {:guestId => guest_os_id}
|
||||
|
||||
vm.ReconfigVM_Task(:spec => spec).wait_for_completion
|
||||
@vm.ReconfigVM_Task(:spec => spec).wait_for_completion
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Set the pciBrdige #
|
||||
# -------------------------------------------------------------------------#
|
||||
def set_pcibridge(deploy_id, pciBridge)
|
||||
if pciBridge.downcase == "yes"
|
||||
spec = { :key => "pciBridge0.present", :value => "TRUE" }
|
||||
else
|
||||
spec = { :key => "pciBridge0.present", :value => "FALSE" }
|
||||
end
|
||||
########################################################################
|
||||
# Set or removes a pciBridge from VM
|
||||
########################################################################
|
||||
def set_pcibridge(pciBridge)
|
||||
|
||||
vmspec = RbVmomi::VIM.VirtualMachineConfigSpec(:extraConfig => spec)
|
||||
return if (pciBridge.nil? || pciBridge.empty? )
|
||||
|
||||
vm.ReconfigVM_Task(:spec => vmspec).wait_for_completion
|
||||
end
|
||||
|
||||
############################################################################
|
||||
# Private Methods #
|
||||
############################################################################
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Poll the monitoring information for a VM #
|
||||
# -------------------------------------------------------------------------#
|
||||
def get_all_vms_info
|
||||
begin
|
||||
vms = get_all_vms
|
||||
str_info = "VM_POLL=YES " if vms.length > 0
|
||||
|
||||
vms.each do |vm|
|
||||
number = -1
|
||||
number = vm.name.split('-').last if (vm.name =~ /^one-\d*$/)
|
||||
|
||||
str_info += "VM=["
|
||||
str_info += "ID=#{number},"
|
||||
str_info += "DEPLOY_ID=#{vm.name},"
|
||||
str_info += "POLL=\"#{get_vm_info(vm)}\"]"
|
||||
end
|
||||
|
||||
return str_info
|
||||
rescue Exception => e
|
||||
str_info = "STATE=d"
|
||||
STDERR.puts e.message
|
||||
end
|
||||
return str_info
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Get hold of a VM by name #
|
||||
# -------------------------------------------------------------------------#
|
||||
def get_vm(name)
|
||||
vm = {}
|
||||
# Traverse all datacenters
|
||||
@rootFolder.childEntity.grep(RbVmomi::VIM::Datacenter).each do |dc|
|
||||
# Traverse all datastores
|
||||
dc.datastoreFolder.childEntity.collect do |ds|
|
||||
# Find the VM called "name"
|
||||
vm[:vm] = ds.vm.find { |v| v.name == name }
|
||||
if vm[:vm]
|
||||
vm[:ds] = ds.name
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return vm
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Get hold of a host by name #
|
||||
# -------------------------------------------------------------------------#
|
||||
def get_host(name)
|
||||
host = {}
|
||||
@rootFolder.childEntity.grep(RbVmomi::VIM::Datacenter).each do |dc|
|
||||
dc.hostFolder.children.first.host.each { |h|
|
||||
if h.name == name
|
||||
host = h
|
||||
break
|
||||
end
|
||||
}
|
||||
break if host != {}
|
||||
end
|
||||
return host
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Get information of a particular VM #
|
||||
# -------------------------------------------------------------------------#
|
||||
def get_vm_info(vm)
|
||||
# Get network information
|
||||
net_info = get_perf_value([vm], ["net.packetsRx","net.packetsTx"])
|
||||
|
||||
state = get_state(vm)
|
||||
return "STATE=d" if state.downcase == "d"
|
||||
|
||||
str_info = ""
|
||||
str_info += "STATE=" + state + " "
|
||||
str_info += "USEDCPU=" + get_used_cpu(vm) + " "
|
||||
str_info += "USEDMEMORY=" + get_used_memory(vm)
|
||||
|
||||
if net_info[vm] && net_info[vm][:metrics] && net_info[vm][:metrics]["net.packetsRx"]
|
||||
str_info += " NETRX=" +
|
||||
net_info[vm][:metrics]["net.packetsRx"].first.to_s + " "
|
||||
str_info += "NETTX=" +
|
||||
net_info[vm][:metrics]["net.packetsTx"].first.to_s
|
||||
end
|
||||
|
||||
return str_info
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Get information of the initialized host #
|
||||
# -------------------------------------------------------------------------#
|
||||
def get_host_info
|
||||
str_info = ""
|
||||
# CPU
|
||||
total_cpu = @host.summary.hardware.numCpuCores*100
|
||||
used_cpu = get_host_used_cpu
|
||||
|
||||
str_info += "MODELNAME=\""+ @host.summary.hardware.cpuModel.to_s + "\" "
|
||||
str_info += "CPUSPEED=" + @host.summary.hardware.cpuMhz.to_s + " "
|
||||
str_info += "TOTALCPU=" + total_cpu.to_s + " "
|
||||
str_info += "USEDCPU=" + used_cpu.to_s + " "
|
||||
str_info += "FREECPU=" + (total_cpu - used_cpu).to_s + " "
|
||||
|
||||
# Memory
|
||||
total_memory = get_host_total_memory
|
||||
used_memory = get_host_used_memory
|
||||
str_info += "TOTALMEMORY=" + total_memory.to_s + " "
|
||||
str_info += "USEDMEMORY=" + used_memory.to_s + " "
|
||||
str_info += "FREEMEMORY=" + (total_memory - used_memory).to_s + " "
|
||||
|
||||
# Networking
|
||||
net_info = get_perf_value([@host], ["net.packetsRx","net.packetsTx"])
|
||||
str_info += "NETRX=" +
|
||||
net_info[@host][:metrics]["net.packetsRx"].first.to_s + " "
|
||||
str_info += "NETTX=" +
|
||||
net_info[@host][:metrics]["net.packetsTx"].first.to_s
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Get used CPO of the initialized host #
|
||||
# -------------------------------------------------------------------------#
|
||||
def get_host_used_cpu
|
||||
overallCpuUsage = @host.summary.quickStats.overallCpuUsage.to_f
|
||||
(overallCpuUsage / (@cpuMhz * @numCpuCores)).round()
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Get total memory of the initialized host #
|
||||
# -------------------------------------------------------------------------#
|
||||
def get_host_total_memory
|
||||
@host.summary.hardware.memorySize/1024
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Get used memory of the initialized host #
|
||||
# -------------------------------------------------------------------------#
|
||||
def get_host_used_memory
|
||||
@host.summary.quickStats.overallMemoryUsage*1024
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Get all VMs available in current @hostname #
|
||||
# -------------------------------------------------------------------------#
|
||||
def get_all_vms
|
||||
@host.vm.collect { |vm| vm if get_state(vm)=="a" }.compact
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Get used memory of a VM #
|
||||
# -------------------------------------------------------------------------#
|
||||
def get_used_memory(vm)
|
||||
(vm.summary.quickStats.hostMemoryUsage*1024).to_s
|
||||
end
|
||||
|
||||
# Get percentage of the CPU used by a VM in a host
|
||||
def get_used_cpu(vm)
|
||||
overallCpuUsage = vm.summary.quickStats.overallCpuUsage.to_f
|
||||
((overallCpuUsage / (@cpuMhz * @numCpuCores)).round()).to_s
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Get OpenNebula state of a VM #
|
||||
# -------------------------------------------------------------------------#
|
||||
def get_state(vm)
|
||||
case vm.summary.runtime.powerState
|
||||
when "poweredOn"
|
||||
"a"
|
||||
when "suspended"
|
||||
"p"
|
||||
if pciBridge.downcase == "yes"
|
||||
spec = { :key => "pciBridge0.present", :value => "TRUE" }
|
||||
else
|
||||
"d"
|
||||
end
|
||||
spec = { :key => "pciBridge0.present", :value => "FALSE" }
|
||||
end
|
||||
|
||||
vmspec = RbVmomi::VIM.VirtualMachineConfigSpec(:extraConfig => spec)
|
||||
|
||||
@vm.ReconfigVM_Task(:spec => vmspec).wait_for_completion
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------#
|
||||
# Get performance values for metrics (array) of objects (array) #
|
||||
# -------------------------------------------------------------------------#
|
||||
def get_perf_value(objects,metrics)
|
||||
perfManager = @client.serviceContent.perfManager
|
||||
########################################################################
|
||||
#
|
||||
########################################################################
|
||||
def attach_nic(bridge, model, mac)
|
||||
return if bridge.empty? || mac.empty?
|
||||
|
||||
metrics.each do |metric|
|
||||
return if !perfManager.perfcounter_hash.member? metric
|
||||
end
|
||||
card_num = 1 # start in one, we want the next avaiable id
|
||||
|
||||
interval = perfManager.provider_summary(objects.first).refreshRate
|
||||
start_time = nil
|
||||
if interval == -1
|
||||
interval = 300
|
||||
start_time = Time.now - 300 * 5
|
||||
end
|
||||
stat_opts = {
|
||||
:interval => interval,
|
||||
:startTime => start_time,
|
||||
}
|
||||
@vm.config.hardware.device.each{ |dv|
|
||||
if dv.class.ancestors[1] == RbVmomi::VIM::VirtualEthernetCard
|
||||
card_num = card_num + 1
|
||||
end
|
||||
}
|
||||
|
||||
return perfManager.retrieve_stats(objects, metrics, stat_opts)
|
||||
backing = RbVmomi::VIM.VirtualEthernetCardNetworkBackingInfo(
|
||||
:deviceName => bridge)
|
||||
|
||||
device_spec = {
|
||||
:key => 0,
|
||||
:deviceInfo => {
|
||||
:label => "net" + card_num.to_s,
|
||||
:summary => bridge
|
||||
},
|
||||
:backing => backing,
|
||||
:addressType => 'manual',
|
||||
:macAddress => mac
|
||||
}
|
||||
|
||||
device = case model.downcase
|
||||
when 'pcnet32'
|
||||
RbVmomi::VIM.VirtualPCNet32(device_spec)
|
||||
when 'VirtualVmxnet'
|
||||
RbVmomi::VIM.VirtualVmxnet(device_spec)
|
||||
else # By default, assume E1000 model
|
||||
RbVmomi::VIM.VirtualE1000(device_spec)
|
||||
end
|
||||
|
||||
spec = {:deviceChange => [:operation => :add, :device => device]}
|
||||
|
||||
@vm.ReconfigVM_Task(:spec => spec).wait_for_completion
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Initialize the vm monitor information
|
||||
########################################################################
|
||||
def detach_nic(mac)
|
||||
nic_to_detach = nil
|
||||
|
||||
@vm.config.hardware.device.each{ |dv|
|
||||
if dv.class.ancestors[1] == RbVmomi::VIM::VirtualEthernetCard
|
||||
nic_to_detach = dv if dv.macAddress == mac
|
||||
break
|
||||
end
|
||||
}
|
||||
|
||||
return -1 if !nic_to_detach
|
||||
|
||||
spec = {
|
||||
:deviceChange => [
|
||||
:operation => :remove,
|
||||
:device => nic_to_detach
|
||||
]
|
||||
}
|
||||
|
||||
@vm.ReconfigVM_Task(:spec => spec).wait_for_completion
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Initialize the vm monitor information
|
||||
########################################################################
|
||||
def monitor
|
||||
@summary = @vm.summary
|
||||
@state = state_to_c(@summary.runtime.powerState)
|
||||
|
||||
if @state != 'a'
|
||||
@used_cpu = 0
|
||||
@used_memory = 0
|
||||
|
||||
@net_rx = 0
|
||||
@net_tx = 0
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
host = VIDriver::host
|
||||
cpuMhz = host.cpuMhz.to_f
|
||||
numCpuCores = host.numCpuCores.to_f
|
||||
|
||||
@used_cpu= (@summary.quickStats.overallCpuUsage.to_f /
|
||||
(cpuMhz * numCpuCores)).round()
|
||||
|
||||
@used_memory = @summary.quickStats.hostMemoryUsage * 1024
|
||||
|
||||
net = VIDriver::retrieve_stats([@vm],
|
||||
["net.packetsRx","net.packetsTx"])
|
||||
@net_rx = 0
|
||||
@net_tx = 0
|
||||
|
||||
if net[@vm] && net[@vm][:metrics]
|
||||
if net[@vm][:metrics]["net.packetsRx"]
|
||||
@net_rx = net[@vm][:metrics]["net.packetsRx"].first
|
||||
end
|
||||
|
||||
if net[@vm][:metrics]["net.packetsTx"]
|
||||
@net_tx = net[@vm][:metrics]["net.packetsTx"].first
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Generates a OpenNebula IM Driver valid string with the monitor info
|
||||
########################################################################
|
||||
def info
|
||||
return 'STATE=d' if @state == 'd'
|
||||
|
||||
str_info = ""
|
||||
|
||||
str_info << "STATE=" << @state << " "
|
||||
str_info << "USEDCPU=" << @used_cpu.to_s << " "
|
||||
str_info << "USEDMEMORY="<< @used_memory.to_s << " "
|
||||
str_info << "NETRX=" << @net_rx.to_s << " "
|
||||
str_info << "NETTX=" << @net_tx.to_s
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
########################################################################
|
||||
# Converts the VI string state to OpenNebula state convention
|
||||
########################################################################
|
||||
def state_to_c(state)
|
||||
case state
|
||||
when 'poweredOn'
|
||||
'a'
|
||||
when 'suspended'
|
||||
'p'
|
||||
else
|
||||
'd'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
############################################################################
|
||||
# The VIHost is a high level abstraction of a HostSystem class for
|
||||
# OpenNebula semantics. The VIDriver::initialize MUST be called before
|
||||
# instantiating this class
|
||||
############################################################################
|
||||
class VIHost
|
||||
attr_reader :host, :cpuMhz, :numCpuCores
|
||||
|
||||
def initialize(hostname)
|
||||
@ip = Socket.getaddrinfo(hostname,nil).first[3]
|
||||
|
||||
raise "Cannot get host IP" if @ip.nil? || @ip.empty?
|
||||
|
||||
@host =VIDriver::root.findByIp @ip, RbVmomi::VIM::HostSystem
|
||||
|
||||
raise "Cannot find host #{hostname}" if @host.nil?
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Initialize the host monitor information
|
||||
########################################################################
|
||||
def monitor
|
||||
summary = @host.summary
|
||||
hardware = summary.hardware
|
||||
stats = summary.quickStats
|
||||
|
||||
@cpuModel = hardware.cpuModel
|
||||
@cpuMhz = hardware.cpuMhz
|
||||
@numCpuCores = hardware.numCpuCores
|
||||
|
||||
@total_cpu = hardware.numCpuCores*100
|
||||
@used_cpu = (stats.overallCpuUsage.to_f /
|
||||
(@cpuMhz.to_f * @numCpuCores.to_f)).round()
|
||||
|
||||
@total_memory = hardware.memorySize/1024
|
||||
@used_memory = stats.overallMemoryUsage*1024
|
||||
|
||||
net = VIDriver::retrieve_stats([@host],
|
||||
["net.packetsRx","net.packetsTx"])
|
||||
@net_rx = 0
|
||||
@net_tx = 0
|
||||
|
||||
if net[@host] && net[@host][:metrics]
|
||||
if net[@host][:metrics]["net.packetsRx"]
|
||||
@net_rx = net[@host][:metrics]["net.packetsRx"].first
|
||||
end
|
||||
|
||||
if net[@host][:metrics]["net.packetsTx"]
|
||||
@net_tx = net[@host][:metrics]["net.packetsTx"].first
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Generates a OpenNebula IM Driver valid string with the monitor info
|
||||
########################################################################
|
||||
def info
|
||||
str_info = ""
|
||||
|
||||
# CPU
|
||||
str_info << "MODELNAME=\"" << @cpuModel.to_s << "\"\n"
|
||||
str_info << "CPUSPEED=" << @cpuMhz.to_s << "\n"
|
||||
str_info << "TOTALCPU=" << @total_cpu.to_s << "\n"
|
||||
str_info << "USEDCPU=" << @used_cpu.to_s << "\n"
|
||||
str_info << "FREECPU=" << (@total_cpu - @used_cpu).to_s << "\n"
|
||||
|
||||
# Memory
|
||||
str_info << "TOTALMEMORY=" << @total_memory.to_s << "\n"
|
||||
str_info << "USEDMEMORY=" << @used_memory.to_s << "\n"
|
||||
str_info << "FREEMEMORY=" << (@total_memory - @used_memory).to_s << "\n"
|
||||
|
||||
# Networking
|
||||
str_info << "NETRX=" << @net_rx.to_s << "\n"
|
||||
str_info << "NETTX=" << @net_tx.to_s <<
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Generates a OpenNebula IM Driver valid string with the monitor info
|
||||
# of all VMs defined/running in the ESXi host.
|
||||
########################################################################
|
||||
def all_vms_info()
|
||||
str_info = ""
|
||||
|
||||
@host.vm.each { |v|
|
||||
begin
|
||||
vivm = VIDriver::VIVm.new("", v)
|
||||
rescue
|
||||
next
|
||||
end
|
||||
|
||||
vivm.monitor
|
||||
|
||||
name = v.name
|
||||
number = -1
|
||||
number = name.split('-').last if (name =~ /^one-\d*$/)
|
||||
|
||||
str_info << "VM = ["
|
||||
str_info << "ID=#{number},"
|
||||
str_info << "DEPLOY_ID=#{name},"
|
||||
str_info << "POLL=\"#{vivm.info}\"]\n"
|
||||
}
|
||||
|
||||
return str_info
|
||||
end
|
||||
|
||||
def vm
|
||||
@host.vm
|
||||
end
|
||||
end
|
||||
|
||||
############################################################################
|
||||
# Get performance values for metrics (array) of objects (array)
|
||||
############################################################################
|
||||
def self.retrieve_stats(objects,metrics)
|
||||
perfManager = @@client.serviceContent.perfManager
|
||||
|
||||
metrics.each do |metric|
|
||||
return if !perfManager.perfcounter_hash.member? metric
|
||||
end
|
||||
|
||||
interval = perfManager.provider_summary(objects.first).refreshRate
|
||||
start_time = nil
|
||||
|
||||
if interval == -1
|
||||
interval = 300
|
||||
start_time = Time.now - 300 * 5
|
||||
end
|
||||
|
||||
stat_opts = {
|
||||
:interval => interval,
|
||||
:startTime => start_time,
|
||||
}
|
||||
|
||||
return perfManager.retrieve_stats(objects, metrics, stat_opts)
|
||||
end
|
||||
|
||||
def self.root
|
||||
@@root
|
||||
end
|
||||
|
||||
def self.host
|
||||
@@host
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -379,8 +379,7 @@ class VMwareDriver
|
||||
|
||||
deploy_id.strip!
|
||||
|
||||
dfile_hash = Document.new(File.open(dfile).read)
|
||||
handle_metadata(dfile_hash, deploy_id)
|
||||
handle_metadata(dfile, deploy_id)
|
||||
|
||||
return deploy_id
|
||||
end
|
||||
@ -390,61 +389,50 @@ class VMwareDriver
|
||||
return rc
|
||||
end
|
||||
|
||||
def handle_metadata(dfile_hash, deploy_id)
|
||||
metadata = XPath.first(dfile_hash, "//metadata")
|
||||
def handle_metadata(dfile, deploy_id)
|
||||
dfile_hash = Document.new(File.open(dfile).read)
|
||||
|
||||
# Check for the known types
|
||||
guestOS = XPath.first(dfile_hash, "//metadata/guestOS")
|
||||
pciBridge = XPath.first(dfile_hash, "//metadata/pciBridge")
|
||||
|
||||
if (guestOS or pciBridge)
|
||||
vi_driver = VIDriver.new(@host)
|
||||
# Check for the known elements in metadata
|
||||
guestOS = XPath.first(dfile_hash, "/domain/metadata/guestOS")
|
||||
pciBridge = XPath.first(dfile_hash, "/domain/metadata/pciBridge")
|
||||
|
||||
if (guestOS || pciBridge)
|
||||
VIDriver::initialize(@host, false)
|
||||
|
||||
vivm = VIDriver::VIVm.new(deploy_id, nil)
|
||||
|
||||
vivm.set_guestos(guestOS.text) if guestOS
|
||||
|
||||
vivm.set_pcibridge(pciBridge.text) if pciBridge
|
||||
end
|
||||
|
||||
dfile_hash = set_guest_os(dfile_hash,
|
||||
vi_driver,
|
||||
deploy_id,
|
||||
guestOS) if guestOS
|
||||
# Append the raw datavmx to vmx file
|
||||
metadata = XPath.first(dfile_hash, "/domain/metadata/datavmx")
|
||||
|
||||
dfile_hash = set_pcibridge(dfile_hash,
|
||||
vi_driver,
|
||||
deploy_id,
|
||||
pciBridge) if pciBridge
|
||||
|
||||
metadata = XPath.first(dfile_hash, "//metadata")
|
||||
|
||||
return if metadata.nil?
|
||||
return if metadata.nil?
|
||||
return if metadata.text.nil?
|
||||
return if metadata.text.strip.empty?
|
||||
|
||||
metadata = metadata.text
|
||||
|
||||
# Get the ds_id for system_ds from the first disk
|
||||
source = XPath.first(dfile_hash, "//disk/source").attributes['file']
|
||||
source = XPath.first(dfile_hash, "/domain//disk/source").attributes['file']
|
||||
ds_id = source.match(/^\[(.*)\](.*)/)[1]
|
||||
|
||||
name = XPath.first(dfile_hash, "//name").text
|
||||
name = XPath.first(dfile_hash, "/domain/name").text
|
||||
vm_id = name.match(/^one-(.*)/)[1]
|
||||
|
||||
# Reconstruct path to vmx & add metadata
|
||||
path_to_vmx = "\$(find /vmfs/volumes/#{ds_id}/#{vm_id}/"
|
||||
path_to_vmx = "\$(find /vmfs/volumes/#{ds_id}/#{vm_id}/"
|
||||
path_to_vmx << " -name #{name}.vmx)"
|
||||
|
||||
metadata.gsub!("\\n","\n")
|
||||
|
||||
sed_str = metadata.scan(/^([^ ]+) *=/).join("|")
|
||||
|
||||
cmd_str = "sed -ri \"/^(#{sed_str}) *=.*$/d\" #{path_to_vmx}; "
|
||||
cmd_str << "cat >> #{path_to_vmx}"
|
||||
|
||||
do_ssh_action(cmd_str, metadata)
|
||||
end
|
||||
|
||||
def set_guest_os(dfile_hash, vi_driver, deploy_id, guestOS)
|
||||
vi_driver.set_guest_os(deploy_id, guestOS.text)
|
||||
dfile_hash.delete_element('//guestOS')
|
||||
return dfile_hash
|
||||
end
|
||||
|
||||
def set_pcibridge(dfile_hash, vi_driver, deploy_id, pciBridge)
|
||||
vi_driver.set_pcibridge(deploy_id, pciBridge.text)
|
||||
dfile_hash.delete_element('//pciBridge')
|
||||
return dfile_hash
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user