1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-28 14:50:08 +03:00

F #2347: Load roles and rules in the scheduler. Helper methods to

generate requirement expressions
This commit is contained in:
Ruben S. Montero 2017-01-16 19:19:05 +01:00
parent 184bd79eaf
commit 70ce346937
9 changed files with 288 additions and 124 deletions

View File

@ -108,12 +108,20 @@ public:
/* Placement constraints */
/* ---------------------------------------------------------------------- */
/**
* Generates a string with the boolean expresion to conform the role
* policy
* Generates a string with the boolean expression to conform the role
* internal policy
* @param vm_id of the VM to generate the requirements for
* @param requirements
*/
void vm_requirements(int vm_id, std::string requirements);
void vm_role_requirements(int vm_id, std::string& requirements);
/**
* Generates a string with the boolean expression to conform an affinity
* constraint policy
* @param policy to place VMs respect to this role VMs
* @param requirements
*/
void role_requirements(Policy policy, std::string& requirements);
private:
/**
@ -145,6 +153,15 @@ public:
by_id.delete_roles();
};
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/**
* Max number of roles in a VMGroup
*/
const static int MAX_ROLES = 32;
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/**
* Function to print the VMGroupRoles into a string in XML format
* @param xml the resulting XML string
@ -173,11 +190,12 @@ public:
/**
* Generates the ids corresponding to a set of role names
* @param keys the set of names
* @param rnames string with a comma separated list of role names
* @param keyi the set of ids
*
* @return 0 if all the names were successfully translated
*/
int names_to_ids(const std::set<std::string> keys, std::set<int>& keyi);
int names_to_ids(const std::string& rnames, std::set<int>& keyi);
/**
* Adds a VM to a role
@ -220,10 +238,60 @@ public:
return by_id.get(id);
}
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/**
* Max number of roles in a VMGroup
* Iterator for the roles in the group
*/
const static int MAX_ROLES = 32;
class RoleIterator
{
public:
RoleIterator& operator=(const RoleIterator& rhs)
{
role_it = rhs.role_it;
return *this;
}
RoleIterator& operator++()
{
++role_it;
return *this;
}
bool operator!=(const RoleIterator& rhs)
{
return role_it != rhs.role_it;
}
VMGroupRole * operator*() const
{
return role_it->second;
}
RoleIterator(){};
RoleIterator(const RoleIterator& rit):role_it(rit.role_it){};
RoleIterator(const std::map<int, VMGroupRole *>::iterator& _role_it)
:role_it(_role_it){};
virtual ~RoleIterator(){};
private:
std::map<int, VMGroupRole *>::iterator role_it;
};
RoleIterator begin()
{
RoleIterator it(by_id.begin());
return it;
}
RoleIterator end()
{
RoleIterator it(by_id.end());
return it;
}
typedef class RoleIterator role_iterator;
private:
/**
@ -308,56 +376,6 @@ private:
std::map<T, VMGroupRole *> roles;
};
class RoleIterator
{
public:
RoleIterator& operator=(const RoleIterator& rhs)
{
role_it = rhs.role_it;
return *this;
}
RoleIterator& operator++()
{
++role_it;
return *this;
}
bool operator!=(const RoleIterator& rhs)
{
return role_it != rhs.role_it;
}
VMGroupRole * operator*() const
{
return role_it->second;
}
RoleIterator(){};
RoleIterator(const RoleIterator& rit):role_it(rit.role_it){};
RoleIterator(const std::map<int, VMGroupRole *>::iterator& _role_it)
:role_it(_role_it){};
virtual ~RoleIterator(){};
private:
std::map<int, VMGroupRole *>::iterator role_it;
};
RoleIterator begin()
{
RoleIterator it(by_id.begin());
return it;
}
RoleIterator end()
{
RoleIterator it(by_id.end());
return it;
}
typedef class RoleIterator role_iterator;
/**
* The role template to store the VMGroupRole
*/

View File

