diff --git a/SConstruct b/SConstruct index f4cce1fba9..d27c7599e5 100644 --- a/SConstruct +++ b/SConstruct @@ -52,6 +52,7 @@ main_env.Append(LIBPATH=[ cwd+'/src/tm', cwd+'/src/dm', cwd+'/src/im', + cwd+'/src/image', cwd+'/src/rm', cwd+'/src/vnm', cwd+'/src/hm', @@ -155,6 +156,7 @@ build_scripts=[ 'src/rm/SConstruct', 'src/tm/SConstruct', 'src/im/SConstruct', + 'src/image/SConstruct', 'src/dm/SConstruct', 'src/scheduler/SConstruct', 'src/vnm/SConstruct', diff --git a/include/Callbackable.h b/include/Callbackable.h index 58501c455b..c22d95a40a 100644 --- a/include/Callbackable.h +++ b/include/Callbackable.h @@ -17,6 +17,8 @@ #ifndef CALLBACKABLE_H_ #define CALLBACKABLE_H_ +#include + using namespace std; /** @@ -27,9 +29,15 @@ class Callbackable { public: - Callbackable():cb(0),arg(0){}; + Callbackable():cb(0),arg(0) + { + pthread_mutex_init(&mutex,0); + }; - virtual ~Callbackable(){}; + virtual ~Callbackable() + { + pthread_mutex_destroy(&mutex); + }; /** * Datatype for call back pointers @@ -38,12 +46,14 @@ public: /** * Set the callback function and custom arguments to be executed by the - * next SQL command + * next SQL command, and locks the mutex until unset_callback is called. * @param ptr to the callback function * @param arg custom arguments for the callback function */ void set_callback(Callback _cb, void * _arg = 0) { + pthread_mutex_lock(&mutex); + cb = _cb; arg = _arg; }; @@ -58,16 +68,26 @@ public: }; /** - * Set the callback function and custom arguments to be executed by the - * next SQL command - * @param ptr to the callback function - * @param arg custom arguments for the callback function + * Call the callback funcion set. This method must be called only if + * isCallBackSet returns true. + * @return the callback function return value. */ int do_callback(int num, char **values, char **names) { return (this->*cb)(arg, num, values, names); }; + /** + * Unset the callback function. + */ + void unset_callback() + { + cb = 0; + arg = 0; + + pthread_mutex_unlock(&mutex); + } + private: /** * SQL callback to be executed for each row result of an SQL statement @@ -78,6 +98,11 @@ private: * Custom arguments for the callback */ void * arg; + + /** + * Mutex for locking the callback function. + */ + pthread_mutex_t mutex; }; #endif /*CALLBACKABLE_H_*/ diff --git a/include/HostPool.h b/include/HostPool.h index e655463cb0..d4bade52ba 100644 --- a/include/HostPool.h +++ b/include/HostPool.h @@ -87,9 +87,10 @@ public: * Get the 10 least monitored hosts * @param discovered hosts, map to store the retrieved hosts hids and * hostnames + * @param host_limit max. number of hosts to monitor at a time * @return int 0 if success */ - int discover(map * discovered_hosts); + int discover(map * discovered_hosts, int host_limit); /** * Allocates a given capacity to the host diff --git a/include/Image.h b/include/Image.h new file mode 100644 index 0000000000..5d6258a151 --- /dev/null +++ b/include/Image.h @@ -0,0 +1,453 @@ +/* ------------------------------------------------------------------------ */ +/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------*/ + +#ifndef IMAGE_H_ +#define IMAGE_H_ + +#include "PoolSQL.h" +#include "ImageTemplate.h" +#include "NebulaLog.h" + +using namespace std; + +/** + * The Image class. + */ +class Image : public PoolObjectSQL +{ +public: + /** + * Type of Images + */ + enum ImageType + { + OS = 0, /** < Base OS image */ + CDROM = 1, /** < An ISO9660 image */ + DATABLOCK = 2 /** < User persistent data device */ + }; + + /** + * Image State + */ + enum ImageState + { + INIT = 0, /** < Initialization state */ + LOCKED = 1, /** < FS operation on the image in progress, don't use */ + READY = 2, /** < Image ready to use */ + USED = 3, /** < Image in use */ + DISABLED = 4 /** < Image can not be instantiated by a VM */ + }; + + /** + * Function to write an Image on an output stream + */ + friend ostream& operator<<(ostream& os, Image& i); + + // ************************************************************************* + // Image Public Methods + // ************************************************************************* + + /** + * Function to print the Image object into a string in plain text + * @param str the resulting string + * @return a reference to the generated string + */ + string& to_str(string& str) const; + + /** + * Function to print the Image object into a string in XML format + * @param xml the resulting XML string + * @return a reference to the generated string + */ + string& to_xml(string& xml) const; + + /** + * Get the Image unique identifier IID, that matches the OID of the object + * @return IID Image identifier + */ + int get_iid() const + { + return oid; + }; + + /** + * Gets the uid of the owner of the Image + * @return uid + **/ + int get_uid() + { + return uid; + } + + /** + * Returns Image's name + * @return name Image's name + */ + const string& get_name() const + { + return name; + }; + + /** + * Returns true if the image is public + * @return true if the image is public + */ + bool is_public() + { + return (public_img == 1); + }; + + /** + * Set enum type + * @return 0 on success, -1 otherwise + */ + int set_type(const string& _type) + { + int rc = 0; + + if ( _type == "OS" ) + { + type = OS; + } + else if ( _type == "CDROM" ) + { + type = CDROM; + } + else if ( _type == "DATABLOCK" ) + { + type = DATABLOCK; + } + else + { + rc = -1; + } + + return rc; + } + + /** + * Get an image to be used in a VM, and updates its state. + * @param overwrite true if the image is going to be overwritten + * @return 0 if success + */ + int acquire_image(bool overwrite); + + + /** + * Releases an image being used by a VM + */ + void release_image(); + + /** + * Enables the image + * @param to_enable true will enable the image. + * @return 0 on success + */ + int enable(bool to_enable) + { + int rc = 0; + + if ((to_enable == true) && (state == DISABLED)) + { + state = READY; + } + else if ((to_enable == false) && (state == READY)) + { + state = DISABLED; + } + else + { + rc = -1; + } + + return rc; + } + + /** + * Publish or unpublish an image + * @param pub true to publish the image + * @return 0 on success + */ + void publish(bool pub) + { + if (pub == true) + { + public_img = 1; + } + else + { + public_img = 0; + } + } + + /** + * Modifies the given disk attribute adding the following attributes: + * * SOURCE: the file-path. + * * BUS: will only be set if the Image's definition includes it. + * * TARGET: the value set depends on: + * - OS images will be mounted at prefix + a: hda, sda. + * - Prefix + b is reserved for the contex cdrom. + * - CDROM images will be at prefix + c: hdc, sdc. + * - Several DATABLOCK images can be mounted, they will be set to + * prefix + (d + index) : hdd, hde, hdf... + * @param disk attribute for the VM template + */ + int disk_attribute(VectorAttribute * disk, int * index); + + // ------------------------------------------------------------------------ + // Template + // ------------------------------------------------------------------------ + + /** + * Gets the values of a template attribute + * @param name of the attribute + * @param values of the attribute + * @return the number of values + */ + int get_template_attribute( + string& name, + vector& values) const + { + return image_template.get(name,values); + }; + + /** + * Gets the values of a template attribute + * @param name of the attribute + * @param values of the attribute + * @return the number of values + */ + int get_template_attribute( + const char *name, + vector& values) const + { + string str=name; + return image_template.get(str,values); + }; + + /** + * Gets a string based Image attribute + * @param name of the attribute + * @param value of the attribute (a string), will be "" if not defined + */ + void get_template_attribute( + const char * name, + string& value) const + { + string str=name; + image_template.get(str,value); + } + + /** + * Gets a string based Image attribute + * @param name of the attribute + * @param value of the attribute (an int), will be 0 if not defined + */ + void get_template_attribute( + const char * name, + int& value) const + { + string str=name; + image_template.get(str,value); + } + + /** + * Removes an Image attribute + * @param name of the attribute + */ + int remove_template_attribute(SqlDB * db, const string& name) + { + return image_template.remove_attribute(db, name); + } + +private: + + // ------------------------------------------------------------------------- + // Friends + // ------------------------------------------------------------------------- + + friend class ImagePool; + + // ------------------------------------------------------------------------- + // Image Description + // ------------------------------------------------------------------------- + + /** + * Owner if the image + */ + int uid; + + /** + * The name of the Image + */ + string name; + + /** + * Type of the Image + */ + ImageType type; + + /** + * Public scope of the Image + */ + int public_img; + + /** + * Registration time + */ + time_t regtime; + + /** + * Path to the image + */ + string source; + + /** + * Image state + */ + ImageState state; + + /** + * Number of VMs using the image + */ + int running_vms; + + // ------------------------------------------------------------------------- + // Image Attributes + // ------------------------------------------------------------------------- + + /** + * The Image template, holds the Image attributes. + */ + ImageTemplate image_template; + + + // ************************************************************************* + // DataBase implementation (Private) + // ************************************************************************* + + /** + * Execute an INSERT or REPLACE Sql query. + * @param db The SQL DB + * @param replace Execute an INSERT or a REPLACE + * @return 0 on success + */ + int insert_replace(SqlDB *db, bool replace); + + /** + * Callback function to unmarshall a Image object (Image::select) + * @param num the number of columns read from the DB + * @param names the column names + * @param values the column values + * @return 0 on success + */ + int select_cb(void *nil, int num, char **values, char **names); + + /** + * Bootstraps the database table(s) associated to the Image + */ + static void bootstrap(SqlDB * db) + { + ostringstream oss_image(Image::db_bootstrap); + ostringstream oss_templ(ImageTemplate::db_bootstrap); + + db->exec(oss_image); + db->exec(oss_templ); + }; + + + /** + * "Encrypts" the password with SHA1 digest + * @param password + * @return sha1 encrypted password + */ + string sha1_digest(const string& pass); + +protected: + + // ************************************************************************* + // Constructor + // ************************************************************************* + + Image(int id=-1); + + virtual ~Image(); + + // ************************************************************************* + // DataBase implementation + // ************************************************************************* + + enum ColNames + { + OID = 0, /* Image identifier (IID) */ + UID = 1, /* Image owner id */ + NAME = 2, /* Image name */ + TYPE = 3, /* 0) OS 1) CDROM 2) DATABLOCK */ + PUBLIC = 4, /* Public scope (YES OR NO) */ + REGTIME = 5, /* Time of registration */ + SOURCE = 6, /* Path to the image */ + STATE = 7, /* 0) INIT 1) ALLOCATED */ + /* 2) READY 3) USED */ + RUNNING_VMS = 8, /* Number of VMs using the img */ + LIMIT = 9 + }; + + static const char * db_names; + + static const char * db_bootstrap; + + static const char * table; + + /** + * Reads the Image (identified with its OID=IID) from the database. + * @param db pointer to the db + * @return 0 on success + */ + virtual int select(SqlDB *db); + + /** + * Writes the Image in the database. + * @param db pointer to the db + * @return 0 on success + */ + virtual int insert(SqlDB *db); + + /** + * Writes/updates the Images data fields in the database. + * @param db pointer to the db + * @return 0 on success + */ + virtual int update(SqlDB *db); + + /** + * Drops Image and associated template from the database + * @param db pointer to the db + * @return 0 on success + */ + virtual int drop(SqlDB *db); + + /** + * Function to output an Image object in to an stream in XML format + * @param oss the output stream + * @param num the number of columns read from the DB + * @param names the column names + * @param vaues the column values + * @return 0 on success + */ + static int dump(ostringstream& oss, int num, char **values, char **names); +}; + +#endif /*IMAGE_H_*/ diff --git a/include/ImagePool.h b/include/ImagePool.h new file mode 100644 index 0000000000..d46c09c4ae --- /dev/null +++ b/include/ImagePool.h @@ -0,0 +1,269 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#ifndef IMAGE_POOL_H_ +#define IMAGE_POOL_H_ + +#include "PoolSQL.h" +#include "Image.h" +#include "NebulaLog.h" + +#include +#include + +#include +#include + +using namespace std; + +/** + * The Image Pool class. + */ +class ImagePool : public PoolSQL +{ +public: + + ImagePool(SqlDB * db, + const string& _source_prefix, + const string& _default_type, + const string& _default_dev_prefix); + + ~ImagePool(){}; + + /** + * Function to allocate a new Image object + * @param uid the user id of the image's owner + * @param stemplate template associated with the image + * @param oid the id assigned to the Image + * @return the oid assigned to the object, + * -1 in case of failure + * -2 in case of template parse failure + */ + int allocate ( + int uid, + const string& stemplate, + int * oid); + + /** + * Function to get a Image from the pool, if the object is not in memory + * it is loaded from the DB + * @param oid Image unique id + * @param lock locks the Image mutex + * @return a pointer to the Image, 0 if the Image could not be loaded + */ + Image * get( + int oid, + bool lock) + { + return static_cast(PoolSQL::get(oid,lock)); + }; + + /** + * Function to get an Image from the pool using the image name + * @param name of the image + * @param lock locks the User mutex + * @return a pointer to the Image, 0 if the User could not be loaded + */ + Image * get( + const string& name, + bool lock) + { + map::iterator index; + + index = image_names.find(name); + + if ( index != image_names.end() ) + { + return get((int)index->second,lock); + } + + return 0; + } + + /** Update a particular Image + * @param image pointer to Image + * @return 0 on success + */ + int update(Image * image) + { + return image->update(db); + }; + + /** Drops an image from the DB, the image mutex MUST BE locked + * @param image pointer to Image + * @return 0 on success + */ + int drop(Image * image) + { + int rc = PoolSQL::drop(image); + + if ( rc == 0) + { + image_names.erase(image->get_name()); + } + + return rc; + }; + + /** Modify an image attribute in the template (Image MUST be locked) + * @param image pointer to Image + * @param name of the attribute to be changed + * @param new value for the attribute + * @return 0 on success, -1 otherwise + */ + int replace_attribute( + Image * image, + const string& name, + const string& value) + { + SingleAttribute * sattr = new SingleAttribute(name,value); + + return image->image_template.replace_attribute(db,sattr); + } + + /** Delete an image attribute in the template (Image MUST be locked) + * @param image pointer to Image + * @param name of the attribute to be removed + * @return 0 on success, -1 otherwise + */ + int remove_attribute( + Image * image, + const string& name) + { + return image->image_template.remove_attribute(db, name); + } + + /** + * Bootstraps the database table(s) associated to the Image pool + */ + static void bootstrap(SqlDB *_db) + { + Image::bootstrap(_db); + }; + + /** + * Dumps the Image 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); + + /** + * Generates a DISK attribute for VM templates using the Image metadata + * @param disk the disk to be generated + * @return 0 on success, -1 error, -2 not using the pool + */ + int disk_attribute(VectorAttribute * disk, int * index) + { + string source; + Image * img; + + source = disk->vector_value("NAME"); + + if (source.empty()) + { + return -2; + } + + img = get(source,true); + + if (img == 0) + { + return -1; + } + + int rc = img->disk_attribute(disk,index); + + img->unlock(); + + return rc; + } + + static const string& source_prefix() + { + return _source_prefix; + }; + + static const string& default_type() + { + return _default_type; + }; + + static const string& default_dev_prefix() + { + return _default_dev_prefix; + }; + +private: + //-------------------------------------------------------------------------- + // Configuration Attributes for Images + // ------------------------------------------------------------------------- + /** + * Path to the image repository + **/ + static string _source_prefix; + + /** + * Default image type + **/ + static string _default_type; + + /** + * Default device prefix + **/ + static string _default_dev_prefix; + + //-------------------------------------------------------------------------- + // Pool Attributes + // ------------------------------------------------------------------------- + /** + * This map stores the association between IIDs and Image names + */ + map image_names; + + /** + * Factory method to produce Image objects + * @return a pointer to the new Image + */ + PoolObjectSQL * create() + { + return new Image; + }; + + /** + * Callback function to get output the image pool in XML format + * (Image::dump) + * @param num the number of columns read from the DB + * @param names the column names + * @param vaues the column values + * @return 0 on success + */ + int dump_cb(void * _oss, int num, char **values, char **names); + + /** + * Callback function to build the image_names map + * @param num the number of columns read from the DB + * @param names the column names + * @param vaues the column values + * @return 0 on success + */ + int init_cb(void *nil, int num, char **values, char **names); + +}; + +#endif /*IMAGE_POOL_H_*/ diff --git a/include/ImageTemplate.h b/include/ImageTemplate.h new file mode 100644 index 0000000000..8a999aa9f4 --- /dev/null +++ b/include/ImageTemplate.h @@ -0,0 +1,48 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#ifndef IMAGE_TEMPLATE_H_ +#define IMAGE_TEMPLATE_H_ + +#include "TemplateSQL.h" + +using namespace std; + +/** + * Image Template class, it represents the attributes of a Host + */ +class ImageTemplate : public TemplateSQL +{ +public: + ImageTemplate(int tid = -1, + const char separator = '='): + TemplateSQL(table,tid,true,separator,"TEMPLATE"){}; + + ~ImageTemplate(){}; + +private: + friend class Image; + friend class ImagePool; + + static const char * table; + + static const char * db_bootstrap; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +#endif /*IMAGE_TEMPLATE_H_*/ diff --git a/include/Nebula.h b/include/Nebula.h index ec52e26208..37d51b59af 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -69,6 +69,11 @@ public: return upool; }; + ImagePool * get_ipool() + { + return ipool; + }; + // -------------------------------------------------------------- // Manager Accessors // -------------------------------------------------------------- @@ -212,32 +217,32 @@ private: // ----------------------------------------------------------------------- Nebula():nebula_configuration(0),db(0),vmpool(0),hpool(0),vnpool(0),upool(0), - lcm(0),vmm(0),im(0),tm(0),dm(0),rm(0) + ipool(0),lcm(0),vmm(0),im(0),tm(0),dm(0),rm(0) { - const char * nl = getenv("ONE_LOCATION"); + const char * nl = getenv("ONE_LOCATION"); if (nl == 0) //OpenNebula installed under root directory { - nebula_location = "/"; + nebula_location = "/"; - mad_location = "/usr/lib/one/mads/"; - etc_location = "/etc/one/"; - log_location = "/var/log/one/"; - var_location = "/var/lib/one/"; + mad_location = "/usr/lib/one/mads/"; + etc_location = "/etc/one/"; + log_location = "/var/log/one/"; + var_location = "/var/lib/one/"; } else { - nebula_location = nl; + nebula_location = nl; - if ( nebula_location.at(nebula_location.size()-1) != '/' ) - { - nebula_location += "/"; - } + if ( nebula_location.at(nebula_location.size()-1) != '/' ) + { + nebula_location += "/"; + } - mad_location = nebula_location + "lib/mads/"; - etc_location = nebula_location + "etc/"; - log_location = nebula_location + "var/"; - var_location = nebula_location + "var/"; + mad_location = nebula_location + "lib/mads/"; + etc_location = nebula_location + "etc/"; + log_location = nebula_location + "var/"; + var_location = nebula_location + "var/"; } }; @@ -263,6 +268,11 @@ private: delete upool; } + if ( ipool != 0) + { + delete ipool; + } + if ( vmm != 0) { delete vmm; @@ -340,6 +350,7 @@ private: HostPool * hpool; VirtualNetworkPool * vnpool; UserPool * upool; + ImagePool * ipool; // --------------------------------------------------------------- // Nebula Managers diff --git a/include/PoolSQL.h b/include/PoolSQL.h index e88223e739..74ffb85fe5 100644 --- a/include/PoolSQL.h +++ b/include/PoolSQL.h @@ -140,22 +140,6 @@ protected: */ SqlDB * db; - /** - * Function to lock the pool - */ - void lock() - { - pthread_mutex_lock(&mutex); - }; - - /** - * Function to unlock the pool - */ - void unlock() - { - pthread_mutex_unlock(&mutex); - }; - private: pthread_mutex_t mutex; @@ -177,7 +161,7 @@ private: * The pool is implemented with a Map of SQL object pointers, using the * OID as key. */ - map pool; + map pool; /** * Factory method, must return an ObjectSQL pointer to an allocated pool @@ -189,7 +173,23 @@ private: * OID queue to implement a FIFO-like replacement policy for the pool * cache. */ - queue oid_queue; + queue oid_queue; + + /** + * Function to lock the pool + */ + void lock() + { + pthread_mutex_lock(&mutex); + }; + + /** + * Function to unlock the pool + */ + void unlock() + { + pthread_mutex_unlock(&mutex); + }; /** * FIFO-like replacement policy function. Before removing an object (pop) diff --git a/include/RequestManager.h b/include/RequestManager.h index 59835b5a72..ca8162d391 100644 --- a/include/RequestManager.h +++ b/include/RequestManager.h @@ -22,6 +22,7 @@ #include "HostPool.h" #include "UserPool.h" #include "VirtualNetworkPool.h" +#include "ImagePool.h" #include #include @@ -42,10 +43,11 @@ public: HostPool * _hpool, VirtualNetworkPool * _vnpool, UserPool * _upool, + ImagePool * _ipool, int _port, string _xml_log_file) :vmpool(_vmpool),hpool(_hpool),vnpool(_vnpool),upool(_upool), - port(_port),socket_fd(-1),xml_log_file(_xml_log_file) + ipool(_ipool),port(_port),socket_fd(-1),xml_log_file(_xml_log_file) { am.addListener(this); }; @@ -118,6 +120,11 @@ private: * Pointer to the User Pool, to access users */ UserPool * upool; + + /** + * Pointer to the Image Pool, to access images + */ + ImagePool * ipool; /** * Port number where the connection will be open @@ -536,6 +543,32 @@ private: VirtualNetworkPool * vnpool; UserPool * upool; }; + + /* ---------------------------------------------------------------------- */ + + class VirtualNetworkPublish: public xmlrpc_c::method + { + public: + VirtualNetworkPublish( + VirtualNetworkPool * _vnpool, + UserPool * _upool): + vnpool(_vnpool), + upool(_upool) + { + _signature="A:sib"; + _help="Enables/Disables a virtual network"; + }; + + ~VirtualNetworkPublish(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + VirtualNetworkPool * vnpool; + UserPool * upool; + }; /* ---------------------------------------------------------------------- */ @@ -639,7 +672,7 @@ private: UserPoolInfo(UserPool * _upool):upool(_upool) { _signature="A:s"; - _help="Creates a new user"; + _help="Returns content of the user pool"; }; ~UserPoolInfo(){}; @@ -651,8 +684,212 @@ private: private: UserPool * upool; }; + + /* ---------------------------------------------------------------------- */ + /* Image Pool Interface */ + /* ---------------------------------------------------------------------- */ + + class ImageAllocate: public xmlrpc_c::method + { + public: + ImageAllocate(ImagePool * _ipool, + UserPool * _upool): + ipool(_ipool), + upool(_upool) + { + _signature="A:ss"; + _help="Creates a new image"; + }; + + ~ImageAllocate(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + ImagePool * ipool; + UserPool * upool; + }; + + /* ---------------------------------------------------------------------- */ + + class ImageDelete: public xmlrpc_c::method + { + public: + ImageDelete(ImagePool * _ipool, + UserPool * _upool): + ipool(_ipool), + upool(_upool) + { + _signature="A:si"; + _help="Deletes an image"; + }; + + ~ImageDelete(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + ImagePool * ipool; + UserPool * upool; + }; + + /* ---------------------------------------------------------------------- */ + + class ImageInfo: public xmlrpc_c::method + { + public: + ImageInfo(ImagePool * _ipool, + UserPool * _upool): + ipool(_ipool), + upool(_upool) + { + _signature="A:si"; + _help="Returns information for an image"; + }; + + ~ImageInfo(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + ImagePool * ipool; + UserPool * upool; + }; + + /* ---------------------------------------------------------------------- */ + + class ImageUpdate: public xmlrpc_c::method + { + public: + ImageUpdate(ImagePool * _ipool, + UserPool * _upool): + ipool(_ipool), + upool(_upool) + { + _signature="A:siss"; + _help="Modifies image attribute"; + }; + + ~ImageUpdate(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + ImagePool * ipool; + UserPool * upool; + }; + + /* ---------------------------------------------------------------------- */ + + class ImageRemoveAttribute: public xmlrpc_c::method + { + public: + ImageRemoveAttribute(ImagePool * _ipool, + UserPool * _upool): + ipool(_ipool), + upool(_upool) + { + _signature="A:sis"; + _help="Removes image attribute"; + }; + + ~ImageRemoveAttribute(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + ImagePool * ipool; + UserPool * upool; + }; + + /* ---------------------------------------------------------------------- */ + + class ImagePublish: public xmlrpc_c::method + { + public: + ImagePublish(ImagePool * _ipool, + UserPool * _upool): + ipool(_ipool), + upool(_upool) + { + _signature="A:sib"; + _help="Publish/Unpublish the Image"; + }; + + ~ImagePublish(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + ImagePool * ipool; + UserPool * upool; + }; + + /* ---------------------------------------------------------------------- */ + + class ImageEnable: public xmlrpc_c::method + { + public: + ImageEnable(ImagePool * _ipool, + UserPool * _upool): + ipool(_ipool), + upool(_upool) + { + _signature="A:sib"; + _help="Enables/Disables the Image"; + }; + + ~ImageEnable(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + ImagePool * ipool; + UserPool * upool; + }; + + /* ---------------------------------------------------------------------- */ + + class ImagePoolInfo: public xmlrpc_c::method + { + public: + ImagePoolInfo(ImagePool * _ipool, + UserPool * _upool): + ipool(_ipool), + upool(_upool) + { + _signature="A:si"; + _help="Returns content of image pool attending to the filter flag"; + }; + + ~ImagePoolInfo(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + ImagePool * ipool; + UserPool * upool; + }; }; + + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/Template.h b/include/Template.h index b8d7030197..d4763a7370 100644 --- a/include/Template.h +++ b/include/Template.h @@ -117,6 +117,14 @@ public: const string& name, vector& values); + + /** + * Removes an attribute from the template, and frees the attributes. + * @param name of the attribute + * @returns the number of attributes removed + */ + virtual int erase(const string& name); + /** * Gets all the attributes with the given name. * @param name the attribute name. diff --git a/include/TemplateSQL.h b/include/TemplateSQL.h index 912d20b735..3c219475ae 100644 --- a/include/TemplateSQL.h +++ b/include/TemplateSQL.h @@ -85,18 +85,18 @@ protected: * @param db pointer to the database. */ int drop(SqlDB *db); - + /** - * Execute an INSERT or REPLACE Sql query. + * Execute an INSERT or REPLACE Sql query. * @param db The SQL DB - * @param replace Execute an INSERT or a REPLACE + * @param replace Execute an INSERT or a REPLACE * @return 0 one success - */ + */ int insert_replace(SqlDB *db, bool replace); /** * Removes a template attribute from the DB. If there are multiple - * attributes with the same name, only one will be replaced. The + * attributes with the same name, only one will be replaced. The * attribute MUST be allocated in the heap. * @param db pointer to the database. * @param attribute pointer to the new attribute. @@ -112,9 +112,11 @@ protected: int insert_attribute(SqlDB * db, Attribute * attribute); /** - * Callback to set the template id (TemplateSQL::insert) + * Remove a given attribute from the template and the DB. + * @param db pointer to the database. + * @param name name of the attribute */ - int insert_cb(void *nil, int num, char **values, char **names); + int remove_attribute(SqlDB * db, const string& name); /** * Callback to recover template attributes (TemplateSQL::select) @@ -125,4 +127,4 @@ protected: /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ -#endif /*TEMPLATE_SQL_H_*/ \ No newline at end of file +#endif /*TEMPLATE_SQL_H_*/ diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 3c28ab7532..b56f4bb8ef 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -21,6 +21,7 @@ #include "PoolSQL.h" #include "History.h" #include "Log.h" +#include "NebulaLog.h" #include #include @@ -615,24 +616,6 @@ public: */ int parse_template_attribute(const string& attribute, string& parsed); - - /** - * Parse a string and substitute variables (e.g. $NAME) using the VM - * template values (blocking-free version for cross references): - * @param vm_id ID of the VM used to substitute the variables - * @param attribute, the string to be parsed - * @param parsed, the resulting parsed string - * @param error_msg, string describing the syntax error - * @return 0 on success. - */ - static int parse_template_attribute(int vm_id, - const string& attribute, - string& parsed, - char ** error_msg) - { - return parse_attribute(0,vm_id,attribute,parsed,error_msg); - } - // ------------------------------------------------------------------------ // States // ------------------------------------------------------------------------ @@ -713,7 +696,7 @@ public: void get_requirements (int& cpu, int& memory, int& disk); // ------------------------------------------------------------------------ - // Network Leases + // Network Leases & Disk Images // ------------------------------------------------------------------------ /** * Get all network leases for this Virtual Machine @@ -726,6 +709,17 @@ public: */ void release_network_leases(); + /** + * Get all disk images for this Virtual Machine + * @return 0 if success + */ + int get_disk_images(); + + /** + * Releases all disk images taken by this Virtual Machine + */ + void release_disk_images(); + // ------------------------------------------------------------------------ // Context related functions // ------------------------------------------------------------------------ @@ -826,6 +820,11 @@ private: */ int net_rx; + /** + * Sequence number of the last history item. + */ + int last_seq; + /** * History record, for the current host */ @@ -875,11 +874,11 @@ private: * @return 0 on success */ int select_cb(void *nil, int num, char **names, char ** values); - + /** - * Execute an INSERT or REPLACE Sql query. + * Execute an INSERT or REPLACE Sql query. * @param db The SQL DB - * @param replace Execute an INSERT or a REPLACE + * @param replace Execute an INSERT or a REPLACE * @return 0 one success */ int insert_replace(SqlDB *db, bool replace); @@ -963,22 +962,24 @@ private: static pthread_mutex_t lex_mutex; /** - * Parse a string and substitute variables (e.g. $NAME) using template - * values: - * @param vm pointer to VirtualMachine if not 0 the template of that VM - * will be used. - * @param vm_id ID of the VM used to substitute the variables, used if vm - * is 0 - * @param attribute, the string to be parsed - * @param parsed, the resulting parsed string - * @param error_msg, string describing the syntax error - * @return 0 on success. + * Parse the "CONTEXT" attribute of the template by substituting + * $VARIABLE, $VARIABLE[ATTR] and $VARIABLE[ATTR, ATTR = VALUE] + * @return 0 on success */ - static int parse_attribute(VirtualMachine * vm, - int vm_id, - const string& attribute, - string& parsed, - char ** error_msg); + int parse_context(); + + /** + * Parse the "REQUIREMENTS" attribute of the template by substituting + * $VARIABLE, $VARIABLE[ATTR] and $VARIABLE[ATTR, ATTR = VALUE] + * @return 0 on success + */ + int parse_requirements(); + + /** + * Parse the "GRAPHICS" attribute and generates a default PORT if not + * defined + */ + void parse_graphics(); protected: @@ -1000,16 +1001,16 @@ protected: UID = 1, NAME = 2, LAST_POLL = 3, - TEMPLATE_ID = 4, - STATE = 5, - LCM_STATE = 6, - STIME = 7, - ETIME = 8, - DEPLOY_ID = 9, - MEMORY = 10, - CPU = 11, - NET_TX = 12, - NET_RX = 13, + STATE = 4, + LCM_STATE = 5, + STIME = 6, + ETIME = 7, + DEPLOY_ID = 8, + MEMORY = 9, + CPU = 10, + NET_TX = 11, + NET_RX = 12, + LAST_SEQ = 13, LIMIT = 14 }; @@ -1041,24 +1042,14 @@ protected: virtual int update(SqlDB * db); /** - * Deletes a VM from the database and all its associated information: - * - History records - * - VM template + * Deletes a VM from the database and all its associated information * @param db pointer to the db - * @return 0 on success + * @return -1 */ virtual int drop(SqlDB * db) { - int rc; - - rc = vm_template.drop(db); - - if ( history != 0 ) - { - rc += history->drop(db); - } - - return rc; + NebulaLog::log("ONE",Log::ERROR, "VM Drop not implemented!"); + return -1; } /** diff --git a/include/VirtualMachinePool.h b/include/VirtualMachinePool.h index 98d15cc032..685179e76a 100644 --- a/include/VirtualMachinePool.h +++ b/include/VirtualMachinePool.h @@ -68,10 +68,15 @@ public: /** * Function to get the IDs of running VMs * @param oids a vector that contains the IDs + * @param vm_limit Max. number of VMs returned + * @param last_poll Return only VMs which last_poll is less than or equal + * to this value. * @return 0 on success */ int get_running( - vector& oids); + vector& oids, + int vm_limit, + time_t last_poll); /** * Function to get the IDs of pending VMs @@ -143,13 +148,6 @@ public: int dump(ostringstream& oss, const string& where); private: - /** - * Generate context file to be sourced upon VM booting - * @param vm_id, ID of the VM to generate context for - * @param attr, the template CONTEXT attribute (the first one) - */ - void generate_context(int vm_id, Attribute * attr); - /** * Factory method to produce VM objects * @return a pointer to the new VM diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index a057906a0a..87841fb94e 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -67,6 +67,32 @@ public: return uid; } + /** + * Returns true if the Virtual Network is public + * @return true if the Virtual Network is public + */ + bool is_public() + { + return (public_vnet == 1); + }; + + /** + * Publish or unpublish a virtual network + * @param pub true to publish the image + * @return 0 on success + */ + void publish(bool pub) + { + if (pub == true) + { + public_vnet = 1; + } + else + { + public_vnet = 0; + } + } + /** * Gets a new lease for a specific VM * @param vid VM identifier @@ -135,114 +161,18 @@ public: */ string& to_xml(string& xml) const; -private: - - // ------------------------------------------------------------------------- - // Friends - // ------------------------------------------------------------------------- - friend class VirtualNetworkPool; - - // ************************************************************************* - // Virtual Network Private Attributes - // ************************************************************************* - - // ------------------------------------------------------------------------- - // Identification variables - // ------------------------------------------------------------------------- /** - * Name of the Virtual Network + * Modifies the given nic attribute adding the following attributes: + * * IP: leased from network + * * MAC: leased from network + * * BRIDGE: for this virtual network + * @param nic attribute for the VM template + * @param vid of the VM getting the lease + * @return 0 on success */ - string name; + int nic_attribute(VectorAttribute * nic, int vid); - /** - * Owner of the Virtual Network - */ - int uid; - - // ------------------------------------------------------------------------- - // Binded physical attributes - // ------------------------------------------------------------------------- - - /** - * Name of the bridge this VNW binds to - */ - string bridge; - - // ------------------------------------------------------------------------- - // Virtual Network Description - // ------------------------------------------------------------------------- - /** - * Holds the type of this network - */ - NetworkType type; - - /** - * Pointer to leases class, can be fixed or ranged. - * Holds information on given (and, optionally, possible) leases - */ - Leases * leases; - - /** - * The Virtual Network template, holds the VNW attributes. - */ - VirtualNetworkTemplate vn_template; - - // ************************************************************************* - // Non persistent data members from Nebula.conf - // ************************************************************************* - - /** - * MAC prefix for this OpenNebula site - */ - unsigned int mac_prefix; - - /** - * Default size for virtual networks - */ - int default_size; - - // ************************************************************************* - // DataBase implementation (Private) - // ************************************************************************* - - /** - * Execute an INSERT or REPLACE Sql query. - * @param db The SQL DB - * @param replace Execute an INSERT or a REPLACE - * @return 0 on success - */ - int insert_replace(SqlDB *db, bool replace); - - /** - * Bootstraps the database table(s) associated to the Virtual Network - */ - static void bootstrap(SqlDB * db) - { - ostringstream oss_vnet(VirtualNetwork::db_bootstrap); - ostringstream oss_templ(VirtualNetworkTemplate::db_bootstrap); - ostringstream oss_lease(Leases::db_bootstrap); - - db->exec(oss_vnet); - db->exec(oss_templ); - db->exec(oss_lease); - }; - - /** - * Callback function to unmarshall a VNW object (VirtualNetwork::select) - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - int select_cb(void * nil, int num, char **values, char **names); - - /** - * Function to drop VN entry in vn_pool - * @return 0 on success - */ - int vn_drop(SqlDB * db); - - // ------------------------------------------------------------------------ + //------------------------------------------------------------------------ // Template // ------------------------------------------------------------------------ @@ -299,6 +229,106 @@ private: vn_template.get(str,value); } +private: + + // ------------------------------------------------------------------------- + // Friends + // ------------------------------------------------------------------------- + friend class VirtualNetworkPool; + + // ************************************************************************* + // Virtual Network Private Attributes + // ************************************************************************* + + // ------------------------------------------------------------------------- + // Identification variables + // ------------------------------------------------------------------------- + /** + * Name of the Virtual Network + */ + string name; + + /** + * Owner of the Virtual Network + */ + int uid; + + // ------------------------------------------------------------------------- + // Binded physical attributes + // ------------------------------------------------------------------------- + + /** + * Name of the bridge this VNW binds to + */ + string bridge; + + // ------------------------------------------------------------------------- + // Virtual Network Description + // ------------------------------------------------------------------------- + /** + * Holds the type of this network + */ + NetworkType type; + + /** + * Public scope of this Virtual Network + */ + int public_vnet; + + /** + * Pointer to leases class, can be fixed or ranged. + * Holds information on given (and, optionally, possible) leases + */ + Leases * leases; + + /** + * The Virtual Network template, holds the VNW attributes. + */ + VirtualNetworkTemplate vn_template; + + // ************************************************************************* + // DataBase implementation (Private) + // ************************************************************************* + + /** + * Execute an INSERT or REPLACE Sql query. + * @param db The SQL DB + * @param replace Execute an INSERT or a REPLACE + * @return 0 on success + */ + int insert_replace(SqlDB *db, bool replace); + + /** + * Bootstraps the database table(s) associated to the Virtual Network + */ + static void bootstrap(SqlDB * db) + { + ostringstream oss_vnet(VirtualNetwork::db_bootstrap); + ostringstream oss_templ(VirtualNetworkTemplate::db_bootstrap); + ostringstream oss_lease(Leases::db_bootstrap); + + db->exec(oss_vnet); + db->exec(oss_templ); + db->exec(oss_lease); + }; + + /** + * Callback function to unmarshall a VNW object (VirtualNetwork::select) + * @param num the number of columns read from the DB + * @param names the column names + * @param vaues the column values + * @return 0 on success + */ + int select_cb(void * nil, int num, char **values, char **names); + + /** + * Function to drop VN entry in vn_pool + * @return 0 on success + */ + int vn_drop(SqlDB * db); + + + /** * Updates the template of a VNW, adding a new attribute (replacing it if * already defined), the VN's mutex SHOULD be locked @@ -332,7 +362,7 @@ protected: // Constructor //************************************************************************** - VirtualNetwork(unsigned int _mac_prefix, int _default_size); + VirtualNetwork(); ~VirtualNetwork(); @@ -347,7 +377,8 @@ protected: NAME = 2, TYPE = 3, BRIDGE = 4, - LIMIT = 5 + PUBLIC = 5, + LIMIT = 6 }; static const char * table; diff --git a/include/VirtualNetworkPool.h b/include/VirtualNetworkPool.h index 4e2c0bee3c..c5e0dd0816 100644 --- a/include/VirtualNetworkPool.h +++ b/include/VirtualNetworkPool.h @@ -80,6 +80,39 @@ public: // Virtual Network DB access functions //-------------------------------------------------------------------------- + /** + * Generates a NIC attribute for VM templates using the VirtualNetwork + * metadata + * @param nic the nic attribute to be generated + * @param vid of the VM requesting the lease + * @return 0 on success, -1 error, -2 not using the pool + */ + int nic_attribute(VectorAttribute * nic, int vid) + { + string network; + VirtualNetwork * vnet; + + network = nic->vector_value("NETWORK"); + + if (network.empty()) + { + return -2; + } + + vnet = get(network,true); + + if (vnet == 0) + { + return -1; + } + + int rc = vnet->nic_attribute(nic,vid); + + vnet->unlock(); + + return rc; + } + /** * Updates the template of a VN, adding a new attribute (replacing it if * already defined), the VN's mutex SHOULD be locked @@ -114,16 +147,34 @@ public: */ int dump(ostringstream& oss, const string& where); + /** + * Get the mac prefix + * @return the mac prefix + */ + static const unsigned int& mac_prefix() + { + return _mac_prefix; + }; + + /** + * Get the default network size + * @return the size + */ + static const unsigned int& default_size() + { + return _default_size; + }; + private: /** * Holds the system-wide MAC prefix */ - unsigned int mac_prefix; + static unsigned int _mac_prefix; /** * Default size for Virtual Networks */ - unsigned int default_size; + static unsigned int _default_size; /** * Factory method to produce VN objects @@ -131,7 +182,7 @@ private: */ PoolObjectSQL * create() { - return new VirtualNetwork(mac_prefix, default_size); + return new VirtualNetwork(); }; /** @@ -155,4 +206,4 @@ private: int get_cb(void * _oss, int num, char **values, char **names); }; -#endif /*VIRTUAL_NETWORK_POOL_H_*/ \ No newline at end of file +#endif /*VIRTUAL_NETWORK_POOL_H_*/ diff --git a/include/test/PoolTest.h b/include/test/PoolTest.h index 40010e9dc8..25a87bbe18 100644 --- a/include/test/PoolTest.h +++ b/include/test/PoolTest.h @@ -96,7 +96,7 @@ public: { if (mysql) { - db = new MySqlDB("localhost","oneadmin","onepass",NULL); + db = new MySqlDB("localhost","oneadmin","oneadmin",NULL); ostringstream oss1; oss1 << "DROP DATABASE IF EXISTS " << db_name; @@ -135,9 +135,9 @@ public: { unlink(db_name.c_str()); } - + if ( pool != 0 ) - { + { delete pool; } diff --git a/install.sh b/install.sh index 4b1ad07b31..2e42c13b10 100755 --- a/install.sh +++ b/install.sh @@ -255,6 +255,7 @@ BIN_FILES="src/nebula/oned \ src/cli/onehost \ src/cli/onevnet \ src/cli/oneuser \ + src/cli/oneimage \ share/scripts/one" #------------------------------------------------------------------------------- @@ -291,6 +292,8 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/OpenNebula/Host.rb \ src/oca/ruby/OpenNebula/VirtualMachinePool.rb \ src/oca/ruby/OpenNebula/VirtualNetwork.rb \ src/oca/ruby/OpenNebula/VirtualNetworkPool.rb \ + src/oca/ruby/OpenNebula/Image.rb \ + src/oca/ruby/OpenNebula/ImagePool.rb \ src/oca/ruby/OpenNebula/XMLUtils.rb" #------------------------------------------------------------------------------- # Driver executable files, to be installed under $LIB_LOCATION/mads @@ -611,13 +614,6 @@ if [ "$UNINSTALL" = "no" ] ; then for d in $CHOWN_DIRS; do chown -R $ONEADMIN_USER:$ONEADMIN_GROUP $DESTDIR$d done - # Create library links - if [ "$CLIENT" = "no" ] ; then - ln -s $DESTDIR$LIB_LOCATION/liboneapi.so \ - $DESTDIR$LIB_LOCATION/liboneapi.so.1 - ln -s $DESTDIR$LIB_LOCATION/liboneapi.so.1 \ - $DESTDIR$LIB_LOCATION/liboneapi.so.1.4 - 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 43f81be607..c719da67cd 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -7,7 +7,8 @@ #------------------------------------------------------------------------------- # HOST_MONITORING_INTERVAL: Time in seconds between host monitorization # -# VM_POLLING_INTERVAL: Time in seconds between virtual machine monitorization +# VM_POLLING_INTERVAL: Time in seconds between virtual machine monitorization. +# (use 0 to disable VM monitoring). # # 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 @@ -22,12 +23,15 @@ # passwd : (mysql) the password for user # db_name : (mysql) the database name # +# VNC_BASE_PORT: VNC ports for VMs can be automatically set to VNC_BASE_PORT + +# VMID +# # DEBUG_LEVEL: 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG #******************************************************************************* -HOST_MONITORING_INTERVAL = 60 +HOST_MONITORING_INTERVAL = 600 -VM_POLLING_INTERVAL = 60 +VM_POLLING_INTERVAL = 600 #VM_DIR=/srv/cloud/one/var @@ -42,6 +46,8 @@ DB = [ backend = "sqlite" ] # passwd = "oneadmin", # db_name = "opennebula" ] +VNC_BASE_PORT = 5000 + DEBUG_LEVEL=3 #******************************************************************************* @@ -56,7 +62,29 @@ DEBUG_LEVEL=3 NETWORK_SIZE = 254 -MAC_PREFIX = "00:03" +MAC_PREFIX = "02:00" + +#******************************************************************************* +# Image Repository Configuration +#******************************************************************************* +# IMAGE_REPOSITORY_PATH: Define the path to the image repository, by default +# is set to $ONE_LOCATION/var +# +# DEFAULT_IMAGE_TYPE: This can take values +# OS Image file holding an operating system +# CDROM Image file holding a CDROM +# DATABLOCK Image file holding a datablock, +# always created as an empty block +# DEFAULT_DEVICE_PREFIX: This can be set to +# hd IDE prefix +# sd SCSI +# xvd XEN Virtual Disk +# vd KVM virtual disk +#******************************************************************************* + +#IMAGE_REPOSITORY_PATH = +DEFAULT_IMAGE_TYPE = "OS" +DEFAULT_DEVICE_PREFIX = "hd" #******************************************************************************* # Information Driver Configuration @@ -230,6 +258,28 @@ TM_MAD = [ HM_MAD = [ executable = "one_hm" ] + + +#-------------------------------- Image Hook ----------------------------------- +# This hook is used to handle image saving and overwriting when virtual machines +# reach the DONE state after being shutdown. +# +# Uncomment one of the following: +# +# Self-contained (substitute [ONE_LOCATION] with its proper path) +# VM_HOOK = [ +# name = "image", +# on = "SHUTDOWN", +# command = "[ONE_LOCATION]/share/hooks/image.rb", +# arguments = "$VMID" ] +# +# System-wide +# VM_HOOK = [ +# name = "image", +# on = "SHUTDOWN", +# command = "/usr/share/doc/opennebula/hooks/image.rb", +# arguments = "$VMID" ] +#------------------------------------------------------------------------------- #-------------------------------- Hook Examples -------------------------------- #VM_HOOK = [ diff --git a/share/examples/vm.schema b/share/examples/vm.schema index 94f85630b0..608c07ce03 100644 --- a/share/examples/vm.schema +++ b/share/examples/vm.schema @@ -88,11 +88,11 @@ RAW = [ # Optional, KVM, XEN #--------------------------------------- # Context for the VM -# values can be: +# values can use: # $ # $[] # $[, =] -# $. +# $NETWORK[, NAME=] #--------------------------------------- CONTEXT = [ # Optional, KVM, XEN @@ -102,7 +102,11 @@ CONTEXT = [ # Optional, KVM, XEN target= "device to attach the context device" ] #--------------------------------------- -# Scheduler +# Scheduler +# Requirements expressions can use: +# $ +# $[] +# $[, =] #--------------------------------------- REQUIREMENTS = "Bool_expression_for_reqs" #Optional diff --git a/share/hooks/image.rb b/share/hooks/image.rb new file mode 100755 index 0000000000..18be081571 --- /dev/null +++ b/share/hooks/image.rb @@ -0,0 +1,82 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- # +# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +ONE_LOCATION=ENV["ONE_LOCATION"] + +if !ONE_LOCATION + RUBY_LIB_LOCATION="/usr/lib/one/ruby" + VMDIR="/var/lib/one" +else + RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" + VMDIR=ONE_LOCATION+"/var" +end + +$: << RUBY_LIB_LOCATION + +require 'OpenNebula' +require 'client_utilities' +require 'ftools' + +TYPES=%w{OS CDROM DATABLOCK} + +if !(vm_id=ARGV[0]) + exit -1 +end + +vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client) +vm.info +template=vm.to_hash +template=template['VM']['TEMPLATE'] +disks=[template['DISK']].flatten if template['DISK'] +disks.each_with_index do |disk,i| + source_path=VMDIR+"/#{vm_id}/disk.#{i}" + if disk["NAME"] and File.exists?(source_path) + if disk["SAVE_AS"] + # Get Type + image=OpenNebula::Image.new_with_id(disk['IID'], get_one_client) + image.info + type=image['TYPE'] + # Perform the allocate if all goes well + image=OpenNebula::Image.new( + OpenNebula::Image.build_xml, get_one_client) + + template="NAME=#{disk['SAVE_AS']}\n" + template+="TYPE=#{TYPES[type.to_i]}\n" if type + result=image.allocate(template) + + # Get the allocated image + image=OpenNebula::Image.new_with_id(image.id, get_one_client) + image.info + template=image.to_hash + template=template['IMAGE']['TEMPLATE'] + + if !is_successful?(result) + exit -1 + end + elsif disk["OVERWRITE"] + # Get the allocated image + image=OpenNebula::Image.new_with_id(disk['IID'], get_one_client) + image.info + image.disable + end + # Perform the copy to the image repo if needed + if File.copy(source_path, image['SOURCE']) + result=image.enable + end + end +end \ No newline at end of file diff --git a/share/scripts/one b/share/scripts/one index 5feff915b9..5514bd29dd 100755 --- a/share/scripts/one +++ b/share/scripts/one @@ -114,7 +114,17 @@ start() fi # Start the scheduler - $ONE_SCHEDULER -p $PORT & + # The following command line arguments are supported by mm_shed: + # [-p port] to connect to oned - default: 2633 + # [-t timer] seconds between two scheduling actions - default: 30 + # [-m machines limit] max number of VMs managed in each scheduling action + # - default: 300 + # [-d dispatch limit] max number of VMs dispatched in each scheduling action + # - default: 30 + # [-h host dispatch] max number of VMs dispatched to a given host in each + # scheduling action - default: 1 + + $ONE_SCHEDULER -p $PORT -t 30 -m 300 -d 30 -h 1& LASTRC=$? LASTPID=$! diff --git a/src/cli/client_utilities.rb b/src/cli/client_utilities.rb index c73d506abc..b1e4a5e257 100644 --- a/src/cli/client_utilities.rb +++ b/src/cli/client_utilities.rb @@ -285,6 +285,10 @@ def get_user_id(name) get_entity_id(name, OpenNebula::UserPool) end +def get_image_id(name) + get_entity_id(name, OpenNebula::ImagePool) +end + def str_running_time(data) stime=Time.at(data["stime"].to_i) if data["etime"]=="0" @@ -297,6 +301,11 @@ def str_running_time(data) "%02d %02d:%02d:%02d" % [dtime.yday-1, dtime.hour, dtime.min, dtime.sec] end +def str_register_time(data) + regtime=Time.at(data["REGTIME"].to_i).getgm + regtime.strftime("%b %d, %Y %H:%M") +end + REG_RANGE=/(.*)\[(\d+)([+-])(\d+)\](.*)/ diff --git a/src/cli/onehost b/src/cli/onehost index d6a9cf6d05..7ad6da8cf6 100755 --- a/src/cli/onehost +++ b/src/cli/onehost @@ -73,7 +73,7 @@ ShowTableHost={ :proc => lambda {|d,e| max_cpu=d["HOST_SHARE/MAX_CPU"].to_i max_cpu=100 if max_cpu==0 - max_cpu-d["HOST_SHARE/USED_CPU"].to_i + max_cpu-d["HOST_SHARE/CPU_USAGE"].to_i } }, :tmem => { @@ -278,7 +278,7 @@ when "show" puts host.template_str else - puts host.to_xml + puts host.to_xml(true) end when "delete" @@ -298,13 +298,7 @@ when "delete" end if host['host_share/running_vms'].to_i != 0 - puts "Host still has associated VMs. It will be disabled instead." - result=host.disable - if is_successful?(result) - puts "Host disabled" if ops[:verbose] - else - break - end + puts "Host still has associated VMs, aborting delete." else result=host.delete if is_successful?(result) @@ -322,7 +316,7 @@ when "list" else hostpool=OpenNebula::HostPool.new(get_one_client) hostpool.info - puts hostpool.to_xml + puts hostpool.to_xml(true) end when "top" diff --git a/src/cli/oneimage b/src/cli/oneimage new file mode 100755 index 0000000000..546540bf9c --- /dev/null +++ b/src/cli/oneimage @@ -0,0 +1,562 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- # +# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +ONE_LOCATION=ENV["ONE_LOCATION"] + +if !ONE_LOCATION + RUBY_LIB_LOCATION="/usr/lib/one/ruby" +else + RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" +end + +$: << RUBY_LIB_LOCATION + + +require 'OpenNebula' +require 'CommandManager' +require 'client_utilities' +require 'command_parse' +require 'ftools' + +ShowTableImage={ + :id => { + :name => "ID", + :desc => "ONE identifier for the Image", + :size => 4, + :proc => lambda {|d,e| d.id } + }, + :user=> { + :name => "USER", + :desc => "Name of the owner", + :size => 8, + :proc => lambda {|d,e| + d["USERNAME"] + } + }, + :name => { + :name => "NAME", + :desc => "Name of the Image", + :size => 20, + :proc => lambda {|d,e| + d.name + } + }, + :type => { + :name => "TYPE", + :desc => "Type of the Image", + :size => 4, + :proc => lambda {|d,e| + d.short_type_str + } + }, + :regtime => { + :name => "REGTIME", + :desc => "Registration time of the Image", + :size => 20, + :proc => lambda {|d,e| + str_register_time(d) + } + }, + :public => { + :name => "PUBLIC", + :desc => "Whether the Image is public or not", + :size => 3, + :proc => lambda {|d,e| + if d["PUBLIC"].to_i == 1 then "Yes" else "No" end} + }, + :state => { + :name => "STAT", + :desc => "State of the Image", + :size => 4, + :proc => lambda {|d,e| + d.short_state_str + } + }, + :runningvms => { + :name => "#VMS", + :desc => "Number of VMs currently running from this Image", + :size => 5, + :proc => lambda {|d,e| d['RUNNING_VMS'] } + }, + + :default => [:id, :user, :name, :type, :regtime, + :public, :state, :runningvms] +} + + + +class ImageShow + + def initialize(client, filter_flag="-2") + @imagepool=OpenNebula::ImagePool.new(client, filter_flag.to_i) + @table=ShowTable.new(ShowTableImage) + end + + def header_image_small + scr_bold + scr_underline + print @table.header_str + scr_restore + puts "" + end + + def top(options=nil) + delay=1 + delay=options[:delay] if options && options[:delay] + + result=nil + + begin + while true + scr_cls + scr_move(0,0) + result=list_short(options) + sleep delay + end + rescue Exception + end + result + end + + def list_short(options=nil) + res=@imagepool.info() + + if options + @table.columns=options[:columns] if options[:columns] + end + + if OpenNebula.is_error?(res) + result=res + puts res.message + exit -1 + else + + if options[:filter_flag] + vms=@imagepool.select{|element| + element['USERNAME']==options[:filter_flag] } + else + vms=@imagepool + end + + result=[true, ""] + header_image_small + + if options + puts @table.data_str(vms, options) + else + puts @table.data_str(vms) + end + + result + end + end + + def top(options=nil) + delay=1 + delay=options[:delay] if options && options[:delay] + + result=nil + + begin + while true + scr_cls + scr_move(0,0) + result=list_short(options) + sleep delay + end + rescue Exception + end + result + end +end + + +########################## +## COMMAND LINE PARSING ## +########################## + +class OneImageParse < CommandParse + + COMMANDS_HELP=<<-EOT +Commands: + +* register (Registers an image, copying it to the repository if it applies) + oneimage register