1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-25 02:50:08 +03:00

Merge branch 'master' into feature-203

This commit is contained in:
Ruben S. Montero 2010-07-08 01:42:49 +02:00
commit 11b39a6a34
146 changed files with 10289 additions and 2279 deletions

View File

@ -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',

View File

@ -17,6 +17,8 @@
#ifndef CALLBACKABLE_H_
#define CALLBACKABLE_H_
#include <pthread.h>
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_*/

View File

@ -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<int, string> * discovered_hosts);
int discover(map<int, string> * discovered_hosts, int host_limit);
/**
* Allocates a given capacity to the host

453
include/Image.h Normal file
View File

@ -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<const Attribute*>& 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<const Attribute*>& 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_*/

269
include/ImagePool.h Normal file
View File

@ -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 <time.h>
#include <sstream>
#include <iostream>
#include <vector>
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<Image *>(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<string, int>::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<string, int> 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_*/

48
include/ImageTemplate.h Normal file
View File

@ -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_*/

View File

@ -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

View File

@ -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<int,PoolObjectSQL *> pool;
map<int,PoolObjectSQL *> 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<int> oid_queue;
queue<int> 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)

View File

@ -22,6 +22,7 @@
#include "HostPool.h"
#include "UserPool.h"
#include "VirtualNetworkPool.h"
#include "ImagePool.h"
#include <xmlrpc-c/base.hpp>
#include <xmlrpc-c/registry.hpp>
@ -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;
};
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -117,6 +117,14 @@ public:
const string& name,
vector<Attribute *>& 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.

View File

@ -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_*/
#endif /*TEMPLATE_SQL_H_*/

View File

@ -21,6 +21,7 @@
#include "PoolSQL.h"
#include "History.h"
#include "Log.h"
#include "NebulaLog.h"
#include <time.h>
#include <sstream>
@ -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;
}
/**

View File

@ -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<int>& oids);
vector<int>& 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

View File

@ -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;

View File

@ -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_*/
#endif /*VIRTUAL_NETWORK_POOL_H_*/

View File

@ -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;
}

View File

@ -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

View File

@ -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 = [

View File

@ -88,11 +88,11 @@ RAW = [ # Optional, KVM, XEN
#---------------------------------------
# Context for the VM
# values can be:
# values can use:
# $<template_variable>
# $<template_variable>[<attribute>]
# $<template_variable>[<attribute>, <attribute2>=<value2>]
# $<vm_id>.<context_var>
# $NETWORK[<vnet_attribute>, NAME=<vnet_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:
# $<template_variable>
# $<template_variable>[<attribute>]
# $<template_variable>[<attribute>, <attribute2>=<value2>]
#---------------------------------------
REQUIREMENTS = "Bool_expression_for_reqs" #Optional

82
share/hooks/image.rb Executable file
View File

@ -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

View File

@ -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=$!

View File

@ -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+)\](.*)/

View File

@ -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"

562
src/cli/oneimage Executable file
View File

