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:
parent
184bd79eaf
commit
70ce346937
@ -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
|
||||
*/
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user