1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-04-02 10:50:07 +03:00

feature #1427: Refactor oneacct

This commit is contained in:
Daniel Molina 2012-08-23 14:24:48 +02:00
parent 435c5ea1b2
commit 521e6ff7c4
3 changed files with 243 additions and 332 deletions

View File

@ -1194,7 +1194,8 @@ ONE_CLI_LIB_FILES="src/cli/one_helper/onegroup_helper.rb \
src/cli/one_helper/onevnet_helper.rb \
src/cli/one_helper/oneacl_helper.rb \
src/cli/one_helper/onedatastore_helper.rb \
src/cli/one_helper/onecluster_helper.rb"
src/cli/one_helper/onecluster_helper.rb \
src/cli/one_helper/oneacct_helper.rb"
CLI_BIN_FILES="src/cli/onevm \
src/cli/onehost \
@ -1205,7 +1206,8 @@ CLI_BIN_FILES="src/cli/onevm \
src/cli/onegroup \
src/cli/oneacl \
src/cli/onedatastore \
src/cli/onecluster"
src/cli/onecluster \
src/cli/oneacct"
CLI_CONF_FILES="src/cli/etc/onegroup.yaml \
src/cli/etc/onehost.yaml \

View File

@ -0,0 +1,179 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #
require 'one_helper'
class AcctHelper < OpenNebulaHelper::OneHelper
START_TIME = {
:name => "start_time",
:short => "-s TIME",
:large => "--start TIME" ,
:description => "Start date and time to take into account",
:format => String # TODO Time
}
END_TIME = {
:name => "end_time",
:short => "-e TIME",
:large => "--end TIME" ,
:description => "End date and time",
:format => String # TODO Time
}
USER = {
:name => "user",
:short => "-u user",
:large => "--user user" ,
:description => "User name or id to filter the results",
:format => String,
:proc => lambda { |o, options|
OpenNebulaHelper.rname_to_id(o, "USER")
}
}
GROUP = {
:name => "group",
:short => "-g group",
:large => "--group group" ,
:description => "Group name or id to filter the results",
:format => String,
:proc => lambda { |o, options|
puts o
OpenNebulaHelper.rname_to_id(o, "GROUP")
}
}
HOST = {
:name => "host",
:short => "-H HOST",
:large => "--host HOST" ,
:description => "Host name or id to filter the results",
:format => String,
:proc => lambda { |o, options|
OpenNebulaHelper.rname_to_id(o, "HOST")
}
}
XPATH = {
:name => "xpath",
:large => "--xpath XPATH_EXPRESSION" ,
:description => "Xpath expression to filter the results. \
For example: oneacct --xpath 'HISTORY[ETIME>0]'",
:format => String
}
XML = {
:name => "xml",
:short => "-x",
:large => "--xml",
:description => "Show the resource in xml format"
}
JSON = {
:name => "json",
:short => "-j",
:large => "--json",
:description => "Show the resource in xml format"
}
SPLIT={
:name => "split",
:large => "--split",
:description => "Split the output in a table for each VM"
}
ACCT_OPTIONS = [START_TIME, END_TIME, USER, GROUP, HOST, XPATH, XML, JSON, SPLIT]
ACCT_TABLE = CLIHelper::ShowTable.new("oneacct.yaml", nil) do
column :VID, "Virtual Machine ID", :size=>4 do |d|
d["OID"]
end
column :SEQ, "History record sequence number", :size=>3 do |d|
d["SEQ"]
end
column :HOSTNAME, "Host name", :left, :size=>15 do |d|
d["HOSTNAME"]
end
column :REASON, "VM state change reason", :left, :size=>4 do |d|
VirtualMachine.get_reason d["REASON"]
end
column :START_TIME, "Start time", :size=>14 do |d|
OpenNebulaHelper.time_to_str(d['STIME'])
end
column :END_TIME, "End time", :size=>14 do |d|
OpenNebulaHelper.time_to_str(d['ETIME'])
end
column :MEMORY, "Assigned memory", :size=>6 do |d|
OpenNebulaHelper.unit_to_str(d["VM"]["TEMPLATE"]["MEMORY"].to_i, {}, 'M')
end
column :CPU, "Number of CPUs", :size=>3 do |d|
d["VM"]["TEMPLATE"]["CPU"]
end
column :NET_RX, "Data received from the network", :size=>6 do |d|
# NET is measured in bytes, unit_to_str expects KBytes
OpenNebulaHelper.unit_to_str(d["VM"]["NET_RX"].to_i / 1024.0, {})
end
column :NET_TX, "Data sent to the network", :size=>6 do |d|
# NET is measured in bytes, unit_to_str expects KBytes
OpenNebulaHelper.unit_to_str(d["VM"]["NET_TX"].to_i / 1024.0, {})
end
default :VID, :HOSTNAME, :REASON, :START_TIME, :END_TIME, :MEMORY, :CPU, :NET_RX, :NET_TX
end
def self.print_start_enc_time_header(start_time, end_time)
print "Showing active history records from "
CLIHelper.scr_bold
if ( start_time != -1 )
print Time.at(start_time).to_s
else
print "-"
end
CLIHelper.scr_restore
print " to "
CLIHelper.scr_bold
if ( end_time != -1 )
print Time.at(end_time).to_s
else
print "-"
end
CLIHelper.scr_restore
puts
puts
end
def self.print_user_header(user_id)
CLIHelper.scr_bold
CLIHelper.scr_underline
puts "# User #{user_id}".ljust(80)
CLIHelper.scr_restore
puts
end
end