@ -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 <template>
template is a file name where the Image description is located
* update (Modifies an image attribute)
oneimage update <image_id> <attribute_name> <attribute_value>
* rmattr (Deletes an Image attribute)
oneimage rmattr <image_id> <attribute_name>
* enable (Enabled an Image)
oneimage enable <image_id>
* disable (Disabled an Image)
oneimage disable <image_id>
* publish (Publish an Image)
oneimage publish <image_id>
* unpublish (Unpublish an Image)
oneimage unpublish <image_id>
* list (Shows Images in the pool)
oneimage list <filter_flag>
where filter_flag can be
a, all --> all the known Images (admin users)
m, mine --> the Images belonging to the user in ONE_AUTH
and all the Public Images
uid --> Images of the user identified by this uid (admin users)
user --> Images of the user identified by the username (admin users)
* top (Lists Images continuously)
onevm top
* show (Gets information about an specific Image)
oneimage show <image_id>
* delete (Deletes an already deployed Image)
oneimage delete <image_id>
EOT
def text_commands
COMMANDS_HELP
end
def text_command_name
"oneimage"
end
def list_options
table=ShowTable.new(ShowTableImage)
table.print_help
end
end
def get_user_flags
ops=Hash.new
if ARGV[0]
case ARGV[0]
when "a", "all"
ops[:filter_user]="-2"
when "m", "mine"
ops[:filter_user]="-1"
else
if !ARGV[0].match(/^[0123456789]+$/)
ops[:filter_user]="-2"
ops[:filter_flag]=ARGV[0]
else
ops[:filter_user]=ARGV[0]
end
end
else
ops[:filter_user]="-2"
end
ops
end
def get_type_and_path(image_template_file)
image_text = open(image_template_file).read
result=Hash.new
image_text.each_line {|line|
case line
when /^\s*(#.*)?$/
# skip empty or commented lines
next
when /^\s*(\w+)\s*=\s*(.*)\s*$/
name = $1.strip.upcase
if name == "PATH" || name == "TYPE" ||
name == "SIZE" || name == "FSTYPE"
result[name] = $2.strip
end
end
}
result
end
oneimage_opts=OneImageParse.new
oneimage_opts.parse(ARGV)
ops=oneimage_opts.options
result=[false, "Unknown error"]
command=ARGV.shift
case command
when "register", "create", "add"
check_parameters("register", 1)
# First, let's check we have everything we need in the template
# Get the path and type from the template file
parser_result = get_type_and_path(ARGV[0])
if parser_result['TYPE']
type = parser_result['TYPE'].upcase
else
type = "OS"
end
result = true
case type
when "OS", "CDROM"
if !parser_result['PATH']
result=OpenNebula::Error.new(
"Image path not present, aborting.")
elsif !File.exists?(parser_result['PATH'])
result=OpenNebula::Error.new(
"Image file could not be found, aborting.")
end
when "DATABLOCK"
if parser_result['PATH'] and !File.exists?(parser_result['PATH'])
if !parser_result['SIZE'] || !parser_result['FSTYPE']
result=OpenNebula::Error.new(
"No image file present for DATABLOCK, " +
"size and/or fstype also missing, aborting.")
end
end
end
if !is_successful?(result)
puts result.message
exit -1
end
# Perform the allocate if all goes well
image=OpenNebula::Image.new(
OpenNebula::Image.build_xml, get_one_client)
begin
template=File.read(ARGV[0])
result=image.allocate(template)
rescue
result=OpenNebula::Error.new("Can not read template: #{ARGV[0]}")
end
if !is_successful?(result)
exit -1
end
# 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']
# Perform the copy to the image repo if needed
if template['PATH']
if File.copy(template['PATH'], image['SOURCE'])
result = image.enable
else
result=OpenNebula::Error.new(
"Cannot copy image, aborting.")
image.delete
end
elsif parser_result['SIZE'] and parser_result['FSTYPE']
local_command=LocalCommand.run(
"dd if=/dev/zero of=#{image['SOURCE']} ibs=1 count=1 " \
"obs=1048576 oseek=#{parser_result['SIZE']}")
if local_command.code!=0
result=OpenNebula::Error.new(
"Cannot create datablock, aborting.")
image.delete
else
local_command=LocalCommand.run(
"mkfs -t #{parser_result['FSTYPE']} -F #{image['SOURCE']}")
if local_command.code!=0
result=OpenNebula::Error.new(
"Cannot format datablock, aborting.")
image.delete
else
image.enable
end
end
end
if is_successful?(result)
puts "ID: " + image.id.to_s if ops[:verbose]
exit 0
end
when "update"
check_parameters("update", 3)
image_id=get_image_id(ARGV[0])
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
result=image.update(ARGV[1],ARGV[2])
if is_successful?(result)
puts "Modified image" if ops[:verbose]
end
when "rmattr"
check_parameters("rmattr", 2)
image_id=get_image_id(ARGV[0])
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
result=image.remove_attr(ARGV[1])
if is_successful?(result)
puts "Removed image atrribute" if ops[:verbose]
end
when "enable"
check_parameters("enable", 1)
image_id=get_image_id(ARGV[0])
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
result=image.enable
if is_successful?(result)
puts "Image enabled" if ops[:verbose]
end
when "disable"
check_parameters("disable", 1)
image_id=get_image_id(ARGV[0])
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
result=image.disable
if is_successful?(result)
puts "Image disabled" if ops[:verbose]
end
when "publish"
check_parameters("publish", 1)
image_id=get_image_id(ARGV[0])
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
result=image.publish
if is_successful?(result)
puts "Image published" if ops[:verbose]
end
when "unpublish"
check_parameters("unpublish", 1)
image_id=get_image_id(ARGV[0])
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
result=image.unpublish
if is_successful?(result)
puts "Image unpublished" if ops[:verbose]
end
when "list"
ops.merge!(get_user_flags)
if !ops[:xml]
imagelist=ImageShow.new(get_one_client, ops[:filter_user].to_i)
ops[:columns]=ops[:list] if ops[:list]
result=imagelist.list_short(ops)
else
imagepool=OpenNebula::ImagePool.new(get_one_client,
ops[:filter_user].to_i)
imagepool.info
puts imagepool.to_xml
end
when "top"
ops.merge!(get_user_flags)
imagelist=ImageShow.new(get_one_client, ops[:filter_user].to_i)
ops[:columns]=ops[:list] if ops[:list]
result=imagelist.top(ops)
when "show"
check_parameters("get_info", 1)
args=expand_args(ARGV)
args.each do |param|
image_id=get_image_id(param)
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
image.info
if !ops[:xml]
str="%-15s: %-20s"
str_h1="%-80s"
print_header(str_h1, "IMAGE #{image[:id]} INFORMATION", true)
puts str % ["ID", image[:id]]
puts str % ["NAME", image[:name]]
puts str % ["TYPE", image.type_str]
value=image[:regtime].to_i
if value==0
value='-'
else
value=Time.at(value).strftime("%m/%d %H:%M:%S")
end
puts str % ["REGISTER TIME", value]
if image[:public].to_i == 1
public_str = "Yes"
else
public_str = "No"
end
puts str % ["PUBLIC", public_str]
puts str % ["SOURCE", image[:source]]
puts str % ["STATE", image.short_state_str]
puts str % ["RUNNING_VMS", image[:runningvms]]
puts
print_header(str_h1,"IMAGE TEMPLATE",false)
puts image.template_str
else
puts image.to_xml
end
end
when "delete"
check_parameters("delete", 1)
args=expand_args(ARGV)
args.each do |param|
image_id=get_image_id(param)
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
result=image.delete
if is_successful?(result)
puts "Image correctly deleted" if ops[:verbose]
else
break
end
end
else
oneimage_opts.print_help
exit -1
end
if OpenNebula.is_error?(result)
puts "Error: " + result.message
exit -1
end

View File

@ -174,16 +174,28 @@ when "delete"
# Check if the user has defined VM's
vms=false
vmpool=OpenNebula::VirtualMachinePool.new(
get_one_client, user_id)
get_one_client, user_id.to_i)
vmpool.info
vmpool.each{ vms=true ; break }
if vms
puts "The user #{param} still has VM's defined, "+
"type YES if you are sure you"
print "want to delete this user: "
answer=STDIN.gets.strip
exit -1 if answer != 'YES'
puts "The user #{param} still has VMs defined, "+
"aborting user delete."
exit -1
end
# Check if the user has defined VN's
vns=false
vnpool=OpenNebula::VirtualNetworkPool.new(
get_one_client, user_id.to_i)
vnpool.info
vnpool.each{ vns=true ; break }
if vns
puts "The user #{param} still has Virtual Networks defined, "+
"aborting user delete."
exit -1
end
user=OpenNebula::User.new(
@ -202,7 +214,7 @@ when "list"
else
userpool=OpenNebula::UserPool.new(get_one_client)
userpool.info
puts userpool.to_xml
puts userpool.to_xml(true)
end
else

View File

@ -1,4 +1,4 @@
#!/usr/bin/env ruby
#!/usr/bin/env ruby
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
@ -36,14 +36,14 @@ ShowTableVM={
:id => {
:name => "ID",
:desc => "ONE identifier for the VM",
:size => 4,
:size => 5,
:proc => lambda {|d,e| d.id }
},
:name => {
:name => "NAME",
:desc => "Name of the domain",
:size => 8,
:proc => lambda {|d,e|
:proc => lambda {|d,e|
d.name
}
},
@ -51,7 +51,7 @@ ShowTableVM={
:name => "USER",
:desc => "Name of the owner",
:size => 8,
:proc => lambda {|d,e|
:proc => lambda {|d,e|
d["USERNAME"]
}
},
@ -59,7 +59,7 @@ ShowTableVM={
:name => "STAT",
:desc => "Actual status of the VM",
:size => 4,
:proc => lambda {|d,e|
:proc => lambda {|d,e|
d.status
}
},
@ -67,7 +67,7 @@ ShowTableVM={
:name => "CPU",
:desc => "CPU percentage used by the VM",
:size => 3,
:proc => lambda {|d,e|
:proc => lambda {|d,e|
d["cpu"]
}
},
@ -91,7 +91,7 @@ ShowTableVM={
:size => 11,
:proc => lambda {|d,e| str_running_time(d) }
},
:default => [:id, :user, :name, :stat, :cpu, :mem, :hostname, :time]
}
@ -152,18 +152,18 @@ ShowTableHistory={
OpenNebula::VirtualMachine.get_reason(d["reason"])
}
},
:default => [:id, :seq, :hostname, :stime, :etime, :time, :reason]
}
class VmShow
def initialize(client, filter_flag="-2")
@vmpool=OpenNebula::VirtualMachinePool.new(client, filter_flag.to_i)
@table=ShowTable.new(ShowTableVM)
@table_history=ShowTable.new(ShowTableHistory)
end
def header_vm_small
scr_bold
scr_underline
@ -179,7 +179,7 @@ class VmShow
scr_restore
puts ""
end
def list_short(options=nil)
res=@vmpool.info()
@ -208,17 +208,17 @@ class VmShow
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
@ -256,7 +256,7 @@ class VmShow
get_vm_history(vm)
end
end
def list_vm_history(vm, options=nil)
#res=@vm.get_history(id)
if options
@ -264,14 +264,14 @@ class VmShow
end
header_history_small
if options
puts @table_history.data_str([vm], options)
else
puts @table_history.data_str([vm])
end
end
def list_vm_history_array(ids, options=nil)
get_vms_history(ids).each {|vm|
puts "History for VM #{vm['id']}"
@ -280,7 +280,7 @@ class VmShow
puts
}
end
def list_vm_history_all(options=nil)
result=@vmpool.info
@ -310,18 +310,18 @@ Commands:
* create (Submits a new virtual machine, adding it to the ONE VM pool)
onevm create <template>
template is a file name where the VM description is located
* deploy (Start a previously submitted VM in an specific host)
onevm deploy <vm_id> <host_id>
* shutdown (Shutdown an already deployed VM)
onevm shutdown <vm_id>
* livemigrate (Migrates a running VM to another host without downtime)
onevm livemigrate <vm_id> <host_id>
* migrate (Saves a running VM and starts it again in the specified host)
onevm migrate <vm_id> <host_id>
@ -333,22 +333,22 @@ Commands:
* stop (Stops a running VM)
onevm stop <vm_id>
* cancel (Cancels a running VM)
onevm cancel <vm_id>
* suspend (Saves a running VM)
onevm suspend <vm_id>
* resume (Resumes the execution of a saved VM)
onevm resume <vm_id>
* delete (Deletes a VM from the pool and DB)
onevm delete <vm_id>
* restart (Resubmits the VM after failure)
onevm restart <vm_id>
* list (Shows VMs in the pool)
onevm list <filter_flag>
where filter_flag can be
@ -356,7 +356,7 @@ Commands:
m, mine --> the VMs belonging to the user in ONE_AUTH
uid --> VMs of the user identified by this uid
user--> VMs of the user identified by the username
* show (Gets information about a specific VM)
onevm show <vm_id>
@ -365,9 +365,9 @@ Commands:
* history (Gets history from VMs)
onevm history [<vm_id> <vm_id> ...]
if no vm_id is provided it will list history for all known VMs
EOT
def text_commands
@ -377,12 +377,12 @@ EOT
def text_command_name
"onevm"
end
def list_options
table=ShowTable.new(ShowTableVM)
table.print_help
end
end
@ -432,17 +432,17 @@ when "submit", "create"
puts "ID: " + vm.id.to_s if ops[:verbose]
exit 0
end
when "deploy"
check_parameters("deploy", 2)
host_id=get_host_id(ARGV[-1])
args=expand_args(ARGV[0..-2])
args.each do |param|
vm_id=get_vm_id(param)
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.deploy(host_id)
if is_successful?(result)
puts "Deploying VM" if ops[:verbose]
@ -454,7 +454,7 @@ when "deploy"
when "shutdown"
check_parameters("shutdown", 1)
args=expand_args(ARGV)
args.each do |param|
vm_id=get_vm_id(param)
@ -471,12 +471,12 @@ when "livemigrate"
check_parameters("livemigrate", 2)
host_id=get_host_id(ARGV[-1])
args=expand_args(ARGV[0..-2])
args.each do |param|
vm_id=get_vm_id(param)
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.live_migrate(host_id)
if is_successful?(result)
puts "Migrating VM" if ops[:verbose]
@ -489,12 +489,12 @@ when "migrate"
check_parameters("migrate", 2)
host_id=get_host_id(ARGV[-1])
args=expand_args(ARGV[0..-2])
args.each do |param|
vm_id=get_vm_id(param)
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.migrate(host_id)
if is_successful?(result)
puts "Migrating VM" if ops[:verbose]
@ -506,12 +506,12 @@ when "migrate"
when "hold"
check_parameters("hold", 1)
args=expand_args(ARGV)
args.each do |param|
vm_id=get_vm_id(param)
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.hold
if is_successful?(result)
puts "Setting VM to hold state" if ops[:verbose]
@ -523,12 +523,12 @@ when "hold"
when "release"
check_parameters("release", 1)
args=expand_args(ARGV)
args.each do |param|
vm_id=get_vm_id(param)
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.release
if is_successful?(result)
puts "Releasing VM" if ops[:verbose]
@ -536,16 +536,16 @@ when "release"
break
end
end
when "stop"
check_parameters("stop", 1)
args=expand_args(ARGV)
args.each do |param|
vm_id=get_vm_id(param)
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.stop
if is_successful?(result)
puts "Stopping VM" if ops[:verbose]
@ -553,11 +553,11 @@ when "stop"
break
end
end
when "cancel"
check_parameters("cancel", 1)
args=expand_args(ARGV)
args.each do |param|
vm_id=get_vm_id(param)
@ -574,12 +574,12 @@ when "cancel"
when "suspend"
check_parameters("suspend", 1)
args=expand_args(ARGV)
args.each do |param|
vm_id=get_vm_id(param)
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.suspend
if is_successful?(result)
puts "Suspending VM" if ops[:verbose]
@ -587,16 +587,16 @@ when "suspend"
break
end
end
when "resume"
check_parameters("resume", 1)
args=expand_args(ARGV)
args.each do |param|
vm_id=get_vm_id(param)
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.resume
if is_successful?(result)
puts "Resuming VM" if ops[:verbose]
@ -604,16 +604,16 @@ when "resume"
break
end
end
when "restart"
check_parameters("restart", 1)
args=expand_args(ARGV)
args.each do |param|
vm_id=get_vm_id(param)
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.restart
if is_successful?(result)
puts "Restarting VM" if ops[:verbose]
@ -621,28 +621,28 @@ when "restart"
break
end
end
when "list"
ops.merge!(get_user_flags)
if !ops[:xml]
vmlist=VmShow.new(get_one_client, ops[:filter_user].to_i)
ops[:columns]=ops[:list] if ops[:list]
result=vmlist.list_short(ops)
result=vmlist.list_short(ops)
else
vmpool=OpenNebula::VirtualMachinePool.new(get_one_client,
ops[:filter_user].to_i)
vmpool.info
puts vmpool.to_xml
puts vmpool.to_xml(true)
end
when "top"
ops.merge!(get_user_flags)
vmlist=VmShow.new(get_one_client, ops[:filter_user].to_i)
ops[:columns]=ops[:list] if ops[:list]
result=vmlist.top(ops)
when "history"
vmlist=VmShow.new(get_one_client)
ops[:columns]=ops[:list] if ops[:list]
@ -653,16 +653,16 @@ when "history"
else
result=vmlist.list_vm_history_all(ops)
end
when "delete"
check_parameters("delete", 1)
args=expand_args(ARGV)
args.each do |param|
vm_id=get_vm_id(param)
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.finalize
if is_successful?(result)
puts "VM correctly deleted" if ops[:verbose]
@ -674,9 +674,9 @@ when "delete"
when "show"
check_parameters("get_info", 1)
args=expand_args(ARGV)
args.each do |param|
vm_id=get_vm_id(param)
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
@ -692,7 +692,7 @@ when "show"
puts str % ["NAME", vm[:name]]
puts str % ["STATE", vm.state_str]
puts str % ["LCM_STATE", vm.lcm_state_str]
value=vm[:stime].to_i
if value==0
value='-'
@ -708,17 +708,17 @@ when "show"
value=Time.at(value).strftime("%m/%d %H:%M:%S")
end
puts str % ["END TIME", value]
value=vm[:deploy_id]
puts str % ["DEPLOY ID:", value=="" ? "-" : value]
puts
print_header(str_h1,"VIRTUAL MACHINE TEMPLATE",false)
puts vm.template_str
else
puts vm.to_xml
puts vm.to_xml(true)
end
end
else

View File

@ -79,6 +79,12 @@ ShowTableVN={
:size => 6,
:proc => lambda {|d,e| d["bridge"] }
},
:public => {
:name => "PUBLIC",
:desc => "Whether the Image is public or not",
:size => 1,
:proc => lambda {|d,e| if d["PUBLIC"].to_i == 1 then "Y" else "N" end}
},
:totalleases => {
:name => "#LEASES",
:desc => "Number of this virtual network's given leases",
@ -86,7 +92,7 @@ ShowTableVN={
:proc => lambda {|d,e| d["TOTAL_LEASES"] }
},
:default => [:id, :user, :name, :type, :bridge, :totalleases]
:default => [:id, :user, :name, :type, :bridge, :public, :totalleases]
}
class VNShow
@ -159,6 +165,12 @@ Commands:
* show (Gets info from a virtual network)
onevnet show <network_id>
* publish (Publish a virtual network)
onevnet publish <network_id>
* unpublish (Unpublish a virtual network)
onevnet unpublish <network_id>
* delete (Removes a virtual network)
onevnet delete <network_id>
@ -223,6 +235,12 @@ when "show"
puts str % ["ID: ",vn.id.to_s]
puts str % ["UID: ",vn["UID"]]
if vn[:public].to_i == 1
public_str = "Y"
else
public_str = "N"
end
puts str % ["PUBLIC", public_str]
puts
print_header(str_h1,"VIRTUAL NETWORK TEMPLATE",false)
@ -236,7 +254,7 @@ when "show"
puts leases_str
end
else
puts vn.to_xml
puts vn.to_xml(true)
end
else
puts "Error: "+result.message
@ -244,6 +262,28 @@ when "show"
end
end
when "publish"
check_parameters("publish", 1)
vn_id=get_vn_id(ARGV[0])
vn=OpenNebula::VirtualNetwork.new_with_id(vn_id, get_one_client)
result=vn.publish
if is_successful?(result)
puts "VirtualNetwork published" if ops[:verbose]
end
when "unpublish"
check_parameters("unpublish", 1)
vn_id=get_vn_id(ARGV[0])
vn=OpenNebula::VirtualNetwork.new_with_id(vn_id, get_one_client)
result=vn.unpublish
if is_successful?(result)
puts "VirtualNetwork unpublished" if ops[:verbose]
end
when "delete"
check_parameters("delete", 1)
args=expand_args(ARGV)
@ -286,7 +326,7 @@ when "list"
vnpool=OpenNebula::VirtualNetworkPool.new(get_one_client,
filter_flag.to_i)
vnpool.info
puts vnpool.to_xml
puts vnpool.to_xml(true)
end
else

View File

@ -33,7 +33,7 @@ rescue LoadError
end
###############################################################################
# The CloudClient module contains general functionality to implement a
# The CloudClient module contains general functionality to implement a
# Cloud Client
###############################################################################
module CloudClient
@ -41,7 +41,7 @@ module CloudClient
# Default location for the authentication file
# #########################################################################
DEFAULT_AUTH_FILE = ENV["HOME"]+"/.one/one_auth"
# #########################################################################
# Gets authorization credentials from ONE_AUTH or default
# auth file.
@ -49,7 +49,7 @@ module CloudClient
# Raises an error if authorization is not found
# #########################################################################
def self.get_one_auth
if ENV["ONE_AUTH"] and !ENV["ONE_AUTH"].empty? and
if ENV["ONE_AUTH"] and !ENV["ONE_AUTH"].empty? and
File.file?(ENV["ONE_AUTH"])
one_auth=File.read(ENV["ONE_AUTH"]).strip.split(':')
elsif File.file?(DEFAULT_AUTH_FILE)
@ -57,31 +57,46 @@ module CloudClient
else
raise "No authorization data present"
end
raise "Authorization data malformed" if one_auth.length < 2
one_auth
end
# #########################################################################
# Starts an http connection and calls the block provided. SSL flag
# is set if needed.
# #########################################################################
def self.http_start(url, &block)
def self.http_start(url, timeout, &block)
http = Net::HTTP.new(url.host, url.port)
if timeout
http.read_timeout = timeout.to_i
end
if url.scheme=='https'
http.use_ssl = true
http.verify_mode=OpenSSL::SSL::VERIFY_NONE
end
begin
http.start do |connection|
block.call(connection)
end
rescue Errno::ECONNREFUSED => e
str = "Error connecting to server (#{e.to_s})."
str = "Error connecting to server (#{e.to_s}).\n"
str << "Server: #{url.host}:#{url.port}"
return CloudClient::Error.new(str)
rescue Errno::ETIMEDOUT => e
str = "Error timeout connecting to server (#{e.to_s}).\n"
str << "Server: #{url.host}:#{url.port}"
return CloudClient::Error.new(str)
rescue Timeout::Error => e
str = "Error timeout while connected to server (#{e.to_s}).\n"
str << "Server: #{url.host}:#{url.port}"
return CloudClient::Error.new(str)
end
end
@ -92,7 +107,7 @@ module CloudClient
# #########################################################################
class Error
attr_reader :message
# +message+ a description of the error
def initialize(message=nil)
@message=message
@ -103,7 +118,7 @@ module CloudClient
end
end
# #########################################################################
# #########################################################################
# Returns true if the object returned by a method of the OpenNebula
# library is an Error
# #########################################################################
@ -111,7 +126,7 @@ module CloudClient
value.class==CloudClient::Error
end
end
# Command line help functions
module CloudCLI
# Returns the command name

View File

@ -44,7 +44,6 @@ class CloudServer
# --- Load the Cloud Server configuration file ---
@config = Configuration.new(config_file)
@auth = "#{@config[:user]}:#{@config[:password]}"
@instance_types = Hash.new
@ -63,7 +62,7 @@ class CloudServer
# --- Start an OpenNebula Session ---
@one_client = Client.new(@auth)
@one_client = Client.new()
@user_pool = UserPool.new(@one_client)
end

View File

@ -1,30 +1,4 @@
#!/usr/bin/env ruby
# == Synopsis
# econe-describe-images
#
# List and describe previously uploaded images of a user for use
# with an OpenNebula Cloud.
#
# == Usage
#
# econe-describe-images [OPTIONS]
#
# -h, --help:
# show help
#
# --access-key <id>, -K <id>:
# The username of the user
#
# --secret-key <key>, -K <key>:
# The password of the user
#
# --url <url>, -U <url>:
# Set url as the web service url to use
#
# --headers, -H:
# Display column headers
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
# #
@ -53,14 +27,42 @@ end
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+"/cloud"
COMMANDS_HELP=<<-EOT
** Synopsis
-----------
econe-describe-images
List and describe previously uploaded images of a user to be
used with an OpenNebula Cloud.
** Usage
--------
econe-describe-images [OPTIONS]
--help, -h:
Show help
--access-key <id>, -K <id>:
The username of the user
--secret-key <key>, -S <key>:
The password of the user
--url <url>, -U <url>:
Set url as the web service url to use
--headers, -H:
Display column headers
EOT
require 'econe/EC2QueryClient'
require 'CloudClient'
require 'getoptlong'
require 'rdoc/usage'
require 'pp'
include CloudCLI
opts = GetoptLong.new(
['--help', '-h',GetoptLong::NO_ARGUMENT],
['--access-key', '-K',GetoptLong::REQUIRED_ARGUMENT],
@ -79,7 +81,8 @@ begin
opts.each do |opt, arg|
case opt
when '--help'
RDoc::usage
puts COMMANDS_HELP
return
when '--access-key'
access = arg
when '--secret-key'

View File

@ -1,29 +1,4 @@
#!/usr/bin/env ruby
# == Synopsis
# econe-describe-instances
#
# List and describe running instances
#
# == Usage
#
# econe-describe-instances [OPTIONS]
#
# -h, --help:
# show help
#
# --access-key <id>, -K <id>:
# The username of the user
#
# --secret-key <key>, -S <key>:
# The password of the user
#
# --url <url>, -U <url>:
# Set url as the web service url to use
#
# --headers, -H:
# Display column headers
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
# #
@ -51,11 +26,37 @@ end
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+"/cloud"
COMMANDS_HELP=<<-EOT
** Synopsis
-----------
econe-describe-instances
List and describe running instances
** Usage
--------
econe-describe-instances [OPTIONS]
--help, -h:
Show help
--access-key <id>, -K <id>:
The username of the user
--secret-key <key>, -S <key>:
The password of the user
--url <url>, -U <url>:
Set url as the web service url to use
--headers, -H:
Display column headers
EOT
require 'econe/EC2QueryClient'
require 'CloudClient'
require 'getoptlong'
require 'rdoc/usage'
require 'pp'
include CloudCLI
@ -77,7 +78,8 @@ begin
opts.each do |opt, arg|
case opt
when '--help'
RDoc::usage
puts COMMANDS_HELP
return
when '--access-key'
access = arg
when '--secret-key'

View File

@ -1,35 +1,4 @@
#!/usr/bin/env ruby
# == Synopsis
# econe-register
#
# Register a previously uploaded image for use with an
# OpenNebula Cloud.
#
# == Usage
#
# econe-register [OPTIONS] ImageId
#
# -h, --help:
# show help
#
# --access-key <id>, -K <id>:
# The username of the user
#
# --secret-key <key>, -S <key>:
# The password of the user
#
# --url <url>, -U <url>:
# Set url as the web service url to use
#
# --headers, -H:
# Display column headers
#
# IMAGE-ID: The image identification as returned by
# the econe-upload command
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
# #
@ -57,11 +26,41 @@ end
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+"/cloud"
COMMANDS_HELP=<<-EOT
** Synopsis
-----------
econe-register
Register a previously uploaded image for use with an
OpenNebula Cloud.
** Usage
--------
econe-register [OPTIONS] IMAGE-ID
--help, -h:
Show help
--access-key <id>, -K <id>:
The username of the user
--secret-key <key>, -S <key>:
The password of the user
--url <url>, -U <url>:
Set url as the web service url to use
--headers, -H:
Display column headers
IMAGE-ID: The image identification as returned by
the econe-upload command
EOT
require 'econe/EC2QueryClient'
require 'CloudClient'
require 'getoptlong'
require 'rdoc/usage'
require 'pp'
include CloudCLI
@ -83,7 +82,8 @@ begin
opts.each do |opt, arg|
case opt
when '--help'
RDoc::usage
puts COMMANDS_HELP
return
when '--access-key'
access = arg
when '--secret-key'

View File

@ -1,31 +1,4 @@
#!/usr/bin/env ruby
# == Synopsis
# econe-run-instances
#
# Runs an instance of a particular image
#
# == Usage
#
# econe-run-instances [OPTIONS]
#
# -h, --help:
# show help
#
# --access-key <id>, -K <id>:
# The username of the user
#
# --secret-key <key>, -S <key>:
# The password of the user
#
# --url <url>, -U <url>:
# Set url as the web service url to use
#
# --type <type>, -t <type>
#
# --headers, -H:
# Display column headers
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
# #
@ -54,11 +27,47 @@ end
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+"/cloud"
COMMANDS_HELP=<<-EOT
** Synopsis
-----------
econe-run-instances
Runs an instance of a particular image
** Usage
--------
econe-run-instances [OPTIONS] IMAGE-ID
--help, -h:
Show help
--access-key <id>, -K <id>:
The username of the user
--secret-key <key>, -S <key>:
The password of the user
--url <url>, -U <url>:
Set url as the web service url to use
--type <type>, -t <type>:
OpenNebula template in which is based this instance
-user-data, -d:
Specifies Base64-encoded MIME user data to be made
available to the instance
--headers, -H:
Display column headers
IMAGE-ID: The image identification as returned by
the econe-upload command
EOT
require 'econe/EC2QueryClient'
require 'CloudClient'
require 'getoptlong'
require 'rdoc/usage'
require 'pp'
include CloudCLI
@ -68,6 +77,7 @@ opts = GetoptLong.new(
['--secret-key', '-S',GetoptLong::REQUIRED_ARGUMENT],
['--url', '-U',GetoptLong::REQUIRED_ARGUMENT],
['--type', '-t',GetoptLong::REQUIRED_ARGUMENT],
['--user-data', '-d',GetoptLong::REQUIRED_ARGUMENT],
['--headers', '-H',GetoptLong::NO_ARGUMENT]
)
@ -77,12 +87,14 @@ access = nil
secret = nil
auth = nil
type = nil
user_data = nil
begin
opts.each do |opt, arg|
case opt
when '--help'
RDoc::usage
puts COMMANDS_HELP
return
when '--access-key'
access = arg
when '--secret-key'
@ -93,6 +105,8 @@ begin
type = arg
when '--headers'
headers = true
when '--user-data'
user_data = arg
end
end
rescue Exception => e
@ -119,7 +133,7 @@ rescue Exception => e
exit -1
end
rc = ec2_client.run_instances(image_id,type)
rc = ec2_client.run_instances(image_id,type, user_data)
if CloudClient::is_error?(rc)
puts "#{cmd_name}: #{rc.message}"

View File

@ -1,31 +1,4 @@
#!/usr/bin/env ruby
# == Synopsis
# econe-terminate-instances
#
# Terminate the selected running instance
#
# == Usage
#
# econe-register [OPTIONS] INSTANCE-ID
#
# -h, --help:
# show help
#
# --access-key <id>, -K <id>:
# The username of the user
#
# --secret-key <key>, -K <key>:
# The password of the user
#
# --url <url>, -U <url>:
# Set url as the web service url to use
#
# INSTANCE-ID: The instance identification as returned by
# the econe-run-instances command
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
# #
@ -54,11 +27,37 @@ end
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+"/cloud"
COMMANDS_HELP=<<-EOT
** Synopsis
-----------
econe-terminate-instances
Terminate the selected running instance
** Usage
--------
econe-register [OPTIONS] INSTANCE-ID
--help, -h:
Show help
--access-key <id>, -K <id>:
The username of the user
--secret-key <key>, -S <key>:
The password of the user
--url <url>, -U <url>:
Set url as the web service url to use
INSTANCE-ID: The instance identification as returned by
the econe-run-instances command
EOT
require 'econe/EC2QueryClient'
require 'CloudClient'
require 'getoptlong'
require 'rdoc/usage'
require 'pp'
include CloudCLI
@ -78,7 +77,8 @@ begin
opts.each do |opt, arg|
case opt
when '--help'
RDoc::usage
puts COMMANDS_HELP
return
when '--access-key'
access = arg
when '--secret-key'

View File

@ -1,32 +1,4 @@
#!/usr/bin/env ruby
# == Synopsis
# econe-upload
#
# Uploads an image for use with an OpenNebula Cloud. This image should
# be later register with econe-register using the returned ImageId
#
# == Usage
#
# econe-upload [OPTIONS] IMAGE-PATH
#
# -h, --help:
# show help
#
# --access-key <id>, -K <id>:
# The username of the user
#
# --secret-key <key>, -K <key>:
# The password of the user
#
# --url <url>, -U <url>:
# Set url as the web service url to use
#
# --multipart, -M:
# Use 'multipart-post' library instead of Curb/Curl
#
# IMAGE-PATH: Path to the image to upload
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
# #
@ -54,11 +26,40 @@ end
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+"/cloud"
COMMANDS_HELP=<<-EOT
** Synopsis
-----------
econe-upload
Uploads an image for use with an OpenNebula Cloud. This image should
be later register with econe-register using the returned ImageId
** Usage
--------
econe-upload [OPTIONS] IMAGE-PATH
--help, -h:
Show help
--access-key <id>, -K <id>:
The username of the user
--secret-key <key>, -S <key>:
The password of the user
--url <url>, -U <url>:
Set url as the web service url to use
--multipart, -M:
Use 'multipart-post' library instead of Curb/Curl
IMAGE-PATH: Path to the image to upload
EOT
require 'econe/EC2QueryClient'
require 'CloudClient'
require 'getoptlong'
require 'rdoc/usage'
require 'pp'
include CloudCLI
@ -80,7 +81,8 @@ begin
opts.each do |opt, arg|
case opt
when '--help'
RDoc::usage
puts COMMANDS_HELP
return
when '--access-key'
access = arg
when '--secret-key'

View File

@ -1,23 +1,29 @@
NAME = eco-vm
#Adjust Capacity for this instance type
CPU = 0.2
MEMORY = 256
OS = [ kernel = /vmlinuz,
initrd = /initrd.img,
root = sda1,
kernel_cmd = "ro xencons=tty console=tty1"]
#Put here specific OS configurations for the cloud hypervisors
#OS = [ kernel = /vmlinuz,
# initrd = /initrd.img,
# root = sda1,
# kernel_cmd = "ro xencons=tty console=tty1"]
DISK = [ source = <%= erb_vm_info[:img_path] %>,
clone = no,
target = sda1,
readonly = no]
NIC=[NETWORK="Public EC2"]
IMAGE_ID = <%= erb_vm_info[:img_id] %>
INSTANCE_TYPE = <%= erb_vm_info[:instance_type ]%>
<% if erb_vm_info[:user_data] %>
CONTEXT = [
EC2_USER_DATA="<%= erb_vm_info[:user_data] %>",
TARGET="hdc"
]
<% end %>

View File

@ -97,13 +97,15 @@ module EC2QueryClient
# :image_id
# :instance_type
######################################################################
def run_instances(ami_id, type)
def run_instances(ami_id, type, user_data=nil)
begin
response = @ec2_connection.run_instances(
:image_id => ami_id,
:min_count => 1,
:max_count => 1,
:instance_type => type
:image_id => ami_id,
:min_count => 1,
:max_count => 1,
:instance_type => type,
:user_data => user_data,
:base64_encoded => true
)
rescue Exception => e
error = CloudClient::Error.new(e.message)

View File

@ -20,6 +20,8 @@ require 'erb'
require 'time'
require 'AWS'
require 'CloudServer'
require 'base64'
###############################################################################
# The EC2Query Server implements a EC2 compatible server based on the
# OpenNebula Engine
@ -69,6 +71,8 @@ class EC2QueryServer < CloudServer
@server_host=@config[:server]
end
@server_port=@config[:port]
print_configuration
end
@ -79,19 +83,65 @@ class EC2QueryServer < CloudServer
# EC2 protocol authentication function
# params:: of the request
# [return] true if authenticated
def authenticate?(params)
def authenticate?(params,env)
user = get_user(params['AWSAccessKeyId'])
return false if !user
signature = case params['SignatureVersion']
when "1" then signature_version_1(params.clone, user[:password])
when "2" then signature_version_2(params,
user[:password],
env,
false)
end
return params['Signature']==signature
end
# Calculates signature version 1
def signature_version_1(params, secret_key, digest='sha1')
params.delete('Signature')
req_desc = params.sort {|x,y| x[0].downcase <=> y[0].downcase}.to_s
digest_generator = OpenSSL::Digest::Digest.new(digest)
digest = OpenSSL::HMAC.digest(digest_generator,
secret_key,
req_desc)
b64sig = Base64.b64encode(digest)
return b64sig.strip
end
# Calculates signature version 2
def signature_version_2(params, secret_key, env, urlencode=true)
signature_params = params.reject { |key,value|
key=='Signature' or key=='file' }
signature = AWS.encode(
user[:password],
AWS.canonical_string(signature_params, @server_host),
false)
return params['Signature']==signature
server_str = @server_host
server_str = server_str + ":" + @server_port unless %w{2008-12-01 2009-11-30}.include? params["Version"]
canonical_str = AWS.canonical_string(signature_params,
server_str,
env['REQUEST_METHOD'])
# Use the correct signature strength
sha_strength = case params['SignatureMethod']
when "HmacSHA1" then 'sha1'
when "HmacSHA256" then 'sha256'
else 'sha1'
end
digest = OpenSSL::Digest::Digest.new(sha_strength)
b64hmac =
Base64.encode64(
OpenSSL::HMAC.digest(digest, secret_key, canonical_str)).gsub("\n","")
if urlencode
return CGI::escape(b64hmac)
else
return b64hmac
end
end
###########################################################################
@ -103,6 +153,7 @@ class EC2QueryServer < CloudServer
image = add_image(user[:id],params["file"][:tempfile])
erb_img_id = image.id
erb_version = params['Version']
response = ERB.new(File.read(@config[:views]+"/register_image.erb"))
return response.result(binding), 200
@ -113,22 +164,25 @@ class EC2QueryServer < CloudServer
image = get_image(params['ImageLocation'])
if !image
return OpenNebula::Error.new('Image not found'), 404
return OpenNebula::Error.new('InvalidAMIID.NotFound'), 400
elsif user[:id] != image[:owner]
return OpenNebula::Error.new('Not permited to use image'), 401
return OpenNebula::Error.new('AuthFailure'), 400
end
erb_img_id=image.id
erb_version = params['Version']
response = ERB.new(File.read(@config[:views]+"/register_image.erb"))
return response.result(binding), 200
end
def describe_images(params)
erb_user = get_user(params['AWSAccessKeyId'])
erb_images = Image.filter(:owner => erb_user[:id])
erb_user = get_user(params['AWSAccessKeyId'])
erb_images = Image.filter(:owner => erb_user[:id])
erb_version = params['Version']
response = ERB.new(File.read(@config[:views]+"/describe_images.erb"))
return response.result(binding), 200
end
@ -141,12 +195,13 @@ class EC2QueryServer < CloudServer
instance_type_name = params['InstanceType']
instance_type = @instance_types[instance_type_name]
return OpenNebula::Error.new('Bad instance type'),400 if !instance_type
return OpenNebula::Error.new('Unsupported'),400 if !instance_type
# Get the image
image = get_image(params['ImageId'])
tmp, img=params['ImageId'].split('-')
image = get_image(img.to_i)
return OpenNebula::Error.new('Bad image id'),400 if !image
return OpenNebula::Error.new('InvalidAMIID.NotFound'),400 if !image
# Get the user
user = get_user(params['AWSAccessKeyId'])
@ -156,24 +211,30 @@ class EC2QueryServer < CloudServer
# Build the VM
erb_vm_info=Hash.new
erb_vm_info[:img_path] = image.path
erb_vm_info[:img_id] = params['ImageId']
erb_vm_info[:instance_type] = instance_type_name
erb_vm_info[:template] = @config[:template_location] +
"/#{instance_type['TEMPLATE']}"
erb_vm_info[:user_data] = params['UserData']
template = ERB.new(File.read(erb_vm_info[:template]))
template_text = template.result(binding)
#Start the VM.
vm = VirtualMachine.new(VirtualMachine.build_xml, one_client)
rc = vm.allocate(template_text)
return rc, 401 if OpenNebula::is_error?(rc)
return OpenNebula::Error.new('Unsupported'),400 if OpenNebula::is_error?(rc)
vm.info
erb_vm_info[:vm_id]=vm.id
erb_vm_info[:vm]=vm
erb_version = params['Version']
response = ERB.new(File.read(@config[:views]+"/run_instances.erb"))
return response.result(binding), 200
@ -195,8 +256,11 @@ class EC2QueryServer < CloudServer
erb_vmpool = VirtualMachinePool.new(one_client, user_flag)
erb_vmpool.info
erb_version = params['Version']
response = ERB.new(File.read(@config[:views]+"/describe_instances.erb"))
return response.result(binding), 200
end
@ -204,13 +268,16 @@ class EC2QueryServer < CloudServer
# Get the user
user = get_user(params['AWSAccessKeyId'])
one_client = one_client_user(user)
vmid=params['InstanceId.1']
vmid=params['InstanceId.01'] if !vmid
tmp, vmid=vmid.split('-') if vmid[0]==?i
erb_vm = VirtualMachine.new(VirtualMachine.build_xml(vmid),one_client)
rc = erb_vm.info
return rc, 401 if OpenNebula::is_error?(rc)
return OpenNebula::Error.new('Unsupported'),400 if OpenNebula::is_error?(rc)
if erb_vm.status == 'runn'
rc = erb_vm.shutdown
@ -218,7 +285,9 @@ class EC2QueryServer < CloudServer
rc = erb_vm.finalize
end
return rc, 401 if OpenNebula::is_error?(rc)
return OpenNebula::Error.new('Unsupported'),400 if OpenNebula::is_error?(rc)
erb_version = params['Version']
response =ERB.new(File.read(@config[:views]+"/terminate_instances.erb"))
return response.result(binding), 200

View File

@ -59,12 +59,47 @@ set :port, $econe_server.config[:port]
##############################################################################
before do
if !$econe_server.authenticate?(params)
halt 401, 'Invalid credentials'
if !$econe_server.authenticate?(params,env)
error 400, error_xml("AuthFailure", 0)
end
end
helpers do
def error_xml(code,id)
message = ''
case code
when 'AuthFailure'
message = 'User not authorized'
when 'InvalidAMIID.NotFound'
message = 'Specified AMI ID does not exist'
when 'Unsupported'
message = 'The instance type or feature is not supported in your requested Availability Zone.'
else
message = code
end
xml = "<Response><Errors><Error><Code>"+
code +
"</Code><Message>" +
message +
"</Message></Error></Errors><RequestID>" +
id.to_s +
"</RequestID></Response>"
return xml
end
end
post '/' do
do_http_request(params)
end
get '/' do
do_http_request(params)
end
def do_http_request(params)
case params['Action']
when 'UploadImage'
result,rc = $econe_server.upload_image(params)
@ -79,10 +114,12 @@ post '/' do
when 'TerminateInstances'
result,rc = $econe_server.terminate_instances(params)
end
if OpenNebula::is_error?(result)
halt rc, result.message
error rc, error_xml(result.message, 0)
end
result
headers['Content-Type'] = 'application/xml'
result
end

View File

@ -1,9 +1,10 @@
<DescribeImagesResponse xmlns="http://ec2.amazonaws.com/doc/2009-04-04/">
<?xml version="1.0"?>
<DescribeImagesResponse xmlns="http://ec2.amazonaws.com/doc/<%= erb_version %>/">
<imagesSet>
<% for image in erb_images %>
<item>
<imageId><%= image.id %></imageId>
<imageLocation><%= image.path %></imageLocation>
<imageId>ami-<%= sprintf('%08i', image.id) %></imageId>
<imageLocation><%= image.path.gsub(/^\//,'') %></imageLocation>
<imageState>available</imageState>
<imageOwnerId><%= erb_user[:name] %></imageOwnerId>
<isPublic>false</isPublic>

View File

@ -1,4 +1,6 @@
<DescribeInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2009-04-04/">
<?xml version="1.0"?>
<DescribeInstancesResponse xmlns="http://ec2.amazonaws.com/doc/<%= erb_version %>/">
<requestId>4ac62eaf-e266-4058-a970-2c01568cd417</requestId>
<reservationSet>
<item>
<reservationId>default</reservationId>
@ -12,7 +14,7 @@
<% erb_vmpool.each do |vm| %>
<% vm.info %>
<item>
<instanceId><%= vm.id %></instanceId>
<instanceId>i-<%= vm.id %></instanceId>
<imageId><%= vm['TEMPLATE/IMAGE_ID'] %></imageId>
<instanceState>
<%= render_state(vm) %>
@ -21,11 +23,19 @@
<dnsName><%= vm["TEMPLATE/NIC/IP"] %></dnsName>
<keyName>default</keyName>
<amiLaunchIndex>0</amiLaunchIndex>
<productCodes/>
<instanceType><%= vm['TEMPLATE/INSTANCE_TYPE'] %></instanceType>
<%= render_launch_time(vm) %>
<placement>
<availabilityZone>default</availabilityZone>
</placement>
<kernelId>eki-EA801065</kernelId>
<ramdiskId>eri-1FEE1144</ramdiskId>
<monitoring>
<state>false</state>
</monitoring>
</item>
<% end %>
</instancesSet>

View File

@ -1,3 +1,3 @@
<RegisterImageResponse xmlns="http://ec2.amazonaws.com/doc/2009-04-04/">
<RegisterImageResponse xmlns="http://ec2.amazonaws.com/doc/<%= erb_version %>/">
<imageId><%= erb_img_id %></imageId>
</RegisterImageResponse>

View File

@ -1,4 +1,4 @@
<RunInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2009-04-04/">
<RunInstancesResponse xmlns="http://ec2.amazonaws.com/doc/<%= erb_version %>/">
<reservationId>r-47a5402e</reservationId>
<ownerId><%= erb_user_name %></ownerId>
<groupSet>
@ -8,7 +8,7 @@
</groupSet>
<instancesSet>
<item>
<instanceId><%= erb_vm_info[:vm_id] %></instanceId>
<instanceId>i-<%= erb_vm_info[:vm_id] %></instanceId>
<imageId><%= erb_vm_info[:img_id] %></imageId>
<instanceState>
<code>0</code>

View File

@ -1,7 +1,7 @@
<TerminateInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2009-04-04/">
<TerminateInstancesResponse xmlns="http://ec2.amazonaws.com/doc/<%= erb_version %>/">
<instancesSet>
<item>
<instanceId><%= erb_vm.id %></instanceId>
<instanceId>i-<%= erb_vm.id %></instanceId>
<shutdownState>
<code>32</code>
<name>shutting-down</name>

View File

@ -1,54 +1,4 @@
#!/usr/bin/env ruby
# == Synopsis
# occi-compute
#
# Manages compute resources
#
# == Usage
#
# occi-compute <COMMAND> [OPTIONS] [ARGUMENTS]
#
# COMMANDS
#
# create <occi xml file>
# creates a new compute resource described by the provided
# <occi xml file>
#
# list
# lists available compute resources
#
# show <compute id>
# retrieves the OCCI XML representation of the compute resource
# identified by <compute id>
#
# update <occi xml file>
# updates the representation of the compute resource represented by the
# provided <occi xml file>
#
# delete <compute id>
# deletes the compute resource idenfitied by <compute id>
#
#
# OPTIONS
#
# -h, --help:
# show help
#
# --username <id>, -U <id>:
# The username of the user
#
# --password <key>, -P <key>:
# The password of the user
#
# --url <url>, -R <url>:
# Set url as the web service url to use
#
# --debug, -D
# Enables verbosity
#
#
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
# #
@ -78,10 +28,61 @@ end
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+"/cloud"
COMMANDS_HELP=<<-EOT
** Synopsis
occi-compute
Manages compute resources
** Usage
occi-compute <COMMAND> [OPTIONS] [ARGUMENTS]
COMMANDS
create <occi xml file>
creates a new compute resource described by the provided
<occi xml file>
list
lists available compute resources
show <compute id>
retrieves the OCCI XML representation of the compute resource
identified by <compute id>
update <occi xml file>
updates the representation of the compute resource represented by the
provided <occi xml file>
delete <compute id>
deletes the compute resource idenfitied by <compute id>
OPTIONS
--help, -h:
Show help
--username <id>, -U <id>:
The username of the user
--password <key>, -P <key>:
The password of the user
--url <url>, -R <url>:
Set url as the web service url to use
--timeout <seconds>, -T <seconds>
Sets a timeout for the http connection
--debug, -D
Enables verbosity
EOT
require 'occi/OCCIClient'
require 'getoptlong'
require 'rdoc/usage'
require 'pp'
require "rexml/document"
include CloudCLI
@ -90,6 +91,7 @@ opts = GetoptLong.new(
['--username', '-U',GetoptLong::REQUIRED_ARGUMENT],
['--password', '-P',GetoptLong::REQUIRED_ARGUMENT],
['--url', '-R',GetoptLong::REQUIRED_ARGUMENT],
['--timeout', '-T',GetoptLong::REQUIRED_ARGUMENT],
['--debug', '-D',GetoptLong::NO_ARGUMENT]
)
@ -97,19 +99,23 @@ url = nil
username = nil
password = nil
auth = nil
timeout = nil
debug = false
begin
opts.each do |opt, arg|
case opt
when '--help'
RDoc::usage
puts COMMANDS_HELP
return
when '--username'
username = arg
when '--password'
password = arg
when '--url'
url = arg
when '--timeout'
timeout = arg
when '--debug'
debug = true
end
@ -119,7 +125,7 @@ rescue Exception => e
end
begin
occi_client = OCCIClient::Client.new(url,username,password,debug)
occi_client = OCCIClient::Client.new(url,username,password, timeout, debug)
rescue Exception => e
puts "#{cmd_name}: #{e.message}"
exit(-1)
@ -182,7 +188,23 @@ end
if CloudClient::is_error?(rc)
puts rc.to_s()
else
puts rc
else
begin
doc = REXML::Document.new(rc)
rescue REXML::ParseException => e
puts e.message
exit(-1)
end
xml = doc.root
if xml.nil?
puts "XML syntax error"
exit(-1)
end
str = ""
REXML::Formatters::Pretty.new(4).write(xml,str)
puts "\n" + str + "\n "
end

View File

@ -1,53 +1,4 @@
#!/usr/bin/env ruby
# == Synopsis
# occi-network
#
# Manages virtual networks
#
# == Usage
#
# occi-network <COMMAND> [OPTIONS] [ARGUMENTS]
#
# COMMANDS
#
# create <occi xml file>
# creates a new virtual network described by the provided
# <occi xml file>
#
# list
# lists available virtual networks
#
# show <network id>
# retrieves the OCCI XML representation of the virtual network
# identified by <network id>
#
# delete <network id>
# deletes the virtual network idenfitied by <network id>
#
#
#
# OPTIONS
#
# -h, --help:
# show help
#
# --username <id>, -U <id>:
# The username of the user
#
# --password <key>, -P <key>:
# The password of the user
#
# --url <url>, -R <url>:
# Set url as the web service url to use
#
# --debug, -D
# Enables verbosity
#
# --multipart, -M:
# Use 'multipart-post' library instead of Curb/Curl
#
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
# #
@ -77,11 +28,62 @@ end
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+"/cloud"
COMMANDS_HELP=<<-EOT
** Synopsis
occi-network
Manages virtual networks
** Usage
occi-network <COMMAND> [OPTIONS] [ARGUMENTS]
COMMANDS
create <occi xml file>
creates a new virtual network described by the provided
<occi xml file>
list
lists available virtual networks
show <network id>
retrieves the OCCI XML representation of the virtual network
identified by <network id>
delete <network id>
deletes the virtual network idenfitied by <network id>
OPTIONS
--help, -h:
Show help
--username <id>, -U <id>:
The username of the user
--password <key>, -P <key>:
The password of the user
--url <url>, -R <url>:
Set url as the web service url to use
--timeout <seconds>, -T <seconds>
Sets a timeout for the http connection
--debug, -D
Enables verbosity
--multipart, -M:
Use 'multipart-post' library instead of Curb/Curl
EOT
require 'occi/OCCIClient'
require 'CloudClient'
require 'getoptlong'
require 'rdoc/usage'
require 'pp'
require "rexml/document"
include CloudCLI
@ -90,6 +92,7 @@ opts = GetoptLong.new(
['--username', '-U',GetoptLong::REQUIRED_ARGUMENT],
['--password', '-P',GetoptLong::REQUIRED_ARGUMENT],
['--url', '-R',GetoptLong::REQUIRED_ARGUMENT],
['--timeout', '-T',GetoptLong::REQUIRED_ARGUMENT],
['--debug', '-D',GetoptLong::NO_ARGUMENT]
)
@ -97,19 +100,23 @@ url = nil
username = nil
password = nil
auth = nil
timeout = nil
debug = false
begin
opts.each do |opt, arg|
case opt
when '--help'
RDoc::usage
puts COMMANDS_HELP
return
when '--username'
username = arg
when '--password'
password = arg
when '--url'
url = arg
when '--timeout'
timeout = arg
when '--debug'
debug = true
end
@ -120,7 +127,7 @@ end
begin
occi_client = OCCIClient::Client.new(url,username,password,debug)
occi_client = OCCIClient::Client.new(url,username,password,timeout,debug)
rescue Exception => e
puts "#{cmd_name}: #{e.message}"
exit(-1)
@ -174,6 +181,22 @@ end
if CloudClient::is_error?(rc)
puts rc.to_s()
else
puts rc
else
begin
doc = REXML::Document.new(rc)
rescue REXML::ParseException => e
puts e.message
exit(-1)
end
xml = doc.root
if xml.nil?
puts "XML syntax error"
exit(-1)
end
str = ""
REXML::Formatters::Pretty.new(4).write(xml,str)
puts "\n" + str + "\n "
end

View File

@ -1,51 +1,4 @@
#!/usr/bin/env ruby
# == Synopsis
# occi-storage
#
# Manages OCCI storage resource
#
# == Usage
#
# occi-storage <COMMAND> [OPTIONS] [PARAMETERS]
#
# COMMANDS
#
# create <occi xml file>
# creates a new storage resource described by the provided
# <occi xml file>
#
# list
# lists available storage resources
#
# show <storage id>
# retrieves the OCCI XML representation of the storage resource
# identified by <storage id>
#
# delete <storage id>
# deletes the storage resource idenfitied by <storage id>
#
#
# OPTIONS
# -h, --help:
# show help
#
# --username <id>, -U <id>:
# The username of the user
#
# --password <key>, -P <key>:
# The password of the user
#
# --url <url>, -R <url>:
# Set url as the web service url to use
#
# --debug, -D
# Enables verbosity
#
# --multipart, -M:
# Use 'multipart-post' library instead of Curb/Curl
#
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
# #
@ -75,11 +28,60 @@ end
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+"/cloud"
COMMANDS_HELP=<<-EOT
** Synopsis
occi-storage
Manages OCCI storage resource
** Usage
occi-storage <COMMAND> [OPTIONS] [PARAMETERS]
COMMANDS
create <occi xml file>
creates a new storage resource described by the provided
<occi xml file>
list
lists available storage resources
show <storage id>
retrieves the OCCI XML representation of the storage resource
identified by <storage id>
delete <storage id>
deletes the storage resource idenfitied by <storage id>
OPTIONS
--help, -h:
Show help
--username <id>, -U <id>:
The username of the user
--password <key>, -P <key>:
The password of the user
--url <url>, -R <url>:
Set url as the web service url to use
--timeout <seconds>, -T <seconds>
Sets a timeout for the http connection
--debug, -D
Enables verbosity
--multipart, -M:
Use 'multipart-post' library instead of Curb/Curl
EOT
require 'occi/OCCIClient'
require 'CloudClient'
require 'getoptlong'
require 'rdoc/usage'
require 'pp'
require "rexml/document"
include CloudCLI
@ -89,6 +91,7 @@ opts = GetoptLong.new(
['--password', '-P',GetoptLong::REQUIRED_ARGUMENT],
['--url', '-R',GetoptLong::REQUIRED_ARGUMENT],
['--debug', '-D',GetoptLong::NO_ARGUMENT],
['--timeout', '-T',GetoptLong::REQUIRED_ARGUMENT],
['--multipart', '-M',GetoptLong::NO_ARGUMENT]
)
@ -96,6 +99,7 @@ url = nil
username = nil
password = nil
auth = nil
timeout = nil
debug = false
curb = true
@ -103,13 +107,16 @@ begin
opts.each do |opt, arg|
case opt
when '--help'
RDoc::usage
puts COMMANDS_HELP
return
when '--username'
username = arg
when '--password'
password = arg
when '--url'
url = arg
when '--timeout'
timeout = arg
when '--debug'
debug = true
when '--multipart'
@ -128,7 +135,7 @@ end
begin
occi_client = OCCIClient::Client.new(url,username,password,debug)
occi_client = OCCIClient::Client.new(url,username,password,timeout,debug)
rescue Exception => e
puts "#{cmd_name}: #{e.message}"
exit(-1)
@ -169,6 +176,22 @@ end
if CloudClient::is_error?(rc)
puts rc.to_s()
else
puts rc
else
begin
doc = REXML::Document.new(rc)
rescue REXML::ParseException => e
puts e.message
exit(-1)
end
xml = doc.root
if xml.nil?
puts "XML syntax error"
exit(-1)
end
str = ""
REXML::Formatters::Pretty.new(4).write(xml,str)
puts "\n" + str + "\n "
end

View File

@ -27,12 +27,12 @@ module ImageOCCI
<SIZE><%= ((size/1024)/1024).to_s %></SIZE>
<URL><%= description %></URL>
</DISK>
}.gsub(/^ /, '')
}
# Creates the OCCI representation of an Image
def to_occi()
occi = ERB.new(OCCI_IMAGE)
return occi.result(binding)
return occi.result(binding).gsub(/\n\s*/,'')
end
end

View File

@ -26,7 +26,7 @@ class ImagePoolOCCI
<DISK href="<%= base_url%>/storage/<%= image[:id] %>"/><%
end %>
</STORAGE>
}.gsub(/^ /, '')
}
def initialize(user_id)
@images=Image.filter(:owner => user_id)
@ -34,7 +34,7 @@ class ImagePoolOCCI
def to_occi(base_url)
occi = ERB.new(OCCI_IMAGE_POOL)
return occi.result(binding)
return occi.result(binding).gsub(/\n\s*/,'')
end
end

View File

@ -33,8 +33,10 @@ module OCCIClient
######################################################################
# Initialize client library
######################################################################
def initialize(endpoint_str=nil, user=nil, pass=nil, debug_flag=true)
@debug = debug_flag
def initialize(endpoint_str=nil, user=nil, pass=nil,
timeout=nil, debug_flag=true)
@debug = debug_flag
@timeout = timeout
# Server location
if endpoint_str
@ -78,7 +80,7 @@ module OCCIClient
req.basic_auth @occiauth[0], @occiauth[1]
res = CloudClient::http_start(url) do |http|
res = CloudClient::http_start(url, @timeout) do |http|
http.request(req)
end
@ -98,7 +100,7 @@ module OCCIClient
req.basic_auth @occiauth[0], @occiauth[1]
res = CloudClient::http_start(url) {|http|
res = CloudClient::http_start(url, @timeout) {|http|
http.request(req)
}
@ -123,7 +125,7 @@ module OCCIClient
req.basic_auth @occiauth[0], @occiauth[1]
res = CloudClient::http_start(url) do |http|
res = CloudClient::http_start(url, @timeout) do |http|
http.request(req)
end
@ -143,7 +145,7 @@ module OCCIClient
req.basic_auth @occiauth[0], @occiauth[1]
res = CloudClient::http_start(url) {|http|
res = CloudClient::http_start(url, @timeout) {|http|
http.request(req)
}
@ -203,7 +205,7 @@ module OCCIClient
req.basic_auth @occiauth[0], @occiauth[1]
res = CloudClient::http_start(url) do |http|
res = CloudClient::http_start(url, @timeout) do |http|
http.request(req)
end
@ -226,7 +228,7 @@ module OCCIClient
req.basic_auth @occiauth[0], @occiauth[1]
res = CloudClient::http_start(url) {|http|
res = CloudClient::http_start(url, @timeout) {|http|
http.request(req)
}
@ -250,7 +252,7 @@ module OCCIClient
req.basic_auth @occiauth[0], @occiauth[1]
res = CloudClient::http_start(url) {|http|
res = CloudClient::http_start(url, @timeout) {|http|
http.request(req)
}
@ -276,7 +278,7 @@ module OCCIClient
req.basic_auth @occiauth[0], @occiauth[1]
res = CloudClient::http_start(url) do |http|
res = CloudClient::http_start(url, @timeout) do |http|
http.request(req)
end
@ -296,7 +298,7 @@ module OCCIClient
req.basic_auth @occiauth[0], @occiauth[1]
res = CloudClient::http_start(url) {|http|
res = CloudClient::http_start(url, @timeout) {|http|
http.request(req)
}
@ -317,7 +319,7 @@ module OCCIClient
req.basic_auth @occiauth[0], @occiauth[1]
res = CloudClient::http_start(url) {|http|
res = CloudClient::http_start(url, @timeout) {|http|
http.request(req)
}
@ -337,7 +339,7 @@ module OCCIClient
req.basic_auth @occiauth[0], @occiauth[1]
res = CloudClient::http_start(url) {|http|
res = CloudClient::http_start(url, @timeout) {|http|
http.request(req)
}
@ -358,7 +360,7 @@ module OCCIClient
req.basic_auth @occiauth[0], @occiauth[1]
res = CloudClient::http_start(url) {|http|
res = CloudClient::http_start(url, @timeout) {|http|
http.request(req)
}

View File

@ -235,6 +235,11 @@ class OCCIServer < CloudServer
network_info['NETWORK'],
@config[:bridge])
rc = network.allocate(vntemplate)
if OpenNebula::is_error?(rc)
return rc, 404
end
network.info
network_xml = network.to_occi
return network_xml, 201

View File

@ -35,7 +35,7 @@ class VirtualMachineOCCI < VirtualMachine
<INSTANCE_TYPE><%=template['INSTANCE_TYPE']%></INSTANCE_TYPE><%
end %>
</COMPUTE>
}.gsub(/^ /, '')
}
# Creates the VMI representation of a Virtual Machine
@ -47,7 +47,7 @@ class VirtualMachineOCCI < VirtualMachine
template['NIC']=[template['NIC']].flatten if template['NIC']
occi = ERB.new(OCCI_VM)
return occi.result(binding)
return occi.result(binding).gsub(/\n\s*/,'')
end
end

View File

@ -12,7 +12,7 @@ class VirtualMachinePoolOCCI < VirtualMachinePool
}
end %>
</COMPUTES>
}.gsub(/^ /, '')
}
# Creates the OCCI representation of a Virtual Machine Pool
@ -20,7 +20,7 @@ class VirtualMachinePoolOCCI < VirtualMachinePool
pool_hash=to_hash
occi = ERB.new(OCCI_VM_POOL)
return occi.result(binding)
return occi.result(binding).gsub(/\n\s*/,'')
end
end

View File

@ -27,7 +27,7 @@ class VirtualNetworkOCCI < VirtualNetwork
<ADDRESS><%= vn_hash['VNET']['TEMPLATE']['NETWORK_ADDRESS'].strip %></ADDRESS>
<SIZE><%= vn_hash['VNET']['TEMPLATE']['NETWORK_SIZE'].strip %></SIZE>
</NETWORK>
}.gsub(/^ /, '')
}
ONE_NETWORK = %q{
NAME = <%= network_hash['NAME'] %>
@ -42,7 +42,7 @@ class VirtualNetworkOCCI < VirtualNetwork
vn_hash = to_hash
occi = ERB.new(OCCI_NETWORK)
return occi.result(binding)
return occi.result(binding).gsub(/\n\s*/,'')
end
def to_one_template(network_hash, bridge)

View File

@ -13,13 +13,13 @@ class VirtualNetworkPoolOCCI < VirtualNetworkPool
}
end %>
</NETWORKS>
}.gsub(/^ /, '')
}
# Creates the OCCI representation of a Virtual Network
def to_occi(base_url)
network_pool_hash=to_hash
occi = ERB.new(OCCI_NETWORK_POOL)
return occi.result(binding)
return occi.result(binding).gsub(/\n\s*/,'')
end
end

