mirror of
https://github.com/OpenNebula/one.git
synced 2024-12-27 03:21:29 +03:00
Merge branch 'feature-200'
This commit is contained in:
commit
0139994dcf
@ -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',
|
||||
@ -154,6 +155,7 @@ build_scripts=[
|
||||
'src/rm/SConstruct',
|
||||
'src/tm/SConstruct',
|
||||
'src/im/SConstruct',
|
||||
'src/image/SConstruct',
|
||||
'src/dm/SConstruct',
|
||||
'src/scheduler/SConstruct',
|
||||
'src/vnm/SConstruct',
|
||||
|
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
|
||||
|
@ -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>
|
||||
@ -695,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
|
||||
@ -708,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
|
||||
// ------------------------------------------------------------------------
|
||||
@ -989,18 +1001,17 @@ 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,
|
||||
LAST_SEQ = 14,
|
||||
LIMIT = 15
|
||||
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
|
||||
};
|
||||
|
||||
static const char * table;
|
||||
@ -1031,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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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,6 +161,17 @@ public:
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
int nic_attribute(VectorAttribute * nic, int vid);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Template
|
||||
// ------------------------------------------------------------------------
|
||||
@ -233,6 +270,11 @@ private:
|
||||
*/
|
||||
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
|
||||
@ -244,20 +286,6 @@ private:
|
||||
*/
|
||||
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)
|
||||
// *************************************************************************
|
||||
@ -334,7 +362,7 @@ protected:
|
||||
// Constructor
|
||||
//**************************************************************************
|
||||
|
||||
VirtualNetwork(unsigned int _mac_prefix, int _default_size);
|
||||
VirtualNetwork();
|
||||
|
||||
~VirtualNetwork();
|
||||
|
||||
@ -349,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_*/
|
||||
|
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
|
||||
|
@ -64,6 +64,28 @@ NETWORK_SIZE = 254
|
||||
|
||||
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
|
||||
#*******************************************************************************
|
||||
@ -236,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 = [
|
||||
|
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
|
@ -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+)\](.*)/
|
||||
|
||||
|
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
|
||||
|
||||
|
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -197,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 )
|
||||
|
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
|
@ -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");
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -254,6 +254,9 @@ void RequestManager::register_xml_methods()
|
||||
|
||||
xmlrpc_c::methodPtr vnpool_info(new
|
||||
RequestManager::VirtualNetworkPoolInfo(vnpool,upool));
|
||||
|
||||
xmlrpc_c::methodPtr vn_publish(new
|
||||
RequestManager::VirtualNetworkPublish(vnpool, upool));
|
||||
|
||||
xmlrpc_c::methodPtr vn_delete(new
|
||||
RequestManager::VirtualNetworkDelete(vnpool, upool));
|
||||
@ -269,6 +272,30 @@ void RequestManager::register_xml_methods()
|
||||
|
||||
xmlrpc_c::methodPtr userpool_info(new
|
||||
RequestManager::UserPoolInfo(upool));
|
||||
|
||||
xmlrpc_c::methodPtr image_allocate(new
|
||||
RequestManager::ImageAllocate(ipool, upool));
|
||||
|
||||
xmlrpc_c::methodPtr image_delete(new
|
||||
RequestManager::ImageDelete(ipool, upool));
|
||||
|
||||
xmlrpc_c::methodPtr image_info(new
|
||||
RequestManager::ImageInfo(ipool, upool));
|
||||
|
||||
xmlrpc_c::methodPtr image_update(new
|
||||
RequestManager::ImageUpdate(ipool, upool));
|
||||
|
||||
xmlrpc_c::methodPtr image_rm_attribute(new
|
||||
RequestManager::ImageRemoveAttribute(ipool, upool));
|
||||
|
||||
xmlrpc_c::methodPtr image_publish(new
|
||||
RequestManager::ImagePublish(ipool, upool));
|
||||
|
||||
xmlrpc_c::methodPtr image_enable(new
|
||||
RequestManager::ImageEnable(ipool, upool));
|
||||
|
||||
xmlrpc_c::methodPtr imagepool_info(new
|
||||
RequestManager::ImagePoolInfo(ipool, upool));
|
||||
|
||||
/* VM related methods */
|
||||
|
||||
@ -293,6 +320,7 @@ void RequestManager::register_xml_methods()
|
||||
|
||||
RequestManagerRegistry.addMethod("one.vn.allocate", vn_allocate);
|
||||
RequestManagerRegistry.addMethod("one.vn.info", vn_info);
|
||||
RequestManagerRegistry.addMethod("one.vn.publish", vn_publish);
|
||||
RequestManagerRegistry.addMethod("one.vn.delete", vn_delete);
|
||||
|
||||
RequestManagerRegistry.addMethod("one.vnpool.info", vnpool_info);
|
||||
@ -306,6 +334,18 @@ void RequestManager::register_xml_methods()
|
||||
|
||||
RequestManagerRegistry.addMethod("one.userpool.info", userpool_info);
|
||||
|
||||
/* Image related methods*/
|
||||
|
||||
RequestManagerRegistry.addMethod("one.image.allocate",image_allocate);
|
||||
RequestManagerRegistry.addMethod("one.image.delete", image_delete);
|
||||
RequestManagerRegistry.addMethod("one.image.info", image_info);
|
||||
RequestManagerRegistry.addMethod("one.image.update", image_update);
|
||||
RequestManagerRegistry.addMethod("one.image.rmattr", image_rm_attribute);
|
||||
RequestManagerRegistry.addMethod("one.image.publish", image_publish);
|
||||
RequestManagerRegistry.addMethod("one.image.enable", image_enable);
|
||||
|
||||
RequestManagerRegistry.addMethod("one.imagepool.info", imagepool_info);
|
||||
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -50,7 +50,7 @@ void RequestManager::HostInfo::execute(
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
// Perform the allocation in the hostpool
|
||||
// Get the host from the HostPool
|
||||
host = HostInfo::hpool->get(hid,true);
|
||||
|
||||
if ( host == 0 )
|
||||
|
107
src/rm/RequestManagerImageAllocate.cc
Normal file
107
src/rm/RequestManagerImageAllocate.cc
Normal file
@ -0,0 +1,107 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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 "RequestManager.h"
|
||||
#include "NebulaLog.h"
|
||||
|
||||
#include "Nebula.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManager::ImageAllocate::execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
string image_template;
|
||||
|
||||
int iid;
|
||||
int uid;
|
||||
int rc;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"ImageAllocate invoked");
|
||||
|
||||
session = xmlrpc_c::value_string(paramList.getString(0));
|
||||
image_template = xmlrpc_c::value_string(paramList.getString(1));
|
||||
image_template += "\n";
|
||||
|
||||
|
||||
// First, we need to authenticate the user
|
||||
rc = ImageAllocate::upool->authenticate(session);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
uid = rc;
|
||||
|
||||
rc = ImageAllocate::ipool->allocate(uid,image_template,&iid);
|
||||
|
||||
if ( rc < 0 )
|
||||
{
|
||||
goto error_allocate;
|
||||
|
||||
}
|
||||
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true));
|
||||
arrayData.push_back(xmlrpc_c::value_int(iid));
|
||||
|
||||
// Copy arrayresult into retval mem space
|
||||
arrayresult = new xmlrpc_c::value_array(arrayData);
|
||||
*retval = *arrayresult;
|
||||
|
||||
delete arrayresult; // and get rid of the original
|
||||
|
||||
return;
|
||||
|
||||
error_authenticate:
|
||||
oss << "User not authenticated, aborting ImageAllocate call.";
|
||||
goto error_common;
|
||||
|
||||
error_allocate:
|
||||
if (rc == -1)
|
||||
{
|
||||
oss << "Error allocating image, check oned.log";
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << "Error parsing image template";
|
||||
}
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
|
||||
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
|
||||
|
||||
NebulaLog::log("ReM",Log::ERROR,oss);
|
||||
|
||||
xmlrpc_c::value_array arrayresult_error(arrayData);
|
||||
|
||||
*retval = arrayresult_error;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
123
src/rm/RequestManagerImageDelete.cc
Normal file
123
src/rm/RequestManagerImageDelete.cc
Normal file
@ -0,0 +1,123 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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 "RequestManager.h"
|
||||
#include "NebulaLog.h"
|
||||
|
||||
#include "Nebula.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManager::ImageDelete::execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
|
||||
int iid;
|
||||
int uid;
|
||||
int rc;
|
||||
|
||||
Image * image;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"ImageDelete invoked");
|
||||
|
||||
session = xmlrpc_c::value_string(paramList.getString(0));
|
||||
iid = xmlrpc_c::value_int (paramList.getInt(1));
|
||||
|
||||
|
||||
// First, we need to authenticate the user
|
||||
rc = ImageDelete::upool->authenticate(session);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
uid = rc;
|
||||
|
||||
// Get image from the ImagePool
|
||||
image = ImageDelete::ipool->get(iid,true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
goto error_image_get;
|
||||
}
|
||||
|
||||
if ( uid != 0 && uid != image->get_uid() )
|
||||
{
|
||||
goto error_authorization;
|
||||
}
|
||||
|
||||
rc = ImageDelete::ipool->drop(image);
|
||||
|
||||
if ( rc < 0 )
|
||||
{
|
||||
goto error_delete;
|
||||
|
||||
}
|
||||
|
||||
image->unlock();
|
||||
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true));
|
||||
arrayData.push_back(xmlrpc_c::value_int(iid));
|
||||
|
||||
// Copy arrayresult into retval mem space
|
||||
arrayresult = new xmlrpc_c::value_array(arrayData);
|
||||
*retval = *arrayresult;
|
||||
|
||||
delete arrayresult; // and get rid of the original
|
||||
|
||||
return;
|
||||
|
||||
error_authenticate:
|
||||
oss << "User not authenticated, aborting ImageDelete call.";
|
||||
goto error_common;
|
||||
|
||||
error_image_get:
|
||||
oss << "Error getting image with ID = " << iid;
|
||||
goto error_common;
|
||||
|
||||
error_authorization:
|
||||
oss << "User not authorized to delete image, aborting ImageDelete call.";
|
||||
goto error_common;
|
||||
|
||||
error_delete:
|
||||
oss << "Cannot delete image, VMs might be running on it.";
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
|
||||
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
|
||||
|
||||
NebulaLog::log("ReM",Log::ERROR,oss);
|
||||
|
||||
xmlrpc_c::value_array arrayresult_error(arrayData);
|
||||
|
||||
*retval = arrayresult_error;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
129
src/rm/RequestManagerImageEnable.cc
Normal file
129
src/rm/RequestManagerImageEnable.cc
Normal file
@ -0,0 +1,129 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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 "RequestManager.h"
|
||||
#include "NebulaLog.h"
|
||||
|
||||
#include "Nebula.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManager::ImageEnable::execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
|
||||
int iid;
|
||||
bool enable_flag;
|
||||
int uid;
|
||||
int rc;
|
||||
|
||||
Image * image;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"ImageEnable invoked");
|
||||
|
||||
session = xmlrpc_c::value_string (paramList.getString(0));
|
||||
iid = xmlrpc_c::value_int (paramList.getInt(1));
|
||||
enable_flag = xmlrpc_c::value_boolean(paramList.getBoolean(2));
|
||||
|
||||
// First, we need to authenticate the user
|
||||
rc = ImageEnable::upool->authenticate(session);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
uid = rc;
|
||||
|
||||
// Get image from the ImagePool
|
||||
image = ImageEnable::ipool->get(iid,true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
goto error_image_get;
|
||||
}
|
||||
|
||||
if ( uid != 0 && uid != image->get_uid() )
|
||||
{
|
||||
goto error_authorization;
|
||||
}
|
||||
|
||||
rc = image->enable(enable_flag);
|
||||
|
||||
if ( rc < 0 )
|
||||
{
|
||||
goto error_enable;
|
||||
|
||||
}
|
||||
|
||||
ImageEnable::ipool->update(image);
|
||||
|
||||
image->unlock();
|
||||
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true));
|
||||
arrayData.push_back(xmlrpc_c::value_int(iid));
|
||||
|
||||
// Copy arrayresult into retval mem space
|
||||
arrayresult = new xmlrpc_c::value_array(arrayData);
|
||||
*retval = *arrayresult;
|
||||
|
||||
delete arrayresult; // and get rid of the original
|
||||
|
||||
return;
|
||||
|
||||
error_authenticate:
|
||||
oss << "[ImageEnable] User not authenticated, aborting call.";
|
||||
goto error_common;
|
||||
|
||||
error_image_get:
|
||||
oss << "[ImageEnable] Error getting image with ID = " << iid;
|
||||
goto error_common;
|
||||
|
||||
error_authorization:
|
||||
oss << "[ImageEnable] User not authorized to enable/disable image" <<
|
||||
" attributes, aborting call.";
|
||||
image->unlock();
|
||||
goto error_common;
|
||||
|
||||
error_enable:
|
||||
oss << "[ImageEnable] Cannot enable/disable image [" << iid << "]";
|
||||
image->unlock();
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
|
||||
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
|
||||
|
||||
NebulaLog::log("ReM",Log::ERROR,oss);
|
||||
|
||||
xmlrpc_c::value_array arrayresult_error(arrayData);
|
||||
|
||||
*retval = arrayresult_error;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
105
src/rm/RequestManagerImageInfo.cc
Normal file
105
src/rm/RequestManagerImageInfo.cc
Normal file
@ -0,0 +1,105 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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 "RequestManager.h"
|
||||
#include "NebulaLog.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManager::ImageInfo::execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
|
||||
int iid;
|
||||
int uid;
|
||||
int rc;
|
||||
Image * image;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
/* -- RPC specific vars -- */
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"ImageInfo method invoked");
|
||||
|
||||
// Get the parameters
|
||||
session = xmlrpc_c::value_string(paramList.getString(0));
|
||||
iid = xmlrpc_c::value_int (paramList.getInt(1));
|
||||
|
||||
// Get image from the ImagePool
|
||||
image = ImageInfo::ipool->get(iid,true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
goto error_image_get;
|
||||
}
|
||||
|
||||
uid = image->get_uid();
|
||||
|
||||
// Check if it is a valid user
|
||||
rc = ImageInfo::upool->authenticate(session);
|
||||
|
||||
if ( rc != 0 && rc != uid && !image->is_public())
|
||||
{
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
oss << *image;
|
||||
|
||||
image->unlock();
|
||||
|
||||
// All nice, return the host info to the client
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS
|
||||
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
|
||||
|
||||
// Copy arrayresult into retval mem space
|
||||
arrayresult = new xmlrpc_c::value_array(arrayData);
|
||||
*retval = *arrayresult;
|
||||
|
||||
delete arrayresult; // and get rid of the original
|
||||
|
||||
return;
|
||||
|
||||
error_image_get:
|
||||
oss << "Error getting image with ID = " << iid;
|
||||
goto error_common;
|
||||
|
||||
error_authenticate:
|
||||
oss << "User doesn't exist, or not authorized to use image with " <<
|
||||
"ID = " << iid << " , ImageInfo call aborted.";
|
||||
image->unlock();
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
|
||||
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
|
||||
|
||||
NebulaLog::log("ReM",Log::ERROR,oss);
|
||||
|
||||
xmlrpc_c::value_array arrayresult_error(arrayData);
|
||||
|
||||
*retval = arrayresult_error;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
142
src/rm/RequestManagerImagePoolInfo.cc
Executable file
142
src/rm/RequestManagerImagePoolInfo.cc
Executable file
@ -0,0 +1,142 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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 "RequestManager.h"
|
||||
#include "NebulaLog.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManager::ImagePoolInfo::execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
|
||||
ostringstream oss;
|
||||
ostringstream where_string;
|
||||
|
||||
int rc;
|
||||
int uid;
|
||||
int filter_flag;
|
||||
|
||||
/* -- RPC specific vars -- */
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"ImagePoolInfo method invoked");
|
||||
|
||||
// Get the parameters
|
||||
session = xmlrpc_c::value_string(paramList.getString(0));
|
||||
filter_flag = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
|
||||
// Check if it is a valid user
|
||||
rc = ImagePoolInfo::upool->authenticate(session);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
uid = rc;
|
||||
|
||||
where_string.str("");
|
||||
|
||||
/** Filter flag meaning table
|
||||
* -2 :: All Images (just for oneadmin)
|
||||
* -1 :: User's Images AND public images belonging to any user
|
||||
* >= 0 :: UID User's Images (just for oneadmin)
|
||||
**/
|
||||
if ( filter_flag < -2 )
|
||||
{
|
||||
goto error_filter_flag;
|
||||
}
|
||||
|
||||
switch(filter_flag)
|
||||
{
|
||||
case -2:
|
||||
if ( uid != 0 )
|
||||
{
|
||||
goto error_authorization;
|
||||
}
|
||||
// where remains empty.
|
||||
break;
|
||||
case -1:
|
||||
where_string << "UID=" << uid << " OR public = 'YES'";
|
||||
break;
|
||||
default:
|
||||
// Only oneadmin or the user can list a specific user's images.
|
||||
if ( uid != 0 && uid != filter_flag )
|
||||
{
|
||||
goto error_authorization;
|
||||
}
|
||||
where_string << "UID=" << filter_flag;
|
||||
}
|
||||
|
||||
// Call the image pool dump
|
||||
rc = ImagePoolInfo::ipool->dump(oss,where_string.str());
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
goto error_dump;
|
||||
}
|
||||
|
||||
// All nice, return pool info to the client
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS
|
||||
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
|
||||
|
||||
arrayresult = new xmlrpc_c::value_array(arrayData);
|
||||
|
||||
// Copy arrayresult into retval mem space
|
||||
*retval = *arrayresult;
|
||||
|
||||
// and get rid of the original
|
||||
delete arrayresult;
|
||||
|
||||
return;
|
||||
|
||||
error_authenticate:
|
||||
oss << "User not authenticated, ImagePoolInfo call aborted.";
|
||||
goto error_common;
|
||||
|
||||
error_authorization:
|
||||
oss << "User not authorized to perform this operation.";
|
||||
goto error_common;
|
||||
|
||||
error_filter_flag:
|
||||
oss << "Incorrect filter_flag, must be >= -2.";
|
||||
goto error_common;
|
||||
|
||||
error_dump:
|
||||
oss << "Error getting image pool";
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
|
||||
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
|
||||
|
||||
NebulaLog::log("ReM",Log::ERROR,oss);
|
||||
|
||||
xmlrpc_c::value_array arrayresult_error(arrayData);
|
||||
|
||||
*retval = arrayresult_error;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
118
src/rm/RequestManagerImagePublish.cc
Normal file
118
src/rm/RequestManagerImagePublish.cc
Normal file
@ -0,0 +1,118 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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 "RequestManager.h"
|
||||
#include "NebulaLog.h"
|
||||
|
||||
#include "Nebula.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManager::ImagePublish::execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
|
||||
int iid;
|
||||
bool publish_flag;
|
||||
int uid;
|
||||
int rc;
|
||||
|
||||
Image * image;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"ImagePublish invoked");
|
||||
|
||||
session = xmlrpc_c::value_string (paramList.getString(0));
|
||||
iid = xmlrpc_c::value_int (paramList.getInt(1));
|
||||
publish_flag = xmlrpc_c::value_boolean(paramList.getBoolean(2));
|
||||
|
||||
// First, we need to authenticate the user
|
||||
rc = ImagePublish::upool->authenticate(session);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
uid = rc;
|
||||
|
||||
// Get image from the ImagePool
|
||||
image = ImagePublish::ipool->get(iid,true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
goto error_image_get;
|
||||
}
|
||||
|
||||
if ( uid != 0 && uid != image->get_uid() )
|
||||
{
|
||||
goto error_authorization;
|
||||
}
|
||||
|
||||
image->publish(publish_flag);
|
||||
|
||||
ImagePublish::ipool->update(image);
|
||||
|
||||
image->unlock();
|
||||
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true));
|
||||
arrayData.push_back(xmlrpc_c::value_int(iid));
|
||||
|
||||
// Copy arrayresult into retval mem space
|
||||
arrayresult = new xmlrpc_c::value_array(arrayData);
|
||||
*retval = *arrayresult;
|
||||
|
||||
delete arrayresult; // and get rid of the original
|
||||
|
||||
return;
|
||||
|
||||
error_authenticate:
|
||||
oss << "[ImagePublish] User not authenticated, aborting call.";
|
||||
goto error_common;
|
||||
|
||||
error_image_get:
|
||||
oss << "[ImagePublish] Error getting image with ID = " << iid;
|
||||
goto error_common;
|
||||
|
||||
error_authorization:
|
||||
oss << "[ImagePublish] User not authorized to publish/unpublish image" <<
|
||||
", aborting call.";
|
||||
image->unlock();
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
|
||||
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
|
||||
|
||||
NebulaLog::log("ReM",Log::ERROR,oss);
|
||||
|
||||
xmlrpc_c::value_array arrayresult_error(arrayData);
|
||||
|
||||
*retval = arrayresult_error;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
129
src/rm/RequestManagerImageRemoveAttribute.cc
Normal file
129
src/rm/RequestManagerImageRemoveAttribute.cc
Normal file
@ -0,0 +1,129 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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 "RequestManager.h"
|
||||
#include "NebulaLog.h"
|
||||
|
||||
#include "Nebula.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManager::ImageRemoveAttribute::execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
string name;
|
||||
|
||||
int iid;
|
||||
int uid;
|
||||
int rc;
|
||||
|
||||
Image * image;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"ImageRemoveAttribute invoked");
|
||||
|
||||
session = xmlrpc_c::value_string(paramList.getString(0));
|
||||
iid = xmlrpc_c::value_int (paramList.getInt(1));
|
||||
name = xmlrpc_c::value_string(paramList.getString(2));
|
||||
|
||||
// First, we need to authenticate the user
|
||||
rc = ImageRemoveAttribute::upool->authenticate(session);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
uid = rc;
|
||||
|
||||
// Get image from the ImagePool
|
||||
image = ImageRemoveAttribute::ipool->get(iid,true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
goto error_image_get;
|
||||
}
|
||||
|
||||
|
||||
if ( uid != 0 && uid != image->get_uid() )
|
||||
{
|
||||
goto error_authorization;
|
||||
}
|
||||
|
||||
rc = ImageRemoveAttribute::ipool->remove_attribute(image, name);
|
||||
|
||||
if ( rc < 0 )
|
||||
{
|
||||
goto error_remove_attribute;
|
||||
|
||||
}
|
||||
|
||||
image->unlock();
|
||||
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true));
|
||||
arrayData.push_back(xmlrpc_c::value_int(iid));
|
||||
|
||||
// Copy arrayresult into retval mem space
|
||||
arrayresult = new xmlrpc_c::value_array(arrayData);
|
||||
*retval = *arrayresult;
|
||||
|
||||
delete arrayresult; // and get rid of the original
|
||||
|
||||
return;
|
||||
|
||||
error_authenticate:
|
||||
oss << "[ImageRemoveAttribute] User not authenticated, aborting call.";
|
||||
goto error_common;
|
||||
|
||||
error_image_get:
|
||||
oss << "[ImageRemoveAttribute] Error getting image with ID = " << iid;
|
||||
goto error_common;
|
||||
|
||||
error_authorization:
|
||||
oss << "[ImageRemoveAttribute] User not authorized to remove image" <<
|
||||
" attributes aborting call.";
|
||||
image->unlock();
|
||||
goto error_common;
|
||||
|
||||
error_remove_attribute:
|
||||
oss << "[ImageRemoveAttribute] Cannot remove attribute with name = "
|
||||
<< name << " for image [" << iid << "]";
|
||||
image->unlock();
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
|
||||
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
|
||||
|
||||
NebulaLog::log("ReM",Log::ERROR,oss);
|
||||
|
||||
xmlrpc_c::value_array arrayresult_error(arrayData);
|
||||
|
||||
*retval = arrayresult_error;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
134
src/rm/RequestManagerImageUpdate.cc
Normal file
134
src/rm/RequestManagerImageUpdate.cc
Normal file
@ -0,0 +1,134 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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 "RequestManager.h"
|
||||
#include "NebulaLog.h"
|
||||
|
||||
#include "Nebula.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManager::ImageUpdate::execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
|
||||
int iid;
|
||||
int uid;
|
||||
string name;
|
||||
string value;
|
||||
int rc;
|
||||
|
||||
Image * image;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"ImageUpdate invoked");
|
||||
|
||||
session = xmlrpc_c::value_string(paramList.getString(0));
|
||||
iid = xmlrpc_c::value_int (paramList.getInt(1));
|
||||
name = xmlrpc_c::value_string(paramList.getString(2));
|
||||
value = xmlrpc_c::value_string(paramList.getString(3));
|
||||
|
||||
|
||||
|
||||
// First, we need to authenticate the user
|
||||
rc = ImageUpdate::upool->authenticate(session);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
uid = rc;
|
||||
|
||||
// Get image from the ImagePool
|
||||
image = ImageUpdate::ipool->get(iid,true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
goto error_image_get;
|
||||
}
|
||||
|
||||
|
||||
if ( uid != 0 && uid != image->get_uid() )
|
||||
{
|
||||
goto error_authorization;
|
||||
}
|
||||
|
||||
// This will perform the update on the DB as well,
|
||||
// so no need to do it manually
|
||||
rc = ImageUpdate::ipool->replace_attribute(image, name, value);
|
||||
|
||||
if ( rc < 0 )
|
||||
{
|
||||
goto error_update;
|
||||
|
||||
}
|
||||
|
||||
image->unlock();
|
||||
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true));
|
||||
arrayData.push_back(xmlrpc_c::value_int(iid));
|
||||
|
||||
// Copy arrayresult into retval mem space
|
||||
arrayresult = new xmlrpc_c::value_array(arrayData);
|
||||
*retval = *arrayresult;
|
||||
|
||||
delete arrayresult; // and get rid of the original
|
||||
|
||||
return;
|
||||
|
||||
error_authenticate:
|
||||
oss << "User not authenticated, aborting ImageUpdate call.";
|
||||
goto error_common;
|
||||
|
||||
error_image_get:
|
||||
oss << "Error getting image with ID = " << iid;
|
||||
goto error_common;
|
||||
|
||||
error_authorization:
|
||||
oss << "User not authorized to modify image attributes " <<
|
||||
", aborting ImageUpdate call.";
|
||||
image->unlock();
|
||||
goto error_common;
|
||||
|
||||
error_update:
|
||||
oss << "Cannot modify image [" << iid << "] attribute with name = " << name;
|
||||
image->unlock();
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
|
||||
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
|
||||
|
||||
NebulaLog::log("ReM",Log::ERROR,oss);
|
||||
|
||||
xmlrpc_c::value_array arrayresult_error(arrayData);
|
||||
|
||||
*retval = arrayresult_error;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
118
src/rm/RequestManagerVirtualNetworkPublish.cc
Normal file
118
src/rm/RequestManagerVirtualNetworkPublish.cc
Normal file
@ -0,0 +1,118 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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 "RequestManager.h"
|
||||
#include "NebulaLog.h"
|
||||
|
||||
#include "Nebula.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManager::VirtualNetworkPublish::execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
|
||||
int nid;
|
||||
bool publish_flag;
|
||||
int uid;
|
||||
int rc;
|
||||
|
||||
VirtualNetwork * vn;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"VirtualNetworkPublish invoked");
|
||||
|
||||
session = xmlrpc_c::value_string (paramList.getString(0));
|
||||
nid = xmlrpc_c::value_int (paramList.getInt(1));
|
||||
publish_flag = xmlrpc_c::value_boolean(paramList.getBoolean(2));
|
||||
|
||||
// First, we need to authenticate the user
|
||||
rc = VirtualNetworkPublish::upool->authenticate(session);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
uid = rc;
|
||||
|
||||
// Get virtual network from the VirtualNetworkPool
|
||||
vn = VirtualNetworkPublish::vnpool->get(nid,true);
|
||||
|
||||
if ( vn == 0 )
|
||||
{
|
||||
goto error_vn_get;
|
||||
}
|
||||
|
||||
if ( uid != 0 && uid != vn->get_uid() )
|
||||
{
|
||||
goto error_authorization;
|
||||
}
|
||||
|
||||
vn->publish(publish_flag);
|
||||
|
||||
VirtualNetworkPublish::vnpool->update(vn);
|
||||
|
||||
vn->unlock();
|
||||
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true));
|
||||
arrayData.push_back(xmlrpc_c::value_int(nid));
|
||||
|
||||
// Copy arrayresult into retval mem space
|
||||
arrayresult = new xmlrpc_c::value_array(arrayData);
|
||||
*retval = *arrayresult;
|
||||
|
||||
delete arrayresult; // and get rid of the original
|
||||
|
||||
return;
|
||||
|
||||
error_authenticate:
|
||||
oss << "[VirtualNetworkPublish] User not authenticated, aborting call.";
|
||||
goto error_common;
|
||||
|
||||
error_vn_get:
|
||||
oss << "[VirtualNetworkPublish] Error getting VN with ID = " << nid;
|
||||
goto error_common;
|
||||
|
||||
error_authorization:
|
||||
oss << "[VirtualNetworkPublish] User not authorized to (un)publish VN" <<
|
||||
", aborting call.";
|
||||
vn->unlock();
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
|
||||
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
|
||||
|
||||
NebulaLog::log("ReM",Log::ERROR,oss);
|
||||
|
||||
xmlrpc_c::value_array arrayresult_error(arrayData);
|
||||
|
||||
*retval = arrayresult_error;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
@ -34,9 +34,18 @@ source_files=[
|
||||
'RequestManagerHostInfo.cc',
|
||||
'RequestManagerHostPoolInfo.cc',
|
||||
'RequestManagerHostEnable.cc',
|
||||
'RequestManagerImageAllocate.cc',
|
||||
'RequestManagerImageDelete.cc',
|
||||
'RequestManagerImageInfo.cc',
|
||||
'RequestManagerImageUpdate.cc',
|
||||
'RequestManagerImageRemoveAttribute.cc',
|
||||
'RequestManagerImagePublish.cc',
|
||||
'RequestManagerImageEnable.cc',
|
||||
'RequestManagerImagePoolInfo.cc',
|
||||
'RequestManagerVirtualNetworkAllocate.cc',
|
||||
'RequestManagerVirtualNetworkInfo.cc',
|
||||
'RequestManagerVirtualNetworkPoolInfo.cc',
|
||||
'RequestManagerVirtualNetworkPublish.cc',
|
||||
'RequestManagerVirtualNetworkDelete.cc',
|
||||
'RequestManagerUserAllocate.cc',
|
||||
'RequestManagerUserInfo.cc',
|
||||
|
@ -45,7 +45,7 @@ pthread_mutex_t Template::mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
extern "C"
|
||||
{
|
||||
typedef struct yy_buffer_state * YY_BUFFER_STATE;
|
||||
|
||||
|
||||
extern FILE *template_in, *template_out;
|
||||
|
||||
int template_parse(Template * tmpl, char ** errmsg);
|
||||
@ -205,6 +205,33 @@ int Template::remove(const string& name, vector<Attribute *>& values)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int Template::erase(const string& name)
|
||||
{
|
||||
multimap<string, Attribute *>::iterator i;
|
||||
|
||||
pair<
|
||||
multimap<string, Attribute *>::iterator,
|
||||
multimap<string, Attribute *>::iterator
|
||||
> index;
|
||||
int j;
|
||||
|
||||
index = attributes.equal_range(name);
|
||||
|
||||
for ( i = index.first,j=0 ; i != index.second ; i++,j++ )
|
||||
{
|
||||
Attribute * attr = i->second;
|
||||
delete attr;
|
||||
}
|
||||
|
||||
attributes.erase(index.first,index.second);
|
||||
|
||||
return j;
|
||||
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int Template::get(
|
||||
const string& name,
|
||||
vector<const Attribute*>& values) const
|
||||
@ -355,9 +382,9 @@ string& Template::to_str(string& str) const
|
||||
ostream& operator << (ostream& os, const Template& t)
|
||||
{
|
||||
string str;
|
||||
|
||||
|
||||
os << t.to_str(str);
|
||||
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
@ -27,43 +27,11 @@ const char * TemplateSQL::db_names = "(id,name,type,value)";
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int TemplateSQL::insert_cb(void *nil, int num, char **values, char **names)
|
||||
{
|
||||
if ( num<=0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( values[0] == 0 )
|
||||
{
|
||||
id = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
id = atoi(values[0]) + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int TemplateSQL::insert(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
// Get next id from the DB table
|
||||
set_callback(
|
||||
static_cast<Callbackable::Callback>(&TemplateSQL::insert_cb));
|
||||
|
||||
oss << "SELECT MAX(id) FROM " << table;
|
||||
|
||||
rc = db->exec(oss,this);
|
||||
|
||||
unset_callback();
|
||||
|
||||
if ( rc != 0 )
|
||||
if ( id == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -78,10 +46,10 @@ int TemplateSQL::insert(SqlDB * db)
|
||||
int TemplateSQL::update(SqlDB * db)
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
||||
rc = insert_replace(db, true);
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@ -120,7 +88,7 @@ int TemplateSQL::insert_replace(SqlDB *db, bool replace)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(replace)
|
||||
{
|
||||
oss << "REPLACE";
|
||||
@ -262,8 +230,6 @@ int TemplateSQL::replace_attribute(SqlDB * db, Attribute * attribute)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
string * astr;
|
||||
char * sql_attr;
|
||||
|
||||
multimap<string, Attribute *>::iterator i;
|
||||
|
||||
@ -272,45 +238,14 @@ int TemplateSQL::replace_attribute(SqlDB * db, Attribute * attribute)
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = attributes.find(attribute->name());
|
||||
rc = remove_attribute(db, attribute->name());
|
||||
|
||||
if ( i != attributes.end() )
|
||||
if (rc == 0)
|
||||
{
|
||||
astr = i->second->marshall();
|
||||
|
||||
if ( astr == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
sql_attr = db->escape_str((*astr).c_str());
|
||||
|
||||
delete astr;
|
||||
|
||||
if ( sql_attr == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
oss << "DELETE FROM " << table << " WHERE id=" << id
|
||||
<< " AND name='" << attribute->name() << "' AND value='"
|
||||
<< sql_attr << "'";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
db->free_str(sql_attr);
|
||||
|
||||
if (rc != 0 )
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
delete i->second;
|
||||
|
||||
attributes.erase(i);
|
||||
rc = insert_attribute(db,attribute);
|
||||
}
|
||||
|
||||
return insert_attribute(db,attribute);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@ -365,3 +300,62 @@ int TemplateSQL::insert_attribute(SqlDB * db, Attribute * attribute)
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int TemplateSQL::remove_attribute(SqlDB * db, const string& name)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
string * astr;
|
||||
char * sql_attr;
|
||||
|
||||
multimap<string, Attribute *>::iterator i;
|
||||
|
||||
if ( id == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = attributes.find(name);
|
||||
|
||||
if ( i != attributes.end() )
|
||||
{
|
||||
astr = i->second->marshall();
|
||||
|
||||
if ( astr == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
sql_attr = db->escape_str((*astr).c_str());
|
||||
|
||||
delete astr;
|
||||
|
||||
if ( sql_attr == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
oss << "DELETE FROM " << table << " WHERE id=" << id
|
||||
<< " AND name='" << name << "' AND value='"
|
||||
<< sql_attr << "'";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
db->free_str(sql_attr);
|
||||
|
||||
if (rc != 0 )
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
delete i->second;
|
||||
|
||||
attributes.erase(i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
@ -278,6 +278,40 @@ public:
|
||||
CPPUNIT_ASSERT(tr_xml == xml);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
void test_erase()
|
||||
{
|
||||
// There are Single and Vector type attributes, and any att. can be
|
||||
// unique within the template, or not.
|
||||
|
||||
int n;
|
||||
|
||||
// Non-existing attribute
|
||||
n = t1->erase("NON_EXISTING_ATT");
|
||||
CPPUNIT_ASSERT( n == 0 );
|
||||
|
||||
// CPU is a Unique & Single Att.
|
||||
n = t1->erase("CPU");
|
||||
CPPUNIT_ASSERT( n == 1 );
|
||||
|
||||
// GRAPHICS is a Unique & Vector Att.
|
||||
n = t1->erase("GRAPHICS");
|
||||
CPPUNIT_ASSERT( n == 1 );
|
||||
|
||||
// MEMORY is now a Multiple & Single Att.
|
||||
SingleAttribute* satt = new SingleAttribute("MEMORY", "123");
|
||||
t1->set(satt);
|
||||
|
||||
n = t1->erase("MEMORY");
|
||||
CPPUNIT_ASSERT( n == 2 );
|
||||
|
||||
// DISK is a Multiple & Vector Att.
|
||||
n = t1->erase("DISK");
|
||||
CPPUNIT_ASSERT( n == 2 );
|
||||
}
|
||||
|
||||
|
||||
/* ********************************************************************* */
|
||||
/* ********************************************************************* */
|
||||
|
||||
@ -312,6 +346,11 @@ public:
|
||||
ts->addTest(new CppUnit::TestCaller<TemplateTest>(
|
||||
"set() Test",
|
||||
&TemplateTest::test_set));
|
||||
|
||||
ts->addTest(new CppUnit::TestCaller<TemplateTest>(
|
||||
"erase() Test",
|
||||
&TemplateTest::test_erase));
|
||||
|
||||
return ts;
|
||||
}
|
||||
};
|
||||
|
@ -1,17 +1,20 @@
|
||||
#include "TemplateSQL.h"
|
||||
#include "SqliteDB.h"
|
||||
#include "SqlDB.h"
|
||||
#include "MySqlDB.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <TestFixture.h>
|
||||
#include <TestAssert.h>
|
||||
#include <TestSuite.h>
|
||||
#include <TestCaller.h>
|
||||
#include <ui/text/TestRunner.h>
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -34,7 +37,7 @@ public:
|
||||
TemplateSQL(_table,template_id,replace,separator,xml_root){}
|
||||
|
||||
~TSQL(){}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
int insert(SqlDB * db){return TemplateSQL::insert(db);}
|
||||
int update(SqlDB * db){return TemplateSQL::update(db);}
|
||||
@ -46,43 +49,52 @@ public:
|
||||
{return TemplateSQL::replace_attribute(db,attr);}
|
||||
int insert_attribute(SqlDB * db, Attribute * attr)
|
||||
{return TemplateSQL::insert_attribute(db,attr);}
|
||||
int remove_attribute(SqlDB * db, const string& name)
|
||||
{return TemplateSQL::remove_attribute(db,name);};
|
||||
/* --------------------------------------------------------------------- */
|
||||
int id(){return TemplateSQL::id;};
|
||||
void sid(int i){TemplateSQL::id = i;}
|
||||
};
|
||||
|
||||
/* ************************************************************************* */
|
||||
/* ************************************************************************* */
|
||||
/* ************************************************************************* */
|
||||
|
||||
class TemplateSQLTest : public CppUnit::TestFixture
|
||||
class TemplateSQLTest : public CppUnit::TestFixture
|
||||
{
|
||||
|
||||
CPPUNIT_TEST_SUITE (TemplateSQLTest);
|
||||
|
||||
CPPUNIT_TEST (test_insert);
|
||||
CPPUNIT_TEST (test_update);
|
||||
CPPUNIT_TEST (test_select);
|
||||
CPPUNIT_TEST (test_drop);
|
||||
CPPUNIT_TEST (test_replace_attribute);
|
||||
CPPUNIT_TEST (test_insert_attribute);
|
||||
CPPUNIT_TEST (test_remove_attribute);
|
||||
|
||||
CPPUNIT_TEST_SUITE_END ();
|
||||
|
||||
private:
|
||||
SqlDB *db;
|
||||
|
||||
string filename;
|
||||
string db_name;
|
||||
|
||||
string template_ok;
|
||||
string template_xml;
|
||||
|
||||
static void log(
|
||||
const char * module,
|
||||
const Log::MessageType type,
|
||||
const ostringstream& message,
|
||||
const char * filename = 0,
|
||||
Log::MessageType clevel = Log::ERROR)
|
||||
{
|
||||
cerr << message.str() << endl;
|
||||
};
|
||||
|
||||
public:
|
||||
// Global flag to use either Sqlite or MySQL
|
||||
static bool mysql;
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
TemplateSQLTest()
|
||||
{
|
||||
filename = "template_sql.db";
|
||||
db_name = "ONE_test_database";
|
||||
|
||||
template_ok =
|
||||
template_ok =
|
||||
"#This line is a comment\n"
|
||||
" # Other comment\n"
|
||||
"MEMORY=345 # more comments behind an attribute\n"
|
||||
@ -110,31 +122,65 @@ public:
|
||||
|
||||
void setUp()
|
||||
{
|
||||
ostringstream db_bs("CREATE TABLE template (id INTEGER, name TEXT,"
|
||||
" type INTEGER, value TEXT)");
|
||||
|
||||
db = new SqliteDB(filename);
|
||||
CPPUNIT_ASSERT(db->exec(db_bs)== 0);
|
||||
if (mysql)
|
||||
{
|
||||
db = new MySqlDB("localhost","oneadmin","oneadmin",NULL);
|
||||
|
||||
ostringstream oss1;
|
||||
oss1 << "DROP DATABASE IF EXISTS " << db_name;
|
||||
db->exec(oss1);
|
||||
|
||||
ostringstream oss;
|
||||
oss << "CREATE DATABASE " << db_name;
|
||||
db->exec(oss);
|
||||
|
||||
ostringstream oss2;
|
||||
oss2 << "use " << db_name;
|
||||
db->exec(oss2);
|
||||
}
|
||||
else
|
||||
{
|
||||
unlink(db_name.c_str());
|
||||
|
||||
db = new SqliteDB(db_name);
|
||||
}
|
||||
|
||||
ostringstream db_bs(
|
||||
"CREATE TABLE IF NOT EXISTS template (id INTEGER, "
|
||||
"name TEXT, type INTEGER, value TEXT)");
|
||||
|
||||
CPPUNIT_ASSERT(db->exec(db_bs) == 0);
|
||||
}
|
||||
|
||||
void tearDown()
|
||||
{
|
||||
delete db;
|
||||
unlink(filename.c_str());
|
||||
if (mysql)
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << "DROP DATABASE IF EXISTS " << db_name;
|
||||
db->exec(oss);
|
||||
}
|
||||
else
|
||||
{
|
||||
unlink(db_name.c_str());
|
||||
}
|
||||
|
||||
if( db != 0 )
|
||||
delete db;
|
||||
}
|
||||
|
||||
/* ********************************************************************* */
|
||||
/* ********************************************************************* */
|
||||
|
||||
|
||||
void test_insert()
|
||||
{
|
||||
char * error = 0;
|
||||
int rc;
|
||||
string tmp;
|
||||
TSQL t("template");
|
||||
|
||||
|
||||
rc = t.parse(template_ok,&error);
|
||||
|
||||
|
||||
if ( error != 0 )
|
||||
{
|
||||
cerr << error << endl;
|
||||
@ -143,14 +189,52 @@ public:
|
||||
|
||||
CPPUNIT_ASSERT( rc == 0);
|
||||
|
||||
t.sid(0);
|
||||
CPPUNIT_ASSERT( t.insert(db) == 0 );
|
||||
CPPUNIT_ASSERT( t.id() == 0 );
|
||||
|
||||
t.sid(1);
|
||||
CPPUNIT_ASSERT( t.insert(db) == 0 );
|
||||
CPPUNIT_ASSERT( t.id() == 1 );
|
||||
}
|
||||
|
||||
CPPUNIT_ASSERT( t.insert(db) == 0 );
|
||||
CPPUNIT_ASSERT( t.id() == 2 );
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
void test_update()
|
||||
{
|
||||
int rc;
|
||||
string att_name = "NEW_ATT";
|
||||
string value = "";
|
||||
|
||||
ostringstream db_bs(
|
||||
"CREATE TABLE IF NOT EXISTS template_replace (id INTEGER, "
|
||||
"name VARCHAR(256), type INTEGER, value TEXT, PRIMARY KEY(id,name))");
|
||||
|
||||
CPPUNIT_ASSERT(db->exec(db_bs) == 0);
|
||||
|
||||
TSQL t ("template_replace",0);
|
||||
TSQL t2("template_replace",0);
|
||||
|
||||
// Insert template t into the DB
|
||||
t.insert(db);
|
||||
|
||||
// Add a new vector attribute to t, and insert it into the DB
|
||||
SingleAttribute * s_att = new SingleAttribute(att_name, "some value");
|
||||
t.insert_attribute(db, ((Attribute*)s_att));
|
||||
|
||||
|
||||
// Now replace the attribute's value
|
||||
s_att->replace("a new value");
|
||||
|
||||
// And update the DB
|
||||
t.update(db);
|
||||
|
||||
// Read from the DB to t2
|
||||
rc = t2.select(db);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
t2.get(att_name, value);
|
||||
CPPUNIT_ASSERT( value == "a new value" );
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -160,10 +244,38 @@ public:
|
||||
char * error = 0;
|
||||
|
||||
TSQL t("template");
|
||||
TSQL t2("template",0);
|
||||
|
||||
TSQL t2("template",23);
|
||||
|
||||
string t2_xml;
|
||||
|
||||
t.sid(23);
|
||||
t.parse(template_ok,&error);
|
||||
|
||||
int rc = t.insert(db);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
if ( error != 0 )
|
||||
{
|
||||
free(error);
|
||||
}
|
||||
|
||||
CPPUNIT_ASSERT( t2.select(db) == 0 );
|
||||
|
||||
t2.to_xml(t2_xml);
|
||||
|
||||
CPPUNIT_ASSERT( t2_xml == template_xml );
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
void test_drop()
|
||||
{
|
||||
char * error = 0;
|
||||
string str = "";
|
||||
|
||||
TSQL t ("template",0);
|
||||
TSQL t2("template",0);
|
||||
|
||||
t.parse(template_ok,&error);
|
||||
t.insert(db);
|
||||
|
||||
@ -171,47 +283,188 @@ public:
|
||||
{
|
||||
free(error);
|
||||
}
|
||||
|
||||
|
||||
// Drop the template from the DB
|
||||
t.drop(db);
|
||||
|
||||
// Try to read it from the DB
|
||||
CPPUNIT_ASSERT( t2.select(db) == 0 );
|
||||
|
||||
t2.to_xml(t2_xml);
|
||||
|
||||
CPPUNIT_ASSERT( t2_xml == template_xml );
|
||||
// It should be empty
|
||||
CPPUNIT_ASSERT( t2.to_str(str) == "" );
|
||||
}
|
||||
|
||||
/* ********************************************************************* */
|
||||
/* ********************************************************************* */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static CppUnit::TestSuite * suite()
|
||||
void test_replace_attribute()
|
||||
{
|
||||
CppUnit::TestSuite *ts=new CppUnit::TestSuite("TemplateSQL Tests");
|
||||
|
||||
ts->addTest(new CppUnit::TestCaller<TemplateSQLTest>(
|
||||
"bootstrap() Test",
|
||||
&TemplateSQLTest::test_insert));
|
||||
|
||||
ts->addTest(new CppUnit::TestCaller<TemplateSQLTest>(
|
||||
"insert() Test",
|
||||
&TemplateSQLTest::test_insert));
|
||||
int rc;
|
||||
string att_name = "NEW_ATT";
|
||||
string value = "";
|
||||
|
||||
ts->addTest(new CppUnit::TestCaller<TemplateSQLTest>(
|
||||
"select() Test",
|
||||
&TemplateSQLTest::test_select));
|
||||
|
||||
return ts;
|
||||
TSQL t ("template",0);
|
||||
TSQL t2("template",0);
|
||||
|
||||
// Add a new vector attribute to t, and insert it into the DB
|
||||
VectorAttribute * v_att = new VectorAttribute(att_name);
|
||||
v_att->replace("A", "A value");
|
||||
v_att->replace("B", "B value");
|
||||
v_att->replace("C", "C value");
|
||||
|
||||
t.insert(db);
|
||||
t.insert_attribute(db, ((Attribute*)v_att));
|
||||
|
||||
|
||||
|
||||
// Now replace its value, with a single value attribute
|
||||
SingleAttribute * s_att = new SingleAttribute(att_name, "some value");
|
||||
|
||||
t.replace_attribute(db, ((Attribute*)s_att) );
|
||||
|
||||
|
||||
// Read from the DB to t2
|
||||
rc = t2.select(db);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
t2.get(att_name, value);
|
||||
CPPUNIT_ASSERT( value == "some value" );
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
void test_insert_attribute()
|
||||
{
|
||||
Attribute * att;
|
||||
int rc;
|
||||
string att_name = "NEW_ATT";
|
||||
string value = "";
|
||||
|
||||
|
||||
TSQL t ("template",0);
|
||||
TSQL t2("template",0);
|
||||
|
||||
// Add a new attribute to t, and insert it into the DB
|
||||
att = new SingleAttribute(att_name, "some value");
|
||||
|
||||
t.insert(db);
|
||||
t.insert_attribute(db, att);
|
||||
|
||||
// Read from the DB to t2
|
||||
rc = t2.select(db);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
t2.get(att_name, value);
|
||||
CPPUNIT_ASSERT( value == "some value" );
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
void test_remove_attribute()
|
||||
{
|
||||
Attribute * att;
|
||||
int rc;
|
||||
string att_name = "NEW_ATT";
|
||||
string value = "";
|
||||
|
||||
|
||||
TSQL t ("template",0);
|
||||
TSQL t2("template",0);
|
||||
|
||||
// Add a new attribute to t, and insert it into the DB
|
||||
att = new SingleAttribute(att_name, "some value");
|
||||
|
||||
t.insert(db);
|
||||
t.insert_attribute(db, att);
|
||||
|
||||
t.remove_attribute(db, att_name);
|
||||
|
||||
// Read from the DB to t2
|
||||
rc = t2.select(db);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
t2.get(att_name, value);
|
||||
CPPUNIT_ASSERT( value == "" );
|
||||
}
|
||||
};
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
||||
bool TemplateSQLTest::mysql;
|
||||
|
||||
/* ************************************************************************* */
|
||||
/* ************************************************************************* */
|
||||
/* ************************************************************************* */
|
||||
|
||||
static void show_options ()
|
||||
{
|
||||
cout << "Options:\n";
|
||||
cout << " -h --help Show this help\n"
|
||||
" -s --sqlite Run Sqlite tests (default)\n"
|
||||
" -m --mysql Run MySQL tests\n"
|
||||
" -l --log Keep the log file, test.log\n";
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
|
||||
// Option flags
|
||||
bool sqlite_flag = true;
|
||||
bool log_flag = false;
|
||||
|
||||
// Long options
|
||||
const struct option long_opt[] =
|
||||
{
|
||||
{ "sqlite", 0, NULL, 's'},
|
||||
{ "mysql", 0, NULL, 'm'},
|
||||
{ "log", 0, NULL, 'l'},
|
||||
{ "help", 0, NULL, 'h'}
|
||||
};
|
||||
|
||||
int c;
|
||||
while ((c = getopt_long (argc, argv, "smlh", long_opt, NULL)) != -1)
|
||||
switch (c)
|
||||
{
|
||||
case 'm':
|
||||
sqlite_flag = false;
|
||||
break;
|
||||
case 'l':
|
||||
log_flag = true;
|
||||
break;
|
||||
case 'h':
|
||||
show_options();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
CppUnit::TextUi::TestRunner tr;
|
||||
|
||||
|
||||
tr.addTest(TemplateSQLTest::suite());
|
||||
|
||||
NebulaLog::init_log_system(NebulaLog::FILE, Log::DEBUG, "test.log");
|
||||
NebulaLog::log("Test", Log::INFO, "Test started");
|
||||
|
||||
|
||||
if (sqlite_flag)
|
||||
{
|
||||
TemplateSQLTest::mysql = false;
|
||||
NebulaLog::log("Test", Log::INFO, "Running Sqlite tests...");
|
||||
cout << "\nRunning Sqlite tests...\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
TemplateSQLTest::mysql = true;
|
||||
NebulaLog::log("Test", Log::INFO, "Running MySQL tests...");
|
||||
cout << "\nRunning MySQL tests...\n";
|
||||
}
|
||||
|
||||
|
||||
tr.run();
|
||||
|
||||
|
||||
|
||||
if (!log_flag)
|
||||
remove("test.log");
|
||||
|
||||
NebulaLog::finalize_log_system();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -83,13 +83,13 @@ VirtualMachine::~VirtualMachine()
|
||||
const char * VirtualMachine::table = "vm_pool";
|
||||
|
||||
const char * VirtualMachine::db_names =
|
||||
"(oid,uid,name,last_poll,template_id,state,lcm_state,stime,etime,deploy_id"
|
||||
",memory,cpu,net_tx,net_rx,last_seq)";
|
||||
"(oid,uid,name,last_poll, state,lcm_state,stime,etime,deploy_id"
|
||||
",memory,cpu,net_tx,net_rx,last_seq)";
|
||||
|
||||
const char * VirtualMachine::db_bootstrap = "CREATE TABLE IF NOT EXISTS "
|
||||
"vm_pool ("
|
||||
"oid INTEGER PRIMARY KEY,uid INTEGER,name TEXT,"
|
||||
"last_poll INTEGER, template_id INTEGER,state INTEGER,lcm_state INTEGER,"
|
||||
"last_poll INTEGER, state INTEGER,lcm_state INTEGER,"
|
||||
"stime INTEGER,etime INTEGER,deploy_id TEXT,memory INTEGER,cpu INTEGER,"
|
||||
"net_tx INTEGER,net_rx INTEGER, last_seq INTEGER)";
|
||||
|
||||
@ -99,20 +99,19 @@ const char * VirtualMachine::db_bootstrap = "CREATE TABLE IF NOT EXISTS "
|
||||
int VirtualMachine::select_cb(void *nil, int num, char **values, char **names)
|
||||
{
|
||||
if ((values[OID] == 0) ||
|
||||
(values[UID] == 0) ||
|
||||
(values[NAME] == 0) ||
|
||||
(values[LAST_POLL] == 0) ||
|
||||
(values[TEMPLATE_ID] == 0) ||
|
||||
(values[STATE] == 0) ||
|
||||
(values[LCM_STATE] == 0) ||
|
||||
(values[STIME] == 0) ||
|
||||
(values[ETIME] == 0) ||
|
||||
(values[MEMORY] == 0) ||
|
||||
(values[CPU] == 0) ||
|
||||
(values[NET_TX] == 0) ||
|
||||
(values[NET_RX] == 0) ||
|
||||
(values[LAST_SEQ] == 0) ||
|
||||
(num != LIMIT ))
|
||||
(values[UID] == 0) ||
|
||||
(values[NAME] == 0) ||
|
||||
(values[LAST_POLL] == 0) ||
|
||||
(values[STATE] == 0) ||
|
||||
(values[LCM_STATE] == 0) ||
|
||||
(values[STIME] == 0) ||
|
||||
(values[ETIME] == 0) ||
|
||||
(values[MEMORY] == 0) ||
|
||||
(values[CPU] == 0) ||
|
||||
(values[NET_TX] == 0) ||
|
||||
(values[NET_RX] == 0) ||
|
||||
(values[LAST_SEQ] == 0) ||
|
||||
(num != LIMIT ))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -140,7 +139,8 @@ int VirtualMachine::select_cb(void *nil, int num, char **values, char **names)
|
||||
net_rx = atoi(values[NET_RX]);
|
||||
last_seq = atoi(values[LAST_SEQ]);
|
||||
|
||||
vm_template.id = atoi(values[TEMPLATE_ID]);
|
||||
// Virtual Machine template ID is the VM ID
|
||||
vm_template.id = oid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -267,6 +267,14 @@ int VirtualMachine::insert(SqlDB * db)
|
||||
string value;
|
||||
ostringstream oss;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Set a template ID if it wasn't already assigned
|
||||
// ------------------------------------------------------------------------
|
||||
if ( vm_template.id == -1 )
|
||||
{
|
||||
vm_template.id = oid;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Set a name if the VM has not got one and VM_ID
|
||||
// ------------------------------------------------------------------------
|
||||
@ -277,7 +285,6 @@ int VirtualMachine::insert(SqlDB * db)
|
||||
|
||||
vm_template.set(attr);
|
||||
|
||||
|
||||
get_template_attribute("NAME",name);
|
||||
|
||||
if ( name.empty() == true )
|
||||
@ -300,13 +307,24 @@ int VirtualMachine::insert(SqlDB * db)
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
goto error_leases;
|
||||
goto error_leases;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Parse the context & requirements
|
||||
// Get disk images
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
rc = get_disk_images();
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
goto error_images;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Parse the context & requirements
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
rc = parse_context();
|
||||
|
||||
if ( rc != 0 )
|
||||
@ -346,26 +364,31 @@ int VirtualMachine::insert(SqlDB * db)
|
||||
error_update:
|
||||
NebulaLog::log("ONE",Log::ERROR, "Can not update VM in the database");
|
||||
vm_template.drop(db);
|
||||
return -1;
|
||||
goto error_common;
|
||||
|
||||
error_template:
|
||||
NebulaLog::log("ONE",Log::ERROR, "Can not insert template in the database");
|
||||
release_network_leases();
|
||||
return -1;
|
||||
goto error_common;
|
||||
|
||||
error_leases:
|
||||
NebulaLog::log("ONE",Log::ERROR, "Could not get network lease for VM");
|
||||
release_network_leases();
|
||||
return -1;
|
||||
|
||||
error_images:
|
||||
NebulaLog::log("ONE",Log::ERROR, "Could not get disk image for VM");
|
||||
goto error_common;
|
||||
|
||||
error_context:
|
||||
NebulaLog::log("ONE",Log::ERROR, "Could not parse CONTEXT for VM");
|
||||
release_network_leases();
|
||||
return -1;
|
||||
goto error_common;
|
||||
|
||||
error_requirements:
|
||||
NebulaLog::log("ONE",Log::ERROR, "Could not parse REQUIREMENTS for VM");
|
||||
|
||||
error_common:
|
||||
release_network_leases();
|
||||
release_disk_images();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -530,11 +553,7 @@ int VirtualMachine::parse_requirements()
|
||||
|
||||
int VirtualMachine::update(SqlDB * db)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = insert_replace(db, true);
|
||||
|
||||
return rc;
|
||||
return insert_replace(db, true);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@ -577,7 +596,6 @@ int VirtualMachine::insert_replace(SqlDB *db, bool replace)
|
||||
<< uid << ","
|
||||
<< "'" << sql_name << "',"
|
||||
<< last_poll << ","
|
||||
<< vm_template.id << ","
|
||||
<< state << ","
|
||||
<< lcm_state << ","
|
||||
<< stime << ","
|
||||
@ -771,103 +789,119 @@ void VirtualMachine::get_requirements (int& cpu, int& memory, int& disk)
|
||||
|
||||
return;
|
||||
}
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::get_disk_images()
|
||||
{
|
||||
int num_disks, rc;
|
||||
vector<Attribute * > disks;
|
||||
ImagePool * ipool;
|
||||
VectorAttribute * disk;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
ipool = nd.get_ipool();
|
||||
|
||||
num_disks = vm_template.get("DISK",disks);
|
||||
|
||||
for(int i=0, index=0; i<num_disks; i++)
|
||||
{
|
||||
|
||||
disk = dynamic_cast<VectorAttribute * >(disks[i]);
|
||||
|
||||
if ( disk == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = ipool->disk_attribute(disk, &index);
|
||||
|
||||
if (rc == -1) // 0 OK, -2 not using the Image pool
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachine::release_disk_images()
|
||||
{
|
||||
string iid;
|
||||
int num_disks;
|
||||
|
||||
vector<Attribute const * > disks;
|
||||
Image * img;
|
||||
ImagePool * ipool;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
ipool = nd.get_ipool();
|
||||
|
||||
num_disks = get_template_attribute("DISK",disks);
|
||||
|
||||
for(int i=0; i<num_disks; i++)
|
||||
{
|
||||
VectorAttribute const * disk =
|
||||
dynamic_cast<VectorAttribute const * >(disks[i]);
|
||||
|
||||
if ( disk == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
iid = disk->vector_value("IID");
|
||||
|
||||
if ( iid.empty() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
img = ipool->get(atoi(iid.c_str()),true);
|
||||
|
||||
if ( img == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
img->release_image();
|
||||
|
||||
img->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::get_network_leases()
|
||||
{
|
||||
int num_nics, rc;
|
||||
vector<Attribute * > nics;
|
||||
VirtualNetworkPool * vnpool;
|
||||
VirtualNetwork * vn;
|
||||
VectorAttribute * nic;
|
||||
map<string,string> new_nic;
|
||||
|
||||
string ip;
|
||||
string mac;
|
||||
string bridge;
|
||||
string network;
|
||||
string model;
|
||||
|
||||
ostringstream vnid;
|
||||
|
||||
// Set the networking attributes.
|
||||
int num_nics, rc;
|
||||
vector<Attribute * > nics;
|
||||
VirtualNetworkPool * vnpool;
|
||||
VectorAttribute * nic;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
vnpool = nd.get_vnpool();
|
||||
|
||||
num_nics = vm_template.get("NIC",nics);
|
||||
|
||||
for(int i=0; i<num_nics; i++,vnid.str(""))
|
||||
for(int i=0; i<num_nics; i++)
|
||||
{
|
||||
nic = dynamic_cast<VectorAttribute * >(nics[i]);
|
||||
nic = dynamic_cast<VectorAttribute * >(nics[i]);
|
||||
|
||||
if ( nic == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
network = nic->vector_value("NETWORK");
|
||||
rc = vnpool->nic_attribute(nic, oid);
|
||||
|
||||
if ( network.empty() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
vn = vnpool->get(network,true);
|
||||
|
||||
if ( vn == 0 )
|
||||
if (rc == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( vn->get_uid() != uid && vn->get_uid() != 0 && uid != 0)
|
||||
{
|
||||
ostringstream ose;
|
||||
ose << "Owner " << uid << " of the VM doesn't have ownership of Virtual Network "
|
||||
<< vn->get_uid();
|
||||
NebulaLog::log("VMM", Log::ERROR, ose);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
ip = nic->vector_value("IP");
|
||||
|
||||
if (ip.empty())
|
||||
{
|
||||
rc = vn->get_lease(oid, ip, mac, bridge);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = vn->set_lease(oid, ip, mac, bridge);
|
||||
}
|
||||
|
||||
vn->unlock();
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
vnid << vn->get_oid();
|
||||
|
||||
new_nic.insert(make_pair("NETWORK",network));
|
||||
new_nic.insert(make_pair("MAC" ,mac));
|
||||
new_nic.insert(make_pair("BRIDGE" ,bridge));
|
||||
new_nic.insert(make_pair("VNID" ,vnid.str()));
|
||||
new_nic.insert(make_pair("IP" ,ip));
|
||||
|
||||
model = nic->vector_value("MODEL");
|
||||
|
||||
if ( !model.empty() )
|
||||
{
|
||||
new_nic.insert(make_pair("MODEL",model));
|
||||
}
|
||||
|
||||
nic->replace(new_nic);
|
||||
|
||||
new_nic.erase(new_nic.begin(),new_nic.end());
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -156,7 +156,6 @@ int VirtualMachinePool::allocate (
|
||||
bool on_hold)
|
||||
{
|
||||
VirtualMachine * vm;
|
||||
string name;
|
||||
|
||||
char * error_msg;
|
||||
int rc;
|
||||
@ -192,7 +191,7 @@ int VirtualMachinePool::allocate (
|
||||
|
||||
delete vm;
|
||||
|
||||
return -2;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -201,11 +200,6 @@ int VirtualMachinePool::allocate (
|
||||
|
||||
*oid = PoolSQL::allocate(vm);
|
||||
|
||||
if ( *oid == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return *oid;
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,7 @@ main_env.Append(LIBPATH=[
|
||||
cwd + '/src/mad',
|
||||
cwd + '/src/vnm',
|
||||
cwd + '/src/um',
|
||||
cwd + '/src/image',
|
||||
'/usr/include/openssl/',
|
||||
])
|
||||
|
||||
@ -62,6 +63,7 @@ main_env.Append(LIBS=[
|
||||
'nebula_vnm',
|
||||
'nebula_template',
|
||||
'nebula_pool',
|
||||
'nebula_image',
|
||||
'nebula_common',
|
||||
'nebula_log',
|
||||
'nebula_core',
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "VirtualMachinePool.h"
|
||||
#include "ImagePool.h"
|
||||
#include "PoolTest.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
|
||||
#include "VirtualNetwork.h"
|
||||
#include "VirtualNetworkPool.h"
|
||||
|
||||
#include "NebulaLog.h"
|
||||
#include "RangedLeases.h"
|
||||
#include "FixedLeases.h"
|
||||
@ -24,15 +26,13 @@
|
||||
/* Virtual Network :: Constructor/Destructor */
|
||||
/* ************************************************************************** */
|
||||
|
||||
VirtualNetwork::VirtualNetwork(unsigned int mp, int ds):
|
||||
VirtualNetwork::VirtualNetwork():
|
||||
PoolObjectSQL(-1),
|
||||
name(""),
|
||||
uid(-1),
|
||||
bridge(""),
|
||||
type(UNINITIALIZED),
|
||||
leases(0),
|
||||
mac_prefix(mp),
|
||||
default_size(ds){};
|
||||
leases(0){};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -49,14 +49,14 @@ VirtualNetwork::~VirtualNetwork()
|
||||
/* Virtual Network :: Database Access Functions */
|
||||
/* ************************************************************************** */
|
||||
|
||||
const char * VirtualNetwork::table = "network_pool";
|
||||
const char * VirtualNetwork::table = "network_pool";
|
||||
|
||||
const char * VirtualNetwork::db_names = "(oid,uid,name,type,bridge)";
|
||||
const char * VirtualNetwork::db_names = "(oid,uid,name,type,bridge,public)";
|
||||
|
||||
const char * VirtualNetwork::db_bootstrap = "CREATE TABLE IF NOT EXISTS"
|
||||
const char * VirtualNetwork::db_bootstrap = "CREATE TABLE IF NOT EXISTS"
|
||||
" network_pool ("
|
||||
"oid INTEGER PRIMARY KEY, uid INTEGER, name VARCHAR(256), type INTEGER, "
|
||||
"bridge TEXT, UNIQUE(name))";
|
||||
"bridge TEXT, public INTEGER, UNIQUE(name))";
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -68,19 +68,22 @@ int VirtualNetwork::select_cb(void * nil, int num, char **values, char **names)
|
||||
(!values[NAME]) ||
|
||||
(!values[TYPE]) ||
|
||||
(!values[BRIDGE]) ||
|
||||
(!values[PUBLIC]) ||
|
||||
(num != LIMIT ))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
oid = atoi(values[OID]);
|
||||
uid = atoi(values[UID]);
|
||||
oid = atoi(values[OID]);
|
||||
uid = atoi(values[UID]);
|
||||
|
||||
name = values[NAME];
|
||||
name = values[NAME];
|
||||
|
||||
type = (NetworkType)atoi(values[TYPE]);
|
||||
type = (NetworkType)atoi(values[TYPE]);
|
||||
|
||||
bridge = values[BRIDGE];
|
||||
bridge = values[BRIDGE];
|
||||
|
||||
public_vnet = atoi(values[PUBLIC]);
|
||||
|
||||
// Virtual Network template ID is the Network ID
|
||||
vn_template.id = oid;
|
||||
@ -101,6 +104,9 @@ int VirtualNetwork::select(SqlDB * db)
|
||||
|
||||
string network_address;
|
||||
|
||||
unsigned int default_size = VirtualNetworkPool::default_size();
|
||||
unsigned int mac_prefix = VirtualNetworkPool::mac_prefix();
|
||||
|
||||
set_callback(
|
||||
static_cast<Callbackable::Callback>(&VirtualNetwork::select_cb));
|
||||
|
||||
@ -222,6 +228,7 @@ int VirtualNetwork::dump(ostringstream& oss,
|
||||
(!values[NAME]) ||
|
||||
(!values[TYPE]) ||
|
||||
(!values[BRIDGE])||
|
||||
(!values[PUBLIC])||
|
||||
(!values[LIMIT]) ||
|
||||
(num != LIMIT + 2 ))
|
||||
{
|
||||
@ -236,6 +243,7 @@ int VirtualNetwork::dump(ostringstream& oss,
|
||||
"<NAME>" << values[NAME] << "</NAME>" <<
|
||||
"<TYPE>" << values[TYPE] << "</TYPE>" <<
|
||||
"<BRIDGE>" << values[BRIDGE] << "</BRIDGE>" <<
|
||||
"<PUBLIC>" << values[PUBLIC] << "</PUBLIC>" <<
|
||||
"<TOTAL_LEASES>" << values[LIMIT]<< "</TOTAL_LEASES>" <<
|
||||
"</VNET>";
|
||||
|
||||
@ -250,12 +258,69 @@ int VirtualNetwork::insert(SqlDB * db)
|
||||
ostringstream ose;
|
||||
int rc;
|
||||
|
||||
string pub;
|
||||
string s_type;
|
||||
|
||||
unsigned int default_size = VirtualNetworkPool::default_size();
|
||||
unsigned int mac_prefix = VirtualNetworkPool::mac_prefix();
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// VirtualNetwork Attributes from the template
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// ------------ TYPE ----------------------
|
||||
get_template_attribute("TYPE",s_type);
|
||||
|
||||
transform(s_type.begin(),s_type.end(),s_type.begin(),(int(*)(int))toupper);
|
||||
|
||||
if (s_type == "RANGED")
|
||||
{
|
||||
type = VirtualNetwork::RANGED;
|
||||
}
|
||||
else if ( s_type == "FIXED")
|
||||
{
|
||||
type = VirtualNetwork::FIXED;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto error_type;
|
||||
}
|
||||
|
||||
// ------------ NAME ----------------------
|
||||
|
||||
get_template_attribute("NAME",name);
|
||||
|
||||
if (name.empty())
|
||||
{
|
||||
goto error_name;
|
||||
}
|
||||
|
||||
// ------------ BRIDGE --------------------
|
||||
|
||||
get_template_attribute("BRIDGE",bridge);
|
||||
|
||||
if (bridge.empty())
|
||||
{
|
||||
goto error_bridge;
|
||||
}
|
||||
|
||||
// ------------ PUBLIC --------------------
|
||||
|
||||
get_template_attribute("PUBLIC", pub);
|
||||
|
||||
transform (pub.begin(), pub.end(), pub.begin(), (int(*)(int))toupper);
|
||||
|
||||
public_vnet = (pub == "YES");
|
||||
|
||||
vn_template.erase("PUBLIC");
|
||||
|
||||
// ------------ TEMPLATE --------------------
|
||||
|
||||
if ( vn_template.id == -1 )
|
||||
{
|
||||
vn_template.id = oid;
|
||||
}
|
||||
|
||||
// Insert the template first
|
||||
rc = vn_template.insert(db);
|
||||
|
||||
if ( rc != 0 )
|
||||
@ -263,7 +328,10 @@ int VirtualNetwork::insert(SqlDB * db)
|
||||
goto error_template;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Insert the Virtual Network
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
rc = insert_replace(db, false);
|
||||
|
||||
if ( rc != 0 )
|
||||
@ -271,7 +339,10 @@ int VirtualNetwork::insert(SqlDB * db)
|
||||
goto error_update;
|
||||
}
|
||||
|
||||
//Get the leases
|
||||
//--------------------------------------------------------------------------
|
||||
// Get the leases
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
if (type == VirtualNetwork::RANGED)
|
||||
{
|
||||
string nclass = "";
|
||||
@ -314,7 +385,7 @@ int VirtualNetwork::insert(SqlDB * db)
|
||||
mac_prefix,
|
||||
naddr);
|
||||
}
|
||||
else if(type == VirtualNetwork::FIXED)
|
||||
else // VirtualNetwork::FIXED
|
||||
{
|
||||
vector<const Attribute *> vector_leases;
|
||||
|
||||
@ -325,10 +396,6 @@ int VirtualNetwork::insert(SqlDB * db)
|
||||
mac_prefix,
|
||||
vector_leases);
|
||||
}
|
||||
else
|
||||
{
|
||||
goto error_type;
|
||||
}
|
||||
|
||||
if (leases == 0)
|
||||
{
|
||||
@ -337,6 +404,18 @@ int VirtualNetwork::insert(SqlDB * db)
|
||||
|
||||
return 0;
|
||||
|
||||
error_type:
|
||||
ose << "Wrong type in template for Virtual Network id " << oid;
|
||||
goto error_common;
|
||||
|
||||
error_name:
|
||||
ose << "No NAME in template for Virtual Network id " << oid;
|
||||
goto error_common;
|
||||
|
||||
error_bridge:
|
||||
ose << "No BRIDGE in template for Virtual Network id " << oid;
|
||||
goto error_common;
|
||||
|
||||
error_template:
|
||||
ose << "Can not insert in DB template for Virtual Network id " << oid;
|
||||
goto error_common;
|
||||
@ -346,10 +425,6 @@ error_update:
|
||||
vn_template.drop(db);
|
||||
goto error_common;
|
||||
|
||||
error_type:
|
||||
ose << "Wrong type of Virtual Network: " << type;
|
||||
goto error_leases;
|
||||
|
||||
error_addr:
|
||||
ose << "Network address is not defined nid: " << oid;
|
||||
goto error_leases;
|
||||
@ -371,17 +446,7 @@ error_common:
|
||||
|
||||
int VirtualNetwork::update(SqlDB * db)
|
||||
{
|
||||
int rc;
|
||||
|
||||
// Update the template first
|
||||
rc = vn_template.update(db);
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
rc = insert_replace(db, true);
|
||||
}
|
||||
|
||||
return rc;
|
||||
return insert_replace(db, true);
|
||||
}
|
||||
|
||||
int VirtualNetwork::insert_replace(SqlDB *db, bool replace)
|
||||
@ -414,12 +479,13 @@ int VirtualNetwork::insert_replace(SqlDB *db, bool replace)
|
||||
oss << "INSERT";
|
||||
}
|
||||
|
||||
oss << " INTO " << table << " "<< db_names <<" VALUES ("<<
|
||||
oid << "," <<
|
||||
uid << "," <<
|
||||
"'" << sql_name << "'," <<
|
||||
type << "," <<
|
||||
"'" << sql_bridge << "')";
|
||||
oss << " INTO " << table << " "<< db_names <<" VALUES ("
|
||||
<< oid << ","
|
||||
<< uid << ","
|
||||
<< "'" << sql_name << "',"
|
||||
<< type << ","
|
||||
<< "'" << sql_bridge << "',"
|
||||
<< public_vnet << ")";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
@ -483,14 +549,17 @@ string& VirtualNetwork::to_xml(string& xml) const
|
||||
|
||||
os <<
|
||||
"<VNET>" <<
|
||||
"<ID>" << oid << "</ID>" <<
|
||||
"<UID>" << uid << "</UID>" <<
|
||||
"<NAME>" << name << "</NAME>" <<
|
||||
"<TYPE>" << type << "</TYPE>" <<
|
||||
"<BRIDGE>"<< bridge<< "</BRIDGE>" <<
|
||||
"<ID>" << oid << "</ID>" <<
|
||||
"<UID>" << uid << "</UID>" <<
|
||||
"<NAME>" << name << "</NAME>" <<
|
||||
"<TYPE>" << type << "</TYPE>" <<
|
||||
"<BRIDGE>" << bridge << "</BRIDGE>" <<
|
||||
"<PUBLIC>" << public_vnet << "</PUBLIC>" <<
|
||||
vn_template.to_xml(template_xml);
|
||||
if (leases)
|
||||
{
|
||||
os << leases->to_xml(leases_xml);
|
||||
}
|
||||
os << "</VNET>";
|
||||
|
||||
xml = os.str();
|
||||
@ -521,7 +590,8 @@ string& VirtualNetwork::to_str(string& str) const
|
||||
os << "Fixed" << endl;
|
||||
}
|
||||
|
||||
os << "Bridge : " << bridge << endl << endl;
|
||||
os << "Bridge : " << bridge << endl;
|
||||
os << "Public : " << public_vnet << endl << endl;
|
||||
|
||||
os << "....: Template :...." << vn_template.to_str(template_str) << endl << endl;
|
||||
|
||||
@ -537,3 +607,62 @@ string& VirtualNetwork::to_str(string& str) const
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid)
|
||||
{
|
||||
int rc;
|
||||
|
||||
string network;
|
||||
string model;
|
||||
string ip;
|
||||
string mac;
|
||||
|
||||
ostringstream vnid;
|
||||
|
||||
map<string,string> new_nic;
|
||||
|
||||
network = nic->vector_value("NETWORK");
|
||||
model = nic->vector_value("MODEL");
|
||||
ip = nic->vector_value("IP");
|
||||
vnid << oid;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// GET NETWORK LEASE
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
if (ip.empty())
|
||||
{
|
||||
rc = leases->get(vid,ip,mac);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = leases->set(vid,ip,mac);
|
||||
}
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// NEW NIC ATTRIBUTES
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
new_nic.insert(make_pair("NETWORK",network));
|
||||
new_nic.insert(make_pair("MAC" ,mac));
|
||||
new_nic.insert(make_pair("BRIDGE" ,bridge));
|
||||
new_nic.insert(make_pair("VNID" ,vnid.str()));
|
||||
new_nic.insert(make_pair("IP" ,ip));
|
||||
|
||||
if (!model.empty())
|
||||
{
|
||||
new_nic.insert(make_pair("MODEL",model));
|
||||
}
|
||||
|
||||
nic->replace(new_nic);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -20,13 +20,18 @@
|
||||
#include <sstream>
|
||||
#include <ctype.h>
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
unsigned int VirtualNetworkPool::_mac_prefix;
|
||||
unsigned int VirtualNetworkPool::_default_size;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
VirtualNetworkPool::VirtualNetworkPool(SqlDB * db,
|
||||
const string& prefix,
|
||||
int _default_size):
|
||||
PoolSQL(db,VirtualNetwork::table),
|
||||
mac_prefix(0),
|
||||
default_size(_default_size)
|
||||
int __default_size):
|
||||
PoolSQL(db,VirtualNetwork::table)
|
||||
{
|
||||
istringstream iss;
|
||||
size_t pos = 0;
|
||||
@ -35,6 +40,9 @@ VirtualNetworkPool::VirtualNetworkPool(SqlDB * db,
|
||||
|
||||
string mac = prefix;
|
||||
|
||||
_mac_prefix = 0;
|
||||
_default_size = __default_size;
|
||||
|
||||
while ( (pos = mac.find(':')) != string::npos )
|
||||
{
|
||||
mac.replace(pos,1," ");
|
||||
@ -45,16 +53,16 @@ VirtualNetworkPool::VirtualNetworkPool(SqlDB * db,
|
||||
{
|
||||
NebulaLog::log("VNM",Log::ERROR,
|
||||
"Wrong MAC prefix format, using default");
|
||||
mac_prefix = 1; //"00:01"
|
||||
_mac_prefix = 1; //"00:01"
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
iss.str(mac);
|
||||
|
||||
iss >> hex >> mac_prefix >> ws >> hex >> tmp >> ws;
|
||||
mac_prefix <<= 8;
|
||||
mac_prefix += tmp;
|
||||
iss >> hex >> _mac_prefix >> ws >> hex >> tmp >> ws;
|
||||
_mac_prefix <<= 8;
|
||||
_mac_prefix += tmp;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -68,59 +76,27 @@ int VirtualNetworkPool::allocate (
|
||||
VirtualNetwork * vn;
|
||||
char * error_msg;
|
||||
int rc;
|
||||
ostringstream oss;
|
||||
|
||||
string name;
|
||||
string bridge;
|
||||
|
||||
string s_type;
|
||||
|
||||
// Build a new Virtual Network object
|
||||
vn = new VirtualNetwork(mac_prefix, default_size);
|
||||
vn = new VirtualNetwork();
|
||||
|
||||
vn->uid = uid;
|
||||
vn->uid = uid;
|
||||
|
||||
rc = vn->vn_template.parse(stemplate,&error_msg);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << error_msg;
|
||||
NebulaLog::log("VNM", Log::ERROR, oss);
|
||||
free(error_msg);
|
||||
|
||||
delete vn;
|
||||
|
||||
return -2;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Information about the VN needs to be extracted from the template
|
||||
vn->get_template_attribute("TYPE",s_type);
|
||||
|
||||
transform(s_type.begin(),s_type.end(),s_type.begin(),(int(*)(int))toupper);
|
||||
|
||||
if (s_type == "RANGED")
|
||||
{
|
||||
vn->type = VirtualNetwork::RANGED;
|
||||
}
|
||||
else if ( s_type == "FIXED")
|
||||
{
|
||||
vn->type = VirtualNetwork::FIXED;
|
||||
}
|
||||
else
|
||||
{
|
||||
NebulaLog::log("VNM", Log::ERROR, "Wrong type for VirtualNetwork "
|
||||
"template");
|
||||
delete vn;
|
||||
|
||||
return -3;
|
||||
}
|
||||
|
||||
vn->get_template_attribute("NAME",name);
|
||||
vn->name = name;
|
||||
|
||||
vn->get_template_attribute("BRIDGE",bridge);
|
||||
vn->bridge = bridge;
|
||||
|
||||
// Insert the VN in the pool so we have a valid OID
|
||||
|
||||
*oid = PoolSQL::allocate(vn);
|
||||
|
@ -41,7 +41,8 @@ const string templates[] =
|
||||
"TYPE = RANGED\n"
|
||||
"BRIDGE = br0\n"
|
||||
"NETWORK_SIZE = C\n"
|
||||
"NETWORK_ADDRESS = 192.168.0.0\n",
|
||||
"NETWORK_ADDRESS = 192.168.0.0\n"
|
||||
"PUBLIC = YES",
|
||||
|
||||
"NAME = \"Net number two\"\n"
|
||||
"TYPE = fixed\n"
|
||||
@ -68,45 +69,18 @@ const string templates[] =
|
||||
|
||||
const string xmls[] =
|
||||
{
|
||||
"<VNET><ID>0</ID><UID>123</UID><NAME>Net number one</NAME>"
|
||||
"<TYPE>1</TYPE><BRIDGE>br1</BRIDGE><TEMPLATE><BRIDGE>"
|
||||
"<![CDATA[br1]]></BRIDGE><LEASES><IP><![CDATA[130.10.0.1]]>"
|
||||
"</IP><MAC><![CDATA[50:20:20:20:20:20]]></MAC></LEASES><NAME>"
|
||||
"<![CDATA[Net number one]]></NAME><TYPE><![CDATA[FIXED]]></TYPE>"
|
||||
"</TEMPLATE><LEASES>"
|
||||
"<LEASE><IP>130.10.0.1</IP><MAC>50:20:20:20:20:20</MAC>"
|
||||
"<USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>",
|
||||
"<VNET><ID>0</ID><UID>123</UID><NAME>Net number one</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><PUBLIC>0</PUBLIC><TEMPLATE><BRIDGE><![CDATA[br1]]></BRIDGE><LEASES><IP><![CDATA[130.10.0.1]]></IP><MAC><![CDATA[50:20:20:20:20:20]]></MAC></LEASES><NAME><![CDATA[Net number one]]></NAME><TYPE><![CDATA[FIXED]]></TYPE></TEMPLATE><LEASES><LEASE><IP>130.10.0.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>",
|
||||
|
||||
"<VNET><ID>1</ID><UID>261</UID><NAME>A virtual network</NAME>"
|
||||
"<TYPE>0</TYPE><BRIDGE>br0</BRIDGE><TEMPLATE><BRIDGE>"
|
||||
"<![CDATA[br0]]></BRIDGE><NAME><![CDATA[A virtual network]]>"
|
||||
"</NAME><NETWORK_ADDRESS><![CDATA[192.168.0.0]]></NETWORK_ADDRESS>"
|
||||
"<NETWORK_SIZE><![CDATA[C]]></NETWORK_SIZE><TYPE><![CDATA[RANGED]]>"
|
||||
"</TYPE></TEMPLATE>"
|
||||
"<LEASES></LEASES></VNET>",
|
||||
"<VNET><ID>1</ID><UID>261</UID><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><PUBLIC>1</PUBLIC><TEMPLATE><BRIDGE><![CDATA[br0]]></BRIDGE><NAME><![CDATA[A virtual network]]></NAME><NETWORK_ADDRESS><![CDATA[192.168.0.0]]></NETWORK_ADDRESS><NETWORK_SIZE><![CDATA[C]]></NETWORK_SIZE><TYPE><![CDATA[RANGED]]></TYPE></TEMPLATE><LEASES></LEASES></VNET>",
|
||||
|
||||
"<VNET><ID>0</ID><UID>133</UID><NAME>Net number two</NAME>"
|
||||
"<TYPE>1</TYPE><BRIDGE>br1</BRIDGE><TEMPLATE><BRIDGE>"
|
||||
"<![CDATA[br1]]></BRIDGE><LEASES><IP><![CDATA[130.10.2.1]]></IP>"
|
||||
"<MAC><![CDATA[50:20:20:20:20:20]]></MAC></LEASES><NAME>"
|
||||
"<![CDATA[Net number two]]></NAME><TYPE><![CDATA[fixed]]></TYPE>"
|
||||
"</TEMPLATE>"
|
||||
"<LEASES><LEASE><IP>130.10.2.1</IP>"
|
||||
"<MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID>"
|
||||
"</LEASE></LEASES></VNET>"
|
||||
"<VNET><ID>0</ID><UID>133</UID><NAME>Net number two</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><PUBLIC>0</PUBLIC><TEMPLATE><BRIDGE><![CDATA[br1]]></BRIDGE><LEASES><IP><![CDATA[130.10.2.1]]></IP><MAC><![CDATA[50:20:20:20:20:20]]></MAC></LEASES><NAME><![CDATA[Net number two]]></NAME><TYPE><![CDATA[fixed]]></TYPE></TEMPLATE><LEASES><LEASE><IP>130.10.2.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>"
|
||||
};
|
||||
|
||||
const string xml_dump =
|
||||
"<VNET_POOL><VNET><ID>0</ID><UID>1</UID><USERNAME>A user</USERNAME><NAME>Ne"
|
||||
"t number one</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><TOTAL_LEASES>0</TOTA"
|
||||
"L_LEASES></VNET><VNET><ID>1</ID><UID>2</UID><USERNAME>B user</USERNAME><NA"
|
||||
"ME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><TOTAL_LEASES"
|
||||
">0</TOTAL_LEASES></VNET></VNET_POOL>";
|
||||
"<VNET_POOL><VNET><ID>0</ID><UID>1</UID><USERNAME>A user</USERNAME><NAME>Net number one</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES></VNET><VNET><ID>1</ID><UID>2</UID><USERNAME>B user</USERNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES></VNET></VNET_POOL>";
|
||||
|
||||
const string xml_dump_where =
|
||||
"<VNET_POOL><VNET><ID>1</ID><UID>2</UID><USERNAME>B user</USERNAME><NA"
|
||||
"ME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><TOTAL_LEASES"
|
||||
">0</TOTAL_LEASES></VNET></VNET_POOL>";
|
||||
"<VNET_POOL><VNET><ID>1</ID><UID>2</UID><USERNAME>B user</USERNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES></VNET></VNET_POOL>";
|
||||
|
||||
/* ************************************************************************* */
|
||||
/* ************************************************************************* */
|
||||
@ -132,6 +106,7 @@ class VirtualNetworkPoolTest : public PoolTest
|
||||
CPPUNIT_TEST (overlapping_leases_rf);
|
||||
CPPUNIT_TEST (overlapping_leases_rr);
|
||||
CPPUNIT_TEST (drop_leases);
|
||||
CPPUNIT_TEST (public_attribute);
|
||||
|
||||
CPPUNIT_TEST_SUITE_END ();
|
||||
|
||||
@ -218,15 +193,15 @@ public:
|
||||
|
||||
// Check template attribute
|
||||
rc = allocate(3);
|
||||
CPPUNIT_ASSERT( rc == -3 );
|
||||
CPPUNIT_ASSERT( rc == -1 );
|
||||
|
||||
// Parser error for Vnet template
|
||||
//TODO: Check memory leak for allocating strings in template parser
|
||||
rc = allocate(4);
|
||||
CPPUNIT_ASSERT( rc == -2 );
|
||||
CPPUNIT_ASSERT( rc == -1 );
|
||||
|
||||
rc = allocate(5);
|
||||
CPPUNIT_ASSERT( rc == -3 );
|
||||
CPPUNIT_ASSERT( rc == -1 );
|
||||
|
||||
rc = allocate(6);
|
||||
CPPUNIT_ASSERT( rc == -1 );
|
||||
@ -832,6 +807,102 @@ public:
|
||||
CPPUNIT_ASSERT(rc == 0);
|
||||
CPPUNIT_ASSERT(results.size() == 0);
|
||||
}
|
||||
|
||||
|
||||
void public_attribute()
|
||||
{
|
||||
int oid;
|
||||
VirtualNetworkPool * vnp = static_cast<VirtualNetworkPool *>(pool);
|
||||
VirtualNetwork * vn;
|
||||
|
||||
string templates[] =
|
||||
{
|
||||
// false
|
||||
"NAME = \"name A\"\n"
|
||||
"TYPE = FIXED\n"
|
||||
"BRIDGE = br1\n"
|
||||
"LEASES = [IP=130.10.0.1, MAC=50:20:20:20:20:20]\n",
|
||||
|
||||
// true
|
||||
"NAME = \"name B\"\n"
|
||||
"TYPE = FIXED\n"
|
||||
"BRIDGE = br1\n"
|
||||
"LEASES = [IP=130.10.0.1, MAC=50:20:20:20:20:20]\n"
|
||||
"PUBLIC = YES",
|
||||
|
||||
// false
|
||||
"NAME = \"name C\"\n"
|
||||
"TYPE = FIXED\n"
|
||||
"BRIDGE = br1\n"
|
||||
"LEASES = [IP=130.10.0.1, MAC=50:20:20:20:20:20]\n"
|
||||
"PUBLIC = NO",
|
||||
|
||||
// false
|
||||
"NAME = \"name D\"\n"
|
||||
"TYPE = FIXED\n"
|
||||
"BRIDGE = br1\n"
|
||||
"LEASES = [IP=130.10.0.1, MAC=50:20:20:20:20:20]\n"
|
||||
"PUBLIC = 1",
|
||||
|
||||
// true
|
||||
"NAME = \"name E\"\n"
|
||||
"TYPE = FIXED\n"
|
||||
"BRIDGE = br1\n"
|
||||
"LEASES = [IP=130.10.0.1, MAC=50:20:20:20:20:20]\n"
|
||||
"PUBLIC = Yes",
|
||||
|
||||
// false
|
||||
"NAME = \"name F\"\n"
|
||||
"TYPE = FIXED\n"
|
||||
"BRIDGE = br1\n"
|
||||
"LEASES = [IP=130.10.0.1, MAC=50:20:20:20:20:20]\n"
|
||||
"PUBLIC = TRUE",
|
||||
|
||||
// true
|
||||
"NAME = \"name G\"\n"
|
||||
"TYPE = FIXED\n"
|
||||
"BRIDGE = br1\n"
|
||||
"LEASES = [IP=130.10.0.1, MAC=50:20:20:20:20:20]\n"
|
||||
"PUBLIC = yes",
|
||||
|
||||
// false
|
||||
"NAME = \"name H\"\n"
|
||||
"TYPE = FIXED\n"
|
||||
"BRIDGE = br1\n"
|
||||
"LEASES = [IP=130.10.0.1, MAC=50:20:20:20:20:20]\n"
|
||||
"PUBLIC = 'YES'",
|
||||
|
||||
// true
|
||||
"NAME = \"name I\"\n"
|
||||
"TYPE = FIXED\n"
|
||||
"BRIDGE = br1\n"
|
||||
"LEASES = [IP=130.10.0.1, MAC=50:20:20:20:20:20]\n"
|
||||
"PUBLIC = \"YES\"",
|
||||
|
||||
"END"
|
||||
};
|
||||
|
||||
bool results[] = { false, true, false, false,
|
||||
true, false, true, false, true };
|
||||
|
||||
int i = 0;
|
||||
while( templates[i] != "END" )
|
||||
{
|
||||
|
||||
vnp->allocate(0, templates[i], &oid);
|
||||
|
||||
CPPUNIT_ASSERT( oid >= 0 );
|
||||
|
||||
vn = vnp->get( oid, false );
|
||||
CPPUNIT_ASSERT( vn != 0 );
|
||||
|
||||
//cout << endl << i << ":expected " << results[i] << " got " << vn->is_public();
|
||||
|
||||
CPPUNIT_ASSERT( vn->is_public() == results[i] );
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
Loading…
Reference in New Issue
Block a user