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:
commit
11b39a6a34
@ -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',
|
||||
|
@ -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_*/
|
||||
|
@ -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
453
include/Image.h
Normal 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
269
include/ImagePool.h
Normal 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
48
include/ImageTemplate.h
Normal 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_*/
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -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.
|
||||
|
@ -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_*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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_*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
10
install.sh
10
install.sh
@ -255,6 +255,7 @@ BIN_FILES="src/nebula/oned \
|
||||
src/cli/onehost \
|
||||
src/cli/onevnet \
|
||||
src/cli/oneuser \
|
||||
src/cli/oneimage \
|
||||
share/scripts/one"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
@ -291,6 +292,8 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/OpenNebula/Host.rb \
|
||||
src/oca/ruby/OpenNebula/VirtualMachinePool.rb \
|
||||
src/oca/ruby/OpenNebula/VirtualNetwork.rb \
|
||||
src/oca/ruby/OpenNebula/VirtualNetworkPool.rb \
|
||||
src/oca/ruby/OpenNebula/Image.rb \
|
||||
src/oca/ruby/OpenNebula/ImagePool.rb \
|
||||
src/oca/ruby/OpenNebula/XMLUtils.rb"
|
||||
#-------------------------------------------------------------------------------
|
||||
# Driver executable files, to be installed under $LIB_LOCATION/mads
|
||||
@ -611,13 +614,6 @@ if [ "$UNINSTALL" = "no" ] ; then
|
||||
for d in $CHOWN_DIRS; do
|
||||
chown -R $ONEADMIN_USER:$ONEADMIN_GROUP $DESTDIR$d
|
||||
done
|
||||
# Create library links
|
||||
if [ "$CLIENT" = "no" ] ; then
|
||||
ln -s $DESTDIR$LIB_LOCATION/liboneapi.so \
|
||||
$DESTDIR$LIB_LOCATION/liboneapi.so.1
|
||||
ln -s $DESTDIR$LIB_LOCATION/liboneapi.so.1 \
|
||||
$DESTDIR$LIB_LOCATION/liboneapi.so.1.4
|
||||
fi
|
||||
else
|
||||
for d in `echo $DELETE_DIRS | awk '{for (i=NF;i>=1;i--) printf $i" "}'`; do
|
||||
rmdir $d
|
||||
|
@ -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 = [
|
||||
|
@ -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
82
share/hooks/image.rb
Executable 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
|
@ -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=$!
|
||||
|
@ -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+)\](.*)/
|
||||
|
||||
|
@ -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
562
src/cli/oneimage
Executable 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
|
||||
|
||||
|
@ -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
|
||||
|
170
src/cli/onevm
170
src/cli/onevm
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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'
|
||||
|
@ -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'
|
||||
|
@ -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'
|
||||
|
@ -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}"
|
||||
|
@ -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'
|
||||
|
@ -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'
|
||||
|
@ -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 %>
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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 )
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -184,6 +184,8 @@ int HostShare::select(SqlDB * db)
|
||||
|
||||
rc = db->exec(oss,this);
|
||||
|
||||
unset_callback();
|
||||
|
||||
if (hsid != bhsid )
|
||||
{
|
||||
rc = -1;
|
||||
|
@ -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',
|
||||
|
@ -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
687
src/image/Image.cc
Normal 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
189
src/image/ImagePool.cc
Normal 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;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
22
src/image/ImageTemplate.cc
Normal file
22
src/image/ImageTemplate.cc
Normal 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
31
src/image/SConstruct
Normal 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)
|
832
src/image/test/ImagePoolTest.cc
Normal file
832
src/image/test/ImagePoolTest.cc
Normal 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
102
src/image/test/SConstruct
Normal 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
1
src/image/test/one_auth
Normal file
@ -0,0 +1 @@
|
||||
one_user_test:password
|
@ -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);
|
||||
|
@ -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 ----------------
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -42,6 +42,7 @@ env.Append(LIBS=[
|
||||
'nebula_um',
|
||||
'nebula_mad',
|
||||
'nebula_template',
|
||||
'nebula_image',
|
||||
'nebula_pool',
|
||||
'nebula_host',
|
||||
'nebula_vnm',
|
||||
|
@ -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'
|
||||
|
163
src/oca/ruby/OpenNebula/Image.rb
Normal file
163
src/oca/ruby/OpenNebula/Image.rb
Normal 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
|
38
src/oca/ruby/OpenNebula/ImagePool.rb
Normal file
38
src/oca/ruby/OpenNebula/ImagePool.rb
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
97
src/oca/ruby/test/HostPool_spec.rb
Normal file
97
src/oca/ruby/test/HostPool_spec.rb
Normal 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
|
251
src/oca/ruby/test/Host_spec.rb
Normal file
251
src/oca/ruby/test/Host_spec.rb
Normal 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
|
49
src/oca/ruby/test/MockClient.rb
Normal file
49
src/oca/ruby/test/MockClient.rb
Normal 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
|
81
src/oca/ruby/test/UserPool_spec.rb
Normal file
81
src/oca/ruby/test/UserPool_spec.rb
Normal 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
|
161
src/oca/ruby/test/User_spec.rb
Normal file
161
src/oca/ruby/test/User_spec.rb
Normal 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
|
105
src/oca/ruby/test/VirtualMachinePool_spec.rb
Normal file
105
src/oca/ruby/test/VirtualMachinePool_spec.rb
Normal 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
|
464
src/oca/ruby/test/VirtualMachine_spec.rb
Normal file
464
src/oca/ruby/test/VirtualMachine_spec.rb
Normal 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
|
103
src/oca/ruby/test/VirtualNetworkPool_spec.rb
Normal file
103
src/oca/ruby/test/VirtualNetworkPool_spec.rb
Normal 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
|
183
src/oca/ruby/test/VirtualNetwork_spec.rb
Normal file
183
src/oca/ruby/test/VirtualNetwork_spec.rb
Normal 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
|
38
src/oca/ruby/test/xml_test/host.xml
Normal file
38
src/oca/ruby/test/xml_test/host.xml
Normal 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>
|
52
src/oca/ruby/test/xml_test/hostpool.xml
Normal file
52
src/oca/ruby/test/xml_test/hostpool.xml
Normal 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>
|
6
src/oca/ruby/test/xml_test/user.xml
Normal file
6
src/oca/ruby/test/xml_test/user.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<USER>
|
||||
<ID>3</ID>
|
||||
<NAME>dan</NAME>
|
||||
<PASSWORD>d22a12348334v33f71ba846572d25250d40701e72</PASSWORD>
|
||||
<ENABLED>False</ENABLED>
|
||||
</USER>
|
14
src/oca/ruby/test/xml_test/userpool.xml
Normal file
14
src/oca/ruby/test/xml_test/userpool.xml
Normal 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>
|
59
src/oca/ruby/test/xml_test/vm.xml
Normal file
59
src/oca/ruby/test/xml_test/vm.xml
Normal 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>
|
92
src/oca/ruby/test/xml_test/vmpool.xml
Normal file
92
src/oca/ruby/test/xml_test/vmpool.xml
Normal 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>
|
23
src/oca/ruby/test/xml_test/vnet.xml
Normal file
23
src/oca/ruby/test/xml_test/vnet.xml
Normal 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>
|
20
src/oca/ruby/test/xml_test/vnetpool.xml
Normal file
20
src/oca/ruby/test/xml_test/vnetpool.xml
Normal 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>
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user