View File

@ -592,6 +592,8 @@ int DispatchManager::finalize(
vm->release_network_leases();
vm->release_disk_images();
vm->log("DiM", Log::INFO, "New VM state is DONE.");
break;

View File

@ -117,6 +117,8 @@ void DispatchManager::done_action(int vid)
vm->log("DiM", Log::INFO, "New VM state is DONE");
vm->release_network_leases();
vm->release_disk_images();
}
else
{

View File

@ -39,7 +39,7 @@ Host::Host(
im_mad_name(_im_mad_name),
vmm_mad_name(_vmm_mad_name),
tm_mad_name(_tm_mad_name),
last_monitored(time(0)),
last_monitored(0),
host_template(id)
{};
@ -110,6 +110,8 @@ int Host::select(SqlDB *db)
rc = db->exec(oss, this);
unset_callback();
if ((rc != 0) || (oid != boid ))
{
return -1;
@ -195,7 +197,7 @@ int Host::update(SqlDB *db)
{
int rc;
// Update the Template
// Update the Template needed by the monitoring action from IM
rc = host_template.update(db);
if ( rc != 0 )

View File

@ -70,23 +70,21 @@ int HostPool::discover_cb(void * _map, int num, char **values, char **names)
/* -------------------------------------------------------------------------- */
int HostPool::discover(map<int, string> * discovered_hosts)
int HostPool::discover(map<int, string> * discovered_hosts, int host_limit)
{
ostringstream sql;
int rc;
lock();
set_callback(static_cast<Callbackable::Callback>(&HostPool::discover_cb),
static_cast<void *>(discovered_hosts));
sql << "SELECT oid, im_mad FROM "
<< Host::table << " WHERE state != "
<< Host::DISABLED << " ORDER BY last_mon_time LIMIT 10";
<< Host::DISABLED << " ORDER BY last_mon_time ASC LIMIT " << host_limit;
rc = db->exec(sql,this);
unlock();
unset_callback();
return rc;
}
@ -127,5 +125,7 @@ int HostPool::dump(ostringstream& oss, const string& where)
oss << "</HOST_POOL>";
unset_callback();
return rc;
}

View File

@ -184,6 +184,8 @@ int HostShare::select(SqlDB * db)
rc = db->exec(oss,this);
unset_callback();
if (hsid != bhsid )
{
rc = -1;

View File

@ -20,24 +20,6 @@ Import('env')
lib_name='nebula_host'
if env['parsers']=='yes':
# LEX
parser=env.Lex(
source='host_parser.l'
)
env.NoClean(parser)
# BISON
parser=env.Bison(
source='host_requirements.y'
)
env.NoClean(parser)
parser=env.Bison(
source='host_rank.y'
)
env.NoClean(parser)
# Sources to generate the library
source_files=[
'Host.cc',

View File

@ -32,11 +32,11 @@ extern "C" void * im_action_loop(void *arg)
NebulaLog::log("InM",Log::INFO,"Information Manager started.");
im = static_cast<InformationManager *>(arg);
im->am.loop(im->timer_period,0);
NebulaLog::log("InM",Log::INFO,"Information Manager stopped.");
return 0;
}
@ -50,30 +50,30 @@ void InformationManager::load_mads(int uid)
ostringstream oss;
const VectorAttribute * vattr;
int rc;
NebulaLog::log("InM",Log::INFO,"Loading Information Manager drivers.");
for(i=0;i<mad_conf.size();i++)
{
vattr = static_cast<const VectorAttribute *>(mad_conf[i]);
oss.str("");
oss << "\tLoading driver: " << vattr->vector_value("NAME");
NebulaLog::log("InM",Log::INFO,oss);
im_mad = new InformationManagerDriver(0,vattr->value(),false,hpool);
rc = add(im_mad);
if ( rc == 0 )
{
oss.str("");
oss.str("");
oss << "\tDriver " << vattr->vector_value("NAME") << " loaded";
NebulaLog::log("InM",Log::INFO,oss);
}
}
}
}
/* -------------------------------------------------------------------------- */
@ -92,7 +92,7 @@ int InformationManager::start()
}
NebulaLog::log("InM",Log::INFO,"Starting Information Manager...");
pthread_attr_init (&pattr);
pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE);
@ -113,14 +113,14 @@ void InformationManager::do_action(const string &action, void * arg)
else if (action == ACTION_FINALIZE)
{
NebulaLog::log("InM",Log::INFO,"Stopping Information Manager...");
MadManager::stop();
MadManager::stop();
}
else
{
ostringstream oss;
oss << "Unknown action name: " << action;
NebulaLog::log("InM", Log::ERROR, oss);
}
}
@ -131,19 +131,22 @@ void InformationManager::do_action(const string &action, void * arg)
void InformationManager::timer_action()
{
static int mark = 0;
int rc;
time_t thetime;
ostringstream oss;
map<int, string> discovered_hosts;
map<int, string>::iterator it;
const InformationManagerDriver * imd;
Host * host;
istringstream iss;
// -------------- Max. number of hosts to monitor. ---------------------
int host_limit = 10;
mark = mark + timer_period;
if ( mark >= 600 )
@ -152,7 +155,7 @@ void InformationManager::timer_action()
mark = 0;
}
rc = hpool->discover(&discovered_hosts);
rc = hpool->discover(&discovered_hosts, host_limit);
if ((rc != 0) || (discovered_hosts.empty() == true))
{
@ -160,55 +163,55 @@ void InformationManager::timer_action()
}
thetime = time(0);
for(it=discovered_hosts.begin();it!=discovered_hosts.end();it++)
{
{
host = hpool->get(it->first,true);
if (host == 0)
{
continue;
}
Host::HostState state = host->get_state();
// TODO: Set apropriate threshold to timeout monitoring
if (( state == Host::MONITORING) &&
(thetime - host->get_last_monitored() >= 600))
{
host->set_state(Host::INIT);
hpool->update(host);
}
if ((state != Host::MONITORING) && (state != Host::DISABLED) &&
(thetime - host->get_last_monitored() >= monitor_period))
{
oss.str("");
oss << "Monitoring host " << host->get_hostname()
oss << "Monitoring host " << host->get_hostname()
<< " (" << it->first << ")";
NebulaLog::log("InM",Log::INFO,oss);
imd = get(it->second);
if (imd == 0)
{
oss.str("");
oss << "Could not find information driver " << it->second;
NebulaLog::log("InM",Log::ERROR,oss);
host->set_state(Host::ERROR);
host->set_state(Host::ERROR);
}
else
{
imd->monitor(it->first,host->get_hostname());
host->set_state(Host::MONITORING);
}
hpool->update(host);
}
host->unlock();
}
host->unlock();
}
}

687
src/image/Image.cc Normal file
View File