View File

@ -16,7 +16,6 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
ONE_LOCATION=ENV["ONE_LOCATION"]
if !ONE_LOCATION
@ -28,356 +27,87 @@ end
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+"/cli"
require 'rubygems'
require 'command_parser'
require 'one_helper/oneacct_helper'
require 'cli/one_helper'
require 'cli/command_parser'
require 'json'
require 'optparse'
require 'optparse/time'
cmd = CommandParser::CmdParser.new(ARGV) do
usage "`oneacct` [<options>]"
description ""
version OpenNebulaHelper::ONE_VERSION
################################################################################
# CLI Helper
################################################################################
option [AcctHelper::ACCT_OPTIONS + CommandParser::OPTIONS]
class AcctHelper < OpenNebulaHelper::OneHelper
main do
filter_flag = (options[:user] || VirtualMachinePool::INFO_ALL)
start_time = options[:start] ? options[:start].to_i : -1
end_time = options[:end] ? options[:end].to_i : -1
def self.conf_file
"oneacct.yaml"
end
common_opts = {
:start_time => start_time,
:end_time => end_time,
:host => options[:host],
:group => options[:group],
:xpath => options[:xpath]
}
=begin
List of <HISTORY> child elements
client = OpenNebula::Client.new
pool = OpenNebula::VirtualMachinePool.new(client)
OID
SEQ
HOSTNAME
HID
STIME
ETIME
VMMMAD
VNMMAD
PSTIME
PETIME
RSTIME
RETIME
ESTIME
EETIME
REASON
=end
def list_history(data)
table = CLIHelper::ShowTable.new(self.class.table_conf, self) do
column :VID, "Virtual Machine ID", :size=>4 do |d|
d["OID"]
if options[:json] || options[:xml]
xml_str = pool.accounting_xml(filter_flag, common_opts)
if OpenNebula.is_error?(xml_str)
puts acct_hash.message
exit -1
end
column :SEQ, "History record sequence number", :size=>3 do |d|
d["SEQ"]
if options[:json]
xmldoc = XMLElement.new
xmldoc.initialize_xml(xml_str, 'HISTORY_RECORDS')
puts xmldoc.to_hash.to_json
elsif options[:xml]
puts xml_str
end
column :HOSTNAME, "Host name", :left, :size=>15 do |d|
d["HOSTNAME"]
exit_code 0
else
order_by = Hash.new
order_by[:order_by_1] = 'VM/UID'
order_by[:order_by_2] = 'VM/ID' if options[:split]
acct_hash = pool.accounting(filter_flag, common_opts.merge(order_by))
if OpenNebula.is_error?(acct_hash)
puts acct_hash.message
exit -1
end
column :REASON, "VM state change reason", :left, :size=>4 do |d|
VirtualMachine.get_reason d["REASON"]
if ( start_time != -1 or end_time != -1 )
AcctHelper.print_start_end_time_header(start_time, end_time)
end
column :START_TIME, "Start time", :size=>14 do |d|
OpenNebulaHelper.time_to_str(d['STIME'])
end
acct_hash.each { |user_id, value|
AcctHelper.print_user_header(user_id)
column :END_TIME, "End time", :size=>14 do |d|
OpenNebulaHelper.time_to_str(d['ETIME'])
end
column :MEMORY, "Assigned memory", :size=>6 do |d|
OpenNebulaHelper.unit_to_str(d["VM/TEMPLATE/MEMORY"].to_i, {}, 'M')
end
column :CPU, "Number of CPUs", :size=>3 do |d|
d["VM/TEMPLATE/CPU"]
end
column :NET_RX, "Data received from the network", :size=>6 do |d|
# NET is measured in bytes, unit_to_str expects KBytes
OpenNebulaHelper.unit_to_str(d["VM/NET_RX"].to_i / 1024.0, {})
end
column :NET_TX, "Data sent to the network", :size=>6 do |d|
# NET is measured in bytes, unit_to_str expects KBytes
OpenNebulaHelper.unit_to_str(d["VM/NET_TX"].to_i / 1024.0, {})
end
default :VID, :HOSTNAME, :REASON, :START_TIME, :END_TIME, :MEMORY, :CPU, :NET_RX, :NET_TX
end
table.show(data)
end
public
def list_users(xmldoc, options=nil)
uids = xmldoc.retrieve_elements('HISTORY/VM/UID')
if uids.nil?
puts "No records found."
exit 0
end
uids.uniq!
history_elems = []
uids.each do |uid|
CLIHelper.scr_bold
CLIHelper.scr_underline
username_elems =
xmldoc.retrieve_elements("HISTORY/VM[UID=#{uid}]/UNAME")
username = username_elems.nil? ? "" : username_elems.uniq
puts "# User #{uid} #{username}".ljust(80)
CLIHelper.scr_restore
puts
history_elems.clear
vm_ids = xmldoc.retrieve_elements("HISTORY/VM[UID=#{uid}]/ID")
vm_ids = [] if vm_ids.nil?
vm_ids.uniq!
vm_ids.each do |vid|
if ( options[:split] )
history_elems.clear
end
xmldoc.each("HISTORY[OID=#{vid}]") do |history|
history_elems << history
end
if ( options[:split] )
list_history(history_elems)
if options[:split]
# Use one table for each VM
value.each { |vm_id, history_array|
array = history_array['HISTORY_RECORDS']['HISTORY']
AcctHelper::ACCT_TABLE.show(array)
puts
}
else
# Use the same table for all the VMs
array = value['HISTORY_RECORDS']['HISTORY']
AcctHelper::ACCT_TABLE.show(array)
puts
end
end
}
if ( !options[:split] )
list_history(history_elems)
puts
end
exit_code 0
end
end
end
################################################################################
# Helper methods
################################################################################
def redo_xmldoc(xmldoc, xpath_str)
xml_str = "<HISTORY_RECORDS>"
xmldoc.each(xpath_str) do |history|
xml_str << history.to_xml
end
xml_str << "</HISTORY_RECORDS>"
xmldoc = XMLElement.new
xmldoc.initialize_xml(xml_str, 'HISTORY_RECORDS')
return xmldoc
end
################################################################################
# Main command
################################################################################
options = Hash.new
options[:format] = :table
opts = OptionParser.new do |opts|
opts.on('-s', '--start TIME', Time,
'Start date and time to take into account') do |ext|
options[:start]=ext
end
opts.on("-e", "--end TIME", Time,
"End date and time" ) do |ext|
options[:end]=ext
end
opts.on("-u", "--user user", String,
"User id to filter the results" ) do |ext|
options[:user]=ext
end
opts.on("-g", "--group group", String,
"Group id to filter the results" ) do |ext|
options[:group]=ext
end
opts.on("-H", "--host hostname", String,
"Host id to filter the results" ) do |ext|
options[:host]=ext
end
opts.on("--xpath expression", String,
"Xpath expression to filter the results. For example: oneacct --xpath 'HISTORY[ETIME>0]'" ) do |ext|
options[:xpath]=ext
end
opts.on("-j", "--json",
"Output in json format" ) do |ext|
options[:format]=:json
end
opts.on("-x", "--xml",
"Output in xml format" ) do |ext|
options[:format]=:xml
end
opts.on("--split",
"Split the output in a table for each VM" ) do |ext|
options[:split]=ext
end
opts.on("-h", "--help", "Show this message" ) do
puts opts
exit
end
opts.on()
end
begin
opts.parse!(ARGV)
rescue OptionParser::ParseError => e
STDERR.puts "Error: " << e.message
exit(-1)
end
client = OpenNebula::Client.new
acct_helper = AcctHelper.new()
time_start = -1
time_end = -1
filter_flag = VirtualMachinePool::INFO_ALL
time_start = options[:start].to_i if options[:start]
time_end = options[:end].to_i if options[:end]
if options[:user]
rc = OpenNebulaHelper.rname_to_id(options[:user], "USER")
if rc[0] == 0
filter_flag = rc[1]
else
puts rc[1]
exit -1
end
end
xml_str = client.call("vmpool.accounting",
filter_flag,
time_start,
time_end)
if OpenNebula.is_error?(xml_str)
puts xml_str.message
exit -1
end
xmldoc = XMLElement.new
xmldoc.initialize_xml(xml_str, 'HISTORY_RECORDS')
xpath = nil
hid = nil
gid = nil
if options[:host]
rc = OpenNebulaHelper.rname_to_id(options[:host], "HOST")
if rc[0] == 0
hid = rc[1]
else
puts rc[1]
exit -1
end
end
if options[:group]
rc = OpenNebulaHelper.rname_to_id(options[:group], "GROUP")
if rc[0] == 0
gid = rc[1]
else
puts rc[1]
exit -1
end
end
if options[:host] && options[:group]
xpath = "HISTORY[VM/GID=#{gid} and HID=#{hid}]"
elsif options[:host]
xpath = "HISTORY[HID=#{hid}]"
elsif options[:group]
xpath = "HISTORY[VM/GID=#{gid}]"
end
xmldoc = redo_xmldoc(xmldoc, xpath) if !xpath.nil?
if options[:xpath]
xmldoc = redo_xmldoc(xmldoc, options[:xpath])
end
case options[:format]
when :table
if ( time_start != -1 or time_end != -1 )
print "Showing active history records from "
CLIHelper.scr_bold
if ( time_start != -1 )
print Time.at(time_start).to_s
else
print "-"
end
CLIHelper.scr_restore
print " to "
CLIHelper.scr_bold
if ( time_end != -1 )
print Time.at(time_end).to_s
else
print "-"
end
CLIHelper.scr_restore
puts
puts
end
acct_helper.list_users(xmldoc, options)
when :xml
puts xmldoc.to_xml
when :json
puts xmldoc.to_hash.to_json
end
end