1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-21 18:03:38 +03:00

Merge of the OpenNebulaXML branch (-r535:HEAD)

git-svn-id: http://svn.opennebula.org/one/trunk@667 3034c82b-c49b-4eb3-8279-a7acafdc01c0
This commit is contained in:
Rubén S. Montero 2009-07-09 14:34:34 +00:00
parent 2f73f9f4d5
commit d965eb44aa
117 changed files with 7554 additions and 1492 deletions

View File

@ -54,6 +54,7 @@ main_env.Append(LIBPATH=[
cwd+'/src/rm',
cwd+'/src/vnm',
cwd+'/src/hm',
cwd+'/src/um',
])
# Compile flags
@ -135,6 +136,7 @@ build_scripts=[
'src/scheduler/SConstruct',
'src/vnm/SConstruct',
'src/hm/SConstruct',
'src/um/SConstruct',
]
for script in build_scripts:

View File

@ -193,6 +193,15 @@ public:
int resume(
int vid);
/**
* Restart a previusly deployed VM.
* @param vid VirtualMachine identification
* @return 0 on success, -1 if the VM does not exits or -2 if the VM is
* in a wrong a state
*/
int restart(
int vid);
/**
* Ends a VM life cycle inside ONE.
* @param vid VirtualMachine identification

View File

@ -58,6 +58,27 @@ public:
~History(){};
/**
* Function to write the History Record in an output stream
*/
friend ostream& operator<<(ostream& os, const History& history);
/**
* Function to print the History object into a string in
* plain text
* @param str the resulting string
* @return a reference to the generated string
*/
string& to_str(string& str) const;
/**
* Function to print the History 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;
private:
friend class VirtualMachine;
@ -192,6 +213,20 @@ private:
* @return 0 on success
*/
int unmarshall(int num, char **names, char ** values);
/**
* Function to unmarshall a History object into an output stream with XML
* format.
* @param oss the output stream
* @param num the number of columns read from the DB
* @param names the column names
* @param vaues the column values
* @return 0 on success
*/
static int unmarshall(ostringstream& oss,
int num,
char ** names,
char ** values);
};
#endif /*HISTORY_H_*/

View File

@ -24,8 +24,15 @@
using namespace std;
extern "C" int host_select_cb (void * _host, int num,char ** values, char ** names);
extern "C" int host_select_cb (void * _host,
int num,
char ** values,
char ** names);
extern "C" int host_dump_cb (void * _oss,
int num,
char ** values,
char ** names);
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -54,6 +61,20 @@ public:
*/
friend ostream& operator<<(ostream& os, Host& h);
/**
* Function to print the Host object into a string in plain text
* @param str the resulting string
* @return a reference to the generated string
*/
string& to_str(string& str) const;
/**
* Function to print the Host object into a string in XML format
* @param xml the resulting XML string
* @return a reference to the generated string
*/
string& to_xml(string& xml) const;
/**
* Get the Host unique identifier HID, that matches the OID of the object
* @return HID Host identifier
@ -62,15 +83,6 @@ public:
{
return oid;
};
/**
* Check if the host is managed
* @return true if the host is managed
*/
bool isManaged() const
{
return managed;
}
/**
* Check if the host is enabled
@ -310,15 +322,17 @@ private:
// -------------------------------------------------------------------------
// Friends
// -------------------------------------------------------------------------
friend class HostPool;
friend int host_select_cb (
void * _host,
int num,
char ** values,
char ** names);
friend int host_select_cb (void * _host,
int num,
char ** values,
char ** names);
friend int host_dump_cb (void * _oss,
int num,
char ** values,
char ** names);
// -------------------------------------------------------------------------
// Host Description
// -------------------------------------------------------------------------
@ -349,13 +363,8 @@ private:
* If Host State = MONITORED last time it got fully monitored or 1 Jan 1970
* Host State = MONITORING last time it got a signal to be monitored
*/
time_t last_monitored;
/**
* This tells if this host pertains to a local managed cluster
*/
bool managed;
time_t last_monitored;
// -------------------------------------------------------------------------
// Host Attributes
// -------------------------------------------------------------------------
@ -363,12 +372,12 @@ private:
/**
* The Host template, holds the Host attributes.
*/
HostTemplate host_template;
HostTemplate host_template;
/**
* This map holds pointers to all the Host's HostShares
* The Share represents the logical capacity associated with the host
*/
HostShare host_share;
HostShare host_share;
// -------------------------------------------------------------------------
// Lex & bison
@ -386,12 +395,24 @@ private:
/**
* Function to unmarshall a Host object
* @param num the number of columns read from the DB
* @para names the column names
* @para vaues the column values
* @param names the column names
* @param vaues the column values
* @return 0 on success
*/
int unmarshall(int num, char **names, char ** values);
/**
* Function to unmarshall a Host object in to an output stream in XML
* @param oss the output stream
* @param num the number of columns read from the DB
* @param names the column names
* @param vaues the column values
* @return 0 on success
*/
static int unmarshall(ostringstream& oss,
int num,
char ** names,
char ** values);
/**
* Bootstraps the database table(s) associated to the Host
*/
@ -399,9 +420,9 @@ private:
{
db->exec(Host::db_bootstrap);
db->exec(HostTemplate::db_bootstrap);
db->exec(HostShare::db_bootstrap);
db->exec(HostTemplate::db_bootstrap);
};
protected:
@ -414,8 +435,7 @@ protected:
string _hostname="",
string _im_mad_name="",
string _vmm_mad_name="",
string _tm_mad_name="",
bool _managed=true);
string _tm_mad_name="");
virtual ~Host();
@ -431,9 +451,8 @@ protected:
IM_MAD = 3,
VM_MAD = 4,
TM_MAD = 5,
LAST_MON_TIME = 6,
MANAGED = 7,
LIMIT = 8
LAST_MON_TIME = 6,
LIMIT = 7
};
static const char * db_names;
@ -468,7 +487,17 @@ protected:
* @param db pointer to the db
* @return 0 on success
*/
virtual int drop(SqliteDB *db);
virtual int drop(SqliteDB *db);
/**
* Dumps the contect of a set of Host objects in the given stream
* using XML format
* @param db pointer to the db
* @param oss the output stream
* @param where string to filter the VirtualMachine objects
* @return 0 on success
*/
static int dump(SqliteDB * db, ostringstream& oss, const string& where);
};
#endif /*HOST_H_*/

View File

@ -51,8 +51,7 @@ public:
string hostname,
string im_mad_name,
string vmm_mad_name,
string tm_mad_name,
bool managed = true);
string tm_mad_name);
/**
* Function to get a Host from the pool, if the object is not in memory
@ -78,36 +77,37 @@ public:
};
/** Drops a host from the cache & DB, the host mutex MUST BE locked
/** Drops a host from the DB, the host mutex MUST BE locked
* @param host pointer to Host
*/
int drop(Host * host)
{
int rc = host->drop(db);
if ( rc == 0)
{
remove(static_cast<PoolObjectSQL *>(host));
}
return rc;
return host->drop(db);
};
/**
* Bootstraps the database table(s) associated to the Host pool
*/
void bootstrap()
static void bootstrap(SqliteDB *_db)
{
Host::bootstrap(db);
Host::bootstrap(_db);
};
/**
* Get the 10 least monitored hosts
* param discovered hosts map to store the retrieved hosts hids and hostnames are
* return int 0 if success
* @param discovered hosts, map to store the retrieved hosts hids and
* hostnames
* @return int 0 if success
*/
int discover(map<int, string> * discovered_hosts);
/**
* Allocates a given capacity to the host
* @param oid the id of the host to allocate the capacity
* @param cpu amount of CPU
* @param mem amount of main memory
* @param disk amount of disk
*/
void add_capacity(int oid,int cpu, int mem, int disk)
{
Host * host = get(oid, true);
@ -121,7 +121,13 @@ public:
host->unlock();
}
};
/**
* De-Allocates a given capacity to the host
* @param oid the id of the host to allocate the capacity
* @param cpu amount of CPU
* @param mem amount of main memory
* @param disk amount of disk
*/
void del_capacity(int oid,int cpu, int mem, int disk)
{
Host * host = get(oid, true);
@ -135,6 +141,27 @@ public:
host->unlock();
}
};
/**
* Dumps the HOST 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)
{
int rc;
oss << "<HOST_POOL>";
rc = Host::dump(db,oss,where);
oss << "</HOST_POOL>";
return rc;
}
private:
/**

View File

@ -24,7 +24,10 @@
using namespace std;
extern "C" int host_share_select_cb (void * _host_share, int num,char ** values, char ** names);
extern "C" int host_share_select_cb (void * _hs,
int num,
char ** values,
char ** names);
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -44,15 +47,6 @@ public:
~HostShare(){};
/**
* Gets the HostShare identifier
* @return HSID HostShare identifier
*/
int get_hsid() const
{
return hsid;
};
/**
* Add a new VM to this share
* @param cpu requested by the VM
@ -104,55 +98,44 @@ public:
*/
friend ostream& operator<<(ostream& os, HostShare& hs);
private:
/**
* HostShare identifier
* Function to print the HostShare object into a string in
* plain text
* @param str the resulting string
* @return a reference to the generated string
*/
int hsid;
string& to_str(string& str) const;
/**
* HostShare's Endpoint
* Function to print the HostShare object into a string in
* XML format
* @param xml the resulting XML string
* @return a reference to the generated string
*/
string endpoint;
string& to_xml(string& xml) const;
private:
/**
* HostShare disk usage (in Kb)
*/
int disk_usage;
int hsid; /**< HostShare identifier */
int disk_usage; /**< Disk allocated to VMs (in Mb). */
int mem_usage; /**< Memory allocated to VMs (in Mb) */
int cpu_usage; /**< CPU allocated to VMs (in percentage) */
int max_disk; /**< Total disk capacity (in Mb) */
int max_mem; /**< Total memory capacity (in Mb) */
int max_cpu; /**< Total cpu capacity (in percentage) */
/**
* HostShare memory usage (in Kb)
*/
int mem_usage;
int free_disk; /**< Free disk from the IM monitor */
int free_mem; /**< Free memory from the IM monitor */
int free_cpu; /**< Free cpu from the IM monitor */
/**
* HostShare cpu usage (in percentage)
*/
int cpu_usage;
int used_disk; /**< Used disk from the IM monitor */
int used_mem; /**< Used memory from the IM monitor */
int used_cpu; /**< Used cpu from the IM monitor */
/**
* HostShare disk share (in GB), 0 means that the share will use all the
* avialable disk in the host
*/
int max_disk;
/**
* HostShare memory share (in MB), 0 means that the share will use all the
* avialable disk in the host
*/
int max_mem;
/**
* HostShare cpu usage (in percentage), 0 means that the share will use all
* the avialable disk in the host
*/
int max_cpu;
/**
* Number of running Virtual Machines in this HostShare
*/
int running_vms;
int running_vms; /**< Number of running VMs in this Host */
// ----------------------------------------
// Friends
// ----------------------------------------
@ -160,9 +143,9 @@ private:
friend class Host;
friend int host_share_select_cb (
void * _hostshare,
int num,
char ** values,
void * _hostshare,
int num,
char ** values,
char ** names);
// ----------------------------------------
@ -171,17 +154,22 @@ private:
enum ColNames
{
HID = 0,
ENDPOINT = 1,
DISK_USAGE = 2,
MEM_USAGE = 3,
CPU_USAGE = 4,
MAX_DISK = 5,
MAX_MEMORY = 6,
MAX_CPU = 7,
RUNNING_VMS = 8,
LIMIT = 9
};
HID = 0,
DISK_USAGE = 1,
MEM_USAGE = 2,
CPU_USAGE = 3,
MAX_DISK = 4,
MAX_MEMORY = 5,
MAX_CPU = 6,
FREE_DISK = 7,
FREE_MEMORY = 8,
FREE_CPU = 9,
USED_DISK = 10,
USED_MEMORY = 11,
USED_CPU = 12,
RUNNING_VMS = 13,
LIMIT = 14
};
static const char * table;
@ -228,7 +216,20 @@ private:
* @para vaues the column values
* @return 0 on success
*/
int unmarshall(int num, char **names, char ** values);
int unmarshall(int num, char **names, char ** values);
/**
* Function to unmarshall a HostShare object in to an output stream in XML
* @param oss the output stream
* @param num the number of columns read from the DB
* @param names the column names
* @param vaues the column values
* @return 0 on success
*/
static int unmarshall(ostringstream& oss,
int num,
char ** names,
char ** values);
};

View File

@ -30,7 +30,7 @@ class HostTemplate : public TemplateSQL
public:
HostTemplate(int tid = -1,
const char separator = '='):
TemplateSQL(table,tid,true,separator,"HOST_TEMPLATE"){};
TemplateSQL(table,tid,true,separator,"TEMPLATE"){};
~HostTemplate(){};

View File

@ -129,7 +129,7 @@ protected:
* @param ip ip of the lease in string
* @param mac mac of the lease in string
*/
void to_string(string& _ip, string& _mac);
void to_string(string& _ip, string& _mac) const;
/**
* Conversion from string IP to unsigned int IP
@ -157,7 +157,23 @@ protected:
* Prints a Lease in a single line
*/
friend ostream& operator<<(ostream& os, Lease& _lease);
/**
* Function to print the Lease object into a string in
* plain text
* @param str the resulting string
* @return a reference to the generated string
*/
string& to_str(string& str) const;
/**
* Function to print the Lease 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;
/**
* Constants to access the array storing the MAC address
*/
@ -176,9 +192,8 @@ protected:
bool used;
};
friend ostream& operator<<(ostream& os, Lease& _lease);
friend class VirtualNetwork;
// -------------------------------------------------------------------------
// Leases fields
@ -242,6 +257,24 @@ protected:
*/
virtual int select(SqliteDB * db);
friend ostream& operator<<(ostream& os, Lease& _lease);
/**
* Function to print the Leases object into a string in
* plain text
* @param str the resulting string
* @return a reference to the generated string
*/
string& to_str(string& str) const;
/**
* Function to print the Leases 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;
private:
friend int leases_select_cb (

View File

@ -44,29 +44,31 @@ public:
enum Actions
{
SAVE_SUCCESS, /**< Send by the VMM when a save action succeeds */
SAVE_FAILURE, /**< Send by the VMM when a save action fails */
DEPLOY_SUCCESS, /**< Send by the VMM when a deploy/restore/migrate action succeeds */
DEPLOY_FAILURE, /**< Send by the VMM when a deploy/restore/migrate action fails */
SHUTDOWN_SUCCESS, /**< Send by the VMM when a shutdown action succeeds*/
SHUTDOWN_FAILURE, /**< Send by the VMM when a shutdown action fails */
CANCEL_SUCCESS, /**< Send by the VMM when a cancel action succeeds */
CANCEL_FAILURE, /**< Send by the VMM when a cancel action fails */
MONITOR_FAILURE, /**< Send by the VMM when a VM has failed while active */
MONITOR_SUSPEND, /**< Send by the VMM when a VM is paused while active */
MONITOR_DONE, /**< Send by the VMM when a VM is not found */
PROLOG_SUCCESS, /**< Send by the TM when the prolog phase succeeds */
PROLOG_FAILURE, /**< Send by the TM when the prolog phase fails */
EPILOG_SUCCESS, /**< Send by the TM when the epilog phase succeeds */
EPILOG_FAILURE, /**< Send by the TM when the epilog phase fails */
DEPLOY, /**< Send by the DM to deploy a VM on a host */
SUSPEND, /**< Send by the DM to suspend an running VM */
RESTORE, /**< Send by the DM to restore a suspended VM */
STOP, /**< Send by the DM to stop an running VM */
CANCEL, /**< Send by the DM to cancel an running VM */
MIGRATE, /**< Send by the DM to migrate a VM to other host */
LIVE_MIGRATE, /**< Send by the DM to live-migrate a VM */
SHUTDOWN, /**< Send by the DM to shutdown an running VM */
SAVE_SUCCESS, /**< Sent by the VMM when a save action succeeds */
SAVE_FAILURE, /**< Sent by the VMM when a save action fails */
DEPLOY_SUCCESS, /**< Sent by the VMM when a deploy/restore/migrate action succeeds */
DEPLOY_FAILURE, /**< Sent by the VMM when a deploy/restore/migrate action fails */
SHUTDOWN_SUCCESS, /**< Sent by the VMM when a shutdown action succeeds*/
SHUTDOWN_FAILURE, /**< Sent by the VMM when a shutdown action fails */
CANCEL_SUCCESS, /**< Sent by the VMM when a cancel action succeeds */
CANCEL_FAILURE, /**< Sent by the VMM when a cancel action fails */
MONITOR_FAILURE, /**< Sent by the VMM when a VM has failed while active */
MONITOR_SUSPEND, /**< Sent by the VMM when a VM is paused while active */
MONITOR_DONE, /**< Sent by the VMM when a VM is not found */
PROLOG_SUCCESS, /**< Sent by the TM when the prolog phase succeeds */
PROLOG_FAILURE, /**< Sent by the TM when the prolog phase fails */
EPILOG_SUCCESS, /**< Sent by the TM when the epilog phase succeeds */
EPILOG_FAILURE, /**< Sent by the TM when the epilog phase fails */
DEPLOY, /**< Sent by the DM to deploy a VM on a host */
SUSPEND, /**< Sent by the DM to suspend an running VM */
RESTORE, /**< Sent by the DM to restore a suspended VM */
STOP, /**< Sent by the DM to stop an running VM */
CANCEL, /**< Sent by the DM to cancel an running VM */
MIGRATE, /**< Sent by the DM to migrate a VM to other host */
LIVE_MIGRATE, /**< Sent by the DM to live-migrate a VM */
SHUTDOWN, /**< Sent by the DM to shutdown a running VM */
RESTART, /**< Sent by the DM to restart a deployed VM */
DELETE, /**< Sent by the DM to delete a VM */
FINALIZE
};
@ -181,6 +183,12 @@ private:
void shutdown_action(int vid);
void failure_action(VirtualMachine * vm);
void restart_action(int vid);
void delete_action(int vid);
void timer_action();
};

View File

@ -74,7 +74,21 @@ protected:
cstr = str.c_str();
::write(nebula_mad_pipe, cstr, str.size());
};
};
/**
* Send a DRIVER_CANCEL command to the driver
* @param oid identifies the action (that associated with oid)
*/
void driver_cancel (const int oid) const
{
ostringstream os;
os << "DRIVER_CANCEL " << oid << endl;
write(os);
};
private:
friend class MadManager;

View File

