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

Functions to generate the context file for a VM, and some minor

modifications and new functionality to deal with the Teamplates


git-svn-id: http://svn.opennebula.org/one/trunk@386 3034c82b-c49b-4eb3-8279-a7acafdc01c0
This commit is contained in:
Rubén S. Montero 2009-03-06 12:10:15 +00:00
parent 294950443c
commit e799c8b3ad
13 changed files with 802 additions and 412 deletions

View File

@ -21,13 +21,13 @@
#include <string> #include <string>
#include <map> #include <map>
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
using namespace std; using namespace std;
/** /**
* Attribute base class for name-value pairs. This class provides a generic * Attribute base class for name-value pairs. This class provides a generic
* interface to implement * interface to implement
*/ */
class Attribute class Attribute
{ {
@ -45,11 +45,11 @@ public:
Attribute(const char * aname) Attribute(const char * aname)
{ {
ostringstream name; ostringstream name;
name << uppercase << aname; name << uppercase << aname;
attribute_name = name.str(); attribute_name = name.str();
}; };
virtual ~Attribute(){}; virtual ~Attribute(){};
enum AttributeType enum AttributeType
@ -57,7 +57,7 @@ public:
SIMPLE = 0, SIMPLE = 0,
VECTOR = 1 VECTOR = 1
}; };
/** /**
* Gets the name of the attribute. * Gets the name of the attribute.
* @return the attribute name * @return the attribute name
@ -72,8 +72,8 @@ public:
* by the calling function. * by the calling function.
* @return a string (allocated in the heap) holding the attribute value. * @return a string (allocated in the heap) holding the attribute value.
*/ */
virtual string * marshall(const char * _sep = 0) = 0; virtual string * marshall(const char * _sep = 0) const = 0;
/** /**
* Write the attribute using a simple XML format. The string MUST be freed * Write the attribute using a simple XML format. The string MUST be freed
* by the calling function. * by the calling function.
@ -84,8 +84,8 @@ public:
/** /**
* Builds a new attribute from a string. * Builds a new attribute from a string.
*/ */
virtual void unmarshall(const string& sattr) = 0; virtual void unmarshall(const string& sattr, const char * _sep = 0) = 0;
/** /**
* Returns the attribute type * Returns the attribute type
*/ */
@ -103,8 +103,8 @@ private:
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/** /**
* The SingleAttribute class represents a simple attribute in the form * The SingleAttribute class represents a simple attribute in the form
* NAME = VALUE. * NAME = VALUE.
*/ */
class SingleAttribute : public Attribute class SingleAttribute : public Attribute
@ -115,12 +115,12 @@ public:
SingleAttribute(const string& name, const string& value): SingleAttribute(const string& name, const string& value):
Attribute(name),attribute_value(value){}; Attribute(name),attribute_value(value){};
SingleAttribute(const char * name, const string& value): SingleAttribute(const char * name, const string& value):
Attribute(name),attribute_value(value){}; Attribute(name),attribute_value(value){};
~SingleAttribute(){}; ~SingleAttribute(){};
/** /**
* Returns the attribute value, a string. * Returns the attribute value, a string.
*/ */
@ -128,43 +128,43 @@ public:
{ {
return attribute_value; return attribute_value;
}; };
/** /**
* Marshall the attribute in a single string. The string MUST be freed * Marshall the attribute in a single string. The string MUST be freed
* by the calling function. * by the calling function.
* @return a string (allocated in the heap) holding the attribute value. * @return a string (allocated in the heap) holding the attribute value.
*/ */
string * marshall(const char * _sep = 0) string * marshall(const char * _sep = 0) const
{ {
string * rs = new string; string * rs = new string;
*rs = attribute_value; *rs = attribute_value;
return rs; return rs;
}; };
/** /**
* Write the attribute using a simple XML format: * Write the attribute using a simple XML format:
* *
* <attribute_name>attribute_value</attribute_name> * <attribute_name>attribute_value</attribute_name>
* *
* The string MUST be freed by the calling function. * The string MUST be freed by the calling function.
* @return a string (allocated in the heap) holding the attribute value. * @return a string (allocated in the heap) holding the attribute value.
*/ */
string * to_xml() const string * to_xml() const
{ {
string * xml = new string; string * xml = new string;
*xml = "<" + name() + ">" + attribute_value *xml = "<" + name() + ">" + attribute_value
+ "</"+ name() + ">"; + "</"+ name() + ">";
return xml; return xml;
} }
/** /**
* Builds a new attribute from a string. * Builds a new attribute from a string.
*/ */
void unmarshall(const string& sattr) void unmarshall(const string& sattr, const char * _sep = 0)
{ {
attribute_value = sattr; attribute_value = sattr;
}; };
@ -179,23 +179,23 @@ public:
/** /**
* Returns the attribute type * Returns the attribute type
*/ */
AttributeType type() AttributeType type()
{ {
return SIMPLE; return SIMPLE;
}; };
private: private:
string attribute_value; string attribute_value;
}; };
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/** /**
* The VectorAttribute class represents an array attribute in the form * The VectorAttribute class represents an array attribute in the form
* NAME = [ VAL_NAME_1=VAL_VALUE_1,...,VAL_NAME_N=VAL_VALUE_N]. * NAME = [ VAL_NAME_1=VAL_VALUE_1,...,VAL_NAME_N=VAL_VALUE_N].
*/ */
class VectorAttribute : public Attribute class VectorAttribute : public Attribute
@ -208,7 +208,7 @@ public:
Attribute(name),attribute_value(value){}; Attribute(name),attribute_value(value){};
~VectorAttribute(){}; ~VectorAttribute(){};
/** /**
* Returns the attribute value, a string. * Returns the attribute value, a string.
*/ */
@ -216,29 +216,29 @@ public:
{ {
return attribute_value; return attribute_value;
}; };
/** /**
* *
*/ */
string vector_value(const char *name) const; string vector_value(const char *name) const;
/** /**
* Marshall the attribute in a single string. The string MUST be freed * Marshall the attribute in a single string. The string MUST be freed
* by the calling function. The string is in the form: * by the calling function. The string is in the form:
* "VAL_NAME_1=VAL_VALUE_1,...,VAL_NAME_N=VAL_VALUE_N". * "VAL_NAME_1=VAL_VALUE_1,...,VAL_NAME_N=VAL_VALUE_N".
* @return a string (allocated in the heap) holding the attribute value. * @return a string (allocated in the heap) holding the attribute value.
*/ */
string * marshall(const char * _sep = 0); string * marshall(const char * _sep = 0) const;
/** /**
* Write the attribute using a simple XML format: * Write the attribute using a simple XML format:
* *
* <attribute_name> * <attribute_name>
* <val_name_1>val_value_1</val_name_1> * <val_name_1>val_value_1</val_name_1>
* ... * ...
* <val_name_n>val_value_n</val_name_n> * <val_name_n>val_value_n</val_name_n>
* </attribute_name> * </attribute_name>
* *
* The string MUST be freed by the calling function. * The string MUST be freed by the calling function.
* @return a string (allocated in the heap) holding the attribute value. * @return a string (allocated in the heap) holding the attribute value.
*/ */
@ -247,8 +247,8 @@ public:
/** /**
* Builds a new attribute from a string of the form: * Builds a new attribute from a string of the form:
* "VAL_NAME_1=VAL_VALUE_1,...,VAL_NAME_N=VAL_VALUE_N". * "VAL_NAME_1=VAL_VALUE_1,...,VAL_NAME_N=VAL_VALUE_N".
*/ */
void unmarshall(const string& sattr); void unmarshall(const string& sattr, const char * _sep = 0);
/** /**
* Replace the value of the given attribute with the provided map * Replace the value of the given attribute with the provided map
@ -258,19 +258,19 @@ public:
/** /**
* Returns the attribute type * Returns the attribute type
*/ */
AttributeType type() AttributeType type()
{ {
return VECTOR; return VECTOR;
}; };
private: private:
static const char * magic_sep; static const char * magic_sep;
static const int magic_sep_size; static const int magic_sep_size;
map<string,string> attribute_value; map<string,string> attribute_value;
}; };
#endif /*ATTRIBUTE_H_*/ #endif /*ATTRIBUTE_H_*/

View File

