1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-26 06:50:09 +03:00

feature #846: Add more message types. Template is loaded in the VirtualMachineXML object. OpenNebula API calls are always made through VirtualMachinePoolXML.

This commit is contained in:
Ruben S. Montero 2013-02-01 02:23:01 +01:00
parent d51444dc23
commit 1995b7a14c
6 changed files with 166 additions and 141 deletions

View File

@ -58,10 +58,28 @@ public:
* Dispatch a VM to the given host
* @param vid the VM id
* @param hid the id of the target host
* @param resched the machine is going to be rescheduled
* @param resched the machine is going to be rescheduled
*/
int dispatch(int vid, int hid, bool resched) const;
/**
* Update the VM template
* @param vid the VM id
* @param st the template string
*/
int update(int vid, const string &st) const;
/**
* Update the VM template
* @param the VM
*/
int update(VirtualMachineXML * vm) const
{
string xml;
return update(vm->get_oid(), vm->get_template(xml));
};
protected:
int get_suitable_nodes(vector<xmlNodePtr>& content)

View File

@ -22,6 +22,7 @@
#include "ObjectXML.h"
#include "HostPoolXML.h"
#include "VirtualMachineTemplate.h"
using namespace std;
@ -29,16 +30,14 @@ class VirtualMachineXML : public ObjectXML
{
public:
VirtualMachineXML(Client * client, const string &xml_doc):
ObjectXML(xml_doc),
client(client)
VirtualMachineXML(const string &xml_doc):
ObjectXML(xml_doc)
{
init_attributes();
};
VirtualMachineXML(Client * client, const xmlNodePtr node):
ObjectXML(node),
client(client)
VirtualMachineXML(const xmlNodePtr node):
ObjectXML(node)
{
init_attributes();
}
@ -107,6 +106,24 @@ public:
return requirements;
};
/**
* Get the user template of the VM
* @return the template as a XML string
*/
string& get_template(string& xml_str)
{
if (vm_template != 0)
{
vm_template->to_xml(xml_str);
}
else
{
xml_str = "";
}
return xml_str;
}
/**
* Function to write a Virtual Machine in an output stream
*/
@ -134,28 +151,11 @@ public:
};
/**
* Adds a message to the VM's USER_TEMPLATE/SCHEDULER_MESSAGE attribute
* @param st Message to set
* Adds a message to the VM's USER_TEMPLATE/SCHED_MESSAGE attribute
* @param st Message to set
*/
void log(const string &st);
/**
* Clears the VM's USER_TEMPLATE/SCHEDULER_MESSAGE attribute
*/
void clear_log()
{
log("");
};
/**
* Replaces the VM USER_TEMPLATE contents
*
* @param st New template contents
*
* @return 0 on success, -1 otherwise
*/
int update(const string &st);
protected:
/**
@ -213,9 +213,9 @@ protected:
vector<VirtualMachineXML::Host *> hosts;
/**
* XML-RPC client
* The VM user template
*/
Client * client;
VirtualMachineTemplate * vm_template;
};
#endif /* VM_XML_H_ */

View File

@ -59,7 +59,7 @@ void VirtualMachinePoolXML::add_object(xmlNodePtr node)
return;
}
VirtualMachineXML* vm = new VirtualMachineXML(client, node);
VirtualMachineXML* vm = new VirtualMachineXML(node);
objects.insert(pair<int,ObjectXML*>(vm->get_oid(),vm));
}
@ -96,7 +96,6 @@ int VirtualMachinePoolXML::load_info(xmlrpc_c::value &result)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachinePoolXML::dispatch(int vid, int hid, bool resched) const
{
ostringstream oss;
@ -108,7 +107,7 @@ int VirtualMachinePoolXML::dispatch(int vid, int hid, bool resched) const
}
else
{
oss << "Dispatching ";
oss << "Dispatching ";
}
oss << "virtual machine " << vid << " to host " << hid;
@ -173,3 +172,40 @@ int VirtualMachinePoolXML::dispatch(int vid, int hid, bool resched) const
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachinePoolXML::update(int vid, const string &st) const
{
xmlrpc_c::value result;
bool success;
try
{
client->call( client->get_endpoint(), // serverUrl
"one.vm.update", // methodName
"sis", // arguments format
&result, // resultP
client->get_oneauth().c_str(), // argument
vid, // VM ID
st.c_str() // Template
);
}
catch (exception const& e)
{
return -1;
}
vector<xmlrpc_c::value> values =
xmlrpc_c::value_array(result).vectorValueValue();
success = xmlrpc_c::value_boolean(values[0]);
if (!success)
{
return -1;
}
return 0;
}

View File