@ -46,15 +46,15 @@ public:
{
int rc;
// -------------------------------------------------------------------------
// ---------------------------------------------------------------------
// Clean the pool to get updated data from OpenNebula
// -------------------------------------------------------------------------
// ---------------------------------------------------------------------
flush();
// -------------------------------------------------------------------------
// ---------------------------------------------------------------------
// Load the ids (to get an updated list of the pool)
// -------------------------------------------------------------------------
// ---------------------------------------------------------------------
xmlrpc_c::value result;
@ -124,8 +124,49 @@ public:
}
};
protected:
/**
* Gets an object and removes it from the pool. The calling function
* needs to free the object memory
* @param oid of the object
*
* @return pointer of the object 0 if not found
*/
virtual ObjectXML * erase(int oid)
{
map<int, ObjectXML *>::iterator it;
it = objects.find(oid);
if ( it == objects.end() )
{
return 0;
}
else
{
ObjectXML * obj = it->second;
objects.erase(it);
return obj;
}
}
/**
* Inserts a new object in the pool
* @param obj pointer to the XML object to be inserted
*
* @return true if the object was successfully inserted
*/
virtual bool insert(int oid, ObjectXML * obj)
{
pair<map<int, ObjectXML *>::iterator, bool> rc;
rc = objects.insert(pair<int,ObjectXML*>(oid, obj));
return rc.second;
}
protected:
// ------------------------------------------------------------------------
PoolXML(Client* client, unsigned int pool_limit = 0):ObjectXML()
@ -140,7 +181,6 @@ protected:
};
// ------------------------------------------------------------------------
/**
* Inserts a new ObjectXML into the objects map
*/
@ -156,10 +196,24 @@ protected:
*/
virtual int load_info(xmlrpc_c::value &result) = 0;
/**
* Deletes pool objects and frees resources.
*/
void flush()
{
map<int,ObjectXML*>::iterator it;
for (it=objects.begin();it!=objects.end();it++)
{
delete it->second;
}
objects.clear();
}
// ------------------------------------------------------------------------
// Attributes
// ------------------------------------------------------------------------
/**
* XML-RPC client
*/
@ -175,23 +229,6 @@ protected:
* Hash map contains the suitable [id, object] pairs.
*/
map<int, ObjectXML *> objects;
private:
/**
* Deletes pool objects and frees resources.
*/
void flush()
{
map<int,ObjectXML*>::iterator it;
for (it=objects.begin();it!=objects.end();it++)
{
delete it->second;
}
objects.clear();
}
};
#endif /* POOL_XML_H_ */

View File

@ -50,15 +50,16 @@ public:
protected:
Scheduler():
acls(0),
upool(0),
hpool(0),
clpool(0),
vmpool(0),
vmapool(0),
dspool(0),
img_dspool(0),
upool(0),
vmpool(0),
vm_roles_pool(0),
vmgpool(0),
acls(0),
vmapool(0),
timer(0),
one_xmlrpc(""),
machines_limit(0),
@ -74,6 +75,7 @@ protected:
delete clpool;
delete vmpool;
delete vm_roles_pool;
delete vmapool;
delete dspool;
@ -88,19 +90,21 @@ protected:
// ---------------------------------------------------------------
// Pools
// ---------------------------------------------------------------
AclXML * acls;
UserPoolXML * upool;
HostPoolXML * hpool;
ClusterPoolXML * clpool;
VirtualMachinePoolXML * vmpool;
VirtualMachineActionsPoolXML* vmapool;
SystemDatastorePoolXML * dspool;
ImageDatastorePoolXML * img_dspool;
UserPoolXML * upool;
ImageDatastorePoolXML * img_dspool;
VirtualMachinePoolXML * vmpool;
VirtualMachinePoolXML * vm_roles_pool;
VMGroupPoolXML * vmgpool;
AclXML * acls;
VirtualMachineActionsPoolXML* vmapool;
// ---------------------------------------------------------------
// Scheduler Policies

View File

