From c1786016237fcabd351bedc2a92d4be35aec4503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 4 May 2012 17:27:57 +0200 Subject: [PATCH 01/27] Feature #1099: Add new one.vmpool.accounting XMLRPC method --- include/History.h | 8 +- include/PoolSQL.h | 13 +++ include/RequestManagerPoolInfoFilter.h | 42 ++++++++- include/VirtualMachine.h | 9 +- include/VirtualMachinePool.h | 2 +- src/pool/PoolSQL.cc | 27 ++++-- src/rm/RequestManager.cc | 2 + src/rm/RequestManagerPoolInfoFilter.cc | 116 +++++++++++++++++++++---- src/vm/History.cc | 10 ++- 9 files changed, 193 insertions(+), 36 deletions(-) diff --git a/include/History.h b/include/History.h index e124ec7a2e..689947bf62 100644 --- a/include/History.h +++ b/include/History.h @@ -62,6 +62,12 @@ public: */ string& to_xml(string& xml) const; + // ---------------------------------------- + // DataBase implementation variables + // ---------------------------------------- + + static const char * table; + private: friend class VirtualMachine; friend class VirtualMachinePool; @@ -70,8 +76,6 @@ private: // DataBase implementation variables // ---------------------------------------- - static const char * table; - static const char * db_names; static const char * db_bootstrap; diff --git a/include/PoolSQL.h b/include/PoolSQL.h index c127d075e6..d29903e678 100644 --- a/include/PoolSQL.h +++ b/include/PoolSQL.h @@ -154,6 +154,19 @@ public: */ virtual int dump(ostringstream& oss, const string& where) = 0; + /** + * Dumps the output of the custom sql query into an xml + * + * @param oss The output stream to dump the xml contents + * @param root_elem_name Name of the root xml element name + * @param sql_query The SQL query to execute + * + * @return 0 on success + */ + int custom_dump(ostringstream& oss, + const string& root_elem_name, + ostringstream& sql_query); + protected: /** diff --git a/include/RequestManagerPoolInfoFilter.h b/include/RequestManagerPoolInfoFilter.h index 2270f7c471..d657138f15 100644 --- a/include/RequestManagerPoolInfoFilter.h +++ b/include/RequestManagerPoolInfoFilter.h @@ -56,11 +56,22 @@ protected: /* -------------------------------------------------------------------- */ - void dump(RequestAttributes& att, + void generate_where_string( + RequestAttributes& att, + int filter_flag, + int start_id, + int end_id, + const string& and_clause, + const string& or_clause, + ostringstream& where_string); + + /* -------------------------------------------------------------------- */ + + void dump(RequestAttributes& att, int filter_flag, - int start_id, + int start_id, int end_id, - const string& and_clause, + const string& and_clause, const string& or_clause); }; @@ -98,6 +109,31 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +class VirtualMachinePoolAccounting : public RequestManagerPoolInfoFilter +{ +public: + + VirtualMachinePoolAccounting(): + RequestManagerPoolInfoFilter("VirtualMachinePoolAccounting", + "Returns the virtual machine history records", + "A:siii") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vmpool(); + auth_object = PoolObjectSQL::VM; + }; + + ~VirtualMachinePoolAccounting(){}; + + /* -------------------------------------------------------------------- */ + + void request_execute( + xmlrpc_c::paramList const& paramList, RequestAttributes& att); +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + class TemplatePoolInfo : public RequestManagerPoolInfoFilter { public: diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index be2ba87c0f..6f20419e33 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -704,6 +704,13 @@ public: static void set_auth_request(int uid, AuthRequest& ar, VirtualMachineTemplate *tmpl); + + // ------------------------------------------------------------------------ + // DataBase implementation (Public) + // ------------------------------------------------------------------------ + + static const char * table; + private: // ------------------------------------------------------------------------- @@ -940,8 +947,6 @@ protected: // DataBase implementation // ************************************************************************* - static const char * table; - static const char * db_names; static const char * db_bootstrap; diff --git a/include/VirtualMachinePool.h b/include/VirtualMachinePool.h index 7e3ea7e6e2..d1fd09b9a3 100644 --- a/include/VirtualMachinePool.h +++ b/include/VirtualMachinePool.h @@ -143,7 +143,7 @@ public: int dump(ostringstream& oss, const string& where) { return PoolSQL::dump(oss, "VM_POOL", VirtualMachine::table, where); - } + }; private: /** diff --git a/src/pool/PoolSQL.cc b/src/pool/PoolSQL.cc index 06d47051d8..d291f07c2a 100644 --- a/src/pool/PoolSQL.cc +++ b/src/pool/PoolSQL.cc @@ -479,14 +479,8 @@ int PoolSQL::dump(ostringstream& oss, const char * table, const string& where) { - int rc; ostringstream cmd; - oss << "<" << elem_name << ">"; - - set_callback(static_cast(&PoolSQL::dump_cb), - static_cast(&oss)); - cmd << "SELECT body FROM " << table; if ( !where.empty() ) @@ -496,9 +490,26 @@ int PoolSQL::dump(ostringstream& oss, cmd << " ORDER BY oid"; - rc = db->exec(cmd, this); + return custom_dump(oss, elem_name, cmd); +} - oss << ""; +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int PoolSQL::custom_dump(ostringstream& oss, + const string& root_elem_name, + ostringstream& sql_query) +{ + int rc; + + oss << "<" << root_elem_name << ">"; + + set_callback(static_cast(&PoolSQL::dump_cb), + static_cast(&oss)); + + rc = db->exec(sql_query, this); + + oss << ""; unset_callback(); diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index f18bad3504..e2413c867c 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -243,6 +243,7 @@ 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_pool_acct(new VirtualMachinePoolAccounting()); // VirtualNetwork Methods xmlrpc_c::methodPtr vn_addleases(new VirtualNetworkAddLeases()); @@ -348,6 +349,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.vm.chmod", vm_chmod); RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info); + RequestManagerRegistry.addMethod("one.vmpool.accounting", vm_pool_acct); /* VM Template related methods*/ RequestManagerRegistry.addMethod("one.template.update", template_update); diff --git a/src/rm/RequestManagerPoolInfoFilter.cc b/src/rm/RequestManagerPoolInfoFilter.cc index e40db5da8d..57ecc505d5 100644 --- a/src/rm/RequestManagerPoolInfoFilter.cc +++ b/src/rm/RequestManagerPoolInfoFilter.cc @@ -91,6 +91,74 @@ void VirtualMachinePoolInfo::request_execute( /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +void VirtualMachinePoolAccounting::request_execute( + xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + int filter_flag = xmlrpc_c::value_int(paramList.getInt(1)); + int time_start = xmlrpc_c::value_int(paramList.getInt(2)); + int time_end = xmlrpc_c::value_int(paramList.getInt(3)); + + ostringstream oss; + ostringstream cmd; + ostringstream vmpool_where; + int rc; + + if ( filter_flag < MINE ) + { + failure_response(XML_RPC_API, + request_error("Incorrect filter_flag",""), + att); + return; + } + + cmd << "SELECT " << History::table << ".body FROM " << History::table + << " INNER JOIN " << VirtualMachine::table + << " WHERE vid=oid"; + + generate_where_string(att, filter_flag, -1, -1, + "", "", vmpool_where); + + if ( !vmpool_where.str().empty() ) //TODO: better empty check? + { + cmd << " AND " << vmpool_where; + } + + if ( time_start != -1 || time_end != -1 ) + { + if ( time_start != -1 ) + { + cmd << " AND (etime > " << time_start << " OR etime = 0)"; + } + + if ( time_end != -1 ) + { + cmd << " AND stime < " << time_end; + } + } + + cmd << " GROUP BY vid,seq"; + + // ------------------------------------------ + // Dump the history records + // ------------------------------------------ + + rc = pool->custom_dump(oss, "HISTORY_RECORDS", cmd); + + 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,19 +209,16 @@ void ClusterPoolInfo::request_execute( /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ -void RequestManagerPoolInfoFilter::dump( +void RequestManagerPoolInfoFilter::generate_where_string( RequestAttributes& att, int filter_flag, int start_id, int end_id, const string& and_clause, - const string& or_clause) + const string& or_clause, + ostringstream& where_string) { - set::iterator it; - - ostringstream oss; bool empty = true; - ostringstream where_string; ostringstream uid_filter; ostringstream id_filter; @@ -162,16 +227,6 @@ void RequestManagerPoolInfoFilter::dump( string acl_str; string id_str; - int rc; - - if ( filter_flag < MINE ) - { - failure_response(XML_RPC_API, - request_error("Incorrect filter_flag",""), - att); - return; - } - Nebula& nd = Nebula::instance(); AclManager* aclm = nd.get_aclm(); bool all; @@ -308,12 +363,39 @@ void RequestManagerPoolInfoFilter::dump( where_string << "(" << or_clause << ")"; } +} + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +void RequestManagerPoolInfoFilter::dump( + RequestAttributes& att, + int filter_flag, + int start_id, + int end_id, + const string& and_clause, + const string& or_clause) +{ + ostringstream oss; + ostringstream where_string; + int rc; + + if ( filter_flag < MINE ) + { + failure_response(XML_RPC_API, + request_error("Incorrect filter_flag",""), + att); + return; + } + + generate_where_string(att, filter_flag, start_id, end_id, + and_clause, or_clause, where_string); // ------------------------------------------ // Get the pool // ------------------------------------------ - rc = pool->dump(oss,where_string.str()); + rc = pool->dump(oss, where_string.str()); if ( rc != 0 ) { diff --git a/src/vm/History.cc b/src/vm/History.cc index 7d581a1937..4fae85a24c 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -25,10 +25,11 @@ const char * History::table = "history"; -const char * History::db_names = "vid, seq, body"; +const char * History::db_names = "vid, seq, body, stime, etime"; const char * History::db_bootstrap = "CREATE TABLE IF NOT EXISTS " - "history (vid INTEGER, seq INTEGER, body TEXT, PRIMARY KEY(vid,seq))"; + "history (vid INTEGER, seq INTEGER, body TEXT, " + "stime INTEGER, etime INTEGER,PRIMARY KEY(vid,seq))"; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -168,7 +169,9 @@ int History::insert_replace(SqlDB *db, bool replace) oss << " INTO " << table << " ("<< db_names <<") VALUES (" << oid << "," << seq << "," - << "'" << sql_xml << "')"; + << "'" << sql_xml << "'," + << stime << "," + << etime << ")"; rc = db->exec(oss); @@ -264,6 +267,7 @@ string& History::to_xml(string& xml) const oss << "" << + "" << oid << "" << "" << seq << "" << "" << hostname << ""<< "" << hid << "" << From 70d5c75d042d4eacecc4a55e803650ddb05c9797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 4 May 2012 17:29:36 +0200 Subject: [PATCH 02/27] Feature #1099: Add VM template information to the History records once they are "closed" --- include/History.h | 21 ++++++++++++++++++++- include/VirtualMachine.h | 8 +++++++- src/vm/History.cc | 31 +++++++++++++++++++++++++++---- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/include/History.h b/include/History.h index 689947bf62..772d3fb2b0 100644 --- a/include/History.h +++ b/include/History.h @@ -63,7 +63,7 @@ public: string& to_xml(string& xml) const; // ---------------------------------------- - // DataBase implementation variables + // DataBase implementation // ---------------------------------------- static const char * table; @@ -108,6 +108,8 @@ private: MigrationReason reason; + string vm_info; + // ------------------------------------------------------------------------- // Non-persistent history fields // ------------------------------------------------------------------------- @@ -173,6 +175,23 @@ private: */ int select_cb(void *nil, int num, char **values, char **names); + /** + * Function to print the History object into a string in + * XML format, to be stored in the DB. It includes the VM template info + * @param xml the resulting XML string + * @return a reference to the generated string + */ + string& to_db_xml(string& xml) const; + + /** + * Function to print the History object into a string in + * XML format. The VM info can be optionally included + * @param xml the resulting XML string + * @param database If it is true, the TEMPLATE element will be included + * @return a reference to the generated string + */ + string& to_xml(string& xml, bool database) const; + /** * Rebuilds the object from an xml node * @param node The xml node pointer diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 6f20419e33..8d7b2f68fe 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -199,7 +199,7 @@ public: /** * Sets the VM exit time - * @param _et VM exit time (when it arraived DONE/FAILED states) + * @param _et VM exit time (when it arrived DONE/FAILED states) */ void set_exit_time(time_t et) { @@ -434,6 +434,9 @@ public: */ void set_etime(time_t _etime) { + string xml; + history->vm_info = obj_template->to_xml(xml); + history->etime=_etime; }; @@ -443,6 +446,9 @@ public: */ void set_previous_etime(time_t _etime) { + string xml; + previous_history->vm_info = obj_template->to_xml(xml); + previous_history->etime=_etime; }; diff --git a/src/vm/History.cc b/src/vm/History.cc index 4fae85a24c..e1199d83e6 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -52,7 +52,8 @@ History::History( running_etime(0), epilog_stime(0), epilog_etime(0), - reason(NONE){}; + reason(NONE), + vm_info("