@ -26,6 +26,7 @@
#include "VirtualMachinePool.h"
#include "VirtualNetworkPool.h"
#include "HostPool.h"
#include "UserPool.h"
#include "VirtualMachineManager.h"
#include "LifeCycleManager.h"
@ -94,6 +95,11 @@ public:
{
return vnpool;
};
UserPool * get_upool()
{
return upool;
};
// --------------------------------------------------------------
// Manager Accessors
@ -237,8 +243,8 @@ private:
//Constructors and = are private to only access the class through instance
// -----------------------------------------------------------------------
Nebula():nebula_configuration(0),db(0),vmpool(0),hpool(0),vnpool(0),lcm(0),
vmm(0),im(0),tm(0),dm(0),rm(0)
Nebula():nebula_configuration(0),db(0),vmpool(0),hpool(0),vnpool(0),upool(0),
lcm(0),vmm(0),im(0),tm(0),dm(0),rm(0)
{
const char * nl = getenv("ONE_LOCATION");
@ -284,6 +290,11 @@ private:
delete hpool;
}
if ( upool != 0)
{
delete upool;
}
if ( vmm != 0)
{
delete vmm;
@ -360,6 +371,7 @@ private:
VirtualMachinePool * vmpool;
HostPool * hpool;
VirtualNetworkPool * vnpool;
UserPool * upool;
// ---------------------------------------------------------------
// Nebula Managers

View File

@ -106,25 +106,12 @@ public:
return rc;
};
/**
* Removes an object from the pool cache. The object mutex MUST be locked.
* The resources of the object are freed, but its record is kept in the DB.
* @param objsql a pointer to the object
*/
void remove(
PoolObjectSQL * objsql);
/**
* Removes all the elements from the pool
*/
void clean();
/**
* Bootstraps the database table(s) associated to the pool
*/
virtual void bootstrap() = 0;
protected:
/**

View File

@ -21,6 +21,7 @@
#include "ActionManager.h"
#include "VirtualMachinePool.h"
#include "HostPool.h"
#include "UserPool.h"
#include "VirtualNetworkPool.h"
#include <xmlrpc-c/base.hpp>
@ -41,10 +42,11 @@ public:
VirtualMachinePool * _vmpool,
HostPool * _hpool,
VirtualNetworkPool * _vnpool,
UserPool * _upool,
int _port,
string _xml_log_file)
:vmpool(_vmpool),hpool(_hpool),vnpool(_vnpool),port(_port),socket_fd(-1),
xml_log_file(_xml_log_file)
:vmpool(_vmpool),hpool(_hpool),vnpool(_vnpool),upool(_upool),
port(_port),socket_fd(-1),xml_log_file(_xml_log_file)
{
am.addListener(this);
};
@ -106,12 +108,17 @@ private:
/**
* Pointer to the Host Pool, to access hosts
*/
HostPool * hpool;
HostPool * hpool;
/**
* Pointer to the VN Pool, to access Virtual Netowrks
*/
VirtualNetworkPool * vnpool;
/**
* Pointer to the User Pool, to access users
*/
UserPool * upool;
/**
* Port number where the connection will be open
@ -154,14 +161,21 @@ private:
int setup_socket();
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// XML-RPC Methods
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
/* ---------------------------------------------------------------------- */
/* Virtual Machine Interface */
/* ---------------------------------------------------------------------- */
class VirtualMachineAllocate: public xmlrpc_c::method
{
public:
VirtualMachineAllocate()
VirtualMachineAllocate(
UserPool * _upool):
upool(_upool)
{
_signature="A:ss";
_help="Allocates a virtual machine in the pool";
@ -172,7 +186,8 @@ private:
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval);
private:
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
@ -182,9 +197,11 @@ private:
public:
VirtualMachineDeploy(
VirtualMachinePool * _vmpool,
HostPool * _hpool):
HostPool * _hpool,
UserPool * _upool):
vmpool(_vmpool),
hpool(_hpool)
hpool(_hpool),
upool(_upool)
{
_signature="A:sii";
_help="Deploys a virtual machine";
@ -198,7 +215,8 @@ private:
private:
VirtualMachinePool * vmpool;
HostPool * hpool;
HostPool * hpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
@ -206,7 +224,11 @@ private:
class VirtualMachineAction: public xmlrpc_c::method
{
public:
VirtualMachineAction()
VirtualMachineAction(
VirtualMachinePool * _vmpool,
UserPool * _upool):
vmpool(_vmpool),
upool(_upool)
{
_signature="A:ssi";
_help="Performs an action on a virtual machine";
@ -220,7 +242,7 @@ private:
private:
VirtualMachinePool * vmpool;
HostPool * hpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
@ -230,9 +252,11 @@ private:
public:
VirtualMachineMigrate(
VirtualMachinePool * _vmpool,
HostPool * _hpool):
HostPool * _hpool,
UserPool * _upool):
vmpool(_vmpool),
hpool(_hpool)
hpool(_hpool),
upool(_upool)
{
_signature="A:siib";
_help="Migrates a virtual machine";
@ -247,6 +271,7 @@ private:
private:
VirtualMachinePool * vmpool;
HostPool * hpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
@ -255,8 +280,10 @@ private:
{
public:
VirtualMachineInfo(
VirtualMachinePool * _vmpool):
vmpool(_vmpool)
VirtualMachinePool * _vmpool,
UserPool * _upool):
vmpool(_vmpool),
upool(_upool)
{
_signature="A:si";
_help="Returns virtual machine information";
@ -270,6 +297,7 @@ private:
private:
VirtualMachinePool * vmpool;
UserPool * upool;
};
@ -279,8 +307,10 @@ private:
{
public:
VirtualMachinePoolInfo(
VirtualMachinePool * _vmpool):
vmpool(_vmpool)
VirtualMachinePool * _vmpool,
UserPool * _upool):
vmpool(_vmpool),
upool(_upool)
{
_signature="A:si";
_help="Returns the virtual machine pool";
@ -294,16 +324,23 @@ private:
private:
VirtualMachinePool * vmpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
/* Host Interface */
/* ---------------------------------------------------------------------- */
class HostAllocate: public xmlrpc_c::method
{
public:
HostAllocate(HostPool * _hpool):hpool(_hpool)
HostAllocate(
HostPool * _hpool,
UserPool * _upool):
hpool(_hpool),
upool(_upool)
{
_signature="A:sssssb";
_signature="A:sssss";
_help="Allocates a host in the pool";
};
@ -315,7 +352,7 @@ private:
private:
HostPool * hpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
@ -323,7 +360,11 @@ private:
class HostInfo: public xmlrpc_c::method
{
public:
HostInfo(HostPool * _hpool):hpool(_hpool)
HostInfo(
HostPool * _hpool,
UserPool * _upool):
hpool(_hpool),
upool(_upool)
{
_signature="A:si";
_help="Returns host information";
@ -337,7 +378,32 @@ private:
private:
HostPool * hpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
class HostPoolInfo: public xmlrpc_c::method
{
public:
HostPoolInfo(HostPool * _hpool,
UserPool * _upool):
hpool(_hpool),
upool(_upool)
{
_signature="A:s";
_help="Returns the host pool information";
};
~HostPoolInfo(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
HostPool * hpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
@ -345,7 +411,11 @@ private:
class HostDelete: public xmlrpc_c::method
{
public:
HostDelete(HostPool * _hpool):hpool(_hpool)
HostDelete(
HostPool * _hpool,
UserPool * _upool):
hpool(_hpool),
upool(_upool)
{
_signature="A:si";
_help="Deletes a host from the pool";
@ -359,7 +429,7 @@ private:
private:
HostPool * hpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
@ -367,7 +437,11 @@ private:
class HostEnable: public xmlrpc_c::method
{
public:
HostEnable(HostPool * _hpool):hpool(_hpool)
HostEnable(
HostPool * _hpool,
UserPool * _upool):
hpool(_hpool),
upool(_upool)
{
_signature="A:sib";
_help="Enables or disables a host";
@ -381,7 +455,7 @@ private:
private:
HostPool * hpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
@ -392,7 +466,11 @@ private:
class VirtualNetworkAllocate: public xmlrpc_c::method
{
public:
VirtualNetworkAllocate(VirtualNetworkPool * _vnpool):vnpool(_vnpool)
VirtualNetworkAllocate(
VirtualNetworkPool * _vnpool,
UserPool * _upool):
vnpool(_vnpool),
upool(_upool)
{
_signature="A:ss";
_help="Creates a virtual network";
@ -406,6 +484,7 @@ private:
private:
VirtualNetworkPool * vnpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
@ -413,7 +492,11 @@ private:
class VirtualNetworkInfo: public xmlrpc_c::method
{
public:
VirtualNetworkInfo(VirtualNetworkPool * _vnpool):vnpool(_vnpool)
VirtualNetworkInfo(
VirtualNetworkPool * _vnpool,
UserPool * _upool):
vnpool(_vnpool),
upool(_upool)
{
_signature="A:si";
_help="Returns virtual network information";
@ -424,18 +507,47 @@ private:
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
VirtualNetworkPool * vnpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
class VirtualNetworkPoolInfo: public xmlrpc_c::method
{
public:
VirtualNetworkPoolInfo(VirtualNetworkPool * _vnpool,
UserPool * _upool):
vnpool(_vnpool),
upool(_upool)
{
_signature="A:si";
_help="Returns the virtual network pool information";
};
~VirtualNetworkPoolInfo(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
VirtualNetworkPool * vnpool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
class VirtualNetworkDelete: public xmlrpc_c::method
{
public:
VirtualNetworkDelete(VirtualNetworkPool * _vnpool):vnpool(_vnpool)
VirtualNetworkDelete(
VirtualNetworkPool * _vnpool,
UserPool * _upool):
vnpool(_vnpool),
upool(_upool)
{
_signature="A:si";
_help="Deletes a virtual network";
@ -449,10 +561,99 @@ private:
private:
VirtualNetworkPool * vnpool;
UserPool * upool;
};
};
/* ---------------------------------------------------------------------- */
/* User Management Interface */
/* ---------------------------------------------------------------------- */
class UserAllocate: public xmlrpc_c::method
{
public:
UserAllocate(UserPool * _upool):upool(_upool)
{
_signature="A:sss";
_help="Creates a new user";
};
~UserAllocate(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
class UserInfo: public xmlrpc_c::method
{
public:
UserInfo(UserPool * _upool):upool(_upool)
{
_signature="A:si";
_help="Returns the Info of the user";
};
~UserInfo(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
class UserDelete: public xmlrpc_c::method
{
public:
UserDelete(UserPool * _upool):upool(_upool)
{
_signature="A:si";
_help="Deletes a user account";
};
~UserDelete(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
class UserPoolInfo: public xmlrpc_c::method
{
public:
UserPoolInfo(UserPool * _upool):upool(_upool)
{
_signature="A:s";
_help="Creates a new user";
};
~UserPoolInfo(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
UserPool * upool;
};
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -187,7 +187,12 @@ private:
// ---------------------------------------------------------------
// XML_RPC related variables
// ---------------------------------------------------------------
/**
* The authentication token
*/
string secret;
/**
* NOTE (from lib doc): "you may not have more than one object of this
* class in a program. The code is not re-entrant -- it uses global
@ -196,5 +201,4 @@ private:
xmlrpc_c::clientSimple xmlrpc_client;
};
#endif /*SCHEDULER_H_*/

View File

@ -52,7 +52,10 @@ public:
PROLOG_RESUME,
EPILOG,
EPILOG_STOP,
EPILOG_DELETE,
EPILOG_DELETE_PREVIOUS,
CHECKPOINT,
DRIVER_CANCEL,
FINALIZE
};
@ -187,10 +190,25 @@ private:
*/
void epilog_stop_action(int vid);
/**
* This function starts the epilog_delete sequence
*/
void epilog_delete_action(int vid);
/**
* This function starts the epilog_delete sequence on the previous host
*/
void epilog_delete_previous_action(int vid);
/**
* This function starts the epilog sequence
*/
void checkpoint_action(int vid);
/**
* This function cancels the operation being performed by the driver
*/
void driver_cancel_action(int vid);
};
#endif /*TRANSFER_MANAGER_H*/

301
include/User.h Normal file
View File

@ -0,0 +1,301 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad */
/* Complutense de Madrid (dsa-research.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 USER_H_
#define USER_H_
#include "PoolSQL.h"
using namespace std;
extern "C" int user_select_cb (void * _host,
int num,
char ** values,
char ** names);
extern "C" int user_dump_cb (void * _oss,
int num,
char ** values,
char ** names);
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/**
* The User class. It represents a User...
*/
class User : public PoolObjectSQL
{
public:
/**
* Function to write a User on an output stream
*/
friend ostream& operator<<(ostream& os, User& u);
/**
* Function to print the User object into a string in plain text
* @param str the resulting string
* @return a reference to the generated string
*/
string& to_str(string& str) const;
/**
* Function to print the User object into a string in XML format
* @param xml the resulting XML string
* @return a reference to the generated string
*/
string& to_xml(string& xml) const;
/**
* Get the User unique identifier UID, that matches the OID of the object
* @return UID User identifier
*/
int get_uid() const
{
return oid;
};
// ----- Getters ---------------------------------
/**
* Check if the user is enabled
* @return true if the user is enabled
*/
bool isEnabled() const
{
return enabled;
}
/**
* Returns user username
* @return username User's hostname
*/
const string& get_username() const
{
return username;
};
/**
* Returns user password
* @return username User's hostname
*/
const string& get_password() const
{
return password;
};
// ----- Setters ---------------------------------
/**
* Enables the current user
*/
void enable()
{
enabled = true;
};
/**
* Disables the current user
*/
void disable()
{
enabled = false;
};
/**
* Sets user username
*/
void set_username(string _username)
{
username = _username;
};
/**
* Sets user password
*/
void set_password(string _password)
{
password = _password;
};
/**
* Looks for a match between _password and user password
* @return -1 if disabled or wrong password, uid otherwise
**/
int authenticate(string _password);
/**
* Splits an authentication token (<usr>:<pass>)
* @param secret, the authentication token
* @param username
* @param password
* @return 0 on success
**/
static int split_secret(const string secret, string& user, string& pass);
/**
* "Encrypts" the password with SHA1 digest
* @param password
* @return sha1 encrypted password
*/
static string sha1_digest(const string& pass);
private:
// -------------------------------------------------------------------------
// Friends
// -------------------------------------------------------------------------
friend class UserPool;
friend int user_select_cb (void * _host,
int num,
char ** values,
char ** names);
friend int user_dump_cb (void * _oss,
int num,
char ** values,
char ** names);
// -------------------------------------------------------------------------
// User Attributes
// -------------------------------------------------------------------------
/**
* User's username
*/
string username;
/**
* User's password
*/
string password;
/**
* Flag marking user enabled/disabled
*/
bool enabled;
// *************************************************************************
// DataBase implementation (Private)
// *************************************************************************
/**
* Function to unmarshall a User object
* @param num the number of columns read from the DB
* @para names the column names
* @para vaues the column values
* @return 0 on success
*/
int unmarshall(int num, char **names, char ** values);
/**
* Function to unmarshall a User object in to an output stream in XML
* @param oss the output stream
* @param num the number of columns read from the DB
* @param names the column names
* @param vaues the column values
* @return 0 on success
*/
static int unmarshall(ostringstream& oss,
int num,
char ** names,
char ** values);
/**
* Bootstraps the database table(s) associated to the User
*/
static void bootstrap(SqliteDB * db)
{
db->exec(User::db_bootstrap);
};
protected:
// *************************************************************************
// Constructor
// *************************************************************************
User(int id=-1,
string _username="",
string _password="",
bool _enabled=true);
virtual ~User();
// *************************************************************************
// DataBase implementation
// *************************************************************************
enum ColNames
{
OID = 0,
USERNAME = 1,
PASSWORD = 2,
ENABLED = 3, // 0 = false, 1 = true
LIMIT = 4
};
static const char * db_names;
static const char * db_bootstrap;
static const char * table;
/**
* Reads the User (identified with its OID=UID) from the database.
* @param db pointer to the db
* @return 0 on success
*/
virtual int select(SqliteDB *db);
/**
* Writes the User in the database.
* @param db pointer to the db
* @return 0 on success
*/
virtual int insert(SqliteDB *db);
/**
* Writes/updates the User data fields in the database.
* @param db pointer to the db
* @return 0 on success
*/
virtual int update(SqliteDB *db);
/**
* Drops USer from the database
* @param db pointer to the db
* @return 0 on success
*/
virtual int drop(SqliteDB *db);
/**
* Dumps the contect of a set of User objects in the given stream
* using XML format
* @param db pointer to the db
* @param oss the output stream
* @param where string to filter the VirtualMachine objects
* @return 0 on success
*/
static int dump(SqliteDB * db, ostringstream& oss, const string& where);
};
#endif /*USER_H_*/

173
include/UserPool.h Normal file
View File

@ -0,0 +1,173 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad */
/* Complutense de Madrid (dsa-research.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 USER_POOL_H_
#define USER_POOL_H_
#include "PoolSQL.h"
#include "User.h"
#include <time.h>
#include <sstream>
#include <iostream>
#include <vector>
using namespace std;
/**
* The User Pool class. ...
*/
class UserPool : public PoolSQL
{
public:
UserPool(SqliteDB * db);
~UserPool(){};
/**
* Function to allocate a new User object
* @param oid the id assigned to the User
* @return 0 on success
*/
int allocate (
int * oid,
string hostname,
string password,
bool enabled);
/**
* Function to get a User from the pool, if the object is not in memory
* it is loaded from the DB
* @param oid User unique id
* @param lock locks the User mutex
* @return a pointer to the Host, 0 if the User could not be loaded
*/
User * get(
int oid,
bool lock)
{
User * user = static_cast<User *>(PoolSQL::get(oid,lock));
return user;
}
/**
* Function to get a User from the pool, if the object is not in memory
* it is loaded from the DB
* @param username
* @param lock locks the User mutex
* @return a pointer to the User, 0 if the User could not be loaded
*/
User * get(
string username,
bool lock)
{
map<string, int>::iterator index;
index = known_users.find(username);
if ( index != known_users.end() )
{
return get((int)index->second,lock);
}
return 0;
}
/** Update a particular User
* @param user pointer to User
* @return 0 on success
*/
int update(User * user)
{
return user->update(db);
};
/** Drops a user from the DB, the user mutex MUST BE locked
* @param user pointer to User
*/
int drop(User * user)
{
int rc = user->drop(db);
if ( rc == 0)
{
known_users.erase(user->get_username());
}
return rc;
};
/**
* Bootstraps the database table(s) associated to the User pool
*/
static void bootstrap(SqliteDB * _db)
{
User::bootstrap(_db);
};
/**
* Returns whether there is a user with given username/password or not
* @param session, colon separated username and password string
* @return -1 if there is no such a user, uid of the user if it exists
*/
int authenticate(string& session);
/**
* Dumps the User 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)
{
int rc;
oss << "<USER_POOL>";
rc = User::dump(db,oss,where);
oss << "</USER_POOL>";
return rc;
}
private:
/**
* Factory method to produce User objects
* @return a pointer to the new User
*/
PoolObjectSQL * create()
{
return new User;
};
/**
* This map stores the association between UIDs and Usernames
*/
map<string, int> known_users;
};
#endif /*USER_POOL_H_*/

View File

@ -77,7 +77,10 @@ public:
EPILOG_STOP = 10,
EPILOG = 11,
SHUTDOWN = 12,
CANCEL = 13
CANCEL = 13,
FAILURE = 14,
DELETE = 15,
UNKNOWN = 16
};
// -------------------------------------------------------------------------
@ -183,6 +186,16 @@ public:
}
};
/**
* Returns the name of the VM
* @return the VM name
*/
const string& get_name() const
{
return name;
};
/**
* Returns the deployment ID
* @return the VMM driver specific ID
@ -247,6 +260,7 @@ public:
{
return (previous_history!=0);
};
/**
* Returns the VMM driver name for the current host. The hasHistory()
* function MUST be called before this one.
@ -257,6 +271,16 @@ public:
return history->vmm_mad_name;
};
/**
* Returns the VMM driver name for the previous host. The hasPreviousHistory()
* function MUST be called before this one.
* @return the VMM mad name
*/
const string & get_previous_vmm_mad() const
{
return previous_history->vmm_mad_name;
};
/**
* Returns the TM driver name for the current host. The hasHistory()
* function MUST be called before this one.
@ -267,6 +291,16 @@ public:
return history->tm_mad_name;
};
/**
* Returns the TM driver name for the previous host. The
* hasPreviousHistory() function MUST be called before this one.
* @return the TM mad name
*/
const string & get_previous_tm_mad() const
{
return previous_history->tm_mad_name;
};
/**
* Returns the transfer filename. The transfer file is in the form:
* $ONE_LOCATION/var/$VM_ID/transfer.$SEQ
@ -750,6 +784,12 @@ private:
// -------------------------------------------------------------------------
// Virtual Machine Description
// -------------------------------------------------------------------------
/**
* Name of the VM
*/
string name;
/**
* The Virtual Machine template, holds the VM attributes.
*/
@ -849,6 +889,20 @@ private:
*/
int unmarshall(int num, char **names, char ** values);
/**
* Function to unmarshall a VM object into an output stream with XML
* format.
* @param oss the output stream
* @param num the number of columns read from the DB
* @param names the column names
* @param vaues the column values
* @return 0 on success
*/
static int unmarshall(ostringstream& oss,
int num,
char ** names,
char ** values);
/**
* Updates the VM history record
* @param db pointer to the db
@ -963,18 +1017,19 @@ protected:
{
OID = 0,
UID = 1,
LAST_POLL = 2,
TEMPLATE_ID = 3,
STATE = 4,
LCM_STATE = 5,
STIME = 6,
ETIME = 7,
DEPLOY_ID = 8,
MEMORY = 9,
CPU = 10,
NET_TX = 11,
NET_RX = 12,
LIMIT = 13
NAME = 2,
LAST_POLL = 3,
TEMPLATE_ID = 4,
STATE = 5,
LCM_STATE = 6,
STIME = 7,
ETIME = 8,
DEPLOY_ID = 9,
MEMORY = 10,
CPU = 11,
NET_TX = 12,
NET_RX = 13,
LIMIT = 14
};
static const char * table;
@ -1003,17 +1058,6 @@ protected:
* @return 0 on success
*/
virtual int update(SqliteDB * db);
/**
* Dumps the contect of a set of VirtualMachine objects in the given stream
* using XML format
* @param db pointer to the db
* @param oss the output stream
* @param where string to filter the VirtualMachine objects
* @return 0 on success
*/
static int dump(SqliteDB * db, ostringstream& oss, const string&
where);
/**
* Deletes a VM from the database and all its associated information:
@ -1035,6 +1079,16 @@ where);
return rc;
}
/**
* Dumps the contect of a set of VirtualMachine objects in the given stream
* using XML format
* @param db pointer to the db
* @param oss the output stream
* @param where string to filter the VirtualMachine objects
* @return 0 on success
*/
static int dump(SqliteDB * db, ostringstream& oss, const string& where);
};
#endif /*VIRTUAL_MACHINE_H_*/

View File

@ -48,10 +48,12 @@ public:
SAVE,
SHUTDOWN,
CANCEL,
CANCEL_PREVIOUS,
MIGRATE,
RESTORE,
POLL,
TIMER,
DRIVER_CANCEL,
FINALIZE
};
@ -201,6 +203,14 @@ private:
void cancel_action(
int vid);
/**
* Cancels a VM (in the previous host) when a CANCEL action is received.
* Note that the domain-id is the last one returned by a boot action
* @param vid the id of the VM.
*/
void cancel_previous_action(
int vid);
/**
* Function to migrate (live) a VM (MIGRATE action).
* @param vid the id of the VM.
@ -226,6 +236,12 @@ private:
* This function is executed periodically to poll the running VMs
*/
void timer_action();
/**
* This function cancels the current driver operation
*/
void driver_cancel_action(
int vid);
};
#endif /*VIRTUAL_MACHINE_MANAGER_H*/

View File

@ -127,9 +127,9 @@ public:
/**
* Bootstraps the database table(s) associated to the VirtualMachine pool
*/
void bootstrap()
static void bootstrap(SqliteDB * _db)
{
VirtualMachine::bootstrap(db);
VirtualMachine::bootstrap(_db);
};
/**

View File

@ -29,7 +29,7 @@ class VirtualMachineTemplate : public TemplateSQL
{
public:
VirtualMachineTemplate(int tid = -1):
TemplateSQL(table,tid,false,'=',"VM_TEMPLATE"){};
TemplateSQL(table,tid,false,'=',"TEMPLATE"){};
~VirtualMachineTemplate(){};

View File

@ -34,6 +34,8 @@ using namespace std;
extern "C" int vn_select_cb (void * _vn, int num,char ** values, char ** names);
extern "C" int vn_dump_cb (void * _oss, int num, char ** values, char ** names);
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -60,6 +62,17 @@ public:
// *************************************************************************
// Virtual Network Public Methods
// *************************************************************************
/**
* Gets the uid of the owner of the Virtual Network
* @return uid
**/
int get_uid()
{
return uid;
}
/**
* Gets a new lease for a specific VM
* @param vid VM identifier
@ -112,6 +125,22 @@ public:
*/
friend ostream& operator<<(ostream& os, VirtualNetwork& vn);
/**
* Function to print the VirtualNetwork object into a string in
* plain text
* @param str the resulting string
* @return a reference to the generated string
*/
string& to_str(string& str) const;
/**
* Function to print the VirtualNetwork 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;
private:
// -------------------------------------------------------------------------
@ -125,6 +154,12 @@ private:
char ** values,
char ** names);
friend int vn_dump_cb (
void * _oss,
int num,
char ** values,
char ** names);
// *************************************************************************
// Virtual Network Private Attributes
// *************************************************************************
@ -209,6 +244,18 @@ private:
*/
int unmarshall(int num, char **names, char ** values);
/**
* Function to unmarshall a VNW object into an stream in XML format.
* @param oss the output stream
* @param num the number of columns read from the DB
* @para names the column names
* @para vaues the column values
* @return 0 on success
*/
static int unmarshall(ostringstream& oss,
int num,
char ** names,
char ** values);
/**
* Function to drop VN entry in vn_pool
* @return 0 on success
@ -369,6 +416,16 @@ protected:
return rc;
}
/**
* Dumps the contect of a set of Host objects in the given stream
* using XML format
* @param db pointer to the db
* @param oss the output stream
* @param where string to filter the VirtualMachine objects
* @return 0 on success
*/
static int dump(SqliteDB * db, ostringstream& oss, const string& where);
};
#endif /*VIRTUAL_NETWORK_H_*/

View File

@ -100,9 +100,9 @@ public:
/**
* Bootstraps the database table(s) associated to the VirtualNetwork pool
*/
void bootstrap()
static void bootstrap(SqliteDB * _db)
{
VirtualNetwork::bootstrap(db);
VirtualNetwork::bootstrap(_db);
};
/** Drops a VN from the cache & DB, the VN mutex MUST BE locked
@ -110,26 +110,31 @@ public:
*/
int drop(VirtualNetwork * vn)
{
int rc = vn->drop(db);
if ( rc == 0)
{
remove(static_cast<PoolObjectSQL *>(vn));
}
return rc;
return vn->drop(db);
};
private:
/**
* Factory method to produce VN objects
* @return a pointer to the new VN
* Dumps the HOST 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
*/
PoolObjectSQL * create()
int dump(ostringstream& oss, const string& where)
{
return new VirtualNetwork(mac_prefix, default_size);
};
int rc;
oss << "<VNET_POOL>";
rc = VirtualNetwork::dump(db,oss,where);
oss << "</VNET_POOL>";
return rc;
}
private:
/**
* Holds the system-wide MAC prefix
*/
@ -139,6 +144,16 @@ private:
* Default size for Virtual Networks
*/
unsigned int default_size;
/**
* Factory method to produce VN objects
* @return a pointer to the new VN
*/
PoolObjectSQL * create()
{
return new VirtualNetwork(mac_prefix, default_size);
};
};
#endif /*VIRTUAL_NETWORK_POOL_H_*/

View File

@ -29,7 +29,7 @@ class VirtualNetworkTemplate : public TemplateSQL
{
public:
VirtualNetworkTemplate(int tid = -1):
TemplateSQL(table,tid,false,'=',"NETWORK_TEMPLATE"){};
TemplateSQL(table,tid,false,'=',"TEMPLATE"){};
~VirtualNetworkTemplate(){};

View File

@ -125,6 +125,7 @@ ETC_DIRS="$ETC_LOCATION/im_kvm \
LIB_DIRS="$LIB_LOCATION/im_probes \
$LIB_LOCATION/ruby \
$LIB_LOCATION/ruby/OpenNebula \
$LIB_LOCATION/tm_commands \
$LIB_LOCATION/tm_commands/nfs \
$LIB_LOCATION/tm_commands/ssh \
@ -143,13 +144,14 @@ INSTALL_FILES[0]="BIN_FILES:$BIN_LOCATION"
INSTALL_FILES[1]="INCLUDE_FILES:$INCLUDE_LOCATION"
INSTALL_FILES[2]="LIB_FILES:$LIB_LOCATION"
INSTALL_FILES[3]="RUBY_LIB_FILES:$LIB_LOCATION/ruby"
INSTALL_FILES[4]="MADS_LIB_FILES:$LIB_LOCATION/mads"
INSTALL_FILES[5]="IM_PROBES_LIB_FILES:$LIB_LOCATION/im_probes"
INSTALL_FILES[6]="NFS_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/nfs"
INSTALL_FILES[7]="SSH_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/ssh"
INSTALL_FILES[8]="DUMMY_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/dummy"
INSTALL_FILES[9]="EXAMPLE_SHARE_FILES:$SHARE_LOCATION/examples"
INSTALL_FILES[10]="TM_EXAMPLE_SHARE_FILES:$SHARE_LOCATION/examples/tm"
INSTALL_FILES[4]="RUBY_OPENNEBULA_LIB_FILES:$LIB_LOCATION/ruby/OpenNebula"
INSTALL_FILES[5]="MADS_LIB_FILES:$LIB_LOCATION/mads"
INSTALL_FILES[6]="IM_PROBES_LIB_FILES:$LIB_LOCATION/im_probes"
INSTALL_FILES[7]="NFS_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/nfs"
INSTALL_FILES[8]="SSH_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/ssh"
INSTALL_FILES[9]="DUMMY_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/dummy"
INSTALL_FILES[10]="EXAMPLE_SHARE_FILES:$SHARE_LOCATION/examples"
INSTALL_FILES[11]="TM_EXAMPLE_SHARE_FILES:$SHARE_LOCATION/examples/tm"
INSTALL_ETC_FILES[0]="ETC_FILES:$ETC_LOCATION"
INSTALL_ETC_FILES[1]="VMM_XEN_ETC_FILES:$ETC_LOCATION/vmm_xen"
@ -172,6 +174,7 @@ BIN_FILES="src/nebula/oned \
src/client/ruby/onevm \
src/client/ruby/onehost \
src/client/ruby/onevnet \
src/client/ruby/oneuser \
share/scripts/one"
#-------------------------------------------------------------------------------
@ -198,8 +201,20 @@ RUBY_LIB_FILES="src/mad/ruby/one_mad.rb \
src/client/ruby/one.rb \
src/client/ruby/client_utilities.rb \
src/client/ruby/command_parse.rb \
src/client/ruby/lib/OpenNebula.rb \
src/tm_mad/TMScript.rb"
RUBY_OPENNEBULA_LIB_FILES="src/client/ruby/lib/OpenNebula/Host.rb \
src/client/ruby/lib/OpenNebula/HostPool.rb \
src/client/ruby/lib/OpenNebula/Pool.rb \
src/client/ruby/lib/OpenNebula/User.rb \
src/client/ruby/lib/OpenNebula/UserPool.rb \
src/client/ruby/lib/OpenNebula/VirtualMachine.rb \
src/client/ruby/lib/OpenNebula/VirtualMachinePool.rb \
src/client/ruby/lib/OpenNebula/VirtualNetwork.rb \
src/client/ruby/lib/OpenNebula/VirtualNetworkPool.rb \
src/client/ruby/lib/OpenNebula/XMLUtils.rb"
#-------------------------------------------------------------------------------
# Driver executable files, to be installed under $LIB_LOCATION/mads
#-------------------------------------------------------------------------------

View File

@ -15,6 +15,8 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
require 'OpenNebula'
#####################
# CONSOLE UTILITIES #
#####################
@ -44,7 +46,14 @@ def scr_move(x,y)
print "\33[#{x};#{y}H"
end
# Print header
def print_header(format_str, str, underline)
scr_bold
scr_underline if underline
print format_str % str
scr_restore
puts
end
##################################
# Class show configurable tables #
@ -207,6 +216,22 @@ end
# Miscelaneous #
################
def get_one_client(session=nil)
if !ENV["ONE_AUTH"] or ENV["ONE_AUTH"].empty? or !ENV["ONE_AUTH"].match(".+:.+")
puts "$ONE_AUTH not defined or malformed"
exit -1
end
OpenNebula::Client.new(session)
end
def is_error?(result)
OpenNebula.is_error?(result)
end
def is_successful?(result)
!OpenNebula.is_error?(result)
end
def check_parameters(name, number)
if ARGV.length < number
print "Command #{name} requires "
@ -220,62 +245,59 @@ def check_parameters(name, number)
end
def get_vm_id(vm, name)
vm_id=vm.get_vm_id(name)
def get_entity_id(name, pool_class)
return name if name.match(/^[0123456789]+$/)
# TODO: get vm's from the actual user
pool=pool_class.new(get_one_client)
result=pool.info
# TODO: Check for errors
objects=pool.select {|object| object.name==name }
result=nil
class_name=pool_class.name.split('::').last.gsub(/Pool$/, '')
if vm_id
if vm_id.kind_of?(Array)
puts "There are multiple VM's with name #{name}."
if objects.length>0
if objects.length>1
puts "There are multiple #{class_name}'s with name #{name}."
exit -1
else
result=vm_id
result=objects.first.id
end
else
puts "VM named #{name} not found."
puts "#{class_name} named #{name} not found."
exit -1
end
result
end
def get_host_id(host, name)
host_id=host.get_host_id(name)
result=nil
if host_id
if host_id.kind_of?(Array)
puts "There are multiple hosts with name #{name}."
exit -1
else
result=host_id
end
else
puts "Host named #{name} not found."
exit -1
end
result
def get_vm_id(name)
get_entity_id(name, OpenNebula::VirtualMachinePool)
end
def get_vn_id(vn, name)
vn_id=vn.get_vn_id(name)
result=nil
if vn_id
if vn_id.kind_of?(Array)
puts "There are multiple virtual networks with name #{name}."
exit -1
else
result=vn_id
end
else
puts "Virtual networks named #{name} not found."
exit -1
end
result
def get_host_id(name)
get_entity_id(name, OpenNebula::HostPool)
end
def get_vn_id(name)
get_entity_id(name, OpenNebula::VirtualNetworkPool)
end
def get_user_id(name)
get_entity_id(name, OpenNebula::UserPool)
end
def str_running_time(data)
stime=Time.at(data["stime"].to_i)
if data["etime"]=="0"
etime=Time.now
else
etime=Time.at(data["etime"].to_i)
end
dtime=Time.at(etime-stime).getgm
"%02d %02d:%02d:%02d" % [dtime.yday-1, dtime.hour, dtime.min, dtime.sec]
end

View File

@ -81,6 +81,11 @@ EOT
"is successful") do |o|
@options[:verbose]=true
end
opts.on("-x", "--xml",
"Returns xml instead of human readable text") do |o|
@options[:xml]=true
end
opts.on_tail("-h", "--help", "Shows this help message") do |o|
print_help

View File

@ -0,0 +1,99 @@
begin # require 'rubygems'
require 'rubygems'
rescue Exception
end
require 'xmlrpc/client'
require 'digest/sha1'
require 'rexml/document'
require 'pp'
require 'OpenNebula/XMLUtils'
require 'OpenNebula/VirtualMachine'
require 'OpenNebula/VirtualMachinePool'
require 'OpenNebula/VirtualNetwork'
require 'OpenNebula/VirtualNetworkPool'
require 'OpenNebula/User'
require 'OpenNebula/UserPool'
require 'OpenNebula/Host'
require 'OpenNebula/HostPool'
module OpenNebula
# -------------------------------------------------------------------------
# The Error Class represents a generic error in the OpenNebula
# library. It contains a readable representation of the error.
# Any function in the OpenNebula module will return an Error
# object in case of error.
# -------------------------------------------------------------------------
class Error
attr_reader :message
# +message+ a description of the error
def initialize(message=nil)
@message=message
end
def to_str()
@message
end
end
# -------------------------------------------------------------------------
# Returns true if the object returned by a method of the OpenNebula
# library is an Error
# -------------------------------------------------------------------------
def self.is_error?(value)
value.class==OpenNebula::Error
end
# -------------------------------------------------------------------------
# The client class, represents the connection with the core and handles the
# xml-rpc calls.
# -------------------------------------------------------------------------
class Client
begin
require 'xmlparser'
XMLPARSER=true
rescue LoadError
XMLPARSER=false
end
def initialize(secret=nil, endpoint=nil)
if secret
one_secret = secret
elsif ENV["ONE_AUTH"]
one_secret = ENV["ONE_AUTH"]
end
one_secret=~/(\w+):(\w+)/
@one_auth = "#{$1}:#{Digest::SHA1.hexdigest($2)}"
if endpoint
@one_endpoint=endpoint
elsif ENV["ONE_XMLRPC"]
@one_endpoint=ENV["ONE_XMLRPC"]
else
@one_endpoint="http://localhost:2633/RPC2"
end
end
def call(action, *args)
server=XMLRPC::Client.new2(@one_endpoint)
if XMLPARSER
server.set_parser(XMLRPC::XMLParser::XMLStreamParser.new)
end
begin
response = server.call("one."+action, @one_auth, *args)
if response[0] == false
Error.new(response[1])
else
response[1] #response[1..-1]
end
rescue Exception => e
Error.new(e.message)
end
end
end
end

View File

@ -0,0 +1,106 @@
require 'OpenNebula/Pool'
module OpenNebula
class Host < PoolElement
#######################################################################
# Constants and Class Methods
#######################################################################
HOST_METHODS = {
:info => "host.info",
:allocate => "host.allocate",
:delete => "host.delete",
:enable => "host.enable"
}
HOST_STATES=%w{INIT MONITORING MONITORED ERROR DISABLED}
SHORT_HOST_STATES={
"INIT" => "on",
"MONITORING" => "on",
"MONITORED" => "on",
"ERROR" => "err",
"DISABLED" => "off"
}
# Creates a Host description with just its identifier
# this method should be used to create plain Host objects.
# +id+ the id of the host
#
# Example:
# host = Host.new(Host.build_xml(3),rpc_client)
#
def Host.build_xml(pe_id=nil)
if pe_id
host_xml = "<HOST><ID>#{pe_id}</ID></HOST>"
else
host_xml = "<HOST></HOST>"
end
XMLUtilsElement.initialize_xml(host_xml, 'HOST')
end
#######################################################################
# Class constructor
#######################################################################
def initialize(xml, client)
super(xml,client)
@client = client
@pe_id = self['ID'].to_i if self['ID']
end
#######################################################################
# XML-RPC Methods for the Host
#######################################################################
def info()
super(HOST_METHODS[:info], 'HOST')
end
def allocate(hostname,im,vmm,tm)
super(HOST_METHODS[:allocate],hostname,im,vmm,tm)
end
def delete()
super(HOST_METHODS[:delete])
end
def enable()
set_enabled(true)
end
def disable()
set_enabled(false)
end
#######################################################################
# Helpers to get Host information
#######################################################################
# Returns the state of the Host (numeric value)
def state
self['STATE'].to_i
end
# Returns the state of the Host (string value)
def state_str
HOST_STATES[state]
end
# Returns the state of the Host (string value)
def short_state_str
SHORT_HOST_STATES[state_str]
end
private
def set_enabled(enabled)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(HOST_METHODS[:enable], @pe_id, enabled)
rc = nil if !OpenNebula.is_error?(rc)
return rc
end
end
end

View File

@ -0,0 +1,35 @@
require 'OpenNebula/Pool'
module OpenNebula
class HostPool < Pool
#######################################################################
# Constants and Class attribute accessors
#######################################################################
HOST_POOL_METHODS = {
:info => "hostpool.info"
}
#######################################################################
# Class constructor & Pool Methods
#######################################################################
# +client+ a Client object that represents a XML-RPC connection
def initialize(client)
super('HOST_POOL','HOST',client)
end
# Factory Method for the Host Pool
def factory(element_xml)
OpenNebula::Host.new(element_xml,@client)
end
#######################################################################
# XML-RPC Methods for the Host Pool
#######################################################################
def info()
super(HOST_POOL_METHODS[:info])
end
end
end

View File

@ -0,0 +1,173 @@
module OpenNebula
# The Pool class represents a generic OpenNebula Pool in XML format
# and provides the basic functionality to handle the Pool elements
class Pool
include Enumerable
include XMLUtilsPool
protected
#pool:: _String_ XML name of the root element
#element:: _String_ XML name of the Pool elements
#client:: _Client_ represents a XML-RPC connection
def initialize(pool,element,client)
@pool_name = pool.upcase
@element_name = element.upcase
@client = client
@xml = nil
end
# Default Factory Method for the Pools. The factory method returns an
# suitable PoolElement object. Each Pool MUST implement the
# corresponding factory method
# element_xml:: _XML_ XML element describing the pool element
# [return] a PoolElement object
def factory(element_xml)
OpenNebula::PoolElement.new(element_xml,client)
end
#######################################################################
# Common XML-RPC Methods for all the Pool Types
#######################################################################
# Calls to the corresponding info method to retreive the pool
# representation in XML format
# xml_method:: _String_ the name of the XML-RPC method
# args:: _Array_ with additional arguments for the info call
# [return] nil in case of success or an Error object
def info(xml_method,*args)
rc = @client.call(xml_method,*args)
if !OpenNebula.is_error?(rc)
@xml = initialize_xml(rc)
rc = nil
end
return rc
end
public
# Iterates over every PoolElement in the Pool and calls the block with a
# a PoolElement obtained calling the factory method
# block:: _Block_
def each(&block)
each_element(block) if @xml
end
# DO NOT USE - ONLY REXML BACKEND
def to_str
str = ""
REXML::Formatters::Pretty.new(1).write(@xml,str)
return str
end
end
# The PoolElement Class represents a generic element of a Pool in
# XML format
class PoolElement
include XMLUtilsElement
protected
# node:: _XML_is a XML element that represents the Pool element
# client:: _Client_ represents a XML-RPC connection
def initialize(node, client)
@xml = node
@client = client
if self['ID']
@pe_id = self['ID'].to_i
else
@pe_id = nil
end
@name = self['NAME'] if self['NAME']
end
#######################################################################
# Common XML-RPC Methods for all the Pool Element Types
#######################################################################
# Calls to the corresponding info method to retreive the element
# detailed information in XML format
# xml_method:: _String_ the name of the XML-RPC method
# root_element:: _String_ Base XML element
# [return] nil in case of success or an Error object
def info(xml_method, root_element)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(xml_method,@pe_id)
if !OpenNebula.is_error?(rc)
@xml = XMLUtilsElement::initialize_xml(rc, root_element)
rc = nil
@pe_id = self['ID'].to_i if self['ID']
@name = self['NAME'] if self['NAME']
end
return rc
end
# Calls to the corresponding allocate method to create a new element
# in the OpenNebula core
# xml_method:: _String_ the name of the XML-RPC method
# args:: _Array_ additional arguments including the template for the
# new element
# [return] nil in case of success or an Error object
def allocate(xml_method, *args)
rc = @client.call(xml_method, *args)
if !OpenNebula.is_error?(rc)
@pe_id = rc
rc = nil
end
return rc
end
# Calls to the corresponding delete method to remove this element
# from the OpenNebula core
# xml_method:: _String_ the name of the XML-RPC method
# [return] nil in case of success or an Error object
def delete(xml_method)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(xml_method,@pe_id)
rc = nil if !OpenNebula.is_error?(rc)
return rc
end
public
# Creates new element specifying its id
# id:: identifyier of the element
# client:: initialized OpenNebula::Client object
def self.new_with_id(id, client=nil)
self.new(self.build_xml(id), client)
end
# Returns element identifier
# [return] _Integer_ the PoolElement ID
def id
@pe_id
end
# Gets element name
# [return] _String_ the PoolElement name
def name
@name
end
# DO NOT USE - ONLY REXML BACKEND
def to_str
str = ""
REXML::Formatters::Pretty.new(1).write(@xml,str)
return str
end
end
end

View File

@ -0,0 +1,55 @@
require 'OpenNebula/Pool'
module OpenNebula
class User < PoolElement
# ---------------------------------------------------------------------
# Constants and Class Methods
# ---------------------------------------------------------------------
USER_METHODS = {
:info => "user.info",
:allocate => "user.allocate",
:delete => "user.delete"
}
# Creates a User description with just its identifier
# this method should be used to create plain User objects.
# +id+ the id of the user
#
# Example:
# user = User.new(User.build_xml(3),rpc_client)
#
def User.build_xml(pe_id=nil)
if pe_id
user_xml = "<USER><ID>#{pe_id}</ID></USER>"
else
user_xml = "<USER></USER>"
end
XMLUtilsElement.initialize_xml(user_xml, 'USER')
end
# ---------------------------------------------------------------------
# Class constructor
# ---------------------------------------------------------------------
def initialize(xml, client)
super(xml,client)
@client = client
end
# ---------------------------------------------------------------------
# XML-RPC Methods for the User Object
# ---------------------------------------------------------------------
def info()
super(USER_METHODS[:info], 'USER')
end
def allocate(username, password)
super(USER_METHODS[:allocate], username, password)
end
def delete()
super(USER_METHODS[:delete])
end
end
end

View File

@ -0,0 +1,35 @@
require 'OpenNebula/Pool'
module OpenNebula
class UserPool < Pool
# ---------------------------------------------------------------------
# Constants and Class attribute accessors
# ---------------------------------------------------------------------
USER_POOL_METHODS = {
:info => "userpool.info"
}
# ---------------------------------------------------------------------
# Class constructor & Pool Methods
# ---------------------------------------------------------------------
# +client+ a Client object that represents a XML-RPC connection
def initialize(client)
super('USER_POOL','USER',client)
end
# Factory method to create User objects
def factory(element_xml)
OpenNebula::User.new(element_xml,@client)
end
# ---------------------------------------------------------------------
# XML-RPC Methods for the User Object
# ---------------------------------------------------------------------
def info()
super(USER_POOL_METHODS[:info])
end
end
end

View File

@ -0,0 +1,216 @@
require 'OpenNebula/Pool'
module OpenNebula
class VirtualMachine < PoolElement
#######################################################################
# Constants and Class Methods
#######################################################################
VM_METHODS = {
:info => "vm.info",
:allocate => "vm.allocate",
:action => "vm.action",
:migrate => "vm.migrate",
:deploy => "vm.deploy"
}
VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED}
LCM_STATE=%w{LCM_INIT PROLOG BOOT RUNNING MIGRATE SAVE_STOP SAVE_SUSPEND
SAVE_MIGRATE PROLOG_MIGRATE PROLOG_RESUME EPILOG_STOP EPILOG
SHUTDOWN CANCEL FAILURE DELETE UNKNOWN}
SHORT_VM_STATES={
"INIT" => "init",
"PENDING" => "pend",
"HOLD" => "hold",
"ACTIVE" => "actv",
"STOPPED" => "stop",
"SUSPENDED" => "susp",
"DONE" => "done",
"FAILED" => "fail"
}
SHORT_LCM_STATES={
"PROLOG" => "prol",
"BOOT" => "boot",
"RUNNING" => "runn",
"MIGRATE" => "migr",
"SAVE_STOP" => "save",
"SAVE_SUSPEND" => "save",
"SAVE_MIGRATE" => "save",
"PROLOG_MIGRATE"=> "migr",
"PROLOG_RESUME" => "prol",
"EPILOG_STOP" => "epil",
"EPILOG" => "epil",
"SHUTDOWN" => "shut",
"CANCEL" => "shut",
"FAILURE" => "fail",
"DELETE" => "dele",
"UNKNOWN" => "unkn"
}
MIGRATE_REASON=%w{NONE ERROR STOP_RESUME USER CANCEL}
SHORT_MIGRATE_REASON={
"NONE" => "none",
"ERROR" => "erro",
"STOP_RESUME" => "stop",
"USER" => "user",
"CANCEL" => "canc"
}
# Creates a VirtualMachine description with just its identifier
# this method should be used to create plain VirtualMachine objects.
# +id+ the id of the vm
#
# Example:
# vnet = VirtualMachine.new(VirtualMachine.build_xml(3),rpc_client)
#
def VirtualMachine.build_xml(pe_id=nil)
if pe_id
vm_xml = "<VM><ID>#{pe_id}</ID></VM>"
else
vm_xml = "<VM></VM>"
end
XMLUtilsElement.initialize_xml(vm_xml, 'VM')
end
def VirtualMachine.get_reason(reason)
reason=MIGRATE_REASON[reason.to_i]
reason_str=SHORT_MIGRATE_REASON[reason]
reason_str
end
#######################################################################
# Class constructor
#######################################################################
def initialize(xml, client)
super(xml,client)
@element_name = "VM"
@client = client
end
#######################################################################
# XML-RPC Methods for the Virtual Machine Object
#######################################################################
def info()
super(VM_METHODS[:info], 'VM')
end
def allocate(description)
super(VM_METHODS[:allocate],description)
end
def deploy(host_id)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(VM_METHODS[:deploy], @pe_id, host_id.to_i)
rc = nil if !OpenNebula.is_error?(rc)
return rc
end
def shutdown
action('shutdown')
end
def cancel
action('cancel')
end
def hold
action('hold')
end
def release
action('release')
end
def stop
action('stop')
end
def suspend
action('suspend')
end
def resume
action('resume')
end
def finalize
action('finalize')
end
def restart
action('restart')
end
def migrate(host_id)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(VM_METHODS[:migrate], @pe_id, host_id.to_i, false)
rc = nil if !OpenNebula.is_error?(rc)
return rc
end
def live_migrate(host_id)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(VM_METHODS[:migrate], @pe_id, host_id.to_i, true)
rc = nil if !OpenNebula.is_error?(rc)
return rc
end
#######################################################################
# Helpers to get VirtualMachine information
#######################################################################
# Returns the VM state of the VirtualMachine (numeric value)
def state
self['STATE'].to_i
end
# Returns the VM state of the VirtualMachine (string value)
def state_str
VM_STATE[state]
end
# Returns the LCM state of the VirtualMachine (numeric value)
def lcm_state
self['LCM_STATE'].to_i
end
# Returns the LCM state of the VirtualMachine (string value)
def lcm_state_str
LCM_STATE[lcm_state]
end
# Returns the short status string for the VirtualMachine
def status
short_state_str=SHORT_VM_STATES[state_str]
if short_state_str=="actv"
short_state_str=SHORT_LCM_STATES[lcm_state_str]
end
short_state_str
end
private
def action(name)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(VM_METHODS[:action], name, @pe_id)
rc = nil if !OpenNebula.is_error?(rc)
return rc
end
end
end

View File

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

View File

@ -0,0 +1,54 @@
require 'OpenNebula/Pool'
module OpenNebula
class VirtualNetwork < PoolElement
# ---------------------------------------------------------------------
# Constants and Class Methods
# ---------------------------------------------------------------------
VN_METHODS = {
:info => "vn.info",
:allocate => "vn.allocate",
:delete => "vn.delete"
}
# Creates a VirtualNetwork description with just its identifier
# this method should be used to create plain VirtualNetwork objects.
# +id+ the id of the network
#
# Example:
# vnet = VirtualNetwork.new(VirtualNetwork.build_xml(3),rpc_client)
#
def VirtualNetwork.build_xml(pe_id=nil)
if pe_id
vn_xml = "<VNET><ID>#{pe_id}</ID></VNET>"
else
vn_xml = "<VNET></VNET>"
end
XMLUtilsElement.initialize_xml(vn_xml, 'VNET')
end
# Class constructor
def initialize(xml, client)
super(xml,client)
@client = client
end
#######################################################################
# XML-RPC Methods for the Virtual Network Object
#######################################################################
def info()
super(VN_METHODS[:info], 'VNET')
end
def allocate(description)
super(VN_METHODS[:allocate],description)
end
def delete()
super(VN_METHODS[:delete])
end
end
end

View File

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

View File

@ -0,0 +1,144 @@
module OpenNebula
begin
require 'nokogiri'
NOKOGIRI=true
rescue LoadError
NOKOGIRI=false
end
###########################################################################
# The XMLUtilsElement module provides an abstraction of the underlying
# XML parser engine. It provides XML-related methods for the Pool Elements
###########################################################################
module XMLUtilsElement
# Initialize a XML document for the element
# xml:: _String_ the XML document of the object
# root_element:: _String_ Base xml element
# [return] _XML_ object for the underlying XML engine
def self.initialize_xml(xml, root_element)
if NOKOGIRI
Nokogiri::XML(xml).xpath("/#{root_element}")
else
REXML::Document.new(xml).root
end
end
# Extract an element from the XML description of the PoolElement.
# key::_String_ The name of the element
# [return] _String_ the value of the element
# Examples:
# ['VID'] # gets VM id
# ['HISTORY/HOSTNAME'] # get the hostname from the history
def [](key)
if NOKOGIRI
element=@xml.xpath(key.to_s.upcase)
else
element=@xml.elements[key.to_s.upcase]
end
if element
element.text
end
end
def template_str(indent=true)
template_like_str('TEMPLATE', indent)
end
def template_like_str(root_element, indent=true)
if NOKOGIRI
xml_template=@xml.xpath(root_element).to_s
rexml=REXML::Document.new(xml_template).root
else
rexml=@xml.elements[root_element]
end
if indent
ind_enter="\n"
ind_tab=' '
else
ind_enter=''
ind_tab=' '
end
str=rexml.collect {|n|
if n.class==REXML::Element
str_line=""
if n.has_elements?
str_line << n.name << "=[" << ind_enter
str_line << n.collect {|n2|
if n2.class==REXML::Element
ind_tab+n2.name+"="+n2.text
end
}.compact.join(","+ind_enter)
str_line<<" ]"
else
str_line<<n.name << "=" << n.text.to_s
end
str_line
end
}.compact.join("\n")
str
end
def to_xml
if NOKOGIRI
@xml.to_xml
else
str = ""
REXML::Formatters::Pretty.new(1).write(@xml,str)
str
end
end
end
###########################################################################
# The XMLUtilsPool module provides an abstraction of the underlying
# XML parser engine. It provides XML-related methods for the Pools
###########################################################################
module XMLUtilsPool
#Initialize a XML document for the element
#xml:: _String_ the XML document of the object
#[return] _XML_ object for the underlying XML engine
def initialize_xml(xml)
if NOKOGIRI
Nokogiri::XML(xml).xpath("/#{@pool_name}")
else
xml=REXML::Document.new(xml).root
end
end
#Executes the given block for each element of the Pool
#block:: _Block_
def each_element(block)
if NOKOGIRI
@xml.xpath(
"#{@element_name}").each {|pelem|
block.call self.factory(pelem)
}
else
@xml.elements.each(
"#{@element_name}") {|pelem|
block.call self.factory(pelem)
}
end
end
def to_xml
if NOKOGIRI
@xml.to_xml
else
str = ""
REXML::Formatters::Pretty.new(1).write(@xml,str)
str
end
end
end
end

View File

@ -25,9 +25,11 @@ else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
end
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION
require 'one'
$: << './lib'
require 'OpenNebula'
require 'client_utilities'
require 'command_parse'
@ -36,60 +38,62 @@ ShowTableHost={
:name => "HID",
:desc => "ONE identifier for host",
:size => 4,
:proc => lambda {|d,e| d["oid"] }
:proc => lambda {|d,e| d.id }
},
:name => {
:name => "NAME",
:desc => "Hostname",
:size => 25,
:left => true,
:proc => lambda {|d,e| d["host_name"] }
:proc => lambda {|d,e| d.name }
},
:rvm => {
:name => "RVM",
:desc => "Number of virtual machines running",
:size => 3,
:proc => lambda {|d,e| d["hs_running_vms"] }
:proc => lambda {|d,e| d["HOST_SHARE/RUNNING_VMS"] }
},
:tcpu => {
:name => "TCPU",
:desc => "Total cpu percentage",
:size => 6,
:proc => lambda {|d,e| d["TOTALCPU"] }
:proc => lambda {|d,e| d["HOST_SHARE/MAX_CPU"] }
},
:fcpu => {
:name => "FCPU",
:desc => "Free cpu percentage",
:size => 6,
:proc => lambda {|d,e| d["TOTALCPU"].to_i-d["USEDCPU"].to_i }
:proc => lambda {|d,e| d["HOST_SHARE/MAX_CPU"].to_i-d["HOST_SHARE/USED_CPU"].to_i }
},
:acpu => {
:name => "ACPU",
:desc => "Available cpu percentage (not reserved by VMs)",
:size => 6,
:proc => lambda {|d,e|
max_cpu=d["hs_max_cpu"].to_i
max_cpu=d["HOST_SHARE/MAX_CPU"].to_i
max_cpu=100 if max_cpu==0
max_cpu-d["hs_cpu_usage"].to_i
max_cpu-d["HOST_SHARE/USED_CPU"].to_i
}
},
:tmem => {
:name => "TMEM",
:desc => "Total memory",
:size => 7,
:proc => lambda {|d,e| d["TOTALMEMORY"] }
:proc => lambda {|d,e| d["HOST_SHARE/MAX_MEM"] }
},
:fmem => {
:name => "FMEM",
:desc => "Free memory",
:size => 7,
:proc => lambda {|d,e| d["FREEMEMORY"] }
:proc => lambda {|d,e| d["HOST_SHARE/FREE_MEM"] }
},
:stat => {
:name => "STAT",
:desc => "Host status",
:size => 4,
:proc => lambda {|d,e| e[:host].get_state(d) }
:proc => lambda {|d,e|
d.short_state_str()
}
},
@ -97,9 +101,9 @@ ShowTableHost={
}
class HostShow
def initialize(host)
@host=host
@table=ShowTable.new(ShowTableHost, :host => @host)
def initialize(client)
@hostpool=OpenNebula::HostPool.new(client)
@table=ShowTable.new(ShowTableHost)
end
def close
@ -114,41 +118,22 @@ class HostShow
end
def list_short(options=nil)
res=@host.get
res=@hostpool.info
if options
@table.columns=options[:columns] if options[:columns]
end
if res[0]
if OpenNebula.is_error?(res)
result=res
header_host_small
res[1].each {|row|
res2=@host.get_host_attributes(row["oid"])
if res2[0]
attributes=res2[1]
attributes.each {|a|
if %w{USEDCPU TOTALMEMORY FREEMEMORY TOTALCPU}.include? a["name"]
row[a["name"]]=a["value"]
end
}
end
res2=@host.get_host_share(row["oid"])
if res2[0]
attributes=res2[1]
attributes.each {|a|
row["hs_running_vms"]=a["running_vms"]
row["hs_max_mem"]=a["max_mem"]
row["hs_max_cpu"]=a["max_cpu"]
row["hs_mem_usage"]=a["mem_usage"]
row["hs_cpu_usage"]=a["cpu_usage"]
}
end
}
puts @table.data_str(result[1], options)
result
else
result=res
result=[true,""]
header_host_small
if options
puts @table.data_str(@hostpool, options)
else
puts @table.data_str(@hostpool)
end
result
end
end
@ -214,28 +199,20 @@ EOT
end
server=ONE::Server.new
$host=host=ONE::Host.new(server)
#$vm=vm=ONE::VM.new(server)
def command_exit(code)
$host.close_db
exit(code)
end
# Returns true if there are non DONE VM's in a host, false otherwise
def vms_in_host?(host)
sql_statement="select history.vid,history.hid,history.seq,vm_pool.state"+
" from history,vm_pool where vm_pool.oid=history.vid and"+
" vm_pool.state<>6 and history.hid=#{host} group by vid"
def vms_in_host?(host_id)
result=$host.get_db.db.execute(sql_statement)
host = OpenNebula::Host.new_with_id(host_id,get_one_client)
if result.length>0
true
else
false
rc = host.info
if OpenNebula::is_error?(rc)
puts rc.message
exit -1
end
host['host_shares/running_vms'].to_i
end
@ -250,76 +227,135 @@ command=ARGV.shift
case command
when "add", "create"
check_parameters("create", 4)
result=host.allocate(*[ARGV[0], ARGV[1], ARGV[2], ARGV[3], "true"])
host=OpenNebula::Host.new(OpenNebula::Host.build_xml, get_one_client)
result=host.allocate(ARGV[0], ARGV[1], ARGV[2], ARGV[3])
if is_successful?(result)
puts "ID: " + host.id.to_s if ops[:verbose]
exit 0
end
when "show"
check_parameters("show", 1)
host_id=get_host_id(host, ARGV[0])
result=host.info(host_id)
if result[0]
puts result[1]
host_id=get_host_id(ARGV[0])
host=OpenNebula::Host.new_with_id(host_id, get_one_client)
result=host.info
if is_successful?(result)
#puts host.template_str
else
puts "Error: "+result[1]
command_exit -1
puts "Error: "+result.message
exit -1
end
if !ops[:xml]
str = "%-22s: %-20s"
str_h1 = "%-80s"
print_header(str_h1, "HOST #{host_id} INFORMATION", true)
puts str % ["ID", host[:id]]
puts str % ["NAME", host[:name]]
puts str % ["STATE", host.state_str]
puts str % ["IM_MAD", host[:im_mad]]
puts str % ["VM_MAD", host[:vm_mad]]
puts str % ["TM_MAD", host[:tm_mad]]
puts
print_header(str_h1, "HOST SHARES", false)
puts str % ["MAX MEM", host['host_share/max_mem']]
puts str % ["USED MEM (REAL)", host['host_share/used_mem']]
puts str % ["USED MEM (ALLOCATED)", host['host_share/mem_usage']]
puts str % ["MAX CPU", host['host_share/max_cpu']]
puts str % ["USED CPU (REAL)", host['host_share/used_cpu']]
puts str % ["USED CPU (ALLOCATED)", host['host_share/cpu_usage']]
puts str % ["RUNNING VMS", host['host_share/running_vms']]
puts
print_header(str_h1, "MONITORING INFORMATION", false)
puts host.template_str
else
puts host.to_xml
end
when "delete"
check_parameters("delete", 1)
host_id=get_host_id(host, ARGV[0])
if vms_in_host?(host_id)
host_id=get_host_id(ARGV[0])
host = OpenNebula::Host.new_with_id(host_id,get_one_client)
rc = host.info
if OpenNebula::is_error?(rc)
puts rc.message
exit -1
end
if host['host_shares/running_vms'].to_i != 0
puts "Host still has associated VMs. It will be disabled instead."
result=host.disable(host_id)
if result[0]
result=host.disable
if is_successful?(result)
puts "Host disabled" if ops[:verbose]
command_exit 0
exit 0
end
else
result=host.delete(host_id)
if result[0]
result=host.delete
if is_successful?(result)
puts "Host deleted" if ops[:verbose]
command_exit 0
exit 0
end
end
when "list"
hostlist=HostShow.new(host)
ops[:columns]=ops[:list] if ops[:list]
result=hostlist.list_short(ops)
hostlist.close
if !ops[:xml]
hostlist=HostShow.new(get_one_client)
ops[:columns]=ops[:list] if ops[:list]
result=hostlist.list_short(ops)
hostlist.close
else
hostpool=OpenNebula::HostPool.new(get_one_client)
hostpool.info
puts hostpool.to_xml
end
when "top"
hostlist=HostShow.new(host)
hostlist=HostShow.new(get_one_client)
ops[:columns]=ops[:list] if ops[:list]
result=hostlist.top(ops)
hostlist.close
when "enable"
check_parameters("enable", 1)
host_id=get_host_id(host, ARGV[0])
result=host.enable(host_id)
if result[0]
host_id=get_host_id(ARGV[0])
host = OpenNebula::Host.new_with_id(host_id,get_one_client)
result=host.enable
if is_successful?(result)
puts "Host enabled" if ops[:verbose]
command_exit 0
exit 0
end
when "disable"
check_parameters("disable", 1)
host_id=get_host_id(host, ARGV[0])
result=host.disable(host_id)
if result[0]
host_id=get_host_id(ARGV[0])
host = OpenNebula::Host.new_with_id(host_id,get_one_client)
result=host.disable
if is_successful?(result)
puts "Host disabled" if ops[:verbose]
command_exit 0
exit 0
end
else
onehost_opts.print_help
command_exit -1
exit -1
end
if !result[0]
puts "Error: " + result[1].to_s
command_exit -1
if is_error?(result)
puts "Error: " + result.message
exit -1
end
command_exit 0
exit 0

203
src/client/ruby/oneuser Executable file
View File

@ -0,0 +1,203 @@
#!/usr/bin/env ruby
# -------------------------------------------------------------------------- #
# Copyright 2002-2009, Distributed Systems Architecture Group, Universidad #
# Complutense de Madrid (dsa-research.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
$: << "./lib"
#require 'one'
require 'OpenNebula'
require 'client_utilities'
require 'command_parse'
ShowTableUP={
:uid => {
:name => "UID",
:desc => "ONE identifier for user",
:size => 4,
:proc => lambda {|d,e| d.id }
},
:name => {
:name => "NAME",
:desc => "name of the user",
:size => 15,
:left => true,
:proc => lambda {|d,e| d.name }
},
:password => {
:name => "PASSWORD",
:desc => "password of the user",
:size => 50,
:left => true,
:proc => lambda {|d,e| d[:password] }
},
:enable => {
:name => "ENABLE",
:desc => "Wether the user is active or not",
:size => 6,
:proc => lambda {|d,e| d[:enabled] }
},
:default => [:uid, :name, :password, :enable]
}
class UPShow
def initialize
@userpool=OpenNebula::UserPool.new(get_one_client)
@table=ShowTable.new(ShowTableUP)
end
def close
end
def header_up_small
scr_bold
scr_underline
print @table.header_str
scr_restore
puts ""
end
def list_short(options=nil)
res=@userpool.info
if options
@table.columns=options[:columns] if options[:columns]
end
if OpenNebula.is_error?(res)
result=res
else
result=res
header_up_small
puts @table.data_str(@userpool, options)
result
end
end
def top(options=nil)
delay=1
delay=options[:delay] if options && options[:delay]
result=nil
begin
while true
scr_cls
scr_move(0,0)
result=list_short(options)
sleep delay
end
rescue Exception
end
result
end
end
class OneUPParse < CommandParse
COMMANDS_HELP=<<-EOT
Commands:
* create (Creates a new user)
oneuser create username password
* delete (Removes a user)
oneuser delete <uid>
* list (Lists virtual networks in the pool)
oneuser list
EOT
def text_commands
COMMANDS_HELP
end
def text_command_name
"oneuser"
end
def list_options
table=ShowTable.new(ShowTableUP)
table.print_help
end
end
oneup_opts=OneUPParse.new
oneup_opts.parse(ARGV)
ops=oneup_opts.options
result=[false, "Unknown error"]
command=ARGV.shift
case command
when "create"
check_parameters("create", 2)
user=OpenNebula::User.new(
OpenNebula::User.build_xml, get_one_client)
sha_password = Digest::SHA1.hexdigest(ARGV[1])
result=user.allocate(ARGV[0],sha_password)
if !OpenNebula.is_error?(result)
puts "UID: " + user.id.to_s if ops[:verbose]
exit 0
end
when "delete"
check_parameters("delete", 1)
user_id=get_user_id(ARGV[0])
user=OpenNebula::User.new(
OpenNebula::User.build_xml(user_id), get_one_client)
result=user.delete
if !OpenNebula.is_error?(result)
puts "User deleted" if ops[:verbose]
exit 0
end
when "list"
if !ops[:xml]
uplist=UPShow.new
ops[:columns]=ops[:list] if ops[:list]
result=uplist.list_short(ops)
uplist.close
else
userpool=OpenNebula::UserPool.new(get_one_client)
userpool.info
puts userpool.to_xml
end
else
oneup_opts.print_help
exit -1
end
if OpenNebula.is_error?(result)
puts "Error: " + result.message
exit -1
end

View File

@ -25,40 +25,56 @@ else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
end
$: << './lib'
$: << RUBY_LIB_LOCATION
require 'one'
#require 'one'
require 'OpenNebula'
require 'client_utilities'
require 'command_parse'
require 'profiler'
ShowTableVM={
:id => {
:name => "ID",
:desc => "ONE identifier for the VM",
:size => 4,
:proc => lambda {|d,e| d["oid"] }
:proc => lambda {|d,e| d.id }
},
:name => {
:name => "NAME",
:desc => "Name of the domain",
:size => 8,
:proc => lambda {|d,e|
tid=d["template_id"]
template=e[:vm].get_template(tid)
template["NAME"]
d.name
}
},
:username => {
:name => "USER",
:desc => "Name of the owner",
:size => 8,
:proc => lambda {|d,e|
d["USERNAME"]
}
},
:stat => {
:name => "STAT",
:desc => "Actual status of the VM",
:size => 4,
:proc => lambda {|d,e| e[:vm].get_state(d) }
:proc => lambda {|d,e|
d.status
}
},
:cpu => {
:name => "CPU",
:desc => "CPU percentage used by the VM",
:size => 3,
:proc => lambda {|d,e| d["cpu"] }
:proc => lambda {|d,e|
d["cpu"]
}
},
:mem => {
:name => "MEM",
@ -70,16 +86,18 @@ ShowTableVM={
:name => "HOSTNAME",
:desc => "Machine where the VM is running",
:size => 15,
:proc => lambda {|d,e| e[:vm].get_history_host(d["oid"]) }
:proc => lambda {|d,e|
d["HISTORY/HOSTNAME"]
}
},
:time => {
:name => "TIME",
:desc => "Time since the VM was submitted",
:size => 11,
:proc => lambda {|d,e| e[:vm].str_running_time(d) }
:proc => lambda {|d,e| str_running_time(d) }
},
:default => [:id, :name, :stat, :cpu, :mem, :hostname, :time]
:default => [:id, :username, :name, :stat, :cpu, :mem, :hostname, :time]
}
ShowTableHistory={
@ -87,7 +105,7 @@ ShowTableHistory={
:name => "ID",
:desc => "ONE identifier for the VM",
:size => 4,
:proc => lambda {|d,e| d["oid"] }
:proc => lambda {|d,e| d["id"] }
},
:seq => {
:name => "SEQ",
@ -127,13 +145,17 @@ ShowTableHistory={
:name => "TIME",
:desc => "Total time",
:size => 11,
:proc => lambda {|d,e| e[:vm].str_running_time(d) }
:proc => lambda {|d,e|
d["time"]
}
},
:reason => {
:name => "REASON",
:desc => "Reason for state change",
:size => "6",
:proc => lambda {|d,e| e[:vm].get_reason(d) }
:proc => lambda {|d,e|
OpenNebula::VirtualMachine.get_reason(d["reason"])
}
},
:default => [:id, :seq, :hostname, :stime, :etime, :time, :reason]
@ -141,10 +163,10 @@ ShowTableHistory={
class VmShow
def initialize(vm)
@vm=vm
@table=ShowTable.new(ShowTableVM, :vm => @vm)
@table_history=ShowTable.new(ShowTableHistory, :vm => @vm)
def initialize(client, filter_flag="-2")
@vmpool=OpenNebula::VirtualMachinePool.new(client, filter_flag.to_i)
@table=ShowTable.new(ShowTableVM)
@table_history=ShowTable.new(ShowTableHistory)
end
def close
@ -167,7 +189,9 @@ class VmShow
end
def print_vm_long(data)
str="%-10s: %-20s"
puts str % ["ID", data["oid"]]
puts str % ["NAME", data["deploy_id"]]
puts str % ["STATE", ONE::VM_STATE[data["state"].to_i]]
@ -175,7 +199,7 @@ class VmShow
puts str % ["MEMORY", data["memory"]]
puts str % ["CPU", data["cpu"]]
puts
puts "Template"
str=" %-20s: %-20s"
data.each {|key,value|
puts str % [key, value] if !%w{oid deploy_id state lcm_state memory cpu template_id}.include? key
@ -183,42 +207,35 @@ class VmShow
end
def list_short(options=nil)
res=@vm.get_vms(:where => "state <> 6")
res=@vmpool.info()
if options
@table.columns=options[:columns] if options[:columns]
end
if res[0]
if OpenNebula.is_error?(res)
result=res
puts res.message
exit -1
else
if options[:filter_flag]
vms=@vmpool.select{|element|
element['USERNAME']==options[:filter_flag] }
else
vms=@vmpool
end
result=[true, ""]
header_vm_small
if options
puts @table.data_str(res[1], options)
else
puts @table.data_str(res[1])
end
result
else
result=res
end
end
def list_long(id)
res=@vm.get(:where => "oid="+id)
if res && res[0] && res[1] && res[1].length>0
result=[true, ""]
res[1].each {|row|
print_vm_long(row)
}
result
else
if res[0]
[false, "VM not found"]
if options
puts @table.data_str(vms, options)
else
result=res
puts @table.data_str(vms)
end
result
end
end
@ -239,47 +256,71 @@ class VmShow
end
result
end
def get_vm_history(vm)
{
'id' => vm.id,
'seq' => vm['history/seq'],
'host_name' => vm['history/hostname'],
'stime' => vm['history/stime'],
'etime' => vm['history/etime'],
'time' => str_running_time(vm),
'reason' => vm['history/reason']
}
end
def get_vms_history(vms)
vms.collect do |vmid|
vm=OpenNebula::VirtualMachine.new_with_id(vmid, get_one_client)
result=vm.info
if is_error?(result)
puts "Error: "+result.message
exit -1
end
get_vm_history(vm)
end
end
def list_vm_history(id, options=nil)
res=@vm.get_history(id)
def list_vm_history(vm, options=nil)
#res=@vm.get_history(id)
if options
@table_history.columns=options[:columns] if options[:columns]
end
if res[0]
result=[true, ""]
header_history_small
if options
puts @table_history.data_str(res[1], options)
else
puts @table_history.data_str(res[1])
end
result
header_history_small
if options
puts @table_history.data_str([vm], options)
else
result=res
puts @table_history.data_str([vm])
end
end
def list_vm_history_array(ids, options=nil)
res=[false, "No VMs found"]
ids.each {|id|
vm_id=get_vm_id(@vm, id)
puts "History for VM #{id}"
get_vms_history(ids).each {|vm|
puts "History for VM #{vm['id']}"
puts
res=list_vm_history(vm_id, options)
list_vm_history(vm, options)
puts
}
res
end
def list_vm_history_all(options=nil)
res=@vm.get
res[1].each {|vm|
list_vm_history_array(vm["oid"], options)
result=@vmpool.info
if is_error?(result)
puts "Error: "+result.message
exit -1
end
@vmpool.each {|vm|
puts "History for VM #{vm.id}"
puts
list_vm_history(get_vm_history(vm), options)
puts
}
res
end
end
@ -331,8 +372,16 @@ Commands:
* delete (Deletes a VM from the pool and DB)
onevm delete <vm_id>
* restart (...)
onevm restart <vm_id>
* list (Shows VMs in the pool)
onevm list
onevm list <filter_flag>
where filter_flag can be
a, all --> all the known VMs
m, mine --> the VMs belonging to the user in ONE_AUTH
uid --> VMs of the user identified by this uid
username --> VMs of the user identified by the username
* show (Gets information about a specific VM)
onevm show <vm_id>
@ -362,17 +411,6 @@ EOT
end
server=ONE::Server.new
$vm=vm=ONE::VM.new(server)
host=ONE::Host.new(server)
def command_exit(code)
$vm.close_db
exit(code)
end
onevm_opts=OnevmParse.new
onevm_opts.parse(ARGV)
ops=onevm_opts.options
@ -384,117 +422,195 @@ command=ARGV.shift
case command
when "submit", "create"
check_parameters("create", 1)
result=vm.allocate(*ARGV)
if result[0]
puts "ID: " + result[1].to_s if ops[:verbose]
command_exit 0
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]}")
end
if is_successful?(result)
puts "ID: " + vm.id.to_s if ops[:verbose]
exit 0
end
when "deploy"
check_parameters("deploy", 2)
vm_id=get_vm_id(vm, ARGV[0])
host_id=get_host_id(host, ARGV[1])
result=vm.deploy(vm_id, host_id)
if result[0]
vm_id=get_vm_id(ARGV[0])
host_id=get_host_id(ARGV[1])
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.deploy(host_id)
if is_successful?(result)
puts "Deploying VM" if ops[:verbose]
command_exit 0
exit 0
end
when "shutdown"
check_parameters("shutdown", 1)
vm_id=get_vm_id(vm, ARGV[0])
result=vm.shutdown(vm_id)
if result[0]
vm_id=get_vm_id(ARGV[0])
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.shutdown
if is_successful?(result)
puts "Shutting down VM" if ops[:verbose]
command_exit 0
exit 0
end
when "livemigrate"
check_parameters("livemigrate", 2)
vm_id=get_vm_id(vm, ARGV[0])
host_id=get_host_id(host, ARGV[1])
result=vm.livemigrate(vm_id, host_id)
if result[0]
vm_id=get_vm_id(ARGV[0])
host_id=get_host_id(ARGV[1])
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.live_migrate(host_id)
if is_successful?(result)
puts "Migrating VM" if ops[:verbose]
command_exit 0
exit 0
end
when "migrate"
check_parameters("migrate", 2)
vm_id=get_vm_id(vm, ARGV[0])
host_id=get_host_id(host, ARGV[1])
result=vm.migrate(vm_id, host_id)
if result[0]
vm_id=get_vm_id(ARGV[0])
host_id=get_host_id(ARGV[1])
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.migrate(host_id)
if is_successful?(result)
puts "Migrating VM" if ops[:verbose]
command_exit 0
exit 0
end
when "hold"
check_parameters("hold", 1)
vm_id=get_vm_id(vm, ARGV[0])
result=vm.hold(vm_id)
if result[0]
vm_id=get_vm_id(ARGV[0])
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.hold
if is_successful?(result)
puts "Setting VM to hold state" if ops[:verbose]
command_exit 0
exit 0
end
when "release"
check_parameters("release", 1)
vm_id=get_vm_id(vm, ARGV[0])
result=vm.release(vm_id)
if result[0]
vm_id=get_vm_id(ARGV[0])
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.release
if is_successful?(result)
puts "Releasing VM" if ops[:verbose]
command_exit 0
exit 0
end
when "stop"
check_parameters("stop", 1)
vm_id=get_vm_id(vm, ARGV[0])
result=vm.stop(vm_id)
if result[0]
vm_id=get_vm_id(ARGV[0])
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.stop
if is_successful?(result)
puts "Stopping VM" if ops[:verbose]
command_exit 0
exit 0
end
when "cancel"
check_parameters("cancel", 1)
result=vm.cancel(*ARGV)
if result[0]
vm_id=get_vm_id(ARGV[0])
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.cancel
if is_successful?(result)
puts "Cancelling VM" if ops[:verbose]
command_exit 0
exit 0
end
when "suspend"
check_parameters("suspend", 1)
vm_id=get_vm_id(vm, ARGV[0])
result=vm.suspend(vm_id)
if result[0]
vm_id=get_vm_id(ARGV[0])
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.suspend
if is_successful?(result)
puts "Suspending VM" if ops[:verbose]
command_exit 0
exit 0
end
when "resume"
check_parameters("resume", 1)
vm_id=get_vm_id(vm, ARGV[0])
result=vm.resume(vm_id)
if result[0]
vm_id=get_vm_id(ARGV[0])
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.resume
if is_successful?(result)
puts "Resuming VM" if ops[:verbose]
command_exit 0
exit 0
end
when "restart"
check_parameters("restart")
vm_id=get_vm_id(ARGV[0])
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.restart
if is_successful?(result)
puts "Restarting VM" if ops[:verbose]
exit 0
end
when "list"
vmlist=VmShow.new(vm)
ops[:columns]=ops[:list] if ops[:list]
result=vmlist.list_short(ops)
vmlist.close
if ARGV[0]
case ARGV[0]
when "a", "all"
filter_flag="-2"
when "m", "mine"
filter_flag="-1"
else
if !ARGV[0].match(/^[0123456789]+$/)
filter_flag="-2"
ops[:filter_flag]=ARGV[0]
else
filter_flag=ARGV[0]
end
end
else
filter_flag="-2"
end
if !ops[:xml]
vmlist=VmShow.new(get_one_client, filter_flag)
ops[:columns]=ops[:list] if ops[:list]
result=vmlist.list_short(ops)
vmlist.close
else
vmpool=OpenNebula::VirtualMachinePool.new(get_one_client,
filter_flag.to_i)
vmpool.info
puts vmpool.to_xml
end
when "top"
vmlist=VmShow.new(vm)
vmlist=VmShow.new(get_one_client)
ops[:columns]=ops[:list] if ops[:list]
result=vmlist.top(ops)
vmlist.close
when "show_db"
# TODO: delete?
check_parameters("show", 1)
vmlist=VmShow.new(vm)
@ -508,10 +624,11 @@ when "show_db"
end
when "history"
vmlist=VmShow.new(vm)
# TODO: change this to new API
vmlist=VmShow.new(get_one_client)
ops[:columns]=ops[:list] if ops[:list]
if ARGV[0]
ids=ARGV.collect {|arg| get_vm_id(vm, arg)}
ids=ARGV.collect {|arg| get_vm_id(arg)}
ids=ids.flatten.compact
result=vmlist.list_vm_history_array(ids)
else
@ -521,16 +638,65 @@ when "history"
when "delete"
check_parameters("delete", 1)
vm_id=get_vm_id(vm, ARGV[0])
result=vm.delete(vm_id)
if result[0]
vm_id=get_vm_id(ARGV[0])
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
result=vm.finalize
if is_successful?(result)
puts "VM correctly deleted" if ops[:verbose]
command_exit 0
exit 0
end
when "show"
check_parameters("get_info", 1)
vm_id=get_vm_id(vm, ARGV[0])
# TODO: change this to the new API
check_parameters("get_info", 1)
vm_id=get_vm_id(ARGV[0])
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
vm.info
if !ops[:xml]
str="%-15s: %-20s"
str_h1="%-80s"
print_header(str_h1, "VIRTUAL MACHINE #{vm[:id]} INFORMATION", true)
puts str % ["ID", vm[:id]]
puts str % ["NAME", vm[:name]]
puts str % ["STATE", vm.state_str]
puts str % ["LCM_STATE", vm.lcm_state_str]
value=vm[:stime].to_i
if value==0
value='-'
else
value=Time.at(value).strftime("%m/%d %H:%M:%S")
end
puts str % ["START TIME", value]
value=vm[:etime].to_i
if value==0
value='-'
else
value=Time.at(value).strftime("%m/%d %H:%M:%S")
end
puts str % ["END TIME", value]
value=vm[:deploy_id]
puts str % ["DEPLOY ID:", value=="" ? "-" : value]
puts
print_header(str_h1,"VIRTUAL MACHINE TEMPLATE",false)
puts vm.template_str
else
puts vm.to_xml
end
=begin
result = res = vm.get_info(vm_id)
if res[0]
res[1].gsub!(/^\n/, '')
@ -564,18 +730,21 @@ when "show"
command_exit 0
end
=end
else
onevm_opts.print_help
command_exit -1
exit -1
end
if !result[0]
puts "Error: " + result[1].to_s
command_exit -1
if OpenNebula.is_error?(result)
puts "Error: " + result.message
exit -1
end
command_exit 0
#command_exit 0

View File

@ -27,7 +27,10 @@ end
$: << RUBY_LIB_LOCATION
require 'one'
$: << "./lib"
#require 'one'
require 'OpenNebula'
require 'client_utilities'
require 'command_parse'
@ -36,14 +39,21 @@ ShowTableVN={
:name => "NID",
:desc => "ONE identifier for virtual network",
:size => 4,
:proc => lambda {|d,e| d["oid"] }
:proc => lambda {|d,e| d.id }
},
:name => {
:name => "NAME",
:desc => "name of the virtual network",
:size => 15,
:left => true,
:proc => lambda {|d,e| d["name"] }
:proc => lambda {|d,e| d.name }
},
:username => {
:name => "USER",
:desc => "Username of the virtual network owner",
:size => 8,
:left => true,
:proc => lambda {|d,e| d["USERNAME"] }
},
:type => {
:name => "TYPE",
@ -71,15 +81,20 @@ ShowTableVN={
:size => 6,
:proc => lambda {|d,e| d["bridge"] }
},
:totalleases => {
:name => "#LEASES",
:desc => "Number of this virtual network's given leases",
:size => 7,
:proc => lambda {|d,e| d["TOTAL_LEASES"] }
},
:default => [:nid, :name, :type, :bridge]
:default => [:nid, :username, :name, :type, :bridge, :totalleases]
}
class VNShow
def initialize(vn)
@vn=vn
@table=ShowTable.new(ShowTableVN, :vn => @vn)
def initialize(filter_flag="-2")
@vnpool=OpenNebula::VirtualNetworkPool.new(get_one_client,filter_flag.to_i)
@table=ShowTable.new(ShowTableVN)
end
def close
@ -94,29 +109,25 @@ class VNShow
end
def list_short(options=nil)
res=@vn.get
res=@vnpool.info
if options
@table.columns=options[:columns] if options[:columns]
end
if res[0]
if OpenNebula.is_error?(res)
result=res
header_vn_small
res[1].each {|row|
res2=@vn.get_vn_attributes(row["oid"])
if res2[0]
attributes=res2[1]
attributes.each {|a|
if %w{SIZE}.include? a["name"]
row[a["name"]]=a["value"]
end
}
end
}
puts @table.data_str(result[1], options)
result
else
result=res
header_vn_small
if options[:filter_flag]
vns=@vnpool.select{|element|
element["USERNAME"]==options[:filter_flag]
}
else
vns=@vnpool
end
puts @table.data_str(vns, options)
result
end
end
@ -156,8 +167,12 @@ Commands:
onevnet delete <network_id>
* list (Lists virtual networks in the pool)
onevnet list
onevnet list <filter_flag>
where filter_flag can be
a, all --> all the known VNs
m, mine --> the VNs belonging to the user in ONE_AUTH
uid --> VNs of the user identified by this uid
username --> VNs of the user identified by the username
EOT
def text_commands
@ -175,9 +190,6 @@ EOT
end
server=ONE::Server.new
vn=ONE::VN.new(server)
onevn_opts=OneVNParse.new
onevn_opts.parse(ARGV)
ops=onevn_opts.options
@ -189,44 +201,97 @@ command=ARGV.shift
case command
when "create"
check_parameters("create", 1)
result=vn.allocate(*ARGV)
if result[0]
puts "NID: " + result[1].to_s if ops[:verbose]
vn=OpenNebula::VirtualNetwork.new(
OpenNebula::VirtualNetwork.build_xml, get_one_client)
template=File.read(ARGV[0])
result=vn.allocate(template)
if !OpenNebula.is_error?(result)
puts "NID: " + vn.id.to_s if ops[:verbose]
exit 0
end
when "show"
check_parameters("show", 1)
vn_id=get_vn_id(vn, ARGV[0])
result=vn.info(vn_id)
if result[0]
puts result[1]
vn_id=get_vn_id(ARGV[0])
vn=OpenNebula::VirtualNetwork.new_with_id(vn_id, get_one_client)
result=vn.info
if is_successful?(result)
if !ops[:xml]
str_h1="%-80s"
str="%-10s: %-20s"
print_header(str_h1,
"VIRTUAL NETWORK #{vn.id.to_s} INFORMATION",true)
puts str % ["ID: ",vn.id.to_s]
puts str % ["UID: ",vn["UID"]]
puts
print_header(str_h1,"VIRTUAL NETWORK TEMPLATE",false)
puts vn.template_str(false)
leases_str = vn.template_like_str('/VNET/LEASES', false)
if !leases_str.empty?
puts
print_header(str_h1,"LEASES INFORMATION",false)
puts leases_str
end
else
puts vn.to_xml
end
else
puts "Error: "+result[1]
puts "Error: "+result.message
exit -1
end
when "delete"
check_parameters("delete", 1)
vn_id=get_vn_id(vn, ARGV[0])
result=vn.delete(vn_id)
if result[0]
vn_id=get_vn_id(ARGV[0])
vn=OpenNebula::VirtualNetwork.new(
OpenNebula::VirtualNetwork.build_xml(vn_id), get_one_client)
result=vn.delete
if !OpenNebula.is_error?(result)
puts "Virtual Network deleted" if ops[:verbose]
exit 0
end
when "list"
vnlist=VNShow.new(vn)
ops[:columns]=ops[:list] if ops[:list]
result=vnlist.list_short(ops)
vnlist.close
if ARGV[0]
case ARGV[0]
when "a", "all"
filter_flag="-2"
when "m", "mine"
filter_flag="-1"
else
if !ARGV[0].match(/^[0123456789]+$/)
filter_flag="-2"
ops[:filter_flag]=ARGV[0]
else
filter_flag=ARGV[0]
end
end
else
filter_flag="-2"
end
if !ops[:xml]
vnlist=VNShow.new(filter_flag)
ops[:columns]=ops[:list] if ops[:list]
result=vnlist.list_short(ops)
vnlist.close
else
vnpool=OpenNebula::VirtualNetworkPool.new(get_one_client,
filter_flag.to_i)
vnpool.info
puts vnpool.to_xml
end
else
onevn_opts.print_help
exit -1
end
if !result[0]
puts "Error: " + result[1].to_s
if OpenNebula.is_error?(result)
puts "Error: " + result.message
exit -1
end

View File

@ -505,8 +505,7 @@ error:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::finalize(
int vid)
int DispatchManager::restart(int vid)
{
VirtualMachine * vm;
ostringstream oss;
@ -518,31 +517,30 @@ int DispatchManager::finalize(
return -1;
}
if (vm->get_state() != VirtualMachine::ACTIVE &&
vm->get_state() != VirtualMachine::DONE )
oss << "Restarting VM " << vid;
Nebula::log("DiM",Log::DEBUG,oss);
if (vm->get_state() == VirtualMachine::ACTIVE &&
(vm->get_lcm_state() == VirtualMachine::UNKNOWN ||
vm->get_lcm_state() == VirtualMachine::BOOT))
{
oss << "Finalizing VM " << vid;
Nebula::log("DiM",Log::DEBUG,oss);
Nebula& nd = Nebula::instance();
LifeCycleManager * lcm = nd.get_lcm();
vm->set_state(VirtualMachine::LCM_INIT);
vm->set_state(VirtualMachine::DONE);
vm->set_exit_time(time(0));
vmpool->update(vm);
vm->log("DiM", Log::INFO, "New VM state is DONE.");
vm->release_network_leases();
vmpool->remove(vm);
return 0;
lcm->trigger(LifeCycleManager::RESTART,vid);
}
else
{
goto error;
}
vm->unlock();
return 0;
error:
oss.str("");
oss << "Could not finalize VM " << vid << ", wrong state.";
oss << "Could not restart VM " << vid << ", wrong state.";
Nebula::log("DiM",Log::ERROR,oss);
vm->unlock();
@ -552,3 +550,60 @@ int DispatchManager::finalize(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::finalize(
int vid)
{
VirtualMachine * vm;
ostringstream oss;
VirtualMachine::VmState state;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return -1;
}
state = vm->get_state();
oss << "Finalizing VM " << vid;
Nebula::log("DiM",Log::DEBUG,oss);
Nebula& nd = Nebula::instance();
TransferManager * tm = nd.get_tm();
LifeCycleManager * lcm = nd.get_lcm();
switch (state)
{
case VirtualMachine::SUSPENDED:
tm->trigger(TransferManager::EPILOG_DELETE,vid);
case VirtualMachine::INIT:
case VirtualMachine::PENDING:
case VirtualMachine::HOLD:
case VirtualMachine::STOPPED:
vm->set_exit_time(time(0));
case VirtualMachine::FAILED:
vm->set_state(VirtualMachine::LCM_INIT);
vm->set_state(VirtualMachine::DONE);
vmpool->update(vm);
vm->release_network_leases();
vm->log("DiM", Log::INFO, "New VM state is DONE.");
break;
case VirtualMachine::ACTIVE:
lcm->trigger(LifeCycleManager::DELETE,vid);
break;
case VirtualMachine::DONE:
break;
}
vm->unlock();
return 0;
}

View File

@ -41,21 +41,16 @@ void DispatchManager::suspend_success_action(int vid)
}
else
{
goto error;
ostringstream oss;
oss << "suspend_success action received but VM " << vid
<< " not in ACTIVE state";
Nebula::log("DiM",Log::ERROR,oss);
}
vm->unlock();
return;
error:
ostringstream oss;
oss << "suspend_success action received but VM " << vid
<< " not in ACTIVE state";
Nebula::log("DiM",Log::ERROR,oss);
vm->unlock();
}
/* -------------------------------------------------------------------------- */
@ -84,21 +79,16 @@ void DispatchManager::stop_success_action(int vid)
}
else
{
goto error;
ostringstream oss;
oss << "stop_success action received but VM " << vid
<< " not in ACTIVE state";
Nebula::log("DiM",Log::ERROR,oss);
}
vm->unlock();
return;
error:
ostringstream oss;
oss << "stop_success action received but VM " << vid
<< " not in ACTIVE state";
Nebula::log("DiM",Log::ERROR,oss);
vm->unlock();
}
/* -------------------------------------------------------------------------- */
@ -128,23 +118,18 @@ void DispatchManager::done_action(int vid)
vm->log("DiM", Log::INFO, "New VM state is DONE");
vm->release_network_leases();
vmpool->remove(vm);
}
else
{
goto error;
ostringstream oss;
oss << "done action received but VM " << vid << " not in ACTIVE state";
Nebula::log("DiM",Log::ERROR,oss);
}
return;
error:
ostringstream oss;
oss << "done action received but VM " << vid << " not in ACTIVE state";
Nebula::log("DiM",Log::ERROR,oss);
vm->unlock();
return;
}
/* -------------------------------------------------------------------------- */
@ -178,3 +163,4 @@ void DispatchManager::failed_action(int vid)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -32,8 +32,7 @@ Host::Host(
string _hostname,
string _im_mad_name,
string _vmm_mad_name,
string _tm_mad_name,
bool _managed):
string _tm_mad_name):
PoolObjectSQL(id),
hostname(_hostname),
state(INIT),
@ -41,9 +40,8 @@ Host::Host(
vmm_mad_name(_vmm_mad_name),
tm_mad_name(_tm_mad_name),
last_monitored(time(0)),
managed(_managed),
host_template(id),
host_share(id){};
host_template(id)
{};
Host::~Host(){};
@ -55,43 +53,39 @@ Host::~Host(){};
const char * Host::table = "host_pool";
const char * Host::db_names = "(oid,host_name,state,im_mad,vm_mad,"
"tm_mad,last_mon_time,managed)";
"tm_mad,last_mon_time)";
const char * Host::db_bootstrap = "CREATE TABLE host_pool ("
"oid INTEGER PRIMARY KEY,host_name TEXT,state INTEGER,"
"im_mad TEXT,vm_mad TEXT,tm_mad TEXT,last_mon_time INTEGER,"
"managed INTEGER)";
"im_mad TEXT,vm_mad TEXT,tm_mad TEXT,last_mon_time INTEGER)";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Host::unmarshall(int num, char **names, char ** values)
{
if ((values[OID] == 0) ||
(values[HOST_NAME] == 0) ||
(values[STATE] == 0) ||
(values[IM_MAD] == 0) ||
(values[VM_MAD] == 0) ||
(values[TM_MAD] == 0) ||
(values[LAST_MON_TIME] == 0) ||
(values[MANAGED] == 0) ||
(num != LIMIT ))
if ((!values[OID]) ||
(!values[HOST_NAME]) ||
(!values[STATE]) ||
(!values[IM_MAD]) ||
(!values[VM_MAD]) ||
(!values[TM_MAD]) ||
(!values[LAST_MON_TIME]) ||
(num != LIMIT ))
{
return -1;
}
oid = atoi(values[OID]);
hostname = values[HOST_NAME];
state = static_cast<HostState>(atoi(values[STATE]));
oid = atoi(values[OID]);
hostname = values[HOST_NAME];
state = static_cast<HostState>(atoi(values[STATE]));
im_mad_name = values[IM_MAD];
vmm_mad_name = values[VM_MAD];
tm_mad_name = values[TM_MAD];
last_monitored = static_cast<time_t>(atoi(values[LAST_MON_TIME]));
managed = atoi(values[MANAGED]) == 1?true:false;
im_mad_name = values[IM_MAD];
vmm_mad_name = values[VM_MAD];
tm_mad_name = values[TM_MAD];
last_monitored = static_cast<time_t>(atoi(values[LAST_MON_TIME]));
host_template.id = oid;
host_share.hsid = oid;
@ -154,8 +148,8 @@ int Host::select(SqliteDB *db)
if ( rc != 0 )
{
return rc;
}
return rc;
}
return 0;
}
@ -201,14 +195,13 @@ int Host::update(SqliteDB *db)
ostringstream oss;
int rc;
int managed_i = managed?1:0;
char * sql_hostname;
char * sql_im_mad_name;
char * sql_tm_mad_name;
char * sql_vmm_mad_name;
//Update template.
// Update the Template
rc = host_template.update(db);
@ -217,7 +210,7 @@ int Host::update(SqliteDB *db)
return rc;
}
// Let's get the HostShares before the host
// Update the HostShare
rc = host_share.update(db);
@ -226,6 +219,8 @@ int Host::update(SqliteDB *db)
return rc;
}
// Update the Host
sql_hostname = sqlite3_mprintf("%q",hostname.c_str());
if ( sql_hostname == 0 )
@ -253,17 +248,17 @@ int Host::update(SqliteDB *db)
{
goto error_vmm;
}
// Construct the SQL statement to Insert or Replace (effectively, update)
oss << "INSERT OR REPLACE INTO " << table << " "<< db_names <<" VALUES ("<<
oid << "," <<
"'" << sql_hostname << "'," <<
state << "," <<
"'" << sql_im_mad_name << "'," <<
"'" << sql_vmm_mad_name << "'," <<
"'" << sql_tm_mad_name << "'," <<
last_monitored << "," <<
managed_i << ")";
oss << "INSERT OR REPLACE INTO " << table << " "<< db_names <<" VALUES ("
<< oid << ","
<< "'" << sql_hostname << "',"
<< state << ","
<< "'" << sql_im_mad_name << "',"
<< "'" << sql_vmm_mad_name << "',"
<< "'" << sql_tm_mad_name << "',"
<< last_monitored << ")";
rc = db->exec(oss);
@ -287,11 +282,87 @@ error_hostname:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Host::unmarshall(ostringstream& oss,
int num,
char ** names,
char ** values)
{
if ((!values[OID]) ||
(!values[HOST_NAME]) ||
(!values[STATE]) ||
(!values[IM_MAD]) ||
(!values[VM_MAD]) ||
(!values[TM_MAD]) ||
(!values[LAST_MON_TIME]) ||
(num != LIMIT + HostShare::LIMIT ))
{
return -1;
}
oss <<
"<HOST>" <<
"<ID>" << values[OID] <<"</ID>" <<
"<NAME>" << values[HOST_NAME] <<"</NAME>" <<
"<STATE>" << values[STATE] <<"</STATE>" <<
"<IM_MAD>" << values[IM_MAD] <<"</IM_MAD>" <<
"<VM_MAD>" << values[VM_MAD] <<"</VM_MAD>" <<
"<TM_MAD>" << values[TM_MAD] <<"</TM_MAD>" <<
"<LAST_MON_TIME>"<< values[LAST_MON_TIME]<<"</LAST_MON_TIME>";
HostShare::unmarshall(oss,num - LIMIT, names + LIMIT, values + LIMIT);
oss << "</HOST>";
return 0;
}
/* -------------------------------------------------------------------------- */
extern "C" int host_dump_cb (
void * _oss,
int num,
char ** values,
char ** names)
{
ostringstream * oss;
oss = static_cast<ostringstream *>(_oss);
if (oss == 0)
{
return -1;
}
return Host::unmarshall(*oss,num,names,values);
};
/* -------------------------------------------------------------------------- */
int Host::dump(SqliteDB * db, ostringstream& oss, const string& where)
{
int rc;
ostringstream cmd;
cmd << "SELECT * FROM " << Host::table << "," << HostShare::table
<< " ON " << Host::table << ".oid = " << HostShare::table << ".hid";
if ( !where.empty() )
{
cmd << " WHERE " << where;
}
rc = db->exec(cmd,host_dump_cb,(void *) &oss);
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Host::drop(SqliteDB * db)
{
ostringstream oss;
map<int,HostShare *>::iterator iter;
// First, drop the template
host_template.drop(db);
@ -312,23 +383,26 @@ int Host::update_info(string &parse_str)
{
char * error_msg;
int rc;
// If we have a default
rc = host_template.parse(parse_str, &error_msg);
if ( rc != 0 )
{
/*
Nebula::log("ONE", Log::ERROR, error_msg);
*/
//Nebula::log("ONE", Log::ERROR, error_msg);
free(error_msg);
return -1;
}
get_template_attribute("TOTALCPU",host_share.max_cpu);
get_template_attribute("TOTALMEMORY",host_share.max_mem);
get_template_attribute("FREECPU",host_share.free_cpu);
get_template_attribute("FREEMEMORY",host_share.free_mem);
get_template_attribute("USEDCPU",host_share.used_cpu);
get_template_attribute("USEDMEMORY",host_share.used_mem);
return 0;
}
@ -338,18 +412,68 @@ int Host::update_info(string &parse_str)
ostream& operator<<(ostream& os, Host& host)
{
os << "HID = " << host.oid << endl;
os << "HOSTNAME = " << host.hostname << endl;
os << "IM MAD = " << host.im_mad_name << endl;
os << "VMM MAD = " << host.vmm_mad_name << endl;
os << "TM MAD = " << host.tm_mad_name << endl;
os << "MANAGED = " << host.managed << endl;
os << "ATTRIBUTES" << endl << host.host_template<< endl;
os << "HOST SHARES" << endl << host.host_share <<endl;
string host_str;
os << host.to_xml(host_str);
return os;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& Host::to_xml(string& xml) const
{
string template_xml;
string share_xml;
ostringstream oss;
oss <<
"<HOST>"
"<ID>" << oid << "</ID>" <<
"<NAME>" << hostname << "</NAME>" <<
"<STATE>" << state << "</STATE>" <<
"<IM_MAD>" << im_mad_name << "</IM_MAD>" <<
"<VM_MAD>" << vmm_mad_name << "</VM_MAD>" <<
"<TM_MAD>" << tm_mad_name << "</TM_MAD>" <<
"<LAST_MON_TIME>" << last_monitored << "</LAST_MON_TIME>" <<
host_share.to_xml(share_xml) <<
host_template.to_xml(template_xml) <<
"</HOST>";
xml = oss.str();
return xml;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& Host::to_str(string& str) const
{
string template_str;
string share_str;
ostringstream os;
os <<
"ID = " << oid << endl <<
"NAME = " << hostname << endl <<
"STATE = " << state << endl <<
"IM MAD = " << im_mad_name << endl <<
"VMM MAD = " << vmm_mad_name << endl <<
"TM MAD = " << tm_mad_name << endl <<
"LAST_MON = " << last_monitored << endl <<
"ATTRIBUTES" << endl << host_template.to_str(template_str) << endl <<
"HOST SHARES" << endl << host_share.to_str(share_str) <<endl;
str = os.str();
return str;
}
/* ************************************************************************** */
/* Host :: Parse functions to compute rank and evaluate requirements */
/* ************************************************************************** */

View File

@ -27,8 +27,7 @@ int HostPool::allocate (
string hostname,
string im_mad_name,
string vmm_mad_name,
string tm_mad_name,
bool managed)
string tm_mad_name)
{
Host * host;
@ -38,8 +37,7 @@ int HostPool::allocate (
hostname,
im_mad_name,
vmm_mad_name,
tm_mad_name,
managed);
tm_mad_name);
// Insert the Object in the pool

View File

@ -34,16 +34,20 @@ HostShare::HostShare(
int _max_cpu):
ObjectSQL(),
hsid(_hsid),
endpoint(""),
disk_usage(0),
mem_usage(0),
cpu_usage(0),
max_disk(_max_disk),
max_mem(_max_mem),
max_cpu(_max_cpu),
free_disk(0),
free_mem(0),
free_cpu(0),
used_disk(0),
used_mem(0),
used_cpu(0),
running_vms(0)
{
}
/* ************************************************************************** */
@ -52,42 +56,64 @@ HostShare::HostShare(
const char * HostShare::table = "host_shares";
const char * HostShare::db_names = "(hid,endpoint,disk_usage,"
"mem_usage,cpu_usage,max_disk,max_mem,max_cpu,running_vms)";
const char * HostShare::db_names = "(hid,"
"disk_usage, mem_usage, cpu_usage,"
"max_disk, max_mem, max_cpu,"
"free_disk, free_mem, free_cpu,"
"used_disk, used_mem, used_cpu,"
"running_vms)";
const char * HostShare::db_bootstrap = "CREATE TABLE host_shares ("
"hid INTEGER PRIMARY KEY, endpoint TEXT,"
"disk_usage INTEGER,mem_usage INTEGER,cpu_usage INTEGER,"
"max_disk INTEGER,max_mem INTEGER,max_cpu INTEGER,running_vms INTEGER)";
"hid INTEGER PRIMARY KEY,"
"disk_usage INTEGER, mem_usage INTEGER, cpu_usage INTEGER,"
"max_disk INTEGER, max_mem INTEGER, max_cpu INTEGER,"
"free_disk INTEGER, free_mem INTEGER, free_cpu INTEGER,"
"used_disk INTEGER, used_mem INTEGER, used_cpu INTEGER,"
"running_vms INTEGER)";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int HostShare::unmarshall(int num, char **names, char ** values)
{
if ((values[HID] == 0) ||
(values[ENDPOINT] == 0) ||
(values[DISK_USAGE] == 0) ||
(values[MEM_USAGE] == 0) ||
(values[CPU_USAGE] == 0) ||
(values[MAX_DISK] == 0) ||
(values[MAX_MEMORY] == 0) ||
(values[MAX_CPU] == 0) ||
(values[RUNNING_VMS] == 0) ||
if ((!values[HID]) ||
(!values[DISK_USAGE]) ||
(!values[MEM_USAGE]) ||
(!values[CPU_USAGE]) ||
(!values[MAX_DISK]) ||
(!values[MAX_MEMORY]) ||
(!values[MAX_CPU]) ||
(!values[FREE_DISK]) ||
(!values[FREE_MEMORY]) ||
(!values[FREE_CPU]) ||
(!values[USED_DISK]) ||
(!values[USED_MEMORY]) ||
(!values[USED_CPU]) ||
(!values[RUNNING_VMS]) ||
(num != LIMIT ))
{
return -1;
}
hsid = atoi(values[HID]);
endpoint = values[ENDPOINT];
hsid = atoi(values[HID]);
disk_usage = atoi(values[DISK_USAGE]);
mem_usage = atoi(values[MEM_USAGE]);
cpu_usage = atoi(values[CPU_USAGE]);
max_disk = atoi(values[MAX_DISK]);
max_mem = atoi(values[MAX_MEMORY]);
max_cpu = atoi(values[MAX_CPU]);
running_vms= atoi(values[RUNNING_VMS]);
max_disk = atoi(values[MAX_DISK]);
max_mem = atoi(values[MAX_MEMORY]);
max_cpu = atoi(values[MAX_CPU]);
free_disk = atoi(values[FREE_DISK]);
free_mem = atoi(values[FREE_MEMORY]);
free_cpu = atoi(values[FREE_CPU]);
used_disk = atoi(values[USED_DISK]);
used_mem = atoi(values[USED_MEMORY]);
used_cpu = atoi(values[USED_CPU]);
running_vms = atoi(values[RUNNING_VMS]);
return 0;
}
@ -95,6 +121,54 @@ int HostShare::unmarshall(int num, char **names, char ** values)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int HostShare::unmarshall(ostringstream& oss,
int num,
char ** names,
char ** values)
{
if ((!values[HID]) ||
(!values[DISK_USAGE]) ||
(!values[MEM_USAGE]) ||
(!values[CPU_USAGE]) ||
(!values[MAX_DISK]) ||
(!values[MAX_MEMORY]) ||
(!values[MAX_CPU]) ||
(!values[FREE_DISK]) ||
(!values[FREE_MEMORY]) ||
(!values[FREE_CPU]) ||
(!values[USED_DISK]) ||
(!values[USED_MEMORY]) ||
(!values[USED_CPU]) ||
(!values[RUNNING_VMS]) ||
(num != LIMIT))
{
return -1;
}
oss <<
"<HOST_SHARE>" <<
"<HID>" << values[HID] << "</HID>" <<
"<DISK_USAGE>"<< values[DISK_USAGE] << "</DISK_USAGE>"<<
"<MEM_USAGE>" << values[MEM_USAGE] << "</MEM_USAGE>" <<
"<CPU_USAGE>" << values[CPU_USAGE] << "</CPU_USAGE>" <<
"<MAX_DISK>" << values[MAX_DISK] << "</MAX_DISK>" <<
"<MAX_MEM>" << values[MAX_MEMORY] << "</MAX_MEM>" <<
"<MAX_CPU>" << values[MAX_CPU] << "</MAX_CPU>" <<
"<FREE_DISK>" << values[FREE_DISK] << "</FREE_DISK>" <<
"<FREE_MEM>" << values[FREE_MEMORY] << "</FREE_MEM>" <<
"<FREE_CPU>" << values[FREE_CPU] << "</FREE_CPU>" <<
"<USED_DISK>" << values[USED_DISK] << "</USED_DISK>" <<
"<USED_MEM>" << values[USED_MEMORY] << "</USED_MEM>" <<
"<USED_CPU>" << values[USED_CPU] << "</USED_CPU>" <<
"<RUNNING_VMS>"<<values[RUNNING_VMS] << "</RUNNING_VMS>"<<
"</HOST_SHARE>";
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
extern "C" int host_share_select_cb (
void * _hs,
int num,
@ -143,7 +217,6 @@ int HostShare::insert(SqliteDB * db)
{
int rc;
//Insert the HostShare
rc = update(db);
if ( rc != 0 )
@ -161,17 +234,14 @@ int HostShare::update(SqliteDB * db)
{
ostringstream oss;
int rc;
oss << "INSERT OR REPLACE INTO " << table << " "<< db_names <<" VALUES ("<<
hsid << "," <<
"'" << endpoint << "'," <<
disk_usage << "," <<
mem_usage << "," <<
cpu_usage << "," <<
max_disk << "," <<
max_mem << "," <<
max_cpu << "," <<
running_vms << ")";
oss << "INSERT OR REPLACE INTO " << table << " "<< db_names <<" VALUES ("
<< hsid << ","
<< disk_usage <<","<< mem_usage <<","<< cpu_usage<< ","
<< max_disk <<","<< max_mem <<","<< max_cpu << ","
<< free_disk <<","<< free_mem <<","<< free_cpu << ","
<< used_disk <<","<< used_mem <<","<< used_cpu << ","
<< running_vms<< ")";
rc = db->exec(oss);
@ -185,7 +255,6 @@ int HostShare::drop(SqliteDB * db)
{
ostringstream oss;
// Drop the HostShare itself
oss << "DELETE FROM " << table << " WHERE hid=" << hsid;
return db->exec(oss);
@ -197,18 +266,70 @@ int HostShare::drop(SqliteDB * db)
ostream& operator<<(ostream& os, HostShare& hs)
{
os << "\tHID = " << hs.hsid << endl;
os << "\tENDPOINT = " << hs.endpoint<< endl;
os << "\tMAX_CPU = " << hs.max_cpu << endl;
os << "\tMAX_MEMORY = " << hs.max_mem << endl;
os << "\tMAX_DISK = " << hs.max_disk<< endl;
string str;
os << "\tCPU_USAGE = " << hs.cpu_usage << endl;
os << "\tMEMORY_USAGE = " << hs.mem_usage << endl;
os << "\tDISK_USAGE = " << hs.disk_usage<< endl;
os << "\tRUNNING_VMS = " << hs.running_vms<< endl;
os << hs.to_xml(str);
return os;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& HostShare::to_xml(string& xml) const
{
string template_xml;
ostringstream oss;
oss << "<HOST_SHARE>"
<< "<HID>" << hsid << "</HID>"
<< "<DISK_USAGE>" << disk_usage << "</DISK_USAGE>"
<< "<MEM_USAGE>" << mem_usage << "</MEM_USAGE>"
<< "<CPU_USAGE>" << cpu_usage << "</CPU_USAGE>"
<< "<MAX_DISK>" << max_disk << "</MAX_DISK>"
<< "<MAX_MEM>" << max_mem << "</MAX_MEM>"
<< "<MAX_CPU>" << max_cpu << "</MAX_CPU>"
<< "<FREE_DISK>" << free_disk << "</FREE_DISK>"
<< "<FREE_MEM>" << free_mem << "</FREE_MEM>"
<< "<FREE_CPU>" << free_cpu << "</FREE_CPU>"
<< "<USED_DISK>" << used_disk << "</USED_DISK>"
<< "<USED_MEM>" << used_mem << "</USED_MEM>"
<< "<USED_CPU>" << used_cpu << "</USED_CPU>"
<< "<RUNNING_VMS>"<<running_vms <<"</RUNNING_VMS>"
<< "</HOST_SHARE>";
xml = oss.str();
return xml;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& HostShare::to_str(string& str) const
{
string template_xml;
ostringstream oss;
oss<< "\tHID = " << hsid
<< "\tCPU_USAGE = " << cpu_usage << endl
<< "\tMEMORY_USAGE = " << mem_usage << endl
<< "\tDISK_USAGE = " << disk_usage<< endl
<< "\tMAX_CPU = " << max_cpu << endl
<< "\tMAX_MEMORY = " << max_mem << endl
<< "\tMAX_DISK = " << max_disk<< endl
<< "\tFREE_CPU = " << free_cpu << endl
<< "\tFREE_MEMORY = " << free_mem << endl
<< "\tFREE_DISK = " << free_disk<< endl
<< "\tUSED_CPU = " << used_cpu << endl
<< "\tUSED_MEMORY = " << used_mem << endl
<< "\tUSED_DISK = " << used_disk<< endl
<< "\tRUNNING_VMS = " << running_vms<< endl;
str = oss.str();
return str;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -59,8 +59,8 @@ class EC2InformationManagerDriver < OpenNebulaDriver
totalmemory = smem + lmem + xlmem
totalcpu = scpu + lcpu + xlcpu
@info = "TOTALMEMORY=#{totalmemory},TOTALCPU=#{totalcpu}," \
"CPUSPEED=1000,FREEMEMORY=#{totalmemory},FREECPU=#{totalcpu}"
@info ="HYPERVISOR=ec2,TOTALMEMORY=#{totalmemory},TOTALCPU=#{totalcpu}," \
"CPUSPEED=1000,FREEMEMORY=#{totalmemory},FREECPU=#{totalcpu}"
end
#---------------------------------------------------------------------------

View File

@ -79,6 +79,8 @@ net_text.split(/\n/).each{|line|
end
}
puts "HYPERVISOR=kvm"
puts "TOTALCPU=#{$total_cpu}"
puts "CPUSPEED=#{$cpu_speed}"

View File

@ -281,4 +281,4 @@ public class GetProperty
{
cb.disConnect();
}
}
}

View File

@ -113,7 +113,7 @@ class OneImVmware extends Thread
GetProperty gP;
boolean rf;
String response = "";
String response = "HYPERVISOR=vmware";
try
{
@ -122,12 +122,11 @@ class OneImVmware extends Thread
for(int i=0;i<arguments.length;i++)
{
argsWithHost[i] = arguments[i];
System.out.println(arguments[i]);
}
argsWithHost[arguments.length] = "--url";
//argsWithHost[arguments.length + 1 ] = "https://" + hostToMonitor + ":443/sdk";
// argsWithHost[arguments.length + 1 ] = "https://" + hostToMonitor + ":443/sdk";
argsWithHost[arguments.length + 1 ] = "https://localhost:8008/sdk";
gP = new GetProperty(argsWithHost, "HostSystem", hostToMonitor);
@ -139,15 +138,15 @@ System.out.println(arguments[i]);
Integer.parseInt(gP.getObjectProperty("hardware.memorySize").toString().trim());
totalMemory /= 1024;
response = response + "TOTALMEMORY=" + totalMemory;
response = response + ",TOTALMEMORY=" + totalMemory;
int numCpus =
Integer.parseInt(gP.getObjectProperty("hardware.cpuInfo.numCpuCores").
toString().trim());
numCpus *= 100;
response = response + " TOTALCPU=" + numCpus;
response = response + ",TOTALCPU=" + numCpus;
response = response + " MODELNAME=\""
response = response + ",MODELNAME=\""
+ gP.getObjectProperty("hardware.systemInfo.model")
+ "\"";
@ -156,7 +155,7 @@ System.out.println(arguments[i]);
// From hz to Mhz
cpuSpeed/=1000000;
response = response + " CPUSPEED=" + (int)cpuSpeed;
response = response + ",CPUSPEED=" + (int)cpuSpeed;
// Dynamic Information
@ -165,27 +164,27 @@ System.out.println(arguments[i]);
if (!rf) throw new Exception();
// Convert from 1/10000 to 1/100
int usedCpu = (int)(gP.getMeasure()/100);
response = response + " USEDCPU="+usedCpu;
response = response + ",USEDCPU="+usedCpu;
response = response + " FREECPU="+(100-usedCpu);
response = response + ",FREECPU="+(100-usedCpu);
// MEM
rf = gP.getPerformanceCounter("mem.usage.average", 60);
if (!rf) throw new Exception();
// Convert from percentage to actual value
int usedMemory = (int)(totalMemory * (gP.getMeasure()/100))/100;
response = response + " USEDMEMORY=" + usedMemory;
response = response + ",USEDMEMORY=" + usedMemory;
response = response + " FREEMEMORY=" + (totalMemory-usedMemory);
response = response + ",FREEMEMORY=" + (totalMemory-usedMemory);
// NET
rf = gP.getPerformanceCounter("net.transmitted.average", 60);
if (!rf) throw new Exception();
response = response + " NETTX=" + (int)gP.getMeasure();
response = response + ",NETTX=" + (int)gP.getMeasure();
rf = gP.getPerformanceCounter("net.received.average", 60);
if (!rf) throw new Exception();
response = response + " NETRX=" + (int)gP.getMeasure();
response = response + ",NETRX=" + (int)gP.getMeasure();
// Send the actual response
System.err.println("MONITOR SUCCESS " + hid_str + " " + response);
@ -196,7 +195,7 @@ System.out.println(arguments[i]);
e.printStackTrace();
System.err.println("MONITOR FAILURE " + hid_str + " Failed monitoring host " +
hostToMonitor + ".");
hostToMonitor + ". Please check the VM log.");
} // catch
} // if (action.equals("MONITOR"))
} // else if (str_split.length != 4)

View File

@ -22,3 +22,8 @@
# Uncomment the following line to active MAD debug
#ONE_MAD_DEBUG=1
# Datastore name
VMWARE_DATASTORE=datastore1
# Datacenter name
VMWARE_DATACENTER=ha-datacenter

View File

@ -19,7 +19,7 @@
#Setup driver variables
DRIVER_NAME="one_im_vmware"
DRIVER_NAME="im_vmware"
if [ -z "${ONE_LOCATION}" ]; then
DRIVERRC=/etc/one/${DRIVER_NAME}/${DRIVER_NAME}rc
@ -47,9 +47,9 @@ fi
# Execute the actual MAD
if [ -n "${ONE_MAD_DEBUG}" ]; then
exec nice -n $PRIORITY java -cp $ONE_LOCATION/lib/mads:$CLASSPATH -Djavax.net.ssl.trustStore=$VMWARE_TRUSTORE -Xmx1024M $MAD_FILE $* 2>> $MAD_LOG_PATH
exec nice -n $PRIORITY java -cp $ONE_LOCATION/lib/mads:$CLASSPATH -Ddatastore=$VMWARE_DATASTORE -Ddatacenter=$VMWARE_DATACENTER -Djavax.net.ssl.trustStore=$VMWARE_TRUSTORE -Xmx1024M $MAD_FILE $* 2>> $MAD_LOG_PATH
else
exec nice -n $PRIORITY java -cp $ONE_LOCATION/lib/mads:$CLASSPATH -Djavax.net.ssl.trustStore=$VMWARE_TRUSTORE -Xmx1024M $MAD_FILE $* 2> /dev/null
exec nice -n $PRIORITY java -cp $ONE_LOCATION/lib/mads:$CLASSPATH -Ddatastore=$VMWARE_DATASTORE -Ddatacenter=$VMWARE_DATACENTER -Djavax.net.ssl.trustStore=$VMWARE_TRUSTORE -Xmx1024M $MAD_FILE $* 2> /dev/null
fi

View File

@ -86,6 +86,7 @@ domains_info.each {|line|
# WRITE INFO
puts "HYPERVISOR=xen"
puts "TOTALCPU=" + cpu_info[:total].round.to_s
puts "CPUSPEED=" + cpu_info[:speed]
puts "TOTALMEMORY=" + memory_info[:total].to_s
@ -95,4 +96,3 @@ puts "USEDCPU=" + vm_info[:cpu].round.to_s
puts "FREECPU=" + (cpu_info[:total]-vm_info[:cpu]).round.to_s
puts "NETTX=" + vm_info[:nettx].to_s
puts "NETRX=" + vm_info[:netrx].to_s

View File

@ -78,16 +78,12 @@ void LifeCycleManager::deploy_action(int vid)
}
else
{
goto error;
vm->log("LCM", Log::ERROR, "deploy_action, VM in a wrong state.");
}
vm->unlock();
return;
error:
vm->log("LCM", Log::ERROR, "deploy_action, VM in a wrong state.");
vm->unlock();
}
/* -------------------------------------------------------------------------- */
@ -126,16 +122,12 @@ void LifeCycleManager::suspend_action(int vid)
}
else
{
goto error;
vm->log("LCM", Log::ERROR, "suspend_action, VM in a wrong state.");
}
vm->unlock();
return;
error:
vm->log("LCM", Log::ERROR, "suspend_action, VM in a wrong state.");
vm->unlock();
}
/* -------------------------------------------------------------------------- */
@ -174,16 +166,12 @@ void LifeCycleManager::stop_action(int vid)
}
else
{
goto error;
vm->log("LCM", Log::ERROR, "stop_action, VM in a wrong state.");
}
vm->unlock();
return;
error:
vm->log("LCM", Log::ERROR, "stop_action, VM in a wrong state.");
vm->unlock();
}
/* -------------------------------------------------------------------------- */
@ -231,16 +219,12 @@ void LifeCycleManager::migrate_action(int vid)
}
else
{
goto error;
vm->log("LCM", Log::ERROR, "migrate_action, VM in a wrong state.");
}
vm->unlock();
return;
error:
vm->log("LCM", Log::ERROR, "migrate_action, VM in a wrong state.");
vm->unlock();
}
/* -------------------------------------------------------------------------- */
@ -289,19 +273,12 @@ void LifeCycleManager::live_migrate_action(int vid)
}
else
{
os << "VM not in a suitable state to migrate";
vm->log("LCM", Log::ERROR, os);
goto error;
vm->log("LCM", Log::ERROR, "live_migrate_action, VM in a wrong state.");
}
vm->unlock();
return;
error:
vm->log("LCM", Log::ERROR, "live_migrate_action, VM in a wrong state.");
vm->unlock();
}
/* -------------------------------------------------------------------------- */
@ -340,16 +317,12 @@ void LifeCycleManager::shutdown_action(int vid)
}
else
{
goto error;
vm->log("LCM", Log::ERROR, "shutdown_action, VM in a wrong state.");
}
vm->unlock();
return;
error:
vm->log("LCM", Log::ERROR, "shutdown_action, VM in a wrong state.");
vm->unlock();
}
/* -------------------------------------------------------------------------- */
@ -404,16 +377,12 @@ void LifeCycleManager::restore_action(int vid)
}
else
{
goto error;
vm->log("LCM", Log::ERROR, "restore_action, VM in a wrong state.");
}
vm->unlock();
return;
error:
vm->log("LCM", Log::ERROR, "restore_action, VM in a wrong state.");
vm->unlock();
}
/* -------------------------------------------------------------------------- */
@ -452,14 +421,203 @@ void LifeCycleManager::cancel_action(int vid)
}
else
{
goto error;
vm->log("LCM", Log::ERROR, "cancel_action, VM in a wrong state.");
}
vm->unlock();
return;
error:
vm->log("LCM", Log::ERROR, "cancel_action, VM in a wrong state.");
vm->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::restart_action(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if (vm->get_state() == VirtualMachine::ACTIVE &&
(vm->get_lcm_state() == VirtualMachine::UNKNOWN ||
vm->get_lcm_state() == VirtualMachine::BOOT))
{
Nebula& nd = Nebula::instance();
VirtualMachineManager * vmm = nd.get_vmm();
//----------------------------------------------------
// RE-START THE VM IN THE SAME HOST
//----------------------------------------------------
if (vm->get_lcm_state() == VirtualMachine::BOOT)
{
vm->log("LCM", Log::INFO, "Sending BOOT command to VM again");
}
else
{
vm->set_state(VirtualMachine::BOOT);
vmpool->update(vm);
vm->log("LCM", Log::INFO, "New VM state is BOOT");
}
//----------------------------------------------------
vmm->trigger(VirtualMachineManager::DEPLOY,vid);
}
else
{
vm->log("LCM", Log::ERROR, "restart_action, VM in a wrong state.");
}
vm->unlock();
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::delete_action(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
VirtualMachine::LcmState state = vm->get_lcm_state();
if ((state == VirtualMachine::LCM_INIT) ||
(state == VirtualMachine::DELETE) ||
(state == VirtualMachine::FAILURE))
{
vm->unlock();
return;
}
int cpu;
int mem;
int disk;
time_t the_time = time(0);
Nebula& nd = Nebula::instance();
TransferManager * tm = nd.get_tm();
DispatchManager * dm = nd.get_dm();
VirtualMachineManager * vmm = nd.get_vmm();
vm->set_state(VirtualMachine::DELETE);
vmpool->update(vm);
vm->set_etime(the_time);
vm->set_reason(History::USER);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_hid(),cpu,mem,disk);
switch (state)
{
case VirtualMachine::PROLOG:
case VirtualMachine::PROLOG_RESUME:
vm->set_prolog_etime(the_time);
vmpool->update_history(vm);
tm->trigger(TransferManager::DRIVER_CANCEL,vid);
tm->trigger(TransferManager::EPILOG_DELETE,vid);
break;
case VirtualMachine::BOOT:
case VirtualMachine::RUNNING:
case VirtualMachine::UNKNOWN:
case VirtualMachine::SHUTDOWN:
case VirtualMachine::CANCEL:
vm->set_running_etime(the_time);
vmpool->update_history(vm);
vmm->trigger(VirtualMachineManager::DRIVER_CANCEL,vid);
vmm->trigger(VirtualMachineManager::CANCEL,vid);
tm->trigger(TransferManager::EPILOG_DELETE,vid);
break;
case VirtualMachine::MIGRATE:
vm->set_running_etime(the_time);
vmpool->update_history(vm);
vm->set_previous_etime(the_time);
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
vmpool->update_previous_history(vm);
hpool->del_capacity(vm->get_previous_hid(),cpu,mem,disk);
vmm->trigger(VirtualMachineManager::DRIVER_CANCEL,vid);
vmm->trigger(VirtualMachineManager::CANCEL,vid);
vmm->trigger(VirtualMachineManager::CANCEL_PREVIOUS,vid);
tm->trigger(TransferManager::EPILOG_DELETE,vid);
break;
case VirtualMachine::SAVE_STOP:
case VirtualMachine::SAVE_SUSPEND:
vm->set_running_etime(the_time);
vmpool->update_history(vm);
vmm->trigger(VirtualMachineManager::DRIVER_CANCEL,vid);
vmm->trigger(VirtualMachineManager::CANCEL,vid);
tm->trigger(TransferManager::EPILOG_DELETE,vid);
break;
case VirtualMachine::SAVE_MIGRATE:
vm->set_running_etime(the_time);
vmpool->update_history(vm);
vm->set_previous_etime(the_time);
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
vmpool->update_previous_history(vm);
hpool->del_capacity(vm->get_previous_hid(),cpu,mem,disk);
vmm->trigger(VirtualMachineManager::DRIVER_CANCEL,vid);
vmm->trigger(VirtualMachineManager::CANCEL_PREVIOUS,vid);
tm->trigger(TransferManager::EPILOG_DELETE_PREVIOUS,vid);
break;
case VirtualMachine::PROLOG_MIGRATE:
vm->set_prolog_etime(the_time);
vmpool->update_history(vm);
tm->trigger(TransferManager::DRIVER_CANCEL,vid);
tm->trigger(TransferManager::EPILOG_DELETE,vid);
tm->trigger(TransferManager::EPILOG_DELETE_PREVIOUS,vid);
break;
case VirtualMachine::EPILOG_STOP:
case VirtualMachine::EPILOG:
vm->set_epilog_etime(the_time);
vmpool->update_history(vm);
tm->trigger(TransferManager::DRIVER_CANCEL,vid);
tm->trigger(TransferManager::EPILOG_DELETE,vid);
break;
default: //FAILURE,LCM_INIT,DELETE
break;
}
dm->trigger(DispatchManager::DONE,vid);
vm->unlock();
return;
}

View File

@ -162,6 +162,14 @@ void LifeCycleManager::trigger(Actions action, int _vid)
aname = "SHUTDOWN";
break;
case RESTART:
aname = "RESTART";
break;
case DELETE:
aname = "DELETE";
break;
case FINALIZE:
aname = ACTION_FINALIZE;
break;
@ -283,6 +291,14 @@ void LifeCycleManager::do_action(const string &action, void * arg)
{
shutdown_action(vid);
}
else if (action == "RESTART")
{
restart_action(vid);
}
else if (action == "DELETE")
{
delete_action(vid);
}
else if (action == ACTION_FINALIZE)
{
Nebula::log("LCM",Log::INFO,"Stopping Life-cycle Manager...");

View File

@ -340,29 +340,11 @@ void LifeCycleManager::deploy_failure_action(int vid)
}
else if (vm->get_lcm_state() == VirtualMachine::BOOT)
{
int cpu,mem,disk;
time_t the_time = time(0);
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
time_t the_time = time(0);
vm->set_running_etime(the_time);
vm->set_etime(the_time);
vm->set_reason(History::ERROR);
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_hid(),cpu,mem,disk);
vm->log("LCM", Log::INFO, "Fail to boot VM.");
//----------------------------------------------------
dm->trigger(DispatchManager::FAILED,vid);
failure_action(vm);
}
vm->unlock();
@ -477,7 +459,10 @@ void LifeCycleManager::prolog_success_action(int vid)
}
else
{
goto error;
vm->log("LCM",Log::ERROR,"prolog_success_action, VM in a wrong state");
vm->unlock();
return;
}
//----------------------------------------------------
@ -503,10 +488,6 @@ void LifeCycleManager::prolog_success_action(int vid)
vm->unlock();
return;
error:
vm->log("LCM",Log::ERROR,"prolog_success_action, VM in a wrong state");
vm->unlock();
}
/* -------------------------------------------------------------------------- */
@ -515,12 +496,8 @@ error:
void LifeCycleManager::prolog_failure_action(int vid)
{
VirtualMachine * vm;
time_t the_time = time(0);
int cpu,mem,disk;
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
time_t the_time = time(0);
vm = vmpool->get(vid,true);
if ( vm == 0 )
@ -529,21 +506,9 @@ void LifeCycleManager::prolog_failure_action(int vid)
}
vm->set_prolog_etime(the_time);
vm->set_etime(the_time);
vm->set_reason(History::ERROR);
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_hid(),cpu,mem,disk);
failure_action(vm);
//----------------------------------------------------
dm->trigger(DispatchManager::FAILED,vid);
vm->unlock();
return;
@ -580,7 +545,10 @@ void LifeCycleManager::epilog_success_action(int vid)
}
else
{
goto error;
vm->log("LCM",Log::ERROR,"epilog_success_action, VM in a wrong state");
vm->unlock();
return;
}
vm->set_epilog_etime(the_time);
@ -600,10 +568,6 @@ void LifeCycleManager::epilog_success_action(int vid)
vm->unlock();
return;
error:
vm->log("LCM",Log::ERROR,"epilog_success_action, VM in a wrong state");
vm->unlock();
}
/* -------------------------------------------------------------------------- */
@ -611,12 +575,8 @@ error:
void LifeCycleManager::epilog_failure_action(int vid)
{
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
VirtualMachine * vm;
time_t the_time = time(0);
int cpu,mem,disk;
VirtualMachine * vm;
time_t the_time = time(0);
vm = vmpool->get(vid,true);
@ -627,20 +587,8 @@ void LifeCycleManager::epilog_failure_action(int vid)
vm->set_epilog_etime(the_time);
vm->set_etime(the_time);
vm->set_reason(History::ERROR);
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_hid(),cpu,mem,disk);
//----------------------------------------------------
dm->trigger(DispatchManager::FAILED,vid);
failure_action(vm);
vm->unlock();
return;
@ -722,13 +670,9 @@ void LifeCycleManager::cancel_failure_action(int vid)
void LifeCycleManager::monitor_failure_action(int vid)
{
VirtualMachine * vm;
VirtualMachine * vm;
int cpu,mem,disk;
time_t the_time = time(0);
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
vm = vmpool->get(vid,true);
@ -738,22 +682,8 @@ void LifeCycleManager::monitor_failure_action(int vid)
}
vm->set_running_etime(the_time);
vm->set_etime(the_time);
vm->set_reason(History::ERROR);
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_hid(),cpu,mem,disk);
vm->log("LCM", Log::INFO, "VM failed.");
//----------------------------------------------------
dm->trigger(DispatchManager::FAILED,vid);
failure_action(vm);
vm->unlock();
}
@ -806,10 +736,6 @@ void LifeCycleManager::monitor_suspend_action(int vid)
void LifeCycleManager::monitor_done_action(int vid)
{
VirtualMachine * vm;
time_t the_time = time(0);
Nebula& nd = Nebula::instance();
TransferManager * tm = nd.get_tm();
vm = vmpool->get(vid,true);
@ -822,21 +748,55 @@ void LifeCycleManager::monitor_done_action(int vid)
// EPILOG STATE
//----------------------------------------------------
vm->set_state(VirtualMachine::EPILOG);
vm->set_state(VirtualMachine::UNKNOWN);
vmpool->update(vm);
vm->set_epilog_stime(the_time);
vm->set_running_etime(the_time);
vmpool->update_history(vm);
vm->log("LCM", Log::INFO, "New VM state is EPILOG");
vm->log("LCM", Log::INFO, "New VM state is UNKNOWN");
//----------------------------------------------------
tm->trigger(TransferManager::EPILOG,vid);
vm->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::failure_action(VirtualMachine * vm)
{
Nebula& nd = Nebula::instance();
TransferManager * tm = nd.get_tm();
DispatchManager * dm = nd.get_dm();
time_t the_time = time(0);
int cpu,mem,disk;
//----------------------------------------------------
// LCM FAILURE STATE
//----------------------------------------------------
vm->set_state(VirtualMachine::FAILURE);
vmpool->update(vm);
vm->set_etime(the_time);
vm->set_reason(History::ERROR);
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
hpool->del_capacity(vm->get_hid(),cpu,mem,disk);
//------------- Clean up remote files ----------------
dm->trigger(DispatchManager::FAILED,vm->get_oid());
tm->trigger(TransferManager::EPILOG_DELETE,vm->get_oid());
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -70,8 +70,10 @@ class ActionManager
@threaded = threaded
@concurrency = concurrency
@num_running = 0
@action_queue = Array.new
@running_actions= 0
@action_running = Hash.new
@threads_mutex = Mutex.new
@threads_cond = ConditionVariable.new
@ -94,15 +96,16 @@ class ActionManager
# Triggers the execution of the action.
#
# +aname+ name of the action
# +action_id+ an id to identify the action (to cancel it later)
# +aargs+ arguments to call the action
def trigger_action(aname,*aargs)
def trigger_action(aname, action_id, *aargs)
@threads_mutex.synchronize {
return if @finalize
if aname == :FINALIZE
@finalize = true
@threads_cond.signal if @running_actions == 0
@threads_cond.signal if @num_running == 0
return
end
@ -127,22 +130,41 @@ class ActionManager
end
end
@action_queue << @actions[aname].merge(:args => aargs)
@action_queue << @actions[aname].merge(:args => aargs,
:id => action_id)
if @running_actions < @concurrency
if @num_running < @concurrency
@threads_cond.signal
end
}
end
def cancel_action(action_id)
@threads_mutex.synchronize {
thread = @action_running[action_id]
if thread
thread.kill!
@num_running -= 1
@action_running.delete(action_id)
@threads_cond.signal
else
i = @action_queue.index{|x| x[:id] == action_id}
@action_queue.delete_at(i) if i
end
}
end
def start_listener
while true
@threads_mutex.synchronize {
while ((@concurrency - @running_actions)==0) ||
while ((@concurrency - @num_running)==0) ||
@action_queue.size==0
@threads_cond.wait(@threads_mutex)
return if (@finalize && @running_actions == 0)
return if (@finalize && @num_running == 0)
end
run_action
@ -156,21 +178,25 @@ private
action = @action_queue.shift
if action
@running_actions += 1
@num_running += 1
if action[:threaded]
Thread.new {
thread = Thread.new {
action[:method].call(*action[:args])
@threads_mutex.synchronize {
@running_actions -= 1
@num_running -= 1
@action_running.delete(action[:id])
@threads_cond.signal
}
}
@action_running[action[:id]] = thread
else
action[:method].call(*action[:args])
@running_actions -= 1
@num_running -= 1
end
end
end
@ -204,15 +230,20 @@ if __FILE__ == $0
Thread.new {
sleep 1
100.times {|n|
s.am.trigger_action(:SLEEP,rand(3)+1,n)
s.am.trigger_action(:NOP)
s.am.trigger_action(:SLEEP,n,rand(3)+1,n)
s.am.trigger_action(:NOP,100+n)
}
s.am.trigger_action(:FINALIZE)
s.am.trigger_action(:SLEEP,301,5,301)
s.am.cancel_action(301)
s.am.trigger_action(:SLEEP,rand(3)+1,999)
s.am.trigger_action(:SLEEP,rand(3)+1,333)
s.am.trigger_action(:FINALIZE,0)
s.am.trigger_action(:SLEEP,999,rand(3)+1,999)
s.am.trigger_action(:SLEEP,333,rand(3)+1,333)
}
s.am.start_listener

View File

@ -39,6 +39,7 @@ class OpenNebulaDriver < ActionManager
super(concurrency,threaded)
register_action(:INIT, method("init"))
@send_mutex=Mutex.new
end
@ -92,7 +93,18 @@ private
action = args.shift.upcase.to_sym
trigger_action(action,*args)
if (args.length == 0) || (!args[0])
action_id = 0
else
action_id = args[0].to_i
end
if action == :DRIVER_CANCEL
cancel_action(action_id)
log(action_id,"Driver command for #{action_id} cancelled")
else
trigger_action(action,action_id,*args)
end
end
end
end
@ -106,7 +118,7 @@ if __FILE__ == $0
register_action(:SLEEP,method("my_sleep"))
end
def my_sleep(timeout, num)
def my_sleep(num, timeout)
log(num,"Sleeping #{timeout} seconds")
sleep(timeout.to_i)
log(num,"Done with #{num}")
@ -117,5 +129,4 @@ if __FILE__ == $0
sd = SampleDriver.new
sd.start_driver
end
end

View File

@ -126,9 +126,21 @@ void Nebula::start()
try
{
string db_name = var_location + "one.db";
string db_name = var_location + "one.db";
struct stat db_stat;
bool db_bootstrap = stat(db_name.c_str(), &db_stat) != 0;
db = new SqliteDB(db_name,Nebula::log);
if (db_bootstrap)
{
Nebula::log("ONE",Log::INFO,"Bootstraping OpenNebula database.");
VirtualMachinePool::bootstrap(db);
HostPool::bootstrap(db);
VirtualNetworkPool::bootstrap(db);
UserPool::bootstrap(db);
}
}
catch (exception&)
{
@ -151,18 +163,14 @@ void Nebula::start()
nebula_configuration->get("NETWORK_SIZE", size);
vnpool = new VirtualNetworkPool(db,mac_prefix,size);
upool = new UserPool(db);
}
catch (exception&)
{
throw;
}
Nebula::log("ONE",Log::INFO,"Bootstraping OpenNebula database.");
vmpool->bootstrap();
hpool->bootstrap();
vnpool->bootstrap();
// -----------------------------------------------------------
// Close stds, we no longer need them
// -----------------------------------------------------------
@ -316,6 +324,7 @@ void Nebula::start()
vmpool,
hpool,
vnpool,
upool,
rm_port,
log_location + "one_xmlrpc.log");
}
@ -382,12 +391,14 @@ void Nebula::start()
vmm->trigger(VirtualMachineManager::FINALIZE,0);
lcm->trigger(LifeCycleManager::FINALIZE,0);
tm->trigger(TransferManager::FINALIZE,0);
dm->trigger(DispatchManager::FINALIZE,0);
im->finalize();
rm->finalize();
hm->finalize();
//sleep to wait drivers???
pthread_join(vmm->get_thread_id(),0);
@ -397,6 +408,7 @@ void Nebula::start()
pthread_join(im->get_thread_id(),0);
pthread_join(rm->get_thread_id(),0);
pthread_join(hm->get_thread_id(),0);
Nebula::log("ONE", Log::INFO, "All modules finalized, exiting.\n");
}

View File

@ -41,6 +41,7 @@ env.Append(LIBS=[
'nebula_rm',
'nebula_dm',
'nebula_tm',
'nebula_um',
'nebula_mad',
'nebula_template',
'nebula_pool',
@ -49,6 +50,7 @@ env.Append(LIBS=[
'nebula_vm',
'nebula_common',
'sqlite3',
'crypto'
])

View File

@ -0,0 +1,73 @@
class OcaConfiguration
NAME_REG=/[\w\d_-]+/
VARIABLE_REG=/\s*(#{NAME_REG})\s*=\s*/
SIMPLE_VARIABLE_REG=/#{VARIABLE_REG}([^\[]+?)(#.*)?/
SINGLE_VARIABLE_REG=/^#{SIMPLE_VARIABLE_REG}$/
ARRAY_VARIABLE_REG=/^#{VARIABLE_REG}\[(.*?)\]/m
def initialize(file)
@conf=parse_conf(file)
end
def add_value(conf, key, value)
if conf[key]
if !conf[key].kind_of?(Array)
conf[key]=[conf[key]]
end
conf[key]<<value
else
conf[key]=value
end
end
def parse_conf(file)
conf_file=File.read(file)
conf=Hash.new
conf_file.scan(SINGLE_VARIABLE_REG) {|m|
key=m[0].strip.upcase
value=m[1].strip
# hack to skip multiline VM_TYPE values
next if %w{NAME TEMPLATE}.include? key.upcase
add_value(conf, key, value)
}
conf_file.scan(ARRAY_VARIABLE_REG) {|m|
master_key=m[0].strip.upcase
pieces=m[1].split(',')
vars=Hash.new
pieces.each {|p|
key, value=p.split('=')
vars[key.strip.upcase]=value.strip
}
add_value(conf, master_key, vars)
}
conf
end
def conf
@conf
end
def [](key)
@conf[key.to_s.upcase]
end
end
if $0 == __FILE__
require 'pp'
conf=OcaConfiguration.new('oca.conf')
pp conf.conf
end

35
src/oca/ec2/client.rb Normal file
View File

@ -0,0 +1,35 @@
#!/usr/bin/ruby
require 'pp'
require 'rubygems'
require 'EC2'
ACCESS_KEY_ID = 'jfontan'
#SECRET_ACCESS_KEY = 'opennebula'
SECRET_ACCESS_KEY = '4478db59d30855454ece114e8ccfa5563d21c9bd'
SERVER = '127.0.0.1'
PORT = 4567
base=EC2::Base.new(
:access_key_id => ACCESS_KEY_ID,
:secret_access_key => SECRET_ACCESS_KEY,
:server => SERVER,
:port => PORT,
:use_ssl => false
)
#pp base.describe_images
#pp base.register_image(
# :image_location => 'eco.rb'
#)
#pp base.run_instances(
# :image_id => "b8329b60-4227-012c-da6e-0019e333ebc5"
#)
pp base.describe_instances

293
src/oca/ec2/eco.rb Normal file
View File

@ -0,0 +1,293 @@
require 'rubygems'
require 'sinatra'
require 'EC2'
$: << './OpenNebulaApi'
$: << './lib'
require 'OpenNebula'
require 'repo_manager'
require 'OcaConfiguration'
require 'pp'
include OpenNebula
CONFIG=OcaConfiguration.new('oca.conf')
AUTH="#{CONFIG[:user]}:#{CONFIG[:password]}"
INSTANCE_TYPES=Hash.new
pp CONFIG
if CONFIG[:vm_type].kind_of?(Array)
# Multiple instance types
CONFIG[:vm_type].each {|type|
INSTANCE_TYPES[type['NAME']]=type
}
else
# When only one instance type is defined
INSTANCE_TYPES[CONFIG[:vm_type]['NAME']]=CONFIG[:vm_type]
end
pp INSTANCE_TYPES
set :host, CONFIG[:server]
set :port, CONFIG[:port]
EC2_STATES={
:pending => {:code => 0, :name => 'pending'},
:running => {:code => 16, :name => 'running'},
:shutdown => {:code => 32, :name => 'shutting-down'},
:terminated => {:code => 48, :name => 'terminated'}
}
ONE_STATES={
'init' => :pending,
'pend' => :pending,
'hold' => :pending,
'stop' => :pending,
'susp' => :pending,
'done' => :terminated,
'fail' => :terminated,
'prol' => :pend,
'boot' => :running,
'runn' => :running,
'migr' => :running,
'save' => :pend,
'epil' => :shutdown,
'shut' => :shutdown,
'fail' => :terminated,
'dele' => :terminated,
'unkn' => :terminated
}
$repoman=RepoManager.new
def get_one_client
Client.new(AUTH)
end
def get_user(name)
user=nil
user_pool=UserPool.new(get_one_client)
user_pool.info
user_pool.each{|u|
if u.name==name
user=Hash.new
user[:id]=u.id
user[:name]=u.name
user[:password]=u[:password]
end
}
user
end
def render_state(vm)
one_state=vm.status
ec2_state=EC2_STATES[ONE_STATES[one_state]]
"<code>#{ec2_state[:code]}</code>
<name>#{ec2_state[:name]}</name>"
end
def authenticate(params)
user_name=params['AWSAccessKeyId']
user=get_user(user_name)
halt 401, "User does not exist" if !user
signature_params=params.reject {|key,value| key=='Signature' }
canonical=EC2.canonical_string(signature_params, CONFIG[:server])
signature=EC2.encode(user[:password], canonical, false)
halt 401, "Bad password" if params['Signature']!=signature
end
before do
authenticate(params)
end
def register_image(params)
user=get_user(params['AWSAccessKeyId'])
img=$repoman.add(user[:id], params["ImageLocation"])
@img_id=img.uuid
erb :register_image
end
def describe_images(params)
@user=get_user(params['AWSAccessKeyId'])
@images=Image.filter(:owner => @user[:id])
pp @images
erb :describe_images
end
def run_instances(params)
@user=get_user(params['AWSAccessKeyId'])
image_id=params['ImageId']
image=$repoman.get(image_id)
@vm_info=Hash.new
@vm_info[:img_path]=image.path
@vm_info[:img_id]=image_id
instance_type_name=params['InstanceType']
instance_type=INSTANCE_TYPES[instance_type_name]
halt 400, "Bad instance type" if !instance_type
@vm_info[:instance_type]=instance_type_name
template=ERB.new(File.read("templates/#{instance_type['TEMPLATE']}"))
template_text=template.result(binding)
pp template_text
vm=VirtualMachine.new(VirtualMachine.build_xml, get_one_client)
response=vm.allocate(template_text)
pp response
@vm_info[:vm_id]=vm.id
erb :run_instances
end
def describe_instances(params)
@user=get_user(params['AWSAccessKeyId'])
@vmpool=VirtualMachinePool.new(get_one_client)
@vmpool.info
erb :describe_instances
end
post '/' do
pp params
case params['Action']
when 'RegisterImage'
register_image(params)
when 'DescribeImages'
describe_images(params)
when 'RunInstances'
run_instances(params)
when 'DescribeInstances'
describe_instances(params)
end
end
__END__
@@ register_image
<RegisterImageResponse xmlns="http://ec2.amazonaws.com/doc/2009-04-04/">
<imageId><%= @img_id %></imageId>
</RegisterImageResponse>
@@ describe_images
<DescribeImagesResponse xmlns="http://ec2.amazonaws.com/doc/2009-04-04/">
<imagesSet>
<% for image in @images %>
<item>
<imageId><%= image.uuid %></imageId>
<imageLocation><%= image.path %></imageLocation>
<imageState>available</imageState>
<imageOwnerId><%= @user[:name] %></imageOwnerId>
<isPublic>false</isPublic>
<architecture>i386</architecture>
<imageType>machine</imageType>
</item>
<% end %>
</imagesSet>
</DescribeImagesResponse>
@@ run_instances
<RunInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2009-04-04/">
<reservationId>r-47a5402e</reservationId>
<ownerId><%= @user[:name] %></ownerId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instancesSet>
<item>
<instanceId><%= @vm_info[:vm_id] %></instanceId>
<imageId><%= @vm_info[:img_id] %></imageId>
<instanceState>
<code>0</code>
<name>pending</name>
</instanceState>
<privateDnsName></privateDnsName>
<dnsName></dnsName>
<keyName>example-key-name</keyName>
<amiLaunchIndex>0</amiLaunchIndex>
<instanceType>m1.small</instanceType>
<launchTime>2007-08-07T11:51:50.000Z</launchTime>
<placement>
<availabilityZone>us-east-1b</availabilityZone>
</placement>
<monitoring>
<enabled>true</enabled>
</monitoring>
</item>
</instancesSet>
</RunInstancesResponse>
@@ describe_instances
<DescribeInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2009-04-04/">
<reservationSet>
<item>
<reservationId>default</reservationId>
<ownerId><%= @user[:name] %></ownerId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instancesSet>
<% @vmpool.each do |vm| %>
<item>
<instanceId><%= vm.id %></instanceId>
<imageId><%= vm.id %></imageId>
<instanceState>
<%= render_state(vm) %>
</instanceState>
<privateDnsName>10-251-50-132.ec2.internal</privateDnsName>
<dnsName>ec2-72-44-33-4.compute-1.amazonaws.com</dnsName>
<keyName>example-key-name</keyName>
<amiLaunchIndex>23</amiLaunchIndex>
<productCodesSet>
<item><productCode>774F4FF8</productCode></item>
</productCodesSet>
<instanceType>m1.large</instanceType>
<launchTime>2007-08-07T11:54:42.000Z</launchTime>
<placement>
<availabilityZone>us-east-1b</availabilityZone>
</placement>
</item>
<% end %>
</instancesSet>
</item>
</reservationSet>
</DescribeInstancesResponse>

24
src/oca/ec2/oca.conf Normal file
View File

@ -0,0 +1,24 @@
# OpenNebula administrator user
USER=jfontan
PASSWORD=opennebula
# OpenNebula sever contact information
ONE_XMLRPC=http://localhost:2633/RPC2
# Host and port where OCA server will run
SERVER=127.0.0.1
PORT=4567
# Configuration for the image repository
DATABASE=./database.db
IMAGE_DIR=./images
# VM types allowed and its template file (inside templates directory)
VM_TYPE=[NAME=m1.small, TEMPLATE=m1.small.erb]
VM_TYPE=[NAME=m1.medium, TEMPLATE=m1.small.erb]
VM_TYPE=[NAME=m1.large, TEMPLATE=m1.small.erb]
VM_TYPE=[
NAME=m2.small,
TEMPLATE=m1.small.erb
]

View File

@ -0,0 +1,20 @@
NAME = eco-vm
CPU = 0.2
MEMORY = 256
OS = [ kernel = /vmlinuz,
initrd = /initrd.img,
root = sda1,
kernel_cmd = "ro xencons=tty console=tty1"]
DISK = [ source = <%= @vm_info[:img_path] %>,
clone = no,
target = sda1,
readonly = no]
IMAGE_ID = <%= @vm_info[:img_id] %>
INSTANCE_TYPE = <%= @vm_info[:instance_type ]%>

151
src/oca/rm/image.rb Normal file
View File

@ -0,0 +1,151 @@
module OpenNebula
class Image < Sequel::Model
# Creates the database table asociated with the model. It first
# checks for table existence before creating it so it is reasonably
# safe to call it when you load the library.
def self.initialize_table
set_schema do
primary_key :id, :type => Integer
varchar :uuid
int :owner
varchar :name
varchar :description
varchar :path
int :size
varchar :md5
end
create_table unless table_exists?
end
# Makes sure the image is deleted from the repository after
# the record is deleted. Make sure that you use destroy and not
# delete as delete method does not call hooks.
before_destroy do
FileUtils.rm(self.path)
end
# Specifies the directory where images will be stored
# dir:: _String_ directory where the images are stored
def self.image_dir=(dir)
@@image_dir=dir
end
# Strips out non user writable columns
# metadata:: _Hash_ hash containing the data to add to the db
# [return] _Hash_ clean metadata
def self.sanitize_metadata(metadata)
metadata.reject {|key,value|
![:name, :description].include? key
}
end
# Creates a new Image object, fills it, copies the image
# to the repository and saves to the database
# uuid:: _String_ UUID identifier for the image
# owner:: _Integer_ identifier of the user that owns this image
# path:: _String_ place where to copy the image from
# metadata:: _Hash_ extra data to add to the image, like name and description
# [return] _Image_ newly created image
def self.create_image(uuid, owner, path, metadata={})
sanitized_metadata=sanitize_metadata(metadata)
data={
:uuid => uuid,
:owner => owner,
}.merge(sanitized_metadata)
image=Image.new(data)
image.copy_image(path)
image.get_image_info
image.save
# set metadata
end
# Updates the image with the metadata provided. Currently only
# name and description can be changed
def change_metadata(metadata)
update(Image.sanitize_metadata(metadata))
end
# Copies the image from the source path to the image repository.
# Its name will be the image uuid. It also stores its new location
# in the object.
def copy_image(path)
FileUtils.cp(path, image_path)
self.path=image_path
end
# Returns the filename and path of the image file associated with
# this Image object.
def image_path
@@image_dir||='images'
File.join(@@image_dir, uuid)
end
# Extracts md5 and size from the image file and stores these data
# in the object.
def get_image_info
self.md5=`md5sum #{image_path}`.split.first
self.size=File.size(image_path)
end
# Adds a user to the list of allowed users of this image
def add_acl(user)
acl=ImageAcl.new({:uuid => self.uuid, :user => user})
acl.save
end
# Deletes a user fom the list of allowed users of this image
def del_acl(user)
acl=ImageAcl[:uuid => self.uuid, :user => user]
acl.destroy if acl
end
# Checks if a user has permissions to use this image
def has_permission?(user)
return true if self.owner==user
ImageAcl[:uuid => self.uuid, :user => user]!=nil
end
# Returns the xml representation of the image.
def to_xml
xml="<IMAGE>\n"
xml<<" <ID>#{uuid}</ID>\n"
xml<<" <OWNER>#{owner}</OWNER>\n"
xml<<" <NAME>#{name}</NAME>\n"
xml<<" <DESCRIPTION>#{description}</DESCRIPTION>\n"
xml<<" <PATH>#{path}</PATH>\n"
xml<<" <SIZE>#{size}</SIZE>\n"
xml<<" <MD5>#{md5}</MD5>\n"
xml<<"</IMAGE>\n"
end
# Like to_xml but does not show image file path data
def to_xml_lite
xml="<IMAGE>\n"
xml<<" <ID>#{uuid}</ID>\n"
xml<<" <OWNER>#{owner}</OWNER>\n"
xml<<" <NAME>#{name}</NAME>\n"
xml<<" <DESCRIPTION>#{description}</DESCRIPTION>\n"
xml<<" <SIZE>#{size}</SIZE>\n"
xml<<" <MD5>#{md5}</MD5>\n"
xml<<"</IMAGE>\n"
end
end
class ImageAcl < Sequel::Model
def self.initialize_table
set_schema do
primary_key :id, :type => Integer
varchar :uuid
int :user
end
create_table unless table_exists?
end
end
end

View File

@ -0,0 +1,59 @@
require 'rubygems'
#require 'storage_pool'
require 'uuid'
require 'fileutils'
require 'sequel'
require 'logger'
# Seems that database should be opened before defining models
# TODO: fix this
DB=Sequel.sqlite('database.db')
#DB.loggers << Logger.new($stdout)
require 'image'
IMAGE_DIR='images'
module OpenNebula
class RepoManager
def initialize
@uuid=UUID.new
Image.initialize_table
ImageAcl.initialize_table
end
def add(owner, path, metadata={})
uuid=@uuid.generate
Image.create_image(uuid, owner, path, metadata)
end
def get(uuid)
Image[:uuid => uuid]
end
def update(uuid, metadata)
image=get(uuid)
image.update(metadata)
end
end
end
=begin
OpenNebula::Image.create_image('uid', 10, 'repo_manager.rb',
:name => 'nombre',
:noexiste => 'nada'
)
=end
if $0 == __FILE__
rm=OpenNebula::RepoManager.new
img=rm.add_image(rand(100), 'image.rb',
:name => 'nombre',
:description => 'desc')
puts img.to_xml
end

View File

@ -254,33 +254,6 @@ void PoolSQL::replace()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void PoolSQL::remove(PoolObjectSQL * obj)
{
map<int,PoolObjectSQL *>::iterator index;
if (obj == 0)
{
return;
}
index = pool.find(obj->oid);
if ( index != pool.end())
{
delete obj;
lock();
pool.erase(index);
unlock();
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void PoolSQL::clean()
{
map<int,PoolObjectSQL *>::iterator it;

View File

@ -215,65 +215,97 @@ void RequestManager::do_action(
void RequestManager::register_xml_methods()
{
xmlrpc_c::methodPtr vm_allocate(new
RequestManager::VirtualMachineAllocate);
RequestManager::VirtualMachineAllocate(upool));
xmlrpc_c::methodPtr vm_deploy(new
RequestManager::VirtualMachineDeploy(vmpool,hpool));
RequestManager::VirtualMachineDeploy(vmpool,hpool,upool));
xmlrpc_c::methodPtr vm_migrate(new
RequestManager::VirtualMachineMigrate(vmpool,hpool));
RequestManager::VirtualMachineMigrate(vmpool,hpool,upool));
xmlrpc_c::methodPtr vm_action(new
RequestManager::VirtualMachineAction);
RequestManager::VirtualMachineAction(vmpool,upool));
xmlrpc_c::methodPtr vm_info(new
RequestManager::VirtualMachineInfo(vmpool));
RequestManager::VirtualMachineInfo(vmpool,upool));
xmlrpc_c::methodPtr vm_pool_info(new
RequestManager::VirtualMachinePoolInfo(vmpool));
RequestManager::VirtualMachinePoolInfo(vmpool,upool));
xmlrpc_c::methodPtr host_allocate(new
RequestManager::HostAllocate(hpool));
RequestManager::HostAllocate(hpool,upool));
xmlrpc_c::methodPtr host_info(new
RequestManager::HostInfo(hpool));
RequestManager::HostInfo(hpool, upool));
xmlrpc_c::methodPtr hostpool_info(new
RequestManager::HostPoolInfo(hpool,upool));
xmlrpc_c::methodPtr host_delete(new
RequestManager::HostDelete(hpool));
RequestManager::HostDelete(hpool,upool));
xmlrpc_c::methodPtr host_enable(new
RequestManager::HostEnable(hpool));
RequestManager::HostEnable(hpool,upool));
xmlrpc_c::methodPtr vn_allocate(new
RequestManager::VirtualNetworkAllocate(vnpool));
RequestManager::VirtualNetworkAllocate(vnpool,upool));
xmlrpc_c::methodPtr vn_info(new
RequestManager::VirtualNetworkInfo(vnpool));
RequestManager::VirtualNetworkInfo(vnpool,upool));
xmlrpc_c::methodPtr vnpool_info(new
RequestManager::VirtualNetworkPoolInfo(vnpool,upool));
xmlrpc_c::methodPtr vn_delete(new
RequestManager::VirtualNetworkDelete(vnpool));
RequestManager::VirtualNetworkDelete(vnpool, upool));
xmlrpc_c::methodPtr user_allocate(new
RequestManager::UserAllocate(upool));
xmlrpc_c::methodPtr user_info(new
RequestManager::UserInfo(upool));
xmlrpc_c::methodPtr user_delete(new
RequestManager::UserDelete(upool));
xmlrpc_c::methodPtr userpool_info(new
RequestManager::UserPoolInfo(upool));
/* VM related methods */
RequestManagerRegistry.addMethod("one.vmallocate", vm_allocate);
RequestManagerRegistry.addMethod("one.vmdeploy", vm_deploy);
RequestManagerRegistry.addMethod("one.vmaction", vm_action);
RequestManagerRegistry.addMethod("one.vmmigrate", vm_migrate);
RequestManagerRegistry.addMethod("one.vmget_info", vm_info);
RequestManagerRegistry.addMethod("one.vmget_pool_info", vm_pool_info);
RequestManagerRegistry.addMethod("one.vm.allocate",vm_allocate);
RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy);
RequestManagerRegistry.addMethod("one.vm.action", vm_action);
RequestManagerRegistry.addMethod("one.vm.migrate", vm_migrate);
RequestManagerRegistry.addMethod("one.vm.info", vm_info);
RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info);
/* Host related methods*/
RequestManagerRegistry.addMethod("one.hostallocate", host_allocate);
RequestManagerRegistry.addMethod("one.hostinfo", host_info);
RequestManagerRegistry.addMethod("one.hostdelete", host_delete);
RequestManagerRegistry.addMethod("one.hostenable", host_enable);
RequestManagerRegistry.addMethod("one.host.allocate", host_allocate);
RequestManagerRegistry.addMethod("one.host.info", host_info);
RequestManagerRegistry.addMethod("one.host.delete", host_delete);
RequestManagerRegistry.addMethod("one.host.enable", host_enable);
RequestManagerRegistry.addMethod("one.hostpool.info", hostpool_info);
/* Network related methods*/
RequestManagerRegistry.addMethod("one.vnallocate", vn_allocate);
RequestManagerRegistry.addMethod("one.vninfo", vn_info);
RequestManagerRegistry.addMethod("one.vndelete", vn_delete);
RequestManagerRegistry.addMethod("one.vn.allocate", vn_allocate);
RequestManagerRegistry.addMethod("one.vn.info", vn_info);
RequestManagerRegistry.addMethod("one.vn.delete", vn_delete);
RequestManagerRegistry.addMethod("one.vnpool.info", vnpool_info);
/* User related methods*/
RequestManagerRegistry.addMethod("one.user.allocate", user_allocate);
RequestManagerRegistry.addMethod("one.user.info", user_info);
RequestManagerRegistry.addMethod("one.user.delete", user_delete);
RequestManagerRegistry.addMethod("one.userpool.info", userpool_info);
};