@ -19,6 +19,7 @@
#include "ObjectXML.h"
#include "VMGroupRole.h"
#include "VMGroupRule.h"
class VMGroupXML : public ObjectXML
{
@ -39,10 +40,17 @@ public:
};
private:
// ------------------------------------------------------------------------
// VMGroup Attributes
// ------------------------------------------------------------------------
int oid;
std::string name;
VMGroupRoles roles;
VMGroupRule::rule_set rules;
void init_attributes();
};

View File

@ -84,6 +84,15 @@ public:
return update(vm->get_oid(), vm->get_template(xml));
};
/**
*
*
* */
void clear()
{
flush();
}
protected:
int get_suitable_nodes(vector<xmlNodePtr>& content)

View File

@ -18,9 +18,13 @@
void VMGroupXML::init_attributes()
{
vector<xmlNodePtr> content;
vector<xmlNodePtr> content;
std::vector<std::string> srules;
std::vector<std::string>::iterator it;
xpath(oid, "/VM_GROUP/ID", -1);
xpath(name,"/VM_GROUP/NAME", "undefined");
// VMGroup roles
get_nodes("/VM_GROUP/ROLES", content);
@ -33,5 +37,33 @@ void VMGroupXML::init_attributes()
free_nodes(content);
content.clear();
xpaths(srules, "/VM_GROUP/TEMPLATE/AFFINED");
for ( it = srules.begin() ; it != srules.end(); ++it )
{
std::set<int> id_set;
roles.names_to_ids(*it, id_set);
VMGroupRule rule(VMGroupRule::AFFINED, id_set);
rules.insert(rule);
}
rules.clear();
xpaths(srules, "/VM_GROUP/TEMPLATE/ANTI_AFFINED");
for ( it = srules.begin() ; it != srules.end(); ++it )
{
std::set<int> id_set;
roles.names_to_ids(*it, id_set);
VMGroupRule rule(VMGroupRule::ANTI_AFFINED, id_set);
rules.insert(rule);
}
};

View File

@ -308,21 +308,23 @@ void Scheduler::start()
// -------------------------------------------------------------------------
// Pools
// -------------------------------------------------------------------------
acls = new AclXML(Client::client(), zone_id);
upool = new UserPoolXML(Client::client());
hpool = new HostPoolXML(Client::client());
upool = new UserPoolXML(Client::client());
clpool = new ClusterPoolXML(Client::client());
vmpool = new VirtualMachinePoolXML(Client::client(), machines_limit,
live_rescheds==1);
vmapool = new VirtualMachineActionsPoolXML(Client::client(), machines_limit);
dspool = new SystemDatastorePoolXML(Client::client());
img_dspool = new ImageDatastorePoolXML(Client::client());
vmpool = new VirtualMachinePoolXML(Client::client(), machines_limit,
live_rescheds==1);
vm_roles_pool = new VirtualMachinePoolXML(Client::client(), machines_limit,
live_rescheds==1);
vmgpool = new VMGroupPoolXML(Client::client());
acls = new AclXML(Client::client(), zone_id);
vmapool = new VirtualMachineActionsPoolXML(Client::client(), machines_limit);
// -----------------------------------------------------------
// Load scheduler policies
@ -470,6 +472,8 @@ int Scheduler::set_up_pools()
return rc;
}
vm_roles_pool->clear();
return 0;
};

View File