@ -17,17 +17,18 @@
#include <algorithm>
#include "VirtualMachineXML.h"
#include "VirtualMachineTemplate.h"
void VirtualMachineXML::init_attributes()
{
vector<string> result;
vector<string> result;
vector<xmlNodePtr> nodes;
oid = atoi(((*this)["/VM/ID"] )[0].c_str());
uid = atoi(((*this)["/VM/UID"])[0].c_str());
gid = atoi(((*this)["/VM/GID"])[0].c_str());
result = ((*this)["/VM/TEMPLATE/MEMORY"]);
if (result.size() > 0)
{
memory = atoi(result[0].c_str());
@ -38,6 +39,7 @@ void VirtualMachineXML::init_attributes()
}
result = ((*this)["/VM/TEMPLATE/CPU"]);
if (result.size() > 0)
{
istringstream iss;
@ -50,6 +52,7 @@ void VirtualMachineXML::init_attributes()
}
result = ((*this)["/VM/TEMPLATE/RANK"]);
if (result.size() > 0)
{
rank = result[0];
@ -60,6 +63,7 @@ void VirtualMachineXML::init_attributes()
}
result = ((*this)["/VM/TEMPLATE/REQUIREMENTS"]);
if (result.size() > 0)
{
requirements = result[0];
@ -67,11 +71,11 @@ void VirtualMachineXML::init_attributes()
else
{
requirements = "";
}
}
result = ((*this)["/VM/HISTORY_RECORDS/HISTORY/HID"]);
if (result.size() > 0)
if (result.size() > 0)
{
hid = atoi(result[0].c_str());
}
@ -89,7 +93,20 @@ void VirtualMachineXML::init_attributes()
else
{
resched = 0;
}
}
if (get_nodes("/VM/USER_TEMPLATE", nodes) > 0)
{
vm_template = new VirtualMachineTemplate;
vm_template->from_xml_node(nodes[0]);
free_nodes(nodes);
}
else
{
vm_template = 0;
}
}
/* -------------------------------------------------------------------------- */
@ -105,6 +122,11 @@ VirtualMachineXML::~VirtualMachineXML()
}
hosts.clear();
if (vm_template != 0)
{
delete vm_template;
}
}
/* -------------------------------------------------------------------------- */
@ -118,7 +140,7 @@ void VirtualMachineXML::add_host(int host_id)
ss = new VirtualMachineXML::Host(host_id);
hosts.push_back(ss);
hosts.push_back(ss);
}
}
@ -229,95 +251,25 @@ void VirtualMachineXML::get_requirements (int& cpu, int& memory, int& disk)
void VirtualMachineXML::log(const string &st)
{
vector<xmlNodePtr> nodes;
ostringstream oss;
string xml_st;
int rc = get_nodes("/VM/USER_TEMPLATE", nodes);
if (rc > 0)
if (vm_template == 0 || st.empty())
{
VirtualMachineTemplate vm_template;
vm_template.from_xml_node(nodes[0]);
return;
}
free_nodes(nodes);
char str[26];
time_t the_time = time(NULL);
if (!st.empty())
{
char str[26];
time_t the_time = time(NULL);
ostringstream oss;
#ifdef SOLARIS
ctime_r(&(the_time),str,sizeof(char)*26);
ctime_r(&(the_time),str,sizeof(char)*26);
#else
ctime_r(&(the_time),str);
ctime_r(&(the_time),str);
#endif
// Get rid of final enter character
str[24] = '\0';
oss << str << ": " << st;
str[24] = '\0'; // Get rid of final enter character
vm_template.replace("SCHEDULER_MESSAGE", oss.str());
oss << str << " : " << st;
update(vm_template.to_xml(xml_st));
}
else
{
vector<Attribute*> attr;
int num = vm_template.remove("SCHEDULER_MESSAGE", attr);
for (int i = 0; i < num ; i++)
{
if (attr[i] != 0)
{
delete attr[i];
}
}
if (num > 0)
{
update(vm_template.to_xml(xml_st));
}
}
}
vm_template->replace("SCHED_MESSAGE", oss.str());
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachineXML::update(const string &st)
{
xmlrpc_c::value result;
bool success;
try
{
client->call( client->get_endpoint(), // serverUrl
"one.vm.update", // methodName
"sis", // arguments format
&result, // resultP
client->get_oneauth().c_str(), // argument
oid,
st.c_str()
);
}
catch (exception const& e)
{
return -1;
}
vector<xmlrpc_c::value> values =
xmlrpc_c::value_array(result).vectorValueValue();
success = xmlrpc_c::value_boolean( values[0] );
if (!success)
{
return -1;
}
return 0;
}

View File