View File

@ -29,19 +29,46 @@ void RequestManager::VirtualMachineAction::execute(
string action;
int vid;
int rc;
int uid;
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
VirtualMachine * vm;
ostringstream oss;
Nebula::log("ReM",Log::DEBUG,"VirtualMachineAction invoked");
session = xmlrpc_c::value_string(paramList.getString(0));
action = xmlrpc_c::value_string(paramList.getString(1));
vid = xmlrpc_c::value_int(paramList.getInt(2));
// Get the VM
vm = VirtualMachineAction::vmpool->get(vid,true);
if ( vm == 0 )
{
goto error_vm_get;
}
uid = vm->get_uid();
vm->unlock();
// Only oneadmin or the VM owner can perform operations upon the VM
rc = VirtualMachineAction::upool->authenticate(session);
if ( rc != 0 && rc != uid)
{
goto error_authenticate;
}
if (action == "shutdown")
{
rc = dm->shutdown(vid);
@ -70,6 +97,10 @@ void RequestManager::VirtualMachineAction::execute(
{
rc = dm->resume(vid);
}
else if (action == "restart")
{
rc = dm->restart(vid);
}
else if (action == "finalize")
{
rc = dm->finalize(vid);
@ -79,34 +110,52 @@ void RequestManager::VirtualMachineAction::execute(
rc = -3;
}
if (rc == 0)
if (rc != 0)
{
arrayData.push_back(xmlrpc_c::value_boolean(true));
}
else
{
ostringstream oss;
if (rc == -1)
{
oss << "Virtual machine does not exist";
}
else if ( rc == -2 )
{
oss << "Wrong state to perform action";
}
else if ( rc == -3 )
{
oss << "Unknown action";
}
arrayData.push_back(xmlrpc_c::value_boolean(false));
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
}
goto error_operation;
xmlrpc_c::value_array arrayresult(arrayData);
*retval = arrayresult;
}
arrayData.push_back(xmlrpc_c::value_boolean(true));
arrayresult = new xmlrpc_c::value_array(arrayData);
*retval = *arrayresult;
delete arrayresult;
return;
error_operation:
if (rc == -1)
{
oss << "Virtual machine does not exist";
}
else if ( rc == -2 )
{
oss << "Wrong state to perform action";
}
else if ( rc == -3 )
{
oss << "Unknown action";
}
goto error_common;
error_vm_get:
oss << "The virtual machine " << vid << " does not exists";
goto error_common;
error_authenticate:
oss << "User not authorized to perform operation upon VirtualMachine [" << vid << "]";
goto error_common;
error_common:
arrayData.push_back(xmlrpc_c::value_boolean(false));
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
xmlrpc_c::value_array arrayresult_error(arrayData);
*retval = arrayresult_error;
return;
}
/* -------------------------------------------------------------------------- */

View File

@ -26,49 +26,104 @@ void RequestManager::VirtualMachineAllocate::execute(
xmlrpc_c::value * const retval)
{
string session;
string username;
string password;
string vm_template;
int vid;
int uid;
int rc;
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
User * user;
ostringstream oss;
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
Nebula::log("ReM",Log::DEBUG,"VirtualMachineAllocate invoked");
session = xmlrpc_c::value_string(paramList.getString(0));
vm_template = xmlrpc_c::value_string(paramList.getString(1));
vm_template += "\n";
// First, we need to authenticate the user
rc = VirtualMachineAllocate::upool->authenticate(session);
if ( rc == -1 )
{
goto error_authenticate;
}
User::split_secret(session,username,password);
// Now let's get the user
user = VirtualMachineAllocate::upool->get(username,true);
if ( user == 0 )
{
goto error_get_user;
}
uid = user->get_uid();
user->unlock();
rc = dm->allocate(0,vm_template,&vid);
rc = dm->allocate(uid,vm_template,&vid);
if ( rc != 0 )
{
ostringstream oss;
if (rc == -1)
{
oss << "Error inserting VM in the database, check oned.log";
}
else
{
oss << "Error parsing VM template";
}
arrayData.push_back(xmlrpc_c::value_boolean(false));
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
goto error_allocate;
}
arrayData.push_back(xmlrpc_c::value_boolean(true));
arrayData.push_back(xmlrpc_c::value_int(vid));
// Copy arrayresult into retval mem space
arrayresult = new xmlrpc_c::value_array(arrayData);
*retval = *arrayresult;
delete arrayresult; // and get rid of the original
return;
error_authenticate:
oss << "User not authenticated, aborting RequestManagerAllocate call.";
goto error_common;
error_get_user:
oss << "User not recognized, cannot allocate VirtualMachine";
goto error_common;
error_allocate:
if (rc == -1)
{
oss << "Error inserting VM in the database, check oned.log";
}
else
{
arrayData.push_back(xmlrpc_c::value_boolean(true));
arrayData.push_back(xmlrpc_c::value_int(vid));
oss << "Error parsing VM template";
}
goto error_common;
xmlrpc_c::value_array arrayresult(arrayData);
*retval = arrayresult;
error_common:
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
Nebula::log("ReM",Log::ERROR,oss);
xmlrpc_c::value_array arrayresult_error(arrayData);
*retval = arrayresult_error;
return;
}
/* -------------------------------------------------------------------------- */

View File

@ -29,7 +29,8 @@ void RequestManager::VirtualMachineCancel::execute(
// <vid> of the vid to retrieve the information for
int vid;
int uid;
VirtualMachine * vm;
ostringstream oss;
@ -44,19 +45,31 @@ void RequestManager::VirtualMachineCancel::execute(
Nebula::log("ReM",Log::DEBUG,"VirtualMachineCancel method invoked");
// Get the parameters
//TODO the session id to validate with the SessionManager
session = xmlrpc_c::value_string(paramList.getString(0));
vid = xmlrpc_c::value_int (paramList.getInt(1));
// Perform the allocation in the vmpool
vm = VirtualMachineCancel::vmpool->get(vid,false);
// Retrieve the VM from the vmpool
vm = VirtualMachineCancel::vmpool->get(vid,true);
if ( vm == 0 )
{
goto error_vm_get;
}
//Deploy the VM
uid = vm->get_uid();
vm->unlock();
// Only oneadmin or the VM owner can perform operations upon the VM
rc = VirtualMachineCancel::upool->authenticate(session);
if ( rc != 0 && rc != uid)
{
goto error_authenticate;
}
//Cancel the VM
dm->cancel(vid);
@ -72,6 +85,10 @@ void RequestManager::VirtualMachineCancel::execute(
return;
error_authenticate:
oss << "User not authorized to cancel VM";
goto error_common;
error_vm_get:
oss << "Error getting vm for cancelling with VID = " << vid;
goto error_common;

View File

@ -28,6 +28,7 @@ void RequestManager::VirtualMachineDeploy::execute(
string session;
int vid;
int hid;
int uid;
int rc;
string hostname;
@ -69,15 +70,8 @@ void RequestManager::VirtualMachineDeploy::execute(
vmm_mad = host->get_vmm_mad();
tm_mad = host->get_tm_mad();
if (host->isManaged() == true)
{
nd.get_configuration_attribute("VM_DIR",vmdir);
}
else
{
goto error_host_managed;
}
nd.get_configuration_attribute("VM_DIR",vmdir);
host->unlock();
//Get the VM
@ -88,7 +82,17 @@ void RequestManager::VirtualMachineDeploy::execute(
{
goto error_vm_get;
}
uid = vm->get_uid();
// Only oneadmin or the VM owner can perform operations upon the VM
rc = VirtualMachineDeploy::upool->authenticate(session);
if ( rc != 0 && rc != uid)
{
goto error_authenticate;
}
if ( vm->get_state() != VirtualMachine::PENDING )
{
goto error_state;
@ -122,11 +126,10 @@ void RequestManager::VirtualMachineDeploy::execute(
delete arrayresult;
return;
error_host_managed:
host->unlock();
oss << "Not managed hosts (id:" << hid << ") not supported";
error_authenticate:
vm->unlock();
oss << "User not authorized to perform the deploy";
goto error_common;
error_host_get:

View File

@ -31,7 +31,6 @@ void RequestManager::HostAllocate::execute(
string im_mad_name;
string vmm_mad_name;
string tm_mad_name;
bool managed;
int hid;
@ -45,22 +44,25 @@ void RequestManager::HostAllocate::execute(
Nebula::log("ReM",Log::DEBUG,"HostAllocate method invoked");
// Get the parameters
//TODO the session id to validate with the SessionManager
session = xmlrpc_c::value_string(paramList.getString(0));
hostname = xmlrpc_c::value_string(paramList.getString(1));
im_mad_name = xmlrpc_c::value_string(paramList.getString(2));
vmm_mad_name = xmlrpc_c::value_string(paramList.getString(3));
tm_mad_name = xmlrpc_c::value_string(paramList.getString(4));
managed = xmlrpc_c::value_boolean(paramList.getBoolean(5));
// Only oneadmin can add new hosts
rc = HostAllocate::upool->authenticate(session);
if ( rc != 0 )
{
goto error_authenticate;
}
// Perform the allocation in the hostpool
rc = HostAllocate::hpool->allocate(&hid,
hostname,
im_mad_name,
vmm_mad_name,
tm_mad_name,
managed);
tm_mad_name);
if ( rc != 0 )
{
goto error_host_allocate;
@ -77,6 +79,10 @@ void RequestManager::HostAllocate::execute(
return;
error_authenticate:
oss << "User not authorized to add new hosts";
goto error_common;
error_host_allocate:
oss << "Can not allocate host " << hostname <<
" in the HostPool, returned error code [" << rc << "]";

View File

@ -40,10 +40,17 @@ void RequestManager::HostDelete::execute(
Nebula::log("ReM",Log::DEBUG,"HostDelete method invoked");
// Get the parameters
//TODO the session id to validate with the SessionManager
session = xmlrpc_c::value_string(paramList.getString(0));
hid = xmlrpc_c::value_int (paramList.getInt(1));
// Only oneadmin can delete hosts
rc = HostDelete::upool->authenticate(session);
if ( rc != 0 )
{
goto error_authenticate;
}
// Perform the allocation in the hostpool
host = HostDelete::hpool->get(hid,true);
@ -65,9 +72,15 @@ void RequestManager::HostDelete::execute(
return;
error_host_get:
error_authenticate:
oss << "User not authorized to delete hosts";
goto error_common;
error_host_get:
oss << "Error getting host with HID = " <<hid;
goto error_common;
error_common:
Nebula::log ("Rem",Log::ERROR,oss);
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE

View File

@ -28,6 +28,7 @@ void RequestManager::HostEnable::execute(
string session;
int hid;
int rc;
bool enable;
Host * host;
ostringstream oss;
@ -43,6 +44,14 @@ void RequestManager::HostEnable::execute(
hid = xmlrpc_c::value_int(paramList.getInt(1));
enable = xmlrpc_c::value_boolean(paramList.getBoolean(2));
// Only oneadmin can enable hosts
rc = HostEnable::upool->authenticate(session);
if ( rc != 0)
{
goto error_authenticate;
}
host = HostEnable::hpool->get(hid,true);
if ( host == 0 )
@ -74,9 +83,15 @@ void RequestManager::HostEnable::execute(
return;
error_authenticate:
oss << "Only oneadmin can enable hosts";
goto error_common;
error_host_get:
oss << "Error getting host with HID = " << hid;
oss << "Error getting host with HID = " << hid;
goto error_common;
error_common:
Nebula::log("ReM",Log::ERROR,oss);
arrayData.push_back(xmlrpc_c::value_boolean(false));

View File

@ -25,14 +25,13 @@ void RequestManager::HostInfo::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
string session;
// <hid> of the host to retrieve the information for
int hid;
int hid;
int rc;
Host * host;
Host * host;
ostringstream oss;
ostringstream oss;
/* -- RPC specific vars -- */
vector<xmlrpc_c::value> arrayData;
@ -41,10 +40,17 @@ void RequestManager::HostInfo::execute(
Nebula::log("ReM",Log::DEBUG,"HostInfo method invoked");
// Get the parameters
//TODO the session id to validate with the SessionManager
session = xmlrpc_c::value_string(paramList.getString(0));
hid = xmlrpc_c::value_int (paramList.getInt(1));
// Check if it is a valid user
rc = HostInfo::upool->authenticate(session);
if ( rc == -1 )
{
goto error_authenticate;
}
// Perform the allocation in the hostpool
host = HostInfo::hpool->get(hid,true);
@ -53,22 +59,26 @@ void RequestManager::HostInfo::execute(
goto error_host_get;
}
// All nice, return the host info to the client
arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS
oss.str("");
oss << *host;
host->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()));
arrayresult = new xmlrpc_c::value_array(arrayData);
// Copy arrayresult into retval mem space
arrayresult = new xmlrpc_c::value_array(arrayData);
*retval = *arrayresult;
// and get rid of the original
delete arrayresult;
delete arrayresult; // and get rid of the original
return;
error_authenticate:
oss << "User not authenticated, HostInfo call aborted.";
goto error_common;
error_host_get:
oss << "Error getting host with HID = " << hid;
goto error_common;

View File

@ -0,0 +1,95 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad */
/* Complutense de Madrid (dsa-research.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 "Nebula.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::HostPoolInfo::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
ostringstream oss;
int rc;
/* -- RPC specific vars -- */
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
Nebula::log("ReM",Log::DEBUG,"HostPoolInfo method invoked");
// Get the parameters
session = xmlrpc_c::value_string(paramList.getString(0));
// Check if it is a valid user
rc = HostPoolInfo::upool->authenticate(session);
if ( rc == -1 )
{
goto error_authenticate;
}
// Perform the allocation in the vmpool
rc = HostPoolInfo::hpool->dump(oss,"");
if ( rc != 0 )
{
goto error_dump;
}
//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()));
arrayresult = new xmlrpc_c::value_array(arrayData);
// Copy arrayresult into retval mem space
*retval = *arrayresult;
// and get rid of the original
delete arrayresult;
return;
error_authenticate:
oss << "User not authenticated, RequestManagerHostPoolInfo aborted.";
goto error_common;
error_dump:
oss << "Error getting host pool";
goto error_common;
error_common:
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
Nebula::log("ReM",Log::ERROR,oss);
xmlrpc_c::value_array arrayresult_error(arrayData);
*retval = arrayresult_error;
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -25,14 +25,12 @@ void RequestManager::VirtualMachineInfo::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
string session;
// <vid> of the vid to retrieve the information for
int vid;
VirtualMachine * vm;
ostringstream oss;
int vid;
VirtualMachine * vm;
ostringstream oss;
/* -- RPC specific vars -- */
vector<xmlrpc_c::value> arrayData;
@ -41,32 +39,30 @@ void RequestManager::VirtualMachineInfo::execute(
Nebula::log("ReM",Log::DEBUG,"VirtualMachineInfo method invoked");
// Get the parameters
//TODO the session id to validate with the SessionManager
session = xmlrpc_c::value_string(paramList.getString(0));
vid = xmlrpc_c::value_int (paramList.getInt(1));
// Perform the allocation in the vmpool
vm = VirtualMachineInfo::vmpool->get(vid,true);
if ( vm == 0 )
{
goto error_vm_get;
}
// All nice, return the vm info to the client
arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS
oss.str("");
oss << *vm;
vm->unlock();
// All nice, return the vm 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
arrayresult = new xmlrpc_c::value_array(arrayData);
*retval = *arrayresult;
// and get rid of the original
delete arrayresult;
delete arrayresult; // and get rid of the original
return;

View File

@ -28,6 +28,7 @@ void RequestManager::VirtualMachineMigrate::execute(
string session;
int vid;
int hid;
int uid;
int rc;
bool live;
@ -65,20 +66,13 @@ void RequestManager::VirtualMachineMigrate::execute(
{
goto error_host_get;
}
hostname = host->get_hostname();
vmm_mad = host->get_vmm_mad();
tm_mad = host->get_tm_mad();
if (host->isManaged() == true)
{
nd.get_configuration_attribute("VM_DIR",vmdir);
}
else
{
goto error_host_managed;
}
nd.get_configuration_attribute("VM_DIR",vmdir);
host->unlock();
//Get the VM and migrate it
@ -89,6 +83,16 @@ void RequestManager::VirtualMachineMigrate::execute(
{
goto error_vm_get;
}
uid = vm->get_uid();
// Only oneadmin or the VM owner can perform operations upon the VM
rc = VirtualMachineMigrate::upool->authenticate(session);
if ( rc != 0 && rc != uid)
{
goto error_authenticate;
}
if ((vm->get_state() != VirtualMachine::ACTIVE) ||
(vm->get_lcm_state() != VirtualMachine::RUNNING))
@ -130,10 +134,9 @@ void RequestManager::VirtualMachineMigrate::execute(
return;
error_host_managed:
host->unlock();
oss << "Not managed hosts (id:" << hid << ") not supported";
error_authenticate:
vm->unlock();
oss << "User not authorized to perform migration upon this VM";
goto error_common;
error_host_get:

View File

@ -26,11 +26,16 @@ void RequestManager::VirtualMachinePoolInfo::execute(
xmlrpc_c::value * const retval)
{
string session;
string username;
string password;
// <vid> of the vid to retrieve the information for
int vid, rc;
int filter_flag;
int rc;
ostringstream oss;
ostringstream where_string;
User * user;
/* -- RPC specific vars -- */
vector<xmlrpc_c::value> arrayData;
@ -39,12 +44,47 @@ void RequestManager::VirtualMachinePoolInfo::execute(
Nebula::log("ReM",Log::DEBUG,"VirtualMachinePoolInfo method invoked");
// Get the parameters
//TODO the session id to validate with the SessionManager
session = xmlrpc_c::value_string(paramList.getString(0));
vid = xmlrpc_c::value_int (paramList.getInt(1));
filter_flag = xmlrpc_c::value_int (paramList.getInt(1));
// Check if it is a valid user
rc = VirtualMachinePoolInfo::upool->authenticate(session);
if ( rc == -1 )
{
goto error_authenticate;
}
where_string.str("");
/** Filter flag meaning table
* <=-2 :: ALL VMs
* -1 :: User's VMs
* >=0 :: UID User's VMs
**/
if (filter_flag == -1)
{
User::split_secret(session,username,password);
// Now let's get the user
user = VirtualMachinePoolInfo::upool->get(username,true);
if ( user == 0 )
{
goto error_get_user;
}
where_string << "UID=" << user->get_uid();
user->unlock();
}
else if (filter_flag>=0)
{
where_string << "UID=" << filter_flag;
}
// Perform the allocation in the vmpool
rc = VirtualMachinePoolInfo::vmpool->dump(oss,"");
rc = VirtualMachinePoolInfo::vmpool->dump(oss,where_string.str());
if ( rc != 0 )
{
@ -63,6 +103,14 @@ void RequestManager::VirtualMachinePoolInfo::execute(
return;
error_authenticate:
oss << "User not authenticated, aborting RequestManagerPoolInfo call.";
goto error_common;
error_get_user:
oss << "An error ocurred getting the user from the UserPool, aborting RequestManagerPoolInfo call";
goto error_common;
error_dump:
oss << "Error getting the pool info";
goto error_common;

View File

@ -0,0 +1,116 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad */
/* Complutense de Madrid (dsa-research.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 "Nebula.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::UserAllocate::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
string username;
string password;
int uid;
int rc;
ostringstream oss;
User * user;
/* -- RPC specific vars -- */
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
Nebula::log("ReM",Log::DEBUG,"UserAllocate method invoked");
// Get the parameters
session = xmlrpc_c::value_string(paramList.getString(0));
username = xmlrpc_c::value_string(paramList.getString(1));
password = xmlrpc_c::value_string(paramList.getString(2));
// Only oneadmin can add users
rc = UserAllocate::upool->authenticate(session);
if ( rc != 0 )
{
goto error_authenticate;
}
// Let's make sure that the user doesn't exist in the database
user = UserAllocate::upool->get(username,false);
if (user != 0 )
{
goto error_duplicate;
}
// Now let's add the user
rc = UserAllocate::upool->allocate(&uid,username,password,true);
if ( rc != 0 )
{
goto error_allocate;
}
// All nice, return the new uid to client
arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS
arrayData.push_back(xmlrpc_c::value_int(uid));
// Copy arrayresult into retval mem space
arrayresult = new xmlrpc_c::value_array(arrayData);
*retval = *arrayresult;
delete arrayresult; // and get rid of the original
return;
error_authenticate:
oss << "User not authorized to add new users";
goto error_common;
error_duplicate:
oss << "Existing user, cannot duplicate";
goto error_common;
error_allocate:
oss << "Error allocating user";
goto error_common;
error_common:
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
Nebula::log("ReM",Log::ERROR,oss);
xmlrpc_c::value_array arrayresult_error(arrayData);
*retval = arrayresult_error;
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -0,0 +1,116 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad */
/* Complutense de Madrid (dsa-research.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 "Nebula.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::UserDelete::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
int uid;
User * user;
int rc;
ostringstream oss;
/* -- RPC specific vars -- */
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
Nebula::log("ReM",Log::DEBUG,"UserDelete method invoked");
// Get the parameters
session = xmlrpc_c::value_string(paramList.getString(0));
uid = xmlrpc_c::value_int(paramList.getInt(1));
// oneadmin cannot be deleted
if ( uid == 0 )
{
goto error_oneadmin_deletion;
}
// Only oneadmin can delete users
rc = UserDelete::upool->authenticate(session);
if ( rc != 0 )
{
goto error_authenticate;
}
// Now let's get the user
user = UserDelete::upool->get(uid,true);
if ( user == 0)
{
goto error_get_user;
}
rc = UserDelete::upool->drop(user);
if ( rc != 0 )
{
goto error_delete;
}
// All nice, return the new uid to client
arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS
// 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_oneadmin_deletion:
oss << "User oneadmin cannot be deleted";
goto error_common;
error_authenticate:
oss << "User not authorized to add new users";
goto error_common;
error_get_user:
oss << "Error retrieving user " << uid;
goto error_common;
error_delete:
oss << "Error deleting user " << uid;
goto error_common;
error_common:
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
Nebula::log("ReM",Log::ERROR,oss);
xmlrpc_c::value_array arrayresult_error(arrayData);
*retval = arrayresult_error;
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -0,0 +1,101 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad */
/* Complutense de Madrid (dsa-research.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 "Nebula.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::UserInfo::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
int uid;
User * user;
int rc;
ostringstream oss;
/* -- RPC specific vars -- */
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
Nebula::log("ReM",Log::DEBUG,"UserInfo method invoked");
// Get the parameters
session = xmlrpc_c::value_string(paramList.getString(0));
uid = xmlrpc_c::value_int(paramList.getInt(1));
// Only oneadmin can retrieve user information
rc = UserInfo::upool->authenticate(session);
if ( rc != 0 )
{
goto error_authenticate;
}
// Now let's get the user
user = UserInfo::upool->get(uid,true);
if ( user == 0 )
{
goto error_get_user;
}
oss << *user;
user->unlock();
// All nice, return the new uid to 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_authenticate:
oss << "User not authorized to retrieve user information";
goto error_common;
error_get_user:
oss << "Error getting user";
goto error_common;
error_common:
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
Nebula::log("ReM",Log::ERROR,oss);
xmlrpc_c::value_array arrayresult_error(arrayData);
*retval = arrayresult_error;
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -0,0 +1,93 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad */
/* Complutense de Madrid (dsa-research.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 "Nebula.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::UserPoolInfo::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
int rc;
ostringstream oss;
/* -- RPC specific vars -- */
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
Nebula::log("ReM",Log::DEBUG,"UserPoolInfo method invoked");
// Get the parameters
session = xmlrpc_c::value_string(paramList.getString(0));
// Only oneadmin can list the whole user pool
rc = UserPoolInfo::upool->authenticate(session);
if ( rc != 0 )
{
goto error_authenticate;
}
// Now let's get the info
rc = UserPoolInfo::upool->dump(oss,"");
if ( rc != 0 )
{
goto error_dumping;
}
// All nice, return the new uid to client
arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
arrayresult = new xmlrpc_c::value_array(arrayData);
// Copy arrayresult into retval mem space
*retval = *arrayresult;
// and get rid of the original
delete arrayresult;
return;
error_authenticate:
oss << "User not authorized to pull user pool info. Error code: " << rc;
goto error_common;
error_dumping:
oss << "Error dumping pool info";
goto error_common;
error_common:
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
Nebula::log("ReM",Log::ERROR,oss);
xmlrpc_c::value_array arrayresult_error(arrayData);
*retval = arrayresult_error;
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -26,14 +26,17 @@ void RequestManager::VirtualNetworkAllocate::execute(
xmlrpc_c::value * const retval)
{
string session;
string username;
string password;
string name;
string stemplate;
int nid;
int uid;
int rc;
User * user;
ostringstream oss;
/* -- RPC specific vars -- */
@ -45,8 +48,25 @@ void RequestManager::VirtualNetworkAllocate::execute(
// Get the parameters & host
session = xmlrpc_c::value_string(paramList.getString(0));
stemplate = xmlrpc_c::value_string(paramList.getString(1));
if ( User::split_secret(session,username,password) != 0 )
{
goto error_session;
}
rc = vnpool->allocate(0,stemplate,&nid);
// Now let's get the user
user = VirtualNetworkAllocate::upool->get(username,true);
if ( user == 0 )
{
goto error_get_user;
}
uid = user->get_uid();
user->unlock();
rc = vnpool->allocate(uid,stemplate,&nid);
if ( rc != 0 )
{
@ -64,9 +84,20 @@ void RequestManager::VirtualNetworkAllocate::execute(
return;
error_session:
oss << "Session information malformed, cannot allocate VirtualNetwork";
goto error_common;
error_get_user:
oss << "User not recognized, cannot allocate VirtualNetwork";
goto error_common;
error_vn_allocate:
oss << "Error allocating VN with template: " << endl << stemplate;
goto error_common;
error_common:
Nebula::log("ReM",Log::ERROR,oss);
arrayData.push_back(xmlrpc_c::value_boolean(false));

View File

@ -29,7 +29,8 @@ void RequestManager::VirtualNetworkDelete::execute(
string name;
int nid;
int uid;
VirtualNetwork * vn;
int rc;
@ -45,13 +46,23 @@ void RequestManager::VirtualNetworkDelete::execute(
session = xmlrpc_c::value_string(paramList.getString(0));
nid = xmlrpc_c::value_int (paramList.getInt (1));
// Perform the allocation in the hostpool
// Retrieve VN from the pool
vn = vnpool->get(nid,true);
if ( vn == 0 )
{
goto error_vn_get;
}
uid = vn->get_uid();
// Only oneadmin or the VN owner can perform operations upon the VN
rc = VirtualNetworkDelete::upool->authenticate(session);
if ( rc != 0 && rc != uid)
{
goto error_authenticate;
}
rc = vnpool->drop(vn);
@ -66,9 +77,16 @@ void RequestManager::VirtualNetworkDelete::execute(
return;
error_vn_get:
error_authenticate:
vn->unlock();
oss << "User cannot delete VN";
goto error_common;
error_vn_get:
oss << "Error getting Virtual Network with NID = " << nid;
goto error_common;
error_common:
Nebula::log ("Rem",Log::ERROR,oss);
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE

View File

@ -28,6 +28,7 @@ void RequestManager::VirtualNetworkInfo::execute(
string session;
int nid;
int rc;
string info;
VirtualNetwork * vn;
@ -43,30 +44,42 @@ void RequestManager::VirtualNetworkInfo::execute(
// Get the parameters & host
session = xmlrpc_c::value_string(paramList.getString(0));
nid = xmlrpc_c::value_int (paramList.getInt (1));
// Check if it is a valid user
rc = VirtualNetworkInfo::upool->authenticate(session);
if ( rc == -1 )
{
goto error_authenticate;
}
vn = vnpool->get(nid,true);
if ( vn == 0 )
{
goto error_vn_get;
}
// All nice, return the Virtual Network info to the client
arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS
oss.str("");
oss << *vn;
vn->unlock();
// All nice, return the Virtual Network 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
arrayresult = new xmlrpc_c::value_array(arrayData);
*retval = *arrayresult;
// and get rid of the original
delete arrayresult;
delete arrayresult; // and get rid of the original
return;
error_authenticate:
oss << "User not authenticated, VirtualNetworkInfo call aborted.";
goto error_common;
error_vn_get:
oss << "Error getting Virtual Network with NID = " << nid;
goto error_common;

View File

@ -0,0 +1,135 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad */
/* Complutense de Madrid (dsa-research.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 "Nebula.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::VirtualNetworkPoolInfo::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
string username;
string password;
ostringstream oss;
ostringstream where_string;
int rc;
int filter_flag;
User * user;
/* -- RPC specific vars -- */
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
Nebula::log("ReM",Log::DEBUG,"VirtualNetworkPoolInfo 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 = VirtualNetworkPoolInfo::upool->authenticate(session);
if ( rc == -1 )
{
goto error_authenticate;
}
where_string.str("");
/** Filter flag meaning table
* <=-2 :: ALL VMs
* -1 :: User's VMs
* >=0 :: UID User's VMs
**/
if (filter_flag == -1)
{
User::split_secret(session,username,password);
// Now let's get the user
user = VirtualNetworkPoolInfo::upool->get(username,true);
if ( user == 0 )
{
goto error_get_user;
}
where_string << "UID=" << user->get_uid();
user->unlock();
}
else if (filter_flag>=0)
{
where_string << "UID=" << filter_flag;
}
// Perform the allocation in the vmpool
rc = VirtualNetworkPoolInfo::vnpool->dump(oss,where_string.str());
if ( rc != 0 )
{
goto error_dump;
}
//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()));
arrayresult = new xmlrpc_c::value_array(arrayData);
// Copy arrayresult into retval mem space
*retval = *arrayresult;
// and get rid of the original
delete arrayresult;
return;
error_authenticate:
oss << "User not authenticated, NetworkPoolInfo call aborted.";
goto error_common;
error_get_user:
oss << "Error getting user, aborting NetworkPoolInfo call";
goto error_common;
error_dump:
oss << "Error getting virtual network pool";
goto error_common;
error_common:
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
Nebula::log("ReM",Log::ERROR,oss);
xmlrpc_c::value_array arrayresult_error(arrayData);
*retval = arrayresult_error;
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -33,10 +33,16 @@ source_files=[
'RequestManagerHostAllocate.cc',
'RequestManagerHostDelete.cc',
'RequestManagerHostInfo.cc',
'RequestManagerHostPoolInfo.cc',
'RequestManagerHostEnable.cc',
'RequestManagerVirtualNetworkAllocate.cc',
'RequestManagerVirtualNetworkInfo.cc',
'RequestManagerVirtualNetworkPoolInfo.cc',
'RequestManagerVirtualNetworkDelete.cc',
'RequestManagerUserAllocate.cc',
'RequestManagerUserInfo.cc',
'RequestManagerUserDelete.cc',
'RequestManagerUserPoolInfo.cc'
]
# Build library

View File

@ -41,6 +41,7 @@ env.StaticLibrary(lib_name, source_files)
env.Append(LIBS=[
'sqlite3',
'crypto',
lib_name,
'nebula_core',
'nebula_host',
@ -49,6 +50,7 @@ env.Append(LIBS=[
'nebula_pool',
'nebula_template',
'nebula_common',
'nebula_um',
])

View File

@ -31,6 +31,7 @@
#include "Scheduler.h"
#include "RankPolicy.h"
#include "Nebula.h"
#include "User.h"
using namespace std;
@ -87,6 +88,24 @@ void Scheduler::start()
throw;
}
const char * one_auth;
string one_name;
string one_pass;
one_auth = getenv("ONE_AUTH");
if (!one_auth)
{
throw runtime_error("ONE_AUTH variable not defined");
}
if ( User::split_secret(one_auth,one_name,one_pass) != 0 )
{
throw runtime_error("ONE_AUTH must be <username>:<password>");
}
secret = one_name + ":" + User::sha1_digest(one_pass);
// -----------------------------------------------------------
// Pools
// -----------------------------------------------------------
@ -421,10 +440,10 @@ void Scheduler::dispatch()
{
xmlrpc_client.call(
one_url,
"one.vmdeploy",
"one.vm.deploy",
"sii",
&deploy_result,
"session",
secret.c_str(),
vm->get_oid(),
hid);
}

View File

@ -97,10 +97,22 @@ void TransferManager::trigger(Actions action, int _vid)
aname = "EPILOG_STOP";
break;
case EPILOG_DELETE:
aname = "EPILOG_DELETE";
break;
case EPILOG_DELETE_PREVIOUS:
aname = "EPILOG_DELETE_PREVIOUS";
break;
case CHECKPOINT:
aname = "CHECKPOINT";
break;
case DRIVER_CANCEL:
aname = "DRIVER_CANCEL";
break;
case FINALIZE:
aname = ACTION_FINALIZE;
break;
@ -149,10 +161,22 @@ void TransferManager::do_action(const string &action, void * arg)
{
epilog_stop_action(vid);
}
else if (action == "EPILOG_DELETE")
{
epilog_delete_action(vid);
}
else if (action == "EPILOG_DELETE_PREVIOUS")
{
epilog_delete_previous_action(vid);
}
else if (action == "CHECKPOINT")
{
checkpoint_action(vid);
}
else if (action == "DRIVER_CANCEL")
{
driver_cancel_action(vid);
}
else if (action == ACTION_FINALIZE)
{
Nebula::log("TrM",Log::INFO,"Stopping Transfer Manager...");
@ -217,7 +241,8 @@ void TransferManager::prolog_action(int vid)
goto error_driver;
}
xfr.open(vm->get_transfer_file().c_str(), ios::out | ios::trunc);
xfr_name = vm->get_transfer_file() + ".prolog";
xfr.open(xfr_name.c_str(), ios::out | ios::trunc);
if (xfr.fail() == true)
{
@ -356,7 +381,7 @@ void TransferManager::prolog_action(int vid)
xfr.close();
tm_md->transfer(vid,vm->get_transfer_file());
tm_md->transfer(vid,xfr_name);
vm->unlock();
@ -374,7 +399,7 @@ error_history:
error_file:
os.str("");
os << "prolog, could not open file: " << vm->get_transfer_file();
os << "prolog, could not open file: " << xfr_name;
goto error_common;
error_driver:
@ -386,7 +411,6 @@ error_empty_disk:
os.str("");
os << "prolog, undefined source disk image in VM template";
xfr.close();
goto error_common;
error_common:
(nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid);
@ -403,6 +427,7 @@ void TransferManager::prolog_migr_action(int vid)
{
ofstream xfr;
ostringstream os;
string xfr_name;
VirtualMachine * vm;
Nebula& nd = Nebula::instance();
@ -433,7 +458,8 @@ void TransferManager::prolog_migr_action(int vid)
goto error_driver;
}
xfr.open(vm->get_transfer_file().c_str(), ios::out | ios::trunc);
xfr_name = vm->get_transfer_file() + ".migrate";
xfr.open(xfr_name.c_str(), ios::out | ios::trunc);
if (xfr.fail() == true)
{
@ -450,7 +476,7 @@ void TransferManager::prolog_migr_action(int vid)
xfr.close();
tm_md->transfer(vid,vm->get_transfer_file());
tm_md->transfer(vid,xfr_name);
vm->unlock();
@ -463,13 +489,12 @@ error_history:
error_file:
os.str("");
os << "prolog_migr, could not open file: " << vm->get_transfer_file();
os << "prolog_migr, could not open file: " << xfr_name;
goto error_common;
error_driver:
os.str("");
os << "prolog_migr, error getting driver " << vm->get_tm_mad();
goto error_common;
error_common:
(nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid);
@ -477,8 +502,6 @@ error_common:
vm->unlock();
return;
(nd.get_lcm())->trigger(LifeCycleManager::PROLOG_SUCCESS,vid);
}
/* -------------------------------------------------------------------------- */
@ -488,6 +511,7 @@ void TransferManager::prolog_resume_action(int vid)
{
ofstream xfr;
ostringstream os;
string xfr_name;
VirtualMachine * vm;
Nebula& nd = Nebula::instance();
@ -518,7 +542,8 @@ void TransferManager::prolog_resume_action(int vid)
goto error_driver;
}
xfr.open(vm->get_transfer_file().c_str(), ios::out | ios::trunc);
xfr_name = vm->get_transfer_file() + ".resume";
xfr.open(xfr_name.c_str(), ios::out | ios::trunc);
if (xfr.fail() == true)
{
@ -535,7 +560,7 @@ void TransferManager::prolog_resume_action(int vid)
xfr.close();
tm_md->transfer(vid,vm->get_transfer_file());
tm_md->transfer(vid,xfr_name);
vm->unlock();
@ -548,13 +573,12 @@ error_history:
error_file:
os.str("");
os << "prolog_resume, could not open file: " << vm->get_transfer_file();
os << "prolog_resume, could not open file: " << xfr_name;
goto error_common;
error_driver:
os.str("");
os << "prolog_resume, error getting driver " << vm->get_tm_mad();
goto error_common;
error_common:
(nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid);
@ -575,9 +599,7 @@ void TransferManager::epilog_action(int vid)
string xfr_name;
const VectorAttribute * disk;
string source;
string save;
string clon;
VirtualMachine * vm;
Nebula& nd = Nebula::instance();
@ -587,7 +609,6 @@ void TransferManager::epilog_action(int vid)
vector<const Attribute *> attrs;
int num;
// ------------------------------------------------------------------------
// Setup & Transfer script
// ------------------------------------------------------------------------
@ -611,7 +632,8 @@ void TransferManager::epilog_action(int vid)
goto error_driver;
}
xfr.open(vm->get_transfer_file().c_str(), ios::out | ios::trunc);
xfr_name = vm->get_transfer_file() + ".epilog";
xfr.open(xfr_name.c_str(), ios::out | ios::trunc);
if (xfr.fail() == true)
{
@ -655,7 +677,7 @@ void TransferManager::epilog_action(int vid)
xfr.close();
tm_md->transfer(vid,vm->get_transfer_file());
tm_md->transfer(vid,xfr_name);
vm->unlock();
@ -668,13 +690,12 @@ error_history:
error_file:
os.str("");
os << "epilog, could not open file: " << vm->get_transfer_file();
os << "epilog, could not open file: " << xfr_name;
goto error_common;
error_driver:
os.str("");
os << "epilog, error getting driver " << vm->get_vmm_mad();
goto error_common;
error_common:
(nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid);
@ -691,6 +712,7 @@ void TransferManager::epilog_stop_action(int vid)
{
ofstream xfr;
ostringstream os;
string xfr_name;
VirtualMachine * vm;
Nebula& nd = Nebula::instance();
@ -721,7 +743,8 @@ void TransferManager::epilog_stop_action(int vid)
goto error_driver;
}
xfr.open(vm->get_transfer_file().c_str(), ios::out | ios::trunc);
xfr_name = vm->get_transfer_file() + ".stop";
xfr.open(xfr_name.c_str(), ios::out | ios::trunc);
if (xfr.fail() == true)
{
@ -738,7 +761,7 @@ void TransferManager::epilog_stop_action(int vid)
xfr.close();
tm_md->transfer(vid,vm->get_transfer_file());
tm_md->transfer(vid,xfr_name);
vm->unlock();
@ -751,13 +774,12 @@ error_history:
error_file:
os.str("");
os << "epilog_stop, could not open file: " << vm->get_transfer_file();
os << "epilog_stop, could not open file: " << xfr_name;
goto error_common;
error_driver:
os.str("");
os << "epilog_stop, error getting driver " << vm->get_tm_mad();
goto error_common;
error_common:
(nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid);
@ -767,6 +789,236 @@ error_common:
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void TransferManager::epilog_delete_action(int vid)
{
ofstream xfr;
ostringstream os;
string xfr_name;
VirtualMachine * vm;
const TransferManagerDriver * tm_md;
// ------------------------------------------------------------------------
// Setup & Transfer script
// ------------------------------------------------------------------------
vm = vmpool->get(vid,true);
if (vm == 0)
{
return;
}
if (!vm->hasHistory())
{
goto error_history;
}
tm_md = get(vm->get_uid(),vm->get_tm_mad());
if ( tm_md == 0 )
{
goto error_driver;
}
xfr_name = vm->get_transfer_file() + ".delete";
xfr.open(xfr_name.c_str(), ios::out | ios::trunc);
if (xfr.fail() == true)
{
goto error_file;
}
// ------------------------------------------------------------------------
// Delete the remote VM Directory
// ------------------------------------------------------------------------
xfr << "DELETE " << vm->get_hostname() <<":"<< vm->get_remote_dir() << endl;
xfr.close();
tm_md->transfer(vid,xfr_name);
vm->unlock();
return;
error_history:
os.str("");
os << "epilog_delete, VM " << vid << " has no history";
goto error_common;
error_file:
os.str("");
os << "epilog_delete, could not open file: " << xfr_name;
os << ". You may need to manually clean " << vm->get_hostname()
<< ":" << vm->get_remote_dir();
goto error_common;
error_driver:
os.str("");
os << "epilog_delete, error getting driver " << vm->get_vmm_mad();
os << ". You may need to manually clean " << vm->get_hostname()
<< ":" << vm->get_remote_dir();
error_common:
vm->log("TM", Log::ERROR, os);
vm->unlock();
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void TransferManager::epilog_delete_previous_action(int vid)
{
ofstream xfr;
ostringstream os;
string xfr_name;
VirtualMachine * vm;
const TransferManagerDriver * tm_md;
// ------------------------------------------------------------------------
// Setup & Transfer script
// ------------------------------------------------------------------------
vm = vmpool->get(vid,true);
if (vm == 0)
{
return;
}
if (!vm->hasHistory() || !vm->hasPreviousHistory())
{
goto error_history;
}
tm_md = get(vm->get_uid(),vm->get_previous_tm_mad());
if ( tm_md == 0 )
{
goto error_driver;
}
xfr_name = vm->get_transfer_file() + ".delete_prev";
xfr.open(xfr_name.c_str(),ios::out | ios::trunc);
if (xfr.fail() == true)
{
goto error_file;
}
// ------------------------------------------------------------------------
// Delete the remote VM Directory
// ------------------------------------------------------------------------
xfr << "DELETE " << vm->get_previous_hostname() <<":"<< vm->get_remote_dir()
<< endl;
xfr.close();
tm_md->transfer(vid,xfr_name);
vm->unlock();
return;
error_history:
os.str("");
os << "epilog_delete_previous, VM " << vid << " has no history";
goto error_common;
error_file:
os.str("");
os << "epilog_delete, could not open file: " << xfr_name;
os << ". You may need to manually clean " << vm->get_previous_hostname()
<< ":" << vm->get_remote_dir();
goto error_common;
error_driver:
os.str("");
os << "epilog_delete, error getting driver " << vm->get_vmm_mad();
os << ". You may need to manually clean " << vm->get_previous_hostname()
<< ":" << vm->get_remote_dir();
error_common:
vm->log("TM", Log::ERROR, os);
vm->unlock();
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void TransferManager::driver_cancel_action(int vid)
{
ofstream xfr;
ostringstream os;
string xfr_name;
VirtualMachine * vm;
const TransferManagerDriver * tm_md;
// ------------------------------------------------------------------------
// Get the Driver for this host
// ------------------------------------------------------------------------
vm = vmpool->get(vid,true);
if (vm == 0)
{
return;
}
if (!vm->hasHistory())
{
goto error_history;
}
tm_md = get(vm->get_uid(),vm->get_tm_mad());
if ( tm_md == 0 )
{
goto error_driver;
}
// ------------------------------------------------------------------------
// Cancel the current operation
// ------------------------------------------------------------------------
tm_md->driver_cancel(vid);
vm->unlock();
return;
error_history:
os.str("");
os << "driver_cancel, VM " << vid << " has no history";
goto error_common;
error_driver:
os.str("");
os << "driver_cancel, error getting driver " << vm->get_vmm_mad();
error_common:
vm->log("TM", Log::ERROR, os);
vm->unlock();
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -95,6 +95,18 @@ void TransferManagerDriver::protocol(
return;
}
if ( vm->get_lcm_state() == VirtualMachine::DELETE ||
vm->get_lcm_state() == VirtualMachine::FAILURE||
vm->get_lcm_state() == VirtualMachine::LCM_INIT )
{
os.str("");
os << "Ignored: " << message;
vm->log("TM",Log::WARNING,os);
vm->unlock();
return;
}
// Driver Actions
if (action == "TRANSFER")
{

View File

@ -46,7 +46,7 @@ exec_and_log "ssh $DST_HOST mkdir -p $DST_DIR"
case $SRC in
http://*)
log "Downloading $SRC"
exec_and_log "ssh $DST_HOST wget -O $DST_PATH $SRC_PATH"
exec_and_log "ssh $DST_HOST wget -O $DST_PATH $SRC"
;;
*)

31
src/um/SConstruct Normal file
View File

@ -0,0 +1,31 @@
# SConstruct for src/vm
# -------------------------------------------------------------------------- #
# Copyright 2002-2009, Distributed Systems Architecture Group, Universidad #
# Complutense de Madrid (dsa-research.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_um'
# Sources to generate the library
source_files=[
'User.cc',
'UserPool.cc'
]
# Build library
env.StaticLibrary(lib_name, source_files)

396
src/um/User.cc Normal file
View File

@ -0,0 +1,396 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad */
/* Complutense de Madrid (dsa-research.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <openssl/evp.h>
#include <iomanip>
#include "User.h"
/* ************************************************************************** */
/* User :: Constructor/Destructor */
/* ************************************************************************** */
User::User(
int id,
string _username,
string _password,
bool _enabled):
PoolObjectSQL(id),
username (_username),
password (_password),
enabled (_enabled)
{};
User::~User(){};
/* ************************************************************************** */
/* User :: Database Access Functions */
/* ************************************************************************** */
const char * User::table = "user_pool";
const char * User::db_names = "(oid,user_name,password,enabled)";
const char * User::db_bootstrap = "CREATE TABLE user_pool ("
"oid INTEGER,user_name TEXT,password TEXT,"
"enabled INTEGER, PRIMARY KEY(oid,user_name), UNIQUE(user_name))";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int User::unmarshall(int num, char **names, char ** values)
{
if ((!values[OID]) ||
(!values[USERNAME]) ||
(!values[PASSWORD]) ||
(!values[ENABLED]) ||
(num != LIMIT ))
{
return -1;
}
oid = atoi(values[OID]);
username = values[USERNAME];
password = values[PASSWORD];
enabled = (atoi(values[ENABLED])==0)?false:true;
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
extern "C" int user_select_cb (
void * _user,
int num,
char ** values,
char ** names)
{
User * user;
user = static_cast<User *>(_user);
if (user == 0)
{
return -1;
}
return user->unmarshall(num,names,values);
};
/* -------------------------------------------------------------------------- */
int User::select(SqliteDB *db)
{
ostringstream oss;
int rc;
int boid;
oss << "SELECT * FROM " << table << " WHERE oid = " << oid;
boid = oid;
oid = -1;
rc = db->exec(oss, user_select_cb, (void *) this);
if ((rc != 0) || (oid != boid ))
{
return -1;
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int User::insert(SqliteDB *db)
{
int rc;
rc = update(db);
if ( rc != 0 )
{
return rc;
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int User::update(SqliteDB *db)
{
ostringstream oss;
int rc;
char * sql_username;
char * sql_password;
int str_enabled = enabled?1:0;
// Update the User
sql_username = sqlite3_mprintf("%q",username.c_str());
if ( sql_username == 0 )
{
goto error_username;
}
sql_password = sqlite3_mprintf("%q",password.c_str());
if ( sql_password == 0 )
{
goto error_password;
}
// Construct the SQL statement to Insert or Replace (effectively, update)
oss << "INSERT OR REPLACE INTO " << table << " "<< db_names <<" VALUES ("
<< oid << ","
<< "'" << sql_username << "',"
<< "'" << sql_password << "',"
<< str_enabled << ")";
rc = db->exec(oss);
sqlite3_free(sql_username);
sqlite3_free(sql_password);
return rc;
error_password:
sqlite3_free(sql_username);
error_username:
return -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int User::unmarshall(ostringstream& oss,
int num,
char ** names,
char ** values)
{
if ((!values[OID]) ||
(!values[USERNAME]) ||
(!values[PASSWORD]) ||
(!values[ENABLED]) ||
(num != LIMIT))
{
return -1;
}
string str_enabled = (atoi(values[ENABLED])==0)?"Fase":"True";
oss <<
"<USER>" <<
"<ID>" << values[OID] <<"</ID>" <<
"<NAME>" << values[USERNAME] <<"</NAME>" <<
"<PASSWORD>" << values[PASSWORD] <<"</PASSWORD>" <<
"<ENABLED>" << str_enabled <<"</ENABLED>" <<
"</USER>";
return 0;
}
/* -------------------------------------------------------------------------- */
extern "C" int user_dump_cb (
void * _oss,
int num,
char ** values,
char ** names)
{
ostringstream * oss;
oss = static_cast<ostringstream *>(_oss);
if (oss == 0)
{
return -1;
}
return User::unmarshall(*oss,num,names,values);
};
/* -------------------------------------------------------------------------- */
int User::dump(SqliteDB * db, ostringstream& oss, const string& where)
{
int rc;
ostringstream cmd;
cmd << "SELECT * FROM " << User::table;
if ( !where.empty() )
{
cmd << " WHERE " << where;
}
rc = db->exec(cmd,user_dump_cb,(void *) &oss);
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int User::drop(SqliteDB * db)
{
ostringstream oss;
oss << "DELETE FROM " << table << " WHERE oid=" << oid;
return db->exec(oss);
}
/* ************************************************************************** */
/* User :: Misc */
/* ************************************************************************** */
ostream& operator<<(ostream& os, User& user)
{
string user_str;
os << user.to_xml(user_str);
return os;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& User::to_xml(string& xml) const
{
ostringstream oss;
int enabled_int = enabled?1:0;
oss <<
"<USER>"
"<ID>" << oid <<"</ID>" <<
"<NAME>" << username <<"</NAME>" <<
"<PASSWORD>" << password <<"</PASSWORD>" <<
"<ENABLED>" << enabled_int <<"</ENABLED>" <<
"</USER>";
xml = oss.str();
return xml;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& User::to_str(string& str) const
{
ostringstream os;
string enabled_str = enabled?"True":"False";
os <<
"ID = " << oid << endl <<
"NAME = " << username << endl <<
"PASSWORD = " << password << endl <<
"ENABLED = " << enabled_str;
str = os.str();
return str;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int User::authenticate(string _password)
{
if (enabled && _password==password)
{
return oid;
}
else
{
return -1;
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int User::split_secret(const string secret, string& user, string& pass)
{
size_t pos;
int rc = -1;
pos=secret.find(":");
if (pos != string::npos)
{
user = secret.substr(0,pos);
pass = secret.substr(pos+1);
rc = 0;
}
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string User::sha1_digest(const string& pass)
{
EVP_MD_CTX mdctx;
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len;
ostringstream oss;
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, EVP_sha1(), NULL);
EVP_DigestUpdate(&mdctx, pass.c_str(), pass.length());
EVP_DigestFinal_ex(&mdctx,md_value,&md_len);
EVP_MD_CTX_cleanup(&mdctx);
for(unsigned int i = 0; i<md_len; i++)
{
oss << setfill('0') << setw(2) << hex << nouppercase
<< (unsigned short) md_value[i];
}
return oss.str();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

172
src/um/UserPool.cc Normal file
View File

@ -0,0 +1,172 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad */
/* Complutense de Madrid (dsa-research.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. */
/* -------------------------------------------------------------------------- */
/* ************************************************************************** */
/* User Pool */
/* ************************************************************************** */
#include "UserPool.h"
#include "Nebula.h"
#include <sys/types.h>
#include <pwd.h>
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
extern "C"
{
static int getuids_cb(
void * _known_users,
int num,
char ** values,
char ** names)
{
map<string, int> * known_users;
known_users = static_cast<map<string, int> *>(_known_users);
if ( num == 0 || values == 0 || values[0] == 0 )
{
return -1;
}
known_users->insert(make_pair(values[1],atoi(values[0])));
return 0;
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
UserPool::UserPool(SqliteDB * db):PoolSQL(db,User::table)
{
// The known_users table needs to be rebuilt
ostringstream sql;
sql << "SELECT oid,user_name FROM " << User::table;
db->exec(sql, getuids_cb, (void *) &known_users);
if ((int) known_users.size() == 0)
{
// User oneadmin needs to be added in the bootstrap
struct passwd * pw_ent;
int one_uid = -1;
ostringstream oss;
pw_ent = getpwuid(getuid());
if ((pw_ent != NULL) && (pw_ent->pw_name != NULL))
{
string one_name;
string one_pass;
const char * one_auth;
one_name = pw_ent->pw_name;
one_auth = getenv("ONE_AUTH");
if ( one_auth != 0 )
{
if ( User::split_secret(one_auth,one_name,one_pass) == 0 )
{
string sha1_pass = User::sha1_digest(one_pass);
allocate(&one_uid, one_name, sha1_pass, true);
}
else
{
oss << "ONE_AUTH must be <username>:<password>";
}
}
else
{
oss << "Environment variable ONE_AUTH is not set";
}
}
else
{
oss << "Error getting the user info";
}
if (one_uid != 0)
{
Nebula::log("ONE",Log::ERROR,oss);
throw;
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int UserPool::allocate (
int * oid,
string username,
string password,
bool enabled)
{
User * user;
// Build a new User object
user = new User(-1,
username,
password,
enabled);
// Insert the Object in the pool
*oid = PoolSQL::allocate(user);
// Add the user to the map of known_users
known_users.insert(make_pair(username,*oid));
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int UserPool::authenticate(string& session)
{
map<string, int>::iterator index;
string username;
string password;
int user_id = -1;
// session holds username:password
if ( User::split_secret(session,username,password) == 0 )
{
index = known_users.find(username);
if ( index != known_users.end() )
{
User * user = get((int)index->second,false);
user_id = user->authenticate(password);
}
}
return user_id;
}

View File

@ -221,51 +221,51 @@ error_hostname:
int History::unmarshall(int num, char **names, char ** values)
{
if ((values[VID] == 0) ||
(values[SEQ] == 0) ||
(values[HOSTNAME] == 0) ||
(values[VM_DIR] == 0) ||
(values[HID] == 0) ||
(values[VMMMAD] == 0) ||
(values[TMMAD] == 0) ||
(values[STIME] == 0) ||
(values[ETIME] == 0) ||
(values[PROLOG_STIME] == 0) ||
(values[PROLOG_ETIME] == 0) ||
(values[RUNNING_STIME] == 0) ||
(values[RUNNING_ETIME] == 0) ||
(values[EPILOG_STIME] == 0) ||
(values[EPILOG_ETIME] == 0) ||
(values[REASON] == 0) ||
(num != LIMIT ))
if ((!values[VID]) ||
(!values[SEQ]) ||
(!values[HOSTNAME]) ||
(!values[VM_DIR]) ||
(!values[HID]) ||
(!values[VMMMAD]) ||
(!values[TMMAD]) ||
(!values[STIME]) ||
(!values[ETIME]) ||
(!values[PROLOG_STIME]) ||
(!values[PROLOG_ETIME]) ||
(!values[RUNNING_STIME]) ||
(!values[RUNNING_ETIME]) ||
(!values[EPILOG_STIME]) ||
(!values[EPILOG_ETIME]) ||
(!values[REASON]) ||
(num != LIMIT ))
{
return -1;
}
oid = atoi(values[VID]);
seq = atoi(values[SEQ]);
oid = atoi(values[VID]);
seq = atoi(values[SEQ]);
hostname = values[HOSTNAME];
vm_dir = values[VM_DIR];
hid = atoi(values[HID]);
hostname = values[HOSTNAME];
vm_dir = values[VM_DIR];
vmm_mad_name = values[VMMMAD];
tm_mad_name = values[TMMAD];
hid = atoi(values[HID]);
stime = static_cast<time_t>(atoi(values[STIME]));
etime = static_cast<time_t>(atoi(values[ETIME]));
vmm_mad_name = values[VMMMAD];
tm_mad_name = values[TMMAD];
stime = static_cast<time_t>(atoi(values[STIME]));
etime = static_cast<time_t>(atoi(values[ETIME]));
prolog_stime = static_cast<time_t>(atoi(values[PROLOG_STIME]));
prolog_etime = static_cast<time_t>(atoi(values[PROLOG_ETIME]));
prolog_stime = static_cast<time_t>(atoi(values[PROLOG_STIME]));
prolog_etime = static_cast<time_t>(atoi(values[PROLOG_ETIME]));
running_stime = static_cast<time_t>(atoi(values[RUNNING_STIME]));
running_etime = static_cast<time_t>(atoi(values[RUNNING_ETIME]));
epilog_stime = static_cast<time_t>(atoi(values[EPILOG_STIME]));
epilog_etime = static_cast<time_t>(atoi(values[EPILOG_ETIME]));
epilog_stime = static_cast<time_t>(atoi(values[EPILOG_STIME]));
epilog_etime = static_cast<time_t>(atoi(values[EPILOG_ETIME]));
reason = static_cast<MigrationReason>(atoi(values[REASON]));
reason = static_cast<MigrationReason>(atoi(values[REASON]));
return 0;
}
@ -273,6 +273,51 @@ int History::unmarshall(int num, char **names, char ** values)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int History::unmarshall(ostringstream& oss,
int num,
char ** names,
char ** values)
{
if ((!values[VID])||
(!values[SEQ])||
(!values[HOSTNAME])||
(!values[HID])||
(!values[STIME])||
(!values[ETIME])||
(!values[PROLOG_STIME])||
(!values[PROLOG_ETIME])||
(!values[RUNNING_STIME])||
(!values[RUNNING_ETIME])||
(!values[EPILOG_STIME])||
(!values[EPILOG_ETIME])||
(!values[REASON])||
(num != LIMIT))
{
return -1;
}
oss <<
"<HISTORY>" <<
"<SEQ>" << values[SEQ] << "</SEQ>" <<
"<HOSTNAME>"<< values[HOSTNAME] << "</HOSTNAME>"<<
"<HID>" << values[HID] << "</HID>" <<
"<STIME>" << values[STIME] << "</STIME>" <<
"<ETIME>" << values[ETIME] << "</ETIME>" <<
"<PSTIME>" << values[PROLOG_STIME] << "</PSTIME>" <<
"<PETIME>" << values[PROLOG_ETIME] << "</PETIME>" <<
"<RSTIME>" << values[RUNNING_STIME] << "</RSTIME>" <<
"<RETIME>" << values[RUNNING_ETIME] << "</RETIME>" <<
"<ESTIME>" << values[EPILOG_STIME] << "</ESTIME>" <<
"<EETIME>" << values[EPILOG_ETIME] << "</EETIME>" <<
"<REASON>" << values[REASON] << "</REASON>" <<
"</HISTORY>";
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
extern "C" int history_select_cb (
void * _history,
int num,
@ -337,3 +382,67 @@ int History::drop(SqliteDB * db)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
ostream& operator<<(ostream& os, const History& history)
{
string history_str;
os << history.to_xml(history_str);
return os;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& History::to_str(string& str) const
{
ostringstream oss;
oss<< "\tSEQ = " << seq << endl
<< "\tHOSTNAME = " << hostname << endl
<< "\tHID = " << hid << endl
<< "\tSTIME = " << stime << endl
<< "\tETIME = " << etime << endl
<< "\tPSTIME = " << prolog_stime << endl
<< "\tPETIME = " << prolog_etime << endl
<< "\tRSTIME = " << running_stime << endl
<< "\tRETIME = " << running_etime << endl
<< "\tESTIME = " << epilog_stime << endl
<< "\tEETIME = " << epilog_etime << endl
<< "\tREASON = " << reason;
str = oss.str();
return str;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& History::to_xml(string& xml) const
{
ostringstream oss;
oss <<
"<HISTORY>" <<
"<SEQ>" << seq << "</SEQ>" <<
"<HOSTNAME>"<< hostname << "</HOSTNAME>"<<
"<HID>" << hid << "</HID>" <<
"<STIME>" << stime << "</STIME>" <<
"<ETIME>" << etime << "</ETIME>" <<
"<PSTIME>" << prolog_stime << "</PSTIME>"<<
"<PETIME>" << prolog_etime << "</PETIME>"<<
"<RSTIME>" << running_stime << "</RSTIME>"<<
"<RETIME>" << running_etime << "</RETIME>"<<
"<ESTIME>" << epilog_stime << "</ESTIME>"<<
"<EETIME>" << epilog_etime << "</EETIME>"<<
"<REASON>" << reason << "</REASON>"<<
"</HISTORY>";
xml = oss.str();
return xml;
}

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