1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-12 09:17:41 +03:00

Merge branch 'feature-487'

This commit is contained in:
Ruben S. Montero 2011-04-26 15:35:44 +02:00
commit ba6c8e8e89
54 changed files with 4092 additions and 75 deletions

View File

@ -63,6 +63,7 @@ main_env.Append(LIBPATH=[
cwd+'/src/pool',
cwd+'/src/template',
cwd+'/src/vm',
cwd+'/src/vm_template',
cwd+'/src/vmm',
cwd+'/src/lcm',
cwd+'/src/tm',
@ -190,6 +191,7 @@ build_scripts=[
'src/nebula/SConstruct',
'src/pool/SConstruct',
'src/vm/SConstruct',
'src/vm_template/SConstruct',
'src/vmm/SConstruct',
'src/lcm/SConstruct',
'src/rm/SConstruct',
@ -240,6 +242,7 @@ if testing=='yes':
'src/vm/test/SConstruct',
'src/vnm/test/SConstruct',
'src/xml/test/SConstruct',
'src/vm_template/test/SConstruct',
])
else:
main_env.Append(testing='no')

View File

@ -82,8 +82,12 @@ public:
*/
virtual AttributeType type() = 0;
private:
/**
* Clones the current attribute
*/
virtual Attribute* clone() const = 0;
protected:
/**
* The attribute name.
*/
@ -107,6 +111,11 @@ public:
SingleAttribute(const string& name, const string& value):
Attribute(name),attribute_value(value){};
SingleAttribute(const SingleAttribute& sa):Attribute(sa.attribute_name)
{
attribute_value = sa.attribute_value;
};
~SingleAttribute(){};
/**
@ -173,6 +182,14 @@ public:
return SIMPLE;
};
/**
* Clones the current attribute
*/
Attribute* clone() const
{
return new SingleAttribute(*this);
};
private:
string attribute_value;
@ -195,6 +212,11 @@ public:
VectorAttribute(const string& name,const map<string,string>& value):
Attribute(name),attribute_value(value){};
VectorAttribute(const VectorAttribute& va):Attribute(va.attribute_name)
{
attribute_value = va.attribute_value;
};
~VectorAttribute(){};
/**
@ -256,6 +278,14 @@ public:
return VECTOR;
};
/**
* Clones the current attribute
*/
Attribute* clone() const
{
return new VectorAttribute(*this);
};
private:
static const char * magic_sep;

View File

@ -276,11 +276,12 @@ public:
*/
enum Operation
{
CREATE, /** Authorization to create an object (host, vm, net, image)*/
DELETE, /** Authorization to delete an object */
USE, /** Authorization to use an object */
MANAGE, /** Authorization to manage an object */
INFO /** Authorization to view an object */
CREATE, /** Authorization to create an object */
DELETE, /** Authorization to delete an object */
USE, /** Authorization to use an object */
MANAGE, /** Authorization to manage an object */
INFO, /** Authorization to view an object */
INSTANTIATE /** Authorization to instantiate a VM from a TEMPLATE */
};
/**
@ -293,7 +294,8 @@ public:
NET,
IMAGE,
USER,
CLUSTER
CLUSTER,
TEMPLATE
};
/**

View File

@ -25,6 +25,7 @@
#include "VirtualNetworkPool.h"
#include "HostPool.h"
#include "UserPool.h"
#include "VMTemplatePool.h"
#include "VirtualMachineManager.h"
#include "LifeCycleManager.h"
@ -81,6 +82,11 @@ public:
return cpool;
};
VMTemplatePool * get_tpool()
{
return tpool;
};
// --------------------------------------------------------------
// Manager Accessors
// --------------------------------------------------------------
@ -233,9 +239,9 @@ private:
//Constructors and = are private to only access the class through instance
// -----------------------------------------------------------------------
Nebula():nebula_configuration(0),db(0),vmpool(0),hpool(0),vnpool(0),upool(0),
ipool(0),cpool(0),lcm(0),vmm(0),im(0),tm(0),dm(0),rm(0),hm(0),authm(0),
imagem(0)
Nebula():nebula_configuration(0),db(0),vmpool(0),hpool(0),vnpool(0),
upool(0),ipool(0),cpool(0),tpool(0),lcm(0),vmm(0),im(0),tm(0),dm(0),
rm(0),hm(0),authm(0),imagem(0)
{
const char * nl = getenv("ONE_LOCATION");
@ -300,6 +306,11 @@ private:
delete cpool;
}
if ( tpool != 0)
{
delete tpool;
}
if ( vmm != 0)
{
delete vmm;
@ -392,6 +403,7 @@ private:
UserPool * upool;
ImagePool * ipool;
ClusterPool * cpool;
VMTemplatePool * tpool;
// ---------------------------------------------------------------
// Nebula Managers

View File

@ -24,6 +24,7 @@
#include "VirtualNetworkPool.h"
#include "ImagePool.h"
#include "ClusterPool.h"
#include "VMTemplatePool.h"
#include <xmlrpc-c/base.hpp>
#include <xmlrpc-c/registry.hpp>
@ -46,10 +47,11 @@ public:
UserPool * _upool,
ImagePool * _ipool,
ClusterPool * _cpool,
VMTemplatePool * _tpool,
int _port,
string _xml_log_file)
:vmpool(_vmpool),hpool(_hpool),vnpool(_vnpool),upool(_upool),
ipool(_ipool),cpool(_cpool),port(_port),socket_fd(-1),
ipool(_ipool),cpool(_cpool),tpool(_tpool),port(_port),socket_fd(-1),
xml_log_file(_xml_log_file)
{
am.addListener(this);
@ -130,10 +132,15 @@ private:
ImagePool * ipool;
/**
* Pointer to the Image Pool, to access images
* Pointer to the Cluster Pool, to access clusters
*/
ClusterPool * cpool;
/**
* Pointer to the Template Pool, to access templates
*/
VMTemplatePool * tpool;
/**
* Port number where the connection will be open
*/
@ -314,10 +321,12 @@ private:
VirtualMachinePool * _vmpool,
VirtualNetworkPool * _vnpool,
ImagePool * _ipool,
VMTemplatePool * _tpool,
UserPool * _upool):
vmpool(_vmpool),
vnpool(_vnpool),
ipool(_ipool),
tpool(_tpool),
upool(_upool)
{
_signature="A:ss";
@ -333,6 +342,7 @@ private:
VirtualMachinePool * vmpool;
VirtualNetworkPool * vnpool;
ImagePool * ipool;
VMTemplatePool * tpool;
UserPool * upool;
};
@ -502,6 +512,185 @@ private:
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
/* Template Interface */
/* ---------------------------------------------------------------------- */
class TemplateAllocate: public xmlrpc_c::method
{
public:
TemplateAllocate(
VMTemplatePool * _tpool,
UserPool * _upool):
tpool(_tpool),
upool(_upool)
{
_signature="A:ss";
_help="Allocates a template in the pool";
};
~TemplateAllocate(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
VMTemplatePool * tpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
class TemplateDelete: public xmlrpc_c::method
{
public:
TemplateDelete(VMTemplatePool * _tpool,
UserPool * _upool):
tpool(_tpool),
upool(_upool)
{
_signature="A:si";
_help="Deletes a Template";
};
~TemplateDelete(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
VMTemplatePool * tpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
class TemplateInfo: public xmlrpc_c::method
{
public:
TemplateInfo(VMTemplatePool * _tpool,
UserPool * _upool):
tpool(_tpool),
upool(_upool)
{
_signature="A:si";
_help="Returns information for a Template";
};
~TemplateInfo(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
VMTemplatePool * tpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
class TemplateUpdate: public xmlrpc_c::method
{
public:
TemplateUpdate(VMTemplatePool * _tpool,
UserPool * _upool):
tpool(_tpool),
upool(_upool)
{
_signature="A:siss";
_help="Modifies Template attribute";
};
~TemplateUpdate(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
VMTemplatePool * tpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
class TemplateRemoveAttribute: public xmlrpc_c::method
{
public:
TemplateRemoveAttribute(VMTemplatePool * _tpool,
UserPool * _upool):
tpool(_tpool),
upool(_upool)
{
_signature="A:sis";
_help="Removes Template attribute";
};
~TemplateRemoveAttribute(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
VMTemplatePool * tpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
class TemplatePublish: public xmlrpc_c::method
{
public:
TemplatePublish(VMTemplatePool * _tpool,
UserPool * _upool):
tpool(_tpool),
upool(_upool)
{
_signature="A:sib";
_help="Publish/Unpublish the Template";
};
~TemplatePublish(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
VMTemplatePool * tpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
class TemplatePoolInfo: public xmlrpc_c::method
{
public:
TemplatePoolInfo(
VMTemplatePool * _tpool,
UserPool * _upool):
tpool(_tpool),
upool(_upool)
{
_signature="A:sii";
_help="Returns the template pool";
};
~TemplatePoolInfo(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
VMTemplatePool * tpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
/* Host Interface */
/* ---------------------------------------------------------------------- */

View File

@ -47,6 +47,20 @@ public:
separator(_separator),
xml_root(_xml_root){};
Template(const Template& t)
{
multimap<string,Attribute *>::const_iterator it;
replace_mode = t.replace_mode;
separator = t.separator;
xml_root = t.xml_root;
for (it = t.attributes.begin() ; it != t.attributes.end() ; it++)
{
attributes.insert(make_pair(it->first,(it->second)->clone()));
}
}
/**
* The class destructor frees all the attributes conforming the template
*/
@ -161,8 +175,10 @@ public:
* @param name the attribute name.
* @param value the attribute value, an int, 0 if the attribute is not
* defined or not Single
*
* @returns True if the Single attribute was found
*/
virtual void get(
virtual bool get(
string& name,
int& value) const;

View File

@ -134,15 +134,6 @@ private:
*/
int insert_replace(SqlDB *db, bool replace);
/**
* Callback function to unmarshall a User object (User::select)
* @param num the number of columns read from the DB
* @param names the column names
* @param vaues the column values
* @return 0 on success
*/
int select_cb(void *nil, int num, char **values, char **names);
/**
* Bootstraps the database table(s) associated to the User
*/

190
include/VMTemplate.h Normal file
View File

@ -0,0 +1,190 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#ifndef VMTEMPLATE_H_
#define VMTEMPLATE_H_
#include "PoolObjectSQL.h"
#include "VirtualMachineTemplate.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/**
* The VMTemplate class.
*/
class VMTemplate : public PoolObjectSQL
{
public:
/**
* Function to write a VMTemplate on an output stream
*/
friend ostream& operator<<(ostream& os, VMTemplate& u);
/**
* Function to print the VMTemplate 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;
/**
* Returns true if the object is public
* @return true if the Virtual Network is public
*/
bool isPublic()
{
return (public_template == 1);
};
/**
* Publish or unpublish an object
* @param pub true to publish the object
* @return 0 on success
*/
bool publish(bool pub)
{
if (pub == true)
{
public_template = 1;
}
else
{
public_template = 0;
}
return true;
};
// ------------------------------------------------------------------------
// Template Contents
// ------------------------------------------------------------------------
/**
* Returns a copy of the VirtualMachineTemplate
* @return A copy of the VirtualMachineTemplate
*/
VirtualMachineTemplate * clone_template() const
{
return new VirtualMachineTemplate(
*(static_cast<VirtualMachineTemplate *>(obj_template)));
// TODO: Check if there is a more efficient way to do this copy.
/*string xml_str;
VirtualMachineTemplate * new_template = new VirtualMachineTemplate();
obj_template->to_xml(xml_str);
new_template->from_xml(xml_str);
return new_template;*/
};
private:
// -------------------------------------------------------------------------
// Friends
// -------------------------------------------------------------------------
friend class VMTemplatePool;
// -------------------------------------------------------------------------
// VMTemplate Attributes
// -------------------------------------------------------------------------
/**
* Owner's name
*/
string user_name;
/**
* Public scope of the VMTemplate
*/
int public_template;
/**
* Registration time
*/
time_t regtime;
// *************************************************************************
// 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 one success
*/
int insert_replace(SqlDB *db, bool replace);
/**
* Bootstraps the database table(s) associated to the VMTemplate
*/
static void bootstrap(SqlDB * db)
{
ostringstream oss(VMTemplate::db_bootstrap);
db->exec(oss);
};
/**
* Rebuilds the object from an xml formatted string
* @param xml_str The xml-formatted string
*
* @return 0 on success, -1 otherwise
*/
int from_xml(const string &xml_str);
protected:
// *************************************************************************
// Constructor
// *************************************************************************
VMTemplate(int id, int uid, string _user_name,
VirtualMachineTemplate * _template_contents);
~VMTemplate();
// *************************************************************************
// DataBase implementation
// *************************************************************************
static const char * db_names;
static const char * db_bootstrap;
static const char * table;
/**
* Writes the VMTemplate in the database.
* @param db pointer to the db
* @return 0 on success
*/
int insert(SqlDB *db, string& error_str);
/**
* Writes/updates the VMTemplate data fields in the database.
* @param db pointer to the db
* @return 0 on success
*/
int update(SqlDB *db)
{
return insert_replace(db, true);
};
};
#endif /*VMTEMPLATE_H_*/

146
include/VMTemplatePool.h Normal file
View File

@ -0,0 +1,146 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#ifndef VMTEMPLATE_POOL_H_
#define VMTEMPLATE_POOL_H_
#include "PoolSQL.h"
#include "VMTemplate.h"
/**
* The VMTemplate Pool class.
*/
class VMTemplatePool : public PoolSQL
{
public:
VMTemplatePool(SqlDB * db) : PoolSQL(db, VMTemplate::table){};
~VMTemplatePool(){};
/**
* Allocates a new object, writting it in the pool database. No memory is
* allocated for the object.
* @param uid user id (the owner of the Template)
* @param user_name Owner's user name
* @param template_contents a VM Template object
* @param oid the id assigned to the Template
* @param error_str Returns the error reason, if any
*
* @return the oid assigned to the object, -1 in case of failure
*/
int allocate(int uid,
string user_name,
VirtualMachineTemplate * template_contents,
int * oid,
string& error_str);
/**
* Gets an object from the pool (if needed the object is loaded from the
* database).
* @param oid the object unique identifier
* @param lock locks the object if true
*
* @return a pointer to the object, 0 in case of failure
*/
VMTemplate * get(int oid, bool lock)
{
return static_cast<VMTemplate *>(PoolSQL::get(oid,lock));
};
/**
* Gets an object from the pool (if needed the object is loaded from the
* database).
* @param name of the object
* @param uid id of owner
* @param lock locks the object if true
*
* @return a pointer to the object, 0 in case of failure
*/
VMTemplate * get(const string& name, int uid, bool lock)
{
return static_cast<VMTemplate *>(PoolSQL::get(name,uid,lock));
};
/**
* Updates the object's data in the data base. The object mutex SHOULD be
* locked.
* @param objsql a pointer to the object
*
* @return 0 on success.
*/
int update(VMTemplate * vm_template)
{
return vm_template->update(db);
};
/**
* Drops the object's data in the data base. The object mutex SHOULD be
* locked.
* @param objsql a pointer to the object
* @return 0 on success.
*/
int drop(VMTemplate * vm_template)
{
return PoolSQL::drop(vm_template);
};
/**
* Dumps the pool in XML format. A filter can be also added to the
* query
* @param oss the output stream to dump the pool contents
* @param where filter for the objects, defaults to all
*
* @return 0 on success
*/
int dump(ostringstream& oss, const string& where)
{
return PoolSQL::dump(oss, "VMTEMPLATE_POOL",VMTemplate::table,where);
};
/**
* Bootstraps the database table(s) associated to the pool
*/
static void bootstrap(SqlDB *_db)
{
VMTemplate::bootstrap(_db);
};
private:
//--------------------------------------------------------------------------
// Configuration Attributes for Images
// -------------------------------------------------------------------------
// TODO
//--------------------------------------------------------------------------
// Pool Attributes
// -------------------------------------------------------------------------
// TODO
/**
* Factory method to produce Image objects
* @return a pointer to the new Image
*/
PoolObjectSQL * create()
{
return new VMTemplate(-1,-1,"", 0);
};
};
#endif /*VMTEMPLATE_POOL_H_*/

View File

@ -41,8 +41,10 @@ public:
/**
* Function to allocate a new VM object
* @param uid user id (the owner of the VM)
* @param user_name Owner's user name
* @param vm_template a VM Template object describing the VM
* @param oid the id assigned to the VM (output)
* @param error_str Returns the error reason, if any
* @param on_hold flag to submit on hold
* @return oid on success, -1 error inserting in DB or -2 error parsing
* the template

View File

@ -19,6 +19,8 @@
#include "Template.h"
#include <string.h>
using namespace std;
/**
@ -32,6 +34,8 @@ public:
~VirtualMachineTemplate(){};
VirtualMachineTemplate(VirtualMachineTemplate& vmt):Template(vmt){};
private:
friend class VirtualMachine;
};

View File

@ -26,6 +26,7 @@
#include "HostPool.h"
#include "UserPool.h"
#include "ClusterPool.h"
#include "VMTemplatePool.h"
#include "VirtualMachineManager.h"
#include "LifeCycleManager.h"
@ -43,7 +44,8 @@ protected:
NebulaTest():mysql(false), need_host_pool(false), need_vm_pool(false),
need_vnet_pool(false), need_image_pool(false),
need_user_pool(false), need_cluster_pool(false),need_vmm(false),
need_user_pool(false), need_cluster_pool(false),
need_template_pool(false),need_vmm(false),
need_im(false), need_tm(false),
need_lcm(false), need_dm(false),
need_rm(false), need_hm(false),
@ -63,6 +65,7 @@ public:
bool need_image_pool;
bool need_user_pool;
bool need_cluster_pool;
bool need_template_pool;
bool need_vmm;
bool need_im;
@ -100,6 +103,8 @@ public:
virtual ClusterPool* create_cpool(SqlDB* db);
virtual VMTemplatePool* create_tpool(SqlDB* db);
// ------------------------------------------------------------------------
// Managers
// ------------------------------------------------------------------------
@ -129,6 +134,7 @@ public:
UserPool * upool,
ImagePool * ipool,
ClusterPool * cpool,
VMTemplatePool * tpool,
string log_file);
virtual HookManager* create_hm(VirtualMachinePool * vmpool);

View File

@ -360,6 +360,7 @@ BIN_FILES="src/nebula/oned \
src/cli/oneuser \
src/cli/oneimage \
src/cli/onecluster \
src/cli/onetemplate \
share/scripts/one \
src/authm_mad/oneauth"
@ -404,6 +405,8 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/OpenNebula/Host.rb \
src/oca/ruby/OpenNebula/ImagePool.rb \
src/oca/ruby/OpenNebula/Cluster.rb \
src/oca/ruby/OpenNebula/ClusterPool.rb \
src/oca/ruby/OpenNebula/Template.rb \
src/oca/ruby/OpenNebula/TemplatePool.rb \
src/oca/ruby/OpenNebula/XMLUtils.rb"
#-------------------------------------------------------------------------------
@ -716,7 +719,8 @@ CLI_BIN_FILES="src/cli/onevm \
src/cli/onevnet \
src/cli/oneuser \
src/cli/oneimage \
src/cli/onecluster"
src/cli/onecluster \
src/cli/onetemplate"
#-----------------------------------------------------------------------------
# Sunstone files
@ -825,6 +829,7 @@ MAN_FILES="share/man/oneauth.8.gz \
share/man/oneuser.8.gz \
share/man/onevm.8.gz \
share/man/onevnet.8.gz \
share/man/onetemplate.8.gz \
share/man/econe-describe-images.8.gz \
share/man/econe-describe-instances.8.gz \
share/man/econe-register.8.gz \

View File

@ -17,7 +17,8 @@ TESTS="$TWD_DIR/vnm/test \
$TWD_DIR/vm/test \
$TWD_DIR/um/test \
$TWD_DIR/lcm/test \
$TWD_DIR/pool/test"
$TWD_DIR/pool/test \
$TWD_DIR/vm_template/test"
#-------------------------------------------------------------------------------
# COMMAND LINE PARSING

View File

@ -86,9 +86,10 @@ void AuthRequest::add_auth(Object ob,
case IMAGE: oss << "IMAGE:" ; break;
case USER: oss << "USER:" ; break;
case CLUSTER: oss << "CLUSTER:" ; break;
case TEMPLATE: oss << "TEMPLATE:" ; break;
}
if (op == CREATE) //encode the ob_id, it is a template
if (op == CREATE || op == INSTANTIATE) //encode the ob_id, it is a template
{
string * encoded_id = base64_encode(ob_id);
@ -128,6 +129,10 @@ void AuthRequest::add_auth(Object ob,
case INFO:
oss << "INFO:" ;
break;
case INSTANTIATE:
oss << "INSTANTIATE:" ;
break;
}
oss << owner << ":" << pub;
@ -147,7 +152,14 @@ void AuthRequest::add_auth(Object ob,
switch (op)
{
case CREATE:
if ( ob == VM || ob == NET || ob == IMAGE )
if ( ob == VM || ob == NET || ob == IMAGE || ob == TEMPLATE )
{
auth = true;
}
break;
case INSTANTIATE:
if ( ob == VM )
{
auth = true;
}
@ -158,7 +170,7 @@ void AuthRequest::add_auth(Object ob,
break;
case USE:
if (ob == NET || ob == IMAGE)
if (ob == NET || ob == IMAGE || ob == TEMPLATE)
{
auth = (owner == uid) || pub;
}

View File

@ -48,7 +48,20 @@ class SimplePermissions
VmUsage.new(cpu, memory)
end
# Checks if the quota is enabled, and if it is not exceeded
def check_quota_enabled(uid, object, id, auth_result)
if @quota_enabled and object=='VM' and auth_result
STDERR.puts 'quota enabled'
@quota.update(uid.to_i)
if !@quota.check(uid.to_i, get_vm_usage(id))
auth_result="Quota exceeded"
end
end
return auth_result
end
# Method called by authorization driver
def auth(uid, tokens)
result=true
@ -71,21 +84,18 @@ class SimplePermissions
case action
when 'CREATE'
auth_result=true if %w{VM NET IMAGE}.include? object
if @quota_enabled and object=='VM' and auth_result
STDERR.puts 'quota enabled'
@quota.update(uid.to_i)
if !@quota.check(uid.to_i, get_vm_usage(id))
auth_result="Quota exceeded"
end
end
auth_result=true if %w{VM NET IMAGE TEMPLATE}.include? object
auth_result = check_quota_enabled(uid, object, id, auth_result)
when 'INSTANTIATE'
auth_result = true if %w{VM}.include? object
auth_result = check_quota_enabled(uid, object, id, auth_result)
when 'DELETE'
auth_result = (owner == uid)
when 'USE'
if %w{VM NET IMAGE}.include? object
if %w{VM NET IMAGE TEMPLATE}.include? object
auth_result = ((owner == uid) | (pub=='1'))
elsif object == 'HOST'
auth_result=true

View File

@ -268,15 +268,19 @@ def get_entity_id(name, pool_class)
pool=pool_class.new(get_one_client)
result=pool.info
# TODO: Check for errors
class_name=pool_class.name.split('::').last.gsub(/Pool$/, '')
if( OpenNebula.is_error?(result) )
puts "Error: #{class_name} Pool info could not be retrieved. " +
result.message
exit -1
end
objects=pool.select {|object| object.name==name }
class_name=pool_class.name.split('::').last.gsub(/Pool$/, '')
if objects.length>0
if objects.length>1
puts "There are multiple #{class_name}'s with name #{name}."
puts "There are multiple #{class_name}s with name #{name}."
exit -1
else
result=objects.first.id
@ -313,6 +317,10 @@ def get_cluster_id(name)
get_entity_id(name, OpenNebula::ClusterPool)
end
def get_template_id(name)
get_entity_id(name, OpenNebula::TemplatePool)
end
def str_running_time(data)
stime=Time.at(data["STIME"].to_i)
if data["ETIME"]=="0"

411
src/cli/onetemplate Executable file
View File

@ -0,0 +1,411 @@
#!/usr/bin/env ruby
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #
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'
ShowTableTemplate={
:id => {
:name => "ID",
:desc => "ONE identifier for the Template",
: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 Template",
:size => 20,
:proc => lambda {|d,e|
d.name
}
},
:regtime => {
:name => "REGTIME",
:desc => "Registration time of the Template",
:size => 20,
:proc => lambda {|d,e|
str_register_time(d)
}
},
:public => {
:name => "PUBLIC",
:desc => "Whether the Template is public or not",
:size => 3,
:proc => lambda {|d,e|
if d["PUBLIC"].to_i == 1 then "Yes" else "No" end}
},
:default => [:id, :user, :name, :regtime, :public]
}
class TemplateShow
def initialize(client, filter_flag="-2")
@templatepool=OpenNebula::TemplatePool.new(client, filter_flag.to_i)
@table=ShowTable.new(ShowTableTemplate)
end
def header_template_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=@templatepool.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]
objs=@templatepool.select{|element|
element['USERNAME']==options[:filter_flag] }
else
objs=@templatepool
end
result=[true, ""]
header_template_small
if options
puts @table.data_str(objs, options)
else
puts @table.data_str(objs)
end
result
end
end
end
##########################
## COMMAND LINE PARSING ##
##########################
class OneTemplateParse < CommandParse
COMMANDS_HELP=<<-EOT
Description:
This command enables the user to manage templates.
Commands:
* create (Registers a Template from a template file)
onetemplate create <file>
file is a file name where the Template description is located
* addattr (Add a new Template attribute)
onetemplate addattr <template_id> <attribute_name> <attribute_value>
* update (Modifies a Template attribute)
onetemplate update <template_id> <attribute_name> <attribute_value>
* rmattr (Deletes a Template attribute)
onetemplate rmattr <template_id> <attribute_name>
* publish (Publish a Template)
onetemplate publish <template_id>
* unpublish (Unpublish an Template)
onetemplate unpublish <template_id>
* list (Shows Templates in the pool)
onetemplate list <filter_flag>
where filter_flag can be
a, all --> all the known Templates
m, mine --> the Templates belonging to the user in ONE_AUTH
and all the Public Templates
uid --> Templates of the user identified by this uid
user --> Templates of the user identified by the username
* top (Lists Templates continuously)
onetemplate top
* show (Gets information about an specific Template)
onetemplate show <template_id>
* delete (Deletes a Template)
onetemplate delete <template_id>
EOT
def text_commands
COMMANDS_HELP
end
def text_command_name
"onetemplate"
end
def list_options
table=ShowTable.new(ShowTableTemplate)
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_template(template_path)
begin
template = File.read(ARGV[0])
rescue
result = OpenNebula::Error.new("Can not read template: #{ARGV[0]}")
end
if !is_successful?(result)
puts result.message
exit -1
end
return template
end
onetemplate_opts=OneTemplateParse.new
onetemplate_opts.parse(ARGV)
ops=onetemplate_opts.options
result=[false, "Unknown error"]
command=ARGV.shift
case command
when "create", "register", "add"
check_parameters("create", 1)
template_contents = get_template(ARGV[0])
template = OpenNebula::Template.new(OpenNebula::Template.build_xml, get_one_client)
result=template.allocate(template_contents)
if !OpenNebula.is_error?(result)
puts "ID: " + template.id.to_s if ops[:verbose]
exit 0
end
when "update", "addattr"
check_parameters("update", 3)
template_id = get_template_id(ARGV[0])
template = OpenNebula::Template.new_with_id(template_id, get_one_client)
result = template.update(ARGV[1],ARGV[2])
if is_successful?(result)
puts "Modified template" if ops[:verbose]
end
when "rmattr"
check_parameters("rmattr", 2)
template_id = get_template_id(ARGV[0])
template = OpenNebula::Template.new_with_id(template_id, get_one_client)
result = template.remove_attr(ARGV[1])
if is_successful?(result)
puts "Removed template attribute" if ops[:verbose]
end
when "publish"
check_parameters("publish", 1)
template_id = get_template_id(ARGV[0])
template = OpenNebula::Template.new_with_id(template_id, get_one_client)
result = template.publish
if is_successful?(result)
puts "Template published" if ops[:verbose]
end
when "unpublish"
check_parameters("unpublish", 1)
template_id = get_template_id(ARGV[0])
template = OpenNebula::Template.new_with_id(template_id, get_one_client)
result = template.unpublish
if is_successful?(result)
puts "Template unpublished" if ops[:verbose]
end
when "list"
ops.merge!(get_user_flags)
if !ops[:xml]
templatelist = TemplateShow.new(get_one_client, ops[:filter_user].to_i)
ops[:columns] = ops[:list] if ops[:list]
result = templatelist.list_short(ops)
else
templatepool = OpenNebula::TemplatePool.new(get_one_client,
ops[:filter_user].to_i)
templatepool.info
puts templatepool.to_xml
end
when "top"
ops.merge!(get_user_flags)
templatelist = TemplateShow.new(get_one_client, ops[:filter_user].to_i)
ops[:columns] = ops[:list] if ops[:list]
result = templatelist.top(ops)
when "show"
check_parameters("get_info", 1)
args = expand_args(ARGV)
args.each do |param|
template_id = get_template_id(param)
template = OpenNebula::Template.new_with_id(template_id, get_one_client)
result = template.info
if is_successful?(result)
if !ops[:xml]
str="%-15s: %-20s"
str_h1="%-80s"
print_header(str_h1, "TEMPLATE #{template[:id]} INFORMATION", true)
puts str % ["ID", template.id.to_s]
puts str % ["NAME", template.name]
value = template['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 template['PUBLIC'].to_i == 1
public_str = "Yes"
else
public_str = "No"
end
puts str % ["PUBLIC", public_str]
puts
print_header(str_h1,"TEMPLATE CONTENTS",false)
puts template.template_str
else
puts template.to_xml
end
end
end
when "delete"
check_parameters("delete", 1)
args = expand_args(ARGV)
args.each do |param|
template_id = get_template_id(param)
template = OpenNebula::Template.new(
OpenNebula::Template.build_xml(template_id),
get_one_client)
result = template.delete
if is_successful?(result)
puts "Template correctly deleted" if ops[:verbose]
end
end
else
onetemplate_opts.print_help
exit -1
end
if OpenNebula.is_error?(result)
puts "Error: " + result.message
exit -1
end

View File

@ -318,9 +318,15 @@ machine with the functionality present in onevm.
Commands:
* create (Submits a new virtual machine, adding it to the ONE VM pool)
onevm create <template>
onevm create [OPTION] {<template-file-path>, <template-id>, <template-name>}
template is a file name where the VM description is located
<template-file-path> is a file name where the VM description is located.
<template-id> is the numeric ID of a registered template (using onetemplate)
<template-name> is the name of a registered template (using onetemplate)
OPTION: -n STRING, --name=STRING
Replaces the NAME attribute if the VM is being created from a registered
Template
* deploy (Starts an existing VM in an specific host)
onevm deploy <vm_id> <host_id>
@ -462,6 +468,10 @@ EOT
"Image type") do |o|
options[:type]=o
end
opts.on_tail("-n vm_name", "--name vm_name", String,
"Set VM name") do |o|
options[:vm_name] = o
end
end
end
@ -502,12 +512,32 @@ when "submit", "create"
check_parameters("create", 1)
vm=OpenNebula::VirtualMachine.new(
OpenNebula::VirtualMachine.build_xml, get_one_client)
begin
template=File.read(ARGV[0])
result=vm.allocate(template)
rescue
result=OpenNebula::Error.new("Can not read template: #{ARGV[0]}")
template = ""
success = false
if( File.file?(ARGV[0]) )
# argument is a file path
begin
template = File.read(ARGV[0])
success = true
rescue
result = OpenNebula::Error.new("Can not read template: #{ARGV[0]}")
end
else
# argument could be a template ID or a template name
template_id = get_template_id(ARGV[0])
template = "TEMPLATE_ID = #{template_id}"
template << "\nNAME = #{ops[:vm_name]}" if ops[:vm_name]
success = true
end
if( success )
result = vm.allocate(template)
end
if is_successful?(result)
puts "ID: " + vm.id.to_s if ops[:verbose]
exit 0

View File

@ -26,7 +26,6 @@ env.Prepend(LIBS=[
'nebula_common',
'nebula_sql',
### TODO: delete not needed
'nebula_core_test',
'nebula_host',
@ -40,6 +39,7 @@ env.Prepend(LIBS=[
'nebula_mad',
'nebula_template',
'nebula_vm',
'nebula_vmtemplate',
'nebula_vnm',
'nebula_image',
'nebula_pool',

View File

@ -31,6 +31,7 @@ env.Prepend(LIBS=[
'nebula_mad',
'nebula_template',
'nebula_vm',
'nebula_vmtemplate',
'nebula_vnm',
'nebula_image',
'nebula_pool',

View File

@ -51,7 +51,7 @@ class DummyInformationManager < OpenNebulaDriver
#---------------------------------------------------------------------------
def action_monitor(number, host, not_used)
results = "HYPERVISOR=dummy,"
results << "NAME=#{host},"
results << "HOSTNAME=#{host},"
results << "TOTALCPU=800,"
results << "CPUSPEED=2.2GHz,"

View File

@ -30,6 +30,7 @@ env.Prepend(LIBS=[
'nebula_mad',
'nebula_template',
'nebula_vm',
'nebula_vmtemplate',
'nebula_vnm',
'nebula_image',
'nebula_pool',

View File

@ -235,6 +235,7 @@ void Nebula::start()
UserPool::bootstrap(db);
ImagePool::bootstrap(db);
ClusterPool::bootstrap(db);
VMTemplatePool::bootstrap(db);
}
catch (exception&)
{
@ -276,6 +277,8 @@ void Nebula::start()
default_device_prefix);
cpool = new ClusterPool(db);
tpool = new VMTemplatePool(db);
}
catch (exception&)
{
@ -442,6 +445,7 @@ void Nebula::start()
upool,
ipool,
cpool,
tpool,
rm_port,
log_location + "one_xmlrpc.log");
}

View File

@ -50,6 +50,7 @@ env.Prepend(LIBS=[
'nebula_host',
'nebula_vnm',
'nebula_vm',
'nebula_vmtemplate',
'nebula_common',
'nebula_sql',
'nebula_log',

View File

@ -22,7 +22,6 @@ import org.opennebula.client.Client;
import org.opennebula.client.OneResponse;
import org.opennebula.client.Pool;
import org.opennebula.client.PoolElement;
import org.opennebula.client.vm.VirtualMachinePool;
import org.w3c.dom.Node;
/**
@ -42,7 +41,7 @@ public class ImagePool extends Pool implements Iterable<Image>
*
* @param client XML-RPC Client.
*
* @see VirtualMachinePool#VirtualMachinePool(Client, int)
* @see ImagePool#ImagePool(Client, int)
*/
public ImagePool(Client client)
{
@ -58,8 +57,8 @@ public class ImagePool extends Pool implements Iterable<Image>
* {@link ImagePool#info()}. Possible values:
* <ul>
* <li><= -2: All Images</li>
* <li>-1: Connected user's Images</li>
* <li>>= 0: UID User's VMs</li>
* <li>-1: Connected user's Images and public ones</li>
* <li>>= 0: UID User's Images</li>
* </ul>
*/
public ImagePool(Client client, int filter)
@ -85,8 +84,8 @@ public class ImagePool extends Pool implements Iterable<Image>
* {@link ImagePool#info()}. Possible values:
* <ul>
* <li><= -2: All Images</li>
* <li>-1: Connected user's Images</li>
* <li>>= 0: UID User's VMs</li>
* <li>-1: Connected user's Images and public ones</li>
* <li>>= 0: UID User's Images</li>
* </ul>
* @return If successful the message contains the string
* with the information returned by OpenNebula.

View File

@ -0,0 +1,236 @@
/*******************************************************************************
* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package org.opennebula.client.template;
import org.opennebula.client.Client;
import org.opennebula.client.OneResponse;
import org.opennebula.client.PoolElement;
import org.w3c.dom.Node;
/**
* This class represents an OpenNebula template.
* It also offers static XML-RPC call wrappers.
*/
public class Template extends PoolElement
{
private static final String METHOD_PREFIX = "template.";
private static final String ALLOCATE = METHOD_PREFIX + "allocate";
private static final String INFO = METHOD_PREFIX + "info";
private static final String DELETE = METHOD_PREFIX + "delete";
private static final String UPDATE = METHOD_PREFIX + "update";
private static final String RMATTR = METHOD_PREFIX + "rmattr";
private static final String PUBLISH = METHOD_PREFIX + "publish";
/**
* Creates a new Template representation.
* @param id The template id.
* @param client XML-RPC Client.
*/
public Template(int id, Client client)
{
super(id, client);
}
/**
* @see PoolElement
*/
protected Template(Node xmlElement, Client client)
{
super(xmlElement, client);
}
// =================================
// Static XML-RPC methods
// =================================
/**
* Allocates a new Template in OpenNebula.
*
* @param client XML-RPC Client.
* @param description A string containing the template of the template.
* @return If successful the message contains the associated
* id generated for this Template.
*/
public static OneResponse allocate(Client client, String description)
{
return client.call(ALLOCATE, description);
}
/**
* Retrieves the information of the given Template.
*
* @param client XML-RPC Client.
* @param id The template id for the template to retrieve the information from
* @return If successful the message contains the string
* with the information returned by OpenNebula.
*/
public static OneResponse info(Client client, int id)
{
return client.call(INFO, id);
}
/**
* Deletes a template from OpenNebula.
*
* @param client XML-RPC Client.
* @param id The template id of the target template we want to delete.
* @return A encapsulated response.
*/
public static OneResponse delete(Client client, int id)
{
return client.call(DELETE, id);
}
/**
* Modifies a template attribute.
*
* @param client XML-RPC Client.
* @param id The template id of the target template we want to modify.
* @param att_name The name of the attribute to update.
* @param att_val The new value for the attribute.
* @return If successful the message contains the template id.
*/
public static OneResponse update(Client client, int id,
String att_name, String att_val)
{
return client.call(UPDATE, id, att_name, att_val);
}
/**
* Removes a template attribute.
*
* @param client XML-RPC Client.
* @param id The template id of the target template we want to modify.
* @param att_name The name of the attribute to remove.
* @return If successful the message contains the template id.
*/
public static OneResponse rmattr(Client client, int id, String att_name)
{
return client.call(RMATTR, id, att_name);
}
/**
* Publishes or unpublishes a template.
*
* @param client XML-RPC Client.
* @param id The template id of the target template we want to modify.
* @param publish True for publishing, false for unpublishing.
* @return If successful the message contains the template id.
*/
public static OneResponse publish(Client client, int id, boolean publish)
{
return client.call(PUBLISH, id, publish);
}
// =================================
// Instanced object XML-RPC methods
// =================================
/**
* Retrieves the information of the Template.
*
* @return If successful the message contains the string
* with the information returned by OpenNebula.
*/
public OneResponse info()
{
OneResponse response = info(client, id);
super.processInfo(response);
return response;
}
/**
* Deletes the template from OpenNebula.
*
* @return A encapsulated response.
*/
public OneResponse delete()
{
return delete(client, id);
}
/**
* Modifies a template attribute.
*
* @param att_name The name of the attribute to update.
* @param att_val The new value for the attribute.
* @return If successful the message contains the template id.
*/
public OneResponse update(String att_name, String att_val)
{
return update(client, id, att_name, att_val);
}
/**
* Removes a template attribute.
*
* @param att_name The name of the attribute to remove.
* @return If successful the message contains the template id.
*/
public OneResponse rmattr(String att_name)
{
return rmattr(client, id, att_name);
}
/**
* Publishes or unpublishes the template.
*
* @param publish True for publishing, false for unpublishing.
* @return If successful the message contains the template id.
*/
public OneResponse publish(boolean publish)
{
return publish(client, id, publish);
}
/**
* Publishes the template.
*
* @return If successful the message contains the template id.
*/
public OneResponse publish()
{
return publish(true);
}
/**
* Unpublishes the template.
*
* @return If successful the message contains the template id.
*/
public OneResponse unpublish()
{
return publish(false);
}
// =================================
// Helpers
// =================================
/**
* Returns true if the template is public.
*
* @return True if the template is public.
*/
public boolean isPublic()
{
String isPub = xpath("PUBLIC");
return isPub != null && isPub.equals("1");
}
}

View File

@ -0,0 +1,132 @@
/*******************************************************************************
* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package org.opennebula.client.template;
import java.util.AbstractList;
import java.util.Iterator;
import org.opennebula.client.Client;
import org.opennebula.client.OneResponse;
import org.opennebula.client.Pool;
import org.opennebula.client.PoolElement;
import org.w3c.dom.Node;
/**
* This class represents an OpenNebula Template pool.
* It also offers static XML-RPC call wrappers.
*/
public class TemplatePool extends Pool implements Iterable<Template>
{
private static final String ELEMENT_NAME = "VMTEMPLATE";
private static final String INFO_METHOD = "templatepool.info";
private int filter;
/**
* Creates a new Template pool with the default filter flag value
* set to 0 (Templates belonging to user with UID 0)
*
* @param client XML-RPC Client.
*
* @see TemplatePool#TemplatePool(Client, int)
*/
public TemplatePool(Client client)
{
super(ELEMENT_NAME, client);
this.filter = 0;
}
/**
* Creates a new Template pool.
*
* @param client XML-RPC Client.
* @param filter Filter flag used by default in the method
* {@link TemplatePool#info()}. Possible values:
* <ul>
* <li><= -2: All Templates</li>
* <li>-1: Connected user's Templates and public ones</li>
* <li>>= 0: UID User's Templates</li>
* </ul>
*/
public TemplatePool(Client client, int filter)
{
super(ELEMENT_NAME, client);
this.filter = filter;
}
/* (non-Javadoc)
* @see org.opennebula.client.Pool#factory(org.w3c.dom.Node)
*/
@Override
public PoolElement factory(Node node)
{
return new Template(node, client);
}
/**
* Retrieves all or part of the templates in the pool.
*
* @param client XML-RPC Client.
* @param filter Filter flag used by default in the method
* {@link TemplatePool#info()}. Possible values:
* <ul>
* <li><= -2: All Templates</li>
* <li>-1: Connected user's Templates and public ones</li>
* <li>>= 0: UID User's Templates</li>
* </ul>
* @return If successful the message contains the string
* with the information returned by OpenNebula.
*/
public static OneResponse info(Client client, int filter)
{
return client.call(INFO_METHOD, filter);
}
/**
* Loads the xml representation of all or part of the
* Templates in the pool. The filter used is the one set in
* the constructor.
*
* @see TemplatePool#info(Client, int)
*
* @return If successful the message contains the string
* with the information returned by OpenNebula.
*/
public OneResponse info()
{
OneResponse response = info(client, filter);
super.processInfo(response);
return response;
}
public Iterator<Template> iterator()
{
AbstractList<Template> ab = new AbstractList<Template>()
{
public int size()
{
return getLength();
}
public Template get(int index)
{
return (Template) item(index);
}
};
return ab.iterator();
}
}

View File

@ -19,6 +19,7 @@ package org.opennebula.client.vm;
import org.opennebula.client.Client;
import org.opennebula.client.OneResponse;
import org.opennebula.client.PoolElement;
import org.opennebula.client.template.Template;
import org.w3c.dom.Node;
/**
@ -134,6 +135,56 @@ public class VirtualMachine extends PoolElement{
return client.call(ALLOCATE, description);
}
/**
* Allocates a new VM in OpenNebula from a registered Template.
*
* @param client XML-RPC Client.
* @param templateId The source Template's ID
* @param newName Name for the new VM, replaces the Template's one.
* Can be null.
* @return If successful the message contains the associated
* id generated for this VM.
*/
public static OneResponse allocateFromTemplate(Client client,
int templateId, String newName)
{
String template = "TEMPLATE_ID = " + templateId;
if( newName != null )
{
template += "\nNAME = " + newName;
}
return allocate(client, template);
}
/**
* Allocates a new VM in OpenNebula from a registered Template.
*
* @param client XML-RPC Client.
* @param templateId The source Template's ID
* @return If successful the message contains the associated
* id generated for this VM.
*/
public static OneResponse allocateFromTemplate(Client client,
int templateId)
{
return allocateFromTemplate(client, templateId, null);
}
/**
* Allocates a new VM in OpenNebula from a registered Template.
*
* @param client XML-RPC Client.
* @param template The source Template.
* @return If successful the message contains the associated
* id generated for this VM.
*/
public static OneResponse allocateFromTemplate(Client client,
Template template)
{
return allocateFromTemplate(client, template.id());
}
/**
* Retrieves the information of the given VM.
*

View File

@ -0,0 +1,201 @@
/*******************************************************************************
* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
import static org.junit.Assert.assertTrue;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.opennebula.client.Client;
import org.opennebula.client.OneResponse;
import org.opennebula.client.template.*;
import org.opennebula.client.vm.VirtualMachine;
public class TemplateTest
{
private static Template template;
private static TemplatePool templatePool;
private static Client client;
private static OneResponse res;
private static String name = "new_test_template";
private static String template_str =
"NAME = \"" + name + "\"\n" +
"ATT1 = \"val1\"";
/**
* @throws java.lang.Exception
*/
@BeforeClass
public static void setUpBeforeClass() throws Exception
{
client = new Client();
templatePool = new TemplatePool(client);
}
/**
* @throws java.lang.Exception
*/
@AfterClass
public static void tearDownAfterClass() throws Exception
{
}
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception
{
res = Template.allocate(client, template_str);
int oid = res.isError() ? -1 : Integer.parseInt(res.getMessage());
template = new Template(oid, client);
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception
{
template.delete();
}
@Test
public void allocate()
{
template.delete();
res = Template.allocate(client, template_str);
assertTrue( !res.isError() );
int oid = res.isError() ? -1 : Integer.parseInt(res.getMessage());
template = new Template(oid, client);
templatePool.info();
boolean found = false;
for(Template temp : templatePool)
{
found = found || temp.getName().equals(name);
}
assertTrue( found );
}
@Test
public void info()
{
res = template.info();
assertTrue( !res.isError() );
// assertTrue( template.getId().equals("0") );
// assertTrue( template.id() == 0 );
assertTrue( template.getName().equals(name) );
}
@Test
public void update()
{
// Update an existing att.
res = template.update("ATT1", "new_val_1");
assertTrue( !res.isError() );
res = template.info();
assertTrue( !res.isError() );
assertTrue( template.xpath("TEMPLATE/ATT1").equals("new_val_1") );
// Create a new att.
res = template.update("ATT2", "new_val_2");
assertTrue( !res.isError() );
res = template.info();
assertTrue( !res.isError() );
assertTrue( template.xpath("TEMPLATE/ATT2").equals("new_val_2") );
}
@Test
public void rmattr()
{
res = template.rmattr("ATT1");
assertTrue( !res.isError() );
res = template.info();
assertTrue( !res.isError() );
assertTrue( template.xpath("ATT1").equals("") );
}
@Test
public void publish()
{
res = template.publish();
assertTrue( !res.isError() );
template.info();
assertTrue( template.isPublic() );
}
@Test
public void unpublish()
{
res = template.unpublish();
assertTrue( !res.isError() );
template.info();
assertTrue( !template.isPublic() );
}
@Test
public void attributes()
{
res = template.info();
assertTrue( !res.isError() );
// assertTrue( template.xpath("ID").equals("0") );
assertTrue( template.xpath("NAME").equals(name) );
}
@Test
public void delete()
{
res = template.delete();
assertTrue( !res.isError() );
res = template.info();
assertTrue( res.isError() );
}
@Test
public void allocateFromTemplate()
{
template.info();
assertTrue( !res.isError() );
res = VirtualMachine.allocateFromTemplate(client, template);
assertTrue( !res.isError() );
assertTrue( res.getMessage().equals("0") );
}
}

View File

@ -1,9 +1,27 @@
#!/bin/bash
if [ -z $ONE_LOCATION ]; then
echo "ONE_LOCATION not defined."
exit -1
fi
ONEDCONF_LOCATION="$ONE_LOCATION/etc/oned.conf"
if [ -f $ONEDCONF_LOCATION ]; then
echo "$ONEDCONF_LOCATION has to be overwritten, move it to a safe place."
exit -1
fi
cp oned.conf $ONEDCONF_LOCATION
export ONE_XMLRPC=http://localhost:2666/RPC2
./test.sh ClusterTest
./test.sh HostTest
./test.sh ImageTest
./test.sh SessionTest
./test.sh UserTest
./test.sh VirtualMachineTest
./test.sh VirtualNetworkTest
./test.sh VirtualNetworkTest
./test.sh TemplateTest

View File

@ -37,6 +37,8 @@ require 'OpenNebula/Host'
require 'OpenNebula/HostPool'
require 'OpenNebula/Cluster'
require 'OpenNebula/ClusterPool'
require 'OpenNebula/Template'
require 'OpenNebula/TemplatePool'
module OpenNebula

View File

@ -0,0 +1,126 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #
require 'OpenNebula/Pool'
module OpenNebula
class Template < PoolElement
# ---------------------------------------------------------------------
# Constants and Class Methods
# ---------------------------------------------------------------------
TEMPLATE_METHODS = {
:allocate => "template.allocate",
:info => "template.info",
:update => "template.update",
:rmattr => "template.rmattr",
:publish => "template.publish",
:delete => "template.delete"
}
# Creates a Template description with just its identifier
# this method should be used to create plain Template objects.
# +id+ the id of the user
#
# Example:
# template = Template.new(Template.build_xml(3),rpc_client)
#
def Template.build_xml(pe_id=nil)
if pe_id
obj_xml = "<VMTEMPLATE><ID>#{pe_id}</ID></VMTEMPLATE>"
else
obj_xml = "<VMTEMPLATE></VMTEMPLATE>"
end
XMLElement.build_xml(obj_xml,'VMTEMPLATE')
end
# ---------------------------------------------------------------------
# Class constructor
# ---------------------------------------------------------------------
def initialize(xml, client)
super(xml,client)
@client = client
end
# ---------------------------------------------------------------------
# XML-RPC Methods for the Template Object
# ---------------------------------------------------------------------
# Retrieves the information of the given Template.
def info()
super(TEMPLATE_METHODS[:info], 'VMTEMPLATE')
end
# Allocates a new Template in OpenNebula
#
# +templatename+ A string containing the name of the Template.
def allocate(templatename)
super(TEMPLATE_METHODS[:allocate], templatename)
end
# Deletes the Template
def delete()
super(TEMPLATE_METHODS[:delete])
end
# Modifies a template attribute
#
# +name+ Name of the attribute to be changed
#
# +value+ New value for the attribute
def update(name, value)
super(TEMPLATE_METHODS[:update], name, value)
end
# Deletes a template attribute
#
# +name+ Name of the attribute to be deleted
def remove_attr(name)
do_rm_attr(name)
end
# Publishes the Template, to be used by other users
def publish
set_publish(true)
end
# Unplubishes the Image
def unpublish
set_publish(false)
end
private
def set_publish(published)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(TEMPLATE_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(TEMPLATE_METHODS[:rmattr], @pe_id, name)
rc = nil if !OpenNebula.is_error?(rc)
return rc
end
end
end

View File

@ -0,0 +1,55 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #
require 'OpenNebula/Pool'
module OpenNebula
class TemplatePool < Pool
# ---------------------------------------------------------------------
# Constants and Class attribute accessors
# ---------------------------------------------------------------------
TEMPLATE_POOL_METHODS = {
:info => "templatepool.info"
}
# ---------------------------------------------------------------------
# Class constructor & Pool Methods
# ---------------------------------------------------------------------
# +client+ a Client object that represents an XML-RPC connection
# +user_id+ used to refer to a Pool with Templates from that user
def initialize(client, user_id=-1)
super('VMTEMPLATE_POOL','VMTEMPLATE',client)
@user_id = user_id
end
# Factory method to create Template objects
def factory(element_xml)
OpenNebula::Template.new(element_xml,@client)
end
# ---------------------------------------------------------------------
# XML-RPC Methods for the Template Object
# ---------------------------------------------------------------------
# Retrieves all the Templates in the pool.
def info()
super(TEMPLATE_POOL_METHODS[:info], @user_id)
end
end
end

View File

@ -214,7 +214,7 @@ void RequestManager::do_action(
void RequestManager::register_xml_methods()
{
xmlrpc_c::methodPtr vm_allocate(new
RequestManager::VirtualMachineAllocate(vmpool, vnpool, ipool, upool));
RequestManager::VirtualMachineAllocate(vmpool,vnpool,ipool,tpool,upool));
xmlrpc_c::methodPtr vm_deploy(new
RequestManager::VirtualMachineDeploy(vmpool,hpool,upool));
@ -233,7 +233,28 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr vm_pool_info(new
RequestManager::VirtualMachinePoolInfo(vmpool,upool));
xmlrpc_c::methodPtr template_allocate(new
RequestManager::TemplateAllocate(tpool,upool));
xmlrpc_c::methodPtr template_delete(new
RequestManager::TemplateDelete(tpool, upool));
xmlrpc_c::methodPtr template_info(new
RequestManager::TemplateInfo(tpool, upool));
xmlrpc_c::methodPtr template_update(new
RequestManager::TemplateUpdate(tpool, upool));
xmlrpc_c::methodPtr template_rm_attribute(new
RequestManager::TemplateRemoveAttribute(tpool, upool));
xmlrpc_c::methodPtr template_publish(new
RequestManager::TemplatePublish(tpool, upool));
xmlrpc_c::methodPtr template_pool_info(new
RequestManager::TemplatePoolInfo(tpool,upool));
xmlrpc_c::methodPtr host_allocate(new
RequestManager::HostAllocate(hpool,upool));
@ -340,7 +361,18 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.vm.savedisk", vm_savedisk);
RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info);
/* VM Template related methods*/
RequestManagerRegistry.addMethod("one.template.allocate",template_allocate);
RequestManagerRegistry.addMethod("one.template.delete", template_delete);
RequestManagerRegistry.addMethod("one.template.info", template_info);
RequestManagerRegistry.addMethod("one.template.update", template_update);
RequestManagerRegistry.addMethod("one.template.rmattr", template_rm_attribute);
RequestManagerRegistry.addMethod("one.template.publish", template_publish);
RequestManagerRegistry.addMethod("one.templatepool.info",template_pool_info);
/* Host related methods*/
RequestManagerRegistry.addMethod("one.host.allocate", host_allocate);

View File

@ -30,10 +30,11 @@ void RequestManager::VirtualMachineAllocate::execute(
string str_template;
string error_str;
string user_name;
string template_id_str = "TEMPLATE_ID";;
const string method_name = "VirtualMachineAllocate";
int vid, uid;
int vid, uid, tid;
int rc;
ostringstream oss;
@ -42,7 +43,13 @@ void RequestManager::VirtualMachineAllocate::execute(
xmlrpc_c::value_array * arrayresult;
VirtualMachineTemplate * vm_template;
VirtualMachineTemplate * vm_template_aux;
User * user;
VMTemplate * registered_template;
bool using_template_pool;
int template_owner;
bool template_public;
char * error_msg = 0;
int num;
@ -77,11 +84,66 @@ void RequestManager::VirtualMachineAllocate::execute(
goto error_parse;
}
//--------------------------------------------------------------------------
// Look for a template id
//--------------------------------------------------------------------------
using_template_pool = vm_template->get(template_id_str, tid);
if( using_template_pool )
{
string name_str = "NAME";
string name_val;
ostringstream template_id_val;
registered_template = VirtualMachineAllocate::tpool->get(tid, true);
if( registered_template == 0 )
{
goto error_template_get;
}
// Use the template contents
vm_template_aux = registered_template->clone_template();
template_owner = registered_template->get_uid();
template_public = registered_template->isPublic();
registered_template->unlock();
// Set NAME & TEMPLATE_ID for the new template
vm_template->get(name_str,name_val);
if ( !name_val.empty() )
{
vm_template_aux->erase(name_str);
vm_template_aux->set(new SingleAttribute(name_str,name_val));
}
vm_template_aux->erase(template_id_str);
template_id_val << tid;
vm_template_aux->set(new
SingleAttribute(template_id_str,template_id_val.str()));
delete vm_template;
vm_template = vm_template_aux;
}
if ( uid != 0 )
{
AuthRequest ar(uid);
string t64;
if( using_template_pool )
{
ar.add_auth(AuthRequest::TEMPLATE,
tid,
AuthRequest::USE,
template_owner,
template_public);
}
num = vm_template->get("DISK",vectors);
for(int i=0; i<num; i++)
@ -113,11 +175,22 @@ void RequestManager::VirtualMachineAllocate::execute(
VirtualMachineAllocate::vnpool->authorize_nic(vector,uid,&ar);
}
ar.add_auth(AuthRequest::VM,
vm_template->to_xml(t64),
AuthRequest::CREATE,
uid,
false);
if( using_template_pool )
{
ar.add_auth(AuthRequest::VM,
vm_template->to_xml(t64),
AuthRequest::INSTANTIATE,
uid,
false);
}
else
{
ar.add_auth(AuthRequest::VM,
vm_template->to_xml(t64),
AuthRequest::CREATE,
uid,
false);
}
if (UserPool::authorize(ar) == -1)
{
@ -165,6 +238,11 @@ void RequestManager::VirtualMachineAllocate::execute(
return;
error_template_get:
oss.str(get_error(method_name, "TEMPLATE", tid));
delete vm_template;
goto error_common;
error_user_get:
oss.str(get_error(method_name, "USER", uid));

View File

@ -65,7 +65,6 @@ void RequestManager::ImagePoolInfo::execute(
switch(filter_flag)
{
case -2:
// TODO define authentication bug #278
break;
case -1:
where_string << "UID=" << rc << " OR PUBLIC=1";

View File

@ -0,0 +1,183 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "RequestManager.h"
#include "NebulaLog.h"
#include "Nebula.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::TemplateAllocate::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
string str_template;
string error_str;
string user_name;
const string method_name = "TemplateAllocate";
int oid, uid;
int rc;
ostringstream oss;
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
VirtualMachineTemplate * template_contents;
User * user;
char * error_msg = 0;
NebulaLog::log("ReM",Log::DEBUG,"TemplateAllocate invoked");
session = xmlrpc_c::value_string(paramList.getString(0));
str_template = xmlrpc_c::value_string(paramList.getString(1));
str_template += "\n";
//--------------------------------------------------------------------------
// Authenticate the user
//--------------------------------------------------------------------------
uid = TemplateAllocate::upool->authenticate(session);
if (uid == -1)
{
goto error_authenticate;
}
//--------------------------------------------------------------------------
// Check the template syntax
//--------------------------------------------------------------------------
template_contents = new VirtualMachineTemplate;
rc = template_contents->parse(str_template,&error_msg);
if ( rc != 0 )
{
goto error_parse;
}
//--------------------------------------------------------------------------
// Authorize this request
//--------------------------------------------------------------------------
if ( uid != 0 )
{
AuthRequest ar(uid);
string t64;
ar.add_auth(AuthRequest::TEMPLATE,
template_contents->to_xml(t64),
AuthRequest::CREATE,
uid,
false);
if (UserPool::authorize(ar) == -1)
{
goto error_authorize;
}
}
//--------------------------------------------------------------------------
// Get the User Name
//--------------------------------------------------------------------------
user = TemplateAllocate::upool->get(uid,true);
if ( user == 0 )
{
goto error_user_get;
}
user_name = user->get_name();
user->unlock();
//--------------------------------------------------------------------------
// Allocate the VMTemplate
//--------------------------------------------------------------------------
rc = TemplateAllocate::tpool->allocate(uid,
user_name,
template_contents,
&oid,
error_str);
if ( rc < 0 )
{
goto error_allocate;
}
arrayData.push_back(xmlrpc_c::value_boolean(true));
arrayData.push_back(xmlrpc_c::value_int(oid));
// 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_user_get:
oss.str(get_error(method_name, "USER", uid));
delete template_contents;
goto error_common;
error_authenticate:
oss.str(authenticate_error(method_name));
goto error_common;
error_authorize:
oss.str(authorization_error(method_name, "CREATE", "TEMPLATE", uid, -1));
delete template_contents;
goto error_common;
error_parse:
oss << action_error(method_name, "PARSE", "VM TEMPLATE",-2,rc);
if (error_msg != 0)
{
oss << ". Reason: " << error_msg;
free(error_msg);
}
delete template_contents;
goto error_common;
error_allocate:
oss << action_error(method_name, "CREATE", "TEMPLATE", -2, 0);
oss << " " << error_str;
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;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -0,0 +1,153 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "RequestManager.h"
#include "NebulaLog.h"
#include "Nebula.h"
#include "AuthManager.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::TemplateDelete::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
int oid;
int uid;
int rc;
int owner;
bool is_public;
VMTemplate * vm_template;
ostringstream oss;
const string method_name = "TemplateDelete";
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
NebulaLog::log("ReM",Log::DEBUG,"TemplateDelete invoked");
session = xmlrpc_c::value_string(paramList.getString(0));
oid = xmlrpc_c::value_int (paramList.getInt(1));
// First, we need to authenticate the user
uid = TemplateDelete::upool->authenticate(session);
if ( uid == -1 )
{
goto error_authenticate;
}
// Get template from the pool
vm_template = TemplateDelete::tpool->get(oid,true);
if ( vm_template == 0 )
{
goto error_get;
}
owner = vm_template->get_uid();
is_public = vm_template->isPublic();
vm_template->unlock();
//Authorize the operation
if ( uid != 0 ) // uid == 0 means oneadmin
{
AuthRequest ar(uid);
ar.add_auth(AuthRequest::TEMPLATE,
oid,
AuthRequest::DELETE,
owner,
is_public);
if (UserPool::authorize(ar) == -1)
{
goto error_authorize;
}
}
// Get template from the pool
vm_template = TemplateDelete::tpool->get(oid,true);
if ( vm_template == 0 )
{
goto error_get;
}
rc = TemplateDelete::tpool->drop(vm_template);
vm_template->unlock();
if ( rc < 0 )
{
goto error_delete;
}
arrayData.push_back(xmlrpc_c::value_boolean(true));
arrayData.push_back(xmlrpc_c::value_int(oid));
// 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.str(authenticate_error(method_name));
goto error_common;
error_get:
oss.str(get_error(method_name, "TEMPLATE", oid));
goto error_common;
error_authorize:
oss.str(authorization_error(method_name, "DELETE", "TEMPLATE", uid, oid));
goto error_common;
error_delete:
oss.str(action_error(method_name, "DELETE", "TEMPLATE", oid, rc));
vm_template->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;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -0,0 +1,107 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "RequestManager.h"
#include "NebulaLog.h"
#include "AuthManager.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::TemplateInfo::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
int oid;
int uid; // owner user id
int rc; // Requesting user id
VMTemplate * vm_template;
ostringstream oss;
const string method_name = "TemplateInfo";
/* -- RPC specific vars -- */
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
NebulaLog::log("ReM",Log::DEBUG,"TemplateInfo method invoked");
// Get the parameters
session = xmlrpc_c::value_string(paramList.getString(0));
oid = xmlrpc_c::value_int (paramList.getInt(1));
// Get template from the pool
vm_template = TemplateInfo::tpool->get(oid,true);
if ( vm_template == 0 )
{
goto error_get;
}
uid = vm_template->get_uid();
// Check if it is a valid user
rc = TemplateInfo::upool->authenticate(session);
if ( rc == -1 )
{
goto error_authenticate;
}
oss << *vm_template;
vm_template->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_get:
oss.str(get_error(method_name, "TEMPLATE", oid));
goto error_common;
error_authenticate:
oss.str(authenticate_error(method_name));
vm_template->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;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -0,0 +1,124 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "RequestManager.h"
#include "NebulaLog.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::TemplatePoolInfo::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
ostringstream oss;
ostringstream where_string;
int rc;
int filter_flag;
const string method_name = "TemplatePoolInfo";
/* -- RPC specific vars -- */
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
NebulaLog::log("ReM",Log::DEBUG,"TemplatePoolInfo 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 = TemplatePoolInfo::upool->authenticate(session);
if ( rc == -1 )
{
goto error_authenticate;
}
/** Filter flag meaning table
* -2 :: All Templates
* -1 :: User's Templates AND public templates belonging to any user
* >= 0 :: UID User's Templates
**/
if ( filter_flag < -2 )
{
goto error_filter_flag;
}
switch(filter_flag)
{
case -2:
break;
case -1:
where_string << "UID=" << rc << " OR PUBLIC=1";
break;
default:
where_string << "UID=" << filter_flag;
}
// Call the template pool dump
rc = TemplatePoolInfo::tpool->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.str(authenticate_error(method_name));
goto error_common;
error_filter_flag:
oss << "Incorrect filter_flag, must be >= -2.";
goto error_common;
error_dump:
oss.str(get_error(method_name, "TEMPLATE", -1));
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;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -0,0 +1,158 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "RequestManager.h"
#include "NebulaLog.h"
#include "Nebula.h"
#include "AuthManager.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::TemplatePublish::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
int oid;
bool publish_flag;
int uid;
int owner;
bool is_public;
VMTemplate * vm_template;
bool response;
ostringstream oss;
const string method_name = "TemplatePublish";
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
NebulaLog::log("ReM",Log::DEBUG,"TemplatePublish invoked");
session = xmlrpc_c::value_string (paramList.getString(0));
oid = xmlrpc_c::value_int (paramList.getInt(1));
publish_flag = xmlrpc_c::value_boolean(paramList.getBoolean(2));
// First, we need to authenticate the user
uid = TemplatePublish::upool->authenticate(session);
if ( uid == -1 )
{
goto error_authenticate;
}
// Get template from the pool
vm_template = TemplatePublish::tpool->get(oid,true);
if ( vm_template == 0 )
{
goto error_get;
}
owner = vm_template->get_uid();
is_public = vm_template->isPublic();
vm_template->unlock();
//Authorize the operation
if ( uid != 0 ) // uid == 0 means oneadmin
{
AuthRequest ar(uid);
ar.add_auth(AuthRequest::TEMPLATE,
oid,
AuthRequest::MANAGE,
owner,
is_public);
if (UserPool::authorize(ar) == -1)
{
goto error_authorize;
}
}
// Get the template locked again
vm_template = TemplatePublish::tpool->get(oid,true);
if ( vm_template == 0 )
{
goto error_get;
}
response = vm_template->publish(publish_flag);
if (!response)
{
vm_template->unlock();
goto error_publish;
}
TemplatePublish::tpool->update(vm_template);
vm_template->unlock();
arrayData.push_back(xmlrpc_c::value_boolean(true));
arrayData.push_back(xmlrpc_c::value_int(oid));
// 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.str(authenticate_error(method_name));
goto error_common;
error_get:
oss.str(get_error(method_name, "TEMPLATE", oid));
goto error_common;
error_authorize:
oss.str(authorization_error(method_name, "MANAGE", "TEMPLATE", uid, oid));
goto error_common;
error_publish:
oss.str(action_error(method_name, "MANAGE", "TEMPLATE", oid, 0));
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;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -0,0 +1,159 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "RequestManager.h"
#include "NebulaLog.h"
#include "Nebula.h"
#include "AuthManager.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::TemplateRemoveAttribute::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
string name;
int oid;
int uid;
int rc;
int owner;
bool is_public;
VMTemplate * vm_template;
ostringstream oss;
const string method_name = "TemplateRemoveAttribute";
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
NebulaLog::log("ReM",Log::DEBUG,"TemplateRemoveAttribute invoked");
session = xmlrpc_c::value_string(paramList.getString(0));
oid = xmlrpc_c::value_int (paramList.getInt(1));
name = xmlrpc_c::value_string(paramList.getString(2));
// First, we need to authenticate the user
uid = TemplateRemoveAttribute::upool->authenticate(session);
if ( uid == -1 )
{
goto error_authenticate;
}
// Get object from the pool
vm_template = TemplateRemoveAttribute::tpool->get(oid,true);
if ( vm_template == 0 )
{
goto error_get;
}
owner = vm_template->get_uid();
is_public = vm_template->isPublic();
vm_template->unlock();
//Authorize the operation
if ( uid != 0 ) // uid == 0 means oneadmin
{
AuthRequest ar(uid);
ar.add_auth(AuthRequest::TEMPLATE,
oid,
AuthRequest::MANAGE,
owner,
is_public);
if (UserPool::authorize(ar) == -1)
{
goto error_authorize;
}
}
// Get object from the pool
vm_template = TemplateRemoveAttribute::tpool->get(oid,true);
if ( vm_template == 0 )
{
goto error_get;
}
rc = vm_template->remove_template_attribute(name);
if(rc == 0)
{
rc = TemplateRemoveAttribute::tpool->update(vm_template);
}
if ( rc < 0 )
{
goto error_remove_attribute;
}
vm_template->unlock();
arrayData.push_back(xmlrpc_c::value_boolean(true));
arrayData.push_back(xmlrpc_c::value_int(oid));
// 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.str(authenticate_error(method_name));
goto error_common;
error_get:
oss.str(get_error(method_name, "TEMPLATE", oid));
goto error_common;
error_authorize:
oss.str(authorization_error(method_name, "MANAGE", "TEMPLATE", uid, oid));
goto error_common;
error_remove_attribute:
oss.str(action_error(method_name, "PUBLISH/UNPUBLISH", "TEMPLATE", oid, rc));
vm_template->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;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -0,0 +1,160 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "RequestManager.h"
#include "NebulaLog.h"
#include "Nebula.h"
#include "AuthManager.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::TemplateUpdate::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
int oid;
int uid;
string name;
string value;
int rc;
int owner;
bool is_public;
VMTemplate * vm_template;
ostringstream oss;
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
const string method_name = "TemplateUpdate";
NebulaLog::log("ReM",Log::DEBUG,"TemplateUpdate invoked");
session = xmlrpc_c::value_string(paramList.getString(0));
oid = 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
uid = TemplateUpdate::upool->authenticate(session);
if ( uid == -1 )
{
goto error_authenticate;
}
// Get template from the pool
vm_template = TemplateUpdate::tpool->get(oid,true);
if ( vm_template == 0 )
{
goto error_get;
}
owner = vm_template->get_uid();
is_public = vm_template->isPublic();
vm_template->unlock();
//Authorize the operation
if ( uid != 0 ) // uid == 0 means oneadmin
{
AuthRequest ar(uid);
ar.add_auth(AuthRequest::TEMPLATE,
oid,
AuthRequest::MANAGE,
owner,
is_public);
if (UserPool::authorize(ar) == -1)
{
goto error_authorize;
}
}
// Get template from the pool
vm_template = TemplateUpdate::tpool->get(oid,true);
if ( vm_template == 0 )
{
goto error_get;
}
rc = vm_template->replace_template_attribute(name, value);
if(rc == 0)
{
rc = TemplateUpdate::tpool->update(vm_template);
}
if ( rc < 0 )
{
goto error_update;
}
vm_template->unlock();
arrayData.push_back(xmlrpc_c::value_boolean(true));
arrayData.push_back(xmlrpc_c::value_int(oid));
// 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.str(authenticate_error(method_name));
goto error_common;
error_get:
oss.str(get_error(method_name, "TEMPLATE", oid));
goto error_common;
error_authorize:
oss.str(authorization_error(method_name, "MANAGE", "TEMPLATE", uid, oid));
goto error_common;
error_update:
oss.str(action_error(method_name, "UPDATE ATTRIBUTE", "TEMPLATE", oid, rc));
vm_template->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;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -61,7 +61,14 @@ source_files=[
'RequestManagerUserDelete.cc',
'RequestManagerUserChangePassword.cc',
'RequestManagerUserInfo.cc',
'RequestManagerUserPoolInfo.cc'
'RequestManagerUserPoolInfo.cc',
'RequestManagerTemplateAllocate.cc',
'RequestManagerTemplateDelete.cc',
'RequestManagerTemplateInfo.cc',
'RequestManagerTemplateUpdate.cc',
'RequestManagerTemplateRemoveAttribute.cc',
'RequestManagerTemplatePublish.cc',
'RequestManagerTemplatePoolInfo.cc',
]
# Build library

View File

@ -309,7 +309,7 @@ void Template::get(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Template::get(
bool Template::get(
string& name,
int& value) const
{
@ -320,12 +320,13 @@ void Template::get(
if ( sval == "" )
{
value = 0;
return;
return false;
}
istringstream iss(sval);
iss >> value;
return true;
}
/* -------------------------------------------------------------------------- */

View File

@ -82,6 +82,11 @@ void Nebula::start()
delete cpool;
}
if ( tpool != 0)
{
delete tpool;
}
if ( vmm != 0)
{
delete vmm;
@ -214,6 +219,11 @@ void Nebula::start()
{
cpool = tester->create_cpool(db);
}
if (tester->need_template_pool)
{
tpool = tester->create_tpool(db);
}
}
catch (exception&)
{
@ -358,7 +368,7 @@ void Nebula::start()
{
try
{
rm = tester->create_rm(vmpool,hpool,vnpool,upool,ipool,cpool,
rm = tester->create_rm(vmpool,hpool,vnpool,upool,ipool,cpool,tpool,
log_location + "one_xmlrpc.log");
}
catch (bad_alloc&)

View File

@ -54,6 +54,11 @@ ClusterPool* NebulaTest::create_cpool(SqlDB* db)
return new ClusterPool(db);
}
VMTemplatePool* NebulaTest::create_tpool(SqlDB* db)
{
return new VMTemplatePool(db);
}
// -----------------------------------------------------------
// Managers
// -----------------------------------------------------------
@ -112,6 +117,7 @@ RequestManager* NebulaTest::create_rm(
UserPool * upool,
ImagePool * ipool,
ClusterPool * cpool,
VMTemplatePool * tpool,
string log_file)
{
int rm_port = 2633;
@ -122,6 +128,7 @@ RequestManager* NebulaTest::create_rm(
upool,
ipool,
cpool,
tpool,
rm_port,
log_file);
}

View File

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

View File

@ -0,0 +1,246 @@
/* ------------------------------------------------------------------------ */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* ------------------------------------------------------------------------ */
#include "VMTemplate.h"
#define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper)
/* ************************************************************************ */
/* VMTemplate :: Constructor/Destructor */
/* ************************************************************************ */
VMTemplate::VMTemplate(int id,
int _uid,
string _user_name,
VirtualMachineTemplate * _template_contents):
PoolObjectSQL(id,"",_uid,table),
user_name(_user_name),
regtime(time(0))
{
if (_template_contents != 0)
{
obj_template = _template_contents;
}
else
{
obj_template = new VirtualMachineTemplate;
}
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
VMTemplate::~VMTemplate()
{
if ( obj_template != 0 )
{
delete obj_template;
}
}
/* ************************************************************************ */
/* VMTemplate :: Database Access Functions */
/* ************************************************************************ */
const char * VMTemplate::table = "template_pool";
const char * VMTemplate::db_names = "oid, name, body, uid, public";
const char * VMTemplate::db_bootstrap =
"CREATE TABLE IF NOT EXISTS template_pool (oid INTEGER PRIMARY KEY, "
"name VARCHAR(256), body TEXT, uid INTEGER, public INTEGER)";
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int VMTemplate::insert(SqlDB *db, string& error_str)
{
int rc;
ostringstream oss;
string public_attr;
// ---------------------------------------------------------------------
// Check default attributes
// ---------------------------------------------------------------------
// ------------ NAME --------------------
get_template_attribute("NAME", name);
if ( name.empty() == true )
{
oss.str("");
oss << "template-" << oid;
name = oss.str();
}
// ------------ PUBLIC --------------------
get_template_attribute("PUBLIC", public_attr);
obj_template->erase("PUBLIC");
TO_UPPER(public_attr);
public_template = (public_attr == "YES");
// ------------------------------------------------------------------------
// Insert the Template
// ------------------------------------------------------------------------
rc = insert_replace(db, false);
if ( rc != 0 )
{
error_str = "Error inserting Template in DB.";
}
return rc;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int VMTemplate::insert_replace(SqlDB *db, bool replace)
{
ostringstream oss;
int rc;
string xml_body;
char * sql_name;
char * sql_xml;
// Update the Object
sql_name = db->escape_str(name.c_str());
if ( sql_name == 0 )
{
goto error_name;
}
sql_xml = db->escape_str(to_xml(xml_body).c_str());
if ( sql_xml == 0 )
{
goto error_body;
}
if(replace)
{
oss << "REPLACE";
}
else
{
oss << "INSERT";
}
// Construct the SQL statement to Insert or Replace
oss <<" INTO "<<table <<" ("<< db_names <<") VALUES ("
<< oid << ","
<< "'" << sql_name << "',"
<< "'" << sql_xml << "',"
<< uid << ","
<< public_template << ")";
rc = db->exec(oss);
db->free_str(sql_name);
db->free_str(sql_xml);
return rc;
error_body:
db->free_str(sql_name);
error_name:
return -1;
}
/* ************************************************************************ */
/* VMTemplate :: Misc */
/* ************************************************************************ */
ostream& operator<<(ostream& os, VMTemplate& vmTemplate)
{
string xml_str;
os << vmTemplate.to_xml(xml_str);
return os;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
string& VMTemplate::to_xml(string& xml) const
{
ostringstream oss;
string template_xml;
oss << "<VMTEMPLATE>"
<< "<ID>" << oid << "</ID>"
<< "<UID>" << uid << "</UID>"
<< "<USERNAME>" << user_name << "</USERNAME>"
<< "<NAME>" << name << "</NAME>"
<< "<PUBLIC>" << public_template << "</PUBLIC>"
<< "<REGTIME>" << regtime << "</REGTIME>"
<< obj_template->to_xml(template_xml)
<< "</VMTEMPLATE>";
xml = oss.str();
return xml;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int VMTemplate::from_xml(const string& xml)
{
vector<xmlNodePtr> content;
int rc = 0;
// Initialize the internal XML object
update_from_str(xml);
// Get class base attributes
rc += xpath(oid, "/VMTEMPLATE/ID", -1);
rc += xpath(uid, "/VMTEMPLATE/UID", -1);
rc += xpath(user_name, "/VMTEMPLATE/USERNAME", "not_found");
rc += xpath(name, "/VMTEMPLATE/NAME", "not_found");
rc += xpath(public_template,"/VMTEMPLATE/PUBLIC", 0);
rc += xpath(regtime, "/VMTEMPLATE/REGTIME", 0);
// Get associated classes
ObjectXML::get_nodes("/VMTEMPLATE/TEMPLATE", content);
if( content.size() < 1 )
{
return -1;
}
// Template contents
rc += obj_template->from_xml_node(content[0]);
if (rc != 0)
{
return -1;
}
return 0;
}

View File

@ -0,0 +1,76 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
/* ************************************************************************** */
/* Template Pool */
/* ************************************************************************** */
#include "VMTemplatePool.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VMTemplatePool::allocate (
int uid,
string user_name,
VirtualMachineTemplate * template_contents,
int * oid,
string& error_str)
{
VMTemplate * vm_template;
VMTemplate * vm_template_aux = 0;
string name;
ostringstream oss;
// ------------------------------------------------------------------------
// Build a new VMTemplate object
// ------------------------------------------------------------------------
vm_template = new VMTemplate(-1, uid, user_name, template_contents);
// Check name
vm_template->get_template_attribute("NAME", name);
if ( !name.empty() )
{
// Check for duplicates
vm_template_aux = get(name,uid,false);
if( vm_template_aux != 0 )
{
goto error_duplicated;
}
}
// ------------------------------------------------------------------------
// Insert the Object in the pool
// ------------------------------------------------------------------------
*oid = PoolSQL::allocate(vm_template, error_str);
return *oid;
error_duplicated:
oss << "NAME is already taken by TEMPLATE "
<< vm_template_aux->get_oid() << ".";
delete vm_template;
*oid = -1;
error_str = oss.str();
return *oid;
}

View File

@ -0,0 +1,39 @@
# --------------------------------------------------------------------------
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# --------------------------------------------------------------------------
Import('env')
env.Prepend(LIBS=[
'nebula_image',
'nebula_um',
'nebula_vm',
'nebula_vmtemplate',
'nebula_hm',
'nebula_vnm',
'nebula_authm',
'nebula_template',
'nebula_pool',
'nebula_mad',
'nebula_common',
'nebula_core',
'nebula_sql',
'nebula_log',
'nebula_xml',
'crypto'
])
env.Program('test','VMTemplatePoolTest.cc')

View File

@ -0,0 +1,553 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include <string>
#include <iostream>
#include <stdlib.h>
#include "VMTemplatePool.h"
#include "PoolTest.h"
using namespace std;
const int uids[] = {0,1,2};
const string user_names[] = {"A user","B user","C user"};
const string names[] = {"Template one", "Second Template", "Third Template"};
const string templates[] =
{
"NAME = \"Template one\"\n"
"MEMORY = 128\n"
"CPU = 1",
"NAME = \"Second Template\"\n"
"MEMORY = 256\n"
"CPU = 2",
"NAME = \"Third Template\"\n"
"MEMORY = 1024\n"
"CPU = 3"
};
const string xmls[] =
{
"<VMTEMPLATE><ID>0</ID><UID>0</UID><USERNAME>A user</USERNAME><NAME>Template one</NAME><PUBLIC>0</PUBLIC><REGTIME>0000000000</REGTIME><TEMPLATE><CPU><![CDATA[1]]></CPU><MEMORY><![CDATA[128]]></MEMORY><NAME><![CDATA[Template one]]></NAME></TEMPLATE></VMTEMPLATE>",
"<VMTEMPLATE><ID>1</ID><UID>1</UID><USERNAME>B user</USERNAME><NAME>Second Template</NAME><PUBLIC>0</PUBLIC><REGTIME>0000000000</REGTIME><TEMPLATE><CPU><![CDATA[2]]></CPU><MEMORY><![CDATA[256]]></MEMORY><NAME><![CDATA[Second Template]]></NAME></TEMPLATE></VMTEMPLATE>",
"<VMTEMPLATE><ID>2</ID><UID>2</UID><USERNAME>C user</USERNAME><NAME>Third Template</NAME><PUBLIC>0</PUBLIC><REGTIME>0000000000</REGTIME><TEMPLATE><CPU><![CDATA[3]]></CPU><MEMORY><![CDATA[1024]]></MEMORY><NAME><![CDATA[Third Template]]></NAME></TEMPLATE></VMTEMPLATE>"
};
// This xml dump result has the STIMEs modified to 0000000000
const string xml_dump =
"<VMTEMPLATE_POOL><VMTEMPLATE><ID>0</ID><UID>0</UID><USERNAME>A user</USERNAME><NAME>Template one</NAME><PUBLIC>0</PUBLIC><REGTIME>0000000000</REGTIME><TEMPLATE><CPU><![CDATA[1]]></CPU><MEMORY><![CDATA[128]]></MEMORY><NAME><![CDATA[Template one]]></NAME></TEMPLATE></VMTEMPLATE><VMTEMPLATE><ID>1</ID><UID>1</UID><USERNAME>B user</USERNAME><NAME>Second Template</NAME><PUBLIC>0</PUBLIC><REGTIME>0000000000</REGTIME><TEMPLATE><CPU><![CDATA[2]]></CPU><MEMORY><![CDATA[256]]></MEMORY><NAME><![CDATA[Second Template]]></NAME></TEMPLATE></VMTEMPLATE><VMTEMPLATE><ID>2</ID><UID>2</UID><USERNAME>C user</USERNAME><NAME>Third Template</NAME><PUBLIC>0</PUBLIC><REGTIME>0000000000</REGTIME><TEMPLATE><CPU><![CDATA[3]]></CPU><MEMORY><![CDATA[1024]]></MEMORY><NAME><![CDATA[Third Template]]></NAME></TEMPLATE></VMTEMPLATE></VMTEMPLATE_POOL>";
const string xml_dump_where =
"<VMTEMPLATE_POOL><VMTEMPLATE><ID>0</ID><UID>0</UID><USERNAME>A user</USERNAME><NAME>Template one</NAME><PUBLIC>0</PUBLIC><REGTIME>0000000000</REGTIME><TEMPLATE><CPU><![CDATA[1]]></CPU><MEMORY><![CDATA[128]]></MEMORY><NAME><![CDATA[Template one]]></NAME></TEMPLATE></VMTEMPLATE><VMTEMPLATE><ID>1</ID><UID>1</UID><USERNAME>B user</USERNAME><NAME>Second Template</NAME><PUBLIC>0</PUBLIC><REGTIME>0000000000</REGTIME><TEMPLATE><CPU><![CDATA[2]]></CPU><MEMORY><![CDATA[256]]></MEMORY><NAME><![CDATA[Second Template]]></NAME></TEMPLATE></VMTEMPLATE></VMTEMPLATE_POOL>";
const string replacement = "0000000000";
class VMTemplatePoolFriend : public VMTemplatePool
{
public:
VMTemplatePoolFriend(SqlDB * db) : VMTemplatePool(db){};
int allocate(int uid,
const string& stemplate,
int * oid)
{
VirtualMachineTemplate * template_contents;
char * error_msg = 0;
int rc;
string err;
template_contents = new VirtualMachineTemplate();
rc = template_contents->parse(stemplate,&error_msg);
if( rc == 0 )
{
return VMTemplatePool::allocate(uid, user_names[uid], template_contents, oid, err);
}
else
{
if (error_msg != 0 )
{
free(error_msg);
}
delete template_contents;
return -2;
}
};
};
/* ************************************************************************* */
/* ************************************************************************* */
class VMTemplatePoolTest : public PoolTest
{
CPPUNIT_TEST_SUITE (VMTemplatePoolTest);
ALL_POOLTEST_CPPUNIT_TESTS();
CPPUNIT_TEST ( names_initialization );
CPPUNIT_TEST ( clone_template );
CPPUNIT_TEST ( update );
CPPUNIT_TEST ( get_using_name );
CPPUNIT_TEST ( wrong_get_name );
CPPUNIT_TEST ( duplicates );
CPPUNIT_TEST ( public_attribute );
CPPUNIT_TEST ( dump );
CPPUNIT_TEST ( dump_where );
CPPUNIT_TEST_SUITE_END ();
protected:
void bootstrap(SqlDB* db)
{
VMTemplatePool::bootstrap(db);
};
PoolSQL* create_pool(SqlDB* db)
{
return new VMTemplatePoolFriend(db);
};
int allocate(int index)
{
int oid;
return ((VMTemplatePoolFriend*)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.
((VMTemplate*)obj)->to_xml(xml_str);
xml_str.replace( xml_str.find("<REGTIME>")+9, 10, replacement);
/*
if( xml_str != xmls[index] )
{
cout << endl << xml_str << endl << xmls[index] << endl;
}
//*/
CPPUNIT_ASSERT( obj->get_name() == names[index] );
CPPUNIT_ASSERT( xml_str == xmls[index]);
};
public:
VMTemplatePoolTest(){xmlInitParser();};
~VMTemplatePoolTest(){xmlCleanupParser();};
/* ********************************************************************* */
void names_initialization()
{
VMTemplatePoolFriend * tpool;
VMTemplate * temp;
// Allocate 2 Templates, 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 Templates.
tpool = new VMTemplatePoolFriend(db);
temp = tpool->get(names[0], uids[0], false);
CPPUNIT_ASSERT( temp != 0 );
temp = tpool->get(names[1], uids[1], false);
CPPUNIT_ASSERT( temp == 0 );
temp = tpool->get(names[2], uids[2], false);
CPPUNIT_ASSERT( temp != 0 );
delete tpool;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void clone_template()
{
string attr_temp;
string attr_vmt;
string name1 = "NAME";
string name2 = "MEMORY";
VMTemplatePoolFriend * tpool;
VMTemplate * temp;
VirtualMachineTemplate * vmt;
int oid_1;
tpool = static_cast<VMTemplatePoolFriend *>(pool);
oid_1 = allocate(0);
temp = tpool->get(oid_1, true);
CPPUNIT_ASSERT( temp != 0 );
vmt = temp->clone_template();
vmt->get(name1,attr_vmt);
CPPUNIT_ASSERT( attr_vmt == "Template one");
temp->get_template_attribute(name1.c_str(), attr_temp);
CPPUNIT_ASSERT( attr_temp == "Template one");
temp->replace_template_attribute(name2.c_str(), "1024");
vmt->get(name2,attr_vmt);
CPPUNIT_ASSERT( attr_vmt == "128");
temp->get_template_attribute(name2.c_str(), attr_temp);
CPPUNIT_ASSERT( attr_temp == "1024");
delete vmt;
temp->get_template_attribute(name2.c_str(), attr_temp);
CPPUNIT_ASSERT( attr_temp == "1024");
tpool->update(temp);
temp->unlock();
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
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";
VMTemplatePoolFriend * tpool;
VMTemplate * temp;
int oid_1;
tpool = static_cast<VMTemplatePoolFriend *>(pool);
oid_1 = allocate(0);
temp = tpool->get(oid_1, true);
CPPUNIT_ASSERT( temp != 0 );
// Object should be cached. Let's change some template attributes
temp->replace_template_attribute(description_name, new_description);
temp->replace_template_attribute(attr_name, new_attr_value);
temp->remove_template_attribute("ORIGINAL_PATH");
tpool->update(temp);
temp->unlock();
temp = tpool->get(oid_1,false);
CPPUNIT_ASSERT( temp != 0 );
temp->get_template_attribute("DESCRIPTION", description_val);
temp->get_template_attribute("NEW_ATTRIBUTE", attr_val);
temp->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();
temp = tpool->get(oid_1,false);
CPPUNIT_ASSERT( temp != 0 );
description_val = "";
attr_val = "";
no_value = "Random value";
temp->get_template_attribute("DESCRIPTION", description_val);
temp->get_template_attribute("NEW_ATTRIBUTE", attr_val);
temp->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;
// 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 = pool->get(names[1], uids[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 = pool->get(names[0], uids[0], false);
check(0, obj);
// Get using its name
obj = pool->get(oid_1, false);
check(1, obj);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void wrong_get_name()
{
// The pool is empty
// Non existing name
obj = pool->get("Wrong name", 0, true);
CPPUNIT_ASSERT( obj == 0 );
// Allocate an object
allocate(0);
// Ask again for a non-existing name
obj = pool->get("Non existing name",uids[0], true);
CPPUNIT_ASSERT( obj == 0 );
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void duplicates()
{
int rc, oid;
VMTemplatePoolFriend * tpool = static_cast<VMTemplatePoolFriend*>(pool);
// Allocate a template
rc = tpool->allocate(uids[0], templates[0], &oid);
CPPUNIT_ASSERT( oid == 0 );
CPPUNIT_ASSERT( oid == rc );
// Try to allocate twice the same template, should fail
rc = tpool->allocate(uids[0], templates[0], &oid);
CPPUNIT_ASSERT( rc == -1 );
CPPUNIT_ASSERT( oid == rc );
// Try again, this time with different uid. Should be allowed
rc = tpool->allocate(uids[1], templates[0], &oid);
CPPUNIT_ASSERT( rc >= 0 );
CPPUNIT_ASSERT( oid == rc );
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void public_attribute()
{
int oid;
VMTemplatePoolFriend * tpool = static_cast<VMTemplatePoolFriend *>(pool);
VMTemplate * temp;
string templates[] =
{
// false
"NAME = \"name A\"\n",
// true
"NAME = \"name B\"\n"
"PUBLIC = YES",
// false
"NAME = \"name C\"\n"
"PUBLIC = NO",
// false
"NAME = \"name D\"\n"
"PUBLIC = 1",
// true
"NAME = \"name E\"\n"
"PUBLIC = Yes",
// false
"NAME = \"name F\"\n"
"PUBLIC = TRUE",
// true
"NAME = \"name G\"\n"
"PUBLIC = yes",
// false
"NAME = \"name H\"\n"
"PUBLIC = 'YES'",
// true
"NAME = \"name I\"\n"
"PUBLIC = \"YES\"",
"END"
};
bool results[] = { false, true, false, false,
true, false, true, false, true };
int i = 0;
while( templates[i] != "END" )
{
tpool->allocate(0, templates[i], &oid);
CPPUNIT_ASSERT( oid >= 0 );
temp = tpool->get( oid, false );
CPPUNIT_ASSERT( temp != 0 );
//cout << endl << i << " : exp. " << results[i] << " got " << temp->is_public();
CPPUNIT_ASSERT( temp->isPublic() == results[i] );
i++;
}
bool success;
// temp 0 is not public.
temp = tpool->get( 0, false );
CPPUNIT_ASSERT( temp != 0 );
success = temp->publish(false);
CPPUNIT_ASSERT( success == true );
CPPUNIT_ASSERT( temp->isPublic() == false );
success = temp->publish(true);
CPPUNIT_ASSERT( success == true );
CPPUNIT_ASSERT( temp->isPublic() == true );
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void dump()
{
VMTemplatePool * tpool = static_cast<VMTemplatePool*>(pool);
ostringstream oss;
int rc;
string nan;
allocate(0);
allocate(1);
allocate(2);
rc = tpool->dump(oss,nan);
CPPUNIT_ASSERT(rc == 0);
string result = oss.str();
result.replace(128, 10, replacement);
result.replace(391, 10, replacement);
result.replace(656, 10, replacement);
/*
if( result != xml_dump )
{
cout << endl << result << endl << xml_dump << endl;
}
//*/
CPPUNIT_ASSERT( result == xml_dump );
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void dump_where()
{
VMTemplatePool * tpool = static_cast<VMTemplatePool*>(pool);
int rc;
ostringstream oss;
ostringstream where;
allocate(0);
allocate(1);
allocate(2);
where << "uid < 2";
rc = tpool->dump(oss, where.str());
CPPUNIT_ASSERT(rc == 0);
string result = oss.str();
result.replace(128, 10, replacement);
result.replace(391, 10, replacement);
/*
if( result != xml_dump_where )
{
cout << endl << result << endl << xml_dump_where << endl;
}
//*/
CPPUNIT_ASSERT( result == xml_dump_where );
}
/* ********************************************************************* */
};
/* ************************************************************************* */
/* ************************************************************************* */
int main(int argc, char ** argv)
{
return PoolTest::main(argc, argv, VMTemplatePoolTest::suite());
}

View File

@ -74,7 +74,7 @@ const char * VirtualNetwork::table = "network_pool";
const char * VirtualNetwork::db_names = "oid, name, body, uid, public";
const char * VirtualNetwork::db_bootstrap = "CREATE TABLE IF NOT EXISTS"
" network_pool (oid INTEGER PRIMARY KEY, name VARCHAR(256),"
" network_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128),"
" body TEXT, uid INTEGER, public INTEGER, UNIQUE(name,uid))";
/* -------------------------------------------------------------------------- */