@ -0,0 +1,687 @@
/* ------------------------------------------------------------------------ */
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* ------------------------------------------------------------------------ */
#include <limits.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <openssl/evp.h>
#include <iomanip>
#include "Image.h"
#include "ImagePool.h"
/* ************************************************************************ */
/* Image :: Constructor/Destructor */
/* ************************************************************************ */
Image::Image(int _uid):
PoolObjectSQL(-1),
uid(_uid),
name(""),
type(OS),
regtime(time(0)),
source(""),
state(INIT),
running_vms(0)
{};
Image::~Image(){};
/* ************************************************************************ */
/* Image :: Database Access Functions */
/* ************************************************************************ */
const char * Image::table = "image_pool";
const char * Image::db_names = "(oid, uid, name, type, public, regtime, "
"source, state, running_vms)";
const char * Image::db_bootstrap = "CREATE TABLE IF NOT EXISTS image_pool ("
"oid INTEGER PRIMARY KEY, uid INTEGER, name VARCHAR(128), "
"type INTEGER, public INTEGER, regtime INTEGER, source TEXT, state INTEGER, "
"running_vms INTEGER, UNIQUE(name) )";
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Image::select_cb(void * nil, int num, char **values, char ** names)
{
if ((!values[OID]) ||
(!values[UID]) ||
(!values[NAME]) ||
(!values[TYPE]) ||
(!values[PUBLIC]) ||
(!values[REGTIME]) ||
(!values[SOURCE]) ||
(!values[STATE]) ||
(!values[RUNNING_VMS]) ||
(num != LIMIT ))
{
return -1;
}
oid = atoi(values[OID]);
uid = atoi(values[UID]);
name = values[NAME];
type = static_cast<ImageType>(atoi(values[TYPE]));
public_img = atoi(values[PUBLIC]);
regtime = static_cast<time_t>(atoi(values[REGTIME]));
source = values[SOURCE];
state = static_cast<ImageState>(atoi(values[STATE]));
running_vms = atoi(values[RUNNING_VMS]);
image_template.id = oid;
return 0;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Image::select(SqlDB *db)
{
ostringstream oss;
int rc;
int boid;
set_callback(static_cast<Callbackable::Callback>(&Image::select_cb));
oss << "SELECT * FROM " << table << " WHERE oid = " << oid;
boid = oid;
oid = -1;
rc = db->exec(oss, this);
if ((rc != 0) || (oid != boid ))
{
return -1;
}
// Get the template
rc = image_template.select(db);
if ( rc != 0 )
{
return -1;
}
return 0;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Image::insert(SqlDB *db)
{
int rc;
string source_att;
string type_att;
string public_attr;
string dev_prefix;
ostringstream tmp_hashstream;
ostringstream tmp_sourcestream;
// ---------------------------------------------------------------------
// Check default image attributes
// ---------------------------------------------------------------------
// ------------ NAME --------------------
get_template_attribute("NAME", name);
if ( name.empty() == true )
{
goto error_name;
}
// ------------ TYPE --------------------
get_template_attribute("TYPE", type_att);
transform (type_att.begin(), type_att.end(), type_att.begin(),
(int(*)(int))toupper);
if ( type_att.empty() == true )
{
type_att = ImagePool::default_type();
}
if (set_type(type_att) != 0)
{
goto error_type;
}
// ------------ PUBLIC --------------------
get_template_attribute("PUBLIC", public_attr);
image_template.erase("PUBLIC");
transform (public_attr.begin(), public_attr.end(), public_attr.begin(),
(int(*)(int))toupper);
public_img = (public_attr == "YES");
// ------------ PREFIX --------------------
get_template_attribute("DEV_PREFIX", dev_prefix);
if( dev_prefix.empty() )
{
SingleAttribute * dev_att = new SingleAttribute("DEV_PREFIX",
ImagePool::default_dev_prefix());
image_template.set(dev_att);
}
// ------------ SOURCE (path to store the image)--------------------
tmp_hashstream << uid << ":" << name;
tmp_sourcestream << ImagePool::source_prefix() << "/";
tmp_sourcestream << sha1_digest(tmp_hashstream.str());
source = tmp_sourcestream.str();
// Set up the template ID, to insert it
if ( image_template.id == -1 )
{
image_template.id = oid;
}
state = DISABLED;
// Insert the Template
rc = image_template.insert(db);
if ( rc != 0 )
{
return rc;
}
//Insert the Image
rc = insert_replace(db, false);
if ( rc != 0 )
{
image_template.drop(db);
return rc;
}
return 0;
error_name:
NebulaLog::log("IMG", Log::ERROR, "NAME not present in image template");
goto error_common;
error_type:
NebulaLog::log("IMG", Log::ERROR, "Incorrect TYPE in image template");
goto error_common;
error_common:
return -1;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Image::update(SqlDB *db)
{
return insert_replace(db, true);;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Image::insert_replace(SqlDB *db, bool replace)
{
ostringstream oss;
int rc;
char * sql_name;
char * sql_source;
// Update the Image
sql_name = db->escape_str(name.c_str());
if ( sql_name == 0 )
{
goto error_name;
}
sql_source = db->escape_str(source.c_str());
if ( sql_source == 0 )
{
goto error_source;
}
if(replace)
{
oss << "REPLACE";
}
else
{
oss << "INSERT";
}
// Construct the SQL statement to Insert or Replace
oss <<" INTO "<< table <<" "<< db_names <<" VALUES ("
<< oid << ","
<< uid << ","
<< "'" << sql_name << "',"
<< type << ","
<< public_img << ","
<< regtime << ","
<< "'" << sql_source << "',"
<< state << ","
<< running_vms << ")";
rc = db->exec(oss);
db->free_str(sql_name);
db->free_str(sql_source);
return rc;
error_source:
db->free_str(sql_name);
error_name:
return -1;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Image::dump(ostringstream& oss, int num, char **values, char **names)
{
if ((!values[OID]) ||
(!values[UID]) ||
(!values[NAME]) ||
(!values[TYPE]) ||
(!values[PUBLIC]) ||
(!values[REGTIME]) ||
(!values[SOURCE]) ||
(!values[STATE]) ||
(!values[RUNNING_VMS]) ||
(num != LIMIT + 1))
{
return -1;
}
oss <<
"<IMAGE>" <<
"<ID>" << values[OID] << "</ID>" <<
"<UID>" << values[UID] << "</UID>" <<
"<USERNAME>" << values[LIMIT] << "</USERNAME>" <<
"<NAME>" << values[NAME] << "</NAME>" <<
"<TYPE>" << values[TYPE] << "</TYPE>" <<
"<PUBLIC>" << values[PUBLIC] << "</PUBLIC>" <<
"<REGTIME>" << values[REGTIME] << "</REGTIME>" <<
"<SOURCE>" << values[SOURCE] << "</SOURCE>" <<
"<STATE>" << values[STATE] << "</STATE>" <<
"<RUNNING_VMS>" << values[RUNNING_VMS] << "</RUNNING_VMS>" <<
"</IMAGE>";
return 0;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Image::drop(SqlDB * db)
{
ostringstream oss;
int rc;
// Only delete the VM
if (running_vms != 0)
{
return -1;
}
image_template.drop(db);
oss << "DELETE FROM " << table << " WHERE oid=" << oid;
rc = db->exec(oss);
if ( rc == 0 )
{
set_valid(false);
}
return rc;
}
/* ************************************************************************ */
/* Image :: Misc */
/* ************************************************************************ */
ostream& operator<<(ostream& os, Image& image)
{
string image_str;
os << image.to_xml(image_str);
return os;
};
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
string& Image::to_xml(string& xml) const
{
string template_xml;
ostringstream oss;
oss <<
"<IMAGE>" <<
"<ID>" << oid << "</ID>" <<
"<UID>" << uid << "</UID>" <<
"<NAME>" << name << "</NAME>" <<
"<TYPE>" << type << "</TYPE>" <<
"<PUBLIC>" << public_img << "</PUBLIC>" <<
"<REGTIME>" << regtime << "</REGTIME>" <<
"<SOURCE>" << source << "</SOURCE>" <<
"<STATE>" << state << "</STATE>" <<
"<RUNNING_VMS>" << running_vms << "</RUNNING_VMS>" <<
image_template.to_xml(template_xml) <<
"</IMAGE>";
xml = oss.str();
return xml;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
string& Image::to_str(string& str) const
{
string template_str;
ostringstream os;
os <<
"ID = " << oid << endl <<
"UID = " << uid << endl <<
"NAME = " << name << endl <<
"TYPE = " << type << endl <<
"PUBLIC = " << public_img << endl <<
"REGTIME = " << regtime << endl <<
"SOURCE = " << source << endl <<
"STATE = " << state << endl <<
"RUNNING_VMS = " << running_vms << endl <<
"TEMPLATE" << endl
<< image_template.to_str(template_str)
<< endl;
str = os.str();
return str;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Image::acquire_image(bool overwrite)
{
int rc = 0;
switch (state)
{
case READY:
running_vms++;
if ( overwrite == true)
{
state = LOCKED;
}
else
{
state = USED;
}
break;
case USED:
if ( overwrite == true)
{
rc = -1;
}
else
{
running_vms++;
}
break;
case DISABLED:
case LOCKED:
default:
rc = -1;
break;
}
return rc;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
void Image::release_image()
{
switch (state)
{
case USED:
case LOCKED:
running_vms--;
if ( running_vms == 0)
{
state = READY;
}
break;
case DISABLED:
case READY:
default:
break;
}
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Image::disk_attribute(VectorAttribute * disk, int * index)
{
string overwrite;
string saveas;
string name;
string bus;
ostringstream iid;
name = disk->vector_value("NAME");
overwrite = disk->vector_value("OVERWRITE");
saveas = disk->vector_value("SAVE_AS");
bus = disk->vector_value("BUS");
iid << oid;
transform(overwrite.begin(), overwrite.end(), overwrite.begin(),
(int(*)(int))toupper);
string template_bus;
string prefix;
get_template_attribute("BUS", template_bus);
get_template_attribute("DEV_PREFIX", prefix);
//--------------------------------------------------------------------------
// Acquire the image
//--------------------------------------------------------------------------
if ( acquire_image(overwrite == "YES") != 0 )
{
return -1;
}
//---------------------------------------------------------------------------
// NEW DISK ATTRIBUTES
//---------------------------------------------------------------------------
map<string,string> new_disk;
new_disk.insert(make_pair("NAME",name));
new_disk.insert(make_pair("IID", iid.str()));
new_disk.insert(make_pair("SOURCE", source));
if (!overwrite.empty())
{
new_disk.insert(make_pair("OVERWRITE",overwrite));
}
if (!saveas.empty())
{
new_disk.insert(make_pair("SAVE_AS",saveas));
}
if (bus.empty())
{
if (!template_bus.empty())
{
new_disk.insert(make_pair("BUS",template_bus));
}
}
else
{
new_disk.insert(make_pair("BUS",bus));
}
//---------------------------------------------------------------------------
// TYPE, READONLY, CLONE, and SAVE attributes
//---------------------------------------------------------------------------
switch(type)
{
case OS:
case DATABLOCK:
new_disk.insert(make_pair("TYPE","DISK"));
new_disk.insert(make_pair("READONLY","NO"));
if (overwrite == "YES")
{
new_disk.insert(make_pair("CLONE","NO"));
new_disk.insert(make_pair("SAVE","YES"));
}
else if (!saveas.empty())
{
new_disk.insert(make_pair("CLONE","YES"));
new_disk.insert(make_pair("SAVE","YES"));
}
else
{
new_disk.insert(make_pair("CLONE","YES"));
new_disk.insert(make_pair("SAVE","NO"));
}
break;
case CDROM:
new_disk.insert(make_pair("TYPE","CDROM"));
new_disk.insert(make_pair("READONLY","YES"));
new_disk.insert(make_pair("CLONE","YES"));
new_disk.insert(make_pair("SAVE","NO"));
break;
}
//---------------------------------------------------------------------------
// TARGET attribute
//---------------------------------------------------------------------------
switch(type)
{
case OS:
prefix += "a";
break;
case CDROM:
prefix += "c"; // b is for context
break;
case DATABLOCK:
prefix += static_cast<char>(('d'+ *index));
*index = *index + 1;
break;
}
new_disk.insert(make_pair("TARGET", prefix));
disk->replace(new_disk);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string Image::sha1_digest(const string& pass)
{
EVP_MD_CTX mdctx;
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len;
ostringstream oss;
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, EVP_sha1(), NULL);
EVP_DigestUpdate(&mdctx, pass.c_str(), pass.length());
EVP_DigestFinal_ex(&mdctx,md_value,&md_len);
EVP_MD_CTX_cleanup(&mdctx);
for(unsigned int i = 0; i<md_len; i++)
{
oss << setfill('0') << setw(2) << hex << nouppercase
<< (unsigned short) md_value[i];
}
return oss.str();
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */

189
src/image/ImagePool.cc Normal file
View File

@ -0,0 +1,189 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
/* ************************************************************************** */
/* Image Pool */
/* ************************************************************************** */
#include "ImagePool.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string ImagePool::_source_prefix;
string ImagePool::_default_type;
string ImagePool::_default_dev_prefix;
int ImagePool::init_cb(void *nil, int num, char **values, char **names)
{
if ( num == 0 || values == 0 || values[0] == 0 )
{
return -1;
}
image_names.insert(make_pair(values[1],atoi(values[0])));
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
ImagePool::ImagePool( SqlDB * db,
const string& __source_prefix,
const string& __default_type,
const string& __default_dev_prefix):
PoolSQL(db,Image::table)
{
ostringstream sql;
int rc;
// Init static defaults
_source_prefix = __source_prefix;
_default_type = __default_type;
_default_dev_prefix = __default_dev_prefix;
// Set default type
if (_default_type != "OS" &&
_default_type != "CDROM" &&
_default_type != "DATABLOCK" )
{
NebulaLog::log("IMG", Log::ERROR,
"Bad default for image type, setting OS");
_default_type = "OS";
}
// Read from the DB the existing images, and build the ID:Name map
set_callback(static_cast<Callbackable::Callback>(&ImagePool::init_cb));
sql << "SELECT oid, name FROM " << Image::table;
rc = db->exec(sql, this);
unset_callback();
if ( rc != 0 )
{
NebulaLog::log("IMG", Log::ERROR,
"Could not load the existing images from the DB.");
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int ImagePool::allocate (
int uid,
const string& stemplate,
int * oid)
{
int rc;
Image * img;
string name;
char * error_msg;
// ---------------------------------------------------------------------
// Build a new Image object
// ---------------------------------------------------------------------
img = new Image(uid);
// ---------------------------------------------------------------------
// Parse template
// ---------------------------------------------------------------------
rc = img->image_template.parse(stemplate, &error_msg);
if ( rc != 0 )
{
ostringstream oss;
oss << "ImagePool template parse error: " << error_msg;
NebulaLog::log("IMG", Log::ERROR, oss);
free(error_msg);
delete img;
return -1;
}
img->get_template_attribute("NAME", name);
// ---------------------------------------------------------------------
// Insert the Object in the pool
// ---------------------------------------------------------------------
*oid = PoolSQL::allocate(img);
if ( *oid == -1 )
{
return -1;
}
// ---------------------------------------------------------------------
// Add the image name to the map of image_names
// ---------------------------------------------------------------------
image_names.insert(make_pair(name, *oid));
return *oid;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int ImagePool::dump_cb(void * _oss, int num, char **values, char **names)
{
ostringstream * oss;
oss = static_cast<ostringstream *>(_oss);
return Image::dump(*oss, num, values, names);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int ImagePool::dump(ostringstream& oss, const string& where)
{
int rc;
ostringstream cmd;
oss << "<IMAGE_POOL>";
set_callback(static_cast<Callbackable::Callback>(&ImagePool::dump_cb),
static_cast<void *>(&oss));
cmd << "SELECT " << Image::table << ".*, user_pool.user_name FROM "
<< Image::table
<< " LEFT OUTER JOIN (SELECT oid, user_name FROM user_pool) "
<< "AS user_pool ON " << Image::table << ".uid = user_pool.oid";
if ( !where.empty() )
{
cmd << " WHERE " << where;
}
rc = db->exec(cmd, this);
oss << "</IMAGE_POOL>";
unset_callback();
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -0,0 +1,22 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "ImageTemplate.h"
const char * ImageTemplate::table = "image_attributes";
const char * ImageTemplate::db_bootstrap = "CREATE TABLE IF NOT EXISTS"
" image_attributes (id INTEGER, name TEXT, type INTEGER, value TEXT)";

31
src/image/SConstruct Normal file
View File

@ -0,0 +1,31 @@
# SConstruct for src/vm
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #
Import('env')
lib_name='nebula_image'
# Sources to generate the library
source_files=[
'ImageTemplate.cc',
'Image.cc',
'ImagePool.cc'
]
# Build library
env.StaticLibrary(lib_name, source_files)

View File

@ -0,0 +1,832 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include <string>
#include <iostream>
#include <stdlib.h>
#include "ImagePool.h"
#include "PoolTest.h"
using namespace std;
const int uids[] = {0,1,2};
const string names[] = {"Image one", "Second Image", "The third image"};
const string templates[] =
{
"NAME = \"Image one\"\n"
"ORIGINAL_PATH = /tmp/image_test\n"
"DESCRIPTION = \"This is a very long description of an image, and to achieve the longness I will copy this over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over.This is a very long description of an image, and to achieve the longness I will copy this over.\"\n",
"NAME = \"Second Image\"\n"
"ORIGINAL_PATH = /tmp/image_second_test\n"
"PUBLIC = YES\n"
"DESCRIPTION = \"This is a rather short description.\"\n",
"NAME = \"The third image\"\n"
"ORIGINAL_PATH = /tmp/image_test\n"
"# DESCRIPTION = \"An image description\"\n"
"BUS = SCSI\n"
"PROFILE = STUDENT\n"
};
const string xmls[] =
{
"<IMAGE><ID>0</ID><UID>0</UID><NAME>Image one</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a very long description of an image, and to achieve the longness I will copy this over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over.This is a very long description of an image, and to achieve the longness I will copy this over.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Image one]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE>",
"<IMAGE><ID>1</ID><UID>1</UID><NAME>Second Image</NAME><TYPE>0</TYPE><PUBLIC>1</PUBLIC><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f3</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a rather short description.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Second Image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_second_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE>",
"<IMAGE><ID>0</ID><UID>2</UID><NAME>The third image</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/e50b0c738be9d431475bf5859629e5580301a7d6</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><BUS><![CDATA[SCSI]]></BUS><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[The third image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH><PROFILE><![CDATA[STUDENT]]></PROFILE></TEMPLATE></IMAGE>"
};
// This xml dump result has the STIMEs modified to 0000000000
const string xml_dump =
"<IMAGE_POOL><IMAGE><ID>0</ID><UID>0</UID><USERNAME>one_user_test</USERNAME><NAME>Image one</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS></IMAGE><IMAGE><ID>1</ID><UID>1</UID><USERNAME>A user</USERNAME><NAME>Second Image</NAME><TYPE>0</TYPE><PUBLIC>1</PUBLIC><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f3</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS></IMAGE><IMAGE><ID>2</ID><UID>2</UID><USERNAME>B user</USERNAME><NAME>The third image</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/e50b0c738be9d431475bf5859629e5580301a7d6</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS></IMAGE></IMAGE_POOL>";
const string xml_dump_where =
"<IMAGE_POOL><IMAGE><ID>0</ID><UID>0</UID><USERNAME>one_user_test</USERNAME><NAME>Image one</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS></IMAGE><IMAGE><ID>1</ID><UID>1</UID><USERNAME>A user</USERNAME><NAME>Second Image</NAME><TYPE>0</TYPE><PUBLIC>1</PUBLIC><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f3</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS></IMAGE></IMAGE_POOL>";
const string replacement = "0000000000";
/* ************************************************************************* */
/* ************************************************************************* */
class ImagePoolTest : public PoolTest
{
CPPUNIT_TEST_SUITE (ImagePoolTest);
ALL_POOLTEST_CPPUNIT_TESTS();
CPPUNIT_TEST ( names_initialization );
CPPUNIT_TEST ( update );
CPPUNIT_TEST ( get_using_name );
CPPUNIT_TEST ( wrong_get_name );
CPPUNIT_TEST ( duplicates );
CPPUNIT_TEST ( extra_attributes );
CPPUNIT_TEST ( wrong_templates );
CPPUNIT_TEST ( target_generation );
CPPUNIT_TEST ( bus_source_assignment );
CPPUNIT_TEST ( public_attribute );
CPPUNIT_TEST ( disk_overwrite );
CPPUNIT_TEST ( dump );
CPPUNIT_TEST ( dump_where );
CPPUNIT_TEST_SUITE_END ();
protected:
void bootstrap(SqlDB* db)
{
ImagePool::bootstrap(db);
};
PoolSQL* create_pool(SqlDB* db)
{
return new ImagePool(db, "source_prefix", "OS", "hd");
};
int allocate(int index)
{
int oid;
return ((ImagePool*)pool)->allocate(uids[index],
templates[index],
&oid);
};
void check(int index, PoolObjectSQL* obj)
{
CPPUNIT_ASSERT( obj != 0 );
string xml_str = "";
// Get the xml and replace the REGTIME to 0, so we can compare
// it.
((Image*)obj)->to_xml(xml_str);
xml_str.replace( xml_str.find("<REGTIME>")+9, 10, replacement);
//cout << endl << xml_str << endl << xmls[index] << endl;
CPPUNIT_ASSERT( ((Image*)obj)->get_name() == names[index] );
CPPUNIT_ASSERT( xml_str == xmls[index]);
};
void set_up_user_pool()
{
// The UserPool constructor checks if the DB contains at least
// one user, and adds one automatically from the ONE_AUTH file.
// So the ONE_AUTH environment is forced to point to a test one_auth
// file.
ostringstream oss;
oss << getenv("PWD") << "/one_auth";
setenv("ONE_AUTH", oss.str().c_str(), 1);
UserPool::bootstrap(db);
UserPool * user_pool = new UserPool(db);
int uid_1, uid_2;
string username_1 = "A user";
string username_2 = "B user";
string pass_1 = "A pass";
string pass_2 = "B pass";
user_pool->allocate(&uid_1, username_1, pass_1, true);
user_pool->allocate(&uid_2, username_2, pass_2, true);
delete user_pool;
};
public:
ImagePoolTest(){};
~ImagePoolTest(){};
/* ********************************************************************* */
void names_initialization()
{
ImagePool * imp;
Image * img;
// Allocate 2 users, so they are written to the DB.
allocate(0);
allocate(2);
// Create a new pool, using the same DB. This new pool should read the
// allocated images.
imp = new ImagePool(db, "source_prefix", "OS", "hd");
img = imp->get(names[0], false);
CPPUNIT_ASSERT( img != 0 );
img = imp->get(names[1], false);
CPPUNIT_ASSERT( img == 0 );
img = imp->get(names[2], false);
CPPUNIT_ASSERT( img != 0 );
delete imp;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void update()
{
string description_name = "DESCRIPTION";
string description_val = "";
string new_description = "A new description";
string attr_name = "NEW_ATTRIBUTE";
string attr_val = "";
string new_attr_value = "New value";
string no_value = "Some random value";
ImagePool * ip;
Image * img;
int oid_1;
ip = static_cast<ImagePool *>(pool);
oid_1 = allocate(0);
img = ip->get(oid_1, true);
CPPUNIT_ASSERT( img != 0 );
// Image object should be cached. Let's change some template attributes
ip->replace_attribute(img, description_name, new_description);
ip->replace_attribute(img, attr_name, new_attr_value);
ip->remove_attribute(img, "ORIGINAL_PATH");
img->unlock();
img = ip->get(oid_1,false);
CPPUNIT_ASSERT( img != 0 );
img->get_template_attribute("DESCRIPTION", description_val);
img->get_template_attribute("NEW_ATTRIBUTE", attr_val);
img->get_template_attribute("ORIGINAL_PATH", no_value);
CPPUNIT_ASSERT( description_val == new_description );
CPPUNIT_ASSERT( attr_val == new_attr_value );
CPPUNIT_ASSERT( no_value == "" );
//Now force access to DB
pool->clean();
img = ip->get(oid_1,false);
CPPUNIT_ASSERT( img != 0 );
description_val = "";
attr_val = "";
no_value = "Random value";
img->get_template_attribute("DESCRIPTION", description_val);
img->get_template_attribute("NEW_ATTRIBUTE", attr_val);
img->get_template_attribute("ORIGINAL_PATH", no_value);
CPPUNIT_ASSERT( description_val == new_description );
CPPUNIT_ASSERT( attr_val == new_attr_value );
CPPUNIT_ASSERT( no_value == "" );
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void get_using_name()
{
int oid_0, oid_1;
ImagePool * imp = static_cast<ImagePool *>(pool);
// Allocate two objects
oid_0 = allocate(0);
oid_1 = allocate(1);
// ---------------------------------
// Get first object and check its integrity
obj = pool->get(oid_0, false);
CPPUNIT_ASSERT( obj != 0 );
check(0, obj);
// Get using its name
obj = imp->get(names[1], true);
CPPUNIT_ASSERT( obj != 0 );
obj->unlock();
check(1, obj);
// ---------------------------------
// Clean the cache, forcing the pool to read the objects from the DB
pool->clean();
// Get first object and check its integrity
obj = imp->get(names[0], false);
check(0, obj);
// Get using its name
obj = imp->get(oid_1, false);
check(1, obj);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void wrong_get_name()
{
ImagePool * imp = static_cast<ImagePool *>(pool);
// The pool is empty
// Non existing name
obj = imp->get("Wrong name", true);
CPPUNIT_ASSERT( obj == 0 );
// Allocate an object
allocate(0);
// Ask again for a non-existing name
obj = imp->get("Non existing name", true);
CPPUNIT_ASSERT( obj == 0 );
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void duplicates()
{
int rc, oid;
ImagePool * imp = static_cast<ImagePool *>(pool);
// Allocate an image.
rc = imp->allocate(uids[0], templates[0], &oid);
CPPUNIT_ASSERT( oid == 0 );
CPPUNIT_ASSERT( oid == rc );
// Try to allocate twice the same image, should fail
rc = imp->allocate(uids[0], templates[0], &oid);
CPPUNIT_ASSERT( rc == -1 );
CPPUNIT_ASSERT( oid == rc );
// Try again, with different uid
rc = imp->allocate(uids[1], templates[0], &oid);
CPPUNIT_ASSERT( rc == -1 );
CPPUNIT_ASSERT( oid == rc );
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void extra_attributes()
{
int oid;
string value = "";
Image * img;
// The third template doen't have a description, but has some
// extra attibutes
oid = allocate(2);
CPPUNIT_ASSERT( oid == 0 );
pool->clean();
img = ((ImagePool*)pool)->get(oid, false);
check(2, img);
img->get_template_attribute("DESCRIPTION", value);
CPPUNIT_ASSERT( value == "" );
img->get_template_attribute("PROFILE", value);
CPPUNIT_ASSERT( value == "STUDENT" );
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void wrong_templates()
{
int rc;
ImagePool * imp = static_cast<ImagePool *>(pool);
string templates[] =
{
"ORIGINAL_PATH = /tmp/image_test\n"
"DESCRIPTION = \"This template lacks name!\"\n",
"NAME = \"name A\"\n"
"ORIGINAL_PATH = /tmp/image_test\n"
"TYPE = WRONG\n",
"NAME \"PARSE ERROR\"\n"
"TYPE = WRONG\n",
"END"
};
int results[] = { -1, -1, -1 };
int i = 0;
while( templates[i] != "END" )
{
imp->allocate(0, templates[i], &rc);
//cout << endl << i << " - rc: " << rc << " expected: "
// << results[i] << endl;
CPPUNIT_ASSERT( rc == results[i] );
i++;
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void target_generation()
{
ImagePool * imp = static_cast<ImagePool *>(pool);
Image * img;
VectorAttribute * disk;
int oid;
string value;
int index=0;
disk = new VectorAttribute("DISK");
// Allocate an OS type image
oid = allocate(0);
img = imp->get(oid, false);
CPPUNIT_ASSERT( img != 0 );
CPPUNIT_ASSERT( oid == 0 );
img->enable(true);
img->disk_attribute(disk, &index);
value = disk->vector_value("TARGET");
CPPUNIT_ASSERT( value == "hda" );
// clean up
delete disk;
value = "";
disk = new VectorAttribute("DISK");
// Allocate a CDROM type image
string templ = "NAME = \"name A\" TYPE = CDROM ORIGINAL_PATH = /tmp";
imp->allocate(0, templ, &oid);
CPPUNIT_ASSERT(oid >= 0);
img = imp->get(oid, false);
img->enable(true);
img->disk_attribute(disk, &index);
value = disk->vector_value("TARGET");
CPPUNIT_ASSERT(value == "hdc");
// clean up
delete disk;
value = "";
disk = new VectorAttribute("DISK");
// Allocate a DATABLOCK type image
templ = "NAME = \"name B\" TYPE = DATABLOCK";
imp->allocate(0, templ, &oid);
CPPUNIT_ASSERT(oid >= 0);
img = imp->get(oid, false);
img->enable(true);
img->disk_attribute(disk, &index);
value = disk->vector_value("TARGET");
CPPUNIT_ASSERT(value == "hdd");
// clean up
delete disk;
value = "";
disk = new VectorAttribute("DISK");
// Allocate a DATABLOCK type image
templ = "NAME = \"name C\" TYPE = DATABLOCK DEV_PREFIX = \"sd\"";
imp->allocate(0, templ, &oid);
CPPUNIT_ASSERT(oid >= 0);
img = imp->get(oid, false);
img->enable(true);
img->disk_attribute(disk, &index);
value = disk->vector_value("TARGET");
CPPUNIT_ASSERT(value == "sde");
// clean up
delete disk;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void bus_source_assignment()
{
ImagePool * imp = static_cast<ImagePool *>(pool);
Image * img;
VectorAttribute * disk;
int oid;
string value;
int index = 0;
// Allocate an OS type image
oid = allocate(0);
img = imp->get(oid, false);
// ---------------------------------------------------------------------
// A disk without a BUS attribute should not have it added.
disk = new VectorAttribute("DISK");
img->enable(true);
img->disk_attribute(disk, &index);
value = "";
value = disk->vector_value("BUS");
CPPUNIT_ASSERT( value == "" );
value = "";
value = disk->vector_value("SOURCE");
CPPUNIT_ASSERT( value ==
"source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198" );
// clean up
delete disk;
// ---------------------------------------------------------------------
// A disk with a BUS attribute should not have it overwritten.
disk = new VectorAttribute("DISK");
disk->replace("BUS", "SCSI");
img->enable(true);
img->disk_attribute(disk, &index);
value = disk->vector_value("BUS");
CPPUNIT_ASSERT( value == "SCSI" );
value = "";
value = disk->vector_value("SOURCE");
CPPUNIT_ASSERT( value ==
"source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198" );
// clean up
delete disk;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void disk_overwrite()
{
ImagePool * imp = static_cast<ImagePool *>(pool);
Image * img;
VectorAttribute * disk;
int oid, rc;
string value;
int index = 0;
// ---------------------------------------------------------------------
// Allocate an OS type image
oid = allocate(0);
CPPUNIT_ASSERT( oid > -1 );
img = imp->get(oid, false);
// Disk with overwrite=yes, save_as empty
disk = new VectorAttribute("DISK");
disk->replace("OVERWRITE", "yes");
img->enable(true);
rc = img->disk_attribute(disk, &index);
CPPUNIT_ASSERT( rc == 0 );
value = disk->vector_value("OVERWRITE");
CPPUNIT_ASSERT( value == "YES" );
value = "";
value = disk->vector_value("SAVE_AS");
CPPUNIT_ASSERT( value == "" );
value = "";
value = disk->vector_value("CLONE");
CPPUNIT_ASSERT( value == "NO" );
value = "";
value = disk->vector_value("SAVE");
CPPUNIT_ASSERT( value == "YES" );
value = "";
value = disk->vector_value("READONLY");
CPPUNIT_ASSERT( value == "NO" );
// clean up
delete disk;
// ---------------------------------------------------------------------
// Allocate an OS type image
oid = allocate(1);
CPPUNIT_ASSERT( oid > -1 );
img = imp->get(oid, false);
// Disk with overwrite=no, save_as not empty
disk = new VectorAttribute("DISK");
disk->replace("OVERWRITE", "NO");
disk->replace("SAVE_AS", "path_to_save");
img->enable(true);
rc = img->disk_attribute(disk, &index);
CPPUNIT_ASSERT( rc == 0 );
value = "";
value = disk->vector_value("OVERWRITE");
CPPUNIT_ASSERT( value == "NO" );
value = "";
value = disk->vector_value("SAVE_AS");
CPPUNIT_ASSERT( value == "path_to_save" );
value = "";
value = disk->vector_value("CLONE");
CPPUNIT_ASSERT( value == "YES" );
value = "";
value = disk->vector_value("SAVE");
CPPUNIT_ASSERT( value == "YES" );
value = "";
value = disk->vector_value("READONLY");
CPPUNIT_ASSERT( value == "NO" );
// clean up
delete disk;
// ---------------------------------------------------------------------
// Allocate an OS type image
oid = allocate(2);
CPPUNIT_ASSERT( oid > -1 );
img = imp->get(oid, false);
// Disk with overwrite=no, save_as not present
disk = new VectorAttribute("DISK");
disk->replace("OVERWRITE", "NO");
img->enable(true);
rc = img->disk_attribute(disk, &index);
CPPUNIT_ASSERT( rc == 0 );
value = "";
value = disk->vector_value("OVERWRITE");
CPPUNIT_ASSERT( value == "NO" );
value = "";
value = disk->vector_value("SAVE_AS");
CPPUNIT_ASSERT( value == "" );
value = "";
value = disk->vector_value("CLONE");
CPPUNIT_ASSERT( value == "YES" );
value = "";
value = disk->vector_value("SAVE");
CPPUNIT_ASSERT( value == "NO" );
value = "";
value = disk->vector_value("READONLY");
CPPUNIT_ASSERT( value == "NO" );
// clean up
delete disk;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void public_attribute()
{
int oid;
ImagePool * imp = static_cast<ImagePool *>(pool);
Image * img;
string templates[] =
{
// false
"NAME = \"name A\"\n"
"ORIGINAL_PATH = \"/tmp/nothing\"\n",
// true
"NAME = \"name B\"\n"
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
"PUBLIC = YES",
// false
"NAME = \"name C\"\n"
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
"PUBLIC = NO",
// false
"NAME = \"name D\"\n"
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
"PUBLIC = 1",
// true
"NAME = \"name E\"\n"
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
"PUBLIC = Yes",
// false
"NAME = \"name F\"\n"
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
"PUBLIC = TRUE",
// true
"NAME = \"name G\"\n"
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
"PUBLIC = yes",
// false
"NAME = \"name H\"\n"
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
"PUBLIC = 'YES'",
// true
"NAME = \"name I\"\n"
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
"PUBLIC = \"YES\"",
"END"
};
bool results[] = { false, true, false, false,
true, false, true, false, true };
int i = 0;
while( templates[i] != "END" )
{
imp->allocate(0, templates[i], &oid);
CPPUNIT_ASSERT( oid >= 0 );
img = imp->get( oid, false );
CPPUNIT_ASSERT( img != 0 );
//cout << endl << i << " : exp. " << results[i] << " got " << img->is_public();
CPPUNIT_ASSERT( img->is_public() == results[i] );
i++;
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void dump()
{
ImagePool * imp = static_cast<ImagePool*>(pool);
ostringstream oss;
int rc;
string nan;
set_up_user_pool();
allocate(0);
allocate(1);
allocate(2);
rc = imp->dump(oss,nan);
CPPUNIT_ASSERT(rc == 0);
string result = oss.str();
result.replace(138, 10, replacement);
result.replace(403, 10, replacement);
result.replace(671, 10, replacement);
CPPUNIT_ASSERT( result == xml_dump );
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void dump_where()
{
ImagePool * imp = static_cast<ImagePool*>(pool);
int rc;
ostringstream oss;
ostringstream where;
set_up_user_pool();
allocate(0);
allocate(1);
allocate(2);
where << "uid < 2";
rc = imp->dump(oss, where.str());
CPPUNIT_ASSERT(rc == 0);
string result = oss.str();
result.replace(138, 10, replacement);
result.replace(403, 10, replacement);
CPPUNIT_ASSERT( result == xml_dump_where );
}
/* ********************************************************************* */
};
/* ************************************************************************* */
/* ************************************************************************* */
int main(int argc, char ** argv)
{
return PoolTest::main(argc, argv, ImagePoolTest::suite());
}

102
src/image/test/SConstruct Normal file
View File

@ -0,0 +1,102 @@
# --------------------------------------------------------------------------
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org)
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# --------------------------------------------------------------------------
import os
import sys
import shutil
sys.path.append("../../../share/scons")
from lex_bison import *
# This is the absolute path where the project is located
cwd="../../../"
# Environment that will be applied to each scons child
main_env=Environment()
main_env['ENV']['PATH']=os.environ['PATH']
# Add builders for flex and bison
add_lex(main_env)
add_bison(main_env)
# Include dirs
main_env.Append(CPPPATH=[
cwd + '/include',
cwd + '/include/test',
'/usr/include/cppunit/',
])
# Library dirs
main_env.Append(LIBPATH=[
cwd + '/src/common',
cwd + '/src/log',
cwd + '/src/nebula',
cwd + '/src/sql',
cwd + '/src/pool',
cwd + '/src/template',
cwd + '/src/vm',
cwd + '/src/hm',
cwd + '/src/mad',
cwd + '/src/vnm',
cwd + '/src/um',
cwd + '/src/image',
'/usr/include/openssl/',
])
main_env.Append(LIBS=[
'nebula_image',
'nebula_um',
'nebula_vm',
'nebula_mad',
'nebula_hm',
'nebula_vnm',
'nebula_template',
'nebula_pool',
'nebula_common',
'nebula_log',
'nebula_core',
'nebula_sql',
'cppunit',
'dl',
'pthread',
'crypto',
])
# MYSQL
main_env.Append(LIBPATH=["/usr/lib/mysql"])
main_env.Append(CPPPATH=["/usr/include/mysql"])
sqlite=ARGUMENTS.get('sqlite', 'yes')
if sqlite=='yes':
main_env.Append(CPPFLAGS=["-DSQLITE_DB"])
main_env.Append(LIBS=[ 'sqlite3', ])
# MySQL
mysql=ARGUMENTS.get('mysql', 'no')
if mysql=='yes':
main_env.Append(CPPFLAGS=["-DMYSQL_DB"])
main_env.Append(LIBS=[ 'mysqlclient', ])
# Compile flags
main_env.Append(CPPFLAGS=[
"-g",
"-Wall"
])
# Linking flags
main_env.Append(LDFLAGS=["-g "])
main_env.Program('test','ImagePoolTest.cc')

1
src/image/test/one_auth Normal file
View File

@ -0,0 +1 @@
one_user_test:password

View File

@ -23,29 +23,29 @@ void LifeCycleManager::deploy_action(int vid)
ostringstream os;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_state() == VirtualMachine::ACTIVE )
{
Nebula& nd = Nebula::instance();
TransferManager * tm = nd.get_tm();
time_t thetime = time(0);
int cpu,mem,disk;
VirtualMachine::LcmState vm_state;
TransferManager::Actions tm_action;
//----------------------------------------------------
// PROLOG STATE
//----------------------------------------------------
vm_state = VirtualMachine::PROLOG;
tm_action = TransferManager::PROLOG;
if (vm->hasPreviousHistory())
{
if (vm->get_previous_reason() == History::STOP_RESUME)
@ -56,21 +56,21 @@ void LifeCycleManager::deploy_action(int vid)
}
vm->set_state(vm_state);
vmpool->update(vm);
vm->set_stime(thetime);
vm->set_prolog_stime(thetime);
vm->set_prolog_stime(thetime);
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->add_capacity(vm->get_hid(),cpu,mem,disk);
vm->log("LCM", Log::INFO, "New VM state is PROLOG.");
//----------------------------------------------------
tm->trigger(tm_action,vid);
@ -79,9 +79,9 @@ void LifeCycleManager::deploy_action(int vid)
{
vm->log("LCM", Log::ERROR, "deploy_action, VM in a wrong state.");
}
vm->unlock();
return;
}
@ -91,14 +91,14 @@ void LifeCycleManager::deploy_action(int vid)
void LifeCycleManager::suspend_action(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if (vm->get_state() == VirtualMachine::ACTIVE &&
vm->get_lcm_state() == VirtualMachine::RUNNING)
{
@ -108,24 +108,24 @@ void LifeCycleManager::suspend_action(int vid)
//----------------------------------------------------
// SAVE_SUSPEND STATE
//----------------------------------------------------
vm->set_state(VirtualMachine::SAVE_SUSPEND);
vmpool->update(vm);
vm->log("LCM", Log::INFO, "New VM state is SAVE_SUSPEND");
//----------------------------------------------------
vmm->trigger(VirtualMachineManager::SAVE,vid);
vmm->trigger(VirtualMachineManager::SAVE,vid);
}
else
{
vm->log("LCM", Log::ERROR, "suspend_action, VM in a wrong state.");
}
vm->unlock();
return;
}
@ -135,14 +135,14 @@ void LifeCycleManager::suspend_action(int vid)
void LifeCycleManager::stop_action(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if (vm->get_state() == VirtualMachine::ACTIVE &&
vm->get_lcm_state() == VirtualMachine::RUNNING)
{
@ -154,22 +154,22 @@ void LifeCycleManager::stop_action(int vid)
//----------------------------------------------------
vm->set_state(VirtualMachine::SAVE_STOP);
vmpool->update(vm);
vm->log("LCM", Log::INFO, "New VM state is SAVE_STOP");
//----------------------------------------------------
vmm->trigger(VirtualMachineManager::SAVE,vid);
vmm->trigger(VirtualMachineManager::SAVE,vid);
}
else
{
vm->log("LCM", Log::ERROR, "stop_action, VM in a wrong state.");
vm->log("LCM", Log::ERROR, "stop_action, VM in a wrong state.");
}
vm->unlock();
return;
}
@ -179,50 +179,50 @@ void LifeCycleManager::stop_action(int vid)
void LifeCycleManager::migrate_action(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if (vm->get_state() == VirtualMachine::ACTIVE &&
vm->get_lcm_state() == VirtualMachine::RUNNING)
{
Nebula& nd = Nebula::instance();
VirtualMachineManager * vmm = nd.get_vmm();
int cpu,mem,disk;
//----------------------------------------------------
// SAVE_MIGRATE STATE
//----------------------------------------------------
vm->set_state(VirtualMachine::SAVE_MIGRATE);
vmpool->update(vm);
vm->set_stime(time(0));
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->add_capacity(vm->get_hid(),cpu,mem,disk);
vm->log("LCM", Log::INFO, "New VM state is SAVE_MIGRATE");
//----------------------------------------------------
vmm->trigger(VirtualMachineManager::SAVE,vid);
vmm->trigger(VirtualMachineManager::SAVE,vid);
}
else
{
vm->log("LCM", Log::ERROR, "migrate_action, VM in a wrong state.");
}
vm->unlock();
return;
}
@ -233,21 +233,21 @@ void LifeCycleManager::live_migrate_action(int vid)
{
VirtualMachine * vm;
ostringstream os;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if (vm->get_state() == VirtualMachine::ACTIVE &&
vm->get_lcm_state() == VirtualMachine::RUNNING)
{
Nebula& nd = Nebula::instance();
VirtualMachineManager * vmm = nd.get_vmm();
int cpu,mem,disk;
//----------------------------------------------------
// MIGRATE STATE
//----------------------------------------------------
@ -257,26 +257,26 @@ void LifeCycleManager::live_migrate_action(int vid)
vmpool->update(vm);
vm->set_stime(time(0));
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->add_capacity(vm->get_hid(),cpu,mem,disk);
vm->log("LCM",Log::INFO,"New VM state is MIGRATE");
//----------------------------------------------------
vmm->trigger(VirtualMachineManager::MIGRATE,vid);
vmm->trigger(VirtualMachineManager::MIGRATE,vid);
}
else
{
vm->log("LCM", Log::ERROR, "live_migrate_action, VM in a wrong state.");
}
vm->unlock();
return;
}
@ -286,14 +286,14 @@ void LifeCycleManager::live_migrate_action(int vid)
void LifeCycleManager::shutdown_action(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if (vm->get_state() == VirtualMachine::ACTIVE &&
vm->get_lcm_state() == VirtualMachine::RUNNING)
{
@ -307,20 +307,20 @@ void LifeCycleManager::shutdown_action(int vid)
vm->set_state(VirtualMachine::SHUTDOWN);
vmpool->update(vm);
vm->log("LCM",Log::INFO,"New VM state is SHUTDOWN");
//----------------------------------------------------
vmm->trigger(VirtualMachineManager::SHUTDOWN,vid);
vmm->trigger(VirtualMachineManager::SHUTDOWN,vid);
}
else
{
vm->log("LCM", Log::ERROR, "shutdown_action, VM in a wrong state.");
}
vm->unlock();
return;
}
@ -331,56 +331,56 @@ void LifeCycleManager::restore_action(int vid)
{
VirtualMachine * vm;
ostringstream os;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if (vm->get_state() == VirtualMachine::ACTIVE)
{
Nebula& nd = Nebula::instance();
VirtualMachineManager * vmm = nd.get_vmm();
int cpu,mem,disk;
time_t the_time = time(0);
vm->log("LCM", Log::INFO, "Restoring VM");
//----------------------------------------------------
// BOOT STATE (FROM SUSPEND)
//----------------------------------------------------
//----------------------------------------------------
vm->set_state(VirtualMachine::BOOT);
vmpool->update(vm);
vm->cp_history();
vmpool->update(vm); //update last_seq & state
vm->set_stime(the_time);
vm->set_running_stime(the_time);
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->add_capacity(vm->get_hid(),cpu,mem,disk);
hpool->add_capacity(vm->get_hid(),cpu,mem,disk);
vm->log("LCM", Log::INFO, "New state is BOOT");
//----------------------------------------------------
vmm->trigger(VirtualMachineManager::RESTORE,vid);
vmm->trigger(VirtualMachineManager::RESTORE,vid);
}
else
{
vm->log("LCM", Log::ERROR, "restore_action, VM in a wrong state.");
}
vm->unlock();
return;
}
@ -390,14 +390,14 @@ void LifeCycleManager::restore_action(int vid)
void LifeCycleManager::cancel_action(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if (vm->get_state() == VirtualMachine::ACTIVE &&
vm->get_lcm_state() == VirtualMachine::RUNNING)
{
@ -409,22 +409,22 @@ void LifeCycleManager::cancel_action(int vid)
//----------------------------------------------------
vm->set_state(VirtualMachine::CANCEL);
vmpool->update(vm);
vm->log("LCM", Log::INFO, "New state is CANCEL");
//----------------------------------------------------
vmm->trigger(VirtualMachineManager::CANCEL,vid);
vmm->trigger(VirtualMachineManager::CANCEL,vid);
}
else
{
vm->log("LCM", Log::ERROR, "cancel_action, VM in a wrong state.");
}
vm->unlock();
return;
}
@ -434,14 +434,14 @@ void LifeCycleManager::cancel_action(int vid)
void LifeCycleManager::restart_action(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if (vm->get_state() == VirtualMachine::ACTIVE &&
(vm->get_lcm_state() == VirtualMachine::UNKNOWN ||
vm->get_lcm_state() == VirtualMachine::BOOT))
@ -452,7 +452,7 @@ void LifeCycleManager::restart_action(int vid)
//----------------------------------------------------
// RE-START THE VM IN THE SAME HOST
//----------------------------------------------------
if (vm->get_lcm_state() == VirtualMachine::BOOT)
{
vm->log("LCM", Log::INFO, "Sending BOOT command to VM again");
@ -460,23 +460,23 @@ void LifeCycleManager::restart_action(int vid)
else
{
vm->set_state(VirtualMachine::BOOT);
vmpool->update(vm);
vm->log("LCM", Log::INFO, "New VM state is BOOT");
}
//----------------------------------------------------
vmm->trigger(VirtualMachineManager::DEPLOY,vid);
vmm->trigger(VirtualMachineManager::DEPLOY,vid);
}
else
{
vm->log("LCM", Log::ERROR, "restart_action, VM in a wrong state.");
}
vm->unlock();
return;
}
@ -489,7 +489,7 @@ void LifeCycleManager::delete_action(int vid)
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
@ -548,7 +548,7 @@ void LifeCycleManager::delete_action(int vid)
tm->trigger(TransferManager::EPILOG_DELETE,vid);
break;
case VirtualMachine::MIGRATE:
vm->set_running_etime(the_time);
vmpool->update_history(vm);
@ -557,8 +557,8 @@ void LifeCycleManager::delete_action(int vid)
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
vmpool->update_previous_history(vm);
hpool->del_capacity(vm->get_previous_hid(),cpu,mem,disk);
hpool->del_capacity(vm->get_previous_hid(),cpu,mem,disk);
vmm->trigger(VirtualMachineManager::DRIVER_CANCEL,vid);
@ -585,8 +585,8 @@ void LifeCycleManager::delete_action(int vid)
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
vmpool->update_previous_history(vm);
hpool->del_capacity(vm->get_previous_hid(),cpu,mem,disk);
hpool->del_capacity(vm->get_previous_hid(),cpu,mem,disk);
vmm->trigger(VirtualMachineManager::DRIVER_CANCEL,vid);
vmm->trigger(VirtualMachineManager::CANCEL_PREVIOUS,vid);

View File

@ -24,49 +24,49 @@ void LifeCycleManager::save_success_action(int vid)
{
VirtualMachine * vm;
ostringstream os;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::SAVE_MIGRATE )
{
Nebula& nd = Nebula::instance();
TransferManager * tm = nd.get_tm();
int cpu,mem,disk;
time_t the_time = time(0);
//----------------------------------------------------
// PROLOG_MIGRATE STATE
//----------------------------------------------------
vm->set_state(VirtualMachine::PROLOG_MIGRATE);
vmpool->update(vm);
vm->set_previous_etime(the_time);
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
vmpool->update_previous_history(vm);
vm->set_prolog_stime(the_time);
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_previous_hid(),cpu,mem,disk);
vm->log("LCM", Log::INFO, "New VM state is PROLOG_MIGRATE");
//----------------------------------------------------
tm->trigger(TransferManager::PROLOG_MIGR,vid);
}
else if ( vm->get_lcm_state() == VirtualMachine::SAVE_SUSPEND)
@ -83,17 +83,17 @@ void LifeCycleManager::save_success_action(int vid)
vm->set_running_etime(the_time);
vm->set_etime(the_time);
vm->set_reason(History::STOP_RESUME);
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_hid(),cpu,mem,disk);
//----------------------------------------------------
dm->trigger(DispatchManager::SUSPEND_SUCCESS,vid);
}
else if ( vm->get_lcm_state() == VirtualMachine::SAVE_STOP)
@ -101,34 +101,34 @@ void LifeCycleManager::save_success_action(int vid)
Nebula& nd = Nebula::instance();
TransferManager * tm = nd.get_tm();
time_t the_time = time(0);
//----------------------------------------------------
// EPILOG_STOP STATE
//----------------------------------------------------
vm->set_state(VirtualMachine::EPILOG_STOP);
vmpool->update(vm);
vm->set_epilog_stime(the_time);
vm->set_running_etime(the_time);
vm->set_running_etime(the_time);
vm->set_reason(History::STOP_RESUME);
vmpool->update_history(vm);
vm->log("LCM", Log::INFO, "New VM state is EPILOG_STOP");
//----------------------------------------------------
tm->trigger(TransferManager::EPILOG_STOP,vid);
}
else
{
vm->log("LCM",Log::ERROR,"save_success_action, VM in a wrong state");
}
vm->unlock();
}
@ -138,69 +138,69 @@ void LifeCycleManager::save_success_action(int vid)
void LifeCycleManager::save_failure_action(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::SAVE_MIGRATE )
{
int cpu,mem,disk;
time_t the_time = time(0);
Nebula& nd = Nebula::instance();
Nebula& nd = Nebula::instance();
VirtualMachineManager * vmm = nd.get_vmm();
//----------------------------------------------------
// RUNNING STATE FROM SAVE_MIGRATE
//----------------------------------------------------
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
vm->set_etime(the_time);
vm->set_reason(History::ERROR);
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_hid(),cpu,mem,disk);
vm->set_previous_etime(the_time);
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
vmpool->update_previous_history(vm);
// --- Add new record by copying the previous one
vm->set_previous_etime(the_time);
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
vmpool->update_previous_history(vm);
// --- Add new record by copying the previous one
vm->cp_previous_history();
vmpool->update(vm); //update last_seq & state
vm->set_stime(the_time);
vm->set_running_stime(the_time);
vmpool->update_history(vm);
vm->log("LCM", Log::INFO, "Fail to save VM state while migrating."
" Assuming that the VM is still RUNNING (will poll VM).");
//----------------------------------------------------
vmm->trigger(VirtualMachineManager::POLL,vid);
vmm->trigger(VirtualMachineManager::POLL,vid);
}
else if ( vm->get_lcm_state() == VirtualMachine::SAVE_SUSPEND ||
vm->get_lcm_state() == VirtualMachine::SAVE_STOP )
{
Nebula& nd = Nebula::instance();
Nebula& nd = Nebula::instance();
VirtualMachineManager * vmm = nd.get_vmm();
//----------------------------------------------------
@ -208,14 +208,14 @@ void LifeCycleManager::save_failure_action(int vid)
//----------------------------------------------------
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
vm->log("LCM", Log::INFO, "Fail to save VM state."
" Assuming that the VM is still RUNNING (will poll VM).");
//----------------------------------------------------
vmm->trigger(VirtualMachineManager::POLL,vid);
}
@ -228,9 +228,9 @@ void LifeCycleManager::save_failure_action(int vid)
void LifeCycleManager::deploy_success_action(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
@ -244,30 +244,30 @@ void LifeCycleManager::deploy_success_action(int vid)
{
int cpu,mem,disk;
time_t the_time = time(0);
vm->set_running_stime(the_time);
vmpool->update_history(vm);
vm->set_previous_etime(the_time);
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
vmpool->update_previous_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_previous_hid(),cpu,mem,disk);
hpool->del_capacity(vm->get_previous_hid(),cpu,mem,disk);
}
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
vm->log("LCM", Log::INFO, "New VM state is RUNNING");
vm->unlock();
}
@ -276,11 +276,11 @@ void LifeCycleManager::deploy_success_action(int vid)
void LifeCycleManager::deploy_failure_action(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
@ -290,52 +290,52 @@ void LifeCycleManager::deploy_failure_action(int vid)
{
int cpu,mem,disk;
time_t the_time = time(0);
Nebula& nd = Nebula::instance();
VirtualMachineManager * vmm = nd.get_vmm();
//----------------------------------------------------
// RUNNING STATE FROM MIGRATE
//----------------------------------------------------
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
vm->set_etime(the_time);
vm->set_reason(History::ERROR);
vmpool->update_history(vm);
vm->set_previous_etime(the_time);
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
vmpool->update_previous_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_hid(),cpu,mem,disk);
// --- Add new record by copying the previous one
vm->set_reason(History::ERROR);
vm->set_previous_etime(the_time);
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
vmpool->update_previous_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_hid(),cpu,mem,disk);
// --- Add new record by copying the previous one
vm->cp_previous_history();
vmpool->update(vm); //update last_seq & state
vm->set_stime(the_time);
vm->set_running_stime(the_time);
vmpool->update_history(vm);
vm->log("LCM", Log::INFO, "Fail to life migrate VM."
" Assuming that the VM is still RUNNING (will poll VM).");
" Assuming that the VM is still RUNNING (will poll VM).");
//----------------------------------------------------
vmm->trigger(VirtualMachineManager::POLL,vid);
vmm->trigger(VirtualMachineManager::POLL,vid);
}
else if (vm->get_lcm_state() == VirtualMachine::BOOT)
{
@ -345,7 +345,7 @@ void LifeCycleManager::deploy_failure_action(int vid)
failure_action(vm);
}
vm->unlock();
}
@ -358,35 +358,35 @@ void LifeCycleManager::shutdown_success_action(int vid)
TransferManager * tm = nd.get_tm();
VirtualMachine * vm;
time_t the_time = time(0);
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
//----------------------------------------------------
// EPILOG STATE
//----------------------------------------------------
vm->set_state(VirtualMachine::EPILOG);
vmpool->update(vm);
vm->set_epilog_stime(the_time);
vm->set_running_etime(the_time);
vmpool->update_history(vm);
vm->log("LCM", Log::INFO, "New VM state is EPILOG");
//----------------------------------------------------
tm->trigger(TransferManager::EPILOG,vid);
vm->unlock();
vm->unlock();
}
/* -------------------------------------------------------------------------- */
@ -395,33 +395,33 @@ void LifeCycleManager::shutdown_success_action(int vid)
void LifeCycleManager::shutdown_failure_action(int vid)
{
VirtualMachine * vm;
Nebula& nd = Nebula::instance();
Nebula& nd = Nebula::instance();
VirtualMachineManager * vmm = nd.get_vmm();
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
//----------------------------------------------------
// RUNNING STATE FROM SHUTDOWN
//----------------------------------------------------
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
vm->log("LCM", Log::INFO, "Fail to shutdown VM."
" Assuming that the VM is still RUNNING (will poll VM).");
//----------------------------------------------------
vmm->trigger(VirtualMachineManager::POLL,vid);
vm->unlock();
vm->unlock();
}
/* -------------------------------------------------------------------------- */
@ -434,31 +434,31 @@ void LifeCycleManager::prolog_success_action(int vid)
VirtualMachine * vm;
time_t the_time = time(0);
ostringstream os;
VirtualMachineManager::Actions action;
VirtualMachine::LcmState lcm_state;
vm = vmpool->get(vid, true);
if ( vm == 0 )
{
return;
}
lcm_state = vm->get_lcm_state();
lcm_state = vm->get_lcm_state();
if (lcm_state == VirtualMachine::PROLOG)
{
action = VirtualMachineManager::DEPLOY;
action = VirtualMachineManager::DEPLOY;
}
else if ( lcm_state == VirtualMachine::PROLOG_MIGRATE ||
lcm_state == VirtualMachine::PROLOG_RESUME )
{
action = VirtualMachineManager::RESTORE;
action = VirtualMachineManager::RESTORE;
}
else
{
vm->log("LCM",Log::ERROR,"prolog_success_action, VM in a wrong state");
vm->log("LCM",Log::ERROR,"prolog_success_action, VM in a wrong state");
vm->unlock();
return;
@ -469,23 +469,23 @@ void LifeCycleManager::prolog_success_action(int vid)
//----------------------------------------------------
vm->set_state(VirtualMachine::BOOT);
vmpool->update(vm);
vm->set_prolog_etime(the_time);
vm->set_running_stime(the_time);
vmpool->update_history(vm);
vm->log("LCM", Log::INFO, "New VM state is BOOT");
//----------------------------------------------------
vmm->trigger(action,vid);
vm->unlock();
return;
}
@ -498,19 +498,19 @@ void LifeCycleManager::prolog_failure_action(int vid)
time_t the_time = time(0);
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
vm->set_prolog_etime(the_time);
failure_action(vm);
vm->unlock();
return;
return;
}
/* -------------------------------------------------------------------------- */
@ -520,20 +520,20 @@ void LifeCycleManager::epilog_success_action(int vid)
{
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
VirtualMachine * vm;
time_t the_time = time(0);
int cpu,mem,disk;
DispatchManager::Actions action;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::EPILOG_STOP )
{
action = DispatchManager::STOP_SUCCESS;
@ -549,23 +549,23 @@ void LifeCycleManager::epilog_success_action(int vid)
return;
}
vm->set_epilog_etime(the_time);
vm->set_etime(the_time);
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_hid(),cpu,mem,disk);
//----------------------------------------------------
dm->trigger(action,vid);
vm->unlock();
return;
}
@ -576,21 +576,21 @@ void LifeCycleManager::epilog_failure_action(int vid)
{
VirtualMachine * vm;
time_t the_time = time(0);
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
vm->set_epilog_etime(the_time);
failure_action(vm);
vm->unlock();
return;
return;
}
/* -------------------------------------------------------------------------- */
@ -601,31 +601,31 @@ void LifeCycleManager::cancel_success_action(int vid)
VirtualMachine * vm;
time_t the_time = time(0);
int cpu,mem,disk;
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
vm->set_etime(the_time);
vm->set_reason(History::CANCEL);
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_hid(),cpu,mem,disk);
//----------------------------------------------------
dm->trigger(DispatchManager::DONE,vid);
vm->unlock();
}
@ -636,32 +636,32 @@ void LifeCycleManager::cancel_failure_action(int vid)
{
VirtualMachine * vm;
Nebula& nd = Nebula::instance();
Nebula& nd = Nebula::instance();
VirtualMachineManager * vmm = nd.get_vmm();
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
//----------------------------------------------------
// RUNNING STATE FROM CANCEL
//----------------------------------------------------
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
vm->log("LCM", Log::INFO, "Fail to cancel VM."
" Assuming that the VM is still RUNNING (will poll VM).");
//----------------------------------------------------
vmm->trigger(VirtualMachineManager::POLL,vid);
vm->unlock();
vm->unlock();
}
/* -------------------------------------------------------------------------- */
@ -672,14 +672,14 @@ void LifeCycleManager::monitor_failure_action(int vid)
VirtualMachine * vm;
time_t the_time = time(0);
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
vm->set_running_etime(the_time);
failure_action(vm);
@ -699,24 +699,24 @@ void LifeCycleManager::monitor_suspend_action(int vid)
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
vm->set_running_etime(the_time);
vm->set_etime(the_time);
vm->set_reason(History::STOP_RESUME);
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_hid(),cpu,mem,disk);
vm->log("LCM", Log::INFO, "VM is suspended.");
@ -735,27 +735,27 @@ void LifeCycleManager::monitor_suspend_action(int vid)
void LifeCycleManager::monitor_done_action(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
//----------------------------------------------------
// EPILOG STATE
//----------------------------------------------------
vm->set_state(VirtualMachine::UNKNOWN);
vmpool->update(vm);
vm->log("LCM", Log::INFO, "New VM state is UNKNOWN");
//----------------------------------------------------
vm->unlock();
vm->unlock();
}
@ -767,10 +767,10 @@ void LifeCycleManager::failure_action(VirtualMachine * vm)
Nebula& nd = Nebula::instance();
TransferManager * tm = nd.get_tm();
DispatchManager * dm = nd.get_dm();
time_t the_time = time(0);
int cpu,mem,disk;
//----------------------------------------------------
// LCM FAILURE STATE
//----------------------------------------------------
@ -778,15 +778,15 @@ void LifeCycleManager::failure_action(VirtualMachine * vm)
vm->set_state(VirtualMachine::FAILURE);
vmpool->update(vm);
vm->set_etime(the_time);
vm->set_reason(History::ERROR);
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_hid(),cpu,mem,disk);
//------------- Clean up remote files ----------------

View File

@ -102,6 +102,7 @@ class ActionManager
return if @finalize
if aname == :FINALIZE
finalize if respond_to?(:finalize)
@finalize = true
@threads_cond.signal if @num_running == 0
return

View File

@ -205,6 +205,7 @@ void Nebula::start()
HostPool::bootstrap(db);
VirtualNetworkPool::bootstrap(db);
UserPool::bootstrap(db);
ImagePool::bootstrap(db);
}
catch (exception&)
{
@ -213,8 +214,11 @@ void Nebula::start()
try
{
string mac_prefix;
int size;
string mac_prefix;
int size;
string repository_path;
string default_image_type;
string default_device_prefix;
vector<const Attribute *> vm_hooks;
@ -229,6 +233,22 @@ void Nebula::start()
vnpool = new VirtualNetworkPool(db,mac_prefix,size);
upool = new UserPool(db);
nebula_configuration->get("IMAGE_REPOSITORY_PATH", repository_path);
if (repository_path.empty()) // Defaults to ONE_LOCATION/var
{
repository_path = var_location;
}
nebula_configuration->get("DEFAULT_IMAGE_TYPE", default_image_type);
nebula_configuration->get("DEFAULT_DEVICE_PREFIX",
default_device_prefix);
ipool = new ImagePool(db,
repository_path,
default_image_type,
default_device_prefix);
}
catch (exception&)
{
@ -389,6 +409,7 @@ void Nebula::start()
hpool,
vnpool,
upool,
ipool,
rm_port,
log_location + "one_xmlrpc.log");
}

View File

@ -74,6 +74,12 @@ NebulaTemplate::NebulaTemplate(string& etc_location, string& var_location)
attribute = new SingleAttribute("NETWORK_SIZE",value);
conf_default.insert(make_pair(attribute->name(),attribute));
//NETWORK_SIZE
value = "5900";
attribute = new SingleAttribute("VNC_BASE_PORT",value);
conf_default.insert(make_pair(attribute->name(),attribute));
//DEBUG_LEVEL
value = Log::WARNING;

View File

@ -42,6 +42,7 @@ env.Append(LIBS=[
'nebula_um',
'nebula_mad',
'nebula_template',
'nebula_image',
'nebula_pool',
'nebula_host',
'nebula_vnm',

View File

@ -13,6 +13,8 @@ require 'OpenNebula/VirtualMachine'
require 'OpenNebula/VirtualMachinePool'
require 'OpenNebula/VirtualNetwork'
require 'OpenNebula/VirtualNetworkPool'
require 'OpenNebula/Image'
require 'OpenNebula/ImagePool'
require 'OpenNebula/User'
require 'OpenNebula/UserPool'
require 'OpenNebula/Host'

View File

@ -0,0 +1,163 @@
require 'OpenNebula/Pool'
module OpenNebula
class Image < PoolElement
# ---------------------------------------------------------------------
# Constants and Class Methods
# ---------------------------------------------------------------------
IMAGE_METHODS = {
:info => "image.info",
:allocate => "image.allocate",
:update => "image.update",
:rmattr => "image.rmattr",
:enable => "image.enable",
:publish => "image.publish",
:delete => "image.delete"
}
IMAGE_STATES=%w{INIT LOCKED READY USED DISABLED}
SHORT_IMAGE_STATES={
"INIT" => "init",
"LOCKED" => "lock",
"READY" => "rdy",
"USED" => "used",
"DISABLED" => "disa"
}
IMAGE_TYPES=%w{OS CDROM DATABLOCK}
SHORT_IMAGE_TYPES={
"OS" => "OS",
"CDROM" => "CD",
"DATABLOCK" => "DB"
}
# Creates an Image description with just its identifier
# this method should be used to create plain Image objects.
# +id+ the id of the image
#
# Example:
# image = Image.new(Image.build_xml(3),rpc_client)
#
def Image.build_xml(pe_id=nil)
if pe_id
image_xml = "<IMAGE><ID>#{pe_id}</ID></IMAGE>"
else
image_xml = "<IMAGE></IMAGE>"
end
XMLUtilsElement.initialize_xml(image_xml, 'IMAGE')
end
# Class constructor
def initialize(xml, client)
super(xml,client)
@client = client
end
#######################################################################
# XML-RPC Methods for the Image Object
#######################################################################
def info()
super(IMAGE_METHODS[:info], 'IMAGE')
end
def allocate(description)
super(IMAGE_METHODS[:allocate],description)
end
def update(name, value)
super(IMAGE_METHODS[:update], name, value)
end
def remove_attr(name)
do_rm_attr(name)
end
def enable
set_enabled(true)
end
def disable
set_enabled(false)
end
def publish
set_publish(true)
end
def unpublish
set_publish(false)
end
def delete()
super(IMAGE_METHODS[:delete])
end
#######################################################################
# Helpers to get Image information
#######################################################################
# Returns the state of the Image (numeric value)
def state
self['STATE'].to_i
end
# Returns the state of the Image (string value)
def state_str
IMAGE_STATES[state]
end
# Returns the state of the Image (string value)
def short_state_str
SHORT_IMAGE_STATES[state_str]
end
# Returns the type of the Image (numeric value)
def type
self['TYPE'].to_i
end
# Returns the type of the Image (string value)
def type_str
IMAGE_TYPES[type]
end
# Returns the state of the Image (string value)
def short_type_str
SHORT_IMAGE_TYPES[type_str]
end
private
def set_enabled(enabled)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(IMAGE_METHODS[:enable], @pe_id, enabled)
rc = nil if !OpenNebula.is_error?(rc)
return rc
end
def set_publish(published)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(IMAGE_METHODS[:publish], @pe_id, published)
rc = nil if !OpenNebula.is_error?(rc)
return rc
end
def do_rm_attr(name)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(IMAGE_METHODS[:rmattr], @pe_id, name)
rc = nil if !OpenNebula.is_error?(rc)
return rc
end
end
end

View File

@ -0,0 +1,38 @@
require 'OpenNebula/Pool'
module OpenNebula
class ImagePool < Pool
#######################################################################
# Constants and Class attribute accessors
#######################################################################
IMAGE_POOL_METHODS = {
:info => "imagepool.info"
}
#######################################################################
# Class constructor & Pool Methods
#######################################################################
# +client+ a Client object that represents a XML-RPC connection
# +user_id+ is to refer to a Pool with Images from that user
def initialize(client, user_id=0)
super('IMAGE_POOL','IMAGE',client)
@user_id = user_id
end
# Default Factory Method for the Pools
def factory(element_xml)
OpenNebula::Image.new(element_xml,@client)
end
#######################################################################
# XML-RPC Methods for the Image Object
#######################################################################
def info()
super(IMAGE_POOL_METHODS[:info],@user_id)
end
end
end

View File

@ -129,6 +129,21 @@ module OpenNebula
return rc
end
# Calls to the corresponding update method to modify
# the object's template
# xml_method:: _String_ the name of the XML-RPC method
# name:: _String_ the name of the property to be modified
# value:: _String_ the new value of the property to be modified
# [return] nil in case of success or an Error object
def update(xml_method, name, value)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(xml_method,@pe_id, name, value)
rc = nil if !OpenNebula.is_error?(rc)
return rc
end
# Calls to the corresponding delete method to remove this element
# from the OpenNebula core

View File

@ -8,6 +8,7 @@ module OpenNebula
VN_METHODS = {
:info => "vn.info",
:allocate => "vn.allocate",
:publish => "vn.publish",
:delete => "vn.delete"
}
@ -46,9 +47,28 @@ module OpenNebula
def allocate(description)
super(VN_METHODS[:allocate],description)
end
def publish
set_publish(true)
end
def unpublish
set_publish(false)
end
def delete()
super(VN_METHODS[:delete])
end
private
def set_publish(published)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(VN_METHODS[:publish], @pe_id, published)
rc = nil if !OpenNebula.is_error?(rc)
return rc
end
end
end

View File

@ -41,6 +41,9 @@ module OpenNebula
def [](key)
if NOKOGIRI
element=@xml.xpath(key.to_s.upcase)
if element.size == 0
return nil
end
else
element=@xml.elements[key.to_s.upcase]
end
@ -95,18 +98,22 @@ module OpenNebula
end
def to_hash
if !@hash
if !@hash && @xml
@hash=Crack::XML.parse(to_xml)
end
return @hash
end
def to_xml
def to_xml(pretty=false)
if NOKOGIRI
@xml.to_xml
else
str = ""
REXML::Formatters::Pretty.new(1).write(@xml,str)
if pretty
REXML::Formatters::Pretty.new(1).write(@xml,str)
else
REXML::Formatters::Default.new.write(@xml,str)
end
str
end
end
@ -146,18 +153,22 @@ module OpenNebula
end
end
def to_xml
def to_xml(pretty=false)
if NOKOGIRI
@xml.to_xml
else
str = ""
REXML::Formatters::Pretty.new(1).write(@xml,str)
if pretty
REXML::Formatters::Pretty.new(1).write(@xml,str)
else
REXML::Formatters::Default.new.write(@xml,str)
end
str
end
end
def to_hash
if !@hash
if !@hash && @xml
@hash=Crack::XML.parse(to_xml)
end
return @hash

View File

@ -0,0 +1,97 @@
$: << '../'
require 'OpenNebula'
require 'MockClient'
module OpenNebula
describe "Host using NOKOGIRI" do
before(:all) do
NOKOGIRI=true
client = MockClient.new()
@host_pool = HostPool.new(client)
end
it "should update the HOST_POOL info" do
rc = @host_pool.info()
rc.nil?.should eql(true)
end
it "should iterate the HOST_POOL elements and get info from them" do
rc = @host_pool.each{ |host|
host.class.to_s.should eql("OpenNebula::Host")
if host.id == 0
host.name.should eql('dummyhost')
elsif host.id == 1
host.name.should eql('thost')
end
}
end
it "should get a hash representation of the HOST_POOL" do
host_hash = @host_pool.to_hash
host_hash['HOST_POOL']['HOST'][0]['ID'].should eql('0')
host_hash['HOST_POOL']['HOST'][0]['NAME'].should eql('dummyhost')
host_hash['HOST_POOL']['HOST'][0]['STATE'].should eql('2')
host_hash['HOST_POOL']['HOST'][0]['IM_MAD'].should eql('im_dummy')
host_hash['HOST_POOL']['HOST'][0]['HOST_SHARE']['MEM_USAGE'].should eql('1572864')
host_hash['HOST_POOL']['HOST'][0]['HOST_SHARE']['CPU_USAGE'].should eql('300')
host_hash['HOST_POOL']['HOST'][0]['HOST_SHARE']['FREE_MEM'].should eql('16777216')
host_hash['HOST_POOL']['HOST'][0]['HOST_SHARE']['RUNNING_VMS'].should eql('3')
host_hash['HOST_POOL']['HOST'][1]['ID'].should eql('1')
host_hash['HOST_POOL']['HOST'][1]['NAME'].should eql('thost')
host_hash['HOST_POOL']['HOST'][1]['STATE'].should eql('2')
host_hash['HOST_POOL']['HOST'][1]['IM_MAD'].should eql('im_dummy')
host_hash['HOST_POOL']['HOST'][1]['HOST_SHARE']['MEM_USAGE'].should eql('0')
host_hash['HOST_POOL']['HOST'][1]['HOST_SHARE']['CPU_USAGE'].should eql('0')
host_hash['HOST_POOL']['HOST'][1]['HOST_SHARE']['FREE_MEM'].should eql('16777216')
host_hash['HOST_POOL']['HOST'][1]['HOST_SHARE']['RUNNING_VMS'].should eql('0')
end
end
describe "Host using REXML" do
before(:all) do
NOKOGIRI=false
client = MockClient.new()
@host_pool = HostPool.new(client)
end
it "should update the HOST_POOL info" do
rc = @host_pool.info()
rc.nil?.should eql(true)
end
it "should iterate the HOST_POOL elements and get info from them" do
rc = @host_pool.each{ |host|
host.class.to_s.should eql("OpenNebula::Host")
if host.id == 0
host.name.should eql('dummyhost')
elsif host.id == 1
host.name.should eql('thost')
end
}
end
it "should get a hash representation of the HOST_POOL" do
host_hash = @host_pool.to_hash
host_hash['HOST_POOL']['HOST'][0]['ID'].should eql('0')
host_hash['HOST_POOL']['HOST'][0]['NAME'].should eql('dummyhost')
host_hash['HOST_POOL']['HOST'][0]['STATE'].should eql('2')
host_hash['HOST_POOL']['HOST'][0]['IM_MAD'].should eql('im_dummy')
host_hash['HOST_POOL']['HOST'][0]['HOST_SHARE']['MEM_USAGE'].should eql('1572864')
host_hash['HOST_POOL']['HOST'][0]['HOST_SHARE']['CPU_USAGE'].should eql('300')
host_hash['HOST_POOL']['HOST'][0]['HOST_SHARE']['FREE_MEM'].should eql('16777216')
host_hash['HOST_POOL']['HOST'][0]['HOST_SHARE']['RUNNING_VMS'].should eql('3')
host_hash['HOST_POOL']['HOST'][1]['ID'].should eql('1')
host_hash['HOST_POOL']['HOST'][1]['NAME'].should eql('thost')
host_hash['HOST_POOL']['HOST'][1]['STATE'].should eql('2')
host_hash['HOST_POOL']['HOST'][1]['IM_MAD'].should eql('im_dummy')
host_hash['HOST_POOL']['HOST'][1]['HOST_SHARE']['MEM_USAGE'].should eql('0')
host_hash['HOST_POOL']['HOST'][1]['HOST_SHARE']['CPU_USAGE'].should eql('0')
host_hash['HOST_POOL']['HOST'][1]['HOST_SHARE']['FREE_MEM'].should eql('16777216')
host_hash['HOST_POOL']['HOST'][1]['HOST_SHARE']['RUNNING_VMS'].should eql('0')
end
end
end

View File

@ -0,0 +1,251 @@
$: << '../'
require 'OpenNebula'
require 'MockClient'
module OpenNebula
describe "Host using NOKOGIRI" do
before(:all) do
NOKOGIRI=true
@xml = Host.build_xml(7)
client = MockClient.new()
@host = Host.new(@xml,client)
end
it "should create a Nokogiri Node" do
@xml.class.to_s.should eql('Nokogiri::XML::NodeSet')
end
it "should allocate the new HOST" do
@host.allocate(nil,nil,nil,nil)
@host.id.should eql(7)
end
it "should update the HOST info" do
@host.info()
@host.id.should eql(7)
@host.name.should eql('dummyhost')
@host.state.should eql(2)
@host.state_str.should eql('MONITORED')
@host.short_state_str.should eql('on')
end
it "should enable the HOST" do
rc = @host.enable()
rc.should eql(nil)
end
it "should disable the HOST" do
rc = @host.disable()
rc.should eql(nil)
end
it "should delete the HOST" do
rc = @host.delete()
rc.should eql(nil)
end
it "should access an attribute using []" do
@host['ID'].should eql('7')
@host['NAME'].should eql('dummyhost')
@host['STATE'].should eql('2')
@host['IM_MAD'].should eql('im_dummy')
@host['LAST_MON_TIME'].should eql('1277733596')
@host['HOST_SHARE/MEM_USAGE'].should eql('1572864')
@host['HOST_SHARE/CPU_USAGE'].should eql('300')
@host['HOST_SHARE/FREE_CPU'].should eql('800')
@host['HOST_SHARE/RUNNING_VMS'].should eql('3')
@host['TEMPLATE/CPUSPEED'].should eql('2.2GHz')
@host['TEMPLATE/HYPERVISOR'].should eql('dummy')
@host['TEMPLATE/TOTALMEMORY'].should eql('16777216')
end
it "should get a hash representation of the HOST" do
host_hash = @host.to_hash
host_hash['HOST']['ID'].should eql('7')
host_hash['HOST']['NAME'].should eql('dummyhost')
host_hash['HOST']['STATE'].should eql('2')
host_hash['HOST']['IM_MAD'].should eql('im_dummy')
host_hash['HOST']['LAST_MON_TIME'].should eql('1277733596')
host_hash['HOST']['HOST_SHARE']['MEM_USAGE'].should eql('1572864')
host_hash['HOST']['HOST_SHARE']['CPU_USAGE'].should eql('300')
host_hash['HOST']['HOST_SHARE']['FREE_CPU'].should eql('800')
host_hash['HOST']['HOST_SHARE']['RUNNING_VMS'].should eql('3')
host_hash['HOST']['TEMPLATE']['CPUSPEED'].should eql('2.2GHz')
host_hash['HOST']['TEMPLATE']['HYPERVISOR'].should eql('dummy')
host_hash['HOST']['TEMPLATE']['TOTALMEMORY'].should eql('16777216')
end
end
describe "Host using REXML" do
before(:all) do
NOKOGIRI=false
@xml = Host.build_xml(7)
client = MockClient.new()
@host = Host.new(@xml,client)
end
it "should create a REXML Element" do
@xml.class.to_s.should eql('REXML::Element')
end
it "should allocate the new HOST" do
@host.allocate(nil,nil,nil,nil)
@host.id.should eql(7)
end
it "should update the HOST info" do
@host.info()
@host.id.should eql(7)
@host.name.should eql('dummyhost')
@host.state.should eql(2)
@host.state_str.should eql('MONITORED')
@host.short_state_str.should eql('on')
end
it "should enable the HOST" do
rc = @host.enable()
rc.should eql(nil)
end
it "should disable the HOST" do
rc = @host.disable()
rc.should eql(nil)
end
it "should delete the HOST" do
rc = @host.delete()
rc.should eql(nil)
end
it "should access an attribute using []" do
@host['ID'].should eql('7')
@host['NAME'].should eql('dummyhost')
@host['STATE'].should eql('2')
@host['IM_MAD'].should eql('im_dummy')
@host['LAST_MON_TIME'].should eql('1277733596')
@host['HOST_SHARE/MEM_USAGE'].should eql('1572864')
@host['HOST_SHARE/CPU_USAGE'].should eql('300')
@host['HOST_SHARE/FREE_CPU'].should eql('800')
@host['HOST_SHARE/RUNNING_VMS'].should eql('3')
@host['TEMPLATE/CPUSPEED'].should eql('2.2GHz')
@host['TEMPLATE/HYPERVISOR'].should eql('dummy')
@host['TEMPLATE/TOTALMEMORY'].should eql('16777216')
end
it "should get a hash representation of the HOST" do
host_hash = @host.to_hash
host_hash['HOST']['ID'].should eql('7')
host_hash['HOST']['NAME'].should eql('dummyhost')
host_hash['HOST']['STATE'].should eql('2')
host_hash['HOST']['IM_MAD'].should eql('im_dummy')
host_hash['HOST']['LAST_MON_TIME'].should eql('1277733596')
host_hash['HOST']['HOST_SHARE']['MEM_USAGE'].should eql('1572864')
host_hash['HOST']['HOST_SHARE']['CPU_USAGE'].should eql('300')
host_hash['HOST']['HOST_SHARE']['FREE_CPU'].should eql('800')
host_hash['HOST']['HOST_SHARE']['RUNNING_VMS'].should eql('3')
host_hash['HOST']['TEMPLATE']['CPUSPEED'].should eql('2.2GHz')
host_hash['HOST']['TEMPLATE']['HYPERVISOR'].should eql('dummy')
host_hash['HOST']['TEMPLATE']['TOTALMEMORY'].should eql('16777216')
end
end
describe "Host using NOKOGIRI without id" do
before(:all) do
NOKOGIRI=true
@xml = Host.build_xml()
client = MockClient.new()
@host = Host.new(@xml,client)
end
it "should create a Nokogiri Node" do
@xml.class.to_s.should eql('Nokogiri::XML::NodeSet')
end
it "should get Error getting info" do
rc = @host.info()
OpenNebula.is_error?(rc).should eql(true)
@host.id.should eql(nil)
@host.name.should eql(nil)
end
it "should enable the HOST" do
rc = @host.enable()
OpenNebula.is_error?(rc).should eql(true)
end
it "should disable the HOST" do
rc = @host.disable()
OpenNebula.is_error?(rc).should eql(true)
end
it "should get Error deleting the HOST" do
rc = @host.delete()
OpenNebula.is_error?(rc).should eql(true)
end
end
describe "Host using REXML without id" do
before(:all) do
NOKOGIRI=false
@xml = Host.build_xml()
client = MockClient.new()
@host = Host.new(@xml,client)
end
it "should create a REXML Element" do
@xml.class.to_s.should eql('REXML::Element')
end
it "should get Error getting info" do
rc = @host.info()
OpenNebula.is_error?(rc).should eql(true)
@host.id.should eql(nil)
@host.name.should eql(nil)
end
it "should enable the HOST" do
rc = @host.enable()
OpenNebula.is_error?(rc).should eql(true)
end
it "should disable the HOST" do
rc = @host.disable()
OpenNebula.is_error?(rc).should eql(true)
end
it "should get Error deleting the HOST" do
rc = @host.delete()
OpenNebula.is_error?(rc).should eql(true)
end
end
end

View File

@ -0,0 +1,49 @@
class MockClient
def call(action, *args)
xmlrpc_action = "one."+action
case xmlrpc_action
when "one.vn.info"
return File.read("xml_test/vnet.xml")
when "one.vn.allocate"
return 3
when "one.vn.delete"
return nil
when "one.vm.info"
return File.read("xml_test/vm.xml")
when "one.vm.allocate"
return 6
when "one.vm.delete"
return nil
when "one.vm.action"
return nil
when "one.vm.deploy"
return nil
when "one.vm.migrate"
return nil
when "one.host.info"
return File.read("xml_test/host.xml")
when "one.host.allocate"
return 7
when "one.host.delete"
return nil
when "one.host.enable"
return nil
when "one.user.allocate"
return 3
when "one.user.info"
return File.read("xml_test/user.xml")
when "one.user.delete"
return nil
when "one.vnpool.info"
return File.read("xml_test/vnetpool.xml")
when "one.vmpool.info"
return File.read("xml_test/vmpool.xml")
when "one.hostpool.info"
return File.read("xml_test/hostpool.xml")
when "one.userpool.info"
return File.read("xml_test/userpool.xml")
end
end
end

View File

@ -0,0 +1,81 @@
$: << '../'
require 'OpenNebula'
require 'MockClient'
module OpenNebula
describe "User using NOKOGIRI" do
before(:all) do
NOKOGIRI=true
client = MockClient.new()
@user_pool = UserPool.new(client)
end
it "should update the USER_POOL info" do
rc = @user_pool.info()
rc.nil?.should eql(true)
end
it "should iterate the USER_POOL elements and get info from them" do
rc = @user_pool.each{ |user|
user.class.to_s.should eql("OpenNebula::User")
if user.id == 0
user.name.should eql('oneadmin')
elsif user.id == 1
user.name.should eql('dan')
end
}
end
it "should get a hash representation of the USER_POOL" do
user_hash = @user_pool.to_hash
user_hash['USER_POOL']['USER'][0]['ID'].should eql('0')
user_hash['USER_POOL']['USER'][0]['NAME'].should eql('oneadmin')
user_hash['USER_POOL']['USER'][0]['PASSWORD'].should eql('f13a1234833436f71ab846572d251c0d40391e72')
user_hash['USER_POOL']['USER'][0]['ENABLED'].should eql('True')
user_hash['USER_POOL']['USER'][1]['ID'].should eql('1')
user_hash['USER_POOL']['USER'][1]['NAME'].should eql('dan')
user_hash['USER_POOL']['USER'][1]['PASSWORD'].should eql('d22a12348334v33f71ba846572d25250d40701e72')
user_hash['USER_POOL']['USER'][1]['ENABLED'].should eql('False')
end
end
describe "User using REXML" do
before(:all) do
NOKOGIRI=false
client = MockClient.new()
@user_pool = UserPool.new(client)
end
it "should update the USER_POOL info" do
rc = @user_pool.info()
rc.nil?.should eql(true)
end
it "should iterate the USER_POOL elements and get info from them" do
rc = @user_pool.each{ |user|
user.class.to_s.should eql("OpenNebula::User")
if user.id == 0
user.name.should eql('oneadmin')
elsif user.id == 1
user.name.should eql('dan')
end
}
end
it "should get a hash representation of the USER_POOL" do
user_hash = @user_pool.to_hash
user_hash['USER_POOL']['USER'][0]['ID'].should eql('0')
user_hash['USER_POOL']['USER'][0]['NAME'].should eql('oneadmin')
user_hash['USER_POOL']['USER'][0]['PASSWORD'].should eql('f13a1234833436f71ab846572d251c0d40391e72')
user_hash['USER_POOL']['USER'][0]['ENABLED'].should eql('True')
user_hash['USER_POOL']['USER'][1]['ID'].should eql('1')
user_hash['USER_POOL']['USER'][1]['NAME'].should eql('dan')
user_hash['USER_POOL']['USER'][1]['PASSWORD'].should eql('d22a12348334v33f71ba846572d25250d40701e72')
user_hash['USER_POOL']['USER'][1]['ENABLED'].should eql('False')
end
end
end

View File

@ -0,0 +1,161 @@
$: << '../'
require 'OpenNebula'
require 'MockClient'
module OpenNebula
describe "User using NOKOGIRI" do
before(:all) do
NOKOGIRI=true
@xml = User.build_xml(3)
client = MockClient.new()
@user = User.new(@xml,client)
end
it "should create a Nokogiri Node" do
@xml.class.to_s.should eql('Nokogiri::XML::NodeSet')
end
it "should allocate the new USER" do
@user.allocate(nil,nil)
@user.id.should eql(3)
end
it "should update the USER info" do
@user.info()
@user.id.should eql(3)
@user.name.should eql('dan')
end
it "should delete the USER" do
rc = @user.delete()
rc.should eql(nil)
end
it "should access an attribute using []" do
@user['ID'].should eql('3')
@user['NAME'].should eql('dan')
@user['PASSWORD'].should eql('d22a12348334v33f71ba846572d25250d40701e72')
@user['ENABLED'].should eql('False')
end
it "should get a hash representation of the USER" do
user_hash = @user.to_hash
user_hash['USER']['ID'].should eql('3')
user_hash['USER']['NAME'].should eql('dan')
user_hash['USER']['PASSWORD'].should eql('d22a12348334v33f71ba846572d25250d40701e72')
user_hash['USER']['ENABLED'].should eql('False')
end
end
describe "User using REXML" do
before(:all) do
NOKOGIRI=false
@xml = User.build_xml(3)
client = MockClient.new()
@user = User.new(@xml,client)
end
it "should create a REXML Element" do
@xml.class.to_s.should eql('REXML::Element')
end
it "should allocate the new USER" do
@user.allocate(nil,nil)
@user.id.should eql(3)
end
it "should update the USER info" do
@user.info()
@user.id.should eql(3)
@user.name.should eql('dan')
end
it "should delete the USER" do
rc = @user.delete()
rc.should eql(nil)
end
it "should access an attribute using []" do
@user['ID'].should eql('3')
@user['NAME'].should eql('dan')
@user['PASSWORD'].should eql('d22a12348334v33f71ba846572d25250d40701e72')
@user['ENABLED'].should eql('False')
end
it "should get a hash representation of the USER" do
user_hash = @user.to_hash
user_hash['USER']['ID'].should eql('3')
user_hash['USER']['NAME'].should eql('dan')
user_hash['USER']['PASSWORD'].should eql('d22a12348334v33f71ba846572d25250d40701e72')
user_hash['USER']['ENABLED'].should eql('False')
end
end
describe "User using NOKOGIRI without id" do
before(:all) do
NOKOGIRI=true
@xml = User.build_xml()
client = MockClient.new()
@user = User.new(@xml,client)
end
it "should create a Nokogiri Node" do
@xml.class.to_s.should eql('Nokogiri::XML::NodeSet')
end
it "should get Error getting info" do
rc = @user.info()
OpenNebula.is_error?(rc).should eql(true)
end
it "should get Error deleting the USER" do
rc = @user.delete()
OpenNebula.is_error?(rc).should eql(true)
end
end
describe "User using REXML without id" do
before(:all) do
NOKOGIRI=false
@xml = User.build_xml()
client = MockClient.new()
@user = User.new(@xml,client)
end
it "should create a REXML Element" do
@xml.class.to_s.should eql('REXML::Element')
end
it "should get Error getting info" do
rc = @user.info()
OpenNebula.is_error?(rc).should eql(true)
end
it "should get Error deleting the USER" do
rc = @user.delete()
OpenNebula.is_error?(rc).should eql(true)
end
end
end

View File

@ -0,0 +1,105 @@
$: << '../'
require 'OpenNebula'
require 'MockClient'
module OpenNebula
describe "VirtualMachinePool using NOKOGIRI" do
before(:all) do
NOKOGIRI=true
client = MockClient.new()
@vm_pool = VirtualMachinePool.new(client)
end
it "should update the VM_POOL info" do
rc = @vm_pool.info()
rc.nil?.should eql(true)
end
it "should iterate the VM_POOL elements and get info from them" do
rc = @vm_pool.each{ |vm|
vm.class.to_s.should eql("OpenNebula::VirtualMachine")
if vm.id == 6
vm.name.should eql('vm-example')
vm.state.should eql(3)
vm.state_str.should eql('ACTIVE')
elsif vm.id == 8
vm.name.should eql('vmext')
vm.state.should eql(4)
vm.state_str.should eql('STOPPED')
end
}
end
it "should get a hash representation of the VM_POOL" do
vm_hash = @vm_pool.to_hash
vm_hash['VM_POOL']['VM'][0]['ID'].should eql('6')
vm_hash['VM_POOL']['VM'][0]['UID'].should eql('0')
vm_hash['VM_POOL']['VM'][0]['USERNAME'].should eql('oneadmin')
vm_hash['VM_POOL']['VM'][0]['NAME'].should eql('vm-example')
vm_hash['VM_POOL']['VM'][0]['LAST_POLL'].should eql('1277910006')
vm_hash['VM_POOL']['VM'][0]['HISTORY']['HOSTNAME'].should eql('dummyhost')
vm_hash['VM_POOL']['VM'][0]['HISTORY']['STIME'].should eql('1277375186')
vm_hash['VM_POOL']['VM'][0]['HISTORY']['REASON'].should eql('0')
vm_hash['VM_POOL']['VM'][2]['ID'].should eql('8')
vm_hash['VM_POOL']['VM'][2]['UID'].should eql('0')
vm_hash['VM_POOL']['VM'][2]['USERNAME'].should eql('oneadmin')
vm_hash['VM_POOL']['VM'][2]['NAME'].should eql('vmext')
vm_hash['VM_POOL']['VM'][2]['LAST_POLL'].should eql('1277910006')
vm_hash['VM_POOL']['VM'][2]['HISTORY']['HOSTNAME'].should eql('thost')
vm_hash['VM_POOL']['VM'][2]['HISTORY']['STIME'].should eql('1277377556')
vm_hash['VM_POOL']['VM'][2]['HISTORY']['REASON'].should eql('0')
end
end
describe "VirtualMachinePool using REXML" do
before(:all) do
NOKOGIRI=false
client = MockClient.new()
@vm_pool = VirtualMachinePool.new(client)
end
it "should update the VM_POOL info" do
rc = @vm_pool.info()
rc.nil?.should eql(true)
end
it "should iterate the VM_POOL elements and get info from them" do
rc = @vm_pool.each{ |vm|
vm.class.to_s.should eql("OpenNebula::VirtualMachine")
if vm.id == 6
vm.name.should eql('vm-example')
vm.state.should eql(3)
vm.state_str.should eql('ACTIVE')
elsif vm.id == 8
vm.name.should eql('vmext')
vm.state.should eql(4)
vm.state_str.should eql('STOPPED')
end
}
end
it "should get a hash representation of the VM_POOL" do
vm_hash = @vm_pool.to_hash
vm_hash['VM_POOL']['VM'][0]['ID'].should eql('6')
vm_hash['VM_POOL']['VM'][0]['UID'].should eql('0')
vm_hash['VM_POOL']['VM'][0]['USERNAME'].should eql('oneadmin')
vm_hash['VM_POOL']['VM'][0]['NAME'].should eql('vm-example')
vm_hash['VM_POOL']['VM'][0]['LAST_POLL'].should eql('1277910006')
vm_hash['VM_POOL']['VM'][0]['HISTORY']['HOSTNAME'].should eql('dummyhost')
vm_hash['VM_POOL']['VM'][0]['HISTORY']['STIME'].should eql('1277375186')
vm_hash['VM_POOL']['VM'][0]['HISTORY']['REASON'].should eql('0')
vm_hash['VM_POOL']['VM'][2]['ID'].should eql('8')
vm_hash['VM_POOL']['VM'][2]['UID'].should eql('0')
vm_hash['VM_POOL']['VM'][2]['USERNAME'].should eql('oneadmin')
vm_hash['VM_POOL']['VM'][2]['NAME'].should eql('vmext')
vm_hash['VM_POOL']['VM'][2]['LAST_POLL'].should eql('1277910006')
vm_hash['VM_POOL']['VM'][2]['HISTORY']['HOSTNAME'].should eql('thost')
vm_hash['VM_POOL']['VM'][2]['HISTORY']['STIME'].should eql('1277377556')
vm_hash['VM_POOL']['VM'][2]['HISTORY']['REASON'].should eql('0')
end
end
end

View File

@ -0,0 +1,464 @@
$: << '../'
require 'OpenNebula'
require 'MockClient'
module OpenNebula
describe "VirtualMachine using NOKOGIRI" do
before(:all) do
NOKOGIRI=true
@xml = VirtualMachine.build_xml(6)
client = MockClient.new()
@vm = VirtualMachine.new(@xml,client)
end
it "should create a Nokogiri Node" do
@xml.class.to_s.should eql('Nokogiri::XML::NodeSet')
end
it "should allocate the new VM" do
@vm.allocate(nil)
@vm.id.should eql(6)
end
it "should update the VM info" do
@vm.info()
@vm.id.should eql(6)
@vm.name.should eql('vm-example')
@vm.state.should eql(3)
@vm.state_str.should eql('ACTIVE')
@vm.lcm_state.should eql(3)
@vm.lcm_state_str.should eql('RUNNING')
@vm.status.should eql('runn')
end
it "should deploy the VNET" do
rc = @vm.deploy(nil)
rc.should eql(nil)
end
it "should migrate the VNET" do
rc = @vm.migrate(nil)
rc.should eql(nil)
end
it "should live_migrate the VNET" do
rc = @vm.live_migrate(nil)
rc.should eql(nil)
end
it "should shutdown the VNET" do
rc = @vm.shutdown()
rc.should eql(nil)
end
it "should cancel the VNET" do
rc = @vm.cancel()
rc.should eql(nil)
end
it "should hold the VNET" do
rc = @vm.hold()
rc.should eql(nil)
end
it "should release the VNET" do
rc = @vm.release()
rc.should eql(nil)
end
it "should stop the VNET" do
rc = @vm.stop()
rc.should eql(nil)
end
it "should suspend the VNET" do
rc = @vm.suspend()
rc.should eql(nil)
end
it "should resume the VNET" do
rc = @vm.resume()
rc.should eql(nil)
end
it "should finalize the VNET" do
rc = @vm.finalize()
rc.should eql(nil)
end
it "should restart the VNET" do
rc = @vm.restart()
rc.should eql(nil)
end
it "should access an attribute using []" do
@vm['NAME'].should eql('vm-example')
@vm['DEPLOY_ID'].should eql('dummy')
@vm['TEMPLATE/MEMORY'].should eql('512')
@vm['ID'].should eql('6')
@vm['NAME'].should eql('vm-example')
@vm['LCM_STATE'].should eql('3')
@vm['DEPLOY_ID'].should eql('dummy')
@vm['TEMPLATE/MEMORY'].should eql('512')
@vm['TEMPLATE/CONTEXT/DNS'].should eql('192.169.1.4')
@vm['TEMPLATE/DISK/SIZE'].should eql('1024')
@vm['HISTORY/HOSTNAME'].should eql('dummyhost')
@vm['HISTORY/PSTIME'].should eql('1277375186')
end
it "should get a hash representation of the VM" do
vm_hash = @vm.to_hash
vm_hash['VM']['ID'].should eql('6')
vm_hash['VM']['NAME'].should eql('vm-example')
vm_hash['VM']['LCM_STATE'].should eql('3')
vm_hash['VM']['DEPLOY_ID'].should eql('dummy')
vm_hash['VM']['TEMPLATE']['MEMORY'].should eql('512')
vm_hash['VM']['TEMPLATE']['CONTEXT']['DNS'].should eql('192.169.1.4')
vm_hash['VM']['TEMPLATE']['DISK'][0]['TARGET'].should eql('sda')
vm_hash['VM']['HISTORY']['HOSTNAME'].should eql('dummyhost')
vm_hash['VM']['HISTORY']['PSTIME'].should eql('1277375186')
end
end
describe "VirtualMachine using REXML" do
before(:all) do
NOKOGIRI=false
@xml = VirtualMachine.build_xml(6)
client = MockClient.new()
@vm = VirtualMachine.new(@xml,client)
end
it "should create a REXML Element" do
@xml.class.to_s.should eql('REXML::Element')
end
it "should allocate the new VM" do
@vm.allocate(nil)
@vm.id.should eql(6)
end
it "should update the VM info" do
@vm.info()
@vm.id.should eql(6)
@vm.name.should eql('vm-example')
@vm.state.should eql(3)
@vm.state_str.should eql('ACTIVE')
@vm.lcm_state.should eql(3)
@vm.lcm_state_str.should eql('RUNNING')
@vm.status.should eql('runn')
end
it "should deploy the VNET" do
rc = @vm.deploy(nil)
rc.should eql(nil)
end
it "should migrate the VNET" do
rc = @vm.migrate(nil)
rc.should eql(nil)
end
it "should live_migrate the VNET" do
rc = @vm.live_migrate(nil)
rc.should eql(nil)
end
it "should shutdown the VNET" do
rc = @vm.shutdown()
rc.should eql(nil)
end
it "should cancel the VNET" do
rc = @vm.cancel()
rc.should eql(nil)
end
it "should hold the VNET" do
rc = @vm.hold()
rc.should eql(nil)
end
it "should release the VNET" do
rc = @vm.release()
rc.should eql(nil)
end
it "should stop the VNET" do
rc = @vm.stop()
rc.should eql(nil)
end
it "should suspend the VNET" do
rc = @vm.suspend()
rc.should eql(nil)
end
it "should resume the VNET" do
rc = @vm.resume()
rc.should eql(nil)
end
it "should finalize the VNET" do
rc = @vm.finalize()
rc.should eql(nil)
end
it "should restart the VNET" do
rc = @vm.restart()
rc.should eql(nil)
end
it "should access an attribute using []" do
@vm['NAME'].should eql('vm-example')
@vm['DEPLOY_ID'].should eql('dummy')
@vm['TEMPLATE/MEMORY'].should eql('512')
@vm['ID'].should eql('6')
@vm['NAME'].should eql('vm-example')
@vm['LCM_STATE'].should eql('3')
@vm['DEPLOY_ID'].should eql('dummy')
@vm['TEMPLATE/MEMORY'].should eql('512')
@vm['TEMPLATE/CONTEXT/DNS'].should eql('192.169.1.4')
@vm['TEMPLATE/DISK/SIZE'].should eql('1024')
@vm['HISTORY/HOSTNAME'].should eql('dummyhost')
@vm['HISTORY/PSTIME'].should eql('1277375186')
end
it "should get a hash representation of the VM" do
vm_hash = @vm.to_hash
vm_hash['VM']['ID'].should eql('6')
vm_hash['VM']['NAME'].should eql('vm-example')
vm_hash['VM']['LCM_STATE'].should eql('3')
vm_hash['VM']['DEPLOY_ID'].should eql('dummy')
vm_hash['VM']['TEMPLATE']['MEMORY'].should eql('512')
vm_hash['VM']['TEMPLATE']['CONTEXT']['DNS'].should eql('192.169.1.4')
vm_hash['VM']['TEMPLATE']['DISK'][0]['TARGET'].should eql('sda')
vm_hash['VM']['HISTORY']['HOSTNAME'].should eql('dummyhost')
vm_hash['VM']['HISTORY']['PSTIME'].should eql('1277375186')
end
end
describe "VirtualMachine using NOKOGIRI without id" do
before(:all) do
NOKOGIRI=true
@xml = VirtualMachine.build_xml()
client = MockClient.new()
@vm = VirtualMachine.new(@xml,client)
end
it "should create a Nokogiri Node" do
@xml.class.to_s.should eql('Nokogiri::XML::NodeSet')
end
it "should deploy the VNET" do
rc = @vm.deploy(nil)
OpenNebula.is_error?(rc).should eql(true)
end
it "should migrate the VNET" do
rc = @vm.migrate(nil)
OpenNebula.is_error?(rc).should eql(true)
end
it "should live_migrate the VNET" do
rc = @vm.live_migrate(nil)
OpenNebula.is_error?(rc).should eql(true)
end
it "should shutdown the VNET" do
rc = @vm.shutdown()
OpenNebula.is_error?(rc).should eql(true)
end
it "should cancel the VNET" do
rc = @vm.cancel()
OpenNebula.is_error?(rc).should eql(true)
end
it "should hold the VNET" do
rc = @vm.hold()
OpenNebula.is_error?(rc).should eql(true)
end
it "should release the VNET" do
rc = @vm.release()
OpenNebula.is_error?(rc).should eql(true)
end
it "should stop the VNET" do
rc = @vm.stop()
OpenNebula.is_error?(rc).should eql(true)
end
it "should suspend the VNET" do
rc = @vm.suspend()
OpenNebula.is_error?(rc).should eql(true)
end
it "should resume the VNET" do
rc = @vm.resume()
OpenNebula.is_error?(rc).should eql(true)
end
it "should finalize the VNET" do
rc = @vm.finalize()
OpenNebula.is_error?(rc).should eql(true)
end
it "should restart the VNET" do
rc = @vm.restart()
OpenNebula.is_error?(rc).should eql(true)
end
it "should get Error getting info" do
rc = @vm.info()
OpenNebula.is_error?(rc).should eql(true)
@vm.id.should eql(nil)
@vm.name.should eql(nil)
end
end
describe "VirtualMachine using REXML without id" do
before(:all) do
NOKOGIRI=false
@xml = VirtualMachine.build_xml()
client = MockClient.new()
@vm = VirtualMachine.new(@xml,client)
end
it "should create a REXML Element" do
@xml.class.to_s.should eql('REXML::Element')
end
it "should deploy the VNET" do
rc = @vm.deploy(nil)
OpenNebula.is_error?(rc).should eql(true)
end
it "should migrate the VNET" do
rc = @vm.migrate(nil)
OpenNebula.is_error?(rc).should eql(true)
end
it "should live_migrate the VNET" do
rc = @vm.live_migrate(nil)
OpenNebula.is_error?(rc).should eql(true)
end
it "should shutdown the VNET" do
rc = @vm.shutdown()
OpenNebula.is_error?(rc).should eql(true)
end
it "should cancel the VNET" do
rc = @vm.cancel()
OpenNebula.is_error?(rc).should eql(true)
end
it "should hold the VNET" do
rc = @vm.hold()
OpenNebula.is_error?(rc).should eql(true)
end
it "should release the VNET" do
rc = @vm.release()
OpenNebula.is_error?(rc).should eql(true)
end
it "should stop the VNET" do
rc = @vm.stop()
OpenNebula.is_error?(rc).should eql(true)
end
it "should suspend the VNET" do
rc = @vm.suspend()
OpenNebula.is_error?(rc).should eql(true)
end
it "should resume the VNET" do
rc = @vm.resume()
OpenNebula.is_error?(rc).should eql(true)
end
it "should finalize the VNET" do
rc = @vm.finalize()
OpenNebula.is_error?(rc).should eql(true)
end
it "should restart the VNET" do
rc = @vm.restart()
OpenNebula.is_error?(rc).should eql(true)
end
it "should get Error getting info" do
rc = @vm.info()
OpenNebula.is_error?(rc).should eql(true)
@vm.id.should eql(nil)
@vm.name.should eql(nil)
end
end
end

View File

@ -0,0 +1,103 @@
$: << '../'
require 'OpenNebula'
require 'MockClient'
module OpenNebula
describe "VirtualNetwork using NOKOGIRI" do
before(:all) do
NOKOGIRI=true
client = MockClient.new()
@vnet_pool = VirtualNetworkPool.new(client)
end
#it "should get nil, trying to get a hash, if the info method was not called before" do
# vnet_hash = @vnet_pool.to_hash
# vnet_hash.nil?.should eql(true)
#end
it "should update the VNET_POOL info" do
rc = @vnet_pool.info()
rc.nil?.should eql(true)
end
it "should iterate the VNET_POOL elements and get info from them" do
rc = @vnet_pool.each{ |vn|
vn.class.to_s.should eql("OpenNebula::VirtualNetwork")
if vn.id == 4
vn.name.should eql('Red LAN')
elsif vn.id == 5
vn.name.should eql('Public')
end
}
end
it "should get a hash representation of the VNET_POOL" do
vnet_hash = @vnet_pool.to_hash
vnet_hash['VNET_POOL']['VNET'][0]['ID'].should eql('4')
vnet_hash['VNET_POOL']['VNET'][0]['UID'].should eql('0')
vnet_hash['VNET_POOL']['VNET'][0]['USERNAME'].should eql('oneadmin')
vnet_hash['VNET_POOL']['VNET'][0]['NAME'].should eql('Red LAN')
vnet_hash['VNET_POOL']['VNET'][0]['TYPE'].should eql('0')
vnet_hash['VNET_POOL']['VNET'][0]['BRIDGE'].should eql('vbr0')
vnet_hash['VNET_POOL']['VNET'][0]['TOTAL_LEASES'].should eql('0')
vnet_hash['VNET_POOL']['VNET'][1]['ID'].should eql('5')
vnet_hash['VNET_POOL']['VNET'][1]['UID'].should eql('0')
vnet_hash['VNET_POOL']['VNET'][1]['USERNAME'].should eql('oneadmin')
vnet_hash['VNET_POOL']['VNET'][1]['NAME'].should eql('Public')
vnet_hash['VNET_POOL']['VNET'][1]['TYPE'].should eql('0')
vnet_hash['VNET_POOL']['VNET'][1]['BRIDGE'].should eql('vbr0')
vnet_hash['VNET_POOL']['VNET'][1]['TOTAL_LEASES'].should eql('1')
end
end
describe "VirtualNetwork using REXML" do
before(:all) do
NOKOGIRI=false
client = MockClient.new()
@vnet_pool = VirtualNetworkPool.new(client)
end
#it "should get nil, trying to get a hash, if the info method was not called before" do
# vnet_hash = @vnet_pool.to_hash
# vnet_hash.nil?.should eql(true)
#end
it "should update the VNET_POOL info" do
rc = @vnet_pool.info()
rc.nil?.should eql(true)
end
it "should iterate the VNET_POOL elements and get info from them" do
rc = @vnet_pool.each{ |vn|
vn.class.to_s.should eql("OpenNebula::VirtualNetwork")
if vn.id == 4
vn.name.should eql('Red LAN')
elsif vn.id == 5
vn.name.should eql('Public')
end
}
end
it "should get a hash representation of the VNET_POOL" do
vnet_hash = @vnet_pool.to_hash
vnet_hash['VNET_POOL']['VNET'][0]['ID'].should eql('4')
vnet_hash['VNET_POOL']['VNET'][0]['UID'].should eql('0')
vnet_hash['VNET_POOL']['VNET'][0]['USERNAME'].should eql('oneadmin')
vnet_hash['VNET_POOL']['VNET'][0]['NAME'].should eql('Red LAN')
vnet_hash['VNET_POOL']['VNET'][0]['TYPE'].should eql('0')
vnet_hash['VNET_POOL']['VNET'][0]['BRIDGE'].should eql('vbr0')
vnet_hash['VNET_POOL']['VNET'][0]['TOTAL_LEASES'].should eql('0')
vnet_hash['VNET_POOL']['VNET'][1]['ID'].should eql('5')
vnet_hash['VNET_POOL']['VNET'][1]['UID'].should eql('0')
vnet_hash['VNET_POOL']['VNET'][1]['USERNAME'].should eql('oneadmin')
vnet_hash['VNET_POOL']['VNET'][1]['NAME'].should eql('Public')
vnet_hash['VNET_POOL']['VNET'][1]['TYPE'].should eql('0')
vnet_hash['VNET_POOL']['VNET'][1]['BRIDGE'].should eql('vbr0')
vnet_hash['VNET_POOL']['VNET'][1]['TOTAL_LEASES'].should eql('1')
end
end
end

View File

@ -0,0 +1,183 @@
$: << '../'
require 'OpenNebula'
require 'MockClient'
module OpenNebula
describe "VirtualNetwork using NOKOGIRI" do
before(:all) do
NOKOGIRI=true
@xml = VirtualNetwork.build_xml(3)
client = MockClient.new()
@vnet = VirtualNetwork.new(@xml,client)
end
it "should create a Nokogiri Node" do
@xml.class.to_s.should eql('Nokogiri::XML::NodeSet')
end
it "should allocate the new VNET" do
@vnet.allocate(nil)
@vnet.id.should eql(3)
end
it "should update the VNET info" do
@vnet.info()
@vnet.id.should eql(3)
@vnet.name.should eql('Red LAN')
end
it "should delete the VNET" do
rc = @vnet.delete()
rc.should eql(nil)
end
it "should access an attribute using []" do
@vnet['ID'].should eql('3')
@vnet['NAME'].should eql('Red LAN')
@vnet['BRIDGE'].should eql('vbr0')
@vnet['TEMPLATE/NETWORK_ADDRESS'].should eql('192.168.0.0')
@vnet['TEMPLATE/TYPE'].should eql('RANGED')
@vnet['LEASES/LEASE/IP'].should eql('192.168.0.1')
@vnet['LEASES/LEASE/USED'].should eql('1')
end
it "should get a hash representation of the VNET" do
vnet_hash = @vnet.to_hash
vnet_hash['VNET']['NAME'].should eql('Red LAN')
vnet_hash['VNET']['BRIDGE'].should eql('vbr0')
vnet_hash['VNET']['TEMPLATE']['NETWORK_ADDRESS'].should eql('192.168.0.0')
vnet_hash['VNET']['ID'].should eql('3')
vnet_hash['VNET']['NAME'].should eql('Red LAN')
vnet_hash['VNET']['BRIDGE'].should eql('vbr0')
vnet_hash['VNET']['TEMPLATE']['NETWORK_ADDRESS'].should eql('192.168.0.0')
vnet_hash['VNET']['TEMPLATE']['TYPE'].should eql('RANGED')
vnet_hash['VNET']['LEASES']['LEASE']['IP'].should eql('192.168.0.1')
vnet_hash['VNET']['LEASES']['LEASE']['USED'].should eql('1')
end
end
describe "VirtualNetwork using REXML" do
before(:all) do
NOKOGIRI=false
@xml = VirtualNetwork.build_xml(3)
client = MockClient.new()
@vnet = VirtualNetwork.new(@xml,client)
end
it "should create a REXML Element" do
@xml.class.to_s.should eql('REXML::Element')
end
it "should allocate the new VNET" do
@vnet.allocate(nil)
@vnet.id.should eql(3)
end
it "should update the VNET info" do
@vnet.info()
@vnet.id.should eql(3)
@vnet.name.should eql('Red LAN')
end
it "should delete the VNET" do
rc = @vnet.delete()
rc.should eql(nil)
end
it "should access an attribute using []" do
@vnet['ID'].should eql('3')
@vnet['NAME'].should eql('Red LAN')
@vnet['BRIDGE'].should eql('vbr0')
@vnet['TEMPLATE/NETWORK_ADDRESS'].should eql('192.168.0.0')
@vnet['TEMPLATE/TYPE'].should eql('RANGED')
@vnet['LEASES/LEASE/IP'].should eql('192.168.0.1')
@vnet['LEASES/LEASE/USED'].should eql('1')
end
it "should get a hash representation of the VNET" do
vnet_hash = @vnet.to_hash
vnet_hash['VNET']['NAME'].should eql('Red LAN')
vnet_hash['VNET']['BRIDGE'].should eql('vbr0')
vnet_hash['VNET']['TEMPLATE']['NETWORK_ADDRESS'].should eql('192.168.0.0')
vnet_hash['VNET']['ID'].should eql('3')
vnet_hash['VNET']['NAME'].should eql('Red LAN')
vnet_hash['VNET']['BRIDGE'].should eql('vbr0')
vnet_hash['VNET']['TEMPLATE']['NETWORK_ADDRESS'].should eql('192.168.0.0')
vnet_hash['VNET']['TEMPLATE']['TYPE'].should eql('RANGED')
vnet_hash['VNET']['LEASES']['LEASE']['IP'].should eql('192.168.0.1')
vnet_hash['VNET']['LEASES']['LEASE']['USED'].should eql('1')
end
end
describe "VirtualNetwork using NOKOGIRI without id" do
before(:all) do
NOKOGIRI=true
@xml = VirtualNetwork.build_xml()
client = MockClient.new()
@vnet = VirtualNetwork.new(@xml,client)
end
it "should create a Nokogiri Node" do
@xml.class.to_s.should eql('Nokogiri::XML::NodeSet')
end
it "should get Error getting info" do
rc = @vnet.info()
OpenNebula.is_error?(rc).should eql(true)
@vnet.id.should eql(nil)
@vnet.name.should eql(nil)
end
it "should get Error deleting the VNET" do
rc = @vnet.delete()
OpenNebula.is_error?(rc).should eql(true)
end
end
describe "VirtualNetwork using REXML without id" do
before(:all) do
NOKOGIRI=false
@xml = VirtualNetwork.build_xml()
client = MockClient.new()
@vnet = VirtualNetwork.new(@xml,client)
end
it "should create a REXML Element" do
@xml.class.to_s.should eql('REXML::Element')
end
it "should get Error getting info" do
rc = @vnet.info()
OpenNebula.is_error?(rc).should eql(true)
@vnet.id.should eql(nil)
@vnet.name.should eql(nil)
end
it "should get Error deleting the VNET" do
rc = @vnet.delete()
OpenNebula.is_error?(rc).should eql(true)
end
end
end

View File

@ -0,0 +1,38 @@
<HOST>
<ID>7</ID>
<NAME>dummyhost</NAME>
<STATE>2</STATE>
<IM_MAD>im_dummy</IM_MAD>
<VM_MAD>vmm_dummy</VM_MAD>
<TM_MAD>tm_dummy</TM_MAD>
<LAST_MON_TIME>1277733596</LAST_MON_TIME>
<HOST_SHARE>
<HID>0</HID>
<DISK_USAGE>0</DISK_USAGE>
<MEM_USAGE>1572864</MEM_USAGE>
<CPU_USAGE>300</CPU_USAGE>
<MAX_DISK>0</MAX_DISK>
<MAX_MEM>16777216</MAX_MEM>
<MAX_CPU>800</MAX_CPU>
<FREE_DISK>0</FREE_DISK>
<FREE_MEM>16777216</FREE_MEM>
<FREE_CPU>800</FREE_CPU>
<USED_DISK>0</USED_DISK>
<USED_MEM>0</USED_MEM>
<USED_CPU>0</USED_CPU>
<RUNNING_VMS>3</RUNNING_VMS>
</HOST_SHARE>
<TEMPLATE>
<CPUSPEED>2.2GHz</CPUSPEED>
<FREECPU>800</FREECPU>
<FREEMEMORY>16777216</FREEMEMORY>
<HOSTNAME>dummyhost</HOSTNAME>
<HYPERVISOR>dummy</HYPERVISOR>
<MAC>50:20:20:20:20:21</MAC>
<NAME>dummyhost</NAME>
<TOTALCPU>800</TOTALCPU>
<TOTALMEMORY>16777216</TOTALMEMORY>
<USEDCPU>0</USEDCPU>
<USEDMEMORY>0</USEDMEMORY>
</TEMPLATE>
</HOST>

View File

@ -0,0 +1,52 @@
<HOST_POOL>
<HOST>
<ID>0</ID>
<NAME>dummyhost</NAME>
<STATE>2</STATE>
<IM_MAD>im_dummy</IM_MAD>
<VM_MAD>vmm_dummy</VM_MAD>
<TM_MAD>tm_dummy</TM_MAD>
<LAST_MON_TIME>1277912461</LAST_MON_TIME>
<HOST_SHARE>
<HID>0</HID>
<DISK_USAGE>0</DISK_USAGE>
<MEM_USAGE>1572864</MEM_USAGE>
<CPU_USAGE>300</CPU_USAGE>
<MAX_DISK>0</MAX_DISK>
<MAX_MEM>16777216</MAX_MEM>
<MAX_CPU>800</MAX_CPU>
<FREE_DISK>0</FREE_DISK>
<FREE_MEM>16777216</FREE_MEM>
<FREE_CPU>800</FREE_CPU>
<USED_DISK>0</USED_DISK>
<USED_MEM>0</USED_MEM>
<USED_CPU>0</USED_CPU>
<RUNNING_VMS>3</RUNNING_VMS>
</HOST_SHARE>
</HOST>
<HOST>
<ID>1</ID>
<NAME>thost</NAME>
<STATE>2</STATE>
<IM_MAD>im_dummy</IM_MAD>
<VM_MAD>vmm_dummy</VM_MAD>
<TM_MAD>tm_dummy</TM_MAD>
<LAST_MON_TIME>1277912461</LAST_MON_TIME>
<HOST_SHARE>
<HID>1</HID>
<DISK_USAGE>0</DISK_USAGE>
<MEM_USAGE>0</MEM_USAGE>
<CPU_USAGE>0</CPU_USAGE>
<MAX_DISK>0</MAX_DISK>
<MAX_MEM>16777216</MAX_MEM>
<MAX_CPU>800</MAX_CPU>
<FREE_DISK>0</FREE_DISK>
<FREE_MEM>16777216</FREE_MEM>
<FREE_CPU>800</FREE_CPU>
<USED_DISK>0</USED_DISK>
<USED_MEM>0</USED_MEM>
<USED_CPU>0</USED_CPU>
<RUNNING_VMS>0</RUNNING_VMS>
</HOST_SHARE>
</HOST>
</HOST_POOL>

View File

@ -0,0 +1,6 @@
<USER>
<ID>3</ID>
<NAME>dan</NAME>
<PASSWORD>d22a12348334v33f71ba846572d25250d40701e72</PASSWORD>
<ENABLED>False</ENABLED>
</USER>

View File

@ -0,0 +1,14 @@
<USER_POOL>
<USER>
<ID>0</ID>
<NAME>oneadmin</NAME>
<PASSWORD>f13a1234833436f71ab846572d251c0d40391e72</PASSWORD>
<ENABLED>True</ENABLED>
</USER>
<USER>
<ID>1</ID>
<NAME>dan</NAME>
<PASSWORD>d22a12348334v33f71ba846572d25250d40701e72</PASSWORD>
<ENABLED>False</ENABLED>
</USER>
</USER_POOL>

View File

@ -0,0 +1,59 @@
<VM>
<ID>6</ID>
<UID>0</UID>
<NAME>vm-example</NAME>
<LAST_POLL>1277729095</LAST_POLL>
<STATE>3</STATE>
<LCM_STATE>3</LCM_STATE>
<STIME>1277375180</STIME>
<ETIME>0</ETIME>
<DEPLOY_ID>dummy</DEPLOY_ID>
<MEMORY>512</MEMORY>
<CPU>1</CPU>
<NET_TX>12345</NET_TX>
<NET_RX>0</NET_RX>
<TEMPLATE>
<CONTEXT>
<DNS>192.169.1.4</DNS>
<TYPE/>
</CONTEXT>
<CPU>1</CPU>
<DISK>
<READONLY>no</READONLY>
<SOURCE>/srv/cloud/images/ttylinux/ttylinux.img</SOURCE>
<TARGET>sda</TARGET>
</DISK>
<DISK>
<READONLY>no</READONLY>
<SIZE>1024</SIZE>
<TARGET>sdb</TARGET>
<TYPE>swap</TYPE>
</DISK>
<MEMORY>512</MEMORY>
<NAME>vm-example</NAME>
<NIC>
<MAC>50:20:20:20:20:20</MAC>
</NIC>
<OS>
<INITRD>/initrd.img</INITRD>
<KERNEL>/vmlinuz</KERNEL>
<ROOT>sda</ROOT>
</OS>
<REQUIREMENTS>MAC="50:20:20:20:20:20"</REQUIREMENTS>
<VMID>6</VMID>
</TEMPLATE>
<HISTORY>
<SEQ>0</SEQ>
<HOSTNAME>dummyhost</HOSTNAME>
<HID>0</HID>
<STIME>1277375186</STIME>
<ETIME>0</ETIME>
<PSTIME>1277375186</PSTIME>
<PETIME>1277375186</PETIME>
<RSTIME>1277375186</RSTIME>
<RETIME>0</RETIME>
<ESTIME>0</ESTIME>
<EETIME>0</EETIME>
<REASON>0</REASON>
</HISTORY>
</VM>

View File

@ -0,0 +1,92 @@
<VM_POOL>
<VM>
<ID>6</ID>
<UID>0</UID>
<USERNAME>oneadmin</USERNAME>
<NAME>vm-example</NAME>
<LAST_POLL>1277910006</LAST_POLL>
<STATE>3</STATE>
<LCM_STATE>3</LCM_STATE>
<STIME>1277375180</STIME>
<ETIME>0</ETIME>
<DEPLOY_ID>dummy</DEPLOY_ID>
<MEMORY>512</MEMORY>
<CPU>1</CPU>
<NET_TX>12345</NET_TX>
<NET_RX>0</NET_RX>
<HISTORY>
<SEQ>0</SEQ>
<HOSTNAME>dummyhost</HOSTNAME>
<HID>0</HID>
<STIME>1277375186</STIME>
<ETIME>0</ETIME>
<PSTIME>1277375186</PSTIME>
<PETIME>1277375186</PETIME>
<RSTIME>1277375186</RSTIME>
<RETIME>0</RETIME>
<ESTIME>0</ESTIME>
<EETIME>0</EETIME>
<REASON>0</REASON>
</HISTORY>
</VM>
<VM>
<ID>7</ID>
<UID>0</UID>
<USERNAME>oneadmin</USERNAME>
<NAME>vm-in</NAME>
<LAST_POLL>1277910006</LAST_POLL>
<STATE>3</STATE>
<LCM_STATE>3</LCM_STATE>
<STIME>1277377464</STIME>
<ETIME>0</ETIME>
<DEPLOY_ID>dummy</DEPLOY_ID>
<MEMORY>1024</MEMORY>
<CPU>2</CPU>
<NET_TX>12345</NET_TX>
<NET_RX>0</NET_RX>
<HISTORY>
<SEQ>0</SEQ>
<HOSTNAME>thost</HOSTNAME>
<HID>0</HID>
<STIME>1277377466</STIME>
<ETIME>0</ETIME>
<PSTIME>1277377466</PSTIME>
<PETIME>1277377466</PETIME>
<RSTIME>1277377466</RSTIME>
<RETIME>0</RETIME>
<ESTIME>0</ESTIME>
<EETIME>0</EETIME>
<REASON>0</REASON>
</HISTORY>
</VM>
<VM>
<ID>8</ID>
<UID>0</UID>
<USERNAME>oneadmin</USERNAME>
<NAME>vmext</NAME>
<LAST_POLL>1277910006</LAST_POLL>
<STATE>4</STATE>
<LCM_STATE>5</LCM_STATE>
<STIME>1277377533</STIME>
<ETIME>0</ETIME>
<DEPLOY_ID>thost</DEPLOY_ID>
<MEMORY>256</MEMORY>
<CPU>1</CPU>
<NET_TX>12345</NET_TX>
<NET_RX>0</NET_RX>
<HISTORY>
<SEQ>0</SEQ>
<HOSTNAME>thost</HOSTNAME>
<HID>0</HID>
<STIME>1277377556</STIME>
<ETIME>0</ETIME>
<PSTIME>1277377556</PSTIME>
<PETIME>1277377556</PETIME>
<RSTIME>1277377556</RSTIME>
<RETIME>0</RETIME>
<ESTIME>0</ESTIME>
<EETIME>0</EETIME>
<REASON>0</REASON>
</HISTORY>
</VM>
</VM_POOL>

View File

@ -0,0 +1,23 @@
<VNET>
<ID>3</ID>
<UID>0</UID>
<NAME>Red LAN</NAME>
<TYPE>0</TYPE>
<BRIDGE>vbr0</BRIDGE>
<TEMPLATE>
<BRIDGE>vbr0</BRIDGE>
<DNS>192.169.1.4</DNS>
<NAME>Red LAN</NAME>
<NETWORK_ADDRESS>192.168.0.0</NETWORK_ADDRESS>
<NETWORK_SIZE>C</NETWORK_SIZE>
<TYPE>RANGED</TYPE>
</TEMPLATE>
<LEASES>
<LEASE>
<IP>192.168.0.1</IP>
<MAC>00:03:c0:a8:00:01</MAC>
<USED>1</USED>
<VID>18</VID>
</LEASE>
</LEASES>
</VNET>

View File

@ -0,0 +1,20 @@
<VNET_POOL>
<VNET>
<ID>4</ID>
<UID>0</UID>
<USERNAME>oneadmin</USERNAME>
<NAME>Red LAN</NAME>
<TYPE>0</TYPE>
<BRIDGE>vbr0</BRIDGE>
<TOTAL_LEASES>0</TOTAL_LEASES>
</VNET>
<VNET>
<ID>5</ID>
<UID>0</UID>
<USERNAME>oneadmin</USERNAME>
<NAME>Public</NAME>
<TYPE>0</TYPE>
<BRIDGE>vbr0</BRIDGE>
<TOTAL_LEASES>1</TOTAL_LEASES>
</VNET>
</VNET_POOL>

View File

@ -31,7 +31,7 @@
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
const unsigned int PoolSQL::MAX_POOL_SIZE = 500;
const unsigned int PoolSQL::MAX_POOL_SIZE = 15000;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -61,6 +61,8 @@ PoolSQL::PoolSQL(SqlDB * _db, const char * table): db(_db), lastOID(-1)
oss << "SELECT MAX(oid) FROM " << table;
db->exec(oss,this);
unset_callback();
};
/* -------------------------------------------------------------------------- */
@ -233,10 +235,13 @@ void PoolSQL::replace()
}
else
{
delete index->second;
PoolObjectSQL * tmp_ptr;
tmp_ptr = index->second;
pool.erase(index);
delete tmp_ptr;
oid_queue.pop();
removed = true;
}
@ -292,8 +297,6 @@ int PoolSQL::search(
ostringstream sql;
int rc;
lock();
set_callback(static_cast<Callbackable::Callback>(&PoolSQL::search_cb),
static_cast<void *>(&oids));
@ -301,7 +304,7 @@ int PoolSQL::search(
rc = db->exec(sql, this);
unlock();
unset_callback();
return rc;
}
}

View File

@ -73,6 +73,8 @@ int TestObjectSQL::select(SqlDB *db)
rc = db->exec(oss, this);
unset_callback();
if ((rc != 0) || (oid != boid ))
{
return -1;
@ -85,7 +87,23 @@ int TestObjectSQL::select(SqlDB *db)
int TestObjectSQL::insert(SqlDB *db)
{
return update(db);
ostringstream oss;
int rc;
char * sql_text;
sql_text = db->escape_str(text.c_str());
oss << "INSERT INTO " << table << " "<< db_names <<" VALUES ("
<< oid << ","
<< number << ","
<< "'" << sql_text << "')";
rc = db->exec(oss);
db->free_str(sql_text);
return rc;
}
/* -------------------------------------------------------------------------- */
@ -99,13 +117,13 @@ int TestObjectSQL::update(SqlDB *db)
sql_text = db->escape_str(text.c_str());
oss << "INSERT OR REPLACE INTO " << table << " "<< db_names <<" VALUES ("
oss << "REPLACE INTO " << table << " "<< db_names <<" VALUES ("
<< oid << ","
<< number << ","
<< "'" << sql_text << "')";
rc = db->exec(oss);
db->free_str(sql_text);
return rc;

Some files were not shown because too many files have changed in this diff Show More