diff --git a/include/VMGroupRule.h b/include/VMGroupRule.h index 5bdb0840c5..edb44a5eee 100644 --- a/include/VMGroupRule.h +++ b/include/VMGroupRule.h @@ -47,27 +47,7 @@ public: /** * @return policy name */ - static std::string policy_to_s(Policy policy) - { - std::string name; - - switch(policy) - { - case AFFINED: - name="AFFINED"; - break; - - case ANTI_AFFINED: - name="ANTI_AFFINED"; - break; - - case NONE: - name="NONE"; - break; - } - - return name; - } + static std::string policy_to_s(Policy policy); /** * A specialized set for rules diff --git a/src/scheduler/include/VMGroupXML.h b/src/scheduler/include/VMGroupXML.h index ed3d9ca29b..5ce001f1d2 100644 --- a/src/scheduler/include/VMGroupXML.h +++ b/src/scheduler/include/VMGroupXML.h @@ -18,6 +18,7 @@ #define VMGROUP_XML_H_ #include "ObjectXML.h" +#include "VMGroupRole.h" class VMGroupXML : public ObjectXML { @@ -40,6 +41,8 @@ public: private: int oid; + VMGroupRoles roles; + void init_attributes(); }; diff --git a/src/scheduler/src/pool/VMGroupXML.cc b/src/scheduler/src/pool/VMGroupXML.cc index e4f962a832..b1cdcec2b5 100644 --- a/src/scheduler/src/pool/VMGroupXML.cc +++ b/src/scheduler/src/pool/VMGroupXML.cc @@ -18,6 +18,20 @@ void VMGroupXML::init_attributes() { - xpath(oid, "/VM_GROUP/ID", -1); + vector content; + + xpath(oid, "/VM_GROUP/ID", -1); + + // VMGroup roles + get_nodes("/VM_GROUP/ROLES", content); + + if (!content.empty()) + { + roles.from_xml_node(content[0]); + } + + free_nodes(content); + + content.clear(); }; diff --git a/src/scheduler/src/sched/SConstruct b/src/scheduler/src/sched/SConstruct index 6518152b2e..72dcda9357 100644 --- a/src/scheduler/src/sched/SConstruct +++ b/src/scheduler/src/sched/SConstruct @@ -30,6 +30,7 @@ sched_env.StaticLibrary(lib_name, source_files) sched_env.Prepend(LIBS=[ 'scheduler_sched', 'scheduler_pool', + 'nebula_vmgroup_roles', 'nebula_log', 'nebula_client', 'nebula_acl', diff --git a/src/vm_group/SConstruct b/src/vm_group/SConstruct index 89900acafe..dc6f285495 100644 --- a/src/vm_group/SConstruct +++ b/src/vm_group/SConstruct @@ -23,8 +23,20 @@ lib_name='nebula_vmgroup' # Sources to generate the library source_files=[ 'VMGroupPool.cc', - 'VMGroup.cc' + 'VMGroup.cc', + 'VMGroupRole.cc', + 'VMGroupRule.cc' ] # Build library env.StaticLibrary(lib_name, source_files) + +# Stripped library for scheduler with role logic +lib_name='nebula_vmgroup_roles' + +source_files=[ + 'VMGroupRole.cc', + 'VMGroupRule.cc' +] + +env.StaticLibrary(lib_name, source_files) diff --git a/src/vm_group/VMGroup.cc b/src/vm_group/VMGroup.cc index 0b411bdacb..6c7cfa1ee9 100644 --- a/src/vm_group/VMGroup.cc +++ b/src/vm_group/VMGroup.cc @@ -18,261 +18,6 @@ #include "VMGroupRole.h" #include "VMGroupRule.h" -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ -/* VMGroupRule */ -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -bool VMGroupRule::compatible(VMGroupRule::rule_set& affined, - VMGroupRule::rule_set& anti, VMGroupRule& err) -{ - VMGroupRule ta, taa; - - rule_set::iterator it; - - for (it=affined.begin() ; it != affined.end(); ++it) - { - ta |= *it; - } - - for (it=anti.begin() ; it != anti.end(); ++it) - { - taa |= *it; - } - - err = ta & taa; - - return err.none(); -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ -/* VMGroupRole */ -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -VMGroupRole::VMGroupRole(VectorAttribute *_va):va(_va) -{ - string vms_str = va->vector_value("VMS"); - - if ( !vms_str.empty() ) - { - one_util::split_unique(vms_str, ',', vms); - } -} - -/* -------------------------------------------------------------------------- */ - -void VMGroupRole::add_vm(int vm_id) -{ - std::pair::iterator, bool> rc; - - rc = vms.insert(vm_id); - - if ( rc.second == false ) - { - return; - } - - set_vms(); -} - -void VMGroupRole::del_vm(int vm_id) -{ - size_t rc = vms.erase(vm_id); - - if ( rc == 0 ) - { - return; - } - - set_vms(); -} - -void VMGroupRole::set_vms() -{ - if ( vms.empty() ) - { - va->remove("VMS"); - return; - } - - std::string vms_str = one_util::join(vms.begin(), vms.end(), ','); - - va->replace("VMS", vms_str); -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int VMGroupRoles::from_xml_node(const xmlNodePtr node) -{ - std::vector roles; - std::vector::iterator it; - - if ( roles_template.from_xml_node(node) == -1 ) - { - return -1; - } - - roles_template.get("ROLE", roles); - - for (it = roles.begin(); it != roles.end(); ++it) - { - std::string rname = (*it)->vector_value("NAME"); - - int rid; - int rc = (*it)->vector_value("ID", rid); - - if ( rname.empty() || rc == -1 ) - { - return -1; - } - - if ( rid >= next_role ) - { - next_role = rid + 1; - } - - VMGroupRole * role = new VMGroupRole((*it)); - - if ( by_id.insert(rid, role) == false ) - { - delete role; - return -1; - } - - if ( by_name.insert(rname, role) == false ) - { - by_id.erase(rid); - - delete role; - return -1; - } - } - - return 0; -} - -/* -------------------------------------------------------------------------- */ - -int VMGroupRoles::add_role(VectorAttribute * vrole, string& error) -{ - std::string rname = vrole->vector_value("NAME"); - - if ( rname.empty() ) - { - error = "Missing NAME in VM group role"; - return -1; - } - - // Remove internal attributes before inserting - vrole->replace("ID", next_role); - - vrole->remove("VMS"); - - VMGroupRole * role = new VMGroupRole(vrole); - - if ( by_id.insert(next_role, role) == false ) - { - delete role; - - error = "Role ID already exists"; - return -1; - } - - if ( by_name.insert(rname, role) == false ) - { - by_id.erase(next_role); - - delete role; - - error = "Role NAME already exists"; - return -1; - } - - next_role += 1; - - roles_template.set(vrole); - - return 0; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int VMGroupRoles::add_vm(const std::string& role_name, int vmid) -{ - VMGroupRole * role; - - role = by_name.get(role_name); - - if ( role == 0 ) - { - return -1; - } - - role->add_vm(vmid); - - return 0; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int VMGroupRoles::del_vm(const std::string& role_name, int vmid) -{ - VMGroupRole * role; - - role = by_name.get(role_name); - - if ( role == 0 ) - { - return -1; - } - - role->del_vm(vmid); - - return 0; -} - -int VMGroupRoles::vm_size() -{ - int total = 0; - - for ( role_iterator it = begin(); it != end() ; ++it ) - { - total += (*it)->get_vms().size(); - } - - return total; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int VMGroupRoles::names_to_ids(const std::set keys, - std::set& keyi) -{ - std::set::iterator it; - - for ( it = keys.begin(); it != keys.end(); ++it ) - { - VMGroupRole *r = by_name.get(*it); - - if ( r == 0 ) - { - keyi.clear(); - return -1; - } - - keyi.insert(r->id()); - } - - return 0; -} - /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* VMGroup */ diff --git a/src/vm_group/VMGroupRole.cc b/src/vm_group/VMGroupRole.cc new file mode 100644 index 0000000000..e24636d0f5 --- /dev/null +++ b/src/vm_group/VMGroupRole.cc @@ -0,0 +1,245 @@ +/* ------------------------------------------------------------------------ */ +/* Copyright 2002-2016, OpenNebula Project, OpenNebula Systems */ +/* */ +/* 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 "VMGroupRole.h" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +/* VMGroupRole */ +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +VMGroupRole::VMGroupRole(VectorAttribute *_va):va(_va) +{ + string vms_str = va->vector_value("VMS"); + + if ( !vms_str.empty() ) + { + one_util::split_unique(vms_str, ',', vms); + } +} + +/* -------------------------------------------------------------------------- */ + +void VMGroupRole::add_vm(int vm_id) +{ + std::pair::iterator, bool> rc; + + rc = vms.insert(vm_id); + + if ( rc.second == false ) + { + return; + } + + set_vms(); +} + +void VMGroupRole::del_vm(int vm_id) +{ + size_t rc = vms.erase(vm_id); + + if ( rc == 0 ) + { + return; + } + + set_vms(); +} + +void VMGroupRole::set_vms() +{ + if ( vms.empty() ) + { + va->remove("VMS"); + return; + } + + std::string vms_str = one_util::join(vms.begin(), vms.end(), ','); + + va->replace("VMS", vms_str); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VMGroupRoles::from_xml_node(const xmlNodePtr node) +{ + std::vector roles; + std::vector::iterator it; + + if ( roles_template.from_xml_node(node) == -1 ) + { + return -1; + } + + roles_template.get("ROLE", roles); + + for (it = roles.begin(); it != roles.end(); ++it) + { + std::string rname = (*it)->vector_value("NAME"); + + int rid; + int rc = (*it)->vector_value("ID", rid); + + if ( rname.empty() || rc == -1 ) + { + return -1; + } + + if ( rid >= next_role ) + { + next_role = rid + 1; + } + + VMGroupRole * role = new VMGroupRole((*it)); + + if ( by_id.insert(rid, role) == false ) + { + delete role; + return -1; + } + + if ( by_name.insert(rname, role) == false ) + { + by_id.erase(rid); + + delete role; + return -1; + } + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ + +int VMGroupRoles::add_role(VectorAttribute * vrole, string& error) +{ + std::string rname = vrole->vector_value("NAME"); + + if ( rname.empty() ) + { + error = "Missing NAME in VM group role"; + return -1; + } + + // Remove internal attributes before inserting + vrole->replace("ID", next_role); + + vrole->remove("VMS"); + + VMGroupRole * role = new VMGroupRole(vrole); + + if ( by_id.insert(next_role, role) == false ) + { + delete role; + + error = "Role ID already exists"; + return -1; + } + + if ( by_name.insert(rname, role) == false ) + { + by_id.erase(next_role); + + delete role; + + error = "Role NAME already exists"; + return -1; + } + + next_role += 1; + + roles_template.set(vrole); + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VMGroupRoles::add_vm(const std::string& role_name, int vmid) +{ + VMGroupRole * role; + + role = by_name.get(role_name); + + if ( role == 0 ) + { + return -1; + } + + role->add_vm(vmid); + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VMGroupRoles::del_vm(const std::string& role_name, int vmid) +{ + VMGroupRole * role; + + role = by_name.get(role_name); + + if ( role == 0 ) + { + return -1; + } + + role->del_vm(vmid); + + return 0; +} + +int VMGroupRoles::vm_size() +{ + int total = 0; + + for ( role_iterator it = begin(); it != end() ; ++it ) + { + total += (*it)->get_vms().size(); + } + + return total; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VMGroupRoles::names_to_ids(const std::set keys, + std::set& keyi) +{ + std::set::iterator it; + + for ( it = keys.begin(); it != keys.end(); ++it ) + { + VMGroupRole *r = by_name.get(*it); + + if ( r == 0 ) + { + keyi.clear(); + return -1; + } + + keyi.insert(r->id()); + } + + return 0; +} + diff --git a/src/vm_group/VMGroupRule.cc b/src/vm_group/VMGroupRule.cc new file mode 100644 index 0000000000..245601135c --- /dev/null +++ b/src/vm_group/VMGroupRule.cc @@ -0,0 +1,72 @@ +/* ------------------------------------------------------------------------ */ +/* Copyright 2002-2016, OpenNebula Project, OpenNebula Systems */ +/* */ +/* 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 "VMGroup.h" +#include "VMGroupRole.h" +#include "VMGroupRule.h" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +/* VMGroupRule */ +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +bool VMGroupRule::compatible(VMGroupRule::rule_set& affined, + VMGroupRule::rule_set& anti, VMGroupRule& err) +{ + VMGroupRule ta, taa; + + rule_set::iterator it; + + for (it=affined.begin() ; it != affined.end(); ++it) + { + ta |= *it; + } + + for (it=anti.begin() ; it != anti.end(); ++it) + { + taa |= *it; + } + + err = ta & taa; + + return err.none(); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +std::string VMGroupRule::policy_to_s(Policy policy) +{ + std::string name; + + switch(policy) + { + case AFFINED: + name="AFFINED"; + break; + + case ANTI_AFFINED: + name="ANTI_AFFINED"; + break; + + case NONE: + name="NONE"; + break; + } + + return name; +}