diff --git a/include/Host.h b/include/Host.h index b4ba3d05f7..def33e677e 100644 --- a/include/Host.h +++ b/include/Host.h @@ -123,6 +123,14 @@ public: **/ int update_info(string &parse_str); + /** + * Inserts the last monitoring, and deletes old monitoring entries. + * + * @param db pointer to the db + * @return 0 on success + */ + int update_monitoring(SqlDB * db); + /** * Retrives host state * @return HostState code number @@ -377,6 +385,12 @@ private: static const char * table; + static const char * monit_db_names; + + static const char * monit_db_bootstrap; + + static const char * monit_table; + /** * Execute an INSERT or REPLACE Sql query. * @param db The SQL DB @@ -392,9 +406,15 @@ private: */ static int bootstrap(SqlDB * db) { - ostringstream oss_host(Host::db_bootstrap); + int rc; - return db->exec(oss_host); + ostringstream oss_host(Host::db_bootstrap); + ostringstream oss_monit(Host::monit_db_bootstrap); + + rc = db->exec(oss_host); + rc += db->exec(oss_monit); + + return rc; }; /** diff --git a/include/HostPool.h b/include/HostPool.h index 0de6e8f8e4..8900b403cc 100644 --- a/include/HostPool.h +++ b/include/HostPool.h @@ -38,7 +38,8 @@ public: HostPool(SqlDB * db, vector hook_mads, const string& hook_location, - const string& remotes_location); + const string& remotes_location, + time_t expire_time); ~HostPool(){}; @@ -196,6 +197,60 @@ public: return PoolSQL::search(oids, Host::table, where); }; + /** + * Dumps the host monitoring information entries in XML format. A filter + * can be also added to the query. + * + * @param oss the output stream to dump the pool contents + * @param where filter for the objects, defaults to all + * + * @return 0 on success + */ + int dump_monitoring(ostringstream& oss, + const string& where); + + /** + * Dumps the HOST monitoring information for a single HOST + * + * @param oss the output stream to dump the pool contents + * @param hostid id of the target HOST + * + * @return 0 on success + */ + int dump_monitoring(ostringstream& oss, + int hostid) + { + ostringstream filter; + + filter << "oid = " << hostid; + + return dump_monitoring(oss, filter.str()); + } + + /** + * Inserts the last monitoring, and deletes old monitoring entries for this + * host + * + * @param host pointer to the host object + * @return 0 on success + */ + int update_monitoring(Host * host) + { + if ( _monitor_expiration <= 0 ) + { + return 0; + } + + return host->update_monitoring(db); + }; + + /** + * Deletes the expired monitoring entries for all hosts + * + * @return 0 on success + */ + int clean_expired_monitoring(); + private: /** @@ -216,6 +271,18 @@ private: * @return 0 on success */ int discover_cb(void * _map, int num, char **values, char **names); + + /** + * Deletes all monitoring entries for all hosts + * + * @return 0 on success + */ + int clean_all_monitoring(); + + /** + * Size, in seconds, of the historical monitoring information + */ + static time_t _monitor_expiration; }; #endif /*HOST_POOL_H_*/ diff --git a/include/RequestManagerHost.h b/include/RequestManagerHost.h index 109542fc91..65f538cf0c 100644 --- a/include/RequestManagerHost.h +++ b/include/RequestManagerHost.h @@ -68,6 +68,26 @@ public: RequestAttributes& att); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class HostMonitoring : public RequestManagerHost +{ +public: + HostMonitoring(): + RequestManagerHost("HostMonitoring", + "Returns the host monitoring records", + "A:si") + { + auth_op = AuthRequest::USE; + }; + + ~HostMonitoring(){}; + + void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att); +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerPoolInfoFilter.h b/include/RequestManagerPoolInfoFilter.h index 08d3459f2c..50bf75b678 100644 --- a/include/RequestManagerPoolInfoFilter.h +++ b/include/RequestManagerPoolInfoFilter.h @@ -132,6 +132,31 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +class VirtualMachinePoolMonitoring : public RequestManagerPoolInfoFilter +{ +public: + + VirtualMachinePoolMonitoring(): + RequestManagerPoolInfoFilter("VirtualMachinePoolMonitoring", + "Returns the virtual machine monitoring records", + "A:si") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vmpool(); + auth_object = PoolObjectSQL::VM; + }; + + ~VirtualMachinePoolMonitoring(){}; + + /* -------------------------------------------------------------------- */ + + void request_execute( + xmlrpc_c::paramList const& paramList, RequestAttributes& att); +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + class TemplatePoolInfo : public RequestManagerPoolInfoFilter { public: @@ -213,6 +238,31 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +class HostPoolMonitoring : public RequestManagerPoolInfoFilter +{ +public: + + HostPoolMonitoring(): + RequestManagerPoolInfoFilter("HostPoolMonitoring", + "Returns the host monitoring records", + "A:s") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_hpool(); + auth_object = PoolObjectSQL::HOST; + }; + + ~HostPoolMonitoring(){}; + + /* -------------------------------------------------------------------- */ + + void request_execute( + xmlrpc_c::paramList const& paramList, RequestAttributes& att); +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + class GroupPoolInfo: public RequestManagerPoolInfoFilter { public: diff --git a/include/RequestManagerVirtualMachine.h b/include/RequestManagerVirtualMachine.h index 2955bbd79b..00326f47fa 100644 --- a/include/RequestManagerVirtualMachine.h +++ b/include/RequestManagerVirtualMachine.h @@ -143,6 +143,29 @@ public: RequestAttributes& att); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VirtualMachineMonitoring : public RequestManagerVirtualMachine +{ +public: + + VirtualMachineMonitoring(): + RequestManagerVirtualMachine("VirtualMachineMonitoring", + "Returns the virtual machine monitoring records", + "A:si") + { + auth_op = AuthRequest::USE; + }; + + ~VirtualMachineMonitoring(){}; + + /* -------------------------------------------------------------------- */ + + void request_execute( + xmlrpc_c::paramList const& paramList, RequestAttributes& att); +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 494b2a342a..12739eefb7 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -838,9 +838,11 @@ private: int rc; ostringstream oss_vm(VirtualMachine::db_bootstrap); + ostringstream oss_monit(VirtualMachine::monit_db_bootstrap); ostringstream oss_hist(History::db_bootstrap); rc = db->exec(oss_vm); + rc += db->exec(oss_monit); rc += db->exec(oss_hist); return rc; @@ -895,6 +897,14 @@ private: return -1; }; + /** + * Inserts the last monitoring, and deletes old monitoring entries. + * + * @param db pointer to the db + * @return 0 on success + */ + int update_monitoring(SqlDB * db); + // ------------------------------------------------------------------------- // Attribute Parser // ------------------------------------------------------------------------- @@ -971,6 +981,12 @@ protected: static const char * db_bootstrap; + static const char * monit_table; + + static const char * monit_db_names; + + static const char * monit_db_bootstrap; + /** * Reads the Virtual Machine (identified with its OID) from the database. * @param db pointer to the db diff --git a/include/VirtualMachinePool.h b/include/VirtualMachinePool.h index 664da7fdb6..71f3843ee8 100644 --- a/include/VirtualMachinePool.h +++ b/include/VirtualMachinePool.h @@ -32,11 +32,12 @@ class VirtualMachinePool : public PoolSQL { public: - VirtualMachinePool(SqlDB * db, - vector hook_mads, - const string& hook_location, - const string& remotes_location, - vector& restricted_attrs); + VirtualMachinePool(SqlDB * db, + vector hook_mads, + const string& hook_location, + const string& remotes_location, + vector& restricted_attrs, + time_t expire_time); ~VirtualMachinePool(){}; @@ -122,6 +123,38 @@ public: return vm->update_previous_history(db); } + /** + * Inserts the last monitoring, and deletes old monitoring entries for this + * VM + * + * @param vm pointer to the virtual machine object + * @return 0 on success + */ + int update_monitoring( + VirtualMachine * vm) + { + if ( _monitor_expiration <= 0 ) + { + return 0; + } + + return vm->update_monitoring(db); + }; + + /** + * Deletes the expired monitoring entries for all VMs + * + * @return 0 on success + */ + int clean_expired_monitoring(); + + /** + * Deletes all monitoring entries for all VMs + * + * @return 0 on success + */ + int clean_all_monitoring(); + /** * Bootstraps the database table(s) associated to the VirtualMachine pool * @return 0 on success @@ -157,6 +190,37 @@ public: const string& where, int time_start, int time_end); + + /** + * Dumps the VM monitoring information entries in XML format. A filter + * can be also added to the query. + * + * @param oss the output stream to dump the pool contents + * @param where filter for the objects, defaults to all + * + * @return 0 on success + */ + int dump_monitoring(ostringstream& oss, + const string& where); + + /** + * Dumps the VM monitoring information for a single VM + * + * @param oss the output stream to dump the pool contents + * @param vmid id of the target VM + * + * @return 0 on success + */ + int dump_monitoring(ostringstream& oss, + int vmid) + { + ostringstream filter; + + filter << "oid = " << vmid; + + return dump_monitoring(oss, filter.str()); + } + private: /** * Factory method to produce VM objects @@ -166,6 +230,11 @@ private: { return new VirtualMachine(-1,-1,-1,"","",0); }; + + /** + * Size, in seconds, of the historical monitoring information + */ + static time_t _monitor_expiration; }; #endif /*VIRTUAL_MACHINE_POOL_H_*/ diff --git a/install.sh b/install.sh index 504353be95..8d37222cff 100755 --- a/install.sh +++ b/install.sh @@ -203,8 +203,7 @@ LIB_DIRS="$LIB_LOCATION/ruby \ $LIB_LOCATION/mads \ $LIB_LOCATION/sh \ $LIB_LOCATION/ruby/cli \ - $LIB_LOCATION/ruby/cli/one_helper \ - $LIB_LOCATION/ruby/acct" + $LIB_LOCATION/ruby/cli/one_helper" VAR_DIRS="$VAR_LOCATION/remotes \ $VAR_LOCATION/remotes/im \ @@ -423,8 +422,6 @@ INSTALL_FILES=( MAN_FILES:$MAN_LOCATION CLI_LIB_FILES:$LIB_LOCATION/ruby/cli ONE_CLI_LIB_FILES:$LIB_LOCATION/ruby/cli/one_helper - ACCT_LIB_FILES:$LIB_LOCATION/ruby/acct - ACCT_BIN_FILES:$BIN_LOCATION ) INSTALL_CLIENT_FILES=( @@ -553,7 +550,6 @@ INSTALL_ETC_FILES=( OCCI_ETC_FILES:$ETC_LOCATION OCCI_ETC_TEMPLATE_FILES:$ETC_LOCATION/occi_templates CLI_CONF_FILES:$ETC_LOCATION/cli - ACCT_ETC_FILES:$ETC_LOCATION ) #------------------------------------------------------------------------------- @@ -1471,21 +1467,6 @@ SELF_SERVICE_PUBLIC_LOCALE_FR_FR="src/cloud/occi/lib/ui/locale/languages/fr_FR.j SELF_SERVICE_PUBLIC_LOCALE_FR_CA="src/cloud/occi/lib/ui/locale/languages/fr_CA.js \ src/cloud/occi/lib/ui/locale/languages/fr_datatable.txt" -#----------------------------------------------------------------------------- -# ACCT files -#----------------------------------------------------------------------------- - -ACCT_BIN_FILES="src/acct/oneacctd" - -ACCT_LIB_FILES="src/acct/monitoring.rb \ - src/acct/accounting.rb \ - src/acct/acctd.rb \ - src/acct/oneacct.rb \ - src/acct/watch_helper.rb \ - src/acct/watch_client.rb" - -ACCT_ETC_FILES="src/acct/etc/acctd.conf" - #----------------------------------------------------------------------------- # MAN files #----------------------------------------------------------------------------- diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 2f4c5d807a..2edc71c8f4 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -11,10 +11,14 @@ # # HOST_MONITORING_INTERVAL: Time in seconds between host monitorization. # HOST_PER_INTERVAL: Number of hosts monitored in each interval. +# HOST_MONITORING_EXPIRATION_TIME: Time, in seconds, to expire monitoring +# information. Use 0 to disable HOST monitoring recording. # # VM_POLLING_INTERVAL: Time in seconds between virtual machine monitorization. -# (use 0 to disable VM monitoring). +# Use 0 to disable VM monitoring. # VM_PER_INTERVAL: Number of VMs monitored in each interval. +# VM_MONITORING_EXPIRATION_TIME: Time, in seconds, to expire monitoring +# information. Use 0 to disable VM monitoring recording. # # SCRIPTS_REMOTE_DIR: Remote path to store the monitoring and VM management # scripts. @@ -38,12 +42,13 @@ #MANAGER_TIMER = 30 -HOST_MONITORING_INTERVAL = 600 -#HOST_PER_INTERVAL = 15 - -VM_POLLING_INTERVAL = 600 -#VM_PER_INTERVAL = 5 +HOST_MONITORING_INTERVAL = 600 +#HOST_PER_INTERVAL = 15 +#HOST_MONITORING_EXPIRATION_TIME = 86400 +VM_POLLING_INTERVAL = 600 +#VM_PER_INTERVAL = 5 +#VM_MONITORING_EXPIRATION_TIME = 86400 SCRIPTS_REMOTE_DIR=/var/tmp/one diff --git a/share/install_gems/install_gems b/share/install_gems/install_gems index 57671cced8..6ddea676d9 100755 --- a/share/install_gems/install_gems +++ b/share/install_gems/install_gems @@ -2,7 +2,7 @@ require 'pp' -DEFAULT=%w{optional sunstone quota cloud ozones_server acct auth_ldap} +DEFAULT=%w{optional sunstone quota cloud ozones_server auth_ldap} if defined?(RUBY_VERSION) && RUBY_VERSION>="1.8.7" SQLITE='sqlite3' @@ -22,9 +22,6 @@ GROUPS={ ], :ozones_server_sqlite => %w{json data_mapper dm-sqlite-adapter}< %w{json data_mapper dm-mysql-adapter mysql}, - :acct => ['sequel', SQLITE, 'mysql'], - :acct_sqlite => ['sequel', SQLITE], - :acct_mysql => ['sequel', 'mysql'], :auth_ldap => 'net-ldap' } diff --git a/src/acct/accounting.rb b/src/acct/accounting.rb deleted file mode 100644 index b30be641d6..0000000000 --- a/src/acct/accounting.rb +++ /dev/null @@ -1,131 +0,0 @@ -# -------------------------------------------------------------------------- # -# 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. # -#--------------------------------------------------------------------------- # - -module OneWatch - require 'watch_helper' - - class Accounting - def initialize(client) - @client = client - @active_vms = Array.new - end - - def insert(hash) - @ptimestamp = @timestamp - @timestamp = generate_timestamp - - new_active_vms = Array.new - last_active_vm = @active_vms.empty? ? -1 : @active_vms.last - - if (vmpool_hash = hash['VM_POOL']) && !vmpool_hash.empty? - [vmpool_hash['VM']].flatten.each { |vm| - vm_id = vm['ID'].to_i - - if vm['STATE'] == 3 - new_active_vms << vm_id - end - - # ACTIVE VMs (including those that are stopped in this step) - # in the last step and NEW VMs - if @active_vms.include?(vm_id) || vm['STATE'].to_i == 3 - insert_vm(vm) - @active_vms.delete(vm_id) - else - # DONE/STOP VMs and non ACTIVE in the last step - next - end - } - end - - # DONE VMs that were ACTIVE in the last step - @active_vms.each { |id| - vm = OpenNebula::VirtualMachine.new_with_id(id, @client) - vm.info - - vm_hash = vm.to_hash - insert_vm(vm_hash) - } - - # DONE VMs that did not exist in the last step - vmpool = OpenNebula::VirtualMachinePool.new(@client) - vmpool.info(-2, last_active_vm, -1, 6) - done_hash = vmpool.to_hash - if (done_vm_hash = done_hash['VM_POOL']) && !done_vm_hash.empty? - [done_vm_hash['VM']].flatten.each { |vm| - insert_vm(vm) - } - end - - # Upate the active VMs - @active_vms = new_active_vms.sort - - WatchHelper::Vm.flush - end - - private - - def generate_timestamp - Time.now.to_i - end - - def insert_register(vm, register, history) - if register && register.seq == history['SEQ'].to_i - register.update_from_history(history) - else - vm.add_register_from_resource(history) - end - end - - def update_history(vm, vm_sql) - last_register = vm_sql.registers.last - seq = last_register ? last_register.seq : 0 - - hr = vm['HISTORY_RECORDS'] - if hr and !hr.empty? - if hr['HISTORY']['SEQ'] == seq - # The VM has not moved from the Host - insert_register(vm_sql, last_register, hr['HISTORY']) - return - else - unless hr['HISTORY'].instance_of?(Array) - # Get the full HISTORY - vm = OpenNebula::VirtualMachine.new_with_id(vm['ID'], @client) - vm.info - - vm_hash = vm.to_hash['VM'] - hr = vm_hash['HISTORY_RECORDS'] - end - - # Insert a new entry for each new history record - [hr['HISTORY']].flatten.each { |history| - if history['SEQ'].to_i < seq - next - else - insert_register(vm_sql, last_register, history) - end - } - end - end - end - - def insert_vm(vm) - vm_sql = WatchHelper::Vm.info(vm) - vm_sql.add_delta_from_resource(vm, @timestamp) - update_history(vm, vm_sql) - end - end -end - diff --git a/src/acct/acctd.rb b/src/acct/acctd.rb deleted file mode 100755 index dd5ee37215..0000000000 --- a/src/acct/acctd.rb +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env ruby - -# -------------------------------------------------------------------------- # -# 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"] - -if !ONE_LOCATION - RUBY_LIB_LOCATION="/usr/lib/one/ruby" - ACCTD_CONF="/etc/one/acctd.conf" -else - RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" - ACCTD_CONF=ONE_LOCATION+"/etc/acctd.conf" -end - -$: << RUBY_LIB_LOCATION -$: << RUBY_LIB_LOCATION+"/acct" - -require 'yaml' - -require 'OpenNebula' -require 'watch_helper' - -class Watcher - def initialize - @monitors = Array.new - end - - def add(resource, steps, pools) - @monitors << { :resource => resource, - :steps => steps, - :pools => [pools].flatten - } - end - - def log(msg) - STDERR.puts "#{Time.now} #{msg}" - end - - def update(step) - # clear pool cache - @pool_cache = Hash.new - - @monitors.each do |monitor| - if monitor[:steps] > 0 and step % monitor[:steps] == 0 - monitor[:pools].each do |pool| - resource = monitor[:resource] - - log "#{resource.class}" - - if pool_hash = @pool_cache[pool] - else - rc = pool.info - if OpenNebula.is_error?(rc) - log "Error: " + rc.message - log "Shutting down" - exit 1 - end - - pool_hash = pool.to_hash - @pool_cache[pool] = pool_hash - end - - resource.insert(pool_hash) - end - end - end - end -end - -watcher = Watcher.new - -# OpenNebula variables -one_client = OpenNebula::Client.new -vm_pool = nil # common for accounting and monitoring -host_pool = nil - -# Initialize VM monitoring -if vm_steps = WatchHelper::get_config(:VM_MONITORING, :STEPS) and - vm_steps > 0 - - require 'monitoring' - vm_monitoring = OneWatch::VmMonitoring.new - vm_pool ||= OpenNebula::VirtualMachinePool.new(one_client, -2) - watcher.add(vm_monitoring, vm_steps, vm_pool) -end - -# Initialize Host monitoring -if host_steps = WatchHelper::get_config(:HOST_MONITORING, :STEPS) and - host_steps > 0 - - require 'monitoring' - host_monitoring = OneWatch::HostMonitoring.new - host_pool ||= OpenNebula::HostPool.new(one_client) - watcher.add(host_monitoring, host_steps, host_pool) -end - -# Initialize accounting -if accounting_steps = WatchHelper::get_config(:ACCOUNTING, :STEPS) and - accounting_steps > 0 - - require 'accounting' - accounting = OneWatch::Accounting.new(one_client) - vm_pool ||= OpenNebula::VirtualMachinePool.new(one_client, -2) - watcher.add(accounting, accounting_steps, vm_pool) -end - -step_time = WatchHelper::get_config(:STEP) - -step = 0 -loop do - start_time = Time.now - expected_end_time = start_time + step_time - - step += 1 - watcher.update(step) - - end_time = Time.now - sleep_time = start_time + step_time - end_time - - if sleep_time >= 1 - sleep sleep_time - else - sleep 1 - end -end diff --git a/src/acct/etc/acctd.conf b/src/acct/etc/acctd.conf deleted file mode 100644 index e97698b8ca..0000000000 --- a/src/acct/etc/acctd.conf +++ /dev/null @@ -1,55 +0,0 @@ -# -------------------------------------------------------------------------- # -# 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. # -#--------------------------------------------------------------------------- # - -# Database URI -#:DB: sqlite:///var/one/oneacct.db - -# Duration of each daemon loop in seconds -:STEP: 300 # 5 minutes - -#------------------------------------------------------------------------------- -# VM Monitoring -#------------------------------------------------------------------------------- - -:VM_MONITORING: - - # Number of daemon loops until a VM monitoring watch - :STEPS: 1 - - # Number of VM records to preserve - :WINDOW_SIZE: 5 - -#------------------------------------------------------------------------------- -# HOST Monitoring -#------------------------------------------------------------------------------- - -:HOST_MONITORING: - - # Number of daemon loops until a Hosts monitoring watch - :STEPS: 3 - - # Number of HOST records to preserve - :WINDOW_SIZE: 5 - -#------------------------------------------------------------------------------- -# Accounting -#------------------------------------------------------------------------------- - -:ACCOUNTING: - - # Number of daemon loops until an accounting watch - :STEPS: 10 - diff --git a/src/acct/examples/acct_client.rb b/src/acct/examples/acct_client.rb deleted file mode 100644 index a85fb173be..0000000000 --- a/src/acct/examples/acct_client.rb +++ /dev/null @@ -1,91 +0,0 @@ -# -------------------------------------------------------------------------- # -# 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 'watch_helper' - -class AcctClient - def prolog_time(t1, t2, opts={}) - times(t1, t2, opts) { |reg| - calculate_time(t1, t2, reg.pstime, reg.petime) - } - end - - def running_time(t1, t2, opts={}) - # TBD Suspened VMs - - times(t1, t2, opts) { |reg| - calculate_time(t1, t2, reg.rstime, reg.retime) - } - end - - def epilog_time(t1, t2, opts={}) - times(t1, t2, opts) { |reg| - calculate_time(t1, t2, reg.estime, reg.eetime) - } - end - - private - - def times(t1, t2, opts={}, &block) - time = 0 - - vms = filter_vms(opts) - - if vms && !vms.empty? - vms.each { |vm| - vm.registers.each { |reg| - time += block.call(reg) - } - } - end - - time - end - - def calculate_time(t1, t2, stime, etime) - if etime < t1 && etime != 0 - return 0 - elsif stime < t2 && stime != 0 - if etime < t2 && etime != 0 - e = etime - else - e = t2 - end - - s = stime > t1 ? stime : t1 - return e - s - end - - return 0 - end - - def filter_vms(opts={}) - opts ||= {} - - if opts[:uid] - vms = WatchHelper::Vm.filter(:uid=>opts[:uid]) - elsif opts[:gid] - vms = WatchHelper::Vm.filter(:gid=>opts[:gid]) - elsif opts[:hid] - vms = WatchHelper::Vm.filter( - :registers=>WatchHelper::Register.filter(:hid => opts[:hid])) - elsif opts[:vmid] - vms = WatchHelper::Vm.filter(:id=>opts[:vmid]) - else - vms = WatchHelper::Vm - end - end -end diff --git a/src/acct/monitoring.rb b/src/acct/monitoring.rb deleted file mode 100644 index e0260b8e32..0000000000 --- a/src/acct/monitoring.rb +++ /dev/null @@ -1,78 +0,0 @@ -# -------------------------------------------------------------------------- # -# 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. # -#--------------------------------------------------------------------------- # - -module OneWatch - require 'watch_helper' - - class Monitoring - def insert(hash) - timestamp = generate_timestamp - - if (pool_hash = hash["#{resource}_POOL"]) && !pool_hash.empty? - [pool_hash["#{resource}"]].flatten.each { |elem| - sql = sql_elem(elem) - sql.add_sample_from_resource(elem, timestamp) - } - end - - sql_elem.flush - end - - private - - def generate_timestamp - Time.now.to_i - end - end - - class VmMonitoring < Monitoring - def resource - 'VM' - end - - def sql_elem(elem=nil) - if elem - WatchHelper::Vm.info(elem) - else - WatchHelper::Vm - end - end - - def generate_timestamp - ts = super - WatchHelper::VmTimestamp.find_or_create(:id=>ts) - end - end - - class HostMonitoring < Monitoring - def resource - 'HOST' - end - - def sql_elem(elem=nil) - if elem - WatchHelper::Host.info(elem) - else - WatchHelper::Host - end - end - - def generate_timestamp - ts = super - WatchHelper::HostTimestamp.find_or_create(:id=>ts) - end - end -end diff --git a/src/acct/oneacct.rb b/src/acct/oneacct.rb deleted file mode 100644 index 013dccd9ed..0000000000 --- a/src/acct/oneacct.rb +++ /dev/null @@ -1,183 +0,0 @@ -# -------------------------------------------------------------------------- -# 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 -# -# -------------------------------------------------------------------------- - - - -require 'acct/watch_helper' - -class AcctClient - def initialize(filters={}) - @filters=filters - @deltas=[] - @users={} - end - - def account(time_start=nil, time_end=nil, user_id=nil) - @filters[:start]=time_start if time_start - @filters[:end]=time_end if time_end - @filters[:user]=user_id if user_id - - get_users_consumption - - @users - end - -private - - def get_users_consumption - # Get all the deltas that match the filters - @deltas=calculate_deltas.map {|q| q.values } - - @users=slices_by_user - - user_slices_and_deltas_to_vms - end - - def slices_by_user - # Get all VM slices that match the filters - query=get_vm_slices(@filters) - - # This hash will hold the users with the resources consumed - users={} - - query.each do |reg| - vm=reg.vm - uid=vm.uid.to_i - - # Create a new user register if it still does not exist - user=users[uid]||={ - :vm_slices => [], - } - - user[:vm_slices] << reg.values - end - - users - end - - def user_slices_and_deltas_to_vms - @users.each do |user, data| - # Get the VM ids array for this user - vms=data[:vm_slices].map {|vm| vm[:id] }.sort.uniq - - data[:vms]={} - - vms.each do |vm| - # Get the slices array for this VM - slices=data[:vm_slices].select {|slice| slice[:id]==vm } - - data[:vms][vm]={ - :slices => [], - :time => 0, - } - - # Get the deltas sum for this VM - vm_delta=@deltas.find {|d| d[:vm_id]==vm } - - data[:vms][vm][:network]=vm_delta - data[:vms][vm][:vmid]=vm - - # Calculate the time consumed by the VM - slices.each do |slice| - data[:vms][vm][:slices] << slice - - time=calculate_time(slice, - @filters[:start], @filters[:end]) - data[:vms][vm][:time]+=time - end - end - - # Delete redundant slices data - data.delete(:vm_slices) - end - end - - def get_vm_slices(filters={}) - vms=WatchHelper::Register - - query=vms.join(:vms, :id => :vm_id) - query=query.filter({:vms__uid => filters[:user]}) if filters[:user] - query=query.filter( - {:retime => 0} | (:retime > filters[:start])) if filters[:start] - query=query.filter(:rstime <= filters[:end]) if filters[:end] - - query - end - - def get_deltas(filters={}) - if filters[:data] - query=filters[:data] - else - query=WatchHelper::VmDelta - end - - query=query.filter( :ptimestamp >= filters[:start] ) if filters[:start] - query=query.filter( :ptimestamp <= filters[:end] ) if filters[:end] - query=query.filter( { :vm_id => filters[:vmid] } ) if filters[:vmid] - - query - end - - def calculate_deltas - query=WatchHelper::VmDelta.select( - :ptimestamp, :vm_id, - 'sum(net_tx) AS net_tx'.lit, 'sum(net_rx) AS net_rx'.lit) - - query=query.group(:vm_id) - - new_filters=@filters.merge(:data => query) - - get_deltas(new_filters) - end - - def calculate_time(slice, period_start, period_end) - ts=slice[:rstime].to_i - te=slice[:retime].to_i - - pstart=period_start.to_i - pend=period_end.to_i - - pend=Time.now.to_i if pend==0 - - ts=pstart if tspend or te==0 - te=pend - end - - te-ts - end -end - -if $0 == __FILE__ - - require 'json' - - acct=AcctClient.new( - :start => 1319476322, - :end => 1319637455 - ) - - a=acct.account() - - puts JSON.pretty_generate(a) - -end - diff --git a/src/acct/oneacctd b/src/acct/oneacctd deleted file mode 100755 index b527f4b970..0000000000 --- a/src/acct/oneacctd +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/bash - -# -------------------------------------------------------------------------- # -# 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. # -#--------------------------------------------------------------------------- # - -if [ -z "$ONE_LOCATION" ]; then - ONE_PID=/var/run/one/oned.pid - LOCK_FILE=/var/lock/one/one - ACCTD_CMD=/usr/lib/one/ruby/acct/acctd.rb - ACCTD_LOG=/var/log/one/oneacctd.log - ACCTD_PID_FILE=/var/run/one/oneacctd.pid -else - ONE_PID=$ONE_LOCATION/var/oned.pid - LOCK_FILE=$ONE_LOCATION/var/.lock - ACCTD_CMD=$ONE_LOCATION/lib/ruby/acct/acctd.rb - ACCTD_LOG=$ONE_LOCATION/var/oneacctd.log - ACCTD_PID_FILE=$ONE_LOCATION/var/oneacctd.pid -fi - -function oned_running { - ONEPID=`cat $ONE_PID 2> /dev/null` - ps $ONEPID > /dev/null 2>&1 - if [ ! -f "$LOCK_FILE" -o ! -f "$ONE_PID" -o $? -ne 0 ]; then - echo oned not running - exit 1 - fi -} - -function acctd_running { - ACCTD_PID=`cat $ACCTD_PID_FILE 2>/dev/null` - ps "$ACCTD_PID" &> /dev/null -} - -COMMAND=$1 - -case $COMMAND in -start) - # check if OpenNebula running - oned_running - - # check if acct already running - acctd_running - if [ "$?" = "0" ]; then - echo "oneacctd already running." - exit 1 - fi - - # acctd not running, safe to start - $ACCTD_CMD &> $ACCTD_LOG & - - LASTRC=$? - LASTPID=$! - - if [ $LASTRC -ne 0 ]; then - echo "Error executing oneacctd." - echo "Check $ACCTD_LOG for more information" - exit 1 - else - echo $LASTPID > $ACCTD_PID_FILE - fi - - sleep 2 - ps $LASTPID > /dev/null 2>&1 - - if [ $? -ne 0 ]; then - echo "Error executing oneacctd." - echo "Check $ACCTD_LOG for more information" - exit 1 - fi - - echo "oneacctd started" - ;; -stop) - # check if running - acctd_running - if [ "$?" != "0" ]; then - echo "oneacctd not running." - exit 1 - fi - - # acctd running, safe to stop - ACCTD_PID=`cat $ACCTD_PID_FILE 2>/dev/null` - kill $ACCTD_PID &> /dev/null - rm -f $ACCTD_PID_FILE &> /dev/null - - echo "oneacctd stop" - ;; -*) - echo "Usage: oneacctd {start|stop}" >&2 - exit 3 - ;; -esac diff --git a/src/acct/test/1Vm1His.rb b/src/acct/test/1Vm1His.rb deleted file mode 100644 index babf836dc9..0000000000 --- a/src/acct/test/1Vm1His.rb +++ /dev/null @@ -1,335 +0,0 @@ -$: << '.' - -require 'helper/test_helper.rb' - -describe "1 Vm 1 History" do - before(:each) do - clean_db - - @mock_client = MockClient.new - @accounting = OneWatch::Accounting.new(@mock_client) - - @watch_client = AcctClient.new - - @db = WatchHelper::DB - check_lines(0,0) - end - - it "Prolog testing" do - ts1 = 100 - @accounting.set_mock_timestamp(ts1) - - @accounting.insert(create_vmpool_hash) - check_lines(0,0) - - ts2 = 200 - @accounting.set_mock_timestamp(ts2) - - values = { - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 0, - :rstime => 0, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(1, values) - - @accounting.insert(create_vmpool_hash) - check_lines(1,1) - - history = values[:history].first - sum = ts2 - history[:pstime] - - warn "* T1 PSTIME T2" - @watch_client.prolog_time(ts1, ts2).to_i.should eql(sum) - warn " - By User" - @watch_client.prolog_time(ts1, ts2, :uid => 2).to_i.should eql(sum) - warn " - By Host" - @watch_client.prolog_time(ts1, ts2, :hid => 7).to_i.should eql(sum) - warn " - By Vm" - @watch_client.prolog_time(ts1, ts2, :vmid => 1).to_i.should eql(sum) - - warn " - Non existent User" - @watch_client.prolog_time(ts1, ts2, :uid => 555).to_i.should eql(0) - warn " - Non existent Host" - @watch_client.prolog_time(ts1, ts2, :hid => 555).to_i.should eql(0) - warn " - Non existent Vm" - @watch_client.prolog_time(ts1, ts2, :vmid => 555).to_i.should eql(0) - - warn "* PSTIME T1 T2" - @watch_client.prolog_time(160, ts2).to_i.should eql(sum-10) - warn "* T1 PSTIME T2-10" - @watch_client.prolog_time(ts1, ts2-10).to_i.should eql(sum-10) - warn "* T1 T2 PSTIME" - @watch_client.prolog_time(110, 130).to_i.should eql(0) - - warn "* Non Epilog time" - @watch_client.epilog_time(ts1, ts2).to_i.should eql(0) - warn "* Non Running time" - @watch_client.running_time(ts1, ts2).to_i.should eql(0) - - ts3 = 300 - @accounting.set_mock_timestamp(ts3) - - values = { - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 240, - :rstime => 0, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(1, values) - - @accounting.insert(create_vmpool_hash) - check_lines(1,1) - - history = values[:history].first - sum = history[:petime] - history[:pstime] - - warn "* T1 PSTIME PETIME T3" - @watch_client.prolog_time(ts1, ts3).to_i.should eql(sum) - warn " - By User" - @watch_client.prolog_time(ts1, ts3, :uid => 2).to_i.should eql(sum) - warn " - By Host" - @watch_client.prolog_time(ts1, ts3, :hid => 7).to_i.should eql(sum) - warn " - By Vm" - @watch_client.prolog_time(ts1, ts3, :vmid => 1).to_i.should eql(sum) - - warn "* T1 PSTIME T3 PETIME" - @watch_client.prolog_time(ts1, 230).to_i.should eql(230 - history[:pstime]) - - warn "* PSTIME T1 PETIME T3" - @watch_client.prolog_time(160, ts3).to_i.should eql(history[:petime] - 160) - - warn "* PSTIME T1 T3 PETIME" - @watch_client.prolog_time(160, 230).to_i.should eql(230 - 160) - end - - it "Running testing" do - ts1 = 100 - @accounting.set_mock_timestamp(ts1) - - @accounting.insert(create_vmpool_hash) - check_lines(0,0) - - ts2 = 200 - @accounting.set_mock_timestamp(ts2) - - values = { - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 155, - :rstime => 155, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(1, values) - - @accounting.insert(create_vmpool_hash) - check_lines(1,1) - - history = values[:history].first - sum = ts2 - history[:rstime] - - warn "* T1 RSTIME T2" - @watch_client.running_time(ts1, ts2).to_i.should eql(sum) - warn " - By User" - @watch_client.running_time(ts1, ts2, :uid => 2).to_i.should eql(sum) - warn " - By Host" - @watch_client.running_time(ts1, ts2, :hid => 7).to_i.should eql(sum) - warn " - By Vm" - @watch_client.running_time(ts1, ts2, :vmid => 1).to_i.should eql(sum) - - warn " - Non existent User" - @watch_client.running_time(ts1, ts2, :uid => 555).to_i.should eql(0) - warn " - Non existent Host" - @watch_client.running_time(ts1, ts2, :hid => 555).to_i.should eql(0) - warn " - Non existent Vm" - @watch_client.running_time(ts1, ts2, :vmid => 555).to_i.should eql(0) - - warn "* RSTIME T1 T2" - @watch_client.running_time(160, ts2).to_i.should eql(ts2-160) - warn "* T1 RSTIME T2-10" - @watch_client.running_time(ts1, ts2-10).to_i.should eql(sum-10) - warn "* T1 T2 RSTIME" - @watch_client.running_time(110, 130).to_i.should eql(0) - - warn "* Non Epilog time" - @watch_client.epilog_time(ts1, ts2).to_i.should eql(0) - warn "* Non Prolog time" - @watch_client.prolog_time(ts1, ts2).to_i.should eql(5) - - ts3 = 300 - @accounting.set_mock_timestamp(ts3) - - values = { - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 155, - :rstime => 155, - :retime => 230, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(1, values) - - @accounting.insert(create_vmpool_hash) - check_lines(1,1) - - history = values[:history].first - sum = history[:retime] - history[:rstime] - - warn "* T1 PSTIME PETIME T3" - @watch_client.running_time(ts1, ts3).to_i.should eql(sum) - warn " - By User" - @watch_client.running_time(ts1, ts3, :uid => 2).to_i.should eql(sum) - warn " - By Host" - @watch_client.running_time(ts1, ts3, :hid => 7).to_i.should eql(sum) - warn " - By Vm" - @watch_client.running_time(ts1, ts3, :vmid => 1).to_i.should eql(sum) - - warn "* T1 PSTIME T3 PETIME" - @watch_client.running_time(ts1, 230).to_i.should eql(230 - history[:rstime]) - - warn "* PSTIME T1 PETIME T3" - @watch_client.running_time(160, ts3).to_i.should eql(history[:retime] - 160) - - warn "* PSTIME T1 T3 PETIME" - @watch_client.running_time(160, 230).to_i.should eql(230 - 160) - end - - it "Epilog testing" do - ts1 = 100 - @accounting.set_mock_timestamp(ts1) - - @accounting.insert(create_vmpool_hash) - check_lines(0,0) - - ts2 = 200 - @accounting.set_mock_timestamp(ts2) - - values = { - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 155, - :rstime => 155, - :retime => 170, - :estime => 180, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(1, values) - - @accounting.insert(create_vmpool_hash) - check_lines(1,1) - - history = values[:history].first - sum = ts2 - history[:estime] - - warn "* T1 ESTIME T2" - @watch_client.epilog_time(ts1, ts2).to_i.should eql(sum) - warn " - By User" - @watch_client.epilog_time(ts1, ts2, :uid => 2).to_i.should eql(sum) - warn " - By Host" - @watch_client.epilog_time(ts1, ts2, :hid => 7).to_i.should eql(sum) - warn " - By Vm" - @watch_client.epilog_time(ts1, ts2, :vmid => 1).to_i.should eql(sum) - - warn " - Non existent User" - @watch_client.epilog_time(ts1, ts2, :uid => 555).to_i.should eql(0) - warn " - Non existent Host" - @watch_client.epilog_time(ts1, ts2, :hid => 555).to_i.should eql(0) - warn " - Non existent Vm" - @watch_client.epilog_time(ts1, ts2, :vmid => 555).to_i.should eql(0) - - warn "* ESTIME T1 T2" - @watch_client.epilog_time(190, ts2).to_i.should eql(ts2-190) - warn "* T1 ESTIME T2-10" - @watch_client.epilog_time(ts1, ts2-10).to_i.should eql(sum-10) - warn "* T1 T2 ESTIME" - @watch_client.epilog_time(110, 130).to_i.should eql(0) - - warn "* Non Running time" - @watch_client.running_time(ts1, ts2).to_i.should eql(15) - warn "* Non Prolog time" - @watch_client.prolog_time(ts1, ts2).to_i.should eql(5) - - ts3 = 300 - @accounting.set_mock_timestamp(ts3) - - values = { - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 155, - :rstime => 155, - :retime => 170, - :estime => 180, - :eetime => 230, - :reason => 0 - ] - } - - @mock_client.add_vm(1, values) - - @accounting.insert(create_vmpool_hash) - check_lines(1,1) - - history = values[:history].first - sum = history[:eetime] - history[:estime] - - warn "* T1 PSTIME PETIME T3" - @watch_client.epilog_time(ts1, ts3).to_i.should eql(sum) - warn " - By User" - @watch_client.epilog_time(ts1, ts3, :uid => 2).to_i.should eql(sum) - warn " - By Host" - @watch_client.epilog_time(ts1, ts3, :hid => 7).to_i.should eql(sum) - warn " - By Vm" - @watch_client.epilog_time(ts1, ts3, :vmid => 1).to_i.should eql(sum) - - warn "* T1 PSTIME T3 PETIME" - @watch_client.epilog_time(ts1, 230).to_i.should eql(230 - history[:estime]) - - warn "* PSTIME T1 PETIME T3" - @watch_client.epilog_time(190, ts3).to_i.should eql(history[:eetime] - 190) - - warn "* PSTIME T1 T3 PETIME" - @watch_client.epilog_time(190, 220).to_i.should eql(220 - 190) - end -end \ No newline at end of file diff --git a/src/acct/test/1VmXHis.rb b/src/acct/test/1VmXHis.rb deleted file mode 100644 index 0d92ebb369..0000000000 --- a/src/acct/test/1VmXHis.rb +++ /dev/null @@ -1,101 +0,0 @@ -$: << '.' - -require 'helper/test_helper.rb' - -describe "1 Vm X History" do - before(:each) do - clean_db - - @mock_client = MockClient.new - @accounting = OneWatch::Accounting.new(@mock_client) - - @watch_client = AcctClient.new - - @db = WatchHelper::DB - check_lines(0,0) - end - - it "Running testing" do - ts1 = 100 - @accounting.set_mock_timestamp(ts1) - - @accounting.insert(create_vmpool_hash) - check_lines(0,0) - - ts2 = 200 - @accounting.set_mock_timestamp(ts2) - - values = { - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :seq => 0, - :pstime => 150, - :petime => 155, - :rstime => 155, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(1, values) - - @accounting.insert(create_vmpool_hash) - check_lines(1,1) - - history = values[:history].first - sum = ts2 - history[:rstime] - - warn "* T1 RSTIME T2" - @watch_client.running_time(ts1, ts2).to_i.should eql(sum) - - ts3 = 300 - @accounting.set_mock_timestamp(ts3) - - values = { - :uid => 2, - :gid => 4, - :history => [ - { - :hid => 7, - :seq => 0, - :pstime => 150, - :petime => 155, - :rstime => 155, - :retime => 230, - :estime => 230, - :eetime => 260, - :reason => 2 - }, - { - :hid => 8, - :seq => 1, - :pstime => 270, - :petime => 275, - :rstime => 275, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - } - ] - } - - @mock_client.add_vm(1, values) - - @accounting.insert(create_vmpool_hash) - check_lines(1,2) - - h1 = values[:history].first - sum1 = h1[:retime] - h1[:rstime] - - h2 = values[:history].last - sum2 = ts3 - h2[:rstime] - - warn "* T1 RSTIME1 RETIME1 RSTIME1 T2" - @watch_client.running_time(ts1, ts3).to_i.should eql(sum1 + sum2) - end -end \ No newline at end of file diff --git a/src/acct/test/XVm1His.rb b/src/acct/test/XVm1His.rb deleted file mode 100644 index c0640feb48..0000000000 --- a/src/acct/test/XVm1His.rb +++ /dev/null @@ -1,93 +0,0 @@ -$: << '.' - -require 'helper/test_helper.rb' - -describe "X Vm 1 History" do - before(:each) do - clean_db - - @mock_client = MockClient.new - @accounting = OneWatch::Accounting.new(@mock_client) - - @watch_client = AcctClient.new - - @db = WatchHelper::DB - check_lines(0,0) - end - - it "Running testing" do - ts1 = 100 - @accounting.set_mock_timestamp(ts1) - - @accounting.insert(create_vmpool_hash) - check_lines(0,0) - - ts2 = 200 - @accounting.set_mock_timestamp(ts2) - - values = { - :uid => 2, - :gid => 4, - :history => [ - :hid => 6, - :seq => 0, - :pstime => 150, - :petime => 155, - :rstime => 155, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(1, values) - - @accounting.insert(create_vmpool_hash) - check_lines(1,1) - - history = values[:history].first - sum = ts2 - history[:rstime] - - warn "* T1 RSTIME T2" - @watch_client.running_time(ts1, ts2).to_i.should eql(sum) - - ts3 = 300 - @accounting.set_mock_timestamp(ts3) - - values2 = { - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :seq => 0, - :pstime => 220, - :petime => 260, - :rstime => 260, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(2, values2) - - @accounting.insert(create_vmpool_hash) - check_lines(2,2) - - history1 = values[:history].first - sum1 = ts3 - history1[:rstime] - - history2 = values2[:history].first - sum2 = ts3 - history2[:rstime] - - warn "* T1 RSTIME T2" - @watch_client.running_time(ts1, ts3).to_i.should eql(sum1 + sum2) - @watch_client.running_time(ts1, ts3, :vmid=>1).to_i.should eql(sum1) - @watch_client.running_time(ts1, ts3, :vmid=>2).to_i.should eql(sum2) - @watch_client.running_time(ts1, ts3, :uid=>2).to_i.should eql(sum1 + sum2) - @watch_client.running_time(ts1, ts3, :hid=>6).to_i.should eql(sum1) - @watch_client.running_time(ts1, ts3, :hid=>7).to_i.should eql(sum2) - end -end \ No newline at end of file diff --git a/src/acct/test/cmonitoring_spec.rb b/src/acct/test/cmonitoring_spec.rb deleted file mode 100644 index dd79ed8719..0000000000 --- a/src/acct/test/cmonitoring_spec.rb +++ /dev/null @@ -1,529 +0,0 @@ -$: << '.' - -require 'helper/test_helper.rb' -require 'watch_client' - -describe "VmWatchClient tests" do - before(:all) do - clean_db - - @mock_client = MockClient.new - @monitoring = OneWatch::VmMonitoring.new - - @watch_client = OneWatchClient::VmWatchClient.new - - @db = WatchHelper::DB - @db[:vms].count.should eql(0) - end - - it "Create a VM: uid=2 gid=4, timestamp=100" do - @monitoring.set_mock_timestamp(100) - - @monitoring.insert(create_vmpool_hash) - @db[:vms].count.should eql(0) - - values = { - :cpu => 1, - :memory => 128, - :net_tx => 200, - :net_rx => 400, - :last_poll => 100, - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 0, - :rstime => 0, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(1, values) - @monitoring.insert(create_vmpool_hash) - @db[:vms].count.should eql(1) - end - - it "should check all the monitoring resources are shown by default" do - mon = @watch_client.resource_monitoring(1) - - mon[:id].should eql(1) - mon[:resource].should eql("VM") - - monitoring = mon[:monitoring] - - monitoring.keys.size.should eql(4) - - monitoring[:cpu_usage].size.should eql(1) - monitoring[:cpu_usage].first.should eql([100,1]) - - monitoring[:mem_usage].size.should eql(1) - monitoring[:mem_usage].first.should eql([100,128]) - - monitoring[:net_tx].size.should eql(1) - monitoring[:net_tx].first.should eql([100,200]) - - monitoring[:net_rx].size.should eql(1) - monitoring[:net_rx].first.should eql([100,400]) - end - - it "should check all the monitoring resources are shown by default and filtered" do - mon = @watch_client.resource_monitoring(1, nil, :uid=>2) - - mon[:id].should eql(1) - mon[:resource].should eql("VM") - - monitoring = mon[:monitoring] - - monitoring.keys.size.should eql(4) - - monitoring[:cpu_usage].size.should eql(1) - monitoring[:cpu_usage].first.should eql([100,1]) - - monitoring[:mem_usage].size.should eql(1) - monitoring[:mem_usage].first.should eql([100,128]) - - monitoring[:net_tx].size.should eql(1) - monitoring[:net_tx].first.should eql([100,200]) - - monitoring[:net_rx].size.should eql(1) - monitoring[:net_rx].first.should eql([100,400]) - end - - it "should check no info for non exisiting user" do - mon = @watch_client.resource_monitoring(1, nil, :uid=>1) - - mon.should eql(nil) - end - - it "should check only one monitoring resource is shown if specified" do - mon = @watch_client.resource_monitoring(1, [:net_tx]) - - monitoring = mon[:monitoring] - - monitoring.keys.size.should eql(1) - - monitoring[:net_tx].size.should eql(1) - monitoring[:net_tx].first.should eql([100,200]) - end - - it "should check only two monitoring resources are shown if specified" do - mon = @watch_client.resource_monitoring(1, [:net_tx, :cpu_usage]) - - monitoring = mon[:monitoring] - - monitoring.keys.size.should eql(2) - - monitoring[:net_tx].size.should eql(1) - monitoring[:net_tx].first.should eql([100,200]) - - monitoring[:cpu_usage].size.should eql(1) - monitoring[:cpu_usage].first.should eql([100,1]) - end - - it "should check all the total monitoring resources are shown by default" do - mon = @watch_client.total_monitoring - - mon[:resource].should eql("VM_POOL") - - monitoring = mon[:monitoring] - - monitoring[:total].size.should eql(1) - monitoring[:total].first.should eql([100,1]) - - monitoring[:active].size.should eql(1) - monitoring[:active].first.should eql([100,1]) - - monitoring[:error].size.should eql(1) - monitoring[:error].first.should eql([100,0]) - - monitoring[:cpu_usage].size.should eql(1) - monitoring[:cpu_usage].first.should eql([100,1]) - - monitoring[:mem_usage].size.should eql(1) - monitoring[:mem_usage].first.should eql([100,128]) - - monitoring[:net_tx].size.should eql(1) - monitoring[:net_tx].first.should eql([100,200]) - - monitoring[:net_rx].size.should eql(1) - monitoring[:net_rx].first.should eql([100,400]) - end - - it "should check only one total monitoring resources is shown if specified" do - mon = @watch_client.total_monitoring([:total]) - - mon[:resource].should eql("VM_POOL") - - monitoring = mon[:monitoring] - - monitoring.keys.size.should eql(1) - - monitoring[:total].size.should eql(1) - monitoring[:total].first.should eql([100,1]) - end - - it "should return an empty Hash if no valid monitoring resource" do - mon = @watch_client.resource_monitoring(1, [:oranges]) - mon[:monitoring].empty?.should eql(true) - end - - it "should return nil if the VM does not exist" do - mon = @watch_client.resource_monitoring(100, [:oranges]) - mon.should eql(nil) - end - - it "Create a second VM: uid=2 gid=4, timestamp=200" do - @monitoring.set_mock_timestamp(200) - - values = { - :cpu => 1, - :memory => 128, - :net_tx => 200, - :net_rx => 400, - :last_poll => 100, - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 0, - :rstime => 0, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(2, values) - @monitoring.insert(create_vmpool_hash) - @db[:vms].count.should eql(2) - end - - it "should check all the monitoring resources are shown by default" do - mon = @watch_client.resource_monitoring(1) - - mon[:id].should eql(1) - mon[:resource].should eql("VM") - - monitoring = mon[:monitoring] - - monitoring.keys.size.should eql(4) - - monitoring[:cpu_usage].size.should eql(2) - monitoring[:cpu_usage].first.should eql([100,1]) - - monitoring[:mem_usage].size.should eql(2) - monitoring[:mem_usage].first.should eql([100,128]) - - monitoring[:net_tx].size.should eql(2) - monitoring[:net_tx].first.should eql([100,200]) - - monitoring[:net_rx].size.should eql(2) - monitoring[:net_rx].first.should eql([100,400]) - - mon = @watch_client.resource_monitoring(2) - - mon[:id].should eql(2) - mon[:resource].should eql("VM") - - monitoring = mon[:monitoring] - - monitoring.keys.size.should eql(4) - - monitoring[:cpu_usage].size.should eql(1) - monitoring[:cpu_usage].first.should eql([100,1]) - - monitoring[:mem_usage].size.should eql(1) - monitoring[:mem_usage].first.should eql([100,128]) - - monitoring[:net_tx].size.should eql(1) - monitoring[:net_tx].first.should eql([100,200]) - - monitoring[:net_rx].size.should eql(1) - monitoring[:net_rx].first.should eql([100,400]) - end - - it "should check all the total monitoring resources are shown by default" do - mon = @watch_client.total_monitoring - - mon[:resource].should eql("VM_POOL") - - monitoring = mon[:monitoring] - - monitoring[:total].size.should eql(2) - monitoring[:total].first.should eql([100,1]) - monitoring[:total][1].should eql([200,2]) - - monitoring[:active].size.should eql(2) - monitoring[:active].first.should eql([100,1]) - monitoring[:active][1].should eql([200,2]) - - monitoring[:error].size.should eql(2) - monitoring[:error].first.should eql([100,0]) - monitoring[:error][1].should eql([200,0]) - - monitoring[:cpu_usage].size.should eql(2) - monitoring[:cpu_usage].first.should eql([100,1]) - monitoring[:cpu_usage][1].should eql([200,1*2]) - - monitoring[:mem_usage].size.should eql(2) - monitoring[:mem_usage].first.should eql([100,128]) - monitoring[:mem_usage][1].should eql([200,128*2]) - - monitoring[:net_tx].size.should eql(2) - monitoring[:net_tx].first.should eql([100,200]) - monitoring[:net_tx][1].should eql([200,200*2]) - - monitoring[:net_rx].size.should eql(2) - monitoring[:net_rx].first.should eql([100,400]) - monitoring[:net_rx][1].should eql([200,400*2]) - end - - it "Create a third VM: uid=3 gid=5, timestamp=300" do - @monitoring.set_mock_timestamp(300) - - values = { - :cpu => 1, - :memory => 128, - :net_tx => 200, - :net_rx => 400, - :last_poll => 270, - :uid => 3, - :gid => 5, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 0, - :rstime => 0, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(3, values) - @monitoring.insert(create_vmpool_hash) - @db[:vms].count.should eql(3) - end - - it "should check the total monitoring resources are filtered by uid(3)" do - mon = @watch_client.total_monitoring(nil, :uid=>3) - - mon[:resource].should eql("VM_POOL") - - monitoring = mon[:monitoring] - - monitoring[:total].size.should eql(3) - monitoring[:total].first.should eql([100,0]) - monitoring[:total][1].should eql([200,0]) - monitoring[:total][2].should eql([300,1]) - - monitoring[:active].size.should eql(3) - monitoring[:active].first.should eql([100,0]) - monitoring[:active][1].should eql([200,0]) - monitoring[:active][2].should eql([300,1]) - - monitoring[:error].size.should eql(3) - monitoring[:error].first.should eql([100,0]) - monitoring[:error][1].should eql([200,0]) - monitoring[:error][2].should eql([300,0]) - - monitoring[:cpu_usage].size.should eql(3) - monitoring[:cpu_usage].first.should eql([100,0]) - monitoring[:cpu_usage][1].should eql([200,0]) - monitoring[:cpu_usage][2].should eql([300,1]) - - monitoring[:mem_usage].size.should eql(3) - monitoring[:mem_usage].first.should eql([100,0]) - monitoring[:mem_usage][1].should eql([200,0]) - monitoring[:mem_usage][2].should eql([300,128]) - - monitoring[:net_tx].size.should eql(3) - monitoring[:net_tx].first.should eql([100,0]) - monitoring[:net_tx][1].should eql([200,0]) - monitoring[:net_tx][2].should eql([300,200]) - - monitoring[:net_rx].size.should eql(3) - monitoring[:net_rx].first.should eql([100,0]) - monitoring[:net_rx][1].should eql([200,0]) - monitoring[:net_rx][2].should eql([300,400]) - end - - it "should check the total monitoring resources are filtered by gid(5)" do - mon = @watch_client.total_monitoring(nil, :gid=>5) - - mon[:resource].should eql("VM_POOL") - - monitoring = mon[:monitoring] - - monitoring[:total].size.should eql(3) - monitoring[:total].first.should eql([100,0]) - monitoring[:total][1].should eql([200,0]) - monitoring[:total][2].should eql([300,1]) - - monitoring[:active].size.should eql(3) - monitoring[:active].first.should eql([100,0]) - monitoring[:active][1].should eql([200,0]) - monitoring[:active][2].should eql([300,1]) - - monitoring[:error].size.should eql(3) - monitoring[:error].first.should eql([100,0]) - monitoring[:error][1].should eql([200,0]) - monitoring[:error][2].should eql([300,0]) - - monitoring[:cpu_usage].size.should eql(3) - monitoring[:cpu_usage].first.should eql([100,0]) - monitoring[:cpu_usage][1].should eql([200,0]) - monitoring[:cpu_usage][2].should eql([300,1]) - - monitoring[:mem_usage].size.should eql(3) - monitoring[:mem_usage].first.should eql([100,0]) - monitoring[:mem_usage][1].should eql([200,0]) - monitoring[:mem_usage][2].should eql([300,128]) - - monitoring[:net_tx].size.should eql(3) - monitoring[:net_tx].first.should eql([100,0]) - monitoring[:net_tx][1].should eql([200,0]) - monitoring[:net_tx][2].should eql([300,200]) - - monitoring[:net_rx].size.should eql(3) - monitoring[:net_rx].first.should eql([100,0]) - monitoring[:net_rx][1].should eql([200,0]) - monitoring[:net_rx][2].should eql([300,400]) - end - - it "should check the total monitoring resources are filtered by uid(2)" do - mon = @watch_client.total_monitoring(nil, :uid=>2) - - mon[:resource].should eql("VM_POOL") - - monitoring = mon[:monitoring] - - monitoring[:total].size.should eql(3) - monitoring[:total].first.should eql([100,1]) - monitoring[:total][1].should eql([200,2]) - monitoring[:active].last.should eql([300,2]) - - monitoring[:active].size.should eql(3) - monitoring[:active].first.should eql([100,1]) - monitoring[:active][1].should eql([200,2]) - monitoring[:active].last.should eql([300,2]) - - monitoring[:error].size.should eql(3) - monitoring[:error].first.should eql([100,0]) - monitoring[:error][1].should eql([200,0]) - monitoring[:error][2].should eql([300,0]) - - monitoring[:cpu_usage].size.should eql(3) - monitoring[:cpu_usage].first.should eql([100,1]) - monitoring[:cpu_usage][1].should eql([200,2]) - monitoring[:cpu_usage][2].should eql([300,2]) - - monitoring[:mem_usage].size.should eql(3) - monitoring[:mem_usage].first.should eql([100,128]) - monitoring[:mem_usage][1].should eql([200,256]) - monitoring[:mem_usage][2].should eql([300,256]) - - monitoring[:net_tx].size.should eql(3) - monitoring[:net_tx].first.should eql([100,200]) - monitoring[:net_tx][1].should eql([200,400]) - monitoring[:net_tx][2].should eql([300,400]) - - monitoring[:net_rx].size.should eql(3) - monitoring[:net_rx].first.should eql([100,400]) - monitoring[:net_rx][1].should eql([200,800]) - monitoring[:net_rx][2].should eql([300,800]) - end - - it "should check the total monitoring resources are filtered by gid(4)" do - mon = @watch_client.total_monitoring(nil, :gid=>4) - - mon[:resource].should eql("VM_POOL") - - monitoring = mon[:monitoring] - - monitoring[:total].size.should eql(3) - monitoring[:total].first.should eql([100,1]) - monitoring[:total][1].should eql([200,2]) - monitoring[:total].last.should eql([300,2]) - - monitoring[:active].size.should eql(3) - monitoring[:active].first.should eql([100,1]) - monitoring[:active][1].should eql([200,2]) - monitoring[:active].last.should eql([300,2]) - - monitoring[:error].size.should eql(3) - monitoring[:error].first.should eql([100,0]) - monitoring[:error][1].should eql([200,0]) - monitoring[:error][2].should eql([300,0]) - - monitoring[:cpu_usage].size.should eql(3) - monitoring[:cpu_usage].first.should eql([100,1]) - monitoring[:cpu_usage][1].should eql([200,2]) - monitoring[:cpu_usage][2].should eql([300,2]) - - monitoring[:mem_usage].size.should eql(3) - monitoring[:mem_usage].first.should eql([100,128]) - monitoring[:mem_usage][1].should eql([200,256]) - monitoring[:mem_usage][2].should eql([300,256]) - - monitoring[:net_tx].size.should eql(3) - monitoring[:net_tx].first.should eql([100,200]) - monitoring[:net_tx][1].should eql([200,400]) - monitoring[:net_tx][2].should eql([300,400]) - - monitoring[:net_rx].size.should eql(3) - monitoring[:net_rx].first.should eql([100,400]) - monitoring[:net_rx][1].should eql([200,800]) - monitoring[:net_rx][2].should eql([300,800]) - end - - it "should check no total info for non existing user" do - mon = @watch_client.total_monitoring(nil, :uid=>5) - - mon[:resource].should eql("VM_POOL") - - monitoring = mon[:monitoring] - - monitoring[:total].size.should eql(3) - monitoring[:total].first.should eql([100,0]) - monitoring[:total][1].should eql([200,0]) - monitoring[:total].last.should eql([300,0]) - - monitoring[:active].size.should eql(3) - monitoring[:active].first.should eql([100,0]) - monitoring[:active][1].should eql([200,0]) - monitoring[:active].last.should eql([300,0]) - - monitoring[:error].size.should eql(3) - monitoring[:error].first.should eql([100,0]) - monitoring[:error][1].should eql([200,0]) - monitoring[:error][2].should eql([300,0]) - - monitoring[:cpu_usage].size.should eql(3) - monitoring[:cpu_usage].first.should eql([100,0]) - monitoring[:cpu_usage][1].should eql([200,0]) - monitoring[:cpu_usage][2].should eql([300,0]) - - monitoring[:mem_usage].size.should eql(3) - monitoring[:mem_usage].first.should eql([100,0]) - monitoring[:mem_usage][1].should eql([200,0]) - monitoring[:mem_usage][2].should eql([300,0]) - - monitoring[:net_tx].size.should eql(3) - monitoring[:net_tx].first.should eql([100,0]) - monitoring[:net_tx][1].should eql([200,0]) - monitoring[:net_tx][2].should eql([300,0]) - - monitoring[:net_rx].size.should eql(3) - monitoring[:net_rx].first.should eql([100,0]) - monitoring[:net_rx][1].should eql([200,0]) - monitoring[:net_rx][2].should eql([300,0]) - end -end \ No newline at end of file diff --git a/src/acct/test/fixtures/empty_pool.xml b/src/acct/test/fixtures/empty_pool.xml deleted file mode 100644 index 2a8bcd37c2..0000000000 --- a/src/acct/test/fixtures/empty_pool.xml +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/acct/test/fixtures/vm.xml b/src/acct/test/fixtures/vm.xml deleted file mode 100644 index 1560a16029..0000000000 --- a/src/acct/test/fixtures/vm.xml +++ /dev/null @@ -1,46 +0,0 @@ - - <%= id %> - <%= vm[:uid] ? vm[:uid] : 0 %> - <%= vm[:gid] ? vm[:gid] : 0 %> - <%= vm[:name] ? vm[:uid] : 'pepe' %> - <%= vm[:last_poll] ? vm[:last_poll] : '1309275256' %> - <%= vm[:state] ? vm[:state] : 3 %> - 3 - 1309275252 - 0 - dummy - <%= vm[:memory] ? vm[:memory] : 128 %> - <%= vm[:cpu] ? vm[:cpu] : 1 %> - <%= vm[:net_tx] ? vm[:net_tx] : 0 %> - <%= vm[:net_rx] ? vm[:net_rx] : 0 %> - - <% if history = vm[:history] %> - - <% history.each do |h| %> - - <%= h[:seq] ? h[:seq] : 0 %> - <%= h[:hostname] ? h[:hostname] : "kvxen" %> - /Users/dmolina/trabajo/acctmoni/install/var/ - <%= h[:hid] ? h[:hid] : 0 %> - 1309275256 - 0 - vmm_dummy - tm_dummy - <%= h[:pstime] ? h[:pstime] : 0 %> - <%= h[:petime] ? h[:petime] : 0 %> - <%= h[:rstime] ? h[:rstime] : 0 %> - <%= h[:retime] ? h[:retime] : 0 %> - <%= h[:estime] ? h[:estime] : 0 %> - <%= h[:eetime] ? h[:eetime] : 0 %> - <%= h[:reason] ? h[:reason] : 0 %> - - <% end %> - - <% end %> - \ No newline at end of file diff --git a/src/acct/test/fixtures/vmpool.xml b/src/acct/test/fixtures/vmpool.xml deleted file mode 100644 index 1ff7f5626e..0000000000 --- a/src/acct/test/fixtures/vmpool.xml +++ /dev/null @@ -1,49 +0,0 @@ - - <% vms.each do |id,vm| %> - - <%= id %> - <%= vm[:uid] ? vm[:uid] : 0 %> - <%= vm[:gid] ? vm[:gid] : 0 %> - <%= vm[:name] ? vm[:uid] : 'pepe' %> - <%= vm[:last_poll] ? vm[:last_poll] : '1309275256' %> - <%= vm[:state] ? vm[:state] : 3 %> - 3 - 1309275252 - 0 - dummy - <%= vm[:memory] ? vm[:memory] : 128 %> - <%= vm[:cpu] ? vm[:cpu] : 1 %> - <%= vm[:net_tx] ? vm[:net_tx] : 0 %> - <%= vm[:net_rx] ? vm[:net_rx] : 0 %> - - <% if history = vm[:history] %> - - <% h = history.last %> - - <%= h[:seq] ? h[:seq] : 0 %> - <%= h[:hostname] ? h[:hostname] : "kvxen" %> - /Users/dmolina/trabajo/acctmoni/install/var/ - <%= h[:hid] ? h[:hid] : 0 %> - 1309275256 - 0 - vmm_dummy - tm_dummy - <%= h[:pstime] ? h[:pstime] : 0 %> - <%= h[:petime] ? h[:petime] : 0 %> - <%= h[:rstime] ? h[:rstime] : 0 %> - <%= h[:retime] ? h[:retime] : 0 %> - <%= h[:estime] ? h[:estime] : 0 %> - <%= h[:eetime] ? h[:eetime] : 0 %> - <%= h[:reason] ? h[:reason] : 0 %> - - - <% end %> - - <% end %> - diff --git a/src/acct/test/helper/mock_client.rb b/src/acct/test/helper/mock_client.rb deleted file mode 100644 index 1f04f5c098..0000000000 --- a/src/acct/test/helper/mock_client.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'erb' - -FPATH = "./fixtures/" - -class MockClient - def initialize - @vmpool = File.read("./fixtures/empty_pool.xml") - @done_vmpool = File.read("./fixtures/empty_pool.xml") - - @vms = Hash.new - @done_vms = Hash.new - end - - - def call(action, *args) - xmlrpc_action = "one."+action - - case xmlrpc_action - when "one.vm.info" - id = args[0] - vm = @vms[id] - return ERB.new(File.read(FPATH+'vm.xml')).result(binding) - when "one.vmpool.info" - case args[3] - when -1 - return File.read("./fixtures/empty_pool.xml") if @vms.empty? - vms = @vms - return ERB.new(File.read(FPATH+'vmpool.xml')).result(binding) - when 6 then - return File.read("./fixtures/empty_pool.xml") if @done_vms.empty? - vms = @done_vms - return ERB.new(File.read(FPATH+'vmpool.xml')).result(binding) - end - end - end - - def add_vm(id, values) - if values[:state] == 6 - @done_vms[id] = values.clone - else - @vms[id] = values.clone - end - end - - def delete_vm(id) - @vms.delete(id) - @vms_done.delete(id) - end -end \ No newline at end of file diff --git a/src/acct/test/helper/test_helper.rb b/src/acct/test/helper/test_helper.rb deleted file mode 100644 index ef4b0948dd..0000000000 --- a/src/acct/test/helper/test_helper.rb +++ /dev/null @@ -1,72 +0,0 @@ -require 'rubygems' -require 'sequel' - -ONE_LOCATION = ENV['ONE_LOCATION'] -if !ONE_LOCATION - RUBY_LIB_LOCATION="/usr/lib/one/ruby" -else - RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" -end - -$: << RUBY_LIB_LOCATION - -require 'OpenNebula' - -$: << './helper' -$: << '.' -$: << '..' - - -require 'examples/acct_client' -require 'mock_client' - -require 'accounting' -require 'monitoring' - -module OneWatch - class Accounting - def set_mock_timestamp(t) - @mock_timestamp = t - end - - def generate_timestamp - @mock_timestamp - end - end - - class Monitoring - def set_mock_timestamp(t) - @mock_timestamp = t - end - - def generate_timestamp - @mock_timestamp - end - end -end - -def create_vmpool_hash - @vm_pool = OpenNebula::VirtualMachinePool.new(@mock_client, -2) - @vm_pool.info - hash = @vm_pool.to_hash -end - -def clean_db - begin - WatchHelper::Register.destroy - WatchHelper::VmDelta.destroy - WatchHelper::VmSample.destroy - WatchHelper::HostSample.destroy - WatchHelper::VmTimestamp.destroy - WatchHelper::HostTimestamp.destroy - WatchHelper::Vm.destroy - WatchHelper::Host.destroy - rescue Exception => e - warn e.message - end -end - -def check_lines(*args) - @db[:vms].count.should eql(args[0]) - @db[:registers].count.should eql(args[1]) -end diff --git a/src/acct/test/vm_monitoring_spec.rb b/src/acct/test/vm_monitoring_spec.rb deleted file mode 100644 index 5465a238a8..0000000000 --- a/src/acct/test/vm_monitoring_spec.rb +++ /dev/null @@ -1,299 +0,0 @@ -$: << '.' - -require 'helper/test_helper.rb' - -describe "VM Monitoring tests" do - before(:all) do - clean_db - - @mock_client = MockClient.new - @monitoring = OneWatch::VmMonitoring.new - - #@watch_client = OneWatchClient::WatchClient.new - - @db = WatchHelper::DB - @db[:vms].count.should eql(0) - @db[:vm_samples].count.should eql(0) - @db[:vm_timestamps].count.should eql(0) - end - - it "after monitoring an empty pool: 0 VMs, 0 Samples, 1 Timestamp" do - ts1 = 100 - @monitoring.set_mock_timestamp(ts1) - - @monitoring.insert(create_vmpool_hash) - @db[:vms].count.should eql(0) - @db[:vm_samples].count.should eql(0) - @db[:vm_timestamps].count.should eql(1) - end - - it "after monitoring a pool of 1 VM: 1 VMs, 1 Samples, 2 Timestamp" do - values = { - :cpu => 80, - :memory => 122, - :net_tx => 200, - :net_rx => 134, - :last_poll => 1309275256, - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 0, - :rstime => 0, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(0, values) - - ts2 = 200 - @monitoring.set_mock_timestamp(ts2) - - @monitoring.insert(create_vmpool_hash) - @db[:vms].count.should eql(1) - @db[:vm_samples].count.should eql(1) - @db[:vm_timestamps].count.should eql(2) - end - - it "after monitoring a pool of 1 VM: 1 VMs, 2 Samples, 3 Timestamp" do - values = { - :cpu => 80, - :memory => 122, - :net_tx => 200, - :net_rx => 134, - :last_poll => 1309275256, - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 0, - :rstime => 0, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(0, values) - - ts = 300 - @monitoring.set_mock_timestamp(ts) - - @monitoring.insert(create_vmpool_hash) - @db[:vms].count.should eql(1) - @db[:vm_samples].count.should eql(2) - @db[:vm_timestamps].count.should eql(3) - end - - it "after monitoring a pool of 2 VM: 2 VMs, 4 Samples, 4 Timestamp" do - values = { - :cpu => 80, - :memory => 122, - :net_tx => 200, - :net_rx => 134, - :last_poll => 1309275256, - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 0, - :rstime => 0, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(1, values) - - ts = 400 - @monitoring.set_mock_timestamp(ts) - - @monitoring.insert(create_vmpool_hash) - @db[:vms].count.should eql(2) - @db[:vm_samples].count.should eql(4) - @db[:vm_timestamps].count.should eql(4) - end - - it "after monitoring a pool of 2 VM: 2 VMs, 6 Samples, 5 Timestamp" do - values = { - :cpu => 80, - :memory => 122, - :net_tx => 200, - :net_rx => 134, - :last_poll => 1309275256, - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 0, - :rstime => 0, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(1, values) - - ts = 500 - @monitoring.set_mock_timestamp(ts) - - @monitoring.insert(create_vmpool_hash) - @db[:vms].count.should eql(2) - @db[:vm_samples].count.should eql(6) - @db[:vm_timestamps].count.should eql(5) - end - - it "after monitoring a pool of 3 VM: 3 VMs, 9 Samples, 5 Timestamp" do - values = { - :cpu => 80, - :memory => 122, - :net_tx => 200, - :net_rx => 134, - :last_poll => 1309275256, - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 0, - :rstime => 0, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(2, values) - - ts = 600 - @monitoring.set_mock_timestamp(ts) - - @monitoring.insert(create_vmpool_hash) - @db[:vms].count.should eql(3) - @db[:vm_samples].count.should eql(9) - @db[:vm_timestamps].count.should eql(5) - end - - it "after monitoring a pool of 3 VM: 3 VMs, 11 Samples, 5 Timestamp" do - values = { - :cpu => 80, - :memory => 122, - :net_tx => 200, - :net_rx => 134, - :last_poll => 1309275256, - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 0, - :rstime => 0, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(2, values) - - ts = 700 - @monitoring.set_mock_timestamp(ts) - - @monitoring.insert(create_vmpool_hash) - @db[:vms].count.should eql(3) - @db[:vm_samples].count.should eql(11) - @db[:vm_timestamps].count.should eql(5) - end - - - it "after monitoring a pool of 3 VM: 3 VMs, 13 Samples, 5 Timestamp" do - values = { - :cpu => 80, - :memory => 122, - :net_tx => 200, - :net_rx => 134, - :last_poll => 1309275256, - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 0, - :rstime => 0, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(2, values) - - ts = 800 - @monitoring.set_mock_timestamp(ts) - - @monitoring.insert(create_vmpool_hash) - @db[:vms].count.should eql(3) - @db[:vm_samples].count.should eql(13) - @db[:vm_timestamps].count.should eql(5) - end - - it "after monitoring a pool of 4 VM: 4 VMs, 16 Samples, 5 Timestamp" do - values = { - :cpu => 80, - :memory => 122, - :net_tx => 200, - :net_rx => 134, - :last_poll => 1309275256, - :uid => 2, - :gid => 4, - :history => [ - :hid => 7, - :pstime => 150, - :petime => 0, - :rstime => 0, - :retime => 0, - :estime => 0, - :eetime => 0, - :reason => 0 - ] - } - - @mock_client.add_vm(3, values) - - ts = 900 - @monitoring.set_mock_timestamp(ts) - - @monitoring.insert(create_vmpool_hash) - @db[:vms].count.should eql(4) - @db[:vm_samples].count.should eql(15) - @db[:vm_timestamps].count.should eql(5) - end - - it "after (10)monitoring a pool of 4 VM: 4 VMs, 20 Samples, 5 Timestamp" do - 10.times { |i| - ts = 1000+i*100 - @monitoring.set_mock_timestamp(ts) - - @monitoring.insert(create_vmpool_hash) - } - - @db[:vms].count.should eql(4) - @db[:vm_samples].count.should eql(20) - @db[:vm_timestamps].count.should eql(5) - end -end \ No newline at end of file diff --git a/src/acct/watch_client.rb b/src/acct/watch_client.rb deleted file mode 100644 index c3da4289bf..0000000000 --- a/src/acct/watch_client.rb +++ /dev/null @@ -1,229 +0,0 @@ -# -------------------------------------------------------------------------- # -# 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. # -#--------------------------------------------------------------------------- # - -module OneWatchClient - require 'acct/watch_helper' - - class WatchClient - TOTAL_COUNT = [:total, :active, :error] - - def resource_monitoring(id, monitoring_resources=[], filter={}) - # Retrieve Sequel resource - rsql = filter_resource(id, filter) - return nil if rsql.nil? - - # By default show all the available monitoring resources. - # If a set of monitoring resources is specified - # select only the allowed ones - allowed_keys = allowed_samples.keys - if monitoring_resources && !monitoring_resources.empty? - monitoring_resources = allowed_keys & monitoring_resources - else - monitoring_resources = allowed_keys - end - - # Initialize monitoring information - mon = Hash.new - monitoring_resources.each { |mr| - mon[mr] = Array.new - } - - # Retrieve information - rsql.samples_dataset.map { |sample| - monitoring_resources.each { |mr| - if sample.last_poll && sample.last_poll != 0 - mon[mr] << [sample.last_poll, sample.send(mr.to_sym)] - end - } - } - - # Format response in a Hash - hash = Hash.new - hash[:resource] = kind - hash[:id] = rsql.id - hash[:monitoring] = mon - hash - end - - def total_monitoring(monitoring_resources=[], filter={}) - # Retrieve Sequel resource - rsql = filter_pool(filter) - return nil if rsql.nil? - - # By default show all the available monitoring resources. - # If a set of monitoring resources is specified - # select only the allowed ones - allowed_keys = allowed_samples.keys + TOTAL_COUNT - if monitoring_resources && !monitoring_resources.empty? - monitoring_resources = allowed_keys & monitoring_resources - else - monitoring_resources = allowed_keys - end - - # Retrieve information - mon = Hash.new - monitoring_resources.each { |opt| - opt = opt.to_sym - if allowed_samples.has_key?(opt) - mon[opt] = sum_monitoring(rsql, opt) - elsif TOTAL_COUNT.include?(opt) - mon[opt] = count_monitoring(rsql, opt) - end - } - - # Format response in a Hash - hash = Hash.new - hash[:resource] = "#{kind.upcase}_POOL" - hash[:monitoring] = mon - hash - end - - private - - def sum_monitoring(rsql, mr) - # Get the MAX for each VM and last_poll value - max_per_vm = - rsql. - group(:timestamp). - select{[:timestamp, sum(mr.to_sym).as(:sum_mr)]} - - # Add all the existing timestamps - with_ts = timestamps.left_join(max_per_vm, :timestamp=>:id) - with_ts.collect do |row| - [row[:id], row[:sum_mr].to_i] - end - end - - def count_monitoring(rsql, opt) - resources = case opt - when :total then rsql - when :active then active(rsql) - when :error then error(rsql) - else return nil - end - - count = resources.group_and_count(:timestamp) - - # Add all the existing timestamps - with_ts = timestamps.left_join(count, :timestamp=>:id) - with_ts.collect do |row| - [row[:id], row[:count].to_i] - end - end - end - - class HostWatchClient < WatchClient - def pool - WatchHelper::Host - end - - def allowed_samples - WatchHelper::HOST_SAMPLE - end - - def kind - "HOST" - end - - def active(pool) - pool.filter('state < 3') - end - - def error(pool) - pool.filter(:state=>3) - end - - def timestamps - WatchHelper::HostTimestamp - end - - def filter_pool(filter) - if filter[:uid] - filter[:uid]==0 ? (hosts = pool) : (return nil) - elsif filter[:gid] - filter[:gid]==0 ? (hosts = pool) : (return nil) - else - hosts = pool - end - - WatchHelper::HostSample.join(hosts.select(:id.as(:host_id)), [:host_id]) - end - - def filter_resource(id, filter) - rsql = pool[id] - return nil if rsql.nil? - - if filter[:uid] - filter[:uid]==0 ? rsql : nil - elsif filter[:gid] - filter[:gid]==0 ? rsql : nil - else - rsql - end - end - end - - class VmWatchClient < WatchClient - def pool - WatchHelper::Vm - end - - def allowed_samples - WatchHelper::VM_SAMPLE - end - - def kind - "VM" - end - - def active(pool) - pool.filter(:state=>3) - end - - def error(pool) - pool.filter(:state=>7) - end - - def timestamps - WatchHelper::VmTimestamp - end - - def filter_pool(filter) - if filter[:uid] - vms = pool.filter(:uid=>filter[:uid]) - elsif filter[:gid] - vms = pool.filter(:gid=>filter[:gid]) - else - vms = pool - end - - WatchHelper::VmSample.join(vms.select(:id.as(:vm_id)), [:vm_id]) - end - - def filter_resource(id, filter) - rsql = pool[id] - return nil if rsql.nil? - - if filter[:uid] - filter[:uid]==rsql.uid ? rsql : nil - elsif filter[:gid] - filter[:gid]==rsql.gid ? rsql : nil - else - rsql - end - end - end -end diff --git a/src/acct/watch_helper.rb b/src/acct/watch_helper.rb deleted file mode 100644 index 925b0b18c3..0000000000 --- a/src/acct/watch_helper.rb +++ /dev/null @@ -1,455 +0,0 @@ -# -------------------------------------------------------------------------- # -# 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. # -#--------------------------------------------------------------------------- # - -module WatchHelper - require 'sequel' - require 'yaml' - - ONE_LOCATION=ENV["ONE_LOCATION"] - - if !ONE_LOCATION - VAR_LOCATION = "/var/lib/one" - ETC_LOCATION = "/etc/one" - else - VAR_LOCATION = ONE_LOCATION + "/var" - ETC_LOCATION = ONE_LOCATION + "/etc" - end - - ACCTD_CONF = ETC_LOCATION + "/acctd.conf" - ACCT_DB = VAR_LOCATION + "/oneacct.db" - - CONF = YAML.load_file(ACCTD_CONF) - - if CONF[:DB] - DB = Sequel.connect(CONF[:DB]) - else - DB = Sequel.connect("sqlite://#{ACCT_DB}") - end - - VM_DELTA = { - :net_rx => { - :type => Integer, - :path => 'NET_RX' - }, - :net_tx => { - :type => Integer, - :path => 'NET_TX' - } - } - - VM_SAMPLE = { - :cpu_usage => { - :type => Integer, - :path => 'CPU' - }, - :mem_usage => { - :type => Integer, - :path => 'MEMORY' - }, - :net_tx => { - :type => Integer, - :path => 'NET_TX' - }, - :net_rx => { - :type => Integer, - :path => 'NET_RX' - } - } - - HOST_SAMPLE = { - :disk_usage => { - :type => Integer, - :path => 'DISK_USAGE' - }, - :mem_usage => { - :type => Integer, - :path => 'MEM_USAGE' - }, - :cpu_usage => { - :type => Integer, - :path => 'CPU_USAGE' - }, - :max_disk => { - :type => Integer, - :path => 'MAX_DISK' - }, - :max_mem => { - :type => Integer, - :path => 'MAX_MEM' - }, - :max_cpu => { - :type => Integer, - :path => 'MAX_CPU' - }, - :free_disk => { - :type => Integer, - :path => 'FREE_DISK' - }, - :free_mem => { - :type => Integer, - :path => 'FREE_MEM' - }, - :free_cpu => { - :type => Integer, - :path => 'FREE_CPU' - }, - :used_disk => { - :type => Integer, - :path => 'USED_DISK' - }, - :used_mem => { - :type => Integer, - :path => 'USED_MEM' - }, - :used_cpu => { - :type => Integer, - :path => 'USED_CPU' - }, - :rvms => { - :type => Integer, - :path => 'RUNNING_VMS' - } - } - - def self.get_config(*params) - conf = CONF - while param = params.shift - conf = conf[param] - break if conf.nil? - end - conf - end - - def self.bootstrap - DB.create_table? :vms do - Integer :id, :primary_key=>true - String :name - Integer :uid - Integer :gid - Integer :mem - Float :cpu - Integer :vcpu - Integer :stime - Integer :etime - end - - DB.create_table? :hosts do - Integer :id, :primary_key=>true - String :name - String :im_mad - String :vm_mad - String :vn_mad - end - - DB.create_table? :vm_timestamps do - Integer :id, :primary_key=>true - end - - DB.create_table? :vm_samples do - foreign_key :vm_id, :vms, :key=>:id - foreign_key :timestamp, :vm_timestamps, :key=>:id - Integer :state - Integer :lcm_state - Integer :last_poll - - VM_SAMPLE.each { |key,value| - column key, value[:type] - } - - primary_key [:vm_id, :timestamp] - end - - DB.create_table? :host_timestamps do - Integer :id, :primary_key=>true - end - - DB.create_table? :host_samples do - foreign_key :host_id, :hosts, :key=>:id - foreign_key :timestamp, :host_timestamps, :key=>:id - Integer :last_poll - Integer :state - - HOST_SAMPLE.each { |key,value| - column key, value[:type] - } - - primary_key [:host_id, :timestamp] - end - - DB.create_table? :registers do - foreign_key :vm_id, :vms, :key=>:id - Integer :hid - String :hostname - Integer :seq - Integer :pstime - Integer :petime - Integer :rstime - Integer :retime - Integer :estime - Integer :eetime - Integer :reason - - primary_key [:vm_id, :seq] - end - - DB.create_table? :vm_deltas do - foreign_key :vm_id, :vms, :key=>:id - Integer :timestamp - Integer :ptimestamp - - VM_DELTA.each { |key,value| - column key, value[:type] - } - - primary_key [:vm_id, :timestamp] - end - end - - self.bootstrap - - class VmSample < Sequel::Model - unrestrict_primary_key - - many_to_one :vm - many_to_one :timestamp, - :class=>"WatchHelper::VmTimestamp", - :key=>:id - end - - class VmTimestamp < Sequel::Model - unrestrict_primary_key - - one_to_many :samples, - :order=>:timestamp, - :class=>"WatchHelper::VmSample", - :key=>:timestamp - - @@window_size = WatchHelper::get_config( - :VM_MONITORING, - :WINDOW_SIZE - ) - - def self.fix_size - if self.count > @@window_size - last_timestamp = self.all.first - last_timestamp.samples_dataset.destroy - last_timestamp.destroy - end - end - end - - class HostSample < Sequel::Model - unrestrict_primary_key - - many_to_one :host - many_to_one :timestamp, - :class=>"WatchHelper::HostTimestamp", - :key=>:id - end - - class HostTimestamp < Sequel::Model - unrestrict_primary_key - - one_to_many :samples, - :order=>:timestamp, - :class=>"WatchHelper::HostSample", - :key=>:timestamp - - @@window_size = WatchHelper::get_config( - :HOST_MONITORING, - :WINDOW_SIZE - ) - - def self.fix_size - if self.count > @@window_size - last_timestamp = self.all.first - last_timestamp.samples_dataset.destroy - last_timestamp.destroy - end - end - end - - class Register < Sequel::Model - unrestrict_primary_key - - many_to_one :vm - - def update_from_history(history) - self.seq = history['SEQ'] - self.hostname = history['HOSTNAME'] - self.hid = history['HID'] - self.pstime = history['PSTIME'] - self.petime = history['PETIME'] - self.rstime = history['RSTIME'] - self.retime = history['RETIME'] - self.estime = history['ESTIME'] - self.eetime = history['EETIME'] - self.reason = history['REASON'] - - self.save - end - end - - class VmDelta < Sequel::Model - unrestrict_primary_key - - many_to_one :vm - end - - class Vm < Sequel::Model - unrestrict_primary_key - - # Accounting - one_to_many :registers, :order=>:seq - one_to_many :deltas, :order=>:timestamp, :class=>"WatchHelper::VmDelta" - - # Monitoring - one_to_many :samples, :order=>:timestamp, :class=>"WatchHelper::VmSample" - - @@samples_cache = [] - @@deltas_cache = [] - - def self.info(vm) - Vm.find_or_create(:id=>vm['ID']) { |v| - v.name = vm['NAME'] - v.uid = vm['UID'].to_i - v.gid = vm['GID'].to_i - v.mem = vm['TEMPLATE']['MEMORY'].to_i - v.cpu = vm['TEMPLATE']['CPU'].to_f - v.vcpu = vm['TEMPLATE']['VCPU'].to_i - v.stime = vm['STIME'].to_i - v.etime = vm['ETIME'].to_i - } - end - - def add_register_from_resource(history) - self.add_register( - :seq => history['SEQ'], - :hostname => history['HOSTNAME'], - :hid => history['HID'], - :pstime => history['PSTIME'], - :petime => history['PETIME'], - :rstime => history['RSTIME'], - :retime => history['RETIME'], - :estime => history['ESTIME'], - :eetime => history['EETIME'], - :reason => history['REASON'] - ) - end - - def add_sample_from_resource(vm, timestamp) - hash = { - :vm_id => vm['ID'], - :timestamp => timestamp.id, - :last_poll => vm['LAST_POLL'], - :state => vm['STATE'], - :lcm_state => vm['LCM_STATE'] - } - - VM_SAMPLE.each { |key,value| - hash[key] = vm[value[:path]] - } - - @@samples_cache << hash - end - - def add_delta_from_resource(vm, timestamp) - hash = Hash.new - - hash[:vm_id] = vm['ID'] - hash[:timestamp] = timestamp - - if last_delta = self.deltas.first - hash[:ptimestamp] = last_delta.send(:timestamp) - - VM_DELTA.each { |key,value| - old_value = last_delta.send("#{key}".to_sym) - new_value = vm[value[:path]].to_i - - if old_value > new_value - hash[key] = new_value - else - hash[key] = new_value - old_value - end - } - else - hash[:ptimestamp] = 0 - - VM_DELTA.each { |key,value| - hash[key] = vm[value[:path]] - } - end - - @@deltas_cache << hash - end - - def self.flush - DB.transaction do - VmDelta.multi_insert(@@deltas_cache) - VmSample.multi_insert(@@samples_cache) - - VmTimestamp.fix_size - end - - @@samples_cache = [] - @@deltas_cache = [] - end - end - - class Host < Sequel::Model - unrestrict_primary_key - - # Monitoring - one_to_many :samples, :order=>:timestamp, :class=>"WatchHelper::HostSample" - - @@samples_cache = [] - - def self.info(host) - Host.find_or_create(:id=>host['ID']) { |h| - h.name = host['NAME'] - h.im_mad = host['IM_MAD'] - h.vm_mad = host['VM_MAD'] - h.vn_mad = host['VN_MAD'] - } - end - - def add_sample_from_resource(host, timestamp) - hash = { - :host_id => host['ID'], - :timestamp => timestamp.id, - :last_poll => host['LAST_MON_TIME'], - :state => host['STATE'], - } - - host_share = host['HOST_SHARE'] - HOST_SAMPLE.each { |key,value| - hash[key] = host_share[value[:path]] - } - - @@samples_cache << hash - end - - def self.flush - DB.transaction do - HostSample.multi_insert(@@samples_cache) - - HostTimestamp.fix_size - end - - @@samples_cache = [] - end - end -end diff --git a/src/host/Host.cc b/src/host/Host.cc index 92abb39f65..804b34a87f 100644 --- a/src/host/Host.cc +++ b/src/host/Host.cc @@ -69,6 +69,14 @@ const char * Host::db_bootstrap = "CREATE TABLE IF NOT EXISTS host_pool (" "last_mon_time INTEGER, uid INTEGER, gid INTEGER, owner_u INTEGER, " "group_u INTEGER, other_u INTEGER, UNIQUE(name))"; + +const char * Host::monit_table = "host_monitoring"; + +const char * Host::monit_db_names = "hid, last_mon_time, body"; + +const char * Host::monit_db_bootstrap = "CREATE TABLE IF NOT EXISTS " + "host_monitoring (hid INTEGER, last_mon_time INTEGER, body TEXT, " + "PRIMARY KEY(hid, last_mon_time))"; /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ @@ -153,7 +161,7 @@ error_hostname: goto error_generic; error_generic: - error_str = "Error inserting Group in DB."; + error_str = "Error inserting Host in DB."; error_common: return -1; } @@ -188,6 +196,60 @@ int Host::update_info(string &parse_str) return 0; } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int Host::update_monitoring(SqlDB * db) +{ + ostringstream oss; + int rc; + + string xml_body; + string error_str; + char * sql_xml; + + sql_xml = db->escape_str(to_xml(xml_body).c_str()); + + if ( sql_xml == 0 ) + { + goto error_body; + } + + if ( validate_xml(sql_xml) != 0 ) + { + goto error_xml; + } + + oss << "INSERT INTO " << monit_table << " ("<< monit_db_names <<") VALUES (" + << oid << "," + << last_monitored << "," + << "'" << sql_xml << "')"; + + db->free_str(sql_xml); + + rc = db->exec(oss); + + return rc; + +error_xml: + db->free_str(sql_xml); + + error_str = "could not transform the Host to XML."; + + goto error_common; + +error_body: + error_str = "could not insert the Host in the DB."; + +error_common: + oss.str(""); + oss << "Error updating Host monitoring information, " << error_str; + + NebulaLog::log("ONE",Log::ERROR, oss); + + return -1; +} + /* ************************************************************************ */ /* Host :: Misc */ /* ************************************************************************ */ diff --git a/src/host/HostPool.cc b/src/host/HostPool.cc index 9bb138a12b..2bf113f4a0 100644 --- a/src/host/HostPool.cc +++ b/src/host/HostPool.cc @@ -29,12 +29,26 @@ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +time_t HostPool::_monitor_expiration; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + HostPool::HostPool(SqlDB* db, vector hook_mads, const string& hook_location, - const string& remotes_location) + const string& remotes_location, + time_t expire_time) : PoolSQL(db, Host::table, true) { + + _monitor_expiration = expire_time; + + if ( _monitor_expiration == 0 ) + { + clean_all_monitoring(); + } + // ------------------ Initialize Hooks for the pool ---------------------- const VectorAttribute * vattr; @@ -289,3 +303,65 @@ int HostPool::discover(map * discovered_hosts, int host_limit) return rc; } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int HostPool::dump_monitoring( + ostringstream& oss, + const string& where) +{ + ostringstream cmd; + + cmd << "SELECT " << Host::monit_table << ".body FROM " << Host::monit_table + << " INNER JOIN " << Host::table + << " WHERE hid = oid"; + + if ( !where.empty() ) + { + cmd << " AND " << where; + } + + cmd << " ORDER BY hid, " << Host::monit_table << ".last_mon_time;"; + + return PoolSQL::dump(oss, "MONITORING_DATA", cmd); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int HostPool::clean_expired_monitoring() +{ + if ( _monitor_expiration == 0 ) + { + return 0; + } + + int rc; + time_t max_mon_time; + ostringstream oss; + + max_mon_time = time(0) - _monitor_expiration; + + oss << "DELETE FROM " << Host::monit_table + << " WHERE last_mon_time < " << max_mon_time; + + rc = db->exec(oss); + + return rc; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int HostPool::clean_all_monitoring() +{ + ostringstream oss; + int rc; + + oss << "DELETE FROM " << Host::monit_table; + + rc = db->exec(oss); + + return rc; +} diff --git a/src/host/test/HostPoolTest.cc b/src/host/test/HostPoolTest.cc index 9f02041dfc..cf5714704c 100644 --- a/src/host/test/HostPoolTest.cc +++ b/src/host/test/HostPoolTest.cc @@ -155,7 +155,7 @@ protected: { vector hook; - return new HostPool(db,hook,"./", "./"); + return new HostPool(db,hook,"./", "./", 0); }; int allocate(int index) diff --git a/src/host/test/NebulaTestHost.h b/src/host/test/NebulaTestHost.h index 1248059f3d..fa9c5c839e 100644 --- a/src/host/test/NebulaTestHost.h +++ b/src/host/test/NebulaTestHost.h @@ -81,7 +81,7 @@ public: host_hooks.push_back(hook); - return new HostPool(db, host_hooks, hook_location, var_location); + return new HostPool(db, host_hooks, hook_location, var_location, 0); } }; diff --git a/src/im/InformationManager.cc b/src/im/InformationManager.cc index 699ff0f9c4..0b2ecc2aea 100644 --- a/src/im/InformationManager.cc +++ b/src/im/InformationManager.cc @@ -162,6 +162,9 @@ void InformationManager::timer_action() mark = 0; } + // Clear the expired monitoring records + hpool->clean_expired_monitoring(); + rc = hpool->discover(&discovered_hosts, host_limit); if ((rc != 0) || (discovered_hosts.empty() == true)) diff --git a/src/im/InformationManagerDriver.cc b/src/im/InformationManagerDriver.cc index 3af422e13c..990638f0f3 100644 --- a/src/im/InformationManagerDriver.cc +++ b/src/im/InformationManagerDriver.cc @@ -128,6 +128,7 @@ void InformationManagerDriver::protocol( host->touch(true); hpool->update(host); + hpool->update_monitoring(host); host->unlock(); } diff --git a/src/lcm/LifeCycleActions.cc b/src/lcm/LifeCycleActions.cc index 17dbca1cba..22518cd56e 100644 --- a/src/lcm/LifeCycleActions.cc +++ b/src/lcm/LifeCycleActions.cc @@ -679,6 +679,7 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm) break; case VirtualMachine::FAILURE: + vmpool->update_history(vm); tm->trigger(TransferManager::EPILOG_DELETE,vid); break; diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index 7ccb90c74b..811c8fce9a 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -263,11 +263,15 @@ void Nebula::start() try { - string mac_prefix; int size; + + string mac_prefix; string default_image_type; string default_device_prefix; + time_t expiration_time; + time_t vm_expiration; + time_t host_expiration; vector vm_hooks; vector host_hooks; @@ -282,12 +286,20 @@ void Nebula::start() nebula_configuration->get("VM_RESTRICTED_ATTR", vm_restricted_attrs); nebula_configuration->get("IMAGE_RESTRICTED_ATTR", img_restricted_attrs); + nebula_configuration->get("VM_MONITORING_EXPIRATION_TIME",vm_expiration); + nebula_configuration->get("HOST_MONITORING_EXPIRATION_TIME",host_expiration); + vmpool = new VirtualMachinePool(db, vm_hooks, hook_location, remotes_location, - vm_restricted_attrs); - hpool = new HostPool(db, host_hooks, hook_location, remotes_location); + vm_restricted_attrs, + vm_expiration); + hpool = new HostPool( db, + host_hooks, + hook_location, + remotes_location, + host_expiration); nebula_configuration->get("MAC_PREFIX", mac_prefix); nebula_configuration->get("NETWORK_SIZE", size); diff --git a/src/nebula/NebulaTemplate.cc b/src/nebula/NebulaTemplate.cc index db998d2a17..7a86acdda2 100644 --- a/src/nebula/NebulaTemplate.cc +++ b/src/nebula/NebulaTemplate.cc @@ -90,8 +90,10 @@ void OpenNebulaTemplate::set_conf_default() #------------------------------------------------------------------------------- # HOST_MONITORING_INTERVAL # HOST_PER_INTERVAL +# HOST_MONITORING_EXPIRATION_TIME # VM_POLLING_INTERVAL -# VM_PER_INTERVAL +# VM_PER_INTERVAL +# VM_MONITORING_EXPIRATION_TIME # PORT # DB # VNC_BASE_PORT @@ -110,6 +112,12 @@ void OpenNebulaTemplate::set_conf_default() attribute = new SingleAttribute("HOST_PER_INTERVAL",value); conf_default.insert(make_pair(attribute->name(),attribute)); + // HOST_MONITORING_EXPIRATION_TIME + value = "86400"; + + attribute = new SingleAttribute("HOST_MONITORING_EXPIRATION_TIME",value); + conf_default.insert(make_pair(attribute->name(),attribute)); + // POLL_INTERVAL value = "600"; @@ -122,6 +130,12 @@ void OpenNebulaTemplate::set_conf_default() attribute = new SingleAttribute("VM_PER_INTERVAL",value); conf_default.insert(make_pair(attribute->name(),attribute)); + // VM_MONITORING_EXPIRATION_TIME + value = "86400"; + + attribute = new SingleAttribute("VM_MONITORING_EXPIRATION_TIME",value); + conf_default.insert(make_pair(attribute->name(),attribute)); + //XML-RPC Server PORT value = "2633"; diff --git a/src/oca/java/src/org/opennebula/client/host/Host.java b/src/oca/java/src/org/opennebula/client/host/Host.java index facfcc57c7..67bf66f9f0 100644 --- a/src/oca/java/src/org/opennebula/client/host/Host.java +++ b/src/oca/java/src/org/opennebula/client/host/Host.java @@ -33,6 +33,7 @@ public class Host extends PoolElement{ private static final String DELETE = METHOD_PREFIX + "delete"; private static final String ENABLE = METHOD_PREFIX + "enable"; private static final String UPDATE = METHOD_PREFIX + "update"; + private static final String MONITORING = METHOD_PREFIX + "monitoring"; private static final String[] HOST_STATES = {"INIT", "MONITORING_MONITORED", "MONITORED", "ERROR", "DISABLED", @@ -171,6 +172,19 @@ public class Host extends PoolElement{ return client.call(UPDATE, id, new_template); } + /** + * Retrieves the monitoring information of the given host, in XML + * + * @param client XML-RPC Client. + * @param id The host id (hid) of the target machine. + * @return If successful the message contains the string + * with the monitoring information returned by OpenNebula. + */ + public static OneResponse monitoring(Client client, int id) + { + return client.call(MONITORING, id); + } + // ================================= // Instanced object XML-RPC methods // ================================= @@ -239,6 +253,17 @@ public class Host extends PoolElement{ return update(client, id, new_template); } + /** + * Retrieves the monitoring information of the given host, in XML + * + * @return If successful the message contains the string + * with the monitoring information returned by OpenNebula. + */ + public OneResponse monitoring() + { + return monitoring(client, id); + } + // ================================= // Helpers // ================================= diff --git a/src/oca/java/src/org/opennebula/client/host/HostPool.java b/src/oca/java/src/org/opennebula/client/host/HostPool.java index d44fc847da..b6dd182136 100644 --- a/src/oca/java/src/org/opennebula/client/host/HostPool.java +++ b/src/oca/java/src/org/opennebula/client/host/HostPool.java @@ -33,6 +33,7 @@ public class HostPool extends Pool implements Iterable{ private static final String ELEMENT_NAME = "HOST"; private static final String INFO_METHOD = "hostpool.info"; + private static final String MONITORING = "hostpool.monitoring"; /** * Creates a new host pool @@ -61,6 +62,18 @@ public class HostPool extends Pool implements Iterable{ return Pool.info(client, INFO_METHOD); } + /** + * Retrieves the monitoring data for all the hosts in the pool. + * + * @param client XML-RPC Client. + * @return If successful the message contains the string + * with the information returned by OpenNebula. + */ + public static OneResponse monitoring(Client client) + { + return client.call(MONITORING); + } + /** * Loads the xml representation of the host pool. * @@ -71,6 +84,17 @@ public class HostPool extends Pool implements Iterable{ return super.info(); } + /** + * Retrieves the monitoring data for all the hosts in the pool. + * + * @return If successful the message contains the string + * with the information returned by OpenNebula. + */ + public OneResponse monitoring() + { + return monitoring(client); + } + public Iterator iterator() { AbstractList ab = new AbstractList() diff --git a/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java b/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java index bec5a7bafa..c8147d5b35 100644 --- a/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java +++ b/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java @@ -36,6 +36,7 @@ public class VirtualMachine extends PoolElement{ private static final String SAVEDISK = METHOD_PREFIX + "savedisk"; private static final String CHOWN = METHOD_PREFIX + "chown"; private static final String CHMOD = METHOD_PREFIX + "chmod"; + private static final String MONITORING = METHOD_PREFIX + "monitoring"; private static final String[] VM_STATES = { @@ -216,6 +217,19 @@ public class VirtualMachine extends PoolElement{ return chmod(client, CHMOD, id, octet); } + /** + * Retrieves the monitoring information of the given VM, in XML + * + * @param client XML-RPC Client. + * @param id The virtual machine id (vid) of the target instance. + * @return If successful the message contains the string + * with the monitoring information returned by OpenNebula. + */ + public static OneResponse monitoring(Client client, int id) + { + return client.call(MONITORING, id); + } + // ================================= // Instanced object XML-RPC methods // ================================= @@ -395,6 +409,17 @@ public class VirtualMachine extends PoolElement{ return chmod(client, id, octet); } + /** + * Retrieves the monitoring information of the given VM, in XML + * + * @return If successful the message contains the string + * with the monitoring information returned by OpenNebula. + */ + public OneResponse monitoring() + { + return monitoring(client, id); + } + // ================================= // Helpers // ================================= diff --git a/src/oca/java/src/org/opennebula/client/vm/VirtualMachinePool.java b/src/oca/java/src/org/opennebula/client/vm/VirtualMachinePool.java index 9fc1de28fd..a15b379ebd 100644 --- a/src/oca/java/src/org/opennebula/client/vm/VirtualMachinePool.java +++ b/src/oca/java/src/org/opennebula/client/vm/VirtualMachinePool.java @@ -33,6 +33,7 @@ public class VirtualMachinePool extends Pool implements Iterable private static final String ELEMENT_NAME = "VM"; private static final String INFO_METHOD = "vmpool.info"; + private static final String MONITORING = "vmpool.monitoring"; /** * Flag for Virtual Machines in any state. @@ -173,6 +174,27 @@ public class VirtualMachinePool extends Pool implements Iterable return client.call(INFO_METHOD, filter, startId, endId, state); } + /** + * Retrieves the monitoring data for all or part of the Virtual + * Machines in the pool. + * + * @param client XML-RPC Client. + * @param filter Filter flag to use. Possible values: + *
    + *
  • {@link Pool#ALL}: All Virtual Machines
  • + *
  • {@link Pool#MINE}: Connected user's Virtual Machines
  • + *
  • {@link Pool#MINE_GROUP}: Connected user's Virtual Machines, and + * the ones in his group
  • + *
  • >= 0: UID User's Virtual Machines
  • + *
+ * @return If successful the message contains the string + * with the information returned by OpenNebula. + */ + public static OneResponse monitoring(Client client, int filter) + { + return client.call(MONITORING, filter); + } + /** * Loads the xml representation of all or part of the * Virtual Machines in the pool. The filter used is the one set in @@ -255,6 +277,26 @@ public class VirtualMachinePool extends Pool implements Iterable return response; } + /** + * Retrieves the monitoring data for all or part of the Virtual + * Machines in the pool. + * + * @param filter Filter flag to use. Possible values: + *
    + *
  • {@link Pool#ALL}: All Virtual Machines
  • + *
  • {@link Pool#MINE}: Connected user's Virtual Machines
  • + *
  • {@link Pool#MINE_GROUP}: Connected user's Virtual Machines, and + * the ones in his group
  • + *
  • >= 0: UID User's Virtual Machines
  • + *
+ * @return If successful the message contains the string + * with the information returned by OpenNebula. + */ + public OneResponse monitoring(int filter) + { + return monitoring(client, filter); + } + public Iterator iterator() { AbstractList ab = new AbstractList() diff --git a/src/oca/ruby/OpenNebula/Host.rb b/src/oca/ruby/OpenNebula/Host.rb index 1029b2ea1e..e56cd64fc4 100644 --- a/src/oca/ruby/OpenNebula/Host.rb +++ b/src/oca/ruby/OpenNebula/Host.rb @@ -25,11 +25,12 @@ module OpenNebula HOST_METHODS = { - :info => "host.info", - :allocate => "host.allocate", - :delete => "host.delete", - :enable => "host.enable", - :update => "host.update" + :info => "host.info", + :allocate => "host.allocate", + :delete => "host.delete", + :enable => "host.enable", + :update => "host.update", + :monitoring => "host.monitoring" } HOST_STATES=%w{INIT MONITORING_MONITORED MONITORED ERROR DISABLED MONITORING_ERROR} @@ -113,6 +114,39 @@ module OpenNebula super(HOST_METHODS[:update], new_template) end + # Retrieves this Host's monitoring data from OpenNebula + # + # @param [Array] xpath_expressions Elements to retrieve. + # + # @return [Hash>>, OpenNebula::Error] Hash with + # the requested xpath expressions, and an Array of 'timestamp, value'. + # + # @example + # host.monitoring( ['HOST_SHARE/FREE_CPU', 'HOST_SHARE/RUNNING_VMS'] ) + # + # { "HOST_SHARE/RUNNING_VMS" => + # [["1337266000", "1"], + # ["1337266044", "1"], + # ["1337266088", "3"]], + # "HOST_SHARE/FREE_CPU" => + # [["1337266000", "800"], + # ["1337266044", "800"], + # ["1337266088", "800"]] + # } + def monitoring(xpath_expressions) + return super(HOST_METHODS[:monitoring], 'HOST', + 'LAST_MON_TIME', xpath_expressions) + end + + # Retrieves this Host's monitoring data from OpenNebula, in XML + # + # @return [String] Monitoring data, in XML + def monitoring_xml() + return Error.new('ID not defined') if !@pe_id + + return @client.call(HOST_METHODS[:monitoring], @pe_id) + end + ####################################################################### # Helpers to get Host information ####################################################################### diff --git a/src/oca/ruby/OpenNebula/HostPool.rb b/src/oca/ruby/OpenNebula/HostPool.rb index 4a87b54303..8d71712d5a 100644 --- a/src/oca/ruby/OpenNebula/HostPool.rb +++ b/src/oca/ruby/OpenNebula/HostPool.rb @@ -25,7 +25,8 @@ module OpenNebula HOST_POOL_METHODS = { - :info => "hostpool.info" + :info => "hostpool.info", + :monitoring => "hostpool.monitoring" } ####################################################################### @@ -51,5 +52,40 @@ module OpenNebula def info() super(HOST_POOL_METHODS[:info]) end + + # Retrieves the monitoring data for all the Hosts in the pool + # + # @param [Array] xpath_expressions Elements to retrieve. + # + # @return [Hash>>>>, + # OpenNebula::Error] The first level hash uses the Host ID as keys, + # and as value a Hash with the requested xpath expressions, + # and an Array of 'timestamp, value'. + # + # @example + # host_pool.monitoring( + # ['HOST_SHARE/FREE_CPU', + # 'HOST_SHARE/RUNNING_VMS', + # 'TEMPLATE/CUSTOM_PROBE'] ) + # + # {"1"=> + # {"TEMPLATE/CUSTOM_PROBE"=>[], + # "HOST_SHARE/FREE_CPU"=>[["1337609673", "800"]], + # "HOST_SHARE/RUNNING_VMS"=>[["1337609673", "3"]]}, + # "0"=> + # {"TEMPLATE/CUSTOM_PROBE"=>[], + # "HOST_SHARE/FREE_CPU"=>[["1337609673", "800"]], + # "HOST_SHARE/RUNNING_VMS"=>[["1337609673", "3"]]}} + def monitoring(xpath_expressions) + return super(HOST_POOL_METHODS[:monitoring], + 'HOST', 'LAST_MON_TIME', xpath_expressions) + end + + # Retrieves the monitoring data for all the Hosts in the pool, in XML + # + # @return [String] VM monitoring data, in XML + def monitoring_xml() + return @client.call(HOST_POOL_METHODS[:monitoring]) + end end end diff --git a/src/oca/ruby/OpenNebula/Pool.rb b/src/oca/ruby/OpenNebula/Pool.rb index 3aaa3bbada..e29cf7c7c7 100644 --- a/src/oca/ruby/OpenNebula/Pool.rb +++ b/src/oca/ruby/OpenNebula/Pool.rb @@ -70,6 +70,51 @@ module OpenNebula return xmlrpc_info(xml_method,who, start_id, end_id) end + # Retrieves the monitoring data for all the Objects in the pool + # + # @param [String] xml_method xml-rcp method + # @param [String] root_elem Root for each individual PoolElement + # @param [String] timestamp_elem Name of the XML element with the last + # monitorization timestamp + # @param [Array] xpath_expressions Elements to retrieve. + # @param args arguemnts for the xml_method call + # + # @return [Hash>>>>, + # OpenNebula::Error] The first level hash uses the Object ID as keys, + # and as value a Hash with the requested xpath expressions, + # and an Array of 'timestamp, value'. + def monitoring(xml_method, root_elem, timestamp_elem, xpath_expressions, + *args) + + rc = @client.call(xml_method, *args) + + if ( OpenNebula.is_error?(rc) ) + return rc + end + + xmldoc = XMLElement.new + xmldoc.initialize_xml(rc, 'MONITORING_DATA') + + hash = {} + + # Get all existing Object IDs + ids = xmldoc.retrieve_elements("#{root_elem}/ID") + + if ids.nil? + return hash + else + ids.uniq! + end + + ids.each { |id| + hash[id] = OpenNebula.process_monitoring( + xmldoc, root_elem, timestamp_elem, id, xpath_expressions) + + } + + return hash + end + private # Calls to the corresponding info method to retreive the pool # representation in XML format @@ -255,6 +300,35 @@ module OpenNebula return rc end + + # Retrieves this Element's monitoring data from OpenNebula + # + # @param [String] xml_method the name of the XML-RPC method + # @param [String] root_elem Root for each individual PoolElement + # @param [String] timestamp_elem Name of the XML element with the last + # monitorization timestamp + # @param xpath_expressions [Array] Xpath expressions for the + # elements to retrieve. + # + # @return [Hash>, OpenNebula::Error] Hash with + # the requested xpath expressions, and an Array of [timestamp, value]. + def monitoring(xml_method, root_elem, timestamp_elem, xpath_expressions) + return Error.new('ID not defined') if !@pe_id + + rc = @client.call(xml_method, @pe_id) + + if ( OpenNebula.is_error?(rc) ) + return rc + end + + xmldoc = XMLElement.new + xmldoc.initialize_xml(rc, 'MONITORING_DATA') + + + return OpenNebula.process_monitoring( + xmldoc, root_elem, timestamp_elem, @pe_id, xpath_expressions) + end + public # Creates new element specifying its id @@ -284,4 +358,34 @@ module OpenNebula return str end end + + # Processes the monitoring data in XML returned by OpenNebula + # + # @param [XMLElement] xmldoc monitoring data returned by OpenNebula + # @param [String] root_elem Root for each individual PoolElement + # @param [String] timestamp_elem Name of the XML element with the last + # monitorization timestamp + # @param [Integer] Id of the object to process + # @param [Array] xpath_expressions Elements to retrieve. + # @param args arguemnts for the xml_method call + # + # @return [Hash>, OpenNebula::Error] Hash with + # the requested xpath expressions, and an Array of [timestamp, value]. + def self.process_monitoring(xmldoc, root_elem, timestamp_elem, oid, xpath_expressions) + hash = {} + timestamps = xmldoc.retrieve_elements( + "#{root_elem}[ID=#{oid}]/#{timestamp_elem}") + + xpath_expressions.each { |xpath| + xpath_values = xmldoc.retrieve_elements("#{root_elem}[ID=#{oid}]/#{xpath}") + + if ( xpath_values.nil? ) + hash[xpath] = [] + else + hash[xpath] = timestamps.zip(xpath_values) + end + } + + return hash + end end diff --git a/src/oca/ruby/OpenNebula/VirtualMachine.rb b/src/oca/ruby/OpenNebula/VirtualMachine.rb index 28d281d354..fd8f126366 100644 --- a/src/oca/ruby/OpenNebula/VirtualMachine.rb +++ b/src/oca/ruby/OpenNebula/VirtualMachine.rb @@ -25,14 +25,15 @@ module OpenNebula VM_METHODS = { - :info => "vm.info", - :allocate => "vm.allocate", - :action => "vm.action", - :migrate => "vm.migrate", - :deploy => "vm.deploy", - :savedisk => "vm.savedisk", - :chown => "vm.chown", - :chmod => "vm.chmod", + :info => "vm.info", + :allocate => "vm.allocate", + :action => "vm.action", + :migrate => "vm.migrate", + :deploy => "vm.deploy", + :savedisk => "vm.savedisk", + :chown => "vm.chown", + :chmod => "vm.chmod", + :monitoring => "vm.monitoring" } VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED} @@ -280,6 +281,41 @@ module OpenNebula group_m, group_a, other_u, other_m, other_a) end + # Retrieves this VM's monitoring data from OpenNebula + # + # @param [Array] xpath_expressions Elements to retrieve. + # + # @return [Hash>>, OpenNebula::Error] Hash with + # the requested xpath expressions, and an Array of 'timestamp, value'. + # + # @example + # vm.monitoring( ['CPU', 'NET_TX', 'TEMPLATE/CUSTOM_PROBE'] ) + # + # { "NET_TX" => + # [["1337264510", "210"], + # ["1337264553", "220"], + # ["1337264584", "230"]], + # "TEMPLATE/CUSTOM_PROBE" => + # [], + # "CPU" => + # [["1337264510", "0"], + # ["1337264553", "0"], + # ["1337264584", "0"]] + # } + def monitoring(xpath_expressions) + return super(VM_METHODS[:monitoring], 'VM', + 'LAST_POLL', xpath_expressions) + end + + # Retrieves this VM's monitoring data from OpenNebula, in XML + # + # @return [String] VM monitoring data, in XML + def monitoring_xml() + return Error.new('ID not defined') if !@pe_id + + return @client.call(VM_METHODS[:monitoring], @pe_id) + end + ####################################################################### # Helpers to get VirtualMachine information ####################################################################### diff --git a/src/oca/ruby/OpenNebula/VirtualMachinePool.rb b/src/oca/ruby/OpenNebula/VirtualMachinePool.rb index aaf3a18546..01dc59fdcf 100644 --- a/src/oca/ruby/OpenNebula/VirtualMachinePool.rb +++ b/src/oca/ruby/OpenNebula/VirtualMachinePool.rb @@ -25,7 +25,8 @@ module OpenNebula VM_POOL_METHODS = { - :info => "vmpool.info" + :info => "vmpool.info", + :monitoring => "vmpool.monitoring" } # Constants for info queries (include/RequestManagerPoolInfoFilter.h) @@ -111,6 +112,50 @@ module OpenNebula INFO_NOT_DONE) end + # Retrieves the monitoring data for all the VMs in the pool + # + # @param [Array] xpath_expressions Elements to retrieve. + # @param [Integer] filter_flag Optional filter flag to retrieve all or + # part of the Pool. Possible values: INFO_ALL, INFO_GROUP, INFO_MINE. + # + # @return [Hash>>>>, + # OpenNebula::Error] The first level hash uses the VM ID as keys, and + # as value a Hash with the requested xpath expressions, + # and an Array of 'timestamp, value'. + # + # @example + # vm_pool.monitoring( ['CPU', 'NET_TX', 'TEMPLATE/CUSTOM_PROBE'] ) + # + # {"1"=> + # {"CPU"=> + # [["1337608271", "0"], ["1337608301", "0"], ["1337608331", "0"]], + # "NET_TX"=> + # [["1337608271", "510"], ["1337608301", "510"], ["1337608331", "520"]], + # "TEMPLATE/CUSTOM_PROBE"=> + # []}, + # + # "0"=> + # {"CPU"=> + # [["1337608271", "0"], ["1337608301", "0"], ["1337608331", "0"]], + # "NET_TX"=> + # [["1337608271", "510"], ["1337608301", "510"], ["1337608331", "520"]], + # "TEMPLATE/CUSTOM_PROBE"=> + # []}} + def monitoring(xpath_expressions, filter_flag=INFO_ALL) + return super(VM_POOL_METHODS[:monitoring], + 'VM', 'LAST_POLL', xpath_expressions, filter_flag) + end + + # Retrieves the monitoring data for all the VMs in the pool, in XML + # + # @param [Integer] filter_flag Optional filter flag to retrieve all or + # part of the Pool. Possible values: INFO_ALL, INFO_GROUP, INFO_MINE. + # + # @return [String] VM monitoring data, in XML + def monitoring_xml(filter_flag=INFO_ALL) + return @client.call(VM_POOL_METHODS[:monitoring], filter_flag) + end + private def info_filter(xml_method, who, start_id, end_id, state) diff --git a/src/rm/Request.cc b/src/rm/Request.cc index bd5b9a9f82..d3ffafdf9a 100644 --- a/src/rm/Request.cc +++ b/src/rm/Request.cc @@ -61,11 +61,6 @@ bool Request::basic_authorization(int oid, PoolObjectSQL * object; PoolObjectAuth perms; - if ( att.uid == 0 ) - { - return true; - } - if ( oid >= 0 ) { object = pool->get(oid,true); @@ -78,12 +73,23 @@ bool Request::basic_authorization(int oid, return false; } + if ( att.uid == 0 ) + { + object->unlock(); + return true; + } + object->get_permissions(perms); object->unlock(); } else { + if ( att.uid == 0 ) + { + return true; + } + perms.obj_type = auth_object; } diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index e2413c867c..8ce9deaec9 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -243,7 +243,9 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr vm_migrate(new VirtualMachineMigrate()); xmlrpc_c::methodPtr vm_action(new VirtualMachineAction()); xmlrpc_c::methodPtr vm_savedisk(new VirtualMachineSaveDisk()); + xmlrpc_c::methodPtr vm_monitoring(new VirtualMachineMonitoring()); xmlrpc_c::methodPtr vm_pool_acct(new VirtualMachinePoolAccounting()); + xmlrpc_c::methodPtr vm_pool_monitoring(new VirtualMachinePoolMonitoring()); // VirtualNetwork Methods xmlrpc_c::methodPtr vn_addleases(new VirtualNetworkAddLeases()); @@ -304,6 +306,8 @@ void RequestManager::register_xml_methods() // Host Methods xmlrpc_c::methodPtr host_enable(new HostEnable()); + xmlrpc_c::methodPtr host_monitoring(new HostMonitoring()); + xmlrpc_c::methodPtr host_pool_monitoring(new HostPoolMonitoring()); // Image Methods xmlrpc_c::methodPtr image_persistent(new ImagePersistent()); @@ -347,9 +351,11 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.vm.info", vm_info); RequestManagerRegistry.addMethod("one.vm.chown", vm_chown); RequestManagerRegistry.addMethod("one.vm.chmod", vm_chmod); + RequestManagerRegistry.addMethod("one.vm.monitoring", vm_monitoring); RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info); RequestManagerRegistry.addMethod("one.vmpool.accounting", vm_pool_acct); + RequestManagerRegistry.addMethod("one.vmpool.monitoring", vm_pool_monitoring); /* VM Template related methods*/ RequestManagerRegistry.addMethod("one.template.update", template_update); @@ -369,8 +375,10 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.host.allocate", host_allocate); RequestManagerRegistry.addMethod("one.host.delete", host_delete); RequestManagerRegistry.addMethod("one.host.info", host_info); + RequestManagerRegistry.addMethod("one.host.monitoring", host_monitoring); RequestManagerRegistry.addMethod("one.hostpool.info", hostpool_info); + RequestManagerRegistry.addMethod("one.hostpool.monitoring", host_pool_monitoring); /* Group related methods */ RequestManagerRegistry.addMethod("one.group.allocate", group_allocate); diff --git a/src/rm/RequestManagerHost.cc b/src/rm/RequestManagerHost.cc index f4f1b1fd9d..e59a6b3dcf 100644 --- a/src/rm/RequestManagerHost.cc +++ b/src/rm/RequestManagerHost.cc @@ -67,3 +67,33 @@ void HostEnable::request_execute(xmlrpc_c::paramList const& paramList, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void HostMonitoring::request_execute( + xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + int id = xmlrpc_c::value_int(paramList.getInt(1)); + int rc; + + ostringstream oss; + + if ( basic_authorization(id, att) == false ) + { + return; + } + + rc = (static_cast(pool))->dump_monitoring(oss, id); + + if ( rc != 0 ) + { + failure_response(INTERNAL,request_error("Internal Error",""), att); + return; + } + + success_response(oss.str(), att); + + return; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + diff --git a/src/rm/RequestManagerPoolInfoFilter.cc b/src/rm/RequestManagerPoolInfoFilter.cc index e48e23d237..53b4f3c225 100644 --- a/src/rm/RequestManagerPoolInfoFilter.cc +++ b/src/rm/RequestManagerPoolInfoFilter.cc @@ -131,6 +131,42 @@ void VirtualMachinePoolAccounting::request_execute( /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +void VirtualMachinePoolMonitoring::request_execute( + xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + int filter_flag = xmlrpc_c::value_int(paramList.getInt(1)); + + ostringstream oss; + string where; + int rc; + + if ( filter_flag < MINE ) + { + failure_response(XML_RPC_API, + request_error("Incorrect filter_flag",""), + att); + return; + } + + where_filter(att, filter_flag, -1, -1, "", "", where); + + rc = (static_cast(pool))->dump_monitoring(oss, where); + + if ( rc != 0 ) + { + failure_response(INTERNAL,request_error("Internal Error",""), att); + return; + } + + success_response(oss.str(), att); + + return; +} + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + void HostPoolInfo::request_execute( xmlrpc_c::paramList const& paramList, RequestAttributes& att) @@ -141,6 +177,32 @@ void HostPoolInfo::request_execute( /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +void HostPoolMonitoring::request_execute( + xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + ostringstream oss; + string where; + int rc; + + where_filter(att, ALL, -1, -1, "", "", where); + + rc = (static_cast(pool))->dump_monitoring(oss, where); + + if ( rc != 0 ) + { + failure_response(INTERNAL,request_error("Internal Error",""), att); + return; + } + + success_response(oss.str(), att); + + return; +} + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + void GroupPoolInfo::request_execute( xmlrpc_c::paramList const& paramList, RequestAttributes& att) diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index fbfdcc102d..ab2908045c 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -21,21 +21,17 @@ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -bool RequestManagerVirtualMachine::vm_authorization(int oid, - ImageTemplate * tmpl, - RequestAttributes& att, - PoolObjectAuth * host_perm, - PoolObjectAuth * ds_perm, - AuthRequest::Operation op) +bool RequestManagerVirtualMachine::vm_authorization( + int oid, + ImageTemplate * tmpl, + RequestAttributes& att, + PoolObjectAuth * host_perm, + PoolObjectAuth * ds_perm, + AuthRequest::Operation op) { PoolObjectSQL * object; PoolObjectAuth vm_perms; - if ( att.uid == 0 ) - { - return true; - } - object = pool->get(oid,true); if ( object == 0 ) @@ -47,6 +43,12 @@ bool RequestManagerVirtualMachine::vm_authorization(int oid, return false; } + if ( att.uid == 0 ) + { + object->unlock(); + return true; + } + object->get_permissions(vm_perms); object->unlock(); @@ -139,6 +141,7 @@ VirtualMachine * RequestManagerVirtualMachine::get_vm(int id, return vm; } + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -174,6 +177,7 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ + void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList, RequestAttributes& att) { @@ -577,3 +581,35 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ + +void VirtualMachineMonitoring::request_execute( + xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + int id = xmlrpc_c::value_int(paramList.getInt(1)); + int rc; + + ostringstream oss; + + bool auth = vm_authorization(id, 0, att, 0, 0, auth_op); + + if ( auth == false ) + { + return; + } + + rc = (static_cast(pool))->dump_monitoring(oss, id); + + if ( rc != 0 ) + { + failure_response(INTERNAL,request_error("Internal Error",""), att); + return; + } + + success_response(oss.str(), att); + + return; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ diff --git a/src/sunstone/models/SunstoneServer.rb b/src/sunstone/models/SunstoneServer.rb index 9892e53b7a..3083a7e589 100644 --- a/src/sunstone/models/SunstoneServer.rb +++ b/src/sunstone/models/SunstoneServer.rb @@ -19,7 +19,6 @@ require 'CloudServer' require 'OpenNebulaJSON' include OpenNebulaJSON -require 'acct/watch_client' require 'OpenNebulaVNC' require 'OpenNebulaJSON/JSONUtils' include JSONUtils @@ -253,37 +252,60 @@ class SunstoneServer < CloudServer ############################################################################ # ############################################################################ - def get_monitoring(id, resource, monitor_resources, opts={}) - watch_client = case resource - when "vm","VM" - OneWatchClient::VmWatchClient.new - when "host","HOST" - OneWatchClient::HostWatchClient.new + def get_pool_monitoring(resource, meters) + #pool_element + pool = case resource + when "vm", "VM" + VirtualMachinePool.new(@client) + when "host", "HOST" + HostPool.new(@client) else - error = Error.new("Monitoring not supported for this resource: #{resource}") + error = Error.new("Monitoring not supported for #{resource}") return [200, error.to_json] end - filter = {} - filter[:uid] = opts[:uid] if opts[:gid]!=0 + meters_a = meters.split(',') - columns = monitor_resources.split(',') - columns.map!{|e| e.to_sym} + rc = pool.monitoring(meters_a) - if id - rc = watch_client.resource_monitoring(id.to_i, columns, filter) - else - rc = watch_client.total_monitoring(columns, filter) - end - - if rc.nil? - error = Error.new("There is no monitoring information for #{resource} #{id}") + if OpenNebula.is_error?(rc) + error = Error.new(rc.message) return [500, error.to_json] end + rc[:resource] = resource + return [200, rc.to_json] end + def get_resource_monitoring(id, resource, meters) + pool_element = case resource + when "vm", "VM" + VirtualMachine.new_with_id(id, @client) + when "host", "HOST" + Host.new_with_id(id, @client) + else + error = Error.new("Monitoring not supported for #{resource}") + return [200, error.to_json] + end + + meters_a = meters.split(',') + + rc = pool_element.monitoring(meters_a) + + if OpenNebula.is_error?(rc) + error = Error.new(rc.message) + return [500, error.to_json] + end + + meters_h = Hash.new + meters_h[:resource] = resource + meters_h[:id] = id + meters_h[:monitoring] = rc + + return [200, meters_h.to_json] + end + private ############################################################################ diff --git a/src/sunstone/public/js/plugins/dashboard-tab.js b/src/sunstone/public/js/plugins/dashboard-tab.js index 674e4180bf..33db3ed62c 100644 --- a/src/sunstone/public/js/plugins/dashboard-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-tab.js @@ -20,13 +20,13 @@ var GRAPH_AUTOREFRESH_INTERVAL=60000; //60 secs var graph1 = { title : "graph1", - monitor_resources : "cpu_usage,used_cpu,max_cpu", + monitor_resources : "HOST_SHARE/CPU_USAGE,HOST_SHARE/USED_CPU,HOST_SHARE/MAX_CPU", history_length : HISTORY_LENGTH }; var graph2 = { title : "graph2", - monitor_resources : "mem_usage,used_mem,max_mem", + monitor_resources : "HOST_SHARE/MEM_USAGE,HOST_SHARE/USED_MEM,HOST_SHARE/MAX_MEM", history_length : HISTORY_LENGTH }; @@ -38,7 +38,7 @@ var graph3 = { var graph4 = { title : "graph4", - monitor_resources : "net_tx,net_rx", + monitor_resources : "NET_TX,NET_RX", history_length : HISTORY_LENGTH }; @@ -134,6 +134,7 @@ var dashboard_tab_content =
\

' + tr("Historical monitoring information") + '

\
\ +\
\
\ \ @@ -227,8 +229,8 @@ function refresh_graphs(){ $(document).ready(function(){ emptyDashboard(); - refresh_graphs(); - graph_autorefresh(); +// refresh_graphs(); +// graph_autorefresh(); }); diff --git a/src/sunstone/public/js/plugins/dashboard-users-tab.js b/src/sunstone/public/js/plugins/dashboard-users-tab.js index 289daed88b..c4073cefb6 100644 --- a/src/sunstone/public/js/plugins/dashboard-users-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-users-tab.js @@ -107,6 +107,7 @@ var dashboard_tab_content =
\

'+tr("Historical monitoring information")+'

\
\ +\
\
\ \ diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index c8571f6c4b..32a5316ba0 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -20,13 +20,13 @@ var HOST_HISTORY_LENGTH = 40; var host_graphs = [ { title : tr("CPU Monitoring information"), - monitor_resources : "cpu_usage,used_cpu,max_cpu", + monitor_resources : "HOST_SHARE/CPU_USAGE,HOST_SHARE/USED_CPU,HOST_SHARE/MAX_CPU", humanize_figures : false, history_length : HOST_HISTORY_LENGTH }, { title: tr("Memory monitoring information"), - monitor_resources : "mem_usage,used_mem,max_mem", + monitor_resources : "HOST_SHARE/MEM_USAGE,HOST_SHARE/USED_MEM,HOST_SHARE/MAX_MEM", humanize_figures : true, history_length : HOST_HISTORY_LENGTH } @@ -547,7 +547,7 @@ function updateHostInfo(request,host){ \ \ ' + tr("Used Mem (allocated)") + '\ - '+humanize_size(host_info.HOST_SHARE.MAX_USAGE)+'\ + '+humanize_size(host_info.HOST_SHARE.MEM_USAGE)+'\ \ \ ' + tr("Max CPU") + '\ diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index 3f9a548ac5..5173b5d4d1 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -26,22 +26,22 @@ loadVNC(); var vm_graphs = [ { title : tr("CPU"), - monitor_resources : "cpu_usage", + monitor_resources : "CPU", humanize_figures : false, history_length : VM_HISTORY_LENGTH }, { title : tr("Memory"), - monitor_resources : "mem_usage", + monitor_resources : "MEMORY", humanize_figures : true, history_length : VM_HISTORY_LENGTH }, { title : tr("Network transmission"), - monitor_resources : "net_tx", + monitor_resources : "NET_TX", humanize_figures : true, history_length : VM_HISTORY_LENGTH }, { title : tr("Network reception"), - monitor_resources : "net_rx", + monitor_resources : "NET_RX", humanize_figures : true, history_length : VM_HISTORY_LENGTH } diff --git a/src/sunstone/public/js/sunstone-util.js b/src/sunstone/public/js/sunstone-util.js index 0f9bd76dae..16484f15ae 100644 --- a/src/sunstone/public/js/sunstone-util.js +++ b/src/sunstone/public/js/sunstone-util.js @@ -605,6 +605,7 @@ function generateMonitoringDivs(graphs, id_prefix){ $.each(graphs,function(){ label = this.monitor_resources; id_suffix=label.replace(/,/g,'_'); + id_suffix=id_suffix.replace(/\//g,'_'); id = id_prefix+id_suffix; str+='\ \ @@ -628,6 +629,7 @@ function plot_graph(data,context,id_prefix,info){ var humanize = info.humanize_figures ? humanize_size : function(val){ return val }; var id_suffix = labels.replace(/,/g,'_'); + id_suffix = id_suffix.replace(/\//g,'_'); var labels_array = labels.split(','); var monitoring = data.monitoring var series = []; @@ -661,7 +663,8 @@ function plot_graph(data,context,id_prefix,info){ yaxis : { labelWidth: 40, tickFormatter: function(val, axis) { return humanize(val); - } + }, + min: 0 } }; diff --git a/src/sunstone/sunstone-server.rb b/src/sunstone/sunstone-server.rb index 1dbd19c367..ff52832f6c 100755 --- a/src/sunstone/sunstone-server.rb +++ b/src/sunstone/sunstone-server.rb @@ -289,24 +289,18 @@ end ############################################################################## get '/:resource/monitor' do - @SunstoneServer.get_monitoring( - nil, + @SunstoneServer.get_pool_monitoring( params[:resource], - params[:monitor_resources], - :uid => session[:user_id].to_i, - :gid => session[:user_gid].to_i) + params[:monitor_resources]) end get '/:resource/:id/monitor' do - @SunstoneServer.get_monitoring( + @SunstoneServer.get_resource_monitoring( params[:id], params[:resource], - params[:monitor_resources], - :uid => session[:user_id].to_i, - :gid => session[:user_gid].to_i) + params[:monitor_resources]) end - ############################################################################## # GET Pool information ############################################################################## diff --git a/src/test/NebulaTest.cc b/src/test/NebulaTest.cc index 1527e57982..2a23f8212c 100644 --- a/src/test/NebulaTest.cc +++ b/src/test/NebulaTest.cc @@ -24,13 +24,13 @@ VirtualMachinePool* NebulaTest::create_vmpool(SqlDB* db, string hook_location, vector hooks; vector restricted_attrs; - return new VirtualMachinePool(db, hooks, hook_location, vloc, restricted_attrs); + return new VirtualMachinePool(db, hooks, hook_location, vloc, restricted_attrs, 0); } HostPool* NebulaTest::create_hpool(SqlDB* db, string hook_location, string vloc) { vector hooks; - return new HostPool(db, hooks, hook_location, vloc); + return new HostPool(db, hooks, hook_location, vloc, 0); } VirtualNetworkPool* NebulaTest::create_vnpool(SqlDB* db, string mac_prefix, int size) diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index f3db0feb78..3612f15e84 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -99,9 +99,18 @@ const char * VirtualMachine::db_names = "owner_u, group_u, other_u"; const char * VirtualMachine::db_bootstrap = "CREATE TABLE IF NOT EXISTS " - "vm_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, " - "gid INTEGER, last_poll INTEGER, state INTEGER, lcm_state INTEGER, " - "owner_u INTEGER, group_u INTEGER, other_u INTEGER)"; + "vm_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, " + "gid INTEGER, last_poll INTEGER, state INTEGER, lcm_state INTEGER, " + "owner_u INTEGER, group_u INTEGER, other_u INTEGER)"; + + +const char * VirtualMachine::monit_table = "vm_monitoring"; + +const char * VirtualMachine::monit_db_names = "vmid, last_poll, body"; + +const char * VirtualMachine::monit_db_bootstrap = "CREATE TABLE IF NOT EXISTS " + "vm_monitoring (vmid INTEGER, last_poll INTEGER, body TEXT, " + "PRIMARY KEY(vmid, last_poll))"; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -640,22 +649,14 @@ int VirtualMachine::insert_replace(SqlDB *db, bool replace, string& error_str) int rc; string xml_body; - char * sql_deploy_id; char * sql_name; char * sql_xml; - sql_deploy_id = db->escape_str(deploy_id.c_str()); - - if ( sql_deploy_id == 0 ) - { - goto error_generic; - } - sql_name = db->escape_str(name.c_str()); if ( sql_name == 0 ) { - goto error_name; + goto error_generic; } sql_xml = db->escape_str(to_xml(xml_body).c_str()); @@ -692,7 +693,6 @@ int VirtualMachine::insert_replace(SqlDB *db, bool replace, string& error_str) << group_u << "," << other_u << ")"; - db->free_str(sql_deploy_id); db->free_str(sql_name); db->free_str(sql_xml); @@ -701,7 +701,6 @@ int VirtualMachine::insert_replace(SqlDB *db, bool replace, string& error_str) return rc; error_xml: - db->free_str(sql_deploy_id); db->free_str(sql_name); db->free_str(sql_xml); @@ -710,14 +709,9 @@ error_xml: goto error_common; error_body: - db->free_str(sql_deploy_id); db->free_str(sql_name); goto error_generic; -error_name: - db->free_str(sql_deploy_id); - goto error_generic; - error_generic: error_str = "Error inserting VM in DB."; error_common: @@ -727,6 +721,60 @@ error_common: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int VirtualMachine::update_monitoring(SqlDB * db) +{ + ostringstream oss; + int rc; + + string xml_body; + string error_str; + char * sql_xml; + + sql_xml = db->escape_str(to_xml(xml_body).c_str()); + + if ( sql_xml == 0 ) + { + goto error_body; + } + + if ( validate_xml(sql_xml) != 0 ) + { + goto error_xml; + } + + oss << "INSERT INTO " << monit_table << " ("<< monit_db_names <<") VALUES (" + << oid << "," + << last_poll << "," + << "'" << sql_xml << "')"; + + db->free_str(sql_xml); + + rc = db->exec(oss); + + return rc; + +error_xml: + db->free_str(sql_xml); + + error_str = "could not transform the VM to XML."; + + goto error_common; + +error_body: + error_str = "could not insert the VM in the DB."; + +error_common: + oss.str(""); + oss << "Error updating VM monitoring information, " << error_str; + + NebulaLog::log("ONE",Log::ERROR, oss); + + return -1; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void VirtualMachine::add_history( int hid, const string& hostname, diff --git a/src/vm/VirtualMachinePool.cc b/src/vm/VirtualMachinePool.cc index 7f7fa7d207..e4afafca8a 100644 --- a/src/vm/VirtualMachinePool.cc +++ b/src/vm/VirtualMachinePool.cc @@ -24,11 +24,18 @@ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -VirtualMachinePool::VirtualMachinePool(SqlDB * db, - vector hook_mads, - const string& hook_location, - const string& remotes_location, - vector& restricted_attrs) +time_t VirtualMachinePool::_monitor_expiration; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +VirtualMachinePool::VirtualMachinePool( + SqlDB * db, + vector hook_mads, + const string& hook_location, + const string& remotes_location, + vector& restricted_attrs, + time_t expire_time) : PoolSQL(db, VirtualMachine::table, false) { const VectorAttribute * vattr; @@ -42,6 +49,13 @@ VirtualMachinePool::VirtualMachinePool(SqlDB * db, bool state_hook = false; + _monitor_expiration = expire_time; + + if ( _monitor_expiration == 0 ) + { + clean_all_monitoring(); + } + for (unsigned int i = 0 ; i < hook_mads.size() ; i++ ) { vattr = static_cast(hook_mads[i]); @@ -300,3 +314,66 @@ int VirtualMachinePool::dump_acct(ostringstream& oss, return PoolSQL::dump(oss, "HISTORY_RECORDS", cmd); }; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VirtualMachinePool::clean_expired_monitoring() +{ + if ( _monitor_expiration == 0 ) + { + return 0; + } + + time_t max_last_poll; + int rc; + ostringstream oss; + + max_last_poll = time(0) - _monitor_expiration; + + oss << "DELETE FROM " << VirtualMachine::monit_table + << " WHERE last_poll < " << max_last_poll; + + rc = db->exec(oss); + + return rc; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VirtualMachinePool::clean_all_monitoring() +{ + ostringstream oss; + int rc; + + oss << "DELETE FROM " << VirtualMachine::monit_table; + + rc = db->exec(oss); + + return rc; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VirtualMachinePool::dump_monitoring( + ostringstream& oss, + const string& where) +{ + ostringstream cmd; + + cmd << "SELECT " << VirtualMachine::monit_table << ".body FROM " + << VirtualMachine::monit_table + << " INNER JOIN " << VirtualMachine::table + << " WHERE vmid = oid"; + + if ( !where.empty() ) + { + cmd << " AND " << where; + } + + cmd << " ORDER BY vmid, " << VirtualMachine::monit_table << ".last_poll;"; + + return PoolSQL::dump(oss, "MONITORING_DATA", cmd); +} diff --git a/src/vm/test/VirtualMachinePoolTest.cc b/src/vm/test/VirtualMachinePoolTest.cc index 8f5f7a9ac7..7de93a3707 100644 --- a/src/vm/test/VirtualMachinePoolTest.cc +++ b/src/vm/test/VirtualMachinePoolTest.cc @@ -90,7 +90,8 @@ public: SqlDB * db, vector hook_mads, vector restricted_attrs): - VirtualMachinePool(db, hook_mads, "./", "./", restricted_attrs) + VirtualMachinePool(db, hook_mads, + "./", "./", restricted_attrs, 0) {}; diff --git a/src/vmm/VirtualMachineManager.cc b/src/vmm/VirtualMachineManager.cc index 7f666d31a0..e676f3524f 100644 --- a/src/vmm/VirtualMachineManager.cc +++ b/src/vmm/VirtualMachineManager.cc @@ -1182,6 +1182,9 @@ void VirtualMachineManager::timer_action() mark = 0; } + // Clear the expired monitoring records + vmpool->clean_expired_monitoring(); + // Monitor only VMs that hasn't been monitored for 'poll_period' seconds. rc = vmpool->get_running(oids, vm_limit, thetime - poll_period); diff --git a/src/vmm/VirtualMachineManagerDriver.cc b/src/vmm/VirtualMachineManagerDriver.cc index bb130cbc12..651d9bbefe 100644 --- a/src/vmm/VirtualMachineManagerDriver.cc +++ b/src/vmm/VirtualMachineManagerDriver.cc @@ -435,6 +435,7 @@ void VirtualMachineManagerDriver::protocol( vmpool->update(vm); vmpool->update_history(vm); + vmpool->update_monitoring(vm); if (state != '-' && (vm->get_lcm_state() == VirtualMachine::RUNNING ||
'+this.title+'