From f308bdeb069e32bfc4ef933117d2498994aa05b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 12 Dec 2013 19:08:59 +0100 Subject: [PATCH] Feature #2562: New Zone pool in core --- SConstruct | 2 + include/Nebula.h | 15 +- include/PoolObjectSQL.h | 4 +- include/RequestManagerAllocate.h | 38 +++- include/RequestManagerDelete.h | 18 ++ include/RequestManagerInfo.h | 18 ++ include/RequestManagerPoolInfoFilter.h | 24 +++ include/Zone.h | 111 ++++++++++++ include/ZonePool.h | 143 +++++++++++++++ src/nebula/Nebula.cc | 2 + src/nebula/SConstruct | 1 + src/rm/Request.cc | 2 + src/rm/RequestManager.cc | 11 ++ src/rm/RequestManagerAllocate.cc | 18 ++ src/rm/RequestManagerPoolInfoFilter.cc | 10 ++ src/zone/SConstruct | 30 ++++ src/zone/Zone.cc | 236 +++++++++++++++++++++++++ src/zone/ZonePool.cc | 106 +++++++++++ 18 files changed, 783 insertions(+), 6 deletions(-) create mode 100644 include/Zone.h create mode 100644 include/ZonePool.h create mode 100644 src/zone/SConstruct create mode 100644 src/zone/Zone.cc create mode 100644 src/zone/ZonePool.cc diff --git a/SConstruct b/SConstruct index ffae6ad7c9..39e42a3e07 100644 --- a/SConstruct +++ b/SConstruct @@ -80,6 +80,7 @@ main_env.Append(LIBPATH=[ cwd+'/src/acl', cwd+'/src/xml', cwd+'/src/document', + cwd+'/src/zone', ]) # Compile flags @@ -243,6 +244,7 @@ build_scripts=[ 'src/acl/SConstruct', 'src/xml/SConstruct', 'src/document/SConstruct', + 'src/zone/SConstruct', 'share/man/SConstruct', 'src/sunstone/locale/languages/SConstruct', 'share/scripts/context-packages/SConstruct', diff --git a/include/Nebula.h b/include/Nebula.h index 59b3b83b6a..97dd177bdb 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -31,6 +31,7 @@ #include "DatastorePool.h" #include "ClusterPool.h" #include "DocumentPool.h" +#include "ZonePool.h" #include "VirtualMachineManager.h" #include "LifeCycleManager.h" @@ -118,6 +119,11 @@ public: return docpool; }; + ZonePool * get_zonepool() + { + return zonepool; + }; + // -------------------------------------------------------------- // Manager Accessors // -------------------------------------------------------------- @@ -564,9 +570,10 @@ private: "/DEFAULT_GROUP_QUOTAS/NETWORK_QUOTA", "/DEFAULT_GROUP_QUOTAS/IMAGE_QUOTA", "/DEFAULT_GROUP_QUOTAS/VM_QUOTA"), - system_db(0), db(0), vmpool(0), hpool(0), vnpool(0), - upool(0), ipool(0), gpool(0), tpool(0), dspool(0), clpool(0), - docpool(0), lcm(0), vmm(0), im(0), tm(0), dm(0), rm(0), hm(0), authm(0), + system_db(0), db(0), + vmpool(0), hpool(0), vnpool(0), upool(0), ipool(0), gpool(0), tpool(0), + dspool(0), clpool(0), docpool(0), zonepool(0), + lcm(0), vmm(0), im(0), tm(0), dm(0), rm(0), hm(0), authm(0), aclm(0), imagem(0) { const char * nl = getenv("ONE_LOCATION"); @@ -612,6 +619,7 @@ private: delete dspool; delete clpool; delete docpool; + delete zonepool; delete vmm; delete lcm; delete im; @@ -679,6 +687,7 @@ private: DatastorePool * dspool; ClusterPool * clpool; DocumentPool * docpool; + ZonePool * zonepool; // --------------------------------------------------------------- // Nebula Managers diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h index 60e7c170af..0875886c7a 100644 --- a/include/PoolObjectSQL.h +++ b/include/PoolObjectSQL.h @@ -59,7 +59,8 @@ public: ACL = 0x0000080000000000LL, DATASTORE = 0x0000100000000000LL, CLUSTER = 0x0000200000000000LL, - DOCUMENT = 0x0000400000000000LL + DOCUMENT = 0x0000400000000000LL, + ZONE = 0x0000800000000000LL }; static string type_to_str(ObjectType ob) @@ -77,6 +78,7 @@ public: case DATASTORE: return "DATASTORE" ; break; case CLUSTER: return "CLUSTER" ; break; case DOCUMENT: return "DOCUMENT" ; break; + case ZONE: return "ZONE" ; break; default: return ""; } }; diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index 48e494a434..89a0cff1ca 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -37,8 +37,8 @@ protected: RequestManagerAllocate(const string& method_name, const string& help, const string& xml_args, - bool dt) - :Request(method_name,xml_args,help), do_template(dt) + bool _do_template) + :Request(method_name,xml_args,help), do_template(_do_template) { auth_op = AuthRequest::CREATE; @@ -487,6 +487,40 @@ public: int umask); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ZoneAllocate: public RequestManagerAllocate +{ +public: + ZoneAllocate(): + RequestManagerAllocate("ZoneAllocate", + "Allocates a new zone", + "A:ss", + true) + { + Nebula& nd = Nebula::instance(); + pool = nd.get_zonepool(); + auth_object = PoolObjectSQL::ZONE; + }; + + ~ZoneAllocate(){}; + + /* --------------------------------------------------------------------- */ + + Template * get_object_template() + { + return new Template; + }; + + int pool_allocate(xmlrpc_c::paramList const& _paramList, + Template * tmpl, + int& id, + string& error_str, + RequestAttributes& att, + int umask); +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerDelete.h b/include/RequestManagerDelete.h index c95e3b7900..d6a6135563 100644 --- a/include/RequestManagerDelete.h +++ b/include/RequestManagerDelete.h @@ -294,6 +294,24 @@ public: ~DocumentDelete(){}; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ZoneDelete: public RequestManagerDelete +{ +public: + ZoneDelete(): + RequestManagerDelete("ZoneDelete", "Deletes a zone") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_zonepool(); + auth_object = PoolObjectSQL::ZONE; + auth_op = AuthRequest::ADMIN; + }; + + ~ZoneDelete(){}; +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerInfo.h b/include/RequestManagerInfo.h index d36d06e0f9..b0226b60f2 100644 --- a/include/RequestManagerInfo.h +++ b/include/RequestManagerInfo.h @@ -265,6 +265,24 @@ public: ~DocumentInfo(){}; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ZoneInfo: public RequestManagerInfo +{ +public: + ZoneInfo(): + RequestManagerInfo("ZoneInfo", + "Returns zone information") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_zonepool(); + auth_object = PoolObjectSQL::ZONE; + }; + + ~ZoneInfo(){}; +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerPoolInfoFilter.h b/include/RequestManagerPoolInfoFilter.h index 5927cdc30a..b9c92ed9d5 100644 --- a/include/RequestManagerPoolInfoFilter.h +++ b/include/RequestManagerPoolInfoFilter.h @@ -380,6 +380,30 @@ public: xmlrpc_c::paramList const& paramList, RequestAttributes& att); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ZonePoolInfo : public RequestManagerPoolInfoFilter +{ +public: + ZonePoolInfo(): + RequestManagerPoolInfoFilter("ZonePoolInfo", + "Returns the zone pool", + "A:s") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_zonepool(); + auth_object = PoolObjectSQL::ZONE; + }; + + ~ZonePoolInfo(){}; + + /* -------------------------------------------------------------------- */ + + void request_execute( + xmlrpc_c::paramList const& paramList, RequestAttributes& att); +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/Zone.h b/include/Zone.h new file mode 100644 index 0000000000..7f9f8d0883 --- /dev/null +++ b/include/Zone.h @@ -0,0 +1,111 @@ +/* ------------------------------------------------------------------------ */ +/* Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs */ +/* */ +/* 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 ZONE_H_ +#define ZONE_H_ + +#include "PoolObjectSQL.h" + +using namespace std; + +/** + * The Zone class. + */ +class Zone : public PoolObjectSQL +{ +public: + + /** + * Function to print the Zone 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 ZonePool; + + // ************************************************************************* + // Constructor + // ************************************************************************* + + Zone(int id, Template* zone_template); + + ~Zone(); + + // ************************************************************************* + // 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 + * @param error_str Returns the error reason, if any + * @return 0 one success + */ + int insert_replace(SqlDB *db, bool replace, string& error_str); + + /** + * Bootstraps the database table(s) associated to the Zone + * @return 0 on success + */ + static int bootstrap(SqlDB * db) + { + ostringstream oss(Zone::db_bootstrap); + + return db->exec(oss); + }; + + /** + * Writes the Zone in the database. + * @param db pointer to the db + * @return 0 on success + */ + int insert(SqlDB *db, string& error_str); + + /** + * Writes/updates the Zone's data fields in the database. + * @param db pointer to the db + * @return 0 on success + */ + int update(SqlDB *db) + { + string error_str; + return insert_replace(db, true, error_str); + } +}; + +#endif /*ZONE_H_*/ diff --git a/include/ZonePool.h b/include/ZonePool.h new file mode 100644 index 0000000000..65b12f6d9c --- /dev/null +++ b/include/ZonePool.h @@ -0,0 +1,143 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs */ +/* */ +/* 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 ZONE_POOL_H_ +#define ZONE_POOL_H_ + +#include "PoolSQL.h" +#include "Zone.h" + +using namespace std; + + +class ZonePool : public PoolSQL +{ +public: + ZonePool(SqlDB * db); + + ~ZonePool(){}; + + /* ---------------------------------------------------------------------- */ + /* Methods for DB management */ + /* ---------------------------------------------------------------------- */ + + /** + * Allocates a new Zone, writing it in the pool database. No memory is + * allocated for the object. + * @param zone_template a Template object + * @param oid the id assigned to the Zone + * @param error_str Returns the error reason, if any + * + * @return the oid assigned to the object, -1 in case of failure + */ + int allocate(Template * zone_template, + int * oid, + string& error_str); + + /** + * Function to get a Zone from the pool, if the object is not in memory + * it is loaded from the DB + * @param oid Zone unique id + * @param lock locks the Zone mutex + * @return a pointer to the Zone, 0 if the Zone could not be loaded + */ + Zone * get(int oid, bool lock) + { + return static_cast(PoolSQL::get(oid,lock)); + }; + + /** + * 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 + */ + Zone * get(const string& name, bool lock) + { + // The owner is set to -1, because it is not used in the key() method + return static_cast(PoolSQL::get(name,-1,lock)); + }; + + /** + * 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) + { + // Name is enough key because Zones can't repeat names. + return name; + }; + + /** Update a particular Zone + * @param zone pointer to Zone + * @return 0 on success + */ + int update(Zone * zone) + { + return zone->update(db); + }; + + /** + * Drops the Zone from the data base. The object mutex SHOULD be + * locked. + * @param objsql a pointer to a Zone object + * @param error_msg Error reason, if any + * @return 0 on success, + * -1 DB error, + * -2 object is a default Zone (ID < 100) + */ + int drop(PoolObjectSQL * objsql, string& error_msg); + + /** + * Bootstraps the database table(s) associated to the Zone pool + * @return 0 on success + */ + static int bootstrap(SqlDB * _db) + { + return Zone::bootstrap(_db); + }; + + /** + * Dumps the Zone 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, "ZONE_POOL", Zone::table, where); + }; + +private: + + /** + * Factory method to produce objects + * @return a pointer to the new object + */ + PoolObjectSQL * create() + { + return new Zone(-1,0); + }; +}; + +#endif /*ZONE_POOL_H_*/ diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index 312c7b956e..cddf9bf885 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -496,6 +496,7 @@ void Nebula::start(bool bootstrap_only) rc += DatastorePool::bootstrap(db); rc += ClusterPool::bootstrap(db); rc += DocumentPool::bootstrap(db); + rc += ZonePool::bootstrap(db); // Create the system tables only if bootstrap went well if ( rc == 0 ) @@ -561,6 +562,7 @@ void Nebula::start(bool bootstrap_only) clpool = new ClusterPool(db); docpool = new DocumentPool(db); + zonepool= new ZonePool(db); nebula_configuration->get("VM_HOOK", vm_hooks); nebula_configuration->get("HOST_HOOK", host_hooks); diff --git a/src/nebula/SConstruct b/src/nebula/SConstruct index 48b8f6ce86..ac93fa2d0c 100644 --- a/src/nebula/SConstruct +++ b/src/nebula/SConstruct @@ -55,6 +55,7 @@ env.Prepend(LIBS=[ 'nebula_vm', 'nebula_vmtemplate', 'nebula_document', + 'nebula_zone', 'nebula_hm', 'nebula_common', 'nebula_sql', diff --git a/src/rm/Request.cc b/src/rm/Request.cc index 530efcf457..a109d777fd 100644 --- a/src/rm/Request.cc +++ b/src/rm/Request.cc @@ -553,6 +553,8 @@ string Request::object_name(PoolObjectSQL::ObjectType ob) return "cluster"; case PoolObjectSQL::DOCUMENT: return "document"; + case PoolObjectSQL::ZONE: + return "zone"; default: return "-"; } diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index bdd4b5e3f9..cbaab4ec99 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -310,6 +310,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr datastore_allocate(new DatastoreAllocate()); xmlrpc_c::methodPtr cluster_allocate(new ClusterAllocate()); xmlrpc_c::methodPtr doc_allocate(new DocumentAllocate()); + xmlrpc_c::methodPtr zone_allocate(new ZoneAllocate()); // Clone Methods xmlrpc_c::methodPtr template_clone(new VMTemplateClone()); @@ -325,6 +326,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr datastore_delete(new DatastoreDelete()); xmlrpc_c::methodPtr cluster_delete(new ClusterDelete()); xmlrpc_c::methodPtr doc_delete(new DocumentDelete()); + xmlrpc_c::methodPtr zone_delete(new ZoneDelete()); // Info Methods xmlrpc_c::methodPtr vm_info(new VirtualMachineInfo()); @@ -337,6 +339,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr datastore_info(new DatastoreInfo()); xmlrpc_c::methodPtr cluster_info(new ClusterInfo()); xmlrpc_c::methodPtr doc_info(new DocumentInfo()); + xmlrpc_c::methodPtr zone_info(new ZoneInfo()); // PoolInfo Methods xmlrpc_c::methodPtr hostpool_info(new HostPoolInfo()); @@ -349,6 +352,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr imagepool_info(new ImagePoolInfo()); xmlrpc_c::methodPtr clusterpool_info(new ClusterPoolInfo()); xmlrpc_c::methodPtr docpool_info(new DocumentPoolInfo()); + xmlrpc_c::methodPtr zonepool_info(new ZonePoolInfo()); // Host Methods xmlrpc_c::methodPtr host_enable(new HostEnable()); @@ -564,6 +568,13 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.documentpool.info",docpool_info); + /* Zone related methods */ + RequestManagerRegistry.addMethod("one.zone.allocate",zone_allocate); + RequestManagerRegistry.addMethod("one.zone.delete", zone_delete); + RequestManagerRegistry.addMethod("one.zone.info", zone_info); + + RequestManagerRegistry.addMethod("one.zonepool.info",zonepool_info); + /* System related methods */ RequestManagerRegistry.addMethod("one.system.version", system_version); RequestManagerRegistry.addMethod("one.system.config", system_config); diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 9a443adf72..eb19343a8a 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -713,3 +713,21 @@ int DocumentAllocate::pool_allocate( return docpool->allocate(att.uid, att.gid, att.uname, att.gname, umask, type, tmpl, &id, error_str); } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int ZoneAllocate::pool_allocate( + xmlrpc_c::paramList const& paramList, + Template * tmpl, + int& id, + string& error_str, + RequestAttributes& att, + int umask) +{ + string name = xmlrpc_c::value_string(paramList.getString(1)); + + ZonePool * zonepool = static_cast(pool); + + return zonepool->allocate(tmpl, &id, error_str); +} diff --git a/src/rm/RequestManagerPoolInfoFilter.cc b/src/rm/RequestManagerPoolInfoFilter.cc index 0651fe0b6f..e75ee060a0 100644 --- a/src/rm/RequestManagerPoolInfoFilter.cc +++ b/src/rm/RequestManagerPoolInfoFilter.cc @@ -261,6 +261,16 @@ void DocumentPoolInfo::request_execute( /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +void ZonePoolInfo::request_execute( + xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + dump(att, ALL, -1, -1, "", ""); +} + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + void RequestManagerPoolInfoFilter::where_filter( RequestAttributes& att, int filter_flag, diff --git a/src/zone/SConstruct b/src/zone/SConstruct new file mode 100644 index 0000000000..d646c1953e --- /dev/null +++ b/src/zone/SConstruct @@ -0,0 +1,30 @@ +# SConstruct for src/zone + +# -------------------------------------------------------------------------- # +# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# 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_zone' + +# Sources to generate the library +source_files=[ + 'ZonePool.cc', + 'Zone.cc' +] + +# Build library +env.StaticLibrary(lib_name, source_files) diff --git a/src/zone/Zone.cc b/src/zone/Zone.cc new file mode 100644 index 0000000000..3b687cd62d --- /dev/null +++ b/src/zone/Zone.cc @@ -0,0 +1,236 @@ +/* ------------------------------------------------------------------------ */ +/* Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs */ +/* */ +/* 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 "Zone.h" + +/* ------------------------------------------------------------------------ */ + +const char * Zone::table = "zone_pool"; + +const char * Zone::db_names = + "oid, name, body, uid, gid, owner_u, group_u, other_u"; + +const char * Zone::db_bootstrap = "CREATE TABLE IF NOT EXISTS zone_pool (" + "oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, " + "gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, " + "UNIQUE(name))"; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +Zone::Zone(int id, Template* zone_template): + PoolObjectSQL(id, ZONE, "", -1, -1, "", "", table) +{ + if (zone_template != 0) + { + obj_template = zone_template; + } + else + { + obj_template = new Template; + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +Zone::~Zone() +{ + delete obj_template; +}; + +/* ************************************************************************ */ +/* Zone :: Database Access Functions */ +/* ************************************************************************ */ + +int Zone::insert(SqlDB *db, string& error_str) +{ + int rc; + ostringstream oss; + + // --------------------------------------------------------------------- + // Check default attributes + // --------------------------------------------------------------------- + + erase_template_attribute("NAME", name); + + if ( name.empty() ) + { + oss << "zone-" << oid; + name = oss.str(); + } + + // ------------------------------------------------------------------------ + // Insert the Zone + // ------------------------------------------------------------------------ + + rc = insert_replace(db, false, error_str); + + return rc; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int Zone::insert_replace(SqlDB *db, bool replace, string& error_str) +{ + ostringstream oss; + + int rc; + string xml_body; + + char * sql_name; + char * sql_xml; + + // Set oneadmin as the owner and group it belongs to + set_user(0,""); + set_group(0,""); + + // Update the zone + + 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 ( validate_xml(sql_xml) != 0 ) + { + goto error_xml; + } + + 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_xml: + db->free_str(sql_name); + db->free_str(sql_xml); + + error_str = "Error transforming the Zone to XML."; + + goto error_common; + +error_body: + db->free_str(sql_name); + goto error_generic; + +error_name: + goto error_generic; + +error_generic: + error_str = "Error inserting Zone in DB."; +error_common: + return -1; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +string& Zone::to_xml(string& xml) const +{ + ostringstream oss; + string template_xml; + + oss << + "" << + "" << oid << "" << + "" << name << "" << + obj_template->to_xml(template_xml) << + ""; + + xml = oss.str(); + + return xml; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +int Zone::from_xml(const string& xml) +{ + vector content; + int rc = 0; + + // Initialize the internal XML object + update_from_str(xml); + + // Get class base attributes + rc += xpath(oid, "/ZONE/ID", -1); + rc += xpath(name,"/ZONE/NAME", "not_found"); + + // Get associated classes + ObjectXML::get_nodes("/ZONE/TEMPLATE", content); + + if (content.empty()) + { + return -1; + } + + // Template contents + rc += obj_template->from_xml_node(content[0]); + + ObjectXML::free_nodes(content); + content.clear(); + + if (rc != 0) + { + return -1; + } + + // Set oneadmin as the owner and group it belongs to + set_user(0,""); + set_group(0,""); + + return 0; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + diff --git a/src/zone/ZonePool.cc b/src/zone/ZonePool.cc new file mode 100644 index 0000000000..5e971cf356 --- /dev/null +++ b/src/zone/ZonePool.cc @@ -0,0 +1,106 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs */ +/* */ +/* 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 "ZonePool.h" +#include "NebulaLog.h" + + +/* -------------------------------------------------------------------------- */ + +ZonePool::ZonePool(SqlDB * db) + :PoolSQL(db, Zone::table, true) +{ + if (get_lastOID() == -1) //lastOID is set in PoolSQL::init_cb + { + // The first 100 Zone IDs are reserved for system Zones. + // Regular ones start from ID 100 + + set_update_lastOID(99); + } + + return; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int ZonePool::allocate( + Template * zone_template, + int * oid, + string& error_str) +{ + Zone * zone; + Zone * zone_aux = 0; + + string name; + + ostringstream oss; + + zone = new Zone(-1, zone_template); + + // ------------------------------------------------------------------------- + // Check name & duplicates + // ------------------------------------------------------------------------- + + zone->get_template_attribute("NAME", name); + + if ( !PoolObjectSQL::name_is_valid(name, error_str) ) + { + goto error_name; + } + + zone_aux = get(name,false); + + if( zone_aux != 0 ) + { + goto error_duplicated; + } + + *oid = PoolSQL::allocate(zone, error_str); + + return *oid; + +error_duplicated: + oss << "NAME is already taken by Zone " << zone_aux->get_oid() << "."; + error_str = oss.str(); + +error_name: + delete zone; + *oid = -1; + + return *oid; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int ZonePool::drop(PoolObjectSQL * objsql, string& error_msg) +{ + Zone * zone = static_cast(objsql); + + // Return error if the zone is a default one. + if( zone->get_oid() < 100 ) + { + error_msg = "System Zones (ID < 100) cannot be deleted."; + NebulaLog::log("ZONE", Log::ERROR, error_msg); + return -2; + } + + return PoolSQL::drop(objsql, error_msg); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */