diff --git a/SConstruct b/SConstruct new file mode 100644 index 0000000000..afcb8b7c5e --- /dev/null +++ b/SConstruct @@ -0,0 +1,96 @@ + +import os +import sys +sys.path.append("./share/scons") +from lex_bison import * + +# This is the absolute path where the project is located +cwd=os.getcwd() + +# Environment that will be applied to each scons child +main_env=Environment() +main_env['ENV']['PATH']=os.environ['PATH'] + +# Add builders for flex and bison +add_lex(main_env) +add_bison(main_env) + + +# Include dirs +main_env.Append(CPPPATH=[ + cwd+'/include', +]) + +# Library dirs +main_env.Append(LIBPATH=[ + cwd+'/src/common', + cwd+'/src/host', + cwd+'/src/mad', + cwd+'/src/nebula', + cwd+'/src/pool', + cwd+'/src/template', + cwd+'/src/vm', + cwd+'/src/vmm', + cwd+'/src/lcm', + cwd+'/src/tm', + cwd+'/src/dm', + cwd+'/src/im', + cwd+'/src/rm', +]) + +# Compile flags +main_env.Append(CPPFLAGS=[ + "-g", + "-Wall" +]) + +# Linking flags +main_env.Append(LDFLAGS=["-g"]) + +####################### +# EXTRA CONFIGURATION # +####################### + +# SQLITE +sqlite_dir=ARGUMENTS.get('sqlite', 'none') +if sqlite_dir!='none': + main_env.Append(LIBPATH=[sqlite_dir+"/lib"]) + main_env.Append(CPPPATH=[sqlite_dir+"/include"]) + +# xmlrpc +xmlrpc_dir=ARGUMENTS.get('xmlrpc', 'none') +if xmlrpc_dir!='none': + main_env.Append(LIBPATH=[xmlrpc_dir+"/lib"]) + main_env.Append(CPPPATH=[xmlrpc_dir+"/include"]) + +# build lex/bison +build_parsers=ARGUMENTS.get('parsers', 'no') +if build_parsers=='yes': + main_env.Append(parsers='yes') +else: + main_env.Append(parsers='no') + + +# SCONS scripts to build +build_scripts=[ + 'src/common/SConstruct', + 'src/template/SConstruct', + 'src/host/SConstruct', + 'src/mad/SConstruct', + 'src/nebula/SConstruct', + 'src/pool/SConstruct', + 'src/vm/SConstruct', + 'src/vmm/SConstruct', + 'src/lcm/SConstruct', + 'src/rm/SConstruct', + 'src/tm/SConstruct', + 'src/im/SConstruct', + 'src/dm/SConstruct', + 'src/scheduler/SConstruct', +] + +for script in build_scripts: + env=main_env.Clone() + SConscript(script, exports='env') + + diff --git a/include/ActionManager.h b/include/ActionManager.h new file mode 100644 index 0000000000..a8dbbb3375 --- /dev/null +++ b/include/ActionManager.h @@ -0,0 +1,155 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 ACTION_MANAGER_H_ +#define ACTION_MANAGER_H_ + +#include +#include +#include +#include + +using namespace std; + + +/** + * ActionListener class. Interface to be implemented by any class + * that need to handle actions. There are two predefined actions + * (each action is identified with its name, a string): + * - ACTION_TIMER, periodic action + * - ACTION_FINALIZE, to finalize the action loop + */ + +class ActionListener +{ +public: + + /** + * Predefined string to refer to the periodic action + */ + static const string ACTION_TIMER; + + /** + * Predefined string to refer to the finalize action + */ + static const string ACTION_FINALIZE; + + ActionListener(){}; + + virtual ~ActionListener(){}; + + /** + * the do_action() function is executed upon action arrival. + * This function should check the action type, and perform the + * corresponding action. + * @param name the action name + * @param args action arguments + */ + virtual void do_action(const string &name, void *args) = 0; +}; + + +/** + * ActionManager. Provides action support for a class implementing + * the ActionListener interface. + */ + +class ActionManager +{ +public: + + ActionManager(); + virtual ~ActionManager(); + + /** Function to trigger an action to this manager. + * @param action the action name + * @param args arguments for the action + */ + void trigger( + const string &action, + void * args); + + /** The calling thread will be suspended until an action is triggeed. + * @param timeout for the periodic action. Use 0 to disable the timer. + * @param timer_args arguments for the timer action + */ + void loop( + time_t timeout, + void * timer_args); + + /** Register the calling object in this action manager. + * @param listener a pointer to the action listner + */ + void addListener( + ActionListener * listener) + { + this->listener = listener; + }; + +private: + + /** + * Implementation class, pending actions are stored in a queue. + * Each element stores the action name and its arguments + */ + struct ActionRequest + { + string name; + void * args; + + ActionRequest( + const string &aname = "", + void * aargs = 0): + name(aname), + args(aargs){}; + }; + + /** + * Queue of pending actions, processed in a FIFO manner + */ + queue actions; + + /** + * Action synchronization is implemented using the pthread library, + * with condition variable and its associated mutex + */ + pthread_mutex_t mutex; + pthread_cond_t cond; + + /** + * The listener notified by this manager + */ + ActionListener * listener; + + /** + * Function to lock the Manager mutex + */ + void lock() + { + pthread_mutex_lock(&mutex); + }; + + /** + * Function to unlock the Manager mutex + */ + void unlock() + { + pthread_mutex_unlock(&mutex); + }; +}; + +#endif /*ACTION_MANAGER_H_*/ diff --git a/include/Attribute.h b/include/Attribute.h new file mode 100644 index 0000000000..ca2435b6e4 --- /dev/null +++ b/include/Attribute.h @@ -0,0 +1,218 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 ATTRIBUTE_H_ +#define ATTRIBUTE_H_ + +#include +#include +#include + +using namespace std; + +/** + * Attribute base class for name-value pairs. This class provides a generic + * interface to implement + */ +class Attribute +{ +public: + + Attribute(string& aname):attribute_name(aname) + { + transform ( + attribute_name.begin(), + attribute_name.end(), + attribute_name.begin(), + (int(*)(int))toupper); + }; + + Attribute(const char * aname) + { + ostringstream name; + + name << uppercase << aname; + attribute_name = name.str(); + }; + + virtual ~Attribute(){}; + + enum AttributeType + { + SIMPLE = 0, + VECTOR = 1 + }; + + /** + * Gets the name of the attribute. + * @return the attribute name + */ + const string& name() const + { + return attribute_name; + }; + + /** + * Marshall the attribute in a single string. The string MUST be freed + * by the calling function. + * @return a string (allocated in the heap) holding the attribute value. + */ + virtual string * marshall() = 0; + + /** + * Builds a new attribute from a string. + */ + virtual void unmarshall(string& sattr) = 0; + + /** + * Returns the attribute type + */ + virtual AttributeType type() = 0; + +private: + + /** + * The attribute name. + */ + string attribute_name; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * The SingleAttribute class represents a simple attribute in the form + * NAME = VALUE. + */ + +class SingleAttribute : public Attribute +{ +public: + + SingleAttribute(string& name):Attribute(name){}; + + SingleAttribute(string& name, string& value): + Attribute(name),attribute_value(value){}; + + SingleAttribute(const char * name, string& value): + Attribute(name),attribute_value(value){}; + + ~SingleAttribute(){}; + + /** + * Returns the attribute value, a string. + */ + const string& value() const + { + return attribute_value; + }; + + /** + * Marshall the attribute in a single string. The string MUST be freed + * by the calling function. + * @return a string (allocated in the heap) holding the attribute value. + */ + string * marshall() + { + string * rs = new string; + + *rs = attribute_value; + + return rs; + }; + + /** + * Builds a new attribute from a string. + */ + void unmarshall(string& sattr) + { + attribute_value = sattr; + }; + + /** + * Returns the attribute type + */ + AttributeType type() + { + return SIMPLE; + }; + +private: + + string attribute_value; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * The VectorAttribute class represents an array attribute in the form + * NAME = [ VAL_NAME_1=VAL_VALUE_1,...,VAL_NAME_N=VAL_VALUE_N]. + */ + +class VectorAttribute : public Attribute +{ +public: + + VectorAttribute(string& name):Attribute(name){}; + + VectorAttribute(string& name, map& value): + Attribute(name),attribute_value(value){}; + + ~VectorAttribute(){}; + + /** + * Returns the attribute value, a string. + */ + const map& value() const + { + return attribute_value; + }; + + /** + * + */ + string vector_value(const char *name) const; + + /** + * Marshall the attribute in a single string. The string MUST be freed + * by the calling function. The string is in the form: + * "VAL_NAME_1=VAL_VALUE_1,...,VAL_NAME_N=VAL_VALUE_N". + * @return a string (allocated in the heap) holding the attribute value. + */ + string * marshall(); + + /** + * Builds a new attribute from a string of the form: + * "VAL_NAME_1=VAL_VALUE_1,...,VAL_NAME_N=VAL_VALUE_N". + */ + void unmarshall(string& sattr); + + /** + * Returns the attribute type + */ + AttributeType type() + { + return VECTOR; + }; + +private: + + map attribute_value; +}; + +#endif /*ATTRIBUTE_H_*/ diff --git a/include/DispatchManager.h b/include/DispatchManager.h new file mode 100644 index 0000000000..0f6f41bdf4 --- /dev/null +++ b/include/DispatchManager.h @@ -0,0 +1,260 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 DISPATCH_MANAGER_H_ +#define DISPATCH_MANAGER_H_ + +#include "ActionManager.h" +#include "HostPool.h" +#include "VirtualMachinePool.h" + +using namespace std; + +extern "C" void * dm_action_loop(void *arg); + +class DispatchManager : public ActionListener +{ +public: + + DispatchManager( + VirtualMachinePool * _vmpool, + HostPool * _hpool): + hpool(_hpool), + vmpool(_vmpool) + { + am.addListener(this); + }; + + ~DispatchManager() + {} + ; + + enum Actions + { + SUSPEND_SUCCESS, /**< Send by LCM when a VM is suspended*/ + SUSPEND_FAILURE, /**< Send by LCM when a VM could not be suspended*/ + STOP_SUCCESS, /**< Send by LCM when a VM is stopped*/ + STOP_FAILURE, /**< Send by LCM when a VM could not be stopped*/ + MIGRATE_FAILURE, /**< Send by LCM when a VM could not be migrated*/ + DONE, /**< Send by LCM when a VM is shut down*/ + FAILED, /**< Send by LCM when one of the execution steps fails*/ + FINALIZE + }; + + /** + * Triggers specific actions to the Dispatch Manager. This function + * wraps the ActionManager trigger function. + * @param action the DM action + * @param vid VM unique id. This is the argument of the passed to the + * invoked action. + */ + void trigger( + Actions action, + int _vid); + + /** + * This functions creates a new thread for the Dispatch Manager. This + * thread will wait in an action loop till it receives ACTION_FINALIZE. + * @return 0 on success. + */ + int start(); + + /** + * Gets the thread identification. + * @return pthread_t for the manager thread (that in the action loop). + */ + pthread_t get_thread_id() const + { + return dm_thread; + }; + + //-------------------------------------------------------------------------- + // DM Actions, the RM and the Scheduler will invoke this methods + //-------------------------------------------------------------------------- + + /** + * Allocates a new virtual machine + * @return 0 on success + */ + int allocate ( + int uid, + const string& stemplate, + int * oid); + + /** + * Deploys a VM. A new history record MUST be added before calling this + * function. Also the VM MUST have its mutex locked. If the function fails + * the calling funtion is responsible for recovering from the error. + * @param vm pointer to a VirtualMachine with its mutex locked. + * @return 0 on success + */ + int deploy ( + VirtualMachine * vm); + + /** + * Migrates a VM. The following actions must be performed before calling + * this function: + * - Lock the VM mutex. + * - Update the History statistics of the current host. + * - Add a new History record with the new host. + * If the function fails the calling funtion is responsible for recovering + * from the error. + * @param vm pointer to a VirtualMachine with its mutex locked. + * @return 0 on success + */ + int migrate( + VirtualMachine * vm); + + /** + * Migrates a VM. The following actions must be performed before calling + * this function: + * - Lock the VM mutex. + * - Update the History statistics of the current host. + * - Add a new History record with the new host. + * If the function fails the calling funtion is responsible for recovering + * from the error. + * @param vm pointer to a VirtualMachine with its mutex locked. + * @return 0 on success + */ + int live_migrate( + VirtualMachine * vm); + + /** + * Shuts down a 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 shutdown ( + int vid); + + /** + * Holds a 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 hold( + int vid); + + /** + * Releases a 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 release( + int vid); + + /** + * Stops a 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 stop( + int vid); + + /** + * Suspends a 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 suspend( + int vid); + + /** + * Resumes a 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 resume( + int vid); + + /** + * Ends a VM life cycle inside ONE. + * @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 finalize( + int vid); + +private: + /** + * Thread id for the Dispatch Manager + */ + pthread_t dm_thread; + + /** + * Pointer to the Host Pool, to access hosts + */ + HostPool * hpool; + + /** + * Pointer to the Host Pool, to access hosts + */ + VirtualMachinePool * vmpool; + + /** + * Action engine for the Manager + */ + ActionManager am; + + /** + * Function to execute the Manager action loop method within a new pthread + * (requires C linkage) + */ + friend void * dm_action_loop(void *arg); + + /** + * The action function executed when an action is triggered. + * @param action the name of the action + * @param arg arguments for the action function + */ + void do_action( + const string & action, + void * arg); + + //-------------------------------------------------------------------------- + // DM Actions associated with a VM state transition + //-------------------------------------------------------------------------- + + void suspend_success_action(int vid); + + void suspend_failure_action(int vid); + + void stop_success_action(int vid); + + void stop_failure_action(int vid); + + void migrate_failure_action(int vid); + + void done_action(int vid); + + void failed_action(int vid); + + void host_add_vm(VirtualMachine *vm); + + void host_del_vm(VirtualMachine *vm); + +}; + +#endif /*DISPATCH_MANAGER_H*/ + diff --git a/include/History.h b/include/History.h new file mode 100644 index 0000000000..4af244521d --- /dev/null +++ b/include/History.h @@ -0,0 +1,234 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 HISTORY_H_ +#define HISTORY_H_ + +#include +#include "ObjectSQL.h" + +using namespace std; + +extern "C" int history_select_cb ( + void * _history, + int num, + char ** values, + char ** names); + +/** + * The History class, it represents an execution record of a Virtual Machine. + */ + +class History:public ObjectSQL +{ +public: + + History(int oid); + + History( + int oid, + int seq, + int hid, + string& hostname, + string& vm_dir, + string& vmm, + string& tm); + + ~History(){}; + + enum MigrationReason + { + NONE, + ERROR, + STOP_RESUME, + PERFORMANCE, + USER, + RESCHEDULING, + KILL + }; + +private: + friend class VirtualMachine; + + // ---------------------------------------- + // DataBase implementation variables + // ---------------------------------------- + enum ColNames + { + OID = 0, + SEQ = 1, + HOSTNAME = 2, + VM_DIR = 3, + HID = 4, + VMMMAD = 5, + TMMAD = 6, + STIME = 7, + ETIME = 8, + PROLOG_STIME = 9, + PROLOG_ETIME = 10, + RUNNING_STIME = 11, + RUNNING_ETIME = 12, + EPILOG_STIME = 13, + EPILOG_ETIME = 14, + REASON = 15, + LIMIT = 16 + }; + + static const char * table; + + static const char * db_names; + + static const char * db_bootstrap; + + void non_persistent_data(); + + static string column_name(const ColNames column) + { + switch (column) + { + case HID: + return "hid"; + case ETIME: + return "etime"; + case RUNNING_ETIME: + return "retime"; + default: + return ""; + } + } + + // ---------------------------------------- + // History fields + // ---------------------------------------- + int oid; + int seq; + + string hostname; + string vm_rdir; + + int hid; + + string vmm_mad_name; + string tm_mad_name; + + time_t stime; + time_t etime; + + time_t prolog_stime; + time_t prolog_etime; + + time_t running_stime; + time_t running_etime; + + time_t epilog_stime; + time_t epilog_etime; + + MigrationReason reason; + + //Non-persistent history fields + string vm_lhome; + string vm_rhome; + + string deployment_lfile; + string deployment_rfile; + + string checkpoint_file; + + friend int history_select_cb ( + void * _history, + int num, + char ** values, + char ** names); + + /** + * Writes the history record in the DB + * @param db pointer to the database. + * @return 0 on success. + */ + int insert(SqliteDB * db); + + /** + * Reads the history record from the DB + * @param db pointer to the database. + * @return 0 on success. + */ + int select(SqliteDB * db); + + /** + * Removes the all history records from the DB + * @param db pointer to the database. + * @return 0 on success. + + */ + int drop(SqliteDB * db); + + /** + * Updates the history record + * @param db pointer to the database. + * @return 0 on success. + */ + int update(SqliteDB * db) + { + return insert(db); + } + + /** + * Gets the value of a column in the pool for a given object + * @param db pointer to Database + * @param column to be selected + * @param where contidtion to select the column + * @param value of the column + * @return 0 on success + */ + int select_column( + SqliteDB * db, + const string& column, + const string& where, + string * value) + { + return ObjectSQL::select_column(db,table,column,where,value); + } + + /** + * Sets the value of a column in the pool for a given object + * @param db pointer to Database + * @param column to be selected + * @param where contidtion to select the column + * @param value of the column + * @return 0 on success + */ + int update_column( + SqliteDB * db, + const string& column, + const string& where, + const string& value) + { + return ObjectSQL::update_column(db,table,column,where,value); + } + + + /** + * Function to unmarshall a history 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); +}; + +#endif /*HISTORY_H_*/ diff --git a/include/Host.h b/include/Host.h new file mode 100644 index 0000000000..48becd54b1 --- /dev/null +++ b/include/Host.h @@ -0,0 +1,474 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 HOST_H_ +#define HOST_H_ + +#include "PoolSQL.h" +#include "HostShare.h" +#include "HostTemplate.h" + +using namespace std; + +extern "C" int host_select_cb (void * _host, int num,char ** values, char ** names); + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * The Host class. It represents a Host... + */ +class Host : public PoolObjectSQL +{ +public: + + // ------------------------------------------------------------------------ + // Host States + // ------------------------------------------------------------------------ + + enum HostState + { + INIT = 0, /**< Initial state for enabled hosts. */ + MONITORING = 1, /**< The host is being monitored. */ + MONITORED = 2, /**< The host has been successfully monitored. */ + ERROR = 3, /**< An error ocurrer while monitoring the host. */ + DISABLED = 4 /**< The host is disabled won't be monitored. */ + }; + + /** + * Function to write a Host on an output stream + */ + friend ostream& operator<<(ostream& os, Host& h); + + /** + * Get the Host unique identifier HID, that matches the OID of the object + * @return HID Host identifier + */ + int get_hid() const + { + 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 + * @return true if the host is enabled + */ + bool isEnabled() const + { + return state != DISABLED; + } + + /** + * Updates the Host's last_monitored time stamp. + * @param success if the monitored action was successfully performed + */ + void touch(bool success) + { + last_monitored = time(0); + + if ( state != DISABLED) //Don't change the state is host is disabled + { + if (success == true) + { + state = MONITORED; + } + else + { + state = ERROR; + } + } + }; + + /** + * Disables the current host, it will not be monitored nor used by the + * scheduler + */ + void disable() + { + state = DISABLED; + }; + + /** + * Enables the current host, it will be monitored and could be used by + * the scheduler + */ + void enable() + { + state = INIT; + }; + + /** + * Returns host host_name + * @return host_name Host's hostname + */ + const string& get_hostname() const + { + return hostname; + }; + + /** Update host counters and update the whole host on the DB + * @param parse_str string with values to be parsed + * @return 0 on success + **/ + int update_info(string &parse_str); + + /** + * + */ + HostState get_state() const + { + return state; + }; + + /** + * + */ + const string& get_vmm_mad() const + { + return vmm_mad_name; + }; + + /** + * + */ + const string& get_tm_mad() const + { + return tm_mad_name; + }; + + /** + * + */ + const string& get_im_mad() const + { + return im_mad_name; + }; + + /** + * + */ + void set_state(HostState state) + { + this->state = state; + }; + + /** + * + */ + time_t get_last_monitored() const + { + return last_monitored; + }; + + // ------------------------------------------------------------------------ + // Template + // ------------------------------------------------------------------------ + + /** + * Gets the values of a template attribute + * @param name of the attribute + * @param values of the attribute + * @return the number of values + */ + int get_template_attribute( + string& name, + vector& values) const + { + return host_template.get(name,values); + }; + + /** + * Gets the values of a template attribute + * @param name of the attribute + * @param values of the attribute + * @return the number of values + */ + int get_template_attribute( + const char *name, + vector& values) const + { + string str=name; + return host_template.get(str,values); + }; + + /** + * Gets a string based host attribute + * @param name of the attribute + * @param value of the attribute (a string), will be "" if not defined + */ + void get_template_attribute( + const char * name, + string& value) const + { + string str=name; + host_template.get(str,value); + } + + /** + * Gets a string based host attribute + * @param name of the attribute + * @param value of the attribute (an int), will be 0 if not defined + */ + void get_template_attribute( + const char * name, + int& value) const + { + string str=name; + host_template.get(str,value); + } + + // --------------------------------------------------------- + // Lex & bison parser for requirements and rank expressions + // --------------------------------------------------------- + + /** + * Evaluates a requirement expression on the given host. + * @param requirements string + * @param result true if the host matches the requirements + * @param errmsg string describing the error, must be freed by the + * calling function + * @return 0 on success + */ + int match(const string& requirements, bool& result, char **errmsg); + + /** + * Evaluates a rank expression on the given host. + * @param rank string + * @param result of the rank evaluation + * @param errmsg string describing the error, must be freed by the + * calling function + * @return 0 on success + */ + int rank(const string& rank, int& result, char **errmsg); + + // ------------------------------------------------------------------------ + // Share functions + // ------------------------------------------------------------------------ + + /** + * Adds a new VM to the given share by icrementing the cpu,mem and disk + * counters + * @param cpu needed by the VM (percentage) + * @param mem needed by the VM (in Kb) + * @param disk needed by the VM + * @return 0 on success + */ + void add_vm(int cpu, int mem, int disk) + { + host_share.add(cpu,mem,disk); + }; + + /** + * Deletes a new VM from the given share by decrementing the cpu,mem and + * disk counters + * @param cpu useded by the VM (percentage) + * @param mem used by the VM (in Kb) + * @param disk used by the VM + * @return 0 on success + */ + void del_vm(int cpu, int mem, int disk) + { + host_share.del(cpu,mem,disk); + }; + + /** + * Tests whether a new VM can be hosted by the host or not + * @param cpu needed by the VM (percentage) + * @param mem needed by the VM (in Kb) + * @param disk needed by the VM + * @return true if the share can host the VM + */ + bool test_vm(int cpu, int mem, int disk) + { + return host_share.test(cpu,mem,disk); + } + +private: + // ------------------------------------------------------------------------- + // Friends + // ------------------------------------------------------------------------- + + friend class HostPool; + + friend int host_select_cb ( + void * _host, + int num, + char ** values, + char ** names); + + // ------------------------------------------------------------------------- + // Host Description + // ------------------------------------------------------------------------- + + string hostname; + + /** + * The state of the Host + */ + HostState state; + + /** + * Name of the IM driver used to monitor this host + */ + string im_mad_name; + + /** + * Name of the VM driver used to execute VMs in this host + */ + string vmm_mad_name; + + /** + * Name of the TM driver used to transfer file to and from this host + */ + string tm_mad_name; + + /** + * 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; + + // ------------------------------------------------------------------------- + // Host Attributes + // ------------------------------------------------------------------------- + + /** + * The Host template, holds the Host attributes. + */ + HostTemplate host_template; + + /** + * This map holds pointers to all the Host's HostShares + */ + HostShare host_share; + + // ------------------------------------------------------------------------- + // Lex & bison + // ------------------------------------------------------------------------- + + /** + * Mutex to perform just one flex-bison parsing at a time + */ + static pthread_mutex_t lex_mutex; + + // ************************************************************************* + // DataBase implementation (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 + * @return 0 on success + */ + int unmarshall(int num, char **names, char ** values); + + /** + * Bootstraps the database table(s) associated to the Host + */ + static void bootstrap(SqliteDB * db) + { + db->exec(Host::db_bootstrap); + + db->exec(HostTemplate::db_bootstrap); + + db->exec(HostShare::db_bootstrap); + }; + +protected: + + // ************************************************************************* + // Constructor + // ************************************************************************* + + Host(int id=-1, + string _hostname="", + string _im_mad_name="", + string _vmm_mad_name="", + string _tm_mad_name="", + bool _managed=true); + + virtual ~Host(); + + // ************************************************************************* + // DataBase implementation + // ************************************************************************* + + enum ColNames + { + HID = 0, + HOST_NAME = 1, + STATE = 2, + IM_MAD = 3, + VM_MAD = 4, + TM_MAD = 5, + LAST_MON_TIME = 6, + MANAGED = 7, + LIMIT = 8 + }; + + static const char * db_names; + + static const char * db_bootstrap; + + static const char * table; + + /** + * Reads the Host (identified with its OID=HID) from the database. + * @param db pointer to the db + * @return 0 on success + */ + virtual int select(SqliteDB *db); + + /** + * Writes the Host and its associated HostShares in the database. + * @param db pointer to the db + * @return 0 on success + */ + virtual int insert(SqliteDB *db); + + /** + * Writes/updates the Hosts data fields in the database. + * @param db pointer to the db + * @return 0 on success + */ + virtual int update(SqliteDB *db); + + /** + * Drops host from the database + * @param db pointer to the db + * @return 0 on success + */ + virtual int drop(SqliteDB *db); +}; + +#endif /*HOST_H_*/ diff --git a/include/HostPool.h b/include/HostPool.h new file mode 100644 index 0000000000..80032b3396 --- /dev/null +++ b/include/HostPool.h @@ -0,0 +1,118 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 HOST_POOL_H_ +#define HOST_POOL_H_ + +#include "PoolSQL.h" +#include "Host.h" + +#include +#include + +#include + +#include + +using namespace std; + +/** + * The Host Pool class. ... + */ +class HostPool : public PoolSQL +{ +public: + + HostPool(SqliteDB * db):PoolSQL(db,Host::table){}; + + ~HostPool(){}; + + /** + * Function to allocate a new Host object + * @param oid the id assigned to the Host + * @return 0 on success + */ + int allocate ( + int * oid, + string hostname, + string im_mad_name, + string vmm_mad_name, + string tm_mad_name, + bool managed = true); + + /** + * Function to get a Host from the pool, if the object is not in memory + * it is loaded from the DB + * @param oid Host unique id + * @param lock locks the Host mutex + * @return a pointer to the Host, 0 if the Host could not be loaded + */ + Host * get( + int oid, + bool lock) + { + return static_cast(PoolSQL::get(oid,lock)); + }; + + /** Update a particular Host + * @param host pointer to Host + * @return 0 on success + */ + int update(Host * host) + { + return host->update(db); + }; + + + /** Drops a host from the cache & DB, the host mutex MUST BE locked + * @param host pointer to Host + */ + int drop(Host * host) + { + remove(static_cast(host)); + + return host->drop(db); + }; + + /** + * Bootstraps the database table(s) associated to the Host pool + */ + void bootstrap() + { + 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 + */ + int discover(map * discovered_hosts); + +private: + /** + * Factory method to produce Host objects + * @return a pointer to the new Host + */ + PoolObjectSQL * create() + { + return new Host; + }; + +}; + +#endif /*HOST_POOL_H_*/ diff --git a/include/HostShare.h b/include/HostShare.h new file mode 100644 index 0000000000..1943c5fcd3 --- /dev/null +++ b/include/HostShare.h @@ -0,0 +1,235 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 HOST_SHARE_H_ +#define HOST_SHARE_H_ + +#include "SqliteDB.h" +#include "ObjectSQL.h" +#include + +using namespace std; + +extern "C" int host_share_select_cb (void * _host_share, int num,char ** values, char ** names); + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * The HostShare class. It represents a logical partition of a host... + */ +class HostShare : public ObjectSQL +{ +public: + + HostShare( + int _hsid=-1, + int _max_disk=0, + int _max_mem=0, + int _max_cpu=0); + + ~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 + * @param mem requested by the VM + * @param disk requested by the VM + */ + void add(int cpu, int mem, int disk) + { + cpu_usage += cpu; + mem_usage += mem; + disk_usage += disk; + + running_vms++; + } + + /** + * Delete a VM from this share + * @param cpu requested by the VM + * @param mem requested by the VM + * @param disk requested by the VM + */ + void del(int cpu, int mem, int disk) + { + cpu_usage -= cpu; + mem_usage -= mem; + disk_usage -= disk; + + running_vms--; + } + + /** + * Check if this share can host a VM. + * @param cpu requested by the VM + * @param mem requested by the VM + * @param disk requested by the VM + * + * @return true if the share can host the VM or it is the only one + * configured + */ + bool test(int cpu, int mem, int disk) const + { + return (((max_cpu - cpu_usage ) >= cpu) && + ((max_mem - mem_usage ) >= mem) && + ((max_disk - disk_usage) >= disk)); + } + + /** + * Function to write a HostShare to an output stream + */ + friend ostream& operator<<(ostream& os, HostShare& hs); + +private: + /** + * HostShare identifier + */ + int hsid; + + /** + * HostShare's Endpoint + */ + string endpoint; + + /** + * HostShare disk usage (in Kb) + */ + int disk_usage; + + /** + * HostShare memory usage (in Kb) + */ + int mem_usage; + + /** + * HostShare cpu usage (in percentage) + */ + int cpu_usage; + + /** + * 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; + + // ---------------------------------------- + // Friends + // ---------------------------------------- + + friend class Host; + + friend int host_share_select_cb ( + void * _hostshare, + int num, + char ** values, + char ** names); + + // ---------------------------------------- + // DataBase implementation variables + // ---------------------------------------- + + enum ColNames + { + HSID = 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 + }; + + static const char * table; + + static const char * db_names; + + static const char * db_bootstrap; + + // ---------------------------------------- + // Database methods + // ---------------------------------------- + + /** + * Reads the HostShare (identified with its HSID) from the database. + * @param db pointer to the db + * @return 0 on success + */ + int select(SqliteDB * db); + + /** + * Writes the HostShare in the database. + * @param db pointer to the db + * @return 0 on success + */ + int insert(SqliteDB * db); + + /** + * Writes/updates the HostShare data fields in the database. + * @param db pointer to the db + * @return 0 on success + */ + int update(SqliteDB * db); + + /** + * Drops hostshare from the database + * @param db pointer to the db + * @return 0 on success + */ + int drop(SqliteDB * db); + + /** + * Function to unmarshall a HostShare 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); +}; + + +#endif /*HOST_SHARE_H_*/ diff --git a/include/HostTemplate.h b/include/HostTemplate.h new file mode 100644 index 0000000000..3e565c807c --- /dev/null +++ b/include/HostTemplate.h @@ -0,0 +1,46 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 HOST_TEMPLATE_H_ +#define HOST_TEMPLATE_H_ + +#include "TemplateSQL.h" + +using namespace std; + +/** + * Host Template class, it represents the attributes of a Host + */ +class HostTemplate : public TemplateSQL +{ +public: + HostTemplate(int tid = -1):TemplateSQL(table,tid,true){}; + + ~HostTemplate(){}; + +private: + friend class Host; + + static const char * table; + + static const char * db_bootstrap; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +#endif /*HOST_TEMPLATE_H_*/ diff --git a/include/InformationManager.h b/include/InformationManager.h new file mode 100644 index 0000000000..1b1c9388fd --- /dev/null +++ b/include/InformationManager.h @@ -0,0 +1,142 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 INFORMATION_MANAGER_H_ +#define INFORMATION_MANAGER_H_ + +#include "MadManager.h" +#include "ActionManager.h" +#include "InformationManagerDriver.h" +#include "HostPool.h" + +using namespace std; + +extern "C" void * im_action_loop(void *arg); + +class InformationManager : public MadManager, public ActionListener +{ +public: + + InformationManager( + HostPool * _hpool, + time_t _timer_period, + time_t _monitor_period, + vector& _mads) + :MadManager(_mads), + hpool(_hpool), + timer_period(_timer_period), + monitor_period(_monitor_period) + { + am.addListener(this); + }; + + ~InformationManager(){}; + + /** + * This functions starts the associated listener thread, and creates a + * new thread for the Information Manager. This thread will wait in + * an action loop till it receives ACTION_FINALIZE. + * @return 0 on success. + */ + int start(); + + /** + * Gets the thread identification. + * @return pthread_t for the manager thread (that in the action loop). + */ + pthread_t get_thread_id() const + { + return im_thread; + }; + + /** + * + */ + void load_mads(int uid=0); + + /** + * + */ + void finalize() + { + am.trigger(ACTION_FINALIZE,0); + }; + +private: + /** + * Thread id for the Information Manager + */ + pthread_t im_thread; + + /** + * Pointer to the Host Pool, to access hosts + */ + HostPool * hpool; + + /** + * Timer period for the Virtual Machine Manager. + */ + time_t timer_period; + + /** + * Host monitoring interval + */ + time_t monitor_period; + + /** + * Action engine for the Manager + */ + ActionManager am; + + /** + * Function to execute the Manager action loop method within a new pthread + * (requires C linkage) + */ + friend void * im_action_loop(void *arg); + + /** + * Returns a pointer to a Information Manager MAD. The driver is + * searched by its name and owned by gwadmin with uid=0. + * @param name of the driver + * @return the VM driver owned by uid 0, with attribute "NAME" equal to + * name or 0 in not found + */ + const InformationManagerDriver * get( + const string& name) + { + string _name("NAME"); + return static_cast + (MadManager::get(0,_name,name)); + }; + + /** + * The action function executed when an action is triggered. + * @param action the name of the action + * @param arg arguments for the action function + */ + void do_action( + const string & action, + void * arg); + + /** + * This function is executed periodically to monitor Nebula hosts. + */ + void timer_action(); +}; + +#endif /*VIRTUAL_MACHINE_MANAGER_H*/ + diff --git a/include/InformationManagerDriver.h b/include/InformationManagerDriver.h new file mode 100644 index 0000000000..9e6c46bd62 --- /dev/null +++ b/include/InformationManagerDriver.h @@ -0,0 +1,89 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 INFORMATION_MANAGER_DRIVER_H_ +#define INFORMATION_MANAGER_DRIVER_H_ + +#include +#include +#include + +#include "Mad.h" +#include "HostPool.h" + + +using namespace std; + +/** + * InformationManagerDriver provides a base class to implement IM + * Drivers. This class implements the protocol and recover functions + * from the Mad interface. This class may be used to further specialize + * the IM driver. + */ +class InformationManagerDriver : public Mad +{ +public: + + InformationManagerDriver( + int userid, + const map& attrs, + bool sudo, + HostPool * pool): + Mad(userid,attrs,sudo),hpool(pool) + {} + ; + + virtual ~InformationManagerDriver() + {} + ; + + /** + * Implements the IM driver protocol. + * @param message the string read from the driver + */ + void protocol( + string& message); + + /** + * TODO: What do we need here? just poll the Hosts to recover.. + */ + void recover(); + + /** + * Sends a monitor request to the MAD: "MONITOR ID HOSTNAME -" + * @param oid the virtual machine id. + * @param host the hostname + * @param conf the filename of the deployment file + */ + void monitor ( + int oid, + const string& host) const; + +private: + /** + * Pointer to the Virtual Machine Pool, to access VMs + */ + HostPool * hpool; + + friend class InformationManager; + +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +#endif /*INFORMATION_MANAGER_DRIVER_H_*/ diff --git a/include/LifeCycleManager.h b/include/LifeCycleManager.h new file mode 100644 index 0000000000..69081a9698 --- /dev/null +++ b/include/LifeCycleManager.h @@ -0,0 +1,169 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 LIFE_CYCLE_MANAGER_H_ +#define LIFE_CYCLE_MANAGER_H_ + +#include "ActionManager.h" +#include "VirtualMachinePool.h" + +using namespace std; + +extern "C" void * lcm_action_loop(void *arg); + +/** + * The Virtual Machine Life-cycle Manager module. This class is responsible for + * managing the life-cycle of a Virtual Machine. + */ +class LifeCycleManager : public ActionListener +{ +public: + + LifeCycleManager(VirtualMachinePool * pool) + { + vmpool = pool; + + am.addListener(this); + }; + + ~LifeCycleManager(){}; + + 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 */ + 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 */ + FINALIZE + }; + + /** + * Triggers specific actions to the Life-cycle Manager. This function + * wraps the ActionManager trigger function. + * @param action the LCM action + * @param vid VM unique id. This is the argument of the passed to the + * invoked action. + */ + void trigger( + Actions action, + int vid); + + /** + * This functions starts a new thread for the Life-cycle Manager. This + * thread will wait in an action loop till it receives ACTION_FINALIZE. + * @return 0 on success. + */ + int start(); + + /** + * Gets the thread identification. + * @return pthread_t for the manager thread (that in the action loop). + */ + pthread_t get_thread_id() const + { + return lcm_thread; + }; + +private: + /** + * Thread id for the Virtual Machine Manager + */ + pthread_t lcm_thread; + + /** + * Pointer to the Virtual Machine Pool, to access VMs + */ + VirtualMachinePool * vmpool; + + /** + * Action engine for the Manager + */ + ActionManager am; + + /** + * Function to execute the Manager action loop method within a new pthread + * (requires C linkage) + */ + friend void * lcm_action_loop(void *arg); + + /** + * The action function executed when an action is triggered. + * @param action the name of the action + * @param arg arguments for the action function + */ + void do_action( + const string & action, + void * arg); + + void save_success_action(int vid); + + void save_failure_action(int vid); + + void deploy_success_action(int vid); + + void deploy_failure_action(int vid); + + void shutdown_success_failure_action(int vid); + + void cancel_success_failure_action(int vid); + + void prolog_success_action(int vid); + + void prolog_failure_action(int vid); + + void epilog_success_action(int vid); + + void epilog_failure_action(int vid); + + void deploy_action(int vid); + + void suspend_action(int vid); + + void restore_action(int vid); + + void stop_action(int vid); + + void cancel_action(int vid); + + void checkpoint_action(int vid); + + void migrate_action(int vid); + + void live_migrate_action(int vid); + + void shutdown_action(int vid); + + void timer_action(); +}; + +#endif /*LIFE_CYCLE_MANAGER_H_*/ diff --git a/include/Log.h b/include/Log.h new file mode 100644 index 0000000000..1bb812aa01 --- /dev/null +++ b/include/Log.h @@ -0,0 +1,67 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 _LOG_H_ +#define _LOG_H_ + +#include +#include + +using namespace std; + +class Log +{ +public: + enum MessageType { + ERROR = 0, + WARNING = 1, + INFO = 2, + DEBUG = 3 + }; + + typedef void (*LogFunction)( + const char *, + const MessageType, + const ostringstream&, + const char *); + + Log(const string& file_name, + const MessageType level = WARNING, + ios_base::openmode mode = ios_base::app); + + ~Log(); + + void log( + const char * module, + const MessageType type, + const ostringstream& message); + + void log( + const char * module, + const MessageType type, + const char * message); + +private: + + static const char error_names[]; + + MessageType log_level; + + ofstream file; +}; + +#endif /* _LOG_H_ */ diff --git a/include/Mad.h b/include/Mad.h new file mode 100644 index 0000000000..96737b849c --- /dev/null +++ b/include/Mad.h @@ -0,0 +1,146 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 MAD_H_ +#define MAD_H_ + +#include +#include + +#include +#include +#include + +#include + +using namespace std; + +/** + * Base class to build specific middleware access drivers (MAD). + * This class provides generic MAD functionality. + */ +class Mad +{ +protected: + /** + * The constructor initialize the class members but DOES NOT start the + * driver. A subsequent call to the start() method is needed. + * @param userid user running this MAD + * @param attrs configuration attributes for the driver + * @param sudo the driver is started through sudo if true + */ + Mad( + int userid, + const map &attrs, + bool sudo): + uid(userid), + attributes(attrs), + sudo_execution(sudo), + pid(-1) + {}; + + /** + * The destructor of the class finalizes the driver process, and all its + * associated resources (i.e. pipes) + */ + virtual ~Mad(); + + /** + * Send a command to the driver + * @param os an output string stream with the message, it must be + * terminated with the end of line character. + */ + void write( + ostringstream& os) const + { + string str; + const char * cstr; + + str = os.str(); + cstr = str.c_str(); + + ::write(nebula_mad_pipe, cstr, str.size()); + }; + +private: + friend class MadManager; + + /** + * Communication pipe file descriptor. Represents the MAD to nebula + * communication stream (nebula<-mad) + */ + int mad_nebula_pipe; + + /** + * Communication pipe file descriptor. Represents the nebula to MAD + * communication stream (nebula->mad) + */ + int nebula_mad_pipe; + + /** + * User running this MAD as defined in the upool DB + */ + int uid; + + /** + * Mad configuration attributes (e.g. executable, attributes...). Attribute + * names MUST be lowecase. + */ + map attributes; + + /** + * True if the mad is to be executed through sudo, with the identity of the + * Mad owner (uid). + */ + bool sudo_execution; + + /** + * Process ID of the running MAD. + */ + pid_t pid; + + /** + * Starts the MAD. This function creates a new process, sets up the + * communication pipes and sends the initialization command to the driver. + * @return 0 on success + */ + int start(); + + /** + * Reloads the driver: sends the finalize command, "waits" for the + * driver process and closes the communication pipes. Then the driver is + * started again by calling the start() function + * @return 0 on success + */ + int reload(); + + /** + * Implements the driver specific protocol, this function should trigger + * actions on the associated manager. + * @param message the string read from the driver + */ + virtual void protocol( + string& message) = 0; + + /** + * This function is called whenever the driver crashes. This function + * should perform the actions needed to recover the VMs. + */ + virtual void recover() = 0; +}; + +#endif /*MAD_H_*/ diff --git a/include/MadManager.h b/include/MadManager.h new file mode 100644 index 0000000000..804ff6c000 --- /dev/null +++ b/include/MadManager.h @@ -0,0 +1,166 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 MAD_MANAGER_H_ +#define MAD_MANAGER_H_ + +#include +#include + +#include +#include +#include +#include + +#include "Mad.h" +#include "Attribute.h" + +using namespace std; + +extern "C" void * mad_manager_listener(void * _mm); + +/** + * Provides general functionality for driver management. The MadManager serves + * Nebula managers as base clase. + */ +class MadManager +{ +public: + /** + * Function to initialize the MAD management system. This function + * MUST be called once before using the MadManager class. This function + * blocks the SIG_PIPE (broken pipe) signal that may occur when a driver + * crashes + */ + static void mad_manager_system_init(); + + /** + * Loads Virtual Machine Manager Mads defined in configuration file + * @param uid of the user executing the driver. When uid is 0 the nebula + * identity will be used. Otherwise the Mad will be loaded through the + * sudo application. + */ + virtual void load_mads(int uid) = 0; + +protected: + + MadManager(vector& _mads); + + virtual ~MadManager(); + + /** + * Vector containing Mad configuration for this Manager, as described in + * the nebula location + */ + vector mad_conf; + + /** + * This function initialize the communication pipes to register new MADs + * in the manager, and starts a listener to wait for driver messages. + */ + virtual int start(); + + + /** + * This function closes the communication pipes, stops the listener thread, + * and finalize the associated drivers. + */ + virtual void stop(); + + /** + * Get a mad + */ + virtual const Mad * get(int uid, const string& name, const string& value); + + /** + * Register a new mad in the manager. The Mad is previously started, and + * then the listener thread is notified through the pipe_w stream. In case + * of failure the calling function MUST free the Mad. + * @param mad pointer to the mad to be added to the manager. + * @return 0 on success. + */ + int add(Mad *mad); + +private: + /** + * Function to lock the Manager + */ + void lock() + { + pthread_mutex_lock(&mutex); + }; + + /** + * Function to unlock the Manager + */ + void unlock() + { + pthread_mutex_unlock(&mutex); + }; + + /** + * Function to execute the listener method within a new pthread (requires + * C linkage) + */ + friend void * mad_manager_listener(void * _mm); + + /** + * Synchronization mutex (listener & manager threads) + */ + pthread_mutex_t mutex; + + /** + * Thread id for the listener process + */ + pthread_t listener_thread; + + /** + * Communication pipe (read end) to link the Manager and the listener + * thread + */ + int pipe_r; + + /** + * Communication pipe (write end) to link the Manager and the listener + * thread + */ + int pipe_w; + + /** + * This vector contains the file descriptors of the driver pipes (to read + * Mads responses) + */ + vector fds; + + /** + * The sets of Mads managed by the MadManager + */ + vector mads; + + /** + * Read buffer for the listener. This variable is in the class so it + * can be free upon listener thread cancellation. + */ + ostringstream buffer; + + /** + * Listener thread implementation. + */ + void listener(); +}; + +#endif /*MAD_MANAGER_H_*/ diff --git a/include/Nebula.h b/include/Nebula.h new file mode 100644 index 0000000000..1bbe139d34 --- /dev/null +++ b/include/Nebula.h @@ -0,0 +1,248 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 NEBULA_H_ +#define NEBULA_H_ + +#include + +#include "Log.h" +#include "NebulaTemplate.h" + +#include "VirtualMachinePool.h" +#include "HostPool.h" + +#include "VirtualMachineManager.h" +#include "LifeCycleManager.h" +#include "InformationManager.h" +#include "TransferManager.h" +#include "DispatchManager.h" +#include "RequestManager.h" + +class Nebula +{ +public: + + static Nebula& instance() + { + static Nebula nebulad; + + return nebulad; + }; + + // --------------------------------------------------------------- + // Loggging + // --------------------------------------------------------------- + + static void log( + const char * module, + const Log::MessageType type, + const ostringstream& message, + const char * filename = 0) + { + static Log nebula_log(filename,Log::DEBUG,ios_base::trunc); + static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER; + + pthread_mutex_lock(&log_mutex); + nebula_log.log(module,type,message); + pthread_mutex_unlock(&log_mutex); + }; + + static void log( + const char * module, + const Log::MessageType type, + const char * message, + const char * filename = 0) + { + ostringstream os(message); + + Nebula::log(module,type,os,filename); + }; + + // -------------------------------------------------------------- + // Pool Accessors + // -------------------------------------------------------------- + + VirtualMachinePool * get_vmpool() + { + return vmpool; + }; + + HostPool * get_hpool() + { + return hpool; + }; + + // -------------------------------------------------------------- + // Manager Accessors + // -------------------------------------------------------------- + + VirtualMachineManager * get_vmm() + { + return vmm; + }; + + LifeCycleManager * get_lcm() + { + return lcm; + }; + + InformationManager * get_im() + { + return im; + }; + + TransferManager * get_tm() + { + return tm; + }; + + DispatchManager * get_dm() + { + return dm; + }; + + // -------------------------------------------------------------- + // Environment & Configuration + // -------------------------------------------------------------- + + string& get_nebula_location() + { + return nebula_location; + }; + + static string version() + { + return "ONE0.1"; + }; + + void start(); + + void get_configuration_attribute( + const char * name, + string& value) const + { + string _name(name); + + nebula_configuration->Template::get(_name,value); + }; + +private: + + // ----------------------------------------------------------------------- + //Constructors and = are private to only access the class through instance + // ----------------------------------------------------------------------- + + Nebula():nebula_configuration(0),db(0),vmpool(0),hpool(0),lcm(0), + vmm(0),im(0),tm(0),dm(0),rm(0){}; + + ~Nebula() + { + if ( vmpool != 0) + { + delete vmpool; + } + + if ( hpool != 0) + { + delete hpool; + } + + if ( vmm != 0) + { + delete vmm; + } + + if ( lcm != 0) + { + delete lcm; + } + + if ( im != 0) + { + delete im; + } + + if ( tm != 0) + { + delete tm; + } + + if ( dm != 0) + { + delete dm; + } + + if ( rm != 0) + { + delete rm; + } + + if ( nebula_configuration != 0) + { + delete nebula_configuration; + } + + if ( db != 0 ) + { + delete db; + } + }; + + Nebula(Nebula const&){}; + + Nebula& operator=(Nebula const&){return *this;}; + + // --------------------------------------------------------------- + // Environment variables + // --------------------------------------------------------------- + + string nebula_location; + + // --------------------------------------------------------------- + // Configuration + // --------------------------------------------------------------- + + NebulaTemplate * nebula_configuration; + + // --------------------------------------------------------------- + // Nebula Pools + // --------------------------------------------------------------- + + SqliteDB * db; + VirtualMachinePool * vmpool; + HostPool * hpool; + + // --------------------------------------------------------------- + // Nebula Managers + // --------------------------------------------------------------- + + LifeCycleManager * lcm; + VirtualMachineManager * vmm; + InformationManager * im; + TransferManager * tm; + DispatchManager * dm; + RequestManager * rm; + + // --------------------------------------------------------------- + // Implementation functions + // --------------------------------------------------------------- + + friend void nebula_signal_handler (int sig); +}; + +#endif /*NEBULA_H_*/ diff --git a/include/NebulaTemplate.h b/include/NebulaTemplate.h new file mode 100644 index 0000000000..3d7645b808 --- /dev/null +++ b/include/NebulaTemplate.h @@ -0,0 +1,54 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 NEBULA_TEMPLATE_H_ +#define NEBULA_TEMPLATE_H_ + +#include "Template.h" +#include + +class NebulaTemplate : public Template +{ +public: + + NebulaTemplate(string& nebula_location); + + ~NebulaTemplate(){}; + + static const char * conf_name; + + int get( + const char * name, + vector& values) const + { + string _name(name); + + return Template::get(_name,values); + }; + +private: + friend class Nebula; + + string conf_file; + + map conf_default; + + int load_configuration(); +}; + + +#endif /*NEBULA_TEMPLATE_H_*/ diff --git a/include/ObjectSQL.h b/include/ObjectSQL.h new file mode 100644 index 0000000000..e849f71f3b --- /dev/null +++ b/include/ObjectSQL.h @@ -0,0 +1,104 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 OBJECT_SQL_H_ +#define OBJECT_SQL_H_ + +#include "SqliteDB.h" + +using namespace std; + +/** + * ObjectSQL class. Provides a SQL backend interface, it should be implemented + * by persistent objects. + */ + +class ObjectSQL +{ +public: + + ObjectSQL(){}; + + virtual ~ObjectSQL(){}; + +protected: + /** + * Gets the value of a column in the pool for a given object + * @param db pointer to Database + * @param table supporting the object + * @param column to be selected + * @param where contidtion to select the column + * @param value of the column + * @return 0 on success + */ + int select_column( + SqliteDB * db, + const string& table, + const string& column, + const string& where, + string * value); + + /** + * Sets the value of a column in the pool for a given object + * @param db pointer to Database + * @param table supporting the object + * @param column to be selected + * @param where contidtion to select the column + * @param value of the column + * @return 0 on success + */ + int update_column( + SqliteDB * db, + const string& table, + const string& column, + const string& where, + const string& value); + + /** + * Reads the ObjectSQL (identified with its OID) from the database. + * @param db pointer to the db + * @return 0 on success + */ + virtual int select( + SqliteDB * db) = 0; + + /** + * Writes the ObjectSQL in the database. + * @param db pointer to the db + * @return 0 on success + */ + virtual int insert( + SqliteDB * db) = 0; + + /** + * Updates the ObjectSQL in the database. + * @param db pointer to the db + * @return 0 on success + */ + virtual int update( + SqliteDB * db) = 0; + + /** + * Removes the ObjectSQL from the database. + * @param db pointer to the db + * @return 0 on success + */ + virtual int drop( + SqliteDB * db) = 0; +}; + +#endif /*OBJECT_SQL_H_*/ diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h new file mode 100644 index 0000000000..86632aea2c --- /dev/null +++ b/include/PoolObjectSQL.h @@ -0,0 +1,93 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 POOL_OBJECT_SQL_H_ +#define POOL_OBJECT_SQL_H_ + +#include "SqliteDB.h" +#include "ObjectSQL.h" +#include + +using namespace std; + +/** + * PoolObject class. Provides a SQL backend interface for Pool components. Each + * object is identified with and unique OID + * + * Note: The PoolObject provides a synchronization mechanism (mutex). This + * implementation assumes that the mutex IS LOCKED when the class destructor + * is called. + */ + +class PoolObjectSQL : public ObjectSQL +{ +public: + + PoolObjectSQL(int id=-1):oid(id) + { + pthread_mutex_init(&mutex,0); + }; + + virtual ~PoolObjectSQL() + { + pthread_mutex_unlock(&mutex); + + pthread_mutex_destroy(&mutex); + }; + + int get_oid() const + { + return oid; + }; + + /** + * Function to lock the object + */ + void lock() + { + pthread_mutex_lock(&mutex); + }; + + /** + * Function to unlock the object + */ + void unlock() + { + pthread_mutex_unlock(&mutex); + }; + +protected: + /** + * The object unique ID + */ + int oid; + +private: + + /** + * The PoolSQL, friend to easily manipulate its Objects + */ + friend class PoolSQL; + + /** + * The mutex for the PoolObject. This implementation assumes that the mutex + * IS LOCKED when the class destructor is called. + */ + pthread_mutex_t mutex; +}; + +#endif /*POOL_OBJECT_SQL_H_*/ diff --git a/include/PoolSQL.h b/include/PoolSQL.h new file mode 100644 index 0000000000..76a19f5e51 --- /dev/null +++ b/include/PoolSQL.h @@ -0,0 +1,185 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 POOL_SQL_H_ +#define POOL_SQL_H_ + +#include +#include +#include + +#include "SqliteDB.h" +#include "PoolObjectSQL.h" +#include "Log.h" + +using namespace std; + +/** + * PoolSQL class. Provides a base class to implement persistent generic pools. + * The PoolSQL provides a synchronization mechanism (mutex) to operate in + * multithreaded applications. Any modification or access function to the pool + * SHOULD block the mutex. + */ +class PoolSQL +{ +public: + + /** + * Initializes the oid counter. This function sets lastOID to + * the last used Object identifier by querying the corresponding database + * table. This function SHOULD be called before any pool related function. + * @param _db a pointer to the database + * @param table the name of the table supporting the pool (to set the oid + * counter). If null the OID counter is not updated. + */ + PoolSQL(SqliteDB * _db, const char * table=0); + + virtual ~PoolSQL(); + + /** + * Allocates a new object, writting it in the pool database. No memory is + * allocated for the object. + * @param objsql an initialized ObjectSQL + * @return the oid assigned to the object or -1 in case of failure + */ + virtual int allocate( + PoolObjectSQL *objsql); + + /** + * Gets an object from the pool (if needed the object is loaded from the + * database). + * @param oid the object unique identifier + * @param lock locks the object if true + * + * @return a pointer to the object, 0 in case of failure + */ + virtual PoolObjectSQL * get( + int oid, + bool lock); + + /** + * Finds a set objects that satisfies a given condition + * @param oids a vector with the oids of the objects. + * @param the name of the DB table. + * @param where condition in SQL format. + * + * @return 0 on success + */ + virtual int search( + vector& oids, + const char * table, + const string& where); + + /** + * Updates the object's data in the data base. The object mutex SHOULD be + * locked. + * @param objsql a pointer to the object + * + * @return 0 on success. + */ + virtual int update( + PoolObjectSQL * objsql) + { + return objsql->update(db); + }; + + /** + * 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: + + /** + * Pointer to the database. + */ + SqliteDB * db; + + /** + * Function to lock the pool + */ + void lock() + { + pthread_mutex_lock(&mutex); + }; + + /** + * Function to unlock the pool + */ + void unlock() + { + pthread_mutex_unlock(&mutex); + }; + +private: + + pthread_mutex_t mutex; + + /** + * Max size for the pool, to control the memory footprint of the pool. This + * number MUST be greater than the max. number of objects that are + * accessed simultaneously. + */ + static const unsigned int MAX_POOL_SIZE; + + /** + * Last object ID assigned to an object. It must be initialized by the + * target pool. + */ + int lastOID; + + /** + * The pool is implemented with a Map, of SQL object pointers, using the + * OID as key. + */ + map pool; + + /** + * Factory method, must return an ObjectSQL pointer to an allocated pool + * specific object. + */ + virtual PoolObjectSQL * create() = 0; + + /** + * OID queue to implement a FIFO-like replacement policy for the pool + * cache. + */ + queue oid_queue; + + /** + * FIFO-like replacement policy function. Before removing an object (pop) + * from the cache it's lock is checked. The object is removed only if + * the associated mutex IS NOT blocked. Otherwise the oid is sent to the + * back of the queue. + */ + void replace(); +}; + +#endif /*POOL_SQL_H_*/ diff --git a/include/RequestManager.h b/include/RequestManager.h new file mode 100644 index 0000000000..d145788489 --- /dev/null +++ b/include/RequestManager.h @@ -0,0 +1,363 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 REQUEST_MANAGER_H_ +#define REQUEST_MANAGER_H_ + +#include "ActionManager.h" +#include "VirtualMachinePool.h" +#include "HostPool.h" + + +#include +#include +#include + +using namespace std; + +extern "C" void * rm_action_loop(void *arg); + +extern "C" void * rm_xml_server_loop(void *arg); + +class RequestManager : public ActionListener +{ +public: + + RequestManager( + VirtualMachinePool * _vmpool, + HostPool * _hpool, + int _port, + string _xml_log_file) + :vmpool(_vmpool),hpool(_hpool),port(_port),socket_fd(-1), + xml_log_file(_xml_log_file) + { + am.addListener(this); + }; + + ~RequestManager() + {} + ; + + /** + * This functions starts the associated listener thread (XML server), and + * creates a new thread for the Request Manager. This thread will wait in + * an action loop till it receives ACTION_FINALIZE. + * @return 0 on success. + */ + int start(); + + /** + * Gets the thread identification. + * @return pthread_t for the manager thread (that in the action loop). + */ + pthread_t get_thread_id() const + { + return rm_thread; + }; + + /** + * + */ + void finalize() + { + am.trigger(ACTION_FINALIZE,0); + }; + +private: + + //-------------------------------------------------------------------------- + // Friends, thread functions require C-linkage + //-------------------------------------------------------------------------- + + friend void * rm_xml_server_loop(void *arg); + + friend void * rm_action_loop(void *arg); + + /** + * Thread id for the RequestManager + */ + pthread_t rm_thread; + + /** + * Thread id for the XML Server + */ + pthread_t rm_xml_server_thread; + + /** + * Pointer to the Host Pool, to access hosts + */ + VirtualMachinePool * vmpool; + + /** + * Pointer to the Host Pool, to access hosts + */ + HostPool * hpool; + + /** + * Port number where the connection will be open + */ + int port; + + /* + * FD for the XML server socket + */ + int socket_fd; + + /** + * Filename for the log of the xmlrpc server that listens + */ + string xml_log_file; + + /** + * Action engine for the Manager + */ + ActionManager am; + + /** + * To register XML-RPC methods + */ + xmlrpc_c::registry RequestManagerRegistry; + + /** + * The XML-RPC server + */ + xmlrpc_c::serverAbyss * AbyssServer; + + /** + * The action function executed when an action is triggered. + * @param action the name of the action + * @param arg arguments for the action function + */ + void do_action(const string & action, void * arg); + + void register_xml_methods(); + + int setup_socket(); + + // ---------------------------------------------------------------------- + // XML-RPC Methods + // ---------------------------------------------------------------------- + + class VirtualMachineAllocate: public xmlrpc_c::method + { + public: + VirtualMachineAllocate() + { + _signature="A:ss"; + _help="Allocates a virtual machine in the pool"; + }; + + ~VirtualMachineAllocate(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retval); + + }; + + /* ---------------------------------------------------------------------- */ + + class VirtualMachineDeploy: public xmlrpc_c::method + { + public: + VirtualMachineDeploy( + VirtualMachinePool * _vmpool, + HostPool * _hpool): + vmpool(_vmpool), + hpool(_hpool) + { + _signature="A:sii"; + _help="Deploys a virtual machine"; + }; + + ~VirtualMachineDeploy(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retval); + + private: + VirtualMachinePool * vmpool; + HostPool * hpool; + }; + + /* ---------------------------------------------------------------------- */ + + class VirtualMachineAction: public xmlrpc_c::method + { + public: + VirtualMachineAction() + { + _signature="A:ssi"; + _help="Performs an action on a virtual machine"; + }; + + ~VirtualMachineAction(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retval); + + private: + VirtualMachinePool * vmpool; + HostPool * hpool; + }; + + /* ---------------------------------------------------------------------- */ + + class VirtualMachineMigrate: public xmlrpc_c::method + { + public: + VirtualMachineMigrate( + VirtualMachinePool * _vmpool, + HostPool * _hpool): + vmpool(_vmpool), + hpool(_hpool) + { + _signature="A:siib"; + _help="Migrates a virtual machine"; + }; + + ~VirtualMachineMigrate(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retval); + + private: + VirtualMachinePool * vmpool; + HostPool * hpool; + }; + + /* ---------------------------------------------------------------------- */ + + class VirtualMachineInfo: public xmlrpc_c::method + { + public: + VirtualMachineInfo( + VirtualMachinePool * _vmpool): + vmpool(_vmpool) + { + _signature="A:si"; + _help="Returns virtual machine information"; + }; + + ~VirtualMachineInfo(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retval); + + private: + VirtualMachinePool * vmpool; + }; + + /* ---------------------------------------------------------------------- */ + + class HostAllocate: public xmlrpc_c::method + { + public: + HostAllocate(HostPool * _hpool):hpool(_hpool) + { + _signature="A:sssssb"; + _help="Allocates a host in the pool"; + }; + + ~HostAllocate(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + HostPool * hpool; + + }; + + /* ---------------------------------------------------------------------- */ + + class HostInfo: public xmlrpc_c::method + { + public: + HostInfo(HostPool * _hpool):hpool(_hpool) + { + _signature="A:si"; + _help="Returns host information"; + }; + + ~HostInfo(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + HostPool * hpool; + + }; + + /* ---------------------------------------------------------------------- */ + + class HostDelete: public xmlrpc_c::method + { + public: + HostDelete(HostPool * _hpool):hpool(_hpool) + { + _signature="A:si"; + _help="Deletes a host from the pool"; + }; + + ~HostDelete(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + HostPool * hpool; + + }; + + /* ---------------------------------------------------------------------- */ + + class HostEnable: public xmlrpc_c::method + { + public: + HostEnable(HostPool * _hpool):hpool(_hpool) + { + _signature="A:sib"; + _help="Enables or disables a host"; + }; + + ~HostEnable(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + HostPool * hpool; + + }; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +#endif + diff --git a/include/Scheduler.h b/include/Scheduler.h new file mode 100644 index 0000000000..0e29b525c1 --- /dev/null +++ b/include/Scheduler.h @@ -0,0 +1,199 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 SCHEDULER_H_ +#define SCHEDULER_H_ + +#include "Log.h" +#include "SchedulerHost.h" +#include "SchedulerVirtualMachine.h" +#include "SchedulerPolicy.h" +#include "ActionManager.h" + +#include +#include +#include +#include +#include + +using namespace std; + + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +extern "C" void * scheduler_action_loop(void *arg); + +/** + * The Scheduler class. It represents the scheduler ... + */ + +class Scheduler: public ActionListener +{ +public: + + // --------------------------------------------------------------- + // Loggging + // --------------------------------------------------------------- + + static void log( + const char * module, + const Log::MessageType type, + const ostringstream& message, + const char * filename = 0) + { + static Log scheduler_log(filename,Log::DEBUG); + static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER; + + pthread_mutex_lock(&log_mutex); + scheduler_log.log(module,type,message); + pthread_mutex_unlock(&log_mutex); + }; + + static void log( + const char * module, + const Log::MessageType type, + const char * message, + const char * filename = 0) + { + ostringstream os(message); + + Scheduler::log(module,type,os,filename); + }; + + void start(); + + virtual void register_policies() = 0; + +protected: + + Scheduler(string& url, time_t _timer) + :hpool(0),vmpool(0),db(0),one_url(url),timer(_timer),threshold(0.9) + { + am.addListener(this); + }; + + virtual ~Scheduler() + { + if ( hpool != 0) + { + delete hpool; + } + + if ( vmpool != 0) + { + delete vmpool; + } + + if (db != 0) + { + delete db; + } + }; + + // --------------------------------------------------------------- + // Pools + // --------------------------------------------------------------- + + SchedulerHostPool * hpool; + SchedulerVirtualMachinePool * vmpool; + + // --------------------------------------------------------------- + // Scheduler Policies + // --------------------------------------------------------------- + + void add_host_policy(SchedulerHostPolicy *policy) + { + host_policies.push_back(policy); + } + + // --------------------------------------------------------------- + // Scheduler main methods + // --------------------------------------------------------------- + + /** + * Gets the hosts that match the requirements of the pending VMs, also + * the capacity of the host is checked. If there is enough room to host the + * VM a share vector is added to the VM. + */ + virtual void match(); + + virtual void dispatch(); + + virtual int schedule(); + + virtual int set_up_pools(); + +private: + Scheduler(Scheduler const&){}; + + Scheduler& operator=(Scheduler const&){return *this;}; + + friend void * scheduler_action_loop(void *arg); + + // --------------------------------------------------------------- + // Database + // --------------------------------------------------------------- + + SqliteDB * db; + + // --------------------------------------------------------------- + // Scheduling Policies + // --------------------------------------------------------------- + + vector host_policies; + + // --------------------------------------------------------------- + // Configuration attributes + // --------------------------------------------------------------- + + /** + * the URL of the XML-RPC server + */ + string one_url; + + + time_t timer; + + /** + * Threshold value to round up freecpu + */ + float threshold; + + // --------------------------------------------------------------- + // Timer to periodically schedule and dispatch VMs + // --------------------------------------------------------------- + + pthread_t sched_thread; + ActionManager am; + + void do_action(const string &name, void *args); + + // --------------------------------------------------------------- + // XML_RPC related variables + // --------------------------------------------------------------- + + /** + * 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 + * variables." + */ + xmlrpc_c::clientSimple xmlrpc_client; +}; + + +#endif /*SCHEDULER_H_*/ diff --git a/include/SchedulerHost.h b/include/SchedulerHost.h new file mode 100644 index 0000000000..883e4e3c07 --- /dev/null +++ b/include/SchedulerHost.h @@ -0,0 +1,141 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 SCHEDULER_HOST_H_ +#define SCHEDULER_HOST_H_ + +#include "Host.h" + +using namespace std; + + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * The SchedulerHost class. It represents the scheduler version of the host, + * only read operations to the pool are allowed for the SchedulerHost class + */ +class SchedulerHost : public Host +{ + +public: + + SchedulerHost(){}; + + ~SchedulerHost(){}; + + /** + * Gets the current host capacity + * @param cpu the host free cpu, scaled according to a given threshold + * @param memory the host free memory + * @param threshold to consider the host totally free + */ + void get_capacity(int& cpu, int& memory, int threshold); + +private: + + // ---------------------------------------- + // Friends + // ---------------------------------------- + friend class SchedulerHostPool; + + // ---------------------------------------- + // SQL functions do not modify the DB! + // ---------------------------------------- + int insert(SqliteDB *db); + + int update(SqliteDB *db); + + int drop(SqliteDB *db); + +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * The SchedulerHost class. It represents the scheduler version of the host, + * read only operation to the pool are allowed for the SchedulerHost class + */ +class SchedulerHostPool : public PoolSQL +{ +public: + + //-------------------------------------------------------------------------- + // Constructor + //-------------------------------------------------------------------------- + + SchedulerHostPool(SqliteDB *db):PoolSQL(db){}; + + ~SchedulerHostPool(){}; + + /** + * Implements the Pool interface, just prints an error message. This + * class DOES NOT modify the database. + */ + int allocate( + PoolObjectSQL *objsql); + + /** + * Gets an ScheulerHost from the pool (if needed the object is loaded from + * the database). + * @param oid the object unique identifier + * @param lock locks the object if true + * + * @return a pointer to the object, 0 in case of failure + */ + SchedulerHost * get( + int oid, + bool lock) + { + return static_cast(PoolSQL::get(oid,lock)); + }; + + /** + * Set ups the host pool by performing the following actions: + * - All the objects stored in the pool are flushed + * - The ids of the hosts in the database are loaded + * @return 0 on success + */ + int set_up(); + +private: + friend class Scheduler; + + /** + * Hosts ids + */ + vector hids; + + /** + * Factory method for the PoolSQL class + * @return a pointer to a new SchedulerHost object + */ + PoolObjectSQL * create() + { + return new SchedulerHost; + }; + + /** + * Bootstrap method from the PoolSQL interface. It just prints + * an error message as this class MUST not modify the DB. + */ + void bootstrap(); +}; + +#endif /*SCHEDULER_HOST_H_*/ diff --git a/include/SchedulerPolicy.h b/include/SchedulerPolicy.h new file mode 100644 index 0000000000..fa7548f5bb --- /dev/null +++ b/include/SchedulerPolicy.h @@ -0,0 +1,112 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 SCHEDULER_POLICY_H_ +#define SCHEDULER_POLICY_H_ + +#include "SchedulerHost.h" +#include "SchedulerVirtualMachine.h" +#include + +using namespace std; + +class SchedulerHostPolicy +{ +public: + + SchedulerHostPolicy( + SchedulerVirtualMachinePool * _vmpool, + SchedulerHostPool * _hpool, + float w=1.0): + vmpool(_vmpool),hpool(_hpool),sw(w){}; + + virtual ~SchedulerHostPolicy(){}; + + const vector& get( + SchedulerVirtualMachine * vm) + { + priority.clear(); + + policy(vm); + + if(priority.empty()!=true) + { + sw.max = *max_element( + priority.begin(), + priority.end(), + SchedulerHostPolicy::abs_cmp); + + transform( + priority.begin(), + priority.end(), + priority.begin(), + sw); + } + + return priority; + }; + +protected: + + vector priority; + + virtual void policy(SchedulerVirtualMachine * vm) = 0; + + SchedulerVirtualMachinePool * vmpool; + SchedulerHostPool * hpool; + +private: + + static bool abs_cmp(float fl1, float fl2) + { + return fabs(fl1)::iterator jt; + + for (jt=hosts.begin();jt!=hosts.end();jt++) + { + delete *jt; + } + }; + + /** + * Adds a new share to the map of suitable shares to start this VM + * @param hid of the selected host + * @param hsid of the selected host share + */ + void add_host(int hid) + { + SchedulerVirtualMachine::Host * ss; + + ss = new SchedulerVirtualMachine::Host(hid); + + hosts.push_back(ss); + }; + + /** + * Gets the matching hosts ids + * @param mh vector with the hids of the matching hosts + */ + void get_matching_hosts(vector& mh) + { + vector::iterator i; + + for(i=hosts.begin();i!=hosts.end();i++) + { + mh.push_back((*i)->hid); + } + }; + + /** + * Sets the priorities for each matching host + */ + void set_priorities(vector& total); + + /** + * + */ + int get_host(int& hid, SchedulerHostPool * hpool); + + /** + * Function to write a Virtual Machine in an output stream + */ + friend ostream& operator<<(ostream& os, SchedulerVirtualMachine& vm); + +private: + + // ------------------------------------------------------------------------- + // Friends + // ------------------------------------------------------------------------- + friend class SchedulerVirtualMachinePool; + + //-------------------------------------------------------------------------- + + struct Host + { + int hid; + float priority; + + Host(int _hid): + hid(_hid), + priority(0){}; + + ~Host(){}; + + bool operator<(const Host& b) { //Sort by priority + return priority < b.priority; + } + }; + + //-------------------------------------------------------------------------- + + /** + * Matching hosts + */ + vector hosts; + + // ------------------------------------------------------------------------- + // SQL functions do not modify the DB! + // ------------------------------------------------------------------------- + + int insert(SqliteDB *db); + + int update(SqliteDB *db); + + int drop(SqliteDB *db); +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * The SchedulerHost class. It represents the scheduler version of the host, + * read only operation to the pool are allowed for the SchedulerHost class + */ +class SchedulerVirtualMachinePool : public PoolSQL +{ +public: + + SchedulerVirtualMachinePool(SqliteDB * db):PoolSQL(db){}; + + ~SchedulerVirtualMachinePool(){}; + + int allocate( + PoolObjectSQL *objsql); + + SchedulerVirtualMachine * get( + int oid, + bool lock) + { + return static_cast(PoolSQL::get(oid,lock)); + }; + + /** + * Set ups the VM pool by performing the following actions: + * - All the objects stored in the pool are flushed + * - The ids of the pendings VMs in the database are loaded + * @return 0 on success + */ + int set_up(); + +private: + friend class Scheduler; + + /** + * The ids of the pending VMs + */ + vector pending_vms; + + PoolObjectSQL * create() + { + return new SchedulerVirtualMachine; + }; + + void bootstrap(); +}; + +#endif /*SCHEDULER_VIRTUAL_MACHINE_H_*/ diff --git a/include/SqliteDB.h b/include/SqliteDB.h new file mode 100644 index 0000000000..391f91242c --- /dev/null +++ b/include/SqliteDB.h @@ -0,0 +1,185 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 SQLITE_DB_H_ +#define SQLITE_DB_H_ + +#include +#include +#include +#include + +#include +#include +#include + +#include "Log.h" + +using namespace std; + +/** + * SqliteDB class. Provides a wrapper to the sqlite3 database interface. It also + * provides "global" synchronization mechanism to use it in a multithread + * environment. + */ +class SqliteDB +{ +public: + + SqliteDB( + string& db_name, + Log::LogFunction _log = 0 + ):log(_log) + { + int rc; + + pthread_mutex_init(&mutex,0); + + rc = sqlite3_open(db_name.c_str(), &db); + + if ( rc != SQLITE_OK ) + { + throw runtime_error("Could not open database."); + } + }; + + ~SqliteDB() + { + pthread_mutex_destroy(&mutex); + + sqlite3_close(db); + }; + + /** + * Wraps the sqlite3_exec function call, and locks the DB mutex. + * @param sql_cmd the SQL command + * @param callbak function to execute on each data returned, watch the + * mutex you block in the callback. + * @param arg to pass to the callback function + * @return 0 on success + */ + int exec( + ostringstream& sql_cmd, + int (*callback)(void*,int,char**,char**)=0, + void * arg=0) + { + int rc; + + const char * c_str; + string str; + + int counter = 0; + + char * err_msg; + char ** ptr = (log==0) ? 0 : &err_msg; + + str = sql_cmd.str(); + c_str = str.c_str(); + + lock(); + + do + { + counter++; + + rc = sqlite3_exec(db, c_str, callback, arg, ptr); + + if (rc == SQLITE_BUSY || rc == SQLITE_IOERR_BLOCKED) + { + struct timeval timeout; + fd_set zero; + + FD_ZERO(&zero); + timeout.tv_sec = 0; + timeout.tv_usec = 100000; + + select(0, &zero, &zero, &zero, &timeout); + } + + }while( (rc == SQLITE_BUSY || rc == SQLITE_IOERR_BLOCKED) && + (counter < 10)); + + unlock(); + + if (rc != SQLITE_OK) + { + if ((log != 0) && (err_msg != 0)) + { + ostringstream oss; + + oss << "SQL command was: " << c_str << ", error: " << err_msg; + log("ONE",Log::ERROR,oss,0); + + sqlite3_free(err_msg); + } + + return -1; + } + + return 0; + }; + + /** + * + */ + int exec( + const char * sql_c_str, + int (*callback)(void*,int,char**,char**)=0, + void * arg=0) + { + string sql_str = sql_c_str; + ostringstream sql_cmd; + + sql_cmd.str(sql_str); + + return exec(sql_cmd,callback,arg); + }; + +private: + /** + * Fine-grain mutex for DB access + */ + pthread_mutex_t mutex; + + /** + * Pointer to the database. + */ + sqlite3 * db; + + /** + * Log facility + */ + Log::LogFunction log; + + /** + * Function to lock the DB + */ + void lock() + { + pthread_mutex_lock(&mutex); + }; + + /** + * Function to unlock the DB + */ + void unlock() + { + pthread_mutex_unlock(&mutex); + }; +}; + +#endif /*SQLITE_DB_H_*/ diff --git a/include/Template.h b/include/Template.h new file mode 100644 index 0000000000..fe27d74382 --- /dev/null +++ b/include/Template.h @@ -0,0 +1,139 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 TEMPLATE_H_ +#define TEMPLATE_H_ + +#include +#include +#include + +#include "Attribute.h" + +using namespace std; + +/** + * Base class for file templates. A template is a file (or a tring for the + * matter of fact) containing a set of attribute definitions of the form: + * NAME = VALUE + * where NAME is a string representing the name of the attribute, and VALUE can + * be a single string or a vector value (array of string pairs). The file can + * contain several attributes with the same name. + */ +class Template +{ +public: + + Template(bool _replace_mode=false):replace_mode(_replace_mode){}; + + /** + * The class destructor frees all the attributes conforming the template + */ + virtual ~Template(); + + /** + * Parse a string representing the template, each attribute is inserted + * in the template class. + * @param parse_str string with template attributes + * @param error_msg error string, must be freed by the calling funtion. + * This string is null if no error occurred. + * @return 0 on success. + */ + int parse(const string &parse_str, char **error_msg); + + /** + * Parse a template file. + * @param filename of the template file + * @param error_msg error string, must be freed by the calling funtion. + * This string is null if no error occurred. + * @return 0 on success. + */ + int parse(const char * filename, char **error_msg); + + /** + * Marshall a template. This function generates a single string with the + * template attributes ("VAR=VAL..."). + * @param str_tempalte string that hold the template + * @param delim to separate attributes + */ + void marshall(string &str, const char delim='\n'); + + /** + * Sets a new attribute, the attribute MUST BE ALLOCATED IN THE HEAP, and + * will be freed when the template destructor is called. + * @param attr pointer to the attribute + */ + virtual void set(Attribute * attr) + { + if ( replace_mode == true ) + { + attributes.erase(attr->name()); + } + + attributes.insert(make_pair(attr->name(),attr)); + }; + + /** + * Gets all the attributes with the given name. + * @param name the attribute name. + * @returns the number of elements in the vector + */ + virtual int get( + string& name, + vector& values) const; + + /** + * Gets the value of a Single attributes (string) with the given name. + * @param name the attribute name. + * @param value the attribute value, a string, "" if the attribute is not + * defined or not Single + */ + virtual void get( + string& name, + string& value) const; + + /** + * Gets the value of a Single attributes (int) with the given name. + * @param name the attribute name. + * @param value the attribute value, an int, 0 if the attribute is not + * defined or not Single + */ + virtual void get( + string& name, + int& value) const; + + friend ostream& operator<<(ostream& os, Template& t); + +protected: + /** + * The template attributes + */ + multimap attributes; + +private: + + bool replace_mode; + /** + * Mutex to perform just one flex-bison parsing at a time + */ + static pthread_mutex_t mutex; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +#endif /*TEMPLATE_H_*/ diff --git a/include/TemplateSQL.h b/include/TemplateSQL.h new file mode 100644 index 0000000000..87c0db69ba --- /dev/null +++ b/include/TemplateSQL.h @@ -0,0 +1,92 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 TEMPLATE_SQL_H_ +#define TEMPLATE_SQL_H_ + +#include +#include +#include + +#include "Template.h" +#include "SqliteDB.h" +#include "ObjectSQL.h" + +using namespace std; + +/** + * SQL Template class, it provides DB support for template objects + */ +class TemplateSQL : public Template, public ObjectSQL +{ +public: + TemplateSQL( + const char * _table, + int template_id = -1, + bool replace = false): + Template(replace),table(_table),id(template_id) + {}; + + virtual ~TemplateSQL(){}; + +protected: + + //Database implementation variables + + const char * table; + + static const char * db_names; + + //Template attributes + + /** + * Template unique identification. + */ + int id; + + /** + * Writes the template in the DB + * @param db pointer to the database. + * @return 0 on success. + */ + int insert(SqliteDB * db); + + /** + * Updates the template in the DB + * @param db pointer to the database. + * @return 0 on success. + */ + int update(SqliteDB *db); + + /** + * Reads the template (identified by its id) from the DB + * @param db pointer to the database. + * @return 0 on success. + */ + int select(SqliteDB *db); + + /** + * Removes the template from the DB + * @param db pointer to the database. + */ + int drop(SqliteDB *db); +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +#endif /*TEMPLATE_SQL_H_*/ diff --git a/include/TransferManager.h b/include/TransferManager.h new file mode 100644 index 0000000000..89fa2a76d2 --- /dev/null +++ b/include/TransferManager.h @@ -0,0 +1,137 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 TRANSFER_MANAGER_H_ +#define TRANSFER_MANAGER_H_ + +#include "MadManager.h" +#include "ActionManager.h" +#include "VirtualMachinePool.h" +#include "LifeCycleManager.h" + +using namespace std; + +extern "C" void * tm_action_loop(void *arg); + +class TransferManager : public MadManager, public ActionListener +{ +public: + + TransferManager( + VirtualMachinePool * pool, + vector& _mads): + MadManager(_mads), + hpool(pool) + { + am.addListener(this); + }; + + ~TransferManager(){}; + + enum Actions + { + PROLOG, + EPILOG, + CHECKPOINT, + FINALIZE + }; + + /** + * Triggers specific actions to the Information Manager. This function + * wraps the ActionManager trigger function. + * @param action the IM action + * @param vid VM unique id. This is the argument of the passed to the + * invoked action. + */ + void trigger( + Actions action, + int vid); + + /** + * This functions starts the associated listener thread, and creates a + * new thread for the Information Manager. This thread will wait in + * an action loop till it receives ACTION_FINALIZE. + * @return 0 on success. + */ + int start(); + + /** + * Loads Virtual Machine Manager Mads defined in configuration file + * @param uid of the user executing the driver. When uid is 0 the nebula + * identity will be used. Otherwise the Mad will be loaded through the + * sudo application. + */ + void load_mads(int uid){}; + + /** + * Gets the thread identification. + * @return pthread_t for the manager thread (that in the action loop). + */ + pthread_t get_thread_id() const + { + return tm_thread; + }; + +private: + /** + * Thread id for the Transfer Manager + */ + pthread_t tm_thread; + + /** + * Pointer to the VM Pool, to access virtual machines + */ + VirtualMachinePool * hpool; + + /** + * Action engine for the Manager + */ + ActionManager am; + + /** + * Function to execute the Manager action loop method within a new pthread + * (requires C linkage) + */ + friend void * tm_action_loop(void *arg); + + /** + * The action function executed when an action is triggered. + * @param action the name of the action + * @param arg arguments for the action function + */ + void do_action( + const string & action, + void * arg); + + /** + * This function starts the prolog sequence + */ + void prolog_action(int vid); + + /** + * This function starts the epilog sequence + */ + void epilog_action(int vid); + + /** + * This function starts the epilog sequence + */ + void checkpoint_action(int vid); +}; + +#endif /*TRANSFER_MANAGER_H*/ + diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h new file mode 100644 index 0000000000..01fc26bde1 --- /dev/null +++ b/include/VirtualMachine.h @@ -0,0 +1,775 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 VIRTUAL_MACHINE_H_ +#define VIRTUAL_MACHINE_H_ + +#include "VirtualMachineTemplate.h" +#include "PoolSQL.h" +#include "History.h" +#include "Log.h" + +#include +#include + +using namespace std; + +extern "C" int vm_select_cb (void * _vm, int num,char ** values, char ** names); + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * The Virtual Machine class. It represents a VM... + */ +class VirtualMachine : public PoolObjectSQL +{ +public: + // ------------------------------------------------------------------------ + // VM States + // ------------------------------------------------------------------------ + + /** + * Global Virtual Machine state + */ + enum VmState + { + INIT = 0, + PENDING = 1, + HOLD = 2, + ACTIVE = 3, + STOPPED = 4, + SUSPENDED = 5, + DONE = 6, + FAILED = 7 + }; + + /** + * Virtual Machine state associated to the Life-cycle Manager + */ + enum LcmState + { + LCM_INIT = 0, + PROLOG = 1, + BOOT = 2, + RUNNING = 3, + MIGRATE = 4, + SAVE_STOP = 5, + SAVE_SUSPEND = 6, + SAVE_MIGRATE = 7, + PROLOG_MIGRATE = 8, + EPILOG_STOP = 9, + EPILOG = 10, + SHUTDOWN = 11, + CANCEL = 12 + }; + + // ------------------------------------------------------------------------ + // Log & Print + // ------------------------------------------------------------------------ + + /** + * writes a log message in vm.log. The class lock should be locked and + * the VM MUST BE obtained through the VirtualMachinePool get() method. + */ + void log( + const char * module, + const Log::MessageType type, + const ostringstream& message) const + { + if (_log != 0) + { + _log->log(module,type,message); + } + }; + + /** + * writes a log message in vm.log. The class lock should be locked and + * the VM MUST BE obtained through the VirtualMachinePool get() method. + */ + void log( + const char * module, + const Log::MessageType type, + const char * message) const + { + if (_log != 0) + { + _log->log(module,type,message); + } + }; + + /** + * Function to write a Virtual Machine in an output stream + */ + friend ostream& operator<<(ostream& os, VirtualMachine& vm); + + // ------------------------------------------------------------------------ + // Dynamic Info + // ------------------------------------------------------------------------ + + /** + * Updates VM dynamic information (id). + * @param _deploy_id the VMM driver specific id + */ + void update_info( + const string& _deploy_id) + { + deploy_id = _deploy_id; + }; + + /** + * Updates VM dynamic information (usage counters). + * @param _memory used by the VM (total) + * @param _cpu used by the VM (rate) + * @param _net_tx transmitted bytes (total) + * @param _net_tx received bytes (total) + */ + void update_info( + const int _memory, + const int _cpu, + const int _net_tx, + const int _net_rx) + { + if (_memory != -1) + { + memory = _memory; + } + + if (_cpu != -1) + { + cpu = _cpu; + } + + if (_net_tx != -1) + { + net_tx = _net_tx; + } + + if (_net_rx != -1) + { + net_rx = _net_rx; + } + }; + + /** + * Returns the deployment ID + * @return the VMM driver specific ID + */ + const string& get_deploy_id() const + { + return deploy_id; + }; + + /** + * Sets the VM exit time + * @param _et VM exit time (when it arraived DONE/FAILED states) + */ + void set_exit_time(time_t et) + { + etime = et; + }; + + // ------------------------------------------------------------------------ + // History + // ------------------------------------------------------------------------ + /** + * Adds a new history record an writes it in the database + */ + void add_history( + int hid, + string& hostname, + string& vm_dir, + string& vmm_mad, + string& tm_mad); + + /** + * Checks if the VM has a defined history record. This function + * MUST be called before using any history related function. + * @return true if the VM has a record + */ + bool hasHistory() const + { + return (history!=0); + }; + + /** + * Returns the VMM driver name for the current host. The hasHistory() + * function MUST be called before this one. + * @return the VMM mad name + */ + const string & get_vmm_mad() const + { + return history->vmm_mad_name; + }; + + /** + * Returns the TM driver name for the current host. The hasHistory() + * function MUST be called before this one. + * @return the TM mad name + */ + const string & get_tm_mad() const + { + return history->tm_mad_name; + }; + + /** + * Returns the deployment filename (local path). The hasHistory() + * function MUST be called before this one. + * @return the deployment filename + */ + const string & get_deployment_lfile() const + { + return history->deployment_lfile; + }; + + /** + * Returns the deployment filename for the current host (remote). The + * hasHistory() function MUST be called before this one. + * @return the deployment filename + */ + const string & get_deployment_rfile() const + { + return history->deployment_rfile; + }; + + /** + * Returns the checkpoint filename for the current host (remote). The + * hasHistory() function MUST be called before this one. + * @return the checkpoint filename + */ + const string & get_checkpoint_file() const + { + return history->checkpoint_file; + }; + + /** + * Returns the hostname for the current host. The hasHistory() + * function MUST be called before this one. + * @return the hostname + */ + const string & get_hostname() const + { + return history->hostname; + }; + + /** + * Get host id where the VM is or is going to execute. The hasHistory() + * function MUST be called before this one. + */ + int get_hid() + { + return history->hid; + } + + /** + * Sets start time of a VM. + * @param _stime time when the VM started + */ + void set_stime(time_t _stime) + { + history->stime=_stime; + }; + + /** + * Sets end time of a VM. + * @param _etime time when the VM finished + */ + void set_etime(time_t _etime) + { + history->etime=_etime; + }; + + /** + * Sets start time of VM prolog. + * @param _stime time when the prolog started + */ + void set_prolog_stime(time_t _stime) + { + history->prolog_stime=_stime; + }; + + /** + * Sets end time of VM prolog. + * @param _etime time when the prolog finished + */ + void set_prolog_etime(time_t _etime) + { + history->prolog_etime=_etime; + }; + + /** + * Sets start time of VM running state. + * @param _stime time when the running state started + */ + void set_running_stime(time_t _stime) + { + history->running_stime=_stime; + }; + + /** + * Sets end time of VM running state. + * @param _etime time when the running state finished + */ + void set_running_etime(time_t _etime) + { + history->running_etime=_etime; + }; + + /** + * Sets start time of VM epilog. + * @param _stime time when the epilog started + */ + void set_epilog_stime(time_t _stime) + { + history->running_stime=_stime; + }; + + /** + * Sets end time of VM epilog. + * @param _etime time when the epilog finished + */ + void set_epilog_etime(time_t _etime) + { + history->running_etime=_etime; + }; + + /** + * Sets the reason that originated the VM migration + * @param _reason migration reason to leave this host + */ + void set_reason(History::MigrationReason _reason) + { + history->reason=_reason; + }; + + // ------------------------------------------------------------------------ + // Template + // ------------------------------------------------------------------------ + + /** + * Gets the values of a template attribute + * @param name of the attribute + * @param values of the attribute + * @return the number of values + */ + int get_template_attribute( + string& name, + vector& values) const + { + return vm_template.get(name,values); + }; + + /** + * Gets the values of a template attribute + * @param name of the attribute + * @param values of the attribute + * @return the number of values + */ + int get_template_attribute( + const char *name, + vector& values) const + { + string str=name; + return vm_template.get(str,values); + }; + + /** + * Gets a string based VM attribute (single) + * @param name of the attribute + * @param value of the attribute (a string), will be "" if not defined or + * not a single attribute + */ + void get_template_attribute( + const char * name, + string& value) const + { + string str=name; + vm_template.get(str,value); + } + + /** + * Gets an int based VM attribute (single) + * @param name of the attribute + * @param value of the attribute (an int), will be 0 if not defined or + * not a single attribute + */ + void get_template_attribute( + const char * name, + int& value) const + { + string str=name; + vm_template.get(str,value); + } + + // ------------------------------------------------------------------------ + // States + // ------------------------------------------------------------------------ + + /** + * Returns the VM state (Dispatch Manager) + * @return the VM state + */ + VmState get_state() const + { + return state; + }; + + /** + * Returns the VM state (life-cycle Manager) + * @return the VM state + */ + LcmState get_lcm_state() const + { + return lcm_state; + }; + + /** + * Sets VM state + * @param s state + */ + void set_state(VmState s) + { + state = s; + }; + + /** + * Sets VM LCM state + * @param s state + */ + void set_state(LcmState s) + { + lcm_state = s; + }; + + /** + * Gets the user id of the owner of this VM + * @return the VM uid + */ + int get_uid() const + { + return uid; + }; + + // ------------------------------------------------------------------------ + // Timers + // ------------------------------------------------------------------------ + /** + * Gets time from last information polling. + * @return time of last poll (epoch) or 0 if never polled + */ + time_t get_last_poll() const + { + return last_poll; + }; + + /** + * Sets time of last information polling. + * @param poll time in epoch, normally time(0) + */ + void set_last_poll(time_t poll) + { + last_poll = poll; + }; + + /** + * Get the VM physical requirements for the host. + * @param cpu + * @param memory + * @param disk + */ + void get_requirements (int& cpu, int& memory, int& disk); + +private: + + // ------------------------------------------------------------------------- + // Friends + // ------------------------------------------------------------------------- + friend class VirtualMachinePool; + + friend int vm_select_cb ( + void * _vm, + int num, + char ** values, + char ** names); + + // ************************************************************************* + // Virtual Machine Attributes + // ************************************************************************* + + // ------------------------------------------------------------------------- + // Identification variables + // ------------------------------------------------------------------------- + /** + * Array id + */ + int aid; + + /** + * Task id + */ + int tid; + + /** + * User (owner) id + */ + int uid; + + // ------------------------------------------------------------------------- + // VM Scheduling & Managing Information + // ------------------------------------------------------------------------- + /** + * Static scheduling priority + */ + int priority; + + /** + * The VM reschedule flag + */ + bool reschedule; + + /** + * Last time (in epoch) that the VM was rescheduled + */ + time_t last_reschedule; + + /** + * Last time (in epoch) that the VM was polled to get its status + */ + time_t last_poll; + + // ------------------------------------------------------------------------- + // Virtual Machine Description + // ------------------------------------------------------------------------- + /** + * The Virtual Machine template, holds the VM attributes. + */ + VirtualMachineTemplate vm_template; + + // Dynamic state of the Virtual Machine + + /** + * The state of the virtual machine. + */ + VmState state; + + /** + * The state of the virtual machine (in the Life-cycle Manager). + */ + LcmState lcm_state; + + /** + * Start time, the VM enter the nebula system (in epoch) + */ + time_t stime; + + /** + * Exit time, the VM leave the nebula system (in epoch) + */ + time_t etime; + + /** + * Deployment specific identification string, as returned by the VM driver + */ + string deploy_id; + + /** + * Memory in Megabytes used by the VM + */ + int memory; + + /** + * CPU usage (percent) + */ + int cpu; + + /** + * Network usage, transmitted Kilobytes + */ + int net_tx; + + /** + * Network usage, received Kilobytes + */ + int net_rx; + + /** + * History record, for the current execution + */ + History * history; + + // ------------------------------------------------------------------------- + // Logging + // ------------------------------------------------------------------------- + + /** + * Log class for the virtual machine, it writes log messages in + * $ONE_LOCATION/var/$VID/vm.log + */ + Log * _log; + + // ************************************************************************* + // DataBase implementation (Private) + // ************************************************************************* + + /** + * Bootstraps the database table(s) associated to the VirtualMachine + */ + static void bootstrap(SqliteDB * db) + { + db->exec(VirtualMachine::db_bootstrap); + + db->exec(VirtualMachineTemplate::db_bootstrap); + + db->exec(History::db_bootstrap); + }; + + /** + * Function to unmarshall a VM object, an associated classes. + * @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); + + /** + * Updates the VM history record + * @param db pointer to the db + * @return 0 on success + */ + int update_history(SqliteDB * db) + { + if ( history != 0 ) + { + return history->insert(db); + } + else + return -1; + }; + + /** + * Sets the value of a column of the previous VM history record + * @param db pointer to the db + * @return 0 on success + */ + int update_previous_history_column( + SqliteDB * db, + const History::ColNames column, + const time_t val); + + /** + * Gets the value of a column of the previous VM history record + * @param db pointer to the db + * @return 0 on success + */ + int select_previous_history_column( + SqliteDB * db, + const History::ColNames column, + string * value); + + /** + * Gets the hid of the previous history host + */ + int get_previous_hid(SqliteDB * db, int * hid); + +protected: + + //************************************************************************** + // Constructor + //************************************************************************** + + VirtualMachine(int id=-1); + + virtual ~VirtualMachine(); + + // ************************************************************************* + // DataBase implementation + // ************************************************************************* + + enum ColNames + { + OID = 0, + AID = 1, + TID = 2, + UID = 3, + PRIORITY = 4, + RESCHEDULE = 5, + LAST_RESCHEDULE = 6, + LAST_POLL = 7, + TEMPLATE_ID = 8, + STATE = 9, + LCM_STATE = 10, + STIME = 11, + ETIME = 12, + DEPLOY_ID = 13, + MEMORY = 14, + CPU = 15, + NET_TX = 16, + NET_RX = 17, + LIMIT = 18 + }; + + static const char * table; + + static const char * db_names; + + static const char * db_bootstrap; + + /** + * Reads the Virtual Machine (identified with its OID) from the database. + * @param db pointer to the db + * @return 0 on success + */ + int select(SqliteDB * db); + + /** + * Writes the Virtual Machine and its associated template in the database. + * @param db pointer to the db + * @return 0 on success + */ + virtual int insert(SqliteDB * db); + + /** + * Writes/updates the Virtual Machine data fields in the database. + * @param db pointer to the db + * @return 0 on success + */ + virtual int update(SqliteDB * db); + + /** + * Deletes a VM from the database and all its associated information: + * - History records + * - VM template + * @param db pointer to the db + * @return 0 on success + */ + virtual int drop(SqliteDB * db) + { + int rc; + + rc = vm_template.drop(db); + + if ( history != 0 ) + { + rc += history->drop(db); + } + + return rc; + } +}; + +#endif /*VIRTUAL_MACHINE_H_*/ diff --git a/include/VirtualMachineManager.h b/include/VirtualMachineManager.h new file mode 100644 index 0000000000..a7bf5fdb6f --- /dev/null +++ b/include/VirtualMachineManager.h @@ -0,0 +1,223 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 VIRTUAL_MACHINE_MANAGER_H_ +#define VIRTUAL_MACHINE_MANAGER_H_ + +#include "MadManager.h" +#include "ActionManager.h" +#include "VirtualMachineManagerDriver.h" +#include "VirtualMachinePool.h" +#include "HostPool.h" +#include "NebulaTemplate.h" + +using namespace std; + +extern "C" void * vmm_action_loop(void *arg); + +class VirtualMachineManager : public MadManager, public ActionListener +{ +public: + + VirtualMachineManager( + VirtualMachinePool * _vmpool, + HostPool * _hpool, + time_t _timer_period, + time_t _poll_period, + vector& _mads); + + ~VirtualMachineManager(){}; + + enum Actions + { + DEPLOY, + SAVE, + SHUTDOWN, + CANCEL, + MIGRATE, + RESTORE, + TIMER, + FINALIZE + }; + + /** + * Triggers specific actions to the Virtual Machine Manager. This function + * wraps the ActionManager trigger function. + * @param action the VMM action + * @param vid VM unique id. This is the argument of the passed to the + * invoked action. + */ + void trigger( + Actions action, + int vid); + + /** + * This functions starts the associated listener thread, and creates a + * new thread for the Virtual Machine Manager. This thread will wait in + * an action loop till it receives ACTION_FINALIZE. + * @return 0 on success. + */ + int start(); + + /** + * Gets the thread identification. + * @return pthread_t for the manager thread (that in the action loop). + */ + pthread_t get_thread_id() const + { + return vmm_thread; + }; + + /** + * Loads Virtual Machine Manager Mads defined in configuration file + * @param uid of the user executing the driver. When uid is 0 the nebula + * identity will be used. Otherwise the Mad will be loaded through the + * sudo application. + */ + void load_mads(int uid); + +private: + /** + * Thread id for the Virtual Machine Manager + */ + pthread_t vmm_thread; + + /** + * Pointer to the Virtual Machine Pool, to access VMs + */ + VirtualMachinePool * vmpool; + + /** + * Pointer to the Host Pool, to access hosts + */ + HostPool * hpool; + + /** + * Timer period for the Virtual Machine Manager. + */ + time_t timer_period; + + /** + * Virtual Machine polling interval + */ + time_t poll_period; + + /** + * Action engine for the Manager + */ + ActionManager am; + + /** + * Function to execute the Manager action loop method within a new pthread + * (requires C linkage) + */ + friend void * vmm_action_loop(void *arg); + + /** + * Returns a pointer to a Virtual Machine Manager driver. + * @param uid of the owner of the driver + * @param name of an attribute of the driver (e.g. its type) + * @param value of the attribute + * @return the VM driver owned by uid with attribute name equal to value + * or 0 in not found + */ + const VirtualMachineManagerDriver * get( + int uid, + const string& name, + const string& value) + { + return static_cast + (MadManager::get(uid,name,value)); + }; + + /** + * Returns a pointer to a Virtual Machine Manager driver. The driver is + * searched by its name. + * @param uid of the owner of the driver + * @param name the name of the driver + * @return the VM driver owned by uid with attribute name equal to value + * or 0 in not found + */ + const VirtualMachineManagerDriver * get( + int uid, + const string& name) + { + string _name("NAME"); + return static_cast + (MadManager::get(uid,_name,name)); + }; + + /** + * The action function executed when an action is triggered. + * @param action the name of the action + * @param arg arguments for the action function + */ + void do_action( + const string & action, + void * arg); + + /** + * Function executed when a DEPLOY action is received. It deploys a VM on + * a Host. + * @param vid the id of the VM to be deployed. + */ + void deploy_action( + int vid); + + /** + * Function to stop a running VM and generate a checkpoint file. This + * function is executed when a SAVE action is triggered. + * @param vid the id of the VM. + */ + void save_action( + int vid); + + /** + * Shutdowns a VM when a SHUTDOWN action is received. + * @param vid the id of the VM. + */ + void shutdown_action( + int vid); + + /** + * Cancels a VM when a CANCEL action is received. + * @param vid the id of the VM. + */ + void cancel_action( + int vid); + + /** + * Function to migrate (live) a VM (MIGRATE action). + * @param vid the id of the VM. + */ + void migrate_action( + int vid); + + /** + * Restores a VM from a checkpoint file. + * @param vid the id of the VM. + */ + void restore_action( + int vid); + + /** + * This function is executed periodically to poll the running VMs + */ + void timer_action(); +}; + +#endif /*VIRTUAL_MACHINE_MANAGER_H*/ diff --git a/include/VirtualMachineManagerDriver.h b/include/VirtualMachineManagerDriver.h new file mode 100644 index 0000000000..815d8165b3 --- /dev/null +++ b/include/VirtualMachineManagerDriver.h @@ -0,0 +1,214 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 VIRTUAL_MACHINE_MANAGER_DRIVER_H_ +#define VIRTUAL_MACHINE_MANAGER_DRIVER_H_ + +#include +#include +#include + +#include "Mad.h" +#include "VirtualMachinePool.h" + +using namespace std; + +/** + * VirtualMachineManagerDriver provides a base class to implement VM Manager + * Drivers. This class implements the protocol and recover functions + * from the Mad interface. Classes derived from the VirtualMachineManagerDriver + * must implement the deployment function to generate specific VM + * deployment information for the unerlying MAD. + */ +class VirtualMachineManagerDriver : public Mad +{ +public: + + VirtualMachineManagerDriver( + int userid, + const map& attrs, + bool sudo, + VirtualMachinePool * pool): + Mad(userid,attrs,sudo),vmpool(pool) + {} + ; + + virtual ~VirtualMachineManagerDriver() + {} + ; + + /** + * Implements the VM Manager driver protocol. + * @param message the string read from the driver + */ + void protocol( + string& message); + + /** + * TODO: What do we need here? just poll the active VMs to recover + * connections? Or an specific recover action from the MAD? + */ + void recover(); + + /** + * Generates a driver-specific deployment file: + * @param vm pointer to a virtual machine + * @param file_name to generate the deployment description + * @return 0 on success + */ + virtual int deployment_description( + const VirtualMachine * vm, + const string& file_name) const = 0; + +private: + /** + * Pointer to the Virtual Machine Pool, to access VMs + */ + VirtualMachinePool * vmpool; + + friend class VirtualMachineManager; + + /** + * Sends a deploy request to the MAD: "DEPLOY ID HOST CONF -" + * @param oid the virtual machine id. + * @param host the hostname + * @param conf the filename of the deployment file + */ + void deploy ( + const int oid, + const string& host, + const string& conf) const; + + /** + * Sends a shutdown request to the MAD: "SHUTDOWN ID HOST NAME -" + * @param oid the virtual machine id. + * @param host the hostname + * @param name of the Virtual Machine (deployment id), as returned by the + * driver + */ + void shutdown ( + const int oid, + const string& host, + const string& name) const; + + /** + * Sends a cancel request to the MAD: "CANCEL ID HOST NAME -" + * @param oid the virtual machine id. + * @param host the hostname + * @param name of the Virtual Machine (deployment id), as returned by the + * driver + */ + void cancel ( + const int oid, + const string& host, + const string& name) const; + + /** + * Sends a checkpoint request to the MAD: "CHECKPOINT ID HOST NAME FILE" + * @param oid the virtual machine id. + * @param host the hostname + * @param name of the Virtual Machine (deployment id), as returned by the + * driver + * @param file the filename to generate the checkpoint file + */ + void checkpoint ( + const int oid, + const string& host, + const string& name, + const string& file) const; + + /** + * Sends a save request to the MAD: "SAVE ID HOST NAME FILE" + * @param oid the virtual machine id. + * @param host the hostname + * @param name of the Virtual Machine (deployment id), as returned by the + * driver + * @param file the filename to generate the checkpoint file + */ + void save ( + const int oid, + const string& host, + const string& name, + const string& file) const; + + /** + * Sends a save request to the MAD: "RESTORE ID HOST FILE -" + * @param oid the virtual machine id. + * @param host the hostname + * @param file the filename of the checkpoint file to restore the VM + * from + */ + void restore ( + const int oid, + const string& host, + const string& file) const; + + /** + * Sends a migrate request to the MAD: "MIGRATE ID HOST NAME DEST" + * @param oid the virtual machine id. + * @param shost the original host (source) + * @param name of the Virtual Machine (deployment id), as returned by the + * driver + * @param dhost the destination host + */ + void migrate ( + const int oid, + const string& shost, + const string& name, + const string& dhost) const; + + /** + * Sends a poll request to the MAD: "POLL ID HOST NAME -" + * @param oid the virtual machine id. + * @param host the hostname + * @param name of the Virtual Machine (deployment id), as returned by the + * driver + */ + void poll ( + const int oid, + const string& host, + const string& name) const; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +class KvmDriver : public VirtualMachineManagerDriver +{ +public: + + KvmDriver( + int userid, + const map &attrs, + bool sudo, + VirtualMachinePool * pool): + VirtualMachineManagerDriver(userid, attrs,sudo,pool) + {}; + + ~KvmDriver(){}; + +private: + int deployment_description( + const VirtualMachine * vm, + const string& file_name) const + { + return 0; + }; +}; + +#endif /*VIRTUAL_MACHINE_MANAGER_DRIVER_H_*/ + diff --git a/include/VirtualMachinePool.h b/include/VirtualMachinePool.h new file mode 100644 index 0000000000..ccce2d28ac --- /dev/null +++ b/include/VirtualMachinePool.h @@ -0,0 +1,133 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 VIRTUAL_MACHINE_POOL_H_ +#define VIRTUAL_MACHINE_POOL_H_ + +#include "PoolSQL.h" +#include "VirtualMachine.h" + +#include + +using namespace std; + + +/** + * The Virtual Machine Pool class. ... + */ +class VirtualMachinePool : public PoolSQL +{ +public: + + VirtualMachinePool(SqliteDB * db):PoolSQL(db,VirtualMachine::table){}; + + ~VirtualMachinePool(){}; + + /** + * Function to allocate a new VM object + * @param uid user id (the owner of the VM) + * @param stemplate a string describing the VM + * @param oid the id assigned to the VM (output) + * @param on_hold flag to submit on hold + * @return 0 on success, -1 error inserting in DB or -2 error parsing + * the template + */ + int allocate ( + int uid, + const string& stemplate, + int * oid, + bool on_hold = false); + + /** + * Function to get a VM from the pool, if the object is not in memory + * it is loade from the DB + * @param oid VM unique id + * @param lock locks the VM mutex + * @return a pointer to the VM, 0 if the VM could not be loaded + */ + VirtualMachine * get( + int oid, + bool lock) + { + return static_cast(PoolSQL::get(oid,lock)); + }; + + /** + * Function to get the IDs of running VMs + * @param oids a vector that contains the IDs + * @return 0 on success + */ + int get_running( + vector& oids); + + /** + * Function to get the IDs of pending VMs + * @param oids a vector that contains the IDs + * @return 0 on success + */ + int get_pending( + vector& oids); + + //-------------------------------------------------------------------------- + // Virtual Machine DB access functions + //-------------------------------------------------------------------------- + + /** + * Updates the history record of a VM, the lock of the vm SHOULD be locked + * @param vm pointer to the virtual machine object + * @return 0 on success + */ + int update_history( + VirtualMachine * vm) + { + return vm->update_history(db); + } + + /** + * Get the ID of the previous host + * @param vm pointer to the virtual machine object + * @param hid the ID of the host + * @return 0 on success + */ + int get_previous_hid( + VirtualMachine * vm, + int * hid) + { + return vm->get_previous_hid(db,hid); + }; + + /** + * Bootstraps the database table(s) associated to the VirtualMachine pool + */ + void bootstrap() + { + VirtualMachine::bootstrap(db); + }; + +private: + + /** + * Factory method to produce VM objects + * @return a pointer to the new VM + */ + PoolObjectSQL * create() + { + return new VirtualMachine; + }; +}; + +#endif /*VIRTUAL_MACHINE_POOL_H_*/ diff --git a/include/VirtualMachineTemplate.h b/include/VirtualMachineTemplate.h new file mode 100644 index 0000000000..48655b8bd2 --- /dev/null +++ b/include/VirtualMachineTemplate.h @@ -0,0 +1,47 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 VIRTUAL_MACHINE_TEMPLATE_H_ +#define VIRTUAL_MACHINE_TEMPLATE_H_ + +#include "TemplateSQL.h" + +using namespace std; + +/** + * Virtual Machine Template class, it represents a VM configuration file. + */ +class VirtualMachineTemplate : public TemplateSQL +{ +public: + VirtualMachineTemplate(int tid = -1): + TemplateSQL(table,tid){}; + + ~VirtualMachineTemplate(){}; + +private: + friend class VirtualMachine; + + static const char * table; + + static const char * db_bootstrap; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +#endif /*VIRTUAL_MACHINE_TEMPLATE_H_*/ diff --git a/include/XenDriver.h b/include/XenDriver.h new file mode 100644 index 0000000000..6b8b0db557 --- /dev/null +++ b/include/XenDriver.h @@ -0,0 +1,114 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 XEN_DRIVER_H_ +#define XEN_DRIVER_H_ + +#include +#include +#include +#include "Nebula.h" +#include "VirtualMachineManagerDriver.h" + +using namespace std; + +/** + * Xen Driver class implements a VM Manager Driver to interface with the Xen + * hypervisor. + */ +class XenDriver : public VirtualMachineManagerDriver +{ +public: + + XenDriver( + int userid, + const map &attrs, + bool sudo, + VirtualMachinePool * pool): + VirtualMachineManagerDriver(userid, attrs,sudo,pool) + { + map::const_iterator it; + char * error_msg = 0; + const char * cfile; + string file; + int rc; + ostringstream oss; + + it = attrs.find("DEFAULT"); + + if ( it != attrs.end() ) + { + if (it->second[0] != '/') //Look in ONE_LOCATION + { + Nebula& nd = Nebula::instance(); + + file = nd.get_nebula_location() + "/" + it->second; + cfile = file.c_str(); + } + else //Absolute Path + { + cfile = it->second.c_str(); + } + + rc = xen_conf.parse(cfile, &error_msg); + + if (( rc != 0 ) && ( error_msg != 0)) + { + oss << "Error loading xen driver configuration file: " + << error_msg; + + Nebula::log("VMM", Log::ERROR, oss); + + free(error_msg); + } + } + }; + + ~XenDriver(){}; + +private: + /** + * Configuration file for the driver + */ + Template xen_conf; + + /** + * Generates a configuration attr from driver configuration file + * @param name of config attribute for the domain + * @param value of the attribute + */ + void get_default( + const char * name, + string& value) const + { + string sn = name; + + xen_conf.get(sn,value); + } + + /** + * Generates a xen-specific deployment file seexmdomain.cfg(5): + * @param vm pointer to a virtual machine + * @param file_name to generate the deployment description + * @return 0 on success + */ + int deployment_description( + const VirtualMachine * vm, + const string& file_name) const; +}; + +#endif /*XEN_DRIVER_H_*/ diff --git a/install.sh b/install.sh new file mode 100755 index 0000000000..1367e8db4d --- /dev/null +++ b/install.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +SRC_DIR=$PWD +DST_DIR=$1 + +echo $SRC_DIR +echo $DST_DIR + +inst_ln() { + ln -s $SRC_DIR/$1 $DST_DIR/$2 +} + +inst_cp() { + cp $SRC_DIR/$1 $DST_DIR/$2 +} + +if [ -z "$SRC_DIR" -o -z "$DST_DIR" ]; then + echo Must supply a destination directory + exit -1 +fi + +DIRS="/bin /etc /etc/mad /etc/default /libexec /lib/ruby /var /share/examples /lib/im_probes" + +for d in $DIRS; do + mkdir -p $DST_DIR$d +done + +inst_ln src/nebula/oned bin +inst_ln src/scheduler/mm_sched bin +inst_ln src/client/ruby/onevm bin +inst_ln src/client/ruby/onehost bin + +inst_cp share/etc/oned.conf etc +inst_ln share/etc/mad/defaultrc etc/mad +inst_ln share/etc/mad/im_sshrc etc/mad +inst_ln share/etc/mad/vmm_xenrc etc/mad +inst_ln share/etc/default/vmm_xen.conf etc/default + +inst_ln share/scripts/madcommon.sh libexec + +inst_ln src/vmm_mad/xen/one_vmm_xen.rb bin +inst_ln src/vmm_mad/xen/one_vmm_xen bin + +inst_ln src/im_mad/xen/one_im_ssh.rb bin +inst_ln src/im_mad/xen/one_im_ssh bin + +inst_cp src/im_mad/xen/one_im_ssh.conf etc +inst_ln src/vmm_mad/xen/one_mad.rb lib/ruby +inst_ln src/im_mad/xen/one_ssh.rb lib/ruby +inst_ln src/client/ruby/one.rb lib/ruby +inst_ln src/client/ruby/client_utilities.rb lib/ruby +inst_ln src/client/ruby/command_parse.rb lib/ruby + +inst_ln src/im_mad/xen/architecture.sh lib/im_probes +inst_ln src/im_mad/xen/cpu.sh lib/im_probes +inst_ln src/im_mad/xen/name.sh lib/im_probes +inst_ln src/im_mad/xen/xen.rb lib/im_probes + +inst_cp share/scripts/one bin + +inst_cp share/examples/vm.template share/examples + + diff --git a/share/doc/design/AuthorizationAuthentication.png b/share/doc/design/AuthorizationAuthentication.png new file mode 100644 index 0000000000..88e8f4a59c Binary files /dev/null and b/share/doc/design/AuthorizationAuthentication.png differ diff --git a/share/doc/design/HostPool.xmi b/share/doc/design/HostPool.xmi new file mode 100644 index 0000000000..5923808bb9 --- /dev/null +++ b/share/doc/design/HostPool.xmi @@ -0,0 +1,429 @@ + + + + + umbrello uml modeller http://uml.sf.net + 1.5.8 + UnicodeUTF8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/doc/design/VMPool.xmi b/share/doc/design/VMPool.xmi new file mode 100644 index 0000000000..f366a9f47d --- /dev/null +++ b/share/doc/design/VMPool.xmi @@ -0,0 +1,401 @@ + + + + + umbrello uml modeller http://uml.sf.net + 1.5.8 + UnicodeUTF8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/doc/design/action manager.xmi b/share/doc/design/action manager.xmi new file mode 100644 index 0000000000..515c5f1727 --- /dev/null +++ b/share/doc/design/action manager.xmi @@ -0,0 +1,297 @@ + + + + + umbrello uml modeller http://uml.sf.net + 1.5.8 + UnicodeUTF8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/doc/design/dispatch manager.xmi b/share/doc/design/dispatch manager.xmi new file mode 100644 index 0000000000..b9a18ec5f5 --- /dev/null +++ b/share/doc/design/dispatch manager.xmi @@ -0,0 +1,335 @@ + + + + + umbrello uml modeller http://uml.sf.net + 1.5.8 + UnicodeUTF8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/doc/design/life-cycle manager.xmi b/share/doc/design/life-cycle manager.xmi new file mode 100644 index 0000000000..6a95a33387 --- /dev/null +++ b/share/doc/design/life-cycle manager.xmi @@ -0,0 +1,437 @@ + + + + + umbrello uml modeller http://uml.sf.net + 1.5.8 + UnicodeUTF8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/doc/design/pool.xmi b/share/doc/design/pool.xmi new file mode 100644 index 0000000000..277e2a0b24 --- /dev/null +++ b/share/doc/design/pool.xmi @@ -0,0 +1,749 @@ + + + + + umbrello uml modeller http://uml.sf.net + 1.5.8 + UnicodeUTF8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/doc/design/requestmanager.xmi b/share/doc/design/requestmanager.xmi new file mode 100644 index 0000000000..5de8125944 --- /dev/null +++ b/share/doc/design/requestmanager.xmi @@ -0,0 +1,740 @@ + + + + + umbrello uml modeller http://uml.sf.net + 1.5.8 + UnicodeUTF8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/doc/nebula/nebula.doxyfile b/share/doc/nebula/nebula.doxyfile new file mode 100644 index 0000000000..308e2acfce --- /dev/null +++ b/share/doc/nebula/nebula.doxyfile @@ -0,0 +1,1294 @@ +# Doxyfile 1.5.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file that +# follow. The default is UTF-8 which is also the encoding used for all text before +# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into +# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of +# possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = "Nebula Internal documentation" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 0.1 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = ./ + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = YES + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, +# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, +# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = NO + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = /home/ruben/Programs/Eclipse_Workspace/ + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be extracted +# and appear in the documentation as a namespace called 'anonymous_namespace{file}', +# where file will be replaced with the base name of the file that contains the anonymous +# namespace. By default anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST = YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = NO + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../../../include + +# This tag can be used to specify the character encoding of the source files that +# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default +# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. +# See http://www.gnu.org/software/libiconv for the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the output. +# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, +# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH +# then you must also enable this option. If you don't then doxygen will produce +# a warning and turn it on anyway + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to +# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to +# specify the directory where the mscgen tool resides. If left empty the tool is assumed to +# be found in the default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the number +# of direct children of the root node in a graph is already larger than +# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/share/etc/default/vmm_xen.conf b/share/etc/default/vmm_xen.conf new file mode 100644 index 0000000000..985d9817cc --- /dev/null +++ b/share/etc/default/vmm_xen.conf @@ -0,0 +1,10 @@ +# +# Default configuration attributes for the Xen driver +# (all domains will use these values as defaults) +# + +MEMORY = 128 + +KERNEL = /vmlinuz + +RAMDISK = /initrd.img diff --git a/share/etc/mad/defaultrc b/share/etc/mad/defaultrc new file mode 100644 index 0000000000..848a58b01e --- /dev/null +++ b/share/etc/mad/defaultrc @@ -0,0 +1,36 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2008, 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. # +#--------------------------------------------------------------------------- # + +#------------------------------------------------------------------------------- +# Global environment configuration file for ONE MADS +# -------------------------------------------------------- +# +# This file is sourced before a driver is started. Also the variables +# declared here are "exported". +# +# Values in this file will be overridden or completed by the MAD +# specific rc file. +# +# This file MUST preserve SH syntax +#------------------------------------------------------------------------------- + +# MADs will generate cores and logs if defined +ONE_MAD_DEBUG= + +# Nice Priority to run the drivers +PRIORITY=19 + diff --git a/share/etc/mad/im_sshrc b/share/etc/mad/im_sshrc new file mode 100644 index 0000000000..3d5eace0b5 --- /dev/null +++ b/share/etc/mad/im_sshrc @@ -0,0 +1,16 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2008, 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. # +#--------------------------------------------------------------------------- # diff --git a/share/etc/mad/vmm_xenrc b/share/etc/mad/vmm_xenrc new file mode 100644 index 0000000000..a3267e2634 --- /dev/null +++ b/share/etc/mad/vmm_xenrc @@ -0,0 +1,16 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2008, 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. # +#--------------------------------------------------------------------------- # \ No newline at end of file diff --git a/share/etc/oned.conf b/share/etc/oned.conf new file mode 100644 index 0000000000..189d801981 --- /dev/null +++ b/share/etc/oned.conf @@ -0,0 +1,41 @@ +# +# VM_RDIR: The VM "remote" directory stores VM related data on the target host. +# Each VM has its own directory ($VM_HOME) within the $VM_DIR, $VMDIR/$VID +# Set this variable to the mount point of $ONE_LOCATION/var/ +# if needed as it defaults to this value +#VM_RDIR=/vCluster/var + +# Time in seconds between host monitorization +HOST_MONITORING_INTERVAL=10 + +# Information manager configuration. You can add more information managers with different +# configuration but make sure it has different names. +# +# name: name for this information manager +# executable: path of the information manager executable, can be an absolute path or +# a relative path from $ONE_LOCATION +# arguments: path where the information manager configuration resides, can also +# be a relative path +# owner: user that will be used for monitoring (we recommend this to be ) +# +IM_MAD=[name="one_im",executable="bin/one_im_ssh",arguments="etc/one_im_ssh.conf",owner="oneadmin"] + +# Time in seconds between virtual machine monitorization +VM_POLLING_INTERVAL=10 + +# Virtual Machine Manager configuration. This component does not have a configuration +# file. You can change the path of xentop in remote machines changing +# XENTOP_PATH in the beginning of this script. +# +# name: name of the virtual manager configuration +# executable: path of the virtual machine manager executable, can be an absolute path or +# a relative path from $ONE_LOCATION +# owner: user that will be used for vm managing (we recommend this to be ) +# config: defult values and configuration parameters for the driver + + +VM_MAD=[name="one_vmm",executable="bin/one_vmm_xen",owner="oneadmin",default="etc/default/vmm_xen.conf"] + +# Port where oned will listen for xmlrpc calls. +PORT=2633 + diff --git a/share/examples/vm.template b/share/examples/vm.template new file mode 100644 index 0000000000..f6b758292d --- /dev/null +++ b/share/examples/vm.template @@ -0,0 +1,6 @@ +DISK=[image="/local/xen/domains/xen-etch/disk.img",dev="sda1",mode=w] +DISK=[image="/local/xen/domains/xen-etch/swap.img",dev="sda2",mode=w] +KERNEL=/boot/vmlinuz-2.6.18-4-xen-amd64 +RAMDISK=/boot/initrd.img-2.6.18-4-xen-amd64 +MEMORY=64 +CPU=1 diff --git a/share/scons/lex_bison.py b/share/scons/lex_bison.py new file mode 100644 index 0000000000..0016b625d2 --- /dev/null +++ b/share/scons/lex_bison.py @@ -0,0 +1,64 @@ + +import os +import SCons + +############ +# BUILDERS # +############ + +def build_lex(target, source, env): + cwd=os.getcwd() + + src=SCons.Util.to_String(source[0]) + src_dir=os.path.dirname(src) + src_name=os.path.basename(src) + + os.chdir(src_dir) + os.system("flex "+src_name) + os.chdir(cwd) + + return None + +def emitter_lex(target, source, env): + src=SCons.Util.to_String(source[0]) + src_dir=os.path.dirname(src) + (src_name, src_ext)=os.path.splitext(os.path.basename(src)) + target.append(src_name+".h") + return target, source + +def add_lex(environment): + lex_bld=SCons.Builder.Builder(action=build_lex, + suffix='.c', + src_suffix='.l', + emitter=emitter_lex) + environment.Append(BUILDERS={'Lex':lex_bld}) + + +def build_bison(target, source, env): + cwd=os.getcwd() + + src=SCons.Util.to_String(source[0]) + src_dir=os.path.dirname(src) + src_name=os.path.basename(src) + (base, ext)=os.path.splitext(src_name) + + os.chdir(src_dir) + os.system("bison "+src_name) + os.rename(base+".hh", base+".h") + os.chdir(cwd) + + return None + +def emitter_bison(target, source, env): + src=SCons.Util.to_String(source[0]) + src_dir=os.path.dirname(src) + (src_name, src_ext)=os.path.splitext(os.path.basename(src)) + target.append(src_name+".h") + return target, source + +def add_bison(environment): + bison_bld=SCons.Builder.Builder(action=build_bison, + suffix='.cc', + src_suffix='.y', + emitter=emitter_bison) + environment.Append(BUILDERS={'Bison':bison_bld}) diff --git a/share/scripts/madcommon.sh b/share/scripts/madcommon.sh new file mode 100644 index 0000000000..5e0cddc449 --- /dev/null +++ b/share/scripts/madcommon.sh @@ -0,0 +1,81 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2008, 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. # +#--------------------------------------------------------------------------- # + +function mad_debug +{ + if [ -n "${ONE_MAD_DEBUG}" ]; then + ulimit -c 15000 + fi +} + +function export_rc_vars +{ + if [ -f $1 ] ; then + ONE_VARS=`cat $1 | egrep -e '^[a-zA-Z\-\_0-9]*=' | sed 's/=.*$//'` + + . $1 + + for v in $ONE_VARS; do + export $v + done + fi +} + +function log_with_date +{ + PID=$$ + LOG_FILE=$1 + shift + + mkfifo /tmp/one_fifo.$PID.err /tmp/one_fifo.$PID.out + + # This line creates an empty log file + echo -n "" > $LOG_FILE + + # Write out fifo to STDOUT + cat /tmp/one_fifo.$PID.out & + + while read line < /tmp/one_fifo.$PID.err + do + echo `date +"%D %T"`: $line >> $LOG_FILE + done & + + $* 2>/tmp/one_fifo.$PID.err 1>/tmp/one_fifo.$PID.out + + rm /tmp/one_fifo.$PID.out /tmp/one_fifo.$PID.err +} + +function execute_mad +{ + MAD_FILE=`basename $0` + + if [ -n "${ONE_MAD_DEBUG}" ]; then + log_with_date var/$MAD_FILE.log nice -n $PRIORITY bin/$MAD_FILE.rb $* + else + exec nice -n $PRIORITY bin/$MAD_FILE.rb $* 2> /dev/null + fi +} + + +# Set global environment + +export_rc_vars $ONE_LOCATION/etc/defaultrc + +# Sanitize PRIORITY variable +if [ -z "$PRIORITY" ]; then + export PRIORITY=19 +fi diff --git a/share/scripts/one b/share/scripts/one new file mode 100755 index 0000000000..617f5b1d32 --- /dev/null +++ b/share/scripts/one @@ -0,0 +1,110 @@ +#! /bin/sh + +if [ -z "$ONE_LOCATION" ]; then + echo "ONE_LOCATION is not defined" + exit 1 +fi + +ONE_PID=$ONE_LOCATION/var/oned.pid +ONE_SCHEDPID=$ONE_LOCATION/var/sched.pid +ONE_CONF=$ONE_LOCATION/etc/oned.conf + +ONED=$ONE_LOCATION/bin/oned +ONE_SCHEDULER=$ONE_LOCATION/bin/mm_sched + +setup() +{ + PORT=`cat $ONE_CONF | grep ^PORT= | cut -d= -f2` + + if [ $? -ne 0 ]; then + echo "Can not find PORT in $ONE_CONF." + exit 1 + fi +} + +start() +{ + if [ ! -x "$ONED" ]; then + echo "Can not find $ONED." + exit 1 + fi + + if [ ! -x "$ONE_SCHEDULER" ]; then + echo "Can not find $ONE_SCHEDULER." + exit 1 + fi + + # Start the one daemon + $ONED -f 2>&1 & + + LASTRC=$? + LASTPID=$! + + if [ $LASTRC -ne 0 ]; then + echo "Error executing $ONED" + exit 1 + else + echo $LASTPID > $ONE_PID + fi + + # Start the scheduler + $ONE_SCHEDULER -p $PORT & + + LASTRC=$? + LASTPID=$! + + if [ $LASTRC -ne 0 ]; then + echo "Error executing $ONE_SCHEDULER" + exit 1 + else + echo $LASTPID > $ONE_SCHEDPID + fi + + echo "oned and scheduler started" +} + +# +# Function that stops the daemon/service +# +stop() +{ + if [ ! -f $ONE_PID ]; then + echo "Couldn't find oned process pid." + exit 1 + fi + + if [ ! -f $ONE_SCHEDPID ]; then + echo "Couldn't find scheduler process pid." + exit 1 + fi + + # Kill the one daemon + + kill `cat $ONE_PID` + + # Kill the scheduler + + kill `cat $ONE_SCHEDPID` + + # Remove pid files + + rm -f $ONE_PID > /dev/null 2>&1 + rm -f $ONE_SCHEDPID > /dev/null 2>&1 + + echo "oned and scheduler stopped" +} + + +case "$1" in + start) + setup + start + ;; + stop) + stop + ;; + *) + echo "Usage: nebula {start|stop}" >&2 + exit 3 + ;; +esac diff --git a/share/test/one.db b/share/test/one.db new file mode 100644 index 0000000000..2d4b4c7b5d Binary files /dev/null and b/share/test/one.db differ diff --git a/share/test/src/common/AMTest.cc b/share/test/src/common/AMTest.cc new file mode 100644 index 0000000000..c489d89812 --- /dev/null +++ b/share/test/src/common/AMTest.cc @@ -0,0 +1,67 @@ +#include "ActionManager.h" +#include +#include + +class AMTest : public ActionListener +{ +public: + AMTest():am() + { + am.addListener(this); + }; + + ~AMTest(){}; + + ActionManager am; + +private: + void do_action(const string &action, void * arg); +}; + +void AMTest::do_action(const string &action, void * arg) +{ + int * i = static_cast(arg); + + cout<<"Event received: "< (arg); + + MT->am.trigger(event,&i); + + sleep(4); + + i = 10; + + MT->am.trigger(event,&i); + + i = 23; + + MT->am.trigger(ActionListener::ACTION_FINALIZE,&i); + + return 0; +} +/* +int main() +{ + pthread_t id; + int i = 3; + AMTest * MT = new AMTest(); + + pthread_create(&id, 0, startThread, MT); + + MT->am.loop(1,&i); + + delete MT; + + pthread_join(id,0); + + return 0; +} +*/ diff --git a/share/test/src/host/TestHostPool.cc b/share/test/src/host/TestHostPool.cc new file mode 100644 index 0000000000..32116e5008 --- /dev/null +++ b/share/test/src/host/TestHostPool.cc @@ -0,0 +1,252 @@ +#include "VirtualMachine.h" +#include "VirtualMachineManagerDriver.h" +#include "Nebula.h" + +#include "InformationManagerDriver.h" +#include "InformationManager.h" +#include "Mad.h" + +#include "Host.h" +#include "HostPool.h" + + + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +extern "C" void *test(void *nothing) +{ + ostringstream os; + + sleep(2); + os.str(""); + + int rc; + + Nebula & pn = Nebula::instance(); + + HostPool * thepool = pn.get_hpool(); + Host * host; + int hid; + + thepool->bootstrap(); + + thepool->allocate(&hid,"foo.dacya","mad1","mad2","mad3",true); + + os.str(""); + os << "Host " << hid << " allocated"; + Nebula::log("TST", Log::ERROR, os); + + thepool->allocate(&hid,"foo2.dacya","mad1","mad2","mad3",true); + + os.str(""); + os << "Host " << hid << " allocated"; + Nebula::log("TST", Log::ERROR, os); + + thepool->allocate(&hid,"foo3.dacya","mad1","mad2","mad3",true); + + os.str(""); + os << "Host " << hid << " allocated"; + Nebula::log("TST", Log::ERROR, os); + + host = static_cast(thepool->get(3422,false)); + + if (host != 0) + { + os.str(""); + os << "Test failed. Shouldn't be here."; + Nebula::log("TST", Log::ERROR, os); + } + + host = static_cast(thepool->get(0,true)); + + if (host != 0) + { + os.str(""); + os << "Going fine. Host " << *host << " retrieved."; + Nebula::log("TST", Log::ERROR, os); + + host->unlock(); + } + else + { + os.str(""); + os << "Test failed!. Not able to retrieve host 0"; + Nebula::log("TST", Log::ERROR, os); + } + + + Host * host2 = static_cast(thepool->get(1,false)); + + if (host2 != 0) + { + os.str(""); + os << "Going fine. Host " << *host2 << " retrieved."; + Nebula::log("TST", Log::ERROR, os); + } + + Host * host3 = static_cast(thepool->get(2,false)); + + if (host3 != 0) + { + os.str(""); + os << "Going fine. Host " << *host3 << " retrieved."; + Nebula::log("TST", Log::ERROR, os); + + } + + + Host * host4 = static_cast(thepool->get(32,false)); + + + if (host4 != 0) + { + os.str(""); + os << "Going fine. Host " << *host4 << " retrieved."; + Nebula::log("TST", Log::ERROR, os); + + } + + host3->lock(); + + string host_info_str("cpuArchitecture=x86_32\nnumberCores=1\ncpuSpeed=2211\ntotalMemory=2046\nfreeMemory=125\nusedMemory=1921\ncpupercentage=50\nnetTX=78516\nnetRX=138612\nnetRX=138612\n"); + rc = host3->update_info(host_info_str); + + host3->touch(); + + + os.str(""); + os << "updated host info with RC = " << rc; + Nebula::log("TST", Log::ERROR, os); + + rc = thepool->update_host(host3); + + os.str(""); + os << "updated host into DB with RC = " << rc; + Nebula::log("TST", Log::ERROR, os); + + bool result; + char * error; + + rc = host3->match("numberCores=1 & cpuArchitecture=\"OTRA ARCH\"",result,&error); + + os.str(""); + if ( rc == 0) + { + os << "REQ result = " << result; + } + else + { + os << "REQ error = " << error; + + free(error); + } + Nebula::log("TST", Log::ERROR, os); + + int resulti; + + rc = host3->rank("cpuSpeed + numberCores",resulti,&error); + + os.str(""); + if ( rc == 0) + { + os << "RANK result = " << resulti; + } + else + { + os << "RANK error = " << error; + + free(error); + } + Nebula::log("TST", Log::ERROR, os); + + host3->unlock(); + + host3->lock(); + + string host_info_str2("cpuArchitecture=\"OTRA ARCH\"\n"); + + rc = host3->update_info(host_info_str2); + + host3->touch(); + + rc = thepool->update_host(host3); + + host3->unlock(); + + + host2->lock(); + + string host_info_str3("cpuArchitecture=x86_32\nnumberCores=8\ncpuSpeed=2211\ntotalMemory=2046\nfreeMemory=125\nusedMemory=1921\ncpupercentage=50\nnetTX=78516\nnetRX=138612\nnetRX=138612\n"); + + rc = host2->update_info(host_info_str3); + + host2->touch(); + + rc = thepool->update_host(host2); + + host2->unlock(); + + map test_discover; + + rc = thepool->discover(&test_discover); + + if(rc!=0) + { + os.str(""); + os << "Error discovering hosts."; + Nebula::log("TST", Log::ERROR, os); + } + + os.str(""); + os << "Discover size:" << test_discover.size(); + Nebula::log("TST", Log::ERROR, os); + + map ::iterator it; + + for(it=test_discover.begin();it!=test_discover.end();it++) + { + os.str(""); + os << "IM_MAD:" << it->second << " has to monitor " << it->first; + Nebula::log("TST", Log::ERROR, os); + } + + return 0; +} + + + +int main() +{ + pthread_t test_thread; + + pthread_create(&test_thread,0,test,(void *)0); + + try + { + Nebula& nd = Nebula::instance(); + nd.start(); + } + catch (exception &e) + { + cout << e.what() << endl; + + return -1; + } + + + return 0; +} diff --git a/share/test/src/im/ImTest.cc b/share/test/src/im/ImTest.cc new file mode 100644 index 0000000000..7a5256fbfe --- /dev/null +++ b/share/test/src/im/ImTest.cc @@ -0,0 +1,99 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2008, 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 "VirtualMachine.h" +#include "VirtualMachineManagerDriver.h" +#include "Nebula.h" + +#include "InformationManagerDriver.h" +#include "InformationManager.h" +#include "Mad.h" + + + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace std; + + +extern "C" void *test(void *nothing) +{ + sleep(2); + + Nebula& pn = Nebula::instance(); + + InformationManager * im = pn.get_im(); + HostPool * hostp = pn.get_hpool(); + + int * oid; + int rc; + + sleep(2); + + /* rc = hostp->allocate(oid,"aquila03","im_test","xen_ssh","dummy",true); + + if ( rc != 0 ) + { + Nebula::log("TST",Log::ERROR,"Error allocating host!"); + return 0; + } +*/ + + im->load_mads(); + + sleep(600); + + return 0; +} + +int main() +{ + pthread_attr_t pattr; + pthread_t test_thread; + + pthread_attr_init (&pattr); + pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE); + + pthread_create(&test_thread,&pattr,test,(void *)0); + + try + { + Nebula& nd = Nebula::instance(); + nd.start(); + } + catch (exception &e) + { + cout << e.what() << endl; + + return -1; + } + + + return 0; +} + diff --git a/share/test/src/mad/MMTest.cc b/share/test/src/mad/MMTest.cc new file mode 100644 index 0000000000..1694209388 --- /dev/null +++ b/share/test/src/mad/MMTest.cc @@ -0,0 +1,188 @@ +#include +#include +#include + +#include + +#include "MadManager.h" + +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +bool finalized = false; + +class MadEcho : public Mad +{ +public: + MadEcho(map &attrs):Mad(0,attrs,false) + {} + ; + + ~MadEcho() + {} + ; + + void protocol(string& message); + + void recover() + { + cout<<"Recover Function @ MadEcho\n"; + }; + + void test(const char *a1, const char *a2, const char *a3) + { + ostringstream buf; + + buf << "TEST " << a1 << " " << a2 << " " << a3 << "\n"; + + write(buf); + } + + void first(const char *a1) + { + ostringstream buf; + + buf << "FIRST " << a1 << "\n"; + + write(buf); + } +}; + +void MadEcho::protocol(string& message) +{ + stringbuf sbuf(message); + iostream sstr(&sbuf); + + string field[5]; + + sstr >> field[0] >> ws; + + if ( field[0] == "INIT" ) + { + getline(sstr,field[1]); + + cout << "Init Result: " << field[1] << "\n"; + } + else if ( field[0] == "FINALIZE" ) + { + getline(sstr,field[1]); + + cout << "Finalize Result: " << field[1] << "\n"; + } + else if ( field[0] == "TEST" ) + { + sstr >> field[1] >> field[2] >> field[3] >> ws; + + getline(sstr,field[4]); + + cout << "Test Result: " << field[1] << "\nArg1: " << field[2] + << "\nArg2: " << field[3] << "\nInfo: " << field[4] << "\n"; + } + else if ( field[0] == "FIRST" ) + { + finalized = true; + + sstr >> field[1] >> ws; + getline(sstr,field[2]); + + cout << "First Result: " << field[1] << "\nArg1: " << field[2] << "\n"; + + pthread_cond_signal(&cond); + } +} + +class MMadManager : public MadManager +{ +public: + MMadManager(vector& _mads):MadManager(_mads){}; + ~MMadManager(){}; + + void load_mads(int uid){}; + + int mstart(){ + return start(); + } + + void mstop(){ + stop(); + } + + int madd(Mad *mad){ + return add(mad); + } +}; + +int main() +{ + vector _mads; + MMadManager *mm; + MadEcho * mad_echo; + map attrs; + int rc; + + MadManager::mad_manager_system_init(); + + mm = new MMadManager(_mads); + + rc = mm->mstart(); + + if ( rc != 0 ) + { + goto error_start; + } + + attrs.insert(make_pair("NAME","echo_mad")); + attrs.insert(make_pair("EXECUTABLE","./mad_echo.sh")); + attrs.insert(make_pair("OWNER","foo")); + + mad_echo = new MadEcho(attrs); + /* + rc = mad_echo->start(); + + if ( rc != 0 ) + { + goto error_start_mad; + } + */ + rc = mm->madd(mad_echo); + + if ( rc != 0 ) + { + goto error_register; + } + + mad_echo->test("argument1","argument2","argument3"); + + mad_echo->first("filed1"); + + pthread_mutex_lock(&mutex); + + while ( finalized == false ) + { + pthread_cond_wait(&cond, &mutex); + } + + printf("Mad_Test - OK\n"); + + mm->mstop(); + + delete mm; + + return 0; + +error_register: + cout << "Mad_Test - error register mad\n"; + mm->mstop(); + + delete mm; + delete mad_echo; + + return -1; + +error_start: + cout << "Mad_Test - error start manager\n"; + mm->mstop(); + + delete mm; + + return -1; +} diff --git a/share/test/src/mad/mad_echo.sh b/share/test/src/mad/mad_echo.sh new file mode 100755 index 0000000000..97e3ae75fb --- /dev/null +++ b/share/test/src/mad/mad_echo.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- +# Copyright 2002-2006 GridWay Team, Distributed Systems Architecture +# Group, Universidad Complutense de Madrid +# +# 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. +# -------------------------------------------------------------------------- + +echo "MAD started" > mad.log + + +while read COMMAND ARG1 ARG2 ARG3 +do + echo "$COMMAND $ARG1 $ARG2 $ARG3" >> mad.log + case $COMMAND in + "INIT" | "init") + echo "INIT SUCCESS" + ;; + "FINALIZE" | "finalize") + echo "FINALIZE SUCCESS" + exit 0 + ;; + "TEST" | "test") + echo "TEST SUCCESS $ARG1 $ARG2 $ARG3" + ;; + "FIRST" | "first") + echo "FIRST SUCCESS $ARG1" + ;; + *) + echo "$COMMAND - FAILURE Unknown command" + ;; + esac +done diff --git a/share/test/src/nebula/log.cc b/share/test/src/nebula/log.cc new file mode 100644 index 0000000000..6121ac8e63 --- /dev/null +++ b/share/test/src/nebula/log.cc @@ -0,0 +1,15 @@ +#include "Log.h" +#include + +int main() +{ + Log log("file.log"); + + ostringstream message; + message << "pepe"; + + log.log("module", Log::ERROR, message); + + return 0; +} + diff --git a/share/test/src/pool/TestSQL.cc b/share/test/src/pool/TestSQL.cc new file mode 100644 index 0000000000..b06795814b --- /dev/null +++ b/share/test/src/pool/TestSQL.cc @@ -0,0 +1,173 @@ +#include "PoolSQL.h" +#include +#include +#include +#include + +class A : public ObjectSQL +{ +public: + A(int n,string &t):number(n),text(t){oid=n;}; + A(int n,const char *t):number(n),text(t){oid=n;}; + A(int n):number(n){oid=n;}; + A(){}; + ~A(){}; + + int number; + string text; + + int insert(sqlite3 *db); + int select(sqlite3 *db); + int update(sqlite3 *db){return 0;}; +}; + +int A::insert(sqlite3 *db) +{ + const char * sql_cmd; + ostringstream buffer; + string sql; + int rc; + + buffer << "INSERT INTO test (numero,texto) VALUES (" << oid << ",\"" << +text << "\")"; + + sql = buffer.str(); + sql_cmd = sql.c_str(); + + rc = sqlite3_exec(db, + sql_cmd, + NULL, + NULL, + NULL); + + if ( rc != SQLITE_OK ) + { + cout << "ERROR : "<text = values[1]; + + cout << "-" << aclass->text << "-\n"; + + return 0; +} + +int A::select(sqlite3 *db){ + + const char * sql_cmd; + ostringstream buffer; + string sql; + + buffer << "SELECT * FROM test WHERE numero=" << oid; + + + sql = buffer.str(); + sql_cmd = sql.c_str(); + + sqlite3_exec(db, + sql_cmd, + select_cb, + this, + NULL); + + return 0; +}; + +class Apool : public PoolSQL +{ +public: + Apool(sqlite3 *db):PoolSQL(db,"test"){}; + ~Apool(){}; +private: + ObjectSQL* create(){ return (new A);}; + +}; + + +/* +int main() +{ + sqlite3 * db; + + sqlite3_open("pool.db", &db); + + sqlite3_exec(db, + "CREATE TABLE test (numero INTEGER," + "texto TEXT)", + NULL, + NULL, + NULL); + + + A *a; + Apool apool(db); + + + a = new A(-1,"prueba"); + + apool.allocate(a); + + a = new A(4,"otro"); + + apool.allocate(a); + + a = new A(8,"otro mas"); + + apool.allocate(a); + + A * aobj = static_cast(apool.get(1,false)); + + cout << aobj->text << "\n"; + + delete aobj; + + aobj = static_cast(apool.get(0,false)); + + cout << aobj->text << "\n"; + + delete aobj; + + sqlite3_close(db); +} +*/ + +/* +int main() +{ + sqlite3 * db; + string s("HOLA"); + A test(8,s); + A otro(8); + + sqlite3_open("pool.db", &db); + + sqlite3_exec(db, + "CREATE TABLE test (numero INTEGER," + "texto TEXT)", + NULL, + NULL, + NULL); + + test.insert(db); + + otro.select(db); + + cout << "texto : " << otro.text; + + sqlite3_close(db); +}*/ diff --git a/share/test/src/template/ATTest.cc b/share/test/src/template/ATTest.cc new file mode 100644 index 0000000000..a66ff43a66 --- /dev/null +++ b/share/test/src/template/ATTest.cc @@ -0,0 +1,122 @@ +#include "VirtualMachineTemplate.h" +#include +#include +#include + + +int main() +{ + VirtualMachineTemplate tmp; + Template t; + + char *error; + string st("MEMORY=345\nCPU=4\nDISK=[FILE=\"img\",TYPE=cd]\nDISK=[FILE=\"../f\"]\n"); + + + ostringstream os; + + if ((tmp.parse("vm.template",&error) != 0 ) && + (error != 0)) + { + cout << "Error parsing file: "<< error << endl; + + free(error); + } + + string mrs; + + tmp.marshall(mrs,':'); + + cout << "-" << mrs << "-"; + + if ((t.parse(st,&error) != 0 ) && + (error != 0)) + { + cout << "Error parsing string: "<< error << endl; + + free(error); + } + cout << "TEMPLATE" << endl << t << endl; + cout << "------" << endl << endl; + cout << "TEMPLATE" << endl << tmp << endl; + + string mm("MEMORY"); + vector values; + + tmp.get(mm,values); + + const SingleAttribute *pmemo; + + pmemo = static_cast(values[0]); + + cout << "MEM = " << pmemo->value() << "\n"; + + cout << "TEMPLATE--" << endl << t << endl; + + // ---- Init template DB ---- + /* + + sqlite3 * db; + sqlite3_open("template.db", &db); + + sqlite3_exec(db, + "CREATE TABLE vm_template (id INTEGER," + "name TEXT, value TEXT)", + 0, + 0, + 0); + + cout << tmp.insert(db) << endl; + + VirtualMachineTemplate rtmp(2); + + rtmp.select(db); + + cout << endl << "FROM DB" << endl << rtmp; + + sqlite3_close(db); + + */ + return 0; +} + + +/* +int main() +{ + TemplateAttribute sa1("ejemplo","valor"); + TemplateAttribute sa2("sample","value"); +// Attribute * pa; +// Attribute * pa2; + + cout << sa1.name() << ":" << sa1.value() << "\n"; + cout << sa2.name() << ":" << sa2.value() << "\n"; + + + cout << sa2.name() << ":" << sa2.value() << "\n"; + + + + + //map mymap; + //TemplateAttribute * pta; + + + + //pa = new TemplateAttribute("ejemplo","valor"); + + //cout << str_attr.name(); + //cout << pa->name(); + + //pta = static_cast *> (pa); + + //cout << pa->name(); + + //mymap.insert(make_pair("cadena",pa)); + + //delete pa; + + return 0; +} +*/ + diff --git a/share/test/src/template/vm.template b/share/test/src/template/vm.template new file mode 100644 index 0000000000..171190715d --- /dev/null +++ b/share/test/src/template/vm.template @@ -0,0 +1,8 @@ +MEMORY = 512 +Cpu = 1 + +DISK = [ ImaGE="/local/VM/disk.img",device="sda",TYPE="hd" ] +DISK = [ image="../debian.iso",DEvice="sdb",TYPE="cdrom" ] + +nic = [ MAC="00:01:02", TYPE="bridged", IP="147.3"] + diff --git a/share/test/src/vm/TestVMPool.cc b/share/test/src/vm/TestVMPool.cc new file mode 100644 index 0000000000..8b279fb118 --- /dev/null +++ b/share/test/src/vm/TestVMPool.cc @@ -0,0 +1,74 @@ +#include "VirtualMachinePool.h" +#include +#include +#include +#include + +int main() +{ + sqlite3 * db; + + sqlite3_open("pool.db", &db); + + VirtualMachinePool thepool(db); + VirtualMachine * vm; + int eid; + string st("MEMORY=345\nCPU=4\nDISK=[FILE=\"img\",TYPE=cd]\nDISK=[FILE=\"../f\"]\n"); + + thepool.bootstrap(); + + thepool.allocate(0,st,&eid); + cout << eid << endl; + + thepool.allocate(0,st,&eid); + cout << eid << endl; + + thepool.allocate(0,st,&eid); + cout << eid << endl; + + vm = static_cast(thepool.get(444,false)); + + if (vm != 0) + { + cout << *vm; + } + + vm = static_cast(thepool.get(1,true)); + + string vmm = "xen"; + string tm = "gridftp"; + + //vm->add_history(2,2,vmm,tm); + + //thepool.update_history(vm); + + if (vm != 0) + { + cout << *vm << endl; + + vm->unlock(); + } + else + { + cout << "VM es cero!" << endl; + } + + VirtualMachine * vm2 = static_cast(thepool.get(2,false)); + + if (vm2 != 0) + { + + cout << *vm2; + } + + VirtualMachine * vm3 = static_cast(thepool.get(3,true)); + + if (vm3 != 0) + { + cout << *vm3; + + vm3->unlock(); + } + + sqlite3_close(db); +} diff --git a/share/test/src/vmm/VMManager.cc b/share/test/src/vmm/VMManager.cc new file mode 100644 index 0000000000..74dc2a14a0 --- /dev/null +++ b/share/test/src/vmm/VMManager.cc @@ -0,0 +1,56 @@ + +#include + +#include "Nebula.h" +#include +#include +#include "VirtualMachine.h" +#include "VirtualMachineManagerDriver.h" + +extern "C" void *test(void *nothing) +{ + VirtualMachineManager *vm_manager; + InformationManager *im_manager; + Nebula& ne = Nebula::instance(); + string s_template; + ostringstream os; + + sleep(20); + + Nebula::log("TST", Log::INFO, "Alive!"); + + vm_manager = ne.get_vmm(); + vm_manager->load_mads(0); + + im_manager = ne.get_im(); + im_manager->load_mads(0); + + return 0; +} + +int main() +{ + pthread_attr_t pattr; + pthread_t test_thread; + + pthread_attr_init (&pattr); + pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE); + + pthread_create(&test_thread,&pattr,test,(void *)0); + + try + { + Nebula& nd = Nebula::instance(); + nd.start(); + } + catch (exception &e) + { + cout << e.what() << endl; + + return -1; + } + + + return 0; +} + diff --git a/src/client/ruby/client_utilities.rb b/src/client/ruby/client_utilities.rb new file mode 100644 index 0000000000..7ffabc654f --- /dev/null +++ b/src/client/ruby/client_utilities.rb @@ -0,0 +1,220 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2008, 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. # +#--------------------------------------------------------------------------- # + +##################### +# CONSOLE UTILITIES # +##################### + +# Sets bold font +def scr_bold + print "\33[1m" +end + +# Sets underline +def scr_underline + print "\33[4m" +end + +# Restore normal font +def scr_restore + print "\33[0m" +end + +# Clears screen +def scr_cls + print "\33[2J\33[H" +end + +# Moves the cursor +def scr_move(x,y) + print "\33[#{x};#{y}H" +end + + + +################################## +# Class show configurable tables # +################################## + +ShowTableExample={ + :id => { + :name => "ID", + :size => 4, + :proc => lambda {|d,e| d["oid"] } + }, + :name => { + :name => "NAME", + :size => 8, + :proc => lambda {|d,e| d["deploy_id"] } + }, + :stat => { + :name => "STAT", + :size => 4, + :proc => lambda {|d,e| e[:vm].get_state(d) } + }, + :default => [:id, :name, :stat] +} + +# Class to print tables +class ShowTable + attr_accessor :ext, :columns + + # table => definition of the table to print + # ext => external variables (Hash), @ext + def initialize(table, ext=nil) + @table=table + @ext=Hash.new + @ext=ext if ext.kind_of?(Hash) + @columns=@table[:default] + end + + # Returns a formated string for header + def header_str + @columns.collect {|c| + if @table[c] + #{}"%#{@table[c][:size]}s" % [@table[c][:name]] + format_data(c, @table[c][:name]) + else + nil + end + }.compact.join(' ') + end + + # Returns an array with header titles + def header_array + @columns.collect {|c| + if @table[c] + @table[c][:name].to_s + else + "" + end + }.compact + end + + def data_str(data, options=nil) + # TODO: Use data_array so it can be ordered and/or filtered + res_data=data_array(data, options) + + res_data.collect {|d| + (0..(@columns.length-1)).collect {|c| + dat=d[c] + col=@columns[c] + + format_data(col, dat) if @table[col] + }.join(' ') + }.join("\n") + + #data.collect {|d| + # @columns.collect {|c| + # format_data(c, @table[c][:proc].call(d, @ext)) if @table[c] + # }.join(' ') + #}.join("\n") + end + + def data_array(data, options=nil) + res_data=data.collect {|d| + @columns.collect {|c| + @table[c][:proc].call(d, @ext).to_s if @table[c] + } + } + + if options + filter_data!(res_data, options[:filter]) if options[:filter] + sort_data!(res_data, options[:order]) if options[:order] + end + + res_data + end + + def format_data(field, data) + minus=( @table[field][:left] ? "-" : "" ) + size=@table[field][:size] + "%#{minus}#{size}.#{size}s" % [ data.to_s ] + end + + def get_order_column(column) + desc=column.match(/^-/) + col_name=column.gsub(/^-/, '') + index=@columns.index(col_name.to_sym) + [index, desc] + end + + def sort_data!(data, order) + data.sort! {|a,b| + # rows are equal by default + res=0 + order.each {|o| + # compare + pos, dec=get_order_column(o) + break if !pos + + r = (b[pos]<=>a[pos]) + + # if diferent set res (return value) and exit loop + if r!=0 + # change sign if the order is decreasing + r=-r if dec + res=r + break + end + } + res + } + end + + def filter_data!(data, filters) + filters.each {|key, value| + pos=@columns.index(key.downcase.to_sym) + if pos + data.reject! {|d| + if !d[pos] + true + else + !d[pos].downcase.match(value.downcase) + end + } + end + } + end + + def print_help + text=[] + @table.each {|option, data| + next if option==:default + text << "%9s (%2d) => %s" % [option, data[:size], data[:desc]] + } + text.join("\n") + end + +end + + +################ +# Miscelaneous # +################ + +def check_parameters(name, number) + if ARGV.length < number + print "Command #{name} requires " + if number>1 + puts "#{number} parameters to run." + else + puts "one parameter to run" + end + exit -1 + end +end diff --git a/src/client/ruby/command_parse.rb b/src/client/ruby/command_parse.rb new file mode 100644 index 0000000000..04cb2e9627 --- /dev/null +++ b/src/client/ruby/command_parse.rb @@ -0,0 +1,115 @@ + +require 'optparse' +require 'pp' + +class CommandParse + + COMMANDS_HELP=<<-EOT +Commands: + +EOT + + USAGE_BANNER=<<-EOT +Usage: + onevm [] [] + +Options: +EOT + + ONE_VERSION=<<-EOT +OpenNEbula preview release (2008/03/26) +Copyright 2002-2008, Distributed Systems Architecture Group, Universidad +Complutense de Madrid (dsa-research.org) + +EOT + + def initialize + @options=Hash.new + + @cmdparse=OptionParser.new do |opts| + opts.banner=text_banner + + opts.on("-l x,y,z", "--list x,y,z", Array, + "Selects columns to display with list", "command") do |o| + @options[:list]=o.collect {|c| c.to_sym } + end + + opts.on("--list-columns", "Information about the columns available", + "to display, order or filter") do |o| + puts list_options + exit + end + + opts.on("-o x,y,z", "--order x,y,z", Array, + "Order by these columns, column starting", + "with - means decreasing order") do |o| + @options[:order]=o + end + + opts.on("-f x,y,z", "--filter x,y,z", Array, + "Filter data. An array is specified", "with column=value pairs.") do |o| + @options[:filter]=Hash.new + o.each {|i| + k,v=i.split('=') + @options[:filter][k]=v + } + end + + opts.on("-d seconds", "--delay seconds", Integer, + "Sets the delay in seconds for top", "command") do |o| + @options[:delay]=o + end + + opts.on_tail("-h", "--help", "Shows this help message") do |o| + print_help + exit + end + + opts.on_tail("-v", "--version", + "Shows version and copyright information") do |o| + puts text_version + exit + end + end + end + + def parse(args) + begin + @cmdparse.parse!(args) + rescue => e + puts e.message + exit -1 + end + end + + def options + @options + end + + def print_help + puts @cmdparse + puts + puts text_commands + end + + def text_commands + COMMANDS_HELP + end + + def text_command_name + "onevm" + end + + def text_banner + USAGE_BANNER.gsub("onevm", text_command_name) + end + + def text_version + ONE_VERSION + end + + def list_options + "\n\n" + end +end + diff --git a/src/client/ruby/one.rb b/src/client/ruby/one.rb new file mode 100644 index 0000000000..78bbc40bc2 --- /dev/null +++ b/src/client/ruby/one.rb @@ -0,0 +1,511 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2008, 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. # +#--------------------------------------------------------------------------- # + + +begin + require 'rubygems' +rescue Exception +end +require 'sqlite3' +require 'xmlrpc/client' +require 'pp' + +module ONE + + ######################## + # DATABASE DEFINITIONS # + ######################## + + ONE_LOCATION=ENV["ONE_LOCATION"] + + TABLES={ + "vmpool" => %w{oid aid tid uid priority reschedule last_reschedule + last_poll template state lcm_state stime etime deploy_id memory + cpu net_tx net_rx}, + "history" => %w{oid seq hostname vm_dir hid vmmad tmmad stime + etime pstime petime rstime retime estime eetime reason}, + "vm_template" => %w{id name type value}, + "hostpool" => %w{hid host_name state im_mad vm_mad tm_mad + last_mon_time managed}, + "host_attributes" => %w{id name type value}, + "hostshares" => %w{hsid endpoint disk_usage mem_usage + cpu_usage max_disk max_mem max_cpu running_vms} + } + + + ####################### + # ENUMS AND CONSTANTS # + ####################### + + 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 EPILOG_STOP EPILOG SHUTDOWN CANCEL} + + HOST_STATE=%w{INIT MONITORING MONITORED ERROR DISABLED} + + MIGRATE_REASON=%w{NONE ERROR STOP_RESUME PERFORMANCE USER RESCHEDULING + KILL} + + + ################## + # HELPER CLASSES # + ################## + + # Server class. This is the one that makes xml-rpc calls. + class Server + #def initialize(host="localhost", port=60666, path="/RPC2") + # @server=XMLRPC::Client.new(host, path, port) + #end + + def initialize(endpoint=nil) + if endpoint + one_endpoint=endpoint + elsif ENV["ONE_XMLRPC"] + one_endpoint=ENV["ONE_XMLRPC"] + else + one_endpoint="http://localhost:2633/RPC2" + end + @server=XMLRPC::Client.new2(one_endpoint) + end + + def call(action, *args) + begin + response=@server.call("one."+action, "sessionID", *args) + response< e + [false, e.message] + end + end + end + + + # This class has the functions to access to the database + class Database + attr_reader :db + + def initialize(file=ONE_LOCATION+"/var/one.db") + @db=SQLite3::Database.new(file) + @db.busy_timeout(5000) + + @db.busy_handler do |data, retries| + if retries < 3 + puts "Timeout connecting to the database, retrying. "+ + "Tries left #{2-retries}" + sleep 1 + 1 + else + 0 + end + end + end + + def select_table_with_names(table, options=nil) + options=Hash.new if !options + where_clause=( options[:where] ? "where #{options[:where]}" : "" ) + order_clause=( options[:order] ? "order by #{options[:order]}" : "" ) + + sql="select * from #{table} #{where_clause} #{order_clause}" + #pp sql + begin + result=@db.execute(sql) + rescue Exception => e + result=[false, e.message] + return result + end + + res=result.collect {|row| + r=Hash.new + TABLES[table].each_with_index {|value, index| + r[value]=row[index] + } + r + } + return [true,res] + end + + def close + @db.close + end + end + + # Prototype class to call server actions + class CommandContainer + def initialize(server) + @server=server + end + + # Magic goes here. This function converts each argument + # using description provided by a hash returned by "commands" + # method. If the position contains a nil or false the + # argument is not converted (right now used for booleans). + def call_method(name, *_args) + args=[] + _args.flatten! + _args.each_with_index {|v,i| + if self.commands[name][i] + args << v.send(self.commands[name][i]) + else + args << v + end + } + + @server.call(prefix+name.gsub(/_$/, ""), *args) + end + + def method_missing(method, *args) + if self.commands.has_key?(method.to_s) + call_method(method.to_s, args) + else + raise NoMethodError + end + end + + # This method should return a hash with action names + # and an array with methods to convert the arguments. + def commands + {} + end + + def prefix + "" + end + end + + + ########################### + # ONE ABSTRACTION CLASSES # + ########################### + + class VM < CommandContainer + + 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", + "EPILOG_STOP" => "epil", + "EPILOG" => "epil", + "SHUTDOWN" => "shut", + "CANCEL" => "shut" + } + + SHORT_MIGRATE_REASON={ + "NONE" => "none", + "ERROR" => "erro", + "STOP_RESUME" => "stop", + "PERFORMANCE" => "perf", + "USER" => "user", + "RESCHEDULING" => "rsch", + "KILL" => "kill" + } + + + def commands + { + "allocate_" => [:to_s], + "deploy" => [:to_i, :to_i], + "action" => [:to_s, :to_i], + "migrate_" => [:to_i, :to_i, nil], + "get_info" => [:to_i] + } + end + + def prefix + "vm" + end + + def allocate(*args) + begin + f=open(args[0], "r") + template=f.read + f.close + rescue + return [false, "Can not read template"] + end + + self.allocate_(template) + end + + def migrate(*args) + self.migrate_(args[0], args[1], false) + end + + def livemigrate(*args) + self.migrate_(args[0], args[1], true) + end + + def shutdown(*args) + self.action("shutdown", args[0]) + end + + def hold(*args) + self.action("hold", args[0]) + end + + def release(*args) + self.action("release", args[0]) + end + + def stop(*args) + self.action("stop", args[0]) + end + + def suspend(*args) + self.action("suspend", args[0]) + end + + def resume(*args) + self.action("resume", args[0]) + end + + def delete(*args) + self.action("finalize", args[0]) + end + + def get(options=nil) + begin + @db=Database.new + + res=@db.select_table_with_names("vmpool", options) + + @db.close + + result=res + rescue + result=[false, "Error accessing database"] + end + + result + end + + def get_vms(options=nil) + res=self.get(options) + if res[0] + res[1].each {|row| + hostname=self.get_history_host(row["oid"]) + row["hostname"]=hostname + } + end + res + end + + + ########### + # HELPERS # + ########### + + def get_history_host(id, db=nil) + if db + my_db=db + else + my_db=Database.new + end + + res=my_db.select_table_with_names("history", :where => "oid=#{id}") + + my_db.close if !db + + if res and res[0] + return hostname=res[1][-1]["hostname"] + else + return nil + end + end + + def get_history(id, db=nil) + if db + my_db=db + else + my_db=Database.new + end + + res=my_db.select_table_with_names("history", :where => "oid=#{id}") + + my_db.close if !db + + return res + end + + def get_template(id, db=nil) + if db + my_db=db + else + my_db=Database.new + end + + res=my_db.select_table_with_names("vm_template", :where => "id=#{id}") + + my_db.close if !db + + if res && res[0] + template=Hash.new + res[1].each {|v| + name=v["name"] + type=v["type"] + value=v["value"] + if type=="0" + template[name]=value + else + template[name]=Hash.new + value.split(',').each {|v2| + name2, value2=v2.split("=") + template[name][name2]=value2 + } + end + } + template + else + nil + end + end + + def get_state(data) + vm_state=ONE::VM_STATE[data["state"].to_i] + state_str=SHORT_VM_STATES[vm_state] + + if state_str=="actv" + lcm_state=ONE::LCM_STATE[data["lcm_state"].to_i] + state_str=SHORT_LCM_STATES[lcm_state] + end + + state_str + end + + def get_reason(data) + reason=ONE::MIGRATE_REASON[data["reason"].to_i] + reason_str=SHORT_MIGRATE_REASON[reason] + + reason_str + 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 + end + + + class Host < CommandContainer + + SHORT_HOST_STATES={ + "INIT" => "on", + "MONITORING" => "on", + "MONITORED" => "on", + "ERROR" => "err", + "DISABLED" => "off", + } + + def commands + { + "allocate_" => [:to_s, :to_s, :to_s, :to_s, nil], + "info" => [:to_i], + "delete" => [:to_i], + "enable_" => [:to_i, nil] + } + end + + def allocate(*args) + case args[4] + when /^true$/i, 1 + managed=true + when /^false$/i, 0 + managed=false + else + puts "Error, use true/false or 0/1 for managed parameter" + exit -1 + end + self.allocate_( args[0..3]< "id=#{hid}") + end + + def get_host_share(hid) + get_generic("hostshares", :where => "hsid=#{hid}") + end + + def prefix + "host" + end + + + ########### + # HELPERS # + ########### + + def get_state(data) + host_state=ONE::HOST_STATE[data["state"].to_i] + state_str=SHORT_HOST_STATES[host_state] + + state_str + end + end + +end diff --git a/src/client/ruby/onehost b/src/client/ruby/onehost new file mode 100755 index 0000000000..fbd286b7c8 --- /dev/null +++ b/src/client/ruby/onehost @@ -0,0 +1,289 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- # +# Copyright 2002-2008, 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 + puts "ONE_LOCATION not set" + exit -1 +end + +$: << ONE_LOCATION+"/lib/ruby" + +require 'one' +require 'client_utilities' +require 'command_parse' + +ShowTableHost={ + :hid => { + :name => "HID", + :desc => "ONE identifier for host", + :size => 4, + :proc => lambda {|d,e| d["hid"] } + }, + :name => { + :name => "NAME", + :desc => "Hostname", + :size => 25, + :left => true, + :proc => lambda {|d,e| d["host_name"] } + }, + :rvm => { + :name => "RVM", + :desc => "Number of virtual machines running", + :size => 3, + :proc => lambda {|d,e| d["hs_running_vms"] } + }, + :tcpu => { + :name => "TCPU", + :desc => "Total cpu percentage", + :size => 6, + :proc => lambda {|d,e| d["TOTALCPU"] } + }, + :fcpu => { + :name => "FCPU", + :desc => "Free cpu percentage", + :size => 6, + :proc => lambda {|d,e| d["TOTALCPU"].to_i-d["USEDCPU"].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=100 if max_cpu==0 + max_cpu-d["hs_cpu_usage"].to_i + } + }, + :tmem => { + :name => "TMEM", + :desc => "Total memory", + :size => 7, + :proc => lambda {|d,e| d["TOTALMEMORY"] } + }, + :fmem => { + :name => "FMEM", + :desc => "Free memory", + :size => 7, + :proc => lambda {|d,e| d["FREEMEMORY"] } + }, + :stat => { + :name => "STAT", + :desc => "Host status", + :size => 4, + :proc => lambda {|d,e| e[:host].get_state(d) } + }, + + + :default => [:hid, :name, :rvm, :tcpu, :fcpu, :acpu, :tmem, :fmem, :stat] +} + +class HostShow + def initialize(host) + @host=host + @table=ShowTable.new(ShowTableHost, :host => @host) + end + + def close + end + + def header_host_small + scr_bold + scr_underline + puts @table.header_str + scr_restore + end + + def list_short(options=nil) + res=@host.get + if options + @table.columns=options[:columns] if options[:columns] + end + + if res[0] + result=res + header_host_small + res[1].each {|row| + res2=@host.get_host_attributes(row["hid"]) + 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["hid"]) + 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"] + row["hs_running_vms"]=a["running_vms"] + } + end + } + puts @table.data_str(result[1], options) + result + else + result=res + 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 OnehostParse < CommandParse + + COMMANDS_HELP=<<-EOT +Commands: + +* add (Adds a new machine to the pool) + onehost add + +* show (Gets info from a host) + onehost show + +* delete (Removes a machine from the pool) + onehost delete + +* list (Lists machines in the pool) + onehost list + +* enable (Enables host) + onehost enable + +* disable (Disables host) + onehost disable + +* top (Lists hosts continuously) + onehost top + +EOT + + def text_commands + COMMANDS_HELP + end + + def text_command_name + "onehost" + end + + def list_options + table=ShowTable.new(ShowTableHost) + table.print_help + end + +end + +server=ONE::Server.new +host=ONE::Host.new(server) + +onehost_opts=OnehostParse.new +onehost_opts.parse(ARGV) + +result=[false, "Unknown error"] + +command=ARGV.shift + +case command +when "add" + check_parameters("add", 3) + result=host.allocate(*[ARGV[0], ARGV[1], ARGV[2], "tm_mad", "true"]) + +when "show" + check_parameters("show", 1) + result=host.info(*ARGV) + if result[0] + puts result[1] + else + puts "Error: "+result[1] + exit -1 + end + +when "delete" + check_parameters("delete", 1) + result=host.delete(*ARGV) + if result[0] + puts "Host deleted" + exit 0 + end + +when "list" + hostlist=HostShow.new(host) + ops=onehost_opts.options + ops[:columns]=ops[:list] if ops[:list] + result=hostlist.list_short(ops) + hostlist.close + +when "top" + hostlist=HostShow.new(host) + ops=onehost_opts.options + ops[:columns]=ops[:list] if ops[:list] + result=hostlist.top(ops) + hostlist.close + +when "enable" + check_parameters("enable", 1) + result=host.enable(*ARGV) + if result[0] + puts "Host enabled" + exit 0 + end + +when "disable" + check_parameters("disable", 1) + result=host.disable(*ARGV) + if result[0] + puts "Host disabled" + exit 0 + end + +else + onehost_opts.print_help + exit -1 +end + +if !result[0] + puts "Error: " + result[1].to_s + exit -1 +end diff --git a/src/client/ruby/onevm b/src/client/ruby/onevm new file mode 100755 index 0000000000..d6ecf3c25b --- /dev/null +++ b/src/client/ruby/onevm @@ -0,0 +1,509 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- # +# Copyright 2002-2008, 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 + puts "ONE_LOCATION not set" + exit -1 +end + +$: << ONE_LOCATION+"/lib/ruby" + +require 'one' +require 'client_utilities' +require 'command_parse' + +ShowTableVM={ + :id => { + :name => "ID", + :desc => "ONE identifier for the VM", + :size => 4, + :proc => lambda {|d,e| d["oid"] } + }, + :name => { + :name => "NAME", + :desc => "Name of the domain", + :size => 8, + :proc => lambda {|d,e| + tid=d["template"] + template=e[:vm].get_template(tid) + template["NAME"] + } + }, + :stat => { + :name => "STAT", + :desc => "Actual status of the VM", + :size => 4, + :proc => lambda {|d,e| e[:vm].get_state(d) } + }, + :cpu => { + :name => "CPU", + :desc => "CPU percentage used by the VM", + :size => 3, + :proc => lambda {|d,e| d["cpu"] } + }, + :mem => { + :name => "MEM", + :desc => "Memory used by the VM", + :size => 7, + :proc => lambda {|d,e| d["memory"] } + }, + :hostname => { + :name => "HOSTNAME", + :desc => "Machine where the VM is running", + :size => 15, + :proc => lambda {|d,e| e[:vm].get_history_host(d["oid"]) } + }, + :time => { + :name => "TIME", + :desc => "Time since the VM was submitted", + :size => 11, + :proc => lambda {|d,e| e[:vm].str_running_time(d) } + }, + + :default => [:id, :name, :stat, :cpu, :mem, :hostname, :time] +} + +ShowTableHistory={ + :id => { + :name => "ID", + :desc => "ONE identifier for the VM", + :size => 4, + :proc => lambda {|d,e| d["oid"] } + }, + :seq => { + :name => "SEQ", + :desc => "Sequence number", + :size => 3, + :proc => lambda {|d,e| d["seq"] } + }, + :hostname => { + :name => "HOSTNAME", + :desc => "Name of the host where the VM was submited", + :size => 15, + :proc => lambda {|d,e| d["hostname"] } + }, + :stime => { + :name => "STIME", + :desc => "Start time", + :size => 14, + :proc => lambda {|d,e| + t=Time.at(d["stime"].to_i) + t.strftime("%m/%d %H:%M:%S") + } + }, + :etime => { + :name => "ETIME", + :desc => "End time", + :size => 14, + :proc => lambda {|d,e| + if d["etime"].to_i==0 + "--" + else + t=Time.at(d["etime"].to_i) + t.strftime("%m/%d %H:%M:%S") + end + } + }, + :time => { + :name => "TIME", + :desc => "Total time", + :size => 11, + :proc => lambda {|d,e| e[:vm].str_running_time(d) } + }, + :reason => { + :name => "REASON", + :desc => "Reason for state change", + :size => "6", + :proc => lambda {|d,e| e[:vm].get_reason(d) } + }, + + :default => [:id, :seq, :hostname, :stime, :etime, :time, :reason] +} + +class VmShow + + def initialize(vm) + @vm=vm + @table=ShowTable.new(ShowTableVM, :vm => @vm) + @table_history=ShowTable.new(ShowTableHistory, :vm => @vm) + end + + def close + end + + def header_vm_small + scr_bold + scr_underline + puts @table.header_str + scr_restore + end + + def header_history_small + scr_bold + scr_underline + puts @table_history.header_str + scr_restore + 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]] + puts str % ["LCM_STATE", ONE::LCM_STATE[data["lcm_state"].to_i]] + 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}.include? key + } + end + + def list_short(options=nil) + res=@vm.get_vms(:where => "state <> 6") + if options + @table.columns=options[:columns] if options[:columns] + end + + if res[0] + 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"] + else + result=res + end + 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 + + def list_vm_history(id, 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, options) + else + puts @table_history.data_str(res) + end + + result + else + result=res + end + end + + def list_vm_history_array(ids, options=nil) + res=[false, "No VMs found"] + ids.each {|id| + puts "History for VM #{id}" + puts + res=list_vm_history(id, 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) + } + res + end +end + + +########################## +## COMMAND LINE PARSING ## +########################## + +class OnevmParse < CommandParse + + COMMANDS_HELP=<<-EOT +Commands: + +* submit (Submits a new virtual machine, adding it to the ONE VM pool) + onevm submit