@ -28,7 +28,7 @@ extern "C" int history_select_cb (
int num, int num,
char ** values, char ** values,
char ** names); char ** names);
/** /**
* The History class, it represents an execution record of a Virtual Machine. * The History class, it represents an execution record of a Virtual Machine.
*/ */
@ -60,7 +60,7 @@ public:
private: private:
friend class VirtualMachine; friend class VirtualMachine;
// ---------------------------------------- // ----------------------------------------
// DataBase implementation variables // DataBase implementation variables
// ---------------------------------------- // ----------------------------------------
@ -88,17 +88,17 @@ private:
static const char * table; static const char * table;
static const char * db_names; static const char * db_names;
static const char * db_bootstrap; static const char * db_bootstrap;
void non_persistent_data(); void non_persistent_data();
static string column_name(const ColNames column) static string column_name(const ColNames column)
{ {
switch (column) switch (column)
{ {
case HID: case HID:
return "hid"; return "hid";
case ETIME: case ETIME:
return "etime"; return "etime";
case RUNNING_ETIME: case RUNNING_ETIME:
@ -116,7 +116,7 @@ private:
string hostname; string hostname;
string vm_dir; string vm_dir;
int hid; int hid;
string vmm_mad_name; string vmm_mad_name;
@ -140,17 +140,18 @@ private:
string vm_lhome; string vm_lhome;
string transfer_file; string transfer_file;
string deployment_file; string deployment_file;
string context_file;
string vm_rhome; string vm_rhome;
string checkpoint_file; string checkpoint_file;
string rdeployment_file; string rdeployment_file;
friend int history_select_cb ( friend int history_select_cb (
void * _history, void * _history,
int num, int num,
char ** values, char ** values,
char ** names); char ** names);
/** /**
* Writes the history record in the DB * Writes the history record in the DB
* @param db pointer to the database. * @param db pointer to the database.
@ -172,14 +173,14 @@ private:
*/ */
int drop(SqliteDB * db); int drop(SqliteDB * db);
/** /**
* Updates the history record * Updates the history record
* @param db pointer to the database. * @param db pointer to the database.
* @return 0 on success. * @return 0 on success.
*/ */
int update(SqliteDB * db) int update(SqliteDB * db)
{ {
return insert(db); return insert(db);
} }
@ -199,7 +200,7 @@ private:
{ {
return ObjectSQL::select_column(db,table,column,where,value); return ObjectSQL::select_column(db,table,column,where,value);
} }
/** /**
* Sets the value of a column in the pool for a given object * Sets the value of a column in the pool for a given object
* @param db pointer to Database * @param db pointer to Database
@ -216,7 +217,7 @@ private:
{ {
return ObjectSQL::update_column(db,table,column,where,value); return ObjectSQL::update_column(db,table,column,where,value);
} }
/** /**
* Function to unmarshall a history object * Function to unmarshall a history object

View File

@ -107,6 +107,17 @@ public:
attributes.insert(make_pair(attr->name(),attr)); attributes.insert(make_pair(attr->name(),attr));
}; };
/**
* Removes an attribute from the template. The attributes are returned. The
* attributes MUST be freed by the calling funtion
* @param name of the attribute
* @param values a vector containing a pointer to the attributes
* @returns the number of attributes removed
*/
virtual int remove(
const string& name,
vector<Attribute *>& values);
/** /**
* Gets all the attributes with the given name. * Gets all the attributes with the given name.
* @param name the attribute name. * @param name the attribute name.

View File

@ -44,29 +44,29 @@ public:
{}; {};
virtual ~TemplateSQL(){}; virtual ~TemplateSQL(){};
protected: protected:
//Database implementation variables //Database implementation variables
const char * table; const char * table;
static const char * db_names; static const char * db_names;
//Template attributes //Template attributes
/** /**
* Template unique identification. * Template unique identification.
*/ */
int id; int id;
/** /**
* Writes the template in the DB * Writes the template in the DB
* @param db pointer to the database. * @param db pointer to the database.
* @return 0 on success. * @return 0 on success.
*/ */
int insert(SqliteDB * db); int insert(SqliteDB * db);
/** /**
* Updates the template in the DB * Updates the template in the DB
* @param db pointer to the database. * @param db pointer to the database.
@ -88,13 +88,21 @@ protected:
int drop(SqliteDB *db); int drop(SqliteDB *db);
/** /**
* Removes a template attribute from the DB (ONLY SINGLE ATTRIBUTES) * Removes a template attribute from the DB. If there are multiple
* attributes with the same name, only one will be replaced. The attribute
* MUST be allocated in the heap.
* @param db pointer to the database. * @param db pointer to the database.
* @param name of the attribute. * @param attribute pointer to the new attribute.
* @param value of the new attribute.
*/ */
int replace_attribute(SqliteDB * db, const string& name, const string& value); int replace_attribute(SqliteDB * db, Attribute * attribute);
/**
* Insert a given attribute (MUST be allocated in the heap) in the template
* and updates the DB.
* @param db pointer to the database.
* @param attribute pointer to the new attribute
*/
int insert_attribute(SqliteDB * db, Attribute * attribute);
}; };
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */

View File

@ -41,7 +41,7 @@ class VirtualMachine : public PoolObjectSQL
public: public:
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// VM States // VM States
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* Global Virtual Machine state * Global Virtual Machine state
@ -59,7 +59,7 @@ public:
}; };
/** /**
* Virtual Machine state associated to the Life-cycle Manager * Virtual Machine state associated to the Life-cycle Manager
*/ */
enum LcmState enum LcmState
{ {
@ -81,11 +81,11 @@ public:
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Log & Print // Log & Print
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* writes a log message in vm.log. The class lock should be locked and * writes a log message in vm.log. The class lock should be locked and
* the VM MUST BE obtained through the VirtualMachinePool get() method. * the VM MUST BE obtained through the VirtualMachinePool get() method.
*/ */
void log( void log(
const char * module, const char * module,
@ -97,22 +97,22 @@ public:
_log->log(module,type,message); _log->log(module,type,message);
} }
}; };
/** /**
* writes a log message in vm.log. The class lock should be locked and * writes a log message in vm.log. The class lock should be locked and
* the VM MUST BE obtained through the VirtualMachinePool get() method. * the VM MUST BE obtained through the VirtualMachinePool get() method.
*/ */
void log( void log(
const char * module, const char * module,
const Log::MessageType type, const Log::MessageType type,
const char * message) const const char * message) const
{ {
if (_log != 0) if (_log != 0)
{ {
_log->log(module,type,message); _log->log(module,type,message);
} }
}; };
/** /**
* Function to write a Virtual Machine in an output stream * Function to write a Virtual Machine in an output stream
*/ */
@ -120,7 +120,7 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Dynamic Info // Dynamic Info
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Updates VM dynamic information (id). * Updates VM dynamic information (id).
@ -186,7 +186,7 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// History // History
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Adds a new history record an writes it in the database. * Adds a new history record an writes it in the database.
*/ */
@ -215,7 +215,7 @@ public:
* Checks if the VM has a valid history record. This function * Checks if the VM has a valid history record. This function
* MUST be called before using any history related function. * MUST be called before using any history related function.
* @return true if the VM has a record * @return true if the VM has a record
*/ */
bool hasHistory() const bool hasHistory() const
{ {
return (history!=0); return (history!=0);
@ -225,7 +225,7 @@ public:
* Checks if the VM has a valid previous history record. This function * Checks if the VM has a valid previous history record. This function
* MUST be called before using any previous_history related function. * MUST be called before using any previous_history related function.
* @return true if the VM has a previous record * @return true if the VM has a previous record
*/ */
bool hasPreviousHistory() const bool hasPreviousHistory() const
{ {
return (previous_history!=0); return (previous_history!=0);
@ -234,7 +234,7 @@ public:
* Returns the VMM driver name for the current host. The hasHistory() * Returns the VMM driver name for the current host. The hasHistory()
* function MUST be called before this one. * function MUST be called before this one.
* @return the VMM mad name * @return the VMM mad name
*/ */
const string & get_vmm_mad() const const string & get_vmm_mad() const
{ {
return history->vmm_mad_name; return history->vmm_mad_name;
@ -244,20 +244,20 @@ public:
* Returns the TM driver name for the current host. The hasHistory() * Returns the TM driver name for the current host. The hasHistory()
* function MUST be called before this one. * function MUST be called before this one.
* @return the TM mad name * @return the TM mad name
*/ */
const string & get_tm_mad() const const string & get_tm_mad() const
{ {
return history->tm_mad_name; return history->tm_mad_name;
}; };
/** /**
* Returns the transfer filename. The transfer file is in the form: * Returns the transfer filename. The transfer file is in the form:
* $ONE_LOCATION/var/$VM_ID/transfer.$SEQ * $ONE_LOCATION/var/$VM_ID/transfer.$SEQ
* or, in case that OpenNebula is installed in root * or, in case that OpenNebula is installed in root
* /var/lib/one/$VM_ID/transfer.$SEQ * /var/lib/one/$VM_ID/transfer.$SEQ
* The hasHistory() function MUST be called before this one. * The hasHistory() function MUST be called before this one.
* @return the transfer filename * @return the transfer filename
*/ */
const string & get_transfer_file() const const string & get_transfer_file() const
{ {
return history->transfer_file; return history->transfer_file;
@ -270,79 +270,92 @@ public:
* /var/lib/one/$VM_ID/deployment.$SEQ * /var/lib/one/$VM_ID/deployment.$SEQ
* The hasHistory() function MUST be called before this one. * The hasHistory() function MUST be called before this one.
* @return the deployment filename * @return the deployment filename
*/ */
const string & get_deployment_file() const const string & get_deployment_file() const
{ {
return history->deployment_file; return history->deployment_file;
}; };
/** /**
* Returns the remote deployment filename. The file is in the form: * Returns the context filename. The context file is in the form:
* $VM_DIR/$VM_ID/images/deployment.$SEQ * $ONE_LOCATION/var/$VM_ID/context.sh
* or, in case that OpenNebula is installed in root
* /var/lib/one/$VM_ID/context.sh
* The hasHistory() function MUST be called before this one. * The hasHistory() function MUST be called before this one.
* @return the deployment filename * @return the deployment filename
*/ */
const string & get_context_file() const
{
return history->context_file;
}
/**
* Returns the remote deployment filename. The file is in the form:
* $VM_DIR/$VM_ID/images/deployment.$SEQ
* The hasHistory() function MUST be called before this one.
* @return the deployment filename
*/
const string & get_remote_deployment_file() const const string & get_remote_deployment_file() const
{ {
return history->rdeployment_file; return history->rdeployment_file;
}; };
/** /**
* Returns the checkpoint filename for the current host. The checkpoint file * Returns the checkpoint filename for the current host. The checkpoint file
* is in the form: * is in the form:
* $VM_DIR/$VM_ID/images/checkpoint * $VM_DIR/$VM_ID/images/checkpoint
* The hasHistory() function MUST be called before this one. * The hasHistory() function MUST be called before this one.
* @return the checkpoint filename * @return the checkpoint filename
*/ */
const string & get_checkpoint_file() const const string & get_checkpoint_file() const
{ {
return history->checkpoint_file; return history->checkpoint_file;
}; };
/** /**
* Returns the remote VM directory. The VM remote dir is in the form: * Returns the remote VM directory. The VM remote dir is in the form:
* $VM_DIR/$VM_ID/ * $VM_DIR/$VM_ID/
* or, in case that OpenNebula is installed in root * or, in case that OpenNebula is installed in root
* /var/lib/one/$VM_ID/ * /var/lib/one/$VM_ID/
* The hasHistory() function MUST be called before this one. * The hasHistory() function MUST be called before this one.
* @return the remote directory * @return the remote directory
*/ */
const string & get_remote_dir() const const string & get_remote_dir() const
{ {
return history->vm_rhome; return history->vm_rhome;
}; };
/** /**
* Returns the local VM directory. The VM local dir is in the form: * Returns the local VM directory. The VM local dir is in the form:
* $ONE_LOCATION/var/$VM_ID/ * $ONE_LOCATION/var/$VM_ID/
* The hasHistory() function MUST be called before this one. * The hasHistory() function MUST be called before this one.
* @return the remote directory * @return the remote directory
*/ */
const string & get_local_dir() const const string & get_local_dir() const
{ {
return history->vm_lhome; return history->vm_lhome;
}; };
/** /**
* Returns the hostname for the current host. The hasHistory() * Returns the hostname for the current host. The hasHistory()
* function MUST be called before this one. * function MUST be called before this one.
* @return the hostname * @return the hostname
*/ */
const string & get_hostname() const const string & get_hostname() const
{ {
return history->hostname; return history->hostname;
}; };
/** /**
* Returns the hostname for the previous host. The hasPreviousHistory() * Returns the hostname for the previous host. The hasPreviousHistory()
* function MUST be called before this one. * function MUST be called before this one.
* @return the hostname * @return the hostname
*/ */
const string & get_previous_hostname() const const string & get_previous_hostname() const
{ {
return previous_history->hostname; return previous_history->hostname;
}; };
/** /**
* Returns the reason that originated the VM migration in the previous host * Returns the reason that originated the VM migration in the previous host
* @return the migration reason to leave this host * @return the migration reason to leave this host
@ -350,8 +363,8 @@ public:
const History::MigrationReason get_previous_reason() const const History::MigrationReason get_previous_reason() const
{ {
return previous_history->reason; return previous_history->reason;
}; };
/** /**
* Get host id where the VM is or is going to execute. The hasHistory() * Get host id where the VM is or is going to execute. The hasHistory()
* function MUST be called before this one. * function MUST be called before this one.
@ -369,7 +382,7 @@ public:
{ {
return previous_history->hid; return previous_history->hid;
} }
/** /**
* Sets start time of a VM. * Sets start time of a VM.
* @param _stime time when the VM started * @param _stime time when the VM started
@ -396,7 +409,7 @@ public:
{ {
previous_history->etime=_etime; previous_history->etime=_etime;
}; };
/** /**
* Sets start time of VM prolog. * Sets start time of VM prolog.
* @param _stime time when the prolog started * @param _stime time when the prolog started
@ -441,7 +454,7 @@ public:
{ {
previous_history->running_etime=_etime; previous_history->running_etime=_etime;
}; };
/** /**
* Sets start time of VM epilog. * Sets start time of VM epilog.
* @param _stime time when the epilog started * @param _stime time when the epilog started
@ -468,7 +481,7 @@ public:
{ {
history->reason=_reason; history->reason=_reason;
}; };
/** /**
* Sets the reason that originated the VM migration in the previous host * Sets the reason that originated the VM migration in the previous host
* @param _reason migration reason to leave this host * @param _reason migration reason to leave this host
@ -476,11 +489,11 @@ public:
void set_previous_reason(History::MigrationReason _reason) void set_previous_reason(History::MigrationReason _reason)
{ {
previous_history->reason=_reason; previous_history->reason=_reason;
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Template // Template
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Gets the values of a template attribute * Gets the values of a template attribute
@ -489,7 +502,7 @@ public:
* @return the number of values * @return the number of values
*/ */
int get_template_attribute( int get_template_attribute(
string& name, string& name,
vector<const Attribute*>& values) const vector<const Attribute*>& values) const
{ {
return vm_template.get(name,values); return vm_template.get(name,values);
@ -513,42 +526,42 @@ public:
* Gets a string based VM attribute (single) * Gets a string based VM attribute (single)
* @param name of the attribute * @param name of the attribute
* @param value of the attribute (a string), will be "" if not defined or * @param value of the attribute (a string), will be "" if not defined or
* not a single attribute * not a single attribute
*/ */
void get_template_attribute( void get_template_attribute(
const char * name, const char * name,
string& value) const string& value) const
{ {
string str=name; string str=name;
vm_template.get(str,value); vm_template.get(str,value);
} }
/** /**
* Gets an int based VM attribute (single) * Gets an int based VM attribute (single)
* @param name of the attribute * @param name of the attribute
* @param value of the attribute (an int), will be 0 if not defined or * @param value of the attribute (an int), will be 0 if not defined or
* not a single attribute * not a single attribute
*/ */
void get_template_attribute( void get_template_attribute(
const char * name, const char * name,
int& value) const int& value) const
{ {
string str=name; string str=name;
vm_template.get(str,value); vm_template.get(str,value);
} }
/** /**
* Generates a XML string for the template of the VM * Generates a XML string for the template of the VM
* @param xml the string to store the XML description. * @param xml the string to store the XML description.
*/ */
void template_to_xml(string &xml) const void template_to_xml(string &xml) const
{ {
vm_template.to_xml(xml); vm_template.to_xml(xml);
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// States // States
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Returns the VM state (Dispatch Manager) * Returns the VM state (Dispatch Manager)
@ -585,7 +598,7 @@ public:
{ {
lcm_state = s; lcm_state = s;
}; };
/** /**
* Gets the user id of the owner of this VM * Gets the user id of the owner of this VM
* @return the VM uid * @return the VM uid
@ -594,11 +607,11 @@ public:
{ {
return uid; return uid;
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Timers // Timers
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Gets time from last information polling. * Gets time from last information polling.
* @return time of last poll (epoch) or 0 if never polled * @return time of last poll (epoch) or 0 if never polled
@ -607,7 +620,7 @@ public:
{ {
return last_poll; return last_poll;
}; };
/** /**
* Sets time of last information polling. * Sets time of last information polling.
* @param poll time in epoch, normally time(0) * @param poll time in epoch, normally time(0)
@ -616,15 +629,15 @@ public:
{ {
last_poll = poll; last_poll = poll;
}; };
/** /**
* Get the VM physical requirements for the host. * Get the VM physical requirements for the host.
* @param cpu * @param cpu
* @param memory * @param memory
* @param disk * @param disk
*/ */
void get_requirements (int& cpu, int& memory, int& disk); void get_requirements (int& cpu, int& memory, int& disk);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Leases // Leases
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -633,12 +646,18 @@ public:
* @return 0 if success * @return 0 if success
*/ */
int get_leases(); int get_leases();
/** /**
* Releases all network leases taken by this Virtual Machine * Releases all network leases taken by this Virtual Machine
*/ */
void release_leases(); void release_leases();
/**
* Writes the context file for this VM.
* @return 0 if success
*/
int write_context();
private: private:
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@ -655,11 +674,11 @@ private:
// ************************************************************************* // *************************************************************************
// Virtual Machine Attributes // Virtual Machine Attributes
// ************************************************************************* // *************************************************************************
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Identification variables // Identification variables
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* User (owner) id * User (owner) id
*/ */
@ -667,12 +686,12 @@ private:
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// VM Scheduling & Managing Information // VM Scheduling & Managing Information
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* Last time (in epoch) that the VM was polled to get its status * Last time (in epoch) that the VM was polled to get its status
*/ */
time_t last_poll; time_t last_poll;
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Virtual Machine Description // Virtual Machine Description
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@ -737,7 +756,7 @@ private:
* History record, for the previous host * History record, for the previous host
*/ */
History * previous_history; History * previous_history;
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Logging // Logging
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@ -749,7 +768,7 @@ private:
* /var/log/one/$VM_ID.log * /var/log/one/$VM_ID.log
*/ */
Log * _log; Log * _log;
// ************************************************************************* // *************************************************************************
// DataBase implementation (Private) // DataBase implementation (Private)
// ************************************************************************* // *************************************************************************
@ -765,7 +784,7 @@ private:
db->exec(History::db_bootstrap); db->exec(History::db_bootstrap);
}; };
/** /**
* Function to unmarshall a VM object, an associated classes. * Function to unmarshall a VM object, an associated classes.
* @param num the number of columns read from the DB * @param num the number of columns read from the DB
@ -774,11 +793,11 @@ private:
* @return 0 on success * @return 0 on success
*/ */
int unmarshall(int num, char **names, char ** values); int unmarshall(int num, char **names, char ** values);
/** /**
* Updates the VM history record * Updates the VM history record
* @param db pointer to the db * @param db pointer to the db
* @return 0 on success * @return 0 on success
*/ */
int update_history(SqliteDB * db) int update_history(SqliteDB * db)
{ {
@ -793,7 +812,7 @@ private:
/** /**
* Updates the previous history record * Updates the previous history record
* @param db pointer to the db * @param db pointer to the db
* @return 0 on success * @return 0 on success
*/ */
int update_previous_history(SqliteDB * db) int update_previous_history(SqliteDB * db)
{ {
@ -804,11 +823,11 @@ private:
else else
return -1; return -1;
}; };
/** /**
* Updates the template of a VM, adding a new attribute (replacing it if * Updates the template of a VM, adding a new attribute (replacing it if
* already defined), the vm's mutex SHOULD be locked * already defined), the vm's mutex SHOULD be locked
* @param vm pointer to the virtual machine object * @param db pointer to the database
* @param name of the new attribute * @param name of the new attribute
* @param value of the new attribute * @param value of the new attribute
* @return 0 on success * @return 0 on success
@ -818,19 +837,41 @@ private:
string& name, string& name,
string& value) string& value)
{ {
return vm_template.replace_attribute(db,name,value); SingleAttribute * sattr;
} int rc;
sattr = new SingleAttribute(name,value);
rc = vm_template.replace_attribute(db,sattr);
if (rc != 0)
delete sattr;
return rc;
}
/**
* Inserts a new attribute in the template of a VM, also the DB is
* updated. The vm's mutex SHOULD be locked
* @param db pointer to the database
* @param attribute the new attribute for the template
* @return 0 on success
*/
int insert_template_attribute(SqliteDB * db, Attribute * attribute)
{
return vm_template.insert_attribute(db,attribute);
}
protected: protected:
//************************************************************************** //**************************************************************************
// Constructor // Constructor
//************************************************************************** //**************************************************************************
VirtualMachine(int id=-1); VirtualMachine(int id=-1);
virtual ~VirtualMachine(); virtual ~VirtualMachine();
// ************************************************************************* // *************************************************************************
// DataBase implementation // DataBase implementation
// ************************************************************************* // *************************************************************************
@ -858,7 +899,7 @@ protected:
static const char * db_names; static const char * db_names;
static const char * db_bootstrap; static const char * db_bootstrap;
/** /**
* Reads the Virtual Machine (identified with its OID) from the database. * Reads the Virtual Machine (identified with its OID) from the database.
* @param db pointer to the db * @param db pointer to the db
@ -879,7 +920,7 @@ protected:
* @return 0 on success * @return 0 on success
*/ */
virtual int update(SqliteDB * db); virtual int update(SqliteDB * db);
/** /**
* Deletes a VM from the database and all its associated information: * Deletes a VM from the database and all its associated information:
* - History records * - History records
@ -888,16 +929,16 @@ protected:
* @return 0 on success * @return 0 on success
*/ */
virtual int drop(SqliteDB * db) virtual int drop(SqliteDB * db)
{ {
int rc; int rc;
rc = vm_template.drop(db); rc = vm_template.drop(db);
if ( history != 0 ) if ( history != 0 )
{ {
rc += history->drop(db); rc += history->drop(db);
} }
return rc; return rc;
} }
}; };

View File

@ -43,7 +43,7 @@ public:
* @param stemplate a string describing the VM * @param stemplate a string describing the VM
* @param oid the id assigned to the VM (output) * @param oid the id assigned to the VM (output)
* @param on_hold flag to submit on hold * @param on_hold flag to submit on hold
* @return 0 on success, -1 error inserting in DB or -2 error parsing * @return 0 on success, -1 error inserting in DB or -2 error parsing
* the template * the template
*/ */
int allocate ( int allocate (
@ -85,9 +85,9 @@ public:
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Virtual Machine DB access functions // Virtual Machine DB access functions
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
/** /**
* Updates the template of a VM, adding a new attribute (replacing it if * Updates the template of a VM, adding a new attribute (replacing it if
* already defined), the vm's mutex SHOULD be locked * already defined), the vm's mutex SHOULD be locked
* @param vm pointer to the virtual machine object * @param vm pointer to the virtual machine object
* @param name of the new attribute * @param name of the new attribute
@ -101,7 +101,7 @@ public:
{ {
return vm->update_template_attribute(db,name,value); return vm->update_template_attribute(db,name,value);
} }
/** /**
* Updates the history record of a VM, the vm's mutex SHOULD be locked * Updates the history record of a VM, the vm's mutex SHOULD be locked
* @param vm pointer to the virtual machine object * @param vm pointer to the virtual machine object
@ -123,7 +123,21 @@ public:
{ {
return vm->update_previous_history(db); return vm->update_previous_history(db);
} }
/**
* Parse a string and substitute variables (e.g. $NAME) using template
* values:
* @param vm_id, ID of the VM used to substitute the variables
* @param attribute, the string to be parsed
* @param parsed, the resulting parsed string
* @param error_msg, string describing the syntax error
* @return 0 on success.
*/
int parse_attribute(int vm_id,
string &attribute,
string &parsed,
char ** error_msg);
/** /**
* Bootstraps the database table(s) associated to the VirtualMachine pool * Bootstraps the database table(s) associated to the VirtualMachine pool
*/ */
@ -131,8 +145,20 @@ public:
{ {
VirtualMachine::bootstrap(db); VirtualMachine::bootstrap(db);
}; };
private: private:
/**
* Mutex to perform just one attribute parse at a time
*/
static pthread_mutex_t lex_mutex;
/**
* Generate context file to be sourced upon VM booting
* @param vm_id, ID of the VM to generate context for
* @param attrs, the template CONTEXT attributes (only the first one will
* be used)
*/
void generate_context(int vm_id, vector<Attribute *> attrs);
/** /**
* Factory method to produce VM objects * Factory method to produce VM objects
@ -143,5 +169,5 @@ private:
return new VirtualMachine; return new VirtualMachine;
}; };
}; };
#endif /*VIRTUAL_MACHINE_POOL_H_*/ #endif /*VIRTUAL_MACHINE_POOL_H_*/

View File

@ -45,18 +45,18 @@ extern "C" int vn_select_cb (void * _vn, int num,char ** values, char ** names);
class VirtualNetwork : public PoolObjectSQL class VirtualNetwork : public PoolObjectSQL
{ {
public: public:
/** /**
* Possible types of networks * Possible types of networks
*/ */
enum NetworkType enum NetworkType
{ {
UNINITIALIZED = -1, UNINITIALIZED = -1,
RANGED = 0, RANGED = 0,
FIXED = 1, FIXED = 1,
}; };
// ************************************************************************* // *************************************************************************
// Virtual Network Public Methods // Virtual Network Public Methods
// ************************************************************************* // *************************************************************************
@ -65,7 +65,7 @@ public:
* @param vid VM identifier * @param vid VM identifier
* @param _ip pointer to string for IP to be stored into * @param _ip pointer to string for IP to be stored into
* @param _mac pointer to string for MAC to be stored into * @param _mac pointer to string for MAC to be stored into
* @param _bridge name of the physical bridge this VN binds to * @param _bridge name of the physical bridge this VN binds to
* @return 0 if success * @return 0 if success
*/ */
int get_lease(int vid, string& _ip, string& _mac, string& _bridge) int get_lease(int vid, string& _ip, string& _mac, string& _bridge)
@ -79,7 +79,7 @@ public:
* @param vid VM identifier * @param vid VM identifier
* @param _ip the ip of the requested lease * @param _ip the ip of the requested lease
* @param _mac pointer to string for MAC to be stored into * @param _mac pointer to string for MAC to be stored into
* @param _bridge name of the physical bridge this VN binds to * @param _bridge name of the physical bridge this VN binds to
* @return 0 if success * @return 0 if success
*/ */
int set_lease(int vid, const string& _ip, string& _mac, string& _bridge) int set_lease(int vid, const string& _ip, string& _mac, string& _bridge)
@ -87,7 +87,7 @@ public:
_bridge = bridge; _bridge = bridge;
return leases->set(vid,_ip,_mac); return leases->set(vid,_ip,_mac);
}; };
/** /**
* Release previously given lease * Release previously given lease
* @param _ip IP identifying the lease * @param _ip IP identifying the lease
@ -97,7 +97,7 @@ public:
{ {
return leases->release(ip); return leases->release(ip);
}; };
/** /**
* Gets size of the network (used + free) * Gets size of the network (used + free)
* @return number of hosts that can be fitted in this network * @return number of hosts that can be fitted in this network
@ -106,12 +106,12 @@ public:
{ {
return leases->size; return leases->size;
}; };
/** /**
* Function to write a Virtual Network in an output stream * Function to write a Virtual Network in an output stream
*/ */
friend ostream& operator<<(ostream& os, VirtualNetwork& vn); friend ostream& operator<<(ostream& os, VirtualNetwork& vn);
private: private:
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@ -136,7 +136,7 @@ private:
* Name of the Virtual Network * Name of the Virtual Network
*/ */
string name; string name;
/** /**
* Owner of the Virtual Network * Owner of the Virtual Network
*/ */
@ -145,7 +145,7 @@ private:
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Binded physical attributes // Binded physical attributes
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* Name of the bridge this VNW binds to * Name of the bridge this VNW binds to
*/ */
@ -158,27 +158,27 @@ private:
* Holds the type of this network * Holds the type of this network
*/ */
NetworkType type; NetworkType type;
/** /**
* Pointer to leases class, can be fixed or ranged. * Pointer to leases class, can be fixed or ranged.
* Holds information on given (and, optionally, possible) leases * Holds information on given (and, optionally, possible) leases
*/ */
Leases * leases; Leases * leases;
/** /**
* The Virtual Network template, holds the VNW attributes. * The Virtual Network template, holds the VNW attributes.
*/ */
VirtualNetworkTemplate vn_template; VirtualNetworkTemplate vn_template;
// ************************************************************************* // *************************************************************************
// Non persistent data members from Nebula.conf // Non persistent data members from Nebula.conf
// ************************************************************************* // *************************************************************************
/** /**
* MAC prefix for this OpenNebula site * MAC prefix for this OpenNebula site
*/ */
unsigned int mac_prefix; unsigned int mac_prefix;
/** /**
* Default size for virtual networks * Default size for virtual networks
*/ */
@ -194,12 +194,12 @@ private:
static void bootstrap(SqliteDB * db) static void bootstrap(SqliteDB * db)
{ {
db->exec(VirtualNetwork::db_bootstrap); db->exec(VirtualNetwork::db_bootstrap);
db->exec(VirtualNetworkTemplate::db_bootstrap); db->exec(VirtualNetworkTemplate::db_bootstrap);
db->exec(Leases::db_bootstrap); db->exec(Leases::db_bootstrap);
}; };
/** /**
* Function to unmarshall a VNW object, and associated classes. * Function to unmarshall a VNW object, and associated classes.
* @param num the number of columns read from the DB * @param num the number of columns read from the DB
@ -208,7 +208,7 @@ private:
* @return 0 on success * @return 0 on success
*/ */
int unmarshall(int num, char **names, char ** values); int unmarshall(int num, char **names, char ** values);
/** /**
* Function to drop VN entry in vn_pool * Function to drop VN entry in vn_pool
* @return 0 on success * @return 0 on success
@ -217,7 +217,7 @@ private:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Template // Template
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Gets the values of a template attribute * Gets the values of a template attribute
@ -226,7 +226,7 @@ private:
* @return the number of values * @return the number of values
*/ */
int get_template_attribute( int get_template_attribute(
string& name, string& name,
vector<const Attribute*>& values) const vector<const Attribute*>& values) const
{ {
return vn_template.get(name,values); return vn_template.get(name,values);
@ -245,35 +245,35 @@ private:
string str=name; string str=name;
return vn_template.get(str,values); return vn_template.get(str,values);
}; };
/** /**
* Gets a string based VN attribute * Gets a string based VN attribute
* @param name of the attribute * @param name of the attribute
* @param value of the attribute (a string), will be "" if not defined * @param value of the attribute (a string), will be "" if not defined
*/ */
void get_template_attribute( void get_template_attribute(
const char * name, const char * name,
string& value) const string& value) const
{ {
string str=name; string str=name;
vn_template.get(str,value); vn_template.get(str,value);
} }
/** /**
* Gets a string based VN attribute * Gets a string based VN attribute
* @param name of the attribute * @param name of the attribute
* @param value of the attribute (an int), will be 0 if not defined * @param value of the attribute (an int), will be 0 if not defined
*/ */
void get_template_attribute( void get_template_attribute(
const char * name, const char * name,
int& value) const int& value) const
{ {
string str=name; string str=name;
vn_template.get(str,value); vn_template.get(str,value);
} }
/** /**
* Updates the template of a VNW, adding a new attribute (replacing it if * Updates the template of a VNW, adding a new attribute (replacing it if
* already defined), the VN's mutex SHOULD be locked * already defined), the VN's mutex SHOULD be locked
* @param vm pointer to the virtual network object * @param vm pointer to the virtual network object
* @param name of the new attribute * @param name of the new attribute
@ -285,19 +285,28 @@ private:
string& name, string& name,
string& value) string& value)
{ {
return vn_template.replace_attribute(db,name,value); SingleAttribute * sattr;
} int rc;
sattr = new SingleAttribute(name,value);
rc = vn_template.replace_attribute(db,sattr);
if (rc != 0)
delete sattr;
return rc;
}
protected: protected:
//************************************************************************** //**************************************************************************
// Constructor // Constructor
//************************************************************************** //**************************************************************************
VirtualNetwork(unsigned int _mac_prefix, int _default_size); VirtualNetwork(unsigned int _mac_prefix, int _default_size);
~VirtualNetwork(); ~VirtualNetwork();
// ************************************************************************* // *************************************************************************
// DataBase implementation // DataBase implementation
// ************************************************************************* // *************************************************************************
@ -317,7 +326,7 @@ protected:
static const char * db_names; static const char * db_names;
static const char * db_bootstrap; static const char * db_bootstrap;
/** /**
* Reads the Virtual Network (identified with its OID) from the database. * Reads the Virtual Network (identified with its OID) from the database.
* @param db pointer to the db * @param db pointer to the db
@ -338,7 +347,7 @@ protected:
* @return 0 on success * @return 0 on success
*/ */
int update(SqliteDB * db); int update(SqliteDB * db);
/** /**
* Deletes a VNW from the database and all its associated information: * Deletes a VNW from the database and all its associated information:
* - VNW template * - VNW template
@ -347,15 +356,15 @@ protected:
* @return 0 on success * @return 0 on success
*/ */
int drop(SqliteDB * db) int drop(SqliteDB * db)
{ {
int rc; int rc;
rc = vn_template.drop(db); rc = vn_template.drop(db);
rc += leases->drop(db); rc += leases->drop(db);
rc += vn_drop(db); rc += vn_drop(db);
return rc; return rc;
} }
}; };

View File

@ -17,6 +17,7 @@
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <cstring>
#include "Attribute.h" #include "Attribute.h"
@ -24,13 +25,14 @@
const char * VectorAttribute::magic_sep = "@^_^@"; const char * VectorAttribute::magic_sep = "@^_^@";
const int VectorAttribute::magic_sep_size = 5; const int VectorAttribute::magic_sep_size = 5;
string * VectorAttribute::marshall(const char * _sep) string * VectorAttribute::marshall(const char * _sep) const
{ {
ostringstream os; ostringstream os;
map<string,string>::iterator it; string * rs;
string * rs; const char * my_sep;
const char * my_sep;
map<string,string>::const_iterator it;
if ( _sep == 0 ) if ( _sep == 0 )
{ {
my_sep = magic_sep; my_sep = magic_sep;
@ -39,7 +41,7 @@ string * VectorAttribute::marshall(const char * _sep)
{ {
my_sep = _sep; my_sep = _sep;
} }
if ( attribute_value.size() == 0 ) if ( attribute_value.size() == 0 )
{ {
return 0; return 0;
@ -69,38 +71,52 @@ string * VectorAttribute::to_xml() const
map<string,string>::const_iterator it; map<string,string>::const_iterator it;
ostringstream oss; ostringstream oss;
string * xml; string * xml;
oss << "<" << name() << ">"; oss << "<" << name() << ">";
for (it=attribute_value.begin();it!=attribute_value.end();it++) for (it=attribute_value.begin();it!=attribute_value.end();it++)
{ {
oss << "<" << it->first << ">" << it->second oss << "<" << it->first << ">" << it->second
<< "</"<< it->first << ">"; << "</"<< it->first << ">";
} }
oss << "</"<< name() << ">"; oss << "</"<< name() << ">";
xml = new string; xml = new string;
*xml = oss.str(); *xml = oss.str();
return xml; return xml;
} }
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
void VectorAttribute::unmarshall(const string& sattr) void VectorAttribute::unmarshall(const string& sattr, const char * _sep)
{ {
size_t bpos=0,epos,mpos; size_t bpos=0,epos,mpos;
string tmp; string tmp;
bool cont = true; bool cont = true;
const char * my_sep;
int my_sep_size;
if ( _sep == 0 )
{
my_sep = magic_sep;
my_sep_size = magic_sep_size;
}
else
{
my_sep = _sep;
my_sep_size = strlen(_sep);
}
while(cont) while(cont)
{ {
epos=sattr.find(magic_sep,bpos); epos=sattr.find(my_sep,bpos);
if (epos == string::npos) if (epos == string::npos)
{ {
tmp = sattr.substr(bpos); tmp = sattr.substr(bpos);
@ -109,16 +125,16 @@ void VectorAttribute::unmarshall(const string& sattr)
else else
{ {
tmp = sattr.substr(bpos,epos-bpos); tmp = sattr.substr(bpos,epos-bpos);
bpos = epos + magic_sep_size; bpos = epos + my_sep_size;
} }
mpos = tmp.find('='); mpos = tmp.find('=');
if (mpos == string::npos) if (mpos == string::npos)
{ {
continue; continue;
} }
attribute_value.insert(make_pair(tmp.substr(0,mpos), attribute_value.insert(make_pair(tmp.substr(0,mpos),
tmp.substr(mpos+1))); tmp.substr(mpos+1)));
} }

View File

@ -242,62 +242,84 @@ int TemplateSQL::drop(SqliteDB * db)
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
int TemplateSQL::replace_attribute( int TemplateSQL::replace_attribute(SqliteDB * db, Attribute * attribute)
SqliteDB * db,
const string& name,
const string& value)
{ {
ostringstream oss; ostringstream oss;
int rc; int rc;
string * astr;
multimap<string, Attribute *>::const_iterator i;
Attribute * attribute; multimap<string, Attribute *>::iterator i;
if ( id == -1 || name.empty() || value.empty() ) if ( id == -1 || attribute == 0)
{ {
return -1; return -1;
} }
i = attributes.find(name); i = attributes.find(attribute->name());
if ( i != attributes.end() ) //attribute exists if ( i != attributes.end() )
{ {
string * attr = i->second->marshall(); astr = i->second->marshall();
if ( attr != 0 ) if ( astr == 0 )
{ {
oss << "DELETE FROM " << table << " WHERE id=" << id return -1;
<< " AND name='" << name << "' AND value='" << *attr << "'"; }
delete attr; oss << "DELETE FROM " << table << " WHERE id=" << id
} << " AND name='" << attribute->name() << "' AND value='"
else << *astr << "'";
{
oss << "DELETE FROM " << table << " WHERE id=" << id delete astr;
<< " AND name='" << name << "'";
} if ((rc = db->exec(oss)) != 0 )
{
rc = db->exec(oss); return rc;
}
if ( rc != 0 )
{ delete i->second;
return rc;
} attributes.erase(i);
attributes.erase(name);
} }
attribute = new SingleAttribute(name,value); return insert_attribute(db,attribute);
}
attributes.insert(make_pair(attribute->name(),attribute));
/* -------------------------------------------------------------------------- */
oss.str(""); /* -------------------------------------------------------------------------- */
oss << "INSERT INTO " << table << " " << db_names int TemplateSQL::insert_attribute(SqliteDB * db, Attribute * attribute)
<< " VALUES (" << id << ",'" << name << "'," << {
Attribute::SIMPLE <<",'" << value << "')"; ostringstream oss;
int rc;
return db->exec(oss); string * astr;
int atype;
if ( id == -1 || attribute == 0)
{
return -1;
}
astr = attribute->marshall();
atype = attribute->type();
if ( astr == 0 )
{
return -1;
}
oss << "INSERT INTO " << table << " " << db_names
<< " VALUES (" << id << ",'" << attribute->name() << "'," << atype
<< ",'" << *astr << "')";
delete astr;
if ((rc = db->exec(oss)) == 0)
{
attributes.insert(make_pair(attribute->name(),attribute));
}
return rc;
} }
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */

View File

@ -95,35 +95,40 @@ void History::non_persistent_data()
{ {
ostringstream os; ostringstream os;
Nebula& nd = Nebula::instance(); Nebula& nd = Nebula::instance();
// ----------- Local Locations ------------ // ----------- Local Locations ------------
os.str(""); os.str("");
os << nd.get_var_location() << oid; os << nd.get_var_location() << oid;
vm_lhome = os.str(); vm_lhome = os.str();
os << "/deployment." << seq; os << "/deployment." << seq;
deployment_file = os.str(); deployment_file = os.str();
os.str(""); os.str("");
os << vm_lhome << "/transfer." << seq; os << vm_lhome << "/transfer." << seq;
transfer_file = os.str(); transfer_file = os.str();
os.str("");
os << vm_lhome << "/context.sh";
context_file = os.str();
// ----------- Remote Locations ------------ // ----------- Remote Locations ------------
os.str(""); os.str("");
os << vm_dir << "/" << oid << "/images"; os << vm_dir << "/" << oid << "/images";
vm_rhome = os.str(); vm_rhome = os.str();
os << "/checkpoint"; os << "/checkpoint";
checkpoint_file = os.str(); checkpoint_file = os.str();
os.str(""); os.str("");
os << vm_rhome << "/deployment." << seq; os << vm_rhome << "/deployment." << seq;
rdeployment_file = os.str(); rdeployment_file = os.str();
} }
@ -194,7 +199,7 @@ int History::unmarshall(int num, char **names, char ** values)
hostname = values[HOSTNAME]; hostname = values[HOSTNAME];
vm_dir = values[VM_DIR]; vm_dir = values[VM_DIR];
hid = atoi(values[HID]); hid = atoi(values[HID]);
vmm_mad_name = values[VMMMAD]; vmm_mad_name = values[VMMMAD];
@ -257,7 +262,7 @@ int History::select(SqliteDB * db)
} }
else else
{ {
oss << "SELECT * FROM history WHERE vid = "<< oid <<" AND seq = "<< seq; oss << "SELECT * FROM history WHERE vid = "<< oid <<" AND seq = "<< seq;
} }
rc = db->exec(oss,history_select_cb,(void *) this); rc = db->exec(oss,history_select_cb,(void *) this);
@ -277,7 +282,7 @@ int History::drop(SqliteDB * db)
{ {
ostringstream oss; ostringstream oss;
oss << "DELETE FROM " << table << " WHERE vid= "<< oid; oss << "DELETE FROM " << table << " WHERE vid= "<< oid;
return db->exec(oss); return db->exec(oss);
} }

View File

@ -21,12 +21,27 @@ Import('env')
lib_name='nebula_vm' lib_name='nebula_vm'
if env['parsers']=='yes':
# LEX
parser=env.Lex(
source='vm_var_parser.l'
)
env.NoClean(parser)
# BISON
parser=env.Bison(
source='vm_var_syntax.y'
)
env.NoClean(parser)
# Sources to generate the library # Sources to generate the library
source_files=[ source_files=[
'History.cc', 'History.cc',
'VirtualMachine.cc', 'VirtualMachine.cc',
'vm_var_parser.c',
'vm_var_syntax.cc',
'VirtualMachinePool.cc', 'VirtualMachinePool.cc',
'VirtualMachineTemplate.cc', 'VirtualMachineTemplate.cc'
] ]
# Build library # Build library

View File

@ -18,8 +18,8 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@ -158,13 +158,13 @@ int VirtualMachine::select(SqliteDB * db)
{ {
ostringstream oss; ostringstream oss;
ostringstream ose; ostringstream ose;
int rc; int rc;
int boid; int boid;
string filename; string filename;
Nebula& nd = Nebula::instance(); Nebula& nd = Nebula::instance();
oss << "SELECT * FROM " << table << " WHERE oid = " << oid; oss << "SELECT * FROM " << table << " WHERE oid = " << oid;
boid = oid; boid = oid;
@ -206,26 +206,26 @@ int VirtualMachine::select(SqliteDB * db)
else if (history->seq > 0) else if (history->seq > 0)
{ {
previous_history = new History(oid,history->seq - 1); previous_history = new History(oid,history->seq - 1);
rc = previous_history->select(db); rc = previous_history->select(db);
if ( rc != 0) if ( rc != 0)
{ {
goto error_previous_history; goto error_previous_history;
} }
} }
//Create support directory fo this VM //Create support directory fo this VM
oss.str(""); oss.str("");
oss << nd.get_var_location() << oid; oss << nd.get_var_location() << oid;
mkdir(oss.str().c_str(), 0777); mkdir(oss.str().c_str(), 0777);
chmod(oss.str().c_str(), 0777); chmod(oss.str().c_str(), 0777);
//Create Log support fo this VM //Create Log support fo this VM
try try
{ {
_log = new Log(nd.get_vm_log_filename(oid),Log::DEBUG); _log = new Log(nd.get_vm_log_filename(oid),Log::DEBUG);
} }
@ -233,7 +233,7 @@ int VirtualMachine::select(SqliteDB * db)
{ {
ose << "Error creating log: " << e.what(); ose << "Error creating log: " << e.what();
Nebula::log("ONE",Log::ERROR, ose); Nebula::log("ONE",Log::ERROR, ose);
_log = 0; _log = 0;
} }
@ -253,60 +253,78 @@ error_history:
ose << "Can not get history for VM id: " << oid; ose << "Can not get history for VM id: " << oid;
log("ONE", Log::ERROR, ose); log("ONE", Log::ERROR, ose);
return -1; return -1;
error_previous_history: error_previous_history:
ose << "Can not get previous history record (seq:" << history->seq ose << "Can not get previous history record (seq:" << history->seq
<< ") for VM id: " << oid; << ") for VM id: " << oid;
log("ONE", Log::ERROR, ose); log("ONE", Log::ERROR, ose);
return -1; return -1;
} }
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
int VirtualMachine::insert(SqliteDB * db) int VirtualMachine::insert(SqliteDB * db)
{ {
int rc; int rc;
string name; string name;
//Set a name if the VM has not got one SingleAttribute * attr;
string value;
ostringstream oss;
// ------------------------------------------------------------------------
// Set a name if the VM has not got one and VM_ID
// ------------------------------------------------------------------------
get_template_attribute("NAME",name); get_template_attribute("NAME",name);
if ( name.empty() == true ) if ( name.empty() == true )
{ {
SingleAttribute * name_attr; oss << "one-" << oid;
ostringstream default_name; value = oss.str();
default_name << "one-" << oid; attr = new SingleAttribute("NAME",value);
name = default_name.str();
vm_template.set(attr);
name_attr = new SingleAttribute("NAME",name); }
vm_template.set(name_attr); oss.str("");
}
oss << oid;
value = oss.str();
attr = new SingleAttribute("VM_ID",value);
vm_template.set(attr);
// ------------------------------------------------------------------------
// Get network leases
// ------------------------------------------------------------------------
rc = get_leases(); rc = get_leases();
if ( rc != 0 ) if ( rc != 0 )
{ {
goto error_leases; goto error_leases;
} }
// Insert the template first, so we get a valid template ID // ------------------------------------------------------------------------
// Insert the template first, so we get a valid template ID. Then the VM
// ------------------------------------------------------------------------
rc = vm_template.insert(db); rc = vm_template.insert(db);
if ( rc != 0 ) if ( rc != 0 )
{ {
goto error_template; goto error_template;
} }
//Insert the VM
rc = update(db); rc = update(db);
if ( rc != 0 ) if ( rc != 0 )
{ {
goto error_update; goto error_update;
} }
return 0; return 0;
@ -375,7 +393,7 @@ void VirtualMachine::add_history(
else else
{ {
seq = history->seq + 1; seq = history->seq + 1;
if (previous_history != 0) if (previous_history != 0)
{ {
delete previous_history; delete previous_history;
@ -389,16 +407,16 @@ void VirtualMachine::add_history(
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
void VirtualMachine::cp_history() void VirtualMachine::cp_history()
{ {
History * htmp; History * htmp;
if (history == 0) if (history == 0)
{ {
return; return;
} }
htmp = new History(oid, htmp = new History(oid,
history->seq + 1, history->seq + 1,
history->hid, history->hid,
@ -406,20 +424,20 @@ void VirtualMachine::cp_history()
history->vm_dir, history->vm_dir,
history->vmm_mad_name, history->vmm_mad_name,
history->tm_mad_name); history->tm_mad_name);
if ( previous_history != 0 ) if ( previous_history != 0 )
{ {
delete previous_history; delete previous_history;
} }
previous_history = history; previous_history = history;
history = htmp; history = htmp;
} }
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
void VirtualMachine::cp_previous_history() void VirtualMachine::cp_previous_history()
{ {
History * htmp; History * htmp;
@ -428,7 +446,7 @@ void VirtualMachine::cp_previous_history()
{ {
return; return;
} }
htmp = new History(oid, htmp = new History(oid,
history->seq + 1, history->seq + 1,
previous_history->hid, previous_history->hid,
@ -436,12 +454,12 @@ void VirtualMachine::cp_previous_history()
previous_history->vm_dir, previous_history->vm_dir,
previous_history->vmm_mad_name, previous_history->vmm_mad_name,
previous_history->tm_mad_name); previous_history->tm_mad_name);
delete previous_history; delete previous_history;
previous_history = history; previous_history = history;
history = htmp; history = htmp;
} }
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -452,7 +470,7 @@ void VirtualMachine::get_requirements (int& cpu, int& memory, int& disk)
string scpu; string scpu;
istringstream iss; istringstream iss;
float fcpu; float fcpu;
get_template_attribute("MEMORY",memory); get_template_attribute("MEMORY",memory);
get_template_attribute("CPU",scpu); get_template_attribute("CPU",scpu);
@ -461,7 +479,7 @@ void VirtualMachine::get_requirements (int& cpu, int& memory, int& disk)
cpu = 0; cpu = 0;
memory = 0; memory = 0;
disk = 0; disk = 0;
return; return;
} }
@ -482,11 +500,11 @@ int VirtualMachine::get_leases()
{ {
int num_nics, rc; int num_nics, rc;
vector<Attribute * > nics; vector<Attribute * > nics;
VirtualNetworkPool * vnpool; VirtualNetworkPool * vnpool;
VirtualNetwork * vn; VirtualNetwork * vn;
VectorAttribute * nic; VectorAttribute * nic;
map<string,string> new_nic; map<string,string> new_nic;
string ip; string ip;
string mac; string mac;
string bridge; string bridge;
@ -495,37 +513,37 @@ int VirtualMachine::get_leases()
ostringstream vnid; ostringstream vnid;
// Set the networking attributes. // Set the networking attributes.
Nebula& nd = Nebula::instance(); Nebula& nd = Nebula::instance();
vnpool = nd.get_vnpool(); vnpool = nd.get_vnpool();
num_nics = vm_template.get("NIC",nics); num_nics = vm_template.get("NIC",nics);
for(int i=0; i<num_nics; i++,vnid.str("")) for(int i=0; i<num_nics; i++,vnid.str(""))
{ {
nic = dynamic_cast<VectorAttribute * >(nics[i]); nic = dynamic_cast<VectorAttribute * >(nics[i]);
if ( nic == 0 ) if ( nic == 0 )
{ {
continue; continue;
} }
network = nic->vector_value("NETWORK"); network = nic->vector_value("NETWORK");
if ( network.empty() ) if ( network.empty() )
{ {
continue; continue;
} }
vn = vnpool->get(network,true); vn = vnpool->get(network,true);
if ( vn == 0 ) if ( vn == 0 )
{ {
continue; return -1;
} }
ip = nic->vector_value("IP"); ip = nic->vector_value("IP");
if (ip.empty()) if (ip.empty())
{ {
rc = vn->get_lease(oid, ip, mac, bridge); rc = vn->get_lease(oid, ip, mac, bridge);
@ -534,9 +552,9 @@ int VirtualMachine::get_leases()
{ {
rc = vn->set_lease(oid, ip, mac, bridge); rc = vn->set_lease(oid, ip, mac, bridge);
} }
vn->unlock(); vn->unlock();
if ( rc != 0 ) if ( rc != 0 )
{ {
return -1; return -1;
@ -549,12 +567,12 @@ int VirtualMachine::get_leases()
new_nic.insert(make_pair("BRIDGE" ,bridge)); new_nic.insert(make_pair("BRIDGE" ,bridge));
new_nic.insert(make_pair("VNID" ,vnid.str())); new_nic.insert(make_pair("VNID" ,vnid.str()));
new_nic.insert(make_pair("IP" ,ip)); new_nic.insert(make_pair("IP" ,ip));
nic->replace(new_nic); nic->replace(new_nic);
new_nic.erase(new_nic.begin(),new_nic.end()); new_nic.erase(new_nic.begin(),new_nic.end());
} }
return 0; return 0;
} }
@ -564,7 +582,7 @@ int VirtualMachine::get_leases()
void VirtualMachine::release_leases() void VirtualMachine::release_leases()
{ {
Nebula& nd = Nebula::instance(); Nebula& nd = Nebula::instance();
VirtualNetworkPool * vnpool = nd.get_vnpool(); VirtualNetworkPool * vnpool = nd.get_vnpool();
string vnid; string vnid;
@ -572,7 +590,7 @@ void VirtualMachine::release_leases()
int num_nics; int num_nics;
vector<Attribute const * > nics; vector<Attribute const * > nics;
VirtualNetwork * vn; VirtualNetwork * vn;
num_nics = get_template_attribute("NIC",nics); num_nics = get_template_attribute("NIC",nics);
@ -591,26 +609,80 @@ void VirtualMachine::release_leases()
{ {
continue; continue;
} }
ip = nic->vector_value("IP"); ip = nic->vector_value("IP");
if ( ip.empty() ) if ( ip.empty() )
{ {
continue; continue;
} }
vn = vnpool->get(atoi(vnid.c_str()),true); vn = vnpool->get(atoi(vnid.c_str()),true);
if ( vn == 0 ) if ( vn == 0 )
{ {
continue; continue;
} }
vn->release_lease(ip); vn->release_lease(ip);
vn->unlock(); vn->unlock();
} }
} }
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::write_context()
{
ofstream file;
vector<const Attribute*> attrs;
const VectorAttribute * context;
map<string, string>::const_iterator it;
if ( history == 0 )
return -1;
if ( get_template_attribute("CONTEXT",attrs) != 1 )
{
log("VM", Log::INFO, "Virtual Machine has no context");
return 0;
}
file.open(history->context_file.c_str(),ios::out);
if (file.fail() == true)
{
ostringstream oss;
oss << "Could not open context file: " << history->context_file;
log("VM", Log::ERROR, oss);
return -1;
}
context = dynamic_cast<const VectorAttribute *>(attrs[0]);
if (context == 0)
{
file.close();
return -1;
}
const map<string, string> values = context->value();
file << "# Context variables generated by OpenNebula\n";
for (it=values.begin(); it != values.end(); it++ )
{
file << it->first <<"=\""<< it->second << "\"" << endl;
}
file.close();
return 0;
}
/* ************************************************************************** */ /* ************************************************************************** */
/* Virtual Machine :: Misc */ /* Virtual Machine :: Misc */
/* ************************************************************************** */ /* ************************************************************************** */
@ -622,15 +694,15 @@ ostream& operator<<(ostream& os, VirtualMachine& vm)
os << "STATE : " << vm.state << endl; os << "STATE : " << vm.state << endl;
os << "LCM STATE : " << vm.lcm_state << endl; os << "LCM STATE : " << vm.lcm_state << endl;
os << "DEPLOY ID : " << vm.deploy_id << endl; os << "DEPLOY ID : " << vm.deploy_id << endl;
os << "MEMORY : " << vm.memory << endl; os << "MEMORY : " << vm.memory << endl;
os << "CPU : " << vm.cpu << endl; os << "CPU : " << vm.cpu << endl;
os << "LAST POLL : " << vm.last_poll << endl; os << "LAST POLL : " << vm.last_poll << endl;
os << "START TIME : " << vm.stime << endl; os << "START TIME : " << vm.stime << endl;
os << "STOP TIME : " << vm.etime << endl; os << "STOP TIME : " << vm.etime << endl;
os << "NET TX : " << vm.net_tx << endl; os << "NET TX : " << vm.net_tx << endl;
os << "NET RX : " << vm.net_rx << endl; os << "NET RX : " << vm.net_rx << endl;
os << "Template" << endl << vm.vm_template << endl; os << "Template" << endl << vm.vm_template << endl;
return os; return os;
}; };

View File

@ -17,6 +17,11 @@
#include "Nebula.h" #include "Nebula.h"
#include "VirtualMachinePool.h" #include "VirtualMachinePool.h"
#include "vm_var_syntax.h"
extern "C"
{
#include "vm_var_parser.h"
}
#include <sstream> #include <sstream>
int VirtualMachinePool::allocate ( int VirtualMachinePool::allocate (
@ -25,15 +30,17 @@ int VirtualMachinePool::allocate (
int * oid, int * oid,
bool on_hold) bool on_hold)
{ {
VirtualMachine * vm; VirtualMachine * vm;
char * error_msg; char * error_msg;
int rc; int rc;
vector<Attribute *> attrs;
// Build a new Virtual Machine object // Build a new Virtual Machine object
vm = new VirtualMachine; vm = new VirtualMachine;
if (on_hold == true) if (on_hold == true)
{ {
vm->state = VirtualMachine::HOLD; vm->state = VirtualMachine::HOLD;
@ -50,23 +57,33 @@ int VirtualMachinePool::allocate (
if ( rc != 0 ) if ( rc != 0 )
{ {
ostringstream oss; ostringstream oss;
oss << error_msg; oss << error_msg;
Nebula::log("ONE", Log::ERROR, oss); Nebula::log("ONE", Log::ERROR, oss);
free(error_msg); free(error_msg);
return -2; return -2;
} }
vm->vm_template.remove("CONTEXT",attrs);
// Insert the Object in the pool // Insert the Object in the pool
*oid = PoolSQL::allocate(vm); *oid = PoolSQL::allocate(vm);
if ( *oid == -1 ) if ( *oid == -1 )
{ {
return -1; return -1;
} }
generate_context(*oid,attrs);
for (int i = 0; i < attrs.size() ; i++)
{
if (attrs[i] != 0)
delete attrs[i];
}
return 0; return 0;
} }
@ -102,3 +119,150 @@ int VirtualMachinePool::get_pending(
return PoolSQL::search(oids,VirtualMachine::table,where); return PoolSQL::search(oids,VirtualMachine::table,where);
}; };
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachinePool::generate_context(int vm_id, vector<Attribute *> attrs)
{
VirtualMachine * vm;
VectorAttribute * context_parsed;
VectorAttribute * context;
string * str;
string parsed;
int rc;
char * error_msg;
if ( attrs.size() == 0 )
{
return;
}
context = dynamic_cast<VectorAttribute *>(attrs[0]);
if (context == 0)
{
return;
}
str = context->marshall(" @^_^@ ");
if (str == 0)
{
return;
}
rc = parse_attribute(vm_id,*str,parsed,&error_msg);
if ( rc != 0 )
{
if (error_msg != 0)
{
ostringstream oss;
oss << error_msg << ": " << *str;
free(error_msg);
Nebula::log("ONE", Log::ERROR, oss);
}
delete str;
return;
}
delete str;
context_parsed = new VectorAttribute("CONTEXT");
context_parsed->unmarshall(parsed," @^_^@ ");
vm = get(vm_id,true);
if ( vm == 0 )
{
return;
}
vm->insert_template_attribute(db,context_parsed);
vm->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
pthread_mutex_t VirtualMachinePool::lex_mutex = PTHREAD_MUTEX_INITIALIZER;
extern "C"
{
int vm_var_parse (VirtualMachinePool * vmpool,
ostringstream * parsed,
VirtualMachine * vm,
char ** errmsg);
int vm_var_lex_destroy();
YY_BUFFER_STATE vm_var__scan_string(const char * str);
void vm_var__delete_buffer(YY_BUFFER_STATE);
}
int VirtualMachinePool::parse_attribute(int vm_id,
string &attribute,
string &parsed,
char ** error_msg)
{
YY_BUFFER_STATE str_buffer;
const char * str;
int rc;
VirtualMachine * vm;
ostringstream oss_parsed;
*error_msg = 0;
pthread_mutex_lock(&lex_mutex);
vm = get(vm_id,true);
if ( vm == 0 )
{
goto error_vm;
}
str = attribute.c_str();
str_buffer = vm_var__scan_string(str);
if (str_buffer == 0)
{
goto error_yy;
}
rc = vm_var_parse(this,&oss_parsed,vm,error_msg);
vm_var__delete_buffer(str_buffer);
vm_var_lex_destroy();
vm->unlock();
pthread_mutex_unlock(&lex_mutex);
parsed = oss_parsed.str();
return rc;
error_vm:
*error_msg=strdup("Could not find virtual machine!");
goto error_common;
error_yy:
*error_msg=strdup("Error setting scan buffer");
vm->unlock();
error_common:
pthread_mutex_unlock(&lex_mutex);
return -1;
}