mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-24 02:03:52 +03:00
feature #1483: Add a separated action VM pool
This commit is contained in:
parent
59f4331b05
commit
2391713df0
@ -19,23 +19,21 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace one_util
|
||||
{
|
||||
string& toupper(string& st)
|
||||
inline string& toupper(string& st)
|
||||
{
|
||||
transform(st.begin(),st.end(),st.begin(),(int(*)(int))std::toupper);
|
||||
return st;
|
||||
};
|
||||
|
||||
string& tolower(string& st)
|
||||
inline string& tolower(string& st)
|
||||
{
|
||||
transform(st.begin(),st.end(),st.begin(),(int(*)(int))std::tolower);
|
||||
return st;
|
||||
};
|
||||
|
||||
string log_time(time_t the_time)
|
||||
inline string log_time(time_t the_time)
|
||||
{
|
||||
char time_str[26];
|
||||
|
||||
@ -50,11 +48,10 @@ namespace one_util
|
||||
return string(time_str);
|
||||
};
|
||||
|
||||
string log_time()
|
||||
inline string log_time()
|
||||
{
|
||||
return log_time( time(0) );
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif /* UTIL_H_ */
|
||||
|
@ -50,6 +50,7 @@ protected:
|
||||
hpool(0),
|
||||
clpool(0),
|
||||
vmpool(0),
|
||||
vmapool(0),
|
||||
acls(0),
|
||||
timer(0),
|
||||
url(""),
|
||||
@ -79,6 +80,11 @@ protected:
|
||||
delete vmpool;
|
||||
}
|
||||
|
||||
if ( vmapool != 0)
|
||||
{
|
||||
delete vmapool;
|
||||
}
|
||||
|
||||
if ( acls != 0)
|
||||
{
|
||||
delete acls;
|
||||
@ -94,11 +100,13 @@ protected:
|
||||
// Pools
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
HostPoolXML * hpool;
|
||||
ClusterPoolXML * clpool;
|
||||
VirtualMachinePoolXML * vmpool;
|
||||
HostPoolXML * hpool;
|
||||
ClusterPoolXML * clpool;
|
||||
|
||||
AclXML * acls;
|
||||
VirtualMachinePoolXML * vmpool;
|
||||
VirtualMachineActionsPoolXML* vmapool;
|
||||
|
||||
AclXML * acls;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Scheduler Policies
|
||||
@ -134,7 +142,7 @@ protected:
|
||||
virtual int set_up_pools();
|
||||
|
||||
|
||||
virtual int scheduled_actions();
|
||||
virtual int do_scheduled_actions();
|
||||
|
||||
private:
|
||||
Scheduler(Scheduler const&){};
|
||||
@ -143,7 +151,6 @@ private:
|
||||
|
||||
friend void * scheduler_action_loop(void *arg);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Scheduling Policies
|
||||
// ---------------------------------------------------------------
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
bool _live_resched):
|
||||
PoolXML(client, machines_limit), live_resched(_live_resched){};
|
||||
|
||||
~VirtualMachinePoolXML(){};
|
||||
virtual ~VirtualMachinePoolXML(){};
|
||||
|
||||
/**
|
||||
* Retrieves the pending and rescheduling VMs
|
||||
@ -43,15 +43,6 @@ public:
|
||||
*/
|
||||
int set_up();
|
||||
|
||||
/**
|
||||
* Retrieves the VMs with scheduled actions
|
||||
*
|
||||
* @return 0 on success
|
||||
* -1 on error
|
||||
* -2 if no VMs need to be scheduled
|
||||
*/
|
||||
int set_up_actions();
|
||||
|
||||
/**
|
||||
* Gets an object from the pool
|
||||
* @param oid the object unique identifier
|
||||
@ -93,6 +84,46 @@ public:
|
||||
return update(vm->get_oid(), vm->get_template(xml));
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
int get_suitable_nodes(vector<xmlNodePtr>& content)
|
||||
{
|
||||
return get_nodes("/VM_POOL/VM[STATE=1 or (LCM_STATE=3 and RESCHED=1)]",
|
||||
content);
|
||||
}
|
||||
|
||||
virtual void add_object(xmlNodePtr node);
|
||||
|
||||
virtual int load_info(xmlrpc_c::value &result);
|
||||
|
||||
/**
|
||||
* Do live migrations to resched VMs
|
||||
*/
|
||||
bool live_resched;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class VirtualMachineActionsPoolXML : public VirtualMachinePoolXML
|
||||
{
|
||||
public:
|
||||
|
||||
VirtualMachineActionsPoolXML(Client* client,
|
||||
unsigned int machines_limit):
|
||||
VirtualMachinePoolXML(client, machines_limit, false){};
|
||||
|
||||
virtual ~VirtualMachineActionsPoolXML(){};
|
||||
|
||||
/**
|
||||
* Retrieves the VMs with pending actions
|
||||
*
|
||||
* @return 0 on success
|
||||
* -1 on error
|
||||
* -2 if no VMs with pending actions
|
||||
*/
|
||||
int set_up();
|
||||
|
||||
/**
|
||||
* Calls one.vm.action
|
||||
*
|
||||
@ -106,22 +137,15 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
int get_suitable_nodes(vector<xmlNodePtr>& content);
|
||||
int get_suitable_nodes(vector<xmlNodePtr>& content)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
virtual void add_object(xmlNodePtr node);
|
||||
oss << "/VM_POOL/VM/USER_TEMPLATE/SCHED_ACTION[TIME < " << time(0)
|
||||
<< " and not(DONE > 0)]/../..";
|
||||
|
||||
virtual int load_info(xmlrpc_c::value &result);
|
||||
|
||||
/**
|
||||
* Do live migrations to resched VMs
|
||||
*/
|
||||
bool live_resched;
|
||||
|
||||
/**
|
||||
* True to retrieve pending/resched VMs, false to get VMs with scheduled
|
||||
* actions
|
||||
*/
|
||||
bool retrieve_pending;
|
||||
return get_nodes(oss.str().c_str(), content);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* VM_POOL_XML_H_ */
|
||||
|
@ -125,14 +125,35 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a the VM Template
|
||||
* Returns the scheduled actions of the VM
|
||||
*
|
||||
* @return A pointer to the VM Template (not to a copy)
|
||||
* @param attributes to hold the VM actions
|
||||
*/
|
||||
VirtualMachineTemplate* get_template()
|
||||
void get_actions(vector<Attribute *>& attributes) const
|
||||
{
|
||||
return vm_template;
|
||||
};
|
||||
attributes.clear();
|
||||
|
||||
vm_template->remove("SCHED_ACTION", attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an attribute in the VM Template, it must be allocated in the heap
|
||||
*
|
||||
* @param attributes to hold the VM actions
|
||||
*/
|
||||
void set_attribute(Attribute* att)
|
||||
{
|
||||
return vm_template->set(att);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the action to be performed and returns the corresponding XML-RPC
|
||||
* method name.
|
||||
* @param action_st, the action to be performed. The XML-RPC name is
|
||||
* returned here
|
||||
* @return 0 on success.
|
||||
*/
|
||||
static int parse_action_name(string& action_st);
|
||||
|
||||
/**
|
||||
* Function to write a Virtual Machine in an output stream
|
||||
|
@ -22,8 +22,6 @@ int VirtualMachinePoolXML::set_up()
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
retrieve_pending = true;
|
||||
|
||||
rc = PoolXML::set_up();
|
||||
|
||||
if ( rc == 0 )
|
||||
@ -52,63 +50,6 @@ int VirtualMachinePoolXML::set_up()
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachinePoolXML::set_up_actions()
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
retrieve_pending = false;
|
||||
|
||||
rc = PoolXML::set_up();
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
if (objects.empty())
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
oss.str("");
|
||||
oss << "VMs with scheduled actions:" << endl;
|
||||
|
||||
map<int,ObjectXML*>::iterator it;
|
||||
|
||||
for (it=objects.begin();it!=objects.end();it++)
|
||||
{
|
||||
oss << " " << it->first;
|
||||
}
|
||||
|
||||
NebulaLog::log("VM",Log::DEBUG,oss);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachinePoolXML::get_suitable_nodes(vector<xmlNodePtr>& content)
|
||||
{
|
||||
if (retrieve_pending)
|
||||
{
|
||||
return get_nodes(
|
||||
"/VM_POOL/VM[STATE=1 or (LCM_STATE=3 and RESCHED=1)]",
|
||||
content);
|
||||
}
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
oss << "/VM_POOL/VM/USER_TEMPLATE/SCHED_ACTION[TIME < " << time(0)
|
||||
<< " and not(DONE > 0)]/../..";
|
||||
|
||||
return get_nodes(
|
||||
oss.str().c_str(),
|
||||
content);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachinePoolXML::add_object(xmlNodePtr node)
|
||||
{
|
||||
if ( node == 0 || node->children == 0 || node->children->next==0 )
|
||||
@ -268,11 +209,42 @@ int VirtualMachinePoolXML::update(int vid, const string &st) const
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachinePoolXML::action(
|
||||
int VirtualMachineActionsPoolXML::set_up()
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
rc = PoolXML::set_up();
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
if (objects.empty())
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
oss.str("");
|
||||
oss << "VMs with scheduled actions:" << endl;
|
||||
|
||||
map<int,ObjectXML*>::iterator it;
|
||||
|
||||
for (it=objects.begin();it!=objects.end();it++)
|
||||
{
|
||||
oss << " " << it->first;
|
||||
}
|
||||
|
||||
NebulaLog::log("VM",Log::DEBUG,oss);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachineActionsPoolXML::action(
|
||||
int vid,
|
||||
const string& action,
|
||||
string& error_msg) const
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "VirtualMachineXML.h"
|
||||
#include "Util.h"
|
||||
|
||||
void VirtualMachineXML::init_attributes()
|
||||
{
|
||||
@ -265,21 +266,42 @@ void VirtualMachineXML::log(const string &st)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ostringstream oss;
|
||||
|
||||
char str[26];
|
||||
time_t the_time = time(NULL);
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
#ifdef SOLARIS
|
||||
ctime_r(&(the_time),str,sizeof(char)*26);
|
||||
#else
|
||||
ctime_r(&(the_time),str);
|
||||
#endif
|
||||
|
||||
str[24] = '\0'; // Get rid of final enter character
|
||||
|
||||
oss << str << " : " << st;
|
||||
oss << one_util::log_time(time(0)) << " : " << st;
|
||||
|
||||
vm_template->replace("SCHED_MESSAGE", oss.str());
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachineXML::parse_action_name(string& action_st)
|
||||
{
|
||||
one_util::tolower(action_st);
|
||||
|
||||
// onevm delete command uses the xml-rpc finalize action
|
||||
if (action_st == "delete")
|
||||
{
|
||||
action_st = "finalize";
|
||||
}
|
||||
|
||||
if ( action_st != "shutdown"
|
||||
&& action_st != "hold"
|
||||
&& action_st != "release"
|
||||
&& action_st != "stop"
|
||||
&& action_st != "cancel"
|
||||
&& action_st != "suspend"
|
||||
&& action_st != "resume"
|
||||
&& action_st != "restart"
|
||||
&& action_st != "resubmit"
|
||||
&& action_st != "reboot"
|
||||
&& action_st != "reset"
|
||||
&& action_st != "poweroff"
|
||||
&& action_st != "finalize")
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
@ -180,6 +180,8 @@ void Scheduler::start()
|
||||
vmpool = new VirtualMachinePoolXML(client,
|
||||
machines_limit,
|
||||
(live_rescheds == 1));
|
||||
vmapool= new VirtualMachineActionsPoolXML(client, machines_limit);
|
||||
|
||||
acls = new AclXML(client);
|
||||
|
||||
// -----------------------------------------------------------
|
||||
@ -624,20 +626,11 @@ void Scheduler::dispatch()
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int Scheduler::scheduled_actions()
|
||||
int Scheduler::do_scheduled_actions()
|
||||
{
|
||||
int rc = vmpool->set_up_actions();
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
VirtualMachineXML* vm;
|
||||
VirtualMachineTemplate* vm_template;
|
||||
|
||||
vector<string> v_st;
|
||||
|
||||
const map<int, ObjectXML*> vms = vmapool->get_objects();
|
||||
map<int, ObjectXML*>::const_iterator vm_it;
|
||||
|
||||
vector<Attribute *> attributes;
|
||||
@ -645,28 +638,23 @@ int Scheduler::scheduled_actions()
|
||||
|
||||
VectorAttribute* vatt;
|
||||
|
||||
time_t the_time = time(0);
|
||||
int action_time;
|
||||
int done_time;
|
||||
int has_time;
|
||||
int has_done;
|
||||
|
||||
int action_time, done_time, has_time, has_done;
|
||||
string action_st, error_msg;
|
||||
|
||||
ostringstream oss;
|
||||
ostringstream oss_aux;
|
||||
|
||||
time_t the_time = time(0);
|
||||
string time_str = one_util::log_time(the_time);
|
||||
|
||||
const map<int, ObjectXML*> vms = vmpool->get_objects();
|
||||
|
||||
for (vm_it=vms.begin(); vm_it != vms.end(); vm_it++)
|
||||
{
|
||||
vm = static_cast<VirtualMachineXML*>(vm_it->second);
|
||||
vm_template = vm->get_template();
|
||||
|
||||
attributes.clear();
|
||||
vm_template->remove("SCHED_ACTION", attributes);
|
||||
vm->get_actions(attributes);
|
||||
|
||||
// TODO: Sort actions by TIME
|
||||
|
||||
for (it=attributes.begin(); it != attributes.end(); it++)
|
||||
{
|
||||
vatt = dynamic_cast<VectorAttribute*>(*it);
|
||||
@ -676,46 +664,26 @@ int Scheduler::scheduled_actions()
|
||||
continue;
|
||||
}
|
||||
|
||||
has_time = vatt->vector_value("TIME", action_time);
|
||||
has_done = vatt->vector_value("DONE", done_time);
|
||||
|
||||
has_time = vatt->vector_value("TIME", action_time);
|
||||
has_done = vatt->vector_value("DONE", done_time);
|
||||
action_st = vatt->vector_value("ACTION");
|
||||
|
||||
one_util::tolower(action_st);
|
||||
|
||||
if (has_time == 0 && has_done == -1 && action_time < the_time)
|
||||
{
|
||||
oss.str("");
|
||||
ostringstream oss;
|
||||
|
||||
// onevm delete command uses the xml-rpc finalize action
|
||||
if (action_st == "delete")
|
||||
{
|
||||
action_st = "finalize";
|
||||
}
|
||||
int rc = VirtualMachineXML::parse_action_name(action_st);
|
||||
|
||||
oss << "Executing action '" << action_st << "' for VM "
|
||||
<< vm->get_oid() << " : ";
|
||||
|
||||
if ( action_st != "shutdown"
|
||||
&& action_st != "hold"
|
||||
&& action_st != "release"
|
||||
&& action_st != "stop"
|
||||
&& action_st != "cancel"
|
||||
&& action_st != "suspend"
|
||||
&& action_st != "resume"
|
||||
&& action_st != "restart"
|
||||
&& action_st != "resubmit"
|
||||
&& action_st != "reboot"
|
||||
&& action_st != "reset"
|
||||
&& action_st != "poweroff"
|
||||
&& action_st != "finalize")
|
||||
if ( rc != 0 )
|
||||
{
|
||||
error_msg = "This action is not supported.";
|
||||
rc = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = vmpool->action(vm->get_oid(), action_st, error_msg);
|
||||
rc = vmapool->action(vm->get_oid(), action_st, error_msg);
|
||||
}
|
||||
|
||||
if (rc == 0)
|
||||
@ -727,7 +695,8 @@ int Scheduler::scheduled_actions()
|
||||
}
|
||||
else
|
||||
{
|
||||
oss_aux.str("");
|
||||
ostringstream oss_aux;
|
||||
|
||||
oss_aux << time_str << " : " << error_msg;
|
||||
|
||||
vatt->replace("MESSAGE", oss_aux.str());
|
||||
@ -735,13 +704,13 @@ int Scheduler::scheduled_actions()
|
||||
oss << "Failure. " << error_msg;
|
||||
}
|
||||
|
||||
NebulaLog::log("VM",Log::INFO,oss);
|
||||
NebulaLog::log("VM", Log::INFO, oss);
|
||||
|
||||
vm->set_attribute(vatt);
|
||||
|
||||
vmpool->update(vm);
|
||||
}
|
||||
|
||||
vm_template->set(vatt);
|
||||
}
|
||||
|
||||
vmpool->update(vm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -756,7 +725,12 @@ void Scheduler::do_action(const string &name, void *args)
|
||||
|
||||
if (name == ACTION_TIMER)
|
||||
{
|
||||
scheduled_actions();
|
||||
rc = vmapool->set_up();
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
do_scheduled_actions();
|
||||
}
|
||||
|
||||
rc = set_up_pools();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user