From 9ec4b450a44d46fbbeb8ff63bec018efc6db0870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 9 Feb 2012 17:56:47 +0100 Subject: [PATCH 001/217] Feature #1112: Create Datastore and DatastorePool classes, and RM methods --- SConstruct | 3 + include/Datastore.h | 138 ++++++++++++++++++ include/DatastorePool.h | 146 +++++++++++++++++++ include/GroupPool.h | 2 +- include/Nebula.h | 7 + include/PoolObjectSQL.h | 17 +-- include/RequestManagerAllocate.h | 26 ++++ include/RequestManagerDelete.h | 18 +++ include/RequestManagerInfo.h | 18 +++ include/RequestManagerPoolInfoFilter.h | 24 ++++ src/datastore/Datastore.cc | 190 +++++++++++++++++++++++++ src/datastore/DatastorePool.cc | 103 ++++++++++++++ src/datastore/SConstruct | 30 ++++ src/host/HostPool.cc | 2 +- src/nebula/Nebula.cc | 2 + src/nebula/SConstruct | 1 + src/rm/RequestManager.cc | 14 +- src/rm/RequestManagerAllocate.cc | 16 +++ src/rm/RequestManagerPoolInfoFilter.cc | 10 ++ 19 files changed, 755 insertions(+), 12 deletions(-) create mode 100644 include/Datastore.h create mode 100644 include/DatastorePool.h create mode 100644 src/datastore/Datastore.cc create mode 100644 src/datastore/DatastorePool.cc create mode 100644 src/datastore/SConstruct diff --git a/SConstruct b/SConstruct index da427b948c..468d96285f 100644 --- a/SConstruct +++ b/SConstruct @@ -57,6 +57,7 @@ main_env.Append(LIBPATH=[ cwd+'/src/log', cwd+'/src/sql', cwd+'/src/host', + cwd+'/src/datastore', cwd+'/src/group', cwd+'/src/mad', cwd+'/src/nebula', @@ -187,6 +188,7 @@ build_scripts=[ 'src/common/SConstruct', 'src/template/SConstruct', 'src/host/SConstruct', + 'src/datastore/SConstruct', 'src/group/SConstruct', 'src/mad/SConstruct', 'src/mad/utils/SConstruct', @@ -236,6 +238,7 @@ if testing=='yes': 'src/authm/test/SConstruct', 'src/common/test/SConstruct', 'src/host/test/SConstruct', + 'src/datastore/test/SConstruct', 'src/group/test/SConstruct', 'src/image/test/SConstruct', 'src/lcm/test/SConstruct', diff --git a/include/Datastore.h b/include/Datastore.h new file mode 100644 index 0000000000..17c2c13623 --- /dev/null +++ b/include/Datastore.h @@ -0,0 +1,138 @@ +/* ------------------------------------------------------------------------ */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------*/ + +#ifndef DATASTORE_H_ +#define DATASTORE_H_ + +#include "PoolSQL.h" +#include "ObjectCollection.h" +//#include "Image.h" + +//using namespace std; + +/** + * The Datastore class. + */ +class Datastore : public PoolObjectSQL, ObjectCollection +{ +public: + + /** + * Function to print the Datastore 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); + + /** + * Adds this image's ID to the set. + * @param id of the image to be added to the Datastore + * @return 0 on success + */ + int add_image(int id) + { + return add_collection_id(id); + } + + /** + * Deletes this image's ID from the set. + * @param id of the image to be deleted from the Datastore + * @return 0 on success + */ + int del_image(int id) + { + return del_collection_id(id); + } + +private: + + // ------------------------------------------------------------------------- + // Friends + // ------------------------------------------------------------------------- + + friend class DatastorePool; + + // ************************************************************************* + // Constructor + // ************************************************************************* + + Datastore(int id, const string& name): + PoolObjectSQL(id,DATASTORE,name,-1,-1,"","",table), + ObjectCollection("IMAGES"){}; + + virtual ~Datastore(){}; + + // ************************************************************************* + // 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 Datastore + * @return 0 on success + */ + static int bootstrap(SqlDB * db) + { + ostringstream oss(Datastore::db_bootstrap); + + return db->exec(oss); + }; + + /** + * Writes the Datastore in the database. + * @param db pointer to the db + * @return 0 on success + */ + int insert(SqlDB *db, string& error_str) + { + return insert_replace(db, false, error_str); + } + + /** + * Writes/updates the Datastore'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 /*DATASTORE_H_*/ diff --git a/include/DatastorePool.h b/include/DatastorePool.h new file mode 100644 index 0000000000..c6f0a97d55 --- /dev/null +++ b/include/DatastorePool.h @@ -0,0 +1,146 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#ifndef DATASTORE_POOL_H_ +#define DATASTORE_POOL_H_ + +#include "Datastore.h" +#include "SqlDB.h" + +using namespace std; + + +class DatastorePool : public PoolSQL +{ +public: + DatastorePool(SqlDB * db):PoolSQL(db, Datastore::table){}; + + ~DatastorePool(){}; + + /* ---------------------------------------------------------------------- */ + /* Constants for DB management */ + /* ---------------------------------------------------------------------- */ + + /* ---------------------------------------------------------------------- */ + /* Methods for DB management */ + /* ---------------------------------------------------------------------- */ + + /** + * Allocates a new Datastore, writing it in the pool database. No memory is + * allocated for the object. + * @param name Datastore name + * @param oid the id assigned to the Datastore + * @param error_str Returns the error reason, if any + * + * @return the oid assigned to the object, -1 in case of failure + */ + int allocate(string name, + int * oid, + string& error_str); + + /** + * Function to get a Datastore from the pool, if the object is not in memory + * it is loaded from the DB + * @param oid Datastore unique id + * @param lock locks the Datastore mutex + * @return a pointer to the Datastore, 0 if the Datastore could not be loaded + */ + Datastore * 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 + */ + Datastore * 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 Datastores can't repeat names. + return name; + }; + + /** Update a particular Datastore + * @param user pointer to Datastore + * @return 0 on success + */ + int update(Datastore * datastore) + { + return datastore->update(db); + }; + + /** + * Drops the Datastore data in the data base. The object mutex SHOULD be + * locked. + * @param objsql a pointer to the Datastore object + * @param error_msg Error reason, if any + * @return 0 on success, -1 DB error + * -3 Datastore's Image IDs set is not empty + */ + int drop(PoolObjectSQL * objsql, string& error_msg); + + /** + * Bootstraps the database table(s) associated to the Datastore pool + * @return 0 on success + */ + static int bootstrap(SqlDB * _db) + { + return Datastore::bootstrap(_db); + }; + + /** + * Dumps the Datastore 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, "DATASTORE_POOL", Datastore::table, where); + }; + +private: + + /** + * Factory method to produce objects + * @return a pointer to the new object + */ + PoolObjectSQL * create() + { + return new Datastore(-1,""); + }; +}; + +#endif /*DATASTORE_POOL_H_*/ diff --git a/include/GroupPool.h b/include/GroupPool.h index 335a52c245..7de343cd1f 100644 --- a/include/GroupPool.h +++ b/include/GroupPool.h @@ -31,7 +31,7 @@ public: ~GroupPool(){}; /* ---------------------------------------------------------------------- */ - /* Constants r DB management */ + /* Constants for DB management */ /* ---------------------------------------------------------------------- */ /** diff --git a/include/Nebula.h b/include/Nebula.h index 876e405808..21068968db 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -27,6 +27,7 @@ #include "UserPool.h" #include "VMTemplatePool.h" #include "GroupPool.h" +#include "DatastorePool.h" #include "VirtualMachineManager.h" #include "LifeCycleManager.h" @@ -91,6 +92,11 @@ public: return tpool; }; + DatastorePool * get_dspool() + { + return dspool; + }; + // -------------------------------------------------------------- // Manager Accessors // -------------------------------------------------------------- @@ -421,6 +427,7 @@ private: ImagePool * ipool; GroupPool * gpool; VMTemplatePool * tpool; + DatastorePool * dspool; // --------------------------------------------------------------- // Nebula Managers diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h index 7829f0c4e6..2fb73c73a5 100644 --- a/include/PoolObjectSQL.h +++ b/include/PoolObjectSQL.h @@ -49,14 +49,15 @@ public: */ enum ObjectType { - VM = 0x0000001000000000LL, - HOST = 0x0000002000000000LL, - NET = 0x0000004000000000LL, - IMAGE = 0x0000008000000000LL, - USER = 0x0000010000000000LL, - TEMPLATE = 0x0000020000000000LL, - GROUP = 0x0000040000000000LL, - ACL = 0x0000080000000000LL + VM = 0x0000001000000000LL, + HOST = 0x0000002000000000LL, + NET = 0x0000004000000000LL, + IMAGE = 0x0000008000000000LL, + USER = 0x0000010000000000LL, + TEMPLATE = 0x0000020000000000LL, + GROUP = 0x0000040000000000LL, + ACL = 0x0000080000000000LL, + DATASTORE = 0x0000100000000000LL }; static string type_to_str(ObjectType ob) diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index 446562b5d3..cdeaf0bc29 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -279,6 +279,32 @@ public: RequestAttributes& att); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class DatastoreAllocate: public RequestManagerAllocate +{ +public: + DatastoreAllocate(): + RequestManagerAllocate("DatastoreAllocate", + "Allocates a new Datastore", + "A:ss", + false) + { + Nebula& nd = Nebula::instance(); + pool = nd.get_dspool(); + auth_object = PoolObjectSQL::DATASTORE; + }; + + ~DatastoreAllocate(){}; + + int pool_allocate(xmlrpc_c::paramList const& _paramList, + Template * tmpl, + int& id, + string& error_str, + RequestAttributes& att); +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerDelete.h b/include/RequestManagerDelete.h index 9162c26a30..1c7c1e1912 100644 --- a/include/RequestManagerDelete.h +++ b/include/RequestManagerDelete.h @@ -178,6 +178,24 @@ public: int drop(int oid, PoolObjectSQL * object, string& error_msg); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class DatastoreDelete: public RequestManagerDelete +{ +public: + DatastoreDelete(): + RequestManagerDelete("DatastoreDelete", "Deletes a datastore") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_upool(); + auth_object = PoolObjectSQL::DATASTORE; + auth_op = AuthRequest::ADMIN; + }; + + ~DatastoreDelete(){}; +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerInfo.h b/include/RequestManagerInfo.h index 6dbc8e8622..316c03e3a3 100644 --- a/include/RequestManagerInfo.h +++ b/include/RequestManagerInfo.h @@ -196,6 +196,24 @@ public: ~UserInfo(){}; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class DatastoreInfo: public RequestManagerInfo +{ +public: + DatastoreInfo(): + RequestManagerInfo("UserInfo", + "Returns datastore information") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_dspool(); + auth_object = PoolObjectSQL::DATASTORE; + }; + + ~DatastoreInfo(){}; +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerPoolInfoFilter.h b/include/RequestManagerPoolInfoFilter.h index 38932edad5..d3fb8980c7 100644 --- a/include/RequestManagerPoolInfoFilter.h +++ b/include/RequestManagerPoolInfoFilter.h @@ -224,6 +224,30 @@ public: xmlrpc_c::paramList const& paramList, RequestAttributes& att); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class DatastorePoolInfo: public RequestManagerPoolInfoFilter +{ +public: + DatastorePoolInfo(): + RequestManagerPoolInfoFilter("DatastorePoolInfo", + "Returns the datastore pool", + "A:s") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_dspool(); + auth_object = PoolObjectSQL::DATASTORE; + }; + + ~DatastorePoolInfo(){}; + + /* -------------------------------------------------------------------- */ + + void request_execute( + xmlrpc_c::paramList const& paramList, RequestAttributes& att); +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc new file mode 100644 index 0000000000..304abf2335 --- /dev/null +++ b/src/datastore/Datastore.cc @@ -0,0 +1,190 @@ +/* ------------------------------------------------------------------------ */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* ------------------------------------------------------------------------ */ + +#include +#include + +#include +#include + +#include "Datastore.h" +#include "GroupPool.h" + +const char * Datastore::table = "datastore_pool"; + +const char * Datastore::db_names = + "oid, name, body, uid, gid, owner_u, group_u, other_u"; + +const char * Datastore::db_bootstrap = + "CREATE TABLE IF NOT EXISTS datastore_pool (" + "oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, " + "gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, " + "UNIQUE(name))"; + +/* ************************************************************************ */ +/* Datastore :: Database Access Functions */ +/* ************************************************************************ */ + +int Datastore::insert_replace(SqlDB *db, bool replace, string& error_str) +{ + ostringstream oss; + + int rc; + string xml_body; + + char * sql_name; + char * sql_xml; + + // Set the owner and group to oneadmin + set_user(0, ""); + set_group(GroupPool::ONEADMIN_ID, GroupPool::ONEADMIN_NAME); + + // Update the Datastore + + 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 Datastore 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 Datastore in DB."; +error_common: + return -1; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +string& Datastore::to_xml(string& xml) const +{ + ostringstream oss; + string collection_xml; + + ObjectCollection::to_xml(collection_xml); + + oss << + "" << + "" << oid << "" << + "" << name << "" << + collection_xml << + ""; + + xml = oss.str(); + + return xml; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +int Datastore::from_xml(const string& xml) +{ + int rc = 0; + vector content; + + // Initialize the internal XML object + update_from_str(xml); + + // Get class base attributes + rc += xpath(oid, "/DATASTORE/ID", -1); + rc += xpath(name,"/DATASTORE/NAME", "not_found"); + + // Set the owner and group to oneadmin + set_user(0, ""); + set_group(GroupPool::ONEADMIN_ID, GroupPool::ONEADMIN_NAME); + + // Get associated classes + ObjectXML::get_nodes("/DATASTORE/IMAGES", content); + + if (content.empty()) + { + return -1; + } + + // Set of IDs + rc += ObjectCollection::from_xml_node(content[0]); + + ObjectXML::free_nodes(content); + + if (rc != 0) + { + return -1; + } + + return 0; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc new file mode 100644 index 0000000000..fdd05d3cf1 --- /dev/null +++ b/src/datastore/DatastorePool.cc @@ -0,0 +1,103 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#include "DatastorePool.h" +#include "Nebula.h" +#include "NebulaLog.h" + +#include + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int DatastorePool::allocate(string name, int * oid, string& error_str) +{ + Datastore * datastore; + ostringstream oss; + + if ( name.empty() ) + { + goto error_name; + } + + if ( name.length() > 128 ) + { + goto error_name_length; + } + + // Check for duplicates + datastore = get(name, false); + + if( datastore != 0 ) + { + goto error_duplicated; + } + + // Build a new Datastore object + datastore = new Datastore(-1, name); + + // Insert the Object in the pool + *oid = PoolSQL::allocate(datastore, error_str); + + return *oid; + +error_name: + oss << "NAME cannot be empty."; + goto error_common; + +error_name_length: + oss << "NAME is too long; max length is 128 chars."; + goto error_common; + +error_duplicated: + oss << "NAME is already taken by DATASTORE " << datastore->get_oid() << "."; + +error_common: + *oid = -1; + error_str = oss.str(); + + return *oid; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int DatastorePool::drop(PoolObjectSQL * objsql, string& error_msg) +{ + Datastore * datastore = static_cast(objsql); + + int rc; + + if( datastore->get_collection_size() > 0 ) + { + ostringstream oss; + oss << "Datastore " << datastore->get_oid() << " is not empty."; + error_msg = oss.str(); + NebulaLog::log("DATASTORE", Log::ERROR, error_msg); + + return -3; + } + + rc = datastore->drop(db); + + if( rc != 0 ) + { + error_msg = "SQL DB error"; + rc = -1; + } + + return rc; +} diff --git a/src/datastore/SConstruct b/src/datastore/SConstruct new file mode 100644 index 0000000000..36514ca0b9 --- /dev/null +++ b/src/datastore/SConstruct @@ -0,0 +1,30 @@ +# SConstruct for src/datastore + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +Import('env') + +lib_name='nebula_datastore' + +# Sources to generate the library +source_files=[ + 'DatastorePool.cc', + 'Datastore.cc' +] + +# Build library +env.StaticLibrary(lib_name, source_files) diff --git a/src/host/HostPool.cc b/src/host/HostPool.cc index 75ba5c5109..689b93a075 100644 --- a/src/host/HostPool.cc +++ b/src/host/HostPool.cc @@ -35,7 +35,7 @@ HostPool::HostPool(SqlDB* db, const string& remotes_location) : PoolSQL(db,Host::table) { - // ------------------ Initialize Hooks fot the pool ---------------------- + // ------------------ Initialize Hooks for the pool ---------------------- const VectorAttribute * vattr; diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index 96523349dd..be7ed52f8d 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -311,6 +311,8 @@ void Nebula::start() img_restricted_attrs); tpool = new VMTemplatePool(db); + + dspool = new DatastorePool(db); } catch (exception&) { diff --git a/src/nebula/SConstruct b/src/nebula/SConstruct index 0f52378d2a..722376edaf 100644 --- a/src/nebula/SConstruct +++ b/src/nebula/SConstruct @@ -41,6 +41,7 @@ env.Prepend(LIBS=[ 'nebula_dm', 'nebula_tm', 'nebula_um', + 'nebula_datastore', 'nebula_group', 'nebula_authm', 'nebula_acl', diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index c0f2be8dce..8333a16ee5 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -263,6 +263,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr template_allocate(new TemplateAllocate()); xmlrpc_c::methodPtr host_allocate(new HostAllocate()); xmlrpc_c::methodPtr user_allocate(new UserAllocate()); + xmlrpc_c::methodPtr datastore_allocate(new DatastoreAllocate()); // Delete Methods xmlrpc_c::methodPtr host_delete(new HostDelete()); @@ -271,6 +272,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr vn_delete(new VirtualNetworkDelete()); xmlrpc_c::methodPtr user_delete(new UserDelete()); xmlrpc_c::methodPtr image_delete(new ImageDelete()); + xmlrpc_c::methodPtr datastore_delete(new DatastoreDelete()); // Info Methods xmlrpc_c::methodPtr vm_info(new VirtualMachineInfo()); @@ -280,13 +282,13 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr vn_info(new VirtualNetworkInfo()); xmlrpc_c::methodPtr user_info(new UserInfo()); xmlrpc_c::methodPtr image_info(new ImageInfo()); + xmlrpc_c::methodPtr datastore_info(new DatastoreInfo()); // PoolInfo Methods xmlrpc_c::methodPtr hostpool_info(new HostPoolInfo()); xmlrpc_c::methodPtr grouppool_info(new GroupPoolInfo()); xmlrpc_c::methodPtr userpool_info(new UserPoolInfo()); - - // PoolInfo Methods with Filtering + xmlrpc_c::methodPtr datastorepool_info(new DatastorePoolInfo()); xmlrpc_c::methodPtr vm_pool_info(new VirtualMachinePoolInfo()); xmlrpc_c::methodPtr template_pool_info(new TemplatePoolInfo()); xmlrpc_c::methodPtr vnpool_info(new VirtualNetworkPoolInfo()); @@ -399,6 +401,14 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.acl.addrule", acl_addrule); RequestManagerRegistry.addMethod("one.acl.delrule", acl_delrule); RequestManagerRegistry.addMethod("one.acl.info", acl_info); + + /* Datastore related methods */ + RequestManagerRegistry.addMethod("one.datastore.allocate",datastore_allocate); + RequestManagerRegistry.addMethod("one.datastore.delete", datastore_delete); + RequestManagerRegistry.addMethod("one.datastore.info", datastore_info); + + RequestManagerRegistry.addMethod("one.datastorepool.info",datastorepool_info); + }; /* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 051463f1dc..d4c8a71710 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -265,3 +265,19 @@ int GroupAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, return gpool->allocate(gname, &id, error_str); } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int DatastoreAllocate::pool_allocate( + xmlrpc_c::paramList const& paramList, + Template * tmpl, + int& id, + string& error_str, + RequestAttributes& att) +{ + string name = xmlrpc_c::value_string(paramList.getString(1)); + + DatastorePool * dspool = static_cast(pool); + + return dspool->allocate(name, &id, error_str); +} diff --git a/src/rm/RequestManagerPoolInfoFilter.cc b/src/rm/RequestManagerPoolInfoFilter.cc index c7f9897150..c3d432480b 100644 --- a/src/rm/RequestManagerPoolInfoFilter.cc +++ b/src/rm/RequestManagerPoolInfoFilter.cc @@ -121,6 +121,16 @@ void UserPoolInfo::request_execute( /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +void DatastorePoolInfo::request_execute( + xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + dump(att, ALL, -1, -1, "", ""); +} + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + void RequestManagerPoolInfoFilter::dump( RequestAttributes& att, int filter_flag, From 2531db2d7a19df8ec239dd47a6948b268e679542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 9 Feb 2012 18:55:18 +0100 Subject: [PATCH 002/217] Feature #1112: Ruby OCA and CLI for datastores --- install.sh | 13 ++- src/cli/etc/onedatastore.yaml | 14 ++++ src/cli/one_helper/onedatastore_helper.rb | 77 ++++++++++++++++++ src/cli/onedatastore | 98 ++++++++++++++++++++++ src/oca/ruby/OpenNebula.rb | 2 + src/oca/ruby/OpenNebula/Datastore.rb | 99 +++++++++++++++++++++++ src/oca/ruby/OpenNebula/DatastorePool.rb | 53 ++++++++++++ 7 files changed, 353 insertions(+), 3 deletions(-) create mode 100644 src/cli/etc/onedatastore.yaml create mode 100644 src/cli/one_helper/onedatastore_helper.rb create mode 100755 src/cli/onedatastore create mode 100644 src/oca/ruby/OpenNebula/Datastore.rb create mode 100644 src/oca/ruby/OpenNebula/DatastorePool.rb diff --git a/install.sh b/install.sh index 4dcf332d88..159fea7c0a 100755 --- a/install.sh +++ b/install.sh @@ -556,6 +556,7 @@ BIN_FILES="src/nebula/oned \ src/cli/onegroup \ src/cli/onetemplate \ src/cli/oneacl \ + src/cli/onedatastore \ src/onedb/onedb \ src/authm_mad/remotes/quota/onequota \ src/mad/utils/tty_expect \ @@ -945,6 +946,8 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/OpenNebula/Host.rb \ src/oca/ruby/OpenNebula/GroupPool.rb \ src/oca/ruby/OpenNebula/Acl.rb \ src/oca/ruby/OpenNebula/AclPool.rb \ + src/oca/ruby/OpenNebula/Datastore.rb \ + src/oca/ruby/OpenNebula/DatastorePool.rb \ src/oca/ruby/OpenNebula/XMLUtils.rb" #------------------------------------------------------------------------------- @@ -1049,7 +1052,8 @@ ONE_CLI_LIB_FILES="src/cli/one_helper/onegroup_helper.rb \ src/cli/one_helper/oneuser_helper.rb \ src/cli/one_helper/onevm_helper.rb \ src/cli/one_helper/onevnet_helper.rb \ - src/cli/one_helper/oneacl_helper.rb" + src/cli/one_helper/oneacl_helper.rb \ + src/cli/one_helper/onedatastore_helper.rb" CLI_BIN_FILES="src/cli/onevm \ src/cli/onehost \ @@ -1058,7 +1062,8 @@ CLI_BIN_FILES="src/cli/onevm \ src/cli/oneimage \ src/cli/onetemplate \ src/cli/onegroup \ - src/cli/oneacl" + src/cli/oneacl \ + src/cli/onedatastore" CLI_CONF_FILES="src/cli/etc/onegroup.yaml \ src/cli/etc/onehost.yaml \ @@ -1067,7 +1072,8 @@ CLI_CONF_FILES="src/cli/etc/onegroup.yaml \ src/cli/etc/oneuser.yaml \ src/cli/etc/onevm.yaml \ src/cli/etc/onevnet.yaml \ - src/cli/etc/oneacl.yaml" + src/cli/etc/oneacl.yaml \ + src/cli/etc/onedatastore.yaml" ETC_CLIENT_FILES="src/cli/etc/group.default" @@ -1401,6 +1407,7 @@ MAN_FILES="share/man/oneauth.1.gz \ share/man/onetemplate.1.gz \ share/man/onegroup.1.gz \ share/man/onedb.1.gz \ + share/man/onedatastore.1.gz \ share/man/econe-describe-images.1.gz \ share/man/econe-describe-instances.1.gz \ share/man/econe-register.1.gz \ diff --git a/src/cli/etc/onedatastore.yaml b/src/cli/etc/onedatastore.yaml new file mode 100644 index 0000000000..a012998163 --- /dev/null +++ b/src/cli/etc/onedatastore.yaml @@ -0,0 +1,14 @@ +--- +:ID: + :desc: ONE identifier for the Datastore + :size: 4 + +:NAME: + :desc: Name of the Datastore + :size: 15 + :left: true + +:default: +- :ID +- :NAME + diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb new file mode 100644 index 0000000000..b0f6602c6c --- /dev/null +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -0,0 +1,77 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +require 'one_helper' + +class OneDatastoreHelper < OpenNebulaHelper::OneHelper + def self.rname + "DATASTORE" + end + + def self.conf_file + "onedatastore.yaml" + end + + def format_pool(options) + config_file = self.class.table_conf + + table = CLIHelper::ShowTable.new(config_file, self) do + column :ID, "ONE identifier for the Datastore", :size=>4 do |d| + d["ID"] + end + + column :NAME, "Name of the Datastore", :left, :size=>15 do |d| + d["NAME"] + end + + default :ID, :NAME + end + + table + end + + private + + def factory(id=nil) + if id + OpenNebula::Datastore.new_with_id(id, @client) + else + xml=OpenNebula::Datastore.build_xml + OpenNebula::Datastore.new(xml, @client) + end + end + + def factory_pool(user_flag=-2) + #TBD OpenNebula::UserPool.new(@client, user_flag) + OpenNebula::DatastorePool.new(@client) + end + + def format_resource(datastore) + str="%-15s: %-20s" + str_h1="%-80s" + + CLIHelper.print_header(str_h1 % "DATASTORE #{datastore['ID']} INFORMATION") + puts str % ["ID", datastore.id.to_s] + puts str % ["NAME", datastore.name] + puts + + CLIHelper.print_header(str_h1 % "IMAGES", false) + CLIHelper.print_header("%-15s" % ["ID"]) + datastore.user_ids.each do |id| + puts "%-15s" % [id] + end + end +end diff --git a/src/cli/onedatastore b/src/cli/onedatastore new file mode 100755 index 0000000000..4dd8e648da --- /dev/null +++ b/src/cli/onedatastore @@ -0,0 +1,98 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +ONE_LOCATION=ENV["ONE_LOCATION"] + +if !ONE_LOCATION + RUBY_LIB_LOCATION="/usr/lib/one/ruby" +else + RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" +end + +$: << RUBY_LIB_LOCATION +$: << RUBY_LIB_LOCATION+"/cli" + +require 'command_parser' +require 'one_helper/onedatastore_helper' + +cmd=CommandParser::CmdParser.new(ARGV) do + usage "`onedatastore` [] []" + version OpenNebulaHelper::ONE_VERSION + + helper = OneDatastoreHelper.new + + ######################################################################## + # Global Options + ######################################################################## + set :option, CommandParser::OPTIONS + + list_options = CLIHelper::OPTIONS + list_options << OpenNebulaHelper::XML + list_options << OpenNebulaHelper::NUMERIC + + ######################################################################## + # Formatters for arguments + ######################################################################## + set :format, :datastoreid, OneDatastoreHelper.to_id_desc do |arg| + helper.to_id(arg) + end + + set :format, :datastoreid_list, OneDatastoreHelper.list_to_id_desc do |arg| + helper.list_to_id(arg) + end + + ######################################################################## + # Commands + ######################################################################## + + create_desc = <<-EOT.unindent + Creates a new Datastore + EOT + + command :create, create_desc, :name do + helper.create_resource(options) do |datastore| + datastore.allocate(args[0]) + end + end + + delete_desc = <<-EOT.unindent + Deletes the given Datastore + EOT + + command :delete, delete_desc, [:range, :datastoreid_list] do + helper.perform_actions(args[0],options,"deleted") do |obj| + obj.delete + end + end + + list_desc = <<-EOT.unindent + Lists Datastores in the pool + EOT + + command :list, list_desc, :options=>list_options do + helper.list_pool(options) + end + + show_desc = <<-EOT.unindent + Shows information for the given Datastore + EOT + + command :show, show_desc, :datastoreid, :options=>OpenNebulaHelper::XML do + helper.show_resource(args[0],options) + end +end diff --git a/src/oca/ruby/OpenNebula.rb b/src/oca/ruby/OpenNebula.rb index 6bb4a4916c..17f8f27aaa 100644 --- a/src/oca/ruby/OpenNebula.rb +++ b/src/oca/ruby/OpenNebula.rb @@ -42,6 +42,8 @@ require 'OpenNebula/Group' require 'OpenNebula/GroupPool' require 'OpenNebula/Acl' require 'OpenNebula/AclPool' +require 'OpenNebula/Datastore' +require 'OpenNebula/DatastorePool' module OpenNebula diff --git a/src/oca/ruby/OpenNebula/Datastore.rb b/src/oca/ruby/OpenNebula/Datastore.rb new file mode 100644 index 0000000000..a88a6b738b --- /dev/null +++ b/src/oca/ruby/OpenNebula/Datastore.rb @@ -0,0 +1,99 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + + +require 'OpenNebula/Pool' + +module OpenNebula + class Datastore < PoolElement + ####################################################################### + # Constants and Class Methods + ####################################################################### + + DATASTORE_METHODS = { + :info => "datastore.info", + :allocate => "datastore.allocate", + :delete => "datastore.delete" + } + + # Creates a Datastore description with just its identifier + # this method should be used to create plain Datastore objects. + # +id+ the id of the user + # + # Example: + # datastore = Datastore.new(Datastore.build_xml(3),rpc_client) + # + def Datastore.build_xml(pe_id=nil) + if pe_id + datastore_xml = "#{pe_id}" + else + datastore_xml = "" + end + + XMLElement.build_xml(datastore_xml,'DATASTORE') + end + + # Class constructor + def initialize(xml, client) + super(xml,client) + end + + ####################################################################### + # XML-RPC Methods for the Datastore Object + ####################################################################### + + # Retrieves the information of the given Datastore. + def info() + super(DATASTORE_METHODS[:info], 'DATASTORE') + end + + # Allocates a new Datastore in OpenNebula + # + # +datastorename+ A string containing the name of the Datastore. + def allocate(datastorename) + super(DATASTORE_METHODS[:allocate], datastorename) + end + + # Deletes the Datastore + def delete() + super(DATASTORE_METHODS[:delete]) + end + + # --------------------------------------------------------------------- + # Helpers to get information + # --------------------------------------------------------------------- + + # Returns whether or not the image with id 'id' is part of this datastore + def contains(id) + #This doesn't work in ruby 1.8.5 + #return self["DATASTORE/ID[.=#{uid}]"] != nil + + id_array = retrieve_elements('DATASTORE/ID') + return id_array != nil && id_array.include?(uid.to_s) + end + + # Returns an array with the numeric image ids + def user_ids + array = Array.new + + self.each("DATASTORE/ID") do |id| + array << id.text.to_i + end + + return array + end + end +end diff --git a/src/oca/ruby/OpenNebula/DatastorePool.rb b/src/oca/ruby/OpenNebula/DatastorePool.rb new file mode 100644 index 0000000000..b491d394fe --- /dev/null +++ b/src/oca/ruby/OpenNebula/DatastorePool.rb @@ -0,0 +1,53 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + + +require 'OpenNebula/Pool' + +module OpenNebula + class DatastorePool < Pool + ####################################################################### + # Constants and Class attribute accessors + ####################################################################### + + DATASTORE_POOL_METHODS = { + :info => "datastorepool.info" + } + + ####################################################################### + # Class constructor & Pool Methods + ####################################################################### + + # +client+ a Client object that represents a XML-RPC connection + def initialize(client) + super('DATASTORE_POOL','DATASTORE',client) + end + + # Factory method to create User objects + def factory(element_xml) + OpenNebula::Group.new(element_xml,@client) + end + + ####################################################################### + # XML-RPC Methods for the User Object + ####################################################################### + + # Retrieves all the Groups in the pool. + def info() + super(DATASTORE_POOL_METHODS[:info]) + end + end +end From 1d8d821d0476656525cfbab09d8a07588a9ea64b Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 10 Feb 2012 00:51:26 +0100 Subject: [PATCH 003/217] feature #1112: Change xml-rpc method name --- include/RequestManagerInfo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/RequestManagerInfo.h b/include/RequestManagerInfo.h index 316c03e3a3..6975f99039 100644 --- a/include/RequestManagerInfo.h +++ b/include/RequestManagerInfo.h @@ -203,7 +203,7 @@ class DatastoreInfo: public RequestManagerInfo { public: DatastoreInfo(): - RequestManagerInfo("UserInfo", + RequestManagerInfo("DatastoreInfo", "Returns datastore information") { Nebula& nd = Nebula::instance(); From 69e9192a980f78795b576ec7e090534257e54bed Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 10 Feb 2012 01:18:46 +0100 Subject: [PATCH 004/217] feature-1112: Delete dspool when destoying the Nebula class --- include/Nebula.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/Nebula.h b/include/Nebula.h index 21068968db..03a928b498 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -329,6 +329,11 @@ private: delete tpool; } + if ( dspool != 0) + { + delete tpool; + } + if ( vmm != 0) { delete vmm; From 2762ed5a62aa7a8a8ec9c7cee9a4cef6bf6758d2 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 10 Feb 2012 01:19:49 +0100 Subject: [PATCH 005/217] feature #1112: Fix compilation of tests --- src/authm/test/SConstruct | 1 + src/group/test/SConstruct | 1 + src/host/test/SConstruct | 1 + src/image/test/SConstruct | 1 + src/lcm/test/SConstruct | 1 + src/um/test/SConstruct | 1 + src/vnm/test/SConstruct | 1 + 7 files changed, 7 insertions(+) diff --git a/src/authm/test/SConstruct b/src/authm/test/SConstruct index 390ef37324..991d6585a5 100644 --- a/src/authm/test/SConstruct +++ b/src/authm/test/SConstruct @@ -22,6 +22,7 @@ env.Prepend(LIBS=[ 'nebula_im', 'nebula_hm', 'nebula_rm', + 'nebula_datastore', 'nebula_dm', 'nebula_tm', 'nebula_um', diff --git a/src/group/test/SConstruct b/src/group/test/SConstruct index a953bac660..0c87811f1b 100644 --- a/src/group/test/SConstruct +++ b/src/group/test/SConstruct @@ -23,6 +23,7 @@ env.Prepend(LIBS=[ 'nebula_im', 'nebula_hm', 'nebula_rm', + 'nebula_datastore', 'nebula_dm', 'nebula_tm', 'nebula_um', diff --git a/src/host/test/SConstruct b/src/host/test/SConstruct index 86fda21c95..1774ad750b 100644 --- a/src/host/test/SConstruct +++ b/src/host/test/SConstruct @@ -26,6 +26,7 @@ env.Prepend(LIBS=[ 'nebula_im', 'nebula_hm', 'nebula_rm', + 'nebula_datastore', 'nebula_dm', 'nebula_tm', 'nebula_um', diff --git a/src/image/test/SConstruct b/src/image/test/SConstruct index 7c8883a3ee..f52fdc7afa 100644 --- a/src/image/test/SConstruct +++ b/src/image/test/SConstruct @@ -23,6 +23,7 @@ env.Prepend(LIBS=[ 'nebula_im', 'nebula_hm', 'nebula_rm', + 'nebula_datastore', 'nebula_dm', 'nebula_tm', 'nebula_um', diff --git a/src/lcm/test/SConstruct b/src/lcm/test/SConstruct index e222b0002f..85491401e3 100644 --- a/src/lcm/test/SConstruct +++ b/src/lcm/test/SConstruct @@ -25,6 +25,7 @@ env.Prepend(LIBS=[ 'nebula_im', 'nebula_hm', 'nebula_rm', + 'nebula_datastore', 'nebula_dm', 'nebula_tm', 'nebula_um', diff --git a/src/um/test/SConstruct b/src/um/test/SConstruct index e35ea02570..371e074bc7 100644 --- a/src/um/test/SConstruct +++ b/src/um/test/SConstruct @@ -23,6 +23,7 @@ env.Prepend(LIBS=[ 'nebula_im', 'nebula_hm', 'nebula_rm', + 'nebula_datastore', 'nebula_dm', 'nebula_tm', 'nebula_um', diff --git a/src/vnm/test/SConstruct b/src/vnm/test/SConstruct index 8aac83869b..505a1e559a 100644 --- a/src/vnm/test/SConstruct +++ b/src/vnm/test/SConstruct @@ -23,6 +23,7 @@ env.Prepend(LIBS=[ 'nebula_im', 'nebula_hm', 'nebula_rm', + 'nebula_datastore', 'nebula_dm', 'nebula_tm', 'nebula_um', From e73ef59fc16c5b403e78fde28135806efee6949e Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 10 Feb 2012 01:20:08 +0100 Subject: [PATCH 006/217] feature #1112: Fix compilation warining in tests --- src/group/test/GroupPoolTest.cc | 4 ++-- src/host/test/HostPoolTest.cc | 4 ++-- src/um/test/UserPoolTest.cc | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/group/test/GroupPoolTest.cc b/src/group/test/GroupPoolTest.cc index a96a1c7d56..68bf2da767 100644 --- a/src/group/test/GroupPoolTest.cc +++ b/src/group/test/GroupPoolTest.cc @@ -231,7 +231,7 @@ public: { Group *group_oid, *group_name; int oid_0; - int uid_0; + //int uid_0; string name_0; oid_0 = allocate(0); @@ -244,7 +244,7 @@ public: CPPUNIT_ASSERT(group_oid != 0); name_0 = group_oid->get_name(); - uid_0 = group_oid->get_uid(); + //uid_0 = group_oid->get_uid(); group_oid->unlock(); diff --git a/src/host/test/HostPoolTest.cc b/src/host/test/HostPoolTest.cc index dbc4a0b419..43ce2a679b 100644 --- a/src/host/test/HostPoolTest.cc +++ b/src/host/test/HostPoolTest.cc @@ -501,7 +501,7 @@ public: HostPool * hp = static_cast(pool); Host *host_oid, *host_name; int oid_0; - int uid_0; + //int uid_0; string name_0; oid_0 = allocate(0); @@ -514,7 +514,7 @@ public: CPPUNIT_ASSERT(host_oid != 0); name_0 = host_oid->get_name(); - uid_0 = host_oid->get_uid(); + //uid_0 = host_oid->get_uid(); host_oid->unlock(); diff --git a/src/um/test/UserPoolTest.cc b/src/um/test/UserPoolTest.cc index fd111fcd4a..8ed333ebfd 100644 --- a/src/um/test/UserPoolTest.cc +++ b/src/um/test/UserPoolTest.cc @@ -380,7 +380,7 @@ public: { User *user_oid, *user_name; int oid_0; - int uid_0; + //int uid_0; string name_0; oid_0 = allocate(0); @@ -393,7 +393,7 @@ public: CPPUNIT_ASSERT(user_oid != 0); name_0 = user_oid->get_name(); - uid_0 = user_oid->get_uid(); + //uid_0 = user_oid->get_uid(); user_oid->unlock(); From 354ef28985be73e0c3d46ae680ec1a08f0ccc46e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 10 Feb 2012 13:24:52 +0100 Subject: [PATCH 007/217] Feature #1112: Continue integration of DatastorePool in Nebula class --- include/Nebula.h | 4 ++-- src/nebula/Nebula.cc | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/Nebula.h b/include/Nebula.h index 03a928b498..a1c7cba6d6 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -260,7 +260,7 @@ private: // ----------------------------------------------------------------------- Nebula():nebula_configuration(0),db(0),vmpool(0),hpool(0),vnpool(0), - upool(0),ipool(0),gpool(0),tpool(0),lcm(0),vmm(0),im(0),tm(0), + upool(0),ipool(0),gpool(0),tpool(0),dspool(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"); @@ -331,7 +331,7 @@ private: if ( dspool != 0) { - delete tpool; + delete dspool; } if ( vmm != 0) diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index be7ed52f8d..bb2f1f6ebc 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -248,6 +248,7 @@ void Nebula::start() rc += ImagePool::bootstrap(db); rc += VMTemplatePool::bootstrap(db); rc += AclManager::bootstrap(db); + rc += DatastorePool::bootstrap(db); // Create the versioning table only if bootstrap went well if ( rc == 0 ) From b495e868b3fda65a7b758e1df0aee97c7ed86922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 10 Feb 2012 13:27:26 +0100 Subject: [PATCH 008/217] Feature #1112: Fix one.datastore.delete --- include/RequestManagerDelete.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/RequestManagerDelete.h b/include/RequestManagerDelete.h index 1c7c1e1912..b97b9b3f6d 100644 --- a/include/RequestManagerDelete.h +++ b/include/RequestManagerDelete.h @@ -188,7 +188,7 @@ public: RequestManagerDelete("DatastoreDelete", "Deletes a datastore") { Nebula& nd = Nebula::instance(); - pool = nd.get_upool(); + pool = nd.get_dspool(); auth_object = PoolObjectSQL::DATASTORE; auth_op = AuthRequest::ADMIN; }; From e76e1227d362d79e5043cdcad14e8d0c25a6b046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 10 Feb 2012 14:55:29 +0100 Subject: [PATCH 009/217] Feature #1112: Add datastore to ObjectType strings --- include/PoolObjectSQL.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h index 2fb73c73a5..d4e83fcf42 100644 --- a/include/PoolObjectSQL.h +++ b/include/PoolObjectSQL.h @@ -64,15 +64,16 @@ public: { switch (ob) { - case VM: return "VM" ; break; - case HOST: return "HOST" ; break; - case NET: return "NET" ; break; - case IMAGE: return "IMAGE" ; break; - case USER: return "USER" ; break; - case TEMPLATE: return "TEMPLATE" ; break; - case GROUP: return "GROUP" ; break; - case ACL: return "ACL" ; break; - default: return ""; + case VM: return "VM" ; break; + case HOST: return "HOST" ; break; + case NET: return "NET" ; break; + case IMAGE: return "IMAGE" ; break; + case USER: return "USER" ; break; + case TEMPLATE: return "TEMPLATE" ; break; + case GROUP: return "GROUP" ; break; + case ACL: return "ACL" ; break; + case DATASTORE: return "DATASTORE" ; break; + default: return ""; } }; From bab1573f316ba3d74bf9f652de531d9daeb0857c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 10 Feb 2012 19:01:20 +0100 Subject: [PATCH 010/217] Feature #1112: Fix onedatastore show output --- src/cli/one_helper/onedatastore_helper.rb | 2 +- src/oca/ruby/OpenNebula/Datastore.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index b0f6602c6c..4c642e818b 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -70,7 +70,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper CLIHelper.print_header(str_h1 % "IMAGES", false) CLIHelper.print_header("%-15s" % ["ID"]) - datastore.user_ids.each do |id| + datastore.img_ids.each do |id| puts "%-15s" % [id] end end diff --git a/src/oca/ruby/OpenNebula/Datastore.rb b/src/oca/ruby/OpenNebula/Datastore.rb index a88a6b738b..75329f32af 100644 --- a/src/oca/ruby/OpenNebula/Datastore.rb +++ b/src/oca/ruby/OpenNebula/Datastore.rb @@ -86,10 +86,10 @@ module OpenNebula end # Returns an array with the numeric image ids - def user_ids + def img_ids array = Array.new - self.each("DATASTORE/ID") do |id| + self.each("IMAGES/ID") do |id| array << id.text.to_i end From e9d026e3ae3e99b7cf7890d887d19ed696c0c645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 10 Feb 2012 19:28:18 +0100 Subject: [PATCH 011/217] Feature #1112: WIP associate Images to Datastores --- include/Image.h | 18 ++++++++++++ src/image/Image.cc | 21 +++++++++++++- src/image/ImageManagerActions.cc | 48 ++++++++++++++++++++++++++++++++ src/image/ImagePool.cc | 31 +++++++++++++++++++++ 4 files changed, 117 insertions(+), 1 deletion(-) diff --git a/include/Image.h b/include/Image.h index 61c7055286..d700cb0c8f 100644 --- a/include/Image.h +++ b/include/Image.h @@ -296,6 +296,14 @@ public: return new ImageTemplate; } + /** + * Returns the Datastore ID + */ + int get_ds_id() + { + return ds_id; + }; + private: // ------------------------------------------------------------------------- @@ -353,6 +361,16 @@ private: */ int running_vms; + /** + * Datastore ID + */ + int ds_id; + + /** + * Datastore name + */ + string ds_name; + // ************************************************************************* // DataBase implementation (Private) // ************************************************************************* diff --git a/src/image/Image.cc b/src/image/Image.cc index 181300ce56..5b1cc75056 100644 --- a/src/image/Image.cc +++ b/src/image/Image.cc @@ -47,7 +47,9 @@ Image::Image(int _uid, fs_type(""), size_mb(0), state(INIT), - running_vms(0) + running_vms(0), + ds_id(-1), + ds_name("") { if (_image_template != 0) { @@ -91,11 +93,14 @@ int Image::insert(SqlDB *db, string& error_str) string path_attr; string type_att; string persistent_attr; + string datastore_attr; string dev_prefix; string source_attr; string aname; ostringstream oss; + istringstream iss; + string ds_id_str; // ------------------------------------------------------------------------ // Check template for restricted attributes @@ -133,6 +138,15 @@ int Image::insert(SqlDB *db, string& error_str) goto error_type; } + // ------------ DATASTORE -------------------- + + erase_template_attribute("DATASTORE_ID", ds_id_str); + + iss.str(ds_id_str); + iss >> ds_id; + + erase_template_attribute("DATASTORE", ds_name); + // ------------ PERSISTENT -------------------- erase_template_attribute("PERSISTENT", persistent_attr); @@ -352,6 +366,8 @@ string& Image::to_xml(string& xml) const "" << size_mb << "" << "" << state << "" << "" << running_vms << "" << + "" << ds_id << ""<< + "" << ds_name << "" << obj_template->to_xml(template_xml) << ""; @@ -393,6 +409,9 @@ int Image::from_xml(const string& xml) rc += xpath(int_state, "/IMAGE/STATE", 0); rc += xpath(running_vms, "/IMAGE/RUNNING_VMS", -1); + rc += xpath(ds_id, "/IMAGE/DATASTORE_ID", -1); + rc += xpath(ds_name,"/IMAGE/DATASTORE", "not_found"); + // Permissions rc += perms_from_xml(); diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index 99e3c61dfb..5166e18e89 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -17,6 +17,8 @@ #include "ImageManager.h" #include "NebulaLog.h" #include "ImagePool.h" +#include "DatastorePool.h" +#include "Nebula.h" /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -370,8 +372,25 @@ int ImageManager::delete_image(int iid) imd->rm(img->get_oid(),img->get_source()); } + int ds_id = img->get_ds_id(); img->unlock(); + + Datastore * ds; + DatastorePool * dspool; + Nebula& nd = Nebula::instance(); + + dspool = nd.get_dspool(); + ds = dspool->get(ds_id, true); + + // TODO check ds != 0 + + ds->del_image(iid); + + dspool->update(ds); + + ds->unlock(); + return 0; } @@ -393,6 +412,35 @@ int ImageManager::register_image(int iid) return -1; } + img = ipool->get(iid,true); + + if (img == 0) + { + return -1; + } + + // Add the image to its datastore + int ds_id = img->get_ds_id(); + + img->unlock(); + + Datastore * ds; + DatastorePool * dspool; + Nebula& nd = Nebula::instance(); + + dspool = nd.get_dspool(); + ds = dspool->get(ds_id, true); + + // TODO check ds != 0 + + ds->add_image(iid); + + dspool->update(ds); + + ds->unlock(); + + + img = ipool->get(iid,true); if (img == 0) diff --git a/src/image/ImagePool.cc b/src/image/ImagePool.cc index 7e023b3868..410ba235ae 100644 --- a/src/image/ImagePool.cc +++ b/src/image/ImagePool.cc @@ -71,7 +71,12 @@ int ImagePool::allocate ( Image * img; Image * img_aux = 0; string name; + int ds_id; ostringstream oss; + Datastore * ds; + DatastorePool * dspool; + + Nebula& nd = Nebula::instance(); img = new Image(uid, gid, uname, gname, img_template); @@ -96,6 +101,32 @@ int ImagePool::allocate ( goto error_duplicated; } + // Check datastore exists + + // TODO: get datastore by name, and replace datastore name from it + + img->get_template_attribute("DATASTORE_ID", ds_id); + + // TODO how to check if "DATASTORE_ID" exists? + // get_template_attribute returns 0 if the attribute does not exist... + // but it can exist and have value 0 + if ( false ) + { + goto error_common; // TODO error + } + + dspool = nd.get_dspool(); + ds = dspool->get(ds_id, true); + + if( ds == 0 ) + { + goto error_common; // TODO error + } + + img->replace_template_attribute("DATASTORE", ds->get_name()); + + ds->unlock(); + // --------------------------------------------------------------------- // Insert the Object in the pool & Register the image in the repository // --------------------------------------------------------------------- From 45382e76b15aed503983cf79779279e5135bf967 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Mon, 13 Feb 2012 12:33:16 +0100 Subject: [PATCH 012/217] feature #1112: Initial changes in the Image driver to support multiple Datastores --- install.sh | 6 +-- share/etc/oned.conf | 2 +- src/image_mad/one_image.rb | 86 ++++++++++++++++++++++++++------------ 3 files changed, 63 insertions(+), 31 deletions(-) diff --git a/install.sh b/install.sh index 159fea7c0a..34e10d969d 100755 --- a/install.sh +++ b/install.sh @@ -235,8 +235,8 @@ VAR_DIRS="$VAR_LOCATION/remotes \ $VAR_LOCATION/remotes/vmm/vmware \ $VAR_LOCATION/remotes/hooks \ $VAR_LOCATION/remotes/hooks/ft \ - $VAR_LOCATION/remotes/image \ - $VAR_LOCATION/remotes/image/fs \ + $VAR_LOCATION/remotes/datastore \ + $VAR_LOCATION/remotes/datastore/fs \ $VAR_LOCATION/remotes/auth \ $VAR_LOCATION/remotes/auth/plain \ $VAR_LOCATION/remotes/auth/ssh \ @@ -385,7 +385,7 @@ INSTALL_FILES=( VMWARE_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/vmware DUMMY_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/dummy LVM_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/lvm - IMAGE_DRIVER_FS_SCRIPTS:$VAR_LOCATION/remotes/image/fs + IMAGE_DRIVER_FS_SCRIPTS:$VAR_LOCATION/remotes/datastore/fs NETWORK_FILES:$VAR_LOCATION/remotes/vnm NETWORK_8021Q_FILES:$VAR_LOCATION/remotes/vnm/802.1Q NETWORK_DUMMY_FILES:$VAR_LOCATION/remotes/vnm/dummy diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 88fd8c0b29..e89cf46340 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -338,7 +338,7 @@ TM_MAD = [ #------------------------------------------------------------------------------- IMAGE_MAD = [ executable = "one_image", - arguments = "fs -t 15" ] + arguments = "-t 15 -d fs" ] #------------------------------------------------------------------------------- #******************************************************************************* diff --git a/src/image_mad/one_image.rb b/src/image_mad/one_image.rb index 520b6e515c..b45a93df00 100755 --- a/src/image_mad/one_image.rb +++ b/src/image_mad/one_image.rb @@ -50,20 +50,30 @@ class ImageDriver < OpenNebulaDriver } # Register default actions for the protocol - def initialize(fs_type, options={}) + def initialize(ds_type, options={}) @options={ :concurrency => 10, :threaded => true, :retries => 0, :local_actions => { - 'MV' => nil, - 'CP' => nil, - 'RM' => nil, - 'MKFS' => nil + ACTION[:mv] => nil, + ACTION[:cp] => nil, + ACTION[:rm] => nil, + ACTION[:mkfs] => nil } }.merge!(options) - super("image/#{fs_type}", @options) + super("datastore/", @options) + + if ds_type == nil + @types = Dir["#{@local_scripts_path}/*/"].map do |d| + d.split('/')[-1] + end + elsif ds_type.class == String + @types = [ds_type] + else + @types = ds_type + end register_action(ACTION[:mv].to_sym, method("mv")) register_action(ACTION[:cp].to_sym, method("cp")) @@ -72,22 +82,47 @@ class ImageDriver < OpenNebulaDriver end # Image Manager Protocol Actions (generic implementation - def mv(id, src, dst) - do_action("#{src} #{dst} #{id}", id, nil, - ACTION[:mv]) + def mv(id, ds, src, dst) + do_image_action(id, ds, :mv, "'#{src}' '#{dst}' '#{id}'") end - def cp(id, src) - do_action("#{src} #{id}", id, nil, ACTION[:cp]) + def cp(id, ds, src) + do_image_action(id, ds, :cp, "'#{src}' '#{id}'") end - def rm(id, dst) - do_action("#{dst} #{id}", id, nil, ACTION[:rm]) + def rm(id, ds, dst) + do_image_action(id, ds, :rm, "'#{dst}' '#{id}'") end - def mkfs(id, fs, size) - do_action("#{fs} #{size} #{id}", id, nil, - ACTION[:mkfs]) + def mkfs(id, ds, fs, size) + do_image_action(id, ds, :mkfs, "'#{fs}' '#{size}' '#{id}'") + end + + private + + def is_available?(ds, id, action) + if @types.include?(ds) + return true + else + send_message(ACTION[action], RESULT[:failure], id, + "Datastore driver '#{ds}' not available") + return false + end + end + + def do_image_action(id, ds, action, arguments) + return if not is_available?(ds,id,:mv) + + path = File.join(@local_scripts_path, ds) + cmd = File.join(path, ACTION[action].downcase) + + cmd << " " << arguments + + rc = LocalCommand.run(cmd, log_method(id)) + + result, info = get_info_from_execution(rc) + + send_message(ACTION[action], result, id, info) end end @@ -95,28 +130,25 @@ end # ImageDriver Main program opts = GetoptLong.new( - [ '--threads', '-t', GetoptLong::OPTIONAL_ARGUMENT ] + [ '--threads', '-t', GetoptLong::OPTIONAL_ARGUMENT ], + [ '--ds-types', '-d', GetoptLong::OPTIONAL_ARGUMENT ] ) -fs_type = '' -threads = 15 +ds_type = nil +threads = 15 begin opts.each do |opt, arg| case opt when '--threads' - threads = arg.to_i + threads = arg.to_i + when '--ds-types' + ds_type = arg.split(',').map {|a| a.strip } end end rescue Exception => e exit(-1) end -if ARGV.length >= 1 - fs_type = ARGV.shift -else - exit(-1) -end - -image_driver = ImageDriver.new(fs_type, :concurrency => threads) +image_driver = ImageDriver.new(ds_type, :concurrency => threads) image_driver.start_driver From d754c987e69f7ff3b577a2769ef524b14ba94a55 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Wed, 15 Feb 2012 00:19:42 +0100 Subject: [PATCH 013/217] feature 1112: Work integrating datastores and images --- include/ImageManager.h | 7 ++- src/image/Image.cc | 13 ----- src/image/ImageManagerActions.cc | 60 ++----------------- src/image/ImagePool.cc | 99 ++++++++++++++++++++++---------- src/rm/RequestManagerDelete.cc | 43 +++++++++++++- 5 files changed, 119 insertions(+), 103 deletions(-) diff --git a/include/ImageManager.h b/include/ImageManager.h index 8858b27fa0..266ceea332 100644 --- a/include/ImageManager.h +++ b/include/ImageManager.h @@ -146,17 +146,18 @@ public: /** * Adds a new image to the repository copying or creating it as needed - * @param iid id of image + * @param img pointer to the image + * @param ds_data data of the associated datastore in XML format * @return 0 on success */ - int register_image(int iid); + int register_image(int iid, const string& ds_data); /** * Deletes an image from the repository and the DB * @param iid id of image * @return 0 on success */ - int delete_image(int iid); + int delete_image(int iid, const string& ds_data); private: /** diff --git a/src/image/Image.cc b/src/image/Image.cc index 5b1cc75056..6772927672 100644 --- a/src/image/Image.cc +++ b/src/image/Image.cc @@ -93,14 +93,11 @@ int Image::insert(SqlDB *db, string& error_str) string path_attr; string type_att; string persistent_attr; - string datastore_attr; string dev_prefix; string source_attr; string aname; ostringstream oss; - istringstream iss; - string ds_id_str; // ------------------------------------------------------------------------ // Check template for restricted attributes @@ -138,15 +135,6 @@ int Image::insert(SqlDB *db, string& error_str) goto error_type; } - // ------------ DATASTORE -------------------- - - erase_template_attribute("DATASTORE_ID", ds_id_str); - - iss.str(ds_id_str); - iss >> ds_id; - - erase_template_attribute("DATASTORE", ds_name); - // ------------ PERSISTENT -------------------- erase_template_attribute("PERSISTENT", persistent_attr); @@ -163,7 +151,6 @@ int Image::insert(SqlDB *db, string& error_str) { SingleAttribute * dev_att = new SingleAttribute("DEV_PREFIX", ImagePool::default_dev_prefix()); - obj_template->set(dev_att); } diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index 5166e18e89..6f4eab9833 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -17,8 +17,6 @@ #include "ImageManager.h" #include "NebulaLog.h" #include "ImagePool.h" -#include "DatastorePool.h" -#include "Nebula.h" /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -311,7 +309,7 @@ int ImageManager::enable_image(int iid, bool to_enable) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int ImageManager::delete_image(int iid) +int ImageManager::delete_image(int iid, const string& ds_data) { Image * img; string source; @@ -372,75 +370,29 @@ int ImageManager::delete_image(int iid) imd->rm(img->get_oid(),img->get_source()); } - int ds_id = img->get_ds_id(); img->unlock(); - - Datastore * ds; - DatastorePool * dspool; - Nebula& nd = Nebula::instance(); - - dspool = nd.get_dspool(); - ds = dspool->get(ds_id, true); - - // TODO check ds != 0 - - ds->del_image(iid); - - dspool->update(ds); - - ds->unlock(); - return 0; } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int ImageManager::register_image(int iid) +int ImageManager::register_image(int iid, const string& ds_data) { const ImageManagerDriver* imd = get(); - ostringstream oss; + ostringstream oss; + Image * img; + string path; - Image* img; if ( imd == 0 ) { - NebulaLog::log("ImM",Log::ERROR, - "Could not get driver to update repository"); + NebulaLog::log("ImM",Log::ERROR, "Could not get datastore driver"); return -1; } - img = ipool->get(iid,true); - - if (img == 0) - { - return -1; - } - - // Add the image to its datastore - int ds_id = img->get_ds_id(); - - img->unlock(); - - Datastore * ds; - DatastorePool * dspool; - Nebula& nd = Nebula::instance(); - - dspool = nd.get_dspool(); - ds = dspool->get(ds_id, true); - - // TODO check ds != 0 - - ds->add_image(iid); - - dspool->update(ds); - - ds->unlock(); - - - img = ipool->get(iid,true); if (img == 0) diff --git a/src/image/ImagePool.cc b/src/image/ImagePool.cc index 410ba235ae..737f289aa8 100644 --- a/src/image/ImagePool.cc +++ b/src/image/ImagePool.cc @@ -68,19 +68,27 @@ int ImagePool::allocate ( int * oid, string& error_str) { - Image * img; - Image * img_aux = 0; - string name; - int ds_id; - ostringstream oss; - Datastore * ds; - DatastorePool * dspool; + Image * img; + Image * img_aux = 0; - Nebula& nd = Nebula::instance(); + ostringstream oss; + istringstream iss; + + string name, ds_id_str, ds_data; + int ds_id; + + Datastore * ds = 0; + + Nebula& nd = Nebula::instance(); + + DatastorePool * dspool = nd.get_dspool(); + ImageManager * imagem = nd.get_imagem(); img = new Image(uid, gid, uname, gname, img_template); - // Check name + // ------------------------------------------------------------------------- + // Check name & duplicates + // ------------------------------------------------------------------------- img->get_template_attribute("NAME", name); if ( name.empty() ) @@ -93,7 +101,6 @@ int ImagePool::allocate ( goto error_name_length; } - // Check for duplicates img_aux = get(name,uid,false); if( img_aux != 0 ) @@ -101,29 +108,39 @@ int ImagePool::allocate ( goto error_duplicated; } - // Check datastore exists + // ------------------------------------------------------------------------- + // Check that the datastore exists + // ------------------------------------------------------------------------- + img->erase_template_attribute("DATASTORE", name); + img->erase_template_attribute("DATASTORE_ID", ds_id_str); - // TODO: get datastore by name, and replace datastore name from it - - img->get_template_attribute("DATASTORE_ID", ds_id); - - // TODO how to check if "DATASTORE_ID" exists? - // get_template_attribute returns 0 if the attribute does not exist... - // but it can exist and have value 0 - if ( false ) + if ( name.empty() ) { - goto error_common; // TODO error + iss.str(ds_id_str); + iss >> ds_id; + + if (ds_id == 0) + { + goto error_ds_system; + } + + ds = dspool->get(ds_id, true); + } + else + { + ds = dspool->get(name, true); } - dspool = nd.get_dspool(); - ds = dspool->get(ds_id, true); - - if( ds == 0 ) + if ( ds == 0 ) { - goto error_common; // TODO error + goto error_no_ds; } - img->replace_template_attribute("DATASTORE", ds->get_name()); + img->ds_name = ds->get_name(); + img->ds_id = ds->get_oid(); + ds_id = ds->get_oid(); + + ds->to_xml(ds_data); ds->unlock(); @@ -134,10 +151,20 @@ int ImagePool::allocate ( if ( *oid != -1 ) { - Nebula& nd = Nebula::instance(); - ImageManager * imagem = nd.get_imagem(); + ds = dspool->get(ds_id, true); + + if ( ds == 0 ) + { + goto error_ds_deleted; + } - if ( imagem->register_image(*oid) == -1 ) + ds->add_image(*oid); + + dspool->update(ds); + + ds->unlock(); + + if ( imagem->register_image(*oid, ds_data) == -1 ) { error_str = "Failed to copy image to repository. " "Image left in ERROR state."; @@ -149,7 +176,6 @@ int ImagePool::allocate ( error_name: oss << "NAME cannot be empty."; - goto error_common; error_name_length: @@ -159,6 +185,19 @@ error_name_length: error_duplicated: oss << "NAME is already taken by IMAGE " << img_aux->get_oid() << "."; + goto error_common; + +error_ds_system: + oss << "System or non datastore in image template."; + goto error_common; + +error_ds_deleted: + oss << "Datastore was deleted while registering image." + << "Image left in LOCKED state."; + return -1; + +error_no_ds: + oss << "No datastore specify to register image."; error_common: delete img; diff --git a/src/rm/RequestManagerDelete.cc b/src/rm/RequestManagerDelete.cc index be06c4f929..9c56df8de5 100644 --- a/src/rm/RequestManagerDelete.cc +++ b/src/rm/RequestManagerDelete.cc @@ -106,10 +106,47 @@ void RequestManagerDelete::request_execute(xmlrpc_c::paramList const& paramList, int ImageDelete::drop(int oid, PoolObjectSQL * object, string& error_msg) { Nebula& nd = Nebula::instance(); - ImageManager * imagem = nd.get_imagem(); - object->unlock(); - int rc = imagem->delete_image(oid); + ImageManager * imagem = nd.get_imagem(); + DatastorePool * dspool = nd.get_dspool(); + + Datastore * ds; + Image * img; + + int ds_id, rc; + string ds_data; + + img = static_cast(object); + ds_id = img->get_ds_id(); + + img->unlock(); + + ds = dspool->get(ds_id, true); + + if ( ds == 0 ) + { + error_msg = "Datastore no longer exists can not remove image"; + return -1; + } + + ds->to_xml(ds_data); + + ds->unlock(); + + rc = imagem->delete_image(oid, ds_data); + + if ( rc == 0 ) + { + ds = dspool->get(ds_id, true); + + if ( ds != 0 ) + { + ds->del_image(oid); + dspool->update(ds); + + ds->unlock(); + } + } return rc; } From 174ba75d63f852fa0210bfcfbc7e30045874c0bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 15 Feb 2012 16:47:52 +0100 Subject: [PATCH 014/217] Feature #1112: Move datastore definition from image template to xml-rcp parameter --- include/ImagePool.h | 6 ++ include/RequestManagerAllocate.h | 22 +++-- src/image/ImagePool.cc | 85 +++----------------- src/rm/RequestManagerAllocate.cc | 107 +++++++++++++++++++++++-- src/rm/RequestManagerVirtualMachine.cc | 7 +- 5 files changed, 131 insertions(+), 96 deletions(-) diff --git a/include/ImagePool.h b/include/ImagePool.h index 2530fcb20c..2a2c63d85b 100644 --- a/include/ImagePool.h +++ b/include/ImagePool.h @@ -52,6 +52,9 @@ public: * @param uname name of the user * @param gname name of the group * @param img_template template associated with the image + * @param ds_id the id of the datastore + * @param ds_name the name of the datastore + * @param ds_data the datastore data * @param oid the id assigned to the Image * @param error_str Returns the error reason, if any * @return the oid assigned to the object, @@ -64,6 +67,9 @@ public: const string& uname, const string& gname, ImageTemplate * img_template, + int ds_id, + const string& ds_name, + const string& ds_data, int * oid, string& error_str); diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index cdeaf0bc29..bc9604f59d 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -46,7 +46,7 @@ protected: /* -------------------------------------------------------------------- */ - void request_execute(xmlrpc_c::paramList const& _paramList, + virtual void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att); virtual bool allocate_authorization(Template * obj_template, @@ -60,7 +60,11 @@ protected: Template * tmpl, int& id, string& error_str, - RequestAttributes& att) = 0; + RequestAttributes& att) + { + return -1; + }; + private: bool do_template; @@ -146,7 +150,7 @@ public: "Allocates a new image", "A:ss", true) - { + { Nebula& nd = Nebula::instance(); pool = nd.get_ipool(); auth_object = PoolObjectSQL::IMAGE; @@ -156,16 +160,8 @@ public: /* --------------------------------------------------------------------- */ - Template * get_object_template() - { - return new ImageTemplate; - }; - - int pool_allocate(xmlrpc_c::paramList const& _paramList, - Template * tmpl, - int& id, - string& error_str, - RequestAttributes& att); + void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att); }; /* ------------------------------------------------------------------------- */ diff --git a/src/image/ImagePool.cc b/src/image/ImagePool.cc index 737f289aa8..2f7275cf22 100644 --- a/src/image/ImagePool.cc +++ b/src/image/ImagePool.cc @@ -65,24 +65,16 @@ int ImagePool::allocate ( const string& uname, const string& gname, ImageTemplate* img_template, + int ds_id, + const string& ds_name, + const string& ds_data, int * oid, string& error_str) { - Image * img; - Image * img_aux = 0; - - ostringstream oss; - istringstream iss; - - string name, ds_id_str, ds_data; - int ds_id; - - Datastore * ds = 0; - - Nebula& nd = Nebula::instance(); - - DatastorePool * dspool = nd.get_dspool(); - ImageManager * imagem = nd.get_imagem(); + Image * img; + Image * img_aux = 0; + string name; + ostringstream oss; img = new Image(uid, gid, uname, gname, img_template); @@ -108,41 +100,8 @@ int ImagePool::allocate ( goto error_duplicated; } - // ------------------------------------------------------------------------- - // Check that the datastore exists - // ------------------------------------------------------------------------- - img->erase_template_attribute("DATASTORE", name); - img->erase_template_attribute("DATASTORE_ID", ds_id_str); - - if ( name.empty() ) - { - iss.str(ds_id_str); - iss >> ds_id; - - if (ds_id == 0) - { - goto error_ds_system; - } - - ds = dspool->get(ds_id, true); - } - else - { - ds = dspool->get(name, true); - } - - if ( ds == 0 ) - { - goto error_no_ds; - } - - img->ds_name = ds->get_name(); - img->ds_id = ds->get_oid(); - ds_id = ds->get_oid(); - - ds->to_xml(ds_data); - - ds->unlock(); + img->ds_name = ds_name; + img->ds_id = ds_id; // --------------------------------------------------------------------- // Insert the Object in the pool & Register the image in the repository @@ -151,18 +110,8 @@ int ImagePool::allocate ( if ( *oid != -1 ) { - ds = dspool->get(ds_id, true); - - if ( ds == 0 ) - { - goto error_ds_deleted; - } - - ds->add_image(*oid); - - dspool->update(ds); - - ds->unlock(); + Nebula& nd = Nebula::instance(); + ImageManager * imagem = nd.get_imagem(); if ( imagem->register_image(*oid, ds_data) == -1 ) { @@ -187,18 +136,6 @@ error_duplicated: << img_aux->get_oid() << "."; goto error_common; -error_ds_system: - oss << "System or non datastore in image template."; - goto error_common; - -error_ds_deleted: - oss << "Datastore was deleted while registering image." - << "Image left in LOCKED state."; - return -1; - -error_no_ds: - oss << "No datastore specify to register image."; - error_common: delete img; diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index d4c8a71710..cd36a27b7b 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -166,17 +166,108 @@ int VirtualNetworkAllocate::pool_allocate(xmlrpc_c::paramList const& _paramList, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int ImageAllocate::pool_allocate(xmlrpc_c::paramList const& _paramList, - Template * tmpl, - int& id, - string& error_str, - RequestAttributes& att) +void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, + RequestAttributes& att) { - ImagePool * ipool = static_cast(pool); - ImageTemplate * itmpl = static_cast(tmpl); + ImageTemplate * tmpl = 0; - return ipool->allocate(att.uid, att.gid, att.uname, att.gname, itmpl, &id, + string error_str; + string ds_name; + string ds_data; + int rc, id; + + PoolObjectAuth ds_perms; + + string str_tmpl = xmlrpc_c::value_string(params.getString(1)); + int ds_id = xmlrpc_c::value_int(params.getInt(2)); + + tmpl = new ImageTemplate; + + rc = tmpl->parse_str_or_xml(str_tmpl, error_str); + + if ( rc != 0 ) + { + failure_response(INTERNAL, allocate_error(error_str), att); + delete tmpl; + + return; + } + + // ------------- Check Datastore exists ----------------------------------- + + Nebula& nd = Nebula::instance(); + + Datastore * ds; + DatastorePool * dspool = nd.get_dspool(); + + if ((ds = dspool->get(ds_id,true)) == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::DATASTORE), ds_id), + att); + + return; + } + + ds->get_permissions(ds_perms); + + ds_name = ds->get_name(); + + ds->to_xml(ds_data); + + ds->unlock(); + + + // ------------- Set authorization request for non-oneadmin's -------------- + + if ( att.uid != 0 ) + { + string tmpl_str = ""; + + AuthRequest ar(att.uid, att.gid); + + if ( tmpl != 0 ) + { + tmpl->to_xml(tmpl_str); + } + + ar.add_create_auth(auth_object, tmpl_str); // CREATE IMAGE + + ar.add_auth(AuthRequest::USE, ds_perms); // USE DATASTORE + + if (UserPool::authorize(ar) == -1) + { + failure_response(AUTHORIZATION, + authorization_error(ar.message, att), + att); + + return; + } + } + + ImagePool * ipool = static_cast(pool); + + rc = ipool->allocate(att.uid, att.gid, att.uname, att.gname, tmpl, ds_id, ds_name, ds_data, &id, error_str); + + if ( rc < 0 ) + { + failure_response(INTERNAL, allocate_error(error_str), att); + return; + } + + ds = dspool->get(ds_id, true); + + if ( ds != 0 ) // TODO: error otherwise? + { + ds->add_image(id); + + dspool->update(ds); + + ds->unlock(); + } + + success_response(id, att); } /* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 084b31c274..d27053af2b 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -447,8 +447,13 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis // ------------------ Create the image ------------------ + // TODO: get values from source image DS + int ds_id = 0; + string ds_name = ""; + string ds_data = ""; + rc = ipool->allocate(att.uid, att.gid, att.uname, att.gname, itemplate, - &iid, error_str); + ds_id, ds_name, ds_data, &iid, error_str); if (rc < 0) { From 0dfb521b9b0804b89fe45b397850d253af36085f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 15 Feb 2012 17:17:32 +0100 Subject: [PATCH 015/217] Feature #1112: Create default system datastore at bootstrap --- include/DatastorePool.h | 12 +++++++++- src/datastore/DatastorePool.cc | 44 ++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/include/DatastorePool.h b/include/DatastorePool.h index c6f0a97d55..347516fd6f 100644 --- a/include/DatastorePool.h +++ b/include/DatastorePool.h @@ -26,7 +26,7 @@ using namespace std; class DatastorePool : public PoolSQL { public: - DatastorePool(SqlDB * db):PoolSQL(db, Datastore::table){}; + DatastorePool(SqlDB * db); ~DatastorePool(){}; @@ -34,6 +34,16 @@ public: /* Constants for DB management */ /* ---------------------------------------------------------------------- */ + /** + * Default name for the oneadmin group + */ + static const string SYSTEM_DS_NAME; + + /** + * Identifier for the oneadmin group + */ + static const int SYSTEM_DS_ID; + /* ---------------------------------------------------------------------- */ /* Methods for DB management */ /* ---------------------------------------------------------------------- */ diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index fdd05d3cf1..86788a80f9 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -20,6 +20,50 @@ #include +/* -------------------------------------------------------------------------- */ +/* There is a default datastore boostrapped by the core: */ +/* The first 100 IDs are reserved for system datastores. Regular ones start */ +/* from ID 100 */ +/* -------------------------------------------------------------------------- */ + +const string DatastorePool::SYSTEM_DS_NAME = "default"; +const int DatastorePool::SYSTEM_DS_ID = 0; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +DatastorePool::DatastorePool(SqlDB * db):PoolSQL(db, Datastore::table) +{ + ostringstream oss; + string error_str; + + if (get_lastOID() == -1) //lastOID is set in PoolSQL::init_cb + { + int rc; + Datastore * ds; + + // Build the default datastore + ds = new Datastore(SYSTEM_DS_ID, SYSTEM_DS_NAME); + + rc = PoolSQL::allocate(ds, error_str); + + if( rc < 0 ) + { + goto error_bootstrap; + } + + set_update_lastOID(99); + } + + return; + +error_bootstrap: + oss << "Error trying to create default datastore: " << error_str; + NebulaLog::log("DATASTORE",Log::ERROR,oss); + + throw runtime_error(oss.str()); +} + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ From 4950f23652beeecb655f472ad3d41ccb86446b9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 15 Feb 2012 17:18:24 +0100 Subject: [PATCH 016/217] Feature #1112: Add datastore id to image creation in ruby OCA and CLI --- src/cli/one_helper.rb | 7 ++++--- src/cli/oneimage | 8 ++++++-- src/oca/ruby/OpenNebula/Image.rb | 10 +++++++--- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/cli/one_helper.rb b/src/cli/one_helper.rb index e900a963bc..3785668a0c 100644 --- a/src/cli/one_helper.rb +++ b/src/cli/one_helper.rb @@ -329,9 +329,10 @@ EOT client = OpenNebula::Client.new pool = case poolname - when "HOST" then OpenNebula::HostPool.new(client) - when "GROUP" then OpenNebula::GroupPool.new(client) - when "USER" then OpenNebula::UserPool.new(client) + when "HOST" then OpenNebula::HostPool.new(client) + when "GROUP" then OpenNebula::GroupPool.new(client) + when "USER" then OpenNebula::UserPool.new(client) + when "DATASTORE" then OpenNebula::DatastorePool.new(client) end rc = pool.info diff --git a/src/cli/oneimage b/src/cli/oneimage index 4647ec1319..bb8635f5db 100755 --- a/src/cli/oneimage +++ b/src/cli/oneimage @@ -56,6 +56,10 @@ cmd=CommandParser::CmdParser.new(ARGV) do OpenNebulaHelper.rname_to_id(arg, "USER") end + set :format, :datastoreid, OpenNebulaHelper.rname_to_id_desc("DATASTORE") do |arg| + OpenNebulaHelper.rname_to_id(arg, "DATASTORE") + end + set :format, :imageid, OneImageHelper.to_id_desc do |arg| helper.to_id(arg) end @@ -76,10 +80,10 @@ cmd=CommandParser::CmdParser.new(ARGV) do Creates a new Image from the given template file EOT - command :create, create_desc, :file do + command :create, create_desc, :file, :datastoreid do helper.create_resource(options) do |image| template=File.read(args[0]) - image.allocate(template) + image.allocate(template, args[1]) end end diff --git a/src/oca/ruby/OpenNebula/Image.rb b/src/oca/ruby/OpenNebula/Image.rb index 348b4c4df1..878115ef3d 100644 --- a/src/oca/ruby/OpenNebula/Image.rb +++ b/src/oca/ruby/OpenNebula/Image.rb @@ -91,9 +91,13 @@ module OpenNebula # Allocates a new Image in OpenNebula # - # +description+ A string containing the template of the Image. - def allocate(description) - super(IMAGE_METHODS[:allocate],description) + # @param description [String] A string containing the template of the Image. + # @param ds_id [Integer] the target datastore ID + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def allocate(description, ds_id) + super(IMAGE_METHODS[:allocate],description, ds_id) end # Replaces the template contents From 0f350b3da03550dc78015e8ff73bed90d9ac55c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 15 Feb 2012 17:37:30 +0100 Subject: [PATCH 017/217] Feature #1112: System datastores can't be deleted --- src/datastore/DatastorePool.cc | 8 ++++++++ src/rm/Request.cc | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index 86788a80f9..98b084cae0 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -125,6 +125,14 @@ int DatastorePool::drop(PoolObjectSQL * objsql, string& error_msg) int rc; + // Return error if the datastore is a default one. + if( datastore->get_oid() < 100 ) + { + error_msg = "System Datastores (ID < 100) cannot be deleted."; + NebulaLog::log("DATASTORE", Log::ERROR, error_msg); + return -2; + } + if( datastore->get_collection_size() > 0 ) { ostringstream oss; diff --git a/src/rm/Request.cc b/src/rm/Request.cc index 4b8b929b96..704eb9e2f1 100644 --- a/src/rm/Request.cc +++ b/src/rm/Request.cc @@ -177,6 +177,8 @@ string Request::object_name(PoolObjectSQL::ObjectType ob) return "group"; case PoolObjectSQL::ACL: return "ACL"; + case PoolObjectSQL::DATASTORE: + return "datastore"; default: return "-"; } From 2a6f5b50dc758a2124cf49b5476bd27f63730b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 15 Feb 2012 18:53:23 +0100 Subject: [PATCH 018/217] Feature #1112: Integrate datastores into acl rules --- src/acl/AclRule.cc | 9 +++++---- src/cli/etc/oneacl.yaml | 6 +++--- src/cli/one_helper/oneacl_helper.rb | 10 ++++++---- src/oca/ruby/OpenNebula/Acl.rb | 3 ++- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/acl/AclRule.cc b/src/acl/AclRule.cc index dc7381f072..1a941d3818 100644 --- a/src/acl/AclRule.cc +++ b/src/acl/AclRule.cc @@ -166,7 +166,7 @@ bool AclRule::malformed(string& error_str) const oss << "when using the ALL bit, [resource] ID must be 0"; } - if ( (resource & 0xFF000000000LL) == 0 ) + if ( (resource & 0xFFF000000000LL) == 0 ) { if ( error ) { @@ -177,7 +177,7 @@ bool AclRule::malformed(string& error_str) const oss << "[resource] type is missing"; } - if ( (resource & 0xFFFFF00000000000LL) != 0 ) + if ( (resource & 0xFFFF000000000000LL) != 0 ) { if ( error ) { @@ -253,12 +253,13 @@ void AclRule::build_str() PoolObjectSQL::IMAGE, PoolObjectSQL::USER, PoolObjectSQL::TEMPLATE, - PoolObjectSQL::GROUP + PoolObjectSQL::GROUP, + PoolObjectSQL::DATASTORE }; bool prefix = false; - for ( int i = 0; i < 7; i++ ) + for ( int i = 0; i < 8; i++ ) { if ( (resource & objects[i]) != 0 ) { diff --git a/src/cli/etc/oneacl.yaml b/src/cli/etc/oneacl.yaml index 4d1e7b66f9..170942867b 100644 --- a/src/cli/etc/oneacl.yaml +++ b/src/cli/etc/oneacl.yaml @@ -9,9 +9,9 @@ :size: 8 :right: true -:RES_VHNIUTG: +:RES_VHNIUTGD: :desc: Which resource the rule applies to - :size: 11 + :size: 12 :RID: :desc: Resource ID @@ -26,6 +26,6 @@ :default: - :ID - :USER -- :RES_VHNIUTG +- :RES_VHNIUTGD - :RID - :OPE_UMAC diff --git a/src/cli/one_helper/oneacl_helper.rb b/src/cli/one_helper/oneacl_helper.rb index 553c6656de..90445607a8 100644 --- a/src/cli/one_helper/oneacl_helper.rb +++ b/src/cli/one_helper/oneacl_helper.rb @@ -44,7 +44,7 @@ private def self.resource_mask(str) resource_type=str.split("/")[0] - mask = "-------" + mask = "--------" resource_type.split("+").each{|type| case type @@ -62,6 +62,8 @@ private mask[5] = "T" when "GROUP" mask[6] = "G" + when "DATASTORE" + mask[7] = "D" end } mask @@ -101,8 +103,8 @@ private d['STRING'].split(" ")[0] end - column :RES_VHNIUTG, "Resource to which the rule applies", - :size => 11 do |d| + column :RES_VHNIUTGD, "Resource to which the rule applies", + :size => 12 do |d| OneAclHelper::resource_mask d['STRING'].split(" ")[1] end @@ -115,7 +117,7 @@ private OneAclHelper::right_mask d['STRING'].split(" ")[2] end - default :ID, :USER, :RES_VHNIUTG, :RID, :OPE_UMAC + default :ID, :USER, :RES_VHNIUTGD, :RID, :OPE_UMAC end table diff --git a/src/oca/ruby/OpenNebula/Acl.rb b/src/oca/ruby/OpenNebula/Acl.rb index 054a8f6648..484bcc8beb 100644 --- a/src/oca/ruby/OpenNebula/Acl.rb +++ b/src/oca/ruby/OpenNebula/Acl.rb @@ -52,7 +52,8 @@ module OpenNebula "IMAGE" => 0x8000000000, "USER" => 0x10000000000, "TEMPLATE" => 0x20000000000, - "GROUP" => 0x40000000000 + "GROUP" => 0x40000000000, + "DATASTORE" => 0x100000000000 } RIGHTS = From dacef3d104e445f77f7b409f310dd47089361bb6 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Wed, 15 Feb 2012 23:52:22 +0100 Subject: [PATCH 019/217] feature-1112: "system" is the default name for DS 0 --- src/datastore/DatastorePool.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index 98b084cae0..5edfbd2c2f 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -26,7 +26,7 @@ /* from ID 100 */ /* -------------------------------------------------------------------------- */ -const string DatastorePool::SYSTEM_DS_NAME = "default"; +const string DatastorePool::SYSTEM_DS_NAME = "system"; const int DatastorePool::SYSTEM_DS_ID = 0; /* -------------------------------------------------------------------------- */ From 2d31a9411501467bc647d77fa13eaf6e6ca60411 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Wed, 15 Feb 2012 23:53:35 +0100 Subject: [PATCH 020/217] feature #1112: Configuration parameters for the System Datastore --- share/etc/oned.conf | 15 ++++++++++++++- src/nebula/NebulaTemplate.cc | 8 ++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/share/etc/oned.conf b/share/etc/oned.conf index e89cf46340..431b641fe1 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -84,8 +84,15 @@ NETWORK_SIZE = 254 MAC_PREFIX = "02:00" #******************************************************************************* -# Image Repository Configuration +# DataStore Configuration #******************************************************************************* +# SYSTEM_DS +# base_path : Base path for the system datastore. The system datastore +# keeps the images (or reference to) of running or stopped VMs. +# The images are stored in the form base_path/. +# type : SSH: non shared, will limit live_migration +# SHARED: needs to be exported and mounted in the hosts +# # DEFAULT_IMAGE_TYPE: This can take values # OS Image file holding an operating system # CDROM Image file holding a CDROM @@ -97,6 +104,12 @@ MAC_PREFIX = "02:00" # xvd XEN Virtual Disk # vd KVM virtual disk #******************************************************************************* + +SYSTEM_DS = [ + base_path = "/var/lib/one/system_ds", + type = "shared" +] + DEFAULT_IMAGE_TYPE = "OS" DEFAULT_DEVICE_PREFIX = "hd" diff --git a/src/nebula/NebulaTemplate.cc b/src/nebula/NebulaTemplate.cc index 4113db6921..7d76ddf089 100644 --- a/src/nebula/NebulaTemplate.cc +++ b/src/nebula/NebulaTemplate.cc @@ -186,6 +186,14 @@ void OpenNebulaTemplate::set_conf_default() # DEFAULT_DEVICE_PREFIX #******************************************************************************* */ + //SYSTEM_DS + vvalue.clear(); + vvalue.insert(make_pair("BASE_PATH","/var/lib/one/system_ds")); + vvalue.insert(make_pair("TYPE","shared")); + + vattribute = new VectorAttribute("SYSTEM_DS",vvalue); + conf_default.insert(make_pair(attribute->name(),vattribute)); + //DEFAULT_IMAGE_TYPE value = "OS"; From 76ae0809d88c1bb882af7573f44713263a553db1 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Wed, 15 Feb 2012 23:54:22 +0100 Subject: [PATCH 021/217] feature #1112: Delete templates in case of failure. Some cosmetic changes --- src/rm/RequestManagerAllocate.cc | 51 ++++++++++++++------------ src/rm/RequestManagerVirtualMachine.cc | 1 + 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index cd36a27b7b..0fb2a8f262 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -116,6 +116,7 @@ void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params, if ( allocate_authorization(tmpl, att) == false ) { + delete tmpl; return; } @@ -169,7 +170,6 @@ int VirtualNetworkAllocate::pool_allocate(xmlrpc_c::paramList const& _paramList, void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, RequestAttributes& att) { - ImageTemplate * tmpl = 0; string error_str; string ds_name; @@ -181,24 +181,27 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, string str_tmpl = xmlrpc_c::value_string(params.getString(1)); int ds_id = xmlrpc_c::value_int(params.getInt(2)); - tmpl = new ImageTemplate; + Nebula& nd = Nebula::instance(); - rc = tmpl->parse_str_or_xml(str_tmpl, error_str); + DatastorePool * dspool = nd.get_dspool(); + ImagePool * ipool = static_cast(pool); + + ImageTemplate * tmpl = new ImageTemplate; + Datastore * ds; + + // ------------------------- Prase image template -------------------------- + + rc = tmpl->parse_str_or_xml(str_tmpl, error_str); if ( rc != 0 ) { failure_response(INTERNAL, allocate_error(error_str), att); - delete tmpl; + delete tmpl; return; } - // ------------- Check Datastore exists ----------------------------------- - - Nebula& nd = Nebula::instance(); - - Datastore * ds; - DatastorePool * dspool = nd.get_dspool(); + // ------------------------- Check Datastore exists ------------------------ if ((ds = dspool->get(ds_id,true)) == 0 ) { @@ -206,6 +209,7 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, get_error(object_name(PoolObjectSQL::DATASTORE), ds_id), att); + delete tmpl; return; } @@ -217,19 +221,14 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, ds->unlock(); - // ------------- Set authorization request for non-oneadmin's -------------- if ( att.uid != 0 ) { - string tmpl_str = ""; - AuthRequest ar(att.uid, att.gid); + string tmpl_str = ""; - if ( tmpl != 0 ) - { - tmpl->to_xml(tmpl_str); - } + tmpl->to_xml(tmpl_str); ar.add_create_auth(auth_object, tmpl_str); // CREATE IMAGE @@ -241,15 +240,21 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, authorization_error(ar.message, att), att); + delete tmpl; return; } } - ImagePool * ipool = static_cast(pool); - - rc = ipool->allocate(att.uid, att.gid, att.uname, att.gname, tmpl, ds_id, ds_name, ds_data, &id, - error_str); - + rc = ipool->allocate(att.uid, + att.gid, + att.uname, + att.gname, + tmpl, + ds_id, + ds_name, + ds_data, + &id, + error_str); if ( rc < 0 ) { failure_response(INTERNAL, allocate_error(error_str), att); @@ -258,7 +263,7 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, ds = dspool->get(ds_id, true); - if ( ds != 0 ) // TODO: error otherwise? + if ( ds != 0 ) // TODO: error otherwise or leave image in ERROR? { ds->add_image(id); diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index d27053af2b..b58d86cc0e 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -442,6 +442,7 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis if ( vm_authorization(id,itemplate,att,0) == false ) { + delete itemplate; return; } From 4e2bd36415642b3d7026af76d1e158e7a101b5a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 16 Feb 2012 19:37:08 +0100 Subject: [PATCH 022/217] Feature #1112: Datastores are now defined with templates. New att. type and base path --- include/Datastore.h | 27 +++++---- include/DatastorePool.h | 10 ++-- include/RequestManagerAllocate.h | 10 +++- src/cli/onedatastore | 7 ++- src/datastore/Datastore.cc | 89 ++++++++++++++++++++++++++-- src/datastore/DatastorePool.cc | 35 +++++++---- src/oca/ruby/OpenNebula/Datastore.rb | 9 ++- src/oca/ruby/OpenNebula/Host.rb | 2 +- src/rm/RequestManagerAllocate.cc | 6 +- 9 files changed, 152 insertions(+), 43 deletions(-) diff --git a/include/Datastore.h b/include/Datastore.h index 17c2c13623..8bce2ed79a 100644 --- a/include/Datastore.h +++ b/include/Datastore.h @@ -19,9 +19,7 @@ #include "PoolSQL.h" #include "ObjectCollection.h" -//#include "Image.h" - -//using namespace std; +#include "DatastoreTemplate.h" /** * The Datastore class. @@ -73,13 +71,25 @@ private: friend class DatastorePool; + // ************************************************************************* + // Datastore Private Attributes + // ************************************************************************* + + /** + * Type of driver + */ + string type; + + /** + * Base path for the storage + */ + string base_path; + // ************************************************************************* // Constructor // ************************************************************************* - Datastore(int id, const string& name): - PoolObjectSQL(id,DATASTORE,name,-1,-1,"","",table), - ObjectCollection("IMAGES"){}; + Datastore(int id, DatastoreTemplate* ds_template); virtual ~Datastore(){}; @@ -118,10 +128,7 @@ private: * @param db pointer to the db * @return 0 on success */ - int insert(SqlDB *db, string& error_str) - { - return insert_replace(db, false, error_str); - } + int insert(SqlDB *db, string& error_str); /** * Writes/updates the Datastore's data fields in the database. diff --git a/include/DatastorePool.h b/include/DatastorePool.h index 347516fd6f..c01b35ad86 100644 --- a/include/DatastorePool.h +++ b/include/DatastorePool.h @@ -51,15 +51,15 @@ public: /** * Allocates a new Datastore, writing it in the pool database. No memory is * allocated for the object. - * @param name Datastore name + * @param ds_template Datastore definition template * @param oid the id assigned to the Datastore * @param error_str Returns the error reason, if any * * @return the oid assigned to the object, -1 in case of failure */ - int allocate(string name, - int * oid, - string& error_str); + int allocate(DatastoreTemplate * ds_template, + int * oid, + string& error_str); /** * Function to get a Datastore from the pool, if the object is not in memory @@ -149,7 +149,7 @@ private: */ PoolObjectSQL * create() { - return new Datastore(-1,""); + return new Datastore(-1, 0); }; }; diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index bc9604f59d..bcd00c4797 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -23,6 +23,7 @@ #include "VirtualNetworkTemplate.h" #include "ImageTemplate.h" #include "VirtualMachineTemplate.h" +#include "DatastoreTemplate.h" using namespace std; @@ -285,7 +286,7 @@ public: RequestManagerAllocate("DatastoreAllocate", "Allocates a new Datastore", "A:ss", - false) + true) { Nebula& nd = Nebula::instance(); pool = nd.get_dspool(); @@ -294,6 +295,13 @@ public: ~DatastoreAllocate(){}; + /* -------------------------------------------------------------------- */ + + Template * get_object_template() + { + return new DatastoreTemplate; + }; + int pool_allocate(xmlrpc_c::paramList const& _paramList, Template * tmpl, int& id, diff --git a/src/cli/onedatastore b/src/cli/onedatastore index 4dd8e648da..bbcdbf6bd1 100755 --- a/src/cli/onedatastore +++ b/src/cli/onedatastore @@ -61,12 +61,13 @@ cmd=CommandParser::CmdParser.new(ARGV) do ######################################################################## create_desc = <<-EOT.unindent - Creates a new Datastore + Creates a new Datastore from the given template file EOT - command :create, create_desc, :name do + command :create, create_desc, :file do helper.create_resource(options) do |datastore| - datastore.allocate(args[0]) + template=File.read(args[0]) + datastore.allocate(template) end end diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index 304abf2335..d7d7628e31 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -22,6 +22,7 @@ #include "Datastore.h" #include "GroupPool.h" +#include "NebulaLog.h" const char * Datastore::table = "datastore_pool"; @@ -35,9 +36,83 @@ const char * Datastore::db_bootstrap = "UNIQUE(name))"; /* ************************************************************************ */ -/* Datastore :: Database Access Functions */ +/* Datastore :: Constructor/Destructor */ /* ************************************************************************ */ +Datastore::Datastore(int id, + DatastoreTemplate* ds_template): + PoolObjectSQL(id,DATASTORE,"",-1,-1,"","",table), + ObjectCollection("IMAGES"), + type(""), + base_path("") +{ + if (ds_template != 0) + { + obj_template = ds_template; + } + else + { + obj_template = new DatastoreTemplate; + } +} + +/* ************************************************************************ */ +/* Datastore :: Database Access Functions */ +/* ************************************************************************ */ + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +int Datastore::insert(SqlDB *db, string& error_str) +{ + int rc; + + // --------------------------------------------------------------------- + // Check default datastore attributes + // --------------------------------------------------------------------- + + + erase_template_attribute("NAME", name); + // NAME is checked in DatastorePool::allocate + + erase_template_attribute("TYPE", type); + + if ( type.empty() == true ) + { + goto error_type; + } + + erase_template_attribute("BASE_PATH", base_path); + + if ( base_path.empty() == true ) + { + goto error_base_path; + } + + //-------------------------------------------------------------------------- + // Insert the Datastore + //-------------------------------------------------------------------------- + + rc = insert_replace(db, false, error_str); + + return rc; + +error_type: + error_str = "No NAME in template."; + goto error_common; + +error_base_path: + error_str = "No BASE_PATH in template."; + goto error_common; + +error_common: + NebulaLog::log("DATASTORE", Log::ERROR, error_str); + return -1; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + int Datastore::insert_replace(SqlDB *db, bool replace, string& error_str) { ostringstream oss; @@ -135,8 +210,10 @@ string& Datastore::to_xml(string& xml) const oss << "" << - "" << oid << "" << - "" << name << "" << + "" << oid << "" << + "" << name << "" << + "" << type << "" << + "" << base_path << "" << collection_xml << ""; @@ -157,8 +234,10 @@ int Datastore::from_xml(const string& xml) update_from_str(xml); // Get class base attributes - rc += xpath(oid, "/DATASTORE/ID", -1); - rc += xpath(name,"/DATASTORE/NAME", "not_found"); + rc += xpath(oid, "/DATASTORE/ID", -1); + rc += xpath(name, "/DATASTORE/NAME", "not_found"); + rc += xpath(type, "/DATASTORE/TYPE", "not_found"); + rc += xpath(base_path, "/DATASTORE/BASE_PATH", "not_found"); // Set the owner and group to oneadmin set_user(0, ""); diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index 5edfbd2c2f..2dcb64f1de 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -43,6 +43,8 @@ DatastorePool::DatastorePool(SqlDB * db):PoolSQL(db, Datastore::table) Datastore * ds; // Build the default datastore + // TODO: create template with default name, type and base path +/* ds = new Datastore(SYSTEM_DS_ID, SYSTEM_DS_NAME); rc = PoolSQL::allocate(ds, error_str); @@ -51,7 +53,7 @@ DatastorePool::DatastorePool(SqlDB * db):PoolSQL(db, Datastore::table) { goto error_bootstrap; } - +*/ set_update_lastOID(99); } @@ -67,11 +69,23 @@ error_bootstrap: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int DatastorePool::allocate(string name, int * oid, string& error_str) +int DatastorePool::allocate(DatastoreTemplate * ds_template, + int * oid, + string& error_str) { - Datastore * datastore; + Datastore * ds; + Datastore * ds_aux = 0; + string name; ostringstream oss; + ds = new Datastore(-1, ds_template); + + // ------------------------------------------------------------------------- + // Check name & duplicates + // ------------------------------------------------------------------------- + + ds->get_template_attribute("NAME", name); + if ( name.empty() ) { goto error_name; @@ -82,19 +96,14 @@ int DatastorePool::allocate(string name, int * oid, string& error_str) goto error_name_length; } - // Check for duplicates - datastore = get(name, false); + ds_aux = get(name,false); - if( datastore != 0 ) + if( ds_aux != 0 ) { goto error_duplicated; } - // Build a new Datastore object - datastore = new Datastore(-1, name); - - // Insert the Object in the pool - *oid = PoolSQL::allocate(datastore, error_str); + *oid = PoolSQL::allocate(ds, error_str); return *oid; @@ -107,9 +116,11 @@ error_name_length: goto error_common; error_duplicated: - oss << "NAME is already taken by DATASTORE " << datastore->get_oid() << "."; + oss << "NAME is already taken by DATASTORE " << ds_aux->get_oid() << "."; error_common: + delete ds; + *oid = -1; error_str = oss.str(); diff --git a/src/oca/ruby/OpenNebula/Datastore.rb b/src/oca/ruby/OpenNebula/Datastore.rb index 75329f32af..f19145e1e6 100644 --- a/src/oca/ruby/OpenNebula/Datastore.rb +++ b/src/oca/ruby/OpenNebula/Datastore.rb @@ -62,9 +62,12 @@ module OpenNebula # Allocates a new Datastore in OpenNebula # - # +datastorename+ A string containing the name of the Datastore. - def allocate(datastorename) - super(DATASTORE_METHODS[:allocate], datastorename) + # @param description [String] The template of the Datastore. + # + # @return [Integer, OpenNebula::Error] the new ID in case of + # success, error otherwise + def allocate(description) + super(DATASTORE_METHODS[:allocate], description) end # Deletes the Datastore diff --git a/src/oca/ruby/OpenNebula/Host.rb b/src/oca/ruby/OpenNebula/Host.rb index b0f183c6c4..74bb2e8edb 100644 --- a/src/oca/ruby/OpenNebula/Host.rb +++ b/src/oca/ruby/OpenNebula/Host.rb @@ -83,7 +83,7 @@ module OpenNebula # @param vmm [String] Name of the vmm_driver # @param tm [String] Name of the tm_driver # - # @return [Integer, OpenNebula::Error] the new VM ID in case of + # @return [Integer, OpenNebula::Error] the new ID in case of # success, error otherwise def allocate(hostname,im,vmm,vnm,tm) super(HOST_METHODS[:allocate],hostname,im,vmm,vnm,tm) diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 0fb2a8f262..79a02672d7 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -371,9 +371,9 @@ int DatastoreAllocate::pool_allocate( string& error_str, RequestAttributes& att) { - string name = xmlrpc_c::value_string(paramList.getString(1)); - DatastorePool * dspool = static_cast(pool); - return dspool->allocate(name, &id, error_str); + DatastoreTemplate * ds_tmpl = static_cast(tmpl); + + return dspool->allocate(ds_tmpl, &id, error_str); } From d2ad28a9091a47cf3ae49f5a609a2ad74cd16538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 16 Feb 2012 20:17:36 +0100 Subject: [PATCH 023/217] Feature #1112: Use SYSTEM_DS values from oned.conf to create default DS --- include/DatastorePool.h | 4 +++- src/datastore/Datastore.cc | 6 ------ src/datastore/DatastorePool.cc | 24 +++++++++++++++++++----- src/nebula/Nebula.cc | 22 +++++++++++++++++++++- 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/include/DatastorePool.h b/include/DatastorePool.h index c01b35ad86..7dbf41913f 100644 --- a/include/DatastorePool.h +++ b/include/DatastorePool.h @@ -26,7 +26,9 @@ using namespace std; class DatastorePool : public PoolSQL { public: - DatastorePool(SqlDB * db); + DatastorePool(SqlDB * db, + const string& base_path, + const string& type); ~DatastorePool(){}; diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index d7d7628e31..d38fcb2731 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -14,12 +14,6 @@ /* limitations under the License. */ /* ------------------------------------------------------------------------ */ -#include -#include - -#include -#include - #include "Datastore.h" #include "GroupPool.h" #include "NebulaLog.h" diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index 2dcb64f1de..a3ac161634 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -32,7 +32,10 @@ const int DatastorePool::SYSTEM_DS_ID = 0; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -DatastorePool::DatastorePool(SqlDB * db):PoolSQL(db, Datastore::table) +DatastorePool::DatastorePool(SqlDB * db, + const string& base_path, + const string& type): + PoolSQL(db, Datastore::table) { ostringstream oss; string error_str; @@ -43,9 +46,20 @@ DatastorePool::DatastorePool(SqlDB * db):PoolSQL(db, Datastore::table) Datastore * ds; // Build the default datastore - // TODO: create template with default name, type and base path -/* - ds = new Datastore(SYSTEM_DS_ID, SYSTEM_DS_NAME); + + oss << "NAME = " << SYSTEM_DS_ID << endl + << "BASE_PATH = " << base_path << endl + << "TYPE = " << type; + + DatastoreTemplate * ds_tmpl = new DatastoreTemplate; + rc = ds_tmpl->parse_str_or_xml(oss.str(), error_str); + + if( rc < 0 ) + { + goto error_bootstrap; + } + + ds = new Datastore(-1, ds_tmpl); rc = PoolSQL::allocate(ds, error_str); @@ -53,7 +67,7 @@ DatastorePool::DatastorePool(SqlDB * db):PoolSQL(db, Datastore::table) { goto error_bootstrap; } -*/ + set_update_lastOID(99); } diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index bb2f1f6ebc..7e2a72e468 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -275,6 +275,10 @@ void Nebula::start() string default_device_prefix; time_t expiration_time; + vector system_ds; + string ds_base_path; + string ds_type; + vector vm_hooks; vector host_hooks; vector vm_restricted_attrs; @@ -313,7 +317,23 @@ void Nebula::start() tpool = new VMTemplatePool(db); - dspool = new DatastorePool(db); + rc = nebula_configuration->get("SYSTEM_DS", system_ds); + + if ( rc != 0 ) + { + string value; + const VectorAttribute * ds_conf = + static_cast(system_ds[0]); + + ds_base_path = ds_conf->vector_value("BASE_PATH"); + ds_type = ds_conf->vector_value("TYPE"); + } + else + { + throw runtime_error("Missing SYSTEM_DS configuration from oned.conf"); + } + + dspool = new DatastorePool(db, ds_base_path, ds_type); } catch (exception&) { From 90f8569f186152cb77420d3ce6e5bf51e4c5bc34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 17 Feb 2012 11:46:46 +0100 Subject: [PATCH 024/217] Feature #1112: Missing file DatastoreTemplate.h --- include/DatastoreTemplate.h | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 include/DatastoreTemplate.h diff --git a/include/DatastoreTemplate.h b/include/DatastoreTemplate.h new file mode 100644 index 0000000000..d8856dbe2f --- /dev/null +++ b/include/DatastoreTemplate.h @@ -0,0 +1,39 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#ifndef DATASTORE_TEMPLATE_H_ +#define DATASTORE_TEMPLATE_H_ + +#include "Template.h" + +using namespace std; + +/** + * Datastore Template class + */ +class DatastoreTemplate : public Template +{ +public: + DatastoreTemplate(): + Template(false,'=',"TEMPLATE"){}; + + ~DatastoreTemplate(){}; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +#endif /*DATASTORE_TEMPLATE_H_*/ From 2b50e27a66fe2db783a0062c693d756346ee6702 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 17 Feb 2012 11:54:08 +0100 Subject: [PATCH 025/217] feature #1112: Remove check for missing attribute (default always added) --- src/nebula/Nebula.cc | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index 7e2a72e468..043af6d6ae 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -317,21 +317,13 @@ void Nebula::start() tpool = new VMTemplatePool(db); - rc = nebula_configuration->get("SYSTEM_DS", system_ds); + nebula_configuration->get("SYSTEM_DS", system_ds); - if ( rc != 0 ) - { - string value; - const VectorAttribute * ds_conf = + const VectorAttribute * ds_conf = static_cast(system_ds[0]); - ds_base_path = ds_conf->vector_value("BASE_PATH"); - ds_type = ds_conf->vector_value("TYPE"); - } - else - { - throw runtime_error("Missing SYSTEM_DS configuration from oned.conf"); - } + ds_base_path = ds_conf->vector_value("BASE_PATH"); + ds_type = ds_conf->vector_value("TYPE"); dspool = new DatastorePool(db, ds_base_path, ds_type); } From b0063c0f80675aabd74e67d36788aa676c260cd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 17 Feb 2012 17:28:31 +0100 Subject: [PATCH 026/217] Feature #1112: WIP, Use XML data in image manager driver messages --- include/ImageManager.h | 11 ++++++++ include/ImageManagerDriver.h | 11 +++++--- src/image/ImageManagerActions.cc | 43 +++++++++++++++++++++++++++----- src/image/ImageManagerDriver.cc | 8 +++--- src/image_mad/one_image.rb | 32 ++++++++++++++++++++++-- 5 files changed, 90 insertions(+), 15 deletions(-) diff --git a/include/ImageManager.h b/include/ImageManager.h index 266ceea332..95c6b7887b 100644 --- a/include/ImageManager.h +++ b/include/ImageManager.h @@ -220,6 +220,17 @@ private: * @param source path of the disk file */ void move_image(Image *img, const string& source); + + /** + * Formats an XML message for the MAD + * + * @param img_data Image XML representation + * @param ds_data Datastore XML representation + * @return the XML message + */ + string * format_message( + const string& img_data, + const string& ds_data); }; #endif /*IMAGE_MANAGER_H*/ diff --git a/include/ImageManagerDriver.h b/include/ImageManagerDriver.h index 081c7bd31a..7840364844 100644 --- a/include/ImageManagerDriver.h +++ b/include/ImageManagerDriver.h @@ -70,7 +70,12 @@ private: */ //Template driver_conf; - void cp(int oid, const string& source) const; + /** + * Sends a copy request to the MAD + * @param oid the image id. + * @param drv_msg xml data for the mad operation. + */ + void cp(int oid, const string& drv_msg) const; /** * Sends a move request to the MAD: "MV IMAGE_ID SRC_PATH DST_PATH" @@ -93,9 +98,9 @@ private: /** * Sends a delete request to the MAD: "DELETE IMAGE_ID PATH" * @param oid the image id. - * @param destination is the path to the image to be removed + * @param drv_msg xml data for the mad operation. */ - void rm(int oid, const string& destination) const; + void rm(int oid, const string& drv_msg) const; }; /* -------------------------------------------------------------------------- */ diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index 6f4eab9833..f9a075bffc 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -17,6 +17,7 @@ #include "ImageManager.h" #include "NebulaLog.h" #include "ImagePool.h" +#include "SSLTools.h" /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -311,8 +312,10 @@ int ImageManager::enable_image(int iid, bool to_enable) int ImageManager::delete_image(int iid, const string& ds_data) { - Image * img; - string source; + Image * img; + string source; + string img_tmpl; + string * drv_msg; img = ipool->get(iid,true); @@ -350,6 +353,8 @@ int ImageManager::delete_image(int iid, const string& ds_data) return -1; } + drv_msg = format_message(img->to_xml(img_tmpl), ds_data); + source = img->get_source(); if (source.empty()) @@ -367,11 +372,13 @@ int ImageManager::delete_image(int iid, const string& ds_data) } else { - imd->rm(img->get_oid(),img->get_source()); + imd->rm(img->get_oid(), *drv_msg); } img->unlock(); + delete drv_msg; + return 0; } @@ -384,8 +391,11 @@ int ImageManager::register_image(int iid, const string& ds_data) ostringstream oss; Image * img; - - string path; + + string path; + string img_tmpl; + string * drv_msg; + if ( imd == 0 ) { @@ -400,6 +410,8 @@ int ImageManager::register_image(int iid, const string& ds_data) return -1; } + drv_msg = format_message(img->to_xml(img_tmpl), ds_data); + path = img->get_path(); if ( path.empty() == true ) //NO PATH -> USE SOURCE OR MKFS FOR DATABLOCK @@ -430,7 +442,7 @@ int ImageManager::register_image(int iid, const string& ds_data) } else //PATH -> COPY TO REPOSITORY AS SOURCE { - imd->cp(img->get_oid(), path); + imd->cp(img->get_oid(), *drv_msg); oss << "Copying " << path <<" to repository for image "<get_oid(); } @@ -438,9 +450,28 @@ int ImageManager::register_image(int iid, const string& ds_data) img->unlock(); + delete drv_msg; + return 0; } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +string * ImageManager::format_message( + const string& img_data, + const string& ds_data) +{ + ostringstream oss; + + oss << "" + << img_data + << ds_data + << ""; + + return SSLTools::base64_encode(oss.str()); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + diff --git a/src/image/ImageManagerDriver.cc b/src/image/ImageManagerDriver.cc index 7c1862fb65..5715636606 100644 --- a/src/image/ImageManagerDriver.cc +++ b/src/image/ImageManagerDriver.cc @@ -27,11 +27,11 @@ /* ************************************************************************** */ void ImageManagerDriver::cp(int oid, - const string& source) const + const string& drv_msg) const { ostringstream os; - os << "CP " << oid << " " << source << endl; + os << "CP " << oid << " " << drv_msg << endl; write(os); } @@ -63,11 +63,11 @@ void ImageManagerDriver::mkfs(int oid, /* -------------------------------------------------------------------------- */ -void ImageManagerDriver::rm(int oid, const string& destination) const +void ImageManagerDriver::rm(int oid, const string& drv_msg) const { ostringstream os; - os << "RM " << oid << " " << destination << endl; + os << "RM " << oid << " " << drv_msg << endl; write(os); } diff --git a/src/image_mad/one_image.rb b/src/image_mad/one_image.rb index b45a93df00..c481727894 100755 --- a/src/image_mad/one_image.rb +++ b/src/image_mad/one_image.rb @@ -33,6 +33,8 @@ $: << RUBY_LIB_LOCATION require "OpenNebulaDriver" require 'getoptlong' +require 'base64' +require 'rexml/document' # This class provides basic messaging and logging functionality # to implement Image Repository Drivers. A image repository driver @@ -86,11 +88,23 @@ class ImageDriver < OpenNebulaDriver do_image_action(id, ds, :mv, "'#{src}' '#{dst}' '#{id}'") end - def cp(id, ds, src) + def cp(id, drv_message) + data = decode(drv_message) +# TODO +# ds = data.elements['DATASTORE/DRIVER'].text + ds = "fs" + src = data.elements['IMAGE/PATH'].text + do_image_action(id, ds, :cp, "'#{src}' '#{id}'") end - def rm(id, ds, dst) + def rm(id, drv_message) + data = decode(drv_message) +# TODO +# ds = data.elements['DATASTORE/DRIVER'].text + ds = "fs" + dst = data.elements['IMAGE/SOURCE'].text + do_image_action(id, ds, :rm, "'#{dst}' '#{id}'") end @@ -124,6 +138,20 @@ class ImageDriver < OpenNebulaDriver send_message(ACTION[action], result, id, info) end + + # TODO: Move decode to OpenNebulaDriver ? + + # Decodes the encoded XML driver message received from the core + # + # @param [String] drv_message the driver message + # @return [REXML::Element] the root element of the decoded XML message + def decode(drv_message) + message = Base64.decode64(drv_message) + + xml_doc = REXML::Document.new(message) + + xml_doc.root + end end From 6bf0f08b9b03743035c0067a4660346b4e056ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 17 Feb 2012 19:38:11 +0100 Subject: [PATCH 027/217] Feature #1112: New default ACL rule, to allow any user to use any datastore --- src/acl/AclManager.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/acl/AclManager.cc b/src/acl/AclManager.cc index 8ffd997c8e..38d5e4886a 100644 --- a/src/acl/AclManager.cc +++ b/src/acl/AclManager.cc @@ -87,6 +87,15 @@ AclManager::AclManager(SqlDB * _db) : db(_db), lastOID(-1) PoolObjectSQL::HOST, AuthRequest::MANAGE, error_str); + + // Users in USERS can use any DATASTORE + // @1 DATASTORE/* USE + add_rule(AclRule::GROUP_ID | + 1, + AclRule::ALL_ID | + PoolObjectSQL::DATASTORE, + AuthRequest::USE, + error_str); } } From 621b8f1e76221daadb393c05da210afc1d276c85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 17 Feb 2012 19:41:15 +0100 Subject: [PATCH 028/217] Feature #1112: Fix default configuration for vector attributes --- src/nebula/NebulaTemplate.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nebula/NebulaTemplate.cc b/src/nebula/NebulaTemplate.cc index 7d76ddf089..22f9c729a5 100644 --- a/src/nebula/NebulaTemplate.cc +++ b/src/nebula/NebulaTemplate.cc @@ -138,7 +138,7 @@ void OpenNebulaTemplate::set_conf_default() vvalue.insert(make_pair("BACKEND","sqlite")); vattribute = new VectorAttribute("DB",vvalue); - conf_default.insert(make_pair(attribute->name(),vattribute)); + conf_default.insert(make_pair(vattribute->name(),vattribute)); //VNC_BASE_PORT value = "5900"; @@ -192,7 +192,7 @@ void OpenNebulaTemplate::set_conf_default() vvalue.insert(make_pair("TYPE","shared")); vattribute = new VectorAttribute("SYSTEM_DS",vvalue); - conf_default.insert(make_pair(attribute->name(),vattribute)); + conf_default.insert(make_pair(vattribute->name(),vattribute)); //DEFAULT_IMAGE_TYPE value = "OS"; From 3a8525bdc1c7d677f05a03e5581d76f91e889e92 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sun, 19 Feb 2012 02:08:03 +0100 Subject: [PATCH 029/217] feature #1112: Work on the datastore drivers: - Moved references to image_mad to datastore_mad. Adjusted installation dirs and source files - FS driver cp command uses DS_DRIVER_ACTION_DATA message - New libfs.sh to deal with datastore protocol - New xpath.rb to get XML elements in shell programs - Change oned.cong and OpenNebula core files to use DATASTORE instead of IMAGE - Change mkfs driver function to use the drv action data --- include/ImageManagerDriver.h | 7 +- install.sh | 42 ++++----- share/etc/oned.conf | 21 ++--- src/datastore/DatastorePool.cc | 4 +- .../one_image => datastore_mad/one_datastore} | 0 .../one_datastore.rb} | 65 ++++++-------- .../remotes/fs/cp | 26 +++--- .../remotes/fs/fs.conf | 6 +- .../remotes/fs/mkfs | 0 .../remotes/fs/mv | 0 .../remotes/fs/rm | 0 .../fsrc => datastore_mad/remotes/libfs.sh} | 88 ++++++++++++------- src/image/ImageManagerActions.cc | 5 +- src/image/ImageManagerDriver.cc | 6 +- src/nebula/Nebula.cc | 2 +- 15 files changed, 142 insertions(+), 130 deletions(-) rename src/{image_mad/one_image => datastore_mad/one_datastore} (100%) rename src/{image_mad/one_image.rb => datastore_mad/one_datastore.rb} (74%) rename src/{image_mad => datastore_mad}/remotes/fs/cp (84%) rename src/{image_mad => datastore_mad}/remotes/fs/fs.conf (91%) rename src/{image_mad => datastore_mad}/remotes/fs/mkfs (100%) rename src/{image_mad => datastore_mad}/remotes/fs/mv (100%) rename src/{image_mad => datastore_mad}/remotes/fs/rm (100%) rename src/{image_mad/remotes/fs/fsrc => datastore_mad/remotes/libfs.sh} (51%) diff --git a/include/ImageManagerDriver.h b/include/ImageManagerDriver.h index 7840364844..3319ebf717 100644 --- a/include/ImageManagerDriver.h +++ b/include/ImageManagerDriver.h @@ -89,12 +89,9 @@ private: /** * Sends a make filesystem request to the MAD: "MKFS IMAGE_ID PATH SIZE_MB" * @param oid the image id. - * @param fs type - * @param size_mb of the image to be created + * @param drv_msg xml data for the mad operation. */ - void mkfs(int oid, - const string& fs, - int size_mb) const; + void mkfs(int oid, const string& drv_msg) const; /** * Sends a delete request to the MAD: "DELETE IMAGE_ID PATH" * @param oid the image id. diff --git a/install.sh b/install.sh index 34e10d969d..58382bff88 100755 --- a/install.sh +++ b/install.sh @@ -99,7 +99,7 @@ if [ -z "$ROOT" ] ; then VAR_LOCATION="/var/lib/one" SUNSTONE_LOCATION="$LIB_LOCATION/sunstone" OZONES_LOCATION="$LIB_LOCATION/ozones" - IMAGES_LOCATION="$VAR_LOCATION/images" + SYSTEM_DS_LOCATION="$VAR_LOCATION/system_ds" RUN_LOCATION="/var/run/one" LOCK_LOCATION="/var/lock/one" INCLUDE_LOCATION="/usr/include" @@ -130,7 +130,7 @@ if [ -z "$ROOT" ] ; then MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $ETC_LOCATION $VAR_LOCATION \ $INCLUDE_LOCATION $SHARE_LOCATION \ $LOG_LOCATION $RUN_LOCATION $LOCK_LOCATION \ - $IMAGES_LOCATION $MAN_LOCATION" + $SYSTEM_DS_LOCATION $MAN_LOCATION" DELETE_DIRS="$LIB_LOCATION $ETC_LOCATION $LOG_LOCATION $VAR_LOCATION \ $RUN_LOCATION $SHARE_DIRS" @@ -145,7 +145,7 @@ else VAR_LOCATION="$ROOT/var" SUNSTONE_LOCATION="$LIB_LOCATION/sunstone" OZONES_LOCATION="$LIB_LOCATION/ozones" - IMAGES_LOCATION="$VAR_LOCATION/images" + SYSTEM_DS_LOCATION="$VAR_LOCATION/system_ds" INCLUDE_LOCATION="$ROOT/include" SHARE_LOCATION="$ROOT/share" MAN_LOCATION="$ROOT/share/man/man1" @@ -166,7 +166,7 @@ else DELETE_DIRS="$MAKE_DIRS" else MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $ETC_LOCATION $VAR_LOCATION \ - $INCLUDE_LOCATION $SHARE_LOCATION $IMAGES_LOCATION \ + $INCLUDE_LOCATION $SHARE_LOCATION $SYSTEM_DS_LOCATION \ $MAN_LOCATION $OZONES_LOCATION" DELETE_DIRS="$MAKE_DIRS" @@ -180,7 +180,7 @@ fi SHARE_DIRS="$SHARE_LOCATION/examples \ $SHARE_LOCATION/examples/tm" -ETC_DIRS="$ETC_LOCATION/image \ +ETC_DIRS="$ETC_LOCATION/datastore \ $ETC_LOCATION/im_ec2 \ $ETC_LOCATION/vmm_ec2 \ $ETC_LOCATION/vmm_exec \ @@ -385,7 +385,8 @@ INSTALL_FILES=( VMWARE_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/vmware DUMMY_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/dummy LVM_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/lvm - IMAGE_DRIVER_FS_SCRIPTS:$VAR_LOCATION/remotes/datastore/fs + DATASTORE_DRIVER_COMMON_SCRIPTS:$VAR_LOCATION/remotes/datastore/ + DATASTORE_DRIVER_FS_SCRIPTS:$VAR_LOCATION/remotes/datastore/fs NETWORK_FILES:$VAR_LOCATION/remotes/vnm NETWORK_8021Q_FILES:$VAR_LOCATION/remotes/vnm/802.1Q NETWORK_DUMMY_FILES:$VAR_LOCATION/remotes/vnm/dummy @@ -524,7 +525,7 @@ INSTALL_ETC_FILES=( VMWARE_ETC_FILES:$ETC_LOCATION VMM_EC2_ETC_FILES:$ETC_LOCATION/vmm_ec2 VMM_EXEC_ETC_FILES:$ETC_LOCATION/vmm_exec - IMAGE_DRIVER_FS_ETC_FILES:$ETC_LOCATION/image/ + DATASTORE_DRIVER_FS_ETC_FILES:$ETC_LOCATION/datastore/ IM_EC2_ETC_FILES:$ETC_LOCATION/im_ec2 TM_SHARED_ETC_FILES:$ETC_LOCATION/tm_shared TM_SSH_ETC_FILES:$ETC_LOCATION/tm_ssh @@ -628,8 +629,8 @@ MADS_LIB_FILES="src/mad/sh/madcommon.sh \ src/hm_mad/one_hm \ src/authm_mad/one_auth_mad.rb \ src/authm_mad/one_auth_mad \ - src/image_mad/one_image.rb \ - src/image_mad/one_image" + src/datastore_mad/one_datastore.rb \ + src/datastore_mad/one_datastore" #------------------------------------------------------------------------------- # VMM SH Driver KVM scripts, to be installed under $REMOTES_LOCATION/vmm/kvm @@ -795,18 +796,19 @@ VMWARE_TM_COMMANDS_LIB_FILES="src/tm_mad/vmware/tm_clone.sh \ src/tm_mad/vmware/tm_context.sh" #------------------------------------------------------------------------------- -# Image Repository drivers, to be installed under $REMOTES_LOCATION/image -# - FS based Image Repository, $REMOTES_LOCATION/image/fs +# Datastore drivers, to be installed under $REMOTES_LOCATION/datastore +# - FS based Image Repository, $REMOTES_LOCATION/datastore/fs #------------------------------------------------------------------------------- -IMAGE_DRIVER_FS_ETC_FILES="src/image_mad/remotes/fs/fs.conf" +DATASTORE_DRIVER_FS_ETC_FILES="src/datastore_mad/remotes/fs/fs.conf" -IMAGE_DRIVER_FS_SCRIPTS="src/image_mad/remotes/fs/cp \ - src/image_mad/remotes/fs/mkfs \ - src/image_mad/remotes/fs/mv \ - src/image_mad/remotes/fs/fsrc \ - src/image_mad/remotes/fs/rm" +DATASTORE_DRIVER_COMMON_SCRIPTS="src/datastore_mad/remotes/xpath.rb \ + src/datastore_mad/remotes/libfs.sh" +DATASTORE_DRIVER_FS_SCRIPTS="src/datastore_mad/remotes/fs/cp \ + src/datastore_mad/remotes/fs/mkfs \ + src/datastore_mad/remotes/fs/mv \ + src/datastore_mad/remotes/fs/rm" #------------------------------------------------------------------------------- # Migration scripts for onedb command, to be installed under $LIB_LOCATION @@ -1505,12 +1507,6 @@ if [ "$UNINSTALL" = "no" ] ; then for d in $CHOWN_DIRS; do chown -R $ONEADMIN_USER:$ONEADMIN_GROUP $DESTDIR$d done - - # --- Set correct permissions for Image Repository --- - - if [ -d "$DESTDIR$IMAGES_LOCATION" ]; then - chmod 3770 $DESTDIR$IMAGES_LOCATION - fi else for d in `echo $DELETE_DIRS | awk '{for (i=NF;i>=1;i--) printf $i" "}'`; do rmdir $d diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 431b641fe1..11165c0d6c 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -107,7 +107,7 @@ MAC_PREFIX = "02:00" SYSTEM_DS = [ base_path = "/var/lib/one/system_ds", - type = "shared" + type = "fs" ] DEFAULT_IMAGE_TYPE = "OS" @@ -336,23 +336,21 @@ TM_MAD = [ #------------------------------------------------------------------------------- #******************************************************************************* -# Image Manager Driver Configuration +# Datastore Driver Configuration #******************************************************************************* -# Drivers to manage the image repository, specialized for the storage backend +# Drivers to manage the datastores, specialized for the storage backend # executable: path of the transfer driver executable, can be an # absolute path or relative to $ONE_LOCATION/lib/mads (or # /usr/lib/one/mads/ if OpenNebula was installed in /) # # arguments : for the driver executable +# -t number of threads, i.e. number of repo operations at the same time +# -d datastore types separated by commas #******************************************************************************* -#------------------------------------------------------------------------------- -# FS based Image Manager Driver Configuration -# -t number of threads, i.e. number of repo operations at the same time -#------------------------------------------------------------------------------- -IMAGE_MAD = [ - executable = "one_image", + +DATASTORE_MAD = [ + executable = "one_datastore", arguments = "-t 15 -d fs" ] -#------------------------------------------------------------------------------- #******************************************************************************* # Hook Manager Configuration @@ -389,7 +387,6 @@ IMAGE_MAD = [ # allocated # - NO, The hook is executed in the OpenNebula server (default) # -# # Host Hooks (HOST_HOOK) defined by: # name : for the hook, useful to track the hook (OPTIONAL) # on : when the hook should be executed, @@ -408,10 +405,8 @@ IMAGE_MAD = [ # - YES, The hook is executed in the host # - NO, The hook is executed in the OpenNebula server (default) #------------------------------------------------------------------------------- - HM_MAD = [ executable = "one_hm" ] - #------------------------------------------------------------------------------- #******************************************************************************* diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index a3ac161634..64f4470f64 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -47,8 +47,8 @@ DatastorePool::DatastorePool(SqlDB * db, // Build the default datastore - oss << "NAME = " << SYSTEM_DS_ID << endl - << "BASE_PATH = " << base_path << endl + oss << "NAME = " << SYSTEM_DS_NAME << endl + << "BASE_PATH = " << base_path << endl << "TYPE = " << type; DatastoreTemplate * ds_tmpl = new DatastoreTemplate; diff --git a/src/image_mad/one_image b/src/datastore_mad/one_datastore similarity index 100% rename from src/image_mad/one_image rename to src/datastore_mad/one_datastore diff --git a/src/image_mad/one_image.rb b/src/datastore_mad/one_datastore.rb similarity index 74% rename from src/image_mad/one_image.rb rename to src/datastore_mad/one_datastore.rb index c481727894..dc00fcb5a4 100755 --- a/src/image_mad/one_image.rb +++ b/src/datastore_mad/one_datastore.rb @@ -37,10 +37,10 @@ require 'base64' require 'rexml/document' # This class provides basic messaging and logging functionality -# to implement Image Repository Drivers. A image repository driver +# to implement Datastore Drivers. A datastore driver # is a program (or a set of) that specialize the OpenNebula behavior # by interfacing with specific infrastructure storage solutions. -class ImageDriver < OpenNebulaDriver +class DatastoreDriver < OpenNebulaDriver # Image Driver Protocol constants ACTION = { @@ -77,39 +77,33 @@ class ImageDriver < OpenNebulaDriver @types = ds_type end - register_action(ACTION[:mv].to_sym, method("mv")) +# register_action(ACTION[:mv].to_sym, method("mv")) register_action(ACTION[:cp].to_sym, method("cp")) register_action(ACTION[:rm].to_sym, method("rm")) register_action(ACTION[:mkfs].to_sym, method("mkfs")) end - # Image Manager Protocol Actions (generic implementation - def mv(id, ds, src, dst) - do_image_action(id, ds, :mv, "'#{src}' '#{dst}' '#{id}'") - end + ############################################################################ + # Image Manager Protocol Actions (generic implementation) + ############################################################################ +# TODO: Integrate this with TM +# def mv(id, ds, src, dst) +# do_image_action(id, ds, :mv, "'#{src}' '#{dst}' '#{id}'") +# end def cp(id, drv_message) - data = decode(drv_message) -# TODO -# ds = data.elements['DATASTORE/DRIVER'].text - ds = "fs" - src = data.elements['IMAGE/PATH'].text - - do_image_action(id, ds, :cp, "'#{src}' '#{id}'") + ds = get_ds_type(drv_message) + do_image_action(id, ds, :cp, "#{drv_message} #{id}") end def rm(id, drv_message) - data = decode(drv_message) -# TODO -# ds = data.elements['DATASTORE/DRIVER'].text - ds = "fs" - dst = data.elements['IMAGE/SOURCE'].text - - do_image_action(id, ds, :rm, "'#{dst}' '#{id}'") + ds = get_ds_type(drv_message) + do_image_action(id, ds, :rm, "#{drv_message} #{id}") end - def mkfs(id, ds, fs, size) - do_image_action(id, ds, :mkfs, "'#{fs}' '#{size}' '#{id}'") + def mkfs(id, drv_message) + ds = get_ds_type(drv_message) + do_image_action(id, ds, :mkfs, "#{drv_message} #{id}") end private @@ -139,23 +133,22 @@ class ImageDriver < OpenNebulaDriver send_message(ACTION[action], result, id, info) end - # TODO: Move decode to OpenNebulaDriver ? - - # Decodes the encoded XML driver message received from the core - # - # @param [String] drv_message the driver message - # @return [REXML::Element] the root element of the decoded XML message - def decode(drv_message) + def get_ds_type(drv_message) message = Base64.decode64(drv_message) - xml_doc = REXML::Document.new(message) - xml_doc.root + dsxml = xml_doc.root.elements['/DS_DRIVER_ACTION_DATA/DATASTORE/TYPE'] + dstxt = dsxml.text if dsxml + + return dstxt end end - -# ImageDriver Main program +################################################################################ +################################################################################ +# DatastoreDriver Main program +################################################################################ +################################################################################ opts = GetoptLong.new( [ '--threads', '-t', GetoptLong::OPTIONAL_ARGUMENT ], @@ -178,5 +171,5 @@ rescue Exception => e exit(-1) end -image_driver = ImageDriver.new(ds_type, :concurrency => threads) -image_driver.start_driver +ds_driver = DatastoreDriver.new(ds_type, :concurrency => threads) +ds_driver.start_driver diff --git a/src/image_mad/remotes/fs/cp b/src/datastore_mad/remotes/fs/cp similarity index 84% rename from src/image_mad/remotes/fs/cp rename to src/datastore_mad/remotes/fs/cp index 808f028a78..712381f0c2 100755 --- a/src/image_mad/remotes/fs/cp +++ b/src/datastore_mad/remotes/fs/cp @@ -30,10 +30,20 @@ else fi . $LIB_LOCATION/sh/scripts_common.sh -source $(dirname $0)/fsrc -SRC=$1 +DRIVER_PATH=$(dirname $0) +source ${DRIVER_PATH}/../libfs.sh + +# -------- Get cp and datastore arguments from OpenNebula core ------------ + +DRV_ACTION=$1 ID=$2 + +set_up_datastore $DRV_ACTION + +XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" +eval "SRC=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/PATH`" + DST=`generate_image_path` # ------------ Copy the image to the repository ------------- @@ -42,8 +52,7 @@ case $SRC in http://*) log "Downloading $SRC to the image repository" - exec_and_log "$WGET -O $DST $SRC" \ - "Error downloading $SRC" + exec_and_log "$WGET -O $DST $SRC" "Error downloading $SRC" exec_and_log "chmod 0660 $DST" ;; @@ -59,8 +68,7 @@ vmware://*) log "Copying local disk folder $SRC to the image repository" - exec_and_log "cp -rf $SRC $DST" \ - "Error copying $SRC to $DST" + exec_and_log "cp -rf $SRC $DST" "Error copying $SRC to $DST" if [ ! -f $DST/disk.vmdk ]; then BASE_DISK_FILE=`ls $DST | grep -v '.*-s[0-9]*\.vmdk'` @@ -81,15 +89,13 @@ vmware://*) log "Copying local image $SRC to the image repository" - exec_and_log "cp -f $SRC $DST" \ - "Error copying $SRC to $DST" + exec_and_log "cp -f $SRC $DST" "Error copying $SRC to $DST" exec_and_log "chmod 0660 $DST" ;; esac -# ---------------- Get the size of the image & fix perms ------------ - +# ---------------- Get the size of the image ------------ SIZE=`fs_du $DST` diff --git a/src/image_mad/remotes/fs/fs.conf b/src/datastore_mad/remotes/fs/fs.conf similarity index 91% rename from src/image_mad/remotes/fs/fs.conf rename to src/datastore_mad/remotes/fs/fs.conf index 6cb6cfdb8b..ec29989e22 100644 --- a/src/image_mad/remotes/fs/fs.conf +++ b/src/datastore_mad/remotes/fs/fs.conf @@ -17,9 +17,9 @@ # PRESERVE BASH SYNTAX #******************************************************************************* -# Configuration File for File-System based Image Repositories +# DEFAULT Configuration File for File-System based Datastores #------------------------------------------------------------------------------- -# IMAGE_REPOSITORY: Path where the images will be stored. If not defined +# BASE_PATH: Path where the images will be stored. If not defined # defaults to /var/lib/one/images or $ONE_LOCATION/var/images # # RESTRICTED_DIRS: Paths that can not be used to register images. A space @@ -31,7 +31,7 @@ # of paths.This will allow you to open specific paths within RESTRICTED_DIRS #******************************************************************************* -#IMAGE_REPOSITORY_PATH=/var/lib/one/images +#BASE_PATH=/var/lib/one/images RESTRICTED_DIRS="/etc/" diff --git a/src/image_mad/remotes/fs/mkfs b/src/datastore_mad/remotes/fs/mkfs similarity index 100% rename from src/image_mad/remotes/fs/mkfs rename to src/datastore_mad/remotes/fs/mkfs diff --git a/src/image_mad/remotes/fs/mv b/src/datastore_mad/remotes/fs/mv similarity index 100% rename from src/image_mad/remotes/fs/mv rename to src/datastore_mad/remotes/fs/mv diff --git a/src/image_mad/remotes/fs/rm b/src/datastore_mad/remotes/fs/rm similarity index 100% rename from src/image_mad/remotes/fs/rm rename to src/datastore_mad/remotes/fs/rm diff --git a/src/image_mad/remotes/fs/fsrc b/src/datastore_mad/remotes/libfs.sh similarity index 51% rename from src/image_mad/remotes/fs/fsrc rename to src/datastore_mad/remotes/libfs.sh index 4693bd1c75..0490a0e78a 100644 --- a/src/image_mad/remotes/fs/fsrc +++ b/src/datastore_mad/remotes/libfs.sh @@ -17,52 +17,73 @@ #--------------------------------------------------------------------------- # #------------------------------------------------------------------------------ -# Configuration File for File-System based Image Repositories -# - IMAGE_REPOSITORY: Path where the images will be stored -# - RESTRICTED_DIRS: Paths that can not be used to register images -# - SAFE_DIRS: Paths that are safe to specify image paths +# Set up environment variables +# @param $1 - template (base 64 encoded) with driver data +# @return sets the following environment variables +# - RESTRICTED_DIRS: Paths that can not be used to register images +# - SAFE_DIRS: Paths that are safe to specify image paths +# - BASE_PATH: Path where the images will be stored #------------------------------------------------------------------------------ -if [ -z "${ONE_LOCATION}" ]; then - VAR_LOCATION=/var/lib/one/ - ETC_LOCATION=/etc/one/ -else - VAR_LOCATION=$ONE_LOCATION/var/ - ETC_LOCATION=$ONE_LOCATION/etc/ -fi - -CONF_FILE=$ETC_LOCATION/image/fs.conf - -source $CONF_FILE - -if [ -z "${IMAGE_REPOSITORY_PATH}" ]; then +function set_up_datastore { + # + # Load the default configuration for FS datastores + # if [ -z "${ONE_LOCATION}" ]; then - IMAGE_REPOSITORY_PATH=/var/lib/one/images + VAR_LOCATION=/var/lib/one/ + ETC_LOCATION=/etc/one/ else - IMAGE_REPOSITORY_PATH=$ONE_LOCATION/var/images + VAR_LOCATION=$ONE_LOCATION/var/ + ETC_LOCATION=$ONE_LOCATION/etc/ fi -fi -RESTRICTED_DIRS="$VAR_LOCATION $ETC_LOCATION $HOME/ $RESTRICTED_DIRS" + CONF_FILE=$ETC_LOCATION/datastore/fs.conf -export IMAGE_REPOSITORY_PATH -export RESTRICTED_DIRS -export SAFE_DIRS + source $CONF_FILE -#------------------------------------------------------------------------------ -# Function used to generate Image names, you should not need to override this -#------------------------------------------------------------------------------ + # + # Load attributes from the Datastore + # + XPATH="$VAR_LOCATION/remotes/datastore/xpath.rb -b $1" + eval "DS_BASE_PATH=`$XPATH /DS_DRIVER_ACTION_DATA/DATASTORE/BASE_PATH`" + + if [ -z "${DS_BASE_PATH}" ]; then + if [ -z "${BASE_PATH}" ]; then + BASE_PATH="${VAR_LOCATION}/images" + fi + else + BASE_PATH=${DS_BASE_PATH} + fi + + # + # RESTRICTED AND SAFE DIRS (from default configuration) + # + RESTRICTED_DIRS="$VAR_LOCATION $ETC_LOCATION $HOME/ $RESTRICTED_DIRS" + + export BASE_PATH + export RESTRICTED_DIRS + export SAFE_DIRS +} + +#------------------------------------------------------------------------------- +# Generates an unique image path. Requires BASE_PATH to be set +# @return path for the image (empty if error) +#------------------------------------------------------------------------------- function generate_image_path { -CANONICAL_STR="`$DATE +%s`:$ID" + CANONICAL_STR="`$DATE +%s`:$ID" -CANONICAL_MD5=$($MD5SUM - << EOF + CANONICAL_MD5=$($MD5SUM - << EOF $CANONICAL_STR EOF ) - -echo "$IMAGE_REPOSITORY_PATH/`echo $CANONICAL_MD5 | cut -d ' ' -f1`" + echo "${BASE_PATH}/`echo $CANONICAL_MD5 | cut -d ' ' -f1`" } +#------------------------------------------------------------------------------- +# Computes the size of an image +# @param $1 - Path to the image +# @return size of the image in Mb +#------------------------------------------------------------------------------- function fs_du { if [ -d "$1" ]; then SIZE=`du -s "$1" | cut -f1` @@ -81,6 +102,11 @@ function fs_du { echo "$SIZE" } +#------------------------------------------------------------------------------- +# Checks if a path is safe for copying the image from +# @param $1 - Path to the image +# @return 0 if the path is safe, 1 otherwise +#------------------------------------------------------------------------------- function check_restricted { for path in $SAFE_DIRS ; do if [ -n "`readlink -f $1 | grep -E "^$path"`" ] ; then diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index f9a075bffc..8b4307e5b2 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -411,8 +411,7 @@ int ImageManager::register_image(int iid, const string& ds_data) } drv_msg = format_message(img->to_xml(img_tmpl), ds_data); - - path = img->get_path(); + path = img->get_path(); if ( path.empty() == true ) //NO PATH -> USE SOURCE OR MKFS FOR DATABLOCK { @@ -421,7 +420,7 @@ int ImageManager::register_image(int iid, const string& ds_data) string fs = img->get_fstype(); int size = img->get_size(); - imd->mkfs(img->get_oid(), fs, size); + imd->mkfs(img->get_oid(), *drv_msg); oss << "Creating disk at " << img->get_source() << " of " << size << "Mb with format " << fs; diff --git a/src/image/ImageManagerDriver.cc b/src/image/ImageManagerDriver.cc index 5715636606..c04f5ff565 100644 --- a/src/image/ImageManagerDriver.cc +++ b/src/image/ImageManagerDriver.cc @@ -52,12 +52,12 @@ void ImageManagerDriver::mv(int oid, /* -------------------------------------------------------------------------- */ void ImageManagerDriver::mkfs(int oid, - const string& fs, - int size_mb) const + const string& drv_msg) const { ostringstream os; - os << "MKFS " << oid << " " << fs << " " << size_mb << endl; + os << "MKFS " << oid << " " << drv_msg << endl; + write(os); } diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index 043af6d6ae..2be815f846 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -561,7 +561,7 @@ void Nebula::start() { vector image_mads; - nebula_configuration->get("IMAGE_MAD", image_mads); + nebula_configuration->get("DATASTORE_MAD", image_mads); imagem = new ImageManager(ipool,image_mads); } From 1540124721e784808061da59d12ff64114d7771f Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Mon, 20 Feb 2012 13:42:50 +0100 Subject: [PATCH 030/217] feature #1112: Added missing file --- src/datastore_mad/remotes/xpath.rb | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100755 src/datastore_mad/remotes/xpath.rb diff --git a/src/datastore_mad/remotes/xpath.rb b/src/datastore_mad/remotes/xpath.rb new file mode 100755 index 0000000000..dad2f13ce6 --- /dev/null +++ b/src/datastore_mad/remotes/xpath.rb @@ -0,0 +1,55 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- */ +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# Licensed under the Apache License, Version 2.0 (the "License"); you may */ +# not use this file except in compliance with the License. You may obtain */ +# a copy of the License at */ +# */ +# http://www.apache.org/licenses/LICENSE-2.0 */ +# */ +# Unless required by applicable law or agreed to in writing, software */ +# distributed under the License is distributed on an "AS IS" BASIS, */ +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +# See the License for the specific language governing permissions and */ +# limitations under the License. */ +# -------------------------------------------------------------------------- */ + +# +# Simple command to parse an XML document (b64 encoded) and return one or more +# elements (refer by xpath) +# +require 'base64' +require 'rexml/document' +require 'getoptlong' + +opts = opts = GetoptLong.new( + [ '--base64', '-b', GetoptLong::REQUIRED_ARGUMENT ] +) + +tmp64 = "" + +begin + opts.each do |opt, arg| + case opt + when '--base64' + tmp64 = arg + end + end +rescue Exception => e + exit(-1) +end + +values = "" + +tmp = Base64::decode64(tmp64) +xml = REXML::Document.new(tmp).root + +ARGV.each { |xpath| + element = xml.elements[xpath] + values << "\'#{element.text}\' " if !element.nil? +} + +puts values + +exit 0 From 867c8380c071ecef82e95542e892d3d8b749f455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 20 Feb 2012 15:41:47 +0100 Subject: [PATCH 031/217] Feature #1112: Update rm and mkfs scripts to use datastore info --- src/datastore_mad/remotes/fs/mkfs | 21 +++++++++++++++------ src/datastore_mad/remotes/fs/rm | 14 +++++++++++--- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/datastore_mad/remotes/fs/mkfs b/src/datastore_mad/remotes/fs/mkfs index 5f49c6e8f2..a1dc19fb81 100755 --- a/src/datastore_mad/remotes/fs/mkfs +++ b/src/datastore_mad/remotes/fs/mkfs @@ -21,7 +21,7 @@ # as (FS) ############################################################################### -# ------------ Set up the environment to source common tools ------------ +# -------- Set up the environment to source common tools & conf ------------ if [ -z "${ONE_LOCATION}" ]; then LIB_LOCATION=/usr/lib/one @@ -30,16 +30,25 @@ else fi . $LIB_LOCATION/sh/scripts_common.sh -source $(dirname $0)/fsrc -# ------------ Create the image to the repository ------------ +DRIVER_PATH=$(dirname $0) +source ${DRIVER_PATH}/../libfs.sh -FSTYPE=$1 -SIZE=$2 -ID=$3 +# -------- Get mkfs and datastore arguments from OpenNebula core ------------ + +DRV_ACTION=$1 +ID=$2 + +set_up_datastore $DRV_ACTION + +XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" +eval "FSTYPE=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/FSTYPE`" +eval "SIZE=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/SIZE`" DST=`generate_image_path` +# ------------ Create the image to the repository ------------ + MKFS_CMD=`mkfs_command $DST $FSTYPE` exec_and_log "$DD if=/dev/zero of=$DST bs=1 count=1 seek=${SIZE}M" \ diff --git a/src/datastore_mad/remotes/fs/rm b/src/datastore_mad/remotes/fs/rm index 4517caeecf..d915786ea4 100755 --- a/src/datastore_mad/remotes/fs/rm +++ b/src/datastore_mad/remotes/fs/rm @@ -29,11 +29,19 @@ else fi . $LIB_LOCATION/sh/scripts_common.sh -source $(dirname $0)/fsrc -# ------------ Remove the image to the repository ------------ +DRIVER_PATH=$(dirname $0) +source ${DRIVER_PATH}/../libfs.sh -SRC=$1 +# -------- Get rm and datastore arguments from OpenNebula core ------------ + +DRV_ACTION=$1 +ID=$2 + +XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" +eval "SRC=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/SOURCE`" + +# ------------ Remove the image from the repository ------------ if [ -e $SRC ] ; then log "Removing $SRC from the image repository" From 30f981e92fb00472a21cc3d963a645500f0972bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 20 Feb 2012 18:51:56 +0100 Subject: [PATCH 032/217] Feature #1112: Fix error message for missing TYPE in datastore creation --- src/datastore/Datastore.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index d38fcb2731..4ae45fabe6 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -92,7 +92,7 @@ int Datastore::insert(SqlDB *db, string& error_str) return rc; error_type: - error_str = "No NAME in template."; + error_str = "No TYPE in template."; goto error_common; error_base_path: From a107c22734bd95dfaac0923659f913273ac6cfc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 20 Feb 2012 20:10:30 +0100 Subject: [PATCH 033/217] Feature #1112: New datastore drivers for vmware --- install.sh | 11 +++ share/etc/oned.conf | 4 +- src/datastore_mad/remotes/fs/cp | 23 ------ src/datastore_mad/remotes/vmware/cp | 86 ++++++++++++++++++++ src/datastore_mad/remotes/vmware/mkfs | 63 ++++++++++++++ src/datastore_mad/remotes/vmware/mv | 75 +++++++++++++++++ src/datastore_mad/remotes/vmware/rm | 50 ++++++++++++ src/datastore_mad/remotes/vmware/vmware.conf | 38 +++++++++ 8 files changed, 326 insertions(+), 24 deletions(-) create mode 100755 src/datastore_mad/remotes/vmware/cp create mode 100755 src/datastore_mad/remotes/vmware/mkfs create mode 100755 src/datastore_mad/remotes/vmware/mv create mode 100755 src/datastore_mad/remotes/vmware/rm create mode 100644 src/datastore_mad/remotes/vmware/vmware.conf diff --git a/install.sh b/install.sh index 58382bff88..7053997a0e 100755 --- a/install.sh +++ b/install.sh @@ -237,6 +237,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \ $VAR_LOCATION/remotes/hooks/ft \ $VAR_LOCATION/remotes/datastore \ $VAR_LOCATION/remotes/datastore/fs \ + $VAR_LOCATION/remotes/datastore/vmware \ $VAR_LOCATION/remotes/auth \ $VAR_LOCATION/remotes/auth/plain \ $VAR_LOCATION/remotes/auth/ssh \ @@ -387,6 +388,7 @@ INSTALL_FILES=( LVM_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/lvm DATASTORE_DRIVER_COMMON_SCRIPTS:$VAR_LOCATION/remotes/datastore/ DATASTORE_DRIVER_FS_SCRIPTS:$VAR_LOCATION/remotes/datastore/fs + DATASTORE_DRIVER_VMWARE_SCRIPTS:$VAR_LOCATION/remotes/datastore/vmware NETWORK_FILES:$VAR_LOCATION/remotes/vnm NETWORK_8021Q_FILES:$VAR_LOCATION/remotes/vnm/802.1Q NETWORK_DUMMY_FILES:$VAR_LOCATION/remotes/vnm/dummy @@ -526,6 +528,7 @@ INSTALL_ETC_FILES=( VMM_EC2_ETC_FILES:$ETC_LOCATION/vmm_ec2 VMM_EXEC_ETC_FILES:$ETC_LOCATION/vmm_exec DATASTORE_DRIVER_FS_ETC_FILES:$ETC_LOCATION/datastore/ + DATASTORE_DRIVER_VMWARE_ETC_FILES:$ETC_LOCATION/datastore/ IM_EC2_ETC_FILES:$ETC_LOCATION/im_ec2 TM_SHARED_ETC_FILES:$ETC_LOCATION/tm_shared TM_SSH_ETC_FILES:$ETC_LOCATION/tm_ssh @@ -798,10 +801,13 @@ VMWARE_TM_COMMANDS_LIB_FILES="src/tm_mad/vmware/tm_clone.sh \ #------------------------------------------------------------------------------- # Datastore drivers, to be installed under $REMOTES_LOCATION/datastore # - FS based Image Repository, $REMOTES_LOCATION/datastore/fs +# - VMware based Image Repository, $REMOTES_LOCATION/datastore/vmware #------------------------------------------------------------------------------- DATASTORE_DRIVER_FS_ETC_FILES="src/datastore_mad/remotes/fs/fs.conf" +DATASTORE_DRIVER_VMWARE_ETC_FILES="src/datastore_mad/remotes/vmware/vmware.conf" + DATASTORE_DRIVER_COMMON_SCRIPTS="src/datastore_mad/remotes/xpath.rb \ src/datastore_mad/remotes/libfs.sh" @@ -810,6 +816,11 @@ DATASTORE_DRIVER_FS_SCRIPTS="src/datastore_mad/remotes/fs/cp \ src/datastore_mad/remotes/fs/mv \ src/datastore_mad/remotes/fs/rm" +DATASTORE_DRIVER_VMWARE_SCRIPTS="src/datastore_mad/remotes/vmware/cp \ + src/datastore_mad/remotes/vmware/mkfs \ + src/datastore_mad/remotes/vmware/mv \ + src/datastore_mad/remotes/vmware/rm" + #------------------------------------------------------------------------------- # Migration scripts for onedb command, to be installed under $LIB_LOCATION #------------------------------------------------------------------------------- diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 11165c0d6c..c75a729a38 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -350,7 +350,9 @@ TM_MAD = [ DATASTORE_MAD = [ executable = "one_datastore", - arguments = "-t 15 -d fs" ] + arguments = "-t 15 -d fs" +# arguments = "-t 15 -d fs,vmware" +] #******************************************************************************* # Hook Manager Configuration diff --git a/src/datastore_mad/remotes/fs/cp b/src/datastore_mad/remotes/fs/cp index 712381f0c2..73e5dafaa6 100755 --- a/src/datastore_mad/remotes/fs/cp +++ b/src/datastore_mad/remotes/fs/cp @@ -57,29 +57,6 @@ http://*) exec_and_log "chmod 0660 $DST" ;; -vmware://*) - SRC=`echo $SRC|sed 's/vmware:\/\///g'` - - if [ `check_restricted $SRC` -eq 1 ]; then - log_error "Not allowed to copy images from $RESTRICTED_DIRS" - error_message "Not allowed to copy image file $SRC" - exit -1 - fi - - log "Copying local disk folder $SRC to the image repository" - - exec_and_log "cp -rf $SRC $DST" "Error copying $SRC to $DST" - - if [ ! -f $DST/disk.vmdk ]; then - BASE_DISK_FILE=`ls $DST | grep -v '.*-s[0-9]*\.vmdk'` - - exec_and_log "mv -f $DST/$BASE_DISK_FILE $DST/disk.vmdk" \ - "Error renaming disk file $BASE_DISK_FILE to disk.vmdk" - fi - - exec_and_log "chmod 0770 $DST" - ;; - *) if [ `check_restricted $SRC` -eq 1 ]; then log_error "Not allowed to copy images from $RESTRICTED_DIRS" diff --git a/src/datastore_mad/remotes/vmware/cp b/src/datastore_mad/remotes/vmware/cp new file mode 100755 index 0000000000..c449d1b1ce --- /dev/null +++ b/src/datastore_mad/remotes/vmware/cp @@ -0,0 +1,86 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +############################################################################### +# This script is used to copy a VM image (SRC) to the image repository as DST +# Several SRC types are supported +############################################################################### + +# -------- Set up the environment to source common tools & conf ------------ + +if [ -z "${ONE_LOCATION}" ]; then + LIB_LOCATION=/usr/lib/one +else + LIB_LOCATION=$ONE_LOCATION/lib +fi + +. $LIB_LOCATION/sh/scripts_common.sh + +DRIVER_PATH=$(dirname $0) +source ${DRIVER_PATH}/../libfs.sh + +# -------- Get cp and datastore arguments from OpenNebula core ------------ + +DRV_ACTION=$1 +ID=$2 + +set_up_datastore $DRV_ACTION + +XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" +eval "SRC=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/PATH`" + +DST=`generate_image_path` + +# ------------ Copy the image to the repository ------------- + +case $SRC in +http://*) + log "Downloading $SRC to the image repository" + + exec_and_log "$WGET -O $DST $SRC" "Error downloading $SRC" + + exec_and_log "chmod 0660 $DST" + ;; + +*) + if [ `check_restricted $SRC` -eq 1 ]; then + log_error "Not allowed to copy images from $RESTRICTED_DIRS" + error_message "Not allowed to copy image file $SRC" + exit -1 + fi + + log "Copying local disk folder $SRC to the image repository" + + exec_and_log "cp -rf $SRC $DST" "Error copying $SRC to $DST" + + if [ ! -f $DST/disk.vmdk ]; then + BASE_DISK_FILE=`ls $DST | grep -v '.*-s[0-9]*\.vmdk'` + + exec_and_log "mv -f $DST/$BASE_DISK_FILE $DST/disk.vmdk" \ + "Error renaming disk file $BASE_DISK_FILE to disk.vmdk" + fi + + exec_and_log "chmod 0770 $DST" + ;; +esac + +# ---------------- Get the size of the image ------------ + +SIZE=`fs_du $DST` + +echo "$DST $SIZE" diff --git a/src/datastore_mad/remotes/vmware/mkfs b/src/datastore_mad/remotes/vmware/mkfs new file mode 100755 index 0000000000..a1dc19fb81 --- /dev/null +++ b/src/datastore_mad/remotes/vmware/mkfs @@ -0,0 +1,63 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +############################################################################### +# This script is used to create a VM image (SRC) of size (SIZE) and formatted +# as (FS) +############################################################################### + +# -------- Set up the environment to source common tools & conf ------------ + +if [ -z "${ONE_LOCATION}" ]; then + LIB_LOCATION=/usr/lib/one +else + LIB_LOCATION=$ONE_LOCATION/lib +fi + +. $LIB_LOCATION/sh/scripts_common.sh + +DRIVER_PATH=$(dirname $0) +source ${DRIVER_PATH}/../libfs.sh + +# -------- Get mkfs and datastore arguments from OpenNebula core ------------ + +DRV_ACTION=$1 +ID=$2 + +set_up_datastore $DRV_ACTION + +XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" +eval "FSTYPE=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/FSTYPE`" +eval "SIZE=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/SIZE`" + +DST=`generate_image_path` + +# ------------ Create the image to the repository ------------ + +MKFS_CMD=`mkfs_command $DST $FSTYPE` + +exec_and_log "$DD if=/dev/zero of=$DST bs=1 count=1 seek=${SIZE}M" \ + "Could not create image $DST" +exec_and_log "$MKFS_CMD" \ + "Unable to create filesystem $FSTYPE in $DST" +exec_and_log "chmod 0660 $DST" + +# ---------------- Get the size of the image ------------ +SIZE=`fs_du $DST` + +echo "$DST $SIZE" diff --git a/src/datastore_mad/remotes/vmware/mv b/src/datastore_mad/remotes/vmware/mv new file mode 100755 index 0000000000..8ea2259a28 --- /dev/null +++ b/src/datastore_mad/remotes/vmware/mv @@ -0,0 +1,75 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +############################################################################### +# This script is used to move a VM image (SRC) to the image repository as DST +# Several SRC types are supported +############################################################################### + +# ------------ Set up the environment to source common tools ------------ + +if [ -z "${ONE_LOCATION}" ]; then + LIB_LOCATION=/usr/lib/one +else + LIB_LOCATION=$ONE_LOCATION/lib +fi + +. $LIB_LOCATION/sh/scripts_common.sh +source $(dirname $0)/fsrc + +SRC=$1 +DST=$2 +ID=$3 + +# ------------ Generate a filename for the image ------------ + +if [ "$DST" = "-" ] ; then + DST=`generate_image_path` +fi + +# ------------ Move the image to the repository ------------ + +case $SRC in +http://*) + log "Downloading $SRC to the image repository" + exec_and_log "$WGET -O $DST $SRC" \ + "Error downloading $SRC" + ;; + +*) + log "Moving local image $SRC to the image repository" + + if [ \( -L $SRC \) -a \ + \( "`$READLINK -f $SRC`" = "`$READLINK -f $DST`" \) ] ; then + log "Not moving files to image repo, they are the same" + else + exec_and_log "mv -f $SRC $DST" "Could not move $SRC to $DST" + fi + ;; +esac + +if [ -d $DST ]; then + exec_and_log "chmod 0770 $DST" +else + exec_and_log "chmod 0660 $DST" +fi + +# ---------------- Get the size of the image ------------ +SIZE=`fs_du $DST` + +echo "$DST $SIZE" diff --git a/src/datastore_mad/remotes/vmware/rm b/src/datastore_mad/remotes/vmware/rm new file mode 100755 index 0000000000..d915786ea4 --- /dev/null +++ b/src/datastore_mad/remotes/vmware/rm @@ -0,0 +1,50 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +############################################################################### +# This script is used to remove a VM image (SRC) from the image repository +############################################################################### + +# ------------ Set up the environment to source common tools ------------ + +if [ -z "${ONE_LOCATION}" ]; then + LIB_LOCATION=/usr/lib/one +else + LIB_LOCATION=$ONE_LOCATION/lib +fi + +. $LIB_LOCATION/sh/scripts_common.sh + +DRIVER_PATH=$(dirname $0) +source ${DRIVER_PATH}/../libfs.sh + +# -------- Get rm and datastore arguments from OpenNebula core ------------ + +DRV_ACTION=$1 +ID=$2 + +XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" +eval "SRC=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/SOURCE`" + +# ------------ Remove the image from the repository ------------ + +if [ -e $SRC ] ; then + log "Removing $SRC from the image repository" + exec_and_log "rm -r $SRC" \ + "Error deleting $SRC" +fi diff --git a/src/datastore_mad/remotes/vmware/vmware.conf b/src/datastore_mad/remotes/vmware/vmware.conf new file mode 100644 index 0000000000..ec29989e22 --- /dev/null +++ b/src/datastore_mad/remotes/vmware/vmware.conf @@ -0,0 +1,38 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +# PRESERVE BASH SYNTAX + +#******************************************************************************* +# DEFAULT Configuration File for File-System based Datastores +#------------------------------------------------------------------------------- +# BASE_PATH: Path where the images will be stored. If not defined +# defaults to /var/lib/one/images or $ONE_LOCATION/var/images +# +# RESTRICTED_DIRS: Paths that can not be used to register images. A space +# separated list of paths. This prevents users to access important files like +# oned.db or /etc/shadow. OpenNebula will automatically add its configuration +# dirs:/var/lib/one, /etc/one and oneadmin's home ($HOME). +# +# SAFE_DIRS: Paths that are safe to specify image paths. A space separated list +# of paths.This will allow you to open specific paths within RESTRICTED_DIRS +#******************************************************************************* + +#BASE_PATH=/var/lib/one/images + +RESTRICTED_DIRS="/etc/" + +SAFE_DIRS="$HOME/public/" From 8f348955763dd6d2d4b08b4521fafd4194371db5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 20 Feb 2012 20:48:52 +0100 Subject: [PATCH 034/217] Feature #1112: Add base path and type to onedatastore output --- src/cli/one_helper/onedatastore_helper.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index 4c642e818b..5f117a6885 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -64,8 +64,10 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper str_h1="%-80s" CLIHelper.print_header(str_h1 % "DATASTORE #{datastore['ID']} INFORMATION") - puts str % ["ID", datastore.id.to_s] - puts str % ["NAME", datastore.name] + puts str % ["ID", datastore.id.to_s] + puts str % ["NAME", datastore.name] + puts str % ["TYPE", datastore['TYPE']] + puts str % ["BASE PATH",datastore['BASE_PATH']] puts CLIHelper.print_header(str_h1 % "IMAGES", false) From 546b6c8a4e889c11db669fd1969e06acd30cfd39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 22 Feb 2012 12:19:47 +0100 Subject: [PATCH 035/217] Feature #1112: Restrict image creation on system DS. Create new default DS --- include/DatastorePool.h | 20 ++++++++++++--- install.sh | 6 +++-- share/etc/oned.conf | 5 ++++ src/datastore/DatastorePool.cc | 43 ++++++++++++++++++++++++++------ src/nebula/Nebula.cc | 25 ++++++++++++++----- src/nebula/NebulaTemplate.cc | 10 +++++++- src/rm/RequestManagerAllocate.cc | 14 ++++++++++- 7 files changed, 102 insertions(+), 21 deletions(-) diff --git a/include/DatastorePool.h b/include/DatastorePool.h index 7dbf41913f..3d68f48f97 100644 --- a/include/DatastorePool.h +++ b/include/DatastorePool.h @@ -27,8 +27,10 @@ class DatastorePool : public PoolSQL { public: DatastorePool(SqlDB * db, - const string& base_path, - const string& type); + const string& system_base_path, + const string& system_type, + const string& default_base_path, + const string& default_type); ~DatastorePool(){}; @@ -37,15 +39,25 @@ public: /* ---------------------------------------------------------------------- */ /** - * Default name for the oneadmin group + * Name for the system datastore */ static const string SYSTEM_DS_NAME; /** - * Identifier for the oneadmin group + * Identifier for the system datastore */ static const int SYSTEM_DS_ID; + /** + * Name for the default datastore + */ + static const string DEFAULT_DS_NAME; + + /** + * Identifier for the default datastore + */ + static const int DEFAULT_DS_ID; + /* ---------------------------------------------------------------------- */ /* Methods for DB management */ /* ---------------------------------------------------------------------- */ diff --git a/install.sh b/install.sh index 7053997a0e..30f20afa67 100755 --- a/install.sh +++ b/install.sh @@ -100,6 +100,7 @@ if [ -z "$ROOT" ] ; then SUNSTONE_LOCATION="$LIB_LOCATION/sunstone" OZONES_LOCATION="$LIB_LOCATION/ozones" SYSTEM_DS_LOCATION="$VAR_LOCATION/system_ds" + DEFAULT_DS_LOCATION="$VAR_LOCATION/images" RUN_LOCATION="/var/run/one" LOCK_LOCATION="/var/lock/one" INCLUDE_LOCATION="/usr/include" @@ -130,7 +131,7 @@ if [ -z "$ROOT" ] ; then MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $ETC_LOCATION $VAR_LOCATION \ $INCLUDE_LOCATION $SHARE_LOCATION \ $LOG_LOCATION $RUN_LOCATION $LOCK_LOCATION \ - $SYSTEM_DS_LOCATION $MAN_LOCATION" + $SYSTEM_DS_LOCATION $DEFAULT_DS_LOCATION $MAN_LOCATION" DELETE_DIRS="$LIB_LOCATION $ETC_LOCATION $LOG_LOCATION $VAR_LOCATION \ $RUN_LOCATION $SHARE_DIRS" @@ -146,6 +147,7 @@ else SUNSTONE_LOCATION="$LIB_LOCATION/sunstone" OZONES_LOCATION="$LIB_LOCATION/ozones" SYSTEM_DS_LOCATION="$VAR_LOCATION/system_ds" + DEFAULT_DS_LOCATION="$VAR_LOCATION/images" INCLUDE_LOCATION="$ROOT/include" SHARE_LOCATION="$ROOT/share" MAN_LOCATION="$ROOT/share/man/man1" @@ -167,7 +169,7 @@ else else MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $ETC_LOCATION $VAR_LOCATION \ $INCLUDE_LOCATION $SHARE_LOCATION $SYSTEM_DS_LOCATION \ - $MAN_LOCATION $OZONES_LOCATION" + $DEFAULT_DS_LOCATION $MAN_LOCATION $OZONES_LOCATION" DELETE_DIRS="$MAKE_DIRS" diff --git a/share/etc/oned.conf b/share/etc/oned.conf index c75a729a38..fb762b4b21 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -110,6 +110,11 @@ SYSTEM_DS = [ type = "fs" ] +DEFAULT_DS = [ + base_path = "/var/lib/one/images", + type = "fs" +] + DEFAULT_IMAGE_TYPE = "OS" DEFAULT_DEVICE_PREFIX = "hd" diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index 64f4470f64..d5e9644cdf 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -29,12 +29,17 @@ const string DatastorePool::SYSTEM_DS_NAME = "system"; const int DatastorePool::SYSTEM_DS_ID = 0; +const string DatastorePool::DEFAULT_DS_NAME = "default"; +const int DatastorePool::DEFAULT_DS_ID = 1; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ DatastorePool::DatastorePool(SqlDB * db, - const string& base_path, - const string& type): + const string& system_base_path, + const string& system_type, + const string& default_base_path, + const string& default_type): PoolSQL(db, Datastore::table) { ostringstream oss; @@ -44,14 +49,38 @@ DatastorePool::DatastorePool(SqlDB * db, { int rc; Datastore * ds; + DatastoreTemplate * ds_tmpl; - // Build the default datastore + // Build the default datastores - oss << "NAME = " << SYSTEM_DS_NAME << endl - << "BASE_PATH = " << base_path << endl - << "TYPE = " << type; + oss << "NAME = " << SYSTEM_DS_NAME << endl + << "BASE_PATH = " << system_base_path << endl + << "TYPE = " << system_type; - DatastoreTemplate * ds_tmpl = new DatastoreTemplate; + ds_tmpl = new DatastoreTemplate; + rc = ds_tmpl->parse_str_or_xml(oss.str(), error_str); + + if( rc < 0 ) + { + goto error_bootstrap; + } + + ds = new Datastore(-1, ds_tmpl); + + rc = PoolSQL::allocate(ds, error_str); + + if( rc < 0 ) + { + goto error_bootstrap; + } + + oss.str(""); + + oss << "NAME = " << DEFAULT_DS_NAME << endl + << "BASE_PATH = " << default_base_path << endl + << "TYPE = " << default_type; + + ds_tmpl = new DatastoreTemplate; rc = ds_tmpl->parse_str_or_xml(oss.str(), error_str); if( rc < 0 ) diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index 2be815f846..f414535537 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -276,8 +276,12 @@ void Nebula::start() time_t expiration_time; vector system_ds; - string ds_base_path; - string ds_type; + string system_ds_base_path; + string system_ds_type; + + vector default_ds; + string default_ds_base_path; + string default_ds_type; vector vm_hooks; vector host_hooks; @@ -319,13 +323,22 @@ void Nebula::start() nebula_configuration->get("SYSTEM_DS", system_ds); - const VectorAttribute * ds_conf = + const VectorAttribute * ds_conf = static_cast(system_ds[0]); - ds_base_path = ds_conf->vector_value("BASE_PATH"); - ds_type = ds_conf->vector_value("TYPE"); + system_ds_base_path = ds_conf->vector_value("BASE_PATH"); + system_ds_type = ds_conf->vector_value("TYPE"); - dspool = new DatastorePool(db, ds_base_path, ds_type); + nebula_configuration->get("DEFAULT_DS", default_ds); + + ds_conf = static_cast(default_ds[0]); + + default_ds_base_path = ds_conf->vector_value("BASE_PATH"); + default_ds_type = ds_conf->vector_value("TYPE"); + + dspool = new DatastorePool(db, + system_ds_base_path, system_ds_type, + default_ds_base_path, default_ds_type); } catch (exception&) { diff --git a/src/nebula/NebulaTemplate.cc b/src/nebula/NebulaTemplate.cc index 22f9c729a5..96a0a89c53 100644 --- a/src/nebula/NebulaTemplate.cc +++ b/src/nebula/NebulaTemplate.cc @@ -189,11 +189,19 @@ void OpenNebulaTemplate::set_conf_default() //SYSTEM_DS vvalue.clear(); vvalue.insert(make_pair("BASE_PATH","/var/lib/one/system_ds")); - vvalue.insert(make_pair("TYPE","shared")); + vvalue.insert(make_pair("TYPE","fs")); vattribute = new VectorAttribute("SYSTEM_DS",vvalue); conf_default.insert(make_pair(vattribute->name(),vattribute)); + //DEFAULT_DS + vvalue.clear(); + vvalue.insert(make_pair("BASE_PATH","/var/lib/one/images")); + vvalue.insert(make_pair("TYPE","fs")); + + vattribute = new VectorAttribute("DEFAULT_DS",vvalue); + conf_default.insert(make_pair(vattribute->name(),vattribute)); + //DEFAULT_IMAGE_TYPE value = "OS"; diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 79a02672d7..8ec46bc581 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -189,7 +189,7 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, ImageTemplate * tmpl = new ImageTemplate; Datastore * ds; - // ------------------------- Prase image template -------------------------- + // ------------------------- Parse image template -------------------------- rc = tmpl->parse_str_or_xml(str_tmpl, error_str); @@ -203,6 +203,18 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, // ------------------------- Check Datastore exists ------------------------ + if ( ds_id == DatastorePool::SYSTEM_DS_ID ) + { + ostringstream oss; + + oss << "New Images cannot be allocated in the system " + << object_name(PoolObjectSQL::DATASTORE) << " [" << ds_id << "]."; + failure_response(INTERNAL, allocate_error(oss.str()), att); + + delete tmpl; + return; + } + if ((ds = dspool->get(ds_id,true)) == 0 ) { failure_response(NO_EXISTS, From 98c5c246c26c7ef4367d2eea2dac368e8b64caeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 22 Feb 2012 16:01:30 +0100 Subject: [PATCH 036/217] Feature #1112: Do not use host's TM_MAD --- include/History.h | 4 +-- include/Host.h | 9 ------ include/RequestManagerVirtualMachine.h | 3 +- include/VirtualMachine.h | 23 +------------- src/rm/RequestManagerVirtualMachine.cc | 15 +++------ src/tm/TransferManager.cc | 44 +++++++++++++++++++------- src/vm/History.cc | 7 +--- src/vm/VirtualMachine.cc | 11 +++---- 8 files changed, 45 insertions(+), 71 deletions(-) diff --git a/include/History.h b/include/History.h index 4541e58ab7..f2551d8e08 100644 --- a/include/History.h +++ b/include/History.h @@ -46,8 +46,7 @@ public: const string& hostname, const string& vm_dir, const string& vmm, - const string& vnm, - const string& tm); + const string& vnm); ~History(){}; @@ -93,7 +92,6 @@ private: string vmm_mad_name; string vnm_mad_name; - string tm_mad_name; time_t stime; time_t etime; diff --git a/include/Host.h b/include/Host.h index 8df66d9ae8..5bcad871f6 100644 --- a/include/Host.h +++ b/include/Host.h @@ -139,15 +139,6 @@ public: return vnm_mad_name; }; - /** - * Retrives TM mad name - * @return string tm mad name - */ - const string& get_tm_mad() const - { - return tm_mad_name; - }; - /** * Retrives IM mad name * @return string im mad name diff --git a/include/RequestManagerVirtualMachine.h b/include/RequestManagerVirtualMachine.h index 8776f6e03f..89355b1999 100644 --- a/include/RequestManagerVirtualMachine.h +++ b/include/RequestManagerVirtualMachine.h @@ -52,14 +52,13 @@ protected: RequestAttributes& att, PoolObjectAuth* host_perms); int get_host_information(int hid, string& name, string& vmm, string& vnm, - string& tm, RequestAttributes& att, PoolObjectAuth& host_perms); + RequestAttributes& att, PoolObjectAuth& host_perms); int add_history(VirtualMachine * vm, int hid, const string& hostname, const string& vmm_mad, const string& vnm_mad, - const string& tm_mad, RequestAttributes& att); VirtualMachine * get_vm(int id, RequestAttributes& att); diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 8df9a9bf9a..18212b469e 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -217,8 +217,7 @@ public: const string& hostname, const string& vm_dir, const string& vmm_mad, - const string& vnm_mad, - const string& tm_mad); + const string& vnm_mad); /** * Duplicates the last history record. Only the host related fields are @@ -294,26 +293,6 @@ public: return previous_history->vnm_mad_name; }; - /** - * Returns the TM driver name for the current host. The hasHistory() - * function MUST be called before this one. - * @return the TM mad name - */ - const string & get_tm_mad() const - { - return history->tm_mad_name; - }; - - /** - * Returns the TM driver name for the previous host. The - * hasPreviousHistory() function MUST be called before this one. - * @return the TM mad name - */ - const string & get_previous_tm_mad() const - { - return previous_history->tm_mad_name; - }; - /** * Returns the transfer filename. The transfer file is in the form: * $ONE_LOCATION/var/$VM_ID/transfer.$SEQ diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index b58d86cc0e..6ac5af3280 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -83,7 +83,6 @@ int RequestManagerVirtualMachine::get_host_information(int hid, string& name, string& vmm, string& vnm, - string& tm, RequestAttributes& att, PoolObjectAuth& host_perms) { @@ -106,7 +105,6 @@ int RequestManagerVirtualMachine::get_host_information(int hid, name = host->get_name(); vmm = host->get_vmm_mad(); vnm = host->get_vnm_mad(); - tm = host->get_tm_mad(); host->get_permissions(host_perms); @@ -141,7 +139,6 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm, const string& hostname, const string& vmm_mad, const string& vnm_mad, - const string& tm_mad, RequestAttributes& att) { Nebula& nd = Nebula::instance(); @@ -153,7 +150,7 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm, nd.get_configuration_attribute("VM_DIR",vmdir); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad); + vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); @@ -278,14 +275,13 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList, string hostname; string vmm_mad; string vnm_mad; - string tm_mad; int id = xmlrpc_c::value_int(paramList.getInt(1)); int hid = xmlrpc_c::value_int(paramList.getInt(2)); bool auth = false; - if (get_host_information(hid,hostname,vmm_mad,vnm_mad,tm_mad, att, host_perms) != 0) + if (get_host_information(hid,hostname,vmm_mad,vnm_mad,att, host_perms) != 0) { return; } @@ -312,7 +308,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList, return; } - if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,tm_mad,att) != 0) + if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,att) != 0) { vm->unlock(); return; @@ -340,7 +336,6 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList string hostname; string vmm_mad; string vnm_mad; - string tm_mad; int id = xmlrpc_c::value_int(paramList.getInt(1)); int hid = xmlrpc_c::value_int(paramList.getInt(2)); @@ -348,7 +343,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList bool auth = false; - if (get_host_information(hid,hostname,vmm_mad,vnm_mad,tm_mad, att, host_perms) != 0) + if (get_host_information(hid,hostname,vmm_mad,vnm_mad,att, host_perms) != 0) { return; } @@ -377,7 +372,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList return; } - if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,tm_mad,att) != 0) + if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,att) != 0) { vm->unlock(); return; diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index 1b19f759d4..62f143de04 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -236,7 +236,9 @@ void TransferManager::prolog_action(int vid) goto error_history; } - tm_md = get(vm->get_tm_mad()); + // TODO: get tm_md from somewhere... +// tm_md = get(vm->get_tm_mad()); + tm_md = 0; if ( tm_md == 0 ) { @@ -416,7 +418,8 @@ error_file: error_driver: os.str(""); - os << "prolog, error getting driver " << vm->get_tm_mad(); + // TODO +// os << "prolog, error getting driver " << vm->get_tm_mad(); goto error_common; error_empty_disk: @@ -463,7 +466,9 @@ void TransferManager::prolog_migr_action(int vid) goto error_history; } - tm_md = get(vm->get_tm_mad()); + // TODO: get tm_md from somewhere... +// tm_md = get(vm->get_tm_mad()); + tm_md = 0; if ( tm_md == 0 ) { @@ -506,7 +511,8 @@ error_file: error_driver: os.str(""); - os << "prolog_migr, error getting driver " << vm->get_tm_mad(); + // TODO +// os << "prolog_migr, error getting driver " << vm->get_tm_mad(); error_common: (nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid); @@ -547,7 +553,9 @@ void TransferManager::prolog_resume_action(int vid) goto error_history; } - tm_md = get(vm->get_tm_mad()); + // TODO: get tm_md from somewhere... +// tm_md = get(vm->get_tm_mad()); + tm_md = 0; if ( tm_md == 0 ) { @@ -590,7 +598,8 @@ error_file: error_driver: os.str(""); - os << "prolog_resume, error getting driver " << vm->get_tm_mad(); + // TODO +// os << "prolog_resume, error getting driver " << vm->get_tm_mad(); error_common: (nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid); @@ -637,7 +646,9 @@ void TransferManager::epilog_action(int vid) goto error_history; } - tm_md = get(vm->get_tm_mad()); + // TODO: get tm_md from somewhere... +// tm_md = get(vm->get_tm_mad()); + tm_md = 0; if ( tm_md == 0 ) { @@ -748,7 +759,9 @@ void TransferManager::epilog_stop_action(int vid) goto error_history; } - tm_md = get(vm->get_tm_mad()); + // TODO: get tm_md from somewhere... +// tm_md = get(vm->get_tm_mad()); + tm_md = 0; if ( tm_md == 0 ) { @@ -791,7 +804,8 @@ error_file: error_driver: os.str(""); - os << "epilog_stop, error getting driver " << vm->get_tm_mad(); + // TODO +// os << "epilog_stop, error getting driver " << vm->get_tm_mad(); error_common: (nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid); @@ -831,7 +845,9 @@ void TransferManager::epilog_delete_action(int vid) goto error_history; } - tm_md = get(vm->get_tm_mad()); + // TODO: get tm_md from somewhere... +// tm_md = get(vm->get_tm_mad()); + tm_md = 0; if ( tm_md == 0 ) { @@ -914,7 +930,9 @@ void TransferManager::epilog_delete_previous_action(int vid) goto error_history; } - tm_md = get(vm->get_previous_tm_mad()); + // TODO: get tm_md from somewhere... +// tm_md = get(vm->get_previous_tm_mad()); + tm_md = 0; if ( tm_md == 0 ) { @@ -998,7 +1016,9 @@ void TransferManager::driver_cancel_action(int vid) goto error_history; } - tm_md = get(vm->get_tm_mad()); + // TODO: get tm_md from somewhere... +// tm_md = get(vm->get_tm_mad()); + tm_md = 0; if ( tm_md == 0 ) { diff --git a/src/vm/History.cc b/src/vm/History.cc index 520f527fcc..d2ffd04c98 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -44,7 +44,6 @@ History::History( hid(-1), vmm_mad_name(""), vnm_mad_name(""), - tm_mad_name(""), stime(0), etime(0), prolog_stime(0), @@ -64,8 +63,7 @@ History::History( const string& _hostname, const string& _vm_dir, const string& _vmm, - const string& _vnm, - const string& _tm): + const string& _vnm): oid(_oid), seq(_seq), hostname(_hostname), @@ -73,7 +71,6 @@ History::History( hid(_hid), vmm_mad_name(_vmm), vnm_mad_name(_vnm), - tm_mad_name(_tm), stime(0), etime(0), prolog_stime(0), @@ -271,7 +268,6 @@ string& History::to_xml(string& xml) const "" << etime << "" << "" << vmm_mad_name << ""<< "" << vnm_mad_name << ""<< - "" << tm_mad_name << "" << "" << prolog_stime << ""<< "" << prolog_etime << ""<< "" << running_stime << ""<< @@ -302,7 +298,6 @@ int History::rebuild_attributes() rc += xpath(etime , "/HISTORY/ETIME", 0); rc += xpath(vmm_mad_name , "/HISTORY/VMMMAD", "not_found"); xpath(vnm_mad_name , "/HISTORY/VNMMAD", "dummy"); - rc += xpath(tm_mad_name , "/HISTORY/TMMAD", "not_found"); rc += xpath(prolog_stime , "/HISTORY/PSTIME", 0); rc += xpath(prolog_etime , "/HISTORY/PETIME", 0); rc += xpath(running_stime, "/HISTORY/RSTIME", 0); diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 49b2575054..1a36291100 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -605,8 +605,7 @@ void VirtualMachine::add_history( const string& hostname, const string& vm_dir, const string& vmm_mad, - const string& vnm_mad, - const string& tm_mad) + const string& vnm_mad) { ostringstream os; int seq; @@ -622,7 +621,7 @@ void VirtualMachine::add_history( previous_history = history; } - history = new History(oid,seq,hid,hostname,vm_dir,vmm_mad,vnm_mad,tm_mad); + history = new History(oid,seq,hid,hostname,vm_dir,vmm_mad,vnm_mad); history_records.push_back(history); }; @@ -645,8 +644,7 @@ void VirtualMachine::cp_history() history->hostname, history->vm_dir, history->vmm_mad_name, - history->vnm_mad_name, - history->tm_mad_name); + history->vnm_mad_name); previous_history = history; @@ -673,8 +671,7 @@ void VirtualMachine::cp_previous_history() previous_history->hostname, previous_history->vm_dir, previous_history->vmm_mad_name, - previous_history->vnm_mad_name, - previous_history->tm_mad_name); + previous_history->vnm_mad_name); previous_history = history; history = htmp; From 1e63b6ce4ec59d96ffa8476e68384cd118fc41ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 22 Feb 2012 18:22:41 +0100 Subject: [PATCH 037/217] Feature #1112: Add TM_MAD to Datastores --- include/Datastore.h | 27 +++++++++++++++++++++++++-- include/DatastorePool.h | 4 +++- share/etc/oned.conf | 6 ++++-- src/datastore/Datastore.cc | 31 ++++++++++++++++++++++++++++++- src/datastore/DatastorePool.cc | 11 ++++++++--- src/image/ImagePool.cc | 23 +++++++++++++++++++---- src/nebula/Nebula.cc | 8 ++++++-- src/nebula/NebulaTemplate.cc | 6 ++++-- 8 files changed, 99 insertions(+), 17 deletions(-) diff --git a/include/Datastore.h b/include/Datastore.h index 8bce2ed79a..df9f2df319 100644 --- a/include/Datastore.h +++ b/include/Datastore.h @@ -51,7 +51,7 @@ public: int add_image(int id) { return add_collection_id(id); - } + }; /** * Deletes this image's ID from the set. @@ -61,7 +61,25 @@ public: int del_image(int id) { return del_collection_id(id); - } + }; + + /** + * Retrieves TM mad name + * @return string tm mad name + */ + const string& get_tm_mad() const + { + return tm_mad; + }; + + /** + * Modifies the given VM disk attribute adding the relevant datastore + * attributes + * + * @param disk + * @return 0 on success + */ + int disk_attribute(VectorAttribute * disk); private: @@ -80,6 +98,11 @@ private: */ string type; + /** + * Name of the TM driver used to transfer file to and from the hosts + */ + string tm_mad; + /** * Base path for the storage */ diff --git a/include/DatastorePool.h b/include/DatastorePool.h index 3d68f48f97..da9bf3aacc 100644 --- a/include/DatastorePool.h +++ b/include/DatastorePool.h @@ -29,8 +29,10 @@ public: DatastorePool(SqlDB * db, const string& system_base_path, const string& system_type, + const string& system_tm_mad, const string& default_base_path, - const string& default_type); + const string& default_type, + const string& default_tm_mad); ~DatastorePool(){}; diff --git a/share/etc/oned.conf b/share/etc/oned.conf index fb762b4b21..d99bea70ba 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -107,12 +107,14 @@ MAC_PREFIX = "02:00" SYSTEM_DS = [ base_path = "/var/lib/one/system_ds", - type = "fs" + type = "fs", + tm_mad = "tm_shared" ] DEFAULT_DS = [ base_path = "/var/lib/one/images", - type = "fs" + type = "fs", + tm_mad = "tm_shared" ] DEFAULT_IMAGE_TYPE = "OS" diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index 4ae45fabe6..a6bfe8e1ea 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -38,6 +38,7 @@ Datastore::Datastore(int id, PoolObjectSQL(id,DATASTORE,"",-1,-1,"","",table), ObjectCollection("IMAGES"), type(""), + tm_mad(""), base_path("") { if (ds_template != 0) @@ -50,6 +51,22 @@ Datastore::Datastore(int id, } } +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +int Datastore::disk_attribute(VectorAttribute * disk) +{ + ostringstream oss; + + oss << oid; + + disk->replace("DATASTORE", get_name()); + disk->replace("DATASTORE_ID", oss.str()); + disk->replace("TM_MAD", get_tm_mad()); + + return 0; +} + /* ************************************************************************ */ /* Datastore :: Database Access Functions */ /* ************************************************************************ */ @@ -65,7 +82,6 @@ int Datastore::insert(SqlDB *db, string& error_str) // Check default datastore attributes // --------------------------------------------------------------------- - erase_template_attribute("NAME", name); // NAME is checked in DatastorePool::allocate @@ -76,6 +92,13 @@ int Datastore::insert(SqlDB *db, string& error_str) goto error_type; } + erase_template_attribute("TM_MAD", tm_mad); + + if ( tm_mad.empty() == true ) + { + goto error_tm; + } + erase_template_attribute("BASE_PATH", base_path); if ( base_path.empty() == true ) @@ -95,6 +118,10 @@ error_type: error_str = "No TYPE in template."; goto error_common; +error_tm: + error_str = "No TM_MAD in template."; + goto error_common; + error_base_path: error_str = "No BASE_PATH in template."; goto error_common; @@ -207,6 +234,7 @@ string& Datastore::to_xml(string& xml) const "" << oid << "" << "" << name << "" << "" << type << "" << + "" << tm_mad << "" << "" << base_path << "" << collection_xml << ""; @@ -231,6 +259,7 @@ int Datastore::from_xml(const string& xml) rc += xpath(oid, "/DATASTORE/ID", -1); rc += xpath(name, "/DATASTORE/NAME", "not_found"); rc += xpath(type, "/DATASTORE/TYPE", "not_found"); + rc += xpath(tm_mad, "/DATASTORE/TM_MAD", "not_found"); rc += xpath(base_path, "/DATASTORE/BASE_PATH", "not_found"); // Set the owner and group to oneadmin diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index d5e9644cdf..f2f96da820 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -38,8 +38,10 @@ const int DatastorePool::DEFAULT_DS_ID = 1; DatastorePool::DatastorePool(SqlDB * db, const string& system_base_path, const string& system_type, + const string& system_tm_mad, const string& default_base_path, - const string& default_type): + const string& default_type, + const string& default_tm_mad): PoolSQL(db, Datastore::table) { ostringstream oss; @@ -55,7 +57,8 @@ DatastorePool::DatastorePool(SqlDB * db, oss << "NAME = " << SYSTEM_DS_NAME << endl << "BASE_PATH = " << system_base_path << endl - << "TYPE = " << system_type; + << "TYPE = " << system_type << endl + << "TM_MAD = " << system_tm_mad; ds_tmpl = new DatastoreTemplate; rc = ds_tmpl->parse_str_or_xml(oss.str(), error_str); @@ -78,7 +81,8 @@ DatastorePool::DatastorePool(SqlDB * db, oss << "NAME = " << DEFAULT_DS_NAME << endl << "BASE_PATH = " << default_base_path << endl - << "TYPE = " << default_type; + << "TYPE = " << default_type << endl + << "TM_MAD = " << default_tm_mad; ds_tmpl = new DatastoreTemplate; rc = ds_tmpl->parse_str_or_xml(oss.str(), error_str); @@ -103,6 +107,7 @@ DatastorePool::DatastorePool(SqlDB * db, return; error_bootstrap: + oss.str(""); oss << "Error trying to create default datastore: " << error_str; NebulaLog::log("DATASTORE",Log::ERROR,oss); diff --git a/src/image/ImagePool.cc b/src/image/ImagePool.cc index 2f7275cf22..1845fc5e13 100644 --- a/src/image/ImagePool.cc +++ b/src/image/ImagePool.cc @@ -221,11 +221,14 @@ int ImagePool::disk_attribute(VectorAttribute * disk, string source; Image * img = 0; int rc = 0; + int datastore_id; ostringstream oss; - Nebula& nd = Nebula::instance(); - ImageManager * imagem = nd.get_imagem(); + Nebula& nd = Nebula::instance(); + ImageManager * imagem = nd.get_imagem(); + DatastorePool * ds_pool = nd.get_dspool(); + Datastore * ds = 0; if (!(source = disk->vector_value("IMAGE")).empty()) { @@ -287,11 +290,23 @@ int ImagePool::disk_attribute(VectorAttribute * disk, { img->disk_attribute(disk, index, img_type); - image_id = img->get_oid(); - + image_id = img->get_oid(); + datastore_id = img->get_ds_id(); + update(img); img->unlock(); + + ds = ds_pool->get(datastore_id, true); + + if ( ds == 0 ) + { + return -1; + } + + ds->disk_attribute(disk); + + ds->unlock(); } oss << disk_id; diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index f414535537..a11504e9e2 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -278,10 +278,12 @@ void Nebula::start() vector system_ds; string system_ds_base_path; string system_ds_type; + string system_tm_mad; vector default_ds; string default_ds_base_path; string default_ds_type; + string default_tm_mad; vector vm_hooks; vector host_hooks; @@ -328,6 +330,7 @@ void Nebula::start() system_ds_base_path = ds_conf->vector_value("BASE_PATH"); system_ds_type = ds_conf->vector_value("TYPE"); + system_tm_mad = ds_conf->vector_value("TM_MAD"); nebula_configuration->get("DEFAULT_DS", default_ds); @@ -335,10 +338,11 @@ void Nebula::start() default_ds_base_path = ds_conf->vector_value("BASE_PATH"); default_ds_type = ds_conf->vector_value("TYPE"); + default_tm_mad = ds_conf->vector_value("TM_MAD"); dspool = new DatastorePool(db, - system_ds_base_path, system_ds_type, - default_ds_base_path, default_ds_type); + system_ds_base_path, system_ds_type, system_tm_mad, + default_ds_base_path, default_ds_type, default_tm_mad); } catch (exception&) { diff --git a/src/nebula/NebulaTemplate.cc b/src/nebula/NebulaTemplate.cc index 96a0a89c53..f6d56b30c9 100644 --- a/src/nebula/NebulaTemplate.cc +++ b/src/nebula/NebulaTemplate.cc @@ -189,7 +189,8 @@ void OpenNebulaTemplate::set_conf_default() //SYSTEM_DS vvalue.clear(); vvalue.insert(make_pair("BASE_PATH","/var/lib/one/system_ds")); - vvalue.insert(make_pair("TYPE","fs")); + vvalue.insert(make_pair("TYPE", "fs")); + vvalue.insert(make_pair("TM_MAD", "tm_shared")); vattribute = new VectorAttribute("SYSTEM_DS",vvalue); conf_default.insert(make_pair(vattribute->name(),vattribute)); @@ -197,7 +198,8 @@ void OpenNebulaTemplate::set_conf_default() //DEFAULT_DS vvalue.clear(); vvalue.insert(make_pair("BASE_PATH","/var/lib/one/images")); - vvalue.insert(make_pair("TYPE","fs")); + vvalue.insert(make_pair("TYPE", "fs")); + vvalue.insert(make_pair("TM_MAD", "tm_shared")); vattribute = new VectorAttribute("DEFAULT_DS",vvalue); conf_default.insert(make_pair(vattribute->name(),vattribute)); From 7ffae6fb8e2ea2f84e681859c5034051fb32a6d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 23 Feb 2012 18:27:35 +0100 Subject: [PATCH 038/217] Feature #1112: Remove datastore initialization from oned.conf --- include/DatastorePool.h | 8 +------- share/etc/oned.conf | 12 ------------ src/datastore/DatastorePool.cc | 22 ++++++++-------------- src/nebula/Nebula.cc | 31 +------------------------------ src/nebula/NebulaTemplate.cc | 18 ------------------ 5 files changed, 10 insertions(+), 81 deletions(-) diff --git a/include/DatastorePool.h b/include/DatastorePool.h index da9bf3aacc..e3cc6420fa 100644 --- a/include/DatastorePool.h +++ b/include/DatastorePool.h @@ -26,13 +26,7 @@ using namespace std; class DatastorePool : public PoolSQL { public: - DatastorePool(SqlDB * db, - const string& system_base_path, - const string& system_type, - const string& system_tm_mad, - const string& default_base_path, - const string& default_type, - const string& default_tm_mad); + DatastorePool(SqlDB * db); ~DatastorePool(){}; diff --git a/share/etc/oned.conf b/share/etc/oned.conf index d99bea70ba..1a3a495bf6 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -105,18 +105,6 @@ MAC_PREFIX = "02:00" # vd KVM virtual disk #******************************************************************************* -SYSTEM_DS = [ - base_path = "/var/lib/one/system_ds", - type = "fs", - tm_mad = "tm_shared" -] - -DEFAULT_DS = [ - base_path = "/var/lib/one/images", - type = "fs", - tm_mad = "tm_shared" -] - DEFAULT_IMAGE_TYPE = "OS" DEFAULT_DEVICE_PREFIX = "hd" diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index f2f96da820..fbbbd2292e 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -35,13 +35,7 @@ const int DatastorePool::DEFAULT_DS_ID = 1; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -DatastorePool::DatastorePool(SqlDB * db, - const string& system_base_path, - const string& system_type, - const string& system_tm_mad, - const string& default_base_path, - const string& default_type, - const string& default_tm_mad): +DatastorePool::DatastorePool(SqlDB * db): PoolSQL(db, Datastore::table) { ostringstream oss; @@ -55,10 +49,10 @@ DatastorePool::DatastorePool(SqlDB * db, // Build the default datastores - oss << "NAME = " << SYSTEM_DS_NAME << endl - << "BASE_PATH = " << system_base_path << endl - << "TYPE = " << system_type << endl - << "TM_MAD = " << system_tm_mad; + oss << "NAME = " << SYSTEM_DS_NAME << endl + << "BASE_PATH = /var/lib/one/system_ds" << endl + << "TYPE = fs" << endl + << "TM_MAD = tm_shared"; ds_tmpl = new DatastoreTemplate; rc = ds_tmpl->parse_str_or_xml(oss.str(), error_str); @@ -80,9 +74,9 @@ DatastorePool::DatastorePool(SqlDB * db, oss.str(""); oss << "NAME = " << DEFAULT_DS_NAME << endl - << "BASE_PATH = " << default_base_path << endl - << "TYPE = " << default_type << endl - << "TM_MAD = " << default_tm_mad; + << "BASE_PATH = /var/lib/one/images" << endl + << "TYPE = fs" << endl + << "TM_MAD = tm_shared"; ds_tmpl = new DatastoreTemplate; rc = ds_tmpl->parse_str_or_xml(oss.str(), error_str); diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index a11504e9e2..fbcd027a83 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -275,16 +275,6 @@ void Nebula::start() string default_device_prefix; time_t expiration_time; - vector system_ds; - string system_ds_base_path; - string system_ds_type; - string system_tm_mad; - - vector default_ds; - string default_ds_base_path; - string default_ds_type; - string default_tm_mad; - vector vm_hooks; vector host_hooks; vector vm_restricted_attrs; @@ -323,26 +313,7 @@ void Nebula::start() tpool = new VMTemplatePool(db); - nebula_configuration->get("SYSTEM_DS", system_ds); - - const VectorAttribute * ds_conf = - static_cast(system_ds[0]); - - system_ds_base_path = ds_conf->vector_value("BASE_PATH"); - system_ds_type = ds_conf->vector_value("TYPE"); - system_tm_mad = ds_conf->vector_value("TM_MAD"); - - nebula_configuration->get("DEFAULT_DS", default_ds); - - ds_conf = static_cast(default_ds[0]); - - default_ds_base_path = ds_conf->vector_value("BASE_PATH"); - default_ds_type = ds_conf->vector_value("TYPE"); - default_tm_mad = ds_conf->vector_value("TM_MAD"); - - dspool = new DatastorePool(db, - system_ds_base_path, system_ds_type, system_tm_mad, - default_ds_base_path, default_ds_type, default_tm_mad); + dspool = new DatastorePool(db); } catch (exception&) { diff --git a/src/nebula/NebulaTemplate.cc b/src/nebula/NebulaTemplate.cc index f6d56b30c9..83ad962b83 100644 --- a/src/nebula/NebulaTemplate.cc +++ b/src/nebula/NebulaTemplate.cc @@ -186,24 +186,6 @@ void OpenNebulaTemplate::set_conf_default() # DEFAULT_DEVICE_PREFIX #******************************************************************************* */ - //SYSTEM_DS - vvalue.clear(); - vvalue.insert(make_pair("BASE_PATH","/var/lib/one/system_ds")); - vvalue.insert(make_pair("TYPE", "fs")); - vvalue.insert(make_pair("TM_MAD", "tm_shared")); - - vattribute = new VectorAttribute("SYSTEM_DS",vvalue); - conf_default.insert(make_pair(vattribute->name(),vattribute)); - - //DEFAULT_DS - vvalue.clear(); - vvalue.insert(make_pair("BASE_PATH","/var/lib/one/images")); - vvalue.insert(make_pair("TYPE", "fs")); - vvalue.insert(make_pair("TM_MAD", "tm_shared")); - - vattribute = new VectorAttribute("DEFAULT_DS",vvalue); - conf_default.insert(make_pair(vattribute->name(),vattribute)); - //DEFAULT_IMAGE_TYPE value = "OS"; From 92d0432012ee3b1dff952667e8d7bed93f4638a0 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 24 Feb 2012 12:53:25 +0100 Subject: [PATCH 039/217] feature #1112: Change error message --- src/rm/RequestManagerAllocate.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 8ec46bc581..222fcf996d 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -207,8 +207,7 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, { ostringstream oss; - oss << "New Images cannot be allocated in the system " - << object_name(PoolObjectSQL::DATASTORE) << " [" << ds_id << "]."; + oss << "New images cannot be allocated in the system datastore."; failure_response(INTERNAL, allocate_error(oss.str()), att); delete tmpl; From a0ca68d0e3bbdd74ac358f577f44adf071957e28 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 24 Feb 2012 14:55:00 +0100 Subject: [PATCH 040/217] Remove TM from Host --- include/Host.h | 8 +------- include/HostPool.h | 1 - include/RequestManagerAllocate.h | 2 +- src/host/Host.cc | 6 +----- src/host/HostPool.cc | 13 +------------ src/rm/RequestManagerAllocate.cc | 4 +--- 6 files changed, 5 insertions(+), 29 deletions(-) diff --git a/include/Host.h b/include/Host.h index 5bcad871f6..0915813eac 100644 --- a/include/Host.h +++ b/include/Host.h @@ -316,11 +316,6 @@ private: */ string vnm_mad_name; - /** - * Name of the TM driver used to transfer file to and from this host - */ - string tm_mad_name; - /** * 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 @@ -343,8 +338,7 @@ private: const string& hostname="", const string& im_mad_name="", const string& vmm_mad_name="", - const string& vnm_mad_name="", - const string& tm_mad_name=""); + const string& vnm_mad_name=""); virtual ~Host(); diff --git a/include/HostPool.h b/include/HostPool.h index 7bdc0bfc23..0d0f016234 100644 --- a/include/HostPool.h +++ b/include/HostPool.h @@ -53,7 +53,6 @@ public: const string& im_mad_name, const string& vmm_mad_name, const string& vnm_mad_name, - const string& tm_mad_name, string& error_str); /** diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index bcd00c4797..26fa728924 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -207,7 +207,7 @@ public: HostAllocate(): RequestManagerAllocate("HostAllocate", "Allocates a new host", - "A:ssssss", + "A:sssss", false) { Nebula& nd = Nebula::instance(); diff --git a/src/host/Host.cc b/src/host/Host.cc index 0fdf0530f0..084568f502 100644 --- a/src/host/Host.cc +++ b/src/host/Host.cc @@ -33,14 +33,12 @@ Host::Host( const string& _hostname, const string& _im_mad_name, const string& _vmm_mad_name, - const string& _vnm_mad_name, - const string& _tm_mad_name): + const string& _vnm_mad_name): PoolObjectSQL(id,HOST,_hostname,-1,-1,"","",table), state(INIT), im_mad_name(_im_mad_name), vmm_mad_name(_vmm_mad_name), vnm_mad_name(_vnm_mad_name), - tm_mad_name(_tm_mad_name), last_monitored(0) { obj_template = new HostTemplate; @@ -205,7 +203,6 @@ string& Host::to_xml(string& xml) const "" << im_mad_name << "" << "" << vmm_mad_name << "" << "" << vnm_mad_name << "" << - "" << tm_mad_name << "" << "" << last_monitored << "" << host_share.to_xml(share_xml) << obj_template->to_xml(template_xml) << @@ -237,7 +234,6 @@ int Host::from_xml(const string& xml) rc += xpath(im_mad_name, "/HOST/IM_MAD", "not_found"); rc += xpath(vmm_mad_name, "/HOST/VM_MAD", "not_found"); rc += xpath(vnm_mad_name, "/HOST/VN_MAD", "not_found"); - rc += xpath(tm_mad_name, "/HOST/TM_MAD", "not_found"); rc += xpath(last_monitored, "/HOST/LAST_MON_TIME", 0); diff --git a/src/host/HostPool.cc b/src/host/HostPool.cc index 689b93a075..82b99a3418 100644 --- a/src/host/HostPool.cc +++ b/src/host/HostPool.cc @@ -153,7 +153,6 @@ int HostPool::allocate ( const string& im_mad_name, const string& vmm_mad_name, const string& vnm_mad_name, - const string& tm_mad_name, string& error_str) { Host * host; @@ -184,11 +183,6 @@ int HostPool::allocate ( goto error_vnm; } - if ( tm_mad_name.empty() ) - { - goto error_tm; - } - host = get(hostname,false); if ( host !=0) @@ -198,8 +192,7 @@ int HostPool::allocate ( // Build a new Host object - host = new Host(-1, hostname, im_mad_name, vmm_mad_name, vnm_mad_name, - tm_mad_name); + host = new Host(-1, hostname, im_mad_name, vmm_mad_name, vnm_mad_name); // Insert the Object in the pool @@ -228,10 +221,6 @@ error_vnm: oss << "VNM_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() << "."; diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 222fcf996d..1ab4a814d0 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -316,12 +316,10 @@ int HostAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, string im_mad = xmlrpc_c::value_string(paramList.getString(2)); string vmm_mad = xmlrpc_c::value_string(paramList.getString(3)); string vnm_mad = xmlrpc_c::value_string(paramList.getString(4)); - string tm_mad = xmlrpc_c::value_string(paramList.getString(5)); HostPool * hpool = static_cast(pool); - return hpool->allocate(&id, host, im_mad, vmm_mad, vnm_mad, tm_mad, - error_str); + return hpool->allocate(&id, host, im_mad, vmm_mad, vnm_mad, error_str); } /* -------------------------------------------------------------------------- */ From f4743b6077609a6755a173e8cd8e93c40f5670aa Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 24 Feb 2012 14:55:31 +0100 Subject: [PATCH 041/217] Fix Tests. --- include/test/NebulaTest.h | 4 ++ src/host/test/HostHookTest.cc | 8 ++-- src/host/test/HostPoolTest.cc | 61 +++++++++++++-------------- src/image/test/ImagePoolTest.cc | 14 +++--- src/lcm/test/LifeCycleManagerTest.cc | 23 +++++----- src/test/Nebula.cc | 11 +++++ src/test/NebulaTest.cc | 5 +++ src/vm/test/SConstruct | 1 + src/vm/test/VirtualMachinePoolTest.cc | 15 +++---- 9 files changed, 79 insertions(+), 63 deletions(-) diff --git a/include/test/NebulaTest.h b/include/test/NebulaTest.h index 875459932d..3768558f3d 100644 --- a/include/test/NebulaTest.h +++ b/include/test/NebulaTest.h @@ -26,6 +26,7 @@ #include "HostPool.h" #include "UserPool.h" #include "VMTemplatePool.h" +#include "DatastorePool.h" #include "VirtualMachineManager.h" #include "LifeCycleManager.h" @@ -67,6 +68,7 @@ public: bool need_user_pool; bool need_template_pool; bool need_group_pool; + bool need_datastore_pool; bool need_vmm; bool need_im; @@ -107,6 +109,8 @@ public: virtual GroupPool* create_gpool(SqlDB* db); + virtual DatastorePool* create_dspool(SqlDB* db); + // ------------------------------------------------------------------------ // Managers // ------------------------------------------------------------------------ diff --git a/src/host/test/HostHookTest.cc b/src/host/test/HostHookTest.cc index e65877c27c..46ffbd7b6c 100644 --- a/src/host/test/HostHookTest.cc +++ b/src/host/test/HostHookTest.cc @@ -96,7 +96,7 @@ public: { string err; - hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", "tm_mad", err); + hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", err); CPPUNIT_ASSERT( oid >= 0 ); sleep(1); @@ -114,7 +114,7 @@ public: { string err; - hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", "tm_mad", err); + hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", err); CPPUNIT_ASSERT( oid >= 0 ); host = hpool->get(oid, true); @@ -140,7 +140,7 @@ public: { string err; - hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", "tm_mad", err); + hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", err); CPPUNIT_ASSERT( oid >= 0 ); host = hpool->get(oid, true); @@ -166,7 +166,7 @@ public: { string err; - hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", "tm_mad", err); + hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", err); CPPUNIT_ASSERT( oid >= 0 ); host = hpool->get(oid, true); diff --git a/src/host/test/HostPoolTest.cc b/src/host/test/HostPoolTest.cc index 43ce2a679b..a46de04219 100644 --- a/src/host/test/HostPoolTest.cc +++ b/src/host/test/HostPoolTest.cc @@ -26,14 +26,13 @@ using namespace std; const string im_mad = "im_mad"; const string vmm_mad = "vmm_mad"; const string vnm_mad = "vnm_mad"; -const string tm_mad = "tm_mad"; const string names[] = {"Host one", "Second host"}; const string xmls[] = { "0Host one0" - "im_madvmm_madvnm_madtm_mad" + "im_madvmm_madvnm_mad" "0" "000" "000" @@ -42,7 +41,7 @@ const string xmls[] = "0", "1Second host0" - "im_madvmm_madvnm_madtm_mad" + "im_madvmm_madvnm_mad" "0" "000" "000" @@ -54,35 +53,35 @@ const string xmls[] = // This xml dump result has the LAST_MON_TIMEs modified to 0000000000 const string xml_dump = "0a0im_madvmm_madvnm_madtm_mad0" + "M_MAD>vmm_madvnm_mad0" "0000000000000" "1a name0im_madvmm_madvnm_madtm_mad0vmm_madvnm_mad000000" "000000002a_name0im_madvmm_madvnm_madtm_mad0vnm_mad000000000000003another " "name0im_madvmm_mad" - "vnm_madtm_mad0vnm_mad000000000000004host0im_madvmm_madvnm_madtm_mad" - "0" + "ATE>0im_madvmm_madvnm_mad" + "0" "000" "0000" "000vmm_madvnm_madtm_mad0" + "M_MAD>vmm_madvnm_mad0" "0000000000000" "1a name0im_madvmm_madvnm_madtm_mad0vmm_madvnm_mad000000" "000000002a_name0im_madvmm_madvnm_madtm_mad0vnm_mad000000000000003another " "name0im_madvmm_mad" - "vnm_madtm_mad0vnm_mad00000000000Host one0im_madvmm_madvnm_madtm_mad00000000000000"; + "0Host one0im_madvmm_madvnm_mad00000000000000"; const string host_0_cluster = - "0Host one0im_madvmm_madvnm_madtm_mad0cluster_a0000000000000"; + "0Host one0im_madvmm_madvnm_mad0cluster_a0000000000000"; /* ************************************************************************* */ /* ************************************************************************* */ @@ -164,7 +163,7 @@ protected: int oid; string err; return ((HostPool*)pool)->allocate(&oid, names[index], im_mad, - vmm_mad, vnm_mad, tm_mad, err); + vmm_mad, vnm_mad, err); }; void check(int index, PoolObjectSQL* obj) @@ -239,28 +238,28 @@ public: Host * host; string err; - string tm_mad_2 = "another_tm_mad"; + string im_mad_2 = "another_im_mad"; // If we try to allocate two hosts with the same name and drivers, // should fail - rc = hp->allocate(&oid_0, names[0], im_mad, vmm_mad, vnm_mad, tm_mad, err); + rc = hp->allocate(&oid_0, names[0], im_mad, vmm_mad, vnm_mad, err); CPPUNIT_ASSERT( oid_0 == 0 ); CPPUNIT_ASSERT( rc == oid_0 ); - rc = hp->allocate(&oid_1, names[0], im_mad, vmm_mad, vnm_mad, tm_mad, err); + rc = hp->allocate(&oid_1, names[0], im_mad, vmm_mad, vnm_mad, err); CPPUNIT_ASSERT( oid_1 == -1 ); CPPUNIT_ASSERT( rc == oid_1 ); // the hostname can not be repeated if the drivers change - rc = hp->allocate(&oid_1, names[0], im_mad, vmm_mad, vnm_mad, tm_mad_2, err); + rc = hp->allocate(&oid_1, names[0], im_mad_2, vmm_mad, vnm_mad, err); CPPUNIT_ASSERT( oid_1 == -1 ); CPPUNIT_ASSERT( rc == oid_1 ); // Get the hosts and check them host = hp->get(oid_0, false); CPPUNIT_ASSERT( host != 0 ); - CPPUNIT_ASSERT( host->get_tm_mad() == tm_mad ); + CPPUNIT_ASSERT( host->get_im_mad() == im_mad ); } /* ********************************************************************* */ @@ -274,7 +273,7 @@ public: for(int i=0; i<5; i++) { ((HostPool*)pool)->allocate(&oid, names[i], - im_mad, vmm_mad, vnm_mad, tm_mad, err); + im_mad, vmm_mad, vnm_mad, err); } ostringstream oss; @@ -285,13 +284,13 @@ public: string result = oss.str(); // A little help for debugging -//* +/* if( result != xml_dump ) { cout << endl << result << endl << "========" << endl << xml_dump << endl; } -//*/ +*/ CPPUNIT_ASSERT( result == xml_dump ); } @@ -307,25 +306,23 @@ public: for(int i=0; i<5; i++) { ((HostPool*)pool)->allocate(&oid, names[i], - im_mad, vmm_mad, vnm_mad, tm_mad, err); + im_mad, vmm_mad, vnm_mad, err); } - ostringstream oss; rc = ((HostPool*)pool)->dump(oss, "name LIKE 'a%'"); 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 << endl; } -//*/ +*/ CPPUNIT_ASSERT( result == xml_dump_like_a ); } @@ -348,7 +345,7 @@ public: { oss << "host" << i; - hp->allocate(&oid, oss.str().c_str(), im_mad, vmm_mad, vnm_mad, tm_mad, err); + hp->allocate(&oid, oss.str().c_str(),im_mad, vmm_mad, vnm_mad, err); CPPUNIT_ASSERT(oid == i); if (i >=8 ) @@ -406,7 +403,7 @@ public: { oss << "host" << j; - hp->allocate(&oid, oss.str().c_str(),im_mad,vmm_mad,vnm_mad,tm_mad,err); + hp->allocate(&oid,oss.str().c_str(),im_mad,vmm_mad,vnm_mad,err); } the_time2 = time(0) - the_time; @@ -435,7 +432,7 @@ public: for (i=10000,oss.str(""); i<30000 ; i++,oss.str("")) { oss << "host" << i; - hp->allocate(&oid,oss.str().c_str(),im_mad,vmm_mad,vnm_mad,tm_mad,err); + hp->allocate(&oid,oss.str().c_str(),im_mad,vmm_mad,vnm_mad,err); host = hp->get(oid, false); diff --git a/src/image/test/ImagePoolTest.cc b/src/image/test/ImagePoolTest.cc index 8427243e70..f4d96a010b 100644 --- a/src/image/test/ImagePoolTest.cc +++ b/src/image/test/ImagePoolTest.cc @@ -51,20 +51,20 @@ const string templates[] = const string xmls[] = { -"001oneoneadminImage one110000000010000000000/tmp/image_test040", +"001oneoneadminImage one110000000010000000000/tmp/image_test0400none", -"111twooneadminSecond Image110000000000000000000/tmp/image_second_test040", +"111twooneadminSecond Image110000000000000000000/tmp/image_second_test0400none", -"021threeusersThe third image110000000000000000000/tmp/image_test040", +"021threeusersThe third image110000000000000000000/tmp/image_test0400none", }; // This xml dump result has the STIMEs modified to 0000000000 const string xml_dump = -"001oneoneadminImage one110000000010000000000/tmp/image_test040111twooneadminSecond Image110000000000000000000/tmp/image_second_test040221threeusersThe third image110000000000000000000/tmp/image_test040"; +"001oneoneadminImage one110000000010000000000/tmp/image_test0400none111twooneadminSecond Image110000000000000000000/tmp/image_second_test0400none221threeusersThe third image110000000000000000000/tmp/image_test0400none"; const string xml_dump_where = -"001oneoneadminImage one110000000010000000000/tmp/image_test040111twooneadminSecond Image110000000000000000000/tmp/image_second_test040"; +"001oneoneadminImage one110000000010000000000/tmp/image_test0400none111twooneadminSecond Image110000000000000000000/tmp/image_second_test0400none"; /* ************************************************************************* */ /* ************************************************************************* */ @@ -80,6 +80,7 @@ public: need_image_pool = true; need_imagem = true; + need_datastore_pool = true; } }; @@ -113,7 +114,8 @@ public: string uname = unames[uid]; string gname = gnames[uid]; - return ImagePool::allocate(uid, 1, uname, gname, img_template, oid, err); + return ImagePool::allocate(uid, 1, uname, gname, + img_template, 0,"none", "", oid, err); } else { diff --git a/src/lcm/test/LifeCycleManagerTest.cc b/src/lcm/test/LifeCycleManagerTest.cc index 50a43f2275..ce1166c8bd 100644 --- a/src/lcm/test/LifeCycleManagerTest.cc +++ b/src/lcm/test/LifeCycleManagerTest.cc @@ -48,7 +48,6 @@ static int hid = 123; static string hostname = "test_hostname"; static string vmm_mad = "vmm_mad"; static string vnm_mad = "vnm_mad"; -static string tm_mad = "tm_mad"; static string vmdir = "vmdir"; class LifeCycleManagerTest : public OneUnitTest @@ -226,7 +225,7 @@ private: vm->lock(); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad); + vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -490,7 +489,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad); + vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -574,7 +573,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad); + vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -595,7 +594,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad); + vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -616,7 +615,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad); + vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -638,7 +637,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad); + vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -662,7 +661,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad); + vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -686,7 +685,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad); + vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -750,7 +749,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad); + vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -773,7 +772,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad); + vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -796,7 +795,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad); + vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); diff --git a/src/test/Nebula.cc b/src/test/Nebula.cc index 86229b0dbe..f9d66ace3d 100644 --- a/src/test/Nebula.cc +++ b/src/test/Nebula.cc @@ -87,6 +87,11 @@ void Nebula::start() delete gpool; } + if ( dspool != 0) + { + delete dspool; + } + if ( vmm != 0) { delete vmm; @@ -184,6 +189,7 @@ void Nebula::start() VMTemplatePool::bootstrap(db); GroupPool::bootstrap(db); AclManager::bootstrap(db); + DatastorePool::bootstrap(db); } catch (exception&) { @@ -235,6 +241,11 @@ void Nebula::start() { tpool = tester->create_tpool(db); } + + if (tester->need_datastore_pool) + { + dspool = tester->create_dspool(db); + } } catch (exception&) { diff --git a/src/test/NebulaTest.cc b/src/test/NebulaTest.cc index eda496815d..b600a59924 100644 --- a/src/test/NebulaTest.cc +++ b/src/test/NebulaTest.cc @@ -62,6 +62,11 @@ GroupPool* NebulaTest::create_gpool(SqlDB* db) return new GroupPool(db); } +DatastorePool* NebulaTest::create_dspool(SqlDB* db) +{ + return new DatastorePool(db); +} + // ----------------------------------------------------------- // Managers // ----------------------------------------------------------- diff --git a/src/vm/test/SConstruct b/src/vm/test/SConstruct index 9fc71af828..c2eb20b3b3 100644 --- a/src/vm/test/SConstruct +++ b/src/vm/test/SConstruct @@ -28,6 +28,7 @@ env.Prepend(LIBS=[ 'nebula_pool', 'nebula_xml', 'nebula_image', + 'nebula_datastore', 'nebula_mad', 'nebula_common', 'nebula_log', diff --git a/src/vm/test/VirtualMachinePoolTest.cc b/src/vm/test/VirtualMachinePoolTest.cc index d74ecfbc3d..4febff2e81 100644 --- a/src/vm/test/VirtualMachinePoolTest.cc +++ b/src/vm/test/VirtualMachinePoolTest.cc @@ -66,7 +66,7 @@ const string xml_dump_where = "011the_userusersVM one110000000010000000000000000"; const string xml_history_dump = - "001the_userusersVM one110000000010000000000000000101the_userusersSecond VM1100000000200000000000000000A_hostnameA_vm_dir000A_vmm_madA_vnm_madA_tm_mad0000000201the_userusersVM one1100000000200000000000000001C_hostnameC_vm_dir200C_vmm_madC_vnm_madC_tm_mad0000000311the_userusersVM one110000000060000000000000000"; + "001the_userusersVM one110000000010000000000000000101the_userusersSecond VM1100000000200000000000000000A_hostnameA_vm_dir000A_vmm_madA_vnm_mad0000000201the_userusersVM one1100000000200000000000000001C_hostnameC_vm_dir200C_vmm_madC_vnm_mad0000000311the_userusersVM one110000000060000000000000000"; /* ************************************************************************* */ /* ************************************************************************* */ @@ -194,7 +194,6 @@ public: string hostname = "hostname"; string vm_dir = "vm_dir"; string vmm_mad = "vm_mad"; - string tm_mad = "tm_mad"; // Allocate two VMs oid = allocate(0); @@ -302,7 +301,6 @@ public: string vm_dirs[] = {"A_vm_dir", "B_vm_dir", "C_vm_dir"}; string vmm_mads[] = {"A_vmm_mad", "B_vmm_mad", "C_vmm_mad"}; string vnm_mads[] = {"A_vnm_mad", "B_vnm_mad", "C_vnm_mad"}; - string tm_mads[] = {"A_tm_mad", "B_tm_mad", "C_tm_mad"}; int oid, rc; ostringstream oss; @@ -324,7 +322,7 @@ public: CPPUNIT_ASSERT( vm != 0 ); // Add a history item - vm->add_history(0, hostnames[0], vm_dirs[0], vmm_mads[0], vnm_mads[0], tm_mads[0]); + vm->add_history(0, hostnames[0], vm_dirs[0], vmm_mads[0], vnm_mads[0]); rc = vmp->update(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -342,7 +340,7 @@ public: CPPUNIT_ASSERT( vm != 0 ); // Add a history item - vm->add_history(1, hostnames[1], vm_dirs[1], vmm_mads[1], vnm_mads[1], tm_mads[1]); + vm->add_history(1, hostnames[1], vm_dirs[1], vmm_mads[1], vnm_mads[1]); rc = vmp->update(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -351,7 +349,7 @@ public: CPPUNIT_ASSERT( rc == 0 ); // Add another history item - vm->add_history(2, hostnames[2], vm_dirs[2], vmm_mads[2], vnm_mads[2], tm_mads[2]); + vm->add_history(2, hostnames[2], vm_dirs[2], vmm_mads[2], vnm_mads[2]); rc = vmp->update(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -409,7 +407,6 @@ public: string vm_dir = "vm_dir"; string vmm_mad = "vm_mad"; string vnm_mad = "vn_mad"; - string tm_mad = "tm_mad"; // Allocate a VM oid = allocate(0); @@ -419,7 +416,7 @@ public: CPPUNIT_ASSERT( vm != 0 ); // Add a history item - vm->add_history(0, hostname, vm_dir, vmm_mad, vnm_mad, tm_mad); + vm->add_history(0, hostname, vm_dir, vmm_mad, vnm_mad); rc = vmp->update(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -427,7 +424,7 @@ public: rc = vmp->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); - vm->add_history(0, new_hostname, vm_dir, vmm_mad, vnm_mad, tm_mad); + vm->add_history(0, new_hostname, vm_dir, vmm_mad, vnm_mad); rc = vmp->update(vm); CPPUNIT_ASSERT( rc == 0 ); From 4e2b33fa236a1dbf064e783d477ed09bb091da4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 24 Feb 2012 15:53:53 +0100 Subject: [PATCH 042/217] Feature #1112: Clusters are coming back into fashion this season --- SConstruct | 3 + include/Cluster.h | 137 +++++++++++++++++ include/ClusterPool.h | 158 ++++++++++++++++++++ include/ClusterPoolOld.h | 140 +++++++++++++++++ include/Nebula.h | 16 +- include/PoolObjectSQL.h | 4 +- include/RequestManagerAllocate.h | 26 ++++ include/RequestManagerDelete.h | 19 ++- include/RequestManagerInfo.h | 19 ++- include/RequestManagerPoolInfoFilter.h | 24 +++ install.sh | 13 +- src/cli/etc/onecluster.yaml | 14 ++ src/cli/one_helper/onecluster_helper.rb | 76 ++++++++++ src/cli/onecluster | 100 +++++++++++++ src/cluster/Cluster.cc | 191 ++++++++++++++++++++++++ src/cluster/ClusterPool.cc | 154 +++++++++++++++++++ src/cluster/SConstruct | 30 ++++ src/nebula/Nebula.cc | 3 + src/nebula/SConstruct | 1 + src/oca/ruby/OpenNebula.rb | 2 + src/oca/ruby/OpenNebula/Cluster.rb | 99 ++++++++++++ src/oca/ruby/OpenNebula/ClusterPool.rb | 53 +++++++ src/rm/Request.cc | 2 + src/rm/RequestManager.cc | 10 ++ src/rm/RequestManagerAllocate.cc | 16 ++ src/rm/RequestManagerPoolInfoFilter.cc | 10 ++ 26 files changed, 1312 insertions(+), 8 deletions(-) create mode 100644 include/Cluster.h create mode 100644 include/ClusterPool.h create mode 100644 include/ClusterPoolOld.h create mode 100644 src/cli/etc/onecluster.yaml create mode 100644 src/cli/one_helper/onecluster_helper.rb create mode 100755 src/cli/onecluster create mode 100644 src/cluster/Cluster.cc create mode 100644 src/cluster/ClusterPool.cc create mode 100644 src/cluster/SConstruct create mode 100644 src/oca/ruby/OpenNebula/Cluster.rb create mode 100644 src/oca/ruby/OpenNebula/ClusterPool.rb diff --git a/SConstruct b/SConstruct index 468d96285f..cf962f4d85 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/datastore', cwd+'/src/group', cwd+'/src/mad', @@ -188,6 +189,7 @@ build_scripts=[ 'src/common/SConstruct', 'src/template/SConstruct', 'src/host/SConstruct', + 'src/cluster/SConstruct', 'src/datastore/SConstruct', 'src/group/SConstruct', 'src/mad/SConstruct', @@ -238,6 +240,7 @@ if testing=='yes': 'src/authm/test/SConstruct', 'src/common/test/SConstruct', 'src/host/test/SConstruct', + 'src/cluster/test/SConstruct', 'src/datastore/test/SConstruct', 'src/group/test/SConstruct', 'src/image/test/SConstruct', diff --git a/include/Cluster.h b/include/Cluster.h new file mode 100644 index 0000000000..0227d66fa1 --- /dev/null +++ b/include/Cluster.h @@ -0,0 +1,137 @@ +/* ------------------------------------------------------------------------ */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------*/ + +#ifndef CLUSTER_H_ +#define CLUSTER_H_ + +#include "PoolSQL.h" +#include "ObjectCollection.h" + +using namespace std; + +/** + * The Cluster class. + */ +class Cluster : public PoolObjectSQL, ObjectCollection +{ +public: + + /** + * 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); + + /** + * Adds this user's ID to the set. + * @param id of the user to be added to the cluster + * @return 0 on success + */ + int add_host(int id) + { + return add_collection_id(id); + } + + /** + * Deletes this users's ID from the set. + * @param id of the user to be deleted from the cluster + * @return 0 on success + */ + int del_host(int id) + { + return del_collection_id(id); + } + +private: + + // ------------------------------------------------------------------------- + // Friends + // ------------------------------------------------------------------------- + + friend class ClusterPool; + + // ************************************************************************* + // Constructor + // ************************************************************************* + + Cluster(int id, const string& name): + PoolObjectSQL(id,CLUSTER,name,-1,-1,"","",table), + ObjectCollection("HOSTS"){}; + + 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 + * @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 Cluster + * @return 0 on success + */ + static int bootstrap(SqlDB * db) + { + ostringstream oss(Cluster::db_bootstrap); + + return db->exec(oss); + }; + + /** + * Writes the Cluster in the database. + * @param db pointer to the db + * @return 0 on success + */ + int insert(SqlDB *db, string& error_str) + { + return insert_replace(db, false, 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) + { + string error_str; + return insert_replace(db, true, error_str); + } +}; + +#endif /*CLUSTER_H_*/ diff --git a/include/ClusterPool.h b/include/ClusterPool.h new file mode 100644 index 0000000000..bd9e487afc --- /dev/null +++ b/include/ClusterPool.h @@ -0,0 +1,158 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#ifndef CLUSTER_POOL_H_ +#define CLUSTER_POOL_H_ + +#include "Cluster.h" +#include "SqlDB.h" + +using namespace std; + + +class ClusterPool : public PoolSQL +{ +public: + ClusterPool(SqlDB * db); + + ~ClusterPool(){}; + + /* ---------------------------------------------------------------------- */ + /* Constants for DB management */ + /* ---------------------------------------------------------------------- */ + + /** + * Name for the default cluster + */ + static const string DEFAULT_CLUSTER_NAME; + + /** + * Identifier for the default cluster + */ + static const int DEFAULT_CLUSTER_ID; + + /* ---------------------------------------------------------------------- */ + /* Methods for DB management */ + /* ---------------------------------------------------------------------- */ + + /** + * Allocates a new cluster, writting it in the pool database. No memory is + * allocated for the object. + * @param name Cluster name + * @param oid the id assigned to the Cluster + * @param error_str Returns the error reason, if any + * + * @return the oid assigned to the object, -1 in case of failure + */ + int allocate(string name, + int * oid, + string& error_str); + + /** + * 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 + */ + Cluster * 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 + */ + Cluster * 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 Clusters can't repeat names. + return name; + }; + + /** Update a particular Cluster + * @param user pointer to Cluster + * @return 0 on success + */ + int update(Cluster * cluster) + { + return cluster->update(db); + }; + + /** + * Drops the Cluster from the data base. The object mutex SHOULD be + * locked. + * @param objsql a pointer to a Cluster object + * @param error_msg Error reason, if any + * @return 0 on success, + * -1 DB error, + * -2 object is a system cluster (ID < 100) + * -3 Cluster's User IDs set is not empty + */ + int drop(PoolObjectSQL * objsql, string& error_msg); + + /** + * Bootstraps the database table(s) associated to the Cluster pool + * @return 0 on success + */ + static int bootstrap(SqlDB * _db) + { + return Cluster::bootstrap(_db); + }; + + /** + * 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); + }; + +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/ClusterPoolOld.h b/include/ClusterPoolOld.h new file mode 100644 index 0000000000..f9f92fe10b --- /dev/null +++ b/include/ClusterPoolOld.h @@ -0,0 +1,140 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +#ifndef CLUSTER_POOL_H_ +#define CLUSTER_POOL_H_ + +#include +#include +#include + +#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 +{ +public: + /** + * Cluster name for the default cluster + */ + static const string DEFAULT_CLUSTER_NAME; + +private: + // ------------------------------------------------------------------------- + // Friends + // ------------------------------------------------------------------------- + friend class HostPool; + + /* ---------------------------------------------------------------------- */ + /* Attributes */ + /* ---------------------------------------------------------------------- */ + /** + * 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); + + /** + * Returns the xml representation of the given cluster + * @param clid ID of the cluster + * + * @return the xml representation of the given cluster + */ + 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) + { + ostringstream oss(ClusterPool::db_bootstrap); + db->exec(oss); + }; + + /** + * 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 + * + * @return 0 on success + */ + void dump_cluster(ostringstream& oss, int id, string name); + + + /* ---------------------------------------------------------------------- */ + /* DB manipulation */ + /* ---------------------------------------------------------------------- */ + + static const char * db_names; + + static const char * db_bootstrap; + + static const char * table; + +}; + +#endif /*CLUSTER_POOL_H_*/ diff --git a/include/Nebula.h b/include/Nebula.h index a1c7cba6d6..e5640ba05c 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -28,6 +28,7 @@ #include "VMTemplatePool.h" #include "GroupPool.h" #include "DatastorePool.h" +#include "ClusterPool.h" #include "VirtualMachineManager.h" #include "LifeCycleManager.h" @@ -97,6 +98,11 @@ public: return dspool; }; + ClusterPool * get_clpool() + { + return clpool; + }; + // -------------------------------------------------------------- // Manager Accessors // -------------------------------------------------------------- @@ -260,8 +266,8 @@ private: // ----------------------------------------------------------------------- Nebula():nebula_configuration(0),db(0),vmpool(0),hpool(0),vnpool(0), - upool(0),ipool(0),gpool(0),tpool(0),dspool(0),lcm(0),vmm(0),im(0),tm(0), - dm(0),rm(0),hm(0),authm(0),aclm(0),imagem(0) + upool(0),ipool(0),gpool(0),tpool(0),dspool(0),clpool(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"); @@ -333,6 +339,11 @@ private: { delete dspool; } + + if ( clpool != 0) + { + delete clpool; + } if ( vmm != 0) { @@ -433,6 +444,7 @@ private: GroupPool * gpool; VMTemplatePool * tpool; DatastorePool * dspool; + ClusterPool * clpool; // --------------------------------------------------------------- // Nebula Managers diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h index d4e83fcf42..0df42280c4 100644 --- a/include/PoolObjectSQL.h +++ b/include/PoolObjectSQL.h @@ -57,7 +57,8 @@ public: TEMPLATE = 0x0000020000000000LL, GROUP = 0x0000040000000000LL, ACL = 0x0000080000000000LL, - DATASTORE = 0x0000100000000000LL + DATASTORE = 0x0000100000000000LL, + CLUSTER = 0x0000200000000000LL }; static string type_to_str(ObjectType ob) @@ -73,6 +74,7 @@ public: case GROUP: return "GROUP" ; break; case ACL: return "ACL" ; break; case DATASTORE: return "DATASTORE" ; break; + case CLUSTER: return "CLUSTER" ; break; default: return ""; } }; diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index 26fa728924..1249407a73 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -309,6 +309,32 @@ public: RequestAttributes& att); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ClusterAllocate: public RequestManagerAllocate +{ +public: + ClusterAllocate(): + RequestManagerAllocate("ClusterAllocate", + "Allocates a new cluster", + "A:ss", + false) + { + Nebula& nd = Nebula::instance(); + pool = nd.get_clpool(); + auth_object = PoolObjectSQL::CLUSTER; + }; + + ~ClusterAllocate(){}; + + int pool_allocate(xmlrpc_c::paramList const& _paramList, + Template * tmpl, + int& id, + string& error_str, + RequestAttributes& att); +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerDelete.h b/include/RequestManagerDelete.h index b97b9b3f6d..037b29dd2e 100644 --- a/include/RequestManagerDelete.h +++ b/include/RequestManagerDelete.h @@ -140,7 +140,6 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ - class GroupDelete: public RequestManagerDelete { public: @@ -196,6 +195,24 @@ public: ~DatastoreDelete(){}; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ClusterDelete: public RequestManagerDelete +{ +public: + ClusterDelete(): + RequestManagerDelete("ClusterDelete", "Deletes a cluster") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_clpool(); + auth_object = PoolObjectSQL::CLUSTER; + auth_op = AuthRequest::ADMIN; + }; + + ~ClusterDelete(){}; +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerInfo.h b/include/RequestManagerInfo.h index 6975f99039..3d5498f997 100644 --- a/include/RequestManagerInfo.h +++ b/include/RequestManagerInfo.h @@ -162,7 +162,6 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ - class GroupInfo: public RequestManagerInfo { public: @@ -214,6 +213,24 @@ public: ~DatastoreInfo(){}; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ClusterInfo: public RequestManagerInfo +{ +public: + ClusterInfo(): + RequestManagerInfo("ClusterInfo", + "Returns cluster information") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_clpool(); + auth_object = PoolObjectSQL::CLUSTER; + }; + + ~ClusterInfo(){}; +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerPoolInfoFilter.h b/include/RequestManagerPoolInfoFilter.h index d3fb8980c7..2270f7c471 100644 --- a/include/RequestManagerPoolInfoFilter.h +++ b/include/RequestManagerPoolInfoFilter.h @@ -248,6 +248,30 @@ public: xmlrpc_c::paramList const& paramList, RequestAttributes& att); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ClusterPoolInfo: public RequestManagerPoolInfoFilter +{ +public: + ClusterPoolInfo(): + RequestManagerPoolInfoFilter("ClusterPoolInfo", + "Returns the cluster pool", + "A:s") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_clpool(); + auth_object = PoolObjectSQL::CLUSTER; + }; + + ~ClusterPoolInfo(){}; + + /* -------------------------------------------------------------------- */ + + void request_execute( + xmlrpc_c::paramList const& paramList, RequestAttributes& att); +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/install.sh b/install.sh index 30f20afa67..ea5fcb7e2e 100755 --- a/install.sh +++ b/install.sh @@ -563,6 +563,7 @@ BIN_FILES="src/nebula/oned \ src/cli/onetemplate \ src/cli/oneacl \ src/cli/onedatastore \ + src/cli/onecluster \ src/onedb/onedb \ src/authm_mad/remotes/quota/onequota \ src/mad/utils/tty_expect \ @@ -963,6 +964,8 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/OpenNebula/Host.rb \ src/oca/ruby/OpenNebula/AclPool.rb \ src/oca/ruby/OpenNebula/Datastore.rb \ src/oca/ruby/OpenNebula/DatastorePool.rb \ + src/oca/ruby/OpenNebula/Cluster.rb \ + src/oca/ruby/OpenNebula/ClusterPool.rb \ src/oca/ruby/OpenNebula/XMLUtils.rb" #------------------------------------------------------------------------------- @@ -1068,7 +1071,8 @@ ONE_CLI_LIB_FILES="src/cli/one_helper/onegroup_helper.rb \ src/cli/one_helper/onevm_helper.rb \ src/cli/one_helper/onevnet_helper.rb \ src/cli/one_helper/oneacl_helper.rb \ - src/cli/one_helper/onedatastore_helper.rb" + src/cli/one_helper/onedatastore_helper.rb \ + src/cli/one_helper/onecluster_helper.rb" CLI_BIN_FILES="src/cli/onevm \ src/cli/onehost \ @@ -1078,7 +1082,8 @@ CLI_BIN_FILES="src/cli/onevm \ src/cli/onetemplate \ src/cli/onegroup \ src/cli/oneacl \ - src/cli/onedatastore" + src/cli/onedatastore \ + src/cli/onecluster" CLI_CONF_FILES="src/cli/etc/onegroup.yaml \ src/cli/etc/onehost.yaml \ @@ -1088,7 +1093,8 @@ CLI_CONF_FILES="src/cli/etc/onegroup.yaml \ src/cli/etc/onevm.yaml \ src/cli/etc/onevnet.yaml \ src/cli/etc/oneacl.yaml \ - src/cli/etc/onedatastore.yaml" + src/cli/etc/onedatastore.yaml \ + src/cli/etc/onecluster.yaml" ETC_CLIENT_FILES="src/cli/etc/group.default" @@ -1423,6 +1429,7 @@ MAN_FILES="share/man/oneauth.1.gz \ share/man/onegroup.1.gz \ share/man/onedb.1.gz \ share/man/onedatastore.1.gz \ + share/man/onecluster.1.gz \ share/man/econe-describe-images.1.gz \ share/man/econe-describe-instances.1.gz \ share/man/econe-register.1.gz \ diff --git a/src/cli/etc/onecluster.yaml b/src/cli/etc/onecluster.yaml new file mode 100644 index 0000000000..b69de015c6 --- /dev/null +++ b/src/cli/etc/onecluster.yaml @@ -0,0 +1,14 @@ +--- +:ID: + :desc: ONE identifier for the Cluster + :size: 4 + +:NAME: + :desc: Name of the Cluster + :size: 15 + :left: true + +:default: +- :ID +- :NAME + diff --git a/src/cli/one_helper/onecluster_helper.rb b/src/cli/one_helper/onecluster_helper.rb new file mode 100644 index 0000000000..087ef5d507 --- /dev/null +++ b/src/cli/one_helper/onecluster_helper.rb @@ -0,0 +1,76 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +require 'one_helper' + +class OneClusterHelper < OpenNebulaHelper::OneHelper + def self.rname + "CLUSTER" + end + + def self.conf_file + "onecluster.yaml" + end + + def format_pool(options) + config_file = self.class.table_conf + + table = CLIHelper::ShowTable.new(config_file, self) do + column :ID, "ONE identifier for the Cluster", :size=>4 do |d| + d["ID"] + end + + column :NAME, "Name of the Cluster", :left, :size=>15 do |d| + d["NAME"] + end + + default :ID, :NAME + end + + table + end + + private + + def factory(id=nil) + if id + OpenNebula::Cluster.new_with_id(id, @client) + else + xml=OpenNebula::Cluster.build_xml + OpenNebula::Cluster.new(xml, @client) + end + end + + def factory_pool(user_flag=-2) + OpenNebula::ClusterPool.new(@client) + end + + def format_resource(cluster) + str="%-15s: %-20s" + str_h1="%-80s" + + CLIHelper.print_header(str_h1 % "CLUSTER #{cluster['ID']} INFORMATION") + puts str % ["ID", cluster.id.to_s] + puts str % ["NAME", cluster.name] + puts + + CLIHelper.print_header(str_h1 % "HOSTS", false) + CLIHelper.print_header("%-15s" % ["ID"]) + cluster.host_ids.each do |id| + puts "%-15s" % [id] + end + end +end diff --git a/src/cli/onecluster b/src/cli/onecluster new file mode 100755 index 0000000000..eb99ed827e --- /dev/null +++ b/src/cli/onecluster @@ -0,0 +1,100 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +ONE_LOCATION=ENV["ONE_LOCATION"] + +if !ONE_LOCATION + RUBY_LIB_LOCATION="/usr/lib/one/ruby" +else + RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" +end + +$: << RUBY_LIB_LOCATION +$: << RUBY_LIB_LOCATION+"/cli" + +require 'command_parser' +require 'one_helper/onecluster_helper' + +cmd=CommandParser::CmdParser.new(ARGV) do + usage "`onecluster` [] []" + version OpenNebulaHelper::ONE_VERSION + + helper = OneClusterHelper.new + + ######################################################################## + # Global Options + ######################################################################## + set :option, CommandParser::OPTIONS + + list_options = CLIHelper::OPTIONS + list_options << OpenNebulaHelper::XML + list_options << OpenNebulaHelper::NUMERIC + + ######################################################################## + # Formatters for arguments + ######################################################################## + set :format, :clusterid, OneClusterHelper.to_id_desc do |arg| + helper.to_id(arg) + end + + set :format, :clusterid_list, OneClusterHelper.list_to_id_desc do |arg| + helper.list_to_id(arg) + end + + ######################################################################## + # Commands + ######################################################################## + + create_desc = <<-EOT.unindent + Creates a new Cluster + EOT + + command :create, create_desc, :name do + helper.create_resource(options) do |cluster| + cluster.allocate(args[0]) + end + end + + delete_desc = <<-EOT.unindent + Deletes the given Cluster + EOT + + command :delete, delete_desc, [:range, :clusterid_list] do + helper.perform_actions(args[0],options,"deleted") do |obj| + obj.delete + end + end + + list_desc = <<-EOT.unindent + Lists Clusters in the pool + EOT + + command :list, list_desc, :options=>list_options do + helper.list_pool(options) + end + + show_desc = <<-EOT.unindent + Shows information for the given Cluster + EOT + + command :show, show_desc,[:clusterid, nil], :options=>OpenNebulaHelper::XML do + cluster = args[0] || OpenNebula::Cluster::SELF + helper.show_resource(cluster,options) + end + +end diff --git a/src/cluster/Cluster.cc b/src/cluster/Cluster.cc new file mode 100644 index 0000000000..44d1cb6ce3 --- /dev/null +++ b/src/cluster/Cluster.cc @@ -0,0 +1,191 @@ +/* ------------------------------------------------------------------------ */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* ------------------------------------------------------------------------ */ + +#include +#include + +#include +#include + +#include "Cluster.h" +#include "GroupPool.h" + +const char * Cluster::table = "cluster_pool"; + +const char * Cluster::db_names = + "oid, name, body, uid, gid, owner_u, group_u, other_u"; + +const char * Cluster::db_bootstrap = "CREATE TABLE IF NOT EXISTS cluster_pool (" + "oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, " + "gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, " + "UNIQUE(name))"; + +/* ************************************************************************ */ +/* Cluster :: Database Access Functions */ +/* ************************************************************************ */ + +int Cluster::insert_replace(SqlDB *db, bool replace, string& error_str) +{ + ostringstream oss; + + int rc; + string xml_body; + + char * sql_name; + char * sql_xml; + + // Set the owner and group to oneadmin + set_user(0, ""); + set_group(GroupPool::ONEADMIN_ID, GroupPool::ONEADMIN_NAME); + + // 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 ( 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 Cluster 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 Cluster in DB."; +error_common: + return -1; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +string& Cluster::to_xml(string& xml) const +{ + ostringstream oss; + string collection_xml; + + ObjectCollection::to_xml(collection_xml); + + oss << + "" << + "" << oid << "" << + "" << name << "" << + collection_xml << + ""; + + xml = oss.str(); + + return xml; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +int Cluster::from_xml(const string& xml) +{ + int rc = 0; + vector content; + + // 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"); + + // Set oneadmin as the owner + set_user(0,""); + + // Set the Cluster ID as the cluster it belongs to + set_group(oid, name); + + // Get associated classes + ObjectXML::get_nodes("/CLUSTER/HOSTS", content); + + if (content.empty()) + { + return -1; + } + + // Set of IDs + rc += ObjectCollection::from_xml_node(content[0]); + + ObjectXML::free_nodes(content); + + 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..3e6924a962 --- /dev/null +++ b/src/cluster/ClusterPool.cc @@ -0,0 +1,154 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#include "ClusterPool.h" +#include "Nebula.h" +#include "NebulaLog.h" + +#include + +/* -------------------------------------------------------------------------- */ +/* There is a default cluster boostrapped by the core: */ +/* The first 100 cluster IDs are reserved for system clusters. */ +/* Regular ones start from ID 100 */ +/* -------------------------------------------------------------------------- */ + +const string ClusterPool::DEFAULT_CLUSTER_NAME = "default"; +const int ClusterPool::DEFAULT_CLUSTER_ID = 0; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +ClusterPool::ClusterPool(SqlDB * db):PoolSQL(db, Cluster::table) +{ + ostringstream oss; + string error_str; + + if (get_lastOID() == -1) //lastOID is set in PoolSQL::init_cb + { + int rc; + Cluster * cluster; + + cluster = new Cluster(DEFAULT_CLUSTER_ID, DEFAULT_CLUSTER_NAME); + + rc = PoolSQL::allocate(cluster, error_str); + + if( rc < 0 ) + { + goto error_bootstrap; + } + + set_update_lastOID(99); + } + + return; + +error_bootstrap: + oss << "Error trying to create default cluster: " << error_str; + NebulaLog::log("CLUSTER",Log::ERROR,oss); + + throw runtime_error(oss.str()); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int ClusterPool::allocate(string name, int * oid, string& error_str) +{ + Cluster * cluster; + ostringstream oss; + + if ( name.empty() ) + { + goto error_name; + } + + if ( name.length() > 128 ) + { + goto error_name_length; + } + + // 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_name_length: + oss << "NAME is too long; max length is 128 chars."; + 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(PoolObjectSQL * objsql, string& error_msg) +{ + Cluster * cluster = static_cast(objsql); + + int rc; + + // Return error if the cluster is a default one. + if( cluster->get_oid() < 100 ) + { + error_msg = "System Clusters (ID < 100) cannot be deleted."; + NebulaLog::log("CLUSTER", Log::ERROR, error_msg); + return -2; + } + + if( cluster->get_collection_size() > 0 ) + { + ostringstream oss; + oss << "Cluster " << cluster->get_oid() << " is not empty."; + error_msg = oss.str(); + NebulaLog::log("CLUSTER", Log::ERROR, error_msg); + + return -3; + } + + rc = cluster->drop(db); + + if( rc != 0 ) + { + error_msg = "SQL DB error"; + rc = -1; + } + + return rc; +} diff --git a/src/cluster/SConstruct b/src/cluster/SConstruct new file mode 100644 index 0000000000..c088beebc3 --- /dev/null +++ b/src/cluster/SConstruct @@ -0,0 +1,30 @@ +# SConstruct for src/group + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +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/nebula/Nebula.cc b/src/nebula/Nebula.cc index fbcd027a83..cb424a74e9 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -249,6 +249,7 @@ void Nebula::start() rc += VMTemplatePool::bootstrap(db); rc += AclManager::bootstrap(db); rc += DatastorePool::bootstrap(db); + rc += ClusterPool::bootstrap(db); // Create the versioning table only if bootstrap went well if ( rc == 0 ) @@ -314,6 +315,8 @@ void Nebula::start() tpool = new VMTemplatePool(db); dspool = new DatastorePool(db); + + clpool = new ClusterPool(db); } catch (exception&) { diff --git a/src/nebula/SConstruct b/src/nebula/SConstruct index 722376edaf..270373332c 100644 --- a/src/nebula/SConstruct +++ b/src/nebula/SConstruct @@ -50,6 +50,7 @@ env.Prepend(LIBS=[ 'nebula_image', 'nebula_pool', 'nebula_host', + 'nebula_cluster', 'nebula_vnm', 'nebula_vm', 'nebula_vmtemplate', diff --git a/src/oca/ruby/OpenNebula.rb b/src/oca/ruby/OpenNebula.rb index 17f8f27aaa..525a18d521 100644 --- a/src/oca/ruby/OpenNebula.rb +++ b/src/oca/ruby/OpenNebula.rb @@ -44,6 +44,8 @@ require 'OpenNebula/Acl' require 'OpenNebula/AclPool' require 'OpenNebula/Datastore' require 'OpenNebula/DatastorePool' +require 'OpenNebula/Cluster' +require 'OpenNebula/ClusterPool' module OpenNebula diff --git a/src/oca/ruby/OpenNebula/Cluster.rb b/src/oca/ruby/OpenNebula/Cluster.rb new file mode 100644 index 0000000000..699445e117 --- /dev/null +++ b/src/oca/ruby/OpenNebula/Cluster.rb @@ -0,0 +1,99 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + + +require 'OpenNebula/Pool' + +module OpenNebula + class Cluster < PoolElement + ####################################################################### + # Constants and Class Methods + ####################################################################### + + CLUSTER_METHODS = { + :info => "cluster.info", + :allocate => "cluster.allocate", + :delete => "cluster.delete" + } + + # Creates a Cluster description with just its identifier + # this method should be used to create plain Cluster objects. + # +id+ the id of the host + # + # Example: + # cluster = Cluster.new(Cluster.build_xml(3),rpc_client) + # + def Cluster.build_xml(pe_id=nil) + if pe_id + cluster_xml = "#{pe_id}" + else + cluster_xml = "" + end + + XMLElement.build_xml(cluster_xml,'CLUSTER') + end + + # Class constructor + def initialize(xml, client) + super(xml,client) + end + + ####################################################################### + # XML-RPC Methods for the Cluster Object + ####################################################################### + + # Retrieves the information of the given Cluster. + def info() + super(CLUSTER_METHODS[:info], 'CLUSTER') + end + + # Allocates a new Cluster in OpenNebula + # + # +clustername+ A string containing the name of the Cluster. + def allocate(clustername) + super(CLUSTER_METHODS[:allocate], clustername) + end + + # Deletes the Cluster + def delete() + super(CLUSTER_METHODS[:delete]) + end + + # --------------------------------------------------------------------- + # Helpers to get information + # --------------------------------------------------------------------- + + # Returns whether or not the host with id 'uid' is part of this group + def contains(uid) + #This doesn't work in ruby 1.8.5 + #return self["HOSTS/ID[.=#{uid}]"] != nil + + id_array = retrieve_elements('HOSTS/ID') + return id_array != nil && id_array.include?(uid.to_s) + end + + # Returns an array with the numeric host ids + def host_ids + array = Array.new + + self.each("HOSTS/ID") do |id| + array << id.text.to_i + end + + return array + end + end +end diff --git a/src/oca/ruby/OpenNebula/ClusterPool.rb b/src/oca/ruby/OpenNebula/ClusterPool.rb new file mode 100644 index 0000000000..8885c399c7 --- /dev/null +++ b/src/oca/ruby/OpenNebula/ClusterPool.rb @@ -0,0 +1,53 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + + +require 'OpenNebula/Pool' + +module OpenNebula + class ClusterPool < Pool + ####################################################################### + # Constants and Class attribute accessors + ####################################################################### + + CLUSTER_POOL_METHODS = { + :info => "clusterpool.info" + } + + ####################################################################### + # Class constructor & Pool Methods + ####################################################################### + + # +client+ a Client object that represents a XML-RPC connection + def initialize(client) + super('CLUSTER_POOL','CLUSTER',client) + end + + # Factory method to create Cluster objects + def factory(element_xml) + OpenNebula::Cluster.new(element_xml,@client) + end + + ####################################################################### + # XML-RPC Methods for the Cluster Object + ####################################################################### + + # Retrieves all the Clusters in the pool. + def info() + super(CLUSTER_POOL_METHODS[:info]) + end + end +end diff --git a/src/rm/Request.cc b/src/rm/Request.cc index 704eb9e2f1..cf50bec1ed 100644 --- a/src/rm/Request.cc +++ b/src/rm/Request.cc @@ -179,6 +179,8 @@ string Request::object_name(PoolObjectSQL::ObjectType ob) return "ACL"; case PoolObjectSQL::DATASTORE: return "datastore"; + case PoolObjectSQL::CLUSTER: + return "cluster"; default: return "-"; } diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 8333a16ee5..b73c8723fb 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -264,6 +264,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr host_allocate(new HostAllocate()); xmlrpc_c::methodPtr user_allocate(new UserAllocate()); xmlrpc_c::methodPtr datastore_allocate(new DatastoreAllocate()); + xmlrpc_c::methodPtr cluster_allocate(new ClusterAllocate()); // Delete Methods xmlrpc_c::methodPtr host_delete(new HostDelete()); @@ -273,6 +274,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr user_delete(new UserDelete()); xmlrpc_c::methodPtr image_delete(new ImageDelete()); xmlrpc_c::methodPtr datastore_delete(new DatastoreDelete()); + xmlrpc_c::methodPtr cluster_delete(new ClusterDelete()); // Info Methods xmlrpc_c::methodPtr vm_info(new VirtualMachineInfo()); @@ -283,6 +285,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr user_info(new UserInfo()); xmlrpc_c::methodPtr image_info(new ImageInfo()); xmlrpc_c::methodPtr datastore_info(new DatastoreInfo()); + xmlrpc_c::methodPtr cluster_info(new ClusterInfo()); // PoolInfo Methods xmlrpc_c::methodPtr hostpool_info(new HostPoolInfo()); @@ -293,6 +296,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr template_pool_info(new TemplatePoolInfo()); xmlrpc_c::methodPtr vnpool_info(new VirtualNetworkPoolInfo()); xmlrpc_c::methodPtr imagepool_info(new ImagePoolInfo()); + xmlrpc_c::methodPtr clusterpool_info(new ClusterPoolInfo()); // Host Methods xmlrpc_c::methodPtr host_enable(new HostEnable()); @@ -409,6 +413,12 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.datastorepool.info",datastorepool_info); + /* Cluster related methods */ + RequestManagerRegistry.addMethod("one.cluster.allocate",cluster_allocate); + RequestManagerRegistry.addMethod("one.cluster.delete", cluster_delete); + RequestManagerRegistry.addMethod("one.cluster.info", cluster_info); + + RequestManagerRegistry.addMethod("one.clusterpool.info",clusterpool_info); }; /* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 1ab4a814d0..b6b32298fe 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -386,3 +386,19 @@ int DatastoreAllocate::pool_allocate( return dspool->allocate(ds_tmpl, &id, error_str); } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int ClusterAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, + Template * tmpl, + int& id, + string& error_str, + RequestAttributes& att) +{ + string name = xmlrpc_c::value_string(paramList.getString(1)); + + ClusterPool * clpool = static_cast(pool); + + return clpool->allocate(name, &id, error_str); +} diff --git a/src/rm/RequestManagerPoolInfoFilter.cc b/src/rm/RequestManagerPoolInfoFilter.cc index c3d432480b..e40db5da8d 100644 --- a/src/rm/RequestManagerPoolInfoFilter.cc +++ b/src/rm/RequestManagerPoolInfoFilter.cc @@ -131,6 +131,16 @@ void DatastorePoolInfo::request_execute( /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +void ClusterPoolInfo::request_execute( + xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + dump(att, ALL, -1, -1, "", ""); +} + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + void RequestManagerPoolInfoFilter::dump( RequestAttributes& att, int filter_flag, From 3e09376ac37ad9f443633497a9986757285f6792 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 24 Feb 2012 16:50:12 +0100 Subject: [PATCH 043/217] Remove TM_MAD from OCA and CLI --- src/acct/watch_helper.rb | 4 ++-- src/cli/one_helper/onehost_helper.rb | 1 - src/cli/onehost | 4 ++-- src/oca/java/src/org/opennebula/client/host/Host.java | 6 ++---- src/oca/java/test/HostTest.java | 6 ++---- src/oca/ruby/OpenNebula/Host.rb | 10 +++++----- 6 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/acct/watch_helper.rb b/src/acct/watch_helper.rb index 218b992369..925b0b18c3 100644 --- a/src/acct/watch_helper.rb +++ b/src/acct/watch_helper.rb @@ -151,7 +151,7 @@ module WatchHelper String :name String :im_mad String :vm_mad - String :tm_mad + String :vn_mad end DB.create_table? :vm_timestamps do @@ -422,7 +422,7 @@ module WatchHelper h.name = host['NAME'] h.im_mad = host['IM_MAD'] h.vm_mad = host['VM_MAD'] - h.tm_mad = host['TM_MAD'] + h.vn_mad = host['VN_MAD'] } end diff --git a/src/cli/one_helper/onehost_helper.rb b/src/cli/one_helper/onehost_helper.rb index b50a02c617..306b1fcf75 100644 --- a/src/cli/one_helper/onehost_helper.rb +++ b/src/cli/one_helper/onehost_helper.rb @@ -122,7 +122,6 @@ class OneHostHelper < OpenNebulaHelper::OneHelper puts str % ["IM_MAD", host['IM_MAD']] puts str % ["VM_MAD", host['VM_MAD']] puts str % ["VN_MAD", host['VN_MAD']] - puts str % ["TM_MAD", host['TM_MAD']] puts str % ["LAST MONITORING TIME", host['LAST_MON_TIME']] puts diff --git a/src/cli/onehost b/src/cli/onehost index 40dbfe737e..115e2f7098 100755 --- a/src/cli/onehost +++ b/src/cli/onehost @@ -61,9 +61,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :create, create_desc, :hostname, :im_mad, :vmm_mad, - :tm_mad, :vnm_mad do + :vnm_mad do helper.create_resource(options) do |host| - host.allocate(args[0], args[1], args[2], args[4], args[3]) + host.allocate(args[0], args[1], args[2], args[3]) end end diff --git a/src/oca/java/src/org/opennebula/client/host/Host.java b/src/oca/java/src/org/opennebula/client/host/Host.java index d264d79130..13fbe45117 100644 --- a/src/oca/java/src/org/opennebula/client/host/Host.java +++ b/src/oca/java/src/org/opennebula/client/host/Host.java @@ -75,7 +75,6 @@ public class Host extends PoolElement{ * @param vnm The name of the virtual network manager mad name * (vnm_mad_name), this values are taken from the oned.conf with the * tag name VN_MAD (name) - * @param tm The transfer manager mad name to be used with this host * @return If successful the message contains the associated * id generated for this host */ @@ -83,10 +82,9 @@ public class Host extends PoolElement{ String hostname, String im, String vmm, - String vnm, - String tm) + String vnm) { - return client.call(ALLOCATE, hostname, im, vmm, vnm, tm); + return client.call(ALLOCATE, hostname, im, vmm, vnm); } /** diff --git a/src/oca/java/test/HostTest.java b/src/oca/java/test/HostTest.java index 431b3ac11e..4126a259eb 100644 --- a/src/oca/java/test/HostTest.java +++ b/src/oca/java/test/HostTest.java @@ -63,8 +63,7 @@ public class HostTest @Before public void setUp() throws Exception { - res = Host.allocate(client, name, "im_dummy", "vmm_dummy", "vnm_dummy", - "tm_dummy"); + res = Host.allocate(client, name, "im_dummy", "vmm_dummy", "vnm_dummy"); int hid = !res.isError() ? Integer.parseInt(res.getMessage()) : -1; host = new Host(hid, client); @@ -84,8 +83,7 @@ public class HostTest { String name = "allocate_test"; - res = Host.allocate(client, name, "im_dummy", "vmm_dummy", "vmm_dummy", - "tm_dummy"); + res = Host.allocate(client, name, "im_dummy", "vmm_dummy", "vmm_dummy"); assertTrue( !res.isError() ); // assertTrue( res.getMessage().equals("0") ); diff --git a/src/oca/ruby/OpenNebula/Host.rb b/src/oca/ruby/OpenNebula/Host.rb index 74bb2e8edb..4a77bd2756 100644 --- a/src/oca/ruby/OpenNebula/Host.rb +++ b/src/oca/ruby/OpenNebula/Host.rb @@ -79,14 +79,14 @@ module OpenNebula # Allocates a new Host in OpenNebula # # @param hostname [String] Name of the new Host. - # @param im [String] Name of the im_driver - # @param vmm [String] Name of the vmm_driver - # @param tm [String] Name of the tm_driver + # @param im [String] Name of the im_driver (information/monitoring) + # @param vmm [String] Name of the vmm_driver (hypervisor) + # @param tm [String] Name of the vnm_driver (networking) # # @return [Integer, OpenNebula::Error] the new ID in case of # success, error otherwise - def allocate(hostname,im,vmm,vnm,tm) - super(HOST_METHODS[:allocate],hostname,im,vmm,vnm,tm) + def allocate(hostname,im,vmm,vnm) + super(HOST_METHODS[:allocate],hostname,im,vmm,vnm) end # Deletes the Host From 304db6457bb05081d28741715302e04723ad088b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 24 Feb 2012 16:54:28 +0100 Subject: [PATCH 044/217] Feature #1112: Remove duplicated cluster header --- include/ClusterPoolOld.h | 140 --------------------------------------- 1 file changed, 140 deletions(-) delete mode 100644 include/ClusterPoolOld.h diff --git a/include/ClusterPoolOld.h b/include/ClusterPoolOld.h deleted file mode 100644 index f9f92fe10b..0000000000 --- a/include/ClusterPoolOld.h +++ /dev/null @@ -1,140 +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. */ -/* -------------------------------------------------------------------------- */ - -#ifndef CLUSTER_POOL_H_ -#define CLUSTER_POOL_H_ - -#include -#include -#include - -#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 -{ -public: - /** - * Cluster name for the default cluster - */ - static const string DEFAULT_CLUSTER_NAME; - -private: - // ------------------------------------------------------------------------- - // Friends - // ------------------------------------------------------------------------- - friend class HostPool; - - /* ---------------------------------------------------------------------- */ - /* Attributes */ - /* ---------------------------------------------------------------------- */ - /** - * 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); - - /** - * Returns the xml representation of the given cluster - * @param clid ID of the cluster - * - * @return the xml representation of the given cluster - */ - 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) - { - ostringstream oss(ClusterPool::db_bootstrap); - db->exec(oss); - }; - - /** - * 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 - * - * @return 0 on success - */ - void dump_cluster(ostringstream& oss, int id, string name); - - - /* ---------------------------------------------------------------------- */ - /* DB manipulation */ - /* ---------------------------------------------------------------------- */ - - static const char * db_names; - - static const char * db_bootstrap; - - static const char * table; - -}; - -#endif /*CLUSTER_POOL_H_*/ From 68fd9211508b44944cfb4caf1ca915f69e443691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 24 Feb 2012 18:28:15 +0100 Subject: [PATCH 045/217] Feature #1112: onecluster show id param is not optional --- src/cli/onecluster | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cli/onecluster b/src/cli/onecluster index eb99ed827e..3af1a1aa8e 100755 --- a/src/cli/onecluster +++ b/src/cli/onecluster @@ -92,9 +92,8 @@ cmd=CommandParser::CmdParser.new(ARGV) do Shows information for the given Cluster EOT - command :show, show_desc,[:clusterid, nil], :options=>OpenNebulaHelper::XML do - cluster = args[0] || OpenNebula::Cluster::SELF - helper.show_resource(cluster,options) + command :show, show_desc,:clusterid, :options=>OpenNebulaHelper::XML do + helper.show_resource(args[0],options) end end From 2580411adf624a283a8c13dfce196df386b3a1b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 24 Feb 2012 18:53:18 +0100 Subject: [PATCH 046/217] Feature #1112: Add cluster attribute to Host --- include/Host.h | 40 ++++++++++++++++++++++++++++---- include/HostPool.h | 4 +++- src/host/Host.cc | 13 +++++++++-- src/host/HostPool.cc | 37 ++++++++++++++++++++++++++++- src/rm/RequestManagerAllocate.cc | 9 ++++++- 5 files changed, 93 insertions(+), 10 deletions(-) diff --git a/include/Host.h b/include/Host.h index 0915813eac..7de9216cb8 100644 --- a/include/Host.h +++ b/include/Host.h @@ -166,6 +166,28 @@ public: return last_monitored; }; + /** + * Changes the cluster this host belongs to + * + * @param _cluster_id Id of the new cluster + * @param _cluster Name of the new cluter + */ + void set_cluster(int _cluster_id, const string& _cluster) + { + cluster_id = _cluster_id; + cluster = _cluster; + }; + + /** + * Returns the cluster ID + * + * @return The cluster ID + */ + int get_cluster_id() + { + return cluster_id; + }; + // ------------------------------------------------------------------------ // Share functions // ------------------------------------------------------------------------ @@ -322,6 +344,12 @@ private: */ time_t last_monitored; + int cluster_id; + /** + * Name of the cluster this host belongs to. + */ + string cluster; + // ------------------------------------------------------------------------- // Host Attributes // ------------------------------------------------------------------------- @@ -334,11 +362,13 @@ private: // Constructor // ************************************************************************* - Host(int id=-1, - const string& hostname="", - const string& im_mad_name="", - const string& vmm_mad_name="", - const string& vnm_mad_name=""); + Host(int id, + const string& hostname, + const string& im_mad_name, + const string& vmm_mad_name, + const string& vnm_mad_name, + int cluster_id, + const string& cluster_name); virtual ~Host(); diff --git a/include/HostPool.h b/include/HostPool.h index 0d0f016234..0de6e8f8e4 100644 --- a/include/HostPool.h +++ b/include/HostPool.h @@ -53,6 +53,8 @@ public: const string& im_mad_name, const string& vmm_mad_name, const string& vnm_mad_name, + int cluster_id, + const string& cluster_name, string& error_str); /** @@ -202,7 +204,7 @@ private: */ PoolObjectSQL * create() { - return new Host; + return new Host(-1,"","","","",-1,""); }; /** diff --git a/src/host/Host.cc b/src/host/Host.cc index 084568f502..977d928aa4 100644 --- a/src/host/Host.cc +++ b/src/host/Host.cc @@ -33,13 +33,17 @@ Host::Host( const string& _hostname, const string& _im_mad_name, const string& _vmm_mad_name, - const string& _vnm_mad_name): + const string& _vnm_mad_name, + int _cluster_id, + const string& _cluster_name): PoolObjectSQL(id,HOST,_hostname,-1,-1,"","",table), state(INIT), im_mad_name(_im_mad_name), vmm_mad_name(_vmm_mad_name), vnm_mad_name(_vnm_mad_name), - last_monitored(0) + last_monitored(0), + cluster_id(_cluster_id), + cluster(_cluster_name) { obj_template = new HostTemplate; } @@ -204,6 +208,8 @@ string& Host::to_xml(string& xml) const "" << vmm_mad_name << "" << "" << vnm_mad_name << "" << "" << last_monitored << "" << + "" << cluster_id << "" << + "" << cluster << "" << host_share.to_xml(share_xml) << obj_template->to_xml(template_xml) << ""; @@ -237,6 +243,9 @@ int Host::from_xml(const string& xml) rc += xpath(last_monitored, "/HOST/LAST_MON_TIME", 0); + rc += xpath(cluster_id, "/HOST/CLUSTER_ID", -1); + rc += xpath(cluster, "/HOST/CLUSTER", "not_found"); + state = static_cast( int_state ); // Set the owner and group to oneadmin diff --git a/src/host/HostPool.cc b/src/host/HostPool.cc index 82b99a3418..e23132daab 100644 --- a/src/host/HostPool.cc +++ b/src/host/HostPool.cc @@ -25,6 +25,7 @@ #include "HostHook.h" #include "NebulaLog.h" #include "GroupPool.h" +#include "Nebula.h" /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -153,11 +154,18 @@ int HostPool::allocate ( const string& im_mad_name, const string& vmm_mad_name, const string& vnm_mad_name, + int cluster_id, + const string& cluster_name, string& error_str) { + Nebula& nd = Nebula::instance(); + Host * host; ostringstream oss; + ClusterPool * clpool; + Cluster * cluster; + if ( hostname.empty() ) { goto error_name; @@ -192,12 +200,39 @@ int HostPool::allocate ( // Build a new Host object - host = new Host(-1, hostname, im_mad_name, vmm_mad_name, vnm_mad_name); + host = new Host( + -1, + hostname, + im_mad_name, + vmm_mad_name, + vnm_mad_name, + cluster_id, + cluster_name); // Insert the Object in the pool *oid = PoolSQL::allocate(host, error_str); + if ( *oid < 0 ) + { + return *oid; + } + + // Add Host to Cluster + clpool = nd.get_clpool(); + cluster = clpool->get(cluster_id, true); + + if( cluster == 0 ) + { + return -1; + } + + cluster->add_host(*oid); + + clpool->update(cluster); + + cluster->unlock(); + return *oid; diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index b6b32298fe..3797e9227b 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -317,9 +317,16 @@ int HostAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, string vmm_mad = xmlrpc_c::value_string(paramList.getString(3)); string vnm_mad = xmlrpc_c::value_string(paramList.getString(4)); + int rc; + + // TODO: include another int parameter for the cluster? + int cluster_id = ClusterPool::DEFAULT_CLUSTER_ID; + string cluster_name = ClusterPool::DEFAULT_CLUSTER_NAME; + HostPool * hpool = static_cast(pool); - return hpool->allocate(&id, host, im_mad, vmm_mad, vnm_mad, error_str); + return hpool->allocate(&id, host, im_mad, vmm_mad, vnm_mad, + cluster_id, cluster_name, error_str); } /* -------------------------------------------------------------------------- */ From f6615f66d241f931550174efe2d319c395b8296b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 24 Feb 2012 18:55:21 +0100 Subject: [PATCH 047/217] Feature #1112: New method & command onecluster addhost --- include/RequestManagerCluster.h | 86 ++++++++++++++ src/cli/onecluster | 11 ++ src/oca/ruby/OpenNebula/Cluster.rb | 14 ++- src/rm/RequestManager.cc | 5 + src/rm/RequestManagerCluster.cc | 175 +++++++++++++++++++++++++++++ src/rm/SConstruct | 1 + 6 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 include/RequestManagerCluster.h create mode 100644 src/rm/RequestManagerCluster.cc diff --git a/include/RequestManagerCluster.h b/include/RequestManagerCluster.h new file mode 100644 index 0000000000..10c2f38977 --- /dev/null +++ b/include/RequestManagerCluster.h @@ -0,0 +1,86 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#ifndef REQUEST_MANAGER_CLUSTER_H +#define REQUEST_MANAGER_CLUSTER_H + +#include "Request.h" +#include "Nebula.h" + +using namespace std; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class RequestManagerCluster: public Request +{ +protected: + RequestManagerCluster(const string& method_name, + const string& help, + const string& params) + :Request(method_name,params,help) + { + Nebula& nd = Nebula::instance(); + clpool = nd.get_clpool(); + hpool = nd.get_hpool(); + + auth_object = PoolObjectSQL::CLUSTER; + auth_op = AuthRequest::MANAGE; + }; + + ~RequestManagerCluster(){}; + + /* --------------------------------------------------------------------- */ + + ClusterPool * clpool; + HostPool * hpool; + + /* --------------------------------------------------------------------- */ + + virtual void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att) = 0; + + int get_info (PoolSQL * pool, + int id, + PoolObjectSQL::ObjectType type, + RequestAttributes& att, + PoolObjectAuth& perms, + string& name); +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ClusterAddHost : public RequestManagerCluster +{ +public: + ClusterAddHost(): + RequestManagerCluster("ClusterAddHost", + "Adds a host to the cluster", + "A:sii"){}; + + ~ClusterAddHost(){}; + + void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att); +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +#endif diff --git a/src/cli/onecluster b/src/cli/onecluster index 3af1a1aa8e..7c04cc566d 100755 --- a/src/cli/onecluster +++ b/src/cli/onecluster @@ -96,4 +96,15 @@ cmd=CommandParser::CmdParser.new(ARGV) do helper.show_resource(args[0],options) end + addhost_desc = <<-EOT.unindent + Adds a Host to the given Cluster + EOT + + # TODO: allow the second param to be [:range, :hostid_list] + command :addhost, addhost_desc,:clusterid, :hostid do + helper.perform_actions(args[0],options,"updated") do |cluster| + cluster.addhost(args[1].to_i) + end + end + end diff --git a/src/oca/ruby/OpenNebula/Cluster.rb b/src/oca/ruby/OpenNebula/Cluster.rb index 699445e117..8cb0d1793f 100644 --- a/src/oca/ruby/OpenNebula/Cluster.rb +++ b/src/oca/ruby/OpenNebula/Cluster.rb @@ -26,7 +26,8 @@ module OpenNebula CLUSTER_METHODS = { :info => "cluster.info", :allocate => "cluster.allocate", - :delete => "cluster.delete" + :delete => "cluster.delete", + :addhost => "cluster.addhost" } # Creates a Cluster description with just its identifier @@ -72,6 +73,17 @@ module OpenNebula super(CLUSTER_METHODS[:delete]) end + # Adds a Host to this Cluster + # @param hid [Integer] Host ID + def addhost(hid) + return Error.new('ID not defined') if !@pe_id + + rc = @client.call(CLUSTER_METHODS[:addhost], @pe_id, hid) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + # --------------------------------------------------------------------- # Helpers to get information # --------------------------------------------------------------------- diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index b73c8723fb..c1085d2263 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -33,6 +33,7 @@ #include "RequestManagerImage.h" #include "RequestManagerUser.h" #include "RequestManagerAcl.h" +#include "RequestManagerCluster.h" #include #include @@ -324,6 +325,9 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr acl_delrule(new AclDelRule()); xmlrpc_c::methodPtr acl_info(new AclInfo()); + // Cluster Methods + xmlrpc_c::methodPtr cluster_addhost(new ClusterAddHost()); + /* VM related methods */ RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy); RequestManagerRegistry.addMethod("one.vm.action", vm_action); @@ -417,6 +421,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.cluster.allocate",cluster_allocate); RequestManagerRegistry.addMethod("one.cluster.delete", cluster_delete); RequestManagerRegistry.addMethod("one.cluster.info", cluster_info); + RequestManagerRegistry.addMethod("one.cluster.addhost", cluster_addhost); RequestManagerRegistry.addMethod("one.clusterpool.info",clusterpool_info); }; diff --git a/src/rm/RequestManagerCluster.cc b/src/rm/RequestManagerCluster.cc new file mode 100644 index 0000000000..315162d72d --- /dev/null +++ b/src/rm/RequestManagerCluster.cc @@ -0,0 +1,175 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#include "RequestManagerCluster.h" + +using namespace std; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +// TODO: same method in RequestManagerChown, should be moved to Request + +int RequestManagerCluster::get_info (PoolSQL * pool, + int id, + PoolObjectSQL::ObjectType type, + RequestAttributes& att, + PoolObjectAuth& perms, + string& name) +{ + PoolObjectSQL * ob; + + if ((ob = pool->get(id,true)) == 0 ) + { + failure_response(NO_EXISTS, get_error(object_name(type), id), att); + return -1; + } + + ob->get_permissions(perms); + + name = ob->get_name(); + + ob->unlock(); + + return 0; +} + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +void ClusterAddHost::request_execute( + xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + int cluster_id = xmlrpc_c::value_int(paramList.getInt(1)); + int host_id = xmlrpc_c::value_int(paramList.getInt(2)); + int old_cluster_id; + + int rc; + + string cluster_name; + string host_name; + + Cluster * cluster; + Host * host; + + PoolObjectAuth c_perms; + PoolObjectAuth h_perms; + + rc = get_info(clpool, cluster_id, PoolObjectSQL::CLUSTER, att, c_perms, cluster_name); + + if ( rc == -1 ) + { + return; + } + + rc = get_info(hpool, host_id, PoolObjectSQL::HOST, att, h_perms, host_name); + + if ( rc == -1 ) + { + return; + } + + if ( att.uid != 0 ) + { + AuthRequest ar(att.uid, att.gid); + + ar.add_auth(auth_op, c_perms); // MANAGE CLUSTER + ar.add_auth(AuthRequest::ADMIN, h_perms); // ADMIN HOST + + if (UserPool::authorize(ar) == -1) + { + failure_response(AUTHORIZATION, + authorization_error(ar.message, att), + att); + + return; + } + } + + // ------------- Add host to new cluster --------------------- + + cluster = clpool->get(cluster_id, true); + + if ( cluster == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::CLUSTER),cluster_id), + att); + return; + } + + cluster->add_host(host_id); + + clpool->update(cluster); + + cluster->unlock(); + + // ------------- Set new cluster id in host --------------------- + + host = hpool->get(host_id, true); + + if ( host == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::HOST), host_id), + att); + + // TODO: rollback + // clpool->get (cluster_id) + // cluster->del_host(host_id); + + return; + } + + old_cluster_id = host->get_cluster_id(); + + if ( old_cluster_id == cluster_id ) + { + host->unlock(); + success_response(cluster_id, att); + return; + } + + host->set_cluster(cluster_id, cluster_name); + + hpool->update(host); + + host->unlock(); + + // ------------- Remove host from old cluster --------------------- + + cluster = clpool->get(old_cluster_id, true); + + if ( cluster == 0 ) + { + // This point should be unreachable. + // The old cluster is not empty (at least has the host_id), + // so it cannot be deleted + success_response(cluster_id, att); + return; + } + + cluster->del_host(host_id); + + clpool->update(cluster); + + cluster->unlock(); + + success_response(cluster_id, att); + + return; +} diff --git a/src/rm/SConstruct b/src/rm/SConstruct index cc692552f9..5c565c5b73 100644 --- a/src/rm/SConstruct +++ b/src/rm/SConstruct @@ -38,6 +38,7 @@ source_files=[ 'RequestManagerChown.cc', 'RequestManagerAcl.cc', 'RequestManagerChmod.cc', + 'RequestManagerCluster.cc' ] # Build library From f411c685d71ecdb121c90a897c6e5d35551e86b0 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 24 Feb 2012 21:12:50 +0100 Subject: [PATCH 048/217] Fix compilation for tests with the new classes --- src/authm/test/SConstruct | 1 + src/group/test/SConstruct | 1 + src/host/test/HostHookTest.cc | 39 +++++++++++-- src/host/test/HostPoolTest.cc | 78 ++++++++++++++++++++++---- src/host/test/SConstruct | 1 + src/image/test/ImagePoolTest.cc | 6 +- src/image/test/SConstruct | 1 + src/lcm/test/SConstruct | 1 + src/um/test/SConstruct | 1 + src/vnm/test/SConstruct | 1 + src/vnm/test/VirtualNetworkPoolTest.cc | 8 +-- 11 files changed, 116 insertions(+), 22 deletions(-) diff --git a/src/authm/test/SConstruct b/src/authm/test/SConstruct index 991d6585a5..0e5538fcc1 100644 --- a/src/authm/test/SConstruct +++ b/src/authm/test/SConstruct @@ -33,6 +33,7 @@ env.Prepend(LIBS=[ 'nebula_template', 'nebula_image', 'nebula_pool', + 'nebula_cluster', 'nebula_host', 'nebula_vnm', 'nebula_vm', diff --git a/src/group/test/SConstruct b/src/group/test/SConstruct index 0c87811f1b..2439c9babc 100644 --- a/src/group/test/SConstruct +++ b/src/group/test/SConstruct @@ -34,6 +34,7 @@ env.Prepend(LIBS=[ 'nebula_template', 'nebula_image', 'nebula_pool', + 'nebula_cluster', 'nebula_host', 'nebula_vnm', 'nebula_vm', diff --git a/src/host/test/HostHookTest.cc b/src/host/test/HostHookTest.cc index 46ffbd7b6c..a9e2222663 100644 --- a/src/host/test/HostHookTest.cc +++ b/src/host/test/HostHookTest.cc @@ -96,7 +96,15 @@ public: { string err; - hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", err); + hpool->allocate(&oid, + "host_test", + "im_mad", + "vmm_mad", + "vnm_mad", + ClusterPool::DEFAULT_CLUSTER_ID, + ClusterPool::DEFAULT_CLUSTER_NAME, + err); + CPPUNIT_ASSERT( oid >= 0 ); sleep(1); @@ -114,7 +122,15 @@ public: { string err; - hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", err); + + hpool->allocate(&oid, + "host_test", + "im_mad", + "vmm_mad", + "vnm_mad", + ClusterPool::DEFAULT_CLUSTER_ID, + ClusterPool::DEFAULT_CLUSTER_NAME, + err); CPPUNIT_ASSERT( oid >= 0 ); host = hpool->get(oid, true); @@ -140,7 +156,14 @@ public: { string err; - hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", err); + hpool->allocate(&oid, + "host_test", + "im_mad", + "vmm_mad", + "vnm_mad", + ClusterPool::DEFAULT_CLUSTER_ID, + ClusterPool::DEFAULT_CLUSTER_NAME, + err); CPPUNIT_ASSERT( oid >= 0 ); host = hpool->get(oid, true); @@ -166,7 +189,15 @@ public: { string err; - hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", err); + hpool->allocate(&oid, + "host_test", + "im_mad", + "vmm_mad", + "vnm_mad", + ClusterPool::DEFAULT_CLUSTER_ID, + ClusterPool::DEFAULT_CLUSTER_NAME, + err); + CPPUNIT_ASSERT( oid >= 0 ); host = hpool->get(oid, true); diff --git a/src/host/test/HostPoolTest.cc b/src/host/test/HostPoolTest.cc index a46de04219..35f60838d8 100644 --- a/src/host/test/HostPoolTest.cc +++ b/src/host/test/HostPoolTest.cc @@ -163,7 +163,9 @@ protected: int oid; string err; return ((HostPool*)pool)->allocate(&oid, names[index], im_mad, - vmm_mad, vnm_mad, err); + vmm_mad, vnm_mad, + ClusterPool::DEFAULT_CLUSTER_ID, + ClusterPool::DEFAULT_CLUSTER_NAME,err); }; void check(int index, PoolObjectSQL* obj) @@ -243,16 +245,37 @@ public: // If we try to allocate two hosts with the same name and drivers, // should fail - rc = hp->allocate(&oid_0, names[0], im_mad, vmm_mad, vnm_mad, err); + rc = hp->allocate(&oid_0, + names[0], + im_mad, + vmm_mad, + vnm_mad, + ClusterPool::DEFAULT_CLUSTER_ID, + ClusterPool::DEFAULT_CLUSTER_NAME, + err); CPPUNIT_ASSERT( oid_0 == 0 ); CPPUNIT_ASSERT( rc == oid_0 ); - rc = hp->allocate(&oid_1, names[0], im_mad, vmm_mad, vnm_mad, err); + rc = hp->allocate(&oid_1, + names[0], + im_mad, + vmm_mad, + vnm_mad, + ClusterPool::DEFAULT_CLUSTER_ID, + ClusterPool::DEFAULT_CLUSTER_NAME, + err); CPPUNIT_ASSERT( oid_1 == -1 ); CPPUNIT_ASSERT( rc == oid_1 ); // the hostname can not be repeated if the drivers change - rc = hp->allocate(&oid_1, names[0], im_mad_2, vmm_mad, vnm_mad, err); + rc = hp->allocate(&oid_1, + names[0], + im_mad_2, + vmm_mad, + vnm_mad, + ClusterPool::DEFAULT_CLUSTER_ID, + ClusterPool::DEFAULT_CLUSTER_NAME, + err); CPPUNIT_ASSERT( oid_1 == -1 ); CPPUNIT_ASSERT( rc == oid_1 ); @@ -272,8 +295,14 @@ public: for(int i=0; i<5; i++) { - ((HostPool*)pool)->allocate(&oid, names[i], - im_mad, vmm_mad, vnm_mad, err); + ((HostPool*)pool)->allocate(&oid, + names[i], + im_mad, + vmm_mad, + vnm_mad, + ClusterPool::DEFAULT_CLUSTER_ID, + ClusterPool::DEFAULT_CLUSTER_NAME, + err); } ostringstream oss; @@ -305,8 +334,14 @@ public: for(int i=0; i<5; i++) { - ((HostPool*)pool)->allocate(&oid, names[i], - im_mad, vmm_mad, vnm_mad, err); + ((HostPool*)pool)->allocate(&oid, + names[i], + im_mad, + vmm_mad, + vnm_mad, + ClusterPool::DEFAULT_CLUSTER_ID, + ClusterPool::DEFAULT_CLUSTER_NAME, + err); } ostringstream oss; @@ -345,7 +380,14 @@ public: { oss << "host" << i; - hp->allocate(&oid, oss.str().c_str(),im_mad, vmm_mad, vnm_mad, err); + hp->allocate(&oid, + oss.str(), + im_mad, + vmm_mad, + vnm_mad, + ClusterPool::DEFAULT_CLUSTER_ID, + ClusterPool::DEFAULT_CLUSTER_NAME, + err); CPPUNIT_ASSERT(oid == i); if (i >=8 ) @@ -403,7 +445,14 @@ public: { oss << "host" << j; - hp->allocate(&oid,oss.str().c_str(),im_mad,vmm_mad,vnm_mad,err); + hp->allocate(&oid, + oss.str(), + im_mad, + vmm_mad, + vnm_mad, + ClusterPool::DEFAULT_CLUSTER_ID, + ClusterPool::DEFAULT_CLUSTER_NAME, + err); } the_time2 = time(0) - the_time; @@ -432,7 +481,14 @@ public: for (i=10000,oss.str(""); i<30000 ; i++,oss.str("")) { oss << "host" << i; - hp->allocate(&oid,oss.str().c_str(),im_mad,vmm_mad,vnm_mad,err); + hp->allocate(&oid, + oss.str(), + im_mad, + vmm_mad, + vnm_mad, + ClusterPool::DEFAULT_CLUSTER_ID, + ClusterPool::DEFAULT_CLUSTER_NAME, + err); host = hp->get(oid, false); diff --git a/src/host/test/SConstruct b/src/host/test/SConstruct index 1774ad750b..c1359e3518 100644 --- a/src/host/test/SConstruct +++ b/src/host/test/SConstruct @@ -19,6 +19,7 @@ Import('env') env.Prepend(LIBS=[ + 'nebula_cluster', 'nebula_host', 'nebula_core_test', 'nebula_vmm', diff --git a/src/image/test/ImagePoolTest.cc b/src/image/test/ImagePoolTest.cc index f4d96a010b..11f1d82003 100644 --- a/src/image/test/ImagePoolTest.cc +++ b/src/image/test/ImagePoolTest.cc @@ -597,7 +597,7 @@ public: VectorAttribute * disk; int oid_0, oid_1, index, img_id; - string value; + string value, error; Image::ImageType img_type; // --------------------------------------------------------------------- @@ -632,7 +632,7 @@ public: disk = new VectorAttribute("DISK"); disk->replace("IMAGE_ID", "0"); - ((ImagePool*)imp)->disk_attribute(disk, 0, &index, &img_type,0, img_id); + ((ImagePool*)imp)->disk_attribute(disk, 0, &index, &img_type,0, img_id,error); value = ""; value = disk->vector_value("TARGET"); @@ -646,7 +646,7 @@ public: disk = new VectorAttribute("DISK"); disk->replace("IMAGE_ID", "1"); - ((ImagePool*)imp)->disk_attribute(disk, 0, &index, &img_type,0, img_id); + ((ImagePool*)imp)->disk_attribute(disk, 0, &index, &img_type,0, img_id,error); value = ""; value = disk->vector_value("TARGET"); diff --git a/src/image/test/SConstruct b/src/image/test/SConstruct index f52fdc7afa..b1f7b9ac8a 100644 --- a/src/image/test/SConstruct +++ b/src/image/test/SConstruct @@ -34,6 +34,7 @@ env.Prepend(LIBS=[ 'nebula_template', 'nebula_image', 'nebula_pool', + 'nebula_cluster', 'nebula_host', 'nebula_vnm', 'nebula_vm', diff --git a/src/lcm/test/SConstruct b/src/lcm/test/SConstruct index 85491401e3..bd5dc5bfd2 100644 --- a/src/lcm/test/SConstruct +++ b/src/lcm/test/SConstruct @@ -36,6 +36,7 @@ env.Prepend(LIBS=[ 'nebula_template', 'nebula_image', 'nebula_pool', + 'nebula_cluster', 'nebula_host', 'nebula_vnm', 'nebula_vm', diff --git a/src/um/test/SConstruct b/src/um/test/SConstruct index 371e074bc7..5d0ff663e0 100644 --- a/src/um/test/SConstruct +++ b/src/um/test/SConstruct @@ -34,6 +34,7 @@ env.Prepend(LIBS=[ 'nebula_template', 'nebula_image', 'nebula_pool', + 'nebula_cluster', 'nebula_host', 'nebula_vnm', 'nebula_vm', diff --git a/src/vnm/test/SConstruct b/src/vnm/test/SConstruct index 505a1e559a..1bb4837eb8 100644 --- a/src/vnm/test/SConstruct +++ b/src/vnm/test/SConstruct @@ -24,6 +24,7 @@ env.Prepend(LIBS=[ 'nebula_hm', 'nebula_rm', 'nebula_datastore', + 'nebula_cluster', 'nebula_dm', 'nebula_tm', 'nebula_um', diff --git a/src/vnm/test/VirtualNetworkPoolTest.cc b/src/vnm/test/VirtualNetworkPoolTest.cc index 5e57f71373..0f0f3f1da1 100644 --- a/src/vnm/test/VirtualNetworkPoolTest.cc +++ b/src/vnm/test/VirtualNetworkPoolTest.cc @@ -1067,7 +1067,7 @@ public: VectorAttribute * disk; int oid_0, oid_1; - string value; + string value, error; // --------------------------------------------------------------------- // Allocate 2 vnets @@ -1092,9 +1092,9 @@ public: disk = new VectorAttribute("DISK"); disk->replace("NETWORK", "Net 0"); - ((VirtualNetworkPool*)vnp)->nic_attribute(disk, 0, 0); + ((VirtualNetworkPool*)vnp)->nic_attribute(disk, 0, 0, error); - ((VirtualNetworkPool*)vnp)->nic_attribute(disk, 0, 0); + ((VirtualNetworkPool*)vnp)->nic_attribute(disk, 0, 0, error); value = ""; value = disk->vector_value("NETWORK"); @@ -1123,7 +1123,7 @@ public: disk = new VectorAttribute("DISK"); disk->replace("NETWORK_ID", "1"); - ((VirtualNetworkPool*)vnp)->nic_attribute(disk,0, 0); + ((VirtualNetworkPool*)vnp)->nic_attribute(disk,0, 0, error); value = ""; value = disk->vector_value("NETWORK"); From fc6aa51c0d853e762ff28949c18b7fa699ba5c91 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 24 Feb 2012 21:13:56 +0100 Subject: [PATCH 049/217] feature #962, feature #1112: Improve error messages when getting an Image or a Virtual Network --- include/ImageManager.h | 8 +++-- include/ImagePool.h | 4 ++- include/VirtualNetworkPool.h | 8 +++-- src/image/ImageManagerActions.cc | 32 ++++++++++++++---- src/image/ImagePool.cc | 16 ++++++--- src/vm/VirtualMachine.cc | 23 ++++++------- src/vnm/VirtualNetwork.cc | 4 +-- src/vnm/VirtualNetworkPool.cc | 56 +++++++++++++++++++++++++------- 8 files changed, 106 insertions(+), 45 deletions(-) diff --git a/include/ImageManager.h b/include/ImageManager.h index 95c6b7887b..98b30be801 100644 --- a/include/ImageManager.h +++ b/include/ImageManager.h @@ -82,17 +82,19 @@ public: /** * Try to acquire an image from the repository for a VM. * @param image_id id of image + * @param error string describing the error * @return pointer to the image or 0 if could not be acquired */ - Image * acquire_image(int image_id); + Image * acquire_image(int image_id, string& error); /** * Try to acquire an image from the repository for a VM. * @param name of the image * @param id of owner + * @param error string describing the error * @return pointer to the image or 0 if could not be acquired */ - Image * acquire_image(const string& name, int uid); + Image * acquire_image(const string& name, int uid, string& error); /** * Releases an image and triggers any needed operations in the repo @@ -212,7 +214,7 @@ private: * @param image pointer to image, it should be locked * @return 0 on success */ - int acquire_image(Image *img); + int acquire_image(Image *img, string& error); /** * Moves a file to an image in the repository diff --git a/include/ImagePool.h b/include/ImagePool.h index 2a2c63d85b..92e13af73b 100644 --- a/include/ImagePool.h +++ b/include/ImagePool.h @@ -139,6 +139,7 @@ public: * @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) * @param image_id on success returns the acquired image id + * @param error_str string describing the error * @return 0 on success, * -1 error, * -2 not using the pool, @@ -148,7 +149,8 @@ public: int * index, Image::ImageType * img_type, int uid, - int& image_id); + int& image_id, + string& error_str); /** * Generates an Authorization token for the DISK attribute * @param disk the disk to be authorized diff --git a/include/VirtualNetworkPool.h b/include/VirtualNetworkPool.h index d1256533e3..431f55c49d 100644 --- a/include/VirtualNetworkPool.h +++ b/include/VirtualNetworkPool.h @@ -92,11 +92,12 @@ public: * metadata * @param nic the nic attribute to be generated * @param vid of the VM requesting the lease + * @param error_str string describing the error * @return 0 on success, * -1 error, * -2 not using the pool */ - int nic_attribute(VectorAttribute * nic, int uid, int vid); + int nic_attribute(VectorAttribute * nic, int uid, int vid, string& error_str); /** * Generates an Authorization token for a NIC attribute @@ -171,12 +172,13 @@ private: */ VirtualNetwork * get_nic_by_name(VectorAttribute * nic, const string& name, - int _uid); + int _uidi, + string& error); /** * Function to get a VirtualNetwork by its id, as provided by a VM template */ - VirtualNetwork * get_nic_by_id(const string& id_s); + VirtualNetwork * get_nic_by_id(const string& id_s, string& error); }; #endif /*VIRTUAL_NETWORK_POOL_H_*/ diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index 8b4307e5b2..2c499730d5 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -22,7 +22,7 @@ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -Image * ImageManager::acquire_image(int image_id) +Image * ImageManager::acquire_image(int image_id, string& error) { Image * img; int rc; @@ -31,10 +31,14 @@ Image * ImageManager::acquire_image(int image_id) if ( img == 0 ) { + ostringstream oss; + oss << "Image with ID: " << image_id << " does not exists"; + + error = oss.str(); return 0; } - rc = acquire_image(img); + rc = acquire_image(img, error); if ( rc != 0 ) { @@ -47,7 +51,7 @@ Image * ImageManager::acquire_image(int image_id) /* -------------------------------------------------------------------------- */ -Image * ImageManager::acquire_image(const string& name, int uid) +Image * ImageManager::acquire_image(const string& name, int uid, string& error) { Image * img; int rc; @@ -56,10 +60,14 @@ Image * ImageManager::acquire_image(const string& name, int uid) if ( img == 0 ) { + ostringstream oss; + oss << "Image " << name << " does not exists for user " << uid; + + error = oss.str(); return 0; } - rc = acquire_image(img); + rc = acquire_image(img, error); if ( rc != 0 ) { @@ -72,7 +80,7 @@ Image * ImageManager::acquire_image(const string& name, int uid) /* -------------------------------------------------------------------------- */ -int ImageManager::acquire_image(Image *img) +int ImageManager::acquire_image(Image *img, string& error) { int rc = 0; @@ -87,7 +95,8 @@ int ImageManager::acquire_image(Image *img) case Image::USED: if (img->isPersistent()) { - rc = -1; + error = "Cannot aquire persistent image, it is already in use"; + rc = -1; } else { @@ -97,10 +106,19 @@ int ImageManager::acquire_image(Image *img) break; case Image::DISABLED: + error = "Cannot aquire image, it is disabled"; + rc = -1; + break; case Image::LOCKED: + error = "Cannot aquire image, it is locked"; + rc = -1; + break; case Image::ERROR: + error = "Cannot aquire image, it is in an error state"; + rc = -1; + break; default: - rc = -1; + rc = -1; break; } diff --git a/src/image/ImagePool.cc b/src/image/ImagePool.cc index 1845fc5e13..255b46de4c 100644 --- a/src/image/ImagePool.cc +++ b/src/image/ImagePool.cc @@ -216,7 +216,8 @@ int ImagePool::disk_attribute(VectorAttribute * disk, int * index, Image::ImageType * img_type, int uid, - int& image_id) + int& image_id, + string& error_str) { string source; Image * img = 0; @@ -227,8 +228,6 @@ int ImagePool::disk_attribute(VectorAttribute * disk, Nebula& nd = Nebula::instance(); ImageManager * imagem = nd.get_imagem(); - DatastorePool * ds_pool = nd.get_dspool(); - Datastore * ds = 0; if (!(source = disk->vector_value("IMAGE")).empty()) { @@ -236,10 +235,11 @@ int ImagePool::disk_attribute(VectorAttribute * disk, if ( uiid == -1) { + error_str = "Cannot get user set in IMAGE_UID or IMAGE_UNAME."; return -1; } - img = imagem->acquire_image(source, uiid); + img = imagem->acquire_image(source, uiid, error_str); if ( img == 0 ) { @@ -252,13 +252,15 @@ int ImagePool::disk_attribute(VectorAttribute * disk, if ( iid == -1) { + error_str = "Wrong ID set in IMAGE_ID"; return -1; } - img = imagem->acquire_image(iid); + img = imagem->acquire_image(iid, error_str); if ( img == 0 ) { + error_str = "Cannot acquire image, it does not exists or in use."; return -1; } } @@ -288,6 +290,9 @@ int ImagePool::disk_attribute(VectorAttribute * disk, if ( img != 0 ) { + DatastorePool * ds_pool = nd.get_dspool(); + Datastore * ds; + img->disk_attribute(disk, index, img_type); image_id = img->get_oid(); @@ -301,6 +306,7 @@ int ImagePool::disk_attribute(VectorAttribute * disk, if ( ds == 0 ) { + error_str = "Associated datastore for the image does not exist"; return -1; } diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 1a36291100..145251ff97 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -743,8 +743,13 @@ int VirtualMachine::get_disk_images(string& error_str) continue; } - rc = ipool->disk_attribute(disk, i, &index, &img_type, uid, image_id); - + rc = ipool->disk_attribute(disk, + i, + &index, + &img_type, + uid, + image_id, + error_str); if (rc == 0 ) { acquired_images.push_back(image_id); @@ -781,7 +786,7 @@ int VirtualMachine::get_disk_images(string& error_str) } else if ( rc == -1 ) { - goto error_image; + goto error_common; } } @@ -799,10 +804,6 @@ error_max_db: error_str = "VM can not use more than 10 DATABLOCK images."; goto error_common; -error_image: - error_str = "Could not get disk image for VM."; - goto error_common; - error_common: ImageManager * imagem = nd.get_imagem(); @@ -893,19 +894,15 @@ int VirtualMachine::get_network_leases(string& estr) continue; } - rc = vnpool->nic_attribute(nic, uid, oid); + rc = vnpool->nic_attribute(nic, uid, oid, estr); if (rc == -1) { - goto error_vnet; + return -1; } } return 0; - -error_vnet: - estr = "Could not get virtual network for VM."; - return -1; } /* -------------------------------------------------------------------------- */ diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index d8083944a9..38a8366746 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -620,8 +620,8 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid) ostringstream vnid; - ip = nic->vector_value("IP"); - vnid << oid; + ip = nic->vector_value("IP"); + vnid << oid; //-------------------------------------------------------------------------- // GET NETWORK LEASE diff --git a/src/vnm/VirtualNetworkPool.cc b/src/vnm/VirtualNetworkPool.cc index 99f3ba47cc..03a7248f2a 100644 --- a/src/vnm/VirtualNetworkPool.cc +++ b/src/vnm/VirtualNetworkPool.cc @@ -141,7 +141,8 @@ error_common: VirtualNetwork * VirtualNetworkPool::get_nic_by_name(VectorAttribute * nic, const string& name, - int _uid) + int _uid, + string& error) { istringstream is; @@ -149,6 +150,8 @@ VirtualNetwork * VirtualNetworkPool::get_nic_by_name(VectorAttribute * nic, string uname; int uid; + VirtualNetwork * vnet; + if (!(uid_s = nic->vector_value("NETWORK_UID")).empty()) { is.str(uid_s); @@ -156,6 +159,7 @@ VirtualNetwork * VirtualNetworkPool::get_nic_by_name(VectorAttribute * nic, if( is.fail() ) { + error = "Cannot get user in NETWORK_UID"; return 0; } } @@ -169,6 +173,7 @@ VirtualNetwork * VirtualNetworkPool::get_nic_by_name(VectorAttribute * nic, if ( user == 0 ) { + error = "User set in NETWORK_UNAME does not exist"; return 0; } @@ -181,39 +186,63 @@ VirtualNetwork * VirtualNetworkPool::get_nic_by_name(VectorAttribute * nic, uid = _uid; } - return get(name,uid,true); + vnet = get(name,uid,true); + + if (vnet == 0) + { + ostringstream oss; + oss << "Virtual network " << name << " does not exist for user " << uid; + + error = oss.str(); + } + + return vnet; } /* -------------------------------------------------------------------------- */ -VirtualNetwork * VirtualNetworkPool::get_nic_by_id(const string& id_s) +VirtualNetwork * VirtualNetworkPool::get_nic_by_id(const string& id_s, + string& error) { istringstream is; int id; + VirtualNetwork * vnet = 0; + is.str(id_s); is >> id; - if( is.fail() ) + if( !is.fail() ) { - return 0; + vnet = get(id,true); } - return get(id,true); + if (vnet == 0) + { + ostringstream oss; + oss << "Virtual network with ID: " << id_s << " does not exist"; + + error = oss.str(); + } + + return vnet; } -int VirtualNetworkPool::nic_attribute(VectorAttribute * nic, int uid, int vid) +int VirtualNetworkPool::nic_attribute(VectorAttribute * nic, + int uid, + int vid, + string& error) { string network; VirtualNetwork * vnet = 0; if (!(network = nic->vector_value("NETWORK")).empty()) { - vnet = get_nic_by_name (nic, network, uid); + vnet = get_nic_by_name (nic, network, uid, error); } else if (!(network = nic->vector_value("NETWORK_ID")).empty()) { - vnet = get_nic_by_id(network); + vnet = get_nic_by_id(network, error); } else //Not using a pre-defined network { @@ -231,6 +260,10 @@ int VirtualNetworkPool::nic_attribute(VectorAttribute * nic, int uid, int vid) { update(vnet); } + else + { + error = "Cannot get IP/MAC lease from virtual network."; + } vnet->unlock(); @@ -247,14 +280,15 @@ void VirtualNetworkPool::authorize_nic(VectorAttribute * nic, string network; VirtualNetwork * vnet = 0; PoolObjectAuth perm; + string error; if (!(network = nic->vector_value("NETWORK")).empty()) { - vnet = get_nic_by_name (nic, network, uid); + vnet = get_nic_by_name (nic, network, uid, error); } else if (!(network = nic->vector_value("NETWORK_ID")).empty()) { - vnet = get_nic_by_id(network); + vnet = get_nic_by_id(network, error); } else //Not using a pre-defined network { From a40bb000fd4dc10357c9f20139916a7a12148219 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 24 Feb 2012 21:29:32 +0100 Subject: [PATCH 050/217] feature #962: Fix wrong error message --- src/image/ImagePool.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/image/ImagePool.cc b/src/image/ImagePool.cc index 255b46de4c..61c42671e3 100644 --- a/src/image/ImagePool.cc +++ b/src/image/ImagePool.cc @@ -260,7 +260,6 @@ int ImagePool::disk_attribute(VectorAttribute * disk, if ( img == 0 ) { - error_str = "Cannot acquire image, it does not exists or in use."; return -1; } } From 80b49ff6b447616466b03be90ce781db575fb862 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 24 Feb 2012 23:13:22 +0100 Subject: [PATCH 051/217] feature #1112: Add system_dir for VMs --- include/Datastore.h | 9 +++++++++ include/Nebula.h | 25 ++++++++++++++++++++++--- include/VirtualMachine.h | 11 ++++++++--- src/vm/VirtualMachine.cc | 36 ++++++++++++++++++++++++++++++++---- src/vm/VirtualMachinePool.cc | 2 +- 5 files changed, 72 insertions(+), 11 deletions(-) diff --git a/include/Datastore.h b/include/Datastore.h index df9f2df319..c99ae31ddb 100644 --- a/include/Datastore.h +++ b/include/Datastore.h @@ -72,6 +72,15 @@ public: return tm_mad; }; + /** + * Retrieves the base path + * @return base path string + */ + const string& get_base_path() const + { + return base_path; + }; + /** * Modifies the given VM disk attribute adding the relevant datastore * attributes diff --git a/include/Nebula.h b/include/Nebula.h index e5640ba05c..064f4dfe02 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -199,9 +199,8 @@ public: }; /** - * Returns the path where the OpenNebula DB and the VM local directories - * are stored. When ONE_LOCATION is defined this path points to - * $ONE_LOCATION/var, otherwise it is /var/lib/one. + * Returns the default var location. When ONE_LOCATION is defined this path + * points to $ONE_LOCATION/var, otherwise it is /var/lib/one. * @return the log location. */ const string& get_var_location() @@ -209,6 +208,26 @@ public: return var_location; }; + /** + * Returns the base for the system datastore (for tmp VM images). When + * ONE_LOCATION is defined this path points to $ONE_LOCATION/var/system_ds, + * otherwise it is /var/lib/one/system_ds. + * @return the log location. + */ + string get_system_ds_path() + { + Datastore * ds; + string system_ds_path; + + ds = dspool->get(DatastorePool::SYSTEM_DS_ID, true); + + system_ds_path = ds->get_base_path(); + + ds->unlock(); + + return system_ds_path; + }; + /** * Returns the path of the log file for a VM, depending where OpenNebula is * installed, diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 18212b469e..0113e170ca 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -760,14 +760,13 @@ private: */ History * previous_history; - /** * Complete set of history records for the VM */ vector history_records; // ------------------------------------------------------------------------- - // Logging + // Logging & Dirs // ------------------------------------------------------------------------- /** @@ -776,7 +775,13 @@ private: * or, in case that OpenNebula is installed in root * /var/log/one/$VM_ID.log */ - FileLog * _log; + FileLog * _log; + + /** + * Directory for the VM in the System DS (system_ds_path/$VID). Defaults to + * $ONE_LOCATION/var/system_ds/$VID or /var/log/one/system_ds/$VID + */ + string system_dir; // ************************************************************************* // DataBase implementation (Private) diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 145251ff97..edf06bc82a 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -56,7 +56,8 @@ VirtualMachine::VirtualMachine(int id, net_rx(0), history(0), previous_history(0), - _log(0) + _log(0), + system_dir("") { if (_vm_template != 0) { @@ -148,14 +149,28 @@ int VirtualMachine::select(SqlDB * db) } } - //Create support directory for this VM + if ( state == DONE ) //Do not recreate dirs. They may be deleted + { + _log = 0; + + return 0; + } + + //-------------------------------------------------------------------------- + //Create support directories for this VM + //-------------------------------------------------------------------------- oss.str(""); oss << nd.get_var_location() << oid; - mkdir(oss.str().c_str(), 0777); - chmod(oss.str().c_str(), 0777); + mkdir(oss.str().c_str(), 0700); + chmod(oss.str().c_str(), 0700); + mkdir(system_dir.c_str(), 0700); + chmod(system_dir.c_str(), 0700); + + //-------------------------------------------------------------------------- //Create Log support for this VM + //-------------------------------------------------------------------------- try { _log = new FileLog(nd.get_vm_log_filename(oid),Log::DEBUG); @@ -191,6 +206,7 @@ int VirtualMachine::insert(SqlDB * db, string& error_str) string value; ostringstream oss; + Nebula& nd = Nebula::instance(); // ------------------------------------------------------------------------ // Check template for restricted attributes @@ -279,6 +295,15 @@ int VirtualMachine::insert(SqlDB * db, string& error_str) parse_graphics(); + // ------------------------------------------------------------------------ + // Set the System DataStore Path for the VM + // ------------------------------------------------------------------------ + + oss.str(""); + oss << nd.get_system_ds_path() << "/" << oid; + + system_dir = oss.str(); + // ------------------------------------------------------------------------ // Insert the VM // ------------------------------------------------------------------------ @@ -1259,6 +1284,7 @@ string& VirtualMachine::to_xml_extended(string& xml, bool extended) const << "" << cpu << "" << "" << net_tx << "" << "" << net_rx << "" + << ""<< system_dir<< "" << obj_template->to_xml(template_xml); if ( hasHistory() ) @@ -1328,6 +1354,8 @@ int VirtualMachine::from_xml(const string &xml_str) rc += xpath(net_tx, "/VM/NET_TX", 0); rc += xpath(net_rx, "/VM/NET_RX", 0); + rc += xpath(system_dir,"/VM/SYSTEM_DIR","not_found"); + // Permissions rc += perms_from_xml(); diff --git a/src/vm/VirtualMachinePool.cc b/src/vm/VirtualMachinePool.cc index 65beced047..6c5031389b 100644 --- a/src/vm/VirtualMachinePool.cc +++ b/src/vm/VirtualMachinePool.cc @@ -216,7 +216,7 @@ int VirtualMachinePool::allocate ( { vm->state = VirtualMachine::PENDING; } - + // ------------------------------------------------------------------------ // Insert the Object in the pool // ------------------------------------------------------------------------ From 7279fc1b960b63a2675aa0d08ebad63b404577b3 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 25 Feb 2012 01:25:28 +0100 Subject: [PATCH 052/217] feature-#1112: Add remote_system_dir for Virtual Machines --- include/VirtualMachine.h | 6 ++++++ src/vm/VirtualMachine.cc | 21 ++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 0113e170ca..8c71eb8fef 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -783,6 +783,12 @@ private: */ string system_dir; + /** + * Directory for the VM in hosts, the System DS (system_ds_path/$VID). Defaults to + * $ONE_LOCATION/var/system_ds/$VID or /var/log/one/system_ds/$VID + */ + string remote_system_dir; + // ************************************************************************* // DataBase implementation (Private) // ************************************************************************* diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index edf06bc82a..1f46ced8b8 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -57,7 +57,8 @@ VirtualMachine::VirtualMachine(int id, history(0), previous_history(0), _log(0), - system_dir("") + system_dir(""), + remote_system_dir("") { if (_vm_template != 0) { @@ -152,7 +153,7 @@ int VirtualMachine::select(SqlDB * db) if ( state == DONE ) //Do not recreate dirs. They may be deleted { _log = 0; - + return 0; } @@ -204,6 +205,8 @@ int VirtualMachine::insert(SqlDB * db, string& error_str) SingleAttribute * attr; string aname; string value; + string ds_location; + ostringstream oss; Nebula& nd = Nebula::instance(); @@ -296,14 +299,20 @@ int VirtualMachine::insert(SqlDB * db, string& error_str) parse_graphics(); // ------------------------------------------------------------------------ - // Set the System DataStore Path for the VM + // Set the System DataStore Paths for the VM // ------------------------------------------------------------------------ - oss.str(""); oss << nd.get_system_ds_path() << "/" << oid; system_dir = oss.str(); + oss.str(""); + + nd.get_configuration_attribute("DATASTORE_LOCATION", ds_location); + oss << ds_location << "/" << DatastorePool::SYSTEM_DS_NAME << "/" << oid; + + remote_system_dir = oss.str(); + // ------------------------------------------------------------------------ // Insert the VM // ------------------------------------------------------------------------ @@ -1284,7 +1293,8 @@ string& VirtualMachine::to_xml_extended(string& xml, bool extended) const << "" << cpu << "" << "" << net_tx << "" << "" << net_rx << "" - << ""<< system_dir<< "" + << "" << system_dir << "" + << "" << remote_system_dir << "" << obj_template->to_xml(template_xml); if ( hasHistory() ) @@ -1355,6 +1365,7 @@ int VirtualMachine::from_xml(const string &xml_str) rc += xpath(net_rx, "/VM/NET_RX", 0); rc += xpath(system_dir,"/VM/SYSTEM_DIR","not_found"); + rc += xpath(remote_system_dir,"/VM/REMOTE_SYSTEM_DIR","not_found"); // Permissions rc += perms_from_xml(); From 96e1055543e62b1fdef0a0dd8d4fcb3df106e640 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 25 Feb 2012 01:25:59 +0100 Subject: [PATCH 053/217] feature #1112: Get TM_MAD from Datastores --- include/Nebula.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/include/Nebula.h b/include/Nebula.h index 064f4dfe02..fa6b03248c 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -212,7 +212,7 @@ public: * Returns the base for the system datastore (for tmp VM images). When * ONE_LOCATION is defined this path points to $ONE_LOCATION/var/system_ds, * otherwise it is /var/lib/one/system_ds. - * @return the log location. + * @return the system datastore path location. */ string get_system_ds_path() { @@ -228,6 +228,23 @@ public: return system_ds_path; }; + /** + * Returns the Transfer Manager for the system datastore + * @return the tm_mad name. + */ + string get_system_ds_tm_mad() + { + Datastore * ds; + string tm_mad; + + ds = dspool->get(DatastorePool::SYSTEM_DS_ID, true); + + tm_mad = ds->get_tm_mad(); + + ds->unlock(); + + return tm_mad; + }; /** * Returns the path of the log file for a VM, depending where OpenNebula is * installed, From aecacf5c803cfe7eb63024c441c98e9c79faccbf Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 25 Feb 2012 01:28:28 +0100 Subject: [PATCH 054/217] feature #1112: Prepare TM to use a single Transfer Manager driver that handle multiple Datastore transfer plugins --- include/TransferManager.h | 17 +++++ src/tm/TransferManager.cc | 138 +++++++++++++++++--------------------- 2 files changed, 77 insertions(+), 78 deletions(-) diff --git a/include/TransferManager.h b/include/TransferManager.h index 54daf0f824..6977ad76fb 100644 --- a/include/TransferManager.h +++ b/include/TransferManager.h @@ -115,6 +115,11 @@ private: */ ActionManager am; + /** + * Generic name for the TransferManager driver + */ + static const char * transfer_driver_name; + /** * Returns a pointer to a Transfer Manager driver. * @param name of an attribute of the driver (e.g. its type) @@ -145,6 +150,18 @@ private: (MadManager::get(0,_name,name)); }; + /** + * Returns a pointer to a Transfer Manager driver. The driver is + * searched by its name. + * @return the TM driver for the Transfer Manager + */ + const TransferManagerDriver * get() + { + string _name("NAME"); + return static_cast + (MadManager::get(0,_name,transfer_driver_name)); + }; + /** * Function to execute the Manager action loop method within a new pthread * (requires C linkage) diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index 62f143de04..3935dee5bc 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -22,6 +22,11 @@ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +const char * TransferManager::transfer_driver_name = "transfer_exe"; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + extern "C" void * tm_action_loop(void *arg) { TransferManager * tm; @@ -209,6 +214,7 @@ void TransferManager::prolog_action(int vid) string files; string size; string format; + string tm_mad; VirtualMachine * vm; Nebula& nd = Nebula::instance(); @@ -236,9 +242,7 @@ void TransferManager::prolog_action(int vid) goto error_history; } - // TODO: get tm_md from somewhere... -// tm_md = get(vm->get_tm_mad()); - tm_md = 0; + tm_md = get(); if ( tm_md == 0 ) { @@ -268,6 +272,13 @@ void TransferManager::prolog_action(int vid) continue; } + tm_mad = disk->vector_value("TM_MAD"); + + if ( tm_mad.empty() ) + { + tm_mad = "default"; + } + type = disk->vector_value("TYPE"); if ( type.empty() == false) @@ -289,7 +300,11 @@ void TransferManager::prolog_action(int vid) continue; } - xfr << "MKSWAP " << size << " " << vm->get_hostname() << ":" + //MKSWAP tm_mad size hostname:system_ds_remote_path/disk.i + xfr << "MKSWAP " + << tm_mad << " " + << size << " " + << vm->get_hostname() << ":" << vm->get_remote_dir() << "/disk." << i << endl; } else if ( type == "FS" ) @@ -418,8 +433,7 @@ error_file: error_driver: os.str(""); - // TODO -// os << "prolog, error getting driver " << vm->get_tm_mad(); + os << "prolog, error getting Transfer Manager driver."; goto error_common; error_empty_disk: @@ -466,9 +480,7 @@ void TransferManager::prolog_migr_action(int vid) goto error_history; } - // TODO: get tm_md from somewhere... -// tm_md = get(vm->get_tm_mad()); - tm_md = 0; + tm_md = get(); if ( tm_md == 0 ) { @@ -511,8 +523,7 @@ error_file: error_driver: os.str(""); - // TODO -// os << "prolog_migr, error getting driver " << vm->get_tm_mad(); + os << "prolog_migr, error getting Transfer Manager driver."; error_common: (nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid); @@ -553,9 +564,7 @@ void TransferManager::prolog_resume_action(int vid) goto error_history; } - // TODO: get tm_md from somewhere... -// tm_md = get(vm->get_tm_mad()); - tm_md = 0; + tm_md = get(); if ( tm_md == 0 ) { @@ -598,8 +607,7 @@ error_file: error_driver: os.str(""); - // TODO -// os << "prolog_resume, error getting driver " << vm->get_tm_mad(); + os << "prolog_resume, error getting Transfer Manager driver."; error_common: (nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid); @@ -646,9 +654,7 @@ void TransferManager::epilog_action(int vid) goto error_history; } - // TODO: get tm_md from somewhere... -// tm_md = get(vm->get_tm_mad()); - tm_md = 0; + tm_md = get(); if ( tm_md == 0 ) { @@ -718,7 +724,7 @@ error_file: error_driver: os.str(""); - os << "epilog, error getting driver " << vm->get_vmm_mad(); + os << "epilog, error getting Transfer Manager driver."; error_common: (nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid); @@ -742,11 +748,9 @@ void TransferManager::epilog_stop_action(int vid) const TransferManagerDriver * tm_md; - // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ - vm = vmpool->get(vid,true); if (vm == 0) @@ -759,9 +763,7 @@ void TransferManager::epilog_stop_action(int vid) goto error_history; } - // TODO: get tm_md from somewhere... -// tm_md = get(vm->get_tm_mad()); - tm_md = 0; + tm_md = get(); if ( tm_md == 0 ) { @@ -804,8 +806,7 @@ error_file: error_driver: os.str(""); - // TODO -// os << "epilog_stop, error getting driver " << vm->get_tm_mad(); + os << "epilog_stop, error getting Transfer Manager driver."; error_common: (nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid); @@ -845,9 +846,7 @@ void TransferManager::epilog_delete_action(int vid) goto error_history; } - // TODO: get tm_md from somewhere... -// tm_md = get(vm->get_tm_mad()); - tm_md = 0; + tm_md = get(); if ( tm_md == 0 ) { @@ -890,7 +889,7 @@ error_file: error_driver: os.str(""); - os << "epilog_delete, error getting driver " << vm->get_vmm_mad(); + os << "epilog_delete, error getting driver Transfer Manager driver."; os << ". You may need to manually clean " << vm->get_hostname() << ":" << vm->get_remote_dir(); @@ -930,9 +929,7 @@ void TransferManager::epilog_delete_previous_action(int vid) goto error_history; } - // TODO: get tm_md from somewhere... -// tm_md = get(vm->get_previous_tm_mad()); - tm_md = 0; + tm_md = get(); if ( tm_md == 0 ) { @@ -976,7 +973,7 @@ error_file: error_driver: os.str(""); - os << "epilog_delete, error getting driver " << vm->get_vmm_mad(); + os << "epilog_delete, error getting driver Transfer Manager driver."; os << ". You may need to manually clean " << vm->get_previous_hostname() << ":" << vm->get_remote_dir(); @@ -1011,14 +1008,7 @@ void TransferManager::driver_cancel_action(int vid) return; } - if (!vm->hasHistory()) - { - goto error_history; - } - - // TODO: get tm_md from somewhere... -// tm_md = get(vm->get_tm_mad()); - tm_md = 0; + tm_md = get(); if ( tm_md == 0 ) { @@ -1035,16 +1025,10 @@ void TransferManager::driver_cancel_action(int vid) return; -error_history: - os.str(""); - os << "driver_cancel, VM " << vid << " has no history"; - goto error_common; - error_driver: os.str(""); - os << "driver_cancel, error getting driver " << vm->get_vmm_mad(); + os << "driver_cancel, error getting driver Transfer Manager driver."; -error_common: vm->log("TM", Log::ERROR, os); vm->unlock(); @@ -1065,43 +1049,41 @@ void TransferManager::checkpoint_action(int vid) void TransferManager::load_mads(int uid) { - unsigned int i; - ostringstream oss; - const VectorAttribute * vattr; - int rc; - string name; - TransferManagerDriver * tm_driver = 0; + ostringstream oss; - oss << "Loading Transfer Manager drivers."; + int rc; + string name; + + const VectorAttribute * vattr; + TransferManagerDriver * tm_driver = 0; + + oss << "Loading Transfer Manager driver."; NebulaLog::log("TM",Log::INFO,oss); - for(i=0,oss.str("");i(mad_conf[0]); + + if ( vattr == 0 ) { - vattr = static_cast(mad_conf[i]); + NebulaLog::log("TM",Log::ERROR,"Failed to load Transfer Manager driver."); + return; + } - name = vattr->vector_value("NAME"); + VectorAttribute tm_conf("TM_MAD",vattr->value()); - oss << "\tLoading driver: " << name; - NebulaLog::log("VMM", Log::INFO, oss); + tm_conf.replace("NAME",transfer_driver_name); - tm_driver = new TransferManagerDriver( - uid, - vattr->value(), - (uid != 0), - vmpool); + tm_driver = new TransferManagerDriver(uid, + tm_conf.value(), + (uid != 0), + vmpool); + rc = add(tm_driver); - if ( tm_driver == 0 ) - continue; + if ( rc == 0 ) + { + oss.str(""); + oss << "\tTransfer manager driver loaded"; - rc = add(tm_driver); - - if ( rc == 0 ) - { - oss.str(""); - oss << "\tDriver " << name << " loaded."; - - NebulaLog::log("TM",Log::INFO,oss); - } + NebulaLog::log("TM",Log::INFO,oss); } } From 3fb433b352f2e95422cfbe3ffef3338431adfd2a Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 25 Feb 2012 01:29:16 +0100 Subject: [PATCH 055/217] feature #1112: Names and paths for default datastores are now the same --- install.sh | 4 ++-- src/datastore/DatastorePool.cc | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/install.sh b/install.sh index ea5fcb7e2e..a2bc187e54 100755 --- a/install.sh +++ b/install.sh @@ -100,7 +100,7 @@ if [ -z "$ROOT" ] ; then SUNSTONE_LOCATION="$LIB_LOCATION/sunstone" OZONES_LOCATION="$LIB_LOCATION/ozones" SYSTEM_DS_LOCATION="$VAR_LOCATION/system_ds" - DEFAULT_DS_LOCATION="$VAR_LOCATION/images" + DEFAULT_DS_LOCATION="$VAR_LOCATION/default_ds" RUN_LOCATION="/var/run/one" LOCK_LOCATION="/var/lock/one" INCLUDE_LOCATION="/usr/include" @@ -147,7 +147,7 @@ else SUNSTONE_LOCATION="$LIB_LOCATION/sunstone" OZONES_LOCATION="$LIB_LOCATION/ozones" SYSTEM_DS_LOCATION="$VAR_LOCATION/system_ds" - DEFAULT_DS_LOCATION="$VAR_LOCATION/images" + DEFAULT_DS_LOCATION="$VAR_LOCATION/default_ds" INCLUDE_LOCATION="$ROOT/include" SHARE_LOCATION="$ROOT/share" MAN_LOCATION="$ROOT/share/man/man1" diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index fbbbd2292e..7812eecc79 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -26,10 +26,10 @@ /* from ID 100 */ /* -------------------------------------------------------------------------- */ -const string DatastorePool::SYSTEM_DS_NAME = "system"; +const string DatastorePool::SYSTEM_DS_NAME = "system_ds"; const int DatastorePool::SYSTEM_DS_ID = 0; -const string DatastorePool::DEFAULT_DS_NAME = "default"; +const string DatastorePool::DEFAULT_DS_NAME = "default_ds"; const int DatastorePool::DEFAULT_DS_ID = 1; /* -------------------------------------------------------------------------- */ @@ -47,7 +47,9 @@ DatastorePool::DatastorePool(SqlDB * db): Datastore * ds; DatastoreTemplate * ds_tmpl; - // Build the default datastores + // --------------------------------------------------------------------- + // Create the system datastore + // --------------------------------------------------------------------- oss << "NAME = " << SYSTEM_DS_NAME << endl << "BASE_PATH = /var/lib/one/system_ds" << endl @@ -71,10 +73,13 @@ DatastorePool::DatastorePool(SqlDB * db): goto error_bootstrap; } + // --------------------------------------------------------------------- + // Create the default datastore + // --------------------------------------------------------------------- oss.str(""); oss << "NAME = " << DEFAULT_DS_NAME << endl - << "BASE_PATH = /var/lib/one/images" << endl + << "BASE_PATH = /var/lib/one/default_ds" << endl << "TYPE = fs" << endl << "TM_MAD = tm_shared"; From 6999911f528ab0a4f0adc6e0f6b1739a359ccde7 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 25 Feb 2012 01:29:36 +0100 Subject: [PATCH 056/217] feature #1112: Adds DATASTORE_LOCATION variable --- share/etc/oned.conf | 17 +++++------------ src/nebula/NebulaTemplate.cc | 16 ++++++++-------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 1a3a495bf6..21ae5623f9 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -16,11 +16,6 @@ # (use 0 to disable VM monitoring). # VM_PER_INTERVAL: Number of VMs monitored in each interval. # -# VM_DIR: Remote path to store the VM images, it should be shared between all -# the cluster nodes to perform live migrations. This variable is the default -# for all the hosts in the cluster. VM_DIR IS ONLY FOR THE NODES AND *NOT* THE -# FRONT-END -# # SCRIPTS_REMOTE_DIR: Remote path to store the monitoring and VM management # scripts. # @@ -49,7 +44,6 @@ HOST_MONITORING_INTERVAL = 600 VM_POLLING_INTERVAL = 600 #VM_PER_INTERVAL = 5 -#VM_DIR=/srv/cloud/one/var SCRIPTS_REMOTE_DIR=/var/tmp/one @@ -86,12 +80,9 @@ MAC_PREFIX = "02:00" #******************************************************************************* # DataStore Configuration #******************************************************************************* -# SYSTEM_DS -# base_path : Base path for the system datastore. The system datastore -# keeps the images (or reference to) of running or stopped VMs. -# The images are stored in the form base_path/. -# type : SSH: non shared, will limit live_migration -# SHARED: needs to be exported and mounted in the hosts +# DATASTORE_LOCATION: Path for Datastores in the hosts. It IS the same all the +# hosts in the cluster. DATASTORE_LOCATION IS ONLY FOR THE HOSTS AND *NOT* THE +# FRONT-END # # DEFAULT_IMAGE_TYPE: This can take values # OS Image file holding an operating system @@ -105,6 +96,8 @@ MAC_PREFIX = "02:00" # vd KVM virtual disk #******************************************************************************* +DATASTORE_LOCATION = /var/lib/one/datastores + DEFAULT_IMAGE_TYPE = "OS" DEFAULT_DEVICE_PREFIX = "hd" diff --git a/src/nebula/NebulaTemplate.cc b/src/nebula/NebulaTemplate.cc index 83ad962b83..db998d2a17 100644 --- a/src/nebula/NebulaTemplate.cc +++ b/src/nebula/NebulaTemplate.cc @@ -91,8 +91,7 @@ void OpenNebulaTemplate::set_conf_default() # HOST_MONITORING_INTERVAL # HOST_PER_INTERVAL # VM_POLLING_INTERVAL -# VM_PER_INTERVAL -# VM_DIR +# VM_PER_INTERVAL # PORT # DB # VNC_BASE_PORT @@ -123,10 +122,6 @@ void OpenNebulaTemplate::set_conf_default() attribute = new SingleAttribute("VM_PER_INTERVAL",value); conf_default.insert(make_pair(attribute->name(),attribute)); - //VM_DIR - attribute = new SingleAttribute("VM_DIR",var_location); - conf_default.insert(make_pair(attribute->name(),attribute)); - //XML-RPC Server PORT value = "2633"; @@ -180,12 +175,18 @@ void OpenNebulaTemplate::set_conf_default() /* #******************************************************************************* -# Image Repository Configuration +# Datastore Configuration #******************************************************************************* +# DATASTORE_LOCATION # DEFAULT_IMAGE_TYPE # DEFAULT_DEVICE_PREFIX #******************************************************************************* */ + //DATASTORE_LOCATION + attribute = new SingleAttribute("DATASTORE_LOCATION", + var_location + "/datastores"); + conf_default.insert(make_pair(attribute->name(),attribute)); + //DEFAULT_IMAGE_TYPE value = "OS"; @@ -198,7 +199,6 @@ void OpenNebulaTemplate::set_conf_default() attribute = new SingleAttribute("DEFAULT_DEVICE_PREFIX",value); conf_default.insert(make_pair(attribute->name(),attribute)); /* - #******************************************************************************* # Auth Manager Configuration #******************************************************************************* From 51e1590cb4b40e31f97271715be0a433ca93aab3 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 25 Feb 2012 03:19:13 +0100 Subject: [PATCH 057/217] feature #1112: Drivers use new location paths --- src/vmm/LibVirtDriverKVM.cc | 18 ++++++++++-------- src/vmm/XenDriver.cc | 4 ++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/vmm/LibVirtDriverKVM.cc b/src/vmm/LibVirtDriverKVM.cc index 29c1b5eb1f..4952f733f6 100644 --- a/src/vmm/LibVirtDriverKVM.cc +++ b/src/vmm/LibVirtDriverKVM.cc @@ -339,20 +339,20 @@ int LibVirtDriver::deployment_description_kvm( if ( type == "BLOCK" ) { file << "\t\t" << endl - << "\t\t\t" << endl; + << "\t\t\t" << endl; } else if ( type == "CDROM" ) { file << "\t\t" << endl - << "\t\t\t" << endl; + << "\t\t\t" << endl; } else { file << "\t\t" << endl - << "\t\t\t" << endl; + << "\t\t\t" << endl; } // ---- target device to map the disk ---- @@ -419,8 +419,10 @@ int LibVirtDriver::deployment_description_kvm( if ( !target.empty() ) { file << "\t\t" << endl; - file << "\t\t\t" << endl; + + file << "\t\t\t" << endl; + file << "\t\t\t" << endl; file << "\t\t\t" << endl; diff --git a/src/vmm/XenDriver.cc b/src/vmm/XenDriver.cc index 0e5fa0bee6..0add29a1d9 100644 --- a/src/vmm/XenDriver.cc +++ b/src/vmm/XenDriver.cc @@ -281,7 +281,7 @@ int XenDriver::deployment_description( } } - file << vm->get_remote_dir() << "/disk." << i << "," + file << vm->get_remote_system_dir() << "/disk." << i << "," << target << "," << mode << "'," << endl; @@ -312,7 +312,7 @@ int XenDriver::deployment_description( file << default_driver; } - file << vm->get_remote_dir() << "/disk." << num <<","<< target <<"," + file << vm->get_remote_system_dir() << "/disk." << num <<","<< target <<"," << "r'," << endl; } else From 5363c4ff0515f6ea22d6c6b73a8a2ab17e8841e9 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 25 Feb 2012 23:31:44 +0100 Subject: [PATCH 058/217] feature #1112: Fix VM paths for the new system datastore --- include/History.h | 12 ++-- include/Nebula.h | 22 ++++++- include/VirtualMachine.h | 49 ++++++++------- src/rm/RequestManagerAllocate.cc | 2 - src/rm/RequestManagerVirtualMachine.cc | 6 +- src/tm/TransferManager.cc | 52 ++++++++++++---- src/vm/History.cc | 82 ++++++++++++-------------- src/vm/VirtualMachine.cc | 27 +++++---- 8 files changed, 149 insertions(+), 103 deletions(-) diff --git a/include/History.h b/include/History.h index f2551d8e08..2913307c74 100644 --- a/include/History.h +++ b/include/History.h @@ -44,7 +44,7 @@ public: int seq, int hid, const string& hostname, - const string& vm_dir, + const string& remote_system_dir, const string& vmm, const string& vnm); @@ -86,7 +86,7 @@ private: int seq; string hostname; - string vm_dir; + string remote_system_dir; int hid; @@ -107,13 +107,15 @@ private: MigrationReason reason; - //Non-persistent history fields - string vm_lhome; + // ------------------------------------------------------------------------- + // Non-persistent history fields + // ------------------------------------------------------------------------- + // Local paths string transfer_file; string deployment_file; string context_file; - string vm_rhome; + // Remote paths string checkpoint_file; string rdeployment_file; diff --git a/include/Nebula.h b/include/Nebula.h index fa6b03248c..2dace61736 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -212,7 +212,7 @@ public: * Returns the base for the system datastore (for tmp VM images). When * ONE_LOCATION is defined this path points to $ONE_LOCATION/var/system_ds, * otherwise it is /var/lib/one/system_ds. - * @return the system datastore path location. + * @return the system datastore pa location. */ string get_system_ds_path() { @@ -230,7 +230,7 @@ public: /** * Returns the Transfer Manager for the system datastore - * @return the tm_mad name. + * @return the tm name. */ string get_system_ds_tm_mad() { @@ -245,6 +245,24 @@ public: return tm_mad; }; + + /** + * Returns the name for the system datastore + * @return the datastore name. + */ + string get_system_ds_name() + { + Datastore * ds; + string name; + + ds = dspool->get(DatastorePool::SYSTEM_DS_ID, true); + + name = ds->get_name(); + + ds->unlock(); + + return name; + }; /** * Returns the path of the log file for a VM, depending where OpenNebula is * installed, diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 8c71eb8fef..0a75b90e7f 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -206,6 +206,30 @@ public: etime = et; }; + // ------------------------------------------------------------------------ + // Access to VM locations + // ------------------------------------------------------------------------ + /** + * Returns the remote VM directory. The VM remote dir is in the form: + * $DATASTORE_LOCATION/$SYSTEM_DS_NAME/$VM_ID. The remote system_dir stores + * disks for a running VM in the target host. + * @return the remote system directory for the VM + */ + const string & get_remote_system_dir() const + { + return remote_system_dir; + }; + + /** + * Returns the local VM directory. The VM local dir is in the form: + * $SYSTEM_DS_BASE_PATH/$VM_ID. Temporary stores VM disks. + * @return the system directory for the VM + */ + const string & get_system_dir() const + { + return system_dir; + }; + // ------------------------------------------------------------------------ // History // ------------------------------------------------------------------------ @@ -215,7 +239,6 @@ public: void add_history( int hid, const string& hostname, - const string& vm_dir, const string& vmm_mad, const string& vnm_mad); @@ -355,30 +378,6 @@ public: return history->checkpoint_file; }; - /** - * Returns the remote VM directory. The VM remote dir is in the form: - * $VM_DIR/$VM_ID/ - * or, in case that OpenNebula is installed in root - * /var/lib/one/$VM_ID/ - * The hasHistory() function MUST be called before this one. - * @return the remote directory - */ - const string & get_remote_dir() const - { - return history->vm_rhome; - }; - - /** - * Returns the local VM directory. The VM local dir is in the form: - * $ONE_LOCATION/var/$VM_ID/ - * The hasHistory() function MUST be called before this one. - * @return the remote directory - */ - const string & get_local_dir() const - { - return history->vm_lhome; - }; - /** * Returns the hostname for the current host. The hasHistory() * function MUST be called before this one. diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 3797e9227b..c5753560a0 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -317,8 +317,6 @@ int HostAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, string vmm_mad = xmlrpc_c::value_string(paramList.getString(3)); string vnm_mad = xmlrpc_c::value_string(paramList.getString(4)); - int rc; - // TODO: include another int parameter for the cluster? int cluster_id = ClusterPool::DEFAULT_CLUSTER_ID; string cluster_name = ClusterPool::DEFAULT_CLUSTER_NAME; diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 6ac5af3280..cca7b559cf 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -141,16 +141,12 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm, const string& vnm_mad, RequestAttributes& att) { - Nebula& nd = Nebula::instance(); string vmdir; - int rc; VirtualMachinePool * vmpool = static_cast(pool); - nd.get_configuration_attribute("VM_DIR",vmdir); - - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); + vm->add_history(hid,hostname,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index 3935dee5bc..52d919a8ff 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -300,12 +300,14 @@ void TransferManager::prolog_action(int vid) continue; } - //MKSWAP tm_mad size hostname:system_ds_remote_path/disk.i + //MKSWAP tm_mad size hostname:remote_system_dir/disk.i + /* xfr << "MKSWAP " << tm_mad << " " << size << " " << vm->get_hostname() << ":" << vm->get_remote_dir() << "/disk." << i << endl; + */ } else if ( type == "FS" ) { @@ -321,10 +323,12 @@ void TransferManager::prolog_action(int vid) " skipping"); continue; } - + //MKIMAGE tm_mad size format hostname:remote_system_dir/disk.i + /* xfr << "MKIMAGE " << size << " " << format << " " << vm->get_hostname() << ":" << vm->get_remote_dir() << "/disk." << i << endl; + */ } else { @@ -344,6 +348,7 @@ void TransferManager::prolog_action(int vid) (int(*)(int))toupper); } + // tm_mad fe:SOURCE hostname:remote_system_ds/disk.i size if (clon == "YES") { xfr << "CLONE "; @@ -371,9 +376,10 @@ void TransferManager::prolog_action(int vid) { xfr << source << " "; } - + /* xfr << vm->get_hostname() << ":" << vm->get_remote_dir() << "/disk." << i; + */ if (!size.empty()) //Add size for dev based disks { @@ -397,6 +403,8 @@ void TransferManager::prolog_action(int vid) if ( context_result ) { + //CONTEXT files hostname:remote_system_dir/disk.i + /* xfr << "CONTEXT " << vm->get_context_file() << " "; if (!files.empty()) @@ -406,6 +414,7 @@ void TransferManager::prolog_action(int vid) xfr << vm->get_hostname() << ":" << vm->get_remote_dir() << "/disk." << num << endl; + */ } xfr.close(); @@ -499,10 +508,12 @@ void TransferManager::prolog_migr_action(int vid) // Move image directory // ------------------------------------------------------------------------ + //MV prev_hostname:remote_system_dir hostname:remote_system_dir + /* xfr << "MV "; xfr << vm->get_previous_hostname() << ":" << vm->get_remote_dir() << " "; xfr << vm->get_hostname() << ":" << vm->get_remote_dir() << endl; - + */ xfr.close(); tm_md->transfer(vid,xfr_name); @@ -583,10 +594,12 @@ void TransferManager::prolog_resume_action(int vid) // Move image directory // ------------------------------------------------------------------------ + //MV fe:system_dir hostname:remote_system_dir + /* xfr << "MV "; xfr << nd.get_nebula_hostname() << ":" << vm->get_local_dir() << "/images "; xfr << vm->get_hostname() << ":" << vm->get_remote_dir() << endl; - + */ xfr.close(); tm_md->transfer(vid,xfr_name); @@ -695,15 +708,20 @@ void TransferManager::epilog_action(int vid) if ( save == "YES" ) { + //MV hostname:remote_system_dir/disk.0 fe:SOURCE? + /* xfr << "MV " << vm->get_hostname() << ":" << vm->get_remote_dir() << "/disk." << i << " " << nd.get_nebula_hostname() << ":" << vm->get_local_dir() << "/disk." << i << endl; + */ } } + //DELETE hostname:remote_system_dir + /* xfr << "DELETE " << vm->get_hostname() <<":"<< vm->get_remote_dir() << endl; - + */ xfr.close(); tm_md->transfer(vid,xfr_name); @@ -782,10 +800,12 @@ void TransferManager::epilog_stop_action(int vid) // Move image directory // ------------------------------------------------------------------------ + //MV hostname:remote_system_dir fe:system_dir + /* xfr << "MV "; xfr << vm->get_hostname() << ":" << vm->get_remote_dir() << " "; xfr << nd.get_nebula_hostname() << ":" << vm->get_local_dir() << endl; - + */ xfr.close(); tm_md->transfer(vid,xfr_name); @@ -864,9 +884,10 @@ void TransferManager::epilog_delete_action(int vid) // ------------------------------------------------------------------------ // Delete the remote VM Directory // ------------------------------------------------------------------------ - + // DELETE hostname:remote_system_dir + /* xfr << "DELETE " << vm->get_hostname() <<":"<< vm->get_remote_dir() << endl; - + */ xfr.close(); tm_md->transfer(vid,xfr_name); @@ -883,15 +904,19 @@ error_history: error_file: os.str(""); os << "epilog_delete, could not open file: " << xfr_name; + /* os << ". You may need to manually clean " << vm->get_hostname() << ":" << vm->get_remote_dir(); + */ goto error_common; error_driver: os.str(""); os << "epilog_delete, error getting driver Transfer Manager driver."; + /* os << ". You may need to manually clean " << vm->get_hostname() << ":" << vm->get_remote_dir(); + */ error_common: vm->log("TM", Log::ERROR, os); @@ -947,10 +972,11 @@ void TransferManager::epilog_delete_previous_action(int vid) // ------------------------------------------------------------------------ // Delete the remote VM Directory // ------------------------------------------------------------------------ - + //DELTE prev_hostname:remote_system_dir + /* xfr << "DELETE " << vm->get_previous_hostname() <<":"<< vm->get_remote_dir() << endl; - + */ xfr.close(); tm_md->transfer(vid,xfr_name); @@ -967,15 +993,19 @@ error_history: error_file: os.str(""); os << "epilog_delete, could not open file: " << xfr_name; + /* os << ". You may need to manually clean " << vm->get_previous_hostname() << ":" << vm->get_remote_dir(); + */ goto error_common; error_driver: os.str(""); os << "epilog_delete, error getting driver Transfer Manager driver."; + /* os << ". You may need to manually clean " << vm->get_previous_hostname() << ":" << vm->get_remote_dir(); + */ error_common: vm->log("TM", Log::ERROR, os); diff --git a/src/vm/History.cc b/src/vm/History.cc index d2ffd04c98..f06a208ca3 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -40,7 +40,7 @@ History::History( oid(_oid), seq(_seq), hostname(""), - vm_dir(""), + remote_system_dir(""), hid(-1), vmm_mad_name(""), vnm_mad_name(""), @@ -61,13 +61,13 @@ History::History( int _seq, int _hid, const string& _hostname, - const string& _vm_dir, + const string& _remote_system_dir, const string& _vmm, const string& _vnm): oid(_oid), seq(_seq), hostname(_hostname), - vm_dir(_vm_dir), + remote_system_dir(_remote_system_dir), hid(_hid), vmm_mad_name(_vmm), vnm_mad_name(_vnm), @@ -89,8 +89,10 @@ History::History( void History::non_persistent_data() { - ostringstream os; - Nebula& nd = Nebula::instance(); + ostringstream os; + string vm_lhome; + string vm_rhome; + Nebula& nd = Nebula::instance(); // ----------- Local Locations ------------ os.str(""); @@ -113,17 +115,11 @@ void History::non_persistent_data() context_file = os.str(); // ----------- Remote Locations ------------ - os.str(""); - os << vm_dir << "/" << oid << "/images"; - vm_rhome = os.str(); - - os << "/checkpoint"; - - checkpoint_file = os.str(); + checkpoint_file = remote_system_dir + "/checkpoint"; os.str(""); - os << vm_rhome << "/deployment." << seq; + os << remote_system_dir << "/deployment." << seq; rdeployment_file = os.str(); } @@ -260,21 +256,21 @@ string& History::to_xml(string& xml) const oss << "" << - "" << seq << "" << - ""<< hostname << ""<< - "" << vm_dir << ""<< - "" << hid << "" << - "" << stime << "" << - "" << etime << "" << - "" << vmm_mad_name << ""<< - "" << vnm_mad_name << ""<< - "" << prolog_stime << ""<< - "" << prolog_etime << ""<< - "" << running_stime << ""<< - "" << running_etime << ""<< - "" << epilog_stime << ""<< - "" << epilog_etime << ""<< - "" << reason << ""<< + "" << seq << "" << + "" << hostname << ""<< + "" << remote_system_dir << ""<< + "" << hid << "" << + "" << stime << "" << + "" << etime << "" << + "" << vmm_mad_name << ""<< + "" << vnm_mad_name << ""<< + "" << prolog_stime << ""<< + "" << prolog_etime << ""<< + "" << running_stime << ""<< + "" << running_etime << ""<< + "" << epilog_stime << ""<< + "" << epilog_etime << ""<< + "" << reason << ""<< ""; xml = oss.str(); @@ -290,21 +286,21 @@ int History::rebuild_attributes() int int_reason; int rc = 0; - rc += xpath(seq , "/HISTORY/SEQ", -1); - rc += xpath(hostname , "/HISTORY/HOSTNAME", "not_found"); - rc += xpath(vm_dir , "/HISTORY/VM_DIR", "not_found"); - rc += xpath(hid , "/HISTORY/HID", -1); - rc += xpath(stime , "/HISTORY/STIME", 0); - rc += xpath(etime , "/HISTORY/ETIME", 0); - rc += xpath(vmm_mad_name , "/HISTORY/VMMMAD", "not_found"); - xpath(vnm_mad_name , "/HISTORY/VNMMAD", "dummy"); - rc += xpath(prolog_stime , "/HISTORY/PSTIME", 0); - rc += xpath(prolog_etime , "/HISTORY/PETIME", 0); - rc += xpath(running_stime, "/HISTORY/RSTIME", 0); - rc += xpath(running_etime, "/HISTORY/RETIME", 0); - rc += xpath(epilog_stime , "/HISTORY/ESTIME", 0); - rc += xpath(epilog_etime , "/HISTORY/EETIME", 0); - rc += xpath(int_reason , "/HISTORY/REASON", 0); + rc += xpath(seq , "/HISTORY/SEQ", -1); + rc += xpath(hostname , "/HISTORY/HOSTNAME", "not_found"); + rc += xpath(remote_system_dir, "/HISTORY/REMOTE_SYSTEM_DIR", "not_found"); + rc += xpath(hid , "/HISTORY/HID", -1); + rc += xpath(stime , "/HISTORY/STIME", 0); + rc += xpath(etime , "/HISTORY/ETIME", 0); + rc += xpath(vmm_mad_name , "/HISTORY/VMMMAD", "not_found"); + xpath(vnm_mad_name , "/HISTORY/VNMMAD", "dummy"); + rc += xpath(prolog_stime , "/HISTORY/PSTIME", 0); + rc += xpath(prolog_etime , "/HISTORY/PETIME", 0); + rc += xpath(running_stime , "/HISTORY/RSTIME", 0); + rc += xpath(running_etime , "/HISTORY/RETIME", 0); + rc += xpath(epilog_stime , "/HISTORY/ESTIME", 0); + rc += xpath(epilog_etime , "/HISTORY/EETIME", 0); + rc += xpath(int_reason , "/HISTORY/REASON", 0); reason = static_cast(int_reason); diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 1f46ced8b8..86b33d47d5 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -202,12 +202,12 @@ int VirtualMachine::insert(SqlDB * db, string& error_str) int rc; string name; - SingleAttribute * attr; - string aname; - string value; - string ds_location; + SingleAttribute * attr; + string aname; + string value; + string ds_location; - ostringstream oss; + ostringstream oss; Nebula& nd = Nebula::instance(); @@ -309,7 +309,7 @@ int VirtualMachine::insert(SqlDB * db, string& error_str) oss.str(""); nd.get_configuration_attribute("DATASTORE_LOCATION", ds_location); - oss << ds_location << "/" << DatastorePool::SYSTEM_DS_NAME << "/" << oid; + oss << ds_location << "/" << nd.get_system_ds_name() << "/" << oid; remote_system_dir = oss.str(); @@ -637,7 +637,6 @@ error_common: void VirtualMachine::add_history( int hid, const string& hostname, - const string& vm_dir, const string& vmm_mad, const string& vnm_mad) { @@ -655,7 +654,13 @@ void VirtualMachine::add_history( previous_history = history; } - history = new History(oid,seq,hid,hostname,vm_dir,vmm_mad,vnm_mad); + history = new History(oid, + seq, + hid, + hostname, + remote_system_dir, + vmm_mad, + vnm_mad); history_records.push_back(history); }; @@ -676,7 +681,7 @@ void VirtualMachine::cp_history() history->seq + 1, history->hid, history->hostname, - history->vm_dir, + remote_system_dir, history->vmm_mad_name, history->vnm_mad_name); @@ -703,7 +708,7 @@ void VirtualMachine::cp_previous_history() history->seq + 1, previous_history->hid, previous_history->hostname, - previous_history->vm_dir, + remote_system_dir, previous_history->vmm_mad_name, previous_history->vnm_mad_name); @@ -874,7 +879,9 @@ void VirtualMachine::release_disk_images() if (hasHistory() != 0) { + /* disk_base_path = get_local_dir(); + */ } for(int i=0; i Date: Sun, 26 Feb 2012 21:52:10 +0100 Subject: [PATCH 059/217] feature #1112: Makes system datastore access safer --- include/Nebula.h | 25 ++++++++++++++++++++++--- src/vm/History.cc | 1 - 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/include/Nebula.h b/include/Nebula.h index 2dace61736..3acc32a8b5 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -217,10 +217,16 @@ public: string get_system_ds_path() { Datastore * ds; - string system_ds_path; + string system_ds_path = ""; ds = dspool->get(DatastorePool::SYSTEM_DS_ID, true); + if ( ds == 0 ) + { + NebulaLog::log("DaS", Log::ERROR, "Can not get system datastore"); + return system_ds_path; + } + system_ds_path = ds->get_base_path(); ds->unlock(); @@ -235,10 +241,16 @@ public: string get_system_ds_tm_mad() { Datastore * ds; - string tm_mad; + string tm_mad = ""; ds = dspool->get(DatastorePool::SYSTEM_DS_ID, true); + if ( ds == 0 ) + { + NebulaLog::log("DaS", Log::ERROR, "Can not get system datastore"); + return tm_mad; + } + tm_mad = ds->get_tm_mad(); ds->unlock(); @@ -253,16 +265,23 @@ public: string get_system_ds_name() { Datastore * ds; - string name; + string name = ""; ds = dspool->get(DatastorePool::SYSTEM_DS_ID, true); + if ( ds == 0 ) + { + NebulaLog::log("DaS", Log::ERROR, "Can not get system datastore"); + return name; + } + name = ds->get_name(); ds->unlock(); return name; }; + /** * Returns the path of the log file for a VM, depending where OpenNebula is * installed, diff --git a/src/vm/History.cc b/src/vm/History.cc index f06a208ca3..747b057be0 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -91,7 +91,6 @@ void History::non_persistent_data() { ostringstream os; string vm_lhome; - string vm_rhome; Nebula& nd = Nebula::instance(); // ----------- Local Locations ------------ From 31be0a20007bc896d1dd9329e0563fa4549c77d6 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sun, 26 Feb 2012 22:08:27 +0100 Subject: [PATCH 060/217] feature #1112: Fix compilation of unit tests --- src/lcm/test/LifeCycleManagerTest.cc | 23 +++++++++++------------ src/vm/test/VirtualMachinePoolTest.cc | 12 +++++------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/lcm/test/LifeCycleManagerTest.cc b/src/lcm/test/LifeCycleManagerTest.cc index ce1166c8bd..03fd372352 100644 --- a/src/lcm/test/LifeCycleManagerTest.cc +++ b/src/lcm/test/LifeCycleManagerTest.cc @@ -48,7 +48,6 @@ static int hid = 123; static string hostname = "test_hostname"; static string vmm_mad = "vmm_mad"; static string vnm_mad = "vnm_mad"; -static string vmdir = "vmdir"; class LifeCycleManagerTest : public OneUnitTest { @@ -225,7 +224,7 @@ private: vm->lock(); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); + vm->add_history(hid,hostname,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -489,7 +488,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); + vm->add_history(hid,hostname,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -573,7 +572,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); + vm->add_history(hid,hostname,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -594,7 +593,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); + vm->add_history(hid,hostname,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -615,7 +614,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); + vm->add_history(hid,hostname,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -637,7 +636,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); + vm->add_history(hid,hostname,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -661,7 +660,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); + vm->add_history(hid,hostname,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -685,7 +684,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); + vm->add_history(hid,hostname,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -749,7 +748,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); + vm->add_history(hid,hostname,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -772,7 +771,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); + vm->add_history(hid,hostname,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -795,7 +794,7 @@ public: { vm = allocate_running(0); - vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad); + vm->add_history(hid,hostname,vmm_mad,vnm_mad); rc = vmpool->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); diff --git a/src/vm/test/VirtualMachinePoolTest.cc b/src/vm/test/VirtualMachinePoolTest.cc index 4febff2e81..3a0ac90c90 100644 --- a/src/vm/test/VirtualMachinePoolTest.cc +++ b/src/vm/test/VirtualMachinePoolTest.cc @@ -298,7 +298,6 @@ public: VirtualMachine* vm; string hostnames[] = {"A_hostname", "B_hostname", "C_hostname"}; - string vm_dirs[] = {"A_vm_dir", "B_vm_dir", "C_vm_dir"}; string vmm_mads[] = {"A_vmm_mad", "B_vmm_mad", "C_vmm_mad"}; string vnm_mads[] = {"A_vnm_mad", "B_vnm_mad", "C_vnm_mad"}; @@ -322,7 +321,7 @@ public: CPPUNIT_ASSERT( vm != 0 ); // Add a history item - vm->add_history(0, hostnames[0], vm_dirs[0], vmm_mads[0], vnm_mads[0]); + vm->add_history(0, hostnames[0], vmm_mads[0], vnm_mads[0]); rc = vmp->update(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -340,7 +339,7 @@ public: CPPUNIT_ASSERT( vm != 0 ); // Add a history item - vm->add_history(1, hostnames[1], vm_dirs[1], vmm_mads[1], vnm_mads[1]); + vm->add_history(1, hostnames[1], vmm_mads[1], vnm_mads[1]); rc = vmp->update(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -349,7 +348,7 @@ public: CPPUNIT_ASSERT( rc == 0 ); // Add another history item - vm->add_history(2, hostnames[2], vm_dirs[2], vmm_mads[2], vnm_mads[2]); + vm->add_history(2, hostnames[2], vmm_mads[2], vnm_mads[2]); rc = vmp->update(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -404,7 +403,6 @@ public: string hostname = "hostname"; string new_hostname = "new_hostname"; - string vm_dir = "vm_dir"; string vmm_mad = "vm_mad"; string vnm_mad = "vn_mad"; @@ -416,7 +414,7 @@ public: CPPUNIT_ASSERT( vm != 0 ); // Add a history item - vm->add_history(0, hostname, vm_dir, vmm_mad, vnm_mad); + vm->add_history(0, hostname, vmm_mad, vnm_mad); rc = vmp->update(vm); CPPUNIT_ASSERT( rc == 0 ); @@ -424,7 +422,7 @@ public: rc = vmp->update_history(vm); CPPUNIT_ASSERT( rc == 0 ); - vm->add_history(0, new_hostname, vm_dir, vmm_mad, vnm_mad); + vm->add_history(0, new_hostname, vmm_mad, vnm_mad); rc = vmp->update(vm); CPPUNIT_ASSERT( rc == 0 ); From 8e3da6cb22d1e52c6f61c61fe97e8409de80db92 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sun, 26 Feb 2012 22:08:50 +0100 Subject: [PATCH 061/217] feature #1112: Prolog uses the new locations --- src/tm/TransferManager.cc | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index 52d919a8ff..a20f6de4e4 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -301,13 +301,11 @@ void TransferManager::prolog_action(int vid) } //MKSWAP tm_mad size hostname:remote_system_dir/disk.i - /* xfr << "MKSWAP " << tm_mad << " " << size << " " << vm->get_hostname() << ":" - << vm->get_remote_dir() << "/disk." << i << endl; - */ + << vm->get_remote_system_dir() << "/disk." << i << endl; } else if ( type == "FS" ) { @@ -324,11 +322,12 @@ void TransferManager::prolog_action(int vid) continue; } //MKIMAGE tm_mad size format hostname:remote_system_dir/disk.i - /* - xfr << "MKIMAGE " << size << " " << format << " " - << vm->get_hostname() << ":" << vm->get_remote_dir() - << "/disk." << i << endl; - */ + xfr << "MKIMAGE " + << tm_mad << " " + << size << " " + << format << " " + << vm->get_hostname() << ":" + << vm->get_remote_system_dir() << "/disk." << i << endl; } else { @@ -358,6 +357,8 @@ void TransferManager::prolog_action(int vid) xfr << "LN "; } + xfr << tm_mad << " "; + // ----------------------------------------------------------------- // Get the disk image, and set source URL // ----------------------------------------------------------------- @@ -376,10 +377,9 @@ void TransferManager::prolog_action(int vid) { xfr << source << " "; } - /* - xfr << vm->get_hostname() << ":" << vm->get_remote_dir() - << "/disk." << i; - */ + + xfr << vm->get_hostname() << ":" + << vm->get_remote_system_dir() << "/disk." << i; if (!size.empty()) //Add size for dev based disks { @@ -404,7 +404,6 @@ void TransferManager::prolog_action(int vid) if ( context_result ) { //CONTEXT files hostname:remote_system_dir/disk.i - /* xfr << "CONTEXT " << vm->get_context_file() << " "; if (!files.empty()) @@ -412,9 +411,9 @@ void TransferManager::prolog_action(int vid) xfr << files << " "; } - xfr << vm->get_hostname() << ":" << vm->get_remote_dir() - << "/disk." << num << endl; - */ + xfr << vm->get_hostname() << ":" + << vm->get_remote_system_dir() << "/disk." << num + << endl; } xfr.close(); From 11f0c3d06bd783dc8bc1ef609ecc51a3a82db63f Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sun, 26 Feb 2012 23:25:31 +0100 Subject: [PATCH 062/217] feature #1112: Transger manager scripts now uses the new system datastore --- src/tm/TransferManager.cc | 180 ++++++++++++++++++++++++-------------- 1 file changed, 115 insertions(+), 65 deletions(-) diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index a20f6de4e4..0837b2ef62 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -214,7 +214,7 @@ void TransferManager::prolog_action(int vid) string files; string size; string format; - string tm_mad; + string tm_mad, system_tm_mad; VirtualMachine * vm; Nebula& nd = Nebula::instance(); @@ -230,6 +230,8 @@ void TransferManager::prolog_action(int vid) // Setup & Transfer script // ------------------------------------------------------------------------ + system_tm_mad = nd.get_system_ds_tm_mad(); + vm = vmpool->get(vid,true); if (vm == 0) @@ -272,13 +274,6 @@ void TransferManager::prolog_action(int vid) continue; } - tm_mad = disk->vector_value("TM_MAD"); - - if ( tm_mad.empty() ) - { - tm_mad = "default"; - } - type = disk->vector_value("TYPE"); if ( type.empty() == false) @@ -302,7 +297,7 @@ void TransferManager::prolog_action(int vid) //MKSWAP tm_mad size hostname:remote_system_dir/disk.i xfr << "MKSWAP " - << tm_mad << " " + << system_tm_mad << " " << size << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << i << endl; @@ -323,7 +318,7 @@ void TransferManager::prolog_action(int vid) } //MKIMAGE tm_mad size format hostname:remote_system_dir/disk.i xfr << "MKIMAGE " - << tm_mad << " " + << system_tm_mad << " " << size << " " << format << " " << vm->get_hostname() << ":" @@ -331,6 +326,13 @@ void TransferManager::prolog_action(int vid) } else { + tm_mad = disk->vector_value("TM_MAD"); + + if ( tm_mad.empty() ) + { + goto error_tm_mad; + } + // ----------------------------------------------------------------- // CLONE or LINK disk images // ----------------------------------------------------------------- @@ -403,8 +405,10 @@ void TransferManager::prolog_action(int vid) if ( context_result ) { - //CONTEXT files hostname:remote_system_dir/disk.i - xfr << "CONTEXT " << vm->get_context_file() << " "; + //CONTEXT tm_mad files hostname:remote_system_dir/disk.i + xfr << "CONTEXT " + << system_tm_mad << " " + << vm->get_context_file() << " "; if (!files.empty()) { @@ -444,6 +448,11 @@ error_driver: os << "prolog, error getting Transfer Manager driver."; goto error_common; +error_tm_mad: + os.str(""); + os << "prolog, undefined TM_MAD for disk image in VM template"; + xfr.close(); + error_empty_disk: os.str(""); os << "prolog, undefined source disk image in VM template"; @@ -465,17 +474,19 @@ void TransferManager::prolog_migr_action(int vid) ofstream xfr; ostringstream os; string xfr_name; + string system_tm_mad; VirtualMachine * vm; Nebula& nd = Nebula::instance(); const TransferManagerDriver * tm_md; - // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ + system_tm_mad = nd.get_system_ds_tm_mad(); + vm = vmpool->get(vid,true); if (vm == 0) @@ -507,12 +518,12 @@ void TransferManager::prolog_migr_action(int vid) // Move image directory // ------------------------------------------------------------------------ - //MV prev_hostname:remote_system_dir hostname:remote_system_dir - /* - xfr << "MV "; - xfr << vm->get_previous_hostname() << ":" << vm->get_remote_dir() << " "; - xfr << vm->get_hostname() << ":" << vm->get_remote_dir() << endl; - */ + //MV tm_mad prev_hostname:remote_system_dir hostname:remote_system_dir + xfr << "MV " + << system_tm_mad << " " + << vm->get_previous_hostname() << ":" << vm->get_remote_system_dir() << " " + << vm->get_hostname() << ":" << vm->get_remote_system_dir() << endl; + xfr.close(); tm_md->transfer(vid,xfr_name); @@ -551,17 +562,19 @@ void TransferManager::prolog_resume_action(int vid) ofstream xfr; ostringstream os; string xfr_name; + string system_tm_mad; VirtualMachine * vm; Nebula& nd = Nebula::instance(); const TransferManagerDriver * tm_md; - // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ + system_tm_mad = nd.get_system_ds_tm_mad(); + vm = vmpool->get(vid,true); if (vm == 0) @@ -593,12 +606,12 @@ void TransferManager::prolog_resume_action(int vid) // Move image directory // ------------------------------------------------------------------------ - //MV fe:system_dir hostname:remote_system_dir - /* - xfr << "MV "; - xfr << nd.get_nebula_hostname() << ":" << vm->get_local_dir() << "/images "; - xfr << vm->get_hostname() << ":" << vm->get_remote_dir() << endl; - */ + //MV tm_mad fe:system_dir hostname:remote_system_dir + xfr << "MV " + << system_tm_mad << " " + << nd.get_nebula_hostname() << ":"<< vm->get_system_dir() << " " + << vm->get_hostname() << ":" << vm->get_remote_system_dir() << endl; + xfr.close(); tm_md->transfer(vid,xfr_name); @@ -638,6 +651,8 @@ void TransferManager::epilog_action(int vid) ofstream xfr; ostringstream os; string xfr_name; + string system_tm_mad; + string tm_mad; const VectorAttribute * disk; string save; @@ -654,6 +669,8 @@ void TransferManager::epilog_action(int vid) // Setup & Transfer script // ------------------------------------------------------------------------ + system_tm_mad = nd.get_system_ds_tm_mad(); + vm = vmpool->get(vid,true); if (vm == 0) @@ -707,20 +724,49 @@ void TransferManager::epilog_action(int vid) if ( save == "YES" ) { - //MV hostname:remote_system_dir/disk.0 fe:SOURCE? - /* - xfr << "MV " << vm->get_hostname() << ":" << vm->get_remote_dir() - << "/disk." << i << " " - << nd.get_nebula_hostname() << ":" << vm->get_local_dir() - << "/disk." << i << endl; - */ + ostringstream tsource; + string source; + + tm_mad = disk->vector_value("TM_MAD"); + + if (tm_mad.empty())//No TM_MAD, keep going to delete and save others + { + tm_mad = "error"; + vm->log("TM", Log::ERROR, "No TM_MAD for disk image"); + } + + source = disk->vector_value("SOURCE"); + + if ( source.empty() ) + { + vm->log("TM", Log::ERROR, "No SOURCE to save disk image"); + continue; + } + + if ( source.find(":") == string::npos ) //Regular file + { + tsource << nd.get_nebula_hostname() << ":" << source << " "; + } + else //TM Plugin specific protocol + { + tsource << source << " "; + } + + //MV tm_mad hostname:remote_system_dir/disk.0 + xfr << "MV " + << tm_mad << " " + << vm->get_hostname() << ":" + << vm->get_remote_system_dir() << "/disk." << i << " " + << tsource.str() << endl; } } - //DELETE hostname:remote_system_dir - /* - xfr << "DELETE " << vm->get_hostname() <<":"<< vm->get_remote_dir() << endl; - */ + //TODO DELETE SHOULD HOOK ON TM'S + //DELETE system_tm_mad hostname:remote_system_dir + xfr << "DELETE " + << system_tm_mad << " " + << vm->get_hostname() << ":" << vm->get_remote_system_dir() << endl; + xfr.close(); tm_md->transfer(vid,xfr_name); @@ -759,6 +805,7 @@ void TransferManager::epilog_stop_action(int vid) ofstream xfr; ostringstream os; string xfr_name; + string system_tm_mad; VirtualMachine * vm; Nebula& nd = Nebula::instance(); @@ -768,6 +815,8 @@ void TransferManager::epilog_stop_action(int vid) // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ + system_tm_mad = nd.get_system_ds_tm_mad(); + vm = vmpool->get(vid,true); if (vm == 0) @@ -798,13 +847,12 @@ void TransferManager::epilog_stop_action(int vid) // ------------------------------------------------------------------------ // Move image directory // ------------------------------------------------------------------------ + //MV system_tm_mad hostname:remote_system_dir fe:system_dir + xfr << "MV " + << system_tm_mad << " " + << vm->get_hostname() << ":" << vm->get_remote_system_dir() << " " + << nd.get_nebula_hostname() << ":" << vm->get_system_dir() << endl; - //MV hostname:remote_system_dir fe:system_dir - /* - xfr << "MV "; - xfr << vm->get_hostname() << ":" << vm->get_remote_dir() << " "; - xfr << nd.get_nebula_hostname() << ":" << vm->get_local_dir() << endl; - */ xfr.close(); tm_md->transfer(vid,xfr_name); @@ -844,14 +892,17 @@ void TransferManager::epilog_delete_action(int vid) ofstream xfr; ostringstream os; string xfr_name; + string system_tm_mad; VirtualMachine * vm; + Nebula& nd = Nebula::instance(); const TransferManagerDriver * tm_md; // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ + system_tm_mad = nd.get_system_ds_tm_mad(); vm = vmpool->get(vid,true); @@ -880,13 +931,15 @@ void TransferManager::epilog_delete_action(int vid) goto error_file; } - // ------------------------------------------------------------------------ + // ------------------------------------------------------------------------- // Delete the remote VM Directory - // ------------------------------------------------------------------------ - // DELETE hostname:remote_system_dir - /* - xfr << "DELETE " << vm->get_hostname() <<":"<< vm->get_remote_dir() << endl; - */ + // ------------------------------------------------------------------------- + //TODO DELETE SHOULD HOOK ON TM'S + //DELETE system_tm_mad hostname:remote_system_dir + xfr << "DELETE " + << system_tm_mad << " " + << vm->get_hostname() <<":"<< vm->get_remote_system_dir() << endl; + xfr.close(); tm_md->transfer(vid,xfr_name); @@ -903,19 +956,15 @@ error_history: error_file: os.str(""); os << "epilog_delete, could not open file: " << xfr_name; - /* os << ". You may need to manually clean " << vm->get_hostname() - << ":" << vm->get_remote_dir(); - */ + << ":" << vm->get_remote_system_dir(); goto error_common; error_driver: os.str(""); os << "epilog_delete, error getting driver Transfer Manager driver."; - /* os << ". You may need to manually clean " << vm->get_hostname() - << ":" << vm->get_remote_dir(); - */ + << ":" << vm->get_remote_system_dir(); error_common: vm->log("TM", Log::ERROR, os); @@ -932,8 +981,10 @@ void TransferManager::epilog_delete_previous_action(int vid) ofstream xfr; ostringstream os; string xfr_name; + string system_tm_mad; VirtualMachine * vm; + Nebula& nd = Nebula::instance(); const TransferManagerDriver * tm_md; @@ -941,6 +992,8 @@ void TransferManager::epilog_delete_previous_action(int vid) // Setup & Transfer script // ------------------------------------------------------------------------ + system_tm_mad = nd.get_system_ds_tm_mad(); + vm = vmpool->get(vid,true); if (vm == 0) @@ -971,11 +1024,12 @@ void TransferManager::epilog_delete_previous_action(int vid) // ------------------------------------------------------------------------ // Delete the remote VM Directory // ------------------------------------------------------------------------ - //DELTE prev_hostname:remote_system_dir - /* - xfr << "DELETE " << vm->get_previous_hostname() <<":"<< vm->get_remote_dir() + //DELTE system_tm_mad prev_hostname:remote_system_dir + xfr << "DELETE " + << system_tm_mad << " " + << vm->get_previous_hostname() <<":"<< vm->get_remote_system_dir() << endl; - */ + xfr.close(); tm_md->transfer(vid,xfr_name); @@ -992,19 +1046,15 @@ error_history: error_file: os.str(""); os << "epilog_delete, could not open file: " << xfr_name; - /* os << ". You may need to manually clean " << vm->get_previous_hostname() - << ":" << vm->get_remote_dir(); - */ + << ":" << vm->get_remote_system_dir(); goto error_common; error_driver: os.str(""); os << "epilog_delete, error getting driver Transfer Manager driver."; - /* os << ". You may need to manually clean " << vm->get_previous_hostname() - << ":" << vm->get_remote_dir(); - */ + << ":" << vm->get_remote_system_dir(); error_common: vm->log("TM", Log::ERROR, os); From 85caad3a1e6fe043bf829c7e3305a5d6cc76ce31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 27 Feb 2012 14:55:43 +0100 Subject: [PATCH 063/217] Feature #1112: Cluster does not inherit from ObjectCollection, instead it now contains 3 collections for hosts, DS and vnets --- include/Cluster.h | 27 +++++++++++++++++++++++---- include/ObjectCollection.h | 2 +- src/cluster/Cluster.cc | 28 +++++++++++++++++++++++----- src/cluster/ClusterPool.cc | 9 +++------ src/rm/RequestManagerAllocate.cc | 2 ++ 5 files changed, 52 insertions(+), 16 deletions(-) diff --git a/include/Cluster.h b/include/Cluster.h index 0227d66fa1..45b128f62c 100644 --- a/include/Cluster.h +++ b/include/Cluster.h @@ -25,7 +25,7 @@ using namespace std; /** * The Cluster class. */ -class Cluster : public PoolObjectSQL, ObjectCollection +class Cluster : public PoolObjectSQL { public: @@ -44,6 +44,15 @@ public: */ int from_xml(const string &xml_str); + /** + * Checks if all the collections are empty, and therefore this cluster + * can be dropped. + * + * @param error_msg Error message, if any. + * @return 0 if cluster can be dropped, -1 otherwise + */ + int check_drop(string& error_msg); + /** * Adds this user's ID to the set. * @param id of the user to be added to the cluster @@ -51,7 +60,7 @@ public: */ int add_host(int id) { - return add_collection_id(id); + return hosts.add_collection_id(id); } /** @@ -61,7 +70,7 @@ public: */ int del_host(int id) { - return del_collection_id(id); + return hosts.del_collection_id(id); } private: @@ -78,10 +87,20 @@ private: Cluster(int id, const string& name): PoolObjectSQL(id,CLUSTER,name,-1,-1,"","",table), - ObjectCollection("HOSTS"){}; + hosts("HOSTS"), + images("DATASTORES"), + vnets("VNETS"){}; virtual ~Cluster(){}; + // ************************************************************************* + // Object Collections (Private) + // ************************************************************************* + + ObjectCollection hosts; + ObjectCollection images; + ObjectCollection vnets; + // ************************************************************************* // DataBase implementation (Private) // ************************************************************************* diff --git a/include/ObjectCollection.h b/include/ObjectCollection.h index 058c646b6b..4d11b25f32 100644 --- a/include/ObjectCollection.h +++ b/include/ObjectCollection.h @@ -28,7 +28,7 @@ using namespace std; */ class ObjectCollection { -protected: +public: ObjectCollection(const string& _collection_name) :collection_name(_collection_name){}; diff --git a/src/cluster/Cluster.cc b/src/cluster/Cluster.cc index 44d1cb6ce3..efaa845a28 100644 --- a/src/cluster/Cluster.cc +++ b/src/cluster/Cluster.cc @@ -33,6 +33,26 @@ const char * Cluster::db_bootstrap = "CREATE TABLE IF NOT EXISTS cluster_pool (" "gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, " "UNIQUE(name))"; +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +int Cluster::check_drop(string& error_msg) +{ + ostringstream oss; + + if ( hosts.get_collection_size() > 0 ) + { + oss << "Cluster " << oid << " is not empty, it contains " + << hosts.get_collection_size() << " hosts."; + + error_msg = oss.str(); + + return -1; + } + + return 0; +} + /* ************************************************************************ */ /* Cluster :: Database Access Functions */ /* ************************************************************************ */ @@ -130,13 +150,11 @@ string& Cluster::to_xml(string& xml) const ostringstream oss; string collection_xml; - ObjectCollection::to_xml(collection_xml); - oss << - "" << + "" << "" << oid << "" << "" << name << "" << - collection_xml << + hosts.to_xml(collection_xml) << ""; xml = oss.str(); @@ -174,7 +192,7 @@ int Cluster::from_xml(const string& xml) } // Set of IDs - rc += ObjectCollection::from_xml_node(content[0]); + rc += hosts.from_xml_node(content[0]); ObjectXML::free_nodes(content); diff --git a/src/cluster/ClusterPool.cc b/src/cluster/ClusterPool.cc index 3e6924a962..266b41aff4 100644 --- a/src/cluster/ClusterPool.cc +++ b/src/cluster/ClusterPool.cc @@ -53,7 +53,7 @@ ClusterPool::ClusterPool(SqlDB * db):PoolSQL(db, Cluster::table) set_update_lastOID(99); } - + return; error_bootstrap: @@ -68,7 +68,7 @@ error_bootstrap: int ClusterPool::allocate(string name, int * oid, string& error_str) { - Cluster * cluster; + Cluster * cluster; ostringstream oss; if ( name.empty() ) @@ -132,11 +132,8 @@ int ClusterPool::drop(PoolObjectSQL * objsql, string& error_msg) return -2; } - if( cluster->get_collection_size() > 0 ) + if ( cluster->check_drop(error_msg) < 0 ) { - ostringstream oss; - oss << "Cluster " << cluster->get_oid() << " is not empty."; - error_msg = oss.str(); NebulaLog::log("CLUSTER", Log::ERROR, error_msg); return -3; diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index c5753560a0..2324b06cad 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -321,6 +321,8 @@ int HostAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, int cluster_id = ClusterPool::DEFAULT_CLUSTER_ID; string cluster_name = ClusterPool::DEFAULT_CLUSTER_NAME; + // TODO: Add to auth request CLUSTER MANAGE or ADMIN + HostPool * hpool = static_cast(pool); return hpool->allocate(&id, host, im_mad, vmm_mad, vnm_mad, From 95b5f405044e05c39565db9cabbbd2346758ae21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 27 Feb 2012 16:08:34 +0100 Subject: [PATCH 064/217] Feature #1112 #962: Better handling of error messages in Clusters --- include/Cluster.h | 158 +++++++++++++++++++++++++------- include/Host.h | 10 ++ src/cluster/Cluster.cc | 70 +++++++++++++- src/host/HostPool.cc | 5 +- src/rm/RequestManagerCluster.cc | 81 +++++++++++----- 5 files changed, 262 insertions(+), 62 deletions(-) diff --git a/include/Cluster.h b/include/Cluster.h index 45b128f62c..a6d1184541 100644 --- a/include/Cluster.h +++ b/include/Cluster.h @@ -29,6 +29,122 @@ class Cluster : public PoolObjectSQL { public: + // ************************************************************************* + // Object Collections (Public) + // ************************************************************************* + + /** + * Adds this host ID to the set. + * @param id to be added to the cluster + * @param error_msg Error message, if any + * @return 0 on success + */ + int add_host(int id, string& error_msg) + { + int rc = hosts.add_collection_id(id); + + if ( rc < 0 ) + { + error_msg = "ID is already in the set."; + } + + return rc; + } + + /** + * Deletes this host ID from the set. + * @param id to be deleted from the cluster + * @param error_msg Error message, if any + * @return 0 on success + */ + int del_host(int id, string& error_msg) + { + int rc = hosts.del_collection_id(id); + + if ( rc < 0 ) + { + error_msg = "ID is not part of the set."; + } + + return rc; + } + + /** + * Adds this datastore ID to the set. + * @param id to be added to the cluster + * @param error_msg Error message, if any + * @return 0 on success + */ + int add_datastore(int id, string& error_msg) + { + int rc = datastores.add_collection_id(id); + + if ( rc < 0 ) + { + error_msg = "ID is already in the set."; + } + + return rc; + } + + /** + * Deletes this datastore ID from the set. + * @param id to be deleted from the cluster + * @param error_msg Error message, if any + * @return 0 on success + */ + int del_datastore(int id, string& error_msg) + { + int rc = datastores.del_collection_id(id); + + if ( rc < 0 ) + { + error_msg = "ID is not part of the set."; + } + + return rc; + } + + /** + * Adds this vnet ID to the set. + * @param id to be added to the cluster + * @param error_msg Error message, if any + * @return 0 on success + */ + int add_vnet(int id, string& error_msg) + { + int rc = vnets.add_collection_id(id); + + if ( rc < 0 ) + { + error_msg = "ID is already in the set."; + } + + return rc; + } + + /** + * Deletes this vnet ID from the set. + * @param id to be deleted from the cluster + * @param error_msg Error message, if any + * @return 0 on success + */ + int del_vnet(int id, string& error_msg) + { + int rc = vnets.del_collection_id(id); + + if ( rc < 0 ) + { + error_msg = "ID is not part of the set."; + } + + return rc; + } + + // ************************************************************************* + // DataBase implementation (Public) + // ************************************************************************* + /** * Function to print the Cluster object into a string in XML format * @param xml the resulting XML string @@ -44,35 +160,6 @@ public: */ int from_xml(const string &xml_str); - /** - * Checks if all the collections are empty, and therefore this cluster - * can be dropped. - * - * @param error_msg Error message, if any. - * @return 0 if cluster can be dropped, -1 otherwise - */ - int check_drop(string& error_msg); - - /** - * Adds this user's ID to the set. - * @param id of the user to be added to the cluster - * @return 0 on success - */ - int add_host(int id) - { - return hosts.add_collection_id(id); - } - - /** - * Deletes this users's ID from the set. - * @param id of the user to be deleted from the cluster - * @return 0 on success - */ - int del_host(int id) - { - return hosts.del_collection_id(id); - } - private: // ------------------------------------------------------------------------- @@ -88,7 +175,7 @@ private: Cluster(int id, const string& name): PoolObjectSQL(id,CLUSTER,name,-1,-1,"","",table), hosts("HOSTS"), - images("DATASTORES"), + datastores("DATASTORES"), vnets("VNETS"){}; virtual ~Cluster(){}; @@ -98,7 +185,7 @@ private: // ************************************************************************* ObjectCollection hosts; - ObjectCollection images; + ObjectCollection datastores; ObjectCollection vnets; // ************************************************************************* @@ -151,6 +238,15 @@ private: string error_str; return insert_replace(db, true, error_str); } + + /** + * Checks if all the collections are empty, and therefore this cluster + * can be dropped. + * + * @param error_msg Error message, if any. + * @return 0 if cluster can be dropped, -1 otherwise + */ + int check_drop(string& error_msg); }; #endif /*CLUSTER_H_*/ diff --git a/include/Host.h b/include/Host.h index 7de9216cb8..0aa0bc30cf 100644 --- a/include/Host.h +++ b/include/Host.h @@ -188,6 +188,16 @@ public: return cluster_id; }; + /** + * Returns the cluster name + * + * @return The cluster name + */ + string get_cluster_name() + { + return cluster; + }; + // ------------------------------------------------------------------------ // Share functions // ------------------------------------------------------------------------ diff --git a/src/cluster/Cluster.cc b/src/cluster/Cluster.cc index efaa845a28..78b93ddd28 100644 --- a/src/cluster/Cluster.cc +++ b/src/cluster/Cluster.cc @@ -45,12 +45,31 @@ int Cluster::check_drop(string& error_msg) oss << "Cluster " << oid << " is not empty, it contains " << hosts.get_collection_size() << " hosts."; - error_msg = oss.str(); + goto error_common; + } - return -1; + if ( datastores.get_collection_size() > 0 ) + { + oss << "Cluster " << oid << " is not empty, it contains " + << datastores.get_collection_size() << " datastores."; + + goto error_common; + } + + if ( vnets.get_collection_size() > 0 ) + { + oss << "Cluster " << oid << " is not empty, it contains " + << vnets.get_collection_size() << " vnets."; + + goto error_common; } return 0; + +error_common: + error_msg = oss.str(); + + return -1; } /* ************************************************************************ */ @@ -148,13 +167,19 @@ error_common: string& Cluster::to_xml(string& xml) const { ostringstream oss; - string collection_xml; + string host_collection_xml; + string ds_collection_xml; + string vnet_collection_xml; oss << "" << "" << oid << "" << "" << name << "" << - hosts.to_xml(collection_xml) << + + hosts.to_xml(host_collection_xml) << + datastores.to_xml(ds_collection_xml) << + vnets.to_xml(vnet_collection_xml) << + ""; xml = oss.str(); @@ -183,7 +208,9 @@ int Cluster::from_xml(const string& xml) // Set the Cluster ID as the cluster it belongs to set_group(oid, name); - // Get associated classes + // ------------------------------------------------------------------------- + // Get associated hosts + // ------------------------------------------------------------------------- ObjectXML::get_nodes("/CLUSTER/HOSTS", content); if (content.empty()) @@ -195,6 +222,39 @@ int Cluster::from_xml(const string& xml) rc += hosts.from_xml_node(content[0]); ObjectXML::free_nodes(content); + content.clear(); + + // ------------------------------------------------------------------------- + // Get associated datastores + // ------------------------------------------------------------------------- + ObjectXML::get_nodes("/CLUSTER/DATASTORES", content); + + if (content.empty()) + { + return -1; + } + + // Set of IDs + rc += datastores.from_xml_node(content[0]); + + ObjectXML::free_nodes(content); + content.clear(); + + // ------------------------------------------------------------------------- + // Get associated vnets + // ------------------------------------------------------------------------- + ObjectXML::get_nodes("/CLUSTER/VNETS", content); + + if (content.empty()) + { + return -1; + } + + // Set of IDs + rc += vnets.from_xml_node(content[0]); + + ObjectXML::free_nodes(content); + content.clear(); if (rc != 0) { diff --git a/src/host/HostPool.cc b/src/host/HostPool.cc index e23132daab..bd72115061 100644 --- a/src/host/HostPool.cc +++ b/src/host/HostPool.cc @@ -227,7 +227,10 @@ int HostPool::allocate ( return -1; } - cluster->add_host(*oid); + if ( cluster->add_host(*oid, error_str) < 0 ) + { + return -1; + } clpool->update(cluster); diff --git a/src/rm/RequestManagerCluster.cc b/src/rm/RequestManagerCluster.cc index 315162d72d..aae900ed45 100644 --- a/src/rm/RequestManagerCluster.cc +++ b/src/rm/RequestManagerCluster.cc @@ -56,12 +56,12 @@ void ClusterAddHost::request_execute( { int cluster_id = xmlrpc_c::value_int(paramList.getInt(1)); int host_id = xmlrpc_c::value_int(paramList.getInt(2)); - int old_cluster_id; int rc; string cluster_name; string host_name; + string err_msg; Cluster * cluster; Host * host; @@ -69,6 +69,9 @@ void ClusterAddHost::request_execute( PoolObjectAuth c_perms; PoolObjectAuth h_perms; + int old_cluster_id; + string old_cluster_name; + rc = get_info(clpool, cluster_id, PoolObjectSQL::CLUSTER, att, c_perms, cluster_name); if ( rc == -1 ) @@ -100,24 +103,6 @@ void ClusterAddHost::request_execute( } } - // ------------- Add host to new cluster --------------------- - - cluster = clpool->get(cluster_id, true); - - if ( cluster == 0 ) - { - failure_response(NO_EXISTS, - get_error(object_name(PoolObjectSQL::CLUSTER),cluster_id), - att); - return; - } - - cluster->add_host(host_id); - - clpool->update(cluster); - - cluster->unlock(); - // ------------- Set new cluster id in host --------------------- host = hpool->get(host_id, true); @@ -128,14 +113,11 @@ void ClusterAddHost::request_execute( get_error(object_name(PoolObjectSQL::HOST), host_id), att); - // TODO: rollback - // clpool->get (cluster_id) - // cluster->del_host(host_id); - return; } - old_cluster_id = host->get_cluster_id(); + old_cluster_id = host->get_cluster_id(); + old_cluster_name = host->get_cluster_name(); if ( old_cluster_id == cluster_id ) { @@ -150,6 +132,46 @@ void ClusterAddHost::request_execute( host->unlock(); + // ------------- Add host to new cluster --------------------- + + cluster = clpool->get(cluster_id, true); + + if ( cluster == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::CLUSTER),cluster_id), + att); + + // Rollback + host = hpool->get(host_id, true); + + if ( host != 0 ) + { + host->set_cluster(old_cluster_id, old_cluster_name); + + hpool->update(host); + + host->unlock(); + } + + return; + } + + if ( cluster->add_host(host_id, err_msg) < 0 ) + { + cluster->unlock(); + + failure_response(INTERNAL, + request_error("Cannot add host to cluster", err_msg), + att); + + return; + } + + clpool->update(cluster); + + cluster->unlock(); + // ------------- Remove host from old cluster --------------------- cluster = clpool->get(old_cluster_id, true); @@ -163,7 +185,16 @@ void ClusterAddHost::request_execute( return; } - cluster->del_host(host_id); + if ( cluster->del_host(host_id, err_msg) < 0 ) + { + cluster->unlock(); + + failure_response(INTERNAL, + request_error("Cannot remove host from cluster", err_msg), + att); + + return; + } clpool->update(cluster); From 313c2967c7db294171d4247cbe1a968b4fa1f74b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 27 Feb 2012 18:55:15 +0100 Subject: [PATCH 065/217] Feature #1112: Refactor Cluster attributes to be used in other classes by inheritance --- include/Clusterable.h | 78 +++++++++++++++++++++++++++++++++ include/Host.h | 41 +---------------- include/RequestManagerCluster.h | 35 ++++++++++++++- src/host/Host.cc | 5 +-- src/rm/RequestManagerCluster.cc | 59 +++++++++++++------------ 5 files changed, 147 insertions(+), 71 deletions(-) create mode 100644 include/Clusterable.h diff --git a/include/Clusterable.h b/include/Clusterable.h new file mode 100644 index 0000000000..94bd133fed --- /dev/null +++ b/include/Clusterable.h @@ -0,0 +1,78 @@ +/* ------------------------------------------------------------------------ */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------*/ + +#ifndef CLUSTERABLE_H_ +#define CLUSTERABLE_H_ + +using namespace std; + +class Clusterable +{ +public: + + /** + * Changes the cluster this object belongs to + * + * @param _cluster_id Id of the new cluster + * @param _cluster Name of the new cluster + */ + void set_cluster(int _cluster_id, const string& _cluster) + { + cluster_id = _cluster_id; + cluster = _cluster; + }; + + /** + * Returns the cluster ID + * + * @return The cluster ID + */ + int get_cluster_id() const + { + return cluster_id; + }; + + /** + * Returns the cluster name + * + * @return The cluster name + */ + const string& get_cluster_name() const + { + return cluster; + }; + + +protected: + + Clusterable(int _cluster_id, const string& _cluster): + cluster_id(_cluster_id), + cluster(_cluster){}; + + ~Clusterable(){}; + + /** + * ID of the cluster this object belongs to. + */ + int cluster_id; + + /** + * Name of the cluster this object belongs to. + */ + string cluster; +}; + +#endif /*CLUSTERABLE_H_*/ diff --git a/include/Host.h b/include/Host.h index 0aa0bc30cf..06b519f450 100644 --- a/include/Host.h +++ b/include/Host.h @@ -20,13 +20,14 @@ #include "PoolSQL.h" #include "HostTemplate.h" #include "HostShare.h" +#include "Clusterable.h" using namespace std; /** * The Host class. */ -class Host : public PoolObjectSQL +class Host : public PoolObjectSQL, public Clusterable { public: @@ -166,38 +167,6 @@ public: return last_monitored; }; - /** - * Changes the cluster this host belongs to - * - * @param _cluster_id Id of the new cluster - * @param _cluster Name of the new cluter - */ - void set_cluster(int _cluster_id, const string& _cluster) - { - cluster_id = _cluster_id; - cluster = _cluster; - }; - - /** - * Returns the cluster ID - * - * @return The cluster ID - */ - int get_cluster_id() - { - return cluster_id; - }; - - /** - * Returns the cluster name - * - * @return The cluster name - */ - string get_cluster_name() - { - return cluster; - }; - // ------------------------------------------------------------------------ // Share functions // ------------------------------------------------------------------------ @@ -354,12 +323,6 @@ private: */ time_t last_monitored; - int cluster_id; - /** - * Name of the cluster this host belongs to. - */ - string cluster; - // ------------------------------------------------------------------------- // Host Attributes // ------------------------------------------------------------------------- diff --git a/include/RequestManagerCluster.h b/include/RequestManagerCluster.h index 10c2f38977..dfa8aebefa 100644 --- a/include/RequestManagerCluster.h +++ b/include/RequestManagerCluster.h @@ -54,6 +54,18 @@ protected: virtual void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) = 0; + void add_generic( + xmlrpc_c::paramList const& _paramList, + RequestAttributes& att, + PoolSQL * pool, + PoolObjectSQL::ObjectType type); + + virtual int add_object(Cluster* cluster, int id, string& error_msg) = 0; + + virtual int del_object(Cluster* cluster, int id, string& error_msg) = 0; + + virtual void get(int oid, bool lock, PoolObjectSQL ** object, Clusterable ** cluster_obj) = 0; + int get_info (PoolSQL * pool, int id, PoolObjectSQL::ObjectType type, @@ -76,7 +88,28 @@ public: ~ClusterAddHost(){}; void request_execute(xmlrpc_c::paramList const& _paramList, - RequestAttributes& att); + RequestAttributes& att) + { + return add_generic(_paramList, att, hpool, PoolObjectSQL::HOST); + } + + virtual int add_object(Cluster* cluster, int id, string& error_msg) + { + return cluster->add_host(id, error_msg); + }; + + virtual int del_object(Cluster* cluster, int id, string& error_msg) + { + return cluster->del_host(id, error_msg); + }; + + virtual void get(int oid, bool lock, PoolObjectSQL ** object, Clusterable ** cluster_obj) + { + Host * host = hpool->get(oid, lock); + + *object = static_cast(host); + *cluster_obj = static_cast(host); + }; }; /* -------------------------------------------------------------------------- */ diff --git a/src/host/Host.cc b/src/host/Host.cc index 977d928aa4..14afbb4ca1 100644 --- a/src/host/Host.cc +++ b/src/host/Host.cc @@ -37,13 +37,12 @@ Host::Host( int _cluster_id, const string& _cluster_name): PoolObjectSQL(id,HOST,_hostname,-1,-1,"","",table), + Clusterable(_cluster_id, _cluster_name), state(INIT), im_mad_name(_im_mad_name), vmm_mad_name(_vmm_mad_name), vnm_mad_name(_vnm_mad_name), - last_monitored(0), - cluster_id(_cluster_id), - cluster(_cluster_name) + last_monitored(0) { obj_template = new HostTemplate; } diff --git a/src/rm/RequestManagerCluster.cc b/src/rm/RequestManagerCluster.cc index aae900ed45..0f2cd79709 100644 --- a/src/rm/RequestManagerCluster.cc +++ b/src/rm/RequestManagerCluster.cc @@ -50,24 +50,28 @@ int RequestManagerCluster::get_info (PoolSQL * pool, /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ -void ClusterAddHost::request_execute( +void RequestManagerCluster::add_generic( xmlrpc_c::paramList const& paramList, - RequestAttributes& att) + RequestAttributes& att, + PoolSQL * pool, + PoolObjectSQL::ObjectType type) { int cluster_id = xmlrpc_c::value_int(paramList.getInt(1)); - int host_id = xmlrpc_c::value_int(paramList.getInt(2)); + int object_id = xmlrpc_c::value_int(paramList.getInt(2)); int rc; string cluster_name; - string host_name; + string obj_name; string err_msg; - Cluster * cluster; - Host * host; + Cluster * cluster; + Clusterable * cluster_obj = 0; + PoolObjectSQL * object = 0; + PoolObjectAuth c_perms; - PoolObjectAuth h_perms; + PoolObjectAuth obj_perms; int old_cluster_id; string old_cluster_name; @@ -79,7 +83,7 @@ void ClusterAddHost::request_execute( return; } - rc = get_info(hpool, host_id, PoolObjectSQL::HOST, att, h_perms, host_name); + rc = get_info(pool, object_id, type, att, obj_perms, obj_name); if ( rc == -1 ) { @@ -91,7 +95,7 @@ void ClusterAddHost::request_execute( AuthRequest ar(att.uid, att.gid); ar.add_auth(auth_op, c_perms); // MANAGE CLUSTER - ar.add_auth(AuthRequest::ADMIN, h_perms); // ADMIN HOST + ar.add_auth(AuthRequest::ADMIN, obj_perms); // ADMIN OBJECT if (UserPool::authorize(ar) == -1) { @@ -103,36 +107,35 @@ void ClusterAddHost::request_execute( } } - // ------------- Set new cluster id in host --------------------- + // ------------- Set new cluster id in object --------------------- + get(object_id, true, &object, &cluster_obj); - host = hpool->get(host_id, true); - - if ( host == 0 ) + if ( object == 0 ) { failure_response(NO_EXISTS, - get_error(object_name(PoolObjectSQL::HOST), host_id), + get_error(object_name(type), object_id), att); return; } - old_cluster_id = host->get_cluster_id(); - old_cluster_name = host->get_cluster_name(); + old_cluster_id = cluster_obj->get_cluster_id(); + old_cluster_name = cluster_obj->get_cluster_name(); if ( old_cluster_id == cluster_id ) { - host->unlock(); + object->unlock(); success_response(cluster_id, att); return; } - host->set_cluster(cluster_id, cluster_name); + cluster_obj->set_cluster(cluster_id, cluster_name); - hpool->update(host); + pool->update(object); - host->unlock(); + object->unlock(); - // ------------- Add host to new cluster --------------------- + // ------------- Add object to new cluster --------------------- cluster = clpool->get(cluster_id, true); @@ -143,21 +146,21 @@ void ClusterAddHost::request_execute( att); // Rollback - host = hpool->get(host_id, true); + get(object_id, true, &object, &cluster_obj); - if ( host != 0 ) + if ( object != 0 ) { - host->set_cluster(old_cluster_id, old_cluster_name); + cluster_obj->set_cluster(old_cluster_id, old_cluster_name); - hpool->update(host); + pool->update(object); - host->unlock(); + object->unlock(); } return; } - if ( cluster->add_host(host_id, err_msg) < 0 ) + if ( add_object(cluster, object_id, err_msg) < 0 ) { cluster->unlock(); @@ -185,7 +188,7 @@ void ClusterAddHost::request_execute( return; } - if ( cluster->del_host(host_id, err_msg) < 0 ) + if ( del_object(cluster, object_id, err_msg) < 0 ) { cluster->unlock(); From 8a7aa7e0f744c0e639fb68fd33597bf73f6cc07d Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Mon, 27 Feb 2012 22:19:49 +0100 Subject: [PATCH 066/217] feature #1112: Updated TM transger scripts --- src/tm/TransferManager.cc | 246 +++++++++++++++++++++++++++++++------- 1 file changed, 202 insertions(+), 44 deletions(-) diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index 0837b2ef62..48f822d44f 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -265,7 +265,7 @@ void TransferManager::prolog_action(int vid) num = vm->get_template_attribute("DISK",attrs); - for (int i=0; i < num ;i++,source="",type="",clon="") + for (int i=0; i < num ;i++, source="", type="", clon="", tm_mad="") { disk = dynamic_cast(attrs[i]); @@ -295,7 +295,7 @@ void TransferManager::prolog_action(int vid) continue; } - //MKSWAP tm_mad size hostname:remote_system_dir/disk.i + //MKSWAP tm_mad size host:remote_system_dir/disk.i xfr << "MKSWAP " << system_tm_mad << " " << size << " " @@ -316,7 +316,7 @@ void TransferManager::prolog_action(int vid) " skipping"); continue; } - //MKIMAGE tm_mad size format hostname:remote_system_dir/disk.i + //MKIMAGE tm_mad size format host:remote_system_dir/disk.i xfr << "MKIMAGE " << system_tm_mad << " " << size << " " @@ -349,7 +349,7 @@ void TransferManager::prolog_action(int vid) (int(*)(int))toupper); } - // tm_mad fe:SOURCE hostname:remote_system_ds/disk.i size + // tm_mad fe:SOURCE host:remote_system_ds/disk.i size if (clon == "YES") { xfr << "CLONE "; @@ -474,7 +474,13 @@ void TransferManager::prolog_migr_action(int vid) ofstream xfr; ostringstream os; string xfr_name; - string system_tm_mad; + + const VectorAttribute * disk; + string tm_mad; + string system_tm_mad; + + vector attrs; + int num; VirtualMachine * vm; Nebula& nd = Nebula::instance(); @@ -515,14 +521,43 @@ void TransferManager::prolog_migr_action(int vid) } // ------------------------------------------------------------------------ - // Move image directory + // Move system directory and disks // ------------------------------------------------------------------------ - //MV tm_mad prev_hostname:remote_system_dir hostname:remote_system_dir + num = vm->get_template_attribute("DISK",attrs); + + for (int i=0 ; i < num ; i++, tm_mad="") + { + disk = dynamic_cast(attrs[i]); + + if ( disk == 0 ) + { + continue; + } + + tm_mad = disk->vector_value("TM_MAD"); + + if ( tm_mad.empty() ) + { + continue; + } + + //MVDISK tm_mad prev_host:remote_system_dir/disk.i host:remote_system_dir/disk.i + xfr << "MVDISK " + << tm_mad << " " + << vm->get_previous_hostname() << ":" + << vm->get_remote_system_dir() << "/disk." << i << " " + << vm->get_hostname() << ":" + << vm->get_remote_system_dir() << "/disk." << i << endl; + } + + //MV tm_mad prev_host:remote_system_dir host:remote_system_dir xfr << "MV " << system_tm_mad << " " - << vm->get_previous_hostname() << ":" << vm->get_remote_system_dir() << " " - << vm->get_hostname() << ":" << vm->get_remote_system_dir() << endl; + << vm->get_previous_hostname() << ":" + << vm->get_remote_system_dir() << " " + << vm->get_hostname() << ":" + << vm->get_remote_system_dir() << endl; xfr.close(); @@ -562,7 +597,13 @@ void TransferManager::prolog_resume_action(int vid) ofstream xfr; ostringstream os; string xfr_name; - string system_tm_mad; + + const VectorAttribute * disk; + string tm_mad; + string system_tm_mad; + + vector attrs; + int num; VirtualMachine * vm; Nebula& nd = Nebula::instance(); @@ -603,10 +644,36 @@ void TransferManager::prolog_resume_action(int vid) } // ------------------------------------------------------------------------ - // Move image directory + // Move system directory and disks // ------------------------------------------------------------------------ + num = vm->get_template_attribute("DISK",attrs); - //MV tm_mad fe:system_dir hostname:remote_system_dir + for (int i=0 ; i < num ; i++, tm_mad="") + { + disk = dynamic_cast(attrs[i]); + + if ( disk == 0 ) + { + continue; + } + + tm_mad = disk->vector_value("TM_MAD"); + + if ( tm_mad.empty() ) + { + continue; + } + + //MVDISK tm_mad fe:system_dir/disk.i host:remote_system_dir/disk.i + xfr << "MVDISK " + << tm_mad << " " + << nd.get_nebula_hostname() << ":" + << vm->get_system_dir() << "/disk." << i << " " + << vm->get_hostname() << ":" + << vm->get_remote_system_dir() << "/disk." << i << endl; + } + + //MV tm_mad fe:system_dir host:remote_system_dir xfr << "MV " << system_tm_mad << " " << nd.get_nebula_hostname() << ":"<< vm->get_system_dir() << " " @@ -642,7 +709,6 @@ error_common: return; } - /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -722,19 +788,13 @@ void TransferManager::epilog_action(int vid) transform(save.begin(),save.end(),save.begin(),(int(*)(int))toupper); + tm_mad = disk->vector_value("TM_MAD"); + if ( save == "YES" ) { ostringstream tsource; string source; - tm_mad = disk->vector_value("TM_MAD"); - - if (tm_mad.empty())//No TM_MAD, keep going to delete and save others - { - tm_mad = "error"; - vm->log("TM", Log::ERROR, "No TM_MAD for disk image"); - } - source = disk->vector_value("SOURCE"); if ( source.empty() ) @@ -759,9 +819,16 @@ void TransferManager::epilog_action(int vid) << vm->get_remote_system_dir() << "/disk." << i << " " << tsource.str() << endl; } + else if ( !tm_mad.empty() ) //No saving disk and no system_ds disk + { + //DELETEDISK tm_mad hostname:remote_system_dir/disk.i + xfr << "DELETEDISK " + << tm_mad << " " + << vm->get_hostname() << ":" + << vm->get_remote_system_dir() << "/disk." << i << endl; + } } - //TODO DELETE SHOULD HOOK ON TM'S //DELETE system_tm_mad hostname:remote_system_dir xfr << "DELETE " << system_tm_mad << " " @@ -802,16 +869,21 @@ error_common: void TransferManager::epilog_stop_action(int vid) { - ofstream xfr; - ostringstream os; - string xfr_name; - string system_tm_mad; + ofstream xfr; + ostringstream os; + string xfr_name; + string tm_mad; + string system_tm_mad; - VirtualMachine * vm; - Nebula& nd = Nebula::instance(); + VirtualMachine * vm; + Nebula& nd = Nebula::instance(); const TransferManagerDriver * tm_md; + vector attrs; + const VectorAttribute * disk; + int num; + // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ @@ -845,8 +917,35 @@ void TransferManager::epilog_stop_action(int vid) } // ------------------------------------------------------------------------ - // Move image directory + // Move system directory and disks // ------------------------------------------------------------------------ + num = vm->get_template_attribute("DISK",attrs); + + for (int i=0 ; i < num ; i++, tm_mad="") + { + disk = dynamic_cast(attrs[i]); + + if ( disk == 0 ) + { + continue; + } + + tm_mad = disk->vector_value("TM_MAD"); + + if ( tm_mad.empty() ) + { + continue; + } + + //MVDISK tm_mad host:remote_system_dir/disk.i fe:system_dir/disk.i + xfr << "MVDISK " + << tm_mad << " " + << vm->get_hostname() << ":" + << vm->get_remote_system_dir() << "/disk." << i << " " + << nd.get_nebula_hostname() << ":" + << vm->get_system_dir() << "/disk." << i << endl; + } + //MV system_tm_mad hostname:remote_system_dir fe:system_dir xfr << "MV " << system_tm_mad << " " @@ -889,16 +988,21 @@ error_common: void TransferManager::epilog_delete_action(int vid) { - ofstream xfr; - ostringstream os; - string xfr_name; - string system_tm_mad; + ofstream xfr; + ostringstream os; + string xfr_name; + string system_tm_mad; + string tm_mad; - VirtualMachine * vm; - Nebula& nd = Nebula::instance(); + VirtualMachine * vm; + Nebula& nd = Nebula::instance(); const TransferManagerDriver * tm_md; + const VectorAttribute * disk; + vector attrs; + int num; + // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ @@ -932,9 +1036,33 @@ void TransferManager::epilog_delete_action(int vid) } // ------------------------------------------------------------------------- - // Delete the remote VM Directory + // Delete disk images and the remote system Directory // ------------------------------------------------------------------------- - //TODO DELETE SHOULD HOOK ON TM'S + num = vm->get_template_attribute("DISK",attrs); + + for (int i=0 ; i < num ; i++, tm_mad="") + { + disk = dynamic_cast(attrs[i]); + + if ( disk == 0 ) + { + continue; + } + + tm_mad = disk->vector_value("TM_MAD"); + + if ( tm_mad.empty() ) + { + continue; + } + + //DELETEDISK tm_mad host:remote_system_dir/disk.i + xfr << "DELETEDISK " + << tm_mad << " " + << vm->get_hostname() << ":" + << vm->get_remote_system_dir() << "/disk." << i << endl; + } + //DELETE system_tm_mad hostname:remote_system_dir xfr << "DELETE " << system_tm_mad << " " @@ -978,16 +1106,21 @@ error_common: void TransferManager::epilog_delete_previous_action(int vid) { - ofstream xfr; - ostringstream os; - string xfr_name; - string system_tm_mad; + ofstream xfr; + ostringstream os; + string xfr_name; + string system_tm_mad; + string tm_mad; - VirtualMachine * vm; - Nebula& nd = Nebula::instance(); + VirtualMachine * vm; + Nebula& nd = Nebula::instance(); const TransferManagerDriver * tm_md; + const VectorAttribute * disk; + vector attrs; + int num; + // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ @@ -1024,7 +1157,32 @@ void TransferManager::epilog_delete_previous_action(int vid) // ------------------------------------------------------------------------ // Delete the remote VM Directory // ------------------------------------------------------------------------ - //DELTE system_tm_mad prev_hostname:remote_system_dir + num = vm->get_template_attribute("DISK",attrs); + + for (int i=0 ; i < num ; i++, tm_mad="") + { + disk = dynamic_cast(attrs[i]); + + if ( disk == 0 ) + { + continue; + } + + tm_mad = disk->vector_value("TM_MAD"); + + if ( tm_mad.empty() ) + { + continue; + } + + //DELETEDISK tm_mad prev_host:remote_system_dir/disk.i + xfr << "DELETEDISK " + << tm_mad << " " + << vm->get_previous_hostname() << ":" + << vm->get_remote_system_dir() << "/disk." << i << endl; + } + + //DELTE system_tm_mad prev_host:remote_system_dir xfr << "DELETE " << system_tm_mad << " " << vm->get_previous_hostname() <<":"<< vm->get_remote_system_dir() From fb95a2f88bec587a326d2244ad8695550019717b Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 28 Feb 2012 00:11:45 +0100 Subject: [PATCH 067/217] feature #1112: Remove TMScript.rb --- install.sh | 1 - src/tm_mad/TMScript.rb | 217 ----------------------------------------- 2 files changed, 218 deletions(-) delete mode 100644 src/tm_mad/TMScript.rb diff --git a/install.sh b/install.sh index a2bc187e54..882cf86a46 100755 --- a/install.sh +++ b/install.sh @@ -591,7 +591,6 @@ RUBY_LIB_FILES="src/mad/ruby/ActionManager.rb \ src/vnm_mad/one_vnm.rb \ src/mad/ruby/Ganglia.rb \ src/oca/ruby/OpenNebula.rb \ - src/tm_mad/TMScript.rb \ src/authm_mad/remotes/ssh/ssh_auth.rb \ src/authm_mad/remotes/quota/quota.rb \ src/authm_mad/remotes/server_x509/server_x509_auth.rb \ diff --git a/src/tm_mad/TMScript.rb b/src/tm_mad/TMScript.rb deleted file mode 100644 index 538982bf2e..0000000000 --- a/src/tm_mad/TMScript.rb +++ /dev/null @@ -1,217 +0,0 @@ - -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -require 'pp' -require 'open3' -require 'CommandManager' - -=begin rdoc - -TMPlugin holds the name of the scripts that will be used for each -TransferManager script command. It is basically a hash where keys -are the names of the commands (uppercase) and contain the path of -the script that will be executed for that command. - -It also contains some methods to execute the scripts, get the output -of the script (success/failure, error and log messages). - -=end -class TMPlugin < Hash - # If a +scripts_file+ is supplied commands are loaded from it. - def initialize(scripts_file=nil) - # Pass nil default value to hash initialization or it will use - # scripts file as the default value if the key does not exist - super(nil) - load_scripts(scripts_file) if scripts_file - end - - # Executes the script associated with the +command+ using - # specified arguments. +logger+ is a proc that takes a message - # as its unique argument. - # - # Returns: - # * It will return +nil+ if the +command+ is not defined. - # * LocalCommand object (exit code and - # error message in case of failure) - # - # Note: the exit code will be written like this: - # ExitCode: 0 - def execute(logger, command, *args) - # Command is not defined - return nil if !self[command] - - # Generates the line to call the script with all the - # arguments provided. - cmd=[self[command], *args].join(" ") - - local_command = LocalCommand.run(cmd, logger) - - logger.call(local_command.stdout) if logger - - local_command - end - - private - - # Loads definitions of commands from the configuration file - def load_scripts(scripts_file) - scripts_text="" - - if File.exist?(scripts_file) - scripts_text = File.read(scripts_file) - else - STDERR.puts("Can not open #{scripts_file}") - STDERR.flush - return - end - - one_location=ENV['ONE_LOCATION'] - - if one_location == nil - tm_commands_location = "/usr/lib/one/tm_commands/" - else - tm_commands_location = one_location + "/lib/tm_commands/" - end - - scripts_text.each_line {|line| - case line - when /^\s*(#.*)?$/ - # skip empty or commented lines - next - when /^\s*(\w+)\s*=\s*(.*)\s*$/ - command = $1.strip.upcase - path = $2.strip - - # Prepend default location for tm commands if the path does not - # start with / - path = tm_commands_location+path if path[0]!=?/ - - self[command] = path - else - STDERR.puts("Can not parse line: #{line}") - end - } - end -end - -# This class will parse and execute TransferManager scripts. -class TMScript - attr_accessor :lines - - # +script_text+ contains the script to be executed. - # +logger+ is a lambda that receives a message and sends it - # to OpenNebula server - def initialize(script_text, logger=nil) - @lines = Array.new - @logger = logger - - parse_script(script_text) - end - - # Executes the script using the TMPlugin specified by +plugin+. - # Returns an array where first element tells if succeded and the - # second one is the error message in case of failure. - def execute(plugin) - return [true,""] if @lines.empty? - - result = @lines.each {|line| - res = plugin.execute(@logger, *line) - - if !res - @logger.call("COMMAND not found: #{line.join(" ")}.") if @logger - - res = [false, "COMMAND not found: #{line.join(" ")}."] - else - if res.code == 0 - res = [true, ""] - else - res = [false, res.get_error_message] - end - end - - # do not continue if command failed - break res if !res[0] - } - - result - end - - private - - # Gets commands from the script and populates +@lines+ - def parse_script(script_text) - script_text.each_line {|line| - # skip if the line is commented - next if line.match(/^\s*#/) - # skip if the line is empty - next if line.match(/^\s*$/) - - command=line.split(" ") - command[0].upcase! - @lines<< command - } - end -end - - -if $0 == __FILE__ - -=begin - require 'one_log' - - logger=ONELog.new - - log_proc=lambda{|message| - logger.log("TRANSFER", "0", message) - } - - log_proc.call(<<-EOT) - Multiple - lines log - - thingy - EOT - -=end - - log_proc=lambda{|message| - puts message - } - - script_text=" - - CLONE localhost:/tmp/source.img ursa:/tmp/one_jfontan/0/hda.img - - - CLONE localhost:/tmp/source.img ursa:/tmp/one_jfontan/1/hda.img - - WRONG the program for WRONG does not exist - ERROR a command not in plugin - - " - - plugin=TMPlugin.new - plugin["OTHER"]="./tm_clone.sh" - plugin["CLONE"]="echo" - plugin["WRONG"]="it_does_not_exist" - - scr=TMScript.new(script_text, log_proc) - pp scr.lines - - - scr.execute(plugin) -end From b6ae3bce87be24acd82f954b0bf7ac48069658f3 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 28 Feb 2012 00:12:36 +0100 Subject: [PATCH 068/217] feature #1112: minor fixes for the datastore driver --- src/datastore_mad/one_datastore | 6 ------ src/datastore_mad/one_datastore.rb | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/datastore_mad/one_datastore b/src/datastore_mad/one_datastore index 9f62176cf8..ba5653805b 100755 --- a/src/datastore_mad/one_datastore +++ b/src/datastore_mad/one_datastore @@ -20,21 +20,15 @@ DRIVER_NAME=`basename $0 | cut -d. -f1` if [ -z "${ONE_LOCATION}" ]; then - DRIVERRC=/etc/one/${DRIVER_NAME}/${DRIVER_NAME}rc MADCOMMON=/usr/lib/one/mads/madcommon.sh VAR_LOCATION=/var/lib/one else - DRIVERRC=$ONE_LOCATION/etc/${DRIVER_NAME}/${DRIVER_NAME}rc MADCOMMON=$ONE_LOCATION/lib/mads/madcommon.sh VAR_LOCATION=$ONE_LOCATION/var fi . $MADCOMMON -# Export the im_mad specific rc - -export_rc_vars $DRIVERRC - # Go to var directory ONE_LOCATION/var or /var/lib/one cd $VAR_LOCATION diff --git a/src/datastore_mad/one_datastore.rb b/src/datastore_mad/one_datastore.rb index dc00fcb5a4..acbef1839c 100755 --- a/src/datastore_mad/one_datastore.rb +++ b/src/datastore_mad/one_datastore.rb @@ -119,7 +119,7 @@ class DatastoreDriver < OpenNebulaDriver end def do_image_action(id, ds, action, arguments) - return if not is_available?(ds,id,:mv) + return if not is_available?(ds,id,action) path = File.join(@local_scripts_path, ds) cmd = File.join(path, ACTION[action].downcase) From f9e18cb569240b40e9f06a5a74e8f50ce5800a6e Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 28 Feb 2012 00:13:34 +0100 Subject: [PATCH 069/217] feature #1112: Adapt TM driver to the new protocol --- src/tm_mad/one_tm | 6 -- src/tm_mad/one_tm.rb | 154 ++++++++++++++++++++++++++++++++----------- 2 files changed, 115 insertions(+), 45 deletions(-) diff --git a/src/tm_mad/one_tm b/src/tm_mad/one_tm index 0144d09498..d1da2965b1 100755 --- a/src/tm_mad/one_tm +++ b/src/tm_mad/one_tm @@ -19,21 +19,15 @@ DRIVER_NAME=`basename $1 | cut -d. -f1` if [ -z "${ONE_LOCATION}" ]; then - DRIVERRC=/etc/one/${DRIVER_NAME}/${DRIVER_NAME}rc MADCOMMON=/usr/lib/one/mads/madcommon.sh VAR_LOCATION=/var/lib/one else - DRIVERRC=$ONE_LOCATION/etc/${DRIVER_NAME}/${DRIVER_NAME}rc MADCOMMON=$ONE_LOCATION/lib/mads/madcommon.sh VAR_LOCATION=$ONE_LOCATION/var fi . $MADCOMMON -# Export the im_mad specific rc - -export_rc_vars $DRIVERRC - # Go to ONE_LOCATION cd $VAR_LOCATION diff --git a/src/tm_mad/one_tm.rb b/src/tm_mad/one_tm.rb index 1791d112d6..a6dafe47a9 100755 --- a/src/tm_mad/one_tm.rb +++ b/src/tm_mad/one_tm.rb @@ -31,64 +31,140 @@ $: << RUBY_LIB_LOCATION require 'pp' require 'OpenNebulaDriver' require 'CommandManager' -require 'TMScript' +require 'getoptlong' +# This class provides basic messaging and logging functionality to implement +# TransferManager Drivers. A TransferManager driver is a program (or a set of) +# that specialize the OpenNebula behavior to distribute disk images in a +# specific datastore to the hosts +class TransferManagerDriver < OpenNebulaDriver -class TransferManager < OpenNebulaDriver - - def initialize(plugin, options={}) + # Register TRANSFER action, and tm drivers available + # @param tm_type [Array] of tm types + # @param options [Hash] basic options for an OpenNebula driver + def initialize(tm_type, options={}) @options={ - :threaded => true + :concurrency => 15, + :threaded => true, + :retries => 0 }.merge!(options) - super('', @options) + super('tm/', @options) - @plugin=plugin + if tm_type == nil + @types = Dir["#{@local_scripts_path}/*/"].map do |d| + d.split('/')[-1] + end + elsif tm_type.class == String + @types = [tm_type] + else + @types = tm_type + end # register actions register_action(:TRANSFER, method("action_transfer")) end - def action_transfer(number, script_file) - script_text="" + # Driver Action: TRANSFER id script_file + # Executes a transfer script + def action_transfer(id, script_file) - if File.exist?(script_file) - open(script_file) {|f| - script_text=f.read - } + script = parse_script(script_file) - script=TMScript.new(script_text, log_method(number)) - res=script.execute(@plugin) - - if res[0] - send_message("TRANSFER", RESULT[:success], number) - else - send_message("TRANSFER", RESULT[:failure], number, res[1]) - end - else - send_message("TRANSFER", RESULT[:failure], number, - "Transfer file not found: #{script_file}") + if script.nil? + send_message("TRANSFER", + RESULT[:failure], + id, + "Transfer file '#{script_file}' does not exist") + return end + + script.each { |command| + result, info = do_transfer_action(id, command) + + if result == RESULT[:failure] + send_message("TRANSFER", result, id, info) + break + end + } + + send_message("TRANSFER", RESULT[:success], id) end + private + + # Parse a script file + # @param sfile [String] path to the transfer script + # @return lines [Array] with the commands of the script. Each command is an + # array itself. + def parse_script(sfile) + return nil if !File.exist?(sfile) + + stext = File.read(sfile) + lines = Array.new + + stext.each_line {|line| + next if line.match(/^\s*#/) # skip if the line is commented + next if line.match(/^\s*$/) # skip if the line is empty + + command = line.split(" ") + + lines << command + } + + return lines + end + + # Executes a single transfer action (command), as returned by the parse + # method + # @param id [String] with the OpenNebula ID for the TRANSFER action + # @param command [Array] + def do_transfer_action(id, command) + cmd = command[0].downcase + tm = command[1] + args = command[2..-1].join(" ") + + if not @types.include?(tm) + return RESULT[:failure], "Transfer Driver '#{tm}' not available" + end + + path = File.join(@local_scripts_path, tm, cmd) + path << " " << arguments + + rc = LocalCommand.run(path, log_method(id)) + + result, info = get_info_from_execution(rc) + + return result, info + end end -tm_conf=ARGV[0] +################################################################################ +################################################################################ +# TransferManager Driver Main program +################################################################################ +################################################################################ -if !tm_conf - puts "You need to specify config file." +opts = GetoptLong.new( + [ '--threads', '-t', GetoptLong::OPTIONAL_ARGUMENT ], + [ '--tm-types', '-d', GetoptLong::OPTIONAL_ARGUMENT ] +) + +tm_type = nil +threads = 15 + +begin + opts.each do |opt, arg| + case opt + when '--threads' + threads = arg.to_i + when '--tm-types' + tm_type = arg.split(',').map {|a| a.strip } + end + end +rescue Exception => e exit(-1) end -tm_conf=ETC_LOCATION+tm_conf if tm_conf[0] != ?/ - -plugin=TMPlugin.new(tm_conf) - -tm=TransferManager.new(plugin, - :concurrency => 15) - -tm.start_driver - - - - +tm_driver = TransferManagerDriver.new(tm_type, :concurrency => threads) +tm_driver.start_driver From dd51ce11bfd5999614f8363563d4e0352e6a3578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 28 Feb 2012 12:17:33 +0100 Subject: [PATCH 070/217] Feature #1112: Associate Datastores to Clusters --- include/Datastore.h | 9 +++- include/DatastorePool.h | 6 ++- include/RequestManagerCluster.h | 44 ++++++++++++++++++- src/cli/one_helper/onecluster_helper.rb | 10 ++++- src/cli/onecluster | 10 +++++ src/datastore/Datastore.cc | 12 +++++- src/datastore/DatastorePool.cc | 50 ++++++++++++++++++---- src/nebula/Nebula.cc | 4 +- src/oca/ruby/OpenNebula/Cluster.rb | 56 +++++++++++++++++++++---- src/rm/RequestManager.cc | 2 + src/rm/RequestManagerAllocate.cc | 8 +++- 11 files changed, 183 insertions(+), 28 deletions(-) diff --git a/include/Datastore.h b/include/Datastore.h index c99ae31ddb..bb4acbbf3a 100644 --- a/include/Datastore.h +++ b/include/Datastore.h @@ -20,11 +20,12 @@ #include "PoolSQL.h" #include "ObjectCollection.h" #include "DatastoreTemplate.h" +#include "Clusterable.h" /** * The Datastore class. */ -class Datastore : public PoolObjectSQL, ObjectCollection +class Datastore : public PoolObjectSQL, ObjectCollection, public Clusterable { public: @@ -121,7 +122,11 @@ private: // Constructor // ************************************************************************* - Datastore(int id, DatastoreTemplate* ds_template); + Datastore( + int id, + DatastoreTemplate* ds_template, + int cluster_id, + const string& cluster_name); virtual ~Datastore(){}; diff --git a/include/DatastorePool.h b/include/DatastorePool.h index e3cc6420fa..395cea46e6 100644 --- a/include/DatastorePool.h +++ b/include/DatastorePool.h @@ -63,12 +63,16 @@ public: * allocated for the object. * @param ds_template Datastore definition template * @param oid the id assigned to the Datastore + * @param cluster_id the id of the cluster this Datastore will belong to + * @param cluster_name the name of the cluster this Datastore will belong to * @param error_str Returns the error reason, if any * * @return the oid assigned to the object, -1 in case of failure */ int allocate(DatastoreTemplate * ds_template, int * oid, + int cluster_id, + const string& cluster_name, string& error_str); /** @@ -159,7 +163,7 @@ private: */ PoolObjectSQL * create() { - return new Datastore(-1, 0); + return new Datastore(-1, 0, -1, ""); }; }; diff --git a/include/RequestManagerCluster.h b/include/RequestManagerCluster.h index dfa8aebefa..4e1dc04fec 100644 --- a/include/RequestManagerCluster.h +++ b/include/RequestManagerCluster.h @@ -37,6 +37,7 @@ protected: Nebula& nd = Nebula::instance(); clpool = nd.get_clpool(); hpool = nd.get_hpool(); + dspool = nd.get_dspool(); auth_object = PoolObjectSQL::CLUSTER; auth_op = AuthRequest::MANAGE; @@ -46,8 +47,9 @@ protected: /* --------------------------------------------------------------------- */ - ClusterPool * clpool; - HostPool * hpool; + ClusterPool * clpool; + HostPool * hpool; + DatastorePool * dspool; /* --------------------------------------------------------------------- */ @@ -112,6 +114,44 @@ public: }; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ClusterAddDatastore : public RequestManagerCluster +{ +public: + ClusterAddDatastore(): + RequestManagerCluster("ClusterAddDatastore", + "Adds a datastore to the cluster", + "A:sii"){}; + + ~ClusterAddDatastore(){}; + + void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att) + { + return add_generic(_paramList, att, dspool, PoolObjectSQL::DATASTORE); + } + + virtual int add_object(Cluster* cluster, int id, string& error_msg) + { + return cluster->add_datastore(id, error_msg); + }; + + virtual int del_object(Cluster* cluster, int id, string& error_msg) + { + return cluster->del_datastore(id, error_msg); + }; + + virtual void get(int oid, bool lock, PoolObjectSQL ** object, Clusterable ** cluster_obj) + { + Datastore * ds = dspool->get(oid, lock); + + *object = static_cast(ds); + *cluster_obj = static_cast(ds); + }; +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/cli/one_helper/onecluster_helper.rb b/src/cli/one_helper/onecluster_helper.rb index 087ef5d507..bc72c25193 100644 --- a/src/cli/one_helper/onecluster_helper.rb +++ b/src/cli/one_helper/onecluster_helper.rb @@ -67,10 +67,16 @@ class OneClusterHelper < OpenNebulaHelper::OneHelper puts str % ["NAME", cluster.name] puts - CLIHelper.print_header(str_h1 % "HOSTS", false) - CLIHelper.print_header("%-15s" % ["ID"]) + CLIHelper.print_header("%-15s" % ["HOSTS"]) cluster.host_ids.each do |id| puts "%-15s" % [id] end + + puts + CLIHelper.print_header("%-15s" % ["DATASTORES"]) + cluster.datastore_ids.each do |id| + puts "%-15s" % [id] + end + end end diff --git a/src/cli/onecluster b/src/cli/onecluster index 7c04cc566d..f74837f06f 100755 --- a/src/cli/onecluster +++ b/src/cli/onecluster @@ -107,4 +107,14 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end + adddatastore_desc = <<-EOT.unindent + Adds a Datastore to the given Cluster + EOT + + # TODO: allow the second param to be [:range, :datastoreid_list] + command :adddatastore, adddatastore_desc,:clusterid, :datastoreid do + helper.perform_actions(args[0],options,"updated") do |cluster| + cluster.adddatastore(args[1].to_i) + end + end end diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index a6bfe8e1ea..159dab849b 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -34,9 +34,12 @@ const char * Datastore::db_bootstrap = /* ************************************************************************ */ Datastore::Datastore(int id, - DatastoreTemplate* ds_template): + DatastoreTemplate* ds_template, + int cluster_id, + const string& cluster_name): PoolObjectSQL(id,DATASTORE,"",-1,-1,"","",table), ObjectCollection("IMAGES"), + Clusterable(cluster_id, cluster_name), type(""), tm_mad(""), base_path("") @@ -235,7 +238,9 @@ string& Datastore::to_xml(string& xml) const "" << name << "" << "" << type << "" << "" << tm_mad << "" << - "" << base_path << "" << + "" << base_path << "" << + "" << cluster_id << "" << + "" << cluster << "" << collection_xml << ""; @@ -262,6 +267,9 @@ int Datastore::from_xml(const string& xml) rc += xpath(tm_mad, "/DATASTORE/TM_MAD", "not_found"); rc += xpath(base_path, "/DATASTORE/BASE_PATH", "not_found"); + rc += xpath(cluster_id, "/DATASTORE/CLUSTER_ID", -1); + rc += xpath(cluster, "/DATASTORE/CLUSTER", "not_found"); + // Set the owner and group to oneadmin set_user(0, ""); set_group(GroupPool::ONEADMIN_ID, GroupPool::ONEADMIN_NAME); diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index 7812eecc79..0981c4e64f 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -43,8 +43,7 @@ DatastorePool::DatastorePool(SqlDB * db): if (get_lastOID() == -1) //lastOID is set in PoolSQL::init_cb { - int rc; - Datastore * ds; + int rc; DatastoreTemplate * ds_tmpl; // --------------------------------------------------------------------- @@ -64,9 +63,11 @@ DatastorePool::DatastorePool(SqlDB * db): goto error_bootstrap; } - ds = new Datastore(-1, ds_tmpl); - - rc = PoolSQL::allocate(ds, error_str); + allocate(ds_tmpl, + &rc, + ClusterPool::DEFAULT_CLUSTER_ID, + ClusterPool::DEFAULT_CLUSTER_NAME, + error_str); if( rc < 0 ) { @@ -91,9 +92,11 @@ DatastorePool::DatastorePool(SqlDB * db): goto error_bootstrap; } - ds = new Datastore(-1, ds_tmpl); - - rc = PoolSQL::allocate(ds, error_str); + allocate(ds_tmpl, + &rc, + ClusterPool::DEFAULT_CLUSTER_ID, + ClusterPool::DEFAULT_CLUSTER_NAME, + error_str); if( rc < 0 ) { @@ -118,6 +121,8 @@ error_bootstrap: int DatastorePool::allocate(DatastoreTemplate * ds_template, int * oid, + int cluster_id, + const string& cluster_name, string& error_str) { Datastore * ds; @@ -125,7 +130,11 @@ int DatastorePool::allocate(DatastoreTemplate * ds_template, string name; ostringstream oss; - ds = new Datastore(-1, ds_template); + Nebula& nd = Nebula::instance(); + ClusterPool * clpool; + Cluster * cluster; + + ds = new Datastore(-1, ds_template, cluster_id, cluster_name); // ------------------------------------------------------------------------- // Check name & duplicates @@ -152,6 +161,29 @@ int DatastorePool::allocate(DatastoreTemplate * ds_template, *oid = PoolSQL::allocate(ds, error_str); + if ( *oid < 0 ) + { + return *oid; + } + + // Add to Cluster + clpool = nd.get_clpool(); + cluster = clpool->get(cluster_id, true); + + if( cluster == 0 ) + { + return -1; + } + + if ( cluster->add_datastore(*oid, error_str) < 0 ) + { + return -1; + } + + clpool->update(cluster); + + cluster->unlock(); + return *oid; error_name: diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index cb424a74e9..3d279aba54 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -281,6 +281,8 @@ void Nebula::start() vector vm_restricted_attrs; vector img_restricted_attrs; + clpool = new ClusterPool(db); + nebula_configuration->get("VM_HOOK", vm_hooks); nebula_configuration->get("HOST_HOOK", host_hooks); @@ -315,8 +317,6 @@ void Nebula::start() tpool = new VMTemplatePool(db); dspool = new DatastorePool(db); - - clpool = new ClusterPool(db); } catch (exception&) { diff --git a/src/oca/ruby/OpenNebula/Cluster.rb b/src/oca/ruby/OpenNebula/Cluster.rb index 8cb0d1793f..70888465b4 100644 --- a/src/oca/ruby/OpenNebula/Cluster.rb +++ b/src/oca/ruby/OpenNebula/Cluster.rb @@ -24,10 +24,11 @@ module OpenNebula ####################################################################### CLUSTER_METHODS = { - :info => "cluster.info", - :allocate => "cluster.allocate", - :delete => "cluster.delete", - :addhost => "cluster.addhost" + :info => "cluster.info", + :allocate => "cluster.allocate", + :delete => "cluster.delete", + :addhost => "cluster.addhost", + :adddatastore => "cluster.adddatastore" } # Creates a Cluster description with just its identifier @@ -75,6 +76,8 @@ module OpenNebula # Adds a Host to this Cluster # @param hid [Integer] Host ID + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise def addhost(hid) return Error.new('ID not defined') if !@pe_id @@ -84,20 +87,36 @@ module OpenNebula return rc end + # Adds a Datastore to this Cluster + # @param ds_id [Integer] Datastore ID + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def adddatastore(ds_id) + return Error.new('ID not defined') if !@pe_id + + rc = @client.call(CLUSTER_METHODS[:adddatastore], @pe_id, ds_id) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + # --------------------------------------------------------------------- # Helpers to get information # --------------------------------------------------------------------- - # Returns whether or not the host with id 'uid' is part of this group - def contains(uid) + # Returns whether or not the host with 'id' is part of this cluster + # @param id [Integer] host ID + # @return [Boolean] true if found + def contains_host(id) #This doesn't work in ruby 1.8.5 #return self["HOSTS/ID[.=#{uid}]"] != nil id_array = retrieve_elements('HOSTS/ID') - return id_array != nil && id_array.include?(uid.to_s) + return id_array != nil && id_array.include?(id.to_s) end # Returns an array with the numeric host ids + # @return [Array] def host_ids array = Array.new @@ -107,5 +126,28 @@ module OpenNebula return array end + + # Returns whether or not the datastore with 'id' is part of this cluster + # @param id [Integer] datastore ID + # @return [Boolean] true if found + def contains_datastore(id) + #This doesn't work in ruby 1.8.5 + #return self["DATASTORES/ID[.=#{uid}]"] != nil + + id_array = retrieve_elements('DATASTORES/ID') + return id_array != nil && id_array.include?(id.to_s) + end + + # Returns an array with the numeric datastore ids + # @return [Array] + def datastore_ids + array = Array.new + + self.each("DATASTORES/ID") do |id| + array << id.text.to_i + end + + return array + end end end diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index c1085d2263..81122d3dfd 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -327,6 +327,7 @@ void RequestManager::register_xml_methods() // Cluster Methods xmlrpc_c::methodPtr cluster_addhost(new ClusterAddHost()); + xmlrpc_c::methodPtr cluster_addds(new ClusterAddDatastore()); /* VM related methods */ RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy); @@ -422,6 +423,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.cluster.delete", cluster_delete); RequestManagerRegistry.addMethod("one.cluster.info", cluster_info); RequestManagerRegistry.addMethod("one.cluster.addhost", cluster_addhost); + RequestManagerRegistry.addMethod("one.cluster.adddatastore", cluster_addds); RequestManagerRegistry.addMethod("one.clusterpool.info",clusterpool_info); }; diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 2324b06cad..b049568133 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -391,7 +391,13 @@ int DatastoreAllocate::pool_allocate( DatastoreTemplate * ds_tmpl = static_cast(tmpl); - return dspool->allocate(ds_tmpl, &id, error_str); + // TODO: include another int parameter for the cluster? + int cluster_id = ClusterPool::DEFAULT_CLUSTER_ID; + string cluster_name = ClusterPool::DEFAULT_CLUSTER_NAME; + + // TODO: Add to auth request CLUSTER MANAGE or ADMIN + + return dspool->allocate(ds_tmpl, &id, cluster_id, cluster_name, error_str); } /* -------------------------------------------------------------------------- */ From 98fcd42e2b24fb9ff7b8cd0647c753ecd03deb9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 28 Feb 2012 15:29:32 +0100 Subject: [PATCH 071/217] Feature #1112: Integrate clusters into acl rules --- include/RequestManagerCluster.h | 2 +- src/acl/AclManager.cc | 7 ++++--- src/acl/AclRule.cc | 5 +++-- src/cli/etc/oneacl.yaml | 6 +++--- src/cli/one_helper/oneacl_helper.rb | 10 ++++++---- src/oca/ruby/OpenNebula/Acl.rb | 3 ++- src/rm/RequestManagerCluster.cc | 2 +- 7 files changed, 20 insertions(+), 15 deletions(-) diff --git a/include/RequestManagerCluster.h b/include/RequestManagerCluster.h index 4e1dc04fec..94958600d7 100644 --- a/include/RequestManagerCluster.h +++ b/include/RequestManagerCluster.h @@ -40,7 +40,7 @@ protected: dspool = nd.get_dspool(); auth_object = PoolObjectSQL::CLUSTER; - auth_op = AuthRequest::MANAGE; + auth_op = AuthRequest::ADMIN; }; ~RequestManagerCluster(){}; diff --git a/src/acl/AclManager.cc b/src/acl/AclManager.cc index 38d5e4886a..0fe8664fcd 100644 --- a/src/acl/AclManager.cc +++ b/src/acl/AclManager.cc @@ -88,11 +88,12 @@ AclManager::AclManager(SqlDB * _db) : db(_db), lastOID(-1) AuthRequest::MANAGE, error_str); - // Users in USERS can use any DATASTORE - // @1 DATASTORE/* USE + // Users in USERS can use the default DATASTORE + // @1 DATASTORE/#1 USE add_rule(AclRule::GROUP_ID | 1, - AclRule::ALL_ID | + AclRule::INDIVIDUAL_ID | + 1 | // TODO: use DatastorePool::DEFAULT_DS_ID PoolObjectSQL::DATASTORE, AuthRequest::USE, error_str); diff --git a/src/acl/AclRule.cc b/src/acl/AclRule.cc index 1a941d3818..e65a1071e2 100644 --- a/src/acl/AclRule.cc +++ b/src/acl/AclRule.cc @@ -254,12 +254,13 @@ void AclRule::build_str() PoolObjectSQL::USER, PoolObjectSQL::TEMPLATE, PoolObjectSQL::GROUP, - PoolObjectSQL::DATASTORE + PoolObjectSQL::DATASTORE, + PoolObjectSQL::CLUSTER }; bool prefix = false; - for ( int i = 0; i < 8; i++ ) + for ( int i = 0; i < 9; i++ ) { if ( (resource & objects[i]) != 0 ) { diff --git a/src/cli/etc/oneacl.yaml b/src/cli/etc/oneacl.yaml index 170942867b..220671a5fd 100644 --- a/src/cli/etc/oneacl.yaml +++ b/src/cli/etc/oneacl.yaml @@ -9,9 +9,9 @@ :size: 8 :right: true -:RES_VHNIUTGD: +:RES_VHNIUTGDC: :desc: Which resource the rule applies to - :size: 12 + :size: 13 :RID: :desc: Resource ID @@ -26,6 +26,6 @@ :default: - :ID - :USER -- :RES_VHNIUTGD +- :RES_VHNIUTGDC - :RID - :OPE_UMAC diff --git a/src/cli/one_helper/oneacl_helper.rb b/src/cli/one_helper/oneacl_helper.rb index 90445607a8..fbd4030c1c 100644 --- a/src/cli/one_helper/oneacl_helper.rb +++ b/src/cli/one_helper/oneacl_helper.rb @@ -44,7 +44,7 @@ private def self.resource_mask(str) resource_type=str.split("/")[0] - mask = "--------" + mask = "---------" resource_type.split("+").each{|type| case type @@ -64,6 +64,8 @@ private mask[6] = "G" when "DATASTORE" mask[7] = "D" + when "CLUSTER" + mask[8] = "C" end } mask @@ -103,8 +105,8 @@ private d['STRING'].split(" ")[0] end - column :RES_VHNIUTGD, "Resource to which the rule applies", - :size => 12 do |d| + column :RES_VHNIUTGDC, "Resource to which the rule applies", + :size => 13 do |d| OneAclHelper::resource_mask d['STRING'].split(" ")[1] end @@ -117,7 +119,7 @@ private OneAclHelper::right_mask d['STRING'].split(" ")[2] end - default :ID, :USER, :RES_VHNIUTGD, :RID, :OPE_UMAC + default :ID, :USER, :RES_VHNIUTGDC, :RID, :OPE_UMAC end table diff --git a/src/oca/ruby/OpenNebula/Acl.rb b/src/oca/ruby/OpenNebula/Acl.rb index 484bcc8beb..de423a1627 100644 --- a/src/oca/ruby/OpenNebula/Acl.rb +++ b/src/oca/ruby/OpenNebula/Acl.rb @@ -53,7 +53,8 @@ module OpenNebula "USER" => 0x10000000000, "TEMPLATE" => 0x20000000000, "GROUP" => 0x40000000000, - "DATASTORE" => 0x100000000000 + "DATASTORE" => 0x100000000000, + "CLUSTER" => 0x200000000000 } RIGHTS = diff --git a/src/rm/RequestManagerCluster.cc b/src/rm/RequestManagerCluster.cc index 0f2cd79709..91584334ea 100644 --- a/src/rm/RequestManagerCluster.cc +++ b/src/rm/RequestManagerCluster.cc @@ -94,7 +94,7 @@ void RequestManagerCluster::add_generic( { AuthRequest ar(att.uid, att.gid); - ar.add_auth(auth_op, c_perms); // MANAGE CLUSTER + ar.add_auth(auth_op, c_perms); // ADMIN CLUSTER ar.add_auth(AuthRequest::ADMIN, obj_perms); // ADMIN OBJECT if (UserPool::authorize(ar) == -1) From f2124cd26b0064f0bda42dab9d373e3f1ea6e138 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 28 Feb 2012 17:06:37 +0100 Subject: [PATCH 072/217] feature #1112: Move default and system datastore to var_location/datastores. Create directories a --- install.sh | 8 ++++---- src/datastore/DatastorePool.cc | 27 ++++++++++++++++----------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/install.sh b/install.sh index 7feb9e8268..6382cd1023 100755 --- a/install.sh +++ b/install.sh @@ -99,8 +99,8 @@ if [ -z "$ROOT" ] ; then VAR_LOCATION="/var/lib/one" SUNSTONE_LOCATION="$LIB_LOCATION/sunstone" OZONES_LOCATION="$LIB_LOCATION/ozones" - SYSTEM_DS_LOCATION="$VAR_LOCATION/system_ds" - DEFAULT_DS_LOCATION="$VAR_LOCATION/default_ds" + SYSTEM_DS_LOCATION="$VAR_LOCATION/datastores/system" + DEFAULT_DS_LOCATION="$VAR_LOCATION/datastores/default" RUN_LOCATION="/var/run/one" LOCK_LOCATION="/var/lock/one" INCLUDE_LOCATION="/usr/include" @@ -146,8 +146,8 @@ else VAR_LOCATION="$ROOT/var" SUNSTONE_LOCATION="$LIB_LOCATION/sunstone" OZONES_LOCATION="$LIB_LOCATION/ozones" - SYSTEM_DS_LOCATION="$VAR_LOCATION/system_ds" - DEFAULT_DS_LOCATION="$VAR_LOCATION/default_ds" + SYSTEM_DS_LOCATION="$VAR_LOCATION/datastores/system" + DEFAULT_DS_LOCATION="$VAR_LOCATION/datastores/default" INCLUDE_LOCATION="$ROOT/include" SHARE_LOCATION="$ROOT/share" MAN_LOCATION="$ROOT/share/man/man1" diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index 0981c4e64f..968ea4f3f3 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -26,10 +26,10 @@ /* from ID 100 */ /* -------------------------------------------------------------------------- */ -const string DatastorePool::SYSTEM_DS_NAME = "system_ds"; +const string DatastorePool::SYSTEM_DS_NAME = "system"; const int DatastorePool::SYSTEM_DS_ID = 0; -const string DatastorePool::DEFAULT_DS_NAME = "default_ds"; +const string DatastorePool::DEFAULT_DS_NAME = "default"; const int DatastorePool::DEFAULT_DS_ID = 1; /* -------------------------------------------------------------------------- */ @@ -43,17 +43,22 @@ DatastorePool::DatastorePool(SqlDB * db): if (get_lastOID() == -1) //lastOID is set in PoolSQL::init_cb { - int rc; DatastoreTemplate * ds_tmpl; + int rc; + string base_path; + Nebula& nd = Nebula::instance(); + + base_path = nd.get_var_location() + "datastores/"; + // --------------------------------------------------------------------- // Create the system datastore // --------------------------------------------------------------------- - oss << "NAME = " << SYSTEM_DS_NAME << endl - << "BASE_PATH = /var/lib/one/system_ds" << endl - << "TYPE = fs" << endl - << "TM_MAD = tm_shared"; + oss << "NAME = " << SYSTEM_DS_NAME << endl + << "BASE_PATH = " << base_path << "system"<< endl + << "TYPE = fs" << endl + << "TM_MAD = tm_shared"; ds_tmpl = new DatastoreTemplate; rc = ds_tmpl->parse_str_or_xml(oss.str(), error_str); @@ -79,10 +84,10 @@ DatastorePool::DatastorePool(SqlDB * db): // --------------------------------------------------------------------- oss.str(""); - oss << "NAME = " << DEFAULT_DS_NAME << endl - << "BASE_PATH = /var/lib/one/default_ds" << endl - << "TYPE = fs" << endl - << "TM_MAD = tm_shared"; + oss << "NAME = " << DEFAULT_DS_NAME << endl + << "BASE_PATH = " << base_path << "default" << endl + << "TYPE = fs" << endl + << "TM_MAD = tm_shared"; ds_tmpl = new DatastoreTemplate; rc = ds_tmpl->parse_str_or_xml(oss.str(), error_str); From c8d1af5e8af9acdf77389f880044baef4115e59c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 28 Feb 2012 17:25:02 +0100 Subject: [PATCH 073/217] Feature #1112: Remove host from its cluster when it is deleted --- include/RequestManagerDelete.h | 4 ++++ src/rm/RequestManagerDelete.cc | 37 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/include/RequestManagerDelete.h b/include/RequestManagerDelete.h index 037b29dd2e..32c2896220 100644 --- a/include/RequestManagerDelete.h +++ b/include/RequestManagerDelete.h @@ -135,6 +135,10 @@ public: }; ~HostDelete(){}; + + /* -------------------------------------------------------------------- */ + + int drop(int oid, PoolObjectSQL * object, string& error_msg); }; /* ------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerDelete.cc b/src/rm/RequestManagerDelete.cc index 9c56df8de5..c6a0f627cc 100644 --- a/src/rm/RequestManagerDelete.cc +++ b/src/rm/RequestManagerDelete.cc @@ -153,6 +153,43 @@ int ImageDelete::drop(int oid, PoolObjectSQL * object, string& error_msg) /* ------------------------------------------------------------------------- */ +int HostDelete::drop(int oid, PoolObjectSQL * object, string& error_msg) +{ + Host * host = static_cast(object); + int cluster_id = host->get_cluster_id(); + + int rc = pool->drop(object, error_msg); + + object->unlock(); + + if ( rc == 0 ) + { + Nebula& nd = Nebula::instance(); + ClusterPool * clpool = nd.get_clpool(); + + Cluster * cluster = clpool->get(cluster_id, true); + + if( cluster != 0 ) + { + rc = cluster->del_host(oid, error_msg); + + if ( rc < 0 ) + { + cluster->unlock(); + return rc; + } + + clpool->update(cluster); + + cluster->unlock(); + } + } + + return rc; +} + +/* ------------------------------------------------------------------------- */ + int UserDelete::drop(int oid, PoolObjectSQL * object, string& error_msg) { User * user = static_cast(object); From f722dafb438189bc6fe5bcd32a3aed9c89b9abf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 28 Feb 2012 17:30:07 +0100 Subject: [PATCH 074/217] Feature #1112: Make cluster parameter mandatory for new hosts --- include/RequestManagerAllocate.h | 11 ++-- src/cli/onehost | 8 ++- src/oca/ruby/OpenNebula/ClusterPool.rb | 2 + src/oca/ruby/OpenNebula/Host.rb | 5 +- src/rm/RequestManagerAllocate.cc | 77 ++++++++++++++++++++++---- 5 files changed, 81 insertions(+), 22 deletions(-) diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index 1249407a73..d22e0d52be 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -207,7 +207,7 @@ public: HostAllocate(): RequestManagerAllocate("HostAllocate", "Allocates a new host", - "A:sssss", + "A:sssssi", false) { Nebula& nd = Nebula::instance(); @@ -217,11 +217,10 @@ public: ~HostAllocate(){}; - int pool_allocate(xmlrpc_c::paramList const& _paramList, - Template * tmpl, - int& id, - string& error_str, - RequestAttributes& att); + /* --------------------------------------------------------------------- */ + + void request_execute(xmlrpc_c::paramList const& paramList, + RequestAttributes& att); }; /* ------------------------------------------------------------------------- */ diff --git a/src/cli/onehost b/src/cli/onehost index 115e2f7098..9da4453de8 100755 --- a/src/cli/onehost +++ b/src/cli/onehost @@ -61,9 +61,13 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :create, create_desc, :hostname, :im_mad, :vmm_mad, - :vnm_mad do + :vnm_mad, [:clusterid, nil] do helper.create_resource(options) do |host| - host.allocate(args[0], args[1], args[2], args[3]) + if args[4] + host.allocate(args[0], args[1], args[2], args[3]) + else + host.allocate(args[0], args[1], args[2], args[3], args[4].to_i) + end end end diff --git a/src/oca/ruby/OpenNebula/ClusterPool.rb b/src/oca/ruby/OpenNebula/ClusterPool.rb index 8885c399c7..b080514628 100644 --- a/src/oca/ruby/OpenNebula/ClusterPool.rb +++ b/src/oca/ruby/OpenNebula/ClusterPool.rb @@ -23,6 +23,8 @@ module OpenNebula # Constants and Class attribute accessors ####################################################################### + DEFAULT_CLUSTER_ID = 0 + CLUSTER_POOL_METHODS = { :info => "clusterpool.info" } diff --git a/src/oca/ruby/OpenNebula/Host.rb b/src/oca/ruby/OpenNebula/Host.rb index 4a77bd2756..e869959396 100644 --- a/src/oca/ruby/OpenNebula/Host.rb +++ b/src/oca/ruby/OpenNebula/Host.rb @@ -82,11 +82,12 @@ module OpenNebula # @param im [String] Name of the im_driver (information/monitoring) # @param vmm [String] Name of the vmm_driver (hypervisor) # @param tm [String] Name of the vnm_driver (networking) + # @param cluster_id [Integer] Id of the cluster # # @return [Integer, OpenNebula::Error] the new ID in case of # success, error otherwise - def allocate(hostname,im,vmm,vnm) - super(HOST_METHODS[:allocate],hostname,im,vmm,vnm) + def allocate(hostname,im,vmm,vnm,cluster_id=ClusterPool::DEFAULT_CLUSTER_ID) + super(HOST_METHODS[:allocate],hostname,im,vmm,vnm,cluster_id) end # Deletes the Host diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index b049568133..53751545c9 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -306,27 +306,80 @@ int TemplateAllocate::pool_allocate(xmlrpc_c::paramList const& _paramList, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int HostAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, - Template * tmpl, - int& id, - string& error_str, - RequestAttributes& att) +void HostAllocate::request_execute( + xmlrpc_c::paramList const& paramList, + RequestAttributes& att) { + string error_str; + string cluster_name; + string ds_data; + int rc, id; + + PoolObjectAuth cluster_perms; + string host = xmlrpc_c::value_string(paramList.getString(1)); string im_mad = xmlrpc_c::value_string(paramList.getString(2)); string vmm_mad = xmlrpc_c::value_string(paramList.getString(3)); string vnm_mad = xmlrpc_c::value_string(paramList.getString(4)); + int cluster_id = xmlrpc_c::value_int(paramList.getInt(5)); - // TODO: include another int parameter for the cluster? - int cluster_id = ClusterPool::DEFAULT_CLUSTER_ID; - string cluster_name = ClusterPool::DEFAULT_CLUSTER_NAME; + Nebula& nd = Nebula::instance(); - // TODO: Add to auth request CLUSTER MANAGE or ADMIN + ClusterPool * clpool = nd.get_clpool(); + HostPool * hpool = static_cast(pool); - HostPool * hpool = static_cast(pool); + Cluster * cluster; - return hpool->allocate(&id, host, im_mad, vmm_mad, vnm_mad, - cluster_id, cluster_name, error_str); + // ------------------------- Check Cluster exists ------------------------ + + if ((cluster = clpool->get(cluster_id,true)) == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::CLUSTER), cluster_id), + att); + + return; + } + + cluster->get_permissions(cluster_perms); + + cluster_name = cluster->get_name(); + + cluster->unlock(); + + // ------------- Set authorization request for non-oneadmin's ------------- + + if ( att.uid != 0 ) + { + AuthRequest ar(att.uid, att.gid); + string tmpl_str = ""; + + ar.add_create_auth(auth_object, tmpl_str); // CREATE HOST + + ar.add_auth(AuthRequest::ADMIN, cluster_perms); // ADMIN CLUSTER + + if (UserPool::authorize(ar) == -1) + { + failure_response(AUTHORIZATION, + authorization_error(ar.message, att), + att); + + return; + } + } + + // ------------- Allocate Host -------------------------------------------- + + rc = hpool->allocate(&id, host, im_mad, vmm_mad, vnm_mad, + cluster_id, cluster_name, error_str); + + if ( rc < 0 ) + { + failure_response(INTERNAL, allocate_error(error_str), att); + return; + } + + success_response(id, att); } /* -------------------------------------------------------------------------- */ From 07eba81abd09fb648844a3740cae9d3cc01b4060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 28 Feb 2012 17:59:03 +0100 Subject: [PATCH 075/217] Feature #1112: refactor Request::get_info --- include/Request.h | 20 ++++++++++++++++++++ include/RequestManagerChown.h | 7 ------- include/RequestManagerCluster.h | 7 ------- src/rm/Request.cc | 28 ++++++++++++++++++++++++++++ src/rm/RequestManagerAllocate.cc | 18 ++---------------- src/rm/RequestManagerChown.cc | 27 --------------------------- src/rm/RequestManagerCluster.cc | 29 ----------------------------- 7 files changed, 50 insertions(+), 86 deletions(-) diff --git a/include/Request.h b/include/Request.h index 1078fd8898..9c479d97b6 100644 --- a/include/Request.h +++ b/include/Request.h @@ -219,6 +219,26 @@ protected: * @return string for logging */ string allocate_error (PoolObjectSQL::ObjectType obj, const string& error); + + /** + * Locks the requested object, gets information, and unlocks it + * + * @param pool object pool + * @param id of the object + * @param type of the object + * @param att the specific request attributes + * + * @param perms returns the object's permissions + * @param name returns the object's name + * + * @return 0 on success, -1 otherwise + */ + int get_info (PoolSQL * pool, + int id, + PoolObjectSQL::ObjectType type, + RequestAttributes& att, + PoolObjectAuth& perms, + string& name); }; /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerChown.h b/include/RequestManagerChown.h index 78569079e0..c0591bb36c 100644 --- a/include/RequestManagerChown.h +++ b/include/RequestManagerChown.h @@ -52,13 +52,6 @@ protected: virtual void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att); - - int get_info (PoolSQL * pool, - int id, - PoolObjectSQL::ObjectType type, - RequestAttributes& att, - PoolObjectAuth& perms, - string& name); }; /* ------------------------------------------------------------------------- */ diff --git a/include/RequestManagerCluster.h b/include/RequestManagerCluster.h index 94958600d7..c90cb124e4 100644 --- a/include/RequestManagerCluster.h +++ b/include/RequestManagerCluster.h @@ -67,13 +67,6 @@ protected: virtual int del_object(Cluster* cluster, int id, string& error_msg) = 0; virtual void get(int oid, bool lock, PoolObjectSQL ** object, Clusterable ** cluster_obj) = 0; - - int get_info (PoolSQL * pool, - int id, - PoolObjectSQL::ObjectType type, - RequestAttributes& att, - PoolObjectAuth& perms, - string& name); }; /* ------------------------------------------------------------------------- */ diff --git a/src/rm/Request.cc b/src/rm/Request.cc index cf50bec1ed..bd5b9a9f82 100644 --- a/src/rm/Request.cc +++ b/src/rm/Request.cc @@ -297,3 +297,31 @@ string Request::allocate_error (const string& error) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ + +int Request::get_info( + PoolSQL * pool, + int id, + PoolObjectSQL::ObjectType type, + RequestAttributes& att, + PoolObjectAuth& perms, + string& name) +{ + PoolObjectSQL * ob; + + if ((ob = pool->get(id,true)) == 0 ) + { + failure_response(NO_EXISTS, get_error(object_name(type), id), att); + return -1; + } + + ob->get_permissions(perms); + + name = ob->get_name(); + + ob->unlock(); + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 53751545c9..909bfcfcc4 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -328,24 +328,10 @@ void HostAllocate::request_execute( ClusterPool * clpool = nd.get_clpool(); HostPool * hpool = static_cast(pool); - Cluster * cluster; - // ------------------------- Check Cluster exists ------------------------ - if ((cluster = clpool->get(cluster_id,true)) == 0 ) - { - failure_response(NO_EXISTS, - get_error(object_name(PoolObjectSQL::CLUSTER), cluster_id), - att); - - return; - } - - cluster->get_permissions(cluster_perms); - - cluster_name = cluster->get_name(); - - cluster->unlock(); + get_info(clpool, cluster_id, PoolObjectSQL::CLUSTER, att, + cluster_perms, cluster_name); // ------------- Set authorization request for non-oneadmin's ------------- diff --git a/src/rm/RequestManagerChown.cc b/src/rm/RequestManagerChown.cc index 4ecbf9ee48..768a87c5e8 100644 --- a/src/rm/RequestManagerChown.cc +++ b/src/rm/RequestManagerChown.cc @@ -23,33 +23,6 @@ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int RequestManagerChown::get_info (PoolSQL * pool, - int id, - PoolObjectSQL::ObjectType type, - RequestAttributes& att, - PoolObjectAuth& perms, - string& name) -{ - PoolObjectSQL * ob; - - if ((ob = pool->get(id,true)) == 0 ) - { - failure_response(NO_EXISTS, get_error(object_name(type), id), att); - return -1; - } - - ob->get_permissions(perms); - - name = ob->get_name(); - - ob->unlock(); - - return 0; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - void RequestManagerChown::request_execute(xmlrpc_c::paramList const& paramList, RequestAttributes& att) { diff --git a/src/rm/RequestManagerCluster.cc b/src/rm/RequestManagerCluster.cc index 91584334ea..09089e110c 100644 --- a/src/rm/RequestManagerCluster.cc +++ b/src/rm/RequestManagerCluster.cc @@ -21,35 +21,6 @@ using namespace std; /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ -// TODO: same method in RequestManagerChown, should be moved to Request - -int RequestManagerCluster::get_info (PoolSQL * pool, - int id, - PoolObjectSQL::ObjectType type, - RequestAttributes& att, - PoolObjectAuth& perms, - string& name) -{ - PoolObjectSQL * ob; - - if ((ob = pool->get(id,true)) == 0 ) - { - failure_response(NO_EXISTS, get_error(object_name(type), id), att); - return -1; - } - - ob->get_permissions(perms); - - name = ob->get_name(); - - ob->unlock(); - - return 0; -} - -/* ------------------------------------------------------------------------- */ -/* ------------------------------------------------------------------------- */ - void RequestManagerCluster::add_generic( xmlrpc_c::paramList const& paramList, RequestAttributes& att, From 01f9641272dd89c6119f7980312b63a5a4223f8a Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 28 Feb 2012 22:52:48 +0100 Subject: [PATCH 076/217] feature #1112: Move tm action scripts to the new locations --- install.sh | 126 +++++++++---------- src/tm_mad/dummy/clone | 1 + src/tm_mad/dummy/context | 1 + src/tm_mad/dummy/delete | 1 + src/tm_mad/dummy/{tm_dummy.sh => dummy.sh} | 0 src/tm_mad/dummy/ln | 1 + src/tm_mad/dummy/mkimage | 1 + src/tm_mad/dummy/mkswap | 1 + src/tm_mad/dummy/mv | 1 + src/tm_mad/dummy/tm_dummy.conf | 23 ---- src/tm_mad/dummy/tm_dummyrc | 15 --- src/tm_mad/lvm/{tm_clone.sh => clone} | 0 src/tm_mad/lvm/{tm_context.sh => context} | 0 src/tm_mad/lvm/{tm_delete.sh => delete} | 0 src/tm_mad/lvm/{tm_ln.sh => ln} | 0 src/tm_mad/lvm/{tm_lvmrc => lvm.conf} | 0 src/tm_mad/lvm/{tm_mkimage.sh => mkimage} | 0 src/tm_mad/lvm/{tm_mkswap.sh => mkswap} | 0 src/tm_mad/lvm/{tm_mv.sh => mv} | 0 src/tm_mad/lvm/tm_lvm.conf | 23 ---- src/tm_mad/shared/{tm_clone.sh => clone} | 0 src/tm_mad/shared/{tm_context.sh => context} | 0 src/tm_mad/shared/{tm_delete.sh => delete} | 0 src/tm_mad/shared/{tm_ln.sh => ln} | 0 src/tm_mad/shared/{tm_mkimage.sh => mkimage} | 0 src/tm_mad/shared/{tm_mkswap.sh => mkswap} | 0 src/tm_mad/shared/{tm_mv.sh => mv} | 0 src/tm_mad/shared/tm_shared.conf | 23 ---- src/tm_mad/shared/tm_sharedrc | 15 --- src/tm_mad/ssh/{tm_clone.sh => clone} | 0 src/tm_mad/ssh/{tm_context.sh => context} | 0 src/tm_mad/ssh/{tm_delete.sh => delete} | 0 src/tm_mad/ssh/{tm_ln.sh => ln} | 0 src/tm_mad/ssh/{tm_mkimage.sh => mkimage} | 0 src/tm_mad/ssh/{tm_mkswap.sh => mkswap} | 0 src/tm_mad/ssh/{tm_mv.sh => mv} | 0 src/tm_mad/ssh/tm_ssh.conf | 23 ---- src/tm_mad/ssh/tm_sshrc | 15 --- src/tm_mad/vmware/{tm_clone.sh => clone} | 0 src/tm_mad/vmware/{tm_context.sh => context} | 0 src/tm_mad/vmware/{tm_ln.sh => ln} | 0 src/tm_mad/vmware/{tm_mv.sh => mv} | 0 src/tm_mad/vmware/tm_vmware.conf | 23 ---- 43 files changed, 64 insertions(+), 229 deletions(-) create mode 120000 src/tm_mad/dummy/clone create mode 120000 src/tm_mad/dummy/context create mode 120000 src/tm_mad/dummy/delete rename src/tm_mad/dummy/{tm_dummy.sh => dummy.sh} (100%) create mode 120000 src/tm_mad/dummy/ln create mode 120000 src/tm_mad/dummy/mkimage create mode 120000 src/tm_mad/dummy/mkswap create mode 120000 src/tm_mad/dummy/mv delete mode 100755 src/tm_mad/dummy/tm_dummy.conf delete mode 100644 src/tm_mad/dummy/tm_dummyrc rename src/tm_mad/lvm/{tm_clone.sh => clone} (100%) rename src/tm_mad/lvm/{tm_context.sh => context} (100%) rename src/tm_mad/lvm/{tm_delete.sh => delete} (100%) rename src/tm_mad/lvm/{tm_ln.sh => ln} (100%) rename src/tm_mad/lvm/{tm_lvmrc => lvm.conf} (100%) rename src/tm_mad/lvm/{tm_mkimage.sh => mkimage} (100%) rename src/tm_mad/lvm/{tm_mkswap.sh => mkswap} (100%) rename src/tm_mad/lvm/{tm_mv.sh => mv} (100%) delete mode 100755 src/tm_mad/lvm/tm_lvm.conf rename src/tm_mad/shared/{tm_clone.sh => clone} (100%) rename src/tm_mad/shared/{tm_context.sh => context} (100%) rename src/tm_mad/shared/{tm_delete.sh => delete} (100%) rename src/tm_mad/shared/{tm_ln.sh => ln} (100%) rename src/tm_mad/shared/{tm_mkimage.sh => mkimage} (100%) rename src/tm_mad/shared/{tm_mkswap.sh => mkswap} (100%) rename src/tm_mad/shared/{tm_mv.sh => mv} (100%) delete mode 100644 src/tm_mad/shared/tm_shared.conf delete mode 100644 src/tm_mad/shared/tm_sharedrc rename src/tm_mad/ssh/{tm_clone.sh => clone} (100%) rename src/tm_mad/ssh/{tm_context.sh => context} (100%) rename src/tm_mad/ssh/{tm_delete.sh => delete} (100%) rename src/tm_mad/ssh/{tm_ln.sh => ln} (100%) rename src/tm_mad/ssh/{tm_mkimage.sh => mkimage} (100%) rename src/tm_mad/ssh/{tm_mkswap.sh => mkswap} (100%) rename src/tm_mad/ssh/{tm_mv.sh => mv} (100%) delete mode 100755 src/tm_mad/ssh/tm_ssh.conf delete mode 100644 src/tm_mad/ssh/tm_sshrc rename src/tm_mad/vmware/{tm_clone.sh => clone} (100%) rename src/tm_mad/vmware/{tm_context.sh => context} (100%) rename src/tm_mad/vmware/{tm_ln.sh => ln} (100%) rename src/tm_mad/vmware/{tm_mv.sh => mv} (100%) delete mode 100644 src/tm_mad/vmware/tm_vmware.conf diff --git a/install.sh b/install.sh index 6382cd1023..7f48651ceb 100755 --- a/install.sh +++ b/install.sh @@ -186,11 +186,7 @@ ETC_DIRS="$ETC_LOCATION/datastore \ $ETC_LOCATION/im_ec2 \ $ETC_LOCATION/vmm_ec2 \ $ETC_LOCATION/vmm_exec \ - $ETC_LOCATION/tm_shared \ - $ETC_LOCATION/tm_ssh \ - $ETC_LOCATION/tm_dummy \ - $ETC_LOCATION/tm_vmware \ - $ETC_LOCATION/tm_lvm \ + $ETC_LOCATION/tm \ $ETC_LOCATION/hm \ $ETC_LOCATION/auth \ $ETC_LOCATION/auth/certificates \ @@ -207,12 +203,6 @@ LIB_DIRS="$LIB_LOCATION/ruby \ $LIB_LOCATION/ruby/cloud/occi \ $LIB_LOCATION/ruby/cloud/CloudAuth \ $LIB_LOCATION/ruby/onedb \ - $LIB_LOCATION/tm_commands \ - $LIB_LOCATION/tm_commands/shared \ - $LIB_LOCATION/tm_commands/ssh \ - $LIB_LOCATION/tm_commands/dummy \ - $LIB_LOCATION/tm_commands/lvm \ - $LIB_LOCATION/tm_commands/vmware \ $LIB_LOCATION/mads \ $LIB_LOCATION/sh \ $LIB_LOCATION/ruby/cli \ @@ -225,7 +215,10 @@ VAR_DIRS="$VAR_LOCATION/remotes \ $VAR_LOCATION/remotes/im/xen.d \ $VAR_LOCATION/remotes/im/vmware.d \ $VAR_LOCATION/remotes/im/ganglia.d \ + $VAR_LOCATION/remotes/vmm \ $VAR_LOCATION/remotes/vmm/kvm \ + $VAR_LOCATION/remotes/vmm/xen \ + $VAR_LOCATION/remotes/vmm/vmware \ $VAR_LOCATION/remotes/vnm \ $VAR_LOCATION/remotes/vnm/802.1Q \ $VAR_LOCATION/remotes/vnm/dummy \ @@ -233,8 +226,12 @@ VAR_DIRS="$VAR_LOCATION/remotes \ $VAR_LOCATION/remotes/vnm/fw \ $VAR_LOCATION/remotes/vnm/ovswitch \ $VAR_LOCATION/remotes/vnm/vmware \ - $VAR_LOCATION/remotes/vmm/xen \ - $VAR_LOCATION/remotes/vmm/vmware \ + $VAR_LOCATION/remotes/tm/ \ + $VAR_LOCATION/remotes/tm/dummy \ + $VAR_LOCATION/remotes/tm/lvm \ + $VAR_LOCATION/remotes/tm/shared \ + $VAR_LOCATION/remotes/tm/ssh \ + $VAR_LOCATION/remotes/tm/vmware \ $VAR_LOCATION/remotes/hooks \ $VAR_LOCATION/remotes/hooks/ft \ $VAR_LOCATION/remotes/datastore \ @@ -384,11 +381,12 @@ INSTALL_FILES=( VMM_EXEC_KVM_SCRIPTS:$VAR_LOCATION/remotes/vmm/kvm VMM_EXEC_XEN_SCRIPTS:$VAR_LOCATION/remotes/vmm/xen VMM_EXEC_VMWARE_SCRIPTS:$VAR_LOCATION/remotes/vmm/vmware - SHARED_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/shared - SSH_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/ssh - VMWARE_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/vmware - DUMMY_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/dummy - LVM_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/lvm + TM_FILES:$VAR_LOCATION/remotes/tm + TM_SHARED_FILES:$VAR_LOCATION/remotes/tm/shared + TM_SSH_FILES:$VAR_LOCATION/remotes/tm/ssh + TM_VMWARE_FILES:$VAR_LOCATION/remotes/tm/vmware + TM_DUMMY_FILES:$VAR_LOCATION/remotes/tm/dummy + TM_LVM_FILES:$VAR_LOCATION/remotes/tm/lvm DATASTORE_DRIVER_COMMON_SCRIPTS:$VAR_LOCATION/remotes/datastore/ DATASTORE_DRIVER_FS_SCRIPTS:$VAR_LOCATION/remotes/datastore/fs DATASTORE_DRIVER_VMWARE_SCRIPTS:$VAR_LOCATION/remotes/datastore/vmware @@ -534,11 +532,7 @@ INSTALL_ETC_FILES=( DATASTORE_DRIVER_FS_ETC_FILES:$ETC_LOCATION/datastore/ DATASTORE_DRIVER_VMWARE_ETC_FILES:$ETC_LOCATION/datastore/ IM_EC2_ETC_FILES:$ETC_LOCATION/im_ec2 - TM_SHARED_ETC_FILES:$ETC_LOCATION/tm_shared - TM_SSH_ETC_FILES:$ETC_LOCATION/tm_ssh - TM_DUMMY_ETC_FILES:$ETC_LOCATION/tm_dummy - TM_LVM_ETC_FILES:$ETC_LOCATION/tm_lvm - TM_VMWARE_ETC_FILES:$ETC_LOCATION/tm_vmware + TM_LVM_ETC_FILES:$ETC_LOCATION/tm/ HM_ETC_FILES:$ETC_LOCATION/hm AUTH_ETC_FILES:$ETC_LOCATION/auth ECO_ETC_FILES:$ETC_LOCATION @@ -613,7 +607,6 @@ MAD_RUBY_LIB_FILES="src/mad/ruby/scripts_common.rb" #------------------------------------------------------------------------------- MADS_LIB_FILES="src/mad/sh/madcommon.sh \ - src/tm_mad/tm_common.sh \ src/vmm_mad/exec/one_vmm_exec.rb \ src/vmm_mad/exec/one_vmm_exec \ src/vmm_mad/exec/one_vmm_sh \ @@ -761,46 +754,53 @@ NETWORK_VMWARE_FILES="src/vnm_mad/remotes/vmware/clean \ src/vnm_mad/remotes/vmware/pre \ src/vnm_mad/remotes/vmware/VMware.rb" - #------------------------------------------------------------------------------- # Transfer Manager commands, to be installed under $LIB_LOCATION/tm_commands -# - SHARED TM, $LIB_LOCATION/tm_commands/shared -# - SSH TM, $LIB_LOCATION/tm_commands/ssh -# - dummy TM, $LIB_LOCATION/tm_commands/dummy -# - LVM TM, $LIB_LOCATION/tm_commands/lvm +# - SHARED TM, $VAR_LOCATION/tm/shared +# - SSH TM, $VAR_LOCATION/tm/ssh +# - dummy TM, $VAR_LOCATION/tm/dummy +# - LVM TM, $VAR_LOCATION/tm/lvm #------------------------------------------------------------------------------- -SHARED_TM_COMMANDS_LIB_FILES="src/tm_mad/shared/tm_clone.sh \ - src/tm_mad/shared/tm_delete.sh \ - src/tm_mad/shared/tm_ln.sh \ - src/tm_mad/shared/tm_mkswap.sh \ - src/tm_mad/shared/tm_mkimage.sh \ - src/tm_mad/shared/tm_mv.sh \ - src/tm_mad/shared/tm_context.sh" +TM_FILES="src/tm_mad/tm_common.sh" -SSH_TM_COMMANDS_LIB_FILES="src/tm_mad/ssh/tm_clone.sh \ - src/tm_mad/ssh/tm_delete.sh \ - src/tm_mad/ssh/tm_ln.sh \ - src/tm_mad/ssh/tm_mkswap.sh \ - src/tm_mad/ssh/tm_mkimage.sh \ - src/tm_mad/ssh/tm_mv.sh \ - src/tm_mad/ssh/tm_context.sh" +TM_SHARED_FILES="src/tm_mad/shared/clone \ + src/tm_mad/shared/delete \ + src/tm_mad/shared/ln \ + src/tm_mad/shared/mkswap \ + src/tm_mad/shared/mkimage \ + src/tm_mad/shared/mv \ + src/tm_mad/shared/context" -DUMMY_TM_COMMANDS_LIB_FILES="src/tm_mad/dummy/tm_dummy.sh" +TM_SSH_FILES="src/tm_mad/ssh/clone \ + src/tm_mad/ssh/delete \ + src/tm_mad/ssh/ln \ + src/tm_mad/ssh/mkswap \ + src/tm_mad/ssh/mkimage \ + src/tm_mad/ssh/mv \ + src/tm_mad/ssh/context" -LVM_TM_COMMANDS_LIB_FILES="src/tm_mad/lvm/tm_clone.sh \ - src/tm_mad/lvm/tm_delete.sh \ - src/tm_mad/lvm/tm_ln.sh \ - src/tm_mad/lvm/tm_mkswap.sh \ - src/tm_mad/lvm/tm_mkimage.sh \ - src/tm_mad/lvm/tm_mv.sh \ - src/tm_mad/lvm/tm_context.sh" +TM_DUMMY_FILES="src/tm_mad/dummy/clone \ + src/tm_mad/dummy/delete \ + src/tm_mad/dummy/ln \ + src/tm_mad/dummy/mkswap \ + src/tm_mad/dummy/mkimage \ + src/tm_mad/dummy/mv \ + src/tm_mad/dummy/context" -VMWARE_TM_COMMANDS_LIB_FILES="src/tm_mad/vmware/tm_clone.sh \ - src/tm_mad/vmware/tm_ln.sh \ - src/tm_mad/vmware/tm_mv.sh \ - src/tm_mad/vmware/functions.sh \ - src/tm_mad/vmware/tm_context.sh" +TM_LVM_FILES="src/tm_mad/lvm/clone \ + src/tm_mad/lvm/delete \ + src/tm_mad/lvm/ln \ + src/tm_mad/lvm/mkswap \ + src/tm_mad/lvm/mkimage \ + src/tm_mad/lvm/mv \ + src/tm_mad/lvm/context" + +TM_VMWARE_FILES="src/tm_mad/vmware/clone \ + src/tm_mad/vmware/ln \ + src/tm_mad/vmware/mv \ + src/tm_mad/vmware/functions.sh \ + src/tm_mad/vmware/context" #------------------------------------------------------------------------------- # Datastore drivers, to be installed under $REMOTES_LOCATION/datastore @@ -881,19 +881,7 @@ IM_EC2_ETC_FILES="src/im_mad/ec2/im_ec2rc \ # - lvm, $ETC_LOCATION/tm_lvm #------------------------------------------------------------------------------- -TM_SHARED_ETC_FILES="src/tm_mad/shared/tm_shared.conf \ - src/tm_mad/shared/tm_sharedrc" - -TM_SSH_ETC_FILES="src/tm_mad/ssh/tm_ssh.conf \ - src/tm_mad/ssh/tm_sshrc" - -TM_DUMMY_ETC_FILES="src/tm_mad/dummy/tm_dummy.conf \ - src/tm_mad/dummy/tm_dummyrc" - -TM_LVM_ETC_FILES="src/tm_mad/lvm/tm_lvm.conf \ - src/tm_mad/lvm/tm_lvmrc" - -TM_VMWARE_ETC_FILES="src/tm_mad/vmware/tm_vmware.conf" +TM_LVM_ETC_FILES="src/tm_mad/lvm/lvm.conf" #------------------------------------------------------------------------------- # Hook Manager driver config. files, to be installed under $ETC_LOCATION/hm diff --git a/src/tm_mad/dummy/clone b/src/tm_mad/dummy/clone new file mode 120000 index 0000000000..00c5fa12de --- /dev/null +++ b/src/tm_mad/dummy/clone @@ -0,0 +1 @@ +dummy.sh \ No newline at end of file diff --git a/src/tm_mad/dummy/context b/src/tm_mad/dummy/context new file mode 120000 index 0000000000..00c5fa12de --- /dev/null +++ b/src/tm_mad/dummy/context @@ -0,0 +1 @@ +dummy.sh \ No newline at end of file diff --git a/src/tm_mad/dummy/delete b/src/tm_mad/dummy/delete new file mode 120000 index 0000000000..00c5fa12de --- /dev/null +++ b/src/tm_mad/dummy/delete @@ -0,0 +1 @@ +dummy.sh \ No newline at end of file diff --git a/src/tm_mad/dummy/tm_dummy.sh b/src/tm_mad/dummy/dummy.sh similarity index 100% rename from src/tm_mad/dummy/tm_dummy.sh rename to src/tm_mad/dummy/dummy.sh diff --git a/src/tm_mad/dummy/ln b/src/tm_mad/dummy/ln new file mode 120000 index 0000000000..00c5fa12de --- /dev/null +++ b/src/tm_mad/dummy/ln @@ -0,0 +1 @@ +dummy.sh \ No newline at end of file diff --git a/src/tm_mad/dummy/mkimage b/src/tm_mad/dummy/mkimage new file mode 120000 index 0000000000..00c5fa12de --- /dev/null +++ b/src/tm_mad/dummy/mkimage @@ -0,0 +1 @@ +dummy.sh \ No newline at end of file diff --git a/src/tm_mad/dummy/mkswap b/src/tm_mad/dummy/mkswap new file mode 120000 index 0000000000..00c5fa12de --- /dev/null +++ b/src/tm_mad/dummy/mkswap @@ -0,0 +1 @@ +dummy.sh \ No newline at end of file diff --git a/src/tm_mad/dummy/mv b/src/tm_mad/dummy/mv new file mode 120000 index 0000000000..00c5fa12de --- /dev/null +++ b/src/tm_mad/dummy/mv @@ -0,0 +1 @@ +dummy.sh \ No newline at end of file diff --git a/src/tm_mad/dummy/tm_dummy.conf b/src/tm_mad/dummy/tm_dummy.conf deleted file mode 100755 index 5bb570cb61..0000000000 --- a/src/tm_mad/dummy/tm_dummy.conf +++ /dev/null @@ -1,23 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -CLONE = dummy/tm_dummy.sh -LN = dummy/tm_dummy.sh -MKSWAP = dummy/tm_dummy.sh -MKIMAGE = dummy/tm_dummy.sh -DELETE = dummy/tm_dummy.sh -MV = dummy/tm_dummy.sh -CONTEXT = dummy/tm_dummy.sh diff --git a/src/tm_mad/dummy/tm_dummyrc b/src/tm_mad/dummy/tm_dummyrc deleted file mode 100644 index 1e12168116..0000000000 --- a/src/tm_mad/dummy/tm_dummyrc +++ /dev/null @@ -1,15 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # diff --git a/src/tm_mad/lvm/tm_clone.sh b/src/tm_mad/lvm/clone similarity index 100% rename from src/tm_mad/lvm/tm_clone.sh rename to src/tm_mad/lvm/clone diff --git a/src/tm_mad/lvm/tm_context.sh b/src/tm_mad/lvm/context similarity index 100% rename from src/tm_mad/lvm/tm_context.sh rename to src/tm_mad/lvm/context diff --git a/src/tm_mad/lvm/tm_delete.sh b/src/tm_mad/lvm/delete similarity index 100% rename from src/tm_mad/lvm/tm_delete.sh rename to src/tm_mad/lvm/delete diff --git a/src/tm_mad/lvm/tm_ln.sh b/src/tm_mad/lvm/ln similarity index 100% rename from src/tm_mad/lvm/tm_ln.sh rename to src/tm_mad/lvm/ln diff --git a/src/tm_mad/lvm/tm_lvmrc b/src/tm_mad/lvm/lvm.conf similarity index 100% rename from src/tm_mad/lvm/tm_lvmrc rename to src/tm_mad/lvm/lvm.conf diff --git a/src/tm_mad/lvm/tm_mkimage.sh b/src/tm_mad/lvm/mkimage similarity index 100% rename from src/tm_mad/lvm/tm_mkimage.sh rename to src/tm_mad/lvm/mkimage diff --git a/src/tm_mad/lvm/tm_mkswap.sh b/src/tm_mad/lvm/mkswap similarity index 100% rename from src/tm_mad/lvm/tm_mkswap.sh rename to src/tm_mad/lvm/mkswap diff --git a/src/tm_mad/lvm/tm_mv.sh b/src/tm_mad/lvm/mv similarity index 100% rename from src/tm_mad/lvm/tm_mv.sh rename to src/tm_mad/lvm/mv diff --git a/src/tm_mad/lvm/tm_lvm.conf b/src/tm_mad/lvm/tm_lvm.conf deleted file mode 100755 index 7662ae32b1..0000000000 --- a/src/tm_mad/lvm/tm_lvm.conf +++ /dev/null @@ -1,23 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -CLONE = lvm/tm_clone.sh -LN = lvm/tm_ln.sh -MKSWAP = lvm/tm_mkswap.sh -MKIMAGE = lvm/tm_mkimage.sh -DELETE = lvm/tm_delete.sh -MV = lvm/tm_mv.sh -CONTEXT = lvm/tm_context.sh diff --git a/src/tm_mad/shared/tm_clone.sh b/src/tm_mad/shared/clone similarity index 100% rename from src/tm_mad/shared/tm_clone.sh rename to src/tm_mad/shared/clone diff --git a/src/tm_mad/shared/tm_context.sh b/src/tm_mad/shared/context similarity index 100% rename from src/tm_mad/shared/tm_context.sh rename to src/tm_mad/shared/context diff --git a/src/tm_mad/shared/tm_delete.sh b/src/tm_mad/shared/delete similarity index 100% rename from src/tm_mad/shared/tm_delete.sh rename to src/tm_mad/shared/delete diff --git a/src/tm_mad/shared/tm_ln.sh b/src/tm_mad/shared/ln similarity index 100% rename from src/tm_mad/shared/tm_ln.sh rename to src/tm_mad/shared/ln diff --git a/src/tm_mad/shared/tm_mkimage.sh b/src/tm_mad/shared/mkimage similarity index 100% rename from src/tm_mad/shared/tm_mkimage.sh rename to src/tm_mad/shared/mkimage diff --git a/src/tm_mad/shared/tm_mkswap.sh b/src/tm_mad/shared/mkswap similarity index 100% rename from src/tm_mad/shared/tm_mkswap.sh rename to src/tm_mad/shared/mkswap diff --git a/src/tm_mad/shared/tm_mv.sh b/src/tm_mad/shared/mv similarity index 100% rename from src/tm_mad/shared/tm_mv.sh rename to src/tm_mad/shared/mv diff --git a/src/tm_mad/shared/tm_shared.conf b/src/tm_mad/shared/tm_shared.conf deleted file mode 100644 index fdd1ed0852..0000000000 --- a/src/tm_mad/shared/tm_shared.conf +++ /dev/null @@ -1,23 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -CLONE = shared/tm_clone.sh -LN = shared/tm_ln.sh -MKSWAP = shared/tm_mkswap.sh -MKIMAGE = shared/tm_mkimage.sh -DELETE = shared/tm_delete.sh -MV = shared/tm_mv.sh -CONTEXT = shared/tm_context.sh diff --git a/src/tm_mad/shared/tm_sharedrc b/src/tm_mad/shared/tm_sharedrc deleted file mode 100644 index 1e12168116..0000000000 --- a/src/tm_mad/shared/tm_sharedrc +++ /dev/null @@ -1,15 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # diff --git a/src/tm_mad/ssh/tm_clone.sh b/src/tm_mad/ssh/clone similarity index 100% rename from src/tm_mad/ssh/tm_clone.sh rename to src/tm_mad/ssh/clone diff --git a/src/tm_mad/ssh/tm_context.sh b/src/tm_mad/ssh/context similarity index 100% rename from src/tm_mad/ssh/tm_context.sh rename to src/tm_mad/ssh/context diff --git a/src/tm_mad/ssh/tm_delete.sh b/src/tm_mad/ssh/delete similarity index 100% rename from src/tm_mad/ssh/tm_delete.sh rename to src/tm_mad/ssh/delete diff --git a/src/tm_mad/ssh/tm_ln.sh b/src/tm_mad/ssh/ln similarity index 100% rename from src/tm_mad/ssh/tm_ln.sh rename to src/tm_mad/ssh/ln diff --git a/src/tm_mad/ssh/tm_mkimage.sh b/src/tm_mad/ssh/mkimage similarity index 100% rename from src/tm_mad/ssh/tm_mkimage.sh rename to src/tm_mad/ssh/mkimage diff --git a/src/tm_mad/ssh/tm_mkswap.sh b/src/tm_mad/ssh/mkswap similarity index 100% rename from src/tm_mad/ssh/tm_mkswap.sh rename to src/tm_mad/ssh/mkswap diff --git a/src/tm_mad/ssh/tm_mv.sh b/src/tm_mad/ssh/mv similarity index 100% rename from src/tm_mad/ssh/tm_mv.sh rename to src/tm_mad/ssh/mv diff --git a/src/tm_mad/ssh/tm_ssh.conf b/src/tm_mad/ssh/tm_ssh.conf deleted file mode 100755 index bf8a5b6f80..0000000000 --- a/src/tm_mad/ssh/tm_ssh.conf +++ /dev/null @@ -1,23 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -CLONE = ssh/tm_clone.sh -LN = ssh/tm_ln.sh -MKSWAP = ssh/tm_mkswap.sh -MKIMAGE = ssh/tm_mkimage.sh -DELETE = ssh/tm_delete.sh -MV = ssh/tm_mv.sh -CONTEXT = ssh/tm_context.sh diff --git a/src/tm_mad/ssh/tm_sshrc b/src/tm_mad/ssh/tm_sshrc deleted file mode 100644 index 1e12168116..0000000000 --- a/src/tm_mad/ssh/tm_sshrc +++ /dev/null @@ -1,15 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # diff --git a/src/tm_mad/vmware/tm_clone.sh b/src/tm_mad/vmware/clone similarity index 100% rename from src/tm_mad/vmware/tm_clone.sh rename to src/tm_mad/vmware/clone diff --git a/src/tm_mad/vmware/tm_context.sh b/src/tm_mad/vmware/context similarity index 100% rename from src/tm_mad/vmware/tm_context.sh rename to src/tm_mad/vmware/context diff --git a/src/tm_mad/vmware/tm_ln.sh b/src/tm_mad/vmware/ln similarity index 100% rename from src/tm_mad/vmware/tm_ln.sh rename to src/tm_mad/vmware/ln diff --git a/src/tm_mad/vmware/tm_mv.sh b/src/tm_mad/vmware/mv similarity index 100% rename from src/tm_mad/vmware/tm_mv.sh rename to src/tm_mad/vmware/mv diff --git a/src/tm_mad/vmware/tm_vmware.conf b/src/tm_mad/vmware/tm_vmware.conf deleted file mode 100644 index 0de9eeb95e..0000000000 --- a/src/tm_mad/vmware/tm_vmware.conf +++ /dev/null @@ -1,23 +0,0 @@ -# ---------------------------------------------------------------------------- # -# Copyright 2010-2011, C12G Labs S.L # -# # -# 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. # -# ---------------------------------------------------------------------------- # - -CLONE = vmware/tm_clone.sh -LN = vmware/tm_ln.sh -MKSWAP = dummy/tm_dummy.sh -MKIMAGE = dummy/tm_dummy.sh -DELETE = shared/tm_delete.sh -MV = vmware/tm_mv.sh -CONTEXT = vmware/tm_context.sh From 7e57e792ae16fea662316e9ad87c37bef9355ca3 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 28 Feb 2012 23:50:51 +0100 Subject: [PATCH 077/217] feature #1112: Change tm drivers for default datastores to the new names --- src/datastore/DatastorePool.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index 968ea4f3f3..b4fae8359c 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -58,7 +58,7 @@ DatastorePool::DatastorePool(SqlDB * db): oss << "NAME = " << SYSTEM_DS_NAME << endl << "BASE_PATH = " << base_path << "system"<< endl << "TYPE = fs" << endl - << "TM_MAD = tm_shared"; + << "TM_MAD = shared"; ds_tmpl = new DatastoreTemplate; rc = ds_tmpl->parse_str_or_xml(oss.str(), error_str); @@ -87,7 +87,7 @@ DatastorePool::DatastorePool(SqlDB * db): oss << "NAME = " << DEFAULT_DS_NAME << endl << "BASE_PATH = " << base_path << "default" << endl << "TYPE = fs" << endl - << "TM_MAD = tm_shared"; + << "TM_MAD = shared"; ds_tmpl = new DatastoreTemplate; rc = ds_tmpl->parse_str_or_xml(oss.str(), error_str); From 9d59ec9fb7a6c604b5be53fc2a82dd1439c34da0 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 28 Feb 2012 23:51:36 +0100 Subject: [PATCH 078/217] feature #1112: oned.conf uses the new TM drivers --- share/etc/oned.conf | 54 +++++---------------------------------------- 1 file changed, 6 insertions(+), 48 deletions(-) diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 21ae5623f9..1e51799aaa 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -272,56 +272,15 @@ VM_MAD = [ # executable: path of the transfer driver executable, can be an # absolute path or relative to $ONE_LOCATION/lib/mads (or # /usr/lib/one/mads/ if OpenNebula was installed in /) -# -# arguments : for the driver executable, usually a commands configuration file -# , can be an absolute path or relative to $ONE_LOCATION/etc (or -# /etc/one/ if OpenNebula was installed in /) +# arguments : +# -t: number of threads, i.e. number of transfers made at the same time +# -d: list of transfer drivers separated by commas, if not defined all the +# drivers available will be enabled #******************************************************************************* -#------------------------------------------------------------------------------- -# SHARED Transfer Manager Driver Configuration -#------------------------------------------------------------------------------- TM_MAD = [ - name = "tm_shared", executable = "one_tm", - arguments = "tm_shared/tm_shared.conf" ] -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# SSH Transfer Manager Driver Configuration -#------------------------------------------------------------------------------- -#TM_MAD = [ -# name = "tm_ssh", -# executable = "one_tm", -# arguments = "tm_ssh/tm_ssh.conf" ] -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# Dummy Transfer Manager Driver Configuration -#------------------------------------------------------------------------------- -#TM_MAD = [ -# name = "tm_dummy", -# executable = "one_tm", -# arguments = "tm_dummy/tm_dummy.conf" ] -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# LVM Transfer Manager Driver Configuration -#------------------------------------------------------------------------------- -#TM_MAD = [ -# name = "tm_lvm", -# executable = "one_tm", -# arguments = "tm_lvm/tm_lvm.conf" ] -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# VMware DataStore Transfer Manager Driver Configuration -#------------------------------------------------------------------------------- -#TM_MAD = [ -# name = "tm_vmware", -# executable = "one_tm", -# arguments = "tm_vmware/tm_vmware.conf" ] -#------------------------------------------------------------------------------- + arguments = "-t 15 -d dummy,lvm,shared,ssh,vmware" ] #******************************************************************************* # Datastore Driver Configuration @@ -338,8 +297,7 @@ TM_MAD = [ DATASTORE_MAD = [ executable = "one_datastore", - arguments = "-t 15 -d fs" -# arguments = "-t 15 -d fs,vmware" + arguments = "-t 15 -d fs,vmware" ] #******************************************************************************* From bc6f8630bf64e0aa115f97a1aa52b8c1ec6acc24 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 28 Feb 2012 23:52:51 +0100 Subject: [PATCH 079/217] feature #1112: Fix variable name --- src/tm_mad/one_tm.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tm_mad/one_tm.rb b/src/tm_mad/one_tm.rb index a6dafe47a9..4f3e56a992 100755 --- a/src/tm_mad/one_tm.rb +++ b/src/tm_mad/one_tm.rb @@ -129,7 +129,7 @@ class TransferManagerDriver < OpenNebulaDriver end path = File.join(@local_scripts_path, tm, cmd) - path << " " << arguments + path << " " << args rc = LocalCommand.run(path, log_method(id)) From 6ee5900bf61a918024c52e8ce1d7de108344775b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 29 Feb 2012 12:50:26 +0100 Subject: [PATCH 080/217] Feature #1112: Move host to cluster addition from Host::allocate to RMAllocate --- src/host/HostPool.cc | 30 -------------------------- src/rm/RequestManagerAllocate.cc | 37 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/host/HostPool.cc b/src/host/HostPool.cc index bd72115061..3ead792f4c 100644 --- a/src/host/HostPool.cc +++ b/src/host/HostPool.cc @@ -25,7 +25,6 @@ #include "HostHook.h" #include "NebulaLog.h" #include "GroupPool.h" -#include "Nebula.h" /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -158,14 +157,9 @@ int HostPool::allocate ( const string& cluster_name, string& error_str) { - Nebula& nd = Nebula::instance(); - Host * host; ostringstream oss; - ClusterPool * clpool; - Cluster * cluster; - if ( hostname.empty() ) { goto error_name; @@ -213,32 +207,8 @@ int HostPool::allocate ( *oid = PoolSQL::allocate(host, error_str); - if ( *oid < 0 ) - { - return *oid; - } - - // Add Host to Cluster - clpool = nd.get_clpool(); - cluster = clpool->get(cluster_id, true); - - if( cluster == 0 ) - { - return -1; - } - - if ( cluster->add_host(*oid, error_str) < 0 ) - { - return -1; - } - - clpool->update(cluster); - - cluster->unlock(); - return *oid; - error_name: oss << "NAME cannot be empty."; goto error_common; diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 909bfcfcc4..cf16784fb3 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -325,6 +325,7 @@ void HostAllocate::request_execute( Nebula& nd = Nebula::instance(); + Cluster * cluster = 0; ClusterPool * clpool = nd.get_clpool(); HostPool * hpool = static_cast(pool); @@ -365,6 +366,42 @@ void HostAllocate::request_execute( return; } + // ------------- Add Host to Cluster -------------------------------------- + + cluster = clpool->get(cluster_id, true); + + if ( cluster == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::CLUSTER), cluster_id), att); + return; + } + + rc = cluster->add_host(id, error_str); + + if ( rc < 0 ) + { + string drop_err; + Host * host = 0; + + cluster->unlock(); + + host = hpool->get(id, true); + + if ( host != 0 ) + { + hpool->drop(host, drop_err); + host->unlock(); + } + + failure_response(INTERNAL, allocate_error(error_str), att); + return; + } + + clpool->update(cluster); + + cluster->unlock(); + success_response(id, att); } From c81ed13e6b575dee8621c0bd880c9d5b32bdf434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 29 Feb 2012 16:05:46 +0100 Subject: [PATCH 081/217] Feature #1112: Fix optional cluster argument in onehost create --- src/cli/onehost | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cli/onehost b/src/cli/onehost index 9da4453de8..9f72204b66 100755 --- a/src/cli/onehost +++ b/src/cli/onehost @@ -63,7 +63,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do command :create, create_desc, :hostname, :im_mad, :vmm_mad, :vnm_mad, [:clusterid, nil] do helper.create_resource(options) do |host| - if args[4] + if args.size == 4 host.allocate(args[0], args[1], args[2], args[3]) else host.allocate(args[0], args[1], args[2], args[3], args[4].to_i) From be00373b09b80a94d39b0aa3e3e6aa216cbc77a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 29 Feb 2012 16:06:29 +0100 Subject: [PATCH 082/217] Feature #1112: Refactor RequestManagerAllocate to be able to add objects to clusters on creation --- include/RequestManagerAllocate.h | 67 +++++++++-- src/rm/RequestManagerAllocate.cc | 184 ++++++++++++++++--------------- 2 files changed, 151 insertions(+), 100 deletions(-) diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index d22e0d52be..cbfeebc714 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -37,10 +37,21 @@ 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 dt, + bool dc=false) + :Request(method_name,xml_args,help), do_template(dt), do_cluster(dc) { auth_op = AuthRequest::CREATE; + + if ( do_cluster ) + { + Nebula& nd = Nebula::instance(); + clpool = nd.get_clpool(); + } + else + { + clpool = 0; + } }; ~RequestManagerAllocate(){}; @@ -50,8 +61,9 @@ protected: virtual void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att); - virtual bool allocate_authorization(Template * obj_template, - RequestAttributes& att); + virtual bool allocate_authorization(Template * obj_template, + RequestAttributes& att, + PoolObjectAuth * cluster_perms); /* -------------------------------------------------------------------- */ @@ -66,9 +78,34 @@ protected: return -1; }; + virtual int pool_allocate(xmlrpc_c::paramList const& _paramList, + Template * tmpl, + int& id, + string& error_str, + RequestAttributes& att, + int cluster_id, + const string& cluster_name) + { + return pool_allocate(_paramList, tmpl, id, error_str, att); + }; + + virtual int get_cluster_id(xmlrpc_c::paramList const& paramList) + { + return -1; + }; + + virtual int add_to_cluster(Cluster* cluster, int id, string& error_msg) + { + return -1; + }; + +protected: + ClusterPool * clpool; + private: bool do_template; + bool do_cluster; }; @@ -90,6 +127,7 @@ public: }; ~VirtualMachineAllocate(){}; + /* --------------------------------------------------------------------- */ Template * get_object_template() @@ -103,8 +141,9 @@ public: string& error_str, RequestAttributes& att); - bool allocate_authorization(Template * obj_template, - RequestAttributes& att); + bool allocate_authorization(Template * obj_template, + RequestAttributes& att, + PoolObjectAuth * cluster_perms); }; /* ------------------------------------------------------------------------- */ @@ -208,7 +247,8 @@ public: RequestManagerAllocate("HostAllocate", "Allocates a new host", "A:sssssi", - false) + false, + true) { Nebula& nd = Nebula::instance(); pool = nd.get_hpool(); @@ -219,8 +259,17 @@ public: /* --------------------------------------------------------------------- */ - void request_execute(xmlrpc_c::paramList const& paramList, - RequestAttributes& att); + int pool_allocate(xmlrpc_c::paramList const& _paramList, + Template * tmpl, + int& id, + string& error_str, + RequestAttributes& att, + int cluster_id, + const string& cluster_name); + + int get_cluster_id(xmlrpc_c::paramList const& paramList); + + int add_to_cluster(Cluster* cluster, int id, string& error_msg); }; /* ------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index cf16784fb3..88c5404761 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -23,8 +23,10 @@ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -bool RequestManagerAllocate::allocate_authorization(Template * tmpl, - RequestAttributes& att) +bool RequestManagerAllocate::allocate_authorization( + Template * tmpl, + RequestAttributes& att, + PoolObjectAuth * cluster_perms) { if ( att.uid == 0 ) { @@ -42,6 +44,11 @@ bool RequestManagerAllocate::allocate_authorization(Template * tmpl, ar.add_create_auth(auth_object, tmpl_str); + if ( do_cluster ) + { + ar.add_auth(AuthRequest::ADMIN, *cluster_perms); // ADMIN CLUSTER + } + if (UserPool::authorize(ar) == -1) { failure_response(AUTHORIZATION, @@ -57,8 +64,10 @@ bool RequestManagerAllocate::allocate_authorization(Template * tmpl, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -bool VirtualMachineAllocate::allocate_authorization(Template * tmpl, - RequestAttributes& att) +bool VirtualMachineAllocate::allocate_authorization( + Template * tmpl, + RequestAttributes& att, + PoolObjectAuth * cluster_perms) { if ( att.uid == 0 ) { @@ -97,6 +106,11 @@ void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params, string error_str; int rc, id; + Cluster * cluster = 0; + int cluster_id = -1; + string cluster_name = ""; + PoolObjectAuth cluster_perms; + if ( do_template == true ) { string str_tmpl = xmlrpc_c::value_string(params.getString(1)); @@ -114,20 +128,73 @@ void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params, } } - if ( allocate_authorization(tmpl, att) == false ) + if ( do_cluster == true ) + { + cluster_id = get_cluster_id(params); + + rc = get_info(clpool, cluster_id, PoolObjectSQL::CLUSTER, att, + cluster_perms, cluster_name); + + if ( rc != 0 ) + { + delete tmpl; + return; + } + } + + if ( allocate_authorization(tmpl, att, &cluster_perms) == false ) { delete tmpl; return; } - rc = pool_allocate(params, tmpl, id, error_str, att); + rc = pool_allocate(params, tmpl, id, error_str, att, cluster_id, cluster_name); if ( rc < 0 ) { failure_response(INTERNAL, allocate_error(error_str), att); return; } - + + if ( do_cluster == true ) + { + cluster = clpool->get(cluster_id, true); + + if ( cluster == 0 ) + { + failure_response( + NO_EXISTS, + get_error(object_name(PoolObjectSQL::CLUSTER), cluster_id), + att); + return; + } + + rc = add_to_cluster(cluster, id, error_str); + + if ( rc < 0 ) + { + string drop_err; + PoolObjectSQL * obj = 0; + + cluster->unlock(); + + obj = pool->get(id, true); + + if ( obj != 0 ) + { + pool->drop(obj, drop_err); + obj->unlock(); + } + + failure_response(INTERNAL, allocate_error(error_str), att); + return; + } + + clpool->update(cluster); + + cluster->unlock(); + } + success_response(id, att); } @@ -170,7 +237,6 @@ int VirtualNetworkAllocate::pool_allocate(xmlrpc_c::paramList const& _paramList, void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, RequestAttributes& att) { - string error_str; string ds_name; string ds_data; @@ -306,103 +372,39 @@ int TemplateAllocate::pool_allocate(xmlrpc_c::paramList const& _paramList, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void HostAllocate::request_execute( +int HostAllocate::pool_allocate( xmlrpc_c::paramList const& paramList, - RequestAttributes& att) + Template * tmpl, + int& id, + string& error_str, + RequestAttributes& att, + int cluster_id, + const string& cluster_name) { - string error_str; - string cluster_name; - string ds_data; - int rc, id; - - PoolObjectAuth cluster_perms; - string host = xmlrpc_c::value_string(paramList.getString(1)); string im_mad = xmlrpc_c::value_string(paramList.getString(2)); string vmm_mad = xmlrpc_c::value_string(paramList.getString(3)); string vnm_mad = xmlrpc_c::value_string(paramList.getString(4)); - int cluster_id = xmlrpc_c::value_int(paramList.getInt(5)); - Nebula& nd = Nebula::instance(); + HostPool * hpool = static_cast(pool); - Cluster * cluster = 0; - ClusterPool * clpool = nd.get_clpool(); - HostPool * hpool = static_cast(pool); - - // ------------------------- Check Cluster exists ------------------------ - - get_info(clpool, cluster_id, PoolObjectSQL::CLUSTER, att, - cluster_perms, cluster_name); - - // ------------- Set authorization request for non-oneadmin's ------------- - - if ( att.uid != 0 ) - { - AuthRequest ar(att.uid, att.gid); - string tmpl_str = ""; - - ar.add_create_auth(auth_object, tmpl_str); // CREATE HOST - - ar.add_auth(AuthRequest::ADMIN, cluster_perms); // ADMIN CLUSTER - - if (UserPool::authorize(ar) == -1) - { - failure_response(AUTHORIZATION, - authorization_error(ar.message, att), - att); - - return; - } - } - - // ------------- Allocate Host -------------------------------------------- - - rc = hpool->allocate(&id, host, im_mad, vmm_mad, vnm_mad, + return hpool->allocate(&id, host, im_mad, vmm_mad, vnm_mad, cluster_id, cluster_name, error_str); - if ( rc < 0 ) - { - failure_response(INTERNAL, allocate_error(error_str), att); - return; - } +} - // ------------- Add Host to Cluster -------------------------------------- +/* -------------------------------------------------------------------------- */ - cluster = clpool->get(cluster_id, true); +int HostAllocate::get_cluster_id(xmlrpc_c::paramList const& paramList) +{ + return xmlrpc_c::value_int(paramList.getInt(5)); +} - if ( cluster == 0 ) - { - failure_response(NO_EXISTS, - get_error(object_name(PoolObjectSQL::CLUSTER), cluster_id), att); - return; - } +/* -------------------------------------------------------------------------- */ - rc = cluster->add_host(id, error_str); - - if ( rc < 0 ) - { - string drop_err; - Host * host = 0; - - cluster->unlock(); - - host = hpool->get(id, true); - - if ( host != 0 ) - { - hpool->drop(host, drop_err); - host->unlock(); - } - - failure_response(INTERNAL, allocate_error(error_str), att); - return; - } - - clpool->update(cluster); - - cluster->unlock(); - - success_response(id, att); +int HostAllocate::add_to_cluster(Cluster* cluster, int id, string& error_msg) +{ + return cluster->add_host(id, error_msg); } /* -------------------------------------------------------------------------- */ From bdd23c67742e188db5914a9b263af8d9251a2960 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Wed, 29 Feb 2012 16:12:47 +0100 Subject: [PATCH 083/217] feature #1112: Fix unsafe eval in xpath.rb by joining values with \0 --- src/datastore_mad/remotes/fs/cp | 12 ++++++------ src/datastore_mad/remotes/fs/mkfs | 16 +++++++++++----- src/datastore_mad/remotes/fs/rm | 10 +++++----- src/datastore_mad/remotes/vmware/cp | 8 ++++---- src/datastore_mad/remotes/vmware/mkfs | 16 ++++++++++++---- src/datastore_mad/remotes/vmware/rm | 10 +++++----- src/datastore_mad/remotes/xpath.rb | 7 ++++--- 7 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/datastore_mad/remotes/fs/cp b/src/datastore_mad/remotes/fs/cp index 73e5dafaa6..3f99bc4324 100755 --- a/src/datastore_mad/remotes/fs/cp +++ b/src/datastore_mad/remotes/fs/cp @@ -21,7 +21,7 @@ # Several SRC types are supported ############################################################################### -# -------- Set up the environment to source common tools & conf ------------ +# -------- Set up the environment to source common tools & conf ------------ if [ -z "${ONE_LOCATION}" ]; then LIB_LOCATION=/usr/lib/one @@ -34,7 +34,7 @@ fi DRIVER_PATH=$(dirname $0) source ${DRIVER_PATH}/../libfs.sh -# -------- Get cp and datastore arguments from OpenNebula core ------------ +# -------- Get cp and datastore arguments from OpenNebula core ------------ DRV_ACTION=$1 ID=$2 @@ -42,11 +42,11 @@ ID=$2 set_up_datastore $DRV_ACTION XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" -eval "SRC=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/PATH`" +SRC=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/PATH` DST=`generate_image_path` -# ------------ Copy the image to the repository ------------- +# ------------ Copy the image to the repository ------------- case $SRC in http://*) @@ -63,9 +63,9 @@ http://*) error_message "Not allowed to copy image file $SRC" exit -1 fi - + log "Copying local image $SRC to the image repository" - + exec_and_log "cp -f $SRC $DST" "Error copying $SRC to $DST" exec_and_log "chmod 0660 $DST" diff --git a/src/datastore_mad/remotes/fs/mkfs b/src/datastore_mad/remotes/fs/mkfs index a1dc19fb81..5ec61bdb36 100755 --- a/src/datastore_mad/remotes/fs/mkfs +++ b/src/datastore_mad/remotes/fs/mkfs @@ -21,7 +21,7 @@ # as (FS) ############################################################################### -# -------- Set up the environment to source common tools & conf ------------ +# -------- Set up the environment to source common tools & conf ------------ if [ -z "${ONE_LOCATION}" ]; then LIB_LOCATION=/usr/lib/one @@ -34,16 +34,22 @@ fi DRIVER_PATH=$(dirname $0) source ${DRIVER_PATH}/../libfs.sh -# -------- Get mkfs and datastore arguments from OpenNebula core ------------ +# -------- Get mkfs and datastore arguments from OpenNebula core ------------ DRV_ACTION=$1 ID=$2 set_up_datastore $DRV_ACTION -XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" -eval "FSTYPE=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/FSTYPE`" -eval "SIZE=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/SIZE`" +unset i XPATH_ELEMENTS + +while IFS= read -r -d '' element; do + XPATH_ELEMENTS[i++]="$element" +done < <($XPATH /DS_DRIVER_ACTION_DATA/IMAGE/FSTYPE \ + /DS_DRIVER_ACTION_DATA/IMAGE/SIZE) + +FSTYPE="${XPATH_ELEMENTS[0]}" +SIZE="${XPATH_ELEMENTS[1]}" DST=`generate_image_path` diff --git a/src/datastore_mad/remotes/fs/rm b/src/datastore_mad/remotes/fs/rm index d915786ea4..2284c21289 100755 --- a/src/datastore_mad/remotes/fs/rm +++ b/src/datastore_mad/remotes/fs/rm @@ -17,10 +17,10 @@ #--------------------------------------------------------------------------- # ############################################################################### -# This script is used to remove a VM image (SRC) from the image repository +# This script is used to remove a VM image (SRC) from the image repository ############################################################################### -# ------------ Set up the environment to source common tools ------------ +# ------------ Set up the environment to source common tools ------------ if [ -z "${ONE_LOCATION}" ]; then LIB_LOCATION=/usr/lib/one @@ -33,15 +33,15 @@ fi DRIVER_PATH=$(dirname $0) source ${DRIVER_PATH}/../libfs.sh -# -------- Get rm and datastore arguments from OpenNebula core ------------ +# -------- Get rm and datastore arguments from OpenNebula core ------------ DRV_ACTION=$1 ID=$2 XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" -eval "SRC=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/SOURCE`" +SRC=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/SOURCE` -# ------------ Remove the image from the repository ------------ +# ------------ Remove the image from the repository ------------ if [ -e $SRC ] ; then log "Removing $SRC from the image repository" diff --git a/src/datastore_mad/remotes/vmware/cp b/src/datastore_mad/remotes/vmware/cp index c449d1b1ce..0a971e25c4 100755 --- a/src/datastore_mad/remotes/vmware/cp +++ b/src/datastore_mad/remotes/vmware/cp @@ -21,7 +21,7 @@ # Several SRC types are supported ############################################################################### -# -------- Set up the environment to source common tools & conf ------------ +# -------- Set up the environment to source common tools & conf ------------ if [ -z "${ONE_LOCATION}" ]; then LIB_LOCATION=/usr/lib/one @@ -34,7 +34,7 @@ fi DRIVER_PATH=$(dirname $0) source ${DRIVER_PATH}/../libfs.sh -# -------- Get cp and datastore arguments from OpenNebula core ------------ +# -------- Get cp and datastore arguments from OpenNebula core ------------ DRV_ACTION=$1 ID=$2 @@ -42,11 +42,11 @@ ID=$2 set_up_datastore $DRV_ACTION XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" -eval "SRC=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/PATH`" +SRC=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/PATH` DST=`generate_image_path` -# ------------ Copy the image to the repository ------------- +# ------------ Copy the image to the repository ------------- case $SRC in http://*) diff --git a/src/datastore_mad/remotes/vmware/mkfs b/src/datastore_mad/remotes/vmware/mkfs index a1dc19fb81..e391694db9 100755 --- a/src/datastore_mad/remotes/vmware/mkfs +++ b/src/datastore_mad/remotes/vmware/mkfs @@ -21,7 +21,7 @@ # as (FS) ############################################################################### -# -------- Set up the environment to source common tools & conf ------------ +# -------- Set up the environment to source common tools & conf ------------ if [ -z "${ONE_LOCATION}" ]; then LIB_LOCATION=/usr/lib/one @@ -34,7 +34,7 @@ fi DRIVER_PATH=$(dirname $0) source ${DRIVER_PATH}/../libfs.sh -# -------- Get mkfs and datastore arguments from OpenNebula core ------------ +# -------- Get mkfs and datastore arguments from OpenNebula core ------------ DRV_ACTION=$1 ID=$2 @@ -42,8 +42,16 @@ ID=$2 set_up_datastore $DRV_ACTION XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" -eval "FSTYPE=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/FSTYPE`" -eval "SIZE=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/SIZE`" + +unset i XPATH_ELEMENTS + +while IFS= read -r -d '' element; do + XPATH_ELEMENTS[i++]="$element" +done < <($XPATH /DS_DRIVER_ACTION_DATA/IMAGE/FSTYPE \ + /DS_DRIVER_ACTION_DATA/IMAGE/SIZE) + +FSTYPE="${XPATH_ELEMENTS[0]}" +SIZE="${XPATH_ELEMENTS[1]}" DST=`generate_image_path` diff --git a/src/datastore_mad/remotes/vmware/rm b/src/datastore_mad/remotes/vmware/rm index d915786ea4..2284c21289 100755 --- a/src/datastore_mad/remotes/vmware/rm +++ b/src/datastore_mad/remotes/vmware/rm @@ -17,10 +17,10 @@ #--------------------------------------------------------------------------- # ############################################################################### -# This script is used to remove a VM image (SRC) from the image repository +# This script is used to remove a VM image (SRC) from the image repository ############################################################################### -# ------------ Set up the environment to source common tools ------------ +# ------------ Set up the environment to source common tools ------------ if [ -z "${ONE_LOCATION}" ]; then LIB_LOCATION=/usr/lib/one @@ -33,15 +33,15 @@ fi DRIVER_PATH=$(dirname $0) source ${DRIVER_PATH}/../libfs.sh -# -------- Get rm and datastore arguments from OpenNebula core ------------ +# -------- Get rm and datastore arguments from OpenNebula core ------------ DRV_ACTION=$1 ID=$2 XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" -eval "SRC=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/SOURCE`" +SRC=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/SOURCE` -# ------------ Remove the image from the repository ------------ +# ------------ Remove the image from the repository ------------ if [ -e $SRC ] ; then log "Removing $SRC from the image repository" diff --git a/src/datastore_mad/remotes/xpath.rb b/src/datastore_mad/remotes/xpath.rb index dad2f13ce6..3cf8af12b5 100755 --- a/src/datastore_mad/remotes/xpath.rb +++ b/src/datastore_mad/remotes/xpath.rb @@ -45,10 +45,11 @@ values = "" tmp = Base64::decode64(tmp64) xml = REXML::Document.new(tmp).root -ARGV.each { |xpath| +ARGV.each do |xpath| element = xml.elements[xpath] - values << "\'#{element.text}\' " if !element.nil? -} + values << element.text if !element.nil? + values << "\0" +end puts values From bb1303c9e6ae08ff042254b3faf03fcb58a4e484 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Wed, 29 Feb 2012 16:15:00 +0100 Subject: [PATCH 084/217] feature #1112: Working mkfs for vmware datastore drivers --- src/datastore_mad/remotes/vmware/mkfs | 28 +++++++++++++++++++++------ src/mad/sh/scripts_common.sh | 3 ++- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/datastore_mad/remotes/vmware/mkfs b/src/datastore_mad/remotes/vmware/mkfs index e391694db9..e7e623c713 100755 --- a/src/datastore_mad/remotes/vmware/mkfs +++ b/src/datastore_mad/remotes/vmware/mkfs @@ -55,17 +55,33 @@ SIZE="${XPATH_ELEMENTS[1]}" DST=`generate_image_path` +DISK=$DST/disk.vmdk +DISK_TMP=$DISK.tmp + +IMAGE_FORMAT=vmdk + +umask 0007 # ------------ Create the image to the repository ------------ -MKFS_CMD=`mkfs_command $DST $FSTYPE` +MKFS_CMD=`mkfs_command $DISK_TMP $FSTYPE` -exec_and_log "$DD if=/dev/zero of=$DST bs=1 count=1 seek=${SIZE}M" \ - "Could not create image $DST" +exec_and_log "mkdir -p $DST" \ + "Could not create disk directory $DST" +exec_and_log "$DD if=/dev/zero of=$DISK_TMP bs=1 count=1 seek=${SIZE}M" \ + "Could not create temporary image $DISK_TMP" exec_and_log "$MKFS_CMD" \ - "Unable to create filesystem $FSTYPE in $DST" -exec_and_log "chmod 0660 $DST" + "Unable to create filesystem $FSTYPE in $DISK_TMP" +exec_and_log "$QEMU_IMG convert -O $IMAGE_FORMAT $DISK_TMP $DISK" \ + "Unable to convert to $IMAGE_FORMAT in $DISK_TMP" +exec_and_log "rm -f $DISK_TMP" \ + "Unable to remove temporary disk $DISK_TMP" +exec_and_log "chmod 0660 $DISK" # ---------------- Get the size of the image ------------ -SIZE=`fs_du $DST` + +SIZE=`$QEMU_IMG info $DISK|grep "^virtual size:"|\ + sed 's/^.*(\([0-9]\+\) bytes.*$/\1/g'` + +SIZE=$(($SIZE/1048576)) echo "$DST $SIZE" diff --git a/src/mad/sh/scripts_common.sh b/src/mad/sh/scripts_common.sh index ea3d484b21..8de8df234d 100755 --- a/src/mad/sh/scripts_common.sh +++ b/src/mad/sh/scripts_common.sh @@ -29,12 +29,13 @@ MD5SUM=md5sum MKFS=mkfs MKISOFS=mkisofs MKSWAP=mkswap +QEMU_IMG=qemu-img +READLINK=readlink SCP=scp SED=sed SSH=ssh SUDO=sudo WGET=wget -READLINK=readlink # Used for log messages SCRIPT_NAME=`basename $0` From 7a487c7308812f2f4cff16eab81d56627c67c89d Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Wed, 29 Feb 2012 16:15:41 +0100 Subject: [PATCH 085/217] feature #1112: Disable 'http://' sources in vmware cp datastore method --- src/datastore_mad/remotes/vmware/cp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/datastore_mad/remotes/vmware/cp b/src/datastore_mad/remotes/vmware/cp index 0a971e25c4..069bd89b72 100755 --- a/src/datastore_mad/remotes/vmware/cp +++ b/src/datastore_mad/remotes/vmware/cp @@ -49,14 +49,6 @@ DST=`generate_image_path` # ------------ Copy the image to the repository ------------- case $SRC in -http://*) - log "Downloading $SRC to the image repository" - - exec_and_log "$WGET -O $DST $SRC" "Error downloading $SRC" - - exec_and_log "chmod 0660 $DST" - ;; - *) if [ `check_restricted $SRC` -eq 1 ]; then log_error "Not allowed to copy images from $RESTRICTED_DIRS" From c3d504293c700f452d2c505e2930cec2a341b869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 29 Feb 2012 16:30:52 +0100 Subject: [PATCH 086/217] Feature #1112: Move datastore to cluster addition from DatastorePool::allocate to RMAllocate --- include/Cluster.h | 12 +++--- include/RequestManagerAllocate.h | 11 ++++- src/cli/onedatastore | 4 +- src/datastore/DatastorePool.cc | 63 ++++++++++++++-------------- src/oca/ruby/OpenNebula/Datastore.rb | 5 ++- src/rm/RequestManagerAllocate.cc | 33 ++++++++++----- 6 files changed, 73 insertions(+), 55 deletions(-) diff --git a/include/Cluster.h b/include/Cluster.h index a6d1184541..fe91731a13 100644 --- a/include/Cluster.h +++ b/include/Cluster.h @@ -45,7 +45,7 @@ public: if ( rc < 0 ) { - error_msg = "ID is already in the set."; + error_msg = "Host ID is already in the cluster set."; } return rc; @@ -63,7 +63,7 @@ public: if ( rc < 0 ) { - error_msg = "ID is not part of the set."; + error_msg = "Host ID is not part of the cluster set."; } return rc; @@ -81,7 +81,7 @@ public: if ( rc < 0 ) { - error_msg = "ID is already in the set."; + error_msg = "Datastore ID is already in the cluster set."; } return rc; @@ -99,7 +99,7 @@ public: if ( rc < 0 ) { - error_msg = "ID is not part of the set."; + error_msg = "Datastore ID is not part of the cluster set."; } return rc; @@ -117,7 +117,7 @@ public: if ( rc < 0 ) { - error_msg = "ID is already in the set."; + error_msg = "Network ID is already in the cluster set."; } return rc; @@ -135,7 +135,7 @@ public: if ( rc < 0 ) { - error_msg = "ID is not part of the set."; + error_msg = "Network ID is not part of the cluster set."; } return rc; diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index cbfeebc714..53bd5299a1 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -333,7 +333,8 @@ public: DatastoreAllocate(): RequestManagerAllocate("DatastoreAllocate", "Allocates a new Datastore", - "A:ss", + "A:ssi", + true, true) { Nebula& nd = Nebula::instance(); @@ -354,7 +355,13 @@ public: Template * tmpl, int& id, string& error_str, - RequestAttributes& att); + RequestAttributes& att, + int cluster_id, + const string& cluster_name); + + int get_cluster_id(xmlrpc_c::paramList const& paramList); + + int add_to_cluster(Cluster* cluster, int id, string& error_msg); }; /* ------------------------------------------------------------------------- */ diff --git a/src/cli/onedatastore b/src/cli/onedatastore index bbcdbf6bd1..8ef00e078b 100755 --- a/src/cli/onedatastore +++ b/src/cli/onedatastore @@ -64,10 +64,10 @@ cmd=CommandParser::CmdParser.new(ARGV) do Creates a new Datastore from the given template file EOT - command :create, create_desc, :file do + command :create, create_desc, :file, :clusterid do helper.create_resource(options) do |datastore| template=File.read(args[0]) - datastore.allocate(template) + datastore.allocate(template, args[1].to_i) end end diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index b4fae8359c..1c47197991 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -45,10 +45,13 @@ DatastorePool::DatastorePool(SqlDB * db): { DatastoreTemplate * ds_tmpl; - int rc; + int rc, system_id, default_id; string base_path; Nebula& nd = Nebula::instance(); + ClusterPool * clpool = nd.get_clpool(); + Cluster * cluster; + base_path = nd.get_var_location() + "datastores/"; // --------------------------------------------------------------------- @@ -69,12 +72,12 @@ DatastorePool::DatastorePool(SqlDB * db): } allocate(ds_tmpl, - &rc, + &system_id, ClusterPool::DEFAULT_CLUSTER_ID, ClusterPool::DEFAULT_CLUSTER_NAME, error_str); - if( rc < 0 ) + if( system_id < 0 ) { goto error_bootstrap; } @@ -98,16 +101,39 @@ DatastorePool::DatastorePool(SqlDB * db): } allocate(ds_tmpl, - &rc, + &default_id, ClusterPool::DEFAULT_CLUSTER_ID, ClusterPool::DEFAULT_CLUSTER_NAME, error_str); - if( rc < 0 ) + if( default_id < 0 ) { goto error_bootstrap; } + // Add to Cluster + cluster = clpool->get(ClusterPool::DEFAULT_CLUSTER_ID, true); + + if( cluster == 0 ) + { + error_str = "Could not get default cluster"; + goto error_bootstrap; + } + + rc = cluster->add_datastore(system_id, error_str); + rc += cluster->add_datastore(default_id, error_str); + + if ( rc != 0 ) + { + cluster->unlock(); + goto error_bootstrap; + } + + clpool->update(cluster); + + cluster->unlock(); + + // User created datastores will start from ID 100 set_update_lastOID(99); } @@ -135,10 +161,6 @@ int DatastorePool::allocate(DatastoreTemplate * ds_template, string name; ostringstream oss; - Nebula& nd = Nebula::instance(); - ClusterPool * clpool; - Cluster * cluster; - ds = new Datastore(-1, ds_template, cluster_id, cluster_name); // ------------------------------------------------------------------------- @@ -166,29 +188,6 @@ int DatastorePool::allocate(DatastoreTemplate * ds_template, *oid = PoolSQL::allocate(ds, error_str); - if ( *oid < 0 ) - { - return *oid; - } - - // Add to Cluster - clpool = nd.get_clpool(); - cluster = clpool->get(cluster_id, true); - - if( cluster == 0 ) - { - return -1; - } - - if ( cluster->add_datastore(*oid, error_str) < 0 ) - { - return -1; - } - - clpool->update(cluster); - - cluster->unlock(); - return *oid; error_name: diff --git a/src/oca/ruby/OpenNebula/Datastore.rb b/src/oca/ruby/OpenNebula/Datastore.rb index f19145e1e6..a2fc8ac8fa 100644 --- a/src/oca/ruby/OpenNebula/Datastore.rb +++ b/src/oca/ruby/OpenNebula/Datastore.rb @@ -63,11 +63,12 @@ module OpenNebula # Allocates a new Datastore in OpenNebula # # @param description [String] The template of the Datastore. + # @param cluster_id [Integer] Id of the cluster # # @return [Integer, OpenNebula::Error] the new ID in case of # success, error otherwise - def allocate(description) - super(DATASTORE_METHODS[:allocate], description) + def allocate(description, cluster_id) + super(DATASTORE_METHODS[:allocate], description, cluster_id) end # Deletes the Datastore diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 88c5404761..d23dc5af5f 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -459,25 +459,36 @@ int GroupAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, /* -------------------------------------------------------------------------- */ int DatastoreAllocate::pool_allocate( - xmlrpc_c::paramList const& paramList, - Template * tmpl, - int& id, - string& error_str, - RequestAttributes& att) + xmlrpc_c::paramList const& paramList, + Template * tmpl, + int& id, + string& error_str, + RequestAttributes& att, + int cluster_id, + const string& cluster_name) { DatastorePool * dspool = static_cast(pool); DatastoreTemplate * ds_tmpl = static_cast(tmpl); - // TODO: include another int parameter for the cluster? - int cluster_id = ClusterPool::DEFAULT_CLUSTER_ID; - string cluster_name = ClusterPool::DEFAULT_CLUSTER_NAME; - - // TODO: Add to auth request CLUSTER MANAGE or ADMIN - return dspool->allocate(ds_tmpl, &id, cluster_id, cluster_name, error_str); } +/* -------------------------------------------------------------------------- */ + +int DatastoreAllocate::get_cluster_id(xmlrpc_c::paramList const& paramList) +{ + return xmlrpc_c::value_int(paramList.getInt(2)); +} + +/* -------------------------------------------------------------------------- */ + +int DatastoreAllocate::add_to_cluster( + Cluster* cluster, int id, string& error_msg) +{ + return cluster->add_datastore(id, error_msg); +} + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ From a04102ce786a0dd263c6ebd8fe888b51caf8324b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 29 Feb 2012 17:00:33 +0100 Subject: [PATCH 087/217] Feature #1112: Refactor RMDelete, hosts and datastores use the same method to be removed from their clusters --- include/RequestManagerDelete.h | 60 +++++++++++++++++++++----- src/rm/RequestManagerDelete.cc | 79 ++++++++++++++++++---------------- 2 files changed, 92 insertions(+), 47 deletions(-) diff --git a/include/RequestManagerDelete.h b/include/RequestManagerDelete.h index 32c2896220..62e1b5073f 100644 --- a/include/RequestManagerDelete.h +++ b/include/RequestManagerDelete.h @@ -31,10 +31,22 @@ class RequestManagerDelete: public Request { protected: RequestManagerDelete(const string& method_name, - const string& help) - :Request(method_name,"A:si",help) + const string& help, + bool _do_cluster=false) + :Request(method_name,"A:si",help), + do_cluster(_do_cluster) { auth_op = AuthRequest::MANAGE; + + if ( do_cluster ) + { + Nebula& nd = Nebula::instance(); + clpool = nd.get_clpool(); + } + else + { + clpool = 0; + } }; ~RequestManagerDelete(){}; @@ -49,15 +61,21 @@ protected: /* -------------------------------------------------------------------- */ - virtual int drop(int oid, PoolObjectSQL * object, string& error_msg) + virtual int drop(int oid, PoolObjectSQL * object, string& error_msg); + + virtual int get_cluster_id(PoolObjectSQL * object) { - int rc = pool->drop(object, error_msg); - - object->unlock(); - - return rc; + return -1; }; + virtual int del_from_cluster(Cluster* cluster, int id, string& error_msg) + { + return -1; + }; + +private: + bool do_cluster; + ClusterPool * clpool; }; @@ -126,7 +144,7 @@ class HostDelete : public RequestManagerDelete { public: HostDelete(): - RequestManagerDelete("HostDelete", "Deletes a host") + RequestManagerDelete("HostDelete", "Deletes a host", true) { Nebula& nd = Nebula::instance(); pool = nd.get_hpool(); @@ -138,7 +156,15 @@ public: /* -------------------------------------------------------------------- */ - int drop(int oid, PoolObjectSQL * object, string& error_msg); + int get_cluster_id(PoolObjectSQL * object) + { + return static_cast(object)->get_cluster_id(); + }; + + int del_from_cluster(Cluster* cluster, int id, string& error_msg) + { + return cluster->del_host(id, error_msg); + }; }; /* ------------------------------------------------------------------------- */ @@ -188,7 +214,7 @@ class DatastoreDelete: public RequestManagerDelete { public: DatastoreDelete(): - RequestManagerDelete("DatastoreDelete", "Deletes a datastore") + RequestManagerDelete("DatastoreDelete", "Deletes a datastore", true) { Nebula& nd = Nebula::instance(); pool = nd.get_dspool(); @@ -197,6 +223,18 @@ public: }; ~DatastoreDelete(){}; + + /* -------------------------------------------------------------------- */ + + int get_cluster_id(PoolObjectSQL * object) + { + return static_cast(object)->get_cluster_id(); + }; + + int del_from_cluster(Cluster* cluster, int id, string& error_msg) + { + return cluster->del_datastore(id, error_msg); + }; }; /* ------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerDelete.cc b/src/rm/RequestManagerDelete.cc index c6a0f627cc..e092c32f6c 100644 --- a/src/rm/RequestManagerDelete.cc +++ b/src/rm/RequestManagerDelete.cc @@ -101,6 +101,49 @@ void RequestManagerDelete::request_execute(xmlrpc_c::paramList const& paramList, return; } +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +int RequestManagerDelete::drop( + int oid, + PoolObjectSQL * object, + string& error_msg) +{ + int cluster_id = -1; + + if ( do_cluster ) + { + cluster_id = get_cluster_id(object); + } + + int rc = pool->drop(object, error_msg); + + object->unlock(); + + if ( do_cluster == true && rc == 0 ) + { + Cluster * cluster = clpool->get(cluster_id, true); + + if( cluster != 0 ) + { + rc = del_from_cluster(cluster, oid, error_msg); + + if ( rc < 0 ) + { + cluster->unlock(); + return rc; + } + + clpool->update(cluster); + + cluster->unlock(); + } + } + + return rc; +} + +/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ int ImageDelete::drop(int oid, PoolObjectSQL * object, string& error_msg) @@ -152,42 +195,6 @@ int ImageDelete::drop(int oid, PoolObjectSQL * object, string& error_msg) } /* ------------------------------------------------------------------------- */ - -int HostDelete::drop(int oid, PoolObjectSQL * object, string& error_msg) -{ - Host * host = static_cast(object); - int cluster_id = host->get_cluster_id(); - - int rc = pool->drop(object, error_msg); - - object->unlock(); - - if ( rc == 0 ) - { - Nebula& nd = Nebula::instance(); - ClusterPool * clpool = nd.get_clpool(); - - Cluster * cluster = clpool->get(cluster_id, true); - - if( cluster != 0 ) - { - rc = cluster->del_host(oid, error_msg); - - if ( rc < 0 ) - { - cluster->unlock(); - return rc; - } - - clpool->update(cluster); - - cluster->unlock(); - } - } - - return rc; -} - /* ------------------------------------------------------------------------- */ int UserDelete::drop(int oid, PoolObjectSQL * object, string& error_msg) From b49a2499435cefefd202829954bdfa9e7fba1a50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 29 Feb 2012 18:09:47 +0100 Subject: [PATCH 088/217] Feature #1112: Associate VNets to Clusters. New VNets are created in the "default" cluster --- include/RequestManagerAllocate.h | 13 ++++++-- include/RequestManagerCluster.h | 40 +++++++++++++++++++++++++ include/RequestManagerDelete.h | 15 +++++++++- include/VirtualNetwork.h | 5 +++- include/VirtualNetworkPool.h | 6 +++- src/cli/one_helper/onecluster_helper.rb | 5 ++++ src/cli/onecluster | 11 +++++++ src/oca/ruby/OpenNebula/Cluster.rb | 39 +++++++++++++++++++++++- src/rm/RequestManager.cc | 2 ++ src/rm/RequestManagerAllocate.cc | 30 +++++++++++++++---- src/vnm/VirtualNetwork.cc | 28 ++++++++++------- src/vnm/VirtualNetworkPool.cc | 5 +++- 12 files changed, 175 insertions(+), 24 deletions(-) diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index 53bd5299a1..cc33edf888 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -156,6 +156,7 @@ public: RequestManagerAllocate("VirtualNetworkAllocate", "Allocates a new virtual network", "A:ss", + true, true) { Nebula& nd = Nebula::instance(); @@ -172,11 +173,17 @@ public: return new VirtualNetworkTemplate; }; - int pool_allocate(xmlrpc_c::paramList const& _paramList, + int pool_allocate(xmlrpc_c::paramList const& _paramList, Template * tmpl, - int& id, + int& id, string& error_str, - RequestAttributes& att); + RequestAttributes& att, + int cluster_id, + const string& cluster_name); + + int get_cluster_id(xmlrpc_c::paramList const& paramList); + + int add_to_cluster(Cluster* cluster, int id, string& error_msg); }; /* ------------------------------------------------------------------------- */ diff --git a/include/RequestManagerCluster.h b/include/RequestManagerCluster.h index c90cb124e4..10215710a5 100644 --- a/include/RequestManagerCluster.h +++ b/include/RequestManagerCluster.h @@ -38,6 +38,7 @@ protected: clpool = nd.get_clpool(); hpool = nd.get_hpool(); dspool = nd.get_dspool(); + vnpool = nd.get_vnpool(); auth_object = PoolObjectSQL::CLUSTER; auth_op = AuthRequest::ADMIN; @@ -50,6 +51,7 @@ protected: ClusterPool * clpool; HostPool * hpool; DatastorePool * dspool; + VirtualNetworkPool * vnpool; /* --------------------------------------------------------------------- */ @@ -145,6 +147,44 @@ public: }; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ClusterAddVNet : public RequestManagerCluster +{ +public: + ClusterAddVNet(): + RequestManagerCluster("ClusterAddVNet", + "Adds a virtual network to the cluster", + "A:sii"){}; + + ~ClusterAddVNet(){}; + + void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att) + { + return add_generic(_paramList, att, vnpool, PoolObjectSQL::NET); + } + + virtual int add_object(Cluster* cluster, int id, string& error_msg) + { + return cluster->add_vnet(id, error_msg); + }; + + virtual int del_object(Cluster* cluster, int id, string& error_msg) + { + return cluster->del_vnet(id, error_msg); + }; + + virtual void get(int oid, bool lock, PoolObjectSQL ** object, Clusterable ** cluster_obj) + { + VirtualNetwork * vnet = vnpool->get(oid, lock); + + *object = static_cast(vnet); + *cluster_obj = static_cast(vnet); + }; +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerDelete.h b/include/RequestManagerDelete.h index 62e1b5073f..9be4b1e616 100644 --- a/include/RequestManagerDelete.h +++ b/include/RequestManagerDelete.h @@ -105,7 +105,8 @@ class VirtualNetworkDelete: public RequestManagerDelete public: VirtualNetworkDelete(): RequestManagerDelete("VirtualNetworkDelete", - "Deletes a virtual network") + "Deletes a virtual network", + true) { Nebula& nd = Nebula::instance(); pool = nd.get_vnpool(); @@ -113,6 +114,18 @@ public: }; ~VirtualNetworkDelete(){}; + + /* -------------------------------------------------------------------- */ + + int get_cluster_id(PoolObjectSQL * object) + { + return static_cast(object)->get_cluster_id(); + }; + + int del_from_cluster(Cluster* cluster, int id, string& error_msg) + { + return cluster->del_vnet(id, error_msg); + }; }; /* ------------------------------------------------------------------------- */ diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index 6fa7df2024..161bdd77b8 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -21,6 +21,7 @@ #include "PoolSQL.h" #include "Leases.h" #include "VirtualNetworkTemplate.h" +#include "Clusterable.h" #include #include @@ -39,7 +40,7 @@ using namespace std; * leases. One lease is formed by one IP and one MAC address. * MAC address are derived from IP addresses. */ -class VirtualNetwork : public PoolObjectSQL +class VirtualNetwork : public PoolObjectSQL, public Clusterable { public: @@ -287,6 +288,8 @@ private: int gid, const string& _uname, const string& _gname, + int _cluster_id, + const string& _cluster_name, VirtualNetworkTemplate * _vn_template = 0); ~VirtualNetwork(); diff --git a/include/VirtualNetworkPool.h b/include/VirtualNetworkPool.h index 431f55c49d..9c0446c018 100644 --- a/include/VirtualNetworkPool.h +++ b/include/VirtualNetworkPool.h @@ -45,6 +45,8 @@ public: * @param gid the id of the group this object is assigned to * @param vn_template a VirtualNetworkTemplate describing the VNET * @param oid the id assigned to the VM (output) + * @param cluster_id the id of the cluster this VNET will belong to + * @param cluster_name the name of the cluster this VNET will belong to * @param error_str Returns the error reason, if any * @return oid on success, -1 error */ @@ -55,6 +57,8 @@ public: const string& gname, VirtualNetworkTemplate * vn_template, int * oid, + int cluster_id, + const string& cluster_name, string& error_str); /** @@ -163,7 +167,7 @@ private: */ PoolObjectSQL * create() { - return new VirtualNetwork(-1,-1,"","",0); + return new VirtualNetwork(-1,-1,"","",-1,"",0); }; /** diff --git a/src/cli/one_helper/onecluster_helper.rb b/src/cli/one_helper/onecluster_helper.rb index bc72c25193..d709b4808c 100644 --- a/src/cli/one_helper/onecluster_helper.rb +++ b/src/cli/one_helper/onecluster_helper.rb @@ -78,5 +78,10 @@ class OneClusterHelper < OpenNebulaHelper::OneHelper puts "%-15s" % [id] end + puts + CLIHelper.print_header("%-15s" % ["VNETS"]) + cluster.vnet_ids.each do |id| + puts "%-15s" % [id] + end end end diff --git a/src/cli/onecluster b/src/cli/onecluster index f74837f06f..7b4bd58df4 100755 --- a/src/cli/onecluster +++ b/src/cli/onecluster @@ -117,4 +117,15 @@ cmd=CommandParser::CmdParser.new(ARGV) do cluster.adddatastore(args[1].to_i) end end + + addvnet_desc = <<-EOT.unindent + Adds a Virtual Network to the given Cluster + EOT + + # TODO: allow the second param to be [:range, :vnetid_list] + command :addvnet, addvnet_desc,:clusterid, :vnetid do + helper.perform_actions(args[0],options,"updated") do |cluster| + cluster.addvnet(args[1].to_i) + end + end end diff --git a/src/oca/ruby/OpenNebula/Cluster.rb b/src/oca/ruby/OpenNebula/Cluster.rb index 70888465b4..1190594d24 100644 --- a/src/oca/ruby/OpenNebula/Cluster.rb +++ b/src/oca/ruby/OpenNebula/Cluster.rb @@ -28,7 +28,8 @@ module OpenNebula :allocate => "cluster.allocate", :delete => "cluster.delete", :addhost => "cluster.addhost", - :adddatastore => "cluster.adddatastore" + :adddatastore => "cluster.adddatastore", + :addvnet => "cluster.addvnet" } # Creates a Cluster description with just its identifier @@ -100,6 +101,19 @@ module OpenNebula return rc end + # Adds a VNet to this Cluster + # @param vnet_id [Integer] VNet ID + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def addvnet(vnet_id) + return Error.new('ID not defined') if !@pe_id + + rc = @client.call(CLUSTER_METHODS[:addvnet], @pe_id, vnet_id) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + # --------------------------------------------------------------------- # Helpers to get information # --------------------------------------------------------------------- @@ -149,5 +163,28 @@ module OpenNebula return array end + + # Returns whether or not the vnet with 'id' is part of this cluster + # @param id [Integer] vnet ID + # @return [Boolean] true if found + def contains_vnet(id) + #This doesn't work in ruby 1.8.5 + #return self["HOSTS/ID[.=#{uid}]"] != nil + + id_array = retrieve_elements('VNETS/ID') + return id_array != nil && id_array.include?(id.to_s) + end + + # Returns an array with the numeric vnet ids + # @return [Array] + def vnet_ids + array = Array.new + + self.each("VNETS/ID") do |id| + array << id.text.to_i + end + + return array + end end end diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 81122d3dfd..83f22f7965 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -328,6 +328,7 @@ void RequestManager::register_xml_methods() // Cluster Methods xmlrpc_c::methodPtr cluster_addhost(new ClusterAddHost()); xmlrpc_c::methodPtr cluster_addds(new ClusterAddDatastore()); + xmlrpc_c::methodPtr cluster_addvnet(new ClusterAddVNet()); /* VM related methods */ RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy); @@ -424,6 +425,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.cluster.info", cluster_info); RequestManagerRegistry.addMethod("one.cluster.addhost", cluster_addhost); RequestManagerRegistry.addMethod("one.cluster.adddatastore", cluster_addds); + RequestManagerRegistry.addMethod("one.cluster.addvnet", cluster_addvnet); RequestManagerRegistry.addMethod("one.clusterpool.info",clusterpool_info); }; diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index d23dc5af5f..5e43f72567 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -218,17 +218,35 @@ int VirtualMachineAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VirtualNetworkAllocate::pool_allocate(xmlrpc_c::paramList const& _paramList, - Template * tmpl, - int& id, - string& error_str, - RequestAttributes& att) +int VirtualNetworkAllocate::pool_allocate( + xmlrpc_c::paramList const& paramList, + Template * tmpl, + int& id, + string& error_str, + RequestAttributes& att, + int cluster_id, + const string& cluster_name) { VirtualNetworkPool * vpool = static_cast(pool); VirtualNetworkTemplate * vtmpl=static_cast(tmpl); return vpool->allocate(att.uid, att.gid, att.uname, att.gname, vtmpl, &id, - error_str); + cluster_id, cluster_name, error_str); +} + +/* -------------------------------------------------------------------------- */ + +int VirtualNetworkAllocate::get_cluster_id(xmlrpc_c::paramList const& paramList) +{ + return ClusterPool::DEFAULT_CLUSTER_ID; +} + +/* -------------------------------------------------------------------------- */ + +int VirtualNetworkAllocate::add_to_cluster( + Cluster* cluster, int id, string& error_msg) +{ + return cluster->add_vnet(id, error_msg); } /* -------------------------------------------------------------------------- */ diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index 38a8366746..81faa2928c 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -35,8 +35,11 @@ VirtualNetwork::VirtualNetwork(int _uid, int _gid, const string& _uname, const string& _gname, + int _cluster_id, + const string& _cluster_name, VirtualNetworkTemplate * _vn_template): PoolObjectSQL(-1,NET,"",_uid,_gid,_uname,_gname,table), + Clusterable(_cluster_id, _cluster_name), bridge(""), type(UNINITIALIZED), leases(0) @@ -474,16 +477,18 @@ string& VirtualNetwork::to_xml_extended(string& xml, bool extended) const os << "" << - "" << oid << "" << - "" << uid << "" << - "" << gid << "" << - "" << uname << "" << - "" << gname << "" << - "" << name << "" << - perms_to_xml(perm_str) << - "" << type << "" << - "" << bridge << ""<< - "" << vlan << ""; + "" << oid << "" << + "" << uid << "" << + "" << gid << "" << + "" << uname << "" << + "" << gname << "" << + "" << name << "" << + perms_to_xml(perm_str) << + "" << cluster_id << "" << + "" << cluster << "" << + "" << type << "" << + "" << bridge << ""<< + "" << vlan << ""; if (!phydev.empty()) { @@ -566,6 +571,9 @@ int VirtualNetwork::from_xml(const string &xml_str) rc += xpath(bridge, "/VNET/BRIDGE", "not_found"); rc += xpath(vlan, "/VNET/VLAN", 0); + rc += xpath(cluster_id, "/VNET/CLUSTER_ID", -1); + rc += xpath(cluster, "/VNET/CLUSTER", "not_found"); + // Permissions rc += perms_from_xml(); diff --git a/src/vnm/VirtualNetworkPool.cc b/src/vnm/VirtualNetworkPool.cc index 123a8882bd..348863b813 100644 --- a/src/vnm/VirtualNetworkPool.cc +++ b/src/vnm/VirtualNetworkPool.cc @@ -78,6 +78,8 @@ int VirtualNetworkPool::allocate ( const string& gname, VirtualNetworkTemplate * vn_template, int * oid, + int cluster_id, + const string& cluster_name, string& error_str) { VirtualNetwork * vn; @@ -85,7 +87,8 @@ int VirtualNetworkPool::allocate ( string name; ostringstream oss; - vn = new VirtualNetwork(uid, gid, uname, gname, vn_template); + vn = new VirtualNetwork(uid, gid, uname, gname, + cluster_id, cluster_name, vn_template); // Check name vn->get_template_attribute("NAME", name); From 55b4b9510a528cf39c2275c05f6d45048a7959e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 1 Mar 2012 14:59:19 +0100 Subject: [PATCH 089/217] Feature #1112: DS base_path is set by the core in /var/lib/one/datastores/$ID --- include/Nebula.h | 13 +++++++++++++ install.sh | 8 ++++---- src/datastore/Datastore.cc | 19 +++++++++---------- src/datastore/DatastorePool.cc | 5 ----- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/include/Nebula.h b/include/Nebula.h index 5cb6c9017f..02386d2adf 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -208,6 +208,16 @@ public: return var_location; }; + /** + * Returns the default var location. When ONE_LOCATION is defined this path + * points to $ONE_LOCATION/var, otherwise it is /var/lib/one. + * @return the log location. + */ + const string& get_ds_location() + { + return ds_location; + }; + /** * Returns the base for the system datastore (for tmp VM images). When * ONE_LOCATION is defined this path points to $ONE_LOCATION/var/system_ds, @@ -353,6 +363,7 @@ private: log_location = "/var/log/one/"; var_location = "/var/lib/one/"; remotes_location = "/var/lib/one/remotes/"; + ds_location = "/var/lib/one/datastores/"; } else { @@ -368,6 +379,7 @@ private: log_location = nebula_location + "var/"; var_location = nebula_location + "var/"; remotes_location = nebula_location + "var/remotes/"; + ds_location = nebula_location + "var/datastores/"; } }; @@ -495,6 +507,7 @@ private: string var_location; string hook_location; string remotes_location; + string ds_location; string hostname; diff --git a/install.sh b/install.sh index 7f48651ceb..0c2304050e 100755 --- a/install.sh +++ b/install.sh @@ -99,8 +99,8 @@ if [ -z "$ROOT" ] ; then VAR_LOCATION="/var/lib/one" SUNSTONE_LOCATION="$LIB_LOCATION/sunstone" OZONES_LOCATION="$LIB_LOCATION/ozones" - SYSTEM_DS_LOCATION="$VAR_LOCATION/datastores/system" - DEFAULT_DS_LOCATION="$VAR_LOCATION/datastores/default" + SYSTEM_DS_LOCATION="$VAR_LOCATION/datastores/0" + DEFAULT_DS_LOCATION="$VAR_LOCATION/datastores/1" RUN_LOCATION="/var/run/one" LOCK_LOCATION="/var/lock/one" INCLUDE_LOCATION="/usr/include" @@ -146,8 +146,8 @@ else VAR_LOCATION="$ROOT/var" SUNSTONE_LOCATION="$LIB_LOCATION/sunstone" OZONES_LOCATION="$LIB_LOCATION/ozones" - SYSTEM_DS_LOCATION="$VAR_LOCATION/datastores/system" - DEFAULT_DS_LOCATION="$VAR_LOCATION/datastores/default" + SYSTEM_DS_LOCATION="$VAR_LOCATION/datastores/0" + DEFAULT_DS_LOCATION="$VAR_LOCATION/datastores/1" INCLUDE_LOCATION="$ROOT/include" SHARE_LOCATION="$ROOT/share" MAN_LOCATION="$ROOT/share/man/man1" diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index 159dab849b..14d75fcfe0 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -17,6 +17,7 @@ #include "Datastore.h" #include "GroupPool.h" #include "NebulaLog.h" +#include "Nebula.h" const char * Datastore::table = "datastore_pool"; @@ -79,7 +80,10 @@ int Datastore::disk_attribute(VectorAttribute * disk) int Datastore::insert(SqlDB *db, string& error_str) { - int rc; + int rc; + ostringstream oss; + + Nebula& nd = Nebula::instance(); // --------------------------------------------------------------------- // Check default datastore attributes @@ -102,12 +106,11 @@ int Datastore::insert(SqlDB *db, string& error_str) goto error_tm; } - erase_template_attribute("BASE_PATH", base_path); + oss << nd.get_ds_location() << oid; - if ( base_path.empty() == true ) - { - goto error_base_path; - } + base_path = oss.str(); + + replace_template_attribute("BASE_PATH", base_path); //-------------------------------------------------------------------------- // Insert the Datastore @@ -125,10 +128,6 @@ error_tm: error_str = "No TM_MAD in template."; goto error_common; -error_base_path: - error_str = "No BASE_PATH in template."; - goto error_common; - error_common: NebulaLog::log("DATASTORE", Log::ERROR, error_str); return -1; diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index 1c47197991..7bec974218 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -46,20 +46,16 @@ DatastorePool::DatastorePool(SqlDB * db): DatastoreTemplate * ds_tmpl; int rc, system_id, default_id; - string base_path; Nebula& nd = Nebula::instance(); ClusterPool * clpool = nd.get_clpool(); Cluster * cluster; - base_path = nd.get_var_location() + "datastores/"; - // --------------------------------------------------------------------- // Create the system datastore // --------------------------------------------------------------------- oss << "NAME = " << SYSTEM_DS_NAME << endl - << "BASE_PATH = " << base_path << "system"<< endl << "TYPE = fs" << endl << "TM_MAD = shared"; @@ -88,7 +84,6 @@ DatastorePool::DatastorePool(SqlDB * db): oss.str(""); oss << "NAME = " << DEFAULT_DS_NAME << endl - << "BASE_PATH = " << base_path << "default" << endl << "TYPE = fs" << endl << "TM_MAD = shared"; From 9a7d78f7f2fbf579d3488199f4423421ba3b8fb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 1 Mar 2012 17:14:52 +0100 Subject: [PATCH 090/217] Feature #1112: Hosts, DS & VNets can belong to the 'none' cluster. The cluster id -1 is used to indicate objects that can be clustered, but are not assigned to any cluster. The new methods to remove objects from their current datastore actually set this 'none' or -1 cluster ID. VNets are always created in this 'none' cluster. Hosts and DS require a cluster ID to be placed when allocated, and the ruby OCA by default sets it to 'none' --- include/ClusterPool.h | 10 ++ include/RequestManagerAllocate.h | 48 +++--- include/RequestManagerCluster.h | 193 +++++++++++++++++++++---- include/RequestManagerDelete.h | 27 +--- src/cli/onecluster | 33 +++++ src/cli/onedatastore | 9 +- src/cluster/ClusterPool.cc | 3 + src/oca/ruby/OpenNebula/Cluster.rb | 44 +++++- src/oca/ruby/OpenNebula/ClusterPool.rb | 1 + src/oca/ruby/OpenNebula/Datastore.rb | 2 +- src/oca/ruby/OpenNebula/Host.rb | 2 +- src/rm/RequestManager.cc | 7 + src/rm/RequestManagerAllocate.cc | 59 ++------ src/rm/RequestManagerCluster.cc | 130 +++++++++-------- src/rm/RequestManagerDelete.cc | 9 +- 15 files changed, 386 insertions(+), 191 deletions(-) diff --git a/include/ClusterPool.h b/include/ClusterPool.h index bd9e487afc..78c47d4af1 100644 --- a/include/ClusterPool.h +++ b/include/ClusterPool.h @@ -44,6 +44,16 @@ public: */ static const int DEFAULT_CLUSTER_ID; + /** + * Name for the "none" cluster + */ + static const string NONE_CLUSTER_NAME; + + /** + * Identifier for the "none" cluster + */ + static const int NONE_CLUSTER_ID; + /* ---------------------------------------------------------------------- */ /* Methods for DB management */ /* ---------------------------------------------------------------------- */ diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index cc33edf888..9522314868 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -37,21 +37,13 @@ protected: RequestManagerAllocate(const string& method_name, const string& help, const string& xml_args, - bool dt, - bool dc=false) - :Request(method_name,xml_args,help), do_template(dt), do_cluster(dc) + bool dt) + :Request(method_name,xml_args,help), do_template(dt) { auth_op = AuthRequest::CREATE; - if ( do_cluster ) - { - Nebula& nd = Nebula::instance(); - clpool = nd.get_clpool(); - } - else - { - clpool = 0; - } + Nebula& nd = Nebula::instance(); + clpool = nd.get_clpool(); }; ~RequestManagerAllocate(){}; @@ -91,7 +83,7 @@ protected: virtual int get_cluster_id(xmlrpc_c::paramList const& paramList) { - return -1; + return ClusterPool::NONE_CLUSTER_ID; }; virtual int add_to_cluster(Cluster* cluster, int id, string& error_msg) @@ -105,7 +97,6 @@ protected: private: bool do_template; - bool do_cluster; }; @@ -156,7 +147,6 @@ public: RequestManagerAllocate("VirtualNetworkAllocate", "Allocates a new virtual network", "A:ss", - true, true) { Nebula& nd = Nebula::instance(); @@ -180,10 +170,6 @@ public: RequestAttributes& att, int cluster_id, const string& cluster_name); - - int get_cluster_id(xmlrpc_c::paramList const& paramList); - - int add_to_cluster(Cluster* cluster, int id, string& error_msg); }; /* ------------------------------------------------------------------------- */ @@ -254,8 +240,7 @@ public: RequestManagerAllocate("HostAllocate", "Allocates a new host", "A:sssssi", - false, - true) + false) { Nebula& nd = Nebula::instance(); pool = nd.get_hpool(); @@ -274,9 +259,15 @@ public: int cluster_id, const string& cluster_name); - int get_cluster_id(xmlrpc_c::paramList const& paramList); + int get_cluster_id(xmlrpc_c::paramList const& paramList) + { + return xmlrpc_c::value_int(paramList.getInt(5)); + }; - int add_to_cluster(Cluster* cluster, int id, string& error_msg); + int add_to_cluster(Cluster* cluster, int id, string& error_msg) + { + return cluster->add_host(id, error_msg); + }; }; /* ------------------------------------------------------------------------- */ @@ -341,7 +332,6 @@ public: RequestManagerAllocate("DatastoreAllocate", "Allocates a new Datastore", "A:ssi", - true, true) { Nebula& nd = Nebula::instance(); @@ -366,9 +356,15 @@ public: int cluster_id, const string& cluster_name); - int get_cluster_id(xmlrpc_c::paramList const& paramList); + int get_cluster_id(xmlrpc_c::paramList const& paramList) + { + return xmlrpc_c::value_int(paramList.getInt(2)); + }; - int add_to_cluster(Cluster* cluster, int id, string& error_msg); + int add_to_cluster(Cluster* cluster, int id, string& error_msg) + { + return cluster->add_datastore(id, error_msg); + }; }; /* ------------------------------------------------------------------------- */ diff --git a/include/RequestManagerCluster.h b/include/RequestManagerCluster.h index 10215710a5..22ab693207 100644 --- a/include/RequestManagerCluster.h +++ b/include/RequestManagerCluster.h @@ -55,11 +55,12 @@ protected: /* --------------------------------------------------------------------- */ - virtual void request_execute(xmlrpc_c::paramList const& _paramList, + virtual void request_execute(xmlrpc_c::paramList const& paramList, RequestAttributes& att) = 0; void add_generic( - xmlrpc_c::paramList const& _paramList, + int cluster_id, + int object_id, RequestAttributes& att, PoolSQL * pool, PoolObjectSQL::ObjectType type); @@ -74,21 +75,16 @@ protected: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ -class ClusterAddHost : public RequestManagerCluster +class RequestManagerClusterHost : public RequestManagerCluster { public: - ClusterAddHost(): - RequestManagerCluster("ClusterAddHost", - "Adds a host to the cluster", - "A:sii"){}; + RequestManagerClusterHost( + const string& method_name, + const string& help, + const string& params): + RequestManagerCluster(method_name, help, params){}; - ~ClusterAddHost(){}; - - void request_execute(xmlrpc_c::paramList const& _paramList, - RequestAttributes& att) - { - return add_generic(_paramList, att, hpool, PoolObjectSQL::HOST); - } + ~RequestManagerClusterHost(){}; virtual int add_object(Cluster* cluster, int id, string& error_msg) { @@ -112,21 +108,66 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ -class ClusterAddDatastore : public RequestManagerCluster +class ClusterAddHost : public RequestManagerClusterHost { public: - ClusterAddDatastore(): - RequestManagerCluster("ClusterAddDatastore", - "Adds a datastore to the cluster", + ClusterAddHost(): + RequestManagerClusterHost("ClusterAddHost", + "Adds a host to the cluster", "A:sii"){}; - ~ClusterAddDatastore(){}; + ~ClusterAddHost(){}; - void request_execute(xmlrpc_c::paramList const& _paramList, + void request_execute(xmlrpc_c::paramList const& paramList, RequestAttributes& att) { - return add_generic(_paramList, att, dspool, PoolObjectSQL::DATASTORE); + int cluster_id = xmlrpc_c::value_int(paramList.getInt(1)); + int object_id = xmlrpc_c::value_int(paramList.getInt(2)); + + return add_generic(cluster_id, object_id, att, + hpool, PoolObjectSQL::HOST); } +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ClusterDelHost : public RequestManagerClusterHost +{ +public: + ClusterDelHost(): + RequestManagerClusterHost("ClusterDelHost", + "Deletes a host from its cluster", + "A:sii"){}; + + ~ClusterDelHost(){}; + + void request_execute(xmlrpc_c::paramList const& paramList, + RequestAttributes& att) + { + // First param is ignored, as objects can be assigned to only + // one cluster + int cluster_id = ClusterPool::NONE_CLUSTER_ID; + int object_id = xmlrpc_c::value_int(paramList.getInt(2)); + + return add_generic(cluster_id, object_id, att, + hpool, PoolObjectSQL::HOST); + } +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class RequestManagerClusterDatastore : public RequestManagerCluster +{ +public: + RequestManagerClusterDatastore( + const string& method_name, + const string& help, + const string& params): + RequestManagerCluster(method_name, help, params){}; + + ~RequestManagerClusterDatastore(){}; virtual int add_object(Cluster* cluster, int id, string& error_msg) { @@ -150,21 +191,67 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ -class ClusterAddVNet : public RequestManagerCluster +class ClusterAddDatastore : public RequestManagerClusterDatastore { public: - ClusterAddVNet(): - RequestManagerCluster("ClusterAddVNet", - "Adds a virtual network to the cluster", + ClusterAddDatastore(): + RequestManagerClusterDatastore("ClusterAddDatastore", + "Adds a datastore to the cluster", "A:sii"){}; - ~ClusterAddVNet(){}; + ~ClusterAddDatastore(){}; - void request_execute(xmlrpc_c::paramList const& _paramList, + void request_execute(xmlrpc_c::paramList const& paramList, RequestAttributes& att) { - return add_generic(_paramList, att, vnpool, PoolObjectSQL::NET); + int cluster_id = xmlrpc_c::value_int(paramList.getInt(1)); + int object_id = xmlrpc_c::value_int(paramList.getInt(2)); + + return add_generic(cluster_id, object_id, att, + dspool, PoolObjectSQL::DATASTORE); } +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ClusterDelDatastore : public RequestManagerClusterDatastore +{ +public: + ClusterDelDatastore(): + RequestManagerClusterDatastore("ClusterDelDatastore", + "Deletes a datastore from its cluster", + "A:sii"){}; + + ~ClusterDelDatastore(){}; + + void request_execute(xmlrpc_c::paramList const& paramList, + RequestAttributes& att) + { + // First param is ignored, as objects can be assigned to only + // one cluster + int cluster_id = ClusterPool::NONE_CLUSTER_ID; + int object_id = xmlrpc_c::value_int(paramList.getInt(2)); + + return add_generic(cluster_id, object_id, att, + dspool, PoolObjectSQL::DATASTORE); + } +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class RequestManagerClusterVNet : public RequestManagerCluster +{ +public: + + RequestManagerClusterVNet( + const string& method_name, + const string& help, + const string& params): + RequestManagerCluster(method_name, help, params){}; + + ~RequestManagerClusterVNet(){}; virtual int add_object(Cluster* cluster, int id, string& error_msg) { @@ -185,6 +272,56 @@ public: }; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ClusterAddVNet : public RequestManagerClusterVNet +{ +public: + ClusterAddVNet(): + RequestManagerClusterVNet("ClusterAddVNet", + "Adds a virtual network to the cluster", + "A:sii"){}; + + ~ClusterAddVNet(){}; + + void request_execute(xmlrpc_c::paramList const& paramList, + RequestAttributes& att) + { + int cluster_id = xmlrpc_c::value_int(paramList.getInt(1)); + int object_id = xmlrpc_c::value_int(paramList.getInt(2)); + + return add_generic(cluster_id, object_id, att, + vnpool, PoolObjectSQL::NET); + } +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ClusterDelVNet : public RequestManagerClusterVNet +{ +public: + ClusterDelVNet(): + RequestManagerClusterVNet("ClusterDelVNet", + "Deletes a virtual network from its cluster", + "A:sii"){}; + + ~ClusterDelVNet(){}; + + void request_execute(xmlrpc_c::paramList const& paramList, + RequestAttributes& att) + { + // First param is ignored, as objects can be assigned to only + // one cluster + int cluster_id = ClusterPool::NONE_CLUSTER_ID; + int object_id = xmlrpc_c::value_int(paramList.getInt(2)); + + return add_generic(cluster_id, object_id, att, + vnpool, PoolObjectSQL::NET); + } +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerDelete.h b/include/RequestManagerDelete.h index 9be4b1e616..0eaf8c6359 100644 --- a/include/RequestManagerDelete.h +++ b/include/RequestManagerDelete.h @@ -31,22 +31,13 @@ class RequestManagerDelete: public Request { protected: RequestManagerDelete(const string& method_name, - const string& help, - bool _do_cluster=false) - :Request(method_name,"A:si",help), - do_cluster(_do_cluster) + const string& help) + :Request(method_name,"A:si",help) { auth_op = AuthRequest::MANAGE; - if ( do_cluster ) - { - Nebula& nd = Nebula::instance(); - clpool = nd.get_clpool(); - } - else - { - clpool = 0; - } + Nebula& nd = Nebula::instance(); + clpool = nd.get_clpool(); }; ~RequestManagerDelete(){}; @@ -65,7 +56,7 @@ protected: virtual int get_cluster_id(PoolObjectSQL * object) { - return -1; + return ClusterPool::NONE_CLUSTER_ID; }; virtual int del_from_cluster(Cluster* cluster, int id, string& error_msg) @@ -74,7 +65,6 @@ protected: }; private: - bool do_cluster; ClusterPool * clpool; }; @@ -105,8 +95,7 @@ class VirtualNetworkDelete: public RequestManagerDelete public: VirtualNetworkDelete(): RequestManagerDelete("VirtualNetworkDelete", - "Deletes a virtual network", - true) + "Deletes a virtual network") { Nebula& nd = Nebula::instance(); pool = nd.get_vnpool(); @@ -157,7 +146,7 @@ class HostDelete : public RequestManagerDelete { public: HostDelete(): - RequestManagerDelete("HostDelete", "Deletes a host", true) + RequestManagerDelete("HostDelete", "Deletes a host") { Nebula& nd = Nebula::instance(); pool = nd.get_hpool(); @@ -227,7 +216,7 @@ class DatastoreDelete: public RequestManagerDelete { public: DatastoreDelete(): - RequestManagerDelete("DatastoreDelete", "Deletes a datastore", true) + RequestManagerDelete("DatastoreDelete", "Deletes a datastore") { Nebula& nd = Nebula::instance(); pool = nd.get_dspool(); diff --git a/src/cli/onecluster b/src/cli/onecluster index 7b4bd58df4..07b0fc1ae8 100755 --- a/src/cli/onecluster +++ b/src/cli/onecluster @@ -107,6 +107,17 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end + delhost_desc = <<-EOT.unindent + Deletes a Host from the given Cluster + EOT + + # TODO: allow the second param to be [:range, :hostid_list] + command :delhost, delhost_desc, :clusterid, :hostid do + helper.perform_actions(args[0],options,"updated") do |cluster| + cluster.delhost(args[1].to_i) + end + end + adddatastore_desc = <<-EOT.unindent Adds a Datastore to the given Cluster EOT @@ -118,6 +129,17 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end + deldatastore_desc = <<-EOT.unindent + Deletes a Datastore from the given Cluster + EOT + + # TODO: allow the second param to be [:range, :datastoreid_list] + command :deldatastore, deldatastore_desc, :clusterid, :datastoreid do + helper.perform_actions(args[0],options,"updated") do |cluster| + cluster.deldatastore(args[1].to_i) + end + end + addvnet_desc = <<-EOT.unindent Adds a Virtual Network to the given Cluster EOT @@ -128,4 +150,15 @@ cmd=CommandParser::CmdParser.new(ARGV) do cluster.addvnet(args[1].to_i) end end + + delvnet_desc = <<-EOT.unindent + Deletes a Virtual Network from the given Cluster + EOT + + # TODO: allow the second param to be [:range, :vnetid_list] + command :delvnet, delvnet_desc,:clusterid, :vnetid do + helper.perform_actions(args[0],options,"updated") do |cluster| + cluster.delvnet(args[1].to_i) + end + end end diff --git a/src/cli/onedatastore b/src/cli/onedatastore index 8ef00e078b..5f30f913ce 100755 --- a/src/cli/onedatastore +++ b/src/cli/onedatastore @@ -64,10 +64,15 @@ cmd=CommandParser::CmdParser.new(ARGV) do Creates a new Datastore from the given template file EOT - command :create, create_desc, :file, :clusterid do + command :create, create_desc, :file, [:clusterid, nil] do helper.create_resource(options) do |datastore| template=File.read(args[0]) - datastore.allocate(template, args[1].to_i) + + if args.size == 1 + datastore.allocate(template) + else + datastore.allocate(template, args[1].to_i) + end end end diff --git a/src/cluster/ClusterPool.cc b/src/cluster/ClusterPool.cc index 266b41aff4..94de028dbc 100644 --- a/src/cluster/ClusterPool.cc +++ b/src/cluster/ClusterPool.cc @@ -29,6 +29,9 @@ const string ClusterPool::DEFAULT_CLUSTER_NAME = "default"; const int ClusterPool::DEFAULT_CLUSTER_ID = 0; +const string ClusterPool::NONE_CLUSTER_NAME = "none"; +const int ClusterPool::NONE_CLUSTER_ID = -1; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/oca/ruby/OpenNebula/Cluster.rb b/src/oca/ruby/OpenNebula/Cluster.rb index 1190594d24..08d8a0b861 100644 --- a/src/oca/ruby/OpenNebula/Cluster.rb +++ b/src/oca/ruby/OpenNebula/Cluster.rb @@ -28,8 +28,11 @@ module OpenNebula :allocate => "cluster.allocate", :delete => "cluster.delete", :addhost => "cluster.addhost", + :delhost => "cluster.delhost", :adddatastore => "cluster.adddatastore", - :addvnet => "cluster.addvnet" + :deldatastore => "cluster.deldatastore", + :addvnet => "cluster.addvnet", + :delvnet => "cluster.delvnet" } # Creates a Cluster description with just its identifier @@ -88,6 +91,19 @@ module OpenNebula return rc end + # Deletes a Host from this Cluster + # @param hid [Integer] Host ID + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def delhost(hid) + return Error.new('ID not defined') if !@pe_id + + rc = @client.call(CLUSTER_METHODS[:delhost], @pe_id, hid) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + # Adds a Datastore to this Cluster # @param ds_id [Integer] Datastore ID # @return [nil, OpenNebula::Error] nil in case of success, Error @@ -101,6 +117,19 @@ module OpenNebula return rc end + # Deletes a Datastore from this Cluster + # @param ds_id [Integer] Datastore ID + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def deldatastore(ds_id) + return Error.new('ID not defined') if !@pe_id + + rc = @client.call(CLUSTER_METHODS[:deldatastore], @pe_id, ds_id) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + # Adds a VNet to this Cluster # @param vnet_id [Integer] VNet ID # @return [nil, OpenNebula::Error] nil in case of success, Error @@ -114,6 +143,19 @@ module OpenNebula return rc end + # Deletes a VNet from this Cluster + # @param vnet_id [Integer] VNet ID + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def delvnet(vnet_id) + return Error.new('ID not defined') if !@pe_id + + rc = @client.call(CLUSTER_METHODS[:delvnet], @pe_id, vnet_id) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + # --------------------------------------------------------------------- # Helpers to get information # --------------------------------------------------------------------- diff --git a/src/oca/ruby/OpenNebula/ClusterPool.rb b/src/oca/ruby/OpenNebula/ClusterPool.rb index b080514628..780b72a347 100644 --- a/src/oca/ruby/OpenNebula/ClusterPool.rb +++ b/src/oca/ruby/OpenNebula/ClusterPool.rb @@ -23,6 +23,7 @@ module OpenNebula # Constants and Class attribute accessors ####################################################################### + NONE_CLUSTER_ID = -1 DEFAULT_CLUSTER_ID = 0 CLUSTER_POOL_METHODS = { diff --git a/src/oca/ruby/OpenNebula/Datastore.rb b/src/oca/ruby/OpenNebula/Datastore.rb index a2fc8ac8fa..23d87c026b 100644 --- a/src/oca/ruby/OpenNebula/Datastore.rb +++ b/src/oca/ruby/OpenNebula/Datastore.rb @@ -67,7 +67,7 @@ module OpenNebula # # @return [Integer, OpenNebula::Error] the new ID in case of # success, error otherwise - def allocate(description, cluster_id) + def allocate(description, cluster_id=ClusterPool::NONE_CLUSTER_ID) super(DATASTORE_METHODS[:allocate], description, cluster_id) end diff --git a/src/oca/ruby/OpenNebula/Host.rb b/src/oca/ruby/OpenNebula/Host.rb index e869959396..c8274532ec 100644 --- a/src/oca/ruby/OpenNebula/Host.rb +++ b/src/oca/ruby/OpenNebula/Host.rb @@ -86,7 +86,7 @@ module OpenNebula # # @return [Integer, OpenNebula::Error] the new ID in case of # success, error otherwise - def allocate(hostname,im,vmm,vnm,cluster_id=ClusterPool::DEFAULT_CLUSTER_ID) + def allocate(hostname,im,vmm,vnm,cluster_id=ClusterPool::NONE_CLUSTER_ID) super(HOST_METHODS[:allocate],hostname,im,vmm,vnm,cluster_id) end diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 83f22f7965..ad21a5fa11 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -327,8 +327,11 @@ void RequestManager::register_xml_methods() // Cluster Methods xmlrpc_c::methodPtr cluster_addhost(new ClusterAddHost()); + xmlrpc_c::methodPtr cluster_delhost(new ClusterDelHost()); xmlrpc_c::methodPtr cluster_addds(new ClusterAddDatastore()); + xmlrpc_c::methodPtr cluster_delds(new ClusterDelDatastore()); xmlrpc_c::methodPtr cluster_addvnet(new ClusterAddVNet()); + xmlrpc_c::methodPtr cluster_delvnet(new ClusterDelVNet()); /* VM related methods */ RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy); @@ -423,9 +426,13 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.cluster.allocate",cluster_allocate); RequestManagerRegistry.addMethod("one.cluster.delete", cluster_delete); RequestManagerRegistry.addMethod("one.cluster.info", cluster_info); + RequestManagerRegistry.addMethod("one.cluster.addhost", cluster_addhost); + RequestManagerRegistry.addMethod("one.cluster.delhost", cluster_delhost); RequestManagerRegistry.addMethod("one.cluster.adddatastore", cluster_addds); + RequestManagerRegistry.addMethod("one.cluster.deldatastore", cluster_delds); RequestManagerRegistry.addMethod("one.cluster.addvnet", cluster_addvnet); + RequestManagerRegistry.addMethod("one.cluster.delvnet", cluster_delvnet); RequestManagerRegistry.addMethod("one.clusterpool.info",clusterpool_info); }; diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 5e43f72567..959a42827f 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -44,7 +44,7 @@ bool RequestManagerAllocate::allocate_authorization( ar.add_create_auth(auth_object, tmpl_str); - if ( do_cluster ) + if ( cluster_perms->oid != ClusterPool::NONE_CLUSTER_ID ) { ar.add_auth(AuthRequest::ADMIN, *cluster_perms); // ADMIN CLUSTER } @@ -107,8 +107,8 @@ void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params, int rc, id; Cluster * cluster = 0; - int cluster_id = -1; - string cluster_name = ""; + int cluster_id = ClusterPool::NONE_CLUSTER_ID; + string cluster_name = ClusterPool::NONE_CLUSTER_NAME; PoolObjectAuth cluster_perms; if ( do_template == true ) @@ -128,10 +128,10 @@ void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params, } } - if ( do_cluster == true ) - { - cluster_id = get_cluster_id(params); + cluster_id = get_cluster_id(params); + if ( cluster_id != ClusterPool::NONE_CLUSTER_ID ) + { rc = get_info(clpool, cluster_id, PoolObjectSQL::CLUSTER, att, cluster_perms, cluster_name); @@ -141,6 +141,10 @@ void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params, return; } } + else + { + cluster_perms.oid = ClusterPool::NONE_CLUSTER_ID; + } if ( allocate_authorization(tmpl, att, &cluster_perms) == false ) { @@ -156,7 +160,7 @@ void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params, return; } - if ( do_cluster == true ) + if ( cluster_id != ClusterPool::NONE_CLUSTER_ID ) { cluster = clpool->get(cluster_id, true); @@ -234,21 +238,6 @@ int VirtualNetworkAllocate::pool_allocate( cluster_id, cluster_name, error_str); } -/* -------------------------------------------------------------------------- */ - -int VirtualNetworkAllocate::get_cluster_id(xmlrpc_c::paramList const& paramList) -{ - return ClusterPool::DEFAULT_CLUSTER_ID; -} - -/* -------------------------------------------------------------------------- */ - -int VirtualNetworkAllocate::add_to_cluster( - Cluster* cluster, int id, string& error_msg) -{ - return cluster->add_vnet(id, error_msg); -} - /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -413,17 +402,6 @@ int HostAllocate::pool_allocate( /* -------------------------------------------------------------------------- */ -int HostAllocate::get_cluster_id(xmlrpc_c::paramList const& paramList) -{ - return xmlrpc_c::value_int(paramList.getInt(5)); -} - -/* -------------------------------------------------------------------------- */ - -int HostAllocate::add_to_cluster(Cluster* cluster, int id, string& error_msg) -{ - return cluster->add_host(id, error_msg); -} /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -492,21 +470,6 @@ int DatastoreAllocate::pool_allocate( return dspool->allocate(ds_tmpl, &id, cluster_id, cluster_name, error_str); } -/* -------------------------------------------------------------------------- */ - -int DatastoreAllocate::get_cluster_id(xmlrpc_c::paramList const& paramList) -{ - return xmlrpc_c::value_int(paramList.getInt(2)); -} - -/* -------------------------------------------------------------------------- */ - -int DatastoreAllocate::add_to_cluster( - Cluster* cluster, int id, string& error_msg) -{ - return cluster->add_datastore(id, error_msg); -} - /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerCluster.cc b/src/rm/RequestManagerCluster.cc index 09089e110c..73bcd3da75 100644 --- a/src/rm/RequestManagerCluster.cc +++ b/src/rm/RequestManagerCluster.cc @@ -22,14 +22,12 @@ using namespace std; /* ------------------------------------------------------------------------- */ void RequestManagerCluster::add_generic( - xmlrpc_c::paramList const& paramList, + int cluster_id, + int object_id, RequestAttributes& att, PoolSQL * pool, PoolObjectSQL::ObjectType type) { - int cluster_id = xmlrpc_c::value_int(paramList.getInt(1)); - int object_id = xmlrpc_c::value_int(paramList.getInt(2)); - int rc; string cluster_name; @@ -47,11 +45,18 @@ void RequestManagerCluster::add_generic( int old_cluster_id; string old_cluster_name; - rc = get_info(clpool, cluster_id, PoolObjectSQL::CLUSTER, att, c_perms, cluster_name); - - if ( rc == -1 ) + if ( cluster_id != ClusterPool::NONE_CLUSTER_ID ) { - return; + rc = get_info(clpool, cluster_id, PoolObjectSQL::CLUSTER, att, c_perms, cluster_name); + + if ( rc == -1 ) + { + return; + } + } + else + { + cluster_name = ClusterPool::NONE_CLUSTER_NAME; } rc = get_info(pool, object_id, type, att, obj_perms, obj_name); @@ -65,7 +70,11 @@ void RequestManagerCluster::add_generic( { AuthRequest ar(att.uid, att.gid); - ar.add_auth(auth_op, c_perms); // ADMIN CLUSTER + if ( cluster_id != ClusterPool::NONE_CLUSTER_ID ) + { + ar.add_auth(auth_op, c_perms); // ADMIN CLUSTER + } + ar.add_auth(AuthRequest::ADMIN, obj_perms); // ADMIN OBJECT if (UserPool::authorize(ar) == -1) @@ -107,73 +116,78 @@ void RequestManagerCluster::add_generic( object->unlock(); // ------------- Add object to new cluster --------------------- - - cluster = clpool->get(cluster_id, true); - - if ( cluster == 0 ) + if ( cluster_id != ClusterPool::NONE_CLUSTER_ID ) { - failure_response(NO_EXISTS, - get_error(object_name(PoolObjectSQL::CLUSTER),cluster_id), - att); + cluster = clpool->get(cluster_id, true); - // Rollback - get(object_id, true, &object, &cluster_obj); - - if ( object != 0 ) + if ( cluster == 0 ) { - cluster_obj->set_cluster(old_cluster_id, old_cluster_name); + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::CLUSTER),cluster_id), + att); - pool->update(object); + // Rollback + get(object_id, true, &object, &cluster_obj); - object->unlock(); + if ( object != 0 ) + { + cluster_obj->set_cluster(old_cluster_id, old_cluster_name); + + pool->update(object); + + object->unlock(); + } + + return; } - return; - } + if ( add_object(cluster, object_id, err_msg) < 0 ) + { + cluster->unlock(); + + failure_response(INTERNAL, + request_error("Cannot add object to cluster", err_msg), + att); + + return; + } + + clpool->update(cluster); - if ( add_object(cluster, object_id, err_msg) < 0 ) - { cluster->unlock(); - - failure_response(INTERNAL, - request_error("Cannot add host to cluster", err_msg), - att); - - return; } - clpool->update(cluster); - - cluster->unlock(); - // ------------- Remove host from old cluster --------------------- - cluster = clpool->get(old_cluster_id, true); - - if ( cluster == 0 ) + if ( old_cluster_id != ClusterPool::NONE_CLUSTER_ID ) { - // This point should be unreachable. - // The old cluster is not empty (at least has the host_id), - // so it cannot be deleted - success_response(cluster_id, att); - return; - } + cluster = clpool->get(old_cluster_id, true); + + if ( cluster == 0 ) + { + // This point should be unreachable. + // The old cluster is not empty (at least has the host_id), + // so it cannot be deleted + success_response(cluster_id, att); + return; + } + + if ( del_object(cluster, object_id, err_msg) < 0 ) + { + cluster->unlock(); + + failure_response(INTERNAL, + request_error("Cannot remove object from cluster", err_msg), + att); + + return; + } + + clpool->update(cluster); - if ( del_object(cluster, object_id, err_msg) < 0 ) - { cluster->unlock(); - - failure_response(INTERNAL, - request_error("Cannot remove host from cluster", err_msg), - att); - - return; } - clpool->update(cluster); - - cluster->unlock(); - success_response(cluster_id, att); return; diff --git a/src/rm/RequestManagerDelete.cc b/src/rm/RequestManagerDelete.cc index e092c32f6c..9466768c30 100644 --- a/src/rm/RequestManagerDelete.cc +++ b/src/rm/RequestManagerDelete.cc @@ -109,18 +109,13 @@ int RequestManagerDelete::drop( PoolObjectSQL * object, string& error_msg) { - int cluster_id = -1; - - if ( do_cluster ) - { - cluster_id = get_cluster_id(object); - } + int cluster_id = get_cluster_id(object); int rc = pool->drop(object, error_msg); object->unlock(); - if ( do_cluster == true && rc == 0 ) + if ( cluster_id != ClusterPool::NONE_CLUSTER_ID && rc == 0 ) { Cluster * cluster = clpool->get(cluster_id, true); From 6d360310f47ea5651ba163b283d2be67213bc3d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 1 Mar 2012 17:40:54 +0100 Subject: [PATCH 091/217] Feature #1112: Add templates to Datastores --- src/cli/one_helper/onedatastore_helper.rb | 4 ++++ src/datastore/Datastore.cc | 19 ++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index 5f117a6885..208aeb7b29 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -75,5 +75,9 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper datastore.img_ids.each do |id| puts "%-15s" % [id] end + + puts + CLIHelper.print_header(str_h1 % "DATASTORE TEMPLATE",false) + puts datastore.template_str end end diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index 14d75fcfe0..fa81ddb0e1 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -110,8 +110,6 @@ int Datastore::insert(SqlDB *db, string& error_str) base_path = oss.str(); - replace_template_attribute("BASE_PATH", base_path); - //-------------------------------------------------------------------------- // Insert the Datastore //-------------------------------------------------------------------------- @@ -228,6 +226,7 @@ string& Datastore::to_xml(string& xml) const { ostringstream oss; string collection_xml; + string template_xml; ObjectCollection::to_xml(collection_xml); @@ -240,7 +239,8 @@ string& Datastore::to_xml(string& xml) const "" << base_path << "" << "" << cluster_id << "" << "" << cluster << "" << - collection_xml << + collection_xml << + obj_template->to_xml(template_xml) << ""; xml = oss.str(); @@ -284,6 +284,19 @@ int Datastore::from_xml(const string& xml) // Set of IDs rc += ObjectCollection::from_xml_node(content[0]); + ObjectXML::free_nodes(content); + content.clear(); + + // Get associated classes + ObjectXML::get_nodes("/DATASTORE/TEMPLATE", content); + + if (content.empty()) + { + return -1; + } + + rc += obj_template->from_xml_node(content[0]); + ObjectXML::free_nodes(content); if (rc != 0) From a4426b68247a97568594fc95bd838e3e1f8a77a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 1 Mar 2012 18:48:25 +0100 Subject: [PATCH 092/217] Feature #1112: Store oneadmin's ID and name in UserPool --- include/UserPool.h | 10 ++++++++++ src/um/UserPool.cc | 13 ++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/include/UserPool.h b/include/UserPool.h index 3926c71613..afe2e54e36 100644 --- a/include/UserPool.h +++ b/include/UserPool.h @@ -176,6 +176,16 @@ public: */ static const char * SERVER_NAME; + /** + * Name of the oneadmin user + */ + static string oneadmin_name; + + /** + * Identifier for the oneadmin user + */ + static const int ONEADMIN_ID; + private: //-------------------------------------------------------------------------- // Configuration Attributes for Users diff --git a/src/um/UserPool.cc b/src/um/UserPool.cc index 49598ed499..d06e6d90d6 100644 --- a/src/um/UserPool.cc +++ b/src/um/UserPool.cc @@ -40,11 +40,15 @@ const char * UserPool::DEFAULT_AUTH = "default"; const char * UserPool::SERVER_NAME = "serveradmin"; +const int UserPool::ONEADMIN_ID = 0; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ time_t UserPool::_session_expiration_time; +string UserPool::oneadmin_name; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -74,8 +78,13 @@ UserPool::UserPool(SqlDB * db, _session_expiration_time = __session_expiration_time; - if (get(0,false) != 0) + User * oneadmin_user = get(0, true); + + if (oneadmin_user != 0) { + oneadmin_name = oneadmin_user->get_name(); + oneadmin_user->unlock(); + return; } @@ -122,6 +131,8 @@ UserPool::UserPool(SqlDB * db, goto error_token; } + oneadmin_name = one_name; + if ( one_name == SERVER_NAME ) { goto error_one_name; From f69a646cebe0c449202560fde28e34b251893dbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 1 Mar 2012 18:50:17 +0100 Subject: [PATCH 093/217] Feature #1112: Add owner and group to DS. To do: chown, chmod methods --- include/Datastore.h | 5 ++- include/DatastorePool.h | 21 +++++++--- src/cli/one_helper/onedatastore_helper.rb | 3 ++ src/datastore/Datastore.cc | 48 ++++++++++++----------- src/datastore/DatastorePool.cc | 30 ++++++++++---- src/rm/RequestManagerAllocate.cc | 3 +- 6 files changed, 72 insertions(+), 38 deletions(-) diff --git a/include/Datastore.h b/include/Datastore.h index bb4acbbf3a..39ea26c348 100644 --- a/include/Datastore.h +++ b/include/Datastore.h @@ -123,7 +123,10 @@ private: // ************************************************************************* Datastore( - int id, + int uid, + int gid, + const string& uname, + const string& gname, DatastoreTemplate* ds_template, int cluster_id, const string& cluster_name); diff --git a/include/DatastorePool.h b/include/DatastorePool.h index 395cea46e6..294af9512d 100644 --- a/include/DatastorePool.h +++ b/include/DatastorePool.h @@ -61,6 +61,10 @@ public: /** * Allocates a new Datastore, writing it in the pool database. No memory is * allocated for the object. + * @param uid the user id of the Datastore owner + * @param gid the id of the group this object is assigned to + * @param uname name of the user + * @param gname name of the group * @param ds_template Datastore definition template * @param oid the id assigned to the Datastore * @param cluster_id the id of the cluster this Datastore will belong to @@ -69,11 +73,16 @@ public: * * @return the oid assigned to the object, -1 in case of failure */ - int allocate(DatastoreTemplate * ds_template, - int * oid, - int cluster_id, - const string& cluster_name, - string& error_str); + int allocate( + int uid, + int gid, + const string& uname, + const string& gname, + DatastoreTemplate * ds_template, + int * oid, + int cluster_id, + const string& cluster_name, + string& error_str); /** * Function to get a Datastore from the pool, if the object is not in memory @@ -163,7 +172,7 @@ private: */ PoolObjectSQL * create() { - return new Datastore(-1, 0, -1, ""); + return new Datastore(-1,-1,"","", 0, -1, ""); }; }; diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index 208aeb7b29..1202763765 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -66,6 +66,9 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper CLIHelper.print_header(str_h1 % "DATASTORE #{datastore['ID']} INFORMATION") puts str % ["ID", datastore.id.to_s] puts str % ["NAME", datastore.name] + puts str % ["USER", datastore['UNAME']] + puts str % ["GROUP", datastore['GNAME']] + puts str % ["TYPE", datastore['TYPE']] puts str % ["BASE PATH",datastore['BASE_PATH']] puts diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index fa81ddb0e1..d363dff1ca 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -34,16 +34,20 @@ const char * Datastore::db_bootstrap = /* Datastore :: Constructor/Destructor */ /* ************************************************************************ */ -Datastore::Datastore(int id, - DatastoreTemplate* ds_template, - int cluster_id, - const string& cluster_name): - PoolObjectSQL(id,DATASTORE,"",-1,-1,"","",table), - ObjectCollection("IMAGES"), - Clusterable(cluster_id, cluster_name), - type(""), - tm_mad(""), - base_path("") +Datastore::Datastore( + int uid, + int gid, + const string& uname, + const string& gname, + DatastoreTemplate* ds_template, + int cluster_id, + const string& cluster_name): + PoolObjectSQL(-1,DATASTORE,"",uid,gid,uname,gname,table), + ObjectCollection("IMAGES"), + Clusterable(cluster_id, cluster_name), + type(""), + tm_mad(""), + base_path("") { if (ds_template != 0) { @@ -144,10 +148,6 @@ int Datastore::insert_replace(SqlDB *db, bool replace, string& error_str) char * sql_name; char * sql_xml; - // Set the owner and group to oneadmin - set_user(0, ""); - set_group(GroupPool::ONEADMIN_ID, GroupPool::ONEADMIN_NAME); - // Update the Datastore sql_name = db->escape_str(name.c_str()); @@ -232,10 +232,14 @@ string& Datastore::to_xml(string& xml) const oss << "" << - "" << oid << "" << - "" << name << "" << - "" << type << "" << - "" << tm_mad << "" << + "" << oid << "" << + "" << uid << "" << + "" << gid << "" << + "" << uname << "" << + "" << gname << "" << + "" << name << "" << + "" << type << "" << + "" << tm_mad << "" << "" << base_path << "" << "" << cluster_id << "" << "" << cluster << "" << @@ -261,6 +265,10 @@ int Datastore::from_xml(const string& xml) // Get class base attributes rc += xpath(oid, "/DATASTORE/ID", -1); + rc += xpath(uid, "/DATASTORE/UID", -1); + rc += xpath(gid, "/DATASTORE/GID", -1); + rc += xpath(uname, "/DATASTORE/UNAME", "not_found"); + rc += xpath(gname, "/DATASTORE/GNAME", "not_found"); rc += xpath(name, "/DATASTORE/NAME", "not_found"); rc += xpath(type, "/DATASTORE/TYPE", "not_found"); rc += xpath(tm_mad, "/DATASTORE/TM_MAD", "not_found"); @@ -269,10 +277,6 @@ int Datastore::from_xml(const string& xml) rc += xpath(cluster_id, "/DATASTORE/CLUSTER_ID", -1); rc += xpath(cluster, "/DATASTORE/CLUSTER", "not_found"); - // Set the owner and group to oneadmin - set_user(0, ""); - set_group(GroupPool::ONEADMIN_ID, GroupPool::ONEADMIN_NAME); - // Get associated classes ObjectXML::get_nodes("/DATASTORE/IMAGES", content); diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index 7bec974218..9897f80790 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -67,7 +67,11 @@ DatastorePool::DatastorePool(SqlDB * db): goto error_bootstrap; } - allocate(ds_tmpl, + allocate(UserPool::ONEADMIN_ID, + GroupPool::ONEADMIN_ID, + UserPool::oneadmin_name, + GroupPool::ONEADMIN_NAME, + ds_tmpl, &system_id, ClusterPool::DEFAULT_CLUSTER_ID, ClusterPool::DEFAULT_CLUSTER_NAME, @@ -95,7 +99,11 @@ DatastorePool::DatastorePool(SqlDB * db): goto error_bootstrap; } - allocate(ds_tmpl, + allocate(UserPool::ONEADMIN_ID, + GroupPool::ONEADMIN_ID, + UserPool::oneadmin_name, + GroupPool::ONEADMIN_NAME, + ds_tmpl, &default_id, ClusterPool::DEFAULT_CLUSTER_ID, ClusterPool::DEFAULT_CLUSTER_NAME, @@ -145,18 +153,24 @@ error_bootstrap: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int DatastorePool::allocate(DatastoreTemplate * ds_template, - int * oid, - int cluster_id, - const string& cluster_name, - string& error_str) +int DatastorePool::allocate( + int uid, + int gid, + const string& uname, + const string& gname, + DatastoreTemplate * ds_template, + int * oid, + int cluster_id, + const string& cluster_name, + string& error_str) { Datastore * ds; Datastore * ds_aux = 0; string name; ostringstream oss; - ds = new Datastore(-1, ds_template, cluster_id, cluster_name); + ds = new Datastore(uid, gid, uname, gname, + ds_template, cluster_id, cluster_name); // ------------------------------------------------------------------------- // Check name & duplicates diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 959a42827f..5342d9efd8 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -467,7 +467,8 @@ int DatastoreAllocate::pool_allocate( DatastoreTemplate * ds_tmpl = static_cast(tmpl); - return dspool->allocate(ds_tmpl, &id, cluster_id, cluster_name, error_str); + return dspool->allocate(att.uid, att.gid, att.uname, att.gname, + ds_tmpl, &id, cluster_id, cluster_name, error_str); } /* -------------------------------------------------------------------------- */ From 0422baa857a8c5af69e639ac4b8021faec34a817 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Thu, 1 Mar 2012 19:12:49 +0100 Subject: [PATCH 094/217] feature #1112: Change verbs in transfer scripts --- src/tm/TransferManager.cc | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index 48f822d44f..20cfe4e821 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -542,8 +542,8 @@ void TransferManager::prolog_migr_action(int vid) continue; } - //MVDISK tm_mad prev_host:remote_system_dir/disk.i host:remote_system_dir/disk.i - xfr << "MVDISK " + //MV tm_mad prev_host:remote_system_dir/disk.i host:remote_system_dir/disk.i + xfr << "MV " << tm_mad << " " << vm->get_previous_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << i << " " @@ -664,8 +664,8 @@ void TransferManager::prolog_resume_action(int vid) continue; } - //MVDISK tm_mad fe:system_dir/disk.i host:remote_system_dir/disk.i - xfr << "MVDISK " + //MV tm_mad fe:system_dir/disk.i host:remote_system_dir/disk.i + xfr << "MV " << tm_mad << " " << nd.get_nebula_hostname() << ":" << vm->get_system_dir() << "/disk." << i << " " @@ -812,8 +812,8 @@ void TransferManager::epilog_action(int vid) tsource << source << " "; } - //MV tm_mad hostname:remote_system_dir/disk.0 - xfr << "MV " + //MVDS tm_mad hostname:remote_system_dir/disk.0 + xfr << "MVDS " << tm_mad << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << i << " " @@ -821,8 +821,8 @@ void TransferManager::epilog_action(int vid) } else if ( !tm_mad.empty() ) //No saving disk and no system_ds disk { - //DELETEDISK tm_mad hostname:remote_system_dir/disk.i - xfr << "DELETEDISK " + //DELETE tm_mad hostname:remote_system_dir/disk.i + xfr << "DELETE " << tm_mad << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << i << endl; @@ -937,8 +937,8 @@ void TransferManager::epilog_stop_action(int vid) continue; } - //MVDISK tm_mad host:remote_system_dir/disk.i fe:system_dir/disk.i - xfr << "MVDISK " + //MV tm_mad host:remote_system_dir/disk.i fe:system_dir/disk.i + xfr << "MV " << tm_mad << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << i << " " @@ -1056,8 +1056,8 @@ void TransferManager::epilog_delete_action(int vid) continue; } - //DELETEDISK tm_mad host:remote_system_dir/disk.i - xfr << "DELETEDISK " + //DELETE tm_mad host:remote_system_dir/disk.i + xfr << "DELETE " << tm_mad << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << i << endl; @@ -1175,8 +1175,8 @@ void TransferManager::epilog_delete_previous_action(int vid) continue; } - //DELETEDISK tm_mad prev_host:remote_system_dir/disk.i - xfr << "DELETEDISK " + //DELETE tm_mad prev_host:remote_system_dir/disk.i + xfr << "DELETE " << tm_mad << " " << vm->get_previous_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << i << endl; From b04d29b4265a9895cc6dd4d3108bb0b05ed9b8a3 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Thu, 1 Mar 2012 19:13:09 +0100 Subject: [PATCH 095/217] feature #1112: Initial work to adapt tm shared to the new functionality --- src/mad/sh/scripts_common.sh | 17 +++++++- src/tm_mad/shared/clone | 40 ++++++++++-------- src/tm_mad/shared/ln | 36 ++++++++++++---- src/tm_mad/tm_common.sh | 82 +++++++----------------------------- 4 files changed, 81 insertions(+), 94 deletions(-) diff --git a/src/mad/sh/scripts_common.sh b/src/mad/sh/scripts_common.sh index 8de8df234d..a3a4254b21 100755 --- a/src/mad/sh/scripts_common.sh +++ b/src/mad/sh/scripts_common.sh @@ -40,6 +40,21 @@ WGET=wget # Used for log messages SCRIPT_NAME=`basename $0` +# ------------------------------------------------------------------------------ +# Path manipulation functions +# ------------------------------------------------------------------------------ + +# Takes out unneeded slashes. Repeated and final directory slashes: +# /some//path///somewhere/ -> /some/path/somewhere +function fix_dir_slashes +{ + dirname "$1/file" | $SED 's/\/+/\//g' +} + +# ------------------------------------------------------------------------------ +# Log functions +# ------------------------------------------------------------------------------ + # Formats date for logs function log_date { @@ -108,8 +123,6 @@ function exec_and_log log "Executed \"$1\"." } - - # Like exec_and_log but the first argument is the number of seconds # before here is timeout and kills the command # diff --git a/src/tm_mad/shared/clone b/src/tm_mad/shared/clone index 5cc373b86e..e2453c2d97 100755 --- a/src/tm_mad/shared/clone +++ b/src/tm_mad/shared/clone @@ -16,6 +16,12 @@ # limitations under the License. # #--------------------------------------------------------------------------- # +# clone fe:SOURCE host:remote_system_ds/disk.i size +# - fe is the front-end hostname +# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk +# - host is the target host to deploy the VM +# - remote_system_ds is the path for the system datastore in the host + SRC=$1 DST=$2 @@ -27,35 +33,35 @@ fi . $TMCOMMON -get_vmdir - +#------------------------------------------------------------------------------- +# Set dst path and dir +#------------------------------------------------------------------------------- SRC_PATH=`arg_path $SRC` DST_PATH=`arg_path $DST` -fix_paths +set_ds_location -log_debug "$1 $2" -log_debug "DST: $DST_PATH" +REL_DST_PATH=${DS_PATH##"$DS_LOCATION/"} +DST_PATH="$ONE_LOCAL_VAR/datastore/$REL_DST_PATH" DST_DIR=`dirname $DST_PATH` -log "Creating directory $DST_DIR" -exec_and_log "mkdir -p $DST_DIR" -exec_and_log "chmod a+w $DST_DIR" +if [ ! -d $DST_DIR ]; then + log "Creating directory $DST_DIR" + exec_and_log "mkdir -p $DST_DIR" +fi +#------------------------------------------------------------------------------- +# Clone (cp) SRC into DST +#------------------------------------------------------------------------------- case $SRC in http://*) - log "Downloading $SRC" - exec_and_log "$WGET -O $DST_PATH $SRC" \ - "Error downloading $SRC" + log "Downloading $SRC into $DST_PATH" + exec_and_log "$WGET -O $DST_PATH $SRC" "Error downloading $SRC" ;; *) - log "Cloning $SRC_PATH" - exec_and_log "cp -r $SRC_PATH $DST_PATH" \ - "Error copying $SRC to $DST" + log "Cloning $SRC_PATH in $DST_PATH" + exec_and_log "cp -r $SRC_PATH $DST_PATH" "Error copying $SRC to $DST" ;; esac - -exec_and_log "chmod a+rw $DST_PATH" - diff --git a/src/tm_mad/shared/ln b/src/tm_mad/shared/ln index 056fd4bc0c..07ddc88544 100755 --- a/src/tm_mad/shared/ln +++ b/src/tm_mad/shared/ln @@ -16,6 +16,12 @@ # limitations under the License. # #--------------------------------------------------------------------------- # +# ln fe:SOURCE host:remote_system_ds/disk.i size +# - fe is the front-end hostname +# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk +# - host is the target host to deploy the VM +# - remote_system_ds is the path for the system datastore in the host + SRC=$1 DST=$2 @@ -27,20 +33,32 @@ fi . $TMCOMMON -get_vmdir - +#------------------------------------------------------------------------------- +# Set dst path and dir +#------------------------------------------------------------------------------- SRC_PATH=`arg_path $SRC` DST_PATH=`arg_path $DST` -fix_dst_path +set_ds_location +REL_DST_PATH=${DS_PATH##"$DS_LOCATION/"} +REL_SRC_PATH=${SRC_PATH##"$ONE_LOCAL_VAR/datastores/"} + +DST_PATH="$ONE_LOCAL_VAR/datastore/$REL_DST_PATH" DST_DIR=`dirname $DST_PATH` -log "Creating directory $DST_DIR" -exec_and_log "mkdir -p $DST_DIR" \ - "Could not create directory $DST_DIR" -exec_and_log "chmod a+w $DST_DIR" +if [ ! -d $DST_DIR ]; then + log "Creating directory $DST_DIR" + exec_and_log "mkdir -p $DST_DIR" +fi -log "Link $SRC_PATH" -exec_and_log "ln -s $SRC_PATH $DST_PATH" +DST_FILE=`basename $DST_DIR` +#------------------------------------------------------------------------------- +# Link (ln) SRC into DST +#------------------------------------------------------------------------------- + +log "Linking $SRC_PATH in $DST_PATH" + +exec_and_log "cd $DST_DIR; ln -s ../$REL_SRC_PATH ./$DST_FILE" \ + "Error linking $SRC to $DST" diff --git a/src/tm_mad/tm_common.sh b/src/tm_mad/tm_common.sh index b5d204afe8..f5d045ec4c 100644 --- a/src/tm_mad/tm_common.sh +++ b/src/tm_mad/tm_common.sh @@ -16,6 +16,13 @@ export LANG=C +ONE_SH=$ONE_LIB/sh + +. $ONE_SH/scripts_common.sh + +# ------------------------------------------------------------------------------ +# Set enviroment for the tm drivers (bash-based) +# ------------------------------------------------------------------------------ if [ -z "$ONE_LOCATION" ]; then ONE_LOCAL_VAR=/var/lib/one ONE_LIB=/usr/lib/one @@ -24,76 +31,15 @@ else ONE_LIB=$ONE_LOCATION/lib fi -ONE_SH=$ONE_LIB/sh - -. $ONE_SH/scripts_common.sh - - - if [ "x$(uname -s)" = "xLinux" ]; then SED="$SED -r" else SED="/usr/bin/sed -E" fi -function get_vmdir -{ - VMDIR=`grep '^VM_DIR=' $ONE_LOCAL_VAR/config | cut -d= -f2` - fix_var_slashes -} - -# Takes out uneeded slashes. Repeated and final directory slashes: -# /some//path///somewhere/ -> /some/path/somewhere -function fix_dir_slashes -{ - dirname "$1/file" | $SED 's/\/+/\//g' -} - -function get_compare_target -{ - echo "$1" | $SED 's/\/+/\//g' | $SED 's/\/images$//' -} - -function full_src_and_dst_equal -{ - s=`get_compare_target "$SRC"` - d=`get_compare_target "$DST"` - - [ "$s" == "$d" ] - -} - -function fix_var_slashes -{ - ONE_LOCAL_VAR=`fix_dir_slashes "$ONE_LOCAL_VAR"` - VMDIR=`fix_dir_slashes "$VMDIR"` -} - -function fix_paths -{ - if [ "x$ONE_LOCAL_VAR" != "x$VMDIR" ]; then - SRC_PATH=`fix_dir_slashes "$SRC_PATH"` - SRC_PATH=${SRC_PATH/$VMDIR/$ONE_LOCAL_VAR} - DST_PATH=`fix_dir_slashes "$DST_PATH"` - DST_PATH=${DST_PATH/$VMDIR/$ONE_LOCAL_VAR} - fi -} - -function fix_src_path -{ - if [ "x$ONE_LOCAL_VAR" != "x$VMDIR" ]; then - SRC_PATH=`fix_dir_slashes "$SRC_PATH"` - SRC_PATH=${SRC_PATH/$VMDIR/$ONE_LOCAL_VAR} - fi -} - -function fix_dst_path -{ - if [ "x$ONE_LOCAL_VAR" != "x$VMDIR" ]; then - DST_PATH=`fix_dir_slashes "$DST_PATH"` - DST_PATH=${DST_PATH/$VMDIR/$ONE_LOCAL_VAR} - fi -} +# ------------------------------------------------------------------------------ +# Function to get hosts and paths from arguments +# ------------------------------------------------------------------------------ # Gets the host from an argument function arg_host @@ -107,5 +53,9 @@ function arg_path echo $1 | $SED 's/^[^:]*:(.*)$/\1/' } - - +#Return the DATASTORE_LOCATION from OpenNebula configuration +function set_ds_location +{ + DS_LOCATION=`grep '^DATASTORE_LOCATION=' $ONE_LOCAL_VAR/config | cut -d= -f2` + DS_LOCATION=`fix_var_slashes $DS_LOCATION` +} From c58dd74666ec8239cefcc6dfbe71c3e5b10f09f6 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 2 Mar 2012 00:06:57 +0100 Subject: [PATCH 096/217] feature #1112: Adjust core modules to generate right paths for system datastore. Fix bugs in TM shared --- include/History.h | 3 -- include/Nebula.h | 50 ---------------------------- include/VirtualMachine.h | 24 ++------------ src/tm_mad/shared/clone | 8 ++--- src/tm_mad/shared/ln | 14 ++++---- src/tm_mad/tm_common.sh | 10 +++--- src/vm/History.cc | 25 ++++++++------ src/vm/VirtualMachine.cc | 70 ++++++++++++++++++++-------------------- 8 files changed, 71 insertions(+), 133 deletions(-) diff --git a/include/History.h b/include/History.h index 2913307c74..e124ec7a2e 100644 --- a/include/History.h +++ b/include/History.h @@ -44,7 +44,6 @@ public: int seq, int hid, const string& hostname, - const string& remote_system_dir, const string& vmm, const string& vnm); @@ -86,8 +85,6 @@ private: int seq; string hostname; - string remote_system_dir; - int hid; string vmm_mad_name; diff --git a/include/Nebula.h b/include/Nebula.h index 02386d2adf..deee3fb633 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -218,32 +218,6 @@ public: return ds_location; }; - /** - * Returns the base for the system datastore (for tmp VM images). When - * ONE_LOCATION is defined this path points to $ONE_LOCATION/var/system_ds, - * otherwise it is /var/lib/one/system_ds. - * @return the system datastore pa location. - */ - string get_system_ds_path() - { - Datastore * ds; - string system_ds_path = ""; - - ds = dspool->get(DatastorePool::SYSTEM_DS_ID, true); - - if ( ds == 0 ) - { - NebulaLog::log("DaS", Log::ERROR, "Can not get system datastore"); - return system_ds_path; - } - - system_ds_path = ds->get_base_path(); - - ds->unlock(); - - return system_ds_path; - }; - /** * Returns the Transfer Manager for the system datastore * @return the tm name. @@ -267,30 +241,6 @@ public: return tm_mad; }; - - /** - * Returns the name for the system datastore - * @return the datastore name. - */ - string get_system_ds_name() - { - Datastore * ds; - string name = ""; - - ds = dspool->get(DatastorePool::SYSTEM_DS_ID, true); - - if ( ds == 0 ) - { - NebulaLog::log("DaS", Log::ERROR, "Can not get system datastore"); - return name; - } - - name = ds->get_name(); - - ds->unlock(); - - return name; - }; /** * Returns the path of the log file for a VM, depending where OpenNebula is diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 0a75b90e7f..8a7fa03708 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -211,24 +211,18 @@ public: // ------------------------------------------------------------------------ /** * Returns the remote VM directory. The VM remote dir is in the form: - * $DATASTORE_LOCATION/$SYSTEM_DS_NAME/$VM_ID. The remote system_dir stores + * $DATASTORE_LOCATION/$SYSTEM_DS_ID/$VM_ID. The remote system_dir stores * disks for a running VM in the target host. * @return the remote system directory for the VM */ - const string & get_remote_system_dir() const - { - return remote_system_dir; - }; + string get_remote_system_dir() const; /** * Returns the local VM directory. The VM local dir is in the form: * $SYSTEM_DS_BASE_PATH/$VM_ID. Temporary stores VM disks. * @return the system directory for the VM */ - const string & get_system_dir() const - { - return system_dir; - }; + string get_system_dir() const; // ------------------------------------------------------------------------ // History @@ -776,18 +770,6 @@ private: */ FileLog * _log; - /** - * Directory for the VM in the System DS (system_ds_path/$VID). Defaults to - * $ONE_LOCATION/var/system_ds/$VID or /var/log/one/system_ds/$VID - */ - string system_dir; - - /** - * Directory for the VM in hosts, the System DS (system_ds_path/$VID). Defaults to - * $ONE_LOCATION/var/system_ds/$VID or /var/log/one/system_ds/$VID - */ - string remote_system_dir; - // ************************************************************************* // DataBase implementation (Private) // ************************************************************************* diff --git a/src/tm_mad/shared/clone b/src/tm_mad/shared/clone index e2453c2d97..cc6b8987a1 100755 --- a/src/tm_mad/shared/clone +++ b/src/tm_mad/shared/clone @@ -26,9 +26,9 @@ SRC=$1 DST=$2 if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/usr/lib/one/mads/tm_common.sh + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh else - TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh fi . $TMCOMMON @@ -41,8 +41,8 @@ DST_PATH=`arg_path $DST` set_ds_location -REL_DST_PATH=${DS_PATH##"$DS_LOCATION/"} -DST_PATH="$ONE_LOCAL_VAR/datastore/$REL_DST_PATH" +REL_DST_PATH=${DST_PATH##"$DS_LOCATION/"} +DST_PATH="$ONE_LOCAL_VAR/datastores/$REL_DST_PATH" DST_DIR=`dirname $DST_PATH` diff --git a/src/tm_mad/shared/ln b/src/tm_mad/shared/ln index 07ddc88544..480ea50def 100755 --- a/src/tm_mad/shared/ln +++ b/src/tm_mad/shared/ln @@ -26,9 +26,9 @@ SRC=$1 DST=$2 if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/usr/lib/one/mads/tm_common.sh + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh else - TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh fi . $TMCOMMON @@ -41,10 +41,10 @@ DST_PATH=`arg_path $DST` set_ds_location -REL_DST_PATH=${DS_PATH##"$DS_LOCATION/"} +REL_DST_PATH=${DST_PATH##"$DS_LOCATION/"} REL_SRC_PATH=${SRC_PATH##"$ONE_LOCAL_VAR/datastores/"} -DST_PATH="$ONE_LOCAL_VAR/datastore/$REL_DST_PATH" +DST_PATH="$ONE_LOCAL_VAR/datastores/$REL_DST_PATH" DST_DIR=`dirname $DST_PATH` if [ ! -d $DST_DIR ]; then @@ -52,7 +52,7 @@ if [ ! -d $DST_DIR ]; then exec_and_log "mkdir -p $DST_DIR" fi -DST_FILE=`basename $DST_DIR` +DST_FILE=`basename $DST_PATH` #------------------------------------------------------------------------------- # Link (ln) SRC into DST @@ -60,5 +60,7 @@ DST_FILE=`basename $DST_DIR` log "Linking $SRC_PATH in $DST_PATH" -exec_and_log "cd $DST_DIR; ln -s ../$REL_SRC_PATH ./$DST_FILE" \ +cd $DST_DIR + +exec_and_log "ln -s ../../$REL_SRC_PATH ./$DST_FILE" \ "Error linking $SRC to $DST" diff --git a/src/tm_mad/tm_common.sh b/src/tm_mad/tm_common.sh index f5d045ec4c..05a75111c9 100644 --- a/src/tm_mad/tm_common.sh +++ b/src/tm_mad/tm_common.sh @@ -16,10 +16,6 @@ export LANG=C -ONE_SH=$ONE_LIB/sh - -. $ONE_SH/scripts_common.sh - # ------------------------------------------------------------------------------ # Set enviroment for the tm drivers (bash-based) # ------------------------------------------------------------------------------ @@ -31,6 +27,10 @@ else ONE_LIB=$ONE_LOCATION/lib fi +ONE_SH=$ONE_LIB/sh + +. $ONE_SH/scripts_common.sh + if [ "x$(uname -s)" = "xLinux" ]; then SED="$SED -r" else @@ -57,5 +57,5 @@ function arg_path function set_ds_location { DS_LOCATION=`grep '^DATASTORE_LOCATION=' $ONE_LOCAL_VAR/config | cut -d= -f2` - DS_LOCATION=`fix_var_slashes $DS_LOCATION` + DS_LOCATION=`fix_dir_slashes $DS_LOCATION` } diff --git a/src/vm/History.cc b/src/vm/History.cc index 747b057be0..7d581a1937 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -40,7 +40,6 @@ History::History( oid(_oid), seq(_seq), hostname(""), - remote_system_dir(""), hid(-1), vmm_mad_name(""), vnm_mad_name(""), @@ -61,13 +60,11 @@ History::History( int _seq, int _hid, const string& _hostname, - const string& _remote_system_dir, const string& _vmm, const string& _vnm): oid(_oid), seq(_seq), hostname(_hostname), - remote_system_dir(_remote_system_dir), hid(_hid), vmm_mad_name(_vmm), vnm_mad_name(_vnm), @@ -90,8 +87,12 @@ History::History( void History::non_persistent_data() { ostringstream os; - string vm_lhome; - Nebula& nd = Nebula::instance(); + + string vm_lhome; + string vm_rhome; + string ds_location; + + Nebula& nd = Nebula::instance(); // ----------- Local Locations ------------ os.str(""); @@ -115,10 +116,18 @@ void History::non_persistent_data() // ----------- Remote Locations ------------ - checkpoint_file = remote_system_dir + "/checkpoint"; + os.str(""); + + nd.get_configuration_attribute("DATASTORE_LOCATION", ds_location); + os << ds_location << "/" << DatastorePool::SYSTEM_DS_ID << "/" << oid; + + vm_rhome = os.str(); + + os << "/checkpoint"; + checkpoint_file = os.str(); os.str(""); - os << remote_system_dir << "/deployment." << seq; + os << vm_rhome << "/deployment." << seq; rdeployment_file = os.str(); } @@ -257,7 +266,6 @@ string& History::to_xml(string& xml) const "" << "" << seq << "" << "" << hostname << ""<< - "" << remote_system_dir << ""<< "" << hid << "" << "" << stime << "" << "" << etime << "" << @@ -287,7 +295,6 @@ int History::rebuild_attributes() rc += xpath(seq , "/HISTORY/SEQ", -1); rc += xpath(hostname , "/HISTORY/HOSTNAME", "not_found"); - rc += xpath(remote_system_dir, "/HISTORY/REMOTE_SYSTEM_DIR", "not_found"); rc += xpath(hid , "/HISTORY/HID", -1); rc += xpath(stime , "/HISTORY/STIME", 0); rc += xpath(etime , "/HISTORY/ETIME", 0); diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 86b33d47d5..1700dff31e 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -56,9 +56,7 @@ VirtualMachine::VirtualMachine(int id, net_rx(0), history(0), previous_history(0), - _log(0), - system_dir(""), - remote_system_dir("") + _log(0) { if (_vm_template != 0) { @@ -111,10 +109,11 @@ int VirtualMachine::select(SqlDB * db) ostringstream oss; ostringstream ose; - int rc; - int last_seq; + string system_dir; + int rc; + int last_seq; - Nebula& nd = Nebula::instance(); + Nebula& nd = Nebula::instance(); // Rebuild the VirtualMachine object rc = PoolObjectSQL::select(db); @@ -166,6 +165,8 @@ int VirtualMachine::select(SqlDB * db) mkdir(oss.str().c_str(), 0700); chmod(oss.str().c_str(), 0700); + system_dir = get_system_dir(); + mkdir(system_dir.c_str(), 0700); chmod(system_dir.c_str(), 0700); @@ -203,14 +204,11 @@ int VirtualMachine::insert(SqlDB * db, string& error_str) string name; SingleAttribute * attr; - string aname; - string value; - string ds_location; + string aname; + string value; ostringstream oss; - Nebula& nd = Nebula::instance(); - // ------------------------------------------------------------------------ // Check template for restricted attributes // ------------------------------------------------------------------------ @@ -298,21 +296,6 @@ int VirtualMachine::insert(SqlDB * db, string& error_str) parse_graphics(); - // ------------------------------------------------------------------------ - // Set the System DataStore Paths for the VM - // ------------------------------------------------------------------------ - oss.str(""); - oss << nd.get_system_ds_path() << "/" << oid; - - system_dir = oss.str(); - - oss.str(""); - - nd.get_configuration_attribute("DATASTORE_LOCATION", ds_location); - oss << ds_location << "/" << nd.get_system_ds_name() << "/" << oid; - - remote_system_dir = oss.str(); - // ------------------------------------------------------------------------ // Insert the VM // ------------------------------------------------------------------------ @@ -658,7 +641,6 @@ void VirtualMachine::add_history( seq, hid, hostname, - remote_system_dir, vmm_mad, vnm_mad); @@ -681,11 +663,9 @@ void VirtualMachine::cp_history() history->seq + 1, history->hid, history->hostname, - remote_system_dir, history->vmm_mad_name, history->vnm_mad_name); - previous_history = history; history = htmp; @@ -708,7 +688,6 @@ void VirtualMachine::cp_previous_history() history->seq + 1, previous_history->hid, previous_history->hostname, - remote_system_dir, previous_history->vmm_mad_name, previous_history->vnm_mad_name); @@ -1300,8 +1279,6 @@ string& VirtualMachine::to_xml_extended(string& xml, bool extended) const << "" << cpu << "" << "" << net_tx << "" << "" << net_rx << "" - << "" << system_dir << "" - << "" << remote_system_dir << "" << obj_template->to_xml(template_xml); if ( hasHistory() ) @@ -1371,9 +1348,6 @@ int VirtualMachine::from_xml(const string &xml_str) rc += xpath(net_tx, "/VM/NET_TX", 0); rc += xpath(net_rx, "/VM/NET_RX", 0); - rc += xpath(system_dir,"/VM/SYSTEM_DIR","not_found"); - rc += xpath(remote_system_dir,"/VM/REMOTE_SYSTEM_DIR","not_found"); - // Permissions rc += perms_from_xml(); @@ -1418,3 +1392,29 @@ int VirtualMachine::from_xml(const string &xml_str) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ + +string VirtualMachine::get_remote_system_dir() const +{ + ostringstream oss; + + string ds_location; + Nebula& nd = Nebula::instance(); + + nd.get_configuration_attribute("DATASTORE_LOCATION", ds_location); + oss << ds_location << "/" << DatastorePool::SYSTEM_DS_ID << "/" << oid; + + return oss.str(); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +string VirtualMachine::get_system_dir() const +{ + ostringstream oss; + Nebula& nd = Nebula::instance(); + + oss << nd.get_ds_location() << DatastorePool::SYSTEM_DS_ID << "/"<< oid; + + return oss.str(); +}; \ No newline at end of file From 1da7f89f5efc30286586e217872488e6102dd4ee Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 2 Mar 2012 01:15:19 +0100 Subject: [PATCH 097/217] feature #1112: clone, ln, mkimage, delete are now functional for tm_shared. Added none fs type for images --- src/mad/sh/scripts_common.sh | 5 ++++ src/tm_mad/shared/delete | 33 ++++++++++++++++------- src/tm_mad/shared/mkimage | 47 ++++++++++++++++++++++----------- src/tm_mad/shared/mv | 51 +----------------------------------- src/tm_mad/tm_common.sh | 14 +++++++++- 5 files changed, 74 insertions(+), 76 deletions(-) mode change 100755 => 120000 src/tm_mad/shared/mv diff --git a/src/mad/sh/scripts_common.sh b/src/mad/sh/scripts_common.sh index a3a4254b21..a1c5cee375 100755 --- a/src/mad/sh/scripts_common.sh +++ b/src/mad/sh/scripts_common.sh @@ -36,6 +36,7 @@ SED=sed SSH=ssh SUDO=sudo WGET=wget +GREP=grep # Used for log messages SCRIPT_NAME=`basename $0` @@ -182,6 +183,10 @@ function mkfs_command { "jfs") OPTS="-q" ;; + "none") + echo "" + return 0 + ;; *) OPTS="" ;; diff --git a/src/tm_mad/shared/delete b/src/tm_mad/shared/delete index 7e498293fe..34f23dc9da 100755 --- a/src/tm_mad/shared/delete +++ b/src/tm_mad/shared/delete @@ -16,23 +16,36 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -SRC=$1 -DST=$2 +# DELETE +# - host is the target host to deploy the VM +# - remote_system_ds is the path for the system datastore in the host + +DST=$1 if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/usr/lib/one/mads/tm_common.sh + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh else - TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh fi . $TMCOMMON -get_vmdir +#------------------------------------------------------------------------------- +# Set dst path and dir +# Return if deleting a disk, we will delete them when removing the +# remote_system_ds directory for the VM +#------------------------------------------------------------------------------- -SRC_PATH=`arg_path $SRC` +DST_PATH=`arg_path $DST` -fix_src_path +if [ `is_disk $DST_PATH` -eq 1 ]; then + exit 0 +fi -log "Deleting $SRC_PATH" -exec_and_log "rm -rf $SRC_PATH" \ - "Error deleting $SRC_PATH" +set_ds_location + +REL_DST_PATH=${DST_PATH##"$DS_LOCATION/"} +DST_PATH="$ONE_LOCAL_VAR/datastores/$REL_DST_PATH" + +log "Deleting $DST_PATH" +exec_and_log "rm -rf $DST_PATH" "Error deleting $DST_PATH" diff --git a/src/tm_mad/shared/mkimage b/src/tm_mad/shared/mkimage index 8684a321ff..7f1ccc11cd 100755 --- a/src/tm_mad/shared/mkimage +++ b/src/tm_mad/shared/mkimage @@ -16,33 +16,50 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/usr/lib/one/mads/tm_common.sh -else - TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh -fi - -. $TMCOMMON - -get_vmdir +# mkimage size format host:remote_system_ds/disk.i size +# - size in MB of the image +# - format for the image +# - host is the target host to deploy the VM +# - remote_system_ds is the path for the system datastore in the host SIZE=$1 FSTYPE=$2 DST=$3 +if [ -z "${ONE_LOCATION}" ]; then + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh +else + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh +fi + +. $TMCOMMON + +#------------------------------------------------------------------------------- +# Set dst path and dir +#------------------------------------------------------------------------------- DST_PATH=`arg_path $DST` -fix_dst_path +set_ds_location + +REL_DST_PATH=${DST_PATH##"$DS_LOCATION/"} +DST_PATH="$ONE_LOCAL_VAR/datastores/$REL_DST_PATH" DST_DIR=`dirname $DST_PATH` +if [ ! -d $DST_DIR ]; then + log "Creating directory $DST_DIR" + exec_and_log "mkdir -p $DST_DIR" +fi + +#------------------------------------------------------------------------------- +# Make the new image (file-based) +#------------------------------------------------------------------------------- + MKFS_CMD=`mkfs_command $DST_PATH $FSTYPE` -exec_and_log "mkdir -p $DST_DIR" \ - "Error creating directory $DST_DIR" exec_and_log "$DD if=/dev/zero of=$DST_PATH bs=1 count=1 seek=${SIZE}M" \ "Could not create image $DST_PATH" -exec_and_log "$MKFS_CMD" \ - "Unable to create filesystem $FSTYPE in $DST_PATH" -exec_and_log "chmod a+rw $DST_PATH" +if [ -n $MKFS_CMD ]; then + exec_and_log "$MKFS_CMD" "Unable to create filesystem $FSTYPE in $DST_PATH" +fi \ No newline at end of file diff --git a/src/tm_mad/shared/mv b/src/tm_mad/shared/mv deleted file mode 100755 index 4e23a36dc5..0000000000 --- a/src/tm_mad/shared/mv +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash - -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -SRC=$1 -DST=$2 - -if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/usr/lib/one/mads/tm_common.sh - VAR_LOCATION=/var/lib/one/ -else - TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh - VAR_LOCATION=$ONE_LOCATION/var/ -fi - -. $TMCOMMON - -get_vmdir - -SRC_PATH=`arg_path $SRC` -DST_PATH=`arg_path $DST` - -fix_paths - -if [ "$SRC_PATH" == "$DST_PATH" ]; then - log "Will not move, source and destination are equal" -else - if [ -d "$SRC_PATH" ]; then - log "Will not move, is not saving image" - else - log "Moving $SRC_PATH" - exec_and_log "mv $SRC_PATH $DST_PATH" \ - "Could not move $SRC_PATH to $DST_PATH" - fi -fi - diff --git a/src/tm_mad/shared/mv b/src/tm_mad/shared/mv new file mode 120000 index 0000000000..2507dfb82d --- /dev/null +++ b/src/tm_mad/shared/mv @@ -0,0 +1 @@ +../dummy/dummy.sh \ No newline at end of file diff --git a/src/tm_mad/tm_common.sh b/src/tm_mad/tm_common.sh index 05a75111c9..07578a18b8 100644 --- a/src/tm_mad/tm_common.sh +++ b/src/tm_mad/tm_common.sh @@ -56,6 +56,18 @@ function arg_path #Return the DATASTORE_LOCATION from OpenNebula configuration function set_ds_location { - DS_LOCATION=`grep '^DATASTORE_LOCATION=' $ONE_LOCAL_VAR/config | cut -d= -f2` + DS_LOCATION=`$GREP '^DATASTORE_LOCATION=' $ONE_LOCAL_VAR/config | cut -d= -f2` DS_LOCATION=`fix_dir_slashes $DS_LOCATION` } + +#Return 1 if the first argument is a disk +function is_disk +{ + echo "$1" | $GREP '/disk\.[0-9]\+' > /dev/null 2>&1 + + if [ $? -eq 0 ]; then + echo "1" + else + echo "0" + fi +} \ No newline at end of file From 5810a3fdb4a3995c21ac2b0e2e02fce64ec0f95e Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 2 Mar 2012 01:17:42 +0100 Subject: [PATCH 098/217] feature #1112: none fs type renamed to raw --- src/mad/sh/scripts_common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mad/sh/scripts_common.sh b/src/mad/sh/scripts_common.sh index a1c5cee375..9b939eb2ed 100755 --- a/src/mad/sh/scripts_common.sh +++ b/src/mad/sh/scripts_common.sh @@ -183,7 +183,7 @@ function mkfs_command { "jfs") OPTS="-q" ;; - "none") + "raw") echo "" return 0 ;; From 864daba3edfd51e50af0b86f81ba034978d44966 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 2 Mar 2012 01:35:18 +0100 Subject: [PATCH 099/217] feature #1112: mkswap for shared TM --- src/mad/sh/scripts_common.sh | 4 ++++ src/tm_mad/shared/mkimage | 2 +- src/tm_mad/shared/mkswap | 37 +++++++----------------------------- 3 files changed, 12 insertions(+), 31 deletions(-) diff --git a/src/mad/sh/scripts_common.sh b/src/mad/sh/scripts_common.sh index 9b939eb2ed..9201d919a9 100755 --- a/src/mad/sh/scripts_common.sh +++ b/src/mad/sh/scripts_common.sh @@ -187,6 +187,10 @@ function mkfs_command { echo "" return 0 ;; + "swap") + echo "$MKSWAP $DST" + return 0 + ;; *) OPTS="" ;; diff --git a/src/tm_mad/shared/mkimage b/src/tm_mad/shared/mkimage index 7f1ccc11cd..d651075dcc 100755 --- a/src/tm_mad/shared/mkimage +++ b/src/tm_mad/shared/mkimage @@ -60,6 +60,6 @@ MKFS_CMD=`mkfs_command $DST_PATH $FSTYPE` exec_and_log "$DD if=/dev/zero of=$DST_PATH bs=1 count=1 seek=${SIZE}M" \ "Could not create image $DST_PATH" -if [ -n $MKFS_CMD ]; then +if [ -n "$MKFS_CMD" ]; then exec_and_log "$MKFS_CMD" "Unable to create filesystem $FSTYPE in $DST_PATH" fi \ No newline at end of file diff --git a/src/tm_mad/shared/mkswap b/src/tm_mad/shared/mkswap index bde0ea0b9f..51ac4d96a1 100755 --- a/src/tm_mad/shared/mkswap +++ b/src/tm_mad/shared/mkswap @@ -16,36 +16,13 @@ # limitations under the License. # #--------------------------------------------------------------------------- # +# mkswap size host:remote_system_ds/disk.i size +# - size in MB of the image +# - host is the target host to deploy the VM +# - remote_system_ds is the path for the system datastore in the host + SIZE=$1 DST=$2 -if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/usr/lib/one/mads/tm_common.sh -else - TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh -fi - -. $TMCOMMON - -get_vmdir - -DST_PATH=`arg_path $DST` - -fix_dst_path - -DST_DIR=`dirname $DST_PATH` - -log_debug "Creating directory $DST_DIR" -exec_and_log "mkdir -p $DST_DIR" -exec_and_log "chmod a+w $DST_DIR" - -log_debug "Creating ${SIZE}Mb image in $DST_PATH" -exec_and_log "$DD if=/dev/zero of=$DST_PATH bs=1 count=1 seek=${SIZE}M" \ - "Could not create image file $DST_PATH" - -log_debug "Initializing swap space" -exec_and_log "$MKSWAP $DST_PATH" \ - "Could not create swap on $DST_PATH" - -exec_and_log "chmod a+w $DST_PATH" - +CMD="`dirname $0`/mkimage $SIZE swap $DST" +`$CMD` From 6ff6e1f200d266f8245db0481ee7f0e873c9ab2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 2 Mar 2012 16:11:50 +0100 Subject: [PATCH 100/217] Feature #1112: Add permissions to DS. New chown & chmod methods --- include/RequestManagerChmod.h | 20 ++++++++++++- include/RequestManagerChown.h | 19 ++++++++++++ src/cli/one_helper/onedatastore_helper.rb | 12 ++++++++ src/cli/onedatastore | 32 +++++++++++++++++++++ src/datastore/Datastore.cc | 5 ++++ src/oca/ruby/OpenNebula/Datastore.rb | 35 ++++++++++++++++++++++- src/oca/ruby/OpenNebula/VirtualNetwork.rb | 9 ++++-- src/rm/RequestManager.cc | 4 +++ 8 files changed, 131 insertions(+), 5 deletions(-) diff --git a/include/RequestManagerChmod.h b/include/RequestManagerChmod.h index 60282af845..4341c1fc4f 100644 --- a/include/RequestManagerChmod.h +++ b/include/RequestManagerChmod.h @@ -81,7 +81,6 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ - class VirtualNetworkChmod: public RequestManagerChmod { public: @@ -117,6 +116,25 @@ public: }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class DatastoreChmod: public RequestManagerChmod +{ +public: + DatastoreChmod(): + RequestManagerChmod("DatastoreChmod", + "Changes permission bits of a datastore") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_dspool(); + auth_object = PoolObjectSQL::DATASTORE; + }; + + ~DatastoreChmod(){}; + +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerChown.h b/include/RequestManagerChown.h index c0591bb36c..9ccedc49a0 100644 --- a/include/RequestManagerChown.h +++ b/include/RequestManagerChown.h @@ -153,6 +153,25 @@ public: RequestAttributes& att); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class DatastoreChown: public RequestManagerChown +{ +public: + DatastoreChown(): + RequestManagerChown("Datastore", + "Changes ownership of a datastore") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_dspool(); + auth_object = PoolObjectSQL::DATASTORE; + }; + + ~DatastoreChown(){}; + +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index 1202763765..b88a5f6b4d 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -73,6 +73,18 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper puts str % ["BASE PATH",datastore['BASE_PATH']] puts + CLIHelper.print_header(str_h1 % "PERMISSIONS",false) + + ["OWNER", "GROUP", "OTHER"].each { |e| + mask = "---" + mask[0] = "u" if datastore["PERMISSIONS/#{e}_U"] == "1" + mask[1] = "m" if datastore["PERMISSIONS/#{e}_M"] == "1" + mask[2] = "a" if datastore["PERMISSIONS/#{e}_A"] == "1" + + puts str % [e, mask] + } + puts + CLIHelper.print_header(str_h1 % "IMAGES", false) CLIHelper.print_header("%-15s" % ["ID"]) datastore.img_ids.each do |id| diff --git a/src/cli/onedatastore b/src/cli/onedatastore index 5f30f913ce..e86de396e8 100755 --- a/src/cli/onedatastore +++ b/src/cli/onedatastore @@ -86,6 +86,38 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end + chgrp_desc = <<-EOT.unindent + Changes the Datastore group + EOT + + command :chgrp, chgrp_desc,[:range, :datastoreid_list], :groupid do + helper.perform_actions(args[0],options,"Group changed") do |obj| + obj.chown(-1, args[1].to_i) + end + end + + chown_desc = <<-EOT.unindent + Changes the Datastore owner and group + EOT + + command :chown, chown_desc, [:range, :datastoreid_list], :userid, + [:groupid,nil] do + gid = args[2].nil? ? -1 : args[2].to_i + helper.perform_actions(args[0],options,"Owner/Group changed") do |obj| + obj.chown(args[1].to_i, gid) + end + end + + chmod_desc = <<-EOT.unindent + Changes the Datastore permissions + EOT + + command :chmod, chmod_desc, [:range, :datastoreid_list], :octet do + helper.perform_actions(args[0],options, "Permissions changed") do |obj| + obj.chmod_octet(args[1]) + end + end + list_desc = <<-EOT.unindent Lists Datastores in the pool EOT diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index d363dff1ca..49da72cfaf 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -227,6 +227,7 @@ string& Datastore::to_xml(string& xml) const ostringstream oss; string collection_xml; string template_xml; + string perms_xml; ObjectCollection::to_xml(collection_xml); @@ -238,6 +239,7 @@ string& Datastore::to_xml(string& xml) const "" << uname << "" << "" << gname << "" << "" << name << "" << + perms_to_xml(perms_xml) << "" << type << "" << "" << tm_mad << "" << "" << base_path << "" << @@ -277,6 +279,9 @@ int Datastore::from_xml(const string& xml) rc += xpath(cluster_id, "/DATASTORE/CLUSTER_ID", -1); rc += xpath(cluster, "/DATASTORE/CLUSTER", "not_found"); + // Permissions + rc += perms_from_xml(); + // Get associated classes ObjectXML::get_nodes("/DATASTORE/IMAGES", content); diff --git a/src/oca/ruby/OpenNebula/Datastore.rb b/src/oca/ruby/OpenNebula/Datastore.rb index 23d87c026b..7c0df9fc7c 100644 --- a/src/oca/ruby/OpenNebula/Datastore.rb +++ b/src/oca/ruby/OpenNebula/Datastore.rb @@ -26,7 +26,9 @@ module OpenNebula DATASTORE_METHODS = { :info => "datastore.info", :allocate => "datastore.allocate", - :delete => "datastore.delete" + :delete => "datastore.delete", + :chown => "datastore.chown", + :chmod => "datastore.chmod" } # Creates a Datastore description with just its identifier @@ -76,6 +78,37 @@ module OpenNebula super(DATASTORE_METHODS[:delete]) end + # Changes the owner/group + # + # @param uid [Integer] the new owner id. Set to -1 to leave the current one + # @param gid [Integer] the new group id. Set to -1 to leave the current one + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def chown(uid, gid) + super(DATASTORE_METHODS[:chown], uid, gid) + end + + # Changes the datastore permissions. + # + # @param octet [String] Permissions octed , e.g. 640 + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def chmod_octet(octet) + super(DATASTORE_METHODS[:chmod], octet) + end + + # Changes the datastore permissions. + # Each [Integer] argument must be 1 to allow, 0 deny, -1 do not change + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def chmod(owner_u, owner_m, owner_a, group_u, group_m, group_a, other_u, + other_m, other_a) + super(DATASTORE_METHODS[:chmod], owner_u, owner_m, owner_a, group_u, + group_m, group_a, other_u, other_m, other_a) + end + # --------------------------------------------------------------------- # Helpers to get information # --------------------------------------------------------------------- diff --git a/src/oca/ruby/OpenNebula/VirtualNetwork.rb b/src/oca/ruby/OpenNebula/VirtualNetwork.rb index 134e0a038c..1c24e0ad95 100644 --- a/src/oca/ruby/OpenNebula/VirtualNetwork.rb +++ b/src/oca/ruby/OpenNebula/VirtualNetwork.rb @@ -158,9 +158,12 @@ module OpenNebula end # Changes the owner/group - # uid:: _Integer_ the new owner id. Set to -1 to leave the current one - # gid:: _Integer_ the new group id. Set to -1 to leave the current one - # [return] nil in case of success or an Error object + # + # @param uid [Integer] the new owner id. Set to -1 to leave the current one + # @param gid [Integer] the new group id. Set to -1 to leave the current one + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise def chown(uid, gid) super(VN_METHODS[:chown], uid, gid) end diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index ad21a5fa11..639980dc8c 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -313,12 +313,14 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr vn_chown(new VirtualNetworkChown()); xmlrpc_c::methodPtr image_chown(new ImageChown()); xmlrpc_c::methodPtr user_chown(new UserChown()); + xmlrpc_c::methodPtr datastore_chown(new DatastoreChown()); // Chmod Methods xmlrpc_c::methodPtr vm_chmod(new VirtualMachineChmod()); xmlrpc_c::methodPtr template_chmod(new TemplateChmod()); xmlrpc_c::methodPtr vn_chmod(new VirtualNetworkChmod()); xmlrpc_c::methodPtr image_chmod(new ImageChmod()); + xmlrpc_c::methodPtr datastore_chmod(new DatastoreChmod()); // ACL Methods xmlrpc_c::methodPtr acl_addrule(new AclAddRule()); @@ -419,6 +421,8 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.datastore.allocate",datastore_allocate); RequestManagerRegistry.addMethod("one.datastore.delete", datastore_delete); RequestManagerRegistry.addMethod("one.datastore.info", datastore_info); + RequestManagerRegistry.addMethod("one.datastore.chown", datastore_chown); + RequestManagerRegistry.addMethod("one.datastore.chmod", datastore_chmod); RequestManagerRegistry.addMethod("one.datastorepool.info",datastorepool_info); From 759c0a23669d7139eedabc17fb60f219efcaad96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 2 Mar 2012 17:25:42 +0100 Subject: [PATCH 101/217] Feature #1112: New onedatastore update method --- include/Datastore.h | 8 ++++++++ include/RequestManagerUpdateTemplate.h | 18 ++++++++++++++++++ src/cli/onedatastore | 11 +++++++++++ src/oca/ruby/OpenNebula/Datastore.rb | 11 +++++++++++ src/rm/RequestManager.cc | 2 ++ 5 files changed, 50 insertions(+) diff --git a/include/Datastore.h b/include/Datastore.h index 39ea26c348..323dfcf0f1 100644 --- a/include/Datastore.h +++ b/include/Datastore.h @@ -180,6 +180,14 @@ private: string error_str; return insert_replace(db, true, error_str); } + + /** + * Factory method for virtual network templates + */ + Template * get_new_template() + { + return new DatastoreTemplate; + } }; #endif /*DATASTORE_H_*/ diff --git a/include/RequestManagerUpdateTemplate.h b/include/RequestManagerUpdateTemplate.h index 67b6068d0a..85b633ba85 100644 --- a/include/RequestManagerUpdateTemplate.h +++ b/include/RequestManagerUpdateTemplate.h @@ -134,6 +134,24 @@ public: ~UserUpdateTemplate(){}; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class DatastoreUpdateTemplate : public RequestManagerUpdateTemplate +{ +public: + DatastoreUpdateTemplate(): + RequestManagerUpdateTemplate("DatastoreUpdateTemplate", + "Updates a datastore template") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_dspool(); + auth_object = PoolObjectSQL::DATASTORE; + }; + + ~DatastoreUpdateTemplate(){}; +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/cli/onedatastore b/src/cli/onedatastore index e86de396e8..58edffcdd0 100755 --- a/src/cli/onedatastore +++ b/src/cli/onedatastore @@ -133,4 +133,15 @@ cmd=CommandParser::CmdParser.new(ARGV) do command :show, show_desc, :datastoreid, :options=>OpenNebulaHelper::XML do helper.show_resource(args[0],options) end + + update_desc = <<-EOT.unindent + Launches the system editor to modify and update the template contents + EOT + + command :update, update_desc, :datastoreid do + helper.perform_action(args[0],options,"modified") do |obj| + str = OpenNebulaHelper.update_template(args[0], obj) + obj.update(str) + end + end end diff --git a/src/oca/ruby/OpenNebula/Datastore.rb b/src/oca/ruby/OpenNebula/Datastore.rb index 7c0df9fc7c..6dbb10b1f4 100644 --- a/src/oca/ruby/OpenNebula/Datastore.rb +++ b/src/oca/ruby/OpenNebula/Datastore.rb @@ -27,6 +27,7 @@ module OpenNebula :info => "datastore.info", :allocate => "datastore.allocate", :delete => "datastore.delete", + :update => "datastore.update", :chown => "datastore.chown", :chmod => "datastore.chmod" } @@ -78,6 +79,16 @@ module OpenNebula super(DATASTORE_METHODS[:delete]) end + # Replaces the template contents + # + # @param new_template [String] New template contents + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def update(new_template) + super(DATASTORE_METHODS[:update], new_template) + end + # Changes the owner/group # # @param uid [Integer] the new owner id. Set to -1 to leave the current one diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 639980dc8c..34a14a82e0 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -255,6 +255,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr host_update(new HostUpdateTemplate()); xmlrpc_c::methodPtr vn_update(new VirtualNetworkUpdateTemplate()); xmlrpc_c::methodPtr user_update(new UserUpdateTemplate()); + xmlrpc_c::methodPtr datastore_update(new DatastoreUpdateTemplate()); // Allocate Methods xmlrpc_c::methodPtr vm_allocate(new VirtualMachineAllocate()); @@ -421,6 +422,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.datastore.allocate",datastore_allocate); RequestManagerRegistry.addMethod("one.datastore.delete", datastore_delete); RequestManagerRegistry.addMethod("one.datastore.info", datastore_info); + RequestManagerRegistry.addMethod("one.datastore.update", datastore_update); RequestManagerRegistry.addMethod("one.datastore.chown", datastore_chown); RequestManagerRegistry.addMethod("one.datastore.chmod", datastore_chmod); From c1b74347747973c9666f0f0a049b026a26151cb4 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 2 Mar 2012 18:24:03 +0100 Subject: [PATCH 102/217] feature 1112: Context fot tm_shared --- src/tm_mad/shared/context | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/tm_mad/shared/context b/src/tm_mad/shared/context index 09d0a7552a..2806793ba1 100755 --- a/src/tm_mad/shared/context +++ b/src/tm_mad/shared/context @@ -16,6 +16,11 @@ # limitations under the License. # #--------------------------------------------------------------------------- # +# context context.sh file1 file2 ... fileN host:remote_system_ds/disk.i +# - context.sh file are the contents of the context ISO +# - host is the target host to deploy the VM +# - remote_system_ds is the path for the system datastore in the host + while (( "$#" )); do if [ "$#" == "1" ]; then DST=$1 @@ -26,39 +31,48 @@ while (( "$#" )); do done if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/usr/lib/one/mads/tm_common.sh + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh else - TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh fi . $TMCOMMON -get_vmdir - +#------------------------------------------------------------------------------- +# Set dst path and dirs +#------------------------------------------------------------------------------- DST_PATH=`arg_path $DST` -fix_dst_path +set_ds_location -DST_DIR=`dirname $DST_PATH` +REL_DST_PATH=${DST_PATH##"$DS_LOCATION/"} +DST_PATH="$ONE_LOCAL_VAR/datastores/$REL_DST_PATH" + +DST_DIR=`dirname $DST_PATH` ISO_DIR=$DST_DIR/isofiles +if [ ! -d $DST_DIR ]; then + log "Creating directory $DST_DIR" + exec_and_log "mkdir -p $DST_DIR" +fi + exec_and_log "mkdir -p $ISO_DIR" +#------------------------------------------------------------------------------- +# Build the Context Block device +#------------------------------------------------------------------------------- for f in $SRC; do case $f in http://*) - exec_and_log "$WGET -P $ISO_DIR $f" \ - "Error downloading $f" + exec_and_log "$WGET -P $ISO_DIR $f" "Error downloading $f" ;; *) - exec_and_log "cp -R $f $ISO_DIR" \ - "Error copying $f to $ISO_DIR" + exec_and_log "cp -R $f $ISO_DIR" "Error copying $f to $ISO_DIR" ;; esac done -exec_and_log "$MKISOFS -o $DST_PATH -J -R $ISO_DIR" \ - "Error creating iso fs" +exec_and_log "$MKISOFS -o $DST_PATH -J -R $ISO_DIR" "Error creating iso fs" exec_and_log "rm -rf $ISO_DIR" From d376c6fa4b6a711d6f1c21b9ec24be9e4892c6bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 2 Mar 2012 18:51:17 +0100 Subject: [PATCH 103/217] Feature #1112: Work on CLI commands, cluster and DS related methods --- src/cli/one_helper.rb | 5 +++++ src/cli/one_helper/onedatastore_helper.rb | 1 + src/cli/one_helper/onehost_helper.rb | 1 + src/cli/one_helper/oneimage_helper.rb | 1 + src/cli/one_helper/onevnet_helper.rb | 1 + src/cli/onecluster | 22 +++++++++++++++++----- src/cli/onedatastore | 12 ++++++++++++ 7 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/cli/one_helper.rb b/src/cli/one_helper.rb index c78c6e9ed6..019d80845e 100644 --- a/src/cli/one_helper.rb +++ b/src/cli/one_helper.rb @@ -333,6 +333,11 @@ EOT when "GROUP" then OpenNebula::GroupPool.new(client) when "USER" then OpenNebula::UserPool.new(client) when "DATASTORE" then OpenNebula::DatastorePool.new(client) + when "CLUSTER" then OpenNebula::ClusterPool.new(client) + when "VNET" then OpenNebula::VirtualNetworkPool.new(client) + when "IMAGE" then OpenNebula::ImagePool.new(client) + when "VMTEMPLATE" then OpenNebula::TemplatePool.new(client) + when "VM" then OpenNebula::VirtualMachinePool.new(client) end rc = pool.info diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index b88a5f6b4d..d263fd4316 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -68,6 +68,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper puts str % ["NAME", datastore.name] puts str % ["USER", datastore['UNAME']] puts str % ["GROUP", datastore['GNAME']] + puts str % ["CLUSTER", datastore['CLUSTER']] puts str % ["TYPE", datastore['TYPE']] puts str % ["BASE PATH",datastore['BASE_PATH']] diff --git a/src/cli/one_helper/onehost_helper.rb b/src/cli/one_helper/onehost_helper.rb index 306b1fcf75..74628bb18f 100644 --- a/src/cli/one_helper/onehost_helper.rb +++ b/src/cli/one_helper/onehost_helper.rb @@ -118,6 +118,7 @@ class OneHostHelper < OpenNebulaHelper::OneHelper puts str % ["ID", host.id.to_s] puts str % ["NAME", host.name] + puts str % ["CLUSTER", host['CLUSTER']] puts str % ["STATE", host.state_str] puts str % ["IM_MAD", host['IM_MAD']] puts str % ["VM_MAD", host['VM_MAD']] diff --git a/src/cli/one_helper/oneimage_helper.rb b/src/cli/one_helper/oneimage_helper.rb index 27a4910ec1..4d13ae95dc 100644 --- a/src/cli/one_helper/oneimage_helper.rb +++ b/src/cli/one_helper/oneimage_helper.rb @@ -118,6 +118,7 @@ class OneImageHelper < OpenNebulaHelper::OneHelper puts str % ["NAME", image.name] puts str % ["USER", image['UNAME']] puts str % ["GROUP",image['GNAME']] + puts str % ["DATASTORE",image['DATASTORE']] puts str % ["TYPE", image.type_str] puts str % ["REGISTER TIME", OpenNebulaHelper.time_to_str(image['REGTIME'])] diff --git a/src/cli/one_helper/onevnet_helper.rb b/src/cli/one_helper/onevnet_helper.rb index 72fb32346c..6b2b439c5a 100644 --- a/src/cli/one_helper/onevnet_helper.rb +++ b/src/cli/one_helper/onevnet_helper.rb @@ -103,6 +103,7 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper puts str % ["NAME", vn['NAME']] puts str % ["USER", vn['UNAME']] puts str % ["GROUP", vn['GNAME']] + puts str % ["CLUSTER", vn['CLUSTER']] puts str % ["TYPE", vn.type_str] puts str % ["BRIDGE", vn["BRIDGE"]] puts str % ["VLAN", OpenNebulaHelper.boolean_to_str(vn['VLAN'])] diff --git a/src/cli/onecluster b/src/cli/onecluster index 07b0fc1ae8..352e4811e0 100755 --- a/src/cli/onecluster +++ b/src/cli/onecluster @@ -56,6 +56,18 @@ cmd=CommandParser::CmdParser.new(ARGV) do helper.list_to_id(arg) end + set :format, :vnetid, OpenNebulaHelper.rname_to_id_desc("VNET") do |arg| + OpenNebulaHelper.rname_to_id(arg, "VNET") + end + + set :format, :hostid, OpenNebulaHelper.rname_to_id_desc("HOST") do |arg| + OpenNebulaHelper.rname_to_id(arg, "HOST") + end + + set :format, :datastoreid, OpenNebulaHelper.rname_to_id_desc("DATASTORE") do |arg| + OpenNebulaHelper.rname_to_id(arg, "DATASTORE") + end + ######################################################################## # Commands ######################################################################## @@ -102,7 +114,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do # TODO: allow the second param to be [:range, :hostid_list] command :addhost, addhost_desc,:clusterid, :hostid do - helper.perform_actions(args[0],options,"updated") do |cluster| + helper.perform_action(args[0],options,"updated") do |cluster| cluster.addhost(args[1].to_i) end end @@ -113,7 +125,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do # TODO: allow the second param to be [:range, :hostid_list] command :delhost, delhost_desc, :clusterid, :hostid do - helper.perform_actions(args[0],options,"updated") do |cluster| + helper.perform_action(args[0],options,"updated") do |cluster| cluster.delhost(args[1].to_i) end end @@ -124,7 +136,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do # TODO: allow the second param to be [:range, :datastoreid_list] command :adddatastore, adddatastore_desc,:clusterid, :datastoreid do - helper.perform_actions(args[0],options,"updated") do |cluster| + helper.perform_action(args[0],options,"updated") do |cluster| cluster.adddatastore(args[1].to_i) end end @@ -135,7 +147,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do # TODO: allow the second param to be [:range, :datastoreid_list] command :deldatastore, deldatastore_desc, :clusterid, :datastoreid do - helper.perform_actions(args[0],options,"updated") do |cluster| + helper.perform_action(args[0],options,"updated") do |cluster| cluster.deldatastore(args[1].to_i) end end @@ -146,7 +158,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do # TODO: allow the second param to be [:range, :vnetid_list] command :addvnet, addvnet_desc,:clusterid, :vnetid do - helper.perform_actions(args[0],options,"updated") do |cluster| + helper.perform_action(args[0],options,"updated") do |cluster| cluster.addvnet(args[1].to_i) end end diff --git a/src/cli/onedatastore b/src/cli/onedatastore index 58edffcdd0..514b5c2249 100755 --- a/src/cli/onedatastore +++ b/src/cli/onedatastore @@ -56,6 +56,18 @@ cmd=CommandParser::CmdParser.new(ARGV) do helper.list_to_id(arg) end + set :format, :clusterid, OpenNebulaHelper.rname_to_id_desc("CLUSTER") do |arg| + OpenNebulaHelper.rname_to_id(arg, "CLUSTER") + end + + set :format, :groupid, OpenNebulaHelper.rname_to_id_desc("GROUP") do |arg| + OpenNebulaHelper.rname_to_id(arg, "GROUP") + end + + set :format, :userid, OpenNebulaHelper.rname_to_id_desc("USER") do |arg| + OpenNebulaHelper.rname_to_id(arg, "USER") + end + ######################################################################## # Commands ######################################################################## From 1bb6d434645dc3e0639f00760c46ab49e86fa269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 2 Mar 2012 19:10:41 +0100 Subject: [PATCH 104/217] Feature #1112: Create system and default datastores in cluster 'none' --- src/datastore/DatastorePool.cc | 44 +++++++--------------------------- 1 file changed, 9 insertions(+), 35 deletions(-) diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index 9897f80790..d45f1eb0d3 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -45,11 +45,7 @@ DatastorePool::DatastorePool(SqlDB * db): { DatastoreTemplate * ds_tmpl; - int rc, system_id, default_id; - Nebula& nd = Nebula::instance(); - - ClusterPool * clpool = nd.get_clpool(); - Cluster * cluster; + int rc; // --------------------------------------------------------------------- // Create the system datastore @@ -72,12 +68,12 @@ DatastorePool::DatastorePool(SqlDB * db): UserPool::oneadmin_name, GroupPool::ONEADMIN_NAME, ds_tmpl, - &system_id, - ClusterPool::DEFAULT_CLUSTER_ID, - ClusterPool::DEFAULT_CLUSTER_NAME, + &rc, + ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME, error_str); - if( system_id < 0 ) + if( rc < 0 ) { goto error_bootstrap; } @@ -104,38 +100,16 @@ DatastorePool::DatastorePool(SqlDB * db): UserPool::oneadmin_name, GroupPool::ONEADMIN_NAME, ds_tmpl, - &default_id, - ClusterPool::DEFAULT_CLUSTER_ID, - ClusterPool::DEFAULT_CLUSTER_NAME, + &rc, + ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME, error_str); - if( default_id < 0 ) + if( rc < 0 ) { goto error_bootstrap; } - // Add to Cluster - cluster = clpool->get(ClusterPool::DEFAULT_CLUSTER_ID, true); - - if( cluster == 0 ) - { - error_str = "Could not get default cluster"; - goto error_bootstrap; - } - - rc = cluster->add_datastore(system_id, error_str); - rc += cluster->add_datastore(default_id, error_str); - - if ( rc != 0 ) - { - cluster->unlock(); - goto error_bootstrap; - } - - clpool->update(cluster); - - cluster->unlock(); - // User created datastores will start from ID 100 set_update_lastOID(99); } From e71c78c18742de020c6d52a18e2fbc97e88f6cd0 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 3 Mar 2012 03:37:06 +0100 Subject: [PATCH 105/217] feature #1112: Do not make system_datastore directory for a VM. --- src/vm/VirtualMachine.cc | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 1700dff31e..759c4b89ce 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -164,12 +164,7 @@ int VirtualMachine::select(SqlDB * db) mkdir(oss.str().c_str(), 0700); chmod(oss.str().c_str(), 0700); - - system_dir = get_system_dir(); - - mkdir(system_dir.c_str(), 0700); - chmod(system_dir.c_str(), 0700); - + //-------------------------------------------------------------------------- //Create Log support for this VM //-------------------------------------------------------------------------- From eb33fab49f833b3f54e8e6d536db9d97cb1caf2e Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 3 Mar 2012 03:37:38 +0100 Subject: [PATCH 106/217] feature #1112: Fix bug when one of the actions of a TM script fails --- src/tm_mad/one_tm.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tm_mad/one_tm.rb b/src/tm_mad/one_tm.rb index 4f3e56a992..d8fc620987 100755 --- a/src/tm_mad/one_tm.rb +++ b/src/tm_mad/one_tm.rb @@ -84,7 +84,7 @@ class TransferManagerDriver < OpenNebulaDriver if result == RESULT[:failure] send_message("TRANSFER", result, id, info) - break + return end } From 193c3d2c94996aa879b1a1121db352fbd5347d8b Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 3 Mar 2012 03:38:18 +0100 Subject: [PATCH 107/217] feature #1112: Do not set DATASTORE_LOCATION value, use the default --- share/etc/oned.conf | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 1e51799aaa..4f99071a3c 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -82,7 +82,8 @@ MAC_PREFIX = "02:00" #******************************************************************************* # DATASTORE_LOCATION: Path for Datastores in the hosts. It IS the same all the # hosts in the cluster. DATASTORE_LOCATION IS ONLY FOR THE HOSTS AND *NOT* THE -# FRONT-END +# FRONT-END. It defaults to /var/lib/one/datastores (or +# $ONE_LOCATION/var/datastores in self-contained mode) # # DEFAULT_IMAGE_TYPE: This can take values # OS Image file holding an operating system @@ -96,7 +97,7 @@ MAC_PREFIX = "02:00" # vd KVM virtual disk #******************************************************************************* -DATASTORE_LOCATION = /var/lib/one/datastores +#DATASTORE_LOCATION = /var/lib/one/datastores DEFAULT_IMAGE_TYPE = "OS" DEFAULT_DEVICE_PREFIX = "hd" From 4dc9a34b790e6f9ec8d48479a072b6cfdd301da8 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 3 Mar 2012 03:39:21 +0100 Subject: [PATCH 108/217] feature #1112: TM shared and ssh. It should allow any combination of system datastore and images datastore types (shared-shared, ssh-shared, shared-ssh, ssh-ssh) --- src/mad/sh/scripts_common.sh | 19 ++++--- src/tm_mad/common/context | 78 ++++++++++++++++++++++++++ src/tm_mad/common/delete | 47 ++++++++++++++++ src/tm_mad/{dummy => common}/dummy.sh | 0 src/tm_mad/common/mkimage | 61 +++++++++++++++++++++ src/tm_mad/common/mkswap | 30 ++++++++++ src/tm_mad/dummy/clone | 2 +- src/tm_mad/dummy/context | 2 +- src/tm_mad/dummy/delete | 2 +- src/tm_mad/dummy/ln | 2 +- src/tm_mad/dummy/mkimage | 2 +- src/tm_mad/dummy/mkswap | 2 +- src/tm_mad/dummy/mv | 2 +- src/tm_mad/dummy/mvds | 1 + src/tm_mad/shared/clone | 26 ++++----- src/tm_mad/shared/context | 79 +-------------------------- src/tm_mad/shared/delete | 52 +----------------- src/tm_mad/shared/ln | 26 +++------ src/tm_mad/shared/mkimage | 66 +--------------------- src/tm_mad/shared/mkswap | 29 +--------- src/tm_mad/shared/mv | 2 +- src/tm_mad/ssh/clone | 37 +++++++------ src/tm_mad/ssh/context | 73 +------------------------ src/tm_mad/ssh/delete | 36 +----------- src/tm_mad/ssh/ln | 35 +----------- src/tm_mad/ssh/mkimage | 44 +-------------- src/tm_mad/ssh/mkswap | 46 +--------------- src/tm_mad/ssh/mv | 38 +++++++++---- src/tm_mad/tm_common.sh | 64 +++++++++++++++++++++- 29 files changed, 374 insertions(+), 529 deletions(-) create mode 100755 src/tm_mad/common/context create mode 100755 src/tm_mad/common/delete rename src/tm_mad/{dummy => common}/dummy.sh (100%) create mode 100755 src/tm_mad/common/mkimage create mode 100755 src/tm_mad/common/mkswap create mode 120000 src/tm_mad/dummy/mvds mode change 100755 => 120000 src/tm_mad/shared/context mode change 100755 => 120000 src/tm_mad/shared/delete mode change 100755 => 120000 src/tm_mad/shared/mkimage mode change 100755 => 120000 src/tm_mad/shared/mkswap mode change 100755 => 120000 src/tm_mad/ssh/context mode change 100755 => 120000 src/tm_mad/ssh/delete mode change 100755 => 120000 src/tm_mad/ssh/ln mode change 100755 => 120000 src/tm_mad/ssh/mkimage mode change 100755 => 120000 src/tm_mad/ssh/mkswap diff --git a/src/mad/sh/scripts_common.sh b/src/mad/sh/scripts_common.sh index 9201d919a9..b60c15d8a7 100755 --- a/src/mad/sh/scripts_common.sh +++ b/src/mad/sh/scripts_common.sh @@ -109,19 +109,20 @@ function error_message function exec_and_log { message=$2 - output=`$1 2>&1 1>/dev/null` - code=$? - if [ "x$code" != "x0" ]; then - log_error "Command \"$1\" failed." - log_error "$output" - if [ -z "$message" ]; then - error_message "$output" + + EXEC_LOG_ERR=`$1 2>&1 1>/dev/null` + EXEC_LOG_RC=$? + + if [ $EXEC_LOG_RC -ne 0 ]; then + log_error "Command \"$1\" failed: $EXEC_LOG_ERR" + + if [ -n "$2" ]; then + error_message "$2" else - error_message "$message" + error_message "Error executing $1: $EXEC_LOG_ERR" fi exit $code fi - log "Executed \"$1\"." } # Like exec_and_log but the first argument is the number of seconds diff --git a/src/tm_mad/common/context b/src/tm_mad/common/context new file mode 100755 index 0000000000..a36c2e5699 --- /dev/null +++ b/src/tm_mad/common/context @@ -0,0 +1,78 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +# context context.sh file1 file2 ... fileN host:remote_system_ds/disk.i +# - context.sh file are the contents of the context ISO +# - host is the target host to deploy the VM +# - remote_system_ds is the path for the system datastore in the host + +while (( "$#" )); do + if [ "$#" == "1" ]; then + DST=$1 + else + SRC="$SRC $1" + fi + shift +done + +if [ -z "${ONE_LOCATION}" ]; then + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh +else + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh +fi + +. $TMCOMMON + +#------------------------------------------------------------------------------- +# Set dst path and dirs +#------------------------------------------------------------------------------- +DST_PATH=`arg_path $DST` +DST_HOST=`arg_host $DST` +DST_DIR=`dirname $DST_PATH` + +ssh_make_path $DST_HOST $DST_DIR + +#------------------------------------------------------------------------------- +# Build the Context Block device (locally) and copy it remotely +#------------------------------------------------------------------------------- +log "Generating context block device at $DST" + +VM_ID=`basename $DST_DIR` +ISO_DIR="$DS_DIR/.isofiles/$VM_ID" +ISO_FILE="$ISO_DIR/$VM_ID.iso" + +exec_and_log "mkdir -p $ISO_DIR" "Could not create tmp dir to make context dev" + +for f in $SRC; do + case $f in + http://*) + exec_and_log "$WGET -P $ISO_DIR $f" "Error downloading $f" + ;; + *) + exec_and_log "cp -R $f $ISO_DIR" "Error copying $f to $ISO_DIR" + ;; + esac +done + +exec_and_log "$MKISOFS -o $ISO_FILE -J -R $ISO_DIR" "Error creating iso fs" + +exec_and_log "$SCP $ISO_FILE $DST" "Error copying context ISO to $DST" + +rm -rf $ISO_DIR > /dev/null 2>&1 + +exit 0 diff --git a/src/tm_mad/common/delete b/src/tm_mad/common/delete new file mode 100755 index 0000000000..f0c68244a6 --- /dev/null +++ b/src/tm_mad/common/delete @@ -0,0 +1,47 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +# DELETE +# - host is the target host to deploy the VM +# - remote_system_ds is the path for the system datastore in the host + +DST=$1 + +if [ -z "${ONE_LOCATION}" ]; then + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh +else + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh +fi + +. $TMCOMMON + +#------------------------------------------------------------------------------- +# Return if deleting a disk, we will delete them when removing the +# remote_system_ds directory for the VM (remotely) +#------------------------------------------------------------------------------- +DST_PATH=`arg_path $DST` +DST_HOST=`arg_host $DST` + +if [ `is_disk $DST_PATH` -eq 1 ]; then + exit 0 +fi + +log "Deleting $DST_PATH" +ssh_exec_and_log $DST_HOST "rm -rf $DST_PATH" "Error deleting $DST_PATH" + +exit 0 diff --git a/src/tm_mad/dummy/dummy.sh b/src/tm_mad/common/dummy.sh similarity index 100% rename from src/tm_mad/dummy/dummy.sh rename to src/tm_mad/common/dummy.sh diff --git a/src/tm_mad/common/mkimage b/src/tm_mad/common/mkimage new file mode 100755 index 0000000000..3471e81410 --- /dev/null +++ b/src/tm_mad/common/mkimage @@ -0,0 +1,61 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +# mkimage size format host:remote_system_ds/disk.i size +# - size in MB of the image +# - format for the image +# - host is the target host to deploy the VM +# - remote_system_ds is the path for the system datastore in the host + +SIZE=$1 +FSTYPE=$2 +DST=$3 + +if [ -z "${ONE_LOCATION}" ]; then + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh +else + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh +fi + +. $TMCOMMON + +#------------------------------------------------------------------------------- +# Set dst path and dir +#------------------------------------------------------------------------------- +DST_PATH=`arg_path $DST` +DST_HOST=`arg_host $DST` +DST_DIR=`dirname $DST_PATH` + +ssh_make_path $DST_HOST $DST_DIR + +#------------------------------------------------------------------------------- +# Make the new image (file-based) +#------------------------------------------------------------------------------- +MKFS_CMD=`mkfs_command $DST_PATH $FSTYPE` + +MKSCRIPT=$(cat < -# - host is the target host to deploy the VM -# - remote_system_ds is the path for the system datastore in the host - -DST=$1 - -if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh -else - TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh -fi - -. $TMCOMMON - -#------------------------------------------------------------------------------- -# Set dst path and dir -# Return if deleting a disk, we will delete them when removing the -# remote_system_ds directory for the VM -#------------------------------------------------------------------------------- - -DST_PATH=`arg_path $DST` - -if [ `is_disk $DST_PATH` -eq 1 ]; then - exit 0 -fi - -set_ds_location - -REL_DST_PATH=${DST_PATH##"$DS_LOCATION/"} -DST_PATH="$ONE_LOCAL_VAR/datastores/$REL_DST_PATH" - -log "Deleting $DST_PATH" -exec_and_log "rm -rf $DST_PATH" "Error deleting $DST_PATH" diff --git a/src/tm_mad/shared/delete b/src/tm_mad/shared/delete new file mode 120000 index 0000000000..230e56774f --- /dev/null +++ b/src/tm_mad/shared/delete @@ -0,0 +1 @@ +../common/delete \ No newline at end of file diff --git a/src/tm_mad/shared/ln b/src/tm_mad/shared/ln index 480ea50def..4ecb76e42b 100755 --- a/src/tm_mad/shared/ln +++ b/src/tm_mad/shared/ln @@ -37,30 +37,22 @@ fi # Set dst path and dir #------------------------------------------------------------------------------- SRC_PATH=`arg_path $SRC` +SRC_PATH="../../${SRC_PATH##"$DS_DIR/"}" + DST_PATH=`arg_path $DST` - -set_ds_location - -REL_DST_PATH=${DST_PATH##"$DS_LOCATION/"} -REL_SRC_PATH=${SRC_PATH##"$ONE_LOCAL_VAR/datastores/"} - -DST_PATH="$ONE_LOCAL_VAR/datastores/$REL_DST_PATH" +DST_HOST=`arg_host $DST` DST_DIR=`dirname $DST_PATH` -if [ ! -d $DST_DIR ]; then - log "Creating directory $DST_DIR" - exec_and_log "mkdir -p $DST_DIR" -fi - -DST_FILE=`basename $DST_PATH` +ssh_make_path $DST_HOST $DST_DIR #------------------------------------------------------------------------------- # Link (ln) SRC into DST #------------------------------------------------------------------------------- -log "Linking $SRC_PATH in $DST_PATH" +log "Linking $SRC_PATH in $DST" -cd $DST_DIR +ssh_exec_and_log $DST_HOST \ + "cd $DST_DIR; ln -s $SRC_PATH $DST_PATH" \ + "Error linking $SRC to $DST" -exec_and_log "ln -s ../../$REL_SRC_PATH ./$DST_FILE" \ - "Error linking $SRC to $DST" +exit 0 diff --git a/src/tm_mad/shared/mkimage b/src/tm_mad/shared/mkimage deleted file mode 100755 index d651075dcc..0000000000 --- a/src/tm_mad/shared/mkimage +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash - -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -# mkimage size format host:remote_system_ds/disk.i size -# - size in MB of the image -# - format for the image -# - host is the target host to deploy the VM -# - remote_system_ds is the path for the system datastore in the host - -SIZE=$1 -FSTYPE=$2 -DST=$3 - -if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh -else - TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh -fi - -. $TMCOMMON - -#------------------------------------------------------------------------------- -# Set dst path and dir -#------------------------------------------------------------------------------- -DST_PATH=`arg_path $DST` - -set_ds_location - -REL_DST_PATH=${DST_PATH##"$DS_LOCATION/"} -DST_PATH="$ONE_LOCAL_VAR/datastores/$REL_DST_PATH" - -DST_DIR=`dirname $DST_PATH` - -if [ ! -d $DST_DIR ]; then - log "Creating directory $DST_DIR" - exec_and_log "mkdir -p $DST_DIR" -fi - -#------------------------------------------------------------------------------- -# Make the new image (file-based) -#------------------------------------------------------------------------------- - -MKFS_CMD=`mkfs_command $DST_PATH $FSTYPE` - -exec_and_log "$DD if=/dev/zero of=$DST_PATH bs=1 count=1 seek=${SIZE}M" \ - "Could not create image $DST_PATH" - -if [ -n "$MKFS_CMD" ]; then - exec_and_log "$MKFS_CMD" "Unable to create filesystem $FSTYPE in $DST_PATH" -fi \ No newline at end of file diff --git a/src/tm_mad/shared/mkimage b/src/tm_mad/shared/mkimage new file mode 120000 index 0000000000..ad1bdd354d --- /dev/null +++ b/src/tm_mad/shared/mkimage @@ -0,0 +1 @@ +../common/mkimage \ No newline at end of file diff --git a/src/tm_mad/shared/mkswap b/src/tm_mad/shared/mkswap deleted file mode 100755 index 51ac4d96a1..0000000000 --- a/src/tm_mad/shared/mkswap +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -# mkswap size host:remote_system_ds/disk.i size -# - size in MB of the image -# - host is the target host to deploy the VM -# - remote_system_ds is the path for the system datastore in the host - -SIZE=$1 -DST=$2 - -CMD="`dirname $0`/mkimage $SIZE swap $DST" -`$CMD` diff --git a/src/tm_mad/shared/mkswap b/src/tm_mad/shared/mkswap new file mode 120000 index 0000000000..3e0699b0f3 --- /dev/null +++ b/src/tm_mad/shared/mkswap @@ -0,0 +1 @@ +../common/mkswap \ No newline at end of file diff --git a/src/tm_mad/shared/mv b/src/tm_mad/shared/mv index 2507dfb82d..300563f2ad 120000 --- a/src/tm_mad/shared/mv +++ b/src/tm_mad/shared/mv @@ -1 +1 @@ -../dummy/dummy.sh \ No newline at end of file +../common/dummy.sh \ No newline at end of file diff --git a/src/tm_mad/ssh/clone b/src/tm_mad/ssh/clone index 10e1c28a96..ef7a0b6db0 100755 --- a/src/tm_mad/ssh/clone +++ b/src/tm_mad/ssh/clone @@ -16,46 +16,49 @@ # limitations under the License. # #--------------------------------------------------------------------------- # +# clone fe:SOURCE host:remote_system_ds/disk.i size +# - fe is the front-end hostname +# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk +# - host is the target host to deploy the VM +# - remote_system_ds is the path for the system datastore in the host + SRC=$1 DST=$2 if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/usr/lib/one/mads/tm_common.sh + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh else - TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh fi . $TMCOMMON +#------------------------------------------------------------------------------- +# Set dst path and dir +#------------------------------------------------------------------------------- + SRC_PATH=`arg_path $SRC` DST_PATH=`arg_path $DST` SRC_HOST=`arg_host $SRC` DST_HOST=`arg_host $DST` - -log_debug "$1 $2" -log_debug "DST: $DST_PATH" - DST_DIR=`dirname $DST_PATH` -log "Creating directory $DST_DIR" -exec_and_log "$SSH $DST_HOST mkdir -p $DST_DIR" \ - "Error creating directory $DST_DIR" +ssh_make_path $DST_HOST $DST_DIR +#------------------------------------------------------------------------------- +# Copy files to the remote host +#------------------------------------------------------------------------------- case $SRC in http://*) log "Downloading $SRC" - exec_and_log "$SSH $DST_HOST $WGET -O $DST_PATH $SRC" \ - "Error downloading $SRC" + RMT_CMD="$WGET -O $DST_PATH $SRC" + ssh_exec_and_log "$DST_HOST" "$RMT_CMD" "Error downloading $SRC" ;; *) - log "Cloning $SRC" - exec_and_log "$SCP $SRC $DST" \ - "Error copying $SRC to $DST" + log "Cloning $SRC in $DST_PATH" + exec_and_log "$SCP $SRC $DST" "Error copying $SRC to $DST" ;; esac - -exec_and_log "$SSH $DST_HOST chmod a+rw $DST_PATH" - diff --git a/src/tm_mad/ssh/context b/src/tm_mad/ssh/context deleted file mode 100755 index 0827fdef9f..0000000000 --- a/src/tm_mad/ssh/context +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/bash - -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -while (( "$#" )); do - if [ "$#" == "1" ]; then - DST=$1 - else - SRC="$SRC $1" - fi - shift -done - - -if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/usr/lib/one/mads/tm_common.sh -else - TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh -fi - -. $TMCOMMON - - -DST_PATH=`arg_path $DST` -DST_DIR=`dirname $DST_PATH` -DST_FILE=`basename $DST_PATH` -DST_HASH=`echo -n $DST | $MD5SUM | $AWK '{print $1}'` -if [ -z "$ONE_LOCATION" ]; then - TMP_DIR="/var/lib/one/$DST_HASH" -else - TMP_DIR="$ONE_LOCATION/var/$DST_HASH" -fi -ISO_DIR="$TMP_DIR/isofiles" - - -exec_and_log "mkdir -p $ISO_DIR" \ - "Error creating directory $ISO_DIR" - -for f in $SRC; do - case $f in - http://*) - exec_and_log "$WGET -P $ISO_DIR $f" \ - "Error downloading $f" - ;; - - *) - exec_and_log "cp -R $f $ISO_DIR" \ - "Error copying $f to $ISO_DIR" - ;; - esac -done - -exec_and_log "$MKISOFS -o $TMP_DIR/$DST_FILE -J -R $ISO_DIR" \ - "Error creating iso fs" -exec_and_log "$SCP $TMP_DIR/$DST_FILE $DST" \ - "Error copying $TMP_DIR/$DST_FILE to $DST" -exec_and_log "rm -rf $TMP_DIR" \ - "Error deleting $TMP_DIR" diff --git a/src/tm_mad/ssh/context b/src/tm_mad/ssh/context new file mode 120000 index 0000000000..921312e950 --- /dev/null +++ b/src/tm_mad/ssh/context @@ -0,0 +1 @@ +../common/context \ No newline at end of file diff --git a/src/tm_mad/ssh/delete b/src/tm_mad/ssh/delete deleted file mode 100755 index 9046c19414..0000000000 --- a/src/tm_mad/ssh/delete +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -SRC=$1 -DST=$2 - -if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/usr/lib/one/mads/tm_common.sh -else - TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh -fi - -. $TMCOMMON - -SRC_PATH=`arg_path $SRC` -SRC_HOST=`arg_host $SRC` - -log "Deleting $SRC_PATH" -exec_and_log "$SSH $SRC_HOST rm -rf $SRC_PATH" \ - "Error deleting $SRC_PATH" diff --git a/src/tm_mad/ssh/delete b/src/tm_mad/ssh/delete new file mode 120000 index 0000000000..230e56774f --- /dev/null +++ b/src/tm_mad/ssh/delete @@ -0,0 +1 @@ +../common/delete \ No newline at end of file diff --git a/src/tm_mad/ssh/ln b/src/tm_mad/ssh/ln deleted file mode 100755 index 40d8e6f2e5..0000000000 --- a/src/tm_mad/ssh/ln +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -SRC=$1 -DST=$2 - -if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/usr/lib/one/mads/tm_common.sh - TM_COMMANDS_LOCATION=/usr/lib/one/tm_commands/ -else - TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh - TM_COMMANDS_LOCATION=$ONE_LOCATION/lib/tm_commands/ -fi - -. $TMCOMMON - -log "Link $SRC_PATH (non shared dir, will clone)" -#exec_and_log "ln -s $SRC_PATH $DST_PATH" -exec $TM_COMMANDS_LOCATION/ssh/tm_clone.sh $SRC $DST diff --git a/src/tm_mad/ssh/ln b/src/tm_mad/ssh/ln new file mode 120000 index 0000000000..4197517ec0 --- /dev/null +++ b/src/tm_mad/ssh/ln @@ -0,0 +1 @@ +./clone \ No newline at end of file diff --git a/src/tm_mad/ssh/mkimage b/src/tm_mad/ssh/mkimage deleted file mode 100755 index ace8017ca8..0000000000 --- a/src/tm_mad/ssh/mkimage +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/usr/lib/one/mads/tm_common.sh -else - TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh -fi - -. $TMCOMMON - -SIZE=$1 -FSTYPE=$2 -DST=$3 - -DST_PATH=`arg_path $DST` -DST_HOST=`arg_host $DST` -DST_DIR=`dirname $DST_PATH` - -MKFS_CMD=`mkfs_command $DST_PATH $FSTYPE` - -exec_and_log "$SSH $DST_HOST mkdir -p $DST_DIR" \ - "Error creating directory $DST_DIR" -exec_and_log "$SSH $DST_HOST $DD if=/dev/zero of=$DST_PATH bs=1 count=1 seek=${SIZE}M" \ - "Could not create image $DST_PATH" -exec_and_log "$SSH $DST_HOST $MKFS_CMD" \ - "Unable to create filesystem $FSTYPE in $DST_PATH" -exec_and_log "$SSH $DST_HOST chmod a+rw $DST_PATH" diff --git a/src/tm_mad/ssh/mkimage b/src/tm_mad/ssh/mkimage new file mode 120000 index 0000000000..ad1bdd354d --- /dev/null +++ b/src/tm_mad/ssh/mkimage @@ -0,0 +1 @@ +../common/mkimage \ No newline at end of file diff --git a/src/tm_mad/ssh/mkswap b/src/tm_mad/ssh/mkswap deleted file mode 100755 index b2c9b80665..0000000000 --- a/src/tm_mad/ssh/mkswap +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -SIZE=$1 -DST=$2 - -if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/usr/lib/one/mads/tm_common.sh -else - TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh -fi - -. $TMCOMMON - -DST_PATH=`arg_path $DST` -DST_HOST=`arg_host $DST` - -DST_DIR=`dirname $DST_PATH` - -log "Creating ${SIZE}Mb image in $DST_PATH" -exec_and_log "$SSH $DST_HOST mkdir -p $DST_DIR" -exec_and_log "$SSH $DST_HOST $DD if=/dev/zero of=$DST_PATH bs=1 count=1 seek=${SIZE}M" \ - "Could not create image file $DST_PATH" - -log "Initializing swap space" -exec_and_log "$SSH $DST_HOST $MKSWAP $DST_PATH" \ - "Could not create swap on $DST_PATH" - -exec_and_log "$SSH $DST_HOST chmod a+w $DST_PATH" - diff --git a/src/tm_mad/ssh/mkswap b/src/tm_mad/ssh/mkswap new file mode 120000 index 0000000000..3e0699b0f3 --- /dev/null +++ b/src/tm_mad/ssh/mkswap @@ -0,0 +1 @@ +../common/mkswap \ No newline at end of file diff --git a/src/tm_mad/ssh/mv b/src/tm_mad/ssh/mv index e7c7e2d668..61319e6612 100755 --- a/src/tm_mad/ssh/mv +++ b/src/tm_mad/ssh/mv @@ -16,17 +16,26 @@ # limitations under the License. # #--------------------------------------------------------------------------- # +# MV +# +# - hostX is the target host to deploy the VM +# - system_ds is the path for the system datastore in the host + SRC=$1 DST=$2 if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/usr/lib/one/mads/tm_common.sh + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh else - TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh fi . $TMCOMMON +#------------------------------------------------------------------------------- +# Return if moving a disk, we will move them when moving the whole system_ds +# directory for the VM +#------------------------------------------------------------------------------- SRC_PATH=`arg_path $SRC` DST_PATH=`arg_path $DST` @@ -35,14 +44,21 @@ DST_HOST=`arg_host $DST` DST_DIR=`dirname $DST_PATH` -if full_src_and_dst_equal; then - log "Not moving $SRC to $DST, they are the same path" -else - log "Moving $SRC_PATH" - exec_and_log "$SSH $DST_HOST mkdir -p $DST_DIR" \ - "Unable to create directory $DST_DIR" - exec_and_log "$SCP -r $SRC $DST" \ - "Could not copy $SRC to $DST" - exec_and_log "$SSH $SRC_HOST rm -rf $SRC_PATH" +if [ `is_disk $DST_PATH` -eq 1 ]; then + exit 0 fi +if [ "$SRC" == "$DST" ]; then + log "Not moving $SRC to $DST, they are the same path" + exit 0 +fi + +ssh_make_path $DST_HOST $DST_DIR + +log "Moving $SRC to $DST" + +exec_and_log "$SCP -r $SRC $DST" "Could not copy $SRC to $DST" + +exec_and_log "$SSH $SRC_HOST rm -rf $SRC_PATH" + +exit 0 diff --git a/src/tm_mad/tm_common.sh b/src/tm_mad/tm_common.sh index 07578a18b8..6626ef591f 100644 --- a/src/tm_mad/tm_common.sh +++ b/src/tm_mad/tm_common.sh @@ -22,9 +22,11 @@ export LANG=C if [ -z "$ONE_LOCATION" ]; then ONE_LOCAL_VAR=/var/lib/one ONE_LIB=/usr/lib/one + DS_DIR=/var/lib/one/datastores else ONE_LOCAL_VAR=$ONE_LOCATION/var ONE_LIB=$ONE_LOCATION/lib + DS_DIR=$ONE_LOCATION/var/datastores fi ONE_SH=$ONE_LIB/sh @@ -56,8 +58,10 @@ function arg_path #Return the DATASTORE_LOCATION from OpenNebula configuration function set_ds_location { - DS_LOCATION=`$GREP '^DATASTORE_LOCATION=' $ONE_LOCAL_VAR/config | cut -d= -f2` - DS_LOCATION=`fix_dir_slashes $DS_LOCATION` + RMT_DS_DIR=`$GREP '^DATASTORE_LOCATION=' $ONE_LOCAL_VAR/config | cut -d= -f2` + RMT_DS_DIR=`fix_dir_slashes $DS_LOCATION` + + export RMT_DS_DIR } #Return 1 if the first argument is a disk @@ -70,4 +74,58 @@ function is_disk else echo "0" fi -} \ No newline at end of file +} + +# ------------------------------------------------------------------------------ +# Function to get hosts and paths from arguments +# ------------------------------------------------------------------------------ + +#This function executes $2 at $1 host and report error $3 +function ssh_exec_and_log +{ + SSH_EXEC_ERR=`$SSH $1 bash -s 2>&1 1>/dev/null <&1 1>/dev/null < Date: Sun, 4 Mar 2012 22:23:01 +0100 Subject: [PATCH 109/217] feature #1112: Move to Datastore action for the shared and ssh transfer drivers --- src/tm_mad/shared/mvds | 73 ++++++++++++++++++++++++++++++++++++++++++ src/tm_mad/ssh/clone | 1 - src/tm_mad/ssh/mvds | 54 +++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 1 deletion(-) create mode 100755 src/tm_mad/shared/mvds create mode 100755 src/tm_mad/ssh/mvds diff --git a/src/tm_mad/shared/mvds b/src/tm_mad/shared/mvds new file mode 100755 index 0000000000..94116583cd --- /dev/null +++ b/src/tm_mad/shared/mvds @@ -0,0 +1,73 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +# mvds host:remote_system_ds/disk.i fe:SOURCE +# - fe is the front-end hostname +# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk +# - host is the target host to deploy the VM +# - remote_system_ds is the path for the system datastore in the host + +SRC=$1 +DST=$2 + +if [ -z "${ONE_LOCATION}" ]; then + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh +else + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh +fi + +. $TMCOMMON + +set_ds_location + +#------------------------------------------------------------------------------- +# Set dst path and dir +#------------------------------------------------------------------------------- +SRC_PATH=`arg_path $SRC` +DST_PATH=`arg_path $DST` + +DST_PATH="$RMT_DS_DIR/${DST_PATH##"$DS_DIR/"}" + +SRC_HOST=`arg_host $DST` + +#------------------------------------------------------------------------------- +# Move the image back to the datastore +#------------------------------------------------------------------------------- +MVSCRIPT=$(cat < Date: Mon, 5 Mar 2012 11:53:59 +0100 Subject: [PATCH 110/217] feature #1112: Remove unnecessary files from install.sh and the 'mv' datastore scripts --- install.sh | 8 --- src/datastore_mad/remotes/fs/fs.conf | 38 ---------- src/datastore_mad/remotes/fs/mv | 75 -------------------- src/datastore_mad/remotes/vmware/mv | 75 -------------------- src/datastore_mad/remotes/vmware/vmware.conf | 38 ---------- 5 files changed, 234 deletions(-) delete mode 100644 src/datastore_mad/remotes/fs/fs.conf delete mode 100755 src/datastore_mad/remotes/fs/mv delete mode 100755 src/datastore_mad/remotes/vmware/mv delete mode 100644 src/datastore_mad/remotes/vmware/vmware.conf diff --git a/install.sh b/install.sh index 0c2304050e..e8403dd398 100755 --- a/install.sh +++ b/install.sh @@ -529,8 +529,6 @@ INSTALL_ETC_FILES=( VMWARE_ETC_FILES:$ETC_LOCATION VMM_EC2_ETC_FILES:$ETC_LOCATION/vmm_ec2 VMM_EXEC_ETC_FILES:$ETC_LOCATION/vmm_exec - DATASTORE_DRIVER_FS_ETC_FILES:$ETC_LOCATION/datastore/ - DATASTORE_DRIVER_VMWARE_ETC_FILES:$ETC_LOCATION/datastore/ IM_EC2_ETC_FILES:$ETC_LOCATION/im_ec2 TM_LVM_ETC_FILES:$ETC_LOCATION/tm/ HM_ETC_FILES:$ETC_LOCATION/hm @@ -808,21 +806,15 @@ TM_VMWARE_FILES="src/tm_mad/vmware/clone \ # - VMware based Image Repository, $REMOTES_LOCATION/datastore/vmware #------------------------------------------------------------------------------- -DATASTORE_DRIVER_FS_ETC_FILES="src/datastore_mad/remotes/fs/fs.conf" - -DATASTORE_DRIVER_VMWARE_ETC_FILES="src/datastore_mad/remotes/vmware/vmware.conf" - DATASTORE_DRIVER_COMMON_SCRIPTS="src/datastore_mad/remotes/xpath.rb \ src/datastore_mad/remotes/libfs.sh" DATASTORE_DRIVER_FS_SCRIPTS="src/datastore_mad/remotes/fs/cp \ src/datastore_mad/remotes/fs/mkfs \ - src/datastore_mad/remotes/fs/mv \ src/datastore_mad/remotes/fs/rm" DATASTORE_DRIVER_VMWARE_SCRIPTS="src/datastore_mad/remotes/vmware/cp \ src/datastore_mad/remotes/vmware/mkfs \ - src/datastore_mad/remotes/vmware/mv \ src/datastore_mad/remotes/vmware/rm" #------------------------------------------------------------------------------- diff --git a/src/datastore_mad/remotes/fs/fs.conf b/src/datastore_mad/remotes/fs/fs.conf deleted file mode 100644 index ec29989e22..0000000000 --- a/src/datastore_mad/remotes/fs/fs.conf +++ /dev/null @@ -1,38 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -# PRESERVE BASH SYNTAX - -#******************************************************************************* -# DEFAULT Configuration File for File-System based Datastores -#------------------------------------------------------------------------------- -# BASE_PATH: Path where the images will be stored. If not defined -# defaults to /var/lib/one/images or $ONE_LOCATION/var/images -# -# RESTRICTED_DIRS: Paths that can not be used to register images. A space -# separated list of paths. This prevents users to access important files like -# oned.db or /etc/shadow. OpenNebula will automatically add its configuration -# dirs:/var/lib/one, /etc/one and oneadmin's home ($HOME). -# -# SAFE_DIRS: Paths that are safe to specify image paths. A space separated list -# of paths.This will allow you to open specific paths within RESTRICTED_DIRS -#******************************************************************************* - -#BASE_PATH=/var/lib/one/images - -RESTRICTED_DIRS="/etc/" - -SAFE_DIRS="$HOME/public/" diff --git a/src/datastore_mad/remotes/fs/mv b/src/datastore_mad/remotes/fs/mv deleted file mode 100755 index 8ea2259a28..0000000000 --- a/src/datastore_mad/remotes/fs/mv +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash - -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -############################################################################### -# This script is used to move a VM image (SRC) to the image repository as DST -# Several SRC types are supported -############################################################################### - -# ------------ Set up the environment to source common tools ------------ - -if [ -z "${ONE_LOCATION}" ]; then - LIB_LOCATION=/usr/lib/one -else - LIB_LOCATION=$ONE_LOCATION/lib -fi - -. $LIB_LOCATION/sh/scripts_common.sh -source $(dirname $0)/fsrc - -SRC=$1 -DST=$2 -ID=$3 - -# ------------ Generate a filename for the image ------------ - -if [ "$DST" = "-" ] ; then - DST=`generate_image_path` -fi - -# ------------ Move the image to the repository ------------ - -case $SRC in -http://*) - log "Downloading $SRC to the image repository" - exec_and_log "$WGET -O $DST $SRC" \ - "Error downloading $SRC" - ;; - -*) - log "Moving local image $SRC to the image repository" - - if [ \( -L $SRC \) -a \ - \( "`$READLINK -f $SRC`" = "`$READLINK -f $DST`" \) ] ; then - log "Not moving files to image repo, they are the same" - else - exec_and_log "mv -f $SRC $DST" "Could not move $SRC to $DST" - fi - ;; -esac - -if [ -d $DST ]; then - exec_and_log "chmod 0770 $DST" -else - exec_and_log "chmod 0660 $DST" -fi - -# ---------------- Get the size of the image ------------ -SIZE=`fs_du $DST` - -echo "$DST $SIZE" diff --git a/src/datastore_mad/remotes/vmware/mv b/src/datastore_mad/remotes/vmware/mv deleted file mode 100755 index 8ea2259a28..0000000000 --- a/src/datastore_mad/remotes/vmware/mv +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash - -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -############################################################################### -# This script is used to move a VM image (SRC) to the image repository as DST -# Several SRC types are supported -############################################################################### - -# ------------ Set up the environment to source common tools ------------ - -if [ -z "${ONE_LOCATION}" ]; then - LIB_LOCATION=/usr/lib/one -else - LIB_LOCATION=$ONE_LOCATION/lib -fi - -. $LIB_LOCATION/sh/scripts_common.sh -source $(dirname $0)/fsrc - -SRC=$1 -DST=$2 -ID=$3 - -# ------------ Generate a filename for the image ------------ - -if [ "$DST" = "-" ] ; then - DST=`generate_image_path` -fi - -# ------------ Move the image to the repository ------------ - -case $SRC in -http://*) - log "Downloading $SRC to the image repository" - exec_and_log "$WGET -O $DST $SRC" \ - "Error downloading $SRC" - ;; - -*) - log "Moving local image $SRC to the image repository" - - if [ \( -L $SRC \) -a \ - \( "`$READLINK -f $SRC`" = "`$READLINK -f $DST`" \) ] ; then - log "Not moving files to image repo, they are the same" - else - exec_and_log "mv -f $SRC $DST" "Could not move $SRC to $DST" - fi - ;; -esac - -if [ -d $DST ]; then - exec_and_log "chmod 0770 $DST" -else - exec_and_log "chmod 0660 $DST" -fi - -# ---------------- Get the size of the image ------------ -SIZE=`fs_du $DST` - -echo "$DST $SIZE" diff --git a/src/datastore_mad/remotes/vmware/vmware.conf b/src/datastore_mad/remotes/vmware/vmware.conf deleted file mode 100644 index ec29989e22..0000000000 --- a/src/datastore_mad/remotes/vmware/vmware.conf +++ /dev/null @@ -1,38 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -# PRESERVE BASH SYNTAX - -#******************************************************************************* -# DEFAULT Configuration File for File-System based Datastores -#------------------------------------------------------------------------------- -# BASE_PATH: Path where the images will be stored. If not defined -# defaults to /var/lib/one/images or $ONE_LOCATION/var/images -# -# RESTRICTED_DIRS: Paths that can not be used to register images. A space -# separated list of paths. This prevents users to access important files like -# oned.db or /etc/shadow. OpenNebula will automatically add its configuration -# dirs:/var/lib/one, /etc/one and oneadmin's home ($HOME). -# -# SAFE_DIRS: Paths that are safe to specify image paths. A space separated list -# of paths.This will allow you to open specific paths within RESTRICTED_DIRS -#******************************************************************************* - -#BASE_PATH=/var/lib/one/images - -RESTRICTED_DIRS="/etc/" - -SAFE_DIRS="$HOME/public/" From f4e20d81ce56062af24644945debd0116adbc794 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Mon, 5 Mar 2012 11:56:18 +0100 Subject: [PATCH 111/217] feature #1112: Improvements in datastora_mad drivers: * Remove unnecessary chowns. * Improve xpath access from datastore shell scripts. * Read UNAME, RESTRICTED_DIRS and SAFE_DIRS from datastore template. * New size function using qemu-img --- src/datastore_mad/remotes/fs/cp | 25 +++++++++---- src/datastore_mad/remotes/fs/mkfs | 23 +++++++++--- src/datastore_mad/remotes/libfs.sh | 54 +++++++++++++++++---------- src/datastore_mad/remotes/vmware/cp | 23 +++++++++--- src/datastore_mad/remotes/vmware/mkfs | 27 ++++++++------ src/datastore_mad/remotes/xpath.rb | 2 +- 6 files changed, 104 insertions(+), 50 deletions(-) diff --git a/src/datastore_mad/remotes/fs/cp b/src/datastore_mad/remotes/fs/cp index 3f99bc4324..b7fe2249f7 100755 --- a/src/datastore_mad/remotes/fs/cp +++ b/src/datastore_mad/remotes/fs/cp @@ -39,10 +39,25 @@ source ${DRIVER_PATH}/../libfs.sh DRV_ACTION=$1 ID=$2 -set_up_datastore $DRV_ACTION - XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" -SRC=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/PATH` + +unset i XPATH_ELEMENTS + +while IFS= read -r -d '' element; do + XPATH_ELEMENTS[i++]="$element" +done < <($XPATH /DS_DRIVER_ACTION_DATA/DATASTORE/BASE_PATH \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/RESTRICTED_DIRS \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/SAFE_DIRS \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/UMASK \ + /DS_DRIVER_ACTION_DATA/IMAGE/PATH) + +BASE_PATH="${XPATH_ELEMENTS[0]}" +RESTRICTED_DIRS="${XPATH_ELEMENTS[1]}" +SAFE_DIRS="${XPATH_ELEMENTS[2]}" +UMASK="${XPATH_ELEMENTS[3]}" +SRC="${XPATH_ELEMENTS[4]}" + +set_up_datastore "$BASE_PATH" "$RESTRICTED_DIRS" "$SAFE_DIRS" "$UMASK" DST=`generate_image_path` @@ -53,8 +68,6 @@ http://*) log "Downloading $SRC to the image repository" exec_and_log "$WGET -O $DST $SRC" "Error downloading $SRC" - - exec_and_log "chmod 0660 $DST" ;; *) @@ -67,8 +80,6 @@ http://*) log "Copying local image $SRC to the image repository" exec_and_log "cp -f $SRC $DST" "Error copying $SRC to $DST" - - exec_and_log "chmod 0660 $DST" ;; esac diff --git a/src/datastore_mad/remotes/fs/mkfs b/src/datastore_mad/remotes/fs/mkfs index 5ec61bdb36..7f27552ad6 100755 --- a/src/datastore_mad/remotes/fs/mkfs +++ b/src/datastore_mad/remotes/fs/mkfs @@ -39,20 +39,32 @@ source ${DRIVER_PATH}/../libfs.sh DRV_ACTION=$1 ID=$2 -set_up_datastore $DRV_ACTION +XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" unset i XPATH_ELEMENTS while IFS= read -r -d '' element; do XPATH_ELEMENTS[i++]="$element" -done < <($XPATH /DS_DRIVER_ACTION_DATA/IMAGE/FSTYPE \ +done < <($XPATH /DS_DRIVER_ACTION_DATA/DATASTORE/BASE_PATH \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/RESTRICTED_DIRS \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/SAFE_DIRS \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/UMASK \ + /DS_DRIVER_ACTION_DATA/IMAGE/PATH \ + /DS_DRIVER_ACTION_DATA/IMAGE/FSTYPE \ /DS_DRIVER_ACTION_DATA/IMAGE/SIZE) -FSTYPE="${XPATH_ELEMENTS[0]}" -SIZE="${XPATH_ELEMENTS[1]}" + +BASE_PATH="${XPATH_ELEMENTS[0]}" +RESTRICTED_DIRS="${XPATH_ELEMENTS[1]}" +SAFE_DIRS="${XPATH_ELEMENTS[2]}" +UMASK="${XPATH_ELEMENTS[3]}" +SRC="${XPATH_ELEMENTS[4]}" +FSTYPE="${XPATH_ELEMENTS[5]}" +SIZE="${XPATH_ELEMENTS[6]}" + +set_up_datastore "$BASE_PATH" "$RESTRICTED_DIRS" "$SAFE_DIRS" "$UMASK" DST=`generate_image_path` - # ------------ Create the image to the repository ------------ MKFS_CMD=`mkfs_command $DST $FSTYPE` @@ -61,7 +73,6 @@ exec_and_log "$DD if=/dev/zero of=$DST bs=1 count=1 seek=${SIZE}M" \ "Could not create image $DST" exec_and_log "$MKFS_CMD" \ "Unable to create filesystem $FSTYPE in $DST" -exec_and_log "chmod 0660 $DST" # ---------------- Get the size of the image ------------ SIZE=`fs_du $DST` diff --git a/src/datastore_mad/remotes/libfs.sh b/src/datastore_mad/remotes/libfs.sh index 4f61c99354..e1b5f67717 100644 --- a/src/datastore_mad/remotes/libfs.sh +++ b/src/datastore_mad/remotes/libfs.sh @@ -17,8 +17,11 @@ #--------------------------------------------------------------------------- # #------------------------------------------------------------------------------ -# Set up environment variables -# @param $1 - template (base 64 encoded) with driver data +# Set up environment variables +# @param $1 - Datastore base_path +# @param $2 - Restricted directories +# @param $3 - Safe dirs +# @param $4 - Umask for new file creation (default: 0007) # @return sets the following environment variables # - RESTRICTED_DIRS: Paths that can not be used to register images # - SAFE_DIRS: Paths that are safe to specify image paths @@ -28,6 +31,11 @@ function set_up_datastore { # # Load the default configuration for FS datastores # + BASE_PATH="$1" + RESTRICTED_DIRS="$2" + SAFE_DIRS="$3" + UMASK="$4" + if [ -z "${ONE_LOCATION}" ]; then VAR_LOCATION=/var/lib/one/ ETC_LOCATION=/etc/one/ @@ -36,24 +44,6 @@ function set_up_datastore { ETC_LOCATION=$ONE_LOCATION/etc/ fi - CONF_FILE=$ETC_LOCATION/datastore/fs.conf - - source $CONF_FILE - - # - # Load attributes from the Datastore - # - XPATH="$VAR_LOCATION/remotes/datastore/xpath.rb -b $1" - eval "DS_BASE_PATH=`$XPATH /DS_DRIVER_ACTION_DATA/DATASTORE/BASE_PATH`" - - if [ -z "${DS_BASE_PATH}" ]; then - if [ -z "${BASE_PATH}" ]; then - BASE_PATH="${VAR_LOCATION}/images" - fi - else - BASE_PATH=${DS_BASE_PATH} - fi - # # RESTRICTED AND SAFE DIRS (from default configuration) # @@ -62,6 +52,14 @@ function set_up_datastore { export BASE_PATH export RESTRICTED_DIRS export SAFE_DIRS + + mkdir -p $BASE_PATH + + if [ -n "$UMASK" ]; then + umask $UMASK + else + umask 0007 + fi } #------------------------------------------------------------------------------- @@ -102,6 +100,22 @@ function fs_du { echo "$SIZE" } +#------------------------------------------------------------------------------- +# Computes the size of an image +# @param $1 - Path to the image +# @return size of the image in Mb +#------------------------------------------------------------------------------- +function qemu_size { + DISK="$1" + + SIZE=`$QEMU_IMG info $DISK|grep "^virtual size:"|\ + sed 's/^.*(\([0-9]\+\) bytes.*$/\1/g'` + + SIZE=$(($SIZE/1048576)) + + echo "$SIZE" +} + #------------------------------------------------------------------------------- # Checks if a path is safe for copying the image from # @param $1 - Path to the image diff --git a/src/datastore_mad/remotes/vmware/cp b/src/datastore_mad/remotes/vmware/cp index 069bd89b72..f216d95892 100755 --- a/src/datastore_mad/remotes/vmware/cp +++ b/src/datastore_mad/remotes/vmware/cp @@ -39,10 +39,25 @@ source ${DRIVER_PATH}/../libfs.sh DRV_ACTION=$1 ID=$2 -set_up_datastore $DRV_ACTION - XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" -SRC=`$XPATH /DS_DRIVER_ACTION_DATA/IMAGE/PATH` + +unset i XPATH_ELEMENTS + +while IFS= read -r -d '' element; do + XPATH_ELEMENTS[i++]="$element" +done < <($XPATH /DS_DRIVER_ACTION_DATA/DATASTORE/BASE_PATH \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/RESTRICTED_DIRS \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/SAFE_DIRS \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/UMASK \ + /DS_DRIVER_ACTION_DATA/IMAGE/PATH) + +BASE_PATH="${XPATH_ELEMENTS[0]}" +RESTRICTED_DIRS="${XPATH_ELEMENTS[1]}" +SAFE_DIRS="${XPATH_ELEMENTS[2]}" +UMASK="${XPATH_ELEMENTS[3]}" +SRC="${XPATH_ELEMENTS[4]}" + +set_up_datastore "$BASE_PATH" "$RESTRICTED_DIRS" "$SAFE_DIRS" "$UMASK" DST=`generate_image_path` @@ -66,8 +81,6 @@ case $SRC in exec_and_log "mv -f $DST/$BASE_DISK_FILE $DST/disk.vmdk" \ "Error renaming disk file $BASE_DISK_FILE to disk.vmdk" fi - - exec_and_log "chmod 0770 $DST" ;; esac diff --git a/src/datastore_mad/remotes/vmware/mkfs b/src/datastore_mad/remotes/vmware/mkfs index e7e623c713..f48f2535d8 100755 --- a/src/datastore_mad/remotes/vmware/mkfs +++ b/src/datastore_mad/remotes/vmware/mkfs @@ -39,19 +39,29 @@ source ${DRIVER_PATH}/../libfs.sh DRV_ACTION=$1 ID=$2 -set_up_datastore $DRV_ACTION - XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" unset i XPATH_ELEMENTS while IFS= read -r -d '' element; do XPATH_ELEMENTS[i++]="$element" -done < <($XPATH /DS_DRIVER_ACTION_DATA/IMAGE/FSTYPE \ +done < <($XPATH /DS_DRIVER_ACTION_DATA/DATASTORE/BASE_PATH \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/RESTRICTED_DIRS \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/SAFE_DIRS \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/UMASK \ + /DS_DRIVER_ACTION_DATA/IMAGE/PATH \ + /DS_DRIVER_ACTION_DATA/IMAGE/FSTYPE \ /DS_DRIVER_ACTION_DATA/IMAGE/SIZE) -FSTYPE="${XPATH_ELEMENTS[0]}" -SIZE="${XPATH_ELEMENTS[1]}" +BASE_PATH="${XPATH_ELEMENTS[0]}" +RESTRICTED_DIRS="${XPATH_ELEMENTS[1]}" +SAFE_DIRS="${XPATH_ELEMENTS[2]}" +UMASK="${XPATH_ELEMENTS[3]}" +SRC="${XPATH_ELEMENTS[4]}" +FSTYPE="${XPATH_ELEMENTS[5]}" +SIZE="${XPATH_ELEMENTS[6]}" + +set_up_datastore "$BASE_PATH" "$RESTRICTED_DIRS" "$SAFE_DIRS" "$UMASK" DST=`generate_image_path` @@ -60,7 +70,6 @@ DISK_TMP=$DISK.tmp IMAGE_FORMAT=vmdk -umask 0007 # ------------ Create the image to the repository ------------ MKFS_CMD=`mkfs_command $DISK_TMP $FSTYPE` @@ -75,13 +84,9 @@ exec_and_log "$QEMU_IMG convert -O $IMAGE_FORMAT $DISK_TMP $DISK" \ "Unable to convert to $IMAGE_FORMAT in $DISK_TMP" exec_and_log "rm -f $DISK_TMP" \ "Unable to remove temporary disk $DISK_TMP" -exec_and_log "chmod 0660 $DISK" # ---------------- Get the size of the image ------------ -SIZE=`$QEMU_IMG info $DISK|grep "^virtual size:"|\ - sed 's/^.*(\([0-9]\+\) bytes.*$/\1/g'` - -SIZE=$(($SIZE/1048576)) +SIZE=`qemu_size $DISK` echo "$DST $SIZE" diff --git a/src/datastore_mad/remotes/xpath.rb b/src/datastore_mad/remotes/xpath.rb index 3cf8af12b5..9a330d7247 100755 --- a/src/datastore_mad/remotes/xpath.rb +++ b/src/datastore_mad/remotes/xpath.rb @@ -47,7 +47,7 @@ xml = REXML::Document.new(tmp).root ARGV.each do |xpath| element = xml.elements[xpath] - values << element.text if !element.nil? + values << element.text.to_s if !element.nil? values << "\0" end From 182d50fd157a24fdb58ba667d36c32492d5e0c54 Mon Sep 17 00:00:00 2001 From: Tino Vazquez Date: Mon, 5 Mar 2012 13:10:16 +0100 Subject: [PATCH 112/217] First work extending oZones with clusters & DS --- .../Server/lib/OZones/AggregatedClusters.rb | 30 +++++++++++ .../Server/lib/OZones/AggregatedDatastores.rb | 30 +++++++++++ .../models/OpenNebulaJSON/ClusterJSON.rb | 45 +++++++++++++++++ .../models/OpenNebulaJSON/DatastoreJSON.rb | 50 +++++++++++++++++++ 4 files changed, 155 insertions(+) create mode 100644 src/ozones/Server/lib/OZones/AggregatedClusters.rb create mode 100644 src/ozones/Server/lib/OZones/AggregatedDatastores.rb create mode 100644 src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb create mode 100644 src/sunstone/models/OpenNebulaJSON/DatastoreJSON.rb diff --git a/src/ozones/Server/lib/OZones/AggregatedClusters.rb b/src/ozones/Server/lib/OZones/AggregatedClusters.rb new file mode 100644 index 0000000000..608cb739ff --- /dev/null +++ b/src/ozones/Server/lib/OZones/AggregatedClusters.rb @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +module OZones + + class AggregatedClusters < AggregatedPool + + def initialize + super("ZONE_POOL") + end + + def factory(client) + OpenNebulaJSON::ClusterPoolJSON.new(client) + end + end + +end diff --git a/src/ozones/Server/lib/OZones/AggregatedDatastores.rb b/src/ozones/Server/lib/OZones/AggregatedDatastores.rb new file mode 100644 index 0000000000..8b2200e70a --- /dev/null +++ b/src/ozones/Server/lib/OZones/AggregatedDatastores.rb @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +module OZones + + class AggregatedDatastores < AggregatedPool + + def initialize + super("ZONE_POOL") + end + + def factory(client) + OpenNebulaJSON::DatastorePoolJSON.new(client) + end + end + +end diff --git a/src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb b/src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb new file mode 100644 index 0000000000..806855c428 --- /dev/null +++ b/src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb @@ -0,0 +1,45 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +require 'OpenNebulaJSON/JSONUtils' + +module OpenNebulaJSON + class ClusterJSON < OpenNebula::Cluster + include JSONUtils + + def create(template_json) + cluster_hash = parse_json(template_json, 'cluster') + + if OpenNebula.is_error?(cluster_hash) + return cluster_hash + end + + + self.allocate(cluster_hash['name']) + end + + def perform_action(template_json) + action_hash = parse_json(template_json, 'action') + if OpenNebula.is_error?(action_hash) + return action_hash + end + + error_msg = "#{action_hash['perform']} action not " << + " available for this resource" + OpenNebula::Error.new(error_msg) + end + end +end diff --git a/src/sunstone/models/OpenNebulaJSON/DatastoreJSON.rb b/src/sunstone/models/OpenNebulaJSON/DatastoreJSON.rb new file mode 100644 index 0000000000..554f901b38 --- /dev/null +++ b/src/sunstone/models/OpenNebulaJSON/DatastoreJSON.rb @@ -0,0 +1,50 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +require 'OpenNebulaJSON/JSONUtils' + +module OpenNebulaJSON + class ClusterJSON < OpenNebula::Datastore + include JSONUtils + + def create(template_json, cluster_id=ClusterPool::NONE_CLUSTER_ID) + datastore_hash = parse_json(template_json, 'datastore') + + if OpenNebula.is_error?(datastore_hash) + return datastore_hash + end + + if datastore_hash['datastore_raw'] + template = datastore_hash['image_raw'] + else + template = template_to_str(datastore_hash) + end + + self.allocate(template,cluster_id) + end + + def perform_action(template_json) + action_hash = parse_json(template_json, 'action') + if OpenNebula.is_error?(action_hash) + return action_hash + end + + error_msg = "#{action_hash['perform']} action not " << + " available for this resource" + OpenNebula::Error.new(error_msg) + end + end +end From 20ff34756ccdbbab29f70c43e10f041ccce0366c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 5 Mar 2012 16:20:04 +0100 Subject: [PATCH 113/217] Feature #1112: Add automatic cluster placement requirements to new VMs --- include/VirtualMachine.h | 8 +++ src/datastore/Datastore.cc | 8 +++ src/vm/VirtualMachine.cc | 121 ++++++++++++++++++++++++++++++++++++- src/vnm/VirtualNetwork.cc | 15 ++++- 4 files changed, 148 insertions(+), 4 deletions(-) diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 8a7fa03708..3204de992b 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -865,6 +865,14 @@ private: */ int parse_requirements(string& error_str); + /** + * Adds automatic placement requirements: Datastore and Cluster + * + * @param error_str Returns the error reason, if any + * @return 0 on success + */ + int automatic_requirements(string& error_str); + /** * Parse the "GRAPHICS" attribute and generates a default PORT if not * defined diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index 49da72cfaf..7a2aaa24df 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -72,6 +72,14 @@ int Datastore::disk_attribute(VectorAttribute * disk) disk->replace("DATASTORE_ID", oss.str()); disk->replace("TM_MAD", get_tm_mad()); + if ( get_cluster_id() != ClusterPool::NONE_CLUSTER_ID ) + { + oss.str(""); + oss << get_cluster_id(); + + disk->replace("CLUSTER_ID", oss.str()); + } + return 0; } diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 759c4b89ce..1b509f4dac 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -289,6 +289,13 @@ int VirtualMachine::insert(SqlDB * db, string& error_str) goto error_requirements; } + rc = automatic_requirements(error_str); + + if ( rc != 0 ) + { + goto error_requirements; + } + parse_graphics(); // ------------------------------------------------------------------------ @@ -519,6 +526,118 @@ int VirtualMachine::parse_requirements(string& error_str) /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ +int VirtualMachine::automatic_requirements(string& error_str) +{ + int num_vatts; + vector v_attributes; + VectorAttribute * vatt; + + ostringstream oss; + string requirements; + string cluster_id; + bool error = false; + + oss << "Incompatible cluster IDs."; + + // Get cluster id from all DISK vector attributes + + num_vatts = obj_template->get("DISK",v_attributes); + + for(int i=0; i(v_attributes[i]); + + if ( vatt == 0 ) + { + continue; + } + + string vatt_cluster_id = vatt->vector_value("CLUSTER_ID"); + + if ( !vatt_cluster_id.empty() ) + { + oss << endl << "DISK [" << i << "]: IMAGE [" + << vatt->vector_value("IMAGE_ID") << "] from DATASTORE [" + << vatt->vector_value("DATASTORE_ID") << "] requires CLUSTER [" + << vatt_cluster_id << "]"; + + if ( cluster_id.empty() ) + { + cluster_id = vatt_cluster_id; + } + else if ( cluster_id != vatt_cluster_id ) + { + error = true; + } + } + } + + // Get cluster id from all NIC vector attributes + + v_attributes.clear(); + num_vatts = obj_template->get("NIC",v_attributes); + + for(int i=0; i(v_attributes[i]); + + if ( vatt == 0 ) + { + continue; + } + + string vatt_cluster_id = vatt->vector_value("CLUSTER_ID"); + + if ( !vatt_cluster_id.empty() ) + { + oss << endl << "NIC [" << i << "]: NETWORK [" + << vatt->vector_value("NETWORK_ID") << "] requires CLUSTER [" + << vatt_cluster_id << "]"; + + if ( cluster_id.empty() ) + { + cluster_id = vatt_cluster_id; + } + else if ( cluster_id != vatt_cluster_id ) + { + error = true; + } + } + } + + if ( error == true ) + { + error_str = oss.str(); + + return -1; + } + + if ( !cluster_id.empty() ) + { + oss.str(""); + oss << "CLUSTER_ID = " << cluster_id; + + obj_template->get("REQUIREMENTS", requirements); + + if ( !requirements.empty() ) + { + oss << " & ( " << requirements << " )"; + } + + SingleAttribute * reqs_att; + + obj_template->erase("REQUIREMENTS"); + + reqs_att = new SingleAttribute("REQUIREMENTS",oss.str()); + obj_template->set(reqs_att); + } + + return 0; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + int VirtualMachine::insert_replace(SqlDB *db, bool replace, string& error_str) { ostringstream oss; @@ -1412,4 +1531,4 @@ string VirtualMachine::get_system_dir() const oss << nd.get_ds_location() << DatastorePool::SYSTEM_DS_ID << "/"<< oid; return oss.str(); -}; \ No newline at end of file +}; diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index 81faa2928c..ae6282be7f 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -24,6 +24,7 @@ #include "FixedLeases.h" #include "AuthManager.h" +#include "ClusterPool.h" #define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper) @@ -626,10 +627,10 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid) string ip; string mac; - ostringstream vnid; + ostringstream oss; ip = nic->vector_value("IP"); - vnid << oid; + oss << oid; //-------------------------------------------------------------------------- // GET NETWORK LEASE @@ -654,7 +655,7 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid) //-------------------------------------------------------------------------- nic->replace("NETWORK" ,name); - nic->replace("NETWORK_ID",vnid.str()); + nic->replace("NETWORK_ID",oss.str()); nic->replace("BRIDGE" ,bridge); nic->replace("MAC" ,mac); nic->replace("IP" ,ip); @@ -678,6 +679,14 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid) nic->replace("VLAN_ID", vlan_id); } + if ( get_cluster_id() != ClusterPool::NONE_CLUSTER_ID ) + { + oss.str(""); + oss << get_cluster_id(); + + nic->replace("CLUSTER_ID", oss.str()); + } + return 0; } From f534f66ca50c7382507141f2eea2d68ac4146a57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 5 Mar 2012 16:46:27 +0100 Subject: [PATCH 114/217] Feature #1112: Show TM_MAD in onedatastore show output --- src/cli/one_helper/onedatastore_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index d263fd4316..38b79b5973 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -71,6 +71,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper puts str % ["CLUSTER", datastore['CLUSTER']] puts str % ["TYPE", datastore['TYPE']] + puts str % ["TM_MAD", datastore['TM_MAD']] puts str % ["BASE PATH",datastore['BASE_PATH']] puts From 05fdb88739f2b82ea697e1c1887a674da689fb5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 5 Mar 2012 16:47:59 +0100 Subject: [PATCH 115/217] Feature #1112: Allow datastore template update to change the internal TYPE and TM_MAD attributes --- include/Datastore.h | 7 +++++++ include/PoolObjectSQL.h | 2 +- src/datastore/Datastore.cc | 38 ++++++++++++++++++++++++++++++++++++-- src/vm/VirtualMachine.cc | 7 +------ 4 files changed, 45 insertions(+), 9 deletions(-) diff --git a/include/Datastore.h b/include/Datastore.h index 323dfcf0f1..1f4f88cf9a 100644 --- a/include/Datastore.h +++ b/include/Datastore.h @@ -91,6 +91,13 @@ public: */ int disk_attribute(VectorAttribute * disk); + /** + * Replace template for this object. Object should be updated + * after calling this method + * @param tmpl string representation of the template + */ + int replace_template(const string& tmpl_str, string& error); + private: // ------------------------------------------------------------------------- diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h index 0df42280c4..a1177c364c 100644 --- a/include/PoolObjectSQL.h +++ b/include/PoolObjectSQL.h @@ -373,7 +373,7 @@ public: * after calling this method * @param tmpl string representation of the template */ - int replace_template(const string& tmpl_str, string& error); + virtual int replace_template(const string& tmpl_str, string& error); /** diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index 7a2aaa24df..18013d69d1 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -104,14 +104,14 @@ int Datastore::insert(SqlDB *db, string& error_str) erase_template_attribute("NAME", name); // NAME is checked in DatastorePool::allocate - erase_template_attribute("TYPE", type); + get_template_attribute("TYPE", type); if ( type.empty() == true ) { goto error_type; } - erase_template_attribute("TM_MAD", tm_mad); + get_template_attribute("TM_MAD", tm_mad); if ( tm_mad.empty() == true ) { @@ -324,6 +324,40 @@ int Datastore::from_xml(const string& xml) return 0; } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int Datastore::replace_template(const string& tmpl_str, string& error) +{ + string new_type; + string new_tm_mad; + + int rc; + + rc = PoolObjectSQL::replace_template(tmpl_str, error); + + if ( rc != 0 ) + { + return rc; + } + + get_template_attribute("TYPE", new_type); + + if ( !new_type.empty() ) + { + type = new_type; + } + + get_template_attribute("TM_MAD", new_tm_mad); + + if ( !new_tm_mad.empty() ) + { + tm_mad = new_tm_mad; + } + + return 0; +} + /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 1b509f4dac..97c823b51c 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -624,12 +624,7 @@ int VirtualMachine::automatic_requirements(string& error_str) oss << " & ( " << requirements << " )"; } - SingleAttribute * reqs_att; - - obj_template->erase("REQUIREMENTS"); - - reqs_att = new SingleAttribute("REQUIREMENTS",oss.str()); - obj_template->set(reqs_att); + replace_template_attribute("REQUIREMENTS", oss.str()); } return 0; From 5ea3d682ee38cf919c068ddc1e1810953bef9681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 5 Mar 2012 17:53:17 +0100 Subject: [PATCH 116/217] Feature #1112: Fix tests compilation --- include/test/NebulaTest.h | 7 ++++++- src/test/Nebula.cc | 11 +++++++++++ src/test/NebulaTest.cc | 5 +++++ src/vm/test/SConstruct | 2 ++ src/vm_template/test/SConstruct | 2 ++ src/vnm/test/VirtualNetworkPoolTest.cc | 4 +++- 6 files changed, 29 insertions(+), 2 deletions(-) diff --git a/include/test/NebulaTest.h b/include/test/NebulaTest.h index 3768558f3d..bd73d4f201 100644 --- a/include/test/NebulaTest.h +++ b/include/test/NebulaTest.h @@ -27,6 +27,7 @@ #include "UserPool.h" #include "VMTemplatePool.h" #include "DatastorePool.h" +#include "ClusterPool.h" #include "VirtualMachineManager.h" #include "LifeCycleManager.h" @@ -46,7 +47,8 @@ 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_template_pool(false), - need_group_pool(false), + need_group_pool(false), need_datastore_pool(false), + need_cluster_pool(false), need_vmm(false), need_im(false), need_tm(false), need_lcm(false), need_dm(false), @@ -69,6 +71,7 @@ public: bool need_template_pool; bool need_group_pool; bool need_datastore_pool; + bool need_cluster_pool; bool need_vmm; bool need_im; @@ -111,6 +114,8 @@ public: virtual DatastorePool* create_dspool(SqlDB* db); + virtual ClusterPool* create_clpool(SqlDB* db); + // ------------------------------------------------------------------------ // Managers // ------------------------------------------------------------------------ diff --git a/src/test/Nebula.cc b/src/test/Nebula.cc index f9d66ace3d..14684ebe4e 100644 --- a/src/test/Nebula.cc +++ b/src/test/Nebula.cc @@ -92,6 +92,11 @@ void Nebula::start() delete dspool; } + if ( clpool != 0) + { + delete clpool; + } + if ( vmm != 0) { delete vmm; @@ -190,6 +195,7 @@ void Nebula::start() GroupPool::bootstrap(db); AclManager::bootstrap(db); DatastorePool::bootstrap(db); + ClusterPool::bootstrap(db); } catch (exception&) { @@ -205,6 +211,11 @@ void Nebula::start() string default_image_type = "OS"; string default_device_prefix = "hd"; + if (tester->need_cluster_pool) + { + clpool = tester->create_clpool(db); + } + if (tester->need_vm_pool) { vmpool = tester->create_vmpool(db,hook_location,var_location); diff --git a/src/test/NebulaTest.cc b/src/test/NebulaTest.cc index b600a59924..1527e57982 100644 --- a/src/test/NebulaTest.cc +++ b/src/test/NebulaTest.cc @@ -67,6 +67,11 @@ DatastorePool* NebulaTest::create_dspool(SqlDB* db) return new DatastorePool(db); } +ClusterPool* NebulaTest::create_clpool(SqlDB* db) +{ + return new ClusterPool(db); +} + // ----------------------------------------------------------- // Managers // ----------------------------------------------------------- diff --git a/src/vm/test/SConstruct b/src/vm/test/SConstruct index c2eb20b3b3..98fd9ad244 100644 --- a/src/vm/test/SConstruct +++ b/src/vm/test/SConstruct @@ -29,6 +29,8 @@ env.Prepend(LIBS=[ 'nebula_xml', 'nebula_image', 'nebula_datastore', + 'nebula_cluster', + 'nebula_um', 'nebula_mad', 'nebula_common', 'nebula_log', diff --git a/src/vm_template/test/SConstruct b/src/vm_template/test/SConstruct index 20e5d89e58..b87e48c44f 100644 --- a/src/vm_template/test/SConstruct +++ b/src/vm_template/test/SConstruct @@ -22,6 +22,8 @@ env.Prepend(LIBS=[ 'nebula_vm', 'nebula_vmtemplate', 'nebula_hm', + 'nebula_cluster', + 'nebula_datastore', 'nebula_vnm', 'nebula_authm', 'nebula_acl', diff --git a/src/vnm/test/VirtualNetworkPoolTest.cc b/src/vnm/test/VirtualNetworkPoolTest.cc index 0f0f3f1da1..a620f9cdaa 100644 --- a/src/vnm/test/VirtualNetworkPoolTest.cc +++ b/src/vnm/test/VirtualNetworkPoolTest.cc @@ -125,7 +125,9 @@ public: if( rc == 0 ) { - return VirtualNetworkPool::allocate(uid, 0,"the_user","oneadmin", vn_template, oid, err); + return VirtualNetworkPool::allocate(uid, 0,"the_user","oneadmin", + vn_template, oid, ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME, err); } else { From 92dd8d4c5ed0af8099b7fc0547deee748fe36dfe Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Mon, 5 Mar 2012 23:49:18 +0100 Subject: [PATCH 117/217] feature #1112: Save_as functionality --- include/Image.h | 39 ++++- include/ImageManager.h | 36 +---- include/ImageTemplate.h | 25 ++++ include/RequestManagerVirtualMachine.h | 7 +- include/VirtualMachine.h | 18 ++- src/image/Image.cc | 47 +++--- src/image/ImageManagerActions.cc | 144 +++--------------- src/image/ImageManagerDriver.cc | 107 ++++++++++---- src/image/ImageTemplate.cc | 2 + src/rm/RequestManagerVirtualMachine.cc | 195 ++++++++++++++++--------- src/tm/TransferManager.cc | 19 +-- src/vm/VirtualMachine.cc | 134 ++++++++++++----- 12 files changed, 430 insertions(+), 343 deletions(-) diff --git a/include/Image.h b/include/Image.h index d700cb0c8f..60ba8cdb82 100644 --- a/include/Image.h +++ b/include/Image.h @@ -39,6 +39,22 @@ public: DATABLOCK = 2 /** < User persistent data device */ }; + /** + * Return the string representation of an ImageType + * @param ob the type + * @return the string + */ + static string type_to_str(ImageType ob) + { + switch (ob) + { + case OS: return "OS" ; break; + case CDROM: return "CDROM" ; break; + case DATABLOCK: return "DATABLOCK" ; break; + default: return ""; + } + }; + /** * Image State */ @@ -199,6 +215,17 @@ public: return (group_u == 1 || other_u == 1); } + /** + * Check if the image is used for saving_as a current one + * @return true if the image will be used to save an existing image. + */ + bool isSaving() + { + ImageTemplate * it = static_cast(obj_template); + + return it->is_saving(); + } + /** * Set permissions for the Image. Extends the PoolSQLObject method * by checking the persistent state of the image. @@ -291,7 +318,7 @@ public: /** * Factory method for image templates */ - Template * get_new_template() + Template * get_new_template() const { return new ImageTemplate; } @@ -299,11 +326,19 @@ public: /** * Returns the Datastore ID */ - int get_ds_id() + int get_ds_id() const { return ds_id; }; + /** + * Returns the Datastore ID + */ + const string& get_ds_name() const + { + return ds_name; + }; + private: // ------------------------------------------------------------------------- diff --git a/include/ImageManager.h b/include/ImageManager.h index 98b30be801..3d75dfd4a9 100644 --- a/include/ImageManager.h +++ b/include/ImageManager.h @@ -99,14 +99,8 @@ public: /** * Releases an image and triggers any needed operations in the repo * @param iid image id of the image to be released - * @param disk_path base path for disk location - * @param disk number for this image in the VM - * @param saveid id of image to save the current image */ - void release_image(const string& iid, - const string& disk_path, - int disk_num, - const string& saveid) + void release_image(const string& iid) { int image_id; istringstream iss; @@ -114,30 +108,14 @@ public: iss.str(iid); iss >> image_id; - release_image(image_id, disk_path, disk_num, saveid); + release_image(image_id); }; /** * Releases an image and triggers any needed operations in the repo * @param iid image id of the image to be released - * @param disk_path base path for disk location - * @param disk number for this image in the VM - * @param saveid id of image to save the current image */ - void release_image(int iid, - const string& disk_path, - int disk_num, - const string& saveid); - - /** - * Moves a VM disk to the Image Repository - * @param disk_path base path for disk location - * @param disk number for this image in the VM - * @param saveid id of image to save the current image - */ - void disk_to_image(const string& disk_path, - int disk_num, - const string& save_id); + void release_image(int iid); /** * Enables the image @@ -205,9 +183,7 @@ private: * @param action the name of the action * @param arg arguments for the action function */ - void do_action( - const string & action, - void * arg); + void do_action(const string& action, void * arg); /** * Acquires an image updating its state. @@ -230,9 +206,7 @@ private: * @param ds_data Datastore XML representation * @return the XML message */ - string * format_message( - const string& img_data, - const string& ds_data); + string * format_message(const string& img_data, const string& ds_data); }; #endif /*IMAGE_MANAGER_H*/ diff --git a/include/ImageTemplate.h b/include/ImageTemplate.h index 21dd0eec64..36c2727bb6 100644 --- a/include/ImageTemplate.h +++ b/include/ImageTemplate.h @@ -41,11 +41,36 @@ public: return Template::check(rs_attr, restricted_attributes); }; + bool is_saving() + { + string saving; + + get(saving_attribute, saving); + + return (saving.empty() == false); + } + + void set_saving() + { + SingleAttribute * attr= new SingleAttribute(saving_attribute, "YES"); + + erase(saving_attribute); + + set(attr); + } + + void unset_saving() + { + erase(saving_attribute); + } + private: friend class ImagePool; static vector restricted_attributes; + static string saving_attribute; + /** * Stores the attributes as restricted, these attributes will be used in * ImageTemplate::check diff --git a/include/RequestManagerVirtualMachine.h b/include/RequestManagerVirtualMachine.h index 89355b1999..6b5472807e 100644 --- a/include/RequestManagerVirtualMachine.h +++ b/include/RequestManagerVirtualMachine.h @@ -48,8 +48,11 @@ protected: virtual void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) = 0; - bool vm_authorization(int id, ImageTemplate *tmpl, - RequestAttributes& att, PoolObjectAuth* host_perms); + bool vm_authorization(int id, + ImageTemplate * tmpl, + RequestAttributes& att, + PoolObjectAuth * host_perms, + PoolObjectAuth * ds_perm); int get_host_information(int hid, string& name, string& vmm, string& vnm, RequestAttributes& att, PoolObjectAuth& host_perms); diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 8a7fa03708..f9dbc1b147 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -653,15 +653,27 @@ public: int generate_context(string &files); // ------------------------------------------------------------------------ - // Image repository related functions + // Datastore related functions // ------------------------------------------------------------------------ /** * Set the SAVE_AS attribute for the "disk_id"th disk. * @param disk_id Index of the disk to save - * @param img_id ID of the image this disk will be saved to. + * @param source to save the disk (SAVE_AS_SOURCE) + * @param img_id ID of the image this disk will be saved to (SAVE_AS). * @return 0 if success */ - int save_disk(int disk_id, int img_id, string& error_str); + int save_disk(const string& disk_id, + const string& source, + int img_id); + + /** + * Get the original image id of the disk. It also checks that the disk can + * be saved_as. + * @param disk_id Index of the disk to save + * @param error_str describes the error + * @return -1 if failure + */ + int get_image_from_disk(int disk_id, string& error_str); // ------------------------------------------------------------------------ // Authorization related functions diff --git a/src/image/Image.cc b/src/image/Image.cc index 6772927672..058d8551a0 100644 --- a/src/image/Image.cc +++ b/src/image/Image.cc @@ -96,6 +96,7 @@ int Image::insert(SqlDB *db, string& error_str) string dev_prefix; string source_attr; string aname; + string saved_id; ostringstream oss; @@ -159,34 +160,36 @@ int Image::insert(SqlDB *db, string& error_str) erase_template_attribute("PATH", path); erase_template_attribute("SOURCE", source); - // The template should contain PATH or SOURCE - if ( source.empty() && path.empty() ) + if (!isSaving()) //Not a saving image { - string size_attr; - istringstream iss; - - erase_template_attribute("SIZE", size_attr); - erase_template_attribute("FSTYPE", fs_type); - - // DATABLOCK image needs SIZE and FSTYPE - if (type != DATABLOCK || size_attr.empty() || fs_type.empty()) + if ( source.empty() && path.empty() ) { - goto error_no_path; + string size_attr; + istringstream iss; + + erase_template_attribute("SIZE", size_attr); + erase_template_attribute("FSTYPE", fs_type); + + // DATABLOCK image needs SIZE and FSTYPE + if (type != DATABLOCK || size_attr.empty() || fs_type.empty()) + { + goto error_no_path; + } + + iss.str(size_attr); + + iss >> size_mb; + + if (iss.fail() == true) + { + goto error_size_format; + } } - - iss.str(size_attr); - - iss >> size_mb; - - if (iss.fail() == true) + else if ( !source.empty() && !path.empty() ) { - goto error_size_format; + goto error_path_and_source; } } - else if ( !source.empty() && !path.empty() ) - { - goto error_path_and_source; - } state = LOCKED; //LOCKED till the ImageManager copies it to the Repository diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index 2c499730d5..eb8056b4cc 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -128,84 +128,14 @@ int ImageManager::acquire_image(Image *img, string& error) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void ImageManager::move_image(Image *img, const string& source) -{ - const ImageManagerDriver* imd = get(); - ostringstream oss; - - if ( imd == 0 ) - { - NebulaLog::log("ImM",Log::ERROR, - "Could not get driver to update repository"); - return; - } - - oss << "Moving disk " << source << " to repository image " - << img->get_oid(); - - imd->mv(img->get_oid(),source,img->get_source()); - - NebulaLog::log("ImM",Log::INFO,oss); -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void ImageManager::disk_to_image(const string& disk_path, - int disk_num, - const string& save_id) -{ - int sid; - - istringstream iss; - Image * img; - - ostringstream disk_file; - - iss.str(save_id); - - iss >> sid; - - img = ipool->get(sid,true); - - if ( img == 0 ) - { - NebulaLog::log("ImM",Log::ERROR,"Could not get image to saveas disk."); - } - else - { - disk_file << disk_path << "/disk." << disk_num; - - move_image(img,disk_file.str()); - } - - img->unlock(); -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void ImageManager::release_image(int iid, - const string& disk_path, - int disk_num, - const string& save_id) +void ImageManager::release_image(int iid) { int rvms; - int sid = -1; - - istringstream iss; - Image * img; + Image * img; ostringstream disk_file; - if ( save_id.empty() == false ) - { - iss.str(save_id); - - iss >> sid; - } - img = ipool->get(iid,true); if ( img == 0 ) @@ -218,48 +148,14 @@ void ImageManager::release_image(int iid, case Image::USED: rvms = img->dec_running(); - if ( img->isPersistent() && !disk_path.empty() ) + if ( img->isPersistent() || rvms == 0 ) { - disk_file << disk_path << "/disk." << disk_num; - - img->set_state(Image::LOCKED); - - move_image(img,disk_file.str()); + img->set_state(Image::READY); ipool->update(img); img->unlock(); } - else - { - if ( rvms == 0) - { - img->set_state(Image::READY); - } - - ipool->update(img); - - img->unlock(); - - if ( sid != -1 ) - { - img = ipool->get(sid,true); - - if ( img == 0 ) - { - NebulaLog::log("ImM",Log::ERROR, - "Could not get image to saveas disk."); - } - else - { - disk_file << disk_path << "/disk." << disk_num; - - move_image(img,disk_file.str()); - } - - img->unlock(); - } - } break; case Image::DISABLED: @@ -372,8 +268,7 @@ int ImageManager::delete_image(int iid, const string& ds_data) } drv_msg = format_message(img->to_xml(img_tmpl), ds_data); - - source = img->get_source(); + source = img->get_source(); if (source.empty()) { @@ -431,30 +326,25 @@ int ImageManager::register_image(int iid, const string& ds_data) drv_msg = format_message(img->to_xml(img_tmpl), ds_data); path = img->get_path(); - if ( path.empty() == true ) //NO PATH -> USE SOURCE OR MKFS FOR DATABLOCK + if ( path.empty() == true ) //NO PATH { - if ( img->get_type() == Image::DATABLOCK) - { - string fs = img->get_fstype(); - int size = img->get_size(); + string source = img->get_source(); + if ( img->isSaving() || img->get_type() == Image::DATABLOCK ) + { imd->mkfs(img->get_oid(), *drv_msg); - oss << "Creating disk at " << img->get_source() << " of " - << size << "Mb with format " << fs; + oss << "Creating disk at " << source + << " of "<< img->get_size() + << "Mb (type: " << img->get_fstype() << ")"; } - else + else if ( !source.empty() ) //Source in Template { - string source = img->get_source(); + img->set_state(Image::READY); + ipool->update(img); - if (source != "-") //SAVE_AS IMAGE DO NOT ENABLE THE IMAGE - { - img->set_state(Image::READY); - ipool->update(img); - - oss << "Using source " << img->get_source() - << " from template for image " << img->get_name(); - } + oss << "Using source " << source + << " from template for image " << img->get_name(); } } else //PATH -> COPY TO REPOSITORY AS SOURCE diff --git a/src/image/ImageManagerDriver.cc b/src/image/ImageManagerDriver.cc index c04f5ff565..64ad5e128e 100644 --- a/src/image/ImageManagerDriver.cc +++ b/src/image/ImageManagerDriver.cc @@ -179,40 +179,69 @@ void ImageManagerDriver::protocol( goto error_cp; } } - else if ( action == "MV" ) - { - if ( result == "SUCCESS" ) - { - if (image->get_source() == "-") - { - image->set_source(source); - } - - image->set_size(size_mb); - - image->set_state(Image::READY); - - ipool->update(image); - - NebulaLog::log("ImM", Log::INFO, "Image saved and ready to use."); - } - else - { - goto error_mv; - } - } else if ( action == "MKFS" ) { if ( result == "SUCCESS" ) { - image->set_source(source); - image->set_size(size_mb); + bool is_saving = image->isSaving(); - image->set_state(Image::READY); + string disk_id; + string vm_id; + int rc; + + image->set_source(source); + + if (is_saving) + { + image->get_template_attribute("SAVED_DISK_ID",disk_id); + image->get_template_attribute("SAVED_VM_ID", vm_id); + } + else + { + image->set_size(size_mb); + + image->set_state(Image::READY); + + NebulaLog::log("ImM", Log::INFO, + "Image created and ready to use"); + } ipool->update(image); - NebulaLog::log("ImM", Log::INFO, "Image created and ready to use"); + image->unlock(); + + if (is_saving) + { + Nebula& nd = Nebula::instance(); + + VirtualMachinePool * vmpool = nd.get_vmpool(); + + VirtualMachine * vm; + istringstream iss(vm_id); + + int vm_id_i; + + iss >> vm_id_i; + + vm = vmpool->get(vm_id_i, true); + + if ( vm == 0 ) + { + goto error_save_no_vm; + } + + rc = vm->save_disk(disk_id, source, id); + + if ( rc == -1 ) + { + vm->unlock(); + goto error_save_state_vm; + } + + vm->unlock(); + } + + return; } else { @@ -255,11 +284,6 @@ error_cp: os << "Error copying image in the repository"; goto error_common; -error_mv: - os.str(""); - os << "Error saving image to the repository"; - goto error_common; - error_mkfs: os.str(""); os << "Error creating datablock"; @@ -280,9 +304,28 @@ error_rm: } NebulaLog::log("ImM", Log::ERROR, os); - return; +error_save_no_vm: + os.str(""); + os << "Image created for SAVE_AS, but the associated VM does not exist."; + + goto error_save_common; + +error_save_state_vm: + os.str(""); + os << "Image created for SAVE_AS, but VM is no longer running"; + + goto error_save_common; + +error_save_common: + image = ipool->get(id, true); + + if (image == 0 ) + { + return; + } + error_common: getline(is,info); diff --git a/src/image/ImageTemplate.cc b/src/image/ImageTemplate.cc index 60c1fb623a..3ef5145020 100644 --- a/src/image/ImageTemplate.cc +++ b/src/image/ImageTemplate.cc @@ -21,5 +21,7 @@ vector ImageTemplate::restricted_attributes; +string ImageTemplate::saving_attribute = "SAVE_AS"; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index cca7b559cf..24e3cd17aa 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -24,7 +24,8 @@ bool RequestManagerVirtualMachine::vm_authorization(int oid, ImageTemplate * tmpl, RequestAttributes& att, - PoolObjectAuth * host_perm) + PoolObjectAuth * host_perm, + PoolObjectAuth * ds_perm) { PoolObjectSQL * object; PoolObjectAuth vm_perms; @@ -57,13 +58,19 @@ bool RequestManagerVirtualMachine::vm_authorization(int oid, { ar.add_auth(AuthRequest::MANAGE, *host_perm); } - else if (tmpl != 0) + + if (tmpl != 0) { string t_xml; ar.add_create_auth(PoolObjectSQL::IMAGE, tmpl->to_xml(t_xml)); } + if ( ds_perm != 0 ) + { + ar.add_auth(AuthRequest::USE, *ds_perm); + } + if (UserPool::authorize(ar) == -1) { failure_response(AUTHORIZATION, @@ -177,7 +184,7 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList, Nebula& nd = Nebula::instance(); DispatchManager * dm = nd.get_dm(); - if ( vm_authorization(id,0,att,0) == false ) + if ( vm_authorization(id, 0, att, 0, 0) == false ) { return; } @@ -282,7 +289,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList, return; } - auth = vm_authorization(id,0,att,&host_perms); + auth = vm_authorization(id, 0, att, &host_perms, 0); if ( auth == false ) { @@ -344,7 +351,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList return; } - auth = vm_authorization(id,0,att,&host_perms); + auth = vm_authorization(id, 0, att, &host_perms, 0); if ( auth == false ) { @@ -394,8 +401,10 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramList, RequestAttributes& att) { - Nebula& nd = Nebula::instance(); - ImagePool * ipool = nd.get_ipool(); + Nebula& nd = Nebula::instance(); + + ImagePool * ipool = nd.get_ipool(); + DatastorePool * dspool = nd.get_dspool(); int id = xmlrpc_c::value_int(paramList.getInt(1)); int disk_id = xmlrpc_c::value_int(paramList.getInt(2)); @@ -403,24 +412,100 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis string img_type = xmlrpc_c::value_string(paramList.getString(4)); VirtualMachine * vm; - string vm_owner; - int iid; - ImageTemplate * itemplate; + int iid_orig; + + Image * img; + Datastore * ds; int rc; - ostringstream oss; string error_str; - // ------------------ Template for the new image ------------------ + // ------------------------------------------------------------------------- + // Prepare and check the VM/DISK to be saved_as + // ------------------------------------------------------------------------- + + if ( (vm = get_vm(id, att)) == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::VM), id), + att); + return; + } - oss << "NAME= \"" << img_name << "\"" << endl; - oss << "PUBLIC = NO " << endl; - oss << "SOURCE = - " << endl; - oss << "SAVED_DISK_ID = " << disk_id << endl; - oss << "SAVED_VM_ID = " << id << endl; + iid_orig = vm->get_image_from_disk(disk_id, error_str); - if ( img_type != "" ) + pool->update(vm); + + vm->unlock(); + + if ( iid_orig == -1 ) + { + failure_response(INTERNAL, + request_error("Can not used selected DISK", error_str), + att); + return; + } + + // ------------------------------------------------------------------------- + // Get the data of the Image to be saved + // ------------------------------------------------------------------------- + + if ( (img = ipool->get(iid_orig, true)) != 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::IMAGE), iid_orig), + att); + return; + } + + int ds_id = img->get_ds_id(); + string ds_name = img->get_ds_name(); + int size = img->get_size(); + + Image::ImageType type = img->get_type(); + + img->unlock(); + + if ((ds = dspool->get(ds_id, true)) == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::DATASTORE), ds_id), + att); + return; + } + + // ------------------------------------------------------------------------- + // Get the data of the DataStore for the new image + // ------------------------------------------------------------------------- + string ds_data; + PoolObjectAuth ds_perms; + + ds->get_permissions(ds_perms); + ds->to_xml(ds_data); + + ds->unlock(); + + // ------------------------------------------------------------------------- + // Create a template for the new Image + // ------------------------------------------------------------------------- + ImageTemplate * itemplate; + ostringstream oss; + + oss << "NAME = \"" << img_name << "\"" << endl; + oss << "PUBLIC = NO" << endl; + oss << "SIZE = " << size << endl; + oss << "FS_TYPE = save_as" << endl; + + oss << "SAVED_IMAGE_ID = " << iid_orig << endl; + oss << "SAVED_DISK_ID = " << disk_id << endl; + oss << "SAVED_VM_ID = " << id << endl; + + if ( img_type.empty() ) + { + oss << "TYPE = " << Image::type_to_str(type) << endl; + } + else { oss << "TYPE = " << img_type << endl; } @@ -429,24 +514,32 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis itemplate->parse_str_or_xml(oss.str(), error_str); - // ------------------ Authorize the operation ------------------ + itemplate->set_saving(); - if ( vm_authorization(id,itemplate,att,0) == false ) + // ------------------------------------------------------------------------- + // Authorize the operation + // ------------------------------------------------------------------------- + + if ( vm_authorization(id, itemplate, att, 0, &ds_perms) == false ) { delete itemplate; return; } - // ------------------ Create the image ------------------ - - // TODO: get values from source image DS - int ds_id = 0; - string ds_name = ""; - string ds_data = ""; - - rc = ipool->allocate(att.uid, att.gid, att.uname, att.gname, itemplate, - ds_id, ds_name, ds_data, &iid, error_str); + // ------------------------------------------------------------------------- + // Create the image + // ------------------------------------------------------------------------- + rc = ipool->allocate(att.uid, + att.gid, + att.uname, + att.gname, + itemplate, + ds_id, + ds_name, + ds_data, + &iid, + error_str); if (rc < 0) { failure_response(INTERNAL, @@ -454,50 +547,6 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis return; } - // ------------------ Store image id to save the disk ------------------ - - if ( (vm = get_vm(id, att)) == 0 ) - { - Image * img; - - if ( (img = ipool->get(iid,true)) != 0 ) - { - string tmp_error; - - ipool->drop(img, tmp_error); - img->unlock(); - } - - return; - } - - rc = vm->save_disk(disk_id, iid, error_str); - - if ( rc == 0 ) - { - pool->update(vm); - } - - vm->unlock(); - - if ( rc == -1 ) - { - Image * img; - - if ( (img = ipool->get(iid,true)) != 0 ) - { - string tmp_error; - - ipool->drop(img, tmp_error); - img->unlock(); - } - - failure_response(INTERNAL, - request_error("Can not save_as disk",error_str), - att); - return; - } - // Return the new allocated Image ID success_response(iid, att); } diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index 20cfe4e821..d3d1212d84 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -790,26 +790,23 @@ void TransferManager::epilog_action(int vid) tm_mad = disk->vector_value("TM_MAD"); - if ( save == "YES" ) + if ( save == "YES" ) //TODO SAVE_SOURCE { - ostringstream tsource; string source; + string save_source; - source = disk->vector_value("SOURCE"); + source = disk->vector_value("SOURCE"); + save_source = disk->vector_value("SAVE_AS_SOURCE"); - if ( source.empty() ) + if ( source.empty() && save_source.empty() ) { vm->log("TM", Log::ERROR, "No SOURCE to save disk image"); continue; } - if ( source.find(":") == string::npos ) //Regular file + if (!save_source.empty()) //Use the save as source instead { - tsource << nd.get_nebula_hostname() << ":" << source << " "; - } - else //TM Plugin specific protocol - { - tsource << source << " "; + source = save_source; } //MVDS tm_mad hostname:remote_system_dir/disk.0 @@ -817,7 +814,7 @@ void TransferManager::epilog_action(int vid) << tm_mad << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << i << " " - << tsource.str() << endl; + << source << endl; } else if ( !tm_mad.empty() ) //No saving disk and no system_ds disk { diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 759c4b89ce..c3f8fb05fa 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -824,9 +824,7 @@ error_common: for ( it=acquired_images.begin() ; it < acquired_images.end(); it++ ) { - // Set disk_path and save_id to empty string, this way the image manager - // won't try to move any files - imagem->release_image(*it,"",-1,""); + imagem->release_image(*it); } return -1; @@ -849,14 +847,7 @@ void VirtualMachine::release_disk_images() Nebula& nd = Nebula::instance(); imagem = nd.get_imagem(); - num_disks = get_template_attribute("DISK",disks); - - if (hasHistory() != 0) - { - /* - disk_base_path = get_local_dir(); - */ - } + num_disks = get_template_attribute("DISK",disks); for(int i=0; ivector_value("IMAGE_ID"); - saveas = disk->vector_value("SAVE_AS"); + iid = disk->vector_value("IMAGE_ID"); - if ( iid.empty() ) + if ( !iid.empty() ) { - if (!saveas.empty()) - { - imagem->disk_to_image(disk_base_path,i,saveas); - } - } - else - { - imagem->release_image(iid,disk_base_path,i,saveas); + imagem->release_image(iid); } } } @@ -1037,26 +1020,45 @@ int VirtualMachine::generate_context(string &files) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VirtualMachine::save_disk(int disk_id, int img_id, string& error_str) +static int id_from_attr (VectorAttribute * attr, const char *name) { - int num_disks; + int id; + string id_str; + + id_str = attr->vector_value(name); + + if (id_str.empty()) + { + return -1; + } + + istringstream iss(id_str); + iss >> id; + + return id; +} + +/* -------------------------------------------------------------------------- */ + +int VirtualMachine::get_image_from_disk(int disk_id, string& error_str) +{ + int num_disks; + int tid; + int iid = -1; + vector disks; VectorAttribute * disk; - string disk_id_str; - int tmp_disk_id; - ostringstream oss; - istringstream iss; + + num_disks = obj_template->get("DISK",disks); if ( state == DONE || state == FAILED ) { goto error_state; } - num_disks = obj_template->get("DISK",disks); - - for(int i=0; i(disks[i]); @@ -1065,12 +1067,9 @@ int VirtualMachine::save_disk(int disk_id, int img_id, string& error_str) continue; } - disk_id_str = disk->vector_value("DISK_ID"); + tid = id_from_attr(disk,"DISK_ID"); - iss.str(disk_id_str); - iss >> tmp_disk_id; - - if ( tmp_disk_id == disk_id ) + if ( disk_id == tid ) { if(!((disk->vector_value("SAVE_AS")).empty())) { @@ -1082,12 +1081,16 @@ int VirtualMachine::save_disk(int disk_id, int img_id, string& error_str) goto error_persistent; } + iid = id_from_attr(disk, "IMAGE_ID"); + + if (iid == -1) + { + goto error_image_id; + } + disk->replace("SAVE", "YES"); - oss << (img_id); - disk->replace("SAVE_AS", oss.str()); - - return 0; + return iid; } } @@ -1105,6 +1108,10 @@ error_saved: oss << "The DISK " << disk_id << " is already going to be saved."; goto error_common; +error_image_id: + oss << "The DISK " << disk_id << "does not have a valid IMAGE_ID."; + goto error_common; + error_not_found: oss << "The DISK " << disk_id << " does not exist for VM " << oid << "."; @@ -1117,6 +1124,53 @@ error_common: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int VirtualMachine::save_disk(const string& disk_id, + const string& source, + int img_id) +{ + vector disks; + VectorAttribute * disk; + + int num_disks; + string tdisk_id; + + ostringstream oss; + + if ( state == DONE || state == FAILED ) + { + return -1; + } + + num_disks = obj_template->get("DISK",disks); + + for(int i=0; i(disks[i]); + + if ( disk == 0 ) + { + continue; + } + + tdisk_id = disk->vector_value("DISK_ID"); + + if ( tdisk_id == disk_id ) + { + disk->replace("SAVE_AS_SOURCE", source); + + oss << (img_id); + disk->replace("SAVE_AS", oss.str()); + + break; + } + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void VirtualMachine::set_auth_request(int uid, AuthRequest& ar, VirtualMachineTemplate *tmpl) From d38292505bb7e57dbfaddf16209e2aef59f4572d Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 6 Mar 2012 00:18:01 +0100 Subject: [PATCH 118/217] feature #1112: Update Image state when releasing it (persistent and save_as images) --- include/ImageManager.h | 8 ++++--- src/image/ImageManagerActions.cc | 37 +++++++++++++++++++++++++++----- src/vm/VirtualMachine.cc | 4 ++-- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/include/ImageManager.h b/include/ImageManager.h index 3d75dfd4a9..38cf5be66f 100644 --- a/include/ImageManager.h +++ b/include/ImageManager.h @@ -99,8 +99,9 @@ public: /** * Releases an image and triggers any needed operations in the repo * @param iid image id of the image to be released + * @param failed the associated VM releasing the images is FAILED */ - void release_image(const string& iid) + void release_image(const string& iid, bool failed) { int image_id; istringstream iss; @@ -108,14 +109,15 @@ public: iss.str(iid); iss >> image_id; - release_image(image_id); + release_image(image_id, failed); }; /** * Releases an image and triggers any needed operations in the repo * @param iid image id of the image to be released + * @param failed the associated VM releasing the images is FAILED */ - void release_image(int iid); + void release_image(int iid, bool failed); /** * Enables the image diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index eb8056b4cc..b507a396f1 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -128,7 +128,7 @@ int ImageManager::acquire_image(Image *img, string& error) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void ImageManager::release_image(int iid) +void ImageManager::release_image(int iid, bool failed) { int rvms; @@ -148,20 +148,47 @@ void ImageManager::release_image(int iid) case Image::USED: rvms = img->dec_running(); - if ( img->isPersistent() || rvms == 0 ) + if (img->isPersistent()) + { + if (failed == true) + { + img->set_state(Image::ERROR); + } + else + { + img->set_state(Image::READY); + } + + ipool->update(img); + } + else if ( rvms == 0 ) { img->set_state(Image::READY); ipool->update(img); - - img->unlock(); } + + img->unlock(); break; + case Image::LOCKED: //SAVE_AS images are LOCKED till released + if (failed == true) + { + img->set_state(Image::ERROR); + } + else + { + img->set_state(Image::READY); + } + + ipool->update(img); + + img->unlock(); + break; + case Image::DISABLED: case Image::READY: case Image::ERROR: - case Image::LOCKED: NebulaLog::log("ImM",Log::ERROR, "Trying to release image in wrong state."); default: diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 827b08d5ac..2b3d3da734 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -938,7 +938,7 @@ error_common: for ( it=acquired_images.begin() ; it < acquired_images.end(); it++ ) { - imagem->release_image(*it); + imagem->release_image(*it, false); } return -1; @@ -977,7 +977,7 @@ void VirtualMachine::release_disk_images() if ( !iid.empty() ) { - imagem->release_image(iid); + imagem->release_image(iid, (state == FAILED)); } } } From bb2b9371a06a571d90489533fbfd199f2454ad2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 6 Mar 2012 14:47:17 +0100 Subject: [PATCH 119/217] Feature #1112: Do not create cluster "default" at bootstrap --- include/ClusterPool.h | 10 ---------- src/cluster/ClusterPool.cc | 21 -------------------- src/host/test/HostHookTest.cc | 16 ++++++++-------- src/host/test/HostPoolTest.cc | 36 +++++++++++++++++------------------ 4 files changed, 26 insertions(+), 57 deletions(-) diff --git a/include/ClusterPool.h b/include/ClusterPool.h index 78c47d4af1..365dac64e3 100644 --- a/include/ClusterPool.h +++ b/include/ClusterPool.h @@ -34,16 +34,6 @@ public: /* Constants for DB management */ /* ---------------------------------------------------------------------- */ - /** - * Name for the default cluster - */ - static const string DEFAULT_CLUSTER_NAME; - - /** - * Identifier for the default cluster - */ - static const int DEFAULT_CLUSTER_ID; - /** * Name for the "none" cluster */ diff --git a/src/cluster/ClusterPool.cc b/src/cluster/ClusterPool.cc index 94de028dbc..c96d660ca1 100644 --- a/src/cluster/ClusterPool.cc +++ b/src/cluster/ClusterPool.cc @@ -26,9 +26,6 @@ /* Regular ones start from ID 100 */ /* -------------------------------------------------------------------------- */ -const string ClusterPool::DEFAULT_CLUSTER_NAME = "default"; -const int ClusterPool::DEFAULT_CLUSTER_ID = 0; - const string ClusterPool::NONE_CLUSTER_NAME = "none"; const int ClusterPool::NONE_CLUSTER_ID = -1; @@ -42,28 +39,10 @@ ClusterPool::ClusterPool(SqlDB * db):PoolSQL(db, Cluster::table) if (get_lastOID() == -1) //lastOID is set in PoolSQL::init_cb { - int rc; - Cluster * cluster; - - cluster = new Cluster(DEFAULT_CLUSTER_ID, DEFAULT_CLUSTER_NAME); - - rc = PoolSQL::allocate(cluster, error_str); - - if( rc < 0 ) - { - goto error_bootstrap; - } - set_update_lastOID(99); } return; - -error_bootstrap: - oss << "Error trying to create default cluster: " << error_str; - NebulaLog::log("CLUSTER",Log::ERROR,oss); - - throw runtime_error(oss.str()); } /* -------------------------------------------------------------------------- */ diff --git a/src/host/test/HostHookTest.cc b/src/host/test/HostHookTest.cc index a9e2222663..f3d8932073 100644 --- a/src/host/test/HostHookTest.cc +++ b/src/host/test/HostHookTest.cc @@ -101,8 +101,8 @@ public: "im_mad", "vmm_mad", "vnm_mad", - ClusterPool::DEFAULT_CLUSTER_ID, - ClusterPool::DEFAULT_CLUSTER_NAME, + ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME, err); CPPUNIT_ASSERT( oid >= 0 ); @@ -128,8 +128,8 @@ public: "im_mad", "vmm_mad", "vnm_mad", - ClusterPool::DEFAULT_CLUSTER_ID, - ClusterPool::DEFAULT_CLUSTER_NAME, + ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME, err); CPPUNIT_ASSERT( oid >= 0 ); @@ -161,8 +161,8 @@ public: "im_mad", "vmm_mad", "vnm_mad", - ClusterPool::DEFAULT_CLUSTER_ID, - ClusterPool::DEFAULT_CLUSTER_NAME, + ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME, err); CPPUNIT_ASSERT( oid >= 0 ); @@ -194,8 +194,8 @@ public: "im_mad", "vmm_mad", "vnm_mad", - ClusterPool::DEFAULT_CLUSTER_ID, - ClusterPool::DEFAULT_CLUSTER_NAME, + ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME, err); CPPUNIT_ASSERT( oid >= 0 ); diff --git a/src/host/test/HostPoolTest.cc b/src/host/test/HostPoolTest.cc index 35f60838d8..d3e81a802d 100644 --- a/src/host/test/HostPoolTest.cc +++ b/src/host/test/HostPoolTest.cc @@ -164,8 +164,8 @@ protected: string err; return ((HostPool*)pool)->allocate(&oid, names[index], im_mad, vmm_mad, vnm_mad, - ClusterPool::DEFAULT_CLUSTER_ID, - ClusterPool::DEFAULT_CLUSTER_NAME,err); + ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME,err); }; void check(int index, PoolObjectSQL* obj) @@ -250,8 +250,8 @@ public: im_mad, vmm_mad, vnm_mad, - ClusterPool::DEFAULT_CLUSTER_ID, - ClusterPool::DEFAULT_CLUSTER_NAME, + ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME, err); CPPUNIT_ASSERT( oid_0 == 0 ); CPPUNIT_ASSERT( rc == oid_0 ); @@ -261,8 +261,8 @@ public: im_mad, vmm_mad, vnm_mad, - ClusterPool::DEFAULT_CLUSTER_ID, - ClusterPool::DEFAULT_CLUSTER_NAME, + ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME, err); CPPUNIT_ASSERT( oid_1 == -1 ); CPPUNIT_ASSERT( rc == oid_1 ); @@ -273,8 +273,8 @@ public: im_mad_2, vmm_mad, vnm_mad, - ClusterPool::DEFAULT_CLUSTER_ID, - ClusterPool::DEFAULT_CLUSTER_NAME, + ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME, err); CPPUNIT_ASSERT( oid_1 == -1 ); CPPUNIT_ASSERT( rc == oid_1 ); @@ -300,8 +300,8 @@ public: im_mad, vmm_mad, vnm_mad, - ClusterPool::DEFAULT_CLUSTER_ID, - ClusterPool::DEFAULT_CLUSTER_NAME, + ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME, err); } @@ -339,8 +339,8 @@ public: im_mad, vmm_mad, vnm_mad, - ClusterPool::DEFAULT_CLUSTER_ID, - ClusterPool::DEFAULT_CLUSTER_NAME, + ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME, err); } @@ -385,8 +385,8 @@ public: im_mad, vmm_mad, vnm_mad, - ClusterPool::DEFAULT_CLUSTER_ID, - ClusterPool::DEFAULT_CLUSTER_NAME, + ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME, err); CPPUNIT_ASSERT(oid == i); @@ -450,8 +450,8 @@ public: im_mad, vmm_mad, vnm_mad, - ClusterPool::DEFAULT_CLUSTER_ID, - ClusterPool::DEFAULT_CLUSTER_NAME, + ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME, err); } @@ -486,8 +486,8 @@ public: im_mad, vmm_mad, vnm_mad, - ClusterPool::DEFAULT_CLUSTER_ID, - ClusterPool::DEFAULT_CLUSTER_NAME, + ClusterPool::NONE_CLUSTER_ID, + ClusterPool::NONE_CLUSTER_NAME, err); host = hp->get(oid, false); From 51cec846bf9e6b75c2a9d1659b8956d7646d1e18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 6 Mar 2012 15:13:55 +0100 Subject: [PATCH 120/217] Feature #1112: Renamge DATASTORE/TYPE to DS_MAD --- include/Datastore.h | 4 +-- share/etc/oned.conf | 2 +- src/cli/one_helper/onedatastore_helper.rb | 2 +- src/datastore/Datastore.cc | 32 ++++++++++++++--------- src/datastore/DatastorePool.cc | 4 +-- src/datastore_mad/one_datastore.rb | 2 +- 6 files changed, 27 insertions(+), 19 deletions(-) diff --git a/include/Datastore.h b/include/Datastore.h index 1f4f88cf9a..39cfa9ef60 100644 --- a/include/Datastore.h +++ b/include/Datastore.h @@ -111,9 +111,9 @@ private: // ************************************************************************* /** - * Type of driver + * Name of the datastore driver used to register new images */ - string type; + string ds_mad; /** * Name of the TM driver used to transfer file to and from the hosts diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 4f99071a3c..400d07ab12 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -293,7 +293,7 @@ TM_MAD = [ # # arguments : for the driver executable # -t number of threads, i.e. number of repo operations at the same time -# -d datastore types separated by commas +# -d datastore mads separated by commas #******************************************************************************* DATASTORE_MAD = [ diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index 38b79b5973..33f812c1a0 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -70,7 +70,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper puts str % ["GROUP", datastore['GNAME']] puts str % ["CLUSTER", datastore['CLUSTER']] - puts str % ["TYPE", datastore['TYPE']] + puts str % ["DS_MAD", datastore['DS_MAD']] puts str % ["TM_MAD", datastore['TM_MAD']] puts str % ["BASE PATH",datastore['BASE_PATH']] puts diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index 18013d69d1..f5fbb57dd8 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -45,7 +45,7 @@ Datastore::Datastore( PoolObjectSQL(-1,DATASTORE,"",uid,gid,uname,gname,table), ObjectCollection("IMAGES"), Clusterable(cluster_id, cluster_name), - type(""), + ds_mad(""), tm_mad(""), base_path("") { @@ -104,11 +104,11 @@ int Datastore::insert(SqlDB *db, string& error_str) erase_template_attribute("NAME", name); // NAME is checked in DatastorePool::allocate - get_template_attribute("TYPE", type); + get_template_attribute("DS_MAD", ds_mad); - if ( type.empty() == true ) + if ( ds_mad.empty() == true ) { - goto error_type; + goto error_ds; } get_template_attribute("TM_MAD", tm_mad); @@ -130,8 +130,8 @@ int Datastore::insert(SqlDB *db, string& error_str) return rc; -error_type: - error_str = "No TYPE in template."; +error_ds: + error_str = "No DS_MAD in template."; goto error_common; error_tm: @@ -248,7 +248,7 @@ string& Datastore::to_xml(string& xml) const "" << gname << "" << "" << name << "" << perms_to_xml(perms_xml) << - "" << type << "" << + "" << ds_mad << "" << "" << tm_mad << "" << "" << base_path << "" << "" << cluster_id << "" << @@ -280,7 +280,7 @@ int Datastore::from_xml(const string& xml) rc += xpath(uname, "/DATASTORE/UNAME", "not_found"); rc += xpath(gname, "/DATASTORE/GNAME", "not_found"); rc += xpath(name, "/DATASTORE/NAME", "not_found"); - rc += xpath(type, "/DATASTORE/TYPE", "not_found"); + rc += xpath(ds_mad, "/DATASTORE/DS_MAD", "not_found"); rc += xpath(tm_mad, "/DATASTORE/TM_MAD", "not_found"); rc += xpath(base_path, "/DATASTORE/BASE_PATH", "not_found"); @@ -329,7 +329,7 @@ int Datastore::from_xml(const string& xml) int Datastore::replace_template(const string& tmpl_str, string& error) { - string new_type; + string new_ds_mad; string new_tm_mad; int rc; @@ -341,11 +341,15 @@ int Datastore::replace_template(const string& tmpl_str, string& error) return rc; } - get_template_attribute("TYPE", new_type); + get_template_attribute("DS_MAD", new_ds_mad); - if ( !new_type.empty() ) + if ( !new_ds_mad.empty() ) { - type = new_type; + ds_mad = new_ds_mad; + } + else + { + replace_template_attribute("DS_MAD", ds_mad); } get_template_attribute("TM_MAD", new_tm_mad); @@ -354,6 +358,10 @@ int Datastore::replace_template(const string& tmpl_str, string& error) { tm_mad = new_tm_mad; } + else + { + replace_template_attribute("TM_MAD", tm_mad); + } return 0; } diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index d45f1eb0d3..7dfd9fe096 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -52,7 +52,7 @@ DatastorePool::DatastorePool(SqlDB * db): // --------------------------------------------------------------------- oss << "NAME = " << SYSTEM_DS_NAME << endl - << "TYPE = fs" << endl + << "DS_MAD = fs" << endl << "TM_MAD = shared"; ds_tmpl = new DatastoreTemplate; @@ -84,7 +84,7 @@ DatastorePool::DatastorePool(SqlDB * db): oss.str(""); oss << "NAME = " << DEFAULT_DS_NAME << endl - << "TYPE = fs" << endl + << "DS_MAD = fs" << endl << "TM_MAD = shared"; ds_tmpl = new DatastoreTemplate; diff --git a/src/datastore_mad/one_datastore.rb b/src/datastore_mad/one_datastore.rb index acbef1839c..295a930bea 100755 --- a/src/datastore_mad/one_datastore.rb +++ b/src/datastore_mad/one_datastore.rb @@ -137,7 +137,7 @@ class DatastoreDriver < OpenNebulaDriver message = Base64.decode64(drv_message) xml_doc = REXML::Document.new(message) - dsxml = xml_doc.root.elements['/DS_DRIVER_ACTION_DATA/DATASTORE/TYPE'] + dsxml = xml_doc.root.elements['/DS_DRIVER_ACTION_DATA/DATASTORE/DS_MAD'] dstxt = dsxml.text if dsxml return dstxt From cefe51b38b0cfc0475d469dc8e56c1b8953931a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 6 Mar 2012 16:30:05 +0100 Subject: [PATCH 121/217] Feature #1112: add src/tm_mad/*/vmds to install.sh --- install.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/install.sh b/install.sh index e8403dd398..f566eb270d 100755 --- a/install.sh +++ b/install.sh @@ -768,7 +768,8 @@ TM_SHARED_FILES="src/tm_mad/shared/clone \ src/tm_mad/shared/mkswap \ src/tm_mad/shared/mkimage \ src/tm_mad/shared/mv \ - src/tm_mad/shared/context" + src/tm_mad/shared/context \ + src/tm_mad/shared/mvds" TM_SSH_FILES="src/tm_mad/ssh/clone \ src/tm_mad/ssh/delete \ @@ -776,7 +777,8 @@ TM_SSH_FILES="src/tm_mad/ssh/clone \ src/tm_mad/ssh/mkswap \ src/tm_mad/ssh/mkimage \ src/tm_mad/ssh/mv \ - src/tm_mad/ssh/context" + src/tm_mad/ssh/context \ + src/tm_mad/ssh/vmds" TM_DUMMY_FILES="src/tm_mad/dummy/clone \ src/tm_mad/dummy/delete \ @@ -792,7 +794,8 @@ TM_LVM_FILES="src/tm_mad/lvm/clone \ src/tm_mad/lvm/mkswap \ src/tm_mad/lvm/mkimage \ src/tm_mad/lvm/mv \ - src/tm_mad/lvm/context" + src/tm_mad/lvm/context \ + src/tm_mad/lvm/dummy" TM_VMWARE_FILES="src/tm_mad/vmware/clone \ src/tm_mad/vmware/ln \ From a48d204b3ea74d34b7ee5871dc5032e4b55a517b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 6 Mar 2012 16:31:12 +0100 Subject: [PATCH 122/217] Feature #1112: RMVMachine save as method: solve image left with its mutex locked, remove PUBLIC att. from new template --- src/rm/RequestManagerVirtualMachine.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 24e3cd17aa..828178bff8 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -451,7 +451,9 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis // Get the data of the Image to be saved // ------------------------------------------------------------------------- - if ( (img = ipool->get(iid_orig, true)) != 0 ) + img = ipool->get(iid_orig, true); + + if ( img == 0 ) { failure_response(NO_EXISTS, get_error(object_name(PoolObjectSQL::IMAGE), iid_orig), @@ -493,7 +495,6 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis ostringstream oss; oss << "NAME = \"" << img_name << "\"" << endl; - oss << "PUBLIC = NO" << endl; oss << "SIZE = " << size << endl; oss << "FS_TYPE = save_as" << endl; From dabcafa2d911583f11cb264d31b4e5a9e1dd2c36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 6 Mar 2012 18:07:14 +0100 Subject: [PATCH 123/217] Feature #1112: Fix exec_and_log functions --- src/mad/sh/scripts_common.sh | 2 +- src/tm_mad/tm_common.sh | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mad/sh/scripts_common.sh b/src/mad/sh/scripts_common.sh index b60c15d8a7..365a6a410e 100755 --- a/src/mad/sh/scripts_common.sh +++ b/src/mad/sh/scripts_common.sh @@ -121,7 +121,7 @@ function exec_and_log else error_message "Error executing $1: $EXEC_LOG_ERR" fi - exit $code + exit $EXEC_LOG_RC fi } diff --git a/src/tm_mad/tm_common.sh b/src/tm_mad/tm_common.sh index 6626ef591f..4c8c721ba9 100644 --- a/src/tm_mad/tm_common.sh +++ b/src/tm_mad/tm_common.sh @@ -88,9 +88,8 @@ $2 EOF` SSH_EXEC_RC=$? - if [ $? -ne 0 ]; then - log_error "Command $2 failed" - log_error "$SSH_EXEC_ERR" + if [ $SSH_EXEC_RC -ne 0 ]; then + log_error "Command \"$2\" failed: $SSH_EXEC_ERR" if [ -n "$3" ]; then error_message "$3" From c9cc70dc814061090894ff485f0bd4aae6fd8ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 6 Mar 2012 18:08:20 +0100 Subject: [PATCH 124/217] Feature #1112: Fix save_as in mkfs datastore_mad drivers --- src/datastore_mad/remotes/fs/mkfs | 8 ++++++++ src/datastore_mad/remotes/vmware/mkfs | 11 +++++++++-- src/image/Image.cc | 17 +++++++++++++++++ src/rm/RequestManagerVirtualMachine.cc | 1 - 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/datastore_mad/remotes/fs/mkfs b/src/datastore_mad/remotes/fs/mkfs index 7f27552ad6..4d3bda68e4 100755 --- a/src/datastore_mad/remotes/fs/mkfs +++ b/src/datastore_mad/remotes/fs/mkfs @@ -65,6 +65,14 @@ SIZE="${XPATH_ELEMENTS[6]}" set_up_datastore "$BASE_PATH" "$RESTRICTED_DIRS" "$SAFE_DIRS" "$UMASK" DST=`generate_image_path` + +# ------------ Image to save_as disk, no need to create a FS ------------ + +if [ "$FSTYPE" = "save_as" ]; then + echo "$DST $SIZE" + exit 0 +fi + # ------------ Create the image to the repository ------------ MKFS_CMD=`mkfs_command $DST $FSTYPE` diff --git a/src/datastore_mad/remotes/vmware/mkfs b/src/datastore_mad/remotes/vmware/mkfs index f48f2535d8..0872965591 100755 --- a/src/datastore_mad/remotes/vmware/mkfs +++ b/src/datastore_mad/remotes/vmware/mkfs @@ -65,13 +65,20 @@ set_up_datastore "$BASE_PATH" "$RESTRICTED_DIRS" "$SAFE_DIRS" "$UMASK" DST=`generate_image_path` +# ------------ Image to save_as disk, no need to create a FS ------------ + +if [ "$FSTYPE" = "save_as" ]; then + echo "$DST $SIZE" + exit 0 +fi + +# ------------ Create the image to the repository ------------ + DISK=$DST/disk.vmdk DISK_TMP=$DISK.tmp IMAGE_FORMAT=vmdk -# ------------ Create the image to the repository ------------ - MKFS_CMD=`mkfs_command $DISK_TMP $FSTYPE` exec_and_log "mkdir -p $DST" \ diff --git a/src/image/Image.cc b/src/image/Image.cc index 058d8551a0..dfa867ee24 100644 --- a/src/image/Image.cc +++ b/src/image/Image.cc @@ -190,6 +190,23 @@ int Image::insert(SqlDB *db, string& error_str) goto error_path_and_source; } } + else + { + string size_attr; + istringstream iss; + + fs_type = "save_as"; + erase_template_attribute("SIZE", size_attr); + + iss.str(size_attr); + + iss >> size_mb; + + if (iss.fail() == true) + { + goto error_size_format; + } + } state = LOCKED; //LOCKED till the ImageManager copies it to the Repository diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 828178bff8..82c3f91640 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -496,7 +496,6 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis oss << "NAME = \"" << img_name << "\"" << endl; oss << "SIZE = " << size << endl; - oss << "FS_TYPE = save_as" << endl; oss << "SAVED_IMAGE_ID = " << iid_orig << endl; oss << "SAVED_DISK_ID = " << disk_id << endl; From ea70484edc621756ba4edc214d2f188d6a014683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 6 Mar 2012 18:44:22 +0100 Subject: [PATCH 125/217] Feature #1112: Fix save_as image state update when VMs in failed state are deleted --- include/Attribute.h | 10 +++++++ include/ImageManager.h | 16 ----------- src/common/Attribute.cc | 24 ++++++++++++++++ src/dm/DispatchManagerActions.cc | 7 ++--- src/image/ImageManagerActions.cc | 41 ++++++++++++++------------ src/vm/VirtualMachine.cc | 49 ++++++++++++++------------------ 6 files changed, 81 insertions(+), 66 deletions(-) diff --git a/include/Attribute.h b/include/Attribute.h index 9d08a8e9ff..d302419987 100644 --- a/include/Attribute.h +++ b/include/Attribute.h @@ -243,6 +243,16 @@ public: */ string vector_value(const char *name) const; + /** + * Returns the integer value + * + * @param name Name of the attribute + * @param value Integer value + * + * @return 0 on success, -1 otherwise + */ + int vector_value(const char *name, int & value) const; + /** * Marshall the attribute in a single string. The string MUST be freed * by the calling function. The string is in the form: diff --git a/include/ImageManager.h b/include/ImageManager.h index 38cf5be66f..2d3d8789ca 100644 --- a/include/ImageManager.h +++ b/include/ImageManager.h @@ -96,22 +96,6 @@ public: */ Image * acquire_image(const string& name, int uid, string& error); - /** - * Releases an image and triggers any needed operations in the repo - * @param iid image id of the image to be released - * @param failed the associated VM releasing the images is FAILED - */ - void release_image(const string& iid, bool failed) - { - int image_id; - istringstream iss; - - iss.str(iid); - iss >> image_id; - - release_image(image_id, failed); - }; - /** * Releases an image and triggers any needed operations in the repo * @param iid image id of the image to be released diff --git a/src/common/Attribute.cc b/src/common/Attribute.cc index 1c70602f11..bce9e58eb8 100644 --- a/src/common/Attribute.cc +++ b/src/common/Attribute.cc @@ -201,3 +201,27 @@ string VectorAttribute::vector_value(const char *name) const } } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VectorAttribute::vector_value(const char *name, int & value) const +{ + map::const_iterator it; + + it = attribute_value.find(name); + + if ( it == attribute_value.end() ) + { + return -1; + } + + if ( it->second.empty() ) + { + return -1; + } + + istringstream iss(it->second); + iss >> value; + + return 0; +} diff --git a/src/dm/DispatchManagerActions.cc b/src/dm/DispatchManagerActions.cc index 7294dad902..f945c98944 100644 --- a/src/dm/DispatchManagerActions.cc +++ b/src/dm/DispatchManagerActions.cc @@ -616,16 +616,15 @@ int DispatchManager::finalize( case VirtualMachine::PENDING: case VirtualMachine::HOLD: case VirtualMachine::STOPPED: + vm->release_network_leases(); + vm->release_disk_images(); + vm->set_exit_time(time(0)); vm->set_state(VirtualMachine::LCM_INIT); vm->set_state(VirtualMachine::DONE); vmpool->update(vm); - vm->release_network_leases(); - - vm->release_disk_images(); - vm->log("DiM", Log::INFO, "New VM state is DONE."); break; diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index b507a396f1..3b41c8d2c2 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -158,34 +158,39 @@ void ImageManager::release_image(int iid, bool failed) { img->set_state(Image::READY); } - - ipool->update(img); } else if ( rvms == 0 ) { img->set_state(Image::READY); - - ipool->update(img); - } - - img->unlock(); - break; - - case Image::LOCKED: //SAVE_AS images are LOCKED till released - if (failed == true) - { - img->set_state(Image::ERROR); - } - else - { - img->set_state(Image::READY); } ipool->update(img); img->unlock(); - break; + break; + case Image::LOCKED: //SAVE_AS images are LOCKED till released + if ( img->isSaving() ) + { + if (failed == true) + { + img->set_state(Image::ERROR); + } + else + { + img->set_state(Image::READY); + } + + ipool->update(img); + } + else + { + NebulaLog::log("ImM",Log::ERROR, + "Trying to release image in wrong state."); + } + + img->unlock(); + break; case Image::DISABLED: case Image::READY: case Image::ERROR: diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 2b3d3da734..5d5595b7f4 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -949,8 +949,9 @@ error_common: void VirtualMachine::release_disk_images() { - string iid; - string saveas; + int iid; + int save_as_id; + int rc; int num_disks; vector disks; @@ -973,12 +974,19 @@ void VirtualMachine::release_disk_images() continue; } - iid = disk->vector_value("IMAGE_ID"); + rc = disk->vector_value("IMAGE_ID", iid); - if ( !iid.empty() ) + if ( rc == 0 ) { imagem->release_image(iid, (state == FAILED)); } + + rc = disk->vector_value("SAVE_AS", save_as_id); + + if ( rc == 0 ) + { + imagem->release_image(save_as_id, (state == FAILED)); + } } } @@ -1131,27 +1139,6 @@ int VirtualMachine::generate_context(string &files) return 1; } -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -static int id_from_attr (VectorAttribute * attr, const char *name) -{ - int id; - string id_str; - - id_str = attr->vector_value(name); - - if (id_str.empty()) - { - return -1; - } - - istringstream iss(id_str); - iss >> id; - - return id; -} - /* -------------------------------------------------------------------------- */ int VirtualMachine::get_image_from_disk(int disk_id, string& error_str) @@ -1159,6 +1146,7 @@ int VirtualMachine::get_image_from_disk(int disk_id, string& error_str) int num_disks; int tid; int iid = -1; + int rc; vector disks; VectorAttribute * disk; @@ -1181,7 +1169,12 @@ int VirtualMachine::get_image_from_disk(int disk_id, string& error_str) continue; } - tid = id_from_attr(disk,"DISK_ID"); + rc = disk->vector_value("DISK_ID", tid); + + if ( rc != 0 ) + { + continue; + } if ( disk_id == tid ) { @@ -1195,9 +1188,9 @@ int VirtualMachine::get_image_from_disk(int disk_id, string& error_str) goto error_persistent; } - iid = id_from_attr(disk, "IMAGE_ID"); + rc = disk->vector_value("IMAGE_ID", iid); - if (iid == -1) + if ( rc != 0 ) { goto error_image_id; } From fb44e1955a1b6f0c149d396856f075df178ccd49 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 6 Mar 2012 22:25:22 +0100 Subject: [PATCH 126/217] feature #1112: Fix file name in install.sh --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index f566eb270d..263bc191cc 100755 --- a/install.sh +++ b/install.sh @@ -778,7 +778,7 @@ TM_SSH_FILES="src/tm_mad/ssh/clone \ src/tm_mad/ssh/mkimage \ src/tm_mad/ssh/mv \ src/tm_mad/ssh/context \ - src/tm_mad/ssh/vmds" + src/tm_mad/ssh/mvds" TM_DUMMY_FILES="src/tm_mad/dummy/clone \ src/tm_mad/dummy/delete \ From e4017e610685a8466aa4fc7ed122e4800585d052 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 6 Mar 2012 22:25:39 +0100 Subject: [PATCH 127/217] feature #1112: Move SED initialization to scripts_common.sh. Always fix path for SRC/DST --- src/mad/sh/scripts_common.sh | 6 ++++++ src/tm_mad/tm_common.sh | 9 ++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/mad/sh/scripts_common.sh b/src/mad/sh/scripts_common.sh index 365a6a410e..307c5cf618 100755 --- a/src/mad/sh/scripts_common.sh +++ b/src/mad/sh/scripts_common.sh @@ -38,6 +38,12 @@ SUDO=sudo WGET=wget GREP=grep +if [ "x$(uname -s)" = "xLinux" ]; then + SED="$SED -r" +else + SED="/usr/bin/sed -E" +fi + # Used for log messages SCRIPT_NAME=`basename $0` diff --git a/src/tm_mad/tm_common.sh b/src/tm_mad/tm_common.sh index 4c8c721ba9..b189b12f33 100644 --- a/src/tm_mad/tm_common.sh +++ b/src/tm_mad/tm_common.sh @@ -33,12 +33,6 @@ ONE_SH=$ONE_LIB/sh . $ONE_SH/scripts_common.sh -if [ "x$(uname -s)" = "xLinux" ]; then - SED="$SED -r" -else - SED="/usr/bin/sed -E" -fi - # ------------------------------------------------------------------------------ # Function to get hosts and paths from arguments # ------------------------------------------------------------------------------ @@ -52,7 +46,8 @@ function arg_host # Gets the path from an argument function arg_path { - echo $1 | $SED 's/^[^:]*:(.*)$/\1/' + ARG_PATH=`echo $1 | $SED 's/^[^:]*:(.*)$/\1/'` + fix_dir_slashes "$ARG_PATH" } #Return the DATASTORE_LOCATION from OpenNebula configuration From ea089f06263fb749fc85425a44eb99d5401df16e Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 6 Mar 2012 23:23:33 +0100 Subject: [PATCH 128/217] feature #1112: Fix errors in mvds scripts --- src/image/ImageManagerDriver.cc | 2 ++ src/tm_mad/shared/mvds | 10 +++++----- src/tm_mad/ssh/mvds | 2 +- src/tm_mad/tm_common.sh | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/image/ImageManagerDriver.cc b/src/image/ImageManagerDriver.cc index 64ad5e128e..c49eba0503 100644 --- a/src/image/ImageManagerDriver.cc +++ b/src/image/ImageManagerDriver.cc @@ -238,6 +238,8 @@ void ImageManagerDriver::protocol( goto error_save_state_vm; } + vmpool->update(vm); + vm->unlock(); } diff --git a/src/tm_mad/shared/mvds b/src/tm_mad/shared/mvds index 94116583cd..6e3744f98d 100755 --- a/src/tm_mad/shared/mvds +++ b/src/tm_mad/shared/mvds @@ -43,20 +43,20 @@ DST_PATH=`arg_path $DST` DST_PATH="$RMT_DS_DIR/${DST_PATH##"$DS_DIR/"}" -SRC_HOST=`arg_host $DST` +SRC_HOST=`arg_host $SRC` #------------------------------------------------------------------------------- # Move the image back to the datastore #------------------------------------------------------------------------------- MVSCRIPT=$(cat <&1 1>/dev/null` EXEC_LOG_RC=$? @@ -192,7 +192,7 @@ function mkfs_command { ;; "raw") echo "" - return 0 + return 0 ;; "swap") echo "$MKSWAP $DST" @@ -205,3 +205,41 @@ function mkfs_command { echo "$MKFS -t $FSTYPE $OPTS $DST" } + +#This function executes $2 at $1 host and report error $3 +function ssh_exec_and_log +{ + SSH_EXEC_ERR=`$SSH $1 bash -s 2>&1 1>/dev/null <&1 1>/dev/null < /dev/null 2>&1 + echo "$1" | $GREP '/disk\.[0-9]\+' > /dev/null 2>&1 if [ $? -eq 0 ]; then echo "1" @@ -70,56 +70,3 @@ function is_disk echo "0" fi } - -# ------------------------------------------------------------------------------ -# Function to get hosts and paths from arguments -# ------------------------------------------------------------------------------ - -#This function executes $2 at $1 host and report error $3 -function ssh_exec_and_log -{ - SSH_EXEC_ERR=`$SSH $1 bash -s 2>&1 1>/dev/null <&1 1>/dev/null < Date: Wed, 7 Mar 2012 12:42:21 +0100 Subject: [PATCH 130/217] feature #1112: DS iSCSI drivers --- install.sh | 7 ++ src/datastore_mad/remotes/iscsi/cp | 112 +++++++++++++++++++++ src/datastore_mad/remotes/iscsi/iscsi.conf | 24 +++++ src/datastore_mad/remotes/iscsi/mkfs | 101 +++++++++++++++++++ src/datastore_mad/remotes/iscsi/rm | 81 +++++++++++++++ src/datastore_mad/remotes/libfs.sh | 34 +++++++ src/mad/sh/scripts_common.sh | 3 +- 7 files changed, 361 insertions(+), 1 deletion(-) create mode 100755 src/datastore_mad/remotes/iscsi/cp create mode 100644 src/datastore_mad/remotes/iscsi/iscsi.conf create mode 100755 src/datastore_mad/remotes/iscsi/mkfs create mode 100755 src/datastore_mad/remotes/iscsi/rm diff --git a/install.sh b/install.sh index 263bc191cc..772aaadee9 100755 --- a/install.sh +++ b/install.sh @@ -237,6 +237,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \ $VAR_LOCATION/remotes/datastore \ $VAR_LOCATION/remotes/datastore/fs \ $VAR_LOCATION/remotes/datastore/vmware \ + $VAR_LOCATION/remotes/datastore/iscsi \ $VAR_LOCATION/remotes/auth \ $VAR_LOCATION/remotes/auth/plain \ $VAR_LOCATION/remotes/auth/ssh \ @@ -390,6 +391,7 @@ INSTALL_FILES=( DATASTORE_DRIVER_COMMON_SCRIPTS:$VAR_LOCATION/remotes/datastore/ DATASTORE_DRIVER_FS_SCRIPTS:$VAR_LOCATION/remotes/datastore/fs DATASTORE_DRIVER_VMWARE_SCRIPTS:$VAR_LOCATION/remotes/datastore/vmware + DATASTORE_DRIVER_ISCSI_SCRIPTS:$VAR_LOCATION/remotes/datastore/iscsi NETWORK_FILES:$VAR_LOCATION/remotes/vnm NETWORK_8021Q_FILES:$VAR_LOCATION/remotes/vnm/802.1Q NETWORK_DUMMY_FILES:$VAR_LOCATION/remotes/vnm/dummy @@ -820,6 +822,11 @@ DATASTORE_DRIVER_VMWARE_SCRIPTS="src/datastore_mad/remotes/vmware/cp \ src/datastore_mad/remotes/vmware/mkfs \ src/datastore_mad/remotes/vmware/rm" +DATASTORE_DRIVER_ISCSI_SCRIPTS="src/datastore_mad/remotes/iscsi/cp \ + src/datastore_mad/remotes/iscsi/mkfs \ + src/datastore_mad/remotes/iscsi/rm \ + src/datastore_mad/remotes/iscsi/iscsi.conf" + #------------------------------------------------------------------------------- # Migration scripts for onedb command, to be installed under $LIB_LOCATION #------------------------------------------------------------------------------- diff --git a/src/datastore_mad/remotes/iscsi/cp b/src/datastore_mad/remotes/iscsi/cp new file mode 100755 index 0000000000..5e4a797899 --- /dev/null +++ b/src/datastore_mad/remotes/iscsi/cp @@ -0,0 +1,112 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +############################################################################### +# This script is used to copy a VM image (SRC) to the image repository as DST +# Several SRC types are supported +############################################################################### + +# -------- Set up the environment to source common tools & conf ------------ + +if [ -z "${ONE_LOCATION}" ]; then + LIB_LOCATION=/usr/lib/one +else + LIB_LOCATION=$ONE_LOCATION/lib +fi + +. $LIB_LOCATION/sh/scripts_common.sh + +DRIVER_PATH=$(dirname $0) +source ${DRIVER_PATH}/../libfs.sh +source ${DRIVER_PATH}/iscsi.conf + +# -------- Get cp and datastore arguments from OpenNebula core ------------ + +DRV_ACTION=$1 +ID=$2 + +XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" + +unset i XPATH_ELEMENTS + +while IFS= read -r -d '' element; do + XPATH_ELEMENTS[i++]="$element" +done < <($XPATH /DS_DRIVER_ACTION_DATA/DATASTORE/BASE_PATH \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/RESTRICTED_DIRS \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/SAFE_DIRS \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/UMASK \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/HOST \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/VG_NAME \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/BASE_IQN \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/BASE_TID \ + /DS_DRIVER_ACTION_DATA/IMAGE/PATH) + + +BASE_PATH="${XPATH_ELEMENTS[0]}" +RESTRICTED_DIRS="${XPATH_ELEMENTS[1]}" +SAFE_DIRS="${XPATH_ELEMENTS[2]}" +UMASK="${XPATH_ELEMENTS[3]}" +DST_HOST="${XPATH_ELEMENTS[4]}" +VG_NAME="${XPATH_ELEMENTS[5]:-$VG_NAME}" +BASE_IQN="${XPATH_ELEMENTS[6]:-$BASE_IQN}" +BASE_TID="${XPATH_ELEMENTS[7]:-$BASE_TID}" +SRC="${XPATH_ELEMENTS[8]}" + +set_up_datastore "$BASE_PATH" "$RESTRICTED_DIRS" "$SAFE_DIRS" "$UMASK" + +SIZE=`fs_du $SRC` +LV_NAME="lv-one-${ID}" +IQN="$BASE_IQN:$DST_HOST.$VG_NAME.$LV_NAME" +DEV="/dev/$VG_NAME/$LV_NAME" + +let TID=ID+BASE_TID + +REGISTER_CMD=$(cat <&2 + exit 1 + fi +EOF +) + +log "Removing $DST_HOST:$DEV from the image repository" + +ssh_exec_and_log "$DST_HOST" "$RM_COMMAND" \ + "Error removing $DST_HOST:$DEV" + +exit 0 diff --git a/src/datastore_mad/remotes/libfs.sh b/src/datastore_mad/remotes/libfs.sh index 76a91c6227..55d5aada37 100644 --- a/src/datastore_mad/remotes/libfs.sh +++ b/src/datastore_mad/remotes/libfs.sh @@ -136,3 +136,37 @@ function check_restricted { echo 0 } + + +# ------------------------------------------------------------------------------ +# iSCSI functions +# ------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------- +# Returns the command to create a new target +# @param $1 - ID of the image +# @param $2 - Target Host +# @param $3 - Device +# @return the command to create a new target +#------------------------------------------------------------------------------- + +function iscsi_target_new { + ID="$1" + IQN="$2" + + echo "$TGTADM --lld iscsi --op new --mode target --tid $ID "\ + "--targetname $IQN" +} + +function iscsi_logicalunit_new { + ID="$1" + DEV="$2" + + echo "$TGTADM --lld iscsi --op new --mode logicalunit --tid $ID "\ + "--lun 1 --backing-store $DEV" +} + +function iscsi_target_delete { + ID="$1" + echo "$TGTADM --lld iscsi --op delete --mode target --tid $ID" +} diff --git a/src/mad/sh/scripts_common.sh b/src/mad/sh/scripts_common.sh index 2679d8a014..6b4ef552d9 100755 --- a/src/mad/sh/scripts_common.sh +++ b/src/mad/sh/scripts_common.sh @@ -22,6 +22,7 @@ CUT=cut DATE=date DD=dd DU=du +GREP=grep LVCREATE=lvcreate LVREMOVE=lvremove LVS=lvs @@ -35,8 +36,8 @@ SCP=scp SED=sed SSH=ssh SUDO=sudo +TGTADM=tgtadm WGET=wget -GREP=grep if [ "x$(uname -s)" = "xLinux" ]; then SED="$SED -r" From 5ec865cb3c49354274f99affde7ea9c8d13760ec Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Wed, 7 Mar 2012 12:45:49 +0100 Subject: [PATCH 131/217] feature #1112: improve debugging for one_datastore.rb --- src/datastore_mad/one_datastore.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/datastore_mad/one_datastore.rb b/src/datastore_mad/one_datastore.rb index 295a930bea..2ed7afc99b 100755 --- a/src/datastore_mad/one_datastore.rb +++ b/src/datastore_mad/one_datastore.rb @@ -83,9 +83,9 @@ class DatastoreDriver < OpenNebulaDriver register_action(ACTION[:mkfs].to_sym, method("mkfs")) end - ############################################################################ + ############################################################################ # Image Manager Protocol Actions (generic implementation) - ############################################################################ + ############################################################################ # TODO: Integrate this with TM # def mv(id, ds, src, dst) # do_image_action(id, ds, :mv, "'#{src}' '#{dst}' '#{id}'") @@ -112,7 +112,7 @@ class DatastoreDriver < OpenNebulaDriver if @types.include?(ds) return true else - send_message(ACTION[action], RESULT[:failure], id, + send_message(ACTION[action], RESULT[:failure], id, "Datastore driver '#{ds}' not available") return false end @@ -130,6 +130,8 @@ class DatastoreDriver < OpenNebulaDriver result, info = get_info_from_execution(rc) + + PP.pp([ACTION[action], result, id, info],STDERR) send_message(ACTION[action], result, id, info) end From 301447560d0f946f983b518fe8c351443743d5cb Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Wed, 7 Mar 2012 13:08:46 +0100 Subject: [PATCH 132/217] feature #1112: Add space in error message --- src/vm/VirtualMachine.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 5d5595b7f4..e56c197029 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -1216,7 +1216,7 @@ error_saved: goto error_common; error_image_id: - oss << "The DISK " << disk_id << "does not have a valid IMAGE_ID."; + oss << "The DISK " << disk_id << " does not have a valid IMAGE_ID."; goto error_common; error_not_found: From 9b9d04a4d2217ebda45139357e347f88a69f2be3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tino=20V=C3=A1zquez?= Date: Wed, 7 Mar 2012 07:04:40 -0600 Subject: [PATCH 133/217] Fix some typos --- share/etc/oned.conf | 6 +++--- src/tm/TransferManagerDriver.cc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 400d07ab12..b98bdf288e 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -80,9 +80,9 @@ MAC_PREFIX = "02:00" #******************************************************************************* # DataStore Configuration #******************************************************************************* -# DATASTORE_LOCATION: Path for Datastores in the hosts. It IS the same all the -# hosts in the cluster. DATASTORE_LOCATION IS ONLY FOR THE HOSTS AND *NOT* THE -# FRONT-END. It defaults to /var/lib/one/datastores (or +# DATASTORE_LOCATION: Path for Datastores in the hosts. It IS the same for all +# the hosts in the cluster. DATASTORE_LOCATION IS ONLY FOR THE HOSTS AND *NOT* +# THE FRONT-END. It defaults to /var/lib/one/datastores (or # $ONE_LOCATION/var/datastores in self-contained mode) # # DEFAULT_IMAGE_TYPE: This can take values diff --git a/src/tm/TransferManagerDriver.cc b/src/tm/TransferManagerDriver.cc index 6eb1e2b8c6..f50388ec7b 100644 --- a/src/tm/TransferManagerDriver.cc +++ b/src/tm/TransferManagerDriver.cc @@ -142,7 +142,7 @@ void TransferManagerDriver::protocol( getline(is,info); os.str(""); - os << "Error excuting image transfer script"; + os << "Error executing image transfer script"; if (!info.empty() && info[0] != '-') { From c49f2ac7daead6cf500706ef7c248004eecbcbdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 7 Mar 2012 15:27:43 +0100 Subject: [PATCH 134/217] Feature #1112: Refactor VirtualMachine::automatic_requirements to improve performance when there are no errors --- src/vm/VirtualMachine.cc | 104 ++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 34 deletions(-) diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 5d5595b7f4..9eb8a42f28 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -535,10 +535,9 @@ int VirtualMachine::automatic_requirements(string& error_str) ostringstream oss; string requirements; string cluster_id; + string vatt_cluster_id; bool error = false; - oss << "Incompatible cluster IDs."; - // Get cluster id from all DISK vector attributes num_vatts = obj_template->get("DISK",v_attributes); @@ -552,23 +551,16 @@ int VirtualMachine::automatic_requirements(string& error_str) continue; } - string vatt_cluster_id = vatt->vector_value("CLUSTER_ID"); + vatt_cluster_id = vatt->vector_value("CLUSTER_ID"); if ( !vatt_cluster_id.empty() ) { - oss << endl << "DISK [" << i << "]: IMAGE [" - << vatt->vector_value("IMAGE_ID") << "] from DATASTORE [" - << vatt->vector_value("DATASTORE_ID") << "] requires CLUSTER [" - << vatt_cluster_id << "]"; + if ( cluster_id != vatt_cluster_id ) + { + goto error; + } - if ( cluster_id.empty() ) - { - cluster_id = vatt_cluster_id; - } - else if ( cluster_id != vatt_cluster_id ) - { - error = true; - } + cluster_id = vatt_cluster_id; } } @@ -586,32 +578,19 @@ int VirtualMachine::automatic_requirements(string& error_str) continue; } - string vatt_cluster_id = vatt->vector_value("CLUSTER_ID"); + vatt_cluster_id = vatt->vector_value("CLUSTER_ID"); if ( !vatt_cluster_id.empty() ) { - oss << endl << "NIC [" << i << "]: NETWORK [" - << vatt->vector_value("NETWORK_ID") << "] requires CLUSTER [" - << vatt_cluster_id << "]"; + if ( cluster_id != vatt_cluster_id ) + { + goto error; + } - if ( cluster_id.empty() ) - { - cluster_id = vatt_cluster_id; - } - else if ( cluster_id != vatt_cluster_id ) - { - error = true; - } + cluster_id = vatt_cluster_id; } } - if ( error == true ) - { - error_str = oss.str(); - - return -1; - } - if ( !cluster_id.empty() ) { oss.str(""); @@ -628,6 +607,63 @@ int VirtualMachine::automatic_requirements(string& error_str) } return 0; + +error: + + oss << "Incompatible cluster IDs."; + + // Get cluster id from all DISK vector attributes + + v_attributes.clear(); + num_vatts = obj_template->get("DISK",v_attributes); + + for(int i=0; i(v_attributes[i]); + + if ( vatt == 0 ) + { + continue; + } + + vatt_cluster_id = vatt->vector_value("CLUSTER_ID"); + + if ( !vatt_cluster_id.empty() ) + { + oss << endl << "DISK [" << i << "]: IMAGE [" + << vatt->vector_value("IMAGE_ID") << "] from DATASTORE [" + << vatt->vector_value("DATASTORE_ID") << "] requires CLUSTER [" + << vatt_cluster_id << "]"; + } + } + + // Get cluster id from all NIC vector attributes + + v_attributes.clear(); + num_vatts = obj_template->get("NIC",v_attributes); + + for(int i=0; i(v_attributes[i]); + + if ( vatt == 0 ) + { + continue; + } + + vatt_cluster_id = vatt->vector_value("CLUSTER_ID"); + + if ( !vatt_cluster_id.empty() ) + { + oss << endl << "NIC [" << i << "]: NETWORK [" + << vatt->vector_value("NETWORK_ID") << "] requires CLUSTER [" + << vatt_cluster_id << "]"; + } + } + + error_str = oss.str(); + + return -1; } /* ------------------------------------------------------------------------ */ From 7bede56655487299cd4de07001511a3974400c4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 7 Mar 2012 15:54:37 +0100 Subject: [PATCH 135/217] Feature #1112: Remove unneeded variable --- src/vm/VirtualMachine.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 546f109f3b..ba168ec86f 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -536,7 +536,6 @@ int VirtualMachine::automatic_requirements(string& error_str) string requirements; string cluster_id; string vatt_cluster_id; - bool error = false; // Get cluster id from all DISK vector attributes From 3a81160c9354ad4184cce1a9a7c1e2fea3c1b337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 7 Mar 2012 17:19:08 +0100 Subject: [PATCH 136/217] Feature #1112: Fix segmentation fault when drivers are not defined in oned.conf --- src/authm/AuthManager.cc | 7 +++++-- src/hm/HookManager.cc | 7 +++++-- src/image/ImageManager.cc | 7 +++++-- src/tm/TransferManager.cc | 7 +++++-- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/authm/AuthManager.cc b/src/authm/AuthManager.cc index 348782c68a..6201ba33e2 100644 --- a/src/authm/AuthManager.cc +++ b/src/authm/AuthManager.cc @@ -429,7 +429,7 @@ void AuthManager::notify_request(int auth_id,bool result,const string& message) void AuthManager::load_mads(int uid) { ostringstream oss; - const VectorAttribute * vattr; + const VectorAttribute * vattr = 0; int rc; string name; AuthManagerDriver * authm_driver = 0; @@ -438,7 +438,10 @@ void AuthManager::load_mads(int uid) NebulaLog::log("AuM",Log::INFO,oss); - vattr = static_cast(mad_conf[0]); + if ( mad_conf.size() > 0 ) + { + vattr = static_cast(mad_conf[0]); + } if ( vattr == 0 ) { diff --git a/src/hm/HookManager.cc b/src/hm/HookManager.cc index 8555d1c4ad..f49a21ea92 100644 --- a/src/hm/HookManager.cc +++ b/src/hm/HookManager.cc @@ -49,12 +49,15 @@ void HookManager::load_mads(int uid) { HookManagerDriver * hm_mad; ostringstream oss; - const VectorAttribute * vattr; + const VectorAttribute * vattr = 0; int rc; NebulaLog::log("HKM",Log::INFO,"Loading Hook Manager driver."); - vattr = static_cast(mad_conf[0]); + if ( mad_conf.size() > 0 ) + { + vattr = static_cast(mad_conf[0]); + } if ( vattr == 0 ) { diff --git a/src/image/ImageManager.cc b/src/image/ImageManager.cc index e0fc6789ff..52c3ab9df8 100644 --- a/src/image/ImageManager.cc +++ b/src/image/ImageManager.cc @@ -50,12 +50,15 @@ void ImageManager::load_mads(int uid) { ImageManagerDriver * imagem_mad; ostringstream oss; - const VectorAttribute * vattr; + const VectorAttribute * vattr = 0; int rc; NebulaLog::log("ImM",Log::INFO,"Loading Image Manager driver."); - vattr = static_cast(mad_conf[0]); + if ( mad_conf.size() > 0 ) + { + vattr = static_cast(mad_conf[0]); + } if ( vattr == 0 ) { diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index d3d1212d84..13af39a96b 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -1288,14 +1288,17 @@ void TransferManager::load_mads(int uid) int rc; string name; - const VectorAttribute * vattr; + const VectorAttribute * vattr = 0; TransferManagerDriver * tm_driver = 0; oss << "Loading Transfer Manager driver."; NebulaLog::log("TM",Log::INFO,oss); - vattr = static_cast(mad_conf[0]); + if ( mad_conf.size() > 0 ) + { + vattr = static_cast(mad_conf[0]); + } if ( vattr == 0 ) { From e522dabcc1db2e8aef96bce9c06e8bd250fcf7f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 7 Mar 2012 17:45:08 +0100 Subject: [PATCH 137/217] Feature #1112, #962: Fix a bunch of typos in error messages --- src/cli/one_helper/oneuser_helper.rb | 2 +- src/cloud/ec2/bin/econe-server | 2 +- src/cloud/occi/bin/occi-server | 2 +- src/cloud/occi/lib/OCCIClient.rb | 4 ++-- src/datastore_mad/remotes/libfs.sh | 2 +- src/dm/DispatchManagerActions.cc | 4 ++-- src/group/GroupPool.cc | 2 +- src/host/test/HostPoolTest.cc | 2 +- src/image/ImageManagerActions.cc | 12 ++++++------ src/mad/Mad.cc | 6 +++--- src/nebula/oned.cc | 4 ++-- src/oca/java/test/oned.conf | 2 +- src/oca/ruby/OpenNebula/Group.rb | 2 +- src/onedb/test/oned_mysql.conf | 4 ++-- src/onedb/test/oned_sqlite.conf | 4 ++-- src/ozones/Server/bin/ozones-server | 2 +- src/ozones/Server/models/OzonesServer.rb | 4 ++-- src/pool/PoolObjectSQL.cc | 2 +- src/rm/RequestManager.cc | 6 +++--- src/rm/RequestManagerDelete.cc | 6 +++--- src/rm/RequestManagerUpdateTemplate.cc | 2 +- src/rm/RequestManagerVirtualMachine.cc | 4 ++-- src/sunstone/bin/sunstone-server | 2 +- src/tm_mad/vmware/functions.sh | 2 +- src/vm/VirtualMachine.cc | 10 +++++----- src/vm/VirtualMachinePool.cc | 2 +- src/vmm_mad/ec2/one_vmm_ec2.rb | 6 +++--- src/vmm_mad/exec/one_vmm_exec.rb | 2 +- src/vmm_mad/remotes/vmware/vmware_driver.rb | 2 +- 29 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/cli/one_helper/oneuser_helper.rb b/src/cli/one_helper/oneuser_helper.rb index 82a060b44e..2b1a532919 100644 --- a/src/cli/one_helper/oneuser_helper.rb +++ b/src/cli/one_helper/oneuser_helper.rb @@ -34,7 +34,7 @@ class OneUserHelper < OpenNebulaHelper::OneHelper begin password = File.read(arg).split("\n").first rescue - return -1, "Can not read file: #{arg}" + return -1, "Cannot read file: #{arg}" end else password = arg.dup diff --git a/src/cloud/ec2/bin/econe-server b/src/cloud/ec2/bin/econe-server index 2071c168d7..5b1d23a9f2 100755 --- a/src/cloud/ec2/bin/econe-server +++ b/src/cloud/ec2/bin/econe-server @@ -53,7 +53,7 @@ setup() start() { if [ ! -f "$ECONE_SERVER" ]; then - echo "Can not find $ECONE_SERVER." + echo "Cannot find $ECONE_SERVER." exit 1 fi diff --git a/src/cloud/occi/bin/occi-server b/src/cloud/occi/bin/occi-server index c7306756c7..5218f42e77 100755 --- a/src/cloud/occi/bin/occi-server +++ b/src/cloud/occi/bin/occi-server @@ -53,7 +53,7 @@ setup() start() { if [ ! -x "$OCCI_SERVER" ]; then - echo "Can not find $OCCI_SERVER." + echo "Cannot find $OCCI_SERVER." exit 1 fi diff --git a/src/cloud/occi/lib/OCCIClient.rb b/src/cloud/occi/lib/OCCIClient.rb index 4b30b9fb2c..c600599a18 100755 --- a/src/cloud/occi/lib/OCCIClient.rb +++ b/src/cloud/occi/lib/OCCIClient.rb @@ -131,7 +131,7 @@ module OCCIClient file_path="/"+m[1] end elsif !image_info.elements['TYPE'] == "DATABLOCK" - return CloudClient::Error.new("Can not find URL") + return CloudClient::Error.new("Cannot find URL") end if curb @@ -316,7 +316,7 @@ module OCCIClient end if info.elements['ID'] == nil - return CloudClient::Error.new("Can not find RESOURCE ID") + return CloudClient::Error.new("Cannot find RESOURCE ID") end resource_id = info.elements['ID'].text diff --git a/src/datastore_mad/remotes/libfs.sh b/src/datastore_mad/remotes/libfs.sh index 55d5aada37..02f238e050 100644 --- a/src/datastore_mad/remotes/libfs.sh +++ b/src/datastore_mad/remotes/libfs.sh @@ -23,7 +23,7 @@ # @param $3 - Safe dirs # @param $4 - Umask for new file creation (default: 0007) # @return sets the following environment variables -# - RESTRICTED_DIRS: Paths that can not be used to register images +# - RESTRICTED_DIRS: Paths that cannot be used to register images # - SAFE_DIRS: Paths that are safe to specify image paths # - BASE_PATH: Path where the images will be stored #------------------------------------------------------------------------------ diff --git a/src/dm/DispatchManagerActions.cc b/src/dm/DispatchManagerActions.cc index f945c98944..4907ed7194 100644 --- a/src/dm/DispatchManagerActions.cc +++ b/src/dm/DispatchManagerActions.cc @@ -664,7 +664,7 @@ int DispatchManager::resubmit(int vid) { case VirtualMachine::SUSPENDED: NebulaLog::log("DiM",Log::ERROR, - "Can not resubmit a suspended VM. Resume it first"); + "Cannot resubmit a suspended VM. Resume it first"); rc = -2; break; @@ -688,7 +688,7 @@ int DispatchManager::resubmit(int vid) break; case VirtualMachine::DONE: NebulaLog::log("DiM",Log::ERROR, - "Can not resubmit a VM already in DONE state"); + "Cannot resubmit a VM already in DONE state"); rc = -2; break; } diff --git a/src/group/GroupPool.cc b/src/group/GroupPool.cc index a476669b06..b12cda200f 100644 --- a/src/group/GroupPool.cc +++ b/src/group/GroupPool.cc @@ -22,7 +22,7 @@ /* -------------------------------------------------------------------------- */ /* There are two default groups boostrapped by the core: */ -/* - oneadmin can not be removed */ +/* - oneadmin cannot be removed */ /* - users to place regular users by default */ /* The first 100 group IDs are reserved for system groups. Regular ones start */ /* from ID 100 */ diff --git a/src/host/test/HostPoolTest.cc b/src/host/test/HostPoolTest.cc index d3e81a802d..9f02041dfc 100644 --- a/src/host/test/HostPoolTest.cc +++ b/src/host/test/HostPoolTest.cc @@ -267,7 +267,7 @@ public: CPPUNIT_ASSERT( oid_1 == -1 ); CPPUNIT_ASSERT( rc == oid_1 ); - // the hostname can not be repeated if the drivers change + // the hostname cannot be repeated if the drivers change rc = hp->allocate(&oid_1, names[0], im_mad_2, diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index 3b41c8d2c2..ad1b8e2627 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -95,7 +95,7 @@ int ImageManager::acquire_image(Image *img, string& error) case Image::USED: if (img->isPersistent()) { - error = "Cannot aquire persistent image, it is already in use"; + error = "Cannot acquire persistent image, it is already in use"; rc = -1; } else @@ -106,15 +106,15 @@ int ImageManager::acquire_image(Image *img, string& error) break; case Image::DISABLED: - error = "Cannot aquire image, it is disabled"; + error = "Cannot acquire image, it is disabled"; rc = -1; break; case Image::LOCKED: - error = "Cannot aquire image, it is locked"; + error = "Cannot acquire image, it is locked"; rc = -1; break; case Image::ERROR: - error = "Cannot aquire image, it is in an error state"; + error = "Cannot acquire image, it is in an error state"; rc = -1; break; default: @@ -276,13 +276,13 @@ int ImageManager::delete_image(int iid, const string& ds_data) if ( img->get_running() != 0 ) { img->unlock(); - return -1; //Can not remove images in use + return -1; //Cannot remove images in use } break; case Image::USED: img->unlock(); - return -1; //Can not remove images in use + return -1; //Cannot remove images in use break; case Image::INIT: diff --git a/src/mad/Mad.cc b/src/mad/Mad.cc index 98388228ee..e33c04cfdb 100644 --- a/src/mad/Mad.cc +++ b/src/mad/Mad.cc @@ -239,13 +239,13 @@ int Mad::start() error_exec: oss.str(""); - oss << "Can not load driver " << executable << ", " << strerror(errno); + oss << "Cannot load driver " << executable << ", " << strerror(errno); NebulaLog::log("MAD", Log::ERROR, oss); exit(-1); error_dup2: oss.str(""); - oss << "Can not duplicate descriptors, " << strerror(errno); + oss << "Cannot duplicate descriptors, " << strerror(errno); NebulaLog::log("MAD", Log::ERROR, oss); exit(-1); @@ -275,7 +275,7 @@ error_attributes: error_pipes: oss.str(""); - oss << "Can not create driver pipes, " << strerror(errno); + oss << "Cannot create driver pipes, " << strerror(errno); NebulaLog::log("MAD", Log::ERROR, oss); return -1; } diff --git a/src/nebula/oned.cc b/src/nebula/oned.cc index 3076c9f4fe..cfe7968607 100644 --- a/src/nebula/oned.cc +++ b/src/nebula/oned.cc @@ -127,7 +127,7 @@ int main(int argc, char **argv) if( fd == -1) { - cerr<< "Error: Can not start oned, opening lock file " << lockfile + cerr<< "Error: Cannot start oned, opening lock file " << lockfile << endl; exit(-1); @@ -186,7 +186,7 @@ int main(int argc, char **argv) return 0; error_chdir: - cerr << "Error: can not change to dir " << wd << "\n"; + cerr << "Error: cannot change to dir " << wd << "\n"; unlink(lockfile.c_str()); exit(-1); diff --git a/src/oca/java/test/oned.conf b/src/oca/java/test/oned.conf index de3fdf51df..7e88254166 100644 --- a/src/oca/java/test/oned.conf +++ b/src/oca/java/test/oned.conf @@ -6,7 +6,7 @@ # Daemon configuration attributes #------------------------------------------------------------------------------- # MANAGER_TIMER: Time in seconds the core uses to evaluate periodical functions. -# HOST_MONITORING_INTERVAL and VM_POLLING_INTERVAL can not have smaller values +# HOST_MONITORING_INTERVAL and VM_POLLING_INTERVAL cannot have smaller values # than MANAGER_TIMER. # # HOST_MONITORING_INTERVAL: Time in seconds between host monitorization. diff --git a/src/oca/ruby/OpenNebula/Group.rb b/src/oca/ruby/OpenNebula/Group.rb index 74d56ddbf3..3fa5a9a41c 100644 --- a/src/oca/ruby/OpenNebula/Group.rb +++ b/src/oca/ruby/OpenNebula/Group.rb @@ -69,7 +69,7 @@ module OpenNebula # Creates ACLs for the group. The ACL rules are described in a file def create_acls(filename = GROUP_DEFAULT) if !File.readable?(filename) - return -1, "Can not read deafult ACL file for group" + return -1, "Cannot read deafult ACL file for group" end msg = String.new diff --git a/src/onedb/test/oned_mysql.conf b/src/onedb/test/oned_mysql.conf index 164abeaf5d..7275333b2c 100644 --- a/src/onedb/test/oned_mysql.conf +++ b/src/onedb/test/oned_mysql.conf @@ -6,7 +6,7 @@ # Daemon configuration attributes #------------------------------------------------------------------------------- # MANAGER_TIMER: Time in seconds the core uses to evaluate periodical functions. -# HOST_MONITORING_INTERVAL and VM_POLLING_INTERVAL can not have smaller values +# HOST_MONITORING_INTERVAL and VM_POLLING_INTERVAL cannot have smaller values # than MANAGER_TIMER. # # HOST_MONITORING_INTERVAL: Time in seconds between host monitorization. @@ -390,7 +390,7 @@ HM_MAD = [ #-------------------------------- ebtables Hook--------------------------------- # You can use these two hooks to isolate networks at the ethernet level so the -# traffic generated in different virtual networks can not be seen in others. +# traffic generated in different virtual networks cannot be seen in others. # # All the network configuration will be done in the cluster nodes, these are the # additional requisites: diff --git a/src/onedb/test/oned_sqlite.conf b/src/onedb/test/oned_sqlite.conf index e8a6aca4f9..09f4189ba0 100644 --- a/src/onedb/test/oned_sqlite.conf +++ b/src/onedb/test/oned_sqlite.conf @@ -6,7 +6,7 @@ # Daemon configuration attributes #------------------------------------------------------------------------------- # MANAGER_TIMER: Time in seconds the core uses to evaluate periodical functions. -# HOST_MONITORING_INTERVAL and VM_POLLING_INTERVAL can not have smaller values +# HOST_MONITORING_INTERVAL and VM_POLLING_INTERVAL cannot have smaller values # than MANAGER_TIMER. # # HOST_MONITORING_INTERVAL: Time in seconds between host monitorization. @@ -390,7 +390,7 @@ HM_MAD = [ #-------------------------------- ebtables Hook--------------------------------- # You can use these two hooks to isolate networks at the ethernet level so the -# traffic generated in different virtual networks can not be seen in others. +# traffic generated in different virtual networks cannot be seen in others. # # All the network configuration will be done in the cluster nodes, these are the # additional requisites: diff --git a/src/ozones/Server/bin/ozones-server b/src/ozones/Server/bin/ozones-server index 9a637cafbb..720aad1742 100755 --- a/src/ozones/Server/bin/ozones-server +++ b/src/ozones/Server/bin/ozones-server @@ -54,7 +54,7 @@ setup() start() { if [ ! -f "$OZONES_SERVER" ]; then - echo "Can not find $OZONES_SERVER." + echo "Cannot find $OZONES_SERVER." exit 1 fi diff --git a/src/ozones/Server/models/OzonesServer.rb b/src/ozones/Server/models/OzonesServer.rb index 1b43ba887b..4b7a952af5 100644 --- a/src/ozones/Server/models/OzonesServer.rb +++ b/src/ozones/Server/models/OzonesServer.rb @@ -217,7 +217,7 @@ class OzonesServer < CloudServer vdc = OZones::OpenNebulaVdc.new(id) rc = vdc.destroy rescue => e - return [404, OZones::Error.new("Error: Can not delete vdc. " \ + return [404, OZones::Error.new("Error: Cannot delete vdc. " \ "Reason: #{e.message}").to_json] end @@ -237,7 +237,7 @@ class OzonesServer < CloudServer rc = zone.destroy else return [404, - OZones::Error.new("Error: Can not delete " \ + OZones::Error.new("Error: Cannot delete " \ "zone. Reason: zone #{id} not found").to_json] end diff --git a/src/pool/PoolObjectSQL.cc b/src/pool/PoolObjectSQL.cc index 2a1706b171..fc45b17dd1 100644 --- a/src/pool/PoolObjectSQL.cc +++ b/src/pool/PoolObjectSQL.cc @@ -172,7 +172,7 @@ int PoolObjectSQL::replace_template(const string& tmpl_str, string& error) if ( new_tmpl == 0 ) { - error = "Can not allocate a new template"; + error = "Cannot allocate a new template"; return -1; } diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 34a14a82e0..9d2099ea18 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -114,7 +114,7 @@ int RequestManager::setup_socket() { ostringstream oss; - oss << "Can not open server socket: " << strerror(errno); + oss << "Cannot open server socket: " << strerror(errno); NebulaLog::log("ReM",Log::ERROR,oss); return -1; @@ -126,7 +126,7 @@ int RequestManager::setup_socket() { ostringstream oss; - oss << "Can not set socket options: " << strerror(errno); + oss << "Cannot set socket options: " << strerror(errno); NebulaLog::log("ReM",Log::ERROR,oss); close(socket_fd); @@ -146,7 +146,7 @@ int RequestManager::setup_socket() { ostringstream oss; - oss << "Can not bind to port " << port << " : " << strerror(errno); + oss << "Cannot bind to port " << port << " : " << strerror(errno); NebulaLog::log("ReM",Log::ERROR,oss); close(socket_fd); diff --git a/src/rm/RequestManagerDelete.cc b/src/rm/RequestManagerDelete.cc index 9466768c30..34ec4d0393 100644 --- a/src/rm/RequestManagerDelete.cc +++ b/src/rm/RequestManagerDelete.cc @@ -91,7 +91,7 @@ void RequestManagerDelete::request_execute(xmlrpc_c::paramList const& paramList, if ( rc != 0 ) { failure_response(INTERNAL, - request_error("Can not delete "+object_name(auth_object),error_msg), + request_error("Cannot delete "+object_name(auth_object),error_msg), att); return; } @@ -163,7 +163,7 @@ int ImageDelete::drop(int oid, PoolObjectSQL * object, string& error_msg) if ( ds == 0 ) { - error_msg = "Datastore no longer exists can not remove image"; + error_msg = "Datastore no longer exists cannot remove image"; return -1; } @@ -199,7 +199,7 @@ int UserDelete::drop(int oid, PoolObjectSQL * object, string& error_msg) if (oid == 0) { - error_msg = "oneadmin can not be deleted."; + error_msg = "oneadmin cannot be deleted."; object->unlock(); return -1; diff --git a/src/rm/RequestManagerUpdateTemplate.cc b/src/rm/RequestManagerUpdateTemplate.cc index 07226eb0b6..1c8988ccbb 100644 --- a/src/rm/RequestManagerUpdateTemplate.cc +++ b/src/rm/RequestManagerUpdateTemplate.cc @@ -54,7 +54,7 @@ void RequestManagerUpdateTemplate::request_execute( if ( rc != 0 ) { failure_response(INTERNAL, - request_error("Can not update template",error_str), + request_error("Cannot update template",error_str), att); object->unlock(); diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 82c3f91640..59ef25b9ef 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -160,7 +160,7 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm, if ( rc != 0 ) { failure_response(INTERNAL, - request_error("Can not update virtual machine history",""), + request_error("Cannot update virtual machine history",""), att); return -1; @@ -442,7 +442,7 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis if ( iid_orig == -1 ) { failure_response(INTERNAL, - request_error("Can not used selected DISK", error_str), + request_error("Cannot use selected DISK", error_str), att); return; } diff --git a/src/sunstone/bin/sunstone-server b/src/sunstone/bin/sunstone-server index 155ff26260..171a8a6938 100755 --- a/src/sunstone/bin/sunstone-server +++ b/src/sunstone/bin/sunstone-server @@ -53,7 +53,7 @@ setup() start() { if [ ! -f "$SUNSTONE_SERVER" ]; then - echo "Can not find $SUNSTONE_SERVER." + echo "Cannot find $SUNSTONE_SERVER." exit 1 fi diff --git a/src/tm_mad/vmware/functions.sh b/src/tm_mad/vmware/functions.sh index d55effbd78..e66d89ee44 100644 --- a/src/tm_mad/vmware/functions.sh +++ b/src/tm_mad/vmware/functions.sh @@ -24,7 +24,7 @@ function fix_iso { if [ $? -eq 0 ]; then bname=`basename $dst_path` exec_and_log "ln -s $bname $dst_path/$bname.iso" \ - "Can not link ISO file." + "Cannot link ISO file." fi fi } diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index ba168ec86f..38fd4100f0 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -183,7 +183,7 @@ int VirtualMachine::select(SqlDB * db) return 0; error_previous_history: - ose << "Can not get previous history record (seq:" << history->seq + ose << "Cannot get previous history record (seq:" << history->seq << ") for VM id: " << oid; log("ONE", Log::ERROR, ose); @@ -380,7 +380,7 @@ int VirtualMachine::parse_context(string& error_str) if (str == 0) { - NebulaLog::log("ONE",Log::ERROR, "Can not marshall CONTEXT"); + NebulaLog::log("ONE",Log::ERROR, "Cannot marshall CONTEXT"); return -1; } @@ -955,15 +955,15 @@ int VirtualMachine::get_disk_images(string& error_str) return 0; error_max_os: - error_str = "VM can not use more than one OS image."; + error_str = "VM cannot use more than one OS image."; goto error_common; error_max_cd: - error_str = "VM can not use more than one CDROM image."; + error_str = "VM cannot use more than one CDROM image."; goto error_common; error_max_db: - error_str = "VM can not use more than 10 DATABLOCK images."; + error_str = "VM cannot use more than 10 DATABLOCK images."; goto error_common; error_common: diff --git a/src/vm/VirtualMachinePool.cc b/src/vm/VirtualMachinePool.cc index 6c5031389b..206d2b4cb4 100644 --- a/src/vm/VirtualMachinePool.cc +++ b/src/vm/VirtualMachinePool.cc @@ -170,7 +170,7 @@ VirtualMachinePool::VirtualMachinePool(SqlDB * db, { ostringstream oss; - oss << "Unkown VM_HOOK " << on << ". Hook not registered!"; + oss << "Unknown VM_HOOK " << on << ". Hook not registered!"; NebulaLog::log("VM",Log::WARNING,oss); } } diff --git a/src/vmm_mad/ec2/one_vmm_ec2.rb b/src/vmm_mad/ec2/one_vmm_ec2.rb index a4ce862b05..dbcd250245 100755 --- a/src/vmm_mad/ec2/one_vmm_ec2.rb +++ b/src/vmm_mad/ec2/one_vmm_ec2.rb @@ -185,7 +185,7 @@ class EC2Driver < VirtualMachineDriver return unless ec2_info if !ec2_value(ec2_info, 'AMI') - msg = "Can not find AMI in deployment file" + msg = "Cannot find AMI in deployment file" send_message(ACTION[:deploy], RESULT[:failure], id, msg) return end @@ -294,7 +294,7 @@ private if !local_dfile send_message(ACTION[:deploy],RESULT[:failure],id, - "Can not open deployment file #{local_dfile}") + "Cannot open deployment file #{local_dfile}") return end @@ -322,7 +322,7 @@ private ec2 = all_ec2_elements[0] else send_message(ACTION[:deploy],RESULT[:failure],id, - "Can not find EC2 element in deployment file "<< + "Cannot find EC2 element in deployment file "<< "#{local_dfile} or couldn't find any EC2 site matching "<< "one of the template.") return diff --git a/src/vmm_mad/exec/one_vmm_exec.rb b/src/vmm_mad/exec/one_vmm_exec.rb index 3570203cef..bd53cfe49e 100755 --- a/src/vmm_mad/exec/one_vmm_exec.rb +++ b/src/vmm_mad/exec/one_vmm_exec.rb @@ -259,7 +259,7 @@ class ExecDriver < VirtualMachineDriver if !local_dfile || File.zero?(local_dfile) send_message(ACTION[:deploy],RESULT[:failure],id, - "Can not open deployment file #{local_dfile}") + "Cannot open deployment file #{local_dfile}") return end diff --git a/src/vmm_mad/remotes/vmware/vmware_driver.rb b/src/vmm_mad/remotes/vmware/vmware_driver.rb index 570b7b0b81..c5be771f11 100644 --- a/src/vmm_mad/remotes/vmware/vmware_driver.rb +++ b/src/vmm_mad/remotes/vmware/vmware_driver.rb @@ -167,7 +167,7 @@ class VMwareDriver # Define the VM dfile = File.dirname(File.dirname(checkpoint)) + "/deployment.0" rescue => e - OpenNebula.log_error("Can not open checkpoint #{e.message}") + OpenNebula.log_error("Cannot open checkpoint #{e.message}") exit -1 end From 41d3bbe20027e9fc4fd1f7fe1e0386d320d405a1 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Wed, 7 Mar 2012 21:13:33 +0100 Subject: [PATCH 138/217] feature #1112: Implement clone, delete, ln, mv, mvds for tm_iscsi --- src/datastore_mad/remotes/iscsi/cp | 5 +- src/datastore_mad/remotes/iscsi/mkfs | 5 +- src/datastore_mad/remotes/iscsi/rm | 11 +--- src/datastore_mad/remotes/libfs.sh | 34 ------------ src/mad/sh/scripts_common.sh | 59 ++++++++++++++++++++ src/tm_mad/iscsi/clone | 68 +++++++++++++++++++++++ src/tm_mad/iscsi/delete | 59 ++++++++++++++++++++ src/tm_mad/iscsi/ln | 80 ++++++++++++++++++++++++++++ src/tm_mad/iscsi/mv | 74 +++++++++++++++++++++++++ src/tm_mad/iscsi/mvds | 50 +++++++++++++++++ 10 files changed, 398 insertions(+), 47 deletions(-) create mode 100755 src/tm_mad/iscsi/clone create mode 100755 src/tm_mad/iscsi/delete create mode 100755 src/tm_mad/iscsi/ln create mode 100755 src/tm_mad/iscsi/mv create mode 100755 src/tm_mad/iscsi/mvds diff --git a/src/datastore_mad/remotes/iscsi/cp b/src/datastore_mad/remotes/iscsi/cp index 5e4a797899..e7de096d11 100755 --- a/src/datastore_mad/remotes/iscsi/cp +++ b/src/datastore_mad/remotes/iscsi/cp @@ -79,8 +79,9 @@ let TID=ID+BASE_TID REGISTER_CMD=$(cat <&2 - exit 1 - fi + $SUDO $(tgtadm_target_delete "$TID") + $SUDO $LVREMOVE -f $VG_NAME/$LV_NAME EOF ) diff --git a/src/datastore_mad/remotes/libfs.sh b/src/datastore_mad/remotes/libfs.sh index 55d5aada37..76a91c6227 100644 --- a/src/datastore_mad/remotes/libfs.sh +++ b/src/datastore_mad/remotes/libfs.sh @@ -136,37 +136,3 @@ function check_restricted { echo 0 } - - -# ------------------------------------------------------------------------------ -# iSCSI functions -# ------------------------------------------------------------------------------ - -#------------------------------------------------------------------------------- -# Returns the command to create a new target -# @param $1 - ID of the image -# @param $2 - Target Host -# @param $3 - Device -# @return the command to create a new target -#------------------------------------------------------------------------------- - -function iscsi_target_new { - ID="$1" - IQN="$2" - - echo "$TGTADM --lld iscsi --op new --mode target --tid $ID "\ - "--targetname $IQN" -} - -function iscsi_logicalunit_new { - ID="$1" - DEV="$2" - - echo "$TGTADM --lld iscsi --op new --mode logicalunit --tid $ID "\ - "--lun 1 --backing-store $DEV" -} - -function iscsi_target_delete { - ID="$1" - echo "$TGTADM --lld iscsi --op delete --mode target --tid $ID" -} diff --git a/src/mad/sh/scripts_common.sh b/src/mad/sh/scripts_common.sh index 6b4ef552d9..1296f3c65a 100755 --- a/src/mad/sh/scripts_common.sh +++ b/src/mad/sh/scripts_common.sh @@ -23,6 +23,7 @@ DATE=date DD=dd DU=du GREP=grep +ISCSIADM=iscsiadm LVCREATE=lvcreate LVREMOVE=lvremove LVS=lvs @@ -244,3 +245,61 @@ EOF` exit $SSH_EXEC_RC fi } + + +# ------------------------------------------------------------------------------ +# iSCSI functions +# ------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------- +# Returns the command to create a new target +# @param $1 - ID of the image +# @param $2 - Target Host +# @param $3 - Device +# @return the command to create a new target +#------------------------------------------------------------------------------- + +function tgtadm_target_new { + ID="$1" + IQN="$2" + + echo "$TGTADM --lld iscsi --op new --mode target --tid $ID "\ + "--targetname $IQN;" +} + +function tgtadm_target_bind_all { + ID="$1" + echo "$TGTADM --lld iscsi --op bind --mode target --tid $ID -I ALL" +} + +function tgtadm_logicalunit_new { + ID="$1" + DEV="$2" + + echo "$TGTADM --lld iscsi --op new --mode logicalunit --tid $ID "\ + "--lun 1 --backing-store $DEV" +} + +function tgtadm_target_delete { + ID="$1" + echo "$TGTADM --lld iscsi --op delete --mode target --tid $ID" +} + +### + +function iscsiadm_discovery { + TARGET_HOST="$1" + echo "$ISCSIADM -m discovery -t st -p $TARGET_HOST" +} + +function iscsiadm_login { + IQN="$1" + TARGET_HOST="$2" + echo "$ISCSIADM -m node --targetname $IQN -p $TARGET_HOST --login" +} + +function iscsiadm_logout { + IQN="$1" + echo "$ISCSIADM -m node --targetname $IQN --logout" +} + diff --git a/src/tm_mad/iscsi/clone b/src/tm_mad/iscsi/clone new file mode 100755 index 0000000000..39edcbe028 --- /dev/null +++ b/src/tm_mad/iscsi/clone @@ -0,0 +1,68 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +# clone fe:SOURCE host:remote_system_ds/disk.i size +# - fe is the front-end hostname +# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk +# - host is the target host to deploy the VM +# - remote_system_ds is the path for the system datastore in the host + +SRC=$1 # iqn.2012-02.org.opennebula:o200.vg-one.lv-one-0 +DST=$2 # o202:/var/lib/one//datastores/0/0/disk.0 + +if [ -z "${ONE_LOCATION}" ]; then + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh +else + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh +fi + +. $TMCOMMON + +#------------------------------------------------------------------------------- +# Set dst path and dir +#------------------------------------------------------------------------------- + +TARGET=`arg_path $SRC` # o200.vg-one.lv-one-0 +DST_PATH=`arg_path $DST` # /var/lib/one/datastores/0/0/disk.0 +DST_HOST=`arg_host $DST` # o202 +DST_DIR=`dirname $DST_PATH` # /var/lib/one/datastores/0/0 + +BASE_IQN=`echo $SRC|$CUT -d: -f1` +TARGET=`echo $SRC|$CUT -d: -f2` +LV_NAME=`echo $TARGET|$AWK -F. '{print $(NF)}'` +VG_NAME=`echo $TARGET|$AWK -F. '{print $(NF-1)}'` +DEV="/dev/$VG_NAME/$LV_NAME" + +exit +ssh_make_path $DST_HOST $DST_DIR + +#------------------------------------------------------------------------------- +# Copy files to the remote host +#------------------------------------------------------------------------------- +case $SRC in +http://*) + log "Downloading $SRC" + RMT_CMD="$WGET -O $DST_PATH $SRC" + ssh_exec_and_log "$DST_HOST" "$RMT_CMD" "Error downloading $SRC" + ;; + +*) + log "Cloning $SRC in $DST_PATH" + exec_and_log "$SCP $SRC $DST" "Error copying $SRC to $DST" + ;; +esac diff --git a/src/tm_mad/iscsi/delete b/src/tm_mad/iscsi/delete new file mode 100755 index 0000000000..c30639d900 --- /dev/null +++ b/src/tm_mad/iscsi/delete @@ -0,0 +1,59 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +# DELETE +# - host is the target host to deploy the VM +# - remote_system_ds is the path for the system datastore in the host + +DST=$1 # o202:/var/lib/one//datastores/0/0/disk.0 + +if [ -z "${ONE_LOCATION}" ]; then + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh +else + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh +fi + +. $TMCOMMON + +#------------------------------------------------------------------------------- +# Return if deleting a disk, we will delete them when removing the +# remote_system_ds directory for the VM (remotely) +#------------------------------------------------------------------------------- +DST_PATH=`arg_path $DST` +DST_HOST=`arg_host $DST` + +if [ `is_disk $DST_PATH` -eq 1 ]; then + # Disk + LOGOUT_CMD=$(cat < +# +# - hostX is the target host to deploy the VM +# - system_ds is the path for the system datastore in the host + +SRC=$1 +DST=$2 + +if [ -z "${ONE_LOCATION}" ]; then + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh +else + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh +fi + +. $TMCOMMON + +# {:path=> +# "/var/lib/one/remotes/tm/iscsi/mv o202:/var/lib/one//datastores/0/3/disk.0 rama:/var/lib/one/datastores/0/3/disk.0", +# :result=>"SUCCESS", +# :info=>"-"} + +# {:path=> +# "/var/lib/one/remotes/tm/shared/mv o202:/var/lib/one//datastores/0/3 rama:/var/lib/one/datastores/0/3", +# :result=>"SUCCESS", +# :info=>"-"} + +#------------------------------------------------------------------------------- +# Return if moving a disk, we will move them when moving the whole system_ds +# directory for the VM +#------------------------------------------------------------------------------- +SRC_PATH=`arg_path $SRC` +SRC_HOST=`arg_host $SRC` + +if [ `is_disk $SRC_PATH` -eq 0 ]; then + log "Removing directory" + ssh_exec_and_log "$SRC_HOST" "rm -rf $SRC_PATH" + + exit 0 +fi + +if [ "$SRC" == "$DST" ]; then + log "Not moving $SRC to $DST, they are the same path" + exit 0 +fi + +log "Logging out $IQN" + +LOGOUT_CMD=$(cat < Date: Thu, 8 Mar 2012 19:17:30 +0100 Subject: [PATCH 139/217] Feature #1112: First version of migrator 3.3.0 to 3.3.80 --- install.sh | 1 + src/onedb/3.3.0_to_3.3.80.rb | 277 +++++++++++++++++++++++++++++++++++ 2 files changed, 278 insertions(+) create mode 100644 src/onedb/3.3.0_to_3.3.80.rb diff --git a/install.sh b/install.sh index 52a312ab3d..b7d3b9f60f 100755 --- a/install.sh +++ b/install.sh @@ -839,6 +839,7 @@ ONEDB_MIGRATOR_FILES="src/onedb/2.0_to_2.9.80.rb \ src/onedb/3.1.80_to_3.2.0.rb \ src/onedb/3.2.0_to_3.2.1.rb \ src/onedb/3.2.1_to_3.3.0.rb \ + src/onedb/3.3.0_to_3.3.80.rb \ src/onedb/onedb.rb \ src/onedb/onedb_backend.rb" diff --git a/src/onedb/3.3.0_to_3.3.80.rb b/src/onedb/3.3.0_to_3.3.80.rb new file mode 100644 index 0000000000..7194edc1e5 --- /dev/null +++ b/src/onedb/3.3.0_to_3.3.80.rb @@ -0,0 +1,277 @@ +# -------------------------------------------------------------------------- * +# 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. * +# -------------------------------------------------------------------------- * + +require "rexml/document" +include REXML + +module Migrator + def db_version + "3.3.80" + end + + def one_version + "OpenNebula 3.3.80" + end + + def up + one_location = ENV["ONE_LOCATION"] + + if !one_location + var_location = "/var/lib/one" + else + var_location = one_location + "/var" + end + + ######################################################################## + # Get oneadmin user and group names + ######################################################################## + + oneadmin_uname = nil + + @db.fetch("SELECT name FROM user_pool WHERE oid=0") do |row| + oneadmin_uname = row[:name] + end + + if oneadmin_uname == nil + puts "Error trying to read oneadmin's user name ('SELECT name FROM user_pool WHERE oid=0')" + return false + end + + oneadmin_gname = nil + + @db.fetch("SELECT name FROM group_pool WHERE oid=0") do |row| + oneadmin_gname = row[:name] + end + + if oneadmin_gname == nil + puts "Error trying to read oneadmin's group name ('SELECT name FROM group_pool WHERE oid=0')" + return false + end + + ######################################################################## + # Create the cluster and datastore tables + ######################################################################## + + # New table for Clusters + @db.run "CREATE TABLE cluster_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name));" + + # New table for Datastores + @db.run "CREATE TABLE datastore_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name));" + + # Insert system datastore + + xml = + "" << + " 0" << + " 0" << + " 0" << + " #{oneadmin_uname}" << + " #{oneadmin_gname}" << + " system" << + " " << + " 1" << + " 1" << + " 0" << + " 0" << + " 0" << + " 0" << + " 0" << + " 0" << + " 0" << + " " << + " fs" << + " shared" << + " #{var_location}/datastores/0" << + " -1" << + " none" << + " " << + " " << + "" + + @db[:datastore_pool].insert( + :oid => 0, + :name => 'system', + :body => xml, + :uid => 0, + :gid => 0, + :owner_u => 1, + :group_u => 0, + :other_u => 0) + + # Last oid for cluster_pool and datastore_pool + + @db[:pool_control].insert( + :tablename => 'cluster_pool', + :last_oid => 99) + + @db[:pool_control].insert( + :tablename => 'datastore_pool', + :last_oid => 99) + + ######################################################################## + # Add each Host to Cluster -1 (none) + ######################################################################## + + @db.run "ALTER TABLE host_pool RENAME TO old_host_pool;" + @db.run "CREATE TABLE host_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, state INTEGER, last_mon_time INTEGER, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name));" + + @db.fetch("SELECT * FROM old_host_pool") do |row| + doc = Document.new(row[:body]) + + # Delete TM_MAD elem + doc.root.delete_element("TM_MAD") + + # Add Cluster elements + doc.root.add_element("CLUSTER_ID").text = "-1" + doc.root.add_element("CLUSTER").text = "none" + + @db[:host_pool].insert( + :oid => row[:oid], + :name => row[:name], + :body => doc.root.to_s, + :state => row[:state], + :last_mon_time => row[:last_mon_time], + :uid => row[:uid], + :gid => row[:gid], + :owner_u => row[:owner_u], + :group_u => row[:group_u], + :other_u => row[:other_u]) + end + + @db.run "DROP TABLE old_host_pool;" + + ######################################################################## + # Add each VNet to Cluster -1 (none) + ######################################################################## + + @db.run "ALTER TABLE network_pool RENAME TO old_network_pool;" + @db.run "CREATE TABLE network_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name,uid));" + + @db.fetch("SELECT * FROM old_network_pool") do |row| + doc = Document.new(row[:body]) + + # Add Cluster elements + doc.root.add_element("CLUSTER_ID").text = "-1" + doc.root.add_element("CLUSTER").text = "none" + + @db[:network_pool].insert( + :oid => row[:oid], + :name => row[:name], + :body => doc.root.to_s, + :uid => row[:uid], + :gid => row[:gid], + :owner_u => row[:owner_u], + :group_u => row[:group_u], + :other_u => row[:other_u]) + end + + @db.run "DROP TABLE old_network_pool;" + + ######################################################################## + # Add each Image to Datastore 1 (default) + ######################################################################## + + images_element = "" + + @db.run "ALTER TABLE image_pool RENAME TO old_image_pool;" + @db.run "CREATE TABLE image_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name,uid) );" + + @db.fetch("SELECT * FROM old_image_pool") do |row| + doc = Document.new(row[:body]) + + # Add Cluster elements + doc.root.add_element("DATASTORE_ID").text = "1" + doc.root.add_element("DATASTORE").text = "default" + + images_element << "#{row[:oid]}" + + # Update SOURCE + doc.root.each_element("SOURCE") { |e| + previous_source = e.text + hash = previous_source.split('/')[-1] + + if ( hash.length == 32 && hash =~ /^[0-9A-F]+$/i ) + e.text = "#{var_location}/datastores/1/#{hash}" + + # TODO: create link, or mv image file? + `ln -s #{previous_source} #{e.text}` + # `mv #{e.text} #{previous_source}` + end + } + + @db[:image_pool].insert( + :oid => row[:oid], + :name => row[:name], + :body => doc.root.to_s, + :uid => row[:uid], + :gid => row[:gid], + :owner_u => row[:owner_u], + :group_u => row[:group_u], + :other_u => row[:other_u]) + end + + @db.run "DROP TABLE old_image_pool;" + + images_element << "" + + # Insert default datastore + + xml = + "" << + " 1" << + " 0" << + " 0" << + " #{oneadmin_uname}" << + " #{oneadmin_gname}" << + " default" << + " " << + " 1" << + " 1" << + " 0" << + " 0" << + " 0" << + " 0" << + " 0" << + " 0" << + " 0" << + " " << + " fs" << # TODO + " shared" << # TODO + " #{var_location}/datastores/1" << + " -1" << + " none" << + images_element << + " " << + "" + + @db[:datastore_pool].insert( + :oid => 1, + :name => 'default', + :body => xml, + :uid => 0, + :gid => 0, + :owner_u => 1, + :group_u => 0, + :other_u => 0) + + return true + end +end From ff1dd894ba9436b7d64c26650e5880229e2eeac5 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 8 Mar 2012 21:33:07 +0100 Subject: [PATCH 140/217] Feature #1112: Add Clusters to Sunstone --- install.sh | 2 + src/sunstone/etc/sunstone-plugins.yaml | 5 + src/sunstone/models/OpenNebulaJSON.rb | 1 + .../models/OpenNebulaJSON/ClusterJSON.rb | 42 +- .../models/OpenNebulaJSON/HostJSON.rb | 2 +- .../models/OpenNebulaJSON/PoolJSON.rb | 1 + src/sunstone/models/SunstoneServer.rb | 3 + src/sunstone/public/js/opennebula.js | 46 +- .../public/js/plugins/clusters-tab.js | 511 ++++++++++++++++++ src/sunstone/public/js/plugins/hosts-tab.js | 81 ++- src/sunstone/public/js/plugins/vnets-tab.js | 37 +- 11 files changed, 696 insertions(+), 35 deletions(-) create mode 100644 src/sunstone/public/js/plugins/clusters-tab.js diff --git a/install.sh b/install.sh index 52a312ab3d..3141640429 100755 --- a/install.sh +++ b/install.sh @@ -1116,6 +1116,7 @@ SUNSTONE_MODELS_JSON_FILES="src/sunstone/models/OpenNebulaJSON/HostJSON.rb \ src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb \ src/sunstone/models/OpenNebulaJSON/TemplateJSON.rb \ src/sunstone/models/OpenNebulaJSON/AclJSON.rb \ + src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb \ src/sunstone/models/OpenNebulaJSON/VirtualNetworkJSON.rb" SUNSTONE_TEMPLATE_FILES="src/sunstone/templates/login.html \ @@ -1134,6 +1135,7 @@ SUNSTONE_PUBLIC_JS_PLUGINS_FILES="\ src/sunstone/public/js/plugins/dashboard-tab.js \ src/sunstone/public/js/plugins/dashboard-users-tab.js \ src/sunstone/public/js/plugins/hosts-tab.js \ + src/sunstone/public/js/plugins/clusters-tab.js \ src/sunstone/public/js/plugins/groups-tab.js \ src/sunstone/public/js/plugins/images-tab.js \ src/sunstone/public/js/plugins/templates-tab.js \ diff --git a/src/sunstone/etc/sunstone-plugins.yaml b/src/sunstone/etc/sunstone-plugins.yaml index ce33cfff64..d08072929d 100644 --- a/src/sunstone/etc/sunstone-plugins.yaml +++ b/src/sunstone/etc/sunstone-plugins.yaml @@ -14,6 +14,11 @@ :user: :group: oneadmin: true +- plugins/clusters-tab.js: + :ALL: false + :user: + :group: + oneadmin: true - plugins/vms-tab.js: :ALL: true :user: diff --git a/src/sunstone/models/OpenNebulaJSON.rb b/src/sunstone/models/OpenNebulaJSON.rb index ad5c493785..60b0ab116c 100644 --- a/src/sunstone/models/OpenNebulaJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON.rb @@ -19,6 +19,7 @@ include OpenNebula require 'OpenNebulaJSON/GroupJSON' require 'OpenNebulaJSON/HostJSON' +require 'OpenNebulaJSON/ClusterJSON' require 'OpenNebulaJSON/ImageJSON' require 'OpenNebulaJSON/TemplateJSON' require 'OpenNebulaJSON/JSONUtils' diff --git a/src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb b/src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb index 806855c428..b834218a38 100644 --- a/src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb @@ -22,12 +22,10 @@ module OpenNebulaJSON def create(template_json) cluster_hash = parse_json(template_json, 'cluster') - if OpenNebula.is_error?(cluster_hash) return cluster_hash end - self.allocate(cluster_hash['name']) end @@ -37,9 +35,43 @@ module OpenNebulaJSON return action_hash end - error_msg = "#{action_hash['perform']} action not " << - " available for this resource" - OpenNebula::Error.new(error_msg) + rc = case action_hash['perform'] + when "addhost" then self.addhost(action_hash['params']) + when "delhost" then self.delhost(action_hash['params']) + when "adddatastore" then self.adddatastore(action_hash['params']) + when "deldatastore" then self.deldatastore(action_hash['params']) + when "addvnet" then self.addvnet(action_hash['params']) + when "delvnet" then self.delvnet(action_hash['params']) + + else + error_msg = "#{action_hash['perform']} action not " << + " available for this resource" + OpenNebula::Error.new(error_msg) + end + end + + def addhost(params=Hash.new) + super(params['host_id'].to_i) + end + + def delhost(params=Hash.new) + super(params['host_id'].to_i) + end + + def adddatastore(params=Hash.new) + super(params['ds_id'].to_i) + end + + def deldatastore(params=Hash.new) + super(params['ds_id'].to_i) + end + + def addvnet(params=Hash.new) + super(params['vnet_id'].to_i) + end + + def delvnet(params=Hash.new) + super(params['vnet_id'].to_i) end end end diff --git a/src/sunstone/models/OpenNebulaJSON/HostJSON.rb b/src/sunstone/models/OpenNebulaJSON/HostJSON.rb index b0dbac71b8..3ca11ecb0b 100644 --- a/src/sunstone/models/OpenNebulaJSON/HostJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/HostJSON.rb @@ -30,7 +30,7 @@ module OpenNebulaJSON host_hash['im_mad'], host_hash['vm_mad'], host_hash['vnm_mad'], - host_hash['tm_mad']) + host_hash['cluster_id'].to_i) end def delete diff --git a/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb b/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb index fbca6fe2a4..fe8e67dcfd 100644 --- a/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb @@ -25,4 +25,5 @@ module OpenNebulaJSON class GroupPoolJSON < OpenNebula::GroupPool; include JSONUtils; end class UserPoolJSON < OpenNebula::UserPool; include JSONUtils; end class AclPoolJSON < OpenNebula::AclPool; include JSONUtils; end + class ClusterPoolJSON < OpenNebula::ClusterPool; include JSONUtils; end end diff --git a/src/sunstone/models/SunstoneServer.rb b/src/sunstone/models/SunstoneServer.rb index 6696d7f436..7a64255bb6 100644 --- a/src/sunstone/models/SunstoneServer.rb +++ b/src/sunstone/models/SunstoneServer.rb @@ -48,6 +48,7 @@ class SunstoneServer < CloudServer pool = case kind when "group" then GroupPoolJSON.new(@client) + when "cluster" then ClusterPoolJSON.new(@client) when "host" then HostPoolJSON.new(@client) when "image" then ImagePoolJSON.new(@client, user_flag) when "vmtemplate" then TemplatePoolJSON.new(@client, user_flag) @@ -100,6 +101,7 @@ class SunstoneServer < CloudServer def create_resource(kind, template) resource = case kind when "group" then GroupJSON.new(Group.build_xml, @client) + when "cluster" then ClusterJSON.new(Group.build_xml, @client) when "host" then HostJSON.new(Host.build_xml, @client) when "image" then ImageJSON.new(Image.build_xml, @client) when "vmtemplate" then TemplateJSON.new(Template.build_xml, @client) @@ -275,6 +277,7 @@ class SunstoneServer < CloudServer def retrieve_resource(kind, id) resource = case kind when "group" then GroupJSON.new_with_id(id, @client) + when "cluster" then ClusterJSON.new_with_id(id, @client) when "host" then HostJSON.new_with_id(id, @client) when "image" then ImageJSON.new_with_id(id, @client) when "vmtemplate" then TemplateJSON.new_with_id(id, @client) diff --git a/src/sunstone/public/js/opennebula.js b/src/sunstone/public/js/opennebula.js index 9552c3563e..560170b6ea 100644 --- a/src/sunstone/public/js/opennebula.js +++ b/src/sunstone/public/js/opennebula.js @@ -852,5 +852,49 @@ var OpenNebula = { "list" : function(params){ OpenNebula.Action.list(params,OpenNebula.Acl.resource); } - } + }, + + "Cluster" : { + "resource" : "CLUSTER", + + "create" : function(params){ + OpenNebula.Action.create(params,OpenNebula.Cluster.resource); + }, + "delete" : function(params){ + OpenNebula.Action.delete(params,OpenNebula.Cluster.resource); + }, + "list" : function(params){ + OpenNebula.Action.list(params,OpenNebula.Cluster.resource); + }, + "addhost" : function(params){ + var action_obj = { "host_id": params.data.extra_param }; + OpenNebula.Action.simple_action(params,OpenNebula.Cluster.resource, + "addhost",action_obj); + }, + "delhost" : function(params){ + var action_obj = { "host_id": params.data.extra_param }; + OpenNebula.Action.simple_action(params,OpenNebula.Cluster.resource, + "delhost",action_obj); + }, + "adddatastore" : function(params){ + var action_obj = { "ds_id": params.data.extra_param }; + OpenNebula.Action.simple_action(params,OpenNebula.Cluster.resource, + "adddatastore",action_obj); + }, + "deldatastore" : function(params){ + var action_obj = { "ds_id": params.data.extra_param }; + OpenNebula.Action.simple_action(params,OpenNebula.Cluster.resource, + "deldatastore",action_obj); + }, + "addvnet" : function(params){ + var action_obj = { "vnet_id": params.data.extra_param }; + OpenNebula.Action.simple_action(params,OpenNebula.Cluster.resource, + "addvnet",action_obj); + }, + "delvnet" : function(params){ + var action_obj = { "vnet_id": params.data.extra_param }; + OpenNebula.Action.simple_action(params,OpenNebula.Cluster.resource, + "delvnet",action_obj); + }, + }, } diff --git a/src/sunstone/public/js/plugins/clusters-tab.js b/src/sunstone/public/js/plugins/clusters-tab.js new file mode 100644 index 0000000000..3d4a2079ca --- /dev/null +++ b/src/sunstone/public/js/plugins/clusters-tab.js @@ -0,0 +1,511 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +/*Cluster tab plugin*/ + + +var clusters_tab_content = +'
\ +
\ +
\ +
\ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
' + tr("All") + '' + tr("id") + '' + tr("Name") + '
\ +'; + +var create_cluster_tmpl = +'
\ +
\ + \ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
'; + +var clusters_select=""; +var dataTable_clusters; +var $create_cluster_dialog; + +//Setup actions +var cluster_actions = { + + "Cluster.create" : { + type: "create", + call : OpenNebula.Cluster.create, + callback : addClusterElement, + error : onError, + notify: true + }, + + "Cluster.create_dialog" : { + type: "custom", + call: popUpCreateClusterDialog + }, + + "Cluster.list" : { + type: "list", + call: OpenNebula.Cluster.list, + callback: updateClustersView, + error: onError + }, + + "Cluster.show" : { + type: "single", + call: OpenNebula.Cluster.show, + callback: updateClusterElement, + error: onError + }, + +/* + + "Cluster.showinfo" : { + type: "single", + call: OpenNebula.Cluster.show, + callback: updateClusterInfo, + error: onError + }, +*/ + + "Cluster.refresh" : { + type: "custom", + call: function(){ + waitingNodes(dataTable_clusters); + Sunstone.runAction("Cluster.list"); + }, + error: onError + }, + + "Cluster.autorefresh" : { + type: "custom", + call : function() { + OpenNebula.Cluster.list({timeout: true, success: updateClustersView,error: onError}); + } + }, + + "Cluster.addhost" : { + type: "single", + call : OpenNebula.Cluster.addhost, + callback : function (req) { + Sunstone.runAction("Host.show",req.request.data[0][1].host_id); + }, + error : onError, + }, + + "Cluster.delhost" : { + type: "single", + call : OpenNebula.Cluster.delhost, + callback : function (req) { + //Sunstone.runAction("Cluster.show",req.request.data[0]); + }, + error : onError, + notify: true + }, + + "Cluster.adddatastore" : { + type: "single", + call : OpenNebula.Cluster.addhost, + callback : function (req) { + Sunstone.runAction("Datastore.show",req.request.data[0][1].ds_id); + //Sunstone.runAction("Cluster.show",req.request.data[0]); + }, + error : onError, + }, + + "Cluster.deldatastore" : { + type: "single", + call : OpenNebula.Cluster.addhost, + callback : function (req) { + //Sunstone.runAction("Cluster.show",req.request.data[0]); + }, + error : onError, + }, + + "Cluster.addvnet" : { + type: "single", + call : OpenNebula.Cluster.addvnet, + callback : function (req) { + Sunstone.runAction("Network.show",req.request.data[0][1].vnet_id); + }, + error : onError, + }, + + "Cluster.delvnet" : { + type: "single", + call : OpenNebula.Cluster.delvnet, + callback : function (req) { + //Sunstone.runAction("Cluster.show",req.request.data[0]); + }, + error : onError, + notify: true + }, + + "Cluster.delete" : { + type: "multiple", + call : OpenNebula.Cluster.delete, + callback : deleteClusterElement, + elements: clusterElements, + error : onError, + notify:true + }, +}; + +var cluster_buttons = { + "Cluster.refresh" : { + type: "image", + text: tr("Refresh list"), + img: "images/Refresh-icon.png" + }, + "Cluster.create_dialog" : { + type: "create_dialog", + text: tr("+ New") + }, + "Cluster.delete" : { + type: "confirm", + text: tr("Delete") + } +}; + +/* +var host_info_panel = { + "host_info_tab" : { + title: tr("Host information"), + content:"" + }, + + "host_template_tab" : { + title: tr("Host template"), + content: "" + }, + "host_monitoring_tab": { + title: tr("Monitoring information"), + content: "" + } +}; +*/ + + +var clusters_tab = { + title: tr("Clusters"), + content: clusters_tab_content, + buttons: cluster_buttons +} + +Sunstone.addActions(cluster_actions); +Sunstone.addMainTab('clusters_tab',clusters_tab); +//Sunstone.addInfoPanel("host_info_panel",host_info_panel); + + +function clusterElements(){ + return getSelectedNodes(dataTable_clusters); +} + +function clusterElementArray(element_json){ + + var element = element_json.CLUSTER; + + return [ + '', + element.ID, + element.NAME, + ]; +} + +/* +//Listen to clicks on the tds of the tables and shows the info dialogs. +function hostInfoListener(){ + $('#tbodyhosts tr',dataTable_hosts).live("click",function(e){ + //do nothing if we are clicking a checkbox! + if ($(e.target).is('input')) {return true;} + + var aData = dataTable_hosts.fnGetData(this); + var id = $(aData[0]).val(); + if (!id) return true; + + popDialogLoading(); + Sunstone.runAction("Host.showinfo",id); + return false; + }); +} +*/ + +//updates the host select by refreshing the options in it +function updateClusterSelect(){ + clusters_select = ''; + clusters_select += makeSelectOptions(dataTable_clusters, + 1,//id_col + 2,//name_col + [],//status_cols + [],//bad_st + true + ); +} + +//callback for an action affecting a host element +function updateClusterElement(request, element_json){ + var id = element_json.CLUSTER.ID; + var element = clusterElementArray(element_json); + updateSingleElement(element,dataTable_clusters,'#cluster_'+id); + updateClusterSelect(); +} + +//callback for actions deleting a host element +function deleteClusterElement(req){ + deleteElement(dataTable_clusters,'#cluster_'+req.request.data); + updateClusterSelect(); +} + +//call back for actions creating a host element +function addClusterElement(request,element_json){ + var id = element_json.CLUSTER.ID; + var element = clusterElementArray(element_json); + addElement(element,dataTable_clusters); + updateClusterSelect(); +} + +//callback to update the list of hosts. +function updateClustersView (request,list){ + var list_array = []; + + $.each(list,function(){ + //Grab table data from the host_list + list_array.push(clusterElementArray(this)); + }); + + updateView(list_array,dataTable_clusters); + updateClusterSelect(); + //dependency with the dashboard plugin + updateDashboard("clusters",list); +} + +/* +//Updates the host info panel tab's content and pops it up +function updateHostInfo(request,host){ + var host_info = host.HOST; + + //Information tab + var info_tab = { + title : tr("Host information"), + content : + '\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
' + tr("Host information") + ' - '+host_info.NAME+'
' + tr("id") + ''+host_info.ID+'
' + tr("Name") + ''+host_info.NAME+'
' + tr("Cluster") + ''+host_info.CLUSTER+'
' + tr("State") + ''+tr(OpenNebula.Helper.resource_state("host",host_info.STATE))+'
' + tr("IM MAD") + ''+host_info.IM_MAD+'
' + tr("VM MAD") + ''+host_info.VM_MAD+'
'+ tr("VN MAD") +''+host_info.VN_MAD+'
'+ tr("TM MAD") +''+host_info.TM_MAD+'
\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
' + tr("Host shares") + '
' + tr("Max Mem") + ''+humanize_size(host_info.HOST_SHARE.MAX_MEM)+'
' + tr("Used Mem (real)") + ''+humanize_size(host_info.HOST_SHARE.USED_MEM)+'
' + tr("Used Mem (allocated)") + ''+humanize_size(host_info.HOST_SHARE.MAX_USAGE)+'
' + tr("Used CPU (real)") + ''+host_info.HOST_SHARE.USED_CPU+'
' + tr("Used CPU (allocated)") + ''+host_info.HOST_SHARE.CPU_USAGE+'
' + tr("Running VMs") + ''+host_info.HOST_SHARE.RUNNING_VMS+'
' + } + + //Template tab + var template_tab = { + title : tr("Host template"), + content : + '\ + '+ + prettyPrintJSON(host_info.TEMPLATE)+ + '
' + tr("Host template") + '
' + } + + var monitor_tab = { + title: tr("Monitoring information"), + content : generateMonitoringDivs(host_graphs,"host_monitor_") + } + + //Sunstone.updateInfoPanelTab(info_panel_name,tab_name, new tab object); + Sunstone.updateInfoPanelTab("host_info_panel","host_info_tab",info_tab); + Sunstone.updateInfoPanelTab("host_info_panel","host_template_tab",template_tab); + Sunstone.updateInfoPanelTab("host_info_panel","host_monitoring_tab",monitor_tab); + + Sunstone.popUpInfoPanel("host_info_panel"); + //pop up panel while we retrieve the graphs + for (var i=0; i'); + $create_cluster_dialog = $('div#create_cluster_dialog'); + var dialog = $create_cluster_dialog; + + dialog.html(create_cluster_tmpl); + dialog.dialog({ + autoOpen: false, + modal: true, + width: 500 + }); + + $('button',dialog).button(); + + //Handle the form submission + $('#create_cluster_form',dialog).submit(function(){ + if (!($('#name',this).val().length)){ + notifyError(tr("Cluster name missing!")); + return false; + } + + var cluster_json = { + "cluster": { + "name": $('#name',this).val(), + } + }; + + //Create the OpenNebula.Host. + //If it's successfull we refresh the list. + Sunstone.runAction("Cluster.create",cluster_json); + $create_cluster_dialog.dialog('close'); + return false; + }); +} + +//Open creation dialogs +function popUpCreateClusterDialog(){ + $create_cluster_dialog.dialog('open'); + return false; +} + +//Prepares the autorefresh for hosts +function setClusterAutorefresh() { + setInterval(function(){ + var checked = $('input.check_item:checked',dataTable_clusters); + var filter = $("#datatable_clusters_filter input",dataTable_clusters.parents('#datatable_clusters_wrapper')).attr('value'); + if (!checked.length && !filter.length){ + Sunstone.runAction("Cluster.autorefresh"); + } + },INTERVAL+someTime()); +} + + +function clusters_sel() { + return clusters_select; +} + +//This is executed after the sunstone.js ready() is run. +//Here we can basicly init the host datatable, preload it +//and add specific listeners +$(document).ready(function(){ + + //prepare host datatable + dataTable_clusters = $("#datatable_clusters",main_tabs_context).dataTable({ + "bJQueryUI": true, + "bSortClasses": false, + "bAutoWidth":false, + "sPaginationType": "full_numbers", + "aoColumnDefs": [ + { "bSortable": false, "aTargets": ["check"] }, + { "sWidth": "60px", "aTargets": [0] }, + { "sWidth": "35px", "aTargets": [1] }, + ], + "oLanguage": (datatable_lang != "") ? + { + sUrl: "locale/"+lang+"/"+datatable_lang + } : "" + }); + + //preload it + dataTable_clusters.fnClearTable(); + addElement([ + spinner, + '','',''],dataTable_clusters); + Sunstone.runAction("Cluster.list"); + + setupCreateClusterDialog(); + + setClusterAutorefresh(); + + initCheckAllBoxes(dataTable_clusters); + tableCheckboxesListener(dataTable_clusters); +// clusterInfoListener(); +}); diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index d076b59573..2d87e1585f 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -43,6 +43,7 @@ var hosts_tab_content = ' + tr("All") + '\ ' + tr("id") + '\ ' + tr("Name") + '\ + ' + tr("Cluster") + '\ ' + tr("Running VMs") + '\ ' + tr("CPU Use") + '\ ' + tr("Memory use") + '\ @@ -93,19 +94,15 @@ var create_host_tmpl = \ \ \ -
\ - \ - \ \
\ \
\
\ -
\ +
\
\
\
\ @@ -250,7 +247,20 @@ var host_actions = { notifyMessage(tr("Template updated correctly")); }, error: onError - } + }, + + "Host.addtocluster" : { + type: "multiple", + call: function(params){ + var cluster = params.data.extra_param; + var host = params.data.id; + Sunstone.runAction("Cluster.addhost",cluster,host); + }, + callback: null, + elements: hostElements, + notify:true, + }, + }; var host_buttons = { @@ -268,6 +278,12 @@ var host_buttons = { text: tr("Update a template"), alwaysActive: true }, + "Host.addtocluster" : { + type: "confirm_with_select", + text: tr("Select cluster"), + select: clusters_sel, + tip: tr("Select the destination cluster:"), + }, "Host.enable" : { type: "action", text: tr("Enable") @@ -305,6 +321,11 @@ var hosts_tab = { buttons: host_buttons } +//Hack since this plugin is loaded earlier +function clusters_sel() { + return clusters_select; +} + Sunstone.addActions(host_actions); Sunstone.addMainTab('hosts_tab',hosts_tab); Sunstone.addInfoPanel("host_info_panel",host_info_panel); @@ -362,6 +383,7 @@ function hostElementArray(host_json){ '', host.ID, host.NAME, + host.CLUSTER, host.HOST_SHARE.RUNNING_VMS, //rvm pb_cpu, pb_mem, @@ -389,7 +411,7 @@ function updateHostSelect(){ hosts_select = makeSelectOptions(dataTable_hosts, 1,//id_col 2,//name_col - [6,6],//status_cols + [7,7],//status_cols ["ERROR","OFF"]//bad_st ); } @@ -448,6 +470,14 @@ function updateHostInfo(request,host){ ' + tr("id") + '\ '+host_info.ID+'\ \ + \ + ' + tr("Name") + '\ + '+host_info.NAME+'\ + \ + \ + ' + tr("Cluster") + '\ + '+host_info.CLUSTER+'\ + \ \ ' + tr("State") + '\ '+tr(OpenNebula.Helper.resource_state("host",host_info.STATE))+'\ @@ -553,15 +583,19 @@ function setupCreateHostDialog(){ notifyError(tr("Host name missing!")); return false; } + + var cluster_id = $('#host_cluster_id',this).val(); + if (!cluster_id) cluster_id = "-1"; + var host_json = { "host": { "name": $('#name',this).val(), - "tm_mad": $('#tm_mad :selected',this).val(), - "vm_mad": $('#vmm_mad :selected',this).val(), - "vnm_mad": $('#vnm_mad :selected',this).val(), - "im_mad": $('#im_mad :selected',this).val() + "vm_mad": $('#vmm_mad',this).val(), + "vnm_mad": $('#vnm_mad',this).val(), + "im_mad": $('#im_mad',this).val(), + "cluster_id": cluster_id } - } + }; //Create the OpenNebula.Host. //If it's successfull we refresh the list. @@ -573,6 +607,7 @@ function setupCreateHostDialog(){ //Open creation dialogs function popUpCreateHostDialog(){ + $('#host_cluster_id',$create_host_dialog).html(clusters_select); $create_host_dialog.dialog('open'); return false; } @@ -614,22 +649,22 @@ $(document).ready(function(){ "sPaginationType": "full_numbers", "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, - { "sWidth": "60px", "aTargets": [0,3] }, + { "sWidth": "60px", "aTargets": [0,4] }, { "sWidth": "35px", "aTargets": [1] }, - { "sWidth": "100px", "aTargets": [6] }, - { "sWidth": "200px", "aTargets": [4,5] } + { "sWidth": "100px", "aTargets": [7,3] }, + { "sWidth": "200px", "aTargets": [5,6] } ], - "oLanguage": (datatable_lang != "") ? - { - sUrl: "locale/"+lang+"/"+datatable_lang - } : "" + "oLanguage": (datatable_lang != "") ? + { + sUrl: "locale/"+lang+"/"+datatable_lang + } : "" }); //preload it dataTable_hosts.fnClearTable(); addElement([ spinner, - '','','','','',''],dataTable_hosts); + '','','','','','',''],dataTable_hosts); Sunstone.runAction("Host.list"); setupCreateHostDialog(); diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index daa3f60a3e..3cc3aff2df 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -28,6 +28,7 @@ var vnets_tab_content = '+tr("Owner")+'\ '+tr("Group")+'\ '+tr("Name")+'\ + '+tr("Cluster")+'\ '+tr("Type")+'\ '+tr("Bridge")+'\ '+tr("Total Leases")+'\ @@ -49,6 +50,7 @@ var create_vn_tmpl =
\ \
\ +
\
\
\ \ @@ -380,6 +382,18 @@ var vnet_actions = { error: onError }, + "Network.addtocluster" : { + type: "multiple", + call: function(params){ + var cluster = params.data.extra_param; + var vnet = params.data.id; + Sunstone.runAction("Cluster.addvnet",cluster,vnet); + }, + callback: null, + elements: vnElements, + notify:true, + }, + }; @@ -400,7 +414,12 @@ var vnet_buttons = { text: tr("Update properties"), alwaysActive: true }, - + "Network.addtocluster" : { + type: "confirm_with_select", + text: tr("Select cluster"), + select: clusters_sel, + tip: tr("Select the destination cluster:"), + }, "Network.chown" : { type: "confirm_with_select", text: tr("Change owner"), @@ -463,6 +482,7 @@ function vNetworkElementArray(vn_json){ network.UNAME, network.GNAME, network.NAME, + network.CLUSTER, parseInt(network.TYPE) ? "FIXED" : "RANGED", network.BRIDGE, network.TOTAL_LEASES ]; @@ -539,6 +559,10 @@ function updateVNetworkInfo(request,vn){ '+tr("Name")+'\ '+vn_info.NAME+'\ \ + \ + '+tr("Cluster")+'\ + '+vn_info.CLUSTER+'\ + \ \ '+tr("Owner")+'\ '+vn_info.UNAME+'\ @@ -849,6 +873,7 @@ function setupCreateVNetDialog() { var phydev = $('#phydev',this).val(); var vlan = $('#vlan',this).val(); var vlan_id = $('#vlan_id',this).val(); + switch (network_mode) { case "default": if (!bridge && !phydev){ @@ -948,7 +973,9 @@ function setupCreateVNetDialog() { //Create the VNetwork. - network_json = {"vnet" : network_json}; + network_json = { + "vnet" : network_json, + }; Sunstone.runAction("Network.create",network_json); $create_vn_dialog.dialog('close'); @@ -1145,9 +1172,9 @@ $(document).ready(function(){ "sPaginationType": "full_numbers", "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, - { "sWidth": "60px", "aTargets": [0,5,6,7] }, + { "sWidth": "60px", "aTargets": [0,6,7,8] }, { "sWidth": "35px", "aTargets": [1] }, - { "sWidth": "100px", "aTargets": [2,3] } + { "sWidth": "100px", "aTargets": [2,3,5] } ], "oLanguage": (datatable_lang != "") ? { @@ -1158,7 +1185,7 @@ $(document).ready(function(){ dataTable_vNetworks.fnClearTable(); addElement([ spinner, - '','','','','','',''],dataTable_vNetworks); + '','','','','','','',''],dataTable_vNetworks); Sunstone.runAction("Network.list"); setupCreateVNetDialog(); From bd5151dcba94f4a1f8b61ba16794575e50ca10e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 9 Mar 2012 15:05:27 +0100 Subject: [PATCH 141/217] Feature #1112: Migrator to 3.3.80 returns error if it finds active VMs --- src/onedb/3.3.0_to_3.3.80.rb | 41 ++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/onedb/3.3.0_to_3.3.80.rb b/src/onedb/3.3.0_to_3.3.80.rb index 7194edc1e5..884d9bceae 100644 --- a/src/onedb/3.3.0_to_3.3.80.rb +++ b/src/onedb/3.3.0_to_3.3.80.rb @@ -25,7 +25,38 @@ module Migrator "OpenNebula 3.3.80" end + SHORT_VM_STATES=%w{init pend hold actv stop susp done fail} + + SHORT_LCM_STATES=%w{prol boot runn migr save save save migr prol, + epil epil shut shut fail clea unkn} + def up + + header_done = false + + @db.fetch("SELECT oid,name,state,lcm_state FROM vm_pool WHERE ( state <> 1 AND state <> 6 )") do |row| + if ( !header_done ) + puts "You can't have active VMs. Please shutdown or delete the following VMs:" + puts + puts " ID STAT NAME" + + header_done = true + end + + if row[:state] != 3 + state_str = SHORT_VM_STATES[row[:state]] + else + state_str = SHORT_LCM_STATES[row[:lcm_state]] + end + + puts "#{'%6.6s' % row[:oid].to_s} #{state_str} #{row[:name]}" + end + + if ( header_done ) + puts + return false + end + one_location = ENV["ONE_LOCATION"] if !one_location @@ -208,9 +239,7 @@ module Migrator if ( hash.length == 32 && hash =~ /^[0-9A-F]+$/i ) e.text = "#{var_location}/datastores/1/#{hash}" - # TODO: create link, or mv image file? `ln -s #{previous_source} #{e.text}` - # `mv #{e.text} #{previous_source}` end } @@ -250,15 +279,15 @@ module Migrator " 0" << " 0" << " " << - " fs" << # TODO - " shared" << # TODO + " fs" << + " shared" << " #{var_location}/datastores/1" << " -1" << " none" << images_element << " " << "" From 3e9af3242ce65199f2b05d67f594c7360a6dd9fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 9 Mar 2012 15:11:00 +0100 Subject: [PATCH 142/217] Feature #1112: Set DS_MAD as '-' for the system datastore --- src/datastore/DatastorePool.cc | 2 +- src/onedb/3.3.0_to_3.3.80.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index 7dfd9fe096..1557659a39 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -52,7 +52,7 @@ DatastorePool::DatastorePool(SqlDB * db): // --------------------------------------------------------------------- oss << "NAME = " << SYSTEM_DS_NAME << endl - << "DS_MAD = fs" << endl + << "DS_MAD = -" << endl << "TM_MAD = shared"; ds_tmpl = new DatastoreTemplate; diff --git a/src/onedb/3.3.0_to_3.3.80.rb b/src/onedb/3.3.0_to_3.3.80.rb index 884d9bceae..3dff69249c 100644 --- a/src/onedb/3.3.0_to_3.3.80.rb +++ b/src/onedb/3.3.0_to_3.3.80.rb @@ -122,14 +122,14 @@ module Migrator " 0" << " 0" << " " << - " fs" << + " -" << " shared" << " #{var_location}/datastores/0" << " -1" << " none" << " " << " " << "" From f2e6303c3ee887af7564b998b583f2ab5d2f7324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 9 Mar 2012 15:49:45 +0100 Subject: [PATCH 143/217] Feature #1112: Add new cluster_id parameter to one.vn.allocate --- include/RequestManagerAllocate.h | 14 ++++++++++++-- src/cli/onehost | 4 ++++ src/cli/onevnet | 13 +++++++++++-- src/oca/ruby/OpenNebula/VirtualNetwork.rb | 10 +++++++--- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index 9522314868..8b3497b418 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -146,7 +146,7 @@ public: VirtualNetworkAllocate(): RequestManagerAllocate("VirtualNetworkAllocate", "Allocates a new virtual network", - "A:ss", + "A:ssi", true) { Nebula& nd = Nebula::instance(); @@ -170,6 +170,16 @@ public: RequestAttributes& att, int cluster_id, const string& cluster_name); + + int get_cluster_id(xmlrpc_c::paramList const& paramList) + { + return xmlrpc_c::value_int(paramList.getInt(2)); + }; + + int add_to_cluster(Cluster* cluster, int id, string& error_msg) + { + return cluster->add_datastore(id, error_msg); + }; }; /* ------------------------------------------------------------------------- */ @@ -181,7 +191,7 @@ public: ImageAllocate(): RequestManagerAllocate("ImageAllocate", "Allocates a new image", - "A:ss", + "A:ssi", true) { Nebula& nd = Nebula::instance(); diff --git a/src/cli/onehost b/src/cli/onehost index 9f72204b66..4c60cc1673 100755 --- a/src/cli/onehost +++ b/src/cli/onehost @@ -52,6 +52,10 @@ cmd=CommandParser::CmdParser.new(ARGV) do helper.list_to_id(arg) end + set :format, :clusterid, OpenNebulaHelper.rname_to_id_desc("CLUSTER") do |arg| + OpenNebulaHelper.rname_to_id(arg, "CLUSTER") + end + ######################################################################## # Commands ######################################################################## diff --git a/src/cli/onevnet b/src/cli/onevnet index 720673db27..6f8a7084ff 100755 --- a/src/cli/onevnet +++ b/src/cli/onevnet @@ -52,6 +52,10 @@ cmd=CommandParser::CmdParser.new(ARGV) do OpenNebulaHelper.rname_to_id(arg, "USER") end + set :format, :clusterid, OpenNebulaHelper.rname_to_id_desc("CLUSTER") do |arg| + OpenNebulaHelper.rname_to_id(arg, "CLUSTER") + end + set :format, :vnetid, OneVNetHelper.to_id_desc do |arg| helper.to_id(arg) end @@ -72,10 +76,15 @@ cmd=CommandParser::CmdParser.new(ARGV) do Creates a new Virtual Network from the given template file EOT - command :create, create_desc, :file do + command :create, create_desc, :file, [:clusterid, nil] do helper.create_resource(options) do |vn| template=File.read(args[0]) - vn.allocate(template) + + if args.size == 1 + vn.allocate(template) + else + vn.allocate(template, args[1].to_i) + end end end diff --git a/src/oca/ruby/OpenNebula/VirtualNetwork.rb b/src/oca/ruby/OpenNebula/VirtualNetwork.rb index 1c24e0ad95..2b82cc1622 100644 --- a/src/oca/ruby/OpenNebula/VirtualNetwork.rb +++ b/src/oca/ruby/OpenNebula/VirtualNetwork.rb @@ -78,9 +78,13 @@ module OpenNebula # Allocates a new VirtualNetwork in OpenNebula # - # +description+ A string containing the template of the VirtualNetwork. - def allocate(description) - super(VN_METHODS[:allocate],description) + # @param description [String] The template of the VirtualNetwork. + # @param cluster_id [Integer] Id of the cluster + # + # @return [Integer, OpenNebula::Error] the new ID in case of + # success, error otherwise + def allocate(description,cluster_id=ClusterPool::NONE_CLUSTER_ID) + super(VN_METHODS[:allocate], description, cluster_id) end # Replaces the template contents From d265f670585d7c5eed5f00c54f3c38542be9e84b Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 9 Mar 2012 17:04:33 +0100 Subject: [PATCH 144/217] feature #1112: new onehost command. Better arguments --- src/cli/command_parser.rb | 2 +- src/cli/etc/onehost.yaml | 10 ++++- src/cli/one_helper/onecluster_helper.rb | 14 +++++++ src/cli/one_helper/onedatastore_helper.rb | 13 ++++++ src/cli/one_helper/onehost_helper.rb | 14 +++++-- src/cli/onehost | 49 +++++++++++++++++++---- src/oca/ruby/OpenNebula/Host.rb | 2 +- 7 files changed, 90 insertions(+), 14 deletions(-) diff --git a/src/cli/command_parser.rb b/src/cli/command_parser.rb index efe463d962..fe3fc911ac 100755 --- a/src/cli/command_parser.rb +++ b/src/cli/command_parser.rb @@ -311,7 +311,7 @@ EOT opts.on(*args) do |o| if e[:proc] - e[:proc].call(o, @options) + @options[e[:name].to_sym]=e[:proc].call(o, @options) elsif e[:name]=="help" help exit diff --git a/src/cli/etc/onehost.yaml b/src/cli/etc/onehost.yaml index 8a8c781f9b..dcb95c9cda 100644 --- a/src/cli/etc/onehost.yaml +++ b/src/cli/etc/onehost.yaml @@ -5,7 +5,12 @@ :NAME: :desc: Name of the Host - :size: 15 + :size: 12 + :left: true + +:CLUSTER: + :desc: Name of the Cluster + :size: 8 :left: true :RVM: @@ -38,11 +43,12 @@ :STAT: :desc: Host status - :size: 6 + :size: 4 :default: - :ID - :NAME +- :CLUSTER - :RVM - :TCPU - :FCPU diff --git a/src/cli/one_helper/onecluster_helper.rb b/src/cli/one_helper/onecluster_helper.rb index d709b4808c..fbf82b0a8a 100644 --- a/src/cli/one_helper/onecluster_helper.rb +++ b/src/cli/one_helper/onecluster_helper.rb @@ -17,6 +17,20 @@ require 'one_helper' class OneClusterHelper < OpenNebulaHelper::OneHelper + + CLUSTER = { + :name => "cluster", + :short => "-c id|name", + :large => "--cluster id|name" , + :description => "Selects the cluster", + :format => String, + :proc => lambda { |o, options| + ch = OneClusterHelper.new + rc, cid = ch.to_id(o) + cid + } + } + def self.rname "CLUSTER" end diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index 33f812c1a0..85f2cde4d7 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -17,6 +17,19 @@ require 'one_helper' class OneDatastoreHelper < OpenNebulaHelper::OneHelper + DATASTORE = { + :name => "datastore", + :short => "-d id|name", + :large => "--datastore id|name" , + :description => "Selects the datastore", + :format => String, + :proc => lambda { |o, options| + ch = OneDatastoreHelper.new + rc, dsid = ch.to_id(o) + dsid + } + } + def self.rname "DATASTORE" end diff --git a/src/cli/one_helper/onehost_helper.rb b/src/cli/one_helper/onehost_helper.rb index 74628bb18f..63434231ba 100644 --- a/src/cli/one_helper/onehost_helper.rb +++ b/src/cli/one_helper/onehost_helper.rb @@ -39,10 +39,18 @@ class OneHostHelper < OpenNebulaHelper::OneHelper d["ID"] end - column :NAME, "Name of the Host", :left, :size=>15 do |d| + column :NAME, "Name of the Host", :left, :size=>12 do |d| d["NAME"] end + column :CLUSTER, "Name of the Cluster", :left, :size=>8 do |d| + if d["CLUSTER"] == "none" + "-" + else + d["CLUSTER"] + end + end + column :RVM, "Number of Virtual Machines running", :size=>6 do |d| d["HOST_SHARE"]["RUNNING_VMS"] end @@ -82,11 +90,11 @@ class OneHostHelper < OpenNebulaHelper::OneHelper OpenNebulaHelper.unit_to_str(acpu,options) end - column :STAT, "Host status", :size=>6 do |d| + column :STAT, "Host status", :size=>4 do |d| OneHostHelper.state_to_str(d["STATE"]) end - default :ID, :NAME, :RVM, :TCPU, :FCPU, :ACPU, :TMEM, :FMEM, + default :ID, :NAME, :CLUSTER, :RVM, :TCPU, :FCPU, :ACPU, :TMEM, :FMEM, :AMEM, :STAT end diff --git a/src/cli/onehost b/src/cli/onehost index 9f72204b66..a56a49792c 100755 --- a/src/cli/onehost +++ b/src/cli/onehost @@ -29,6 +29,7 @@ $: << RUBY_LIB_LOCATION+"/cli" require 'command_parser' require 'one_helper/onehost_helper' +require 'one_helper/onecluster_helper' cmd=CommandParser::CmdParser.new(ARGV) do usage "`onehost` [] []" @@ -41,6 +42,31 @@ cmd=CommandParser::CmdParser.new(ARGV) do ######################################################################## set :option, CommandParser::OPTIONS + IM = { + :name => "im", + :short => "-i im_mad", + :large => "--im im_mad" , + :description => "Set the information driver for the host", + :format => String + } + + VMM = { + :name => "vmm", + :short => "-v vmm_mad", + :large => "--vm vmm_mad" , + :description => "Set the virtualization driver for the host", + :format => String + } + + VNET = { + :name => "vnm", + :short => "-n vnet_mad", + :large => "--net vnet_mad" , + :description => "Set the network driver for the host", + :format => String + } + + CREAT_OPTIONS = [ IM, VMM, VNET, OneClusterHelper::CLUSTER ] ######################################################################## # Formatters for arguments ######################################################################## @@ -60,14 +86,23 @@ cmd=CommandParser::CmdParser.new(ARGV) do Creates a new Host EOT - command :create, create_desc, :hostname, :im_mad, :vmm_mad, - :vnm_mad, [:clusterid, nil] do + command :create, create_desc, :hostname, :options=>CREAT_OPTIONS do + if options[:im].nil? or options[:vmm].nil? or options[:vnm].nil? + STDERR.puts "Drivers are mandatory to create a host:" + STDERR.puts "\t -i information driver" + STDERR.puts "\t -v hypervisor driver" + STDERR.puts "\t -n network driver" + exit -1 + end + + cid = options[:cluster] || ClusterPool::NONE_CLUSTER_ID + helper.create_resource(options) do |host| - if args.size == 4 - host.allocate(args[0], args[1], args[2], args[3]) - else - host.allocate(args[0], args[1], args[2], args[3], args[4].to_i) - end + host.allocate(args[0], + options[:im], + options[:vmm], + options[:vnm], + cid) end end diff --git a/src/oca/ruby/OpenNebula/Host.rb b/src/oca/ruby/OpenNebula/Host.rb index c8274532ec..f0c6286939 100644 --- a/src/oca/ruby/OpenNebula/Host.rb +++ b/src/oca/ruby/OpenNebula/Host.rb @@ -82,7 +82,7 @@ module OpenNebula # @param im [String] Name of the im_driver (information/monitoring) # @param vmm [String] Name of the vmm_driver (hypervisor) # @param tm [String] Name of the vnm_driver (networking) - # @param cluster_id [Integer] Id of the cluster + # @param cluster_id [String] Id of the cluster # # @return [Integer, OpenNebula::Error] the new ID in case of # success, error otherwise From 6861fa660ebd8fe3ca4c71f760ebbf72307ef304 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 9 Mar 2012 17:13:24 +0100 Subject: [PATCH 145/217] feature #1112: Removed formatter --- src/cli/onehost | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/cli/onehost b/src/cli/onehost index 354c3c284e..3b7d89fa63 100755 --- a/src/cli/onehost +++ b/src/cli/onehost @@ -67,9 +67,11 @@ cmd=CommandParser::CmdParser.new(ARGV) do } CREAT_OPTIONS = [ IM, VMM, VNET, OneClusterHelper::CLUSTER ] + ######################################################################## # Formatters for arguments ######################################################################## + set :format, :hostid, OneHostHelper.to_id_desc do |arg| helper.to_id(arg) end @@ -78,10 +80,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do helper.list_to_id(arg) end - set :format, :clusterid, OpenNebulaHelper.rname_to_id_desc("CLUSTER") do |arg| - OpenNebulaHelper.rname_to_id(arg, "CLUSTER") - end - ######################################################################## # Commands ######################################################################## From 961e368116aa02301916eb58bded4d3dbeb770ea Mon Sep 17 00:00:00 2001 From: Tino Vazquez Date: Fri, 9 Mar 2012 17:13:42 +0100 Subject: [PATCH 146/217] TM shared drivers compatibility with VMware --- src/mad/sh/scripts_common.sh | 1 + src/tm_mad/common/context | 3 ++ src/tm_mad/shared/ln | 39 +++++++++++++++++---- src/tm_mad/tm_common.sh | 15 ++++++++ src/vmm/LibVirtDriverVMware.cc | 6 ++-- src/vmm_mad/exec/vmm_exec_vmware.conf | 9 ++--- src/vmm_mad/remotes/vmware/vmware_driver.rb | 3 +- 7 files changed, 61 insertions(+), 15 deletions(-) diff --git a/src/mad/sh/scripts_common.sh b/src/mad/sh/scripts_common.sh index 1296f3c65a..7e6bb04ce8 100755 --- a/src/mad/sh/scripts_common.sh +++ b/src/mad/sh/scripts_common.sh @@ -27,6 +27,7 @@ ISCSIADM=iscsiadm LVCREATE=lvcreate LVREMOVE=lvremove LVS=lvs +LN=ln MD5SUM=md5sum MKFS=mkfs MKISOFS=mkisofs diff --git a/src/tm_mad/common/context b/src/tm_mad/common/context index a36c2e5699..d519110140 100755 --- a/src/tm_mad/common/context +++ b/src/tm_mad/common/context @@ -73,6 +73,9 @@ exec_and_log "$MKISOFS -o $ISO_FILE -J -R $ISO_DIR" "Error creating iso fs" exec_and_log "$SCP $ISO_FILE $DST" "Error copying context ISO to $DST" +# Creates symbolic link to add a .iso suffix, needed for VMware CDROMs +ssh_exec_and_log $DST_HOST "$LN -s $DST_PATH $DST_PATH.iso" "Error creating ISO symbolic link" + rm -rf $ISO_DIR > /dev/null 2>&1 exit 0 diff --git a/src/tm_mad/shared/ln b/src/tm_mad/shared/ln index 4ecb76e42b..2a9395d484 100755 --- a/src/tm_mad/shared/ln +++ b/src/tm_mad/shared/ln @@ -16,7 +16,7 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -# ln fe:SOURCE host:remote_system_ds/disk.i size +# ln fe:SOURCE host:remote_system_ds/disk.i # - fe is the front-end hostname # - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk # - host is the target host to deploy the VM @@ -43,16 +43,41 @@ DST_PATH=`arg_path $DST` DST_HOST=`arg_host $DST` DST_DIR=`dirname $DST_PATH` -ssh_make_path $DST_HOST $DST_DIR - #------------------------------------------------------------------------------- # Link (ln) SRC into DST #------------------------------------------------------------------------------- -log "Linking $SRC_PATH in $DST" +# Is it a file or a folder (VMware)? +if [ -d `arg_path $SRC` ]; then + ssh_make_path $DST_HOST $DST_PATH + + # It's a folder, make links for all elements + SRC_FOLDER_NAME=`basename $SRC_PATH` + SRC_WITH_NO_FOLDER=`dirname $SRC_PATH` + SRC_DS_NAME=`basename $SRC_WITH_NO_FOLDER` + REL_SRC_PATH="../../../$SRC_DS_NAME/$SRC_FOLDER_NAME" + + log "Link all files in $SRC_PATH to $DST_PATH" + +LINK_SCRIPT=$(cat <" << endl; file << "\t\t\tget_oid() - << "/images/disk." << i << "'/>" << endl; + << "/disk." << i << "'/>" << endl; } else if ( type == "CDROM" ) { file << "\t\t" << endl; file << "\t\t\tget_oid() - << "/images/disk." << i << ".iso'/>" << endl; + << "/disk." << i << ".iso'/>" << endl; } else { file << "\t\t" << endl << "\t\t\t" << endl; + << "/disk." << i << "/disk.vmdk'/>" << endl; } file << "\t\t\t e OpenNebula.log_error("Cannot open checkpoint #{e.message}") exit -1 From a9d7a9b072367cf64bd8566d77020662b8c7a7d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 9 Mar 2012 17:32:54 +0100 Subject: [PATCH 147/217] Bug #1159: Move restricted attribute checks to RM. Do not check restricted attributes when a template owned by oneadmin is instantiated --- include/RequestManagerAllocate.h | 4 +++ src/image/Image.cc | 20 ------------ src/rm/RequestManagerAllocate.cc | 52 ++++++++++++++++++++++++++++++ src/rm/RequestManagerVMTemplate.cc | 21 ++++++++++++ src/vm/VirtualMachine.cc | 28 ++-------------- 5 files changed, 80 insertions(+), 45 deletions(-) diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index 8b3497b418..faceccd4db 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -205,6 +205,10 @@ public: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att); + + bool allocate_authorization(Template * obj_template, + RequestAttributes& att, + PoolObjectAuth * cluster_perms); }; /* ------------------------------------------------------------------------- */ diff --git a/src/image/Image.cc b/src/image/Image.cc index dfa867ee24..e05c4b8ffd 100644 --- a/src/image/Image.cc +++ b/src/image/Image.cc @@ -95,25 +95,10 @@ int Image::insert(SqlDB *db, string& error_str) string persistent_attr; string dev_prefix; string source_attr; - string aname; string saved_id; ostringstream oss; - // ------------------------------------------------------------------------ - // Check template for restricted attributes - // ------------------------------------------------------------------------ - - if ( uid != 0 && gid != GroupPool::ONEADMIN_ID ) - { - ImageTemplate *img_template = static_cast(obj_template); - - if (img_template->check(aname)) - { - goto error_restricted; - } - } - // --------------------------------------------------------------------- // Check default image attributes // --------------------------------------------------------------------- @@ -242,11 +227,6 @@ error_path_and_source: error_str = "Template malformed, PATH and SOURCE are mutually exclusive."; goto error_common; -error_restricted: - oss << "Template includes a restricted attribute " << aname << "."; - error_str = oss.str(); - goto error_common; - error_common: NebulaLog::log("IMG", Log::ERROR, error_str); return -1; diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 5342d9efd8..e5c70bda4a 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -76,9 +76,28 @@ bool VirtualMachineAllocate::allocate_authorization( AuthRequest ar(att.uid, att.gid); string t64; + string aname; VirtualMachineTemplate * ttmpl = static_cast(tmpl); + // Check template for restricted attributes + + if ( att.uid != 0 && att.gid != GroupPool::ONEADMIN_ID ) + { + if (ttmpl->check(aname)) + { + ostringstream oss; + + oss << "VM Template includes a restricted attribute " << aname; + + failure_response(AUTHORIZATION, + authorization_error(oss.str(), att), + att); + + return false; + } + } + ar.add_create_auth(auth_object, tmpl->to_xml(t64)); VirtualMachine::set_auth_request(att.uid, ar, ttmpl); @@ -98,6 +117,39 @@ bool VirtualMachineAllocate::allocate_authorization( /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +bool ImageAllocate::allocate_authorization( + Template * tmpl, + RequestAttributes& att, + PoolObjectAuth * cluster_perms) +{ + string aname; + + ImageTemplate * itmpl = static_cast(tmpl); + + // Check template for restricted attributes + + if ( att.uid != 0 && att.gid != GroupPool::ONEADMIN_ID ) + { + if (itmpl->check(aname)) + { + ostringstream oss; + + oss << "Template includes a restricted attribute " << aname; + + failure_response(AUTHORIZATION, + authorization_error(oss.str(), att), + att); + + return false; + } + } + + return RequestManagerAllocate::allocate_authorization(tmpl, att, cluster_perms); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params, RequestAttributes& att) { diff --git a/src/rm/RequestManagerVMTemplate.cc b/src/rm/RequestManagerVMTemplate.cc index a62aa2f56d..d354d5a037 100644 --- a/src/rm/RequestManagerVMTemplate.cc +++ b/src/rm/RequestManagerVMTemplate.cc @@ -39,6 +39,7 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList VMTemplate * rtmpl; string error_str; + string aname; rtmpl = tpool->get(id,true); @@ -57,6 +58,26 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList rtmpl->unlock(); + // Check template for restricted attributes, but only if the Template owner + // is not oneadmin + + if ( perms.uid != 0 && perms.gid != GroupPool::ONEADMIN_ID ) + { + if (tmpl->check(aname)) + { + ostringstream oss; + + oss << "VM Template includes a restricted attribute " << aname; + + failure_response(AUTHORIZATION, + authorization_error(oss.str(), att), + att); + + delete tmpl; + return; + } + } + tmpl->erase("NAME"); tmpl->set(new SingleAttribute("NAME",name)); diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 38fd4100f0..f11f91ac70 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -198,26 +198,9 @@ int VirtualMachine::insert(SqlDB * db, string& error_str) int rc; string name; - SingleAttribute * attr; - string aname; - string value; - - ostringstream oss; - - // ------------------------------------------------------------------------ - // Check template for restricted attributes - // ------------------------------------------------------------------------ - - if ( uid != 0 && gid != GroupPool::ONEADMIN_ID ) - { - VirtualMachineTemplate *vt = - static_cast(obj_template); - - if (vt->check(aname)) - { - goto error_restricted; - } - } + SingleAttribute * attr; + string value; + ostringstream oss; // ------------------------------------------------------------------------ // Set a name if the VM has not got one and VM_ID @@ -327,11 +310,6 @@ error_leases_rollback: release_network_leases(); goto error_common; -error_restricted: - oss << "VM Template includes a restricted attribute " << aname << "."; - error_str = oss.str(); - goto error_common; - error_name_length: oss << "NAME is too long; max length is 128 chars."; error_str = oss.str(); From c88fdb617afbc2d6118e8c3f0870d48871b5424a Mon Sep 17 00:00:00 2001 From: Tino Vazquez Date: Fri, 9 Mar 2012 18:11:53 +0100 Subject: [PATCH 148/217] SSH TM drivers compatibility with VMware --- src/tm_mad/ssh/clone | 2 +- src/tm_mad/ssh/mvds | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tm_mad/ssh/clone b/src/tm_mad/ssh/clone index 87a95357fb..8a81d9b95d 100755 --- a/src/tm_mad/ssh/clone +++ b/src/tm_mad/ssh/clone @@ -58,6 +58,6 @@ http://*) *) log "Cloning $SRC in $DST_PATH" - exec_and_log "$SCP $SRC $DST" "Error copying $SRC to $DST" + exec_and_log "$SCP -r $SRC $DST" "Error copying $SRC to $DST" ;; esac diff --git a/src/tm_mad/ssh/mvds b/src/tm_mad/ssh/mvds index 74bb8cc8cf..47c66b6b41 100755 --- a/src/tm_mad/ssh/mvds +++ b/src/tm_mad/ssh/mvds @@ -49,6 +49,6 @@ SRC_HOST=`arg_host $SRC` # Move the image back to the datastore #------------------------------------------------------------------------------- log "Moving $SRC_PATH to datastore as $DST_PATH" -exec_and_log "$SCP $SRC $DST" "Error copying $SRC to $DST" +exec_and_log "$SCP -r $SRC $DST" "Error copying $SRC to $DST" exit 0 From 94088ad0797e3f57d6d98cccf25feef148432a97 Mon Sep 17 00:00:00 2001 From: Tino Vazquez Date: Fri, 9 Mar 2012 18:15:53 +0100 Subject: [PATCH 149/217] change bash ssh wrapper to sh to ensure vSphere 5.x compatibility --- src/mad/sh/scripts_common.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mad/sh/scripts_common.sh b/src/mad/sh/scripts_common.sh index 7e6bb04ce8..204b87eb38 100755 --- a/src/mad/sh/scripts_common.sh +++ b/src/mad/sh/scripts_common.sh @@ -212,7 +212,7 @@ function mkfs_command { #This function executes $2 at $1 host and report error $3 function ssh_exec_and_log { - SSH_EXEC_ERR=`$SSH $1 bash -s 2>&1 1>/dev/null <&1 1>/dev/null <&1 1>/dev/null <&1 1>/dev/null < Date: Fri, 9 Mar 2012 18:24:20 +0100 Subject: [PATCH 150/217] Feature #1112: onedb restores the original DB if the upgrade process fails --- src/onedb/onedb.rb | 74 +++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/src/onedb/onedb.rb b/src/onedb/onedb.rb index a6a041ad38..967b27962b 100644 --- a/src/onedb/onedb.rb +++ b/src/onedb/onedb.rb @@ -107,43 +107,57 @@ class OneDB backup(ops[:backup], ops) end - result = nil - i = 0 + begin + result = nil + i = 0 - while ( matches.size > 0 ) - if ( matches.size > 1 ) - raise "There are more than one file that match \ - \"#{RUBY_LIB_LOCATION}/onedb/#{version}_to_*.rb\"" + while ( matches.size > 0 ) + if ( matches.size > 1 ) + raise "There are more than one file that match \ + \"#{RUBY_LIB_LOCATION}/onedb/#{version}_to_*.rb\"" + end + + file = matches[0] + + puts " > Running migrator #{file}" if ops[:verbose] + + load(file) + @backend.extend Migrator + result = @backend.up + + if !result + raise "Error while upgrading from #{version} to " << + " #{@backend.db_version}" + end + + puts " > Done" if ops[:verbose] + puts "" if ops[:verbose] + + matches = Dir.glob( + "#{RUBY_LIB_LOCATION}/onedb/#{@backend.db_version}_to_*.rb") end - file = matches[0] - - puts " > Running migrator #{file}" if ops[:verbose] - - load(file) - @backend.extend Migrator - result = @backend.up - - if !result - raise "Error while upgrading from #{version} to " << - " #{@backend.db_version}" + # Modify db_versioning table + if result != nil + @backend.update_db_version(version) + else + puts "Database already uses version #{version}" end - puts " > Done" if ops[:verbose] - puts "" if ops[:verbose] + return 0 - matches = Dir.glob( - "#{RUBY_LIB_LOCATION}/onedb/#{@backend.db_version}_to_*.rb") + rescue Exception => e + puts e.message + + puts + puts "The database will be restored" + + ops[:force] = true + + restore(ops[:backup], ops) + + return -1 end - - # Modify db_versioning table - if result != nil - @backend.update_db_version(version) - else - puts "Database already uses version #{version}" - end - - return 0 end private From 0e8ecf97f76302eab9a90e6f2d2e98e038e500b2 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 9 Mar 2012 18:28:11 +0100 Subject: [PATCH 151/217] feature #1112: Datastore Command --- src/cli/etc/onedatastore.yaml | 24 ++++++++++++++ src/cli/one_helper/onedatastore_helper.rb | 39 +++++++++++++++++------ src/cli/onedatastore | 18 +++++++---- 3 files changed, 65 insertions(+), 16 deletions(-) diff --git a/src/cli/etc/onedatastore.yaml b/src/cli/etc/onedatastore.yaml index a012998163..7b9ffe5237 100644 --- a/src/cli/etc/onedatastore.yaml +++ b/src/cli/etc/onedatastore.yaml @@ -8,7 +8,31 @@ :size: 15 :left: true +:CLUSTER: + :desc: Name of the Cluster + :size: 8 + :left: true + +:IMAGES: + :desc: Number of Images + :size: 6 + :left: true + +:TYPE: + :desc: Datastore driver + :size: 6 + :left: true + +:TM: + :desc: Transfer driver + :size: 6 + :left: true + :default: - :ID - :NAME +- :CLUSTER +- :IMAGES +- :TYPE +- :TM diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index 85f2cde4d7..a143379d24 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -29,7 +29,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper dsid } } - + def self.rname "DATASTORE" end @@ -46,11 +46,31 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper d["ID"] end - column :NAME, "Name of the Datastore", :left, :size=>15 do |d| + column :NAME, "Name of the Datastore", :left, :size=>12 do |d| d["NAME"] end - default :ID, :NAME + column :CLUSTER, "Name of the Cluster", :left, :size=>8 do |d| + if d["CLUSTER"] == "none" + "-" + else + d["CLUSTER"] + end + end + + column :IMAGES, "Number of Images", :left, :size=>6 do |d| + d["IMAGES"].size + end + + column :TYPE, "Datastore driver", :left, :size=>6 do |d| + d["DS_MAD"] + end + + column :TM, "Transfer driver", :left, :size=>6 do |d| + d["TM_MAD"] + end + + default :ID, :CLUSTER, :NAME, :IMAGES, :TYPE, :TM_MAD end table @@ -82,6 +102,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper puts str % ["USER", datastore['UNAME']] puts str % ["GROUP", datastore['GNAME']] puts str % ["CLUSTER", datastore['CLUSTER']] + puts str % ["CLUSTER_ID", datastore['CLUSTER_ID']] puts str % ["DS_MAD", datastore['DS_MAD']] puts str % ["TM_MAD", datastore['TM_MAD']] @@ -100,14 +121,14 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper } puts - CLIHelper.print_header(str_h1 % "IMAGES", false) - CLIHelper.print_header("%-15s" % ["ID"]) + CLIHelper.print_header(str_h1 % "DATASTORE TEMPLATE",false) + puts datastore.template_str + + puts + + CLIHelper.print_header(str_h1 % "REGISTERED IMAGES", false) datastore.img_ids.each do |id| puts "%-15s" % [id] end - - puts - CLIHelper.print_header(str_h1 % "DATASTORE TEMPLATE",false) - puts datastore.template_str end end diff --git a/src/cli/onedatastore b/src/cli/onedatastore index 514b5c2249..02dbab9189 100755 --- a/src/cli/onedatastore +++ b/src/cli/onedatastore @@ -29,6 +29,7 @@ $: << RUBY_LIB_LOCATION+"/cli" require 'command_parser' require 'one_helper/onedatastore_helper' +require 'one_helper/onecluster_helper' cmd=CommandParser::CmdParser.new(ARGV) do usage "`onedatastore` [] []" @@ -76,14 +77,17 @@ cmd=CommandParser::CmdParser.new(ARGV) do Creates a new Datastore from the given template file EOT - command :create, create_desc, :file, [:clusterid, nil] do - helper.create_resource(options) do |datastore| - template=File.read(args[0]) + command :create, create_desc, :file, :options=>[OneClusterHelper::CLUSTER] do - if args.size == 1 - datastore.allocate(template) - else - datastore.allocate(template, args[1].to_i) + cid = options[:cluster] || ClusterPool::NONE_CLUSTER_ID + + helper.create_resource(options) do |datastore| + begin + template=File.read(args[0]) + datastore.allocate(template, cid) + rescue =>e + STDERR.puts e.message + exit -1 end end end From 5c9dcf90337a692d41a8c4ddb517a895f4be0830 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 9 Mar 2012 21:25:05 +0100 Subject: [PATCH 152/217] feature #1112: Work on onecluster command --- src/cli/etc/onecluster.yaml | 19 ++++++++++++++++- src/cli/one_helper/onecluster_helper.rb | 26 +++++++++++++++++------ src/cli/one_helper/onedatastore_helper.rb | 4 ++-- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/cli/etc/onecluster.yaml b/src/cli/etc/onecluster.yaml index b69de015c6..f3d4949e85 100644 --- a/src/cli/etc/onecluster.yaml +++ b/src/cli/etc/onecluster.yaml @@ -8,7 +8,24 @@ :size: 15 :left: true +:HOSTS: + :desc: Number of Hosts + :size: 5 + :left: true + +:NETS: + :desc: Number of Networks + :size: 5 + :left: true + +:DATASTORES: + :desc: Number of Datastores + :size: 10 + :left: true + :default: - :ID - :NAME - +- :HOSTS +- :NETS +- :DATASTORES diff --git a/src/cli/one_helper/onecluster_helper.rb b/src/cli/one_helper/onecluster_helper.rb index fbf82b0a8a..4e837f9a29 100644 --- a/src/cli/one_helper/onecluster_helper.rb +++ b/src/cli/one_helper/onecluster_helper.rb @@ -51,7 +51,19 @@ class OneClusterHelper < OpenNebulaHelper::OneHelper d["NAME"] end - default :ID, :NAME + column :HOSTS, "Number of Hosts", :left, :size=>5 do |d| + d["HOSTS"].size + end + + column :NETS, "Number of Networks", :left, :size=>5 do |d| + d["HOSTS"].size + end + + column :DATASTORES, "Number of Datastores", :left, :size=>10 do |d| + d["DATASTORES"].size + end + + default :ID, :NAME, :HOSTS, :NETS, :DATASTORES end table @@ -86,16 +98,16 @@ class OneClusterHelper < OpenNebulaHelper::OneHelper puts "%-15s" % [id] end - puts - CLIHelper.print_header("%-15s" % ["DATASTORES"]) - cluster.datastore_ids.each do |id| - puts "%-15s" % [id] - end - puts CLIHelper.print_header("%-15s" % ["VNETS"]) cluster.vnet_ids.each do |id| puts "%-15s" % [id] end + + puts + CLIHelper.print_header("%-15s" % ["DATASTORES"]) + cluster.datastore_ids.each do |id| + puts "%-15s" % [id] + end end end diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index a143379d24..16f68d6e6b 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -121,12 +121,12 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper } puts - CLIHelper.print_header(str_h1 % "DATASTORE TEMPLATE",false) + CLIHelper.print_header(str_h1 % "DATASTORE TEMPLATE", false) puts datastore.template_str puts - CLIHelper.print_header(str_h1 % "REGISTERED IMAGES", false) + CLIHelper.print_header("%-15s" % "IMAGES") datastore.img_ids.each do |id| puts "%-15s" % [id] end From 9ae062e39ea873f3f18f7616d0ed43fcde8c69de Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 9 Mar 2012 21:45:02 +0100 Subject: [PATCH 153/217] feature #1112: Update onevnet command --- src/cli/etc/onevnet.yaml | 16 +++++++++++----- src/cli/one_helper/onevnet_helper.rb | 22 +++++++++++++++------- src/cli/onevnet | 23 ++++++++++++----------- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/cli/etc/onevnet.yaml b/src/cli/etc/onevnet.yaml index 12820657ad..36d07930ca 100644 --- a/src/cli/etc/onevnet.yaml +++ b/src/cli/etc/onevnet.yaml @@ -3,11 +3,6 @@ :desc: ONE identifier for Virtual Network :size: 4 -:NAME: - :desc: Name of the Virtual Network - :size: 15 - :left: true - :USER: :desc: Username of the Virtual Network owner :size: 8 @@ -18,6 +13,16 @@ :size: 8 :left: true +:NAME: + :desc: Name of the Virtual Network + :size: 15 + :left: true + +:CLUSTER: + :desc: Name of the Cluster + :size: 8 + :left: true + :TYPE: :desc: Type of Virtual Network :size: 6 @@ -39,6 +44,7 @@ - :USER - :GROUP - :NAME +- :CLUSTER - :TYPE - :BRIDGE - :LEASES diff --git a/src/cli/one_helper/onevnet_helper.rb b/src/cli/one_helper/onevnet_helper.rb index 6b2b439c5a..8281f51eff 100644 --- a/src/cli/one_helper/onevnet_helper.rb +++ b/src/cli/one_helper/onevnet_helper.rb @@ -39,11 +39,6 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper d["ID"] end - column :NAME, "Name of the Virtual Network", :left, - :size=>15 do |d| - d["NAME"] - end - column :USER, "Username of the Virtual Network owner", :left, :size=>8 do |d| helper.user_name(d, options) @@ -54,11 +49,24 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper helper.group_name(d, options) end + column :NAME, "Name of the Virtual Network", :left, + :size=>15 do |d| + d["NAME"] + end + + column :CLUSTER, "Name of the Cluster", :left, :size=>8 do |d| + if d["CLUSTER"] == "none" + "-" + else + d["CLUSTER"] + end + end + column :TYPE, "Type of Virtual Network", :size=>6 do |d| OneVNetHelper.type_to_str(d["TYPE"]) end - column :SIZE, "Size of the Virtual Network", :size=>6 do |d| + column :SIZE, "Size of the Virtual Network", :size=>5 do |d| d["SIZE"] end @@ -68,7 +76,7 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper end column :LEASES, "Number of this Virtual Network's given leases", - :size=>7 do |d| + :size=>6 do |d| d["TOTAL_LEASES"] end diff --git a/src/cli/onevnet b/src/cli/onevnet index 6f8a7084ff..e76da4b48d 100755 --- a/src/cli/onevnet +++ b/src/cli/onevnet @@ -29,6 +29,7 @@ $: << RUBY_LIB_LOCATION+"/cli" require 'command_parser' require 'one_helper/onevnet_helper' +require 'one_helper/onecluster_helper' cmd=CommandParser::CmdParser.new(ARGV) do usage "`onevnet` [] []" @@ -41,6 +42,8 @@ cmd=CommandParser::CmdParser.new(ARGV) do ######################################################################## set :option, CommandParser::OPTIONS + CREATE_OPTIONS = [OneClusterHelper::CLUSTER] + ######################################################################## # Formatters for arguments ######################################################################## @@ -52,10 +55,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do OpenNebulaHelper.rname_to_id(arg, "USER") end - set :format, :clusterid, OpenNebulaHelper.rname_to_id_desc("CLUSTER") do |arg| - OpenNebulaHelper.rname_to_id(arg, "CLUSTER") - end - set :format, :vnetid, OneVNetHelper.to_id_desc do |arg| helper.to_id(arg) end @@ -76,14 +75,16 @@ cmd=CommandParser::CmdParser.new(ARGV) do Creates a new Virtual Network from the given template file EOT - command :create, create_desc, :file, [:clusterid, nil] do - helper.create_resource(options) do |vn| - template=File.read(args[0]) + command :create, create_desc, :file, options=>CREATE_OPTIONS do + cid = options[:cluster] || ClusterPool::NONE_CLUSTER_ID - if args.size == 1 - vn.allocate(template) - else - vn.allocate(template, args[1].to_i) + helper.create_resource(options) do |vn| + begin + template=File.read(args[0]) + vn.allocate(template, cid) + rescue => e + STDERR.puts e.message + exit -1 end end end From fbbf10950ac9dbcdc9b3452309336f741c8fca96 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 9 Mar 2012 22:43:44 +0100 Subject: [PATCH 154/217] feature #1112: Image command includes datastore information --- src/cli/etc/oneimage.yaml | 17 +++++++++++------ src/cli/one_helper/onedatastore_helper.rb | 6 +++++- src/cli/one_helper/oneimage_helper.rb | 19 +++++++++---------- src/cli/oneimage | 23 ++++++++++++++++------- 4 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/cli/etc/oneimage.yaml b/src/cli/etc/oneimage.yaml index c8ddff7956..235d7e8ca9 100644 --- a/src/cli/etc/oneimage.yaml +++ b/src/cli/etc/oneimage.yaml @@ -3,11 +3,6 @@ :desc: ONE identifier for the Image :size: 4 -:NAME: - :desc: Name of the Image - :size: 12 - :left: true - :USER: :desc: Username of the Virtual Machine owner :size: 8 @@ -18,6 +13,16 @@ :size: 8 :left: true +:NAME: + :desc: Name of the Image + :size: 12 + :left: true + +:DATASTORE: + :desc: Name of the Datastore + :size: 10 + :left: true + :SIZE: :desc: Size of the Image :size: 7 @@ -47,9 +52,9 @@ - :USER - :GROUP - :NAME +- :DATASTORE - :SIZE - :TYPE -- :REGTIME - :PERSISTENT - :STAT - :RVMS diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index 16f68d6e6b..4f524bbd71 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -59,7 +59,11 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper end column :IMAGES, "Number of Images", :left, :size=>6 do |d| - d["IMAGES"].size + if d["IMAGES"]["ID"].nil? + "0" + else + d["IMAGES"]["ID"].size + end end column :TYPE, "Datastore driver", :left, :size=>6 do |d| diff --git a/src/cli/one_helper/oneimage_helper.rb b/src/cli/one_helper/oneimage_helper.rb index 4d13ae95dc..b02ea356d9 100644 --- a/src/cli/one_helper/oneimage_helper.rb +++ b/src/cli/one_helper/oneimage_helper.rb @@ -45,10 +45,6 @@ class OneImageHelper < OpenNebulaHelper::OneHelper d["ID"] end - column :NAME, "Name of the Image", :left, :size=>12 do |d| - d["NAME"] - end - column :USER, "Username of the Virtual Machine owner", :left, :size=>8 do |d| helper.user_name(d, options) @@ -59,13 +55,16 @@ class OneImageHelper < OpenNebulaHelper::OneHelper helper.group_name(d, options) end - column :TYPE, "Type of the Image", :size=>4 do |d,e| - OneImageHelper.type_to_str(d["TYPE"]) + column :NAME, "Name of the Image", :left, :size=>12 do |d| + d["NAME"] end - column :REGTIME, "Registration time of the Image", - :size=>20 do |d| - OpenNebulaHelper.time_to_str(d["REGTIME"]) + column :DATASTORE, "Name of the Image", :left, :size=>10 do |d| + d["DATASTORE"] + end + + column :TYPE, "Type of the Image", :size=>4 do |d,e| + OneImageHelper.type_to_str(d["TYPE"]) end column :PERSISTENT, "Whether the Image is persistent or not", @@ -87,7 +86,7 @@ class OneImageHelper < OpenNebulaHelper::OneHelper OpenNebulaHelper.unit_to_str(d['SIZE'].to_i,options,"M") end - default :ID, :USER, :GROUP, :NAME, :SIZE, :TYPE, :REGTIME, + default :ID, :USER, :GROUP, :NAME, :DATASTORE, :SIZE, :TYPE, :PERSISTENT , :STAT, :RVMS end diff --git a/src/cli/oneimage b/src/cli/oneimage index bb8635f5db..fca548c8ce 100755 --- a/src/cli/oneimage +++ b/src/cli/oneimage @@ -29,6 +29,7 @@ $: << RUBY_LIB_LOCATION+"/cli" require 'command_parser' require 'one_helper/oneimage_helper' +require 'one_helper/onedatastore_helper' cmd=CommandParser::CmdParser.new(ARGV) do usage "`oneimage` [] []" @@ -45,6 +46,8 @@ cmd=CommandParser::CmdParser.new(ARGV) do list_options << OpenNebulaHelper::XML list_options << OpenNebulaHelper::NUMERIC + CREATE_OPTIONS = [OneDatastoreHelper::DATASTORE] + ######################################################################## # Formatters for arguments ######################################################################## @@ -56,10 +59,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do OpenNebulaHelper.rname_to_id(arg, "USER") end - set :format, :datastoreid, OpenNebulaHelper.rname_to_id_desc("DATASTORE") do |arg| - OpenNebulaHelper.rname_to_id(arg, "DATASTORE") - end - set :format, :imageid, OneImageHelper.to_id_desc do |arg| helper.to_id(arg) end @@ -80,10 +79,20 @@ cmd=CommandParser::CmdParser.new(ARGV) do Creates a new Image from the given template file EOT - command :create, create_desc, :file, :datastoreid do + command :create, create_desc, :file, :options=>CREATE_OPTIONS do + if options[:datastore].nil? + STDERR.puts "Datastore to save the image is mandatory: " + STDERR.puts "\t -d datastore_id" + exit -1 + end helper.create_resource(options) do |image| - template=File.read(args[0]) - image.allocate(template, args[1]) + begin + template=File.read(args[0]) + image.allocate(template, options[:datastore] ) + rescue => e + STDERR.puts e.messsage + exit -1 + end end end From d1012c8146c5e767715282b77ef74597bc79fe88 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Sat, 10 Mar 2012 17:47:15 +0100 Subject: [PATCH 155/217] Feature #1112: Add datastores to Sunstone --- install.sh | 2 + src/sunstone/etc/sunstone-plugins.yaml | 4 + src/sunstone/models/OpenNebulaJSON.rb | 1 + .../models/OpenNebulaJSON/DatastoreJSON.rb | 48 +- .../models/OpenNebulaJSON/ImageJSON.rb | 7 +- .../models/OpenNebulaJSON/PoolJSON.rb | 1 + src/sunstone/models/SunstoneServer.rb | 19 +- src/sunstone/public/js/opennebula.js | 42 ++ src/sunstone/public/js/plugins/acls-tab.js | 10 +- .../public/js/plugins/clusters-tab.js | 4 +- .../public/js/plugins/datastores-tab.js | 657 ++++++++++++++++++ src/sunstone/public/js/plugins/hosts-tab.js | 11 +- src/sunstone/public/js/plugins/images-tab.js | 32 +- .../public/js/plugins/templates-tab.js | 23 +- src/sunstone/public/js/plugins/vms-tab.js | 1 - src/sunstone/public/js/plugins/vnets-tab.js | 2 +- src/sunstone/public/js/sunstone-util.js | 6 + 17 files changed, 810 insertions(+), 60 deletions(-) create mode 100644 src/sunstone/public/js/plugins/datastores-tab.js diff --git a/install.sh b/install.sh index 8ca6422020..d5de5583f0 100755 --- a/install.sh +++ b/install.sh @@ -1118,6 +1118,7 @@ SUNSTONE_MODELS_JSON_FILES="src/sunstone/models/OpenNebulaJSON/HostJSON.rb \ src/sunstone/models/OpenNebulaJSON/TemplateJSON.rb \ src/sunstone/models/OpenNebulaJSON/AclJSON.rb \ src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb \ + src/sunstone/models/OpenNebulaJSON/DatastoreJSON.rb \ src/sunstone/models/OpenNebulaJSON/VirtualNetworkJSON.rb" SUNSTONE_TEMPLATE_FILES="src/sunstone/templates/login.html \ @@ -1137,6 +1138,7 @@ SUNSTONE_PUBLIC_JS_PLUGINS_FILES="\ src/sunstone/public/js/plugins/dashboard-users-tab.js \ src/sunstone/public/js/plugins/hosts-tab.js \ src/sunstone/public/js/plugins/clusters-tab.js \ + src/sunstone/public/js/plugins/datastores-tab.js \ src/sunstone/public/js/plugins/groups-tab.js \ src/sunstone/public/js/plugins/images-tab.js \ src/sunstone/public/js/plugins/templates-tab.js \ diff --git a/src/sunstone/etc/sunstone-plugins.yaml b/src/sunstone/etc/sunstone-plugins.yaml index d08072929d..ff4d2aaac3 100644 --- a/src/sunstone/etc/sunstone-plugins.yaml +++ b/src/sunstone/etc/sunstone-plugins.yaml @@ -23,6 +23,10 @@ :ALL: true :user: :group: +- plugins/datastores-tab.js: + :ALL: true + :user: + :group: - plugins/templates-tab.js: :ALL: true :user: diff --git a/src/sunstone/models/OpenNebulaJSON.rb b/src/sunstone/models/OpenNebulaJSON.rb index 60b0ab116c..7055b7a302 100644 --- a/src/sunstone/models/OpenNebulaJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON.rb @@ -28,6 +28,7 @@ require 'OpenNebulaJSON/UserJSON' require 'OpenNebulaJSON/VirtualMachineJSON' require 'OpenNebulaJSON/VirtualNetworkJSON' require 'OpenNebulaJSON/AclJSON' +require 'OpenNebulaJSON/DatastoreJSON' module OpenNebula class Error diff --git a/src/sunstone/models/OpenNebulaJSON/DatastoreJSON.rb b/src/sunstone/models/OpenNebulaJSON/DatastoreJSON.rb index 554f901b38..095f30d61a 100644 --- a/src/sunstone/models/OpenNebulaJSON/DatastoreJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/DatastoreJSON.rb @@ -17,23 +17,27 @@ require 'OpenNebulaJSON/JSONUtils' module OpenNebulaJSON - class ClusterJSON < OpenNebula::Datastore + class DatastoreJSON < OpenNebula::Datastore include JSONUtils - def create(template_json, cluster_id=ClusterPool::NONE_CLUSTER_ID) - datastore_hash = parse_json(template_json, 'datastore') - - if OpenNebula.is_error?(datastore_hash) - return datastore_hash + def create(template_json) + ds_hash = parse_json(template_json, 'datastore') + if OpenNebula.is_error?(ds_hash) + return ds_hash end - if datastore_hash['datastore_raw'] - template = datastore_hash['image_raw'] + cluster_id = parse_json(template_json, 'cluster_id') + if OpenNebula.is_error?(cluster_id) + return cluster_id + end + + if ds_hash['datastore_raw'] + template = ds_hash['datastore_raw'] else - template = template_to_str(datastore_hash) + template = template_to_str(ds_hash) end - self.allocate(template,cluster_id) + self.allocate(template,cluster_id.to_i) end def perform_action(template_json) @@ -42,9 +46,27 @@ module OpenNebulaJSON return action_hash end - error_msg = "#{action_hash['perform']} action not " << - " available for this resource" - OpenNebula::Error.new(error_msg) + rc = case action_hash['perform'] + when "update" then self.update(action_hash['params']) + when "chown" then self.chown(action_hash['params']) + when "chmod" then self.chmod_octet(action_hash['params']) + else + error_msg = "#{action_hash['perform']} action not " << + " available for this resource" + OpenNebula::Error.new(error_msg) + end + end + + def update(params=Hash.new) + super(params['template_raw']) + end + + def chown(params=Hash.new) + super(params['owner_id'].to_i,params['group_id'].to_i) + end + + def chmod_octet(params=Hash.new) + super(params['octet']) end end end diff --git a/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb b/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb index 8a5f0a0d35..11c03966ee 100644 --- a/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb @@ -26,13 +26,18 @@ module OpenNebulaJSON return image_hash end + ds_id = parse_json(template_json, 'ds_id') + if OpenNebula.is_error?(ds_id) + return ds_id + end + if image_hash['image_raw'] template = image_hash['image_raw'] else template = template_to_str(image_hash) end - self.allocate(template) + self.allocate(template,ds_id) end def perform_action(template_json) diff --git a/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb b/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb index fe8e67dcfd..791b723645 100644 --- a/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb @@ -26,4 +26,5 @@ module OpenNebulaJSON class UserPoolJSON < OpenNebula::UserPool; include JSONUtils; end class AclPoolJSON < OpenNebula::AclPool; include JSONUtils; end class ClusterPoolJSON < OpenNebula::ClusterPool; include JSONUtils; end + class DatastorePoolJSON < OpenNebula::DatastorePool; include JSONUtils; end end diff --git a/src/sunstone/models/SunstoneServer.rb b/src/sunstone/models/SunstoneServer.rb index 7a64255bb6..fba385ec96 100644 --- a/src/sunstone/models/SunstoneServer.rb +++ b/src/sunstone/models/SunstoneServer.rb @@ -56,6 +56,7 @@ class SunstoneServer < CloudServer when "vnet" then VirtualNetworkPoolJSON.new(@client, user_flag) when "user" then UserPoolJSON.new(@client) when "acl" then AclPoolJSON.new(@client) + when "datastore" then DatastorePoolJSON.new(@client) else error = Error.new("Error: #{kind} resource not supported") return [404, error.to_json] @@ -109,6 +110,7 @@ class SunstoneServer < CloudServer when "vnet" then VirtualNetworkJSON.new(VirtualNetwork.build_xml, @client) when "user" then UserJSON.new(User.build_xml, @client) when "acl" then AclJSON.new(Acl.build_xml, @client) + when "datastore" then DatastoreJSON.new(Acl.build_xml, @client) else error = Error.new("Error: #{kind} resource not supported") return [404, error.to_json] @@ -276,15 +278,16 @@ class SunstoneServer < CloudServer ############################################################################ def retrieve_resource(kind, id) resource = case kind - when "group" then GroupJSON.new_with_id(id, @client) - when "cluster" then ClusterJSON.new_with_id(id, @client) - when "host" then HostJSON.new_with_id(id, @client) - when "image" then ImageJSON.new_with_id(id, @client) + when "group" then GroupJSON.new_with_id(id, @client) + when "cluster" then ClusterJSON.new_with_id(id, @client) + when "host" then HostJSON.new_with_id(id, @client) + when "image" then ImageJSON.new_with_id(id, @client) when "vmtemplate" then TemplateJSON.new_with_id(id, @client) - when "vm" then VirtualMachineJSON.new_with_id(id, @client) - when "vnet" then VirtualNetworkJSON.new_with_id(id, @client) - when "user" then UserJSON.new_with_id(id, @client) - when "acl" then AclJSON.new_with_id(id, @client) + when "vm" then VirtualMachineJSON.new_with_id(id, @client) + when "vnet" then VirtualNetworkJSON.new_with_id(id, @client) + when "user" then UserJSON.new_with_id(id, @client) + when "acl" then AclJSON.new_with_id(id, @client) + when "datastore" then DatastoreJSON.new_with_id(id, @client) else error = Error.new("Error: #{kind} resource not supported") return error diff --git a/src/sunstone/public/js/opennebula.js b/src/sunstone/public/js/opennebula.js index 560170b6ea..eb4f149d30 100644 --- a/src/sunstone/public/js/opennebula.js +++ b/src/sunstone/public/js/opennebula.js @@ -866,6 +866,9 @@ var OpenNebula = { "list" : function(params){ OpenNebula.Action.list(params,OpenNebula.Cluster.resource); }, + "show" : function(params){ + OpenNebula.Action.show(params,OpenNebula.Cluster.resource); + }, "addhost" : function(params){ var action_obj = { "host_id": params.data.extra_param }; OpenNebula.Action.simple_action(params,OpenNebula.Cluster.resource, @@ -897,4 +900,43 @@ var OpenNebula = { "delvnet",action_obj); }, }, + "Datastore" : { + "resource" : "DATASTORE", + + "create" : function(params){ + OpenNebula.Action.create(params,OpenNebula.Datastore.resource); + }, + "delete" : function(params){ + OpenNebula.Action.delete(params,OpenNebula.Datastore.resource); + }, + "list" : function(params){ + OpenNebula.Action.list(params,OpenNebula.Datastore.resource); + }, + "show" : function(params){ + OpenNebula.Action.show(params,OpenNebula.Datastore.resource); + }, + "chown" : function(params){ + OpenNebula.Action.chown(params,OpenNebula.Datastore.resource); + }, + "chgrp" : function(params){ + OpenNebula.Action.chgrp(params,OpenNebula.Datastore.resource); + }, + "chmod" : function(params){ + var action_obj = params.data.extra_param; + OpenNebula.Action.simple_action(params, + OpenNebula.Datastore.resource, + "chmod", + action_obj); + }, + "update" : function(params){ + var action_obj = {"template_raw" : params.data.extra_param }; + OpenNebula.Action.simple_action(params, + OpenNebula.Datastore.resource, + "update", + action_obj); + }, + "fetch_template" : function(params){ + OpenNebula.Action.show(params,OpenNebula.Datastore.resource,"template"); + }, + }, } diff --git a/src/sunstone/public/js/plugins/acls-tab.js b/src/sunstone/public/js/plugins/acls-tab.js index 9216424a7b..8688c3be92 100644 --- a/src/sunstone/public/js/plugins/acls-tab.js +++ b/src/sunstone/public/js/plugins/acls-tab.js @@ -45,8 +45,10 @@ var create_acl_tmpl = \ \
\ - \ + \ '+tr("Hosts")+'
\ + '+tr("Clusters")+'
\ + '+tr("Datastores")+'
\ '+tr("Virtual Machines")+'
\ '+tr("Virtual Networks")+'
\ '+tr("Images")+'
\ @@ -247,6 +249,12 @@ function parseAclString(string) { case "GROUP": resources_str+=tr("Groups")+", "; break; + case "CLUSTER": + resources_str+=tr("Clusters")+", "; + break; + case "DATASTORE": + resources_str+=tr("Datastores")+", "; + break; }; }; //remove ", " from end diff --git a/src/sunstone/public/js/plugins/clusters-tab.js b/src/sunstone/public/js/plugins/clusters-tab.js index 3d4a2079ca..0a9a90c52a 100644 --- a/src/sunstone/public/js/plugins/clusters-tab.js +++ b/src/sunstone/public/js/plugins/clusters-tab.js @@ -128,7 +128,7 @@ var cluster_actions = { "Cluster.adddatastore" : { type: "single", - call : OpenNebula.Cluster.addhost, + call : OpenNebula.Cluster.adddatastore, callback : function (req) { Sunstone.runAction("Datastore.show",req.request.data[0][1].ds_id); //Sunstone.runAction("Cluster.show",req.request.data[0]); @@ -138,7 +138,7 @@ var cluster_actions = { "Cluster.deldatastore" : { type: "single", - call : OpenNebula.Cluster.addhost, + call : OpenNebula.Cluster.deldatastore, callback : function (req) { //Sunstone.runAction("Cluster.show",req.request.data[0]); }, diff --git a/src/sunstone/public/js/plugins/datastores-tab.js b/src/sunstone/public/js/plugins/datastores-tab.js new file mode 100644 index 0000000000..603fd6867e --- /dev/null +++ b/src/sunstone/public/js/plugins/datastores-tab.js @@ -0,0 +1,657 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +/*Datastore tab plugin*/ + + +var datastores_tab_content = +'
\ +
\ +
\ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
' + tr("All") + ''+tr("ID")+''+tr("Owner")+''+tr("Group")+''+tr("Name")+''+tr("Cluster")+'
\ +
'; + +var create_datastore_tmpl = +'
\ +
\ + \ + \ + \ + \ + \ + \ + \ + \ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
'; + +var update_datastore_tmpl = + '
\ +

'+tr("Please, choose and modify the datastore you want to update")+':

\ +
\ + \ + \ +
\ +
\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
'+tr("Permissions")+':'+tr("Use")+''+tr("Manage")+''+tr("Admin")+'
'+tr("Owner")+'
'+tr("Group")+'
'+tr("Other")+'
\ +
\ + \ +
\ + \ +
\ +
\ +
\ + \ +
\ +
\ +
'; + +var datastores_select=""; +var dataTable_datastores; +var $create_datastore_dialog; + +//Setup actions +var datastore_actions = { + + "Datastore.create" : { + type: "create", + call : OpenNebula.Datastore.create, + callback : addDatastoreElement, + error : onError, + notify: true + }, + + "Datastore.create_dialog" : { + type: "custom", + call: popUpCreateDatastoreDialog + }, + + "Datastore.list" : { + type: "list", + call: OpenNebula.Datastore.list, + callback: updateDatastoresView, + error: onError + }, + + "Datastore.show" : { + type: "single", + call: OpenNebula.Datastore.show, + callback: updateDatastoreElement, + error: onError + }, + + "Datastore.showinfo" : { + type: "single", + call: OpenNebula.Datastore.show, + callback: updateDatastoreInfo, + error: onError + }, + + "Datastore.refresh" : { + type: "custom", + call: function(){ + waitingNodes(dataTable_datastores); + Sunstone.runAction("Datastore.list"); + }, + error: onError + }, + + "Datastore.fetch_template" : { + type: "single", + call: OpenNebula.Datastore.fetch_template, + callback: function (request,response) { + $('#datastore_template_update_dialog #datastore_template_update_textarea').val(response.template); + }, + error: onError + }, + + "Datastore.fetch_permissions" : { + type: "single", + call: OpenNebula.Datastore.show, + callback: function(request,element_json){ + var dialog = $('#datastore_template_update_dialog form'); + var ds = element_json.DATASTORE; + setPermissionsTable(ds,dialog); + }, + error: onError + }, + + "Datastore.update_dialog" : { + type: "custom", + call: popUpDatastoreTemplateUpdateDialog, + }, + + "Datastore.update" : { + type: "single", + call: OpenNebula.Datastore.update, + callback: function() { + notifyMessage(tr("Datastore updated correctly")); + }, + error: onError + }, + + "Datastore.autorefresh" : { + type: "custom", + call : function() { + OpenNebula.Datastore.list({timeout: true, success: updateDatastoresView,error: onError}); + } + }, + + "Datastore.delete" : { + type: "multiple", + call : OpenNebula.Datastore.delete, + callback : deleteDatastoreElement, + elements: datastoreElements, + error : onError, + notify:true + }, + + "Datastore.chown" : { + type: "multiple", + call: OpenNebula.Datastore.chown, + callback: function (req) { + Sunstone.runAction("Datastore.show",req.request.data[0][0]); + }, + elements: datastoreElements, + error: onError, + notify: true + }, + + "Datastore.chgrp" : { + type: "multiple", + call: OpenNebula.Datastore.chgrp, + callback: function (req) { + Sunstone.runAction("Datastore.show",req.request.data[0][0]); + }, + elements: datastoreElements, + error: onError, + notify: true + }, + + "Datastore.chmod" : { + type: "single", + call: OpenNebula.Datastore.chmod, +// callback + error: onError, + notify: true + }, + + "Datastore.addtocluster" : { + type: "multiple", + call: function(params){ + var cluster = params.data.extra_param; + var ds = params.data.id; + Sunstone.runAction("Cluster.adddatastore",cluster,ds); + }, + elements: datastoreElements, + notify:true, + }, + +}; + +var datastore_buttons = { + "Datastore.refresh" : { + type: "image", + text: tr("Refresh list"), + img: "images/Refresh-icon.png" + }, + "Datastore.create_dialog" : { + type: "create_dialog", + text: tr("+ New") + }, + "Datastore.update_dialog" : { + type: "action", + text: tr("Update properties"), + alwaysActive: true + }, + "Datastore.addtocluster" : { + type: "confirm_with_select", + text: tr("Select cluster"), + select: clusters_sel, + tip: tr("Select the destination cluster:"), + }, + "Datastore.chown" : { + type: "confirm_with_select", + text: tr("Change owner"), + select: users_sel, + tip: tr("Select the new owner")+":", + condition: mustBeAdmin + }, + "Datastore.chgrp" : { + type: "confirm_with_select", + text: tr("Change group"), + select: groups_sel, + tip: tr("Select the new group")+":", + condition: mustBeAdmin + }, + "Datastore.delete" : { + type: "confirm", + text: tr("Delete") + } +} + +var datastore_info_panel = { + "datastore_info_tab" : { + title: tr("Datastore information"), + content: "" + }, + "datastore_template_tab" : { + title: tr("Datastore template"), + content: "" + }, +} + +var datastores_tab = { + title: tr("Datastores"), + content: datastores_tab_content, + buttons: datastore_buttons +} + +Sunstone.addActions(datastore_actions); +Sunstone.addMainTab('datastores_tab',datastores_tab); +Sunstone.addInfoPanel('datastore_info_panel',datastore_info_panel); + + +function datastoreElements() { + return getSelectedNodes(dataTable_datastores); +} + +function vmShow(req) { + Sunstone.runAction("Datastore.show",req.request.data[0]); +} + +function datastoreElementArray(element_json){ + var element = element_json.DATASTORE; + + return [ + '', + element.ID, + element.UNAME, + element.GNAME, + element.NAME, + element.CLUSTER + ]; +} + +function datastoreInfoListener(){ + + $('#tbodydatastores tr',dataTable_datastores).live("click", function(e){ + if ($(e.target).is('input') || $(e.target).is('a img')) {return true;} + + var aData = dataTable_datastores.fnGetData(this); + var id = $(aData[0]).val(); + if (!id) return true; + + popDialogLoading(); + Sunstone.runAction("Datastore.showinfo",id); + return false; + }); +} + +function updateDatastoreElement(request, element_json){ + var id = element_json.DATASTORE.ID; + var element = datastoreElementArray(element_json); + updateSingleElement(element,dataTable_datastores,'#datastore_'+id) +} + +function deleteDatastoreElement(request){ + deleteElement(dataTable_datastores,'#datastore_'+request.request.data); +} + +function addDatastoreElement(request,element_json){ + var id = element_json.DATASTORE.ID; + var element = datastoreElementArray(element_json); + addElement(element,dataTable_datastores); +} + + +function updateDatastoresView(request, list){ + var list_array = []; + + $.each(list,function(){ + list_array.push( datastoreElementArray(this)); + }); + + updateView(list_array,dataTable_datastores); + updateDashboard("datastores",list); +} + + +function updateDatastoreInfo(request,ds){ + var info = ds.DATASTORE; + + var info_tab = { + title : tr("Datastore information"), + content: + '\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
'+tr("Datastore information")+' - '+info.NAME+'
'+tr("ID")+''+info.ID+'
'+tr("Name")+''+info.NAME+'
'+tr("Owner")+''+info.UNAME+'
'+tr("Group")+''+info.GNAME+'
'+tr("Cluster")+''+info.CLUSTER+'
'+tr("DS Mad")+''+info.DS_MAD+'
'+tr("TM Mad")+''+ info.TM_MAD +'
'+tr("Base path")+''+info.BASE_PATH+'
'+tr("Permissions")+'
     '+tr("Owner")+''+ownerPermStr(info)+'
     '+tr("Group")+''+groupPermStr(info)+'
     '+tr("Other")+''+otherPermStr(info)+'
' + } + + var template_tab = { + title: tr("Datastore Template"), + content: + '\ + '+ + prettyPrintJSON(info.TEMPLATE)+ + '
'+tr("Datastore template")+'
' + } + + Sunstone.updateInfoPanelTab("datastore_info_panel","datastore_info_tab",info_tab); + Sunstone.updateInfoPanelTab("datastore_info_panel","datastore_template_tab",template_tab); + Sunstone.popUpInfoPanel("datastore_info_panel"); +} + +// Sets up the create-template dialog and all the processing associated to it, +// which is a lot. +function setupCreateDatastoreDialog(){ + + dialogs_context.append('
'); + //Insert HTML in place + $create_datastore_dialog = $('#create_datastore_dialog') + var dialog = $create_datastore_dialog; + dialog.html(create_datastore_tmpl); + + //Prepare jquery dialog + dialog.dialog({ + autoOpen: false, + modal: true, + width: 400 + }); + + $('button',dialog).button(); + setupTips(dialog); + + $('#create_datastore_form',dialog).submit(function(){ + var name = $('#name',this).val(); + var cluster_id = $('#cluster_id',this).val(); + var ds_mad = $('#ds_mad',this).val(); + var tm_mad = $('#tm_mad',this).val(); + + if (!name){ + notifyError("Please provide a name"); + return false; + }; + + var ds_obj = { + "datastore" : { + "name" : name, + "ds_mad" : ds_mad, + "tm_mad" : tm_mad + }, + "cluster_id" : cluster_id + }; + + Sunstone.runAction("Datastore.create",ds_obj); + + $create_datastore_dialog.dialog('close'); + return false; + }); +} + +function popUpCreateDatastoreDialog(){ + $('select#cluster_id',$create_datastore_dialog).html(clusters_sel()); + $create_datastore_dialog.dialog('open'); +} + +function setupDatastoreTemplateUpdateDialog(){ + //Append to DOM + dialogs_context.append('
'); + var dialog = $('#datastore_template_update_dialog',dialogs_context); + + //Put HTML in place + dialog.html(update_datastore_tmpl); + + var height = Math.floor($(window).height()*0.8); //set height to a percentage of the window + + //Convert into jQuery + dialog.dialog({ + autoOpen:false, + width:500, + modal:true, + height:height, + resizable:true, + }); + + $('button',dialog).button(); + + $('#datastore_template_update_select',dialog).change(function(){ + var id = $(this).val(); + $('.permissions_table input',dialog).removeAttr('checked'); + $('.permissions_table',dialog).removeAttr('update'); + if (id && id.length){ + var dialog = $('#datastore_template_update_dialog'); + $('#template_template_update_textarea',dialog).val(tr("Loading")+"..."); + Sunstone.runAction("Datastore.fetch_template",id); + Sunstone.runAction("Datastore.fetch_permissions",id); + } else { + $('#datastore_template_update_textarea',dialog).val(""); + }; + }); + + $('.permissions_table input',dialog).change(function(){ + $(this).parents('table').attr('update','update'); + }); + + $('form',dialog).submit(function(){ + var dialog = $(this); + var new_template = $('#datastore_template_update_textarea',dialog).val(); + var id = $('#datastore_template_update_select',dialog).val(); + if (!id || !id.length) { + $(this).parents('#datastore_template_update_dialog').dialog('close'); + return false; + }; + + var permissions = $('.permissions_table',dialog); + if (permissions.attr('update')){ + var perms = { + octet : buildOctet(permissions) + }; + Sunstone.runAction("Datastore.chmod",id,perms); + }; + + Sunstone.runAction("Datastore.update",id,new_template); + $(this).parents('#datastore_template_update_dialog').dialog('close'); + return false; + }); +}; + +function popUpDatastoreTemplateUpdateDialog(){ + var select = makeSelectOptions(dataTable_datastores, + 1,//id_col + 4,//name_col + [], + [] + ); + var sel_elems = getSelectedNodes(dataTable_datastores); + + + var dialog = $('#datastore_template_update_dialog'); + $('#datastore_template_update_select',dialog).html(select); + $('#datastore_template_update_textarea',dialog).val(""); + $('.permissions_table input',dialog).removeAttr('checked'); + $('.permissions_table',dialog).removeAttr('update'); + + if (sel_elems.length >= 1){ //several items in the list are selected + //grep them + var new_select= sel_elems.length > 1? '' : ""; + $('option','').each(function(){ + var val = $(this).val(); + if ($.inArray(val,sel_elems) >= 0){ + new_select+=''; + }; + }); + $('#datastore_template_update_select',dialog).html(new_select); + if (sel_elems.length == 1) { + $('#datastore_template_update_select option',dialog).attr('selected','selected'); + $('#datastore_template_update_select',dialog).trigger("change"); + }; + }; + + dialog.dialog('open'); + return false; +}; + +//Prepares autorefresh +function setDatastoreAutorefresh(){ + setInterval(function(){ + var checked = $('input.check_item:checked',dataTable_datastores); + var filter = $("#datatable_datastores_filter input", + dataTable_datastores.parents('#datatable_datastores_wrapper')).attr('value'); + if (!checked.length && !filter.length){ + Sunstone.runAction("Datastore.autorefresh"); + }; + },INTERVAL+someTime()); +} + + +$(document).ready(function(){ + + dataTable_datastores = $("#datatable_datastores",main_tabs_context).dataTable({ + "bJQueryUI": true, + "bSortClasses": false, + "sPaginationType": "full_numbers", + "bAutoWidth":false, + "aoColumnDefs": [ + { "bSortable": false, "aTargets": ["check"] }, + { "sWidth": "60px", "aTargets": [0] }, + { "sWidth": "35px", "aTargets": [1] }, + { "sWidth": "100px", "aTargets": [2,3,5] } + ], + "oLanguage": (datatable_lang != "") ? + { + sUrl: "locale/"+lang+"/"+datatable_lang + } : "" + }); + + dataTable_datastores.fnClearTable(); + addElement([ + spinner, + '','','','',''],dataTable_datastores); + Sunstone.runAction("Datastore.list"); + + setupCreateDatastoreDialog(); + setupDatastoreTemplateUpdateDialog(); + setDatastoreAutorefresh(); + + initCheckAllBoxes(dataTable_datastores); + tableCheckboxesListener(dataTable_datastores); + datastoreInfoListener(); +}) \ No newline at end of file diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 2d87e1585f..084434343c 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -321,11 +321,6 @@ var hosts_tab = { buttons: host_buttons } -//Hack since this plugin is loaded earlier -function clusters_sel() { - return clusters_select; -} - Sunstone.addActions(host_actions); Sunstone.addMainTab('hosts_tab',hosts_tab); Sunstone.addInfoPanel("host_info_panel",host_info_panel); @@ -607,7 +602,7 @@ function setupCreateHostDialog(){ //Open creation dialogs function popUpCreateHostDialog(){ - $('#host_cluster_id',$create_host_dialog).html(clusters_select); + $('#host_cluster_id',$create_host_dialog).html(clusters_sel()); $create_host_dialog.dialog('open'); return false; } @@ -632,10 +627,6 @@ function hostMonitorError(req,error_json){ $('#host_monitoring_tab '+id).html('
'+message+'
'); } -function hosts_sel() { - return hosts_select; -} - //This is executed after the sunstone.js ready() is run. //Here we can basicly init the host datatable, preload it //and add specific listeners diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index 02e441da56..ad8d818883 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -28,6 +28,7 @@ var images_tab_content = '+tr("Owner")+'\ '+tr("Group")+'\ '+tr("Name")+'\ + '+tr("Datastore")+'\ '+tr("Size")+'\ '+tr("Type")+'\ '+tr("Registration time")+'\ @@ -316,7 +317,7 @@ var image_actions = { type: "single", call: OpenNebula.Image.update, callback: function() { - notifyMessage(tr("Template updated correctly")); + notifyMessage(tr("Image updated correctly")); }, error: onError }, @@ -378,7 +379,7 @@ var image_actions = { type: "multiple", call: OpenNebula.Image.chown, callback: function (req) { - Sunstone.runAction("Image.show",req.request.data[0]); + Sunstone.runAction("Image.show",req.request.data[0][0]); }, elements: imageElements, error: onError, @@ -389,7 +390,7 @@ var image_actions = { type: "multiple", call: OpenNebula.Image.chgrp, callback: function (req) { - Sunstone.runAction("Image.show",req.request.data[0]); + Sunstone.runAction("Image.show",req.request.data[0][0]); }, elements: imageElements, error: onError, @@ -522,6 +523,7 @@ function imageElementArray(image_json){ image.UNAME, image.GNAME, image.NAME, + image.DATASTORE, image.SIZE, '', pretty_time(image.REGTIME), @@ -599,6 +601,10 @@ function updateImageInfo(request,img){ '+tr("Name")+'\ '+img_info.NAME+'\ \ + \ + '+tr("Datastore")+'\ + '+img_info.DATASTORE+'\ + \ \ '+tr("Owner")+'\ '+img_info.UNAME+'\ @@ -643,7 +649,7 @@ function updateImageInfo(request,img){ '+tr("Running #VMS")+'\ '+img_info.RUNNING_VMS+'\ \ - Permissions\ + '+tr("Permissions")+'\ \      '+tr("Owner")+'\ '+ownerPermStr(img_info)+'\ @@ -843,6 +849,9 @@ function setupCreateImageDialog(){ } }); if (exit) { return false; } + + var ds_id = $('#img_ds_id',this).val(); + var img_json = {}; var name = $('#img_name',this).val(); @@ -897,8 +906,9 @@ function setupCreateImageDialog(){ img_json[attr_name] = attr_value; }); - - img_obj = { "image" : img_json }; + ds_id = 1; + img_obj = { "image" : img_json, + "ds_id" : ds_id}; if (upload){ uploader._onInputChange(file_input); @@ -1094,10 +1104,10 @@ $(document).ready(function(){ "sPaginationType": "full_numbers", "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, - { "sWidth": "60px", "aTargets": [0,2,3,8,9] }, - { "sWidth": "35px", "aTargets": [1,5,10] }, - { "sWidth": "100px", "aTargets": [6] }, - { "sWidth": "150px", "aTargets": [7] } + { "sWidth": "60px", "aTargets": [0,2,3,9,10] }, + { "sWidth": "35px", "aTargets": [1,6,11] }, + { "sWidth": "100px", "aTargets": [5,7] }, + { "sWidth": "150px", "aTargets": [8] } ], "oLanguage": (datatable_lang != "") ? { @@ -1108,7 +1118,7 @@ $(document).ready(function(){ dataTable_images.fnClearTable(); addElement([ spinner, - '','','','','','','','','',''],dataTable_images); + '','','','','','','','','','',''],dataTable_images); Sunstone.runAction("Image.list"); setupCreateImageDialog(); diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index 5375aaf892..f4f1f8a28e 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -599,21 +599,21 @@ var update_template_tmpl = '+tr("Admin")+'\ \ '+tr("Owner")+'\ - \ - \ - \ + \ + \ + \ \ \ '+tr("Group")+'\ - \ - \ - \ + \ + \ + \ \ \ '+tr("Other")+'\ - \ - \ - \ + \ + \ + \ \ \ \ @@ -624,7 +624,7 @@ var update_template_tmpl =
\
\ \
\
\ @@ -956,7 +956,7 @@ function updateTemplateInfo(request,template){ '+tr("Register time")+'\ '+pretty_time(template_info.REGTIME)+'\ \ - Permissions\ + '+tr("Permissions")+'\ \      '+tr("Owner")+'\ '+ownerPermStr(template_info)+'\ @@ -2088,7 +2088,6 @@ function setupTemplateTemplateUpdateDialog(){ Sunstone.runAction("Template.update",id,new_template); $(this).parents('#template_template_update_dialog').dialog('close'); - dialog.dialog('close'); return false; }); }; diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index cfb477c9c7..ae2364a0e6 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -1302,7 +1302,6 @@ $(document).ready(function(){ setupSaveasDialog(); setVMAutorefresh(); setupVNC(); - setupTips initCheckAllBoxes(dataTable_vMachines); tableCheckboxesListener(dataTable_vMachines); diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index 3cc3aff2df..b9b63a21b7 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -587,7 +587,7 @@ function updateVNetworkInfo(request,vn){ '+tr("VLAN ID")+'\ '+ (typeof(vn_info.VLAN_ID) == "object" ? "--": vn_info.VLAN_ID) +'\ \ - Permissions\ + '+tr("Permissions")+'\ \      '+tr("Owner")+'\ '+ownerPermStr(vn_info)+'\ diff --git a/src/sunstone/public/js/sunstone-util.js b/src/sunstone/public/js/sunstone-util.js index 24a4cf81ae..02a060b5d3 100644 --- a/src/sunstone/public/js/sunstone-util.js +++ b/src/sunstone/public/js/sunstone-util.js @@ -751,6 +751,12 @@ function hosts_sel(){ return hosts_select; } +function clusters_sel() { + return clusters_select; +} + + + function ownerUse(resource){ return parseInt(resource.PERMISSIONS.OWNER_U); }; From b20a063d7f13f136f06e97137638dc134262c552 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 12 Mar 2012 12:45:38 +0100 Subject: [PATCH 156/217] Feature #1112: Update Sunstone dashboards, allow DS select on image creation, list images in DS in extended info and various small bugfixes. --- .../models/OpenNebulaJSON/ImageJSON.rb | 2 +- src/sunstone/models/SunstoneServer.rb | 15 +++++++- .../public/js/plugins/dashboard-tab.js | 22 ++++++++++-- .../public/js/plugins/dashboard-users-tab.js | 14 +++++++- .../public/js/plugins/datastores-tab.js | 35 +++++++++++++++++-- src/sunstone/public/js/plugins/images-tab.js | 15 ++++++-- src/sunstone/public/js/plugins/vnets-tab.js | 1 + src/sunstone/public/js/sunstone-util.js | 19 +++++++--- 8 files changed, 109 insertions(+), 14 deletions(-) diff --git a/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb b/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb index 11c03966ee..99a0bdf04b 100644 --- a/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb @@ -37,7 +37,7 @@ module OpenNebulaJSON template = template_to_str(image_hash) end - self.allocate(template,ds_id) + self.allocate(template,ds_id.to_i) end def perform_action(template_json) diff --git a/src/sunstone/models/SunstoneServer.rb b/src/sunstone/models/SunstoneServer.rb index fba385ec96..2739d9b2b4 100644 --- a/src/sunstone/models/SunstoneServer.rb +++ b/src/sunstone/models/SunstoneServer.rb @@ -130,9 +130,22 @@ class SunstoneServer < CloudServer ############################################################################ def upload(template, file_path) image_hash = parse_json(template, 'image') + if OpenNebula.is_error?(image_hash) + return [500, image_hash.to_json] + end + image_hash['PATH'] = file_path - new_template = {:image => image_hash}.to_json + ds_id = parse_json(template, 'ds_id') + if OpenNebula.is_error?(ds_id) + return [500, ds_id.to_json] + end + + new_template = { + :image => image_hash, + :ds_id => ds_id, + }.to_json + image = ImageJSON.new(Image.build_xml, @client) rc = image.create(new_template) diff --git a/src/sunstone/public/js/plugins/dashboard-tab.js b/src/sunstone/public/js/plugins/dashboard-tab.js index 362c51e347..06b931244b 100644 --- a/src/sunstone/public/js/plugins/dashboard-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-tab.js @@ -58,6 +58,10 @@ var dashboard_tab_content = ' + tr("Hosts (total/active)") + '\ \ \ + \ + ' + tr("Clusters") + '\ + \ + \ \ ' + tr("Groups") + '\ \ @@ -78,6 +82,10 @@ var dashboard_tab_content = ' + tr("Virtual Networks (total/public)") + '\ \ \ + \ + ' + tr("Datastores") + '\ + \ + \ \ ' + tr("Images (total/public)") + '\ \ @@ -102,11 +110,13 @@ var dashboard_tab_content =

' + tr("Quickstart") + '

\
\ \ \ \ + \ + \ + \ + \ \ \ \ @@ -85,7 +89,7 @@ var dashboard_tab_content =

'+tr("Quickstart")+'

\
\
\ -\ +\ ' + tr("Host") + '
\ + ' + tr("Cluster") + '
\ ' + tr("VM Instance") + '
\ ' + tr("VM Template") + '
\ - ' + tr("Virtual Network") + '
\ + ' + tr("Virtual Network") + '
\ + ' + tr("Datastore") + '
\ ' + tr("Image") + '
\ ' + tr("User") + '
\ ' + tr("Group") + '
\ @@ -316,5 +326,13 @@ function updateDashboard(what,json_info){ var total_acls=json_info.length; $('#total_acls',db).html(total_acls); break; + case "clusters": + var total_clusters=json_info.length; + $('#total_clusters',db).html(total_clusters); + break; + case "datastores": + var total_datastores=json_info.length; + $('#total_datastores',db).html(total_datastores); + break; } } diff --git a/src/sunstone/public/js/plugins/dashboard-users-tab.js b/src/sunstone/public/js/plugins/dashboard-users-tab.js index 4e602814be..f27ed855fb 100644 --- a/src/sunstone/public/js/plugins/dashboard-users-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-users-tab.js @@ -69,6 +69,10 @@ var dashboard_tab_content =
'+tr("Virtual Networks (total/public)")+'
' + tr("Datastores") + '
'+tr("Images (total/public)")+'
\ - \ + \ '+tr("VM Template")+'
\ '+tr("VM Instance")+'
\ '+tr("Virtual Network")+'
\ @@ -296,5 +300,13 @@ function updateDashboard(what,json_info){ var total_acls=json_info.length; $('#total_acls',db).html(total_acls); break; + case "clusters": + var total_clusters=json_info.length; + $('#total_clusters',db).html(total_clusters); + break; + case "datastores": + var total_datastores=json_info.length; + $('#total_datastores',db).html(total_datastores); + break; } } \ No newline at end of file diff --git a/src/sunstone/public/js/plugins/datastores-tab.js b/src/sunstone/public/js/plugins/datastores-tab.js index 603fd6867e..88afb16aab 100644 --- a/src/sunstone/public/js/plugins/datastores-tab.js +++ b/src/sunstone/public/js/plugins/datastores-tab.js @@ -265,7 +265,8 @@ var datastore_buttons = { }, "Datastore.create_dialog" : { type: "create_dialog", - text: tr("+ New") + text: tr("+ New"), + condition: mustBeAdmin, }, "Datastore.update_dialog" : { type: "action", @@ -277,6 +278,7 @@ var datastore_buttons = { text: tr("Select cluster"), select: clusters_sel, tip: tr("Select the destination cluster:"), + condition: mustBeAdmin, }, "Datastore.chown" : { type: "confirm_with_select", @@ -354,22 +356,34 @@ function datastoreInfoListener(){ Sunstone.runAction("Datastore.showinfo",id); return false; }); -} +}; + +function updateDatastoreSelect(){ + datastores_select = makeSelectOptions(dataTable_datastores, + 1, + 4, + [], + [] + ); +}; function updateDatastoreElement(request, element_json){ var id = element_json.DATASTORE.ID; var element = datastoreElementArray(element_json); updateSingleElement(element,dataTable_datastores,'#datastore_'+id) + updateDatastoreSelect(); } function deleteDatastoreElement(request){ deleteElement(dataTable_datastores,'#datastore_'+request.request.data); + updateDatastoreSelect(); } function addDatastoreElement(request,element_json){ var id = element_json.DATASTORE.ID; var element = datastoreElementArray(element_json); addElement(element,dataTable_datastores); + updateDatastoreSelect(); } @@ -381,17 +395,28 @@ function updateDatastoresView(request, list){ }); updateView(list_array,dataTable_datastores); + updateDatastoreSelect(); updateDashboard("datastores",list); } function updateDatastoreInfo(request,ds){ var info = ds.DATASTORE; + var images_str = ""; + if (info.IMAGES.ID && + info.IMAGES.ID.constructor == Array){ + for (var i=0; i\ + '\ \ \ \ @@ -428,6 +453,10 @@ function updateDatastoreInfo(request,ds){ \ \ \ + \ + \ + \ + \ \ \ \ diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index ad8d818883..ca5dd57182 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -63,6 +63,12 @@ var create_image_tmpl = \
'+tr("Human readable description of the image for other users.")+'
\ \ +
\ + \ + \ +
'+tr("Select the datastore for this image")+'
\ +
\ \
\
\ @@ -850,7 +856,11 @@ function setupCreateImageDialog(){ }); if (exit) { return false; } - var ds_id = $('#img_ds_id',this).val(); + var ds_id = $('#img_datastore',this).val(); + if (!ds_id){ + notifyError(tr("Please select a datastore for this image")); + return false; + }; var img_json = {}; @@ -906,7 +916,6 @@ function setupCreateImageDialog(){ img_json[attr_name] = attr_value; }); - ds_id = 1; img_obj = { "image" : img_json, "ds_id" : ds_id}; @@ -932,6 +941,8 @@ function popUpCreateImageDialog(){ $('#file-uploader input',$create_image_dialog).removeAttr("style"); $('#file-uploader input',$create_image_dialog).attr('style','margin:0;width:256px!important'); + $('#img_datastore',$create_image_dialog).html(datastores_sel()); + $create_image_dialog.dialog('open'); } diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index b9b63a21b7..f1865b92dc 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -419,6 +419,7 @@ var vnet_buttons = { text: tr("Select cluster"), select: clusters_sel, tip: tr("Select the destination cluster:"), + condition: mustBeAdmin, }, "Network.chown" : { type: "confirm_with_select", diff --git a/src/sunstone/public/js/sunstone-util.js b/src/sunstone/public/js/sunstone-util.js index 02a060b5d3..4b16656250 100644 --- a/src/sunstone/public/js/sunstone-util.js +++ b/src/sunstone/public/js/sunstone-util.js @@ -403,19 +403,26 @@ function waitingNodes(dataTable){ function getUserName(uid){ if (typeof(dataTable_users) != "undefined"){ - return getName(uid,dataTable_users); + return getName(uid,dataTable_users,2); } return uid; } function getGroupName(gid){ if (typeof(dataTable_groups) != "undefined"){ - return getName(gid,dataTable_groups); + return getName(gid,dataTable_groups,2); } return gid; } -function getName(id,dataTable){ +function getImageName(id){ + if (typeof(dataTable_images) != "undefined"){ + return getName(id,dataTable_images,4); + } + return id; +}; + +function getName(id,dataTable,name_col){ var name = id; if (typeof(dataTable) == "undefined") { return name; @@ -424,7 +431,7 @@ function getName(id,dataTable){ $.each(nodes,function(){ if (id == this[1]) { - name = this[2]; + name = this[name_col]; return false; } }); @@ -755,6 +762,10 @@ function clusters_sel() { return clusters_select; } +function datastores_sel() { + return datastores_select; +} + function ownerUse(resource){ From 5178369f0a3683110ef56ba9ca4f574902fefedb Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 12 Mar 2012 16:27:51 +0100 Subject: [PATCH 157/217] Feature #1112: Support improved submenus and menu expansion --- src/sunstone/public/css/layout.css | 16 +++++++--- src/sunstone/public/js/layout.js | 49 +++++++++++++++++++----------- src/sunstone/public/js/sunstone.js | 7 ++++- src/sunstone/views/index.erb | 2 +- 4 files changed, 51 insertions(+), 23 deletions(-) diff --git a/src/sunstone/public/css/layout.css b/src/sunstone/public/css/layout.css index f7b14cf703..6bf81da6ed 100644 --- a/src/sunstone/public/css/layout.css +++ b/src/sunstone/public/css/layout.css @@ -120,15 +120,23 @@ background-image: -moz-linear-gradient( rgb(53,55,53) 100% ); } -#navigation { + +.navigation { list-style: none; padding: 0; } -#navigation li { +.navigation li.topTab { line-height: 2em; - text-align: right; - padding-right: 10px; + text-align: left; + padding-left: 15px; +} + +.navigation li.subTab { + line-height: 1.8em; + font-size: 12px; + text-align: left; + padding-left: 30px; } #navigation li a { diff --git a/src/sunstone/public/js/layout.js b/src/sunstone/public/js/layout.js index b783835236..b0489446bc 100644 --- a/src/sunstone/public/js/layout.js +++ b/src/sunstone/public/js/layout.js @@ -48,28 +48,44 @@ function showTab(tabname){ $(".tab").hide(); $(activeTab).show(); //~ if (activeTab == '#dashboard') { - //~ emptyDashboard(); - //~ preloadTables(); - //~ } + //~ emptyDashboard(); + //~ preloadTables(); + //~ } innerLayout.close("south"); } +function setupTabs(){ + + var topTabs = $(".outer-west ul li.topTab"); + var subTabs = $(".outer-west ul li.subTab"); + + subTabs.live("click",function(){ + var tab = $('a',this).attr('href'); + showTab(tab); + return false; + }); + + topTabs.live("click",function(e){ + var tab = $('a',this).attr('href'); + //toggle subtabs trick + if ($(e.target).is('span')){ + $('li.'+tab.substr(1)).fadeToggle('fast'); + $('span',this).toggleClass('ui-icon-circle-plus ui-icon-circle-minus'); + return false; + } else if ($(this).hasClass("navigation-active-li")){//duplicate + $('li.'+tab.substr(1)).fadeToggle('fast'); + $('span',this).toggleClass('ui-icon-circle-plus ui-icon-circle-minus'); + }; + showTab(tab); + return false; + }); + +}; + $(document).ready(function () { $(".tab").hide(); - $(".outer-west ul li.subTab").live("click",function(){ - var tab = $('a',this).attr('href'); - showTab(tab); - return false; - }); - - $(".outer-west ul li.topTab").live("click",function(){ - var tab = $('a',this).attr('href'); - //toggle subtabs trick - $('li.'+tab.substr(1)).toggle(); - showTab(tab); - return false; - }); + setupTabs(); outerLayout = $('body').layout({ applyDefaultStyles: false @@ -106,4 +122,3 @@ $(document).ready(function () { }); }); - diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js index 73cb79fd84..6edbc35447 100644 --- a/src/sunstone/public/js/sunstone.js +++ b/src/sunstone/public/js/sunstone.js @@ -470,7 +470,12 @@ function insertTab(tab_name){ $('div#'+tab_name,main_tabs_context).html(tab_info.content); - $('div#menu ul#navigation').append('
  • '+tab_info.title+'
  • '); + $('div#menu ul#navigation').append('
  • '+tab_info.title+'
  • '); + + if (parent){ //this is a subtab + $('div#menu li#li_'+tab_name).hide();//hide by default + $('div#menu li#li_'+parent+' span').css("display","inline-block"); + }; } function hideSubTabs(){ diff --git a/src/sunstone/views/index.erb b/src/sunstone/views/index.erb index 45f277b48c..bca3dc5a1f 100644 --- a/src/sunstone/views/index.erb +++ b/src/sunstone/views/index.erb @@ -58,7 +58,7 @@
    From 891a7172b4499e85c45d95848503f8f1c84eb9f9 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Mon, 12 Mar 2012 16:39:58 +0100 Subject: [PATCH 158/217] feature #1112: Use tar for tm_ssh/mv copies. Use iscsi helper functions --- src/datastore_mad/remotes/iscsi/iscsi.conf | 4 ++ src/mad/sh/scripts_common.sh | 29 +++++++++ src/tm_mad/iscsi/clone | 23 ++++---- src/tm_mad/iscsi/delete | 2 +- src/tm_mad/iscsi/mv | 68 +++++++++++++++++++--- src/tm_mad/ssh/mv | 16 +++-- 6 files changed, 116 insertions(+), 26 deletions(-) diff --git a/src/datastore_mad/remotes/iscsi/iscsi.conf b/src/datastore_mad/remotes/iscsi/iscsi.conf index ec117b652f..2938398891 100644 --- a/src/datastore_mad/remotes/iscsi/iscsi.conf +++ b/src/datastore_mad/remotes/iscsi/iscsi.conf @@ -22,3 +22,7 @@ VG_NAME=vg-one # Starting TID for iSCSI targets BASE_TID=1 + +# Lists of hosts (separated by spaces) for which no iscsiadm login or logout +# is performed. +NO_ISCSI="$HOSTNAME" diff --git a/src/mad/sh/scripts_common.sh b/src/mad/sh/scripts_common.sh index 204b87eb38..d499d6db1d 100755 --- a/src/mad/sh/scripts_common.sh +++ b/src/mad/sh/scripts_common.sh @@ -38,6 +38,7 @@ SCP=scp SED=sed SSH=ssh SUDO=sudo +TAR=tar TGTADM=tgtadm WGET=wget @@ -304,3 +305,31 @@ function iscsiadm_logout { echo "$ISCSIADM -m node --targetname $IQN --logout" } +function is_iscsi { + if echo "$NO_ISCSI"|grep -q "\b$1\b"; then + return 1 + else + return 0 + fi +} + +function iqn_get_lv_name { + IQN="$1" + TARGET=`echo "$IQN"|$CUT -d: -f2` + echo $TARGET|$AWK -F. '{print $(NF)}' +} + +function iqn_get_vg_name { + IQN="$1" + TARGET=`echo "$IQN"|$CUT -d: -f2` + echo $TARGET|$AWK -F. '{print $(NF-1)}' +} + +function iqn_get_host { + IQN="$1" + + LV_NAME=$(iqn_get_lv_name "$IQN") + VG_NAME=$(iqn_get_vg_name "$IQN") + + echo ${TARGET%%.$VG_NAME.$LV_NAME} +} diff --git a/src/tm_mad/iscsi/clone b/src/tm_mad/iscsi/clone index 39edcbe028..cf172ed818 100755 --- a/src/tm_mad/iscsi/clone +++ b/src/tm_mad/iscsi/clone @@ -22,8 +22,8 @@ # - host is the target host to deploy the VM # - remote_system_ds is the path for the system datastore in the host -SRC=$1 # iqn.2012-02.org.opennebula:o200.vg-one.lv-one-0 -DST=$2 # o202:/var/lib/one//datastores/0/0/disk.0 +SRC=$1 +DST=$2 if [ -z "${ONE_LOCATION}" ]; then TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh @@ -37,19 +37,18 @@ fi # Set dst path and dir #------------------------------------------------------------------------------- -TARGET=`arg_path $SRC` # o200.vg-one.lv-one-0 -DST_PATH=`arg_path $DST` # /var/lib/one/datastores/0/0/disk.0 -DST_HOST=`arg_host $DST` # o202 -DST_DIR=`dirname $DST_PATH` # /var/lib/one/datastores/0/0 +TARGET=`arg_path $SRC` +DST_PATH=`arg_path $DST` +DST_HOST=`arg_host $DST` +DST_DIR=`dirname $DST_PATH` -BASE_IQN=`echo $SRC|$CUT -d: -f1` -TARGET=`echo $SRC|$CUT -d: -f2` -LV_NAME=`echo $TARGET|$AWK -F. '{print $(NF)}'` -VG_NAME=`echo $TARGET|$AWK -F. '{print $(NF-1)}'` +IQN="$SRC" + +LV_NAME=`iqn_get_lv_name "$IQN"` +VG_NAME=`iqn_get_vg_name "$IQN"` DEV="/dev/$VG_NAME/$LV_NAME" -exit -ssh_make_path $DST_HOST $DST_DIR +ssh_make_path "$DST_HOST" "$DST_DIR" #------------------------------------------------------------------------------- # Copy files to the remote host diff --git a/src/tm_mad/iscsi/delete b/src/tm_mad/iscsi/delete index c30639d900..fb4a4fbd0c 100755 --- a/src/tm_mad/iscsi/delete +++ b/src/tm_mad/iscsi/delete @@ -20,7 +20,7 @@ # - host is the target host to deploy the VM # - remote_system_ds is the path for the system datastore in the host -DST=$1 # o202:/var/lib/one//datastores/0/0/disk.0 +DST=$1 if [ -z "${ONE_LOCATION}" ]; then TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh diff --git a/src/tm_mad/iscsi/mv b/src/tm_mad/iscsi/mv index d564daf8c9..38005f85b4 100755 --- a/src/tm_mad/iscsi/mv +++ b/src/tm_mad/iscsi/mv @@ -24,6 +24,7 @@ SRC=$1 DST=$2 + if [ -z "${ONE_LOCATION}" ]; then TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh else @@ -32,6 +33,10 @@ fi . $TMCOMMON +DRIVER_PATH=$(dirname $0) + +source ${DRIVER_PATH}/../../datastore/iscsi/iscsi.conf + # {:path=> # "/var/lib/one/remotes/tm/iscsi/mv o202:/var/lib/one//datastores/0/3/disk.0 rama:/var/lib/one/datastores/0/3/disk.0", # :result=>"SUCCESS", @@ -47,11 +52,22 @@ fi # directory for the VM #------------------------------------------------------------------------------- SRC_PATH=`arg_path $SRC` +DST_PATH=`arg_path $DST` + SRC_HOST=`arg_host $SRC` +DST_HOST=`arg_host $DST` + +DST_DIR=`dirname $DST_PATH` if [ `is_disk $SRC_PATH` -eq 0 ]; then - log "Removing directory" - ssh_exec_and_log "$SRC_HOST" "rm -rf $SRC_PATH" + ssh_make_path $DST_HOST $DST_DIR + + log "Moving $SRC to $DST" + + exec_and_log "$SCP -r $SRC $DST" "Could not copy $SRC to $DST" + + ssh_exec_and_log "$SRC_HOST" "rm -rf $SRC_PATH" \ + "Could not remove $SRC_HOST:$SRC_PATH" exit 0 fi @@ -61,14 +77,50 @@ if [ "$SRC" == "$DST" ]; then exit 0 fi -log "Logging out $IQN" +if is_iscsi "$SRC_HOST"; then + log "Logging out of $IQN in $SRC_HOST" -LOGOUT_CMD=$(cat < -# +# MV +# # - hostX is the target host to deploy the VM # - system_ds is the path for the system datastore in the host @@ -34,7 +34,7 @@ fi #------------------------------------------------------------------------------- # Return if moving a disk, we will move them when moving the whole system_ds -# directory for the VM +# directory for the VM #------------------------------------------------------------------------------- SRC_PATH=`arg_path $SRC` DST_PATH=`arg_path $DST` @@ -53,11 +53,17 @@ if [ "$SRC" == "$DST" ]; then exit 0 fi -ssh_make_path $DST_HOST $DST_DIR +ssh_make_path "$DST_HOST" "$DST_DIR" log "Moving $SRC to $DST" -exec_and_log "$SCP -r $SRC $DST" "Could not copy $SRC to $DST" +ssh_exec_and_log "$DST_HOST" "rm -rf '$DST_PATH'" \ + "Error removing target path to prevent overwrite errors" + +TAR_COPY="$SSH $SRC_HOST '$TAR -C $SRC_PATH/.. -cf - .'" +TAR_COPY="$TAR_COPY | $SSH $DST_HOST '$TAR -C $DST_DIR -xf -'" + +exec_and_log "eval $TAR_COPY" "Error copying disk directory to target host" exec_and_log "$SSH $SRC_HOST rm -rf $SRC_PATH" From 78dfdd250371d62009d3cf64d2296e2f756fd96e Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Mon, 12 Mar 2012 19:09:24 +0100 Subject: [PATCH 159/217] feature #1112: Cast to integer in to_id method in one_helper.rb --- src/cli/one_helper.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cli/one_helper.rb b/src/cli/one_helper.rb index 019d80845e..c9646e0809 100644 --- a/src/cli/one_helper.rb +++ b/src/cli/one_helper.rb @@ -178,7 +178,7 @@ EOT # Formatters for arguments ######################################################################## def to_id(name) - return 0, name if name.match(/^[0123456789]+$/) + return 0, name.to_i if name.match(/^[0123456789]+$/) rc = get_pool return rc if rc.first != 0 @@ -288,11 +288,11 @@ EOT def pool_to_array(pool) if !pool.instance_of?(Hash) - phash = pool.to_hash + phash = pool.to_hash else phash = pool end - + rname = self.class.rname if phash["#{rname}_POOL"] && @@ -408,7 +408,7 @@ EOT rc = resource.info if OpenNebula.is_error?(rc) - puts rc.message + puts rc.message exit -1 end From 46776157a32013b080a1bb6ba1b751be433b4e47 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Mon, 12 Mar 2012 19:11:33 +0100 Subject: [PATCH 160/217] feature #1112: Fix wrong paths in tm_ssh/mv remote copy --- src/mad/sh/scripts_common.sh | 3 +-- src/tm_mad/iscsi/mv | 1 - src/tm_mad/ssh/mv | 5 ++++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/mad/sh/scripts_common.sh b/src/mad/sh/scripts_common.sh index d499d6db1d..addd2ba59c 100755 --- a/src/mad/sh/scripts_common.sh +++ b/src/mad/sh/scripts_common.sh @@ -327,9 +327,8 @@ function iqn_get_vg_name { function iqn_get_host { IQN="$1" - + TARGET=`echo "$IQN"|$CUT -d: -f2` LV_NAME=$(iqn_get_lv_name "$IQN") VG_NAME=$(iqn_get_vg_name "$IQN") - echo ${TARGET%%.$VG_NAME.$LV_NAME} } diff --git a/src/tm_mad/iscsi/mv b/src/tm_mad/iscsi/mv index 38005f85b4..21cc55bdd2 100755 --- a/src/tm_mad/iscsi/mv +++ b/src/tm_mad/iscsi/mv @@ -110,7 +110,6 @@ if is_iscsi "$DST_HOST"; then set -e mkdir -p $DST_DIR $SUDO $(iscsiadm_discovery "$TARGET_HOST") - $SUDO $(iscsiadm_discovery "$TARGET_HOST") $SUDO $(iscsiadm_login "$IQN" "$TARGET_HOST") sleep 1 DISK_BY_PATH=\$(ls /dev/disk/by-path/*$IQN-lun-1) diff --git a/src/tm_mad/ssh/mv b/src/tm_mad/ssh/mv index 4d929d8d44..90c4143dec 100755 --- a/src/tm_mad/ssh/mv +++ b/src/tm_mad/ssh/mv @@ -44,6 +44,9 @@ DST_HOST=`arg_host $DST` DST_DIR=`dirname $DST_PATH` +SRC_DS_DIR=`dirname $SRC_PATH` +SRC_VM_DIR=`basename $SRC_PATH` + if [ `is_disk $DST_PATH` -eq 1 ]; then exit 0 fi @@ -60,7 +63,7 @@ log "Moving $SRC to $DST" ssh_exec_and_log "$DST_HOST" "rm -rf '$DST_PATH'" \ "Error removing target path to prevent overwrite errors" -TAR_COPY="$SSH $SRC_HOST '$TAR -C $SRC_PATH/.. -cf - .'" +TAR_COPY="$SSH $SRC_HOST '$TAR -C $SRC_DS_DIR -cf - $SRC_VM_DIR'" TAR_COPY="$TAR_COPY | $SSH $DST_HOST '$TAR -C $DST_DIR -xf -'" exec_and_log "eval $TAR_COPY" "Error copying disk directory to target host" From 557124605ed519188840c9460e627005fef5994b Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 12 Mar 2012 12:45:38 +0100 Subject: [PATCH 161/217] Feature #1112: Update Sunstone dashboards, allow DS select on image creation, list images in DS in extended info and various small bugfixes. (cherry picked from commit b20a063d7f13f136f06e97137638dc134262c552) --- .../models/OpenNebulaJSON/ImageJSON.rb | 2 +- src/sunstone/models/SunstoneServer.rb | 15 +++++++- .../public/js/plugins/dashboard-tab.js | 22 ++++++++++-- .../public/js/plugins/dashboard-users-tab.js | 14 +++++++- .../public/js/plugins/datastores-tab.js | 35 +++++++++++++++++-- src/sunstone/public/js/plugins/images-tab.js | 15 ++++++-- src/sunstone/public/js/plugins/vnets-tab.js | 1 + src/sunstone/public/js/sunstone-util.js | 19 +++++++--- 8 files changed, 109 insertions(+), 14 deletions(-) diff --git a/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb b/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb index 11c03966ee..99a0bdf04b 100644 --- a/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb @@ -37,7 +37,7 @@ module OpenNebulaJSON template = template_to_str(image_hash) end - self.allocate(template,ds_id) + self.allocate(template,ds_id.to_i) end def perform_action(template_json) diff --git a/src/sunstone/models/SunstoneServer.rb b/src/sunstone/models/SunstoneServer.rb index fba385ec96..2739d9b2b4 100644 --- a/src/sunstone/models/SunstoneServer.rb +++ b/src/sunstone/models/SunstoneServer.rb @@ -130,9 +130,22 @@ class SunstoneServer < CloudServer ############################################################################ def upload(template, file_path) image_hash = parse_json(template, 'image') + if OpenNebula.is_error?(image_hash) + return [500, image_hash.to_json] + end + image_hash['PATH'] = file_path - new_template = {:image => image_hash}.to_json + ds_id = parse_json(template, 'ds_id') + if OpenNebula.is_error?(ds_id) + return [500, ds_id.to_json] + end + + new_template = { + :image => image_hash, + :ds_id => ds_id, + }.to_json + image = ImageJSON.new(Image.build_xml, @client) rc = image.create(new_template) diff --git a/src/sunstone/public/js/plugins/dashboard-tab.js b/src/sunstone/public/js/plugins/dashboard-tab.js index 362c51e347..06b931244b 100644 --- a/src/sunstone/public/js/plugins/dashboard-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-tab.js @@ -58,6 +58,10 @@ var dashboard_tab_content =
    \ \ \ + \ + \ + \ + \ \ \ \ @@ -78,6 +82,10 @@ var dashboard_tab_content = \ \ \ + \ + \ + \ + \ \ \ \ @@ -102,11 +110,13 @@ var dashboard_tab_content =

    ' + tr("Quickstart") + '

    \
    \
    '+tr("Datastore information")+' - '+info.NAME+'
    '+tr("Base path")+''+info.BASE_PATH+'
    '+tr("Images")+''+images_str+'
    '+tr("Permissions")+'
         '+tr("Owner")+'' + tr("Hosts (total/active)") + '
    ' + tr("Clusters") + '
    ' + tr("Groups") + '' + tr("Virtual Networks (total/public)") + '
    ' + tr("Datastores") + '
    ' + tr("Images (total/public)") + '
    \ \ \ + \ + \ + \ + \ \ \ \ @@ -85,7 +89,7 @@ var dashboard_tab_content =

    '+tr("Quickstart")+'

    \
    \
    \ -\ +\ ' + tr("Host") + '
    \ + ' + tr("Cluster") + '
    \ ' + tr("VM Instance") + '
    \ ' + tr("VM Template") + '
    \ - ' + tr("Virtual Network") + '
    \ + ' + tr("Virtual Network") + '
    \ + ' + tr("Datastore") + '
    \ ' + tr("Image") + '
    \ ' + tr("User") + '
    \ ' + tr("Group") + '
    \ @@ -316,5 +326,13 @@ function updateDashboard(what,json_info){ var total_acls=json_info.length; $('#total_acls',db).html(total_acls); break; + case "clusters": + var total_clusters=json_info.length; + $('#total_clusters',db).html(total_clusters); + break; + case "datastores": + var total_datastores=json_info.length; + $('#total_datastores',db).html(total_datastores); + break; } } diff --git a/src/sunstone/public/js/plugins/dashboard-users-tab.js b/src/sunstone/public/js/plugins/dashboard-users-tab.js index 4e602814be..f27ed855fb 100644 --- a/src/sunstone/public/js/plugins/dashboard-users-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-users-tab.js @@ -69,6 +69,10 @@ var dashboard_tab_content =
    '+tr("Virtual Networks (total/public)")+'
    ' + tr("Datastores") + '
    '+tr("Images (total/public)")+'
    \ - \ + \ '+tr("VM Template")+'
    \ '+tr("VM Instance")+'
    \ '+tr("Virtual Network")+'
    \ @@ -296,5 +300,13 @@ function updateDashboard(what,json_info){ var total_acls=json_info.length; $('#total_acls',db).html(total_acls); break; + case "clusters": + var total_clusters=json_info.length; + $('#total_clusters',db).html(total_clusters); + break; + case "datastores": + var total_datastores=json_info.length; + $('#total_datastores',db).html(total_datastores); + break; } } \ No newline at end of file diff --git a/src/sunstone/public/js/plugins/datastores-tab.js b/src/sunstone/public/js/plugins/datastores-tab.js index 603fd6867e..88afb16aab 100644 --- a/src/sunstone/public/js/plugins/datastores-tab.js +++ b/src/sunstone/public/js/plugins/datastores-tab.js @@ -265,7 +265,8 @@ var datastore_buttons = { }, "Datastore.create_dialog" : { type: "create_dialog", - text: tr("+ New") + text: tr("+ New"), + condition: mustBeAdmin, }, "Datastore.update_dialog" : { type: "action", @@ -277,6 +278,7 @@ var datastore_buttons = { text: tr("Select cluster"), select: clusters_sel, tip: tr("Select the destination cluster:"), + condition: mustBeAdmin, }, "Datastore.chown" : { type: "confirm_with_select", @@ -354,22 +356,34 @@ function datastoreInfoListener(){ Sunstone.runAction("Datastore.showinfo",id); return false; }); -} +}; + +function updateDatastoreSelect(){ + datastores_select = makeSelectOptions(dataTable_datastores, + 1, + 4, + [], + [] + ); +}; function updateDatastoreElement(request, element_json){ var id = element_json.DATASTORE.ID; var element = datastoreElementArray(element_json); updateSingleElement(element,dataTable_datastores,'#datastore_'+id) + updateDatastoreSelect(); } function deleteDatastoreElement(request){ deleteElement(dataTable_datastores,'#datastore_'+request.request.data); + updateDatastoreSelect(); } function addDatastoreElement(request,element_json){ var id = element_json.DATASTORE.ID; var element = datastoreElementArray(element_json); addElement(element,dataTable_datastores); + updateDatastoreSelect(); } @@ -381,17 +395,28 @@ function updateDatastoresView(request, list){ }); updateView(list_array,dataTable_datastores); + updateDatastoreSelect(); updateDashboard("datastores",list); } function updateDatastoreInfo(request,ds){ var info = ds.DATASTORE; + var images_str = ""; + if (info.IMAGES.ID && + info.IMAGES.ID.constructor == Array){ + for (var i=0; i\ + '\ \ \ \ @@ -428,6 +453,10 @@ function updateDatastoreInfo(request,ds){ \ \ \ + \ + \ + \ + \ \ \ \ diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index ad8d818883..ca5dd57182 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -63,6 +63,12 @@ var create_image_tmpl = \
    '+tr("Human readable description of the image for other users.")+'
    \ \ +
    \ + \ + \ +
    '+tr("Select the datastore for this image")+'
    \ +
    \ \
    \
    \ @@ -850,7 +856,11 @@ function setupCreateImageDialog(){ }); if (exit) { return false; } - var ds_id = $('#img_ds_id',this).val(); + var ds_id = $('#img_datastore',this).val(); + if (!ds_id){ + notifyError(tr("Please select a datastore for this image")); + return false; + }; var img_json = {}; @@ -906,7 +916,6 @@ function setupCreateImageDialog(){ img_json[attr_name] = attr_value; }); - ds_id = 1; img_obj = { "image" : img_json, "ds_id" : ds_id}; @@ -932,6 +941,8 @@ function popUpCreateImageDialog(){ $('#file-uploader input',$create_image_dialog).removeAttr("style"); $('#file-uploader input',$create_image_dialog).attr('style','margin:0;width:256px!important'); + $('#img_datastore',$create_image_dialog).html(datastores_sel()); + $create_image_dialog.dialog('open'); } diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index b9b63a21b7..f1865b92dc 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -419,6 +419,7 @@ var vnet_buttons = { text: tr("Select cluster"), select: clusters_sel, tip: tr("Select the destination cluster:"), + condition: mustBeAdmin, }, "Network.chown" : { type: "confirm_with_select", diff --git a/src/sunstone/public/js/sunstone-util.js b/src/sunstone/public/js/sunstone-util.js index 02a060b5d3..4b16656250 100644 --- a/src/sunstone/public/js/sunstone-util.js +++ b/src/sunstone/public/js/sunstone-util.js @@ -403,19 +403,26 @@ function waitingNodes(dataTable){ function getUserName(uid){ if (typeof(dataTable_users) != "undefined"){ - return getName(uid,dataTable_users); + return getName(uid,dataTable_users,2); } return uid; } function getGroupName(gid){ if (typeof(dataTable_groups) != "undefined"){ - return getName(gid,dataTable_groups); + return getName(gid,dataTable_groups,2); } return gid; } -function getName(id,dataTable){ +function getImageName(id){ + if (typeof(dataTable_images) != "undefined"){ + return getName(id,dataTable_images,4); + } + return id; +}; + +function getName(id,dataTable,name_col){ var name = id; if (typeof(dataTable) == "undefined") { return name; @@ -424,7 +431,7 @@ function getName(id,dataTable){ $.each(nodes,function(){ if (id == this[1]) { - name = this[2]; + name = this[name_col]; return false; } }); @@ -755,6 +762,10 @@ function clusters_sel() { return clusters_select; } +function datastores_sel() { + return datastores_select; +} + function ownerUse(resource){ From d8350b255176c601609aa49f397aec2e9c714694 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Tue, 13 Mar 2012 12:07:31 +0100 Subject: [PATCH 162/217] feature #1112: Improve debugging for one_tm.rb --- src/tm_mad/one_tm.rb | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/tm_mad/one_tm.rb b/src/tm_mad/one_tm.rb index d8fc620987..0a9a70eff1 100755 --- a/src/tm_mad/one_tm.rb +++ b/src/tm_mad/one_tm.rb @@ -33,9 +33,9 @@ require 'OpenNebulaDriver' require 'CommandManager' require 'getoptlong' -# This class provides basic messaging and logging functionality to implement -# TransferManager Drivers. A TransferManager driver is a program (or a set of) -# that specialize the OpenNebula behavior to distribute disk images in a +# This class provides basic messaging and logging functionality to implement +# TransferManager Drivers. A TransferManager driver is a program (or a set of) +# that specialize the OpenNebula behavior to distribute disk images in a # specific datastore to the hosts class TransferManagerDriver < OpenNebulaDriver @@ -72,9 +72,9 @@ class TransferManagerDriver < OpenNebulaDriver script = parse_script(script_file) if script.nil? - send_message("TRANSFER", + send_message("TRANSFER", RESULT[:failure], - id, + id, "Transfer file '#{script_file}' does not exist") return end @@ -84,7 +84,7 @@ class TransferManagerDriver < OpenNebulaDriver if result == RESULT[:failure] send_message("TRANSFER", result, id, info) - return + return end } @@ -106,7 +106,7 @@ class TransferManagerDriver < OpenNebulaDriver stext.each_line {|line| next if line.match(/^\s*#/) # skip if the line is commented next if line.match(/^\s*$/) # skip if the line is empty - + command = line.split(" ") lines << command @@ -115,7 +115,7 @@ class TransferManagerDriver < OpenNebulaDriver return lines end - # Executes a single transfer action (command), as returned by the parse + # Executes a single transfer action (command), as returned by the parse # method # @param id [String] with the OpenNebula ID for the TRANSFER action # @param command [Array] @@ -131,10 +131,13 @@ class TransferManagerDriver < OpenNebulaDriver path = File.join(@local_scripts_path, tm, cmd) path << " " << args + rc = LocalCommand.run(path, log_method(id)) result, info = get_info_from_execution(rc) + PP.pp([path,result,info],STDERR) + return result, info end end From 6b86f36cad681b32e13e70021bb87a0a9bc60022 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Tue, 13 Mar 2012 12:07:53 +0100 Subject: [PATCH 163/217] feature #1112: tm_iscsi/clone not implemented --- src/tm_mad/iscsi/clone | 50 ++---------------------------------------- 1 file changed, 2 insertions(+), 48 deletions(-) diff --git a/src/tm_mad/iscsi/clone b/src/tm_mad/iscsi/clone index cf172ed818..322f2a511e 100755 --- a/src/tm_mad/iscsi/clone +++ b/src/tm_mad/iscsi/clone @@ -16,52 +16,6 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -# clone fe:SOURCE host:remote_system_ds/disk.i size -# - fe is the front-end hostname -# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk -# - host is the target host to deploy the VM -# - remote_system_ds is the path for the system datastore in the host +log_error "CLONE not supported for TM_ISCSI. Use persistent images" -SRC=$1 -DST=$2 - -if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh -else - TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh -fi - -. $TMCOMMON - -#------------------------------------------------------------------------------- -# Set dst path and dir -#------------------------------------------------------------------------------- - -TARGET=`arg_path $SRC` -DST_PATH=`arg_path $DST` -DST_HOST=`arg_host $DST` -DST_DIR=`dirname $DST_PATH` - -IQN="$SRC" - -LV_NAME=`iqn_get_lv_name "$IQN"` -VG_NAME=`iqn_get_vg_name "$IQN"` -DEV="/dev/$VG_NAME/$LV_NAME" - -ssh_make_path "$DST_HOST" "$DST_DIR" - -#------------------------------------------------------------------------------- -# Copy files to the remote host -#------------------------------------------------------------------------------- -case $SRC in -http://*) - log "Downloading $SRC" - RMT_CMD="$WGET -O $DST_PATH $SRC" - ssh_exec_and_log "$DST_HOST" "$RMT_CMD" "Error downloading $SRC" - ;; - -*) - log "Cloning $SRC in $DST_PATH" - exec_and_log "$SCP $SRC $DST" "Error copying $SRC to $DST" - ;; -esac +exit 1 From dce32e135196cf05cd59bd1abec14cd987d63e57 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Tue, 13 Mar 2012 12:08:36 +0100 Subject: [PATCH 164/217] feature #1112: Include tm_iscsi files in install.sh --- install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/install.sh b/install.sh index d5de5583f0..d49113c7f9 100755 --- a/install.sh +++ b/install.sh @@ -232,6 +232,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \ $VAR_LOCATION/remotes/tm/shared \ $VAR_LOCATION/remotes/tm/ssh \ $VAR_LOCATION/remotes/tm/vmware \ + $VAR_LOCATION/remotes/tm/iscsi \ $VAR_LOCATION/remotes/hooks \ $VAR_LOCATION/remotes/hooks/ft \ $VAR_LOCATION/remotes/datastore \ @@ -386,6 +387,7 @@ INSTALL_FILES=( TM_SHARED_FILES:$VAR_LOCATION/remotes/tm/shared TM_SSH_FILES:$VAR_LOCATION/remotes/tm/ssh TM_VMWARE_FILES:$VAR_LOCATION/remotes/tm/vmware + TM_ISCSI_FILES:$VAR_LOCATION/remotes/tm/iscsi TM_DUMMY_FILES:$VAR_LOCATION/remotes/tm/dummy TM_LVM_FILES:$VAR_LOCATION/remotes/tm/lvm DATASTORE_DRIVER_COMMON_SCRIPTS:$VAR_LOCATION/remotes/datastore/ @@ -805,6 +807,11 @@ TM_VMWARE_FILES="src/tm_mad/vmware/clone \ src/tm_mad/vmware/functions.sh \ src/tm_mad/vmware/context" +TM_ISCSI_FILES="src/tm_mad/iscsi/clone \ + src/tm_mad/iscsi/ln \ + src/tm_mad/iscsi/mv \ + src/tm_mad/iscsi/mvds \ + src/tm_mad/iscsi/delete" #------------------------------------------------------------------------------- # Datastore drivers, to be installed under $REMOTES_LOCATION/datastore # - FS based Image Repository, $REMOTES_LOCATION/datastore/fs From 0fd1d0ec857e015be92913e1c2e98ac446731bf9 Mon Sep 17 00:00:00 2001 From: Tino Vazquez Date: Tue, 13 Mar 2012 12:56:53 +0100 Subject: [PATCH 165/217] Avoid unneeded errors deleting non existent files in install.sh --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index d5de5583f0..b36e70d26c 100755 --- a/install.sh +++ b/install.sh @@ -1453,7 +1453,7 @@ if [ "$UNINSTALL" = "no" ] ; then done # Remove old migrators - rm $LIB_LOCATION/ruby/onedb/*.rb + rm $LIB_LOCATION/ruby/onedb/*.rb &> /dev/null fi # --- Install/Uninstall files --- From b304a6d896fc4e7f69a80daf1c6ace92f85fc06a Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Tue, 13 Mar 2012 16:00:55 +0100 Subject: [PATCH 166/217] feature #1112: Fix CLI option procs --- src/cli/command_parser.rb | 2 +- src/cli/one_helper.rb | 2 +- src/cli/one_helper/onecluster_helper.rb | 8 +++++++- src/cli/one_helper/onedatastore_helper.rb | 8 +++++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/cli/command_parser.rb b/src/cli/command_parser.rb index fe3fc911ac..efe463d962 100755 --- a/src/cli/command_parser.rb +++ b/src/cli/command_parser.rb @@ -311,7 +311,7 @@ EOT opts.on(*args) do |o| if e[:proc] - @options[e[:name].to_sym]=e[:proc].call(o, @options) + e[:proc].call(o, @options) elsif e[:name]=="help" help exit diff --git a/src/cli/one_helper.rb b/src/cli/one_helper.rb index c9646e0809..16f08400f3 100644 --- a/src/cli/one_helper.rb +++ b/src/cli/one_helper.rb @@ -202,7 +202,7 @@ EOT result = names.split(',').collect { |name| if name.match(/^[0123456789]+$/) - name + name.to_i else rc = OneHelper.name_to_id(name, pool, poolname) diff --git a/src/cli/one_helper/onecluster_helper.rb b/src/cli/one_helper/onecluster_helper.rb index 4e837f9a29..40024d5b53 100644 --- a/src/cli/one_helper/onecluster_helper.rb +++ b/src/cli/one_helper/onecluster_helper.rb @@ -27,7 +27,13 @@ class OneClusterHelper < OpenNebulaHelper::OneHelper :proc => lambda { |o, options| ch = OneClusterHelper.new rc, cid = ch.to_id(o) - cid + if rc == 0 + options[:cluster] = cid + else + puts cid + puts "option cluster: Parsing error" + exit -1 + end } } diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index 4f524bbd71..b94ad60a3f 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -26,7 +26,13 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper :proc => lambda { |o, options| ch = OneDatastoreHelper.new rc, dsid = ch.to_id(o) - dsid + if rc == 0 + options[:datastore] = dsid + else + puts dsid + puts "option datastore: Parsing error" + exit -1 + end } } From 44c9946c5037bb3de7daf3a3027e3b37f42c7614 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Tue, 13 Mar 2012 16:27:39 +0100 Subject: [PATCH 167/217] Revert "feature #1112: Improve debugging for one_tm.rb" This reverts commit d8350b255176c601609aa49f397aec2e9c714694. --- src/tm_mad/one_tm.rb | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/tm_mad/one_tm.rb b/src/tm_mad/one_tm.rb index 0a9a70eff1..d8fc620987 100755 --- a/src/tm_mad/one_tm.rb +++ b/src/tm_mad/one_tm.rb @@ -33,9 +33,9 @@ require 'OpenNebulaDriver' require 'CommandManager' require 'getoptlong' -# This class provides basic messaging and logging functionality to implement -# TransferManager Drivers. A TransferManager driver is a program (or a set of) -# that specialize the OpenNebula behavior to distribute disk images in a +# This class provides basic messaging and logging functionality to implement +# TransferManager Drivers. A TransferManager driver is a program (or a set of) +# that specialize the OpenNebula behavior to distribute disk images in a # specific datastore to the hosts class TransferManagerDriver < OpenNebulaDriver @@ -72,9 +72,9 @@ class TransferManagerDriver < OpenNebulaDriver script = parse_script(script_file) if script.nil? - send_message("TRANSFER", + send_message("TRANSFER", RESULT[:failure], - id, + id, "Transfer file '#{script_file}' does not exist") return end @@ -84,7 +84,7 @@ class TransferManagerDriver < OpenNebulaDriver if result == RESULT[:failure] send_message("TRANSFER", result, id, info) - return + return end } @@ -106,7 +106,7 @@ class TransferManagerDriver < OpenNebulaDriver stext.each_line {|line| next if line.match(/^\s*#/) # skip if the line is commented next if line.match(/^\s*$/) # skip if the line is empty - + command = line.split(" ") lines << command @@ -115,7 +115,7 @@ class TransferManagerDriver < OpenNebulaDriver return lines end - # Executes a single transfer action (command), as returned by the parse + # Executes a single transfer action (command), as returned by the parse # method # @param id [String] with the OpenNebula ID for the TRANSFER action # @param command [Array] @@ -131,13 +131,10 @@ class TransferManagerDriver < OpenNebulaDriver path = File.join(@local_scripts_path, tm, cmd) path << " " << args - rc = LocalCommand.run(path, log_method(id)) result, info = get_info_from_execution(rc) - PP.pp([path,result,info],STDERR) - return result, info end end From b2a9bae2488e49684da7513d60979080cb720b11 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Tue, 13 Mar 2012 17:37:50 +0100 Subject: [PATCH 168/217] feature #1112: Include iscsi in oned.conf --- share/etc/oned.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/etc/oned.conf b/share/etc/oned.conf index b98bdf288e..ba4cb5cba7 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -281,7 +281,7 @@ VM_MAD = [ TM_MAD = [ executable = "one_tm", - arguments = "-t 15 -d dummy,lvm,shared,ssh,vmware" ] + arguments = "-t 15 -d dummy,lvm,shared,ssh,vmware,iscsi" ] #******************************************************************************* # Datastore Driver Configuration @@ -298,7 +298,7 @@ TM_MAD = [ DATASTORE_MAD = [ executable = "one_datastore", - arguments = "-t 15 -d fs,vmware" + arguments = "-t 15 -d fs,vmware,iscsi" ] #******************************************************************************* From 55b26c3f0f7dc43c081c42d8eb4274cd159d435a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 13 Mar 2012 18:13:09 +0100 Subject: [PATCH 169/217] Feature #1112: Fix onevnet create options --- src/cli/onevnet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cli/onevnet b/src/cli/onevnet index e76da4b48d..2c82e5b1fe 100755 --- a/src/cli/onevnet +++ b/src/cli/onevnet @@ -75,7 +75,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do Creates a new Virtual Network from the given template file EOT - command :create, create_desc, :file, options=>CREATE_OPTIONS do + command :create, create_desc, :file, :options=>CREATE_OPTIONS do cid = options[:cluster] || ClusterPool::NONE_CLUSTER_ID helper.create_resource(options) do |vn| From 6db8eea366d67ecdfdbe5d6e67ead843359df373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 13 Mar 2012 18:38:50 +0100 Subject: [PATCH 170/217] Feature #1112: Bug, new vnets were added to their clusters in the datastore set --- include/RequestManagerAllocate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index faceccd4db..e13bdbc42c 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -178,7 +178,7 @@ public: int add_to_cluster(Cluster* cluster, int id, string& error_msg) { - return cluster->add_datastore(id, error_msg); + return cluster->add_vnet(id, error_msg); }; }; From 4f00c6a608fdf8d2ed3771dea4d034279e75267a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 13 Mar 2012 18:39:34 +0100 Subject: [PATCH 171/217] Feature #1112: Fix onecluster delvnet --- src/cli/onecluster | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cli/onecluster b/src/cli/onecluster index 352e4811e0..8cb5ac0dd3 100755 --- a/src/cli/onecluster +++ b/src/cli/onecluster @@ -169,7 +169,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do # TODO: allow the second param to be [:range, :vnetid_list] command :delvnet, delvnet_desc,:clusterid, :vnetid do - helper.perform_actions(args[0],options,"updated") do |cluster| + helper.perform_action(args[0],options,"updated") do |cluster| cluster.delvnet(args[1].to_i) end end From d9907f271ac59075ff40e686887b6cc57b9701b1 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Wed, 14 Mar 2012 12:20:06 +0100 Subject: [PATCH 172/217] feature #1112: Dummy datastore driver --- install.sh | 6 ++++++ src/datastore_mad/remotes/dummy/cp | 19 +++++++++++++++++++ src/datastore_mad/remotes/dummy/mkfs | 19 +++++++++++++++++++ src/datastore_mad/remotes/dummy/rm | 19 +++++++++++++++++++ 4 files changed, 63 insertions(+) create mode 100755 src/datastore_mad/remotes/dummy/cp create mode 100755 src/datastore_mad/remotes/dummy/mkfs create mode 100755 src/datastore_mad/remotes/dummy/rm diff --git a/install.sh b/install.sh index d49113c7f9..70bd372da3 100755 --- a/install.sh +++ b/install.sh @@ -236,6 +236,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \ $VAR_LOCATION/remotes/hooks \ $VAR_LOCATION/remotes/hooks/ft \ $VAR_LOCATION/remotes/datastore \ + $VAR_LOCATION/remotes/datastore/dummy \ $VAR_LOCATION/remotes/datastore/fs \ $VAR_LOCATION/remotes/datastore/vmware \ $VAR_LOCATION/remotes/datastore/iscsi \ @@ -391,6 +392,7 @@ INSTALL_FILES=( TM_DUMMY_FILES:$VAR_LOCATION/remotes/tm/dummy TM_LVM_FILES:$VAR_LOCATION/remotes/tm/lvm DATASTORE_DRIVER_COMMON_SCRIPTS:$VAR_LOCATION/remotes/datastore/ + DATASTORE_DRIVER_DUMMY_SCRIPTS:$VAR_LOCATION/remotes/datastore/dummy DATASTORE_DRIVER_FS_SCRIPTS:$VAR_LOCATION/remotes/datastore/fs DATASTORE_DRIVER_VMWARE_SCRIPTS:$VAR_LOCATION/remotes/datastore/vmware DATASTORE_DRIVER_ISCSI_SCRIPTS:$VAR_LOCATION/remotes/datastore/iscsi @@ -821,6 +823,10 @@ TM_ISCSI_FILES="src/tm_mad/iscsi/clone \ DATASTORE_DRIVER_COMMON_SCRIPTS="src/datastore_mad/remotes/xpath.rb \ src/datastore_mad/remotes/libfs.sh" +DATASTORE_DRIVER_DUMMY_SCRIPTS="src/datastore_mad/remotes/dummy/cp \ + src/datastore_mad/remotes/dummy/mkfs \ + src/datastore_mad/remotes/dummy/rm" + DATASTORE_DRIVER_FS_SCRIPTS="src/datastore_mad/remotes/fs/cp \ src/datastore_mad/remotes/fs/mkfs \ src/datastore_mad/remotes/fs/rm" diff --git a/src/datastore_mad/remotes/dummy/cp b/src/datastore_mad/remotes/dummy/cp new file mode 100755 index 0000000000..d915146f42 --- /dev/null +++ b/src/datastore_mad/remotes/dummy/cp @@ -0,0 +1,19 @@ +#!/bin/sh + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +echo "dummy_path 1024" diff --git a/src/datastore_mad/remotes/dummy/mkfs b/src/datastore_mad/remotes/dummy/mkfs new file mode 100755 index 0000000000..d915146f42 --- /dev/null +++ b/src/datastore_mad/remotes/dummy/mkfs @@ -0,0 +1,19 @@ +#!/bin/sh + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +echo "dummy_path 1024" diff --git a/src/datastore_mad/remotes/dummy/rm b/src/datastore_mad/remotes/dummy/rm new file mode 100755 index 0000000000..6c1cd9257d --- /dev/null +++ b/src/datastore_mad/remotes/dummy/rm @@ -0,0 +1,19 @@ +#!/bin/sh + +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +exit 0 From 3c1cf1f1b3c91c87e3a932d615d3ac8ebed60a4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 14 Mar 2012 15:48:06 +0100 Subject: [PATCH 173/217] Feature #1112: Fix oneimage update (broken in commit:92dd8d4c) --- include/Datastore.h | 2 +- include/Host.h | 2 +- include/PoolObjectSQL.h | 2 +- include/User.h | 2 +- include/VMTemplate.h | 2 +- include/VirtualMachine.h | 2 +- include/VirtualNetwork.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/Datastore.h b/include/Datastore.h index 39cfa9ef60..43c5cd3e9e 100644 --- a/include/Datastore.h +++ b/include/Datastore.h @@ -191,7 +191,7 @@ private: /** * Factory method for virtual network templates */ - Template * get_new_template() + Template * get_new_template() const { return new DatastoreTemplate; } diff --git a/include/Host.h b/include/Host.h index 06b519f450..0c60e7f783 100644 --- a/include/Host.h +++ b/include/Host.h @@ -281,7 +281,7 @@ public: /** * Factory method for host templates */ - Template * get_new_template() + Template * get_new_template() const { return new HostTemplate; } diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h index a1177c364c..bd4e72b449 100644 --- a/include/PoolObjectSQL.h +++ b/include/PoolObjectSQL.h @@ -363,7 +363,7 @@ public: * by classes that uses templates * @return a new template */ - virtual Template * get_new_template() + virtual Template * get_new_template() const { return 0; } diff --git a/include/User.h b/include/User.h index befac1f21b..770b5943bc 100644 --- a/include/User.h +++ b/include/User.h @@ -162,7 +162,7 @@ public: /** * Factory method for image templates */ - Template * get_new_template() + Template * get_new_template() const { return new UserTemplate; } diff --git a/include/VMTemplate.h b/include/VMTemplate.h index 610f7e43a5..b48f7ddb75 100644 --- a/include/VMTemplate.h +++ b/include/VMTemplate.h @@ -44,7 +44,7 @@ public: /** * Factory method for virtual machine templates */ - Template * get_new_template() + Template * get_new_template() const { return new VirtualMachineTemplate; } diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 06150277a7..9254ec2b4c 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -542,7 +542,7 @@ public: /** * Factory method for virtual machine templates */ - Template * get_new_template() + Template * get_new_template() const { return new VirtualMachineTemplate; } diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index 161bdd77b8..069a7449a6 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -62,7 +62,7 @@ public: /** * Factory method for virtual network templates */ - Template * get_new_template() + Template * get_new_template() const { return new VirtualNetworkTemplate; } From 51ed17ea0d747ba913c9e4c63e792101f32afd76 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 14 Mar 2012 16:15:05 +0100 Subject: [PATCH 174/217] Feature #1112: Implement cluster menus and submenus. Insert new dashboards. Implement top menu. --- install.sh | 2 + src/sunstone/etc/sunstone-plugins.yaml | 64 +++-- src/sunstone/public/css/application.css | 26 +- src/sunstone/public/css/layout.css | 73 ++++++ src/sunstone/public/js/layout.js | 65 +++-- src/sunstone/public/js/plugins/acls-tab.js | 5 +- .../public/js/plugins/clusters-tab.js | 233 +++++++++++++++++- src/sunstone/public/js/plugins/config-tab.js | 6 +- .../public/js/plugins/dashboard-tab.js | 87 +++---- .../public/js/plugins/dashboard-users-tab.js | 69 ++---- .../public/js/plugins/datastores-tab.js | 8 +- src/sunstone/public/js/plugins/groups-tab.js | 7 +- src/sunstone/public/js/plugins/hosts-tab.js | 10 +- src/sunstone/public/js/plugins/images-tab.js | 5 +- src/sunstone/public/js/plugins/system-tab.js | 113 +++++++++ .../public/js/plugins/templates-tab.js | 6 +- src/sunstone/public/js/plugins/users-tab.js | 7 +- src/sunstone/public/js/plugins/vms-tab.js | 5 +- src/sunstone/public/js/plugins/vnets-tab.js | 8 +- .../public/js/plugins/vresources-tab.js | 137 ++++++++++ src/sunstone/public/js/sunstone-util.js | 28 +++ src/sunstone/public/js/sunstone.js | 27 +- src/sunstone/views/index.erb | 9 + 23 files changed, 819 insertions(+), 181 deletions(-) create mode 100644 src/sunstone/public/js/plugins/system-tab.js create mode 100644 src/sunstone/public/js/plugins/vresources-tab.js diff --git a/install.sh b/install.sh index d5de5583f0..028efd1f0b 100755 --- a/install.sh +++ b/install.sh @@ -1139,6 +1139,8 @@ SUNSTONE_PUBLIC_JS_PLUGINS_FILES="\ src/sunstone/public/js/plugins/hosts-tab.js \ src/sunstone/public/js/plugins/clusters-tab.js \ src/sunstone/public/js/plugins/datastores-tab.js \ + src/sunstone/public/js/plugins/system-tab.js \ + src/sunstone/public/js/plugins/vresources-tab.js \ src/sunstone/public/js/plugins/groups-tab.js \ src/sunstone/public/js/plugins/images-tab.js \ src/sunstone/public/js/plugins/templates-tab.js \ diff --git a/src/sunstone/etc/sunstone-plugins.yaml b/src/sunstone/etc/sunstone-plugins.yaml index ff4d2aaac3..6ae31242a4 100644 --- a/src/sunstone/etc/sunstone-plugins.yaml +++ b/src/sunstone/etc/sunstone-plugins.yaml @@ -9,36 +9,15 @@ :user: :group: oneadmin: false -- plugins/hosts-tab.js: +- plugins/config-tab.js: + :ALL: true + :user: + :group: +- plugins/system-tab.js: :ALL: false :user: :group: oneadmin: true -- plugins/clusters-tab.js: - :ALL: false - :user: - :group: - oneadmin: true -- plugins/vms-tab.js: - :ALL: true - :user: - :group: -- plugins/datastores-tab.js: - :ALL: true - :user: - :group: -- plugins/templates-tab.js: - :ALL: true - :user: - :group: -- plugins/vnets-tab.js: - :ALL: true - :user: - :group: -- plugins/images-tab.js: - :ALL: true - :user: - :group: - plugins/users-tab.js: :ALL: false :user: @@ -54,7 +33,38 @@ :user: :group: oneadmin: true -- plugins/config-tab.js: +- plugins/vresources-tab.js: :ALL: true :user: :group: +- plugins/vms-tab.js: + :ALL: true + :user: + :group: +- plugins/templates-tab.js: + :ALL: true + :user: + :group: +- plugins/images-tab.js: + :ALL: true + :user: + :group: +- plugins/hosts-tab.js: + :ALL: false + :user: + :group: + oneadmin: true +- plugins/datastores-tab.js: + :ALL: true + :user: + :group: +- plugins/vnets-tab.js: + :ALL: true + :user: + :group: +- plugins/clusters-tab.js: + :ALL: false + :user: + :group: + oneadmin: true + diff --git a/src/sunstone/public/css/application.css b/src/sunstone/public/css/application.css index 2f4bbcc15b..c4fca87454 100644 --- a/src/sunstone/public/css/application.css +++ b/src/sunstone/public/css/application.css @@ -31,6 +31,11 @@ select, button { padding: 2px; } +.inline-icon { + display:inline-block; + vertical-align:middle; +} + h2 { float:left; font-size:20px; @@ -46,19 +51,34 @@ h3 { margin: 0 0; } -table#dashboard_table{ +table.dashboard_table{ width:100%; margin: 0; } -table#dashboard_table tr { +table.dashboard_table tr { vertical-align: top; } -table#dashboard_table > tbody > tr > td{ +table.dashboard_table > tbody > tr > td{ width:50%; } +table.dashboard_table .inline-icon { + margin-left: 40px; +} + + +.dashboard_p { + color: #353735; + text-align:justify; +} + + +.clusterElemLi { + list-style: circle; +} + div.panel { background-color: #ffffff; padding:0; diff --git a/src/sunstone/public/css/layout.css b/src/sunstone/public/css/layout.css index 6bf81da6ed..142047d310 100644 --- a/src/sunstone/public/css/layout.css +++ b/src/sunstone/public/css/layout.css @@ -38,6 +38,10 @@ body { padding: 5px 10px 0 10px; } +.hidden { + display:none; +} + body { font-family: Arial, Verdana, Geneva, Helvetica, sans-serif; font-size: 13px; @@ -139,6 +143,29 @@ background-image: -moz-linear-gradient( padding-left: 30px; } +.navigation li.subsubTab { + line-height: 1.7em; + font-size: 11px; + text-align: left; + padding-left: 40px; + +} + +.navigation li.topTab span.plusIcon, +.navigation li.subTab span.plusIcon { + display : none; + float: right; + margin-right: 1em; +} + +.navigation li.topTab span.plusIcon { + margin-top: 5px; +} + +.navigation li.subTab span.plusIcon { + margin-top: 3px; +} + #navigation li a { color: #ffffff; } @@ -177,3 +204,49 @@ background-image: -moz-linear-gradient( #navigation li:hover a, .navigation-active-li-a { color: #ffffff !important; } + + +/* top menu css */ +#menutop_container{ + margin:0px 171px; + color:#FFFFFF; + font-size:13px; + font-weight:bold; +} +#menutop_navbar{ + float:left; + height:25px; + font-size:13px; +} +#menutop_navbar ul{ + float:left; + height:25px; + color:#000000; + margin: 0 0; + padding-left: 1px; +} +#menutop_navbar ul{ + background-color: #353735; +} +#menutop_navbar ul li{ + float:left; + min-width:72px; + margin:0px 0 0 0; + height:22px; + display: inline; + text-align:center; + padding-left:5px; + padding-right: 5px; + padding-top: 4px; + padding-bottom: 4px; + border-left:1px solid white; + cursor:pointer; + color: white; +} + +#menutop_navbar ul li:hover { + background-color: #E69138; + +} + +/* end top menu css */ \ No newline at end of file diff --git a/src/sunstone/public/js/layout.js b/src/sunstone/public/js/layout.js index b0489446bc..54b7bcb06f 100644 --- a/src/sunstone/public/js/layout.js +++ b/src/sunstone/public/js/layout.js @@ -31,19 +31,27 @@ function popDialogLoading(){ popDialog(loading); } -function showTab(tabname){ - activeTab = tabname; +function showTab(tabname,highlight_tab){ + var activeTab = tabname; + + if (!highlight_tab) highlight_tab = activeTab; //clean selected menu $("#navigation li").removeClass("navigation-active-li"); $("#navigation li a").removeClass("navigation-active-li-a"); + $("div#header ul#menutop_ul li").removeClass("navigation-active-li"); - //select menu - var li = $("#navigation li:has(a[href='"+activeTab+"'])") - var li_a = $("#navigation li a[href='"+activeTab+"']") + //select tab in left menu + var li = $("#navigation li:has(a[href='"+highlight_tab+"'])") + var li_a = $("#navigation li a[href='"+highlight_tab+"']") li.addClass("navigation-active-li"); li_a.addClass("navigation-active-li-a"); + //select tab in top menu + var top_li = $("div#header ul#menutop_ul li#top_"+highlight_tab.substring(1)); + top_li.addClass("navigation-active-li"); + + //show tab $(".tab").hide(); $(activeTab).show(); @@ -60,38 +68,67 @@ function setupTabs(){ var subTabs = $(".outer-west ul li.subTab"); subTabs.live("click",function(){ + //leave floor to topTab listener in case of tabs with both classes + if ($(this).hasClass('topTab')) return false; + var tab = $('a',this).attr('href'); showTab(tab); return false; }); topTabs.live("click",function(e){ - var tab = $('a',this).attr('href'); - //toggle subtabs trick - if ($(e.target).is('span')){ - $('li.'+tab.substr(1)).fadeToggle('fast'); - $('span',this).toggleClass('ui-icon-circle-plus ui-icon-circle-minus'); - return false; - } else if ($(this).hasClass("navigation-active-li")){//duplicate - $('li.'+tab.substr(1)).fadeToggle('fast'); + var tab = $('a',this).attr('href'); //This tabs #name + //Subtabs have a class with the name of this tab + var subtabs = $('div#menu li.'+tab.substr(1)); + + //toggle subtabs only when clicking on the icon or when clicking on an + //already selected menu + if ($(e.target).is('span') || + $(this).hasClass("navigation-active-li")){ + //for each subtab, we hide the subsubtabs + subtabs.each(function(){ + //for each subtab, hide its subtabs + var subsubtabs = $('a',this); + //subsubtabs class + subsubtabs = subsubtabs.attr('href').substr(1); + subsubtabs = $('div#menu li.'+subsubtabs); + subsubtabs.hide(); + }); + //hide subtabs and reset icon to + position, since all subsubtabs + //are hidden + subtabs.fadeToggle('fast'); + $('span',subtabs).removeClass('ui-icon-circle-minus'); + $('span',subtabs).addClass('ui-icon-circle-plus'); + //toggle icon on this tab $('span',this).toggleClass('ui-icon-circle-plus ui-icon-circle-minus'); }; + //if we are clicking on the icon only, do not show the tab + if ($(e.target).is('span')) return false; + showTab(tab); return false; }); }; +function setupTopMenu(){ + $('div#header ul#menutop_ul li').live('click',function(){ + var tab = "#" + $(this).attr('id').substring(4); + showTab(tab); + }); +}; + $(document).ready(function () { $(".tab").hide(); setupTabs(); + setupTopMenu(); outerLayout = $('body').layout({ applyDefaultStyles: false , center__paneSelector: ".outer-center" , west__paneSelector: ".outer-west" - , west__size: 133 + , west__size: 181 , north__size: 26 , south__size: 26 , spacing_open: 0 // ALL panes diff --git a/src/sunstone/public/js/plugins/acls-tab.js b/src/sunstone/public/js/plugins/acls-tab.js index 8688c3be92..6a78b08d4f 100644 --- a/src/sunstone/public/js/plugins/acls-tab.js +++ b/src/sunstone/public/js/plugins/acls-tab.js @@ -156,7 +156,9 @@ var acl_buttons = { var acls_tab = { title: tr("ACLs"), content: acls_tab_content, - buttons: acl_buttons + buttons: acl_buttons, + tabClass: 'subTab', + parentTab: 'system_tab' } Sunstone.addActions(acl_actions); @@ -303,6 +305,7 @@ function updateAclsView(request,list){ }); updateView(list_array,dataTable_acls); updateDashboard("acls",list); + updateSystemDashboard("acls",list); } function setupCreateAclDialog(){ diff --git a/src/sunstone/public/js/plugins/clusters-tab.js b/src/sunstone/public/js/plugins/clusters-tab.js index 0a9a90c52a..405353ebbd 100644 --- a/src/sunstone/public/js/plugins/clusters-tab.js +++ b/src/sunstone/public/js/plugins/clusters-tab.js @@ -212,7 +212,8 @@ var host_info_panel = { var clusters_tab = { title: tr("Clusters"), content: clusters_tab_content, - buttons: cluster_buttons + buttons: cluster_buttons, + showOnTopMenu: true, } Sunstone.addActions(cluster_actions); @@ -296,11 +297,232 @@ function updateClustersView (request,list){ list_array.push(clusterElementArray(this)); }); + removeClusterMenus(); + updateView(list_array,dataTable_clusters); updateClusterSelect(); //dependency with the dashboard plugin updateDashboard("clusters",list); -} + newClusterMenu(list); +}; + + +function clusterTabContent(cluster_json) { + var cluster = cluster_json.CLUSTER; + + var dss_list = '
  • '+tr("No datastores in this cluster")+'
  • '; + if (cluster.DATASTORES.ID && + cluster.DATASTORES.ID.constructor == Array){ + dss_list = ''; + for (var i=0; i'; + }; + } else if (cluster.DATASTORES.ID) + dss_list = '
  • '+cluster.DATASTORES.ID+' - '+getDatastoreName(cluster.DATASTORES.ID)+'
  • '; + + var hosts_list = '
  • '+tr("No hosts in this cluster")+'
  • '; + if (cluster.HOSTS.ID && + cluster.HOSTS.ID.constructor == Array){ + hosts_list = ''; + for (var i=0; i'; + }; + } else if (cluster.HOSTS.ID) + hosts_list = '
  • '+cluster.HOSTS.ID+' - '+getHostName(cluster.HOSTS.ID)+'
  • '; + + var vnets_list = '
  • '+tr("No virtual networks in this cluster")+'
  • '; + if (cluster.VNETS.ID && + cluster.VNETS.ID.constructor == Array){ + vnets_list = ''; + for (var i=0; i'; + }; + } else if (cluster.VNETS.ID) + vnets_list = '
  • '+cluster.VNETS.ID+' - '+getVNetName(cluster.VNETS.ID)+'
  • '; + + var html_code = '\ +
    '+tr("Datastore information")+' - '+info.NAME+'
    '+tr("Base path")+''+info.BASE_PATH+'
    '+tr("Images")+''+images_str+'
    '+tr("Permissions")+'
         '+tr("Owner")+'
    \ +\ +\ +\ +
    \ +\ + \ + \ + \ + \ + \ + \ +
    \ +
    \ +

    ' + tr("Cluster information") + '

    \ +
    \ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
    ' + tr("ID") + ''+cluster.ID+'
    ' + tr("Name") + ''+cluster.NAME+'
    \ +\ +
    \ +
    \ +
    \ +
    \ +

    ' + tr("Hosts in this cluster") + '

    \ +
    \ +\ +
      '+hosts_list+'\ +
    \ +\ +
    \ +
    \ +
    \ +\ + \ + \ + \ + \ + \ + \ +
    \ +
    \ +

    ' + tr("Datastores in this cluster") + '

    \ +
    \ +\ +
      '+dss_list+'\ +
    \ +\ +
    \ +
    \ +
    \ +
    \ +

    ' + tr("Virtual Networks in this cluster") + '

    \ +
    \ +\ +
      '+vnets_list+'\ +
    \ +\ +
    \ +
    \ +
    \ +
    \ +'; + + return html_code; +}; + +function removeClusterMenus(){ + var data = dataTable_clusters.fnGetData(); + + Sunstone.removeMainTab('cluster_vnets_tab_n',true); + Sunstone.removeMainTab('cluster_datastores_tab_n',true); + Sunstone.removeMainTab('cluster_hosts_tab_n',true); + Sunstone.removeMainTab('cluster_tab_n',true); + + for (var i=0; i < data.length; i++){ + var id = data[i][1]; + Sunstone.removeMainTab('cluster_vnets_tab_'+id,true); + Sunstone.removeMainTab('cluster_datastores_tab_'+id,true); + Sunstone.removeMainTab('cluster_hosts_tab_'+id,true); + Sunstone.removeMainTab('cluster_tab_'+id,true); + }; +}; + + +function newClusterMenu(list){ + var cluster_none = { + 'CLUSTER' : { + 'NAME' : 'None', + 'ID' : 'n', + 'DATASTORES' : [], + 'HOSTS' : [], + 'VNETS' : [] + } + }; + + newClusterMenuElement(cluster_none); + + for (var i=0; i < list.length; i++){ + newClusterMenuElement(list[i]); + }; + $('div#menu li#li_clusters_tab span').removeClass('ui-icon-circle-minus'); + $('div#menu li#li_clusters_tab span').addClass('ui-icon-circle-plus'); +}; + +function newClusterMenuElement(element){ + var cluster = element.CLUSTER; + var menu_name = cluster.NAME.length > 10 ? + cluster.NAME.substring(0,9)+'...' : cluster.NAME; + + var menu_cluster = { + title: menu_name + ' (id ' + cluster.ID + ')', + content: clusterTabContent(element), + tabClass: 'topTab subTab', + parentTab: 'clusters_tab' +// buttons: null + }; + + var submenu_hosts = { + title: tr("Hosts"), + content: '', + tabClass: "subTab clusterHosts subsubTab", + parentTab: "cluster_tab_" + cluster.ID + }; + + var submenu_datastores = { + title: tr("Datastores"), + content: '', + tabClass: "subTab clusterDatastores subsubTab", + parentTab: "cluster_tab_" + cluster.ID + }; + + var submenu_vnets = { + title: tr("Virtual Networks"), + content: '', + tabClass: "subTab clusterVnets subsubTab", + parentTab: "cluster_tab_" + cluster.ID + }; + + Sunstone.addMainTab('cluster_tab_'+cluster.ID,menu_cluster,true); + Sunstone.addMainTab('cluster_hosts_tab_'+cluster.ID,submenu_hosts,true); + Sunstone.addMainTab('cluster_datastores_tab_'+cluster.ID,submenu_datastores,true); + Sunstone.addMainTab('cluster_vnets_tab_'+cluster.ID,submenu_vnets,true); +}; + +function clusterSubmenusListeners(){ + //hack the menu selection + $('div#menu li.clusterHosts').live('click',function(){ + var id = $(this).attr('id'); + id = id.split('_'); + id = id[id.length-1]; + dataTable_hosts.fnFilter(getClusterName(id),3,false,true,false,true); + showTab('#hosts_tab',$('a',this).attr('href')); + return false; + }); + + $('div#menu li.clusterDatastores').live('click',function(){ + var id = $(this).attr('id'); + id = id.split('_'); + id = id[id.length-1]; + dataTable_datastores.fnFilter(getClusterName(id),5,false,true,false,true); + showTab('#datastores_tab',$('a',this).attr('href')); + return false; + }); + + $('div#menu li.clusterVnets').live('click',function(){ + var id = $(this).attr('id'); + id = id.split('_'); + id = id[id.length-1]; + dataTable_vNetworks.fnFilter(getClusterName(id),5,false,true,false,true); + showTab('#vnets_tab',$('a',this).attr('href')); + return false; + }); +}; /* //Updates the host info panel tab's content and pops it up @@ -459,9 +681,12 @@ function popUpCreateClusterDialog(){ //Prepares the autorefresh for hosts function setClusterAutorefresh() { setInterval(function(){ + var selected_menu = $('div#menu li.navigation-active-li'); + var inSubMenu = selected_menu.attr('id').indexOf('cluster') > 0; + var checked = $('input.check_item:checked',dataTable_clusters); var filter = $("#datatable_clusters_filter input",dataTable_clusters.parents('#datatable_clusters_wrapper')).attr('value'); - if (!checked.length && !filter.length){ + if (!checked.length && !filter.length && !inSubMenu){ Sunstone.runAction("Cluster.autorefresh"); } },INTERVAL+someTime()); @@ -505,6 +730,8 @@ $(document).ready(function(){ setClusterAutorefresh(); + clusterSubmenusListeners(); + initCheckAllBoxes(dataTable_clusters); tableCheckboxesListener(dataTable_clusters); // clusterInfoListener(); diff --git a/src/sunstone/public/js/plugins/config-tab.js b/src/sunstone/public/js/plugins/config-tab.js index 303961fb60..7b2ec99427 100644 --- a/src/sunstone/public/js/plugins/config-tab.js +++ b/src/sunstone/public/js/plugins/config-tab.js @@ -58,8 +58,10 @@ var config_actions = { var config_tab = { title: tr("Configuration"), - content: config_tab_content -} + content: config_tab_content, + tabClass: "subTab", + parentTab: "dashboard_tab", +}; Sunstone.addActions(config_actions); Sunstone.addMainTab('config_tab',config_tab); diff --git a/src/sunstone/public/js/plugins/dashboard-tab.js b/src/sunstone/public/js/plugins/dashboard-tab.js index 06b931244b..3e06fb4de2 100644 --- a/src/sunstone/public/js/plugins/dashboard-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-tab.js @@ -43,7 +43,7 @@ var graph4 = { }; var dashboard_tab_content = -'\ +'
    \ \
    \ \ @@ -67,28 +67,28 @@ var dashboard_tab_content = \ \ \ - \ - \ + \ + \ \ \ \ \ \ \ - \ - \ + \ + \ \ \ \ \ \ \ - \ - \ + \ + \ \ \ \ @@ -108,20 +108,20 @@ var dashboard_tab_content = \ \ @@ -158,7 +158,8 @@ var dashboard_tab_content = var dashboard_tab = { title: tr("Dashboard"), - content: dashboard_tab_content + content: dashboard_tab_content, + showOnTopMenu: true, } Sunstone.addMainTab('dashboard_tab',dashboard_tab); @@ -209,13 +210,6 @@ function plot_global_graph(data,info){ $.plot($('#'+id+'_graph',context),series,options); } -function quickstart_setup(){ - - $('#dashboard_table #quickstart_form input',main_tabs_context).click(function(){ - Sunstone.runAction($(this).val()); - }); -} - function graph_autorefresh(){ setInterval(function(){ refresh_graphs(); @@ -232,7 +226,7 @@ function refresh_graphs(){ $(document).ready(function(){ //Dashboard link listener - $("#dashboard_table h3 a",main_tabs_context).live("click", function (){ + $("#dashboard_tab h3 a",main_tabs_context).live("click", function (){ var tab = $(this).attr('href'); showTab(tab); return false; @@ -240,8 +234,6 @@ $(document).ready(function(){ emptyDashboard(); - quickstart_setup(); - refresh_graphs(); graph_autorefresh(); @@ -288,14 +280,8 @@ function updateDashboard(what,json_info){ $('#failed_vms',db).html(failed_vms); break; case "vnets": - var public_vnets=0; var total_vnets=json_info.length; - $.each(json_info,function(){ - if (parseInt(this.VNET.PUBLIC)){ - public_vnets++;} - }); - $('#total_vnets',db).html(total_vnets+' / '); - $('#public_vnets',db).html(public_vnets); + $('#total_vnets',db).html(total_vnets); break; case "users": var total_users=json_info.length; @@ -303,24 +289,11 @@ function updateDashboard(what,json_info){ break; case "images": var total_images=json_info.length; - var public_images=0; - $.each(json_info,function(){ - if (parseInt(this.IMAGE.PUBLIC)){ - public_images++;} - }); - $('#total_images',db).html(total_images+' / '); - $('#public_images',db).html(public_images); + $('#total_images',db).html(total_images); break; case "templates": var total_templates=json_info.length; - var public_templates=0; - $.each(json_info,function(){ - if (parseInt(this.VMTEMPLATE.PUBLIC)){ - public_templates++; - } - }); - $('#total_templates',db).html(total_templates+' / '); - $('#public_templates',db).html(public_templates); + $('#total_templates',db).html(total_templates); break; case "acls": var total_acls=json_info.length; @@ -335,4 +308,4 @@ function updateDashboard(what,json_info){ $('#total_datastores',db).html(total_datastores); break; } -} +}; diff --git a/src/sunstone/public/js/plugins/dashboard-users-tab.js b/src/sunstone/public/js/plugins/dashboard-users-tab.js index f27ed855fb..e929667e86 100644 --- a/src/sunstone/public/js/plugins/dashboard-users-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-users-tab.js @@ -43,7 +43,7 @@ var graph4 = { }; var dashboard_tab_content = -'
    ' + tr("VM Templates (total/public)") + '' + tr("VM Templates") + '
    ' + - tr("VM Instances")+ ' (' + + tr("VM Instances")+ ' (' + tr("total") + '/' + - tr("running") + '/' + + tr("running") + '/' + tr("failed") + ')
    ' + tr("Virtual Networks (total/public)") + '' + tr("Virtual Networks") + '
    ' + tr("Datastores") + '
    ' + tr("Images (total/public)") + '' + tr("Images") + '
    ' + tr("Users")+'\
    \

    ' + tr("Quickstart") + '

    \ -
    \ -
    \ -\ - ' + tr("Host") + '
    \ - ' + tr("Cluster") + '
    \ - ' + tr("VM Instance") + '
    \ - ' + tr("VM Template") + '
    \ - ' + tr("Virtual Network") + '
    \ - ' + tr("Datastore") + '
    \ - ' + tr("Image") + '
    \ - ' + tr("User") + '
    \ - ' + tr("Group") + '
    \ - ' + tr("Acl") + '
    \ -
    \ + \
    \
    \ +'
    \ \ \ \ @@ -131,7 +131,8 @@ var dashboard_tab_content = var dashboard_tab = { title: tr("Dashboard"), - content: dashboard_tab_content + content: dashboard_tab_content, + showOnTopMenu: true, } Sunstone.addMainTab('dashboard_tab',dashboard_tab); @@ -183,13 +184,6 @@ function plot_global_graph(data,info){ $.plot($('#'+id+'_graph',context),series,options); } -function quickstart_setup(){ - - $('#dashboard_table #quickstart_form input',main_tabs_context).click(function(){ - Sunstone.runAction($(this).val()); - }); -} - function graph_autorefresh(){ setInterval(function(){ refresh_graphs(); @@ -214,8 +208,6 @@ $(document).ready(function(){ emptyDashboard(); - quickstart_setup(); - refresh_graphs(); graph_autorefresh(); @@ -262,14 +254,8 @@ function updateDashboard(what,json_info){ $('#failed_vms',db).html(failed_vms); break; case "vnets": - var public_vnets=0; var total_vnets=json_info.length; - $.each(json_info,function(){ - if (parseInt(this.VNET.PUBLIC)){ - public_vnets++;} - }); - $('#total_vnets',db).html(total_vnets+' / '); - $('#public_vnets',db).html(public_vnets); + $('#total_vnets',db).html(total_vnets); break; case "users": var total_users=json_info.length; @@ -277,24 +263,11 @@ function updateDashboard(what,json_info){ break; case "images": var total_images=json_info.length; - var public_images=0; - $.each(json_info,function(){ - if (parseInt(this.IMAGE.PUBLIC)){ - public_images++;} - }); - $('#total_images',db).html(total_images+' / '); - $('#public_images',db).html(public_images); + $('#total_images',db).html(total_images); break; case "templates": var total_templates=json_info.length; - var public_templates=0; - $.each(json_info,function(){ - if (parseInt(this.VMTEMPLATE.PUBLIC)){ - public_templates++; - } - }); - $('#total_templates',db).html(total_templates+' / '); - $('#public_templates',db).html(public_templates); + $('#total_templates',db).html(total_templates); break; case "acls": var total_acls=json_info.length; @@ -309,4 +282,4 @@ function updateDashboard(what,json_info){ $('#total_datastores',db).html(total_datastores); break; } -} \ No newline at end of file +}; \ No newline at end of file diff --git a/src/sunstone/public/js/plugins/datastores-tab.js b/src/sunstone/public/js/plugins/datastores-tab.js index 88afb16aab..906508e706 100644 --- a/src/sunstone/public/js/plugins/datastores-tab.js +++ b/src/sunstone/public/js/plugins/datastores-tab.js @@ -314,7 +314,9 @@ var datastore_info_panel = { var datastores_tab = { title: tr("Datastores"), content: datastores_tab_content, - buttons: datastore_buttons + buttons: datastore_buttons, + tabClass: "hidden", + showOnTopMenu: true, } Sunstone.addActions(datastore_actions); @@ -683,4 +685,8 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_datastores); tableCheckboxesListener(dataTable_datastores); datastoreInfoListener(); + + $('div#header ul#menutop_ul li#top_datastores_tab').live('click',function(){ + dataTable_datastores.fnFilter('',5); + }); }) \ No newline at end of file diff --git a/src/sunstone/public/js/plugins/groups-tab.js b/src/sunstone/public/js/plugins/groups-tab.js index 981ed8f3c7..bd267b42e7 100644 --- a/src/sunstone/public/js/plugins/groups-tab.js +++ b/src/sunstone/public/js/plugins/groups-tab.js @@ -142,8 +142,10 @@ var group_buttons = { var groups_tab = { title: tr("Groups"), content: groups_tab_content, - buttons: group_buttons -} + buttons: group_buttons, + tabClass: 'subTab', + parentTab: 'system_tab' +}; Sunstone.addActions(group_actions); Sunstone.addMainTab('groups_tab',groups_tab); @@ -224,6 +226,7 @@ function updateGroupsView(request, group_list){ updateView(group_list_array,dataTable_groups); updateGroupSelect(group_list); updateDashboard("groups",group_list); + updateSystemDashboard("groups",group_list); } //Prepares the dialog to create diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 084434343c..3ada27792f 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -318,8 +318,10 @@ var host_info_panel = { var hosts_tab = { title: tr("Hosts"), content: hosts_tab_content, - buttons: host_buttons -} + buttons: host_buttons, + tabClass: "hidden", + showOnTopMenu: true, +}; Sunstone.addActions(host_actions); Sunstone.addMainTab('hosts_tab',hosts_tab); @@ -665,4 +667,8 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_hosts); tableCheckboxesListener(dataTable_hosts); hostInfoListener(); + + $('div#header ul#menutop_ul li#top_hosts_tab').live('click',function(){ + dataTable_hosts.fnFilter('',3); + }); }); diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index ca5dd57182..5fddb91c4e 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -496,7 +496,9 @@ var image_info_panel = { var images_tab = { title: tr("Images"), content: images_tab_content, - buttons: image_buttons + buttons: image_buttons, + tabClass: 'subTab', + parentTab: 'vres_tab' } Sunstone.addActions(image_actions); @@ -586,6 +588,7 @@ function updateImagesView(request, images_list){ updateView(image_list_array,dataTable_images); updateDashboard("images",images_list); + updateVResDashboard("images",images_list); } // Callback to update the information panel tabs and pop it up diff --git a/src/sunstone/public/js/plugins/system-tab.js b/src/sunstone/public/js/plugins/system-tab.js new file mode 100644 index 0000000000..ac636eb503 --- /dev/null +++ b/src/sunstone/public/js/plugins/system-tab.js @@ -0,0 +1,113 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +var system_tab_content = +'
    \ \ @@ -55,8 +55,8 @@ var dashboard_tab_content = \
    \ \ - \ - \ + \ + \ \ \ \ \ \ - \ - \ + \ + \ \ \ \ \ \ \ - \ - \ + \ + \ \
    '+tr("VM Templates (total/public)")+''+tr("VM Templates")+'
    '+tr("VM Instances")+' ('+ @@ -66,16 +66,16 @@ var dashboard_tab_content =
    '+tr("Virtual Networks (total/public)")+''+tr("Virtual Networks")+'
    ' + tr("Datastores") + '
    '+tr("Images (total/public)")+''+tr("Images")+'
    \ \ @@ -87,14 +87,14 @@ var dashboard_tab_content =
    \
    \

    '+tr("Quickstart")+'

    \ -
    \ -
    \ - \ - '+tr("VM Template")+'
    \ - '+tr("VM Instance")+'
    \ - '+tr("Virtual Network")+'
    \ - '+tr("Image")+'
    \ -
    \ + \
    \
    \ +\ +\ +\ +
    \ +\ + \ + \ + \ + \ + \ + \ +
    \ +
    \ +

    ' + tr("Summary of system resources") + '

    \ +
    \ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
    ' + tr("Groups") + '
    ' + tr("Users")+'
    ' + tr("ACL Rules") + '
    \ +\ +
    \ +
    \ +
    \ +
    \ +

    ' + tr("Quickstart") + '

    \ + \ +
    \ +
    \ +
    \ +\ + \ + \ + \ +
    \ +
    \ +

    ' + tr("System Resources") + '

    \ +
    \ +

    '+tr("System resources management is only accesible to users of the oneadmin group. It comprises the operations regarding OpenNebula groups, users and ACLs.")+'

    \ +

    '+tr("You can find further information on the following links:")+'

    \ + \ +
    \ +
    \ +
    \ +
    '; + +var system_tab = { + title: tr("System"), + content: system_tab_content +} + +Sunstone.addMainTab('system_tab',system_tab); + +function updateSystemDashboard(what, json_info){ + var db = $('#system_tab',main_tabs_context); + switch (what){ + case "groups": + var total_groups=json_info.length; + $('#system_total_groups',db).html(total_groups); + break; + case "users": + var total_users=json_info.length; + $('#system_total_users',db).html(total_users); + break; + case "acls": + var total_acls=json_info.length; + $('#system_total_acls',db).html(total_acls); + break; + }; +} + +$(document).ready(function(){ + +}); \ No newline at end of file diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index f4f1f8a28e..dc9566daa3 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -830,7 +830,9 @@ var template_info_panel = { var templates_tab = { title: tr("Templates"), content: templates_tab_content, - buttons: template_buttons + buttons: template_buttons, + tabClass: 'subTab', + parentTab: 'vres_tab' } Sunstone.addActions(template_actions); @@ -922,7 +924,7 @@ function updateTemplatesView(request, templates_list){ updateView(template_list_array,dataTable_templates); updateTemplateSelect(); updateDashboard("templates",templates_list); - + updateVResDashboard("templates",templates_list); } // Callback to update the information panel tabs and pop it up diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index 19d48435e1..906004e77d 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -306,8 +306,10 @@ var user_info_panel = { var users_tab = { title: tr("Users"), content: users_tab_content, - buttons: user_buttons -} + buttons: user_buttons, + tabClass: 'subTab', + parentTab: 'system_tab' +}; Sunstone.addActions(user_actions); Sunstone.addMainTab('users_tab',users_tab); @@ -383,6 +385,7 @@ function updateUsersView(request,users_list){ }); updateView(user_list_array,dataTable_users); updateDashboard("users",users_list); + updateSystemDashboard("users",users_list); updateUserSelect(); }; diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index ae2364a0e6..ff5815c3fe 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -598,7 +598,9 @@ var vm_info_panel = { var vms_tab = { title: tr("Virtual Machines"), content: vms_tab_content, - buttons: vm_buttons + buttons: vm_buttons, + tabClass: 'subTab', + parentTab: 'vres_tab' } Sunstone.addActions(vm_actions); @@ -700,6 +702,7 @@ function updateVMachinesView(request, vmachine_list){ updateView(vmachine_list_array,dataTable_vMachines); updateDashboard("vms",vmachine_list); + updateVResDashboard("vms",vmachine_list); } diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index f1865b92dc..3716278276 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -457,7 +457,9 @@ var vnet_info_panel = { var vnets_tab = { title: tr("Virtual Networks"), content: vnets_tab_content, - buttons: vnet_buttons + buttons: vnet_buttons, + tabClass: "hidden", + showOnTopMenu: true, } Sunstone.addActions(vnet_actions); @@ -1197,4 +1199,8 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_vNetworks); tableCheckboxesListener(dataTable_vNetworks); vNetworkInfoListener(); + + $('div#header ul#menutop_ul li#top_vnets_tab').live('click',function(){ + dataTable_vNetworks.fnFilter('',5); + }); }); diff --git a/src/sunstone/public/js/plugins/vresources-tab.js b/src/sunstone/public/js/plugins/vresources-tab.js new file mode 100644 index 0000000000..080e933aa0 --- /dev/null +++ b/src/sunstone/public/js/plugins/vresources-tab.js @@ -0,0 +1,137 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +var vres_tab_content = +'\ +\ +\ +\ +
    \ +\ + \ + \ + \ + \ + \ + \ +
    \ +
    \ +

    ' + tr("Summary of virtual resources") + '

    \ +
    \ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ +\ + \ + \ + \ +
    ' + tr("VM Templates") + '
    ' + + tr("VM Instances")+ ' (' + + tr("total") + '/' + + tr("running") + '/' + + tr("failed") + ')
    ' + tr("Images") + '
    \ +\ +
    \ +
    \ +
    \ + \ +
    \ +
    \ +\ + \ + \ + \ +
    \ +
    \ +

    ' + tr("Virtual Resources") + '

    \ +
    \ +

    '+tr("The Virtual Resources menu allows management of Virtual Machine Templates, Instances and Images.")+'

    \ +

    '+tr("You can find further information on the following links:")+'

    \ + \ +
    \ +
    \ +
    \ +
    '; + +var vres_tab = { + title: tr("Virtual Resources"), + content: vres_tab_content +} + +Sunstone.addMainTab('vres_tab',vres_tab); + +function updateVResDashboard(what,json_info){ + var db = $('#vres_tab',main_tabs_context); + switch (what){ + case "vms": + var total_vms=json_info.length; + var running_vms=0; + failed_vms=0; + $.each(json_info,function(){ + vm_state = parseInt(this.VM.STATE); + if (vm_state == 3){ + running_vms++; + } + else if (vm_state == 7) { + failed_vms++; + } + }); + $('#vres_total_vms',db).html(total_vms+' / '); + $('#vres_running_vms',db).html(running_vms+' / '); + $('#vres_failed_vms',db).html(failed_vms); + break; + case "vnets": + var total_vnets=json_info.length; + $('#vres_total_vnets',db).html(total_vnets); + break; + case "images": + var total_images=json_info.length; + $('#vres_total_images',db).html(total_images); + break; + case "templates": + var total_templates=json_info.length; + $('#vres_total_templates',db).html(total_templates); + break; + }; +}; + +$(document).ready(function(){ + +}); \ No newline at end of file diff --git a/src/sunstone/public/js/sunstone-util.js b/src/sunstone/public/js/sunstone-util.js index 4b16656250..22064569de 100644 --- a/src/sunstone/public/js/sunstone-util.js +++ b/src/sunstone/public/js/sunstone-util.js @@ -422,6 +422,34 @@ function getImageName(id){ return id; }; +function getClusterName(id){ + if (typeof(dataTable_clusters) != "undefined"){ + return getName(id,dataTable_clusters,2); + } + return id; +}; + +function getDatastoreName(id){ + if (typeof(dataTable_datastores) != "undefined"){ + return getName(id,dataTable_datastores,4); + } + return id; +}; + +function getVNetName(id){ + if (typeof(dataTable_vNetworks) != "undefined"){ + return getName(id,dataTable_vNetworks,4); + } + return id; +}; + +function getHostName(id){ + if (typeof(dataTable_hosts) != "undefined"){ + return getName(id,dataTable_hosts,2); + } + return id; +}; + function getName(id,dataTable,name_col){ var name = id; if (typeof(dataTable) == "undefined") { diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js index 6edbc35447..b44b45ed76 100644 --- a/src/sunstone/public/js/sunstone.js +++ b/src/sunstone/public/js/sunstone.js @@ -296,7 +296,7 @@ $(document).ready(function(){ //Insert the tabs in the DOM and their buttons. insertTabs(); - //hideSubTabs(); +// hideSubTabs(); insertButtons(); //Enhace the look of select buttons @@ -452,31 +452,30 @@ function insertTabs(){ //adding the content to the proper div and by adding a list item //link to the navigation menu function insertTab(tab_name){ - var tab_info = SunstoneCfg["tabs"][tab_name]; - var condition = tab_info["condition"]; - var tabClass = tab_info["tabClass"]; - var parent = ""; - - if (!tabClass) { - tabClass="topTab"; - } else if (tabClass=="subTab") { - parent = tab_info["parentTab"]; - }; + var tab_info = SunstoneCfg['tabs'][tab_name]; + var condition = tab_info['condition']; + var tabClass = tab_info['tabClass'] ? tab_info['tabClass'] : 'topTab'; + var parent = tab_info['parentTab'] ? tab_info['parentTab'] : ''; + var showOnTop = tab_info['showOnTopMenu']; //skip this tab if we do not meet the condition if (condition && !condition()) {return;} - main_tabs_context.append('
    '); + main_tabs_context.append(''); $('div#'+tab_name,main_tabs_context).html(tab_info.content); - $('div#menu ul#navigation').append('
  • '+tab_info.title+'
  • '); + $('div#menu ul#navigation').append('
  • '+tab_info.title+'
  • '); if (parent){ //this is a subtab $('div#menu li#li_'+tab_name).hide();//hide by default $('div#menu li#li_'+parent+' span').css("display","inline-block"); }; -} + + if (showOnTop){ + $('div#header ul#menutop_ul').append('
  • '+tab_info.title+'
  • '); + }; +}; function hideSubTabs(){ for (tab in SunstoneCfg["tabs"]){ diff --git a/src/sunstone/views/index.erb b/src/sunstone/views/index.erb index bca3dc5a1f..a2ad30582d 100644 --- a/src/sunstone/views/index.erb +++ b/src/sunstone/views/index.erb @@ -66,6 +66,15 @@ + + +
    Welcome  | Sign Out
    From b3351aa4b421836a06d172333468586cbb1bcc45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 14 Mar 2012 17:12:10 +0100 Subject: [PATCH 175/217] Feature #1112: Add missing mvds file in dummy tm_mad to install.sh --- install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 70bd372da3..aaf18f4b24 100755 --- a/install.sh +++ b/install.sh @@ -792,7 +792,8 @@ TM_DUMMY_FILES="src/tm_mad/dummy/clone \ src/tm_mad/dummy/mkswap \ src/tm_mad/dummy/mkimage \ src/tm_mad/dummy/mv \ - src/tm_mad/dummy/context" + src/tm_mad/dummy/context \ + src/tm_mad/dummy/mvds" TM_LVM_FILES="src/tm_mad/lvm/clone \ src/tm_mad/lvm/delete \ From cb458260fadfe2247c37d782cc22c91eb8c21a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 14 Mar 2012 17:24:13 +0100 Subject: [PATCH 176/217] Feature #1112: Remove non-existent file from install.sh, introduced in commit:4dc9a34b --- install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/install.sh b/install.sh index aaf18f4b24..f7242cd493 100755 --- a/install.sh +++ b/install.sh @@ -801,8 +801,7 @@ TM_LVM_FILES="src/tm_mad/lvm/clone \ src/tm_mad/lvm/mkswap \ src/tm_mad/lvm/mkimage \ src/tm_mad/lvm/mv \ - src/tm_mad/lvm/context \ - src/tm_mad/lvm/dummy" + src/tm_mad/lvm/context" TM_VMWARE_FILES="src/tm_mad/vmware/clone \ src/tm_mad/vmware/ln \ From 3506116a5eaade40b240fcaf1044328a55e358a2 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 15 Mar 2012 00:17:51 +0100 Subject: [PATCH 177/217] Feature #1112: Remove links from menu items. No need to use them as the effect is achieved with cursor: pointer; CSS property on
  • items directly. Update necessary sunstone files. --- src/sunstone/public/css/layout.css | 8 ++--- src/sunstone/public/js/layout.js | 30 +++++++++---------- .../public/js/plugins/clusters-tab.js | 6 ++-- .../public/js/plugins/dashboard-tab.js | 7 ----- .../public/js/plugins/dashboard-users-tab.js | 7 ----- src/sunstone/public/js/sunstone.js | 4 +-- 6 files changed, 24 insertions(+), 38 deletions(-) diff --git a/src/sunstone/public/css/layout.css b/src/sunstone/public/css/layout.css index 142047d310..4c28a08978 100644 --- a/src/sunstone/public/css/layout.css +++ b/src/sunstone/public/css/layout.css @@ -148,7 +148,6 @@ background-image: -moz-linear-gradient( font-size: 11px; text-align: left; padding-left: 40px; - } .navigation li.topTab span.plusIcon, @@ -166,8 +165,9 @@ background-image: -moz-linear-gradient( margin-top: 3px; } -#navigation li a { +#navigation li { color: #ffffff; + cursor: pointer; } #navigation li:hover, .navigation-active-li { @@ -198,10 +198,10 @@ background-image: -moz-linear-gradient( ); */ } -.navigation-active-li-a { +.navigation-active-li { font-weight: bold; } -#navigation li:hover a, .navigation-active-li-a { +#navigation li:hover { color: #ffffff !important; } diff --git a/src/sunstone/public/js/layout.js b/src/sunstone/public/js/layout.js index 54b7bcb06f..c655a50b10 100644 --- a/src/sunstone/public/js/layout.js +++ b/src/sunstone/public/js/layout.js @@ -32,33 +32,34 @@ function popDialogLoading(){ } function showTab(tabname,highlight_tab){ + //Since menu items no longer have an element + //we no longer expect #tab_id here, but simply tab_id + //So safety check - remove # from #tab_id if present to ensure compatibility + if (tabname.indexOf('#') == 0) + tabname = tabname.substring(1); + if (highlight_tab && highlight_tab.indexOf('#') == 0) + highlight_tab == highlight.substring(1); + var activeTab = tabname; if (!highlight_tab) highlight_tab = activeTab; //clean selected menu $("#navigation li").removeClass("navigation-active-li"); - $("#navigation li a").removeClass("navigation-active-li-a"); $("div#header ul#menutop_ul li").removeClass("navigation-active-li"); //select tab in left menu - var li = $("#navigation li:has(a[href='"+highlight_tab+"'])") - var li_a = $("#navigation li a[href='"+highlight_tab+"']") + var li = $("#navigation li#li_"+highlight_tab) li.addClass("navigation-active-li"); - li_a.addClass("navigation-active-li-a"); //select tab in top menu - var top_li = $("div#header ul#menutop_ul li#top_"+highlight_tab.substring(1)); + var top_li = $("div#header ul#menutop_ul li#top_"+highlight_tab); top_li.addClass("navigation-active-li"); //show tab $(".tab").hide(); - $(activeTab).show(); - //~ if (activeTab == '#dashboard') { - //~ emptyDashboard(); - //~ preloadTables(); - //~ } + $('#'+activeTab).show(); innerLayout.close("south"); } @@ -71,15 +72,15 @@ function setupTabs(){ //leave floor to topTab listener in case of tabs with both classes if ($(this).hasClass('topTab')) return false; - var tab = $('a',this).attr('href'); + var tab = $(this).attr('id').substring(3); showTab(tab); return false; }); topTabs.live("click",function(e){ - var tab = $('a',this).attr('href'); //This tabs #name + var tab = $(this).attr('id').substring(3); //Subtabs have a class with the name of this tab - var subtabs = $('div#menu li.'+tab.substr(1)); + var subtabs = $('div#menu li.'+tab); //toggle subtabs only when clicking on the icon or when clicking on an //already selected menu @@ -88,9 +89,8 @@ function setupTabs(){ //for each subtab, we hide the subsubtabs subtabs.each(function(){ //for each subtab, hide its subtabs - var subsubtabs = $('a',this); + var subsubtabs = $(this).attr('id').substr(3); //subsubtabs class - subsubtabs = subsubtabs.attr('href').substr(1); subsubtabs = $('div#menu li.'+subsubtabs); subsubtabs.hide(); }); diff --git a/src/sunstone/public/js/plugins/clusters-tab.js b/src/sunstone/public/js/plugins/clusters-tab.js index 405353ebbd..e063f160d3 100644 --- a/src/sunstone/public/js/plugins/clusters-tab.js +++ b/src/sunstone/public/js/plugins/clusters-tab.js @@ -501,7 +501,7 @@ function clusterSubmenusListeners(){ id = id.split('_'); id = id[id.length-1]; dataTable_hosts.fnFilter(getClusterName(id),3,false,true,false,true); - showTab('#hosts_tab',$('a',this).attr('href')); + showTab('#hosts_tab',$(this).attr('id').substring(3)); return false; }); @@ -510,7 +510,7 @@ function clusterSubmenusListeners(){ id = id.split('_'); id = id[id.length-1]; dataTable_datastores.fnFilter(getClusterName(id),5,false,true,false,true); - showTab('#datastores_tab',$('a',this).attr('href')); + showTab('#datastores_tab',$(this).attr('id').substring(3)); return false; }); @@ -519,7 +519,7 @@ function clusterSubmenusListeners(){ id = id.split('_'); id = id[id.length-1]; dataTable_vNetworks.fnFilter(getClusterName(id),5,false,true,false,true); - showTab('#vnets_tab',$('a',this).attr('href')); + showTab('#vnets_tab',$(this).attr('id').substring(3)); return false; }); }; diff --git a/src/sunstone/public/js/plugins/dashboard-tab.js b/src/sunstone/public/js/plugins/dashboard-tab.js index 3e06fb4de2..6549fb56cf 100644 --- a/src/sunstone/public/js/plugins/dashboard-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-tab.js @@ -225,13 +225,6 @@ function refresh_graphs(){ } $(document).ready(function(){ - //Dashboard link listener - $("#dashboard_tab h3 a",main_tabs_context).live("click", function (){ - var tab = $(this).attr('href'); - showTab(tab); - return false; - }); - emptyDashboard(); refresh_graphs(); diff --git a/src/sunstone/public/js/plugins/dashboard-users-tab.js b/src/sunstone/public/js/plugins/dashboard-users-tab.js index e929667e86..fe0bf48c30 100644 --- a/src/sunstone/public/js/plugins/dashboard-users-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-users-tab.js @@ -199,13 +199,6 @@ function refresh_graphs(){ } $(document).ready(function(){ - //Dashboard link listener - $("#dashboard_table h3 a",main_tabs_context).live("click", function (){ - var tab = $(this).attr('href'); - showTab(tab); - return false; - }); - emptyDashboard(); refresh_graphs(); diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js index b44b45ed76..df9659a96c 100644 --- a/src/sunstone/public/js/sunstone.js +++ b/src/sunstone/public/js/sunstone.js @@ -373,7 +373,7 @@ $(document).ready(function(){ }); //Start with the dashboard (supposing we have one). - showTab('#dashboard_tab'); + showTab('dashboard_tab'); }); @@ -465,7 +465,7 @@ function insertTab(tab_name){ $('div#'+tab_name,main_tabs_context).html(tab_info.content); - $('div#menu ul#navigation').append('
  • '+tab_info.title+'
  • '); + $('div#menu ul#navigation').append('
  • '+tab_info.title+'
  • '); if (parent){ //this is a subtab $('div#menu li#li_'+tab_name).hide();//hide by default From 7eec9e111139720c1dc2f862ca2c1fe1c2913e29 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 15 Mar 2012 00:20:52 +0100 Subject: [PATCH 178/217] Feature #1112: Fix ozones and SelfService UIs to work with Sunstone latest menus. Since sunstone menus were reworked, some CSS needed to be updated. layout.js file, which is particular to SelfService, was updated to work with latest version of sunstone too. --- src/cloud/occi/lib/ui/public/css/layout.css | 87 ++++++++++++++- src/cloud/occi/lib/ui/public/js/layout.js | 116 +++++++++++++++----- src/ozones/Server/public/css/layout.css | 73 +++++++++++- 3 files changed, 238 insertions(+), 38 deletions(-) diff --git a/src/cloud/occi/lib/ui/public/css/layout.css b/src/cloud/occi/lib/ui/public/css/layout.css index 5fcdfcb292..624e1e39a3 100644 --- a/src/cloud/occi/lib/ui/public/css/layout.css +++ b/src/cloud/occi/lib/ui/public/css/layout.css @@ -125,14 +125,44 @@ background-image: -moz-linear-gradient( padding: 0; } -#navigation li { +.navigation li.topTab { line-height: 2em; - text-align: right; - padding-right: 10px; + text-align: left; + padding-left: 15px; } -#navigation li a { +.navigation li.subTab { + line-height: 1.8em; + font-size: 12px; + text-align: left; + padding-left: 30px; +} + +.navigation li.subsubTab { + line-height: 1.7em; + font-size: 11px; + text-align: left; + padding-left: 40px; +} + +.navigation li.topTab span.plusIcon, +.navigation li.subTab span.plusIcon { + display : none; + float: right; + margin-right: 1em; +} + +.navigation li.topTab span.plusIcon { + margin-top: 5px; +} + +.navigation li.subTab span.plusIcon { + margin-top: 3px; +} + +#navigation li { color: #ffffff; + cursor: pointer; } #navigation li:hover, .navigation-active-li { @@ -163,10 +193,10 @@ background-image: -moz-linear-gradient( ); */ } -.navigation-active-li-a { +.navigation-active-li { font-weight: bold; } -#navigation li:hover a, .navigation-active-li-a { +#navigation li:hover { color: #ffffff !important; } @@ -181,3 +211,48 @@ background-image: -moz-linear-gradient( width: 100px; height: 22px; } + +/* top menu css */ +#menutop_container{ + margin:0px 171px; + color:#FFFFFF; + font-size:13px; + font-weight:bold; +} +#menutop_navbar{ + float:left; + height:25px; + font-size:13px; +} +#menutop_navbar ul{ + float:left; + height:25px; + color:#000000; + margin: 0 0; + padding-left: 1px; +} +#menutop_navbar ul{ + background-color: #353735; +} +#menutop_navbar ul li{ + float:left; + min-width:72px; + margin:0px 0 0 0; + height:22px; + display: inline; + text-align:center; + padding-left:5px; + padding-right: 5px; + padding-top: 4px; + padding-bottom: 4px; + border-left:1px solid white; + cursor:pointer; + color: white; +} + +#menutop_navbar ul li:hover { + background-color: #E69138; + +} + +/* end top menu css */ \ No newline at end of file diff --git a/src/cloud/occi/lib/ui/public/js/layout.js b/src/cloud/occi/lib/ui/public/js/layout.js index 7b315b443c..2fee0f93e9 100644 --- a/src/cloud/occi/lib/ui/public/js/layout.js +++ b/src/cloud/occi/lib/ui/public/js/layout.js @@ -14,16 +14,21 @@ /* limitations under the License. */ /* -------------------------------------------------------------------------- */ +//This file is mostly a copy of layout.js from Sunstone. +//Instead of opening a south panel, it opens an east panel. +//Apart from document.ready() modifications, the rest of different lines are +//makerd with MODIFIED + var activeTab; var outerLayout, innerLayout; function hideDialog(){ - innerLayout.close("east"); + innerLayout.close("east");//MODIFIED } function popDialog(content){ $("#dialog").html(content); - innerLayout.open("east"); + innerLayout.open("east");//MODIFIED } function popDialogLoading(){ @@ -31,45 +36,98 @@ function popDialogLoading(){ popDialog(loading); } -function showTab(tabname){ - activeTab = tabname; +function showTab(tabname,highlight_tab){ + //Since menu items no longer have an element + //we no longer expect #tab_id here, but simply tab_id + //So safety check - remove # from #tab_id if present to ensure compatibility + if (tabname.indexOf('#') == 0) + tabname = tabname.substring(1); + if (highlight_tab && highlight_tab.indexOf('#') == 0) + highlight_tab == highlight.substring(1); + + var activeTab = tabname; + + if (!highlight_tab) highlight_tab = activeTab; //clean selected menu $("#navigation li").removeClass("navigation-active-li"); - $("#navigation li a").removeClass("navigation-active-li-a"); + $("div#header ul#menutop_ul li").removeClass("navigation-active-li"); - //select menu - var li = $("#navigation li:has(a[href='"+activeTab+"'])") - var li_a = $("#navigation li a[href='"+activeTab+"']") + //select tab in left menu + var li = $("#navigation li#li_"+highlight_tab) li.addClass("navigation-active-li"); - li_a.addClass("navigation-active-li-a"); + + //select tab in top menu + var top_li = $("div#header ul#menutop_ul li#top_"+highlight_tab); + top_li.addClass("navigation-active-li"); + //show tab $(".tab").hide(); - $(activeTab).show(); - //~ if (activeTab == '#dashboard') { - //~ emptyDashboard(); - //~ preloadTables(); - //~ } - innerLayout.close("south"); -} + $('#'+activeTab).show(); +// innerLayout.close("south");//MODIFIED commented +}; + +function setupTabs(){ + + var topTabs = $(".outer-west ul li.topTab"); + var subTabs = $(".outer-west ul li.subTab"); + + subTabs.live("click",function(){ + //leave floor to topTab listener in case of tabs with both classes + if ($(this).hasClass('topTab')) return false; + + var tab = $(this).attr('id').substring(3); + showTab(tab); + return false; + }); + + topTabs.live("click",function(e){ + var tab = $(this).attr('id').substring(3); + //Subtabs have a class with the name of this tab + var subtabs = $('div#menu li.'+tab); + + //toggle subtabs only when clicking on the icon or when clicking on an + //already selected menu + if ($(e.target).is('span') || + $(this).hasClass("navigation-active-li")){ + //for each subtab, we hide the subsubtabs + subtabs.each(function(){ + //for each subtab, hide its subtabs + var subsubtabs = $(this).attr('id').substr(3); + //subsubtabs class + subsubtabs = $('div#menu li.'+subsubtabs); + subsubtabs.hide(); + }); + //hide subtabs and reset icon to + position, since all subsubtabs + //are hidden + subtabs.fadeToggle('fast'); + $('span',subtabs).removeClass('ui-icon-circle-minus'); + $('span',subtabs).addClass('ui-icon-circle-plus'); + //toggle icon on this tab + $('span',this).toggleClass('ui-icon-circle-plus ui-icon-circle-minus'); + }; + //if we are clicking on the icon only, do not show the tab + if ($(e.target).is('span')) return false; + + showTab(tab); + return false; + }); + +}; + +function setupTopMenu(){ + $('div#header ul#menutop_ul li').live('click',function(){ + var tab = "#" + $(this).attr('id').substring(4); + showTab(tab); + }); +}; $(document).ready(function () { $(".tab").hide(); - $(".outer-west ul li.subTab").live("click",function(){ - var tab = $('a',this).attr('href'); - showTab(tab); - return false; - }); - - $(".outer-west ul li.topTab").live("click",function(){ - var tab = $('a',this).attr('href'); - //toggle subtabs trick - $('li.'+tab.substr(1)).toggle(); - showTab(tab); - return false; - }); + setupTabs(); + //setupTopMenu(); outerLayout = $('body').layout({ applyDefaultStyles: false diff --git a/src/ozones/Server/public/css/layout.css b/src/ozones/Server/public/css/layout.css index 99812fc2b0..5a3762eb53 100644 --- a/src/ozones/Server/public/css/layout.css +++ b/src/ozones/Server/public/css/layout.css @@ -136,9 +136,31 @@ background-image: -moz-linear-gradient( padding-left: 30px; } +.navigation li.subsubTab { + line-height: 1.7em; + font-size: 11px; + text-align: left; + padding-left: 40px; +} -.navigation li a { +.navigation li.topTab span.plusIcon, +.navigation li.subTab span.plusIcon { + display : none; + float: right; + margin-right: 1em; +} + +.navigation li.topTab span.plusIcon { + margin-top: 5px; +} + +.navigation li.subTab span.plusIcon { + margin-top: 3px; +} + +.navigation li { color: #ffffff; + cursor: pointer; } .navigation li:hover, .navigation-active-li { @@ -169,9 +191,54 @@ background-image: -moz-linear-gradient( ); */ } -.navigation-active-li-a { +.navigation-active-li { font-weight: bold; } -.navigation li:hover a, .navigation-active-li-a { +.navigation li:hover { color: #ffffff !important; } + +/* top menu css */ +#menutop_container{ + margin:0px 171px; + color:#FFFFFF; + font-size:13px; + font-weight:bold; +} +#menutop_navbar{ + float:left; + height:25px; + font-size:13px; +} +#menutop_navbar ul{ + float:left; + height:25px; + color:#000000; + margin: 0 0; + padding-left: 1px; +} +#menutop_navbar ul{ + background-color: #353735; +} +#menutop_navbar ul li{ + float:left; + min-width:72px; + margin:0px 0 0 0; + height:22px; + display: inline; + text-align:center; + padding-left:5px; + padding-right: 5px; + padding-top: 4px; + padding-bottom: 4px; + border-left:1px solid white; + cursor:pointer; + color: white; +} + +#menutop_navbar ul li:hover { + background-color: #E69138; + +} + +/* end top menu css */ \ No newline at end of file From 0fbc43e0eac52c82aa181eeeb6a1addd0c8599e3 Mon Sep 17 00:00:00 2001 From: Tino Vazquez Date: Thu, 15 Mar 2012 12:30:12 +0100 Subject: [PATCH 179/217] Fix bad test expression in XEN shutdown script --- src/vmm_mad/remotes/xen/shutdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vmm_mad/remotes/xen/shutdown b/src/vmm_mad/remotes/xen/shutdown index b217235577..d7ed0a16c6 100755 --- a/src/vmm_mad/remotes/xen/shutdown +++ b/src/vmm_mad/remotes/xen/shutdown @@ -30,7 +30,7 @@ exec_and_log "$XM_SHUTDOWN $deploy_id" \ OUT=$(gdm) -while [ -n "$OUT" -a $(echo $OUT | awk '{print $5}') != "---s--" ]; do +while [ -n "$OUT" -a "$(echo $OUT | awk '{print $5}')" != "---s--" ]; do sleep 1 OUT=$(gdm) done From 6dc08dbfa6e86b10aea8e2a598bba4dda0d344d9 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Thu, 15 Mar 2012 15:13:29 +0100 Subject: [PATCH 180/217] Fix econe configuration file_path --- src/cloud/ec2/lib/econe-server.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cloud/ec2/lib/econe-server.rb b/src/cloud/ec2/lib/econe-server.rb index 0d20b59cc4..01c18da86c 100644 --- a/src/cloud/ec2/lib/econe-server.rb +++ b/src/cloud/ec2/lib/econe-server.rb @@ -33,9 +33,9 @@ end EC2_AUTH = VAR_LOCATION + "/.one/ec2_auth" EC2_LOG = LOG_LOCATION + "/econe-server.log" -CONFIGURATION_FILE = ETC_LOCATION + "/occi-server.conf" +CONFIGURATION_FILE = ETC_LOCATION + "/econe.conf" -TEMPLATE_LOCATION = ETC_LOCATION + "/occi_templates" +TEMPLATE_LOCATION = ETC_LOCATION + "/econe_templates" VIEWS_LOCATION = RUBY_LIB_LOCATION + "/cloud/econe/views" $: << RUBY_LIB_LOCATION From 2eec562361fa11b4a5e8802475be6ca09f2ac6a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 15 Mar 2012 17:19:27 +0100 Subject: [PATCH 181/217] Feature #1112: Fix bug in cluster requirements generation --- src/vm/VirtualMachine.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index f11f91ac70..87e6a19943 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -512,7 +512,7 @@ int VirtualMachine::automatic_requirements(string& error_str) ostringstream oss; string requirements; - string cluster_id; + string cluster_id = ""; string vatt_cluster_id; // Get cluster id from all DISK vector attributes @@ -532,7 +532,7 @@ int VirtualMachine::automatic_requirements(string& error_str) if ( !vatt_cluster_id.empty() ) { - if ( cluster_id != vatt_cluster_id ) + if ( !cluster_id.empty() && cluster_id != vatt_cluster_id ) { goto error; } @@ -559,7 +559,7 @@ int VirtualMachine::automatic_requirements(string& error_str) if ( !vatt_cluster_id.empty() ) { - if ( cluster_id != vatt_cluster_id ) + if ( !cluster_id.empty() && cluster_id != vatt_cluster_id ) { goto error; } From 2fe4daa875654f21f3be6a5f11100ca24c545cce Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 16 Mar 2012 05:23:51 +0100 Subject: [PATCH 182/217] feature #1112: VDCs are now defined by a set of Hosts, Datastores and Networks from a Cluster of a given Zone. Users are not granted to create new networks. Hosts does not need to be unique --- src/cloud/common/CloudServer.rb | 15 +- src/ozones/Client/bin/onevdc | 12 +- .../lib/cli/ozones_helper/vdc_helper.rb | 46 +++- src/ozones/Client/lib/zona.rb | 5 - src/ozones/Server/lib/OZones/VDC.rb | 213 +++++++++++------- src/ozones/Server/models/OzonesServer.rb | 70 +----- 6 files changed, 194 insertions(+), 167 deletions(-) diff --git a/src/cloud/common/CloudServer.rb b/src/cloud/common/CloudServer.rb index 9e3883ad1a..d092e5c4fc 100755 --- a/src/cloud/common/CloudServer.rb +++ b/src/cloud/common/CloudServer.rb @@ -37,7 +37,7 @@ class CloudServer ########################################################################## # Public attributes ########################################################################## - attr_reader :config, :logger + attr_reader :config # Initializes the Cloud server based on a config file # config_file:: _String_ for the server. MUST include the following @@ -47,9 +47,18 @@ class CloudServer # XMLRPC def initialize(config, logger=nil) # --- Load the Cloud Server configuration file --- - @config = config - @logger = logger + @config = config + @@logger = logger end + + def self.logger + return @@logger + end + + def logger + return @@logger + end + # # Prints the configuration of the server # diff --git a/src/ozones/Client/bin/onevdc b/src/ozones/Client/bin/onevdc index 1fb688a2b2..9820efff68 100755 --- a/src/ozones/Client/bin/onevdc +++ b/src/ozones/Client/bin/onevdc @@ -43,13 +43,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do ######################################################################## set :option, CommandParser::OPTIONS - FORCE={ - :name => "force", - :short => "-f", - :large => "--force", - :description => "Force the usage of Hosts in more than one VDC" - } - begin helper = VDCHelper.new "vdc" rescue Exception => e @@ -57,7 +50,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do exit -1 end - command :create, 'Create a new VDC', :file, :options=>[FORCE] do + command :create, 'Create a new VDC', :file do helper.create_resource(args[0], options) end @@ -74,8 +67,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do helper.delete_resource(args[0],options) end - command :addhost, 'Adds the set of hosts to the VDC', - :vdcid, :range, :options=>[FORCE] do + command :addhost, 'Adds the set of hosts to the VDC', :vdcid, :range do helper.addhost(args[0], args[1], options) end diff --git a/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb b/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb index cf0970e24c..44ae9e884f 100644 --- a/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb +++ b/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb @@ -17,7 +17,14 @@ require 'cli/ozones_helper' require 'cli/one_helper' +require 'zona' + class VDCHelper < OZonesHelper::OZHelper + NAME_REG = /[\w\d_-]+/ + VAR_REG = /\s*(#{NAME_REG})\s*=\s*/ + + SVAR_REG = /^#{VAR_REG}([^\[]+?)(#.*)?$/ + def initialize(kind, user=nil, pass=nil, endpoint_str=nil, timeout=nil, debug_flag=true) @vdc_str = kind @@ -25,13 +32,27 @@ class VDCHelper < OZonesHelper::OZHelper end def create_resource(template, options) - tmpl_str = File.read(template) + tmpl_str = File.read(template) + tmpl_hash = Hash.new - if options[:force] - tmpl_str << "FORCE=YES\n" + tmpl_str.scan(SVAR_REG) do | m | + key = m[0].strip.upcase + value = m[1].strip + + tmpl_hash[key] = value end - rc = @client.post_resource_str(@vdc_str, tmpl_str) + hosts = tmpl_hash.delete("HOSTS") + ds = tmpl_hash.delete("DATASTORES") + nets = tmpl_hash.delete("NETWORKS") + + tmpl_hash["RESOURCES"] = { "HOSTS" => eval("[#{hosts}]"), + "DATASTORES" => eval("[#{ds}]"), + "NETWORKS" => eval("[#{nets}]") } + + vdc = { "#{@vdc_str.upcase}" => tmpl_hash } + + rc = @client.post_resource(@vdc_str,Zona::OZonesJSON.to_json(vdc)) if Zona::is_error?(rc) [-1, rc.message] @@ -108,16 +129,19 @@ class VDCHelper < OZonesHelper::OZHelper def format_resource(vdc, options) str_h1="%-60s" - str="%-10s: %-20s" + str="%-12s: %-20s" CLIHelper.print_header(str_h1 % ["VDC #{vdc['name']} INFORMATION"]) - puts str % ["ID ", vdc[:ID].to_s] - puts str % ["NAME ", vdc[:NAME].to_s] - puts str % ["GROUP_ID ", vdc[:GROUP_ID].to_s] - puts str % ["ZONEID ", vdc[:ZONES_ID].to_s] - puts str % ["VDCADMIN ", vdc[:VDCADMINNAME].to_s] - puts str % ["HOST IDs ", vdc[:HOSTS].to_s] + puts str % ["ID ", vdc[:ID].to_s] + puts str % ["NAME ", vdc[:NAME].to_s] + puts str % ["ZONE_ID ", vdc[:ZONES_ID].to_s] + puts str % ["CLUSTER_ID ", vdc[:CLUSTER_ID].to_s] + puts str % ["GROUP_ID ", vdc[:GROUP_ID].to_s] + puts str % ["VDCADMIN ", vdc[:VDCADMINNAME].to_s] + puts str % ["HOSTS ", vdc[:RESOURCES][:HOSTS].to_s] + puts str % ["DATASTORES ", vdc[:RESOURCES][:DATASTORES].to_s] + puts str % ["NETWORKS ", vdc[:RESOURCES][:NETWORKS].to_s] puts return 0 diff --git a/src/ozones/Client/lib/zona.rb b/src/ozones/Client/lib/zona.rb index d22a8270c4..fcec4978f3 100644 --- a/src/ozones/Client/lib/zona.rb +++ b/src/ozones/Client/lib/zona.rb @@ -224,12 +224,8 @@ EOT return Client.parse_error(res, kind) end - - private - - # Starts an http connection and calls the block provided. SSL flag # is set if needed. def self.http_start(url, timeout, &block) @@ -296,7 +292,6 @@ EOT end - # Parses a OpenNebula template string and turns it into a JSON string # @param [String] kind element kind # @param [String] tmpl_str template diff --git a/src/ozones/Server/lib/OZones/VDC.rb b/src/ozones/Server/lib/OZones/VDC.rb index b3b89bb905..e090699497 100644 --- a/src/ozones/Server/lib/OZones/VDC.rb +++ b/src/ozones/Server/lib/OZones/VDC.rb @@ -14,49 +14,78 @@ # limitations under the License. # #--------------------------------------------------------------------------- # +require 'OzonesServer' + module OZones + # VDC class represents a virtual datacenter abstraction. It is defined by an + # ID, NAME, the GROUP backing the VDC, the admin credentials and the VDC + # resources. VDC resources are stored in JSON document in the DB and used as + # a hash in the VDC. class Vdc include DataMapper::Resource include OpenNebulaJSON::JSONUtils - extend OpenNebulaJSON::JSONUtils + extend OpenNebulaJSON::JSONUtils property :ID, Serial property :NAME, String, :required => true, :unique => true property :GROUP_ID, Integer property :VDCADMINNAME, String, :required => true property :VDCADMIN_ID, Integer - property :ACLS, Text - property :HOSTS, Text + property :CLUSTER_ID, Integer + property :RESOURCES, Text belongs_to :zones + def resources + rsrc_json = self.RESOURCES + + parser = JSON.parser.new(rsrc_json, {:symbolize_names => true}) + parser.parse + end + + def resources=(rsrc_hash) + self.RESOURCES = JSON.generate(rsrc_hash) + end + def self.to_hash zonePoolHash = Hash.new - zonePoolHash["VDC_POOL"] = Hash.new + + zonePoolHash["VDC_POOL"] = Hash.new zonePoolHash["VDC_POOL"]["VDC"] = Array.new unless self.all.empty? - self.all.each{|vdc| - # Hack! zones_ID does not respect the - # "all capital letters" policy + + self.all.each{ |vdc| + # Hack! zones_ID does not respect the "all capital letters" policy attrs = vdc.attributes.clone + attrs[:ZONES_ID] = vdc.attributes[:zones_ID] attrs.delete(:zones_ID) + rsrc_json = attrs.delete(:RESOURCES) + parser = JSON.parser.new(rsrc_json, {:symbolize_names=>true}) + attrs[:RESOURCES] = parser.parse + zonePoolHash["VDC_POOL"]["VDC"] << attrs } + return zonePoolHash end def to_hash vdc_attributes = Hash.new - # Hack! zones_ID does not respect the - # "all capital letters" policy + # Hack! zones_ID does not respect the "all capital letters" policy attrs = attributes.clone + attrs[:ZONES_ID] = attributes[:zones_ID] attrs.delete(:zones_ID) + rsrc_json = attrs.delete(:RESOURCES) + parser = JSON.parser.new(rsrc_json, {:symbolize_names=>true}) + attrs[:RESOURCES] = parser.parse + vdc_attributes["VDC"] = attrs + return vdc_attributes end end @@ -70,14 +99,17 @@ module OZones ####################################################################### # Constants ####################################################################### - VDC_ATTRS = [:VDCADMINNAME, :VDCADMINPASS, :NAME, :HOSTS] + VDC_ATTRS = [:VDCADMINNAME, + :VDCADMINPASS, + :NAME, + :CLUSTER_ID, + :RESOURCES] attr_reader :vdc attr_reader :zone #Creates an OpenNebula VDC, using its ID, vdcid and the associated zone def initialize(vdcid, zone = nil) - if vdcid != -1 @vdc = Vdc.get(vdcid) @@ -102,21 +134,29 @@ module OZones # ####################################################################### def create(vdc_data) - #Check and prepare VDC data + OzonesServer::logger.debug {"Creating new VDC #{vdc_data}"} + + #Check and prepare VDC data and preserve RESOURCES VDC_ATTRS.each { |param| if !vdc_data[param] return OZones::Error.new("Error: Couldn't create vdc." \ - "Mandatory attribute '#{param}' is missing.") + "Mandatory attribute '#{param}' is missing.") end } - #Create a vdc record + rsrc = vdc_data.delete(:RESOURCES) + vdcpass = vdc_data.delete(:VDCADMINPASS) + + #------------------------------------------------------------------- + # Create a vdc record + #------------------------------------------------------------------- @vdc = Vdc.new - vdcpass = vdc_data.delete(:VDCADMINPASS) @vdc.attributes = vdc_data + #------------------------------------------------------------------- # Create a group in the zone with the VDC name + #------------------------------------------------------------------- group = OpenNebula::Group.new(OpenNebula::Group.build_xml, @client) rc = group.allocate(@vdc.NAME) @@ -124,7 +164,11 @@ module OZones @vdc.GROUP_ID = group.id + OzonesServer::logger.debug {"Group #{group.id} created"} + + #------------------------------------------------------------------- # Create the VDC admin user in the Zone + #------------------------------------------------------------------- user = OpenNebula::User.new(OpenNebula::User.build_xml, @client) rc = user.allocate(@vdc.VDCADMINNAME, vdcpass) @@ -132,31 +176,44 @@ module OZones @vdc.VDCADMIN_ID = user.id + OzonesServer::logger.debug {"VDC admin user #{user.id} created"} + + #------------------------------------------------------------------- # Change primary group of the admin user to the VDC group + #------------------------------------------------------------------- rc = user.chgrp(group.id) return rollback(group, user, nil, rc) if OpenNebula.is_error?(rc) + #------------------------------------------------------------------- # Add ACLs - aclp = OpenNebula::AclPool.new(@client) - rules = get_acls + #------------------------------------------------------------------- + rules = get_acls(rsrc) - rc, acls_str = create_acls(rules) - return rollback(group, user,acls_str,rc) if OpenNebula.is_error?(rc) + OzonesServer::logger.debug {"Creating ACLs #{rules}..."} - @vdc.ACLS = acls_str + rc, acl_ids = create_acls(rules) + return rollback(group, user, acl_ids,rc) if OpenNebula.is_error?(rc) + + OzonesServer::logger.debug {"ACLs #{acl_ids} created"} + + rsrc[:ACLS] = acl_ids + @vdc.resources = rsrc return true end def destroy + #------------------------------------------------------------------- # Delete the resources from the VDC + #------------------------------------------------------------------- delete_images delete_templates delete_vms - delete_vns delete_acls - # Delete users from a group + #------------------------------------------------------------------- + # Delete users from a group and the group + #------------------------------------------------------------------- up = OpenNebula::UserPool.new(@client) up.info @@ -166,7 +223,6 @@ module OZones end } - # Delete the group OpenNebula::Group.new_with_id(@vdc.GROUP_ID, @client).delete return @vdc.destroy @@ -180,33 +236,37 @@ module OZones OpenNebula::Group.new_with_id(@vdc.GROUP_ID, @client).delete end - def update(host_list) + def update(rsrc_hash) + # ------------------------------------------------------------------ # Delete existing host ACLs - delete_host_acls + # ------------------------------------------------------------------ + delete_resource_acls - if @vdc.ACLS =~ /((\d+,){#{HOST_ACL_FIRST_ID}}).*/ - newacls = $1.chop - else - newacls = @vdc.ACLS.clone - end + acls = @vcd.resources[:ACLS] + acls.slice!(RESOURCE_ACL_FIRST_ID..-1) + + # ------------------------------------------------------------------ # Create new ACLs. TODO Rollback ACL creation - if !host_list.empty? - host_acls = get_host_acls(host_list) - rc, acls_str = create_acls(host_acls) + # ------------------------------------------------------------------ + if !rsrc_hash.nil? + rsrc_acls = get_resource_acls(rsrc_hash) + rc, acls_ids = create_acls(rsrc_acls) return rc if OpenNebula.is_error?(rc) - #Create the new acl string. - newacls << "," << acls_str + acls << acls_id + end + rsrc_hash[:ACLS] = acls + # ------------------------------------------------------------------ #Update the VDC Record + # ------------------------------------------------------------------ begin @vdc.raise_on_save_failure = true - @vdc.HOSTS = host_list - @vdc.ACLS = newacls + @vdc.resources = rsrc_hash @vdc.save rescue => e @@ -220,63 +280,67 @@ module OZones ####################################################################### # Functions to generate ACL Strings ####################################################################### - # The ID of the first host ACL - HOST_ACL_FIRST_ID = 3 + # The ID of the first resource ACL + RESOURCE_ACL_FIRST_ID = 3 # This method returns an Array of ACL strings to create them # in the target zone - def get_acls + def get_acls(rsrc_hash) rule_str = Array.new # Grant permissions to the group - rule_str << "@#{@vdc.GROUP_ID} VM+NET+IMAGE+TEMPLATE/* CREATE" + rule_str << "@#{@vdc.GROUP_ID} VM+IMAGE+TEMPLATE/* CREATE" # Grant permissions to the vdc admin rule_str << "##{@vdc.VDCADMIN_ID} USER/* CREATE" rule_str << "##{@vdc.VDCADMIN_ID} USER/@#{@vdc.GROUP_ID} " \ "USE+MANAGE+ADMIN" - ############################################################### - #When more rules are added the class constant HOST_ACL_FIRST_ID + #################################################################### + #When more rules are added the class constant RESOURCE_ACL_FIRST_ID #must be modified - ############################################################### + #################################################################### - rule_str.concat(get_host_acls) + rule_str.concat(get_resource_acls(rsrc_hash)) end - def get_host_acls(host_list = nil) - rule_str = Array.new - - if host_list == nil - host_list = @vdc.HOSTS - end + def get_resource_acls(rsrc_hash) + rule_str = Array.new # Grant permissions to use the vdc hosts - host_list.split(',').each{|hostid| + rsrc_hash[:HOSTS].each{ |hostid| rule_str << "@#{@vdc.GROUP_ID} HOST/##{hostid} MANAGE" } + # Grant permissions to use the vdc datastores + rsrc_hash[:DATASTORES].each{ |dsid| + rule_str << "@#{@vdc.GROUP_ID} DATASTORE/##{dsid} USE" + } + + # Grant permissions to use the vdc networks + rsrc_hash[:NETWORKS].each{ |netid| + rule_str << "@#{@vdc.GROUP_ID} NET/##{netid} USE" + } + return rule_str end ####################################################################### # Functions to delete resources associated to the VDC ####################################################################### - # Deletes ACLs for the hosts - def delete_host_acls - host_acls = @vdc.ACLS.split(',')[HOST_ACL_FIRST_ID..-1] - - if host_acls - host_acls.each{|acl| - OpenNebula::Acl.new_with_id(acl.to_i, @client).delete - } - end + # Deletes ACLs for the resources + def delete_resource_acls + delete_acls(RESOURCE_ACL_FIRST_ID) end # Delete ACLs - def delete_acls - @vdc.ACLS.split(",").each{|acl| - OpenNebula::Acl.new_with_id(acl.to_i, @client).delete + def delete_acls(first_id = 0) + rsrc = @vdc.resources + + return if rsrc[:ACLS].nil? + + rsrc[:ACLS][first_id..-1].each { |acl_id| + OpenNebula::Acl.new_with_id(acl_id, @client).delete } end @@ -310,16 +374,6 @@ module OZones } end - # Deletes VNs - def delete_vns - vnp = OpenNebula::VirtualNetworkPool.new(@client) - vnp.info - - vnp.each{|vn| - vnp.delete if vn['GID'].to_i == @vdc.GROUP_ID - } - end - ####################################################################### # Misc helper functions for the class ####################################################################### @@ -330,9 +384,8 @@ module OZones user.delete if user if acls - acls.chop - acls.split(",").each{|acl| - OpenNebula::Acl.new_with_id(acl.to_i, @client).delete + acls.each{|acl_id| + OpenNebula::Acl.new_with_id(acl_id, @client).delete } end @@ -342,7 +395,7 @@ module OZones # Creates an acl array of acl strings. Returns true or error and # a comma-separated list with the new acl ids def create_acls(acls) - acls_str = "" + acls_ids = Array.new rc = true acls.each{|rule| @@ -351,10 +404,10 @@ module OZones break if OpenNebula.is_error?(rc) - acls_str << acl.id.to_s << "," + acls_ids << acl.id } - return rc, acls_str.chop + return rc, acls_ids end end end diff --git a/src/ozones/Server/models/OzonesServer.rb b/src/ozones/Server/models/OzonesServer.rb index 4b7a952af5..903a3bff4d 100644 --- a/src/ozones/Server/models/OzonesServer.rb +++ b/src/ozones/Server/models/OzonesServer.rb @@ -15,10 +15,8 @@ #--------------------------------------------------------------------------- # require 'CloudServer' - require 'JSONUtils' - class OzonesServer < CloudServer include OpenNebulaJSON::JSONUtils @@ -93,27 +91,17 @@ class OzonesServer < CloudServer end #Get the Zone that will host the VDC. And check resouces - zoneid = vdc_data.delete(:ZONEID) - force = vdc_data.delete(:FORCE) + zoneid = vdc_data.delete(:ZONE_ID) if !zoneid - return [400, - OZones::Error.new("Error: Couldn't create vdc. " \ - "Mandatory attribute zoneid missing.").to_json] + return [400, OZones::Error.new("Error: Couldn't create vdc. " \ + "Mandatory attribute zoneid missing.").to_json] end zone = OZones::Zones.get(zoneid) if !zone return [404, OZones::Error.new("Error: Couldn't create vdc. " \ - "Zone #{zoneid} not found.").to_json] - end - - if (!force or force.upcase!="YES") and - !host_uniqueness?(zone, vdc_data[:HOSTS]) - - return [403, - OZones::Error.new("Error: Couldn't create vdc. " \ - "Hosts are not unique, use force to override").to_json] + "Zone #{zoneid} not found.").to_json] end # Create de VDC @@ -132,11 +120,11 @@ class OzonesServer < CloudServer begin zone.save rescue => e - vdc.clean_bootstrap + #vdc.clean_bootstrap + logger.error {"create_vdc: #{e.resource.errors.inspect}"} - return [400, - OZones::Error.new("Error: Couldn't create " \ - "vdc. Zone could not be saved: #{e.message}").to_json] + return [400, OZones::Error.new("Error: Couldn't create " \ + "vdc. Zone could not be saved: #{e.message}").to_json] end pr.update # Rewrite proxy conf file @@ -174,13 +162,12 @@ class OzonesServer < CloudServer "Reason: #{data.message}.").to_json] end - hosts = vdc_data.delete(:HOSTS) - force = vdc_data.delete(:FORCE) + rsrc = vdc_data.delete(:RESOURCES) # Check parameters - if !hosts + if !rsrc return [400, OZones::Error.new("Error: Couldn't update vdc. " \ - "Missing HOSTS.").to_json] + "Missing RESOURCES.").to_json] end # Check if the referenced Vdc exists @@ -191,15 +178,7 @@ class OzonesServer < CloudServer "#{e.message}").to_json] end - if (!force or force.upcase != "YES") and - !host_uniqueness?(vdc.zone, hosts, vdc_id.to_i) - - return [403, - OZones::Error.new("Error: Couldn't update vdc. " \ - "Hosts are not unique, use force to override").to_json] - end - - rc = vdc.update(hosts) + rc = vdc.update(rsrc) if !OpenNebula.is_error?(rc) return [200, rc] @@ -249,29 +228,4 @@ class OzonesServer < CloudServer return [200, OZones.str_to_json("Zone #{id} successfully deleted")] end end - - ############################################################################ - # Misc Helper Functions - ############################################################################ - private - - # Check if hosts are already include in any Vdc of the zone - def host_uniqueness?(zone, host_list, vdc_id = -1) - return true if host_list.empty? - - all_hosts = "" - zone.vdcs.all.each{|vdc| - if vdc.HOSTS != nil and !vdc.HOSTS.empty? and vdc.id != vdc_id - all_hosts << ',' << vdc.HOSTS - end - } - - all_hosts = all_hosts.split(',') - - host_list.split(",").each{|host| - return false if all_hosts.include?(host) - } - - return true - end end From 2b787588926327ed58639df9c8f7cb96e4dc55ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 16 Mar 2012 15:56:56 +0100 Subject: [PATCH 183/217] Bug #1170: Log RM error with the right image source --- src/image/ImageManagerDriver.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/image/ImageManagerDriver.cc b/src/image/ImageManagerDriver.cc index c49eba0503..43eae93c5a 100644 --- a/src/image/ImageManagerDriver.cc +++ b/src/image/ImageManagerDriver.cc @@ -292,11 +292,11 @@ error_mkfs: goto error_common; error_rm: - image->unlock(); - os.str(""); - os << "Error removing image from repository. Remove file " << source - << " to completely delete image."; + os << "Error removing image from repository. Remove file " << image->get_source() + << " to completely delete image."; + + image->unlock(); getline(is,info); From 25460dd9957069b67dff21b250643e6ea769c622 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 16 Mar 2012 17:22:29 +0100 Subject: [PATCH 184/217] feature #1112: Fix issues in VDC. Restores unique functionality. CloudServer has a static/class logger --- src/cli/one_helper/oneimage_helper.rb | 5 ++ src/cloud/common/CloudServer.rb | 16 +++- src/ozones/Client/bin/onevdc | 9 ++- .../lib/cli/ozones_helper/vdc_helper.rb | 3 + src/ozones/Client/lib/zona.rb | 30 ++++---- src/ozones/Server/models/OzonesServer.rb | 73 ++++++++++++++++--- 6 files changed, 105 insertions(+), 31 deletions(-) diff --git a/src/cli/one_helper/oneimage_helper.rb b/src/cli/one_helper/oneimage_helper.rb index b02ea356d9..e73866f1a3 100644 --- a/src/cli/one_helper/oneimage_helper.rb +++ b/src/cli/one_helper/oneimage_helper.rb @@ -67,6 +67,11 @@ class OneImageHelper < OpenNebulaHelper::OneHelper OneImageHelper.type_to_str(d["TYPE"]) end + column :REGTIME, "Registration time of the Image", + :size=>20 do |d| + OpenNebulaHelper.time_to_str(d["REGTIME"]) + end + column :PERSISTENT, "Whether the Image is persistent or not", :size=>3 do |d| OpenNebulaHelper.boolean_to_str(d["PERSISTENT"]) diff --git a/src/cloud/common/CloudServer.rb b/src/cloud/common/CloudServer.rb index d092e5c4fc..904e072ec0 100755 --- a/src/cloud/common/CloudServer.rb +++ b/src/cloud/common/CloudServer.rb @@ -110,15 +110,27 @@ module CloudLogger DATE_FORMAT = "%a %b %d %H:%M:%S %Y" # Patch logger class to be compatible with Rack::CommonLogger - class ::Logger + class CloudLogger < Logger + + def initialize(path) + super(path) + end + def write(msg) info msg.chop end + + def add(severity, message = nil, progname = nil, &block) + rc = super(severity, message, progname, &block) + @logdev.dev.flush + + rc + end end def enable_logging(path=nil, debug_level=3) path ||= $stdout - logger = ::Logger.new(path) + logger = CloudLogger.new(path) logger.level = DEBUG_LEVEL[debug_level] logger.formatter = proc do |severity, datetime, progname, msg| MSG_FORMAT % [ diff --git a/src/ozones/Client/bin/onevdc b/src/ozones/Client/bin/onevdc index 9820efff68..f6ff4ced27 100755 --- a/src/ozones/Client/bin/onevdc +++ b/src/ozones/Client/bin/onevdc @@ -43,6 +43,13 @@ cmd=CommandParser::CmdParser.new(ARGV) do ######################################################################## set :option, CommandParser::OPTIONS + FORCE={ + :name => "force", + :short => "-f", + :large => "--force", + :description => "Force the usage of Hosts in more than one VDC" + } + begin helper = VDCHelper.new "vdc" rescue Exception => e @@ -50,7 +57,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do exit -1 end - command :create, 'Create a new VDC', :file do + command :create, 'Create a new VDC', :file, :options=>[FORCE] do helper.create_resource(args[0], options) end diff --git a/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb b/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb index 44ae9e884f..8831ac7def 100644 --- a/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb +++ b/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb @@ -49,6 +49,9 @@ class VDCHelper < OZonesHelper::OZHelper tmpl_hash["RESOURCES"] = { "HOSTS" => eval("[#{hosts}]"), "DATASTORES" => eval("[#{ds}]"), "NETWORKS" => eval("[#{nets}]") } + if options[:force] + tmpl_hash["FORCE"] = "YES" + end vdc = { "#{@vdc_str.upcase}" => tmpl_hash } diff --git a/src/ozones/Client/lib/zona.rb b/src/ozones/Client/lib/zona.rb index fcec4978f3..e479e67d2d 100644 --- a/src/ozones/Client/lib/zona.rb +++ b/src/ozones/Client/lib/zona.rb @@ -270,26 +270,22 @@ EOT def self.parse_error(value, kind) if Zona.is_error?(value) return value - else - if Zona.is_http_error?(value) - str = "Operating with #{kind} failed with HTTP error" - str += " code: #{value.code}\n" - if value.body - # Try to extract error message - begin - str << "Body: " << - OZonesJSON.parse_json(value.body, - "error")["message"] - rescue - str.gsub!("\nBody:","") - end - end - return Error.new(str) - end end + + if Zona.is_http_error?(value) + str = "Operating with #{kind} failed with HTTP error" + str += " code: #{value.code}\n" + + if value.body + ehash = OZonesJSON.parse_json(value.body,"error") + str << ehash[:message] if !ehash.nil? + end + + return Error.new(str) + end + value # If it is not an error, return it as-is end - end # Parses a OpenNebula template string and turns it into a JSON string diff --git a/src/ozones/Server/models/OzonesServer.rb b/src/ozones/Server/models/OzonesServer.rb index 903a3bff4d..01e68d09bb 100644 --- a/src/ozones/Server/models/OzonesServer.rb +++ b/src/ozones/Server/models/OzonesServer.rb @@ -90,8 +90,11 @@ class OzonesServer < CloudServer "Reason: #{data.message}.").to_json] end + #----------------------------------------------------------------------- #Get the Zone that will host the VDC. And check resouces + #----------------------------------------------------------------------- zoneid = vdc_data.delete(:ZONE_ID) + force = vdc_data.delete(:FORCE) if !zoneid return [400, OZones::Error.new("Error: Couldn't create vdc. " \ @@ -104,7 +107,14 @@ class OzonesServer < CloudServer "Zone #{zoneid} not found.").to_json] end + if (!force or force.upcase != "YES") and !host_unique?(zone, vdc_data) + return [403, OZones::Error.new("Error: Couldn't create vdc. " \ + "Hosts are not unique, use force to override").to_json] + end + + #----------------------------------------------------------------------- # Create de VDC + #----------------------------------------------------------------------- vdc = OZones::OpenNebulaVdc.new(-1,zone) rc = vdc.create(vdc_data) @@ -113,7 +123,9 @@ class OzonesServer < CloudServer "Reason: #{rc.message}").to_json] end + #----------------------------------------------------------------------- #Update the zone and save the vdc + #----------------------------------------------------------------------- zone.raise_on_save_failure = true zone.vdcs << vdc.vdc @@ -160,17 +172,16 @@ class OzonesServer < CloudServer if OpenNebula.is_error?(vdc_data) return [400, OZones::Error.new("Error: Couldn't update vdc. " \ "Reason: #{data.message}.").to_json] - end - - rsrc = vdc_data.delete(:RESOURCES) - - # Check parameters - if !rsrc + end + + #----------------------------------------------------------------------- + # Check parameters & VDC + #----------------------------------------------------------------------- + if !vdc_data[:RESOURCES] return [400, OZones::Error.new("Error: Couldn't update vdc. " \ "Missing RESOURCES.").to_json] end - # Check if the referenced Vdc exists begin vdc = OZones::OpenNebulaVdc.new(vdc_id) rescue => e @@ -178,7 +189,17 @@ class OzonesServer < CloudServer "#{e.message}").to_json] end - rc = vdc.update(rsrc) + vdc_data[:CLUSTER_ID] = vdc.CLUSTER_ID + vdc_data[:ID] = vdc.ID + + force = vdc_data.delete(:FORCE) + + if (!force or force.upcase!="YES") and !host_unique?(vdc.zone, vdc_data) + return [403, OZones::Error.new("Error: Couldn't update vdc. " \ + "Hosts are not unique, use force to override").to_json] + end + + rc = vdc.update(vdc_data[:RESOURCES]) if !OpenNebula.is_error?(rc) return [200, rc] @@ -215,9 +236,8 @@ class OzonesServer < CloudServer if zone rc = zone.destroy else - return [404, - OZones::Error.new("Error: Cannot delete " \ - "zone. Reason: zone #{id} not found").to_json] + return [404, OZones::Error.new("Error: Cannot delete " \ + "zone. Reason: zone #{id} not found").to_json] end if !rc @@ -228,4 +248,35 @@ class OzonesServer < CloudServer return [200, OZones.str_to_json("Zone #{id} successfully deleted")] end end + + ############################################################################ + # Misc Helper Functions + ############################################################################ + private + + # Check if hosts are already include in any Vdc of the zone + def host_unique?(zone, vdc_data) + + hosts = vdc_data[:RESOURCES][:HOSTS] + c_id = vdc_data[:CLUSTER_ID] + + return true if hosts.empty? + + all_hosts = Array.new + + zone.vdcs.all(:CLUSTER_ID =>c_id).each{ |vdc| + + rsrc = vdc.resources + + if !rsrc[:HOSTS].empty? and vdc.ID != vdc_data[:ID] + all_hosts.concat(rsrc[:HOSTS]) + end + } + + hosts.each{|hid| + return false if all_hosts.include?(hid) + } + + return true + end end From a1af3ec1656b4ca353c6aa787b40e12fb7df1060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 16 Mar 2012 17:30:43 +0100 Subject: [PATCH 185/217] Feature #1112: Set group_u to 1 for new DS. DS 'default' other_u is also set to 1 --- src/acl/AclManager.cc | 10 ---------- src/datastore/Datastore.cc | 2 ++ src/datastore/DatastorePool.cc | 13 +++++++++++++ src/onedb/3.3.0_to_3.3.80.rb | 8 ++++---- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/acl/AclManager.cc b/src/acl/AclManager.cc index 0fe8664fcd..8ffd997c8e 100644 --- a/src/acl/AclManager.cc +++ b/src/acl/AclManager.cc @@ -87,16 +87,6 @@ AclManager::AclManager(SqlDB * _db) : db(_db), lastOID(-1) PoolObjectSQL::HOST, AuthRequest::MANAGE, error_str); - - // Users in USERS can use the default DATASTORE - // @1 DATASTORE/#1 USE - add_rule(AclRule::GROUP_ID | - 1, - AclRule::INDIVIDUAL_ID | - 1 | // TODO: use DatastorePool::DEFAULT_DS_ID - PoolObjectSQL::DATASTORE, - AuthRequest::USE, - error_str); } } diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index f5fbb57dd8..ea7b1d50e8 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -49,6 +49,8 @@ Datastore::Datastore( tm_mad(""), base_path("") { + group_u = 1; + if (ds_template != 0) { obj_template = ds_template; diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index 1557659a39..f98396ca38 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -44,6 +44,7 @@ DatastorePool::DatastorePool(SqlDB * db): if (get_lastOID() == -1) //lastOID is set in PoolSQL::init_cb { DatastoreTemplate * ds_tmpl; + Datastore * ds; int rc; @@ -110,6 +111,18 @@ DatastorePool::DatastorePool(SqlDB * db): goto error_bootstrap; } + ds = get(rc, true); + + ds->set_permissions( + -1,-1,-1, + -1,-1,-1, + 1,-1,-1, + error_str); + + update(ds); + + ds->unlock(); + // User created datastores will start from ID 100 set_update_lastOID(99); } diff --git a/src/onedb/3.3.0_to_3.3.80.rb b/src/onedb/3.3.0_to_3.3.80.rb index 3dff69249c..da472d349f 100644 --- a/src/onedb/3.3.0_to_3.3.80.rb +++ b/src/onedb/3.3.0_to_3.3.80.rb @@ -115,7 +115,7 @@ module Migrator " 1" << " 1" << " 0" << - " 0" << + " 1" << " 0" << " 0" << " 0" << @@ -141,7 +141,7 @@ module Migrator :uid => 0, :gid => 0, :owner_u => 1, - :group_u => 0, + :group_u => 1, :other_u => 0) # Last oid for cluster_pool and datastore_pool @@ -272,7 +272,7 @@ module Migrator " 1" << " 1" << " 0" << - " 0" << + " 1" << " 0" << " 0" << " 0" << @@ -298,7 +298,7 @@ module Migrator :uid => 0, :gid => 0, :owner_u => 1, - :group_u => 0, + :group_u => 1, :other_u => 0) return true From 226844a99667850865e8744518202aa31e4744e0 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Fri, 16 Mar 2012 17:52:12 +0100 Subject: [PATCH 186/217] feature #1112: Add cluster and datastore support to OCCI --- src/cloud/occi/etc/occi-server.conf | 3 +++ src/cloud/occi/lib/OCCIServer.rb | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cloud/occi/etc/occi-server.conf b/src/cloud/occi/etc/occi-server.conf index 5ab9849e09..971326cd20 100644 --- a/src/cloud/occi/etc/occi-server.conf +++ b/src/cloud/occi/etc/occi-server.conf @@ -37,6 +37,9 @@ # 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG :debug_level: 3 +:cluster_id: +:datastore_id: + # VM types allowed and its template file (inside templates directory) :instance_types: :small: diff --git a/src/cloud/occi/lib/OCCIServer.rb b/src/cloud/occi/lib/OCCIServer.rb index a3102da56c..ee3fc5d406 100755 --- a/src/cloud/occi/lib/OCCIServer.rb +++ b/src/cloud/occi/lib/OCCIServer.rb @@ -342,7 +342,7 @@ class OCCIServer < CloudServer template = network.to_one_template return template, 500 if OpenNebula.is_error?(template) - rc = network.allocate(template) + rc = network.allocate(template, @config[:cluster_id]||ClusterPool::NONE_CLUSTER_ID) if OpenNebula.is_error?(rc) return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end @@ -446,7 +446,7 @@ class OCCIServer < CloudServer template = image.to_one_template return template, 500 if OpenNebula.is_error?(template) - rc = image.allocate(template) + rc = image.allocate(template, @config[:datastore_id]||1t) if OpenNebula.is_error?(rc) return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end From 187265f8283cb0dd3416c3d6bc46f09f5e7b9586 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Fri, 16 Mar 2012 17:53:46 +0100 Subject: [PATCH 187/217] feature #1112: Add cluster and datastore support to econe --- src/cloud/ec2/etc/econe.conf | 3 +++ src/cloud/ec2/lib/EC2QueryServer.rb | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cloud/ec2/etc/econe.conf b/src/cloud/ec2/etc/econe.conf index f9ba61e670..02e352aa1b 100644 --- a/src/cloud/ec2/etc/econe.conf +++ b/src/cloud/ec2/etc/econe.conf @@ -37,6 +37,9 @@ # 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG :debug_level: 3 +:cluster_id: +:datastore_id: + # VM types allowed and its template file (inside templates directory) :instance_types: :m1.small: diff --git a/src/cloud/ec2/lib/EC2QueryServer.rb b/src/cloud/ec2/lib/EC2QueryServer.rb index 66c14ad2a0..9b02650a9c 100644 --- a/src/cloud/ec2/lib/EC2QueryServer.rb +++ b/src/cloud/ec2/lib/EC2QueryServer.rb @@ -79,7 +79,7 @@ class EC2QueryServer < CloudServer return OpenNebula::Error.new('Unsupported'), 400 end - rc = image.allocate(template) + rc = image.allocate(template, @config[:datastore_id]||1) if OpenNebula.is_error?(rc) return OpenNebula::Error.new('Unsupported'), 400 end From 761e3d5973907c2ac15a409f4c21aa86e64396b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 16 Mar 2012 18:19:00 +0100 Subject: [PATCH 188/217] Feature #1112: Cluster -1 elements now have empty Cluster name element. The CLI shows '-' for these resources --- src/cli/one_helper.rb | 12 ++++++++++++ src/cli/one_helper/onedatastore_helper.rb | 9 ++------- src/cli/one_helper/onehost_helper.rb | 8 ++------ src/cli/one_helper/onevnet_helper.rb | 8 ++------ src/cluster/ClusterPool.cc | 2 +- src/onedb/3.3.0_to_3.3.80.rb | 8 ++++---- 6 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/cli/one_helper.rb b/src/cli/one_helper.rb index 16f08400f3..50cc513fc1 100644 --- a/src/cli/one_helper.rb +++ b/src/cli/one_helper.rb @@ -399,6 +399,18 @@ EOT end end + # If the cluster name is empty, returns a '-' char. + # + # @param str [String || Hash] Cluster name, or empty Hash (when ) + # @return [String] the same Cluster name, or '-' if it is empty + def OpenNebulaHelper.cluster_str(str) + if str != nil && !str.empty? + str + else + "-" + end + end + def OpenNebulaHelper.update_template(id, resource) require 'tempfile' diff --git a/src/cli/one_helper/onedatastore_helper.rb b/src/cli/one_helper/onedatastore_helper.rb index b94ad60a3f..5e4c4eecfb 100644 --- a/src/cli/one_helper/onedatastore_helper.rb +++ b/src/cli/one_helper/onedatastore_helper.rb @@ -57,11 +57,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper end column :CLUSTER, "Name of the Cluster", :left, :size=>8 do |d| - if d["CLUSTER"] == "none" - "-" - else - d["CLUSTER"] - end + OpenNebulaHelper.cluster_str(d["CLUSTER"]) end column :IMAGES, "Number of Images", :left, :size=>6 do |d| @@ -111,8 +107,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper puts str % ["NAME", datastore.name] puts str % ["USER", datastore['UNAME']] puts str % ["GROUP", datastore['GNAME']] - puts str % ["CLUSTER", datastore['CLUSTER']] - puts str % ["CLUSTER_ID", datastore['CLUSTER_ID']] + puts str % ["CLUSTER", OpenNebulaHelper.cluster_str(datastore['CLUSTER'])] puts str % ["DS_MAD", datastore['DS_MAD']] puts str % ["TM_MAD", datastore['TM_MAD']] diff --git a/src/cli/one_helper/onehost_helper.rb b/src/cli/one_helper/onehost_helper.rb index 63434231ba..1abdb32b4f 100644 --- a/src/cli/one_helper/onehost_helper.rb +++ b/src/cli/one_helper/onehost_helper.rb @@ -44,11 +44,7 @@ class OneHostHelper < OpenNebulaHelper::OneHelper end column :CLUSTER, "Name of the Cluster", :left, :size=>8 do |d| - if d["CLUSTER"] == "none" - "-" - else - d["CLUSTER"] - end + OpenNebulaHelper.cluster_str(d["CLUSTER"]) end column :RVM, "Number of Virtual Machines running", :size=>6 do |d| @@ -126,7 +122,7 @@ class OneHostHelper < OpenNebulaHelper::OneHelper puts str % ["ID", host.id.to_s] puts str % ["NAME", host.name] - puts str % ["CLUSTER", host['CLUSTER']] + puts str % ["CLUSTER", OpenNebulaHelper.cluster_str(host['CLUSTER'])] puts str % ["STATE", host.state_str] puts str % ["IM_MAD", host['IM_MAD']] puts str % ["VM_MAD", host['VM_MAD']] diff --git a/src/cli/one_helper/onevnet_helper.rb b/src/cli/one_helper/onevnet_helper.rb index 8281f51eff..39907836b1 100644 --- a/src/cli/one_helper/onevnet_helper.rb +++ b/src/cli/one_helper/onevnet_helper.rb @@ -55,11 +55,7 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper end column :CLUSTER, "Name of the Cluster", :left, :size=>8 do |d| - if d["CLUSTER"] == "none" - "-" - else - d["CLUSTER"] - end + OpenNebulaHelper.cluster_str(d["CLUSTER"]) end column :TYPE, "Type of Virtual Network", :size=>6 do |d| @@ -111,7 +107,7 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper puts str % ["NAME", vn['NAME']] puts str % ["USER", vn['UNAME']] puts str % ["GROUP", vn['GNAME']] - puts str % ["CLUSTER", vn['CLUSTER']] + puts str % ["CLUSTER", OpenNebulaHelper.cluster_str(vn['CLUSTER'])] puts str % ["TYPE", vn.type_str] puts str % ["BRIDGE", vn["BRIDGE"]] puts str % ["VLAN", OpenNebulaHelper.boolean_to_str(vn['VLAN'])] diff --git a/src/cluster/ClusterPool.cc b/src/cluster/ClusterPool.cc index c96d660ca1..32d549b1dc 100644 --- a/src/cluster/ClusterPool.cc +++ b/src/cluster/ClusterPool.cc @@ -26,7 +26,7 @@ /* Regular ones start from ID 100 */ /* -------------------------------------------------------------------------- */ -const string ClusterPool::NONE_CLUSTER_NAME = "none"; +const string ClusterPool::NONE_CLUSTER_NAME = ""; const int ClusterPool::NONE_CLUSTER_ID = -1; /* -------------------------------------------------------------------------- */ diff --git a/src/onedb/3.3.0_to_3.3.80.rb b/src/onedb/3.3.0_to_3.3.80.rb index da472d349f..3fd8ee4631 100644 --- a/src/onedb/3.3.0_to_3.3.80.rb +++ b/src/onedb/3.3.0_to_3.3.80.rb @@ -126,7 +126,7 @@ module Migrator " shared" << " #{var_location}/datastores/0" << " -1" << - " none" << + " " << " " << "