From 719b509d05fb59b26d29477a86e373a70080da5e Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Tue, 30 Aug 2011 13:02:30 +0200 Subject: [PATCH] feature #754: Improve get_usage method --- src/authm_mad/remotes/quota/one_usage.rb | 85 +++++++++++++----------- src/authm_mad/remotes/quota/quota.rb | 4 +- src/oca/ruby/OpenNebula/XMLUtils.rb | 26 ++++++-- 3 files changed, 69 insertions(+), 46 deletions(-) diff --git a/src/authm_mad/remotes/quota/one_usage.rb b/src/authm_mad/remotes/quota/one_usage.rb index 8a52a84121..0d83e684d2 100644 --- a/src/authm_mad/remotes/quota/one_usage.rb +++ b/src/authm_mad/remotes/quota/one_usage.rb @@ -23,55 +23,63 @@ class OneUsage VM_USAGE = { :cpu => { :proc_info => lambda {|template| template['CPU']}, - :proc_total => lambda {|resource| resource['TEMPLATE']['CPU']} + :xpath => 'TEMPLATE/CPU' }, :memory => { :proc_info => lambda {|template| template['MEMORY']}, - :proc_total => lambda {|resource| resource['TEMPLATE']['MEMORY']} + :xpath => 'TEMPLATE/MEMORY' }, :num_vms => { :proc_info => lambda {|template| 1 }, - :proc_total => lambda {|resource| 1 } + :xpath => 'ID', + :count => true } } IMAGE_USAGE = { :storage => { :proc_info => lambda {|template| File.size(template['PATH']) }, - :proc_total => lambda {|resource| File.size(resource['TEMPLATE']['SOURCE']) } + :proc_total => 'TEMPLATE/SIZE' } } + RESOURCES = ["VM", "IMAGE"] + def initialize() @client = OpenNebula::Client.new - @usage = Hash.new - - keys = VM_USAGE.keys + IMAGE_USAGE.keys - keys.each { |key| - @usage[key] = 0 - } - end - - def total(resource, user_id) - pool_array = pool_to_array(resource, user_id) - + def total(user_id, resource=nil, force=false) usage = Hash.new - pool_array.each { |elem| - OneUsage.const_get("#{resource}_USAGE".to_sym).each { |key, params| - usage[key] ||= 0 - usage[key] += params[:proc_total].call(elem).to_i + + if force + resources = [resource] if RESOURCES.include?(resource) + + resources.each{ |res| + pool = get_pool(res, user_id) + + base_xpath = "/#{res}_POOL/#{resource}" + OneUsage.const_get("#{res}_USAGE".to_sym).each { |key, params| + usage[key] ||= 0 + pool.each_xpath("#{base_xpath}/#{params[:xpath]}") { |elem| + usage[key] += params[:count] ? 1 : elem.to_i + } + } + + @usage[:user_id] ||= Hash.new + @usage[:user_id].merge!(usage) } - } + else + usage = get_usage(user_id) + end usage end # Retrieve the useful information of the template for the specified # kind of resource - def get_info(resource, xml_template) + def get_resources(resource, xml_template) template = OpenNebula::XMLElement.new template.initialize_xml(xml_template, 'TEMPLATE') @@ -86,28 +94,31 @@ class OneUsage private + def get_usage(user_id) + usage = @usage[:user_id] + + unless usage + usage = Hash.new + + keys = VM_USAGE.keys + IMAGE_USAGE.keys + keys.each { |key| + usage[key] = 0 + } + + @usage[:user_id] = usage + end + + usage + end + # Returns a an Array than contains the elements of the resource Pool - def pool_to_array(resource, user_id) + def get_pool(resource, user_id) pool = case resource when "VM" then OpenNebula::VirtualMachinePool.new(@client, user_id) when "IMAGE" then OpenNebula::ImagePool.new(@client, user_id) end rc = pool.info - - phash = pool.to_hash - - if phash["#{resource}_POOL"] && - phash["#{resource}_POOL"]["#{resource}"] - if phash["#{resource}_POOL"]["#{resource}"].instance_of?(Array) - parray = phash["#{resource}_POOL"]["#{resource}"] - else - parray = [phash["#{resource}_POOL"]["#{resource}"]] - end - else - parray = Array.new - end - - return parray + return pool end end diff --git a/src/authm_mad/remotes/quota/quota.rb b/src/authm_mad/remotes/quota/quota.rb index 69977c60b4..e46a7eb7f9 100644 --- a/src/authm_mad/remotes/quota/quota.rb +++ b/src/authm_mad/remotes/quota/quota.rb @@ -124,14 +124,14 @@ class Quota end def check_quotas(user_id, obj, template) - info = @one_usage.get_info(obj, template) + info = @one_usage.get_resources(obj, template) total = @one_usage.total(obj, user_id) quota = get(user_id) msg = "" info.each { |quota_name, quota_requested| spent = total[quota_name].to_i + quota_requested.to_i - if spent > quota[quota_name].to_i + if quota[quota_name] && spent > quota[quota_name].to_i msg << " #{quota_name.to_s.upcase} quota exceeded " msg << "(Quota: #{quota[quota_name].to_i}, " msg << "Used: #{spent.to_i}, " diff --git a/src/oca/ruby/OpenNebula/XMLUtils.rb b/src/oca/ruby/OpenNebula/XMLUtils.rb index 912c2e4561..c71dece114 100644 --- a/src/oca/ruby/OpenNebula/XMLUtils.rb +++ b/src/oca/ruby/OpenNebula/XMLUtils.rb @@ -101,11 +101,11 @@ module OpenNebula element.text end end - - # Gets an array of text from elemenets extracted + + # Gets an array of text from elemenets extracted # using the XPATH expression passed as filter def retrieve_elements(filter) - elements_array = Array.new + elements_array = Array.new if NOKOGIRI @xml.xpath(filter.to_s).each { |pelem| @@ -116,13 +116,13 @@ module OpenNebula elements_array << pelem.text if pelem.text } end - - if elements_array.size == 0 + + if elements_array.size == 0 return nil else return elements_array end - + end # Gets an attribute from an elemenT @@ -164,6 +164,18 @@ module OpenNebula end end + def each_xpath(xpath_str,&block) + if NOKOGIRI + @xml.xpath(xpath_str).each { |pelem| + block.call pelem.text + } + else + @xml.elements.each(xpath_str) { |pelem| + block.call pelem.text + } + end + end + def name @xml.name end @@ -285,7 +297,7 @@ module OpenNebula hash end - + private def attr_to_str(attr) attr.gsub!('"',"\\\"")