# Copyright (c) 2011 VMware, Inc. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. class RbVmomi::VIM::HostSystem def self.ls_properties %w(name summary.hardware.memorySize summary.hardware.cpuModel summary.hardware.cpuMhz summary.hardware.numCpuPkgs summary.hardware.numCpuCores summary.hardware.numCpuThreads) end def ls_text r memorySize, cpuModel, cpuMhz, numCpuPkgs, numCpuCores = %w(memorySize cpuModel cpuMhz numCpuPkgs numCpuCores).map { |x| r["summary.hardware.#{x}"] } " (host): cpu #{numCpuPkgs}*#{numCpuCores}*#{"%.2f" % (cpuMhz.to_f/1000)} GHz, memory #{"%.2f" % (memorySize/10**9)} GB" end field 'state.connection' do summary "State of connection to VC." property 'runtime.connectionState' end field 'state.power' do summary "Host power state." property 'runtime.powerState' end field 'uptime' do summary "Host's uptime in days" properties %w(runtime.bootTime) block { |t| t ? MetricNumber.new(((Time.now-t) / (24 * 60 * 60)), 'd') : nil } end field 'num.vms' do summary "Number of VMs on the host" properties %w(vm) block { |t| t ? t.length : nil } end field 'num.poweredonvms' do summary "Number of VMs on the host" properties %w(vm) block do |vms| if vms && vms.length > 0 conn = vms.first._connection pc = conn.propertyCollector vmsProps = pc.collectMultiple(vms, 'runtime.powerState') vmsProps.select{|vm, p| p['runtime.powerState'] == 'poweredOn'}.length end end end field 'cpuusage' do summary "Realtime CPU usage in percent" properties %w(summary.hardware.numCpuCores summary.hardware.cpuMhz summary.quickStats) block do |cores, mhz, stats| if cores && mhz && stats value = stats.overallCpuUsage.to_f * 100 / (cores * mhz) MetricNumber.new(value, '%') end end end field 'memusage' do summary "Realtime Mem usage in percent" properties %w(summary.hardware.memorySize summary.quickStats) block do |mem, stats| if mem && stats value = stats.overallMemoryUsage.to_f * 100 / (mem / 1024.0 / 1024.0) MetricNumber.new(value, '%') end end end [['.realtime', 1], ['.5min', 5 * 3], ['.10min', 10 * 3]].each do |label, max_samples| field "cpuusage#{label}" do summary "CPU Usage in Percent" perfmetrics %w(cpu.usage) perfmetric_settings :max_samples => max_samples block do |value| if value value = value.sum.to_f / value.length / 100 MetricNumber.new(value, '%') else nil end end end end [['.realtime', 1], ['.5min', 5 * 3], ['.10min', 10 * 3]].each do |label, max_samples| field "memusage#{label}" do summary "Mem Usage in Percent" perfmetrics %w(mem.usage) perfmetric_settings :max_samples => max_samples block do |value| if value value = value.sum.to_f / value.length / 100 MetricNumber.new(value, '%') else nil end end end end def display_info super summary = self.summary runtime = summary.runtime stats = summary.quickStats hw = summary.hardware puts "connection state: #{runtime.connectionState}" puts "power state: #{runtime.powerState}" puts "uptime: #{"%0.2f" % ((Time.now - runtime.bootTime)/(24*3600))} days" if runtime.bootTime puts "in maintenance mode: #{runtime.inMaintenanceMode}" puts "standby mode: #{runtime.standbyMode}" if runtime.standbyMode if about = summary.config.product puts "product: #{about.fullName}" puts "license: #{about.licenseProductName} #{about.licenseProductVersion}" if about.licenseProductName end if runtime.connectionState == 'connected' and runtime.powerState == 'poweredOn' overallCpu = hw.numCpuPkgs * hw.numCpuCores * hw.cpuMhz puts "cpu: %d*%d*%.2f GHz = %.2f GHz" % [hw.numCpuPkgs, hw.numCpuCores, hw.cpuMhz/1e3, overallCpu/1e3] puts "cpu usage: %.2f GHz (%.1f%%)" % [stats.overallCpuUsage/1e3, 100*stats.overallCpuUsage/overallCpu] puts "memory: %.2f GB" % [hw.memorySize/1e9] puts "memory usage: %.2f GB (%.1f%%)" % [stats.overallMemoryUsage/1e3, 100*1e6*stats.overallMemoryUsage/hw.memorySize] end end def children { 'vms' => RVC::FakeFolder.new(self, :ls_vms), 'datastores' => RVC::FakeFolder.new(self, :ls_datastores), 'networks' => RVC::FakeFolder.new(self, :ls_networks), } end def ls_vms RVC::Util.collect_children self, :vm end def ls_datastores RVC::Util.collect_children self, :datastore end def ls_networks RVC::Util.collect_children self, :network end end class VIM::EsxcliCommand def option_parser parser = Trollop::Parser.new parser.text cli_info.help cli_info.param.each do |cli_param| vmodl_param = type_info.paramTypeInfo.find { |x| x.name == cli_param.name } opts = trollop_type(vmodl_param.type) opts[:required] = vmodl_param.annotation.find { |a| a.name == "optional"} ? false : true opts[:long] = cli_param.displayName #pp opts.merge(:name => cli_param.name) # XXX correct short options parser.opt cli_param.name, cli_param.help, opts end parser end def trollop_type t if t[-2..-1] == '[]' multi = true t = t[0...-2] else multi = false end type = case t when 'string', 'boolean' then t.to_sym when 'long' then :int else fail "unexpected esxcli type #{t.inspect}" end { :type => type, :multi => multi } end end