@ -235,25 +235,17 @@ int VMGroup::check_rule_names(VMGroupRule::Policy policy, std::string& error)
for ( jt = affined.begin() ; jt != affined.end() ; ++jt )
{
std::set<std::string> a_set, key_set;
std::set<std::string>::iterator s_it;
std::set<int> id_set;
one_util::split_unique((*jt)->value(), ',', a_set);
for (s_it = a_set.begin(); s_it != a_set.end() ; ++s_it)
{
key_set.insert(one_util::trim(*s_it));
}
if ( roles.names_to_ids(key_set, id_set) != 0 )
if ( roles.names_to_ids((*jt)->value(), id_set) != 0 )
{
std::ostringstream oss;
oss << "Some roles used in " << aname << " attribute ("
<< (*jt)->value() << ") are not defined";
error = oss.str();
return -1;
}
}
@ -276,21 +268,11 @@ int VMGroup::get_rules(VMGroupRule::Policy policy, VMGroupRule::rule_set& rules,
for ( jt = affined.begin() ; jt != affined.end() ; ++jt )
{
std::set<std::string> a_set, key_set;
std::set<std::string>::iterator s_it;
std::set<int> id_set;
std::pair<std::set<VMGroupRule>::iterator, bool> rc;
one_util::split_unique((*jt)->value(), ',', a_set);
for (s_it = a_set.begin(); s_it != a_set.end() ; ++s_it)
{
key_set.insert(one_util::trim(*s_it));
}
roles.names_to_ids(key_set, id_set);
roles.names_to_ids((*jt)->value(), id_set);
VMGroupRule rule(policy, id_set);
@ -298,8 +280,12 @@ int VMGroup::get_rules(VMGroupRule::Policy policy, VMGroupRule::rule_set& rules,
if ( rc.second == false )
{
error_str = "Duplicated " + aname + " rule (" +
(*jt)->value() + ") detected.";
std::ostringstream oss;
oss << "Duplicated " << aname << " rule (" << (*jt)->value()
<< ") detected.";
error_str = oss.str();
return -1;
}

View File

@ -32,6 +32,7 @@ VMGroupRole::VMGroupRole(VectorAttribute *_va):va(_va)
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VMGroupRole::add_vm(int vm_id)
@ -76,6 +77,60 @@ void VMGroupRole::set_vms()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
static void affinity_requirements(int vm_id, std::string& requirements,
VMGroupRole::Policy policy, const std::set<int>& vms)
{
string op;
requirements = "";
switch(policy)
{
case VMGroupRole::AFFINED:
op = "=";
break;
case VMGroupRole::ANTI_AFFINED:
op = "!=";
break;
case VMGroupRole::NONE:
return;
}
std::ostringstream oss;
std::set<int>::const_iterator it;
for ( it = vms.begin(); it != vms.end(); ++it )
{
if ( vm_id == -1 || vm_id != *it )
{
if ( it != vms.begin() )
{
oss << " & ";
}
oss << "( CURRENT_VMS " << op << " " << *it << ") ";
}
}
requirements = oss.str();
}
void VMGroupRole::vm_role_requirements(int vm_id, std::string& requirements)
{
affinity_requirements(vm_id, requirements, policy(), vms);
}
void VMGroupRole::role_requirements(Policy policy, std::string& requirements)
{
affinity_requirements(-1, requirements, policy, vms);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* VMGroupRoles */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VMGroupRoles::from_xml_node(const xmlNodePtr node)
{
std::vector<VectorAttribute *> roles;
@ -125,6 +180,7 @@ int VMGroupRoles::from_xml_node(const xmlNodePtr node)
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VMGroupRoles::add_role(VectorAttribute * vrole, string& error)
@ -207,6 +263,9 @@ int VMGroupRoles::del_vm(const std::string& role_name, int vmid)
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VMGroupRoles::vm_size()
{
int total = 0;
@ -222,12 +281,19 @@ int VMGroupRoles::vm_size()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VMGroupRoles::names_to_ids(const std::set<std::string> keys,
std::set<int>& keyi)
int VMGroupRoles::names_to_ids(const std::string& rnames, std::set<int>& keyi)
{
std::set<std::string> a_set, key_set;
std::set<std::string>::iterator it;
for ( it = keys.begin(); it != keys.end(); ++it )
one_util::split_unique(rnames, ',', a_set);
for ( it = a_set.begin(); it != a_set.end() ; ++it )
{
key_set.insert(one_util::trim(*it));
}
for ( it = key_set.begin(); it != key_set.end(); ++it )
{
VMGroupRole *r = by_name.get(*it);