diff --git a/src/cli/oneacct b/src/cli/oneacct index a9a3e52fe6..feebf1f769 100755 --- a/src/cli/oneacct +++ b/src/cli/oneacct @@ -1,25 +1,20 @@ #!/usr/bin/env ruby -# -------------------------------------------------------------------------- -# Copyright 2010-2012, C12G Labs S.L. -# -# This file is part of OpenNebula addons. -# -# OpenNebula addons are free software: you can redistribute it -# and/or modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation, either version 3 of -# the License, or the hope That it will be useful, but (at your -# option) any later version. -# -# OpenNebula addons are distributed in WITHOUT ANY WARRANTY; -# without even the implied warranty of MERCHANTABILITY or FITNESS FOR -# A PARTICULAR PURPOSE. See the GNU General Public License for more -# details. -# -# You should have received a copy of the GNU General Public License -# along with OpenNebula addons. If not, see -# -# -------------------------------------------------------------------------- +# -------------------------------------------------------------------------- # +# 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. # +#--------------------------------------------------------------------------- # ONE_LOCATION=ENV["ONE_LOCATION"] @@ -35,7 +30,6 @@ $: << RUBY_LIB_LOCATION+"/cli" require 'rubygems' -require 'acct/oneacct' require 'cli/one_helper' require 'cli/command_parser' require 'json' @@ -43,164 +37,167 @@ require 'json' require 'optparse' require 'optparse/time' -REG_DATE=/((\d{4})\/)?(\d\d?)(\/(\d\d?))?/ -REG_TIME=/(\d\d?):(\d\d?)(:(\d\d?))?/ - class AcctHelper - def format_vm(options=nil) - table = CLIHelper::ShowTable.new(nil, nil) do - column :VMID, "VM ID", :size=>4 do |d| - d[:vmid] + def initialize(client) + @client = client + end + +=begin + List of child elements + + OID + SEQ + HOSTNAME + HID + STIME + ETIME + VMMMAD + VNMMAD + PSTIME + PETIME + RSTIME + RETIME + ESTIME + EETIME + REASON +=end + + def list_history(data) + table = CLIHelper::ShowTable.new(nil, self) do + column :VID, "Virtual Machine ", :size=>4 do |d| + d["OID"] end - column :MEMORY, "Consumed memory", :right, :size=>8 do |d| - OpenNebulaHelper.unit_to_str( - d[:slices].first[:mem]*1024, - {}) + column :SEQ, "Sequence number", :size=>3 do |d| + d["SEQ"] end - column :CPU, "Group of the User", :right, :size=>8 do |d| - d[:slices].first[:cpu] + column :HOSTNAME, "Host name", :size=>15 do |d| + d["HOSTNAME"] end - column :NETRX, "Group of the User", :right, :size=>10 do |d| - OpenNebulaHelper.unit_to_str( - d[:network][:net_rx].to_i/1024.0, - {}) + column :REASON, "VM state change reason", :size=>6 do |d| + VirtualMachine.get_reason d["REASON"] end - column :NETTX, "Group of the User", :right, :size=>10 do |d| - OpenNebulaHelper.unit_to_str( - d[:network][:net_tx].to_i/1024.0, - {}) + column :STIME, "Start time", :size=>15 do |d| + OpenNebulaHelper.time_to_str(d['STIME']) end - column :TIME, "Group of the User", :right, :size=>15 do |d| - OpenNebulaHelper.period_to_str(d[:time]) + column :ETIME, "End time", :size=>15 do |d| + OpenNebulaHelper.time_to_str(d['ETIME']) end - default :VMID, :MEMORY, :CPU, :NETRX, :NETTX, :TIME + column :MEMORY, "Assigned memory", :right, :size=>8 do |d| + OpenNebulaHelper.unit_to_str(d["VM/TEMPLATE/MEMORY"].to_i, {}) + end + + column :CPU, "Number of CPUs", :right, :size=>3 do |d| + d["VM/TEMPLATE/CPU"] + end + + column :NETRX, "Data received from the network", :right, :size=>8 do |d| + OpenNebulaHelper.unit_to_str(d["VM/NET_RX"].to_i, {}) + end + + column :NETTX, "Data sent to the network", :right, :size=>8 do |d| + OpenNebulaHelper.unit_to_str(d["VM/NET_TX"].to_i, {}) + end + + default :VID, :HOSTNAME, :REASON, :STIME, :ETIME, :MEMORY, :CPU, :NETRX, :NETTX end - table + table.show(data) end - def list_vms(data) - format_vm().show(data) - end +public + def list_users(xml_info, options=nil) - def list_users(filters) - a=gen_accounting(filters) + xmldoc = XMLElement.new + xmldoc.initialize_xml(xml_info, 'HISTORY_RECORDS') - a.each do |user, data| + 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 - puts "# User #{user}" + # TODO: username? + puts "# User #{uid} " CLIHelper.scr_restore puts - vms=data[:vms].map do |k, v| - v - end + vm_ids = xmldoc.retrieve_elements("HISTORY/VM[UID=#{uid}]/ID") + vm_ids.uniq! - self.list_vms(vms) + vm_ids.each do |vid| - puts - puts - - end - end - - def gen_accounting(filters) - acct=AcctClient.new(filters) - acct.account() - end - - def gen_json(filters) - begin - require 'json' - rescue LoadError - STDERR.puts "JSON gem is needed to give the result in this format" - exit(-1) - end - - acct=gen_accounting(filters) - acct.to_json - end - - def xml_tag(tag, value) - "<#{tag}>#{value}\n" - end - - def gen_xml(filters) - acct=gen_accounting(filters) - - xml="" - - acct.each do |user, data| - xml<<"\n" - - data[:vms].each do |vmid, vm| - xml<<" \n" - - xml<<" "<\n" - - slice.each do |key, value| - xml<<" "<\n" + if ( options[:split] ) + history_elems.clear end - xml<<" \n" + xmldoc.each("HISTORY[OID=#{vid}]") do |history| + history_elems << history + end + + if ( options[:split] ) + list_history(history_elems) + puts + end end - xml<<"\n" + if ( !options[:split] ) + list_history(history_elems) + puts + end end - - xml end end -@options=Hash.new +options = Hash.new -@options[:format]=:table +options[:format] = :table -opts=OptionParser.new do |opts| +opts = OptionParser.new do |opts| opts.on('-s', '--start TIME', Time, 'Start date and time to take into account') do |ext| - @options[:start]=ext + options[:start]=ext end opts.on("-e", "--end TIME", Time, "End date and time" ) do |ext| - @options[:end]=ext + options[:end]=ext end + # TODO: Allow username opts.on("-u", "--user user", Integer, "User id to make accounting" ) do |ext| - @options[:user]=ext.to_i + options[:user]=ext.to_i end opts.on("-j", "--json", "Output in json format" ) do |ext| - @options[:format]=:json + options[:format]=:json end opts.on("-x", "--xml", "Output in xml format" ) do |ext| - @options[:format]=:xml + options[:format]=:xml + end + + opts.on("--split", + "Split the output in a table for each VM" ) do |ext| + options[:split]=ext end opts.on() @@ -215,27 +212,68 @@ rescue OptionParser::ParseError => e end -acct_helper=AcctHelper.new +client = OpenNebula::Client.new + +acct_helper = AcctHelper.new(client) + +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] +filter_flag = options[:user].to_i if options[:user] -filters=Hash.new +ret = client.call("vmpool.accounting", + filter_flag, + time_start, + time_end) -filters[:start]=@options[:start].to_i if @options[:start] -filters[:end]=@options[:end].to_i if @options[:end] -filters[:user]=@options[:user].to_i if @options[:user] - - -case @options[:format] -when :table - acct_helper.list_users(filters) -when :json - puts acct_helper.gen_json(filters) -when :xml - puts acct_helper.gen_xml(filters) +if OpenNebula.is_error?(ret) + puts ret.message + exit -1 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(ret, options) + +when :xml + puts ret + +when :json + xmldoc = XMLElement.new + xmldoc.initialize_xml(ret, 'HISTORY_RECORDS') + puts xmldoc.to_hash.to_json + +end