@ -128,7 +128,7 @@ void Scheduler::start()
conf.get("ONED_PORT", oned_port);
oss.str("");
oss << "http://localhost:" << oned_port << "/RPC2";
oss << "http://localhost:" << oned_port << "/RPC2";
url = oss.str();
conf.get("SCHED_INTERVAL", timer);
@ -142,9 +142,9 @@ void Scheduler::start()
conf.get("LIVE_RESCHEDS", live_rescheds);
conf.get("HYPERVISOR_MEM", hypervisor_mem);
oss.str("");
oss << "Starting Scheduler Daemon" << endl;
oss << "----------------------------------------\n";
oss << " Scheduler Configuration File \n";
@ -176,7 +176,7 @@ void Scheduler::start()
hpool = new HostPoolXML(client, hypervisor_mem);
clpool = new ClusterPoolXML(client);
vmpool = new VirtualMachinePoolXML(client,
vmpool = new VirtualMachinePoolXML(client,
machines_limit,
(live_rescheds == 1));
acls = new AclXML(client);
@ -340,7 +340,8 @@ void Scheduler::match()
int gid;
int n_hosts;
int n_matched;
bool req_error;
int n_auth;
int n_error;
string reqs;
@ -368,7 +369,8 @@ void Scheduler::match()
n_hosts = 0;
n_matched = 0;
req_error = false;
n_auth = 0;
n_error = 0;
for (h_it=hosts.begin(), matched=false; h_it != hosts.end(); h_it++)
{
@ -410,6 +412,8 @@ void Scheduler::match()
continue;
}
n_auth++;
// -----------------------------------------------------------------
// Evaluate VM requirements
// -----------------------------------------------------------------
@ -424,7 +428,7 @@ void Scheduler::match()
ostringstream error_msg;
matched = false;
req_error = true;
n_error++;
error_msg << "Error evaluating REQUIREMENTS expression: '"
<< reqs << "', error: " << error;
@ -443,7 +447,7 @@ void Scheduler::match()
{
matched = true;
}
if ( matched == false )
{
ostringstream oss;
@ -480,16 +484,33 @@ void Scheduler::match()
}
}
if (n_hosts == 0 && !req_error)
// ---------------------------------------------------------------------
// Log scheduling errors to VM user if any
// ---------------------------------------------------------------------
if (n_hosts == 0) //No hosts assigned, let's see why
{
if (n_matched == 0)
if (n_error == 0) //No syntax error
{
vm->log("The Scheduler could not find any Host that meets the requirements expression");
}
else
{
vm->log("The Scheduler could not find any Host with enough capacity to deploy the VM");
if (hosts.size() == 0)
{
vm->log("No hosts enabled to run VMs");
}
else if (n_auth == 0)
{
vm->log("User is not authorized to use any host");
}
else if (n_matched == 0)
{
vm->log("No host meets the REQUIREMENTS expression");
}
else
{
vm->log("No host with enough capacity to deploy the VM");
}
}
vmpool->update(vm);
}
}
}
@ -591,8 +612,6 @@ void Scheduler::dispatch()
{
rc = vmpool->dispatch(vm_it->first, hid, vm->is_resched());
vm->clear_log();
if (rc == 0 && !vm->is_resched())
{
dispatched_vms++;

View File

@ -73,19 +73,19 @@ void SchedulerTemplate::set_conf_default()
attribute = new SingleAttribute("MAX_HOST",value);
conf_default.insert(make_pair(attribute->name(),attribute));
//LIVE_RESCHEDS
value = "0";
attribute = new SingleAttribute("LIVE_RESCHEDS",value);
conf_default.insert(make_pair(attribute->name(),attribute));
//DEFAULT_SCHED
//DEFAULT_SCHED
map<string,string> vvalue;
vvalue.insert(make_pair("POLICY","1"));
vattribute = new VectorAttribute("DEFAULT_SCHED",vvalue);
conf_default.insert(make_pair(attribute->name(),vattribute));
conf_default.insert(make_pair(vattribute->name(),vattribute));
//HYPERVISOR_MEM
value = "0.1";
@ -105,7 +105,7 @@ string SchedulerTemplate::get_policy() const
istringstream iss;
vector<const Attribute *> vsched;
const VectorAttribute * sched;
const VectorAttribute * sched;
get("DEFAULT_SCHED", vsched);
@ -123,7 +123,7 @@ string SchedulerTemplate::get_policy() const
case 1: //Striping
rank = "- RUNNING_VMS";
break;
case 2: //Load-aware
rank = "FREE_CPU";
break;
@ -137,4 +137,4 @@ string SchedulerTemplate::get_policy() const
}
return rank;
}
}