diff --git a/SConstruct b/SConstruct index 54b3e6aab3..1c3203d935 100644 --- a/SConstruct +++ b/SConstruct @@ -57,6 +57,7 @@ main_env.Append(LIBPATH=[ cwd+'/src/log', cwd+'/src/sql', cwd+'/src/host', + cwd+'/src/cluster', cwd+'/src/mad', cwd+'/src/nebula', cwd+'/src/pool', @@ -73,6 +74,7 @@ main_env.Append(LIBPATH=[ cwd+'/src/hm', cwd+'/src/um', cwd+'/src/authm', + cwd+'/src/xml', ]) # Compile flags @@ -171,6 +173,7 @@ build_scripts=[ 'src/common/SConstruct', 'src/template/SConstruct', 'src/host/SConstruct', + 'src/cluster/SConstruct', 'src/mad/SConstruct', 'src/nebula/SConstruct', 'src/pool/SConstruct', @@ -187,6 +190,7 @@ build_scripts=[ 'src/hm/SConstruct', 'src/um/SConstruct', 'src/authm/SConstruct', + 'src/xml/SConstruct', ] # Testing @@ -214,6 +218,7 @@ if testing=='yes': 'src/authm/test/SConstruct', 'src/common/test/SConstruct', 'src/host/test/SConstruct', + 'src/cluster/test/SConstruct', 'src/image/test/SConstruct', 'src/lcm/test/SConstruct', 'src/pool/test/SConstruct', @@ -222,6 +227,7 @@ if testing=='yes': 'src/um/test/SConstruct', 'src/vm/test/SConstruct', 'src/vnm/test/SConstruct', + 'src/xml/test/SConstruct', ]) else: main_env.Append(testing='no') diff --git a/include/Cluster.h b/include/Cluster.h new file mode 100644 index 0000000000..bf0c2d6a11 --- /dev/null +++ b/include/Cluster.h @@ -0,0 +1,132 @@ +/* ------------------------------------------------------------------------ */ +/* Copyright 2002-2010, 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. */ +/* -------------------------------------------------------------------------*/ + +#ifndef CLUSTER_H_ +#define CLUSTER_H_ + +#include "PoolSQL.h" +#include "Host.h" + +using namespace std; + +/** + * The Cluster class. + */ +class Cluster : public PoolObjectSQL +{ +public: + /** + * Adds the host to this cluster + * @param host The host to add + * + * @return 0 on success + */ +/* + int add_host(Host * host) + { + return host->set_cluster(name); + }; +*/ + + /** + * Removes the host from this cluster + * @param host The host to add + * + * @return 0 on success + */ +// May be needed in a future +// int remove_host(Host * host); + + /** + * Function to write a Cluster on an output stream + */ + friend ostream& operator<<(ostream& os, Cluster& cluster); + + /** + * Function to print the Cluster object into a string in XML format + * @param xml the resulting XML string + * @return a reference to the generated string + */ + string& to_xml(string& xml) const; + + /** + * Rebuilds the object from an xml formatted string + * @param xml_str The xml-formatted string + * + * @return 0 on success, -1 otherwise + */ + int from_xml(const string &xml_str); + +private: + + // ------------------------------------------------------------------------- + // Friends + // ------------------------------------------------------------------------- + + friend class ClusterPool; + + // ************************************************************************* + // Constructor + // ************************************************************************* + + Cluster(int id, const string& name); + + virtual ~Cluster(); + + // ************************************************************************* + // DataBase implementation (Private) + // ************************************************************************* + + static const char * db_names; + + static const char * db_bootstrap; + + static const char * table; + + /** + * Execute an INSERT or REPLACE Sql query. + * @param db The SQL DB + * @param replace Execute an INSERT or a REPLACE + * @return 0 one success + */ + int insert_replace(SqlDB *db, bool replace); + + /** + * Bootstraps the database table(s) associated to the Cluster + */ + static void bootstrap(SqlDB * db) + { + ostringstream oss_cluster(Cluster::db_bootstrap); + + db->exec(oss_cluster); + }; + + /** + * Writes the Cluster in the database. + * @param db pointer to the db + * @return 0 on success + */ + int insert(SqlDB *db, string& error_str); + + /** + * Writes/updates the Cluster's data fields in the database. + * @param db pointer to the db + * @return 0 on success + */ + int update(SqlDB *db); +}; + +#endif /*CLUSTER_H_*/ diff --git a/include/ClusterPool.h b/include/ClusterPool.h index f9f92fe10b..13b5ac7fab 100644 --- a/include/ClusterPool.h +++ b/include/ClusterPool.h @@ -17,124 +17,123 @@ #ifndef CLUSTER_POOL_H_ #define CLUSTER_POOL_H_ -#include -#include -#include - +#include "Cluster.h" +#include "Host.h" #include "SqlDB.h" using namespace std; - /** * A cluster helper class. It is not a normal PoolSQL, * but a series of static methods related to clusters. */ -class ClusterPool +class ClusterPool : public PoolSQL { public: + ClusterPool(SqlDB * db); + + ~ClusterPool(){}; + + /** + * Removes the host from the given cluster setting the default one. + * @param host The host to assign + * + * @return 0 on success + */ + int set_default_cluster(Host * host) + { + return host->set_cluster(ClusterPool::DEFAULT_CLUSTER_NAME); + }; + /** * Cluster name for the default cluster */ static const string DEFAULT_CLUSTER_NAME; -private: - // ------------------------------------------------------------------------- - // Friends - // ------------------------------------------------------------------------- - friend class HostPool; - /* ---------------------------------------------------------------------- */ - /* Attributes */ + /* Methods for DB management */ /* ---------------------------------------------------------------------- */ - /** - * This map stores the clusters - */ - map cluster_names; - - - /* ---------------------------------------------------------------------- */ - /* Methods for cluster management */ - /* ---------------------------------------------------------------------- */ - - /** - * Returns true if the clid is an id for an existing cluster - * @param clid ID of the cluster - * - * @return true if the clid is an id for an existing cluster - */ - bool exists(int clid) - { - return cluster_names.count(clid) > 0; - }; /** * Allocates a new cluster in the pool * @param clid the id assigned to the cluster * @return the id assigned to the cluster or -1 in case of failure */ - int allocate(int * clid, string name, SqlDB *db, string& error_str); + int allocate(int * oid, string name, string& error_str); /** - * Returns the xml representation of the given cluster - * @param clid ID of the cluster - * - * @return the xml representation of the given cluster + * Function to get a Cluster from the pool, if the object is not in memory + * it is loaded from the DB + * @param oid Cluster unique id + * @param lock locks the Cluster mutex + * @return a pointer to the Cluster, 0 if the Cluster could not be loaded */ - string info(int clid); - - /** - * Removes the given cluster from the pool and the DB - * @param clid ID of the cluster - * - * @return 0 on success - */ - int drop(int clid, SqlDB *db); - - /** - * Dumps the cluster pool in XML format. - * @param oss the output stream to dump the pool contents - * - * @return 0 on success - */ - int dump(ostringstream& oss); - - /** - * Bootstraps the database table(s) associated to the Cluster - */ - static void bootstrap(SqlDB * db) + Cluster * get(int oid, bool lock) { - ostringstream oss(ClusterPool::db_bootstrap); - db->exec(oss); + return static_cast(PoolSQL::get(oid,lock)); }; /** - * Function to insert new Cluster in the pool - * @param oid the id assigned to the Cluster - * @param name the Cluster's name - * @return 0 on success, -1 in case of failure - */ - int insert (int oid, string name, SqlDB *db); - - /** - * Formats as XML the given id and name. - * @param oss the output stream to dump the pool contents + * Gets an object from the pool (if needed the object is loaded from the + * database). + * @param name of the object + * @param lock locks the object if true * + * @return a pointer to the object, 0 in case of failure + */ + Cluster * get(const string& name, bool lock) + { + return static_cast(PoolSQL::get(name,-1,lock)); + }; + + /** Update a particular Cluster + * @param user pointer to Cluster * @return 0 on success */ - void dump_cluster(ostringstream& oss, int id, string name); + int update(Cluster * cluster) + { + return cluster->update(db); + }; + /** + * Drops the Cluster from the data base. The object mutex SHOULD be + * locked. + * @param cluster a pointer to the object + * @return 0 on success. + */ + int drop(Cluster * cluster); - /* ---------------------------------------------------------------------- */ - /* DB manipulation */ - /* ---------------------------------------------------------------------- */ + /** + * Bootstraps the database table(s) associated to the Cluster pool + */ + static void bootstrap(SqlDB * _db) + { + Cluster::bootstrap(_db); + }; - static const char * db_names; + /** + * Dumps the Cluster pool 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(ostringstream& oss, const string& where) + { + return PoolSQL::dump(oss, "CLUSTER_POOL", Cluster::table, where); + }; - static const char * db_bootstrap; - - static const char * table; +private: + /** + * Factory method to produce objects + * @return a pointer to the new object + */ + PoolObjectSQL * create() + { + return new Cluster(-1,""); + }; }; #endif /*CLUSTER_POOL_H_*/ diff --git a/include/FixedLeases.h b/include/FixedLeases.h index ba7e146324..fc1c420d08 100644 --- a/include/FixedLeases.h +++ b/include/FixedLeases.h @@ -150,6 +150,13 @@ private: * @return 0 if success */ int unset(const string& ip); + + /** + * Updates the DB entry for this lease + * @param lease Lease to be updated + * @return 0 if success + */ + int update_lease(Lease * lease); }; #endif /*FIXED_LEASES_H_*/ diff --git a/include/History.h b/include/History.h index bdb202d336..35e38a3569 100644 --- a/include/History.h +++ b/include/History.h @@ -25,7 +25,7 @@ using namespace std; * The History class, it represents an execution record of a Virtual Machine. */ -class History:public ObjectSQL +class History:public ObjectSQL, public ObjectXML { public: enum MigrationReason @@ -40,13 +40,13 @@ public: History(int oid, int _seq = -1); History( - int oid, - int seq, - int hid, - string& hostname, - string& vm_dir, - string& vmm, - string& tm); + int oid, + int seq, + int hid, + const string& hostname, + const string& vm_dir, + const string& vmm, + const string& tm); ~History(){}; @@ -55,14 +55,6 @@ public: */ friend ostream& operator<<(ostream& os, const History& history); - /** - * Function to print the History object into a string in - * plain text - * @param str the resulting string - * @return a reference to the generated string - */ - string& to_str(string& str) const; - /** * Function to print the History object into a string in * XML format @@ -78,52 +70,15 @@ private: // ---------------------------------------- // DataBase implementation variables // ---------------------------------------- - enum ColNames - { - VID = 0, - SEQ = 1, - HOSTNAME = 2, - VM_DIR = 3, - HID = 4, - VMMMAD = 5, - TMMAD = 6, - STIME = 7, - ETIME = 8, - PROLOG_STIME = 9, - PROLOG_ETIME = 10, - RUNNING_STIME = 11, - RUNNING_ETIME = 12, - EPILOG_STIME = 13, - EPILOG_ETIME = 14, - REASON = 15, - LIMIT = 16 - }; static const char * table; static const char * db_names; - static const char * extended_db_names; - static const char * db_bootstrap; void non_persistent_data(); - static string column_name(const ColNames column) - { - switch (column) - { - case HID: - return "hid"; - case ETIME: - return "etime"; - case RUNNING_ETIME: - return "retime"; - default: - return ""; - } - } - // ---------------------------------------- // History fields // ---------------------------------------- @@ -167,7 +122,12 @@ private: * @param db pointer to the database. * @return 0 on success. */ - int insert(SqlDB * db, string& error_str); + int insert(SqlDB * db, string& error_str) + { + error_str.clear(); + + return insert_replace(db, false); + } /** * Reads the history record from the DB @@ -181,7 +141,10 @@ private: * @param db pointer to the database. * @return 0 on success. */ - int update(SqlDB * db); + int update(SqlDB * db) + { + return insert_replace(db, true); + } /** * Removes the all history records from the DB @@ -208,15 +171,35 @@ private: int select_cb(void *nil, int num, char **values, char **names); /** - * Function to unmarshall a History object into an output stream with XML - * format. - * @param oss the output stream - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success + * Rebuilds the object from an xml node + * @param node The xml node pointer + * + * @return 0 on success, -1 otherwise */ - static int dump(ostringstream& oss, int num, char **names, char **values); + int from_xml_node(const xmlNodePtr node) + { + ObjectXML::update_from_node(node); + + return rebuild_attributes(); + } + + /** + * Rebuilds the object from an xml formatted string + * @param xml_str The xml-formatted string + * + * @return 0 on success, -1 otherwise + */ + int from_xml(const string &xml_str) + { + ObjectXML::update_from_str(xml_str); + + return rebuild_attributes(); + } + + /** + * Rebuilds the internal attributes using xpath + */ + int rebuild_attributes(); }; #endif /*HISTORY_H_*/ diff --git a/include/Host.h b/include/Host.h index 72039a9cd9..6f7982413f 100644 --- a/include/Host.h +++ b/include/Host.h @@ -20,7 +20,6 @@ #include "PoolSQL.h" #include "HostTemplate.h" #include "HostShare.h" -#include "ClusterPool.h" using namespace std; @@ -49,28 +48,20 @@ public: */ friend ostream& operator<<(ostream& os, Host& h); - /** - * Function to print the Host object into a string in plain text - * @param str the resulting string - * @return a reference to the generated string - */ - string& to_str(string& str) const; - - /** - * Function to print the Host object into a string in XML format - * @param xml the resulting XML string - * @return a reference to the generated string - */ - string& to_xml(string& xml) const; + /** + * Function to print the Host object into a string in XML format + * @param xml the resulting XML string + * @return a reference to the generated string + */ + string& to_xml(string& xml) const; /** - * Get the Host unique identifier HID, that matches the OID of the object - * @return HID Host identifier + * Rebuilds the object from an xml formatted string + * @param xml_str The xml-formatted string + * + * @return 0 on success, -1 otherwise */ - int get_hid() const - { - return oid; - }; + int from_xml(const string &xml_str); /** * Check if the host is enabled @@ -120,15 +111,6 @@ public: state = INIT; }; - /** - * Returns host host_name - * @return host_name Host's hostname - */ - const string& get_hostname() const - { - return hostname; - }; - /** Update host counters and update the whole host on the DB * @param parse_str string with values to be parsed * @return 0 on success @@ -378,9 +360,6 @@ private: // ------------------------------------------------------------------------- // Host Description // ------------------------------------------------------------------------- - - string hostname; - /** * The state of the Host */ @@ -402,7 +381,7 @@ private: string tm_mad_name; /** - * If Host State = MONITORED last time it got fully monitored or 1 Jan 1970 + * If Host State= MONITORED last time it got fully monitored or 1 Jan 1970 * Host State = MONITORING last time it got a signal to be monitored */ time_t last_monitored; @@ -426,10 +405,29 @@ private: */ HostShare host_share; + // ************************************************************************* + // Constructor + // ************************************************************************* + + Host(int id=-1, + const string& hostname="", + const string& im_mad_name="", + const string& vmm_mad_name="", + const string& tm_mad_name="", + const string& cluster=""); + + virtual ~Host(); + // ************************************************************************* // DataBase implementation (Private) // ************************************************************************* + static const char * db_names; + + static const char * db_bootstrap; + + static const char * table; + /** * Execute an INSERT or REPLACE Sql query. * @param db The SQL DB @@ -438,102 +436,29 @@ private: */ int insert_replace(SqlDB *db, bool replace); - /** - * Callback function to unmarshall a Host object (Host::select) - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - int select_cb(void *nil, int num, char **values, char **names); - /** * Bootstraps the database table(s) associated to the Host */ static void bootstrap(SqlDB * db) { ostringstream oss_host(Host::db_bootstrap); - ostringstream oss_share(HostShare::db_bootstrap); db->exec(oss_host); - db->exec(oss_share); }; -protected: - - // ************************************************************************* - // Constructor - // ************************************************************************* - - Host(int id=-1, - string _hostname="", - string _im_mad_name="", - string _vmm_mad_name="", - string _tm_mad_name=""); - - virtual ~Host(); - - // ************************************************************************* - // DataBase implementation - // ************************************************************************* - - enum ColNames - { - OID = 0, - HOST_NAME = 1, - STATE = 2, - IM_MAD = 3, - VM_MAD = 4, - TM_MAD = 5, - LAST_MON_TIME = 6, - CLUSTER = 7, - TEMPLATE = 8, - LIMIT = 9 - }; - - static const char * db_names; - - static const char * db_bootstrap; - - static const char * table; - - /** - * Reads the Host (identified with its OID=HID) from the database. - * @param db pointer to the db - * @return 0 on success - */ - virtual int select(SqlDB *db); - /** * Writes the Host and its associated HostShares in the database. * @param db pointer to the db * @return 0 on success */ - virtual int insert(SqlDB *db, string& error_str); + int insert(SqlDB *db, string& error_str); /** * Writes/updates the Hosts data fields in the database. * @param db pointer to the db * @return 0 on success */ - virtual int update(SqlDB *db); - - /** - * Drops host from the database - * @param db pointer to the db - * @return 0 on success - */ - virtual int drop(SqlDB *db); - - /** - * Function to output a Host object in to an stream in XML format - * @param oss the output stream - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - static int dump(ostringstream& oss, int num, char **values, char **names); + int update(SqlDB *db); }; #endif /*HOST_H_*/ diff --git a/include/HostPool.h b/include/HostPool.h index ff2ffda2b9..4dcf149bbe 100644 --- a/include/HostPool.h +++ b/include/HostPool.h @@ -19,7 +19,6 @@ #include "PoolSQL.h" #include "Host.h" -#include "ClusterPool.h" #include #include @@ -69,14 +68,24 @@ public: return static_cast(PoolSQL::get(oid,lock)); }; + /** + * Function to get a Host from the pool, if the object is not in memory + * it is loaded from the DB + * @param hostname + * @param lock locks the Host mutex + * @return a pointer to the Host, 0 if the Host could not be loaded + */ + Host * get(string name, bool lock) + { + return static_cast(PoolSQL::get(name,-1,lock)); + }; + /** * Bootstraps the database table(s) associated to the Host pool */ static void bootstrap(SqlDB *_db) { Host::bootstrap(_db); - - ClusterPool::bootstrap(_db); }; /** @@ -138,102 +147,25 @@ public: * * @return 0 on success */ - int dump(ostringstream& oss, const string& where); - - /* ---------------------------------------------------------------------- */ - /* ---------------------------------------------------------------------- */ - /* Methods for cluster management */ - /* ---------------------------------------------------------------------- */ - /* ---------------------------------------------------------------------- */ - - /** - * Returns true if the clid is an id for an existing cluster - * @param clid ID of the cluster - * - * @return true if the clid is an id for an existing cluster - */ - /* bool exists_cluster(int clid) + int dump(ostringstream& oss, const string& where) { - return cluster_pool.exists(clid); - };*/ - - /** - * Allocates a new cluster in the pool - * @param clid the id assigned to the cluster - * @return the id assigned to the cluster or -1 in case of failure - */ - int allocate_cluster(int * clid, const string& name, string& error_str) - { - return cluster_pool.allocate(clid, name, db, error_str); + return PoolSQL::dump(oss, "HOST_POOL", Host::table, where); }; /** - * Returns the xml representation of the given cluster - * @param clid ID of the cluster + * Finds a set objects that satisfies a given condition + * @param oids a vector with the oids of the objects. + * @param the name of the DB table. + * @param where condition in SQL format. * - * @return the xml representation of the given cluster + * @return 0 on success */ - string info_cluster(int clid) + int search(vector& oids, const string& where) { - return cluster_pool.info(clid); - }; - - /** - * Removes the given cluster from the pool and the DB - * @param clid ID of the cluster - * - * @return 0 on success - */ - int drop_cluster(int clid); - - /** - * Dumps the cluster pool in XML format. - * @param oss the output stream to dump the pool contents - * - * @return 0 on success - */ - int dump_cluster(ostringstream& oss) - { - return cluster_pool.dump(oss); - }; - - /** - * Assigns the host to the given cluster - * @param host The host to assign - * @param clid ID of the cluster - * - * @return 0 on success - */ - int set_cluster(Host* host, int clid) - { - map::iterator it; - - it = cluster_pool.cluster_names.find(clid); - - if (it == cluster_pool.cluster_names.end()) - { - return -1; - } - - return host->set_cluster( it->second ); - }; - - /** - * Removes the host from the given cluster setting the default one. - * @param host The host to assign - * - * @return 0 on success - */ - int set_default_cluster(Host* host) - { - return host->set_cluster(ClusterPool::DEFAULT_CLUSTER_NAME); + return PoolSQL::search(oids, Host::table, where); }; private: - /** - * ClusterPool, clusters defined and persistance functionality - */ - ClusterPool cluster_pool; /** * Factory method to produce Host objects @@ -244,15 +176,6 @@ private: return new Host; }; - /** - * Callback function to build the cluster pool - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - int init_cb(void *nil, int num, char **values, char **names); - /** * Callback function to get the IDs of the hosts to be monitored * (Host::discover) @@ -262,16 +185,6 @@ private: * @return 0 on success */ int discover_cb(void * _map, int num, char **values, char **names); - - /** - * Callback function to get output the host pool in XML format - * (Host::dump) - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - int dump_cb(void * _oss, int num, char **values, char **names); }; #endif /*HOST_POOL_H_*/ diff --git a/include/HostShare.h b/include/HostShare.h index 29e0dc9960..9cd1422a51 100644 --- a/include/HostShare.h +++ b/include/HostShare.h @@ -17,8 +17,7 @@ #ifndef HOST_SHARE_H_ #define HOST_SHARE_H_ -#include "SqlDB.h" -#include "ObjectSQL.h" +#include "ObjectXML.h" #include using namespace std; @@ -29,12 +28,11 @@ using namespace std; /** * The HostShare class. It represents a logical partition of a host... */ -class HostShare : public ObjectSQL +class HostShare : public ObjectXML { public: HostShare( - int _hsid=-1, int _max_disk=0, int _max_mem=0, int _max_cpu=0); @@ -92,14 +90,6 @@ public: */ friend ostream& operator<<(ostream& os, HostShare& hs); - /** - * Function to print the HostShare object into a string in - * plain text - * @param str the resulting string - * @return a reference to the generated string - */ - string& to_str(string& str) const; - /** * Function to print the HostShare object into a string in * XML format @@ -110,8 +100,6 @@ public: private: - int hsid; /**< HostShare identifier */ - int disk_usage; /**< Disk allocated to VMs (in Mb). */ int mem_usage; /**< Memory allocated to VMs (in Mb) */ int cpu_usage; /**< CPU allocated to VMs (in percentage) */ @@ -128,7 +116,7 @@ private: int used_mem; /**< Used memory from the IM monitor */ int used_cpu; /**< Used cpu from the IM monitor */ - int running_vms; /**< Number of running VMs in this Host */ + int running_vms;/**< Number of running VMs in this Host */ // ---------------------------------------- // Friends @@ -137,95 +125,13 @@ private: friend class Host; friend class HostPool; - // ---------------------------------------- - // DataBase implementation variables - // ---------------------------------------- - - enum ColNames - { - HID = 0, - DISK_USAGE = 1, - MEM_USAGE = 2, - CPU_USAGE = 3, - MAX_DISK = 4, - MAX_MEMORY = 5, - MAX_CPU = 6, - FREE_DISK = 7, - FREE_MEMORY = 8, - FREE_CPU = 9, - USED_DISK = 10, - USED_MEMORY = 11, - USED_CPU = 12, - RUNNING_VMS = 13, - LIMIT = 14 - }; - - static const char * table; - - static const char * db_names; - - static const char * db_bootstrap; - - // ---------------------------------------- - // Database methods - // ---------------------------------------- - /** - * Reads the HostShare (identified with its HSID) from the database. - * @param db pointer to the db - * @return 0 on success + * Rebuilds the object from an xml node + * @param node The xml node pointer + * + * @return 0 on success, -1 otherwise */ - int select(SqlDB * db); - - /** - * Writes the HostShare in the database. - * @param db pointer to the db - * @return 0 on success - */ - int insert(SqlDB * db, string& error_str); - - /** - * Writes/updates the HostShare data fields in the database. - * @param db pointer to the db - * @return 0 on success - */ - int update(SqlDB * db); - - /** - * Drops hostshare from the database - * @param db pointer to the db - * @return 0 on success - */ - int drop(SqlDB * db); - - /** - * Execute an INSERT or REPLACE Sql query. - * @param db The SQL DB - * @param replace Execute an INSERT or a REPLACE - * @return 0 one success - */ - int insert_replace(SqlDB *db, bool replace); - - /** - * Callback function to unmarshall a HostShare object (HostShare::select) - * @param num the number of columns read from the DB - * @para names the column names - * @para vaues the column values - * @return 0 on success - */ - int select_cb(void * nil, int num, char **values, char **names); - - /** - * Function to unmarshall a HostShare object in to an output stream in XML - * @param oss the output stream - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - static int dump(ostringstream& oss, int num, char **values, char **names); - + int from_xml_node(const xmlNodePtr node); }; - #endif /*HOST_SHARE_H_*/ diff --git a/include/Image.h b/include/Image.h index 72aa5bab52..90b4a116ee 100644 --- a/include/Image.h +++ b/include/Image.h @@ -59,13 +59,6 @@ public: // Image Public Methods // ************************************************************************* - /** - * Function to print the Image object into a string in plain text - * @param str the resulting string - * @return a reference to the generated string - */ - string& to_str(string& str) const; - /** * Function to print the Image object into a string in XML format * @param xml the resulting XML string @@ -74,31 +67,12 @@ public: string& to_xml(string& xml) const; /** - * Get the Image unique identifier IID, that matches the OID of the object - * @return IID Image identifier + * Rebuilds the object from an xml formatted string + * @param xml_str The xml-formatted string + * + * @return 0 on success, -1 otherwise */ - int get_iid() const - { - return oid; - }; - - /** - * Gets the uid of the owner of the Image - * @return uid - **/ - int get_uid() - { - return uid; - } - - /** - * Returns Image's name - * @return name Image's name - */ - const string& get_name() const - { - return name; - }; + int from_xml(const string &xml_str); /** * Returns true if the image is public @@ -356,34 +330,29 @@ private: // ------------------------------------------------------------------------- /** - * Owner if the image + * Image owner's name */ - int uid; - - /** - * The name of the Image - */ - string name; + string user_name; /** * Type of the Image */ - ImageType type; + ImageType type; /** * Public scope of the Image */ - int public_img; + int public_img; /** * Persistency of the Image */ - int persistent_img; + int persistent_img; /** * Registration time */ - time_t regtime; + time_t regtime; /** * Path to the image @@ -422,15 +391,6 @@ private: */ int insert_replace(SqlDB *db, bool replace); - /** - * Callback function to unmarshall a Image object (Image::select) - * @param num the number of columns read from the DB - * @param names the column names - * @param values the column values - * @return 0 on success - */ - int select_cb(void *nil, int num, char **values, char **names); - /** * Bootstraps the database table(s) associated to the Image */ @@ -455,7 +415,9 @@ protected: // Constructor // ************************************************************************* - Image(int uid=-1, ImageTemplate *img_template = 0); + Image(int uid, + const string& user_name, + ImageTemplate* img_template); virtual ~Image(); @@ -463,37 +425,12 @@ protected: // DataBase implementation // ************************************************************************* - enum ColNames - { - OID = 0, /* Image identifier (IID) */ - UID = 1, /* Image owner id */ - NAME = 2, /* Image name */ - TYPE = 3, /* 0) OS 1) CDROM 2) DATABLOCK */ - PUBLIC = 4, /* Public scope (YES OR NO) */ - PERSISTENT = 5, /* Peristency (YES OR NO) */ - REGTIME = 6, /* Time of registration */ - SOURCE = 7, /* Path to the image */ - STATE = 8, /* 0) INIT 1) ALLOCATED */ - RUNNING_VMS = 9, /* Number of VMs using the img */ - TEMPLATE = 10, /* Image template xml data */ - LIMIT = 11 - }; - - static const char * extended_db_names; - static const char * db_names; static const char * db_bootstrap; static const char * table; - /** - * Reads the Image (identified with its OID=IID) from the database. - * @param db pointer to the db - * @return 0 on success - */ - virtual int select(SqlDB *db); - /** * Writes the Image in the database. * @param db pointer to the db @@ -507,23 +444,6 @@ protected: * @return 0 on success */ virtual int update(SqlDB *db); - - /** - * Drops Image and associated template from the database - * @param db pointer to the db - * @return 0 on success - */ - virtual int drop(SqlDB *db); - - /** - * Function to output an Image object in to an stream in XML format - * @param oss the output stream - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - static int dump(ostringstream& oss, int num, char **values, char **names); }; #endif /*IMAGE_H_*/ diff --git a/include/ImagePool.h b/include/ImagePool.h index e65d6f2a27..d319ff1dda 100644 --- a/include/ImagePool.h +++ b/include/ImagePool.h @@ -38,10 +38,10 @@ class ImagePool : public PoolSQL { public: - ImagePool(SqlDB * db, - const string& _source_prefix, - const string& _default_type, - const string& _default_dev_prefix); + ImagePool(SqlDB * db, + const string& _source_prefix, + const string& _default_type, + const string& _default_dev_prefix); ~ImagePool(){}; @@ -56,20 +56,19 @@ public: */ int allocate ( int uid, + string user_name, ImageTemplate * img_template, int * oid, string& error_str); /** - * Function to get a Image from the pool, if the object is not in memory + ** Function to get a Image from the pool, if the object is not in memory * it is loaded from the DB * @param oid Image unique id * @param lock locks the Image mutex * @return a pointer to the Image, 0 if the Image could not be loaded */ - Image * get( - int oid, - bool lock) + Image * get(int oid, bool lock) { return static_cast(PoolSQL::get(oid,lock)); }; @@ -78,25 +77,15 @@ public: * Function to get an Image from the pool using the image name * @param name of the image * @param lock locks the User mutex - * @return a pointer to the Image, 0 if the User could not be loaded + * @return a pointer to the Image, 0 if the image could not be loaded */ - Image * get( - const string& name, - bool lock) + Image * get(const string& name, int uid, bool lock) { - map::iterator index; - - index = image_names.find(name); - - if ( index != image_names.end() ) - { - return get((int)index->second,lock); - } - - return 0; + return static_cast(PoolSQL::get(name,uid,lock)); } - /** Update a particular Image + /** + * Update a particular Image * @param image pointer to Image * @return 0 on success */ @@ -111,14 +100,7 @@ public: */ int drop(Image * image) { - int rc = PoolSQL::drop(image); - - if ( rc == 0) - { - image_names.erase(image->get_name()); - } - - return rc; + return PoolSQL::drop(image); }; /** @@ -136,7 +118,10 @@ public: * @param where filter for the objects, defaults to all * @return 0 on success */ - int dump(ostringstream& oss, const string& where); + int dump(ostringstream& oss, const string& where) + { + return PoolSQL::dump(oss, "IMAGE_POOL", Image::table, where); + } /** * Generates a DISK attribute for VM templates using the Image metadata @@ -145,18 +130,21 @@ public: * @param index number of datablock images used by the same VM. Will be * automatically increased. * @param img_type will be set to the used image's type + * @param uid of VM owner (to look for the image id within its images) * @return 0 on success, -1 error, -2 not using the pool */ int disk_attribute(VectorAttribute * disk, int disk_id, int * index, - Image::ImageType * img_type); + Image::ImageType * img_type, + int uid); /** * Generates an Authorization token for the DISK attribute * @param disk the disk to be authorized + * @param uid of owner (to look for the image id within her images) * @param ar the AuthRequest */ - void authorize_disk(VectorAttribute * disk, AuthRequest * ar); + void authorize_disk(VectorAttribute * disk, int uid, AuthRequest * ar); static const string& source_prefix() { @@ -180,54 +168,29 @@ private: /** * Path to the image repository **/ - static string _source_prefix; + static string _source_prefix; /** * Default image type **/ - static string _default_type; + static string _default_type; /** * Default device prefix **/ - static string _default_dev_prefix; + static string _default_dev_prefix; //-------------------------------------------------------------------------- // Pool Attributes // ------------------------------------------------------------------------- - /** - * This map stores the association between IIDs and Image names - */ - map image_names; - /** * Factory method to produce Image objects * @return a pointer to the new Image */ PoolObjectSQL * create() { - return new Image; + return new Image(-1,"",0); }; - - /** - * Callback function to get output the image pool in XML format - * (Image::dump) - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - int dump_cb(void * _oss, int num, char **values, char **names); - - /** - * Callback function to build the image_names map - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - int init_cb(void *nil, int num, char **values, char **names); - }; #endif /*IMAGE_POOL_H_*/ diff --git a/include/Leases.h b/include/Leases.h index 280e051953..ef38c2c13b 100644 --- a/include/Leases.h +++ b/include/Leases.h @@ -18,6 +18,7 @@ #define LEASES_H_ #include "ObjectSQL.h" +#include "ObjectXML.h" #include "Attribute.h" #include @@ -40,7 +41,8 @@ public: * @param _size the max number of leases */ Leases(SqlDB * _db, int _oid, unsigned long _size): - oid(_oid), size(_size), db(_db){}; + ObjectSQL(), + oid(_oid), size(_size), n_used(0), db(_db){}; virtual ~Leases() { @@ -108,7 +110,7 @@ protected: * The Lease class, it represents a pair of IP and MAC assigned to * a Virtual Machine */ - class Lease + class Lease : public ObjectXML { public: /** @@ -129,13 +131,19 @@ protected: * @param _used, the lease is in use */ Lease(unsigned int _ip, unsigned int _mac[], int _vid, bool _used=true) - :ip(_ip), vid(_vid), used(_used) + :ObjectXML(),ip(_ip), vid(_vid), used(_used) { // TODO check size mac[PREFIX]=_mac[PREFIX]; mac[SUFFIX]=_mac[SUFFIX]; }; + /** + * Creates a new empty lease. Method from_xml should be called right + * after this constructor. + */ + Lease():ObjectXML(){}; + ~Lease(){}; /** @@ -172,14 +180,6 @@ protected: */ friend ostream& operator<<(ostream& os, Lease& _lease); - /** - * Function to print the Lease object into a string in - * plain text - * @param str the resulting string - * @return a reference to the generated string - */ - string& to_str(string& str) const; - /** * Function to print the Lease object into a string in * XML format @@ -188,6 +188,23 @@ protected: */ string& to_xml(string& xml) const; + /** + * Function to print the Lease object into a string in + * XML format. The output contains all the internal attributes, + * to be saved in the DB as a blob + * @param xml the resulting XML string + * @return a reference to the generated string + */ + string& to_xml_db(string& xml) const; + + /** + * Rebuilds the object from an xml formatted string + * @param xml_str The xml-formatted string + * + * @return 0 on success, -1 otherwise + */ + int from_xml(const string &xml_str); + /** * Constants to access the array storing the MAC address */ @@ -227,6 +244,11 @@ protected: */ map leases; + /** + * Number of used leases + */ + int n_used; + // ------------------------------------------------------------------------- // DataBase implementation variables // ------------------------------------------------------------------------- @@ -235,17 +257,6 @@ protected: */ SqlDB * db; - enum ColNames - { - OID = 0, - IP = 1, - MAC_PREFIX = 2, - MAC_SUFFIX = 3, - VID = 4, - USED = 5, - LIMIT = 6 - }; - static const char * table; static const char * db_names; @@ -274,14 +285,6 @@ protected: friend ostream& operator<<(ostream& os, Lease& _lease); - /** - * Function to print the Leases object into a string in - * plain text - * @param str the resulting string - * @return a reference to the generated string - */ - string& to_str(string& str) const; - /** * Function to print the Leases object into a string in * XML format diff --git a/include/Nebula.h b/include/Nebula.h index ccfbcf7e04..9019ae8ddb 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -75,6 +75,11 @@ public: return ipool; }; + ClusterPool * get_cpool() + { + return cpool; + }; + // -------------------------------------------------------------- // Manager Accessors // -------------------------------------------------------------- @@ -224,7 +229,7 @@ private: // ----------------------------------------------------------------------- Nebula():nebula_configuration(0),db(0),vmpool(0),hpool(0),vnpool(0),upool(0), - ipool(0),lcm(0),vmm(0),im(0),tm(0),dm(0),rm(0),hm(0),authm(0) + ipool(0),cpool(0),lcm(0),vmm(0),im(0),tm(0),dm(0),rm(0),hm(0),authm(0) { const char * nl = getenv("ONE_LOCATION"); @@ -284,6 +289,11 @@ private: delete ipool; } + if ( cpool != 0) + { + delete cpool; + } + if ( vmm != 0) { delete vmm; @@ -370,6 +380,7 @@ private: VirtualNetworkPool * vnpool; UserPool * upool; ImagePool * ipool; + ClusterPool * cpool; // --------------------------------------------------------------- // Nebula Managers diff --git a/src/scheduler/include/ObjectXML.h b/include/ObjectXML.h similarity index 65% rename from src/scheduler/include/ObjectXML.h rename to include/ObjectXML.h index 186309d437..72fa91d878 100644 --- a/src/scheduler/include/ObjectXML.h +++ b/include/ObjectXML.h @@ -60,6 +60,61 @@ public: */ vector operator[] (const char * xpath_expr); + /** + * Gets and sets a xpath attribute, if the attribute is not found a default + * is used + * @param value to set + * @param xpath_expr of the xml element + * @param def default value if the element is not found + * + * @return -1 if default was set + */ + int xpath(string& value, const char * xpath_expr, const char * def); + + /** + * Gets and sets a xpath attribute, if the attribute is not found a default + * is used + * @param value to set + * @param xpath_expr of the xml element + * @param def default value if the element is not found + * + * @return -1 if default was set + */ + int xpath(int& value, const char * xpath_expr, const int& def); + + /** + * Gets and sets a xpath attribute, if the attribute is not found a default + * is used + * @param value to set + * @param xpath_expr of the xml element + * @param def default value if the element is not found + * + * @return -1 if default was set + */ + int xpath(unsigned int& value, const char * xpath_expr, + const unsigned int& def); + + /** + * Gets and sets a xpath attribute, if the attribute is not found a default + * is used + * @param value to set + * @param xpath_expr of the xml element + * @param def default value if the element is not found + * + * @return -1 if default was set + */ + int xpath(time_t& value, const char * xpath_expr, const time_t& def); + + /** + * Gets the value of an element from an xml string + * @param value the value of the element + * @param xml the xml string + * @param xpath the xpath of the target element + * + * @return -1 if the element was not found + */ + static int xpath_value(string& value, const char *xml, const char *xpath); + /** * Get xml nodes by Xpath * @param xpath_expr the Xpath for the elements @@ -67,14 +122,21 @@ public: * returned as pointers to the object nodes. * @return the number of nodes found */ - int get_nodes (const char * xpath_expr, vector& content); + int get_nodes(const char * xpath_expr, vector& content); /** * Updates the object representation with a new XML document. Previous * XML resources are freed * @param xml_doc the new xml document */ - int update(const string &xml_doc); + int update_from_str(const string &xml_doc); + + /** + * Updates the object representation with a new XML document. Previous + * XML resources are freed + * @param xml_doc the new xml document + */ + int update_from_node(const xmlNodePtr node); // --------------------------------------------------------- // Lex & bison parser for requirements and rank expressions diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h index b64c35c76f..fc8727004c 100644 --- a/include/PoolObjectSQL.h +++ b/include/PoolObjectSQL.h @@ -18,7 +18,9 @@ #define POOL_OBJECT_SQL_H_ #include "ObjectSQL.h" +#include "ObjectXML.h" #include +#include using namespace std; @@ -31,11 +33,13 @@ using namespace std; * is called. */ -class PoolObjectSQL : public ObjectSQL +class PoolObjectSQL : public ObjectSQL, public ObjectXML { public: - PoolObjectSQL(int id=-1):oid(id),valid(true) + PoolObjectSQL(int id, const string& _name, int _uid,const char *_table) + :ObjectSQL(),ObjectXML(),oid(id),name(_name),uid(_uid), + valid(true),table(_table) { pthread_mutex_init(&mutex,0); }; @@ -47,11 +51,25 @@ public: pthread_mutex_destroy(&mutex); }; + /* --------------------------------------------------------------------- */ + int get_oid() const { return oid; }; + const string& get_name() const + { + return name; + }; + + int get_uid() + { + return uid; + }; + + /* --------------------------------------------------------------------- */ + /** * Check if the object is valid * @return true if object is valid @@ -68,7 +86,7 @@ public: void set_valid(const bool _valid) { valid = _valid; - } + }; /** * Function to lock the object @@ -86,17 +104,99 @@ public: pthread_mutex_unlock(&mutex); }; + /** + * Function to print the object into a string in XML format + * @param xml the resulting XML string + * @return a reference to the generated string + */ + virtual string& to_xml(string& xml) const = 0; + + /** + * Rebuilds the object from an xml formatted string + * @param xml_str The xml-formatted string + * + * @return 0 on success, -1 otherwise + */ + virtual int from_xml(const string &xml_str) = 0; + protected: /** - * The object unique ID + * Callback function to unmarshall a PoolObjectSQL + * @param num the number of columns read from the DB + * @param names the column names + * @param vaues the column values + * @return 0 on success */ - int oid; + int select_cb(void *nil, int num, char **values, char **names) + { + if ( (!values[0]) || (num != 1) ) + { + return -1; + } + + return from_xml(values[0]); + }; /** - * The contents ob this object are valid + * Reads the PoolObjectSQL (identified by its OID) from the database. + * @param db pointer to the db + * @return 0 on success */ - bool valid; + virtual int select(SqlDB *db); + + /** + * Reads the PoolObjectSQL (identified by its OID) from the database. + * @param db pointer to the db + * @return 0 on success + */ + virtual int select(SqlDB *db, const string& _name, int _uid); + + /** + * Drops object from the database + * @param db pointer to the db + * @return 0 on success + */ + virtual int drop(SqlDB *db); + + /** + * Function to output a pool object into a stream in XML format + * @param oss the output stream + * @param num the number of columns read from the DB + * @param names the column names + * @param vaues the column values + * @return 0 on success + */ + static int dump(ostringstream& oss, int num, char **values, char **names) + { + if ( (!values[0]) || (num != 1) ) + { + return -1; + } + + oss << values[0]; + return 0; + }; + + /** + * The object's unique ID + */ + int oid; + + /** + * The object's name + */ + string name; + + /** + * Object's owner, set it to -1 if owner is not used + */ + int uid; + + /** + * The contents of this object are valid + */ + bool valid; private: @@ -110,6 +210,11 @@ private: * IS LOCKED when the class destructor is called. */ pthread_mutex_t mutex; + + /** + * Pointer to the SQL table for the PoolObjectSQL + */ + const char * table; }; #endif /*POOL_OBJECT_SQL_H_*/ diff --git a/include/PoolSQL.h b/include/PoolSQL.h index d095e692ab..fef4fee546 100644 --- a/include/PoolSQL.h +++ b/include/PoolSQL.h @@ -45,6 +45,7 @@ public: * @param _db a pointer to the database * @param table the name of the table supporting the pool (to set the oid * counter). If null the OID counter is not updated. + * @param with_uid the Pool objects have an owner id (uid) */ PoolSQL(SqlDB * _db, const char * table); @@ -68,9 +69,18 @@ public: * * @return a pointer to the object, 0 in case of failure */ - virtual PoolObjectSQL * get( - int oid, - bool lock); + PoolObjectSQL * get(int oid, bool lock); + + /** + * Gets an object from the pool (if needed the object is loaded from the + * database). + * @param name of the object + * @param uid id of owner + * @param lock locks the object if true + * + * @return a pointer to the object, 0 in case of failure + */ + PoolObjectSQL * get(const string& name, int uid, bool lock); /** * Finds a set objects that satisfies a given condition @@ -141,6 +151,27 @@ protected: */ SqlDB * db; + /** + * Dumps the pool in XML format. A filter can be also added to the + * query + * @param oss the output stream to dump the pool contents + * @param elem_name Name of the root xml pool name + * @param table Pool table name + * @param where filter for the objects, defaults to all + * + * @return 0 on success + */ + int dump(ostringstream& oss, const string& elem_name, + const char * table, const string& where); + + /** + * Returns the value of the last identifier assigned by the pool + */ + int get_lastOID() + { + return lastOID; + }; + private: pthread_mutex_t mutex; @@ -156,7 +187,7 @@ private: * Last object ID assigned to an object. It must be initialized by the * target pool. */ - int lastOID; + int lastOID; /** * The pool is implemented with a Map of SQL object pointers, using the @@ -164,6 +195,12 @@ private: */ map pool; + /** + * This is a name index for the pool map. The key is the name of the object + * , that may be combained with the owner id. + */ + map name_pool; + /** * Factory method, must return an ObjectSQL pointer to an allocated pool * specific object. @@ -200,6 +237,25 @@ private: */ void replace(); + /** + * Generate an index key for the object + * @param name of the object + * @param uid owner of the object, only used if needed + * + * @return the key, a string + */ + string key(const string& name, int uid) + { + ostringstream key; + + key << name << ':' << uid; + + return key.str(); + }; + + /* ---------------------------------------------------------------------- */ + /* ---------------------------------------------------------------------- */ + /** * Callback to set the lastOID (PoolSQL::PoolSQL) */ @@ -209,6 +265,15 @@ private: * Callback to store the IDs of pool objects (PoolSQL::search) */ int search_cb(void *_oids, int num, char **values, char **names); + + /** + * Callback function to get output in XML format + * @param num the number of columns read from the DB + * @param names the column names + * @param vaues the column values + * @return 0 on success + */ + int dump_cb(void * _oss, int num, char **values, char **names); }; #endif /*POOL_SQL_H_*/ diff --git a/include/RequestManager.h b/include/RequestManager.h index 11d589f88b..4128b20784 100644 --- a/include/RequestManager.h +++ b/include/RequestManager.h @@ -23,6 +23,7 @@ #include "UserPool.h" #include "VirtualNetworkPool.h" #include "ImagePool.h" +#include "ClusterPool.h" #include #include @@ -44,10 +45,12 @@ public: VirtualNetworkPool * _vnpool, UserPool * _upool, ImagePool * _ipool, + ClusterPool * _cpool, int _port, string _xml_log_file) :vmpool(_vmpool),hpool(_hpool),vnpool(_vnpool),upool(_upool), - ipool(_ipool),port(_port),socket_fd(-1),xml_log_file(_xml_log_file) + ipool(_ipool),cpool(_cpool),port(_port),socket_fd(-1), + xml_log_file(_xml_log_file) { am.addListener(this); }; @@ -126,6 +129,11 @@ private: */ ImagePool * ipool; + /** + * Pointer to the Image Pool, to access images + */ + ClusterPool * cpool; + /** * Port number where the connection will be open */ @@ -478,7 +486,7 @@ private: vmpool(_vmpool), upool(_upool) { - _signature="A:sibi"; + _signature="A:sii"; _help="Returns the virtual machine pool"; }; @@ -632,10 +640,10 @@ private: { public: ClusterAllocate( - HostPool * _hpool, - UserPool * _upool): - hpool(_hpool), - upool(_upool) + UserPool * _upool, + ClusterPool * _cpool): + upool(_upool), + cpool(_cpool) { _signature="A:ss"; _help="Allocates a cluster in the pool"; @@ -648,8 +656,8 @@ private: xmlrpc_c::value * const retvalP); private: - HostPool * hpool; - UserPool * upool; + UserPool * upool; + ClusterPool * cpool; }; /* ---------------------------------------------------------------------- */ @@ -658,10 +666,10 @@ private: { public: ClusterInfo( - HostPool * _hpool, - UserPool * _upool): - hpool(_hpool), - upool(_upool) + UserPool * _upool, + ClusterPool * _cpool): + upool(_upool), + cpool(_cpool) { _signature="A:si"; _help="Returns cluster information"; @@ -674,8 +682,8 @@ private: xmlrpc_c::value * const retvalP); private: - HostPool * hpool; - UserPool * upool; + UserPool * upool; + ClusterPool * cpool; }; /* ---------------------------------------------------------------------- */ @@ -684,10 +692,10 @@ private: { public: ClusterDelete( - HostPool * _hpool, - UserPool * _upool): - hpool(_hpool), - upool(_upool) + UserPool * _upool, + ClusterPool * _cpool): + upool(_upool), + cpool(_cpool) { _signature="A:si"; _help="Deletes a cluster from the pool"; @@ -700,8 +708,8 @@ private: xmlrpc_c::value * const retvalP); private: - HostPool * hpool; - UserPool * upool; + UserPool * upool; + ClusterPool * cpool; }; /* ---------------------------------------------------------------------- */ @@ -710,10 +718,12 @@ private: { public: ClusterAdd( - HostPool * _hpool, - UserPool * _upool): + HostPool * _hpool, + UserPool * _upool, + ClusterPool * _cpool): hpool(_hpool), - upool(_upool) + upool(_upool), + cpool(_cpool) { _signature="A:sii"; _help="Adds a host to a cluster"; @@ -726,8 +736,9 @@ private: xmlrpc_c::value * const retvalP); private: - HostPool * hpool; - UserPool * upool; + HostPool * hpool; + UserPool * upool; + ClusterPool * cpool; }; /* ---------------------------------------------------------------------- */ @@ -736,10 +747,12 @@ private: { public: ClusterRemove( - HostPool * _hpool, - UserPool * _upool): + HostPool * _hpool, + UserPool * _upool, + ClusterPool * _cpool): hpool(_hpool), - upool(_upool) + upool(_upool), + cpool(_cpool) { _signature="A:si"; _help="Removes a host from its cluster"; @@ -752,8 +765,9 @@ private: xmlrpc_c::value * const retvalP); private: - HostPool * hpool; - UserPool * upool; + HostPool * hpool; + UserPool * upool; + ClusterPool * cpool; }; /* ---------------------------------------------------------------------- */ @@ -762,10 +776,10 @@ private: { public: ClusterPoolInfo( - HostPool * _hpool, - UserPool * _upool): - hpool(_hpool), - upool(_upool) + UserPool * _upool, + ClusterPool * _cpool): + upool(_upool), + cpool(_cpool) { _signature="A:s"; _help="Returns the cluster pool information"; @@ -778,8 +792,8 @@ private: xmlrpc_c::value * const retvalP); private: - HostPool * hpool; - UserPool * upool; + UserPool * upool; + ClusterPool * cpool; }; diff --git a/include/Template.h b/include/Template.h index 1f4a703302..d81cf4b8c2 100644 --- a/include/Template.h +++ b/include/Template.h @@ -176,6 +176,14 @@ public: */ int from_xml(const string &xml_str); + /** + * Rebuilds the object from an xml node + * @param node The xml node pointer + * + * @return 0 on success, -1 otherwise + */ + int from_xml_node(const xmlNodePtr node); + protected: /** * The template attributes @@ -215,6 +223,12 @@ private: * Name of the Root element for the XML document */ string xml_root; + + /** + * Builds the template attribute from the node + * @param root_element The xml element to build the template from. + */ + void rebuild_attributes(const xmlNode * root_element); }; /* -------------------------------------------------------------------------- */ diff --git a/include/User.h b/include/User.h index 9806b4839a..c2437bc617 100644 --- a/include/User.h +++ b/include/User.h @@ -36,13 +36,6 @@ public: */ friend ostream& operator<<(ostream& os, User& u); - /** - * Function to print the User object into a string in plain text - * @param str the resulting string - * @return a reference to the generated string - */ - string& to_str(string& str) const; - /** * Function to print the User object into a string in XML format * @param xml the resulting XML string @@ -50,15 +43,6 @@ public: */ string& to_xml(string& xml) const; - /** - * Get the User unique identifier UID, that matches the OID of the object - * @return UID User identifier - */ - int get_uid() const - { - return oid; - }; - /** * Check if the user is enabled * @return true if the user is enabled @@ -68,15 +52,6 @@ public: return enabled; } - /** - * Returns user username - * @return username User's hostname - */ - const string& get_username() const - { - return username; - }; - /** * Returns user password * @return username User's hostname @@ -102,14 +77,6 @@ public: enabled = false; }; - /** - * Sets user username - */ - void set_username(string _username) - { - username = _username; - }; - /** * Sets user password */ @@ -145,11 +112,6 @@ private: // User Attributes // ------------------------------------------------------------------------- - /** - * User's username - */ - string username; - /** * User's password */ @@ -191,16 +153,24 @@ private: db->exec(oss_user); }; + /** + * Rebuilds the object from an xml formatted string + * @param xml_str The xml-formatted string + * + * @return 0 on success, -1 otherwise + */ + int from_xml(const string &xml_str); + protected: // ************************************************************************* // Constructor // ************************************************************************* - User(int id=-1, - string _username="", - string _password="", - bool _enabled=true); + User(int id, + string _username, + string _password, + bool _enabled); virtual ~User(); @@ -208,58 +178,28 @@ protected: // DataBase implementation // ************************************************************************* - enum ColNames - { - OID = 0, - USERNAME = 1, - PASSWORD = 2, - ENABLED = 3, // 0 = false, 1 = true - LIMIT = 4 - }; - static const char * db_names; static const char * db_bootstrap; static const char * table; - /** - * Reads the User (identified with its OID=UID) from the database. - * @param db pointer to the db - * @return 0 on success - */ - virtual int select(SqlDB *db); - /** * Writes the User in the database. * @param db pointer to the db * @return 0 on success */ - virtual int insert(SqlDB *db, string& error_str); + int insert(SqlDB *db, string& error_str); /** * Writes/updates the User data fields in the database. * @param db pointer to the db * @return 0 on success */ - virtual int update(SqlDB *db); - - /** - * Drops USer from the database - * @param db pointer to the db - * @return 0 on success - */ - virtual int drop(SqlDB *db); - - /** - * Function to output a User object in to an stream in XML format - * @param oss the output stream - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - static int dump(ostringstream& oss, int num, char **values, char **names); + int update(SqlDB *db) + { + return insert_replace(db, true); + } }; #endif /*USER_H_*/ diff --git a/include/UserPool.h b/include/UserPool.h index 4a68ae2e99..e381deb017 100644 --- a/include/UserPool.h +++ b/include/UserPool.h @@ -59,17 +59,12 @@ public: * it is loaded from the DB * @param oid User unique id * @param lock locks the User mutex - * @return a pointer to the Host, 0 if the User could not be loaded + * @return a pointer to the User, 0 if the User could not be loaded */ - User * get( - int oid, - bool lock) + User * get(int oid, bool lock) { - User * user = static_cast(PoolSQL::get(oid,lock)); - - return user; - } - + return static_cast(PoolSQL::get(oid,lock)); + }; /** * Function to get a User from the pool, if the object is not in memory @@ -78,21 +73,10 @@ public: * @param lock locks the User mutex * @return a pointer to the User, 0 if the User could not be loaded */ - User * get( - string username, - bool lock) + User * get(string name, bool lock) { - map::iterator index; - - index = known_users.find(username); - - if ( index != known_users.end() ) - { - return get((int)index->second,lock); - } - - return 0; - } + return static_cast(PoolSQL::get(name,-1,lock)); + }; /** Update a particular User * @param user pointer to User @@ -103,20 +87,12 @@ public: return user->update(db); }; - /** Drops a user from the DB, the user mutex MUST BE locked * @param user pointer to User */ int drop(User * user) { - int rc = PoolSQL::drop(user); - - if ( rc == 0) - { - known_users.erase(user->get_username()); - } - - return rc; + return PoolSQL::drop(user); }; /** @@ -149,7 +125,10 @@ public: * * @return 0 on success */ - int dump(ostringstream& oss, const string& where); + int dump(ostringstream& oss, const string& where) + { + return PoolSQL::dump(oss, "USER_POOL", User::table, where); + }; private: /** @@ -158,33 +137,8 @@ private: */ PoolObjectSQL * create() { - return new User; + return new User(-1,"","",true); }; - - /** - * This map stores the association between UIDs and Usernames - */ - map known_users; - - /** - * Callback function to get output the user pool in XML format - * (User::dump) - * @param _oss pointer to the output stream - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - int dump_cb(void * _oss, int num, char **values, char **names); - - /** - * Callback function to build the knwon_user map (User::User) - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - int init_cb(void *nil, int num, char **values, char **names); }; #endif /*USER_POOL_H_*/ diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 789f0ad095..970a0ae22f 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -119,14 +119,6 @@ public: */ friend ostream& operator<<(ostream& os, const VirtualMachine& vm); - /** - * Function to print the VirtualMachine object into a string in - * plain text - * @param str the resulting string - * @return a reference to the generated string - */ - string& to_str(string& str) const; - /** * Function to print the VirtualMachine object into a string in * XML format @@ -135,6 +127,14 @@ public: */ string& to_xml(string& xml) const; + /** + * Rebuilds the object from an xml formatted string + * @param xml_str The xml-formatted string + * + * @return 0 on success, -1 otherwise + */ + int from_xml(const string &xml_str); + // ------------------------------------------------------------------------ // Dynamic Info // ------------------------------------------------------------------------ @@ -183,16 +183,6 @@ public: } }; - - /** - * Returns the name of the VM - * @return the VM name - */ - const string& get_name() const - { - return name; - }; - /** * Returns the deployment ID * @return the VMM driver specific ID @@ -218,11 +208,11 @@ public: * Adds a new history record an writes it in the database. */ void add_history( - int hid, - string& hostname, - string& vm_dir, - string& vmm_mad, - string& tm_mad); + int hid, + const string& hostname, + const string& vm_dir, + const string& vmm_mad, + const string& tm_mad); /** * Duplicates the last history record. Only the host related fields are @@ -678,16 +668,6 @@ public: lcm_state = s; }; - /** - * Gets the user id of the owner of this VM - * @return the VM uid - */ - int get_uid() const - { - return uid; - }; - - // ------------------------------------------------------------------------ // Timers // ------------------------------------------------------------------------ @@ -733,6 +713,7 @@ public: /** * Get all disk images for this Virtual Machine + * @param error_str Returns the error reason, if any * @return 0 if success */ int get_disk_images(string &error_str); @@ -753,7 +734,6 @@ public: */ int generate_context(string &files); - // ------------------------------------------------------------------------ // Image repository related functions // ------------------------------------------------------------------------ @@ -779,11 +759,10 @@ private: // ------------------------------------------------------------------------- // Identification variables // ------------------------------------------------------------------------- - /** - * User (owner) id + * Owner's name */ - int uid; + string user_name; // ------------------------------------------------------------------------- // VM Scheduling & Managing Information @@ -797,11 +776,6 @@ private: // Virtual Machine Description // ------------------------------------------------------------------------- - /** - * Name of the VM - */ - string name; - /** * The Virtual Machine template, holds the VM attributes. */ @@ -854,11 +828,6 @@ private: */ int net_rx; - /** - * Sequence number of the last history item. - */ - int last_seq; - /** * History record, for the current host */ @@ -958,16 +927,18 @@ private: /** * Parse the "CONTEXT" attribute of the template by substituting * $VARIABLE, $VARIABLE[ATTR] and $VARIABLE[ATTR, ATTR = VALUE] + * @param error_str Returns the error reason, if any * @return 0 on success */ - int parse_context(); + int parse_context(string& error_str); /** * Parse the "REQUIREMENTS" attribute of the template by substituting * $VARIABLE, $VARIABLE[ATTR] and $VARIABLE[ATTR, ATTR = VALUE] + * @param error_str Returns the error reason, if any * @return 0 on success */ - int parse_requirements(); + int parse_requirements(string& error_str); /** * Parse the "GRAPHICS" attribute and generates a default PORT if not @@ -981,7 +952,8 @@ protected: // Constructor //************************************************************************** - VirtualMachine(int id=-1, VirtualMachineTemplate * _vm_template = 0); + VirtualMachine(int id, int uid, string _user_name, + VirtualMachineTemplate * _vm_template); virtual ~VirtualMachine(); @@ -989,32 +961,10 @@ protected: // DataBase implementation // ************************************************************************* - enum ColNames - { - OID = 0, - UID = 1, - NAME = 2, - LAST_POLL = 3, - STATE = 4, - LCM_STATE = 5, - STIME = 6, - ETIME = 7, - DEPLOY_ID = 8, - MEMORY = 9, - CPU = 10, - NET_TX = 11, - NET_RX = 12, - LAST_SEQ = 13, - TEMPLATE = 14, - LIMIT = 15 - }; - static const char * table; static const char * db_names; - static const char * extended_db_names; - static const char * db_bootstrap; /** @@ -1029,48 +979,28 @@ protected: * @param db pointer to the db * @return 0 on success */ - virtual int insert(SqlDB * db, string& error_str); + int insert(SqlDB * db, string& error_str); /** * Writes/updates the Virtual Machine data fields in the database. * @param db pointer to the db * @return 0 on success */ - virtual int update(SqlDB * db); + int update(SqlDB * db) + { + return insert_replace(db, true); + } /** * Deletes a VM from the database and all its associated information * @param db pointer to the db * @return -1 */ - virtual int drop(SqlDB * db) + int drop(SqlDB * db) { NebulaLog::log("ONE",Log::ERROR, "VM Drop not implemented!"); return -1; } - - /** - * Dumps the contect of a set of VirtualMachine objects in the given stream - * using XML format - * @param oss the output stream - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - static int dump(ostringstream& oss, int num, char ** values, char ** names); - - /** - * Dumps the contect of a set of VirtualMachine objects in the given stream - * using XML format - * @param oss the output stream - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - static int dump_extended( ostringstream& oss, - int num, char ** values, char ** names); }; #endif /*VIRTUAL_MACHINE_H_*/ diff --git a/include/VirtualMachinePool.h b/include/VirtualMachinePool.h index 94f12a2c32..c069357f61 100644 --- a/include/VirtualMachinePool.h +++ b/include/VirtualMachinePool.h @@ -48,11 +48,12 @@ public: * the template */ int allocate ( - int uid, - VirtualMachineTemplate *vm_template, - int * oid, - string& error_str, - bool on_hold = false); + int uid, + string user_name, + VirtualMachineTemplate * vm_template, + int * oid, + string& error_str, + bool on_hold = false); /** * Function to get a VM from the pool, if the object is not in memory @@ -134,7 +135,7 @@ public: */ int dump(ostringstream& oss, const string& where) { - return dump(oss, true, -1, where); + return dump(oss, -1, where); } /** @@ -149,7 +150,7 @@ public: * * @return 0 on success */ - int dump(ostringstream& oss, bool extended, int state, const string& where); + int dump(ostringstream& oss, int state, const string& where); private: /** @@ -158,29 +159,8 @@ private: */ PoolObjectSQL * create() { - return new VirtualMachine; + return new VirtualMachine(-1,-1,"", 0); }; - - /** - * Callback function to get output the vm pool in XML format - * (VirtualMachinePool::dump) - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - int dump_cb(void * _oss, int num, char **values, char **names); - - /** - * Callback function to get output the vm pool in XML format - * (VirtualMachinePool::dump) - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - int dump_extended_cb(void * _oss, int num, char **values, char **names); - }; #endif /*VIRTUAL_MACHINE_POOL_H_*/ diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index 2a67f3bf58..daf20f5d62 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -58,24 +58,6 @@ public: // Virtual Network Public Methods // ************************************************************************* - /** - * Get the Vnet unique identifier VNID, that matches the OID of the object - * @return VNID Image identifier - */ - int get_vnid() const - { - return oid; - }; - - /** - * Gets the uid of the owner of the Virtual Network - * @return uid - **/ - int get_uid() - { - return uid; - } - /** * Returns true if the Virtual Network is public * @return true if the Virtual Network is public @@ -175,14 +157,6 @@ public: */ friend ostream& operator<<(ostream& os, VirtualNetwork& vn); - /** - * Function to print the VirtualNetwork object into a string in - * plain text - * @param str the resulting string - * @return a reference to the generated string - */ - string& to_str(string& str) const; - /** * Function to print the VirtualNetwork object into a string in * XML format @@ -274,14 +248,9 @@ private: // Identification variables // ------------------------------------------------------------------------- /** - * Name of the Virtual Network + * Owner's name */ - string name; - - /** - * Owner of the Virtual Network - */ - int uid; + string user_name; // ------------------------------------------------------------------------- // Binded physical attributes @@ -341,28 +310,29 @@ private: }; /** - * Callback function to unmarshall a VNW object (VirtualNetwork::select) - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success + * Function to print the VirtualNetwork object into a string in + * XML format + * @param xml the resulting XML string + * @param extended If true, leases are included + * @return a reference to the generated string */ - int select_cb(void * nil, int num, char **values, char **names); + string& to_xml_extended(string& xml, bool extended) const; /** - * Function to drop VN entry in vn_pool - * @return 0 on success + * Rebuilds the object from an xml formatted string + * @param xml_str The xml-formatted string + * + * @return 0 on success, -1 otherwise */ - int vn_drop(SqlDB * db); - - -protected: + int from_xml(const string &xml_str); //************************************************************************** // Constructor //************************************************************************** - VirtualNetwork(VirtualNetworkTemplate * _vn_template = 0); + VirtualNetwork(int uid, + string _user_name, + VirtualNetworkTemplate * _vn_template = 0); ~VirtualNetwork(); @@ -370,24 +340,10 @@ protected: // DataBase implementation // ************************************************************************* - enum ColNames - { - OID = 0, - UID = 1, - NAME = 2, - TYPE = 3, - BRIDGE = 4, - PUBLIC = 5, - TEMPLATE = 6, - LIMIT = 7 - }; - static const char * table; static const char * db_names; - static const char * extended_db_names; - static const char * db_bootstrap; /** @@ -397,6 +353,23 @@ protected: */ int select(SqlDB * db); + /** + * Reads the Virtual Network (identified with its OID) from the database. + * @param db pointer to the db + * @param name of the network + * @param uid of the owner + * + * @return 0 on success + */ + int select(SqlDB * db, const string& name, int uid); + + /** + * Reads the Virtual Network leases from the database. + * @param db pointer to the db + * @return 0 on success + */ + int select_leases(SqlDB * db); + /** * Writes the Virtual Network and its associated template and leases in the database. * @param db pointer to the db @@ -409,7 +382,10 @@ protected: * @param db pointer to the db * @return 0 on success */ - int update(SqlDB * db); + int update(SqlDB * db) + { + return insert_replace(db, true); + } /** * Deletes a VNW from the database and all its associated information: @@ -418,27 +394,7 @@ protected: * @param db pointer to the db * @return 0 on success */ - int drop(SqlDB * db) - { - int rc; - - rc = leases->drop(db); - - rc += vn_drop(db); - - return rc; - } - - /** - * Dumps the contect of a VirtualNetwork object in the given stream using - * XML format - * @param oss the output stream - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - static int dump(ostringstream& oss, int num, char **values, char **names); + int drop(SqlDB * db); }; #endif /*VIRTUAL_NETWORK_H_*/ diff --git a/include/VirtualNetworkPool.h b/include/VirtualNetworkPool.h index c49aec9323..09e908cf93 100644 --- a/include/VirtualNetworkPool.h +++ b/include/VirtualNetworkPool.h @@ -48,6 +48,7 @@ public: */ int allocate ( int uid, + string user_name, VirtualNetworkTemplate * vn_template, int * oid, string& error_str); @@ -59,9 +60,7 @@ public: * @param lock locks the VN mutex * @return a pointer to the VN, 0 if the VN could not be loaded */ - VirtualNetwork * get( - int oid, - bool lock) + VirtualNetwork * get(int oid, bool lock) { return static_cast(PoolSQL::get(oid,lock)); }; @@ -70,12 +69,14 @@ public: * Function to get a VN from the pool using the network name * If the object is not in memory it is loaded from the DB * @param name VN unique name + * @param uid of the VN owner * @param lock locks the VN mutex * @return a pointer to the VN, 0 if the VN could not be loaded */ - VirtualNetwork * get( - const string& name, - bool lock); + VirtualNetwork * get(const string& name, int uid, bool lock) + { + return static_cast(PoolSQL::get(name,uid,lock)); + }; //-------------------------------------------------------------------------- // Virtual Network DB access functions @@ -88,14 +89,14 @@ public: * @param vid of the VM requesting the lease * @return 0 on success, -1 error, -2 not using the pool */ - int nic_attribute(VectorAttribute * nic, int vid); + int nic_attribute(VectorAttribute * nic, int uid, int vid); /** * Generates an Authorization token for a NIC attribute * @param nic the nic to be authorized * @param ar the AuthRequest */ - void authorize_nic(VectorAttribute * nic, AuthRequest * ar); + void authorize_nic(VectorAttribute * nic, int uid, AuthRequest * ar); /** * Bootstraps the database table(s) associated to the VirtualNetwork pool @@ -113,7 +114,10 @@ public: * * @return 0 on success */ - int dump(ostringstream& oss, const string& where); + int dump(ostringstream& oss, const string& where) + { + return PoolSQL::dump(oss, "VNET_POOL", VirtualNetwork::table,where); + } /** * Get the mac prefix @@ -150,28 +154,8 @@ private: */ PoolObjectSQL * create() { - return new VirtualNetwork(); + return new VirtualNetwork(0,"",0); }; - - /** - * Callback function to get output the virtual network pool in XML format - * (VirtualNetworkPool::dump) - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - int dump_cb(void * _oss, int num, char **values, char **names); - - /** - * Callback function to get the ID of a given virtual network - * (VirtualNetworkPool::get) - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - int get_cb(void * _oss, int num, char **values, char **names); }; #endif /*VIRTUAL_NETWORK_POOL_H_*/ diff --git a/include/test/NebulaTest.h b/include/test/NebulaTest.h index b02cdc3056..18589b0da4 100644 --- a/include/test/NebulaTest.h +++ b/include/test/NebulaTest.h @@ -25,6 +25,7 @@ #include "VirtualNetworkPool.h" #include "HostPool.h" #include "UserPool.h" +#include "ClusterPool.h" #include "VirtualMachineManager.h" #include "LifeCycleManager.h" @@ -41,7 +42,7 @@ protected: NebulaTest():mysql(false), need_host_pool(false), need_vm_pool(false), need_vnet_pool(false), need_image_pool(false), - need_user_pool(false), need_vmm(false), + need_user_pool(false), need_cluster_pool(false),need_vmm(false), need_im(false), need_tm(false), need_lcm(false), need_dm(false), need_rm(false), need_hm(false), @@ -60,6 +61,7 @@ public: bool need_vnet_pool; bool need_image_pool; bool need_user_pool; + bool need_cluster_pool; bool need_vmm; bool need_im; @@ -94,6 +96,8 @@ public: string default_image_type, string default_device_prefix); + virtual ClusterPool* create_cpool(SqlDB* db); + // ------------------------------------------------------------------------ // Managers // ------------------------------------------------------------------------ @@ -122,6 +126,7 @@ public: VirtualNetworkPool * vnpool, UserPool * upool, ImagePool * ipool, + ClusterPool * cpool, string log_file); virtual HookManager* create_hm(VirtualMachinePool * vmpool); diff --git a/include/test/PoolTest.h b/include/test/PoolTest.h index ce952ed3e0..1e5afe32d9 100644 --- a/include/test/PoolTest.h +++ b/include/test/PoolTest.h @@ -166,14 +166,14 @@ public: { // The pool is empty // Non existing oid - obj = pool->get(13, true); + obj = pool->get(13, false); CPPUNIT_ASSERT( obj == 0 ); // Allocate an object allocate(0); // Ask again for a non-existing oid - obj = pool->get(213, true); + obj = pool->get(213, false); CPPUNIT_ASSERT( obj == 0 ); } diff --git a/share/test/do_tests.sh b/share/test/do_tests.sh index 6eb634a459..c56fa0a3e6 100755 --- a/share/test/do_tests.sh +++ b/share/test/do_tests.sh @@ -6,10 +6,11 @@ TWD_DIR="../../src" BASE_DIR=$PWD TESTS="$TWD_DIR/vnm/test \ - $TWD_DIR/scheduler/src/xml/test \ + $TWD_DIR/xml/test \ $TWD_DIR/scheduler/src/pool/test \ $TWD_DIR/common/test \ $TWD_DIR/host/test \ + $TWD_DIR/cluster/test \ $TWD_DIR/template/test \ $TWD_DIR/image/test \ $TWD_DIR/authm/test \ diff --git a/src/cluster/Cluster.cc b/src/cluster/Cluster.cc new file mode 100644 index 0000000000..185604d78f --- /dev/null +++ b/src/cluster/Cluster.cc @@ -0,0 +1,184 @@ +/* ------------------------------------------------------------------------ */ +/* Copyright 2002-2010, 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. */ +/* ------------------------------------------------------------------------ */ + +#include +#include + +#include +#include + +#include "Cluster.h" + + +const char * Cluster::table = "cluster_pool"; + +const char * Cluster::db_names = "oid, name, body"; + +const char * Cluster::db_bootstrap = "CREATE TABLE IF NOT EXISTS cluster_pool (" + "oid INTEGER PRIMARY KEY, name VARCHAR(256), body TEXT, UNIQUE(name))"; + + +/* ************************************************************************ */ +/* Cluster :: Constructor/Destructor */ +/* ************************************************************************ */ + +Cluster::Cluster(int id, const string& name):PoolObjectSQL(id,name,-1,table){}; + +Cluster::~Cluster(){}; + +/* ************************************************************************ */ +/* Cluster :: Database Access Functions */ +/* ************************************************************************ */ + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +int Cluster::insert(SqlDB *db, string& error_str) +{ + int rc; + + rc = insert_replace(db, false); + + if ( rc != 0 ) + { + error_str = "Error inserting Cluster in DB."; + } + + return rc; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +int Cluster::update(SqlDB *db) +{ + int rc; + + rc = insert_replace(db, true); + + return rc; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +int Cluster::insert_replace(SqlDB *db, bool replace) +{ + ostringstream oss; + + int rc; + string xml_body; + + char * sql_name; + char * sql_xml; + + // Update the Cluster + + sql_name = db->escape_str(name.c_str()); + + if ( sql_name == 0 ) + { + goto error_name; + } + + sql_xml = db->escape_str(to_xml(xml_body).c_str()); + + if ( sql_xml == 0 ) + { + goto error_body; + } + + if(replace) + { + oss << "REPLACE"; + } + else + { + oss << "INSERT"; + } + + // Construct the SQL statement to Insert or Replace + + oss <<" INTO "<exec(oss); + + db->free_str(sql_name); + db->free_str(sql_xml); + + return rc; + +error_body: + db->free_str(sql_name); +error_name: + return -1; +} + +/* ************************************************************************ */ +/* Cluster :: Misc */ +/* ************************************************************************ */ + +ostream& operator<<(ostream& os, Cluster& cluster) +{ + string cluster_str; + + os << cluster.to_xml(cluster_str); + + return os; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +string& Cluster::to_xml(string& xml) const +{ + ostringstream oss; + + oss << + "" << + "" << oid << "" << + "" << name << "" << + ""; + + xml = oss.str(); + + return xml; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +int Cluster::from_xml(const string& xml) +{ + int rc = 0; + + // Initialize the internal XML object + update_from_str(xml); + + // Get class base attributes + rc += xpath(oid, "/CLUSTER/ID", -1); + rc += xpath(name,"/CLUSTER/NAME", "not_found"); + + if (rc != 0) + { + return -1; + } + + return 0; +} diff --git a/src/cluster/ClusterPool.cc b/src/cluster/ClusterPool.cc new file mode 100644 index 0000000000..ef1280e8ef --- /dev/null +++ b/src/cluster/ClusterPool.cc @@ -0,0 +1,150 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2010, 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. */ +/* -------------------------------------------------------------------------- */ + +#include "ClusterPool.h" +#include "Nebula.h" +#include "NebulaLog.h" + +#include + +const string ClusterPool::DEFAULT_CLUSTER_NAME = "default"; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +ClusterPool::ClusterPool(SqlDB * db):PoolSQL(db, Cluster::table) +{ + // lastOID is set in PoolSQL::init_cb + if (get_lastOID() == -1) + { + int rc; + Cluster * cluster; + string error_str; + + // Build a new Cluster object + cluster = new Cluster(0, ClusterPool::DEFAULT_CLUSTER_NAME); + + // Insert the Object in the pool + rc = PoolSQL::allocate(cluster, error_str); + + if(rc != 0) + { + ostringstream oss; + + oss << "Error trying to create default cluster: " << error_str; + NebulaLog::log("CLUSTER",Log::ERROR,oss); + + throw runtime_error(oss.str()); + } + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int ClusterPool::allocate(int * oid, string name, string& error_str) +{ + Cluster * cluster; + ostringstream oss; + + if ( name.empty() ) + { + goto error_name; + } + + // Check for duplicates + cluster = get(name, false); + + if( cluster != 0 ) + { + goto error_duplicated; + } + + // Build a new Cluster object + cluster = new Cluster(-1, name); + + // Insert the Object in the pool + *oid = PoolSQL::allocate(cluster, error_str); + + return *oid; + + +error_name: + oss << "NAME cannot be empty."; + goto error_common; + +error_duplicated: + oss << "NAME is already taken by CLUSTER " << cluster->get_oid() << "."; + +error_common: + *oid = -1; + error_str = oss.str(); + + return *oid; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int ClusterPool::drop(Cluster * cluster) +{ + int rc; + + Host* host; + vector hids; + vector::iterator hid_it; + + Nebula& nd = Nebula::instance(); + HostPool * hpool = nd.get_hpool(); + + string cluster_name = cluster->get_name(); + string where = "cluster = '" + cluster_name + "'"; + + // Return error if cluster is 'default' + if( cluster->get_oid() == 0 ) + { + NebulaLog::log("CLUSTER",Log::WARNING, + "Default cluster cannot be deleted."); + + return -1; + } + + rc = cluster->drop(db); + + // Move the hosts assigned to the deleted cluster to the default one + if( rc == 0 ) + { + hpool->search(hids, where); + + for ( hid_it=hids.begin() ; hid_it < hids.end(); hid_it++ ) + { + host = hpool->get(*hid_it, true); + + if ( host == 0 ) + { + continue; + } + + set_default_cluster(host); + + hpool->update(host); + + host->unlock(); + } + } + + return rc; +} diff --git a/src/cluster/SConstruct b/src/cluster/SConstruct new file mode 100644 index 0000000000..9112f8fbba --- /dev/null +++ b/src/cluster/SConstruct @@ -0,0 +1,30 @@ +# SConstruct for src/cluster + +# -------------------------------------------------------------------------- # +# Copyright 2002-2010, 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. # +#--------------------------------------------------------------------------- # + +Import('env') + +lib_name='nebula_cluster' + +# Sources to generate the library +source_files=[ + 'ClusterPool.cc', + 'Cluster.cc' +] + +# Build library +env.StaticLibrary(lib_name, source_files) diff --git a/src/cluster/test/ClusterPoolTest.cc b/src/cluster/test/ClusterPoolTest.cc new file mode 100644 index 0000000000..bdb102dd05 --- /dev/null +++ b/src/cluster/test/ClusterPoolTest.cc @@ -0,0 +1,415 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2010, 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. */ +/* -------------------------------------------------------------------------- */ + +#include +#include +#include + +#include "ClusterPool.h" +#include "PoolTest.h" + +using namespace std; + +const string names[] = {"cluster_a", "Second cluster"}; + +const string xmls[] = +{ + "1cluster_a", + "2Second cluster" +}; + +const string cluster_default = + "0default"; + +const string cluster_xml_dump = + "0default1cluster_a3cluster_c4cluster_d"; + +const string host_0_cluster = + "0Host one0im_madvmm_madtm_mad0cluster_a0000000000000"; + +const string host_0_default = + "0Host one0" + "im_madvmm_madtm_mad" + "0default" + "000" + "000" + "000" + "000" + "0"; + +/* ************************************************************************* */ +/* ************************************************************************* */ + + +#include "NebulaTest.h" + +class NebulaTestCluster: public NebulaTest +{ +public: + NebulaTestCluster():NebulaTest() + { + NebulaTest::the_tester = this; + + need_host_pool = true; + need_cluster_pool= true; + } +}; + +class ClusterPoolTest : public PoolTest +{ + CPPUNIT_TEST_SUITE (ClusterPoolTest); + + // Not all tests from PoolTest can be used. Because + // of the initial default cluster added to the DB, the + // oid_assignment would fail. + CPPUNIT_TEST (get_from_cache); + CPPUNIT_TEST (get_from_db); + CPPUNIT_TEST (wrong_get); + CPPUNIT_TEST (drop_and_get); + + CPPUNIT_TEST (name_pool); + + CPPUNIT_TEST (duplicates); + CPPUNIT_TEST (set_cluster); + CPPUNIT_TEST (remove_cluster); + CPPUNIT_TEST (delete_cluster); + CPPUNIT_TEST (dump); + + CPPUNIT_TEST_SUITE_END (); + +protected: + + NebulaTestCluster * tester; + HostPool * hpool; + ClusterPool * cpool; + + + + void bootstrap(SqlDB* db) + { + // setUp overwritten + }; + + PoolSQL* create_pool(SqlDB* db) + { + // setUp overwritten + return cpool; + }; + + int allocate(int index) + { + int oid; + string err; + + return cpool->allocate(&oid, names[index], err); + }; + + void check(int index, PoolObjectSQL* obj) + { + Cluster * cluster = static_cast(obj); + + CPPUNIT_ASSERT( obj != 0 ); + + string xml_str = ""; + string name = cluster->get_name(); + + CPPUNIT_ASSERT( name == names[index] ); + + // Get the xml + cluster->to_xml(xml_str); + +// A little help for debugging +/* + if( xml_str != xmls[index] ) + { + cout << endl << xml_str << endl << "========" + << endl << xmls[index]; + } +//*/ + CPPUNIT_ASSERT( xml_str == xmls[index]); + }; + +private: + + /** + * Allocates a Host. + */ + void init_hp() + { + int oid; + string err; + + // Allocate a host + oid = hpool->allocate(&oid, "Host one","im_mad","vmm_mad", "tm_mad", err); + CPPUNIT_ASSERT(oid == 0); + + hpool->clean(); + }; + +public: + ClusterPoolTest() + { + xmlInitParser(); + }; + + ~ClusterPoolTest() + { + xmlCleanupParser(); + }; + + void setUp() + { + create_db(); + + tester = new NebulaTestCluster(); + + Nebula& neb = Nebula::instance(); + neb.start(); + + hpool = neb.get_hpool(); + cpool = neb.get_cpool(); + + pool = cpool; + }; + + void tearDown() + { + delete_db(); + + delete tester; + }; + + /* ********************************************************************* */ + /* ********************************************************************* */ + + // Test intended to check the PoolSQL name index functionallity + void name_pool() + { + Cluster * cluster; + int oid; + string err; + + + // Allocate some clusters + cpool->allocate(&oid, "name_1", err); + CPPUNIT_ASSERT( oid == 1 ); + + cpool->allocate(&oid, "name_2", err); + CPPUNIT_ASSERT( oid == 2 ); + + cpool->allocate(&oid, "name_3", err); + CPPUNIT_ASSERT( oid == 3 ); + + // Clean the cache + cpool->clean(); + + cpool->allocate(&oid, "name_4", err); + CPPUNIT_ASSERT( oid == 4 ); + + cpool->allocate(&oid, "name_5", err); + CPPUNIT_ASSERT( oid == 5 ); + + // Cluster names 0-3 should be unknown, and 4-5 cached + // Ask for a cached object + cluster = cpool->get("name_5", false); + CPPUNIT_ASSERT( cluster != 0 ); + CPPUNIT_ASSERT( cluster->get_oid() == 5 ); + CPPUNIT_ASSERT( cluster->get_name() == "name_5" ); + + // Ask for non-cached object + cluster = cpool->get("name_2", false); + CPPUNIT_ASSERT( cluster != 0 ); + CPPUNIT_ASSERT( cluster->get_oid() == 2 ); + CPPUNIT_ASSERT( cluster->get_name() == "name_2" ); + + // Ask for non-existing object + cluster = cpool->get("name_X", false); + CPPUNIT_ASSERT( cluster == 0 ); + }; + + /* ********************************************************************* */ + + void duplicates() + { + int rc, oid; + string err; + + // Allocate a cluster. + rc = cpool->allocate(&oid, names[1], err); + CPPUNIT_ASSERT( oid == 1 ); + CPPUNIT_ASSERT( oid == rc ); + + // Try to allocate twice the same cluster, should fail + rc = cpool->allocate(&oid, names[1], err); + CPPUNIT_ASSERT( rc == -1 ); + CPPUNIT_ASSERT( oid == rc ); + } + + /* ********************************************************************* */ + + void set_cluster() + { + Host* host; + int rc; + string xml_str, err; + + init_hp(); + + host = hpool->get(0, false); + CPPUNIT_ASSERT(host != 0); + + rc = host->set_cluster("cluster_a"); + CPPUNIT_ASSERT( rc == 0 ); + + hpool->update(host); + + host->to_xml(xml_str); + CPPUNIT_ASSERT( xml_str == host_0_cluster); + } + + /* ********************************************************************* */ + + void remove_cluster() + { + Host* host; + + int rc; + string xml_str; + + init_hp(); + + host = hpool->get(0, false); + CPPUNIT_ASSERT(host != 0); + + // Set cluster + rc = host->set_cluster("cluster_a"); + CPPUNIT_ASSERT( rc == 0 ); + + hpool->update(host); + + host->to_xml(xml_str); + CPPUNIT_ASSERT( xml_str == host_0_cluster); + + // Remove from the cluster + rc = cpool->set_default_cluster(host); + CPPUNIT_ASSERT( rc == 0 ); + + hpool->update(host); + + // The host should have been moved to the default cluster + + host = hpool->get(0, false); + CPPUNIT_ASSERT(host != 0); + + host->to_xml(xml_str); + CPPUNIT_ASSERT( xml_str == host_0_default); + } + + /* ********************************************************************* */ + + void delete_cluster() + { + Host * host; + Cluster * cluster; + + int rc, oid; + string xml_str; + + init_hp(); + host = hpool->get(0, false); + CPPUNIT_ASSERT(host != 0); + + // Allocate a cluster + oid = allocate(0); + CPPUNIT_ASSERT(oid == 1); + + cluster = cpool->get(1, false); + + // Set cluster + rc = host->set_cluster(cluster->get_name()); + CPPUNIT_ASSERT( rc == 0 ); + + hpool->update(host); + + host->to_xml(xml_str); + CPPUNIT_ASSERT( xml_str == host_0_cluster); + + // Delete the cluster + rc = cpool->drop(cluster); + CPPUNIT_ASSERT( rc == 0 ); + + // The host should have been moved to the default cluster + host = hpool->get(0, false); + host->to_xml(xml_str); +/* + if( xml_str != host_0_default ) + { + cout << endl << xml_str << endl << "========" + << endl << host_0_default; + } +//*/ + CPPUNIT_ASSERT( xml_str == host_0_default); + } + + /* ********************************************************************* */ + + void dump() + { + Cluster * cluster; + int oid, rc; + ostringstream oss; + string err; + + // Allocate some clusters + rc = cpool->allocate(&oid, "cluster_a", err); + CPPUNIT_ASSERT( rc == 1 ); + + rc = cpool->allocate(&oid, "cluster_b", err); + CPPUNIT_ASSERT( rc == 2 ); + + rc = cpool->allocate(&oid, "cluster_c", err); + CPPUNIT_ASSERT( rc == 3 ); + + rc = cpool->allocate(&oid, "cluster_d", err); + CPPUNIT_ASSERT( rc == 4 ); + + // Drop one of them + cluster = cpool->get(2, false); + CPPUNIT_ASSERT( cluster != 0 ); + + rc = cpool->drop(cluster); + CPPUNIT_ASSERT( rc == 0 ); + + // dump the pool + rc = cpool->dump(oss,""); +/* + if( oss.str() != cluster_xml_dump ) + { + cout << endl << oss.str() << endl << "========" + << endl << cluster_xml_dump; + } +//*/ + CPPUNIT_ASSERT( oss.str() == cluster_xml_dump ); + } +}; + +/* ************************************************************************* */ +/* ************************************************************************* */ + +int main(int argc, char ** argv) +{ + return PoolTest::main(argc, argv, ClusterPoolTest::suite()); +} diff --git a/src/cluster/test/SConstruct b/src/cluster/test/SConstruct new file mode 100644 index 0000000000..b55dee66c1 --- /dev/null +++ b/src/cluster/test/SConstruct @@ -0,0 +1,56 @@ +# -------------------------------------------------------------------------- +# Copyright 2002-2010, 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. +# -------------------------------------------------------------------------- + +Import('env') + +env.Prepend(LIBS=[ + 'nebula_cluster', + 'nebula_host', + 'nebula_pool', + 'nebula_template', + 'nebula_xml', + 'nebula_log', + 'nebula_common', + 'nebula_sql', + + +### TODO: delete not needed + 'nebula_core_test', + 'nebula_host', + 'nebula_cluster', + 'nebula_xml', + 'nebula_vmm', + 'nebula_im', + 'nebula_rm', + 'nebula_tm', + 'nebula_um', + 'nebula_mad', + 'nebula_template', + 'nebula_vm', + 'nebula_vnm', + 'nebula_image', + 'nebula_pool', + 'nebula_hm', + 'nebula_authm', + 'nebula_common', + 'nebula_lcm', + 'nebula_dm', + 'nebula_sql', + 'nebula_log', + 'crypto' +]) + +env.Program('test','ClusterPoolTest.cc') diff --git a/src/host/ClusterPool.cc b/src/host/ClusterPool.cc deleted file mode 100644 index 9376bec747..0000000000 --- a/src/host/ClusterPool.cc +++ /dev/null @@ -1,185 +0,0 @@ -/* -------------------------------------------------------------------------- */ -/* Copyright 2002-2011, 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. */ -/* -------------------------------------------------------------------------- */ - -#include "ClusterPool.h" -#include "NebulaLog.h" - -const char * ClusterPool::table = "cluster_pool"; - -const char * ClusterPool::db_names = "oid, cluster_name"; - -const char * ClusterPool::db_bootstrap = - "CREATE TABLE IF NOT EXISTS cluster_pool (" - "oid INTEGER PRIMARY KEY, cluster_name VARCHAR(128), " - "UNIQUE(cluster_name) )"; - -const string ClusterPool::DEFAULT_CLUSTER_NAME = "default"; - -/* -------------------------------------------------------------------------- */ - -int ClusterPool::allocate(int * clid, string name, SqlDB *db, string& error_str) -{ - int rc; - map::iterator it; - - ostringstream oss; - - // Return error if name already exists - for(it=cluster_names.begin();it!=cluster_names.end();it++) - { - if(it->second == name) - { - goto error_existing_name; - } - } - - // Get the highest key, and add 1 - *clid = cluster_names.rbegin()->first + 1; - - rc = insert(*clid, name, db); - - if(rc != 0) - { - goto error_db; - } - - return *clid; - - -error_existing_name: - oss << "Could not allocate new cluster: " - << name << ", already exists."; - - goto error_common; -error_db: - oss << "Could not allocate new cluster " << name << "."; - goto error_common; - -error_common: - error_str = oss.str(); - NebulaLog::log("CLUSTER", Log::ERROR, oss); - - *clid = -1; - return *clid; -} - -/* -------------------------------------------------------------------------- */ - -string ClusterPool::info(int clid) -{ - ostringstream oss; - - map::iterator it; - - it = cluster_names.find(clid); - - if(it != cluster_names.end()) - { - dump_cluster(oss, it->first, it->second); - } - - return oss.str(); -} - -/* -------------------------------------------------------------------------- */ - -int ClusterPool::drop(int clid, SqlDB *db) -{ - int rc; - ostringstream oss; - - // Return error if cluster is 'default' or if it doesn't exist - if( clid == 0 || cluster_names.count(clid) == 0 ) - { - return -1; - } - - oss << "DELETE FROM " << table << " WHERE oid=" << clid; - - rc = db->exec(oss); - - if(rc == 0) - { - cluster_names.erase(clid); - } - - return rc; -} - -/* -------------------------------------------------------------------------- */ - -int ClusterPool::dump(ostringstream& oss) -{ - map::iterator it; - - - oss << ""; - - for(it=cluster_names.begin();it!=cluster_names.end();it++) - { - dump_cluster(oss, it->first, it->second); - } - - oss << ""; - - return 0; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int ClusterPool::insert(int oid, string name, SqlDB *db) -{ - ostringstream oss; - - int rc; - - char * sql_name; - - sql_name = db->escape_str(name.c_str()); - - if ( sql_name == 0 ) - { - return -1; - } - - oss << "INSERT INTO "<< table <<" ("<< db_names <<") VALUES (" - << oid << "," - << "'" << sql_name << "')"; - - rc = db->exec(oss); - - db->free_str(sql_name); - - if( rc == 0 ) - { - cluster_names.insert( make_pair(oid, name) ); - } - - return rc; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void ClusterPool::dump_cluster(ostringstream& oss, int id, string name) -{ - oss << - "" << - "" << id << "" << - "" << name << "" << - ""; -} diff --git a/src/host/Host.cc b/src/host/Host.cc index 519b1d76fe..f8095c24c5 100644 --- a/src/host/Host.cc +++ b/src/host/Host.cc @@ -29,18 +29,18 @@ Host::Host( int id, - string _hostname, - string _im_mad_name, - string _vmm_mad_name, - string _tm_mad_name): - PoolObjectSQL(id), - hostname(_hostname), + const string& _hostname, + const string& _im_mad_name, + const string& _vmm_mad_name, + const string& _tm_mad_name, + const string& _cluster): + PoolObjectSQL(id,_hostname,-1,table), state(INIT), im_mad_name(_im_mad_name), vmm_mad_name(_vmm_mad_name), tm_mad_name(_tm_mad_name), last_monitored(0), - cluster(ClusterPool::DEFAULT_CLUSTER_NAME), + cluster(_cluster), host_template() {} @@ -52,92 +52,11 @@ Host::~Host(){} const char * Host::table = "host_pool"; -const char * Host::db_names = "oid,host_name,state,im_mad,vm_mad," - "tm_mad,last_mon_time, cluster, template"; +const char * Host::db_names = "oid, name, body, state, last_mon_time, cluster"; const char * Host::db_bootstrap = "CREATE TABLE IF NOT EXISTS host_pool (" - "oid INTEGER PRIMARY KEY,host_name VARCHAR(256), state INTEGER," - "im_mad VARCHAR(128),vm_mad VARCHAR(128),tm_mad VARCHAR(128)," - "last_mon_time INTEGER, cluster VARCHAR(128), template TEXT, " - "UNIQUE(host_name))"; - -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ - -int Host::select_cb(void * nil, int num, char **values, char ** names) -{ - if ((!values[OID]) || - (!values[HOST_NAME]) || - (!values[STATE]) || - (!values[IM_MAD]) || - (!values[VM_MAD]) || - (!values[TM_MAD]) || - (!values[LAST_MON_TIME]) || - (!values[CLUSTER]) || - (!values[TEMPLATE]) || - (num != LIMIT )) - { - return -1; - } - - oid = atoi(values[OID]); - hostname = values[HOST_NAME]; - state = static_cast(atoi(values[STATE])); - - im_mad_name = values[IM_MAD]; - vmm_mad_name = values[VM_MAD]; - tm_mad_name = values[TM_MAD]; - - last_monitored = static_cast(atoi(values[LAST_MON_TIME])); - - cluster = values[CLUSTER]; - - host_template.from_xml(values[TEMPLATE]); - - host_share.hsid = oid; - - return 0; -} - -/* ------------------------------------------------------------------------ */ - -int Host::select(SqlDB *db) -{ - ostringstream oss; - int rc; - int boid; - - set_callback(static_cast(&Host::select_cb)); - - oss << "SELECT " << db_names << " FROM " << table << " WHERE oid = " << oid; - - boid = oid; - oid = -1; - - rc = db->exec(oss, this); - - unset_callback(); - - if ((rc != 0) || (oid != boid )) - { - return -1; - } - - if ( rc != 0 ) - { - return -1; - } - - // Select the host shares from the DB - rc = host_share.select(db); - - if ( rc != 0 ) - { - return rc; - } - - return 0; -} + "oid INTEGER PRIMARY KEY, name VARCHAR(256), body TEXT, state INTEGER, " + "last_mon_time INTEGER, cluster VARCHAR(128), UNIQUE(name))"; /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ @@ -145,34 +64,15 @@ int Host::select(SqlDB *db) int Host::insert(SqlDB *db, string& error_str) { int rc; - map::iterator iter; - // Set up the share ID, to insert it - if ( host_share.hsid == -1 ) - { - host_share.hsid = oid; - } - - // Update the HostShare - rc = host_share.insert(db, error_str); - - if ( rc != 0 ) - { - return rc; - } - - //Insert the Host rc = insert_replace(db, false); if ( rc != 0 ) { error_str = "Error inserting Host in DB."; - host_share.drop(db); - - return rc; } - return 0; + return rc; } /* ------------------------------------------------------------------------ */ @@ -182,24 +82,9 @@ int Host::update(SqlDB *db) { int rc; - // Update the HostShare - rc = host_share.update(db); - - if ( rc != 0 ) - { - return rc; - } - rc = insert_replace(db, true); - if ( rc != 0 ) - { - return rc; - } - - return 0; - - + return rc; } /* ------------------------------------------------------------------------ */ @@ -210,45 +95,21 @@ int Host::insert_replace(SqlDB *db, bool replace) ostringstream oss; int rc; - string xml_template; + string xml_body; char * sql_hostname; - char * sql_im_mad_name; - char * sql_tm_mad_name; - char * sql_vmm_mad_name; char * sql_cluster; - char * sql_template; + char * sql_xml; // Update the Host - sql_hostname = db->escape_str(hostname.c_str()); + sql_hostname = db->escape_str(name.c_str()); if ( sql_hostname == 0 ) { goto error_hostname; } - sql_im_mad_name = db->escape_str(im_mad_name.c_str()); - - if ( sql_im_mad_name == 0 ) - { - goto error_im; - } - - sql_tm_mad_name = db->escape_str(tm_mad_name.c_str()); - - if ( sql_tm_mad_name == 0 ) - { - goto error_tm; - } - - sql_vmm_mad_name = db->escape_str(vmm_mad_name.c_str()); - - if ( sql_vmm_mad_name == 0 ) - { - goto error_vmm; - } - sql_cluster = db->escape_str(cluster.c_str()); if ( sql_cluster == 0 ) @@ -256,12 +117,11 @@ int Host::insert_replace(SqlDB *db, bool replace) goto error_cluster; } - host_template.to_xml(xml_template); - sql_template = db->escape_str(xml_template.c_str()); + sql_xml = db->escape_str(to_xml(xml_body).c_str()); - if ( sql_template == 0 ) + if ( sql_xml == 0 ) { - goto error_template; + goto error_body; } if(replace) @@ -275,37 +135,25 @@ int Host::insert_replace(SqlDB *db, bool replace) // Construct the SQL statement to Insert or Replace - oss <<" INTO "<< table <<" ("<< db_names <<") VALUES (" + oss <<" INTO "<
exec(oss); db->free_str(sql_hostname); - db->free_str(sql_im_mad_name); - db->free_str(sql_tm_mad_name); - db->free_str(sql_vmm_mad_name); db->free_str(sql_cluster); - db->free_str(sql_template); + db->free_str(sql_xml); return rc; -error_template: +error_body: db->free_str(sql_cluster); error_cluster: - db->free_str(sql_vmm_mad_name); -error_vmm: - db->free_str(sql_tm_mad_name); -error_tm: - db->free_str(sql_im_mad_name); -error_im: db->free_str(sql_hostname); error_hostname: return -1; @@ -314,66 +162,6 @@ error_hostname: /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ -int Host::dump(ostringstream& oss, int num, char **values, char **names) -{ - if ((!values[OID]) || - (!values[HOST_NAME]) || - (!values[STATE]) || - (!values[IM_MAD]) || - (!values[VM_MAD]) || - (!values[TM_MAD]) || - (!values[LAST_MON_TIME]) || - (!values[CLUSTER]) || - (!values[TEMPLATE]) || - (num != LIMIT + HostShare::LIMIT )) - { - return -1; - } - - oss << - "" << - "" << values[OID] <<"" << - "" << values[HOST_NAME] <<"" << - "" << values[STATE] <<"" << - "" << values[IM_MAD] <<"" << - "" << values[VM_MAD] <<"" << - "" << values[TM_MAD] <<"" << - ""<< values[LAST_MON_TIME]<<""<< - "" << values[CLUSTER] <<"" << - values[TEMPLATE]; - - HostShare::dump(oss,num - LIMIT, values + LIMIT, names + LIMIT); - - oss << ""; - - return 0; -} - -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ - -int Host::drop(SqlDB * db) -{ - ostringstream oss; - int rc; - - host_share.drop(db); - - oss << "DELETE FROM " << table << " WHERE oid=" << oid; - - rc = db->exec(oss); - - if ( rc == 0 ) - { - set_valid(false); - } - - return rc; -} - -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ - int Host::update_info(string &parse_str) { char * error_msg; @@ -426,7 +214,7 @@ string& Host::to_xml(string& xml) const oss << "" "" << oid << "" << - "" << hostname << "" << + "" << name << "" << "" << state << "" << "" << im_mad_name << "" << "" << vmm_mad_name << "" << @@ -445,26 +233,55 @@ string& Host::to_xml(string& xml) const /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ -string& Host::to_str(string& str) const +int Host::from_xml(const string& xml) { - string template_str; - string share_str; + vector content; + + int int_state; + int rc = 0; - ostringstream os; + // Initialize the internal XML object + update_from_str(xml); - os << - "ID = " << oid << endl << - "NAME = " << hostname << endl << - "STATE = " << state << endl << - "IM MAD = " << im_mad_name << endl << - "VMM MAD = " << vmm_mad_name << endl << - "TM MAD = " << tm_mad_name << endl << - "LAST_MON = " << last_monitored << endl << - "CLUSTER = " << cluster << endl << - "ATTRIBUTES" << endl << host_template.to_str(template_str) << endl << - "HOST SHARES" << endl << host_share.to_str(share_str) <( int_state ); + + // Get associated classes + ObjectXML::get_nodes("/HOST/HOST_SHARE", content); + + if( content.size() < 1 ) + { + return -1; + } + + rc += host_share.from_xml_node( content[0] ); + + content.clear(); + + ObjectXML::get_nodes("/HOST/TEMPLATE", content); + + if( content.size() < 1 ) + { + return -1; + } + + rc += host_template.from_xml_node( content[0] ); + + if (rc != 0) + { + return -1; + } + + return 0; } diff --git a/src/host/HostHook.cc b/src/host/HostHook.cc index 8d72f0ed13..060bc6b56d 100644 --- a/src/host/HostHook.cc +++ b/src/host/HostHook.cc @@ -55,7 +55,7 @@ void HostAllocateHook::do_hook(void *arg) { hmd->execute(host->get_oid(), name, - host->get_hostname(), + host->get_name(), cmd, parsed_args); } @@ -179,7 +179,7 @@ void HostStateHook::do_hook(void *arg) { hmd->execute(host->get_oid(), name, - host->get_hostname(), + host->get_name(), cmd, parsed_args); } diff --git a/src/host/HostPool.cc b/src/host/HostPool.cc index e93275785b..785facd3e3 100644 --- a/src/host/HostPool.cc +++ b/src/host/HostPool.cc @@ -22,54 +22,17 @@ #include "HostPool.h" #include "HostHook.h" -#include "ClusterPool.h" #include "NebulaLog.h" +#include "ClusterPool.h" /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int HostPool::init_cb(void *nil, int num, char **values, char **names) -{ - if ( num != 2 || values == 0 || values[0] == 0 ) - { - return -1; - } - - cluster_pool.cluster_names.insert( make_pair(atoi(values[0]), values[1]) ); - - return 0; -} - -/* -------------------------------------------------------------------------- */ - HostPool::HostPool(SqlDB* db, vector hook_mads, const string& hook_location) : PoolSQL(db,Host::table) { - // ------------------ Initialize Cluster Array ---------------------- - - ostringstream sql; - - set_callback(static_cast(&HostPool::init_cb)); - - sql << "SELECT " << ClusterPool::db_names << " FROM " - << ClusterPool::table; - - db->exec(sql, this); - - unset_callback(); - - if (cluster_pool.cluster_names.empty()) - { - int rc = cluster_pool.insert(0, ClusterPool::DEFAULT_CLUSTER_NAME, db); - - if(rc != 0) - { - throw runtime_error("Could not create default cluster HostPool"); - } - } - // ------------------ Initialize Hooks fot the pool ---------------------- const VectorAttribute * vattr; @@ -180,6 +143,34 @@ int HostPool::allocate ( string& error_str) { Host * host; + ostringstream oss; + + if ( hostname.empty() ) + { + goto error_name; + } + + if ( im_mad_name.empty() ) + { + goto error_im; + } + + if ( vmm_mad_name.empty() ) + { + goto error_vmm; + } + + if ( tm_mad_name.empty() ) + { + goto error_tm; + } + + host = get(hostname,false); + + if ( host !=0) + { + goto error_duplicated; + } // Build a new Host object @@ -187,13 +178,40 @@ int HostPool::allocate ( hostname, im_mad_name, vmm_mad_name, - tm_mad_name); + tm_mad_name, + ClusterPool::DEFAULT_CLUSTER_NAME); // Insert the Object in the pool *oid = PoolSQL::allocate(host, error_str); return *oid; + + +error_name: + oss << "NAME cannot be empty."; + goto error_common; + +error_im: + oss << "IM_MAD_NAME cannot be empty."; + goto error_common; + +error_vmm: + oss << "VMM_MAD_NAME cannot be empty."; + goto error_common; + +error_tm: + oss << "TM_MAD_NAME cannot be empty."; + goto error_common; + +error_duplicated: + oss << "NAME is already taken by HOST " << host->get_oid() << "."; + +error_common: + *oid = -1; + error_str = oss.str(); + + return *oid; } /* -------------------------------------------------------------------------- */ @@ -202,18 +220,24 @@ int HostPool::allocate ( int HostPool::discover_cb(void * _map, int num, char **values, char **names) { map * discovered_hosts; - string im_mad(values[1]); + string im_mad; int hid; + int rc; discovered_hosts = static_cast *>(_map); - if ( (num<=0) || (values[0] == 0) ) + if ( (num<2) || (values[0] == 0) || (values[1] == 0) ) { return -1; } - hid = atoi(values[0]); - im_mad = values[1]; + hid = atoi(values[0]); + rc = ObjectXML::xpath_value(im_mad,values[1],"/HOST/IM_MAD"); + + if( rc != 0) + { + return -1; + } discovered_hosts->insert(make_pair(hid,im_mad)); @@ -230,7 +254,7 @@ int HostPool::discover(map * discovered_hosts, int host_limit) set_callback(static_cast(&HostPool::discover_cb), static_cast(discovered_hosts)); - sql << "SELECT oid, im_mad FROM " + sql << "SELECT oid, body FROM " << Host::table << " WHERE state != " << Host::DISABLED << " ORDER BY last_mon_time ASC LIMIT " << host_limit; @@ -240,97 +264,3 @@ int HostPool::discover(map * discovered_hosts, int host_limit) return rc; } - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int HostPool::dump_cb(void * _oss, int num, char **values, char **names) -{ - ostringstream * oss; - - oss = static_cast(_oss); - - return Host::dump(*oss, num, values, names); -} - -/* -------------------------------------------------------------------------- */ - -int HostPool::dump(ostringstream& oss, const string& where) -{ - int rc; - ostringstream cmd; - - oss << ""; - - set_callback(static_cast(&HostPool::dump_cb), - static_cast(&oss)); - - cmd << "SELECT " << Host::db_names << " , " << HostShare::db_names - << " FROM " << Host::table << " JOIN " << HostShare::table - << " ON " << Host::table << ".oid = " << HostShare::table << ".hid"; - - if ( !where.empty() ) - { - cmd << " WHERE " << where; - } - - rc = db->exec(cmd, this); - - oss << ""; - - unset_callback(); - - return rc; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int HostPool::drop_cluster(int clid) -{ - int rc; - map::iterator it; - string cluster_name; - - it = cluster_pool.cluster_names.find(clid); - - if ( it == cluster_pool.cluster_names.end() ) - { - return -1; - } - - cluster_name = it->second; - - // try to drop the cluster from the pool and DB - rc = cluster_pool.drop(clid, db); - - // Move the hosts assigned to the deleted cluster to the default one - if( rc == 0 ) - { - Host* host; - vector hids; - vector::iterator hid_it; - - string where = "cluster = '" + cluster_name + "'"; - - search(hids, Host::table, where); - - for ( hid_it=hids.begin() ; hid_it < hids.end(); hid_it++ ) - { - host = get(*hid_it, true); - - if ( host == 0 ) - { - continue; - } - - set_default_cluster(host); - - update(host); - - host->unlock(); - } - } - - return rc; -} diff --git a/src/host/HostShare.cc b/src/host/HostShare.cc index 0e3583fb0b..51b324d5a4 100644 --- a/src/host/HostShare.cc +++ b/src/host/HostShare.cc @@ -28,12 +28,10 @@ /* ************************************************************************ */ HostShare::HostShare( - int _hsid, int _max_disk, int _max_mem, int _max_cpu): - ObjectSQL(), - hsid(_hsid), + ObjectXML(), disk_usage(0), mem_usage(0), cpu_usage(0), @@ -46,228 +44,7 @@ HostShare::HostShare( used_disk(0), used_mem(0), used_cpu(0), - running_vms(0) -{ -} - -/* ************************************************************************ */ -/* HostShare :: Database Access Functions */ -/* ************************************************************************ */ - -const char * HostShare::table = "host_shares"; - -const char * HostShare::db_names = "hid," - "disk_usage, mem_usage, cpu_usage," - "max_disk, max_mem, max_cpu," - "free_disk, free_mem, free_cpu," - "used_disk, used_mem, used_cpu," - "running_vms"; - -const char * HostShare::db_bootstrap = "CREATE TABLE IF NOT EXISTS host_shares(" - "hid INTEGER PRIMARY KEY," - "disk_usage INTEGER, mem_usage INTEGER, cpu_usage INTEGER," - "max_disk INTEGER, max_mem INTEGER, max_cpu INTEGER," - "free_disk INTEGER, free_mem INTEGER, free_cpu INTEGER," - "used_disk INTEGER, used_mem INTEGER, used_cpu INTEGER," - "running_vms INTEGER)"; - -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ - -int HostShare::select_cb(void * nil, int num, char **values, char **names) -{ - if ((!values[HID]) || - (!values[DISK_USAGE]) || - (!values[MEM_USAGE]) || - (!values[CPU_USAGE]) || - (!values[MAX_DISK]) || - (!values[MAX_MEMORY]) || - (!values[MAX_CPU]) || - (!values[FREE_DISK]) || - (!values[FREE_MEMORY]) || - (!values[FREE_CPU]) || - (!values[USED_DISK]) || - (!values[USED_MEMORY]) || - (!values[USED_CPU]) || - (!values[RUNNING_VMS]) || - (num != LIMIT )) - { - return -1; - } - - hsid = atoi(values[HID]); - - disk_usage = atoi(values[DISK_USAGE]); - mem_usage = atoi(values[MEM_USAGE]); - cpu_usage = atoi(values[CPU_USAGE]); - - max_disk = atoi(values[MAX_DISK]); - max_mem = atoi(values[MAX_MEMORY]); - max_cpu = atoi(values[MAX_CPU]); - - free_disk = atoi(values[FREE_DISK]); - free_mem = atoi(values[FREE_MEMORY]); - free_cpu = atoi(values[FREE_CPU]); - - used_disk = atoi(values[USED_DISK]); - used_mem = atoi(values[USED_MEMORY]); - used_cpu = atoi(values[USED_CPU]); - - running_vms = atoi(values[RUNNING_VMS]); - - return 0; -} - -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ - -int HostShare::dump(ostringstream& oss, - int num, - char ** values, - char ** names) -{ - if ((!values[HID]) || - (!values[DISK_USAGE]) || - (!values[MEM_USAGE]) || - (!values[CPU_USAGE]) || - (!values[MAX_DISK]) || - (!values[MAX_MEMORY]) || - (!values[MAX_CPU]) || - (!values[FREE_DISK]) || - (!values[FREE_MEMORY]) || - (!values[FREE_CPU]) || - (!values[USED_DISK]) || - (!values[USED_MEMORY]) || - (!values[USED_CPU]) || - (!values[RUNNING_VMS]) || - (num != LIMIT)) - { - return -1; - } - - oss << - "" << - "" << values[HID] << "" << - ""<< values[DISK_USAGE] << ""<< - "" << values[MEM_USAGE] << "" << - "" << values[CPU_USAGE] << "" << - "" << values[MAX_DISK] << "" << - "" << values[MAX_MEMORY] << "" << - "" << values[MAX_CPU] << "" << - "" << values[FREE_DISK] << "" << - "" << values[FREE_MEMORY] << "" << - "" << values[FREE_CPU] << "" << - "" << values[USED_DISK] << "" << - "" << values[USED_MEMORY] << "" << - "" << values[USED_CPU] << "" << - ""<"<< - ""; - - return 0; -} - -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ - -int HostShare::select(SqlDB * db) -{ - ostringstream oss; - int rc; - int bhsid; - - set_callback(static_cast(&HostShare::select_cb)); - - oss << "SELECT "<< db_names << " FROM " << table << " WHERE hid = " << hsid; - - bhsid = hsid; - hsid = -1; - - rc = db->exec(oss,this); - - unset_callback(); - - if (hsid != bhsid ) - { - rc = -1; - } - - return rc; -} - -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ - -int HostShare::insert(SqlDB * db, string& error_str) -{ - int rc; - - rc = insert_replace(db, false); - - if ( rc == -1 ) - { - error_str = "Error inserting Host Share in DB."; - } - - return rc; -} - -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ - -int HostShare::update(SqlDB * db) -{ - int rc; - - rc = insert_replace(db, true); - - return rc; -} - -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ - -int HostShare::insert_replace(SqlDB *db, bool replace) -{ - ostringstream oss; - int rc; - - if(replace) - { - oss << "REPLACE"; - } - else - { - oss << "INSERT"; - } - - oss << " INTO " << table << " ("<< db_names <<") VALUES (" - << hsid << "," - << disk_usage <<","<< mem_usage <<","<< cpu_usage<< "," - << max_disk <<","<< max_mem <<","<< max_cpu << "," - << free_disk <<","<< free_mem <<","<< free_cpu << "," - << used_disk <<","<< used_mem <<","<< used_cpu << "," - << running_vms<< ")"; - - rc = db->exec(oss); - - return rc; -} - -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ - -int HostShare::drop(SqlDB * db) -{ - ostringstream oss; - - oss << "DELETE FROM " << table << " WHERE hid=" << hsid; - - return db->exec(oss); -} - -/* ************************************************************************ */ -/* HostShare :: Misc */ -/* ************************************************************************ */ + running_vms(0){}; ostream& operator<<(ostream& os, HostShare& hs) { @@ -287,7 +64,6 @@ string& HostShare::to_xml(string& xml) const ostringstream oss; oss << "" - << "" << hsid << "" << "" << disk_usage << "" << "" << mem_usage << "" << "" << cpu_usage << "" @@ -311,30 +87,35 @@ string& HostShare::to_xml(string& xml) const /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ -string& HostShare::to_str(string& str) const +int HostShare::from_xml_node(const xmlNodePtr node) { - string template_xml; - ostringstream oss; + int rc = 0; - oss<< "\tHID = " << hsid - << "\tCPU_USAGE = " << cpu_usage << endl - << "\tMEMORY_USAGE = " << mem_usage << endl - << "\tDISK_USAGE = " << disk_usage<< endl - << "\tMAX_CPU = " << max_cpu << endl - << "\tMAX_MEMORY = " << max_mem << endl - << "\tMAX_DISK = " << max_disk<< endl - << "\tFREE_CPU = " << free_cpu << endl - << "\tFREE_MEMORY = " << free_mem << endl - << "\tFREE_DISK = " << free_disk<< endl - << "\tUSED_CPU = " << used_cpu << endl - << "\tUSED_MEMORY = " << used_mem << endl - << "\tUSED_DISK = " << used_disk<< endl - << "\tRUNNING_VMS = " << running_vms<< endl; + // Initialize the internal XML object + ObjectXML::update_from_node(node); - str = oss.str(); + rc += xpath(disk_usage, "/HOST_SHARE/DISK_USAGE", -1); + rc += xpath(mem_usage, "/HOST_SHARE/MEM_USAGE", -1); + rc += xpath(cpu_usage, "/HOST_SHARE/CPU_USAGE", -1); - return str; + rc += xpath(max_disk, "/HOST_SHARE/MAX_DISK", -1); + rc += xpath(max_mem , "/HOST_SHARE/MAX_MEM", -1); + rc += xpath(max_cpu , "/HOST_SHARE/MAX_CPU", -1); + + rc += xpath(free_disk, "/HOST_SHARE/FREE_DISK", -1); + rc += xpath(free_mem , "/HOST_SHARE/FREE_MEM", -1); + rc += xpath(free_cpu , "/HOST_SHARE/FREE_CPU", -1); + + rc += xpath(used_disk, "/HOST_SHARE/USED_DISK", -1); + rc += xpath(used_mem , "/HOST_SHARE/USED_MEM", -1); + rc += xpath(used_cpu , "/HOST_SHARE/USED_CPU", -1); + + rc += xpath(running_vms,"/HOST_SHARE/RUNNING_VMS",-1); + + if (rc != 0) + { + return -1; + } + + return 0; } - -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ diff --git a/src/host/SConstruct b/src/host/SConstruct index f76294a26b..acba39ff73 100644 --- a/src/host/SConstruct +++ b/src/host/SConstruct @@ -25,7 +25,6 @@ source_files=[ 'Host.cc', 'HostShare.cc', 'HostPool.cc', - 'ClusterPool.cc', 'HostHook.cc' ] diff --git a/src/host/test/HostPoolTest.cc b/src/host/test/HostPoolTest.cc index 32051bb19b..5a658b2307 100644 --- a/src/host/test/HostPoolTest.cc +++ b/src/host/test/HostPoolTest.cc @@ -33,7 +33,7 @@ const string xmls[] = { "0Host one0" "im_madvmm_madtm_mad" - "0default0" + "0default" "000" "000" "000" @@ -42,7 +42,7 @@ const string xmls[] = "1Second host0" "im_madvmm_madtm_mad" - "0default1" + "0default" "000" "000" "000" @@ -54,72 +54,72 @@ const string xmls[] = const string xml_dump = "0a0im_madvmm_madtm_mad0" - "default00default0000000000000" + "SED_CPU>00" "1a name0im_madvmm_madtm_mad0default100default00000" "00000000202a_name0im_madvmm_madtm_mad0default200tm_mad0default00000000000003another " + "NING_VMS>03another " "name0im_madvmm_mad" - "tm_mad0default300tm_mad0default00000000000004host04host0im_madvmm_madtm_mad" - "0default4" + "0default" "000" "0000" "000000"; + "VMS>"; const string xml_dump_like_a = "0a0im_madvmm_madtm_mad0" - "default00default0000000000000" + "SED_CPU>00" "1a name0im_madvmm_madtm_mad0default100default00000" "00000000202a_name0im_madvmm_madtm_mad0default200tm_mad0default00000000000003another " + "NING_VMS>03another " "name0im_madvmm_mad" - "tm_mad0default300tm_mad0default0000000000000"; + "MS>0"; const string host0_updated = - "0Host one0im_madvmm_madtm_mad0default00000000000000"; + "0Host one0im_madvmm_madtm_mad0default0000000000000"; const string cluster_default = "0default"; @@ -128,7 +128,7 @@ const string cluster_xml_dump = "0default1cluster_a3cluster_c4cluster_d"; const string host_0_cluster = - "0Host one0im_madvmm_madtm_mad0cluster_a00000000000000"; + "0Host one0im_madvmm_madtm_mad0cluster_a0000000000000"; /* ************************************************************************* */ /* ************************************************************************* */ @@ -143,16 +143,10 @@ class HostPoolTest : public PoolTest CPPUNIT_TEST (dump_where); CPPUNIT_TEST (discover); CPPUNIT_TEST (duplicates); - - CPPUNIT_TEST (cluster_init); - CPPUNIT_TEST (cluster_allocate); - CPPUNIT_TEST (cluster_drop); - CPPUNIT_TEST (cluster_id); - CPPUNIT_TEST (cluster_dump); - CPPUNIT_TEST (set_cluster); - CPPUNIT_TEST (remove_cluster); CPPUNIT_TEST (update_info); +// CPPUNIT_TEST (scale_test); + CPPUNIT_TEST_SUITE_END (); protected: @@ -184,12 +178,21 @@ protected: CPPUNIT_ASSERT( obj != 0 ); string xml_str = ""; - string name = host->get_hostname(); + string name = host->get_name(); CPPUNIT_ASSERT( name == names[index] ); // Get the xml host->to_xml(xml_str); + +// A little help for debugging +/* + if( xml_str != xmls[index] ) + { + cout << endl << xml_str << endl << "========" + << endl << xmls[index]; + } +//*/ CPPUNIT_ASSERT( xml_str == xmls[index]); }; @@ -285,6 +288,15 @@ public: string result = oss.str(); +// A little help for debugging +/* + if( result != xml_dump ) + { + cout << endl << result << endl << "========" + << endl << xml_dump; + } +//*/ + CPPUNIT_ASSERT( result == xml_dump ); } @@ -304,12 +316,21 @@ public: ostringstream oss; - rc = ((HostPool*)pool)->dump(oss, "host_name LIKE 'a%'"); + rc = ((HostPool*)pool)->dump(oss, "name LIKE 'a%' ORDER BY oid"); CPPUNIT_ASSERT(rc == 0); string result = oss.str(); +// A little help for debugging +/* + if( result != xml_dump_like_a ) + { + cout << endl << result << endl << "========" + << endl << xml_dump_like_a; + } +//*/ + CPPUNIT_ASSERT( result == xml_dump_like_a ); } @@ -360,201 +381,87 @@ public: } } - /* ********************************************************************* */ /* ********************************************************************* */ - void cluster_init() + void scale_test() { + time_t the_time, the_time2; + int oid,i,j,rc; + + ostringstream oss,ossdump; + string err; + Host * host; + + string monitor = "ARCH=x86_64 MODELNAME=\"Intel(R) Core(TM)2 Duo CPU P9300 @ 2.26GHz\" HYPERVISOR=kvm TOTALCPU=200 CPUSPEED=800 TOTALMEMORY=4005416 USEDMEMORY=2351928 FREEMEMORY=2826904 FREECPU=188.4 USEDCPU=11.599999999999994 NETRX=0 NETTX=0 HOSTNAME=pc-ruben"; + + cout << endl << "Allocate Test" << endl; + + tearDown(); + + for (i=1000; i<30000 ; i = i + 5000) + { + setUp(); + + HostPool * hp = static_cast(pool); + + the_time = time(0); + + for (j=0,oss.str(""); jallocate(&oid, oss.str().c_str(),im_mad,vmm_mad,tm_mad,err); + } + + the_time2 = time(0) - the_time; + + hp->clean(); + + the_time = time(0); + + rc = hp->dump(ossdump, ""); + + cout <<"\t"<(pool); - CPPUNIT_ASSERT( hp->info_cluster(0) == cluster_default ); - } + for (i=10000,oss.str(""); i<30000 ; i++,oss.str("")) + { + oss << "host" << i; + hp->allocate(&oid,oss.str().c_str(),im_mad,vmm_mad,tm_mad,err); - /* ********************************************************************* */ + host = hp->get(oid, false); - void cluster_allocate() - { - HostPool * hp = static_cast(pool); - int clid, rc; - string err; + host->update_info(monitor); + hp->update(host); + } + + //Load test + for (i=0; i<25000; i=i+5000) + { + hp->clean(); - rc = hp->allocate_cluster(&clid, "new_cluster", err); - CPPUNIT_ASSERT( rc == clid ); - CPPUNIT_ASSERT( clid == 1 ); + the_time = time(0); - CPPUNIT_ASSERT( hp->info_cluster(clid) == - "1new_cluster"); + for (j=0; jget(j,true); + host->unlock(); + } - // Try to allocate using the same name - rc = hp->allocate_cluster(&clid, "new_cluster", err); - CPPUNIT_ASSERT( rc == clid ); - CPPUNIT_ASSERT( clid == -1 ); - } - - /* ********************************************************************* */ - - void cluster_drop() - { - HostPool * hp = static_cast(pool); - int clid, rc; - string err; - - // Drop a non-existing cluster - rc = hp->drop_cluster(20); - CPPUNIT_ASSERT( rc == -1 ); - - // Allocate a cluster and drop it - rc = hp->allocate_cluster(&clid, "new_cluster", err); - CPPUNIT_ASSERT( clid == 1); - - rc = hp->drop_cluster(clid); - CPPUNIT_ASSERT( rc == 0 ); - - // Try to drop the default cluster, should fail - rc = hp->drop_cluster(0); - CPPUNIT_ASSERT( rc == -1 ); - } - - /* ********************************************************************* */ - - void cluster_id() - { - HostPool * hp = static_cast(pool); - int clid, rc; - ostringstream oss; - string err; - - // Allocate some clusters - rc = hp->allocate_cluster(&clid, "cluster_a", err); - CPPUNIT_ASSERT( rc == 1 ); - - rc = hp->allocate_cluster(&clid, "cluster_b", err); - CPPUNIT_ASSERT( rc == 2 ); - - rc = hp->allocate_cluster(&clid, "cluster_c", err); - CPPUNIT_ASSERT( rc == 3 ); - - rc = hp->allocate_cluster(&clid, "cluster_d", err); - CPPUNIT_ASSERT( rc == 4 ); - - // Drop id 2 - rc = hp->drop_cluster(2); - CPPUNIT_ASSERT( rc == 0 ); - - // Next one should use id 5, because the biggest id is 4 - rc = hp->allocate_cluster(&clid, "cluster_e", err); - CPPUNIT_ASSERT( rc == 5 ); - - // Drop id 5 - rc = hp->drop_cluster(5); - CPPUNIT_ASSERT( rc == 0 ); - - // Next one should use id 5, because the biggest id is 4 again - rc = hp->allocate_cluster(&clid, "cluster_f", err); - CPPUNIT_ASSERT( rc == 5 ); - - } - - /* ********************************************************************* */ - - void cluster_dump() - { - HostPool * hp = static_cast(pool); - int clid, rc; - ostringstream oss; - string err; - - // Allocate some clusters - rc = hp->allocate_cluster(&clid, "cluster_a", err); - CPPUNIT_ASSERT( rc == 1 ); - - rc = hp->allocate_cluster(&clid, "cluster_b", err); - CPPUNIT_ASSERT( rc == 2 ); - - rc = hp->allocate_cluster(&clid, "cluster_c", err); - CPPUNIT_ASSERT( rc == 3 ); - - rc = hp->allocate_cluster(&clid, "cluster_d", err); - CPPUNIT_ASSERT( rc == 4 ); - - - // Drop one of them - rc = hp->drop_cluster(2); - CPPUNIT_ASSERT( rc == 0 ); - - // dump the pool - rc = hp->dump_cluster(oss); - CPPUNIT_ASSERT( oss.str() == cluster_xml_dump ); - } - - /* ********************************************************************* */ - - void set_cluster() - { - HostPool * hp = static_cast(pool); - Host* host; - int clid, rc, oid; - string xml_str, err; - - // Allocate a host - oid = allocate(0); - CPPUNIT_ASSERT(oid >= 0); - - host = hp->get(0, false); - CPPUNIT_ASSERT(host != 0); - - rc = hp->allocate_cluster(&clid, "cluster_a", err); - CPPUNIT_ASSERT( rc == 1 ); - - rc = hp->set_cluster(host, clid); - CPPUNIT_ASSERT( rc == 0 ); - - host->to_xml(xml_str); - CPPUNIT_ASSERT( xml_str == host_0_cluster); - - - // Try to set a non-existing cluster - rc = hp->set_cluster(host, 20); - CPPUNIT_ASSERT( rc == -1 ); - - CPPUNIT_ASSERT( xml_str == host_0_cluster); - - } - - /* ********************************************************************* */ - - void remove_cluster() - { - HostPool * hp = static_cast(pool); - Host* host; - int clid, rc, oid; - string xml_str, err; - - // Allocate a host - oid = allocate(0); - CPPUNIT_ASSERT(oid >= 0); - - host = hp->get(0, false); - CPPUNIT_ASSERT(host != 0); - - rc = hp->allocate_cluster(&clid, "cluster_a", err); - CPPUNIT_ASSERT( rc == 1 ); - - // Set host 0 to cluster 1 - rc = hp->set_cluster(host, clid); - CPPUNIT_ASSERT( rc == 0 ); - - // Check - host->to_xml(xml_str); - CPPUNIT_ASSERT( xml_str == host_0_cluster); - - // Remove the cluster - rc = hp->set_default_cluster(host); - CPPUNIT_ASSERT( rc == 0 ); - - // The host should have been moved to the default cluster - host->to_xml(xml_str); - check(0, host); + cout << "\t" << i << "\t" << time(0) - the_time << endl; + } } /* ********************************************************************* */ diff --git a/src/host/test/SConstruct b/src/host/test/SConstruct index 5b660b8371..1c44bf24bb 100644 --- a/src/host/test/SConstruct +++ b/src/host/test/SConstruct @@ -21,6 +21,8 @@ Import('env') env.Prepend(LIBS=[ 'nebula_core_test', 'nebula_host', + 'nebula_cluster', + 'nebula_xml', 'nebula_vmm', 'nebula_im', 'nebula_rm', diff --git a/src/im/InformationManager.cc b/src/im/InformationManager.cc index 235142d06f..fc662ed910 100644 --- a/src/im/InformationManager.cc +++ b/src/im/InformationManager.cc @@ -201,7 +201,7 @@ void InformationManager::timer_action() (thetime - host->get_last_monitored() >= monitor_period)) { oss.str(""); - oss << "Monitoring host " << host->get_hostname() + oss << "Monitoring host " << host->get_name() << " (" << it->first << ")"; NebulaLog::log("InM",Log::INFO,oss); @@ -225,7 +225,7 @@ void InformationManager::timer_action() update_remotes = true; } - imd->monitor(it->first,host->get_hostname(),update_remotes); + imd->monitor(it->first,host->get_name(),update_remotes); host->set_state(Host::MONITORING); } diff --git a/src/image/Image.cc b/src/image/Image.cc index c333c56df4..a261558507 100644 --- a/src/image/Image.cc +++ b/src/image/Image.cc @@ -28,14 +28,17 @@ #include "AuthManager.h" #include "UserPool.h" +#define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper) + /* ************************************************************************ */ -/* Image :: Constructor/Destructor */ +/* Image :: Constructor/Destructor */ /* ************************************************************************ */ -Image::Image(int _uid, ImageTemplate * _image_template): - PoolObjectSQL(-1), - uid(_uid), - name(""), +Image::Image(int _uid, + const string& _user_name, + ImageTemplate * _image_template): + PoolObjectSQL(-1,"",_uid,table), + user_name(_user_name), type(OS), regtime(time(0)), source(""), @@ -61,92 +64,16 @@ Image::~Image() } /* ************************************************************************ */ -/* Image :: Database Access Functions */ +/* Image :: Database Access Functions */ /* ************************************************************************ */ const char * Image::table = "image_pool"; -const char * Image::db_names = "oid, uid, name, type, public, persistent, regtime, " - "source, state, running_vms, template"; - -const char * Image::extended_db_names = "image_pool.oid, image_pool.uid, " - "image_pool.name, image_pool.type, image_pool.public, " - "image_pool.persistent, image_pool.regtime, image_pool.source, " - "image_pool.state, image_pool.running_vms, image_pool.template"; +const char * Image::db_names = "oid, name, body, uid, public"; const char * Image::db_bootstrap = "CREATE TABLE IF NOT EXISTS image_pool (" - "oid INTEGER PRIMARY KEY, uid INTEGER, name VARCHAR(128), " - "type INTEGER, public INTEGER, persistent INTEGER, regtime INTEGER, source TEXT, state INTEGER, " - "running_vms INTEGER, template TEXT, UNIQUE(name) )"; - -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ - -int Image::select_cb(void * nil, int num, char **values, char ** names) -{ - if ((!values[OID]) || - (!values[UID]) || - (!values[NAME]) || - (!values[TYPE]) || - (!values[PUBLIC]) || - (!values[PERSISTENT]) || - (!values[REGTIME]) || - (!values[SOURCE]) || - (!values[STATE]) || - (!values[RUNNING_VMS]) || - (!values[TEMPLATE]) || - (num != LIMIT )) - { - return -1; - } - - oid = atoi(values[OID]); - uid = atoi(values[UID]); - - name = values[NAME]; - - type = static_cast(atoi(values[TYPE])); - public_img = atoi(values[PUBLIC]); - persistent_img = atoi(values[PERSISTENT]); - regtime = static_cast(atoi(values[REGTIME])); - - source = values[SOURCE]; - - state = static_cast(atoi(values[STATE])); - - running_vms = atoi(values[RUNNING_VMS]); - - image_template->from_xml(values[TEMPLATE]); - - return 0; -} - -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ - -int Image::select(SqlDB *db) -{ - ostringstream oss; - int rc; - int boid; - - set_callback(static_cast(&Image::select_cb)); - - oss << "SELECT " << db_names << " FROM " << table << " WHERE oid = " << oid; - - boid = oid; - oid = -1; - - rc = db->exec(oss, this); - - if ((rc != 0) || (oid != boid )) - { - return -1; - } - - return 0; -} - + "oid INTEGER PRIMARY KEY, name VARCHAR(256), body TEXT, uid INTEGER, " + "public INTEGER, UNIQUE(name,uid) )"; /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ @@ -155,11 +82,11 @@ int Image::insert(SqlDB *db, string& error_str) { int rc; - string source_att; - string type_att; - string public_attr; - string persistent_attr; - string dev_prefix; + string path_attr; + string type_att; + string public_attr; + string persistent_attr; + string dev_prefix; // --------------------------------------------------------------------- // Check default image attributes @@ -169,17 +96,11 @@ int Image::insert(SqlDB *db, string& error_str) get_template_attribute("NAME", name); - if ( name.empty() == true ) - { - goto error_name; - } - // ------------ TYPE -------------------- get_template_attribute("TYPE", type_att); - transform (type_att.begin(), type_att.end(), type_att.begin(), - (int(*)(int))toupper); + TO_UPPER(type_att); if ( type_att.empty() == true ) { @@ -194,20 +115,20 @@ int Image::insert(SqlDB *db, string& error_str) // ------------ PUBLIC -------------------- get_template_attribute("PUBLIC", public_attr); + image_template->erase("PUBLIC"); - transform (public_attr.begin(), public_attr.end(), public_attr.begin(), - (int(*)(int))toupper); + TO_UPPER(public_attr); public_img = (public_attr == "YES"); // ------------ PERSISTENT -------------------- get_template_attribute("PERSISTENT", persistent_attr); + image_template->erase("PERSISTENT"); - transform (persistent_attr.begin(), persistent_attr.end(), persistent_attr.begin(), - (int(*)(int))toupper); + TO_UPPER(persistent_attr); persistent_img = (persistent_attr == "YES"); @@ -230,10 +151,32 @@ int Image::insert(SqlDB *db, string& error_str) image_template->set(dev_att); } - // ------------ SOURCE (path to store the image)-------------------- + // ------------ PATH -------------------- + get_template_attribute("PATH", path_attr); + // ------------ SOURCE (path to store the image) -------------------- get_template_attribute("SOURCE", source); + // The template should contain PATH or SOURCE + if ( source.empty() && path_attr.empty() ) + { + string size_attr; + string fstype_attr; + + get_template_attribute("SIZE", size_attr); + get_template_attribute("FSTYPE", fstype_attr); + + // It could be an empty DATABLOCK image, if it declares SIZE and FSTYPE + if ( type_att != "DATABLOCK" || size_attr.empty() || fstype_attr.empty() ) + { + goto error_no_path; + } + } + else if ( !source.empty() && !path_attr.empty() ) + { + goto error_path_and_source; + } + if (source.empty()) { ostringstream tmp_hashstream; @@ -262,18 +205,30 @@ int Image::insert(SqlDB *db, string& error_str) return rc; -error_name: - error_str = "NAME not present in image template."; - goto error_common; - error_type: - error_str = "Incorrect TYPE in image template."; + error_str = "Incorrect TYPE in template."; goto error_common; error_public_and_persistent: error_str = "Image cannot be public and persistent."; goto error_common; +error_no_path: + if ( type_att == "DATABLOCK" ) + { + error_str = "A DATABLOCK type IMAGE has to declare a PATH, or both " + "SIZE and FSTYPE."; + } + else + { + error_str = "No PATH in template."; + } + goto error_common; + +error_path_and_source: + error_str = "Template malformed, PATH and SOURCE are mutuallly exclusive."; + goto error_common; + error_common: NebulaLog::log("IMG", Log::ERROR, error_str); return -1; @@ -296,11 +251,10 @@ int Image::insert_replace(SqlDB *db, bool replace) int rc; - string xml_template; + string xml_body; char * sql_name; - char * sql_source; - char * sql_template; + char * sql_xml; // Update the Image @@ -311,19 +265,11 @@ int Image::insert_replace(SqlDB *db, bool replace) goto error_name; } - sql_source = db->escape_str(source.c_str()); + sql_xml = db->escape_str(to_xml(xml_body).c_str()); - if ( sql_source == 0 ) + if ( sql_xml == 0 ) { - goto error_source; - } - - image_template->to_xml(xml_template); - sql_template = db->escape_str(xml_template.c_str()); - - if ( sql_template == 0 ) - { - goto error_template; + goto error_body; } if(replace) @@ -339,100 +285,24 @@ int Image::insert_replace(SqlDB *db, bool replace) oss <<" INTO "<< table <<" ("<< db_names <<") VALUES (" << oid << "," - << uid << "," << "'" << sql_name << "'," - << type << "," - << public_img << "," - << persistent_img << "," - << regtime << "," - << "'" << sql_source << "'," - << state << "," - << running_vms << "," - << "'" << sql_template << "')"; + << "'" << sql_xml << "'," + << uid << "," + << public_img << ")"; rc = db->exec(oss); db->free_str(sql_name); - db->free_str(sql_source); - db->free_str(sql_template); + db->free_str(sql_xml); return rc; -error_template: - db->free_str(sql_source); -error_source: +error_body: db->free_str(sql_name); error_name: return -1; } -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ - -int Image::dump(ostringstream& oss, int num, char **values, char **names) -{ - if ((!values[OID]) || - (!values[UID]) || - (!values[NAME]) || - (!values[TYPE]) || - (!values[PUBLIC]) || - (!values[PERSISTENT]) || - (!values[REGTIME]) || - (!values[SOURCE]) || - (!values[STATE]) || - (!values[RUNNING_VMS]) || - (!values[TEMPLATE]) || - (num != LIMIT + 1)) - { - return -1; - } - - oss << - "" << - "" << values[OID] << "" << - "" << values[UID] << "" << - "" << values[LIMIT] << "" << - "" << values[NAME] << "" << - "" << values[TYPE] << "" << - "" << values[PUBLIC] << "" << - "" << values[PERSISTENT] << "" << - "" << values[REGTIME] << "" << - "" << values[SOURCE] << "" << - "" << values[STATE] << "" << - "" << values[RUNNING_VMS] << "" << - values[TEMPLATE] << - ""; - - return 0; -} - -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ - -int Image::drop(SqlDB * db) -{ - ostringstream oss; - int rc; - - // Only delete the VM - if (running_vms != 0) - { - return -1; - } - - oss << "DELETE FROM " << table << " WHERE oid=" << oid; - - rc = db->exec(oss); - - if ( rc == 0 ) - { - set_valid(false); - } - - return rc; -} - - /* ************************************************************************ */ /* Image :: Misc */ /* ************************************************************************ */ @@ -458,6 +328,7 @@ string& Image::to_xml(string& xml) const "" << "" << oid << "" << "" << uid << "" << + "" << user_name << "" << "" << name << "" << "" << type << "" << "" << public_img << "" << @@ -477,30 +348,50 @@ string& Image::to_xml(string& xml) const /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ -string& Image::to_str(string& str) const +int Image::from_xml(const string& xml) { - string template_str; + vector content; + int int_state; + int int_type; - ostringstream os; + int rc = 0; - os << - "ID = " << oid << endl << - "UID = " << uid << endl << - "NAME = " << name << endl << - "TYPE = " << type << endl << - "PUBLIC = " << public_img << endl << - "PERSISTENT = " << persistent_img << endl << - "REGTIME = " << regtime << endl << - "SOURCE = " << source << endl << - "STATE = " << state << endl << - "RUNNING_VMS = " << running_vms << endl << - "TEMPLATE" << endl - << image_template->to_str(template_str) - << endl; + // Initialize the internal XML object + update_from_str(xml); - str = os.str(); + // Get class base attributes + rc += xpath(oid, "/IMAGE/ID", -1); + rc += xpath(uid, "/IMAGE/UID", -1); + rc += xpath(user_name, "/IMAGE/USERNAME", "not_found"); + rc += xpath(name, "/IMAGE/NAME", "not_found"); - return str; + rc += xpath(int_type, "/IMAGE/TYPE", 0); + rc += xpath(public_img, "/IMAGE/PUBLIC", 0); + rc += xpath(persistent_img, "/IMAGE/PERSISTENT", 0); + rc += xpath(regtime, "/IMAGE/REGTIME", 0); + + rc += xpath(source, "/IMAGE/SOURCE", "not_found"); + rc += xpath(int_state, "/IMAGE/STATE", 0); + rc += xpath(running_vms, "/IMAGE/RUNNING_VMS", -1); + + type = static_cast(int_type); + state = static_cast(int_state); + + // Get associated classes + ObjectXML::get_nodes("/IMAGE/TEMPLATE", content); + if( content.size() < 1 ) + { + return -1; + } + + rc += image_template->from_xml_node(content[0]); + + if (rc != 0) + { + return -1; + } + + return 0; } /* ------------------------------------------------------------------------ */ diff --git a/src/image/ImagePool.cc b/src/image/ImagePool.cc index fc43d6f043..45e200915e 100644 --- a/src/image/ImagePool.cc +++ b/src/image/ImagePool.cc @@ -27,61 +27,30 @@ string ImagePool::_source_prefix; string ImagePool::_default_type; string ImagePool::_default_dev_prefix; -int ImagePool::init_cb(void *nil, int num, char **values, char **names) -{ - if ( num == 0 || values == 0 || values[0] == 0 ) - { - return -1; - } - - image_names.insert(make_pair(values[1],atoi(values[0]))); - - return 0; -} - /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ - -ImagePool::ImagePool( SqlDB * db, - const string& __source_prefix, - const string& __default_type, - const string& __default_dev_prefix): - +ImagePool::ImagePool(SqlDB * db, + const string& __source_prefix, + const string& __default_type, + const string& __default_dev_prefix): PoolSQL(db,Image::table) { - ostringstream sql; - int rc; + ostringstream sql; // Init static defaults - _source_prefix = __source_prefix; - _default_type = __default_type; - _default_dev_prefix = __default_dev_prefix; + _source_prefix = __source_prefix; + _default_type = __default_type; + _default_dev_prefix = __default_dev_prefix; // Set default type if (_default_type != "OS" && _default_type != "CDROM" && _default_type != "DATABLOCK" ) { - NebulaLog::log("IMG", Log::ERROR, - "Bad default for image type, setting OS"); + NebulaLog::log("IMG", Log::ERROR, "Bad default for type, setting OS"); _default_type = "OS"; } - - // Read from the DB the existing images, and build the ID:Name map - set_callback(static_cast(&ImagePool::init_cb)); - - sql << "SELECT oid, name FROM " << Image::table; - - rc = db->exec(sql, this); - - unset_callback(); - - if ( rc != 0 ) - { - NebulaLog::log("IMG", Log::ERROR, - "Could not load the existing images from the DB."); - } } /* -------------------------------------------------------------------------- */ @@ -89,32 +58,57 @@ ImagePool::ImagePool( SqlDB * db, int ImagePool::allocate ( int uid, + string user_name, ImageTemplate* img_template, int * oid, string& error_str) { - Image * img; - string name; + Image * img; + Image * img_aux; + string name; + ostringstream oss; // --------------------------------------------------------------------- // Build a new Image object // --------------------------------------------------------------------- - img = new Image(uid,img_template); + img = new Image(uid, user_name, img_template); + // Check name img->get_template_attribute("NAME", name); + if ( name.empty() ) + { + goto error_name; + } + + // Check for duplicates + img_aux = get(name,uid,false); + + if( img_aux != 0 ) + { + goto error_duplicated; + } + // --------------------------------------------------------------------- // Insert the Object in the pool // --------------------------------------------------------------------- *oid = PoolSQL::allocate(img, error_str); - // --------------------------------------------------------------------- - // Add the image name to the map of image_names - // --------------------------------------------------------------------- - if ( *oid != -1 ) - { - image_names.insert(make_pair(name, *oid)); - } + return *oid; + + +error_name: + oss << "NAME cannot be empty."; + goto error_common; + +error_duplicated: + oss << "NAME is already taken by IMAGE " << img_aux->get_oid() << "."; + +error_common: + delete img; + + *oid = -1; + error_str = oss.str(); return *oid; } @@ -122,54 +116,11 @@ int ImagePool::allocate ( /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int ImagePool::dump_cb(void * _oss, int num, char **values, char **names) -{ - ostringstream * oss; - - oss = static_cast(_oss); - - return Image::dump(*oss, num, values, names); -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int ImagePool::dump(ostringstream& oss, const string& where) -{ - int rc; - ostringstream cmd; - - oss << ""; - - set_callback(static_cast(&ImagePool::dump_cb), - static_cast(&oss)); - - cmd << "SELECT "<< Image::extended_db_names << ", user_pool.user_name FROM " - << Image::table - << " LEFT OUTER JOIN (SELECT oid, user_name FROM user_pool) " - << "AS user_pool ON " << Image::table << ".uid = user_pool.oid"; - - if ( !where.empty() ) - { - cmd << " WHERE " << where; - } - - rc = db->exec(cmd, this); - - oss << ""; - - unset_callback(); - - return rc; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - int ImagePool::disk_attribute(VectorAttribute * disk, int disk_id, int * index, - Image::ImageType * img_type) + Image::ImageType * img_type, + int uid) { string source; Image * img = 0; @@ -204,7 +155,7 @@ int ImagePool::disk_attribute(VectorAttribute * disk, } else { - img = get(source,true); + img = get(source,uid,true); if (img == 0) { @@ -255,7 +206,7 @@ int ImagePool::disk_attribute(VectorAttribute * disk, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void ImagePool::authorize_disk(VectorAttribute * disk, AuthRequest * ar) +void ImagePool::authorize_disk(VectorAttribute * disk,int uid, AuthRequest * ar) { string source; Image * img = 0; @@ -284,7 +235,7 @@ void ImagePool::authorize_disk(VectorAttribute * disk, AuthRequest * ar) } else { - img = get(source,true); + img = get(source,uid,true); } if (img == 0) @@ -293,7 +244,7 @@ void ImagePool::authorize_disk(VectorAttribute * disk, AuthRequest * ar) } ar->add_auth(AuthRequest::IMAGE, - img->get_iid(), + img->get_oid(), AuthRequest::USE, img->get_uid(), img->isPublic()); diff --git a/src/image/test/ImagePoolTest.cc b/src/image/test/ImagePoolTest.cc index ed0efdb4e5..041076cbba 100644 --- a/src/image/test/ImagePoolTest.cc +++ b/src/image/test/ImagePoolTest.cc @@ -24,6 +24,7 @@ using namespace std; const int uids[] = {0,1,2}; +const string user_names[] = {"A user","B user","C user"}; const string names[] = {"Image one", "Second Image", "The third image"}; @@ -49,19 +50,19 @@ const string templates[] = const string xmls[] = { - "00Image one0010000000000source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa19830", + "00A userImage one0010000000000source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa19830", - "11Second Image0100000000000source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f330", + "11B userSecond Image0100000000000source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f330", - "02The third image0000000000000source_prefix/e50b0c738be9d431475bf5859629e5580301a7d630" + "02C userThe third image0000000000000source_prefix/e50b0c738be9d431475bf5859629e5580301a7d630" }; // This xml dump result has the STIMEs modified to 0000000000 const string xml_dump = -"00one_user_testImage one0010000000000source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa1983011A userSecond Image0100000000000source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f33022B userThe third image0000000000000source_prefix/e50b0c738be9d431475bf5859629e5580301a7d630"; +"00A userImage one0010000000000source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa1983011B userSecond Image0100000000000source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f33022C userThe third image0000000000000source_prefix/e50b0c738be9d431475bf5859629e5580301a7d630"; const string xml_dump_where = -"00one_user_testImage one0010000000000source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa1983011A userSecond Image0100000000000source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f330"; +"00A userImage one0010000000000source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa1983011B userSecond Image0100000000000source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f330"; const string replacement = "0000000000"; @@ -91,7 +92,7 @@ public: if( rc == 0 ) { - return ImagePool::allocate(uid, img_template, oid, err); + return ImagePool::allocate(uid, user_names[uid], img_template, oid, err); } else { @@ -167,33 +168,17 @@ protected: ((Image*)obj)->to_xml(xml_str); xml_str.replace( xml_str.find("")+9, 10, replacement); - //cout << endl << xml_str << endl << xmls[index] << endl; +/* + if( xml_str != xmls[index] ) + { + cout << endl << xml_str << endl << xmls[index] << endl; + } +//*/ CPPUNIT_ASSERT( ((Image*)obj)->get_name() == names[index] ); CPPUNIT_ASSERT( xml_str == xmls[index]); }; - void set_up_user_pool() - { - string err; - - UserPool::bootstrap(db); - UserPool * user_pool = new UserPool(db); - int uid_1, uid_2; - - string username_1 = "A user"; - string username_2 = "B user"; - - string pass_1 = "A pass"; - string pass_2 = "B pass"; - - user_pool->allocate(&uid_1, username_1, pass_1, true, err); - user_pool->allocate(&uid_2, username_2, pass_2, true, err); - - delete user_pool; - }; - - public: ImagePoolTest(){xmlInitParser();}; @@ -207,7 +192,7 @@ public: ImagePool * imp; Image * img; - // Allocate 2 users, so they are written to the DB. + // Allocate 2 images, so they are written to the DB. allocate(0); allocate(2); @@ -215,13 +200,13 @@ public: // allocated images. imp = new ImagePool(db, "source_prefix", "OS", "hd"); - img = imp->get(names[0], false); + img = imp->get(names[0], uids[0], false); CPPUNIT_ASSERT( img != 0 ); - img = imp->get(names[1], false); + img = imp->get(names[1], uids[1], false); CPPUNIT_ASSERT( img == 0 ); - img = imp->get(names[2], false); + img = imp->get(names[2], uids[2], false); CPPUNIT_ASSERT( img != 0 ); @@ -312,7 +297,7 @@ public: check(0, obj); // Get using its name - obj = imp->get(names[1], true); + obj = imp->get(names[1], uids[1], true); CPPUNIT_ASSERT( obj != 0 ); obj->unlock(); @@ -324,7 +309,7 @@ public: pool->clean(); // Get first object and check its integrity - obj = imp->get(names[0], false); + obj = imp->get(names[0], uids[0], false); check(0, obj); // Get using its name @@ -341,14 +326,14 @@ public: // The pool is empty // Non existing name - obj = imp->get("Wrong name", true); + obj = imp->get("Wrong name", 0, true); CPPUNIT_ASSERT( obj == 0 ); // Allocate an object allocate(0); // Ask again for a non-existing name - obj = imp->get("Non existing name", true); + obj = imp->get("Non existing name",uids[0], true); CPPUNIT_ASSERT( obj == 0 ); } @@ -370,9 +355,9 @@ public: CPPUNIT_ASSERT( rc == -1 ); CPPUNIT_ASSERT( oid == rc ); - // Try again, with different uid + // Try again, this time with different uid. Should be allowed rc = imp->allocate(uids[1], templates[0], &oid); - CPPUNIT_ASSERT( rc == -1 ); + CPPUNIT_ASSERT( rc >= 0 ); CPPUNIT_ASSERT( oid == rc ); } @@ -487,6 +472,7 @@ public: CPPUNIT_ASSERT(oid >= 0); img = imp->get(oid, false); + CPPUNIT_ASSERT( img != 0 ); img->enable(true); img->disk_attribute(disk, &index, &img_type); @@ -508,6 +494,7 @@ public: CPPUNIT_ASSERT(oid >= 0); img = imp->get(oid, false); + CPPUNIT_ASSERT( img != 0 ); img->enable(true); img->disk_attribute(disk, &index, &img_type); @@ -529,6 +516,7 @@ public: CPPUNIT_ASSERT(oid >= 0); img = imp->get(oid, false); + CPPUNIT_ASSERT( img != 0 ); img->enable(true); img->disk_attribute(disk, &index, &img_type); @@ -557,6 +545,7 @@ public: // Allocate an OS type image oid = allocate(0); img = imp->get(oid, false); + CPPUNIT_ASSERT( img != 0 ); // --------------------------------------------------------------------- // A disk without a BUS attribute should not have it added. @@ -643,7 +632,7 @@ public: disk = new VectorAttribute("DISK"); disk->replace("IMAGE", "Image 0"); - ((ImagePool*)imp)->disk_attribute(disk, 0, &index, &img_type); + ((ImagePool*)imp)->disk_attribute(disk, 0, &index, &img_type,0); value = ""; value = disk->vector_value("TARGET"); @@ -660,7 +649,7 @@ public: disk = new VectorAttribute("DISK"); disk->replace("IMAGE_ID", "1"); - ((ImagePool*)imp)->disk_attribute(disk, 0, &index, &img_type); + ((ImagePool*)imp)->disk_attribute(disk, 0, &index, &img_type,0); value = ""; value = disk->vector_value("TARGET"); @@ -865,8 +854,6 @@ public: int rc; string nan; - set_up_user_pool(); - allocate(0); allocate(1); allocate(2); @@ -876,9 +863,16 @@ public: string result = oss.str(); - result.replace(164, 10, replacement); - result.replace(1154, 10, replacement); - result.replace(1684, 10, replacement); + result.replace(157, 10, replacement); + result.replace(1147, 10, replacement); + result.replace(1677, 10, replacement); + +/* + if( result != xml_dump ) + { + cout << endl << result << endl << xml_dump << endl; + } +//*/ CPPUNIT_ASSERT( result == xml_dump ); } @@ -894,8 +888,6 @@ public: ostringstream oss; ostringstream where; - set_up_user_pool(); - allocate(0); allocate(1); allocate(2); @@ -906,8 +898,15 @@ public: CPPUNIT_ASSERT(rc == 0); string result = oss.str(); - result.replace(164, 10, replacement); - result.replace(1154, 10, replacement); + result.replace(157, 10, replacement); + result.replace(1147, 10, replacement); + +/* + if( result != xml_dump_where ) + { + cout << endl << result << endl << xml_dump_where << endl; + } +//*/ CPPUNIT_ASSERT( result == xml_dump_where ); } @@ -921,7 +920,5 @@ public: int main(int argc, char ** argv) { - OneUnitTest::set_one_auth(); - return PoolTest::main(argc, argv, ImagePoolTest::suite()); } diff --git a/src/image/test/SConstruct b/src/image/test/SConstruct index 958db2137b..4d5bc99d00 100644 --- a/src/image/test/SConstruct +++ b/src/image/test/SConstruct @@ -30,6 +30,7 @@ env.Prepend(LIBS=[ 'nebula_core', 'nebula_sql', 'nebula_log', + 'nebula_xml', 'crypto' ]) diff --git a/src/lcm/test/LifeCycleManagerTest.cc b/src/lcm/test/LifeCycleManagerTest.cc index 70d0adbc42..23672f7c21 100644 --- a/src/lcm/test/LifeCycleManagerTest.cc +++ b/src/lcm/test/LifeCycleManagerTest.cc @@ -185,7 +185,7 @@ private: if( rc == 0 ) { - return vmpool->allocate(uids[index], vm_template, &oid, + return vmpool->allocate(uids[index], "username", vm_template, &oid, err, false); } else diff --git a/src/lcm/test/SConstruct b/src/lcm/test/SConstruct index 7e3b2867f2..21f5bea0c7 100644 --- a/src/lcm/test/SConstruct +++ b/src/lcm/test/SConstruct @@ -21,6 +21,7 @@ Import('env') env.Prepend(LIBS=[ 'nebula_core_test', 'nebula_host', + 'nebula_cluster', 'nebula_vmm', 'nebula_im', 'nebula_rm', @@ -32,6 +33,7 @@ env.Prepend(LIBS=[ 'nebula_vnm', 'nebula_image', 'nebula_pool', + 'nebula_xml', 'nebula_hm', 'nebula_authm', 'nebula_common', diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index 69f350d37c..d05290d690 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -234,6 +234,7 @@ void Nebula::start() VirtualNetworkPool::bootstrap(db); UserPool::bootstrap(db); ImagePool::bootstrap(db); + ClusterPool::bootstrap(db); } catch (exception&) { @@ -273,6 +274,8 @@ void Nebula::start() repository_path, default_image_type, default_device_prefix); + + cpool = new ClusterPool(db); } catch (exception&) { @@ -438,6 +441,7 @@ void Nebula::start() vnpool, upool, ipool, + cpool, rm_port, log_location + "one_xmlrpc.log"); } diff --git a/src/nebula/SConstruct b/src/nebula/SConstruct index 9879736c12..90c3d33dfd 100644 --- a/src/nebula/SConstruct +++ b/src/nebula/SConstruct @@ -46,12 +46,14 @@ env.Prepend(LIBS=[ 'nebula_template', 'nebula_image', 'nebula_pool', + 'nebula_cluster', 'nebula_host', 'nebula_vnm', 'nebula_vm', 'nebula_common', 'nebula_sql', 'nebula_log', + 'nebula_xml', 'crypto' ]) diff --git a/src/pool/PoolObjectSQL.cc b/src/pool/PoolObjectSQL.cc new file mode 100644 index 0000000000..103ab92e50 --- /dev/null +++ b/src/pool/PoolObjectSQL.cc @@ -0,0 +1,110 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2010, 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. */ +/* -------------------------------------------------------------------------- */ + +#include "PoolObjectSQL.h" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int PoolObjectSQL::select(SqlDB *db) +{ + ostringstream oss; + int rc; + int boid; + + set_callback( + static_cast(&PoolObjectSQL::select_cb)); + + oss << "SELECT body FROM " << table << " WHERE oid = " << oid; + + boid = oid; + oid = -1; + + rc = db->exec(oss, this); + + unset_callback(); + + if ((rc != 0) || (oid != boid )) + { + return -1; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int PoolObjectSQL::select(SqlDB *db, const string& _name, int _uid) +{ + ostringstream oss; + + int rc; + char * sql_name; + + sql_name = db->escape_str(_name.c_str()); + + if ( sql_name == 0 ) + { + return -1; + } + + set_callback( + static_cast(&PoolObjectSQL::select_cb)); + + oss << "SELECT body FROM " << table << " WHERE name = '" <<_name << "'"; + + if ( _uid != -1 ) + { + oss << " AND uid = " << _uid; + } + + name = ""; + uid = -1; + + rc = db->exec(oss, this); + + unset_callback(); + + db->free_str(sql_name); + + if ((rc != 0) || (_name != name) || (_uid != uid)) + { + return -1; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int PoolObjectSQL::drop(SqlDB *db) +{ + ostringstream oss; + int rc; + + oss << "DELETE FROM " << table << " WHERE oid=" << oid; + + rc = db->exec(oss); + + if ( rc == 0 ) + { + set_valid(false); + } + + return rc; +} diff --git a/src/pool/PoolSQL.cc b/src/pool/PoolSQL.cc index c813d934c0..c698e51581 100644 --- a/src/pool/PoolSQL.cc +++ b/src/pool/PoolSQL.cc @@ -86,6 +86,7 @@ PoolSQL::~PoolSQL() pthread_mutex_destroy(&mutex); } + /* ************************************************************************** */ /* PoolSQL public interface */ /* ************************************************************************** */ @@ -185,7 +186,82 @@ PoolObjectSQL * PoolSQL::get( return 0; } + string okey = key(objectsql->name,objectsql->uid); + pool.insert(make_pair(objectsql->oid,objectsql)); + name_pool.insert(make_pair(okey, objectsql)); + + if ( olock == true ) + { + objectsql->lock(); + } + + oid_queue.push(objectsql->oid); + + if ( pool.size() > MAX_POOL_SIZE ) + { + replace(); + } + + unlock(); + + return objectsql; + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +PoolObjectSQL * PoolSQL::get(const string& name, int ouid, bool olock) +{ + map::iterator index; + + PoolObjectSQL * objectsql; + int rc; + + lock(); + + index = name_pool.find(key(name,ouid)); + + if ( index != name_pool.end() ) + { + if ( index->second->isValid() == false ) + { + objectsql = 0; + } + else + { + objectsql = index->second; + + if ( olock == true ) + { + objectsql->lock(); + } + } + + unlock(); + + return objectsql; + } + else + { + objectsql = create(); + + rc = objectsql->select(db,name,ouid); + + if ( rc != 0 ) + { + delete objectsql; + + unlock(); + + return 0; + } + + string okey = key(objectsql->name,objectsql->uid); + + pool.insert(make_pair(objectsql->oid, objectsql)); + name_pool.insert(make_pair(okey, objectsql)); if ( olock == true ) { @@ -236,10 +312,11 @@ void PoolSQL::replace() } else { - PoolObjectSQL * tmp_ptr; + PoolObjectSQL * tmp_ptr = index->second; + string okey = key(tmp_ptr->name,tmp_ptr->uid); - tmp_ptr = index->second; pool.erase(index); + name_pool.erase(okey); delete tmp_ptr; @@ -266,12 +343,63 @@ void PoolSQL::clean() } pool.clear(); + name_pool.clear(); unlock(); } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ + +int PoolSQL::dump_cb(void * _oss, int num, char **values, char **names) +{ + ostringstream * oss; + + oss = static_cast(_oss); + + if ( (!values[0]) || (num != 1) ) + { + return -1; + } + + *oss << values[0]; + return 0; +} + +/* -------------------------------------------------------------------------- */ + +int PoolSQL::dump(ostringstream& oss, + const string& elem_name, + 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() ) + { + cmd << " WHERE " << where; + } + + rc = db->exec(cmd, this); + + oss << ""; + + unset_callback(); + + return rc; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int PoolSQL:: search_cb(void * _oids, int num, char **values, char **names) { vector * oids; @@ -309,3 +437,4 @@ int PoolSQL::search( return rc; } + diff --git a/src/pool/SConstruct b/src/pool/SConstruct index 47ceedfdf6..734ce963e5 100644 --- a/src/pool/SConstruct +++ b/src/pool/SConstruct @@ -22,7 +22,8 @@ lib_name='nebula_pool' # Sources to generate the library source_files=[ - 'PoolSQL.cc' + 'PoolSQL.cc', + 'PoolObjectSQL.cc' ] # Build library diff --git a/src/pool/test/SConstruct b/src/pool/test/SConstruct index bdec5bdd9e..085b413a2b 100644 --- a/src/pool/test/SConstruct +++ b/src/pool/test/SConstruct @@ -23,6 +23,7 @@ env.Append(LIBPATH=[ env.Prepend(LIBS=[ 'nebula_pool', + 'nebula_xml', 'nebula_common', 'nebula_log', 'nebula_core', diff --git a/src/pool/test/TestPoolSQL.cc b/src/pool/test/TestPoolSQL.cc index 82f307c9df..4442d62e96 100644 --- a/src/pool/test/TestPoolSQL.cc +++ b/src/pool/test/TestPoolSQL.cc @@ -32,10 +32,10 @@ const char * TestObjectSQL::table = "test_pool"; -const char * TestObjectSQL::db_names = "(oid,number,text)"; +const char * TestObjectSQL::db_names = "(oid,number,name)"; const char * TestObjectSQL::db_bootstrap = "CREATE TABLE test_pool (" - "oid INTEGER, number INTEGER, text TEXT, PRIMARY KEY(oid))"; + "oid INTEGER, number INTEGER, name TEXT, PRIMARY KEY(oid))"; /* -------------------------------------------------------------------------- */ diff --git a/src/pool/test/TestPoolSQL.h b/src/pool/test/TestPoolSQL.h index ca8e0c891e..0ef0b23cf8 100644 --- a/src/pool/test/TestPoolSQL.h +++ b/src/pool/test/TestPoolSQL.h @@ -30,7 +30,7 @@ class TestObjectSQL : public PoolObjectSQL { public: //OBJECT ATTRIBUTES - TestObjectSQL(int n=-1, string t="default"):number(n),text(t){}; + TestObjectSQL(int n=-1, string t="default"):PoolObjectSQL(-1,"",0,0),number(n),text(t){}; ~TestObjectSQL(){}; @@ -71,6 +71,16 @@ public: db->exec(oss,0); }; + + string& to_xml(string& xml) const + { + return xml; + }; + + int from_xml(const string &xml_str) + { + return 0; + }; }; // THE POOL diff --git a/src/pool/test/pool.cc b/src/pool/test/pool.cc index b976dadf26..e0df566f90 100644 --- a/src/pool/test/pool.cc +++ b/src/pool/test/pool.cc @@ -141,7 +141,7 @@ public: vector results; const char * table = "test_pool"; - string where = "text = '" + stB + "'"; + string where = "name = '" + stB + "'"; int ret; ret = pool->search(results, table, where); @@ -205,4 +205,4 @@ public: int main(int argc, char ** argv) { return OneUnitTest::main(argc, argv, PoolTest::suite()); -} \ No newline at end of file +} diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index a4271f480a..10606df497 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -250,22 +250,22 @@ void RequestManager::register_xml_methods() RequestManager::HostEnable(hpool,upool)); xmlrpc_c::methodPtr cluster_allocate(new - RequestManager::ClusterAllocate(hpool,upool)); + RequestManager::ClusterAllocate(upool,cpool)); xmlrpc_c::methodPtr cluster_info(new - RequestManager::ClusterInfo(hpool,upool)); + RequestManager::ClusterInfo(upool,cpool)); xmlrpc_c::methodPtr cluster_delete(new - RequestManager::ClusterDelete(hpool,upool)); + RequestManager::ClusterDelete(upool,cpool)); xmlrpc_c::methodPtr cluster_add(new - RequestManager::ClusterAdd(hpool,upool)); + RequestManager::ClusterAdd(hpool,upool,cpool)); xmlrpc_c::methodPtr cluster_remove(new - RequestManager::ClusterRemove(hpool,upool)); + RequestManager::ClusterRemove(hpool,upool,cpool)); xmlrpc_c::methodPtr clusterpool_info(new - RequestManager::ClusterPoolInfo(hpool,upool)); + RequestManager::ClusterPoolInfo(upool,cpool)); xmlrpc_c::methodPtr vn_allocate(new RequestManager::VirtualNetworkAllocate(vnpool,upool)); diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 9aaeef590e..6ae73f60bc 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -29,6 +29,7 @@ void RequestManager::VirtualMachineAllocate::execute( string session; string str_template; string error_str; + string user_name; const string method_name = "VirtualMachineAllocate"; @@ -41,6 +42,7 @@ void RequestManager::VirtualMachineAllocate::execute( xmlrpc_c::value_array * arrayresult; VirtualMachineTemplate * vm_template; + User * user; char * error_msg = 0; int num; @@ -92,7 +94,7 @@ void RequestManager::VirtualMachineAllocate::execute( continue; } - VirtualMachineAllocate::ipool->authorize_disk(vector,&ar); + VirtualMachineAllocate::ipool->authorize_disk(vector,uid,&ar); } vectors.clear(); @@ -108,7 +110,7 @@ void RequestManager::VirtualMachineAllocate::execute( continue; } - VirtualMachineAllocate::vnpool->authorize_nic(vector,&ar); + VirtualMachineAllocate::vnpool->authorize_nic(vector,uid,&ar); } ar.add_auth(AuthRequest::VM, @@ -123,10 +125,26 @@ void RequestManager::VirtualMachineAllocate::execute( } } + //-------------------------------------------------------------------------- + // Get the User Name + //-------------------------------------------------------------------------- + + user = VirtualMachineAllocate::upool->get(uid,true); + + if ( user == 0 ) + { + goto error_user_get; + } + + user_name = user->get_name(); + + user->unlock(); + //-------------------------------------------------------------------------- // Allocate the VirtualMAchine //-------------------------------------------------------------------------- rc = VirtualMachineAllocate::vmpool->allocate(uid, + user_name, vm_template, &vid, error_str, @@ -147,6 +165,13 @@ void RequestManager::VirtualMachineAllocate::execute( return; + +error_user_get: + oss.str(get_error(method_name, "USER", uid)); + + delete vm_template; + goto error_common; + error_authenticate: oss.str(authenticate_error(method_name)); goto error_common; diff --git a/src/rm/RequestManagerClusterAdd.cc b/src/rm/RequestManagerClusterAdd.cc index 9e0391f30e..0ffe63f389 100644 --- a/src/rm/RequestManagerClusterAdd.cc +++ b/src/rm/RequestManagerClusterAdd.cc @@ -34,7 +34,8 @@ void RequestManager::ClusterAdd::execute( const string method_name = "ClusterAdd"; - Host * host; + Host * host; + Cluster * cluster; ostringstream oss; @@ -71,6 +72,14 @@ void RequestManager::ClusterAdd::execute( } } + // Check if cluster exists + cluster = ClusterAdd::cpool->get(clid,true); + + if ( cluster == 0 ) + { + goto error_cluster_get; + } + // Check if host exists host = ClusterAdd::hpool->get(hid,true); @@ -80,7 +89,7 @@ void RequestManager::ClusterAdd::execute( } // Set cluster - rc = ClusterAdd::hpool->set_cluster(host, clid); + rc = host->set_cluster(cluster->get_name()); if ( rc != 0 ) { @@ -92,6 +101,8 @@ void RequestManager::ClusterAdd::execute( host->unlock(); + cluster->unlock(); + // All nice, return success to the client arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS @@ -112,11 +123,17 @@ error_authorize: goto error_common; error_host_get: + cluster->unlock(); oss.str(get_error(method_name, "HOST", hid)); goto error_common; +error_cluster_get: + oss.str(get_error(method_name, "CLUSTER", clid)); + goto error_common; + error_cluster_add: host->unlock(); + cluster->unlock(); oss.str(action_error(method_name, "USE", "CLUSTER", clid, rc)); goto error_common; diff --git a/src/rm/RequestManagerClusterAllocate.cc b/src/rm/RequestManagerClusterAllocate.cc index 5184f925d8..54fff40ccc 100644 --- a/src/rm/RequestManagerClusterAllocate.cc +++ b/src/rm/RequestManagerClusterAllocate.cc @@ -69,7 +69,7 @@ void RequestManager::ClusterAllocate::execute( } // Perform the allocation in the hostpool - rc = ClusterAllocate::hpool->allocate_cluster(&id, clustername, error_str); + rc = ClusterAllocate::cpool->allocate(&id, clustername, error_str); if ( rc == -1 ) { diff --git a/src/rm/RequestManagerClusterDelete.cc b/src/rm/RequestManagerClusterDelete.cc index b403b52b7c..a1a938faa4 100644 --- a/src/rm/RequestManagerClusterDelete.cc +++ b/src/rm/RequestManagerClusterDelete.cc @@ -26,14 +26,14 @@ void RequestManager::ClusterDelete::execute( xmlrpc_c::paramList const& paramList, xmlrpc_c::value * const retval) { - string session; + string session; - // of the cluster to delete from the HostPool - int clid; - ostringstream oss; - int rc; + int clid; + Cluster * cluster; + ostringstream oss; + int rc; - const string method_name = "ClusterDelete"; + const string method_name = "ClusterDelete"; /* -- RPC specific vars -- */ vector arrayData; @@ -66,7 +66,17 @@ void RequestManager::ClusterDelete::execute( } } - rc = ClusterDelete::hpool->drop_cluster(clid); + // Perform the deletion from the pool + cluster = ClusterDelete::cpool->get(clid,true); + + if ( cluster == 0 ) + { + goto error_cluster_get; + } + + rc = ClusterDelete::cpool->drop(cluster); + + cluster->unlock(); if ( rc != 0 ) { @@ -92,6 +102,10 @@ error_authorize: oss.str(authorization_error(method_name, "DELETE", "CLUSTER", rc, clid)); goto error_common; +error_cluster_get: + oss.str(get_error(method_name, "CLUSTER", clid)); + goto error_common; + error_cluster_delete: oss.str(action_error(method_name, "DELETE", "CLUSTER", clid, rc)); goto error_common; diff --git a/src/rm/RequestManagerClusterInfo.cc b/src/rm/RequestManagerClusterInfo.cc index 5f09d56b83..d446e7677e 100644 --- a/src/rm/RequestManagerClusterInfo.cc +++ b/src/rm/RequestManagerClusterInfo.cc @@ -29,12 +29,14 @@ void RequestManager::ClusterInfo::execute( string session; string info; - int clid; - int rc; - + Cluster * cluster; + ostringstream oss; + + int clid; + int rc; + const string method_name = "ClusterInfo"; - ostringstream oss; /* -- RPC specific vars -- */ vector arrayData; @@ -54,14 +56,18 @@ void RequestManager::ClusterInfo::execute( goto error_authenticate; } - info = ClusterInfo::hpool->info_cluster(clid); + // Get the cluster + cluster = ClusterInfo::cpool->get(clid,true); - // Cluster does not exists - if ( info.empty() ) + if ( cluster == 0 ) { - goto error_cluster; + goto error_cluster_get; } + oss << *cluster; + + cluster->unlock(); + // All nice, return the cluster info to the client arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS arrayData.push_back(xmlrpc_c::value_string(info)); @@ -78,7 +84,7 @@ error_authenticate: oss.str(authenticate_error(method_name)); goto error_common; -error_cluster: +error_cluster_get: oss.str(get_error(method_name, "CLUSTER", clid)); goto error_common; diff --git a/src/rm/RequestManagerClusterPoolInfo.cc b/src/rm/RequestManagerClusterPoolInfo.cc old mode 100755 new mode 100644 index fb9ba26b8f..ece06d4274 --- a/src/rm/RequestManagerClusterPoolInfo.cc +++ b/src/rm/RequestManagerClusterPoolInfo.cc @@ -29,7 +29,7 @@ void RequestManager::ClusterPoolInfo::execute( string session; ostringstream oss; int rc; - + const string method_name = "ClusterPoolInfo"; /* -- RPC specific vars -- */ @@ -49,8 +49,8 @@ void RequestManager::ClusterPoolInfo::execute( goto error_authenticate; } - // Perform the allocation in the vmpool - rc = ClusterPoolInfo::hpool->dump_cluster(oss); + // Dump the pool + rc = ClusterPoolInfo::cpool->dump(oss, ""); if ( rc != 0 ) { diff --git a/src/rm/RequestManagerClusterRemove.cc b/src/rm/RequestManagerClusterRemove.cc index f18e75c6a7..1fe7fa9b80 100644 --- a/src/rm/RequestManagerClusterRemove.cc +++ b/src/rm/RequestManagerClusterRemove.cc @@ -27,10 +27,10 @@ void RequestManager::ClusterRemove::execute( xmlrpc_c::value * const retval) { string session; - + int hid; int rc; - + const string method_name = "ClusterRemove"; Host * host; @@ -77,7 +77,7 @@ void RequestManager::ClusterRemove::execute( } // Remove host from cluster - rc = ClusterRemove::hpool->set_default_cluster(host); + rc = ClusterRemove::cpool->set_default_cluster(host); if ( rc != 0 ) { diff --git a/src/rm/RequestManagerDeploy.cc b/src/rm/RequestManagerDeploy.cc index 44643d23bf..5c982e95b3 100644 --- a/src/rm/RequestManagerDeploy.cc +++ b/src/rm/RequestManagerDeploy.cc @@ -107,7 +107,7 @@ void RequestManager::VirtualMachineDeploy::execute( goto error_host_get; } - hostname = host->get_hostname(); + hostname = host->get_name(); vmm_mad = host->get_vmm_mad(); tm_mad = host->get_tm_mad(); diff --git a/src/rm/RequestManagerHostDelete.cc b/src/rm/RequestManagerHostDelete.cc index 67a8f2f6e5..fa8bc3e968 100644 --- a/src/rm/RequestManagerHostDelete.cc +++ b/src/rm/RequestManagerHostDelete.cc @@ -67,7 +67,7 @@ void RequestManager::HostDelete::execute( } } - // Perform the allocation in the hostpool + // Perform the deletion from the hostpool host = HostDelete::hpool->get(hid,true); if ( host == 0 ) diff --git a/src/rm/RequestManagerHostPoolInfo.cc b/src/rm/RequestManagerHostPoolInfo.cc old mode 100755 new mode 100644 diff --git a/src/rm/RequestManagerImageAllocate.cc b/src/rm/RequestManagerImageAllocate.cc index 7c0e307006..a572d38059 100644 --- a/src/rm/RequestManagerImageAllocate.cc +++ b/src/rm/RequestManagerImageAllocate.cc @@ -31,8 +31,10 @@ void RequestManager::ImageAllocate::execute( string session; string str_template; string error_str; + string user_name; - ImageTemplate * img_template; + ImageTemplate * img_template = 0; + User * user; int iid; int uid; @@ -96,10 +98,28 @@ void RequestManager::ImageAllocate::execute( } } + + //-------------------------------------------------------------------------- + // Get the User Name + //-------------------------------------------------------------------------- + + user = ImageAllocate::upool->get(uid,true); + + if ( user == 0 ) + { + goto error_user_get; + } + + user_name = user->get_name(); + + user->unlock(); + //-------------------------------------------------------------------------- // Allocate the Image //-------------------------------------------------------------------------- - rc = ImageAllocate::ipool->allocate(uid,img_template,&iid, error_str); + + rc = ImageAllocate::ipool->allocate(uid,user_name, + img_template,&iid, error_str); if ( rc < 0 ) { @@ -118,6 +138,12 @@ void RequestManager::ImageAllocate::execute( return; + +error_user_get: + oss.str(get_error(method_name, "USER", uid)); + delete img_template; + goto error_common; + error_authenticate: oss.str(authenticate_error(method_name)); goto error_common; diff --git a/src/rm/RequestManagerImagePoolInfo.cc b/src/rm/RequestManagerImagePoolInfo.cc old mode 100755 new mode 100644 diff --git a/src/rm/RequestManagerMigrate.cc b/src/rm/RequestManagerMigrate.cc index 2fe2d1b513..9761692b33 100644 --- a/src/rm/RequestManagerMigrate.cc +++ b/src/rm/RequestManagerMigrate.cc @@ -67,7 +67,7 @@ void RequestManager::VirtualMachineMigrate::execute( goto error_host_get; } - hostname = host->get_hostname(); + hostname = host->get_name(); vmm_mad = host->get_vmm_mad(); tm_mad = host->get_tm_mad(); diff --git a/src/rm/RequestManagerPoolInfo.cc b/src/rm/RequestManagerPoolInfo.cc index 95ba3b7879..cfbb31d162 100644 --- a/src/rm/RequestManagerPoolInfo.cc +++ b/src/rm/RequestManagerPoolInfo.cc @@ -32,8 +32,6 @@ void RequestManager::VirtualMachinePoolInfo::execute( int rc; int state; - bool extended; - ostringstream oss; ostringstream where_string; @@ -45,18 +43,17 @@ void RequestManager::VirtualMachinePoolInfo::execute( NebulaLog::log("ReM",Log::DEBUG,"VirtualMachinePoolInfo method invoked"); + // For backwards compatibility, 2 or 3 arguments can be present. switch (paramList.size()) { case 2: - extended = true; state = -1; break; - case 4: - extended = xmlrpc_c::value_boolean(paramList.getBoolean(2)); + case 3: state = xmlrpc_c::value_int (paramList.getInt(3)); break; default: - paramList.verifyEnd(4); + paramList.verifyEnd(3); return; } @@ -86,7 +83,7 @@ void RequestManager::VirtualMachinePoolInfo::execute( where_string << "UID=" << filter_flag; } - rc = VirtualMachinePoolInfo::vmpool->dump(oss, extended, state, where_string.str()); + rc = VirtualMachinePoolInfo::vmpool->dump(oss, state, where_string.str()); if ( rc != 0 ) { diff --git a/src/rm/RequestManagerVirtualNetworkAllocate.cc b/src/rm/RequestManagerVirtualNetworkAllocate.cc index d010505af6..ef687ad5f9 100644 --- a/src/rm/RequestManagerVirtualNetworkAllocate.cc +++ b/src/rm/RequestManagerVirtualNetworkAllocate.cc @@ -28,10 +28,12 @@ void RequestManager::VirtualNetworkAllocate::execute( { string session; string name; + string user_name; string str_template; string error_str; VirtualNetworkTemplate * vn_template; + User * user; int nid; int uid; @@ -96,10 +98,25 @@ void RequestManager::VirtualNetworkAllocate::execute( } } + //-------------------------------------------------------------------------- + // Get the User Name + //-------------------------------------------------------------------------- + + user = VirtualNetworkAllocate::upool->get(uid,true); + + if ( user == 0 ) + { + goto error_user_get; + } + + user_name = user->get_name(); + + user->unlock(); + //-------------------------------------------------------------------------- // Allocate the Virtual Network //-------------------------------------------------------------------------- - rc = vnpool->allocate(uid,vn_template,&nid,error_str); + rc = vnpool->allocate(uid,user_name,vn_template,&nid,error_str); if ( rc < 0 ) { @@ -118,6 +135,12 @@ void RequestManager::VirtualNetworkAllocate::execute( return; +error_user_get: + oss.str(get_error(method_name, "USER", uid)); + + delete vn_template; + goto error_common; + error_authenticate: oss.str(authenticate_error(method_name)); goto error_common; diff --git a/src/rm/RequestManagerVirtualNetworkPoolInfo.cc b/src/rm/RequestManagerVirtualNetworkPoolInfo.cc old mode 100755 new mode 100644 diff --git a/src/scheduler/SConstruct b/src/scheduler/SConstruct index a41d005437..7a69cab7c7 100644 --- a/src/scheduler/SConstruct +++ b/src/scheduler/SConstruct @@ -28,7 +28,7 @@ env.Append(CPPPATH=[ # Library dirs env.Append(LIBPATH=[ - cwd+'/src/xml', + cwd+'/src/client', cwd+'/src/pool', cwd+'/src/sched' ]) @@ -38,7 +38,7 @@ env.Append(LIBPATH=[ ################################################################################ build_scripts=[ - 'src/xml/SConstruct', + 'src/client/SConstruct', 'src/pool/SConstruct', 'src/sched/SConstruct' ] @@ -46,7 +46,6 @@ build_scripts=[ if env['testing']=='yes': build_scripts.extend([ 'src/pool/test/SConstruct', - 'src/xml/test/SConstruct', ]) for script in build_scripts: diff --git a/src/scheduler/include/PoolXML.h b/src/scheduler/include/PoolXML.h index 146bd1bbad..428cf10d69 100644 --- a/src/scheduler/include/PoolXML.h +++ b/src/scheduler/include/PoolXML.h @@ -84,7 +84,7 @@ public: return -1; } - update(message); + update_from_str(message); vector nodes; int num_objs; diff --git a/src/scheduler/src/xml/Client.cc b/src/scheduler/src/client/Client.cc similarity index 100% rename from src/scheduler/src/xml/Client.cc rename to src/scheduler/src/client/Client.cc diff --git a/src/scheduler/src/client/SConstruct b/src/scheduler/src/client/SConstruct new file mode 100644 index 0000000000..d9509465b1 --- /dev/null +++ b/src/scheduler/src/client/SConstruct @@ -0,0 +1,26 @@ +# SConstruct for src/pool + +# -------------------------------------------------------------------------- # +# Copyright 2002-2010, 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. # +#--------------------------------------------------------------------------- # + +Import('sched_env') + +lib_name='scheduler_client' + +source_files=['Client.cc'] + +# Build library +sched_env.StaticLibrary(lib_name, source_files) diff --git a/src/scheduler/src/pool/test/SConstruct b/src/scheduler/src/pool/test/SConstruct index 964b474ae2..69d4ce0b46 100644 --- a/src/scheduler/src/pool/test/SConstruct +++ b/src/scheduler/src/pool/test/SConstruct @@ -18,7 +18,7 @@ Import('sched_env') # Libraries sched_env.Prepend(LIBS=[ - 'scheduler_xml', + 'nebula_xml', 'scheduler_pool', 'nebula_log', 'nebula_common', diff --git a/src/scheduler/src/sched/SConstruct b/src/scheduler/src/sched/SConstruct index 7d30c335c7..41cb064c98 100644 --- a/src/scheduler/src/sched/SConstruct +++ b/src/scheduler/src/sched/SConstruct @@ -31,7 +31,8 @@ sched_env.Prepend(LIBS=[ 'scheduler_sched', 'scheduler_pool', 'nebula_log', - 'scheduler_xml', + 'scheduler_client', + 'nebula_xml', 'nebula_common', 'crypto', ]) diff --git a/src/template/Template.cc b/src/template/Template.cc index b1dd8b5ad9..75a2b9f712 100644 --- a/src/template/Template.cc +++ b/src/template/Template.cc @@ -445,12 +445,7 @@ Attribute * Template::vector_xml_att(const xmlNode * node) int Template::from_xml(const string &xml_str) { xmlDocPtr xml_doc = 0; - xmlNode * root_element; - xmlNode * cur_node = 0; - - Attribute * attr; - // Parse xml string as libxml document xml_doc = xmlParseMemory (xml_str.c_str(),xml_str.length()); @@ -460,6 +455,44 @@ int Template::from_xml(const string &xml_str) return -1; } + // Get the