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

F #2347: VMs are added/removed from VMGROUP roles. VMGROUP with VMs

cannot be updated
This commit is contained in:
Ruben S. Montero 2017-01-04 15:23:35 +01:00
parent 1b4c543712
commit a6fc7b23cb
7 changed files with 287 additions and 31 deletions

View File

@ -70,6 +70,33 @@ public:
return new Template(*obj_template);
};
// -------------------------------------------------------------------------
// Role Management
// -------------------------------------------------------------------------
/**
* Adds a VM to a role
* @param role_name
* @param vmid
*
* @return 0 if VM was successfully added, -1 otherwise
*/
int add_vm(const std::string& role_name, int vmid)
{
return roles.add_vm(role_name, vmid);
}
/**
* Deletes a VM from a role
* @param role_name
* @param vmid
*
* @return 0 if VM was successfully added, -1 otherwise
*/
int del_vm(const std::string& role_name, int vmid)
{
return roles.del_vm(role_name, vmid);
}
private:
// -------------------------------------------------------------------------
// Friends
@ -96,30 +123,6 @@ private:
*/
int check_affinity(const std::string& aname, std::string& error_str);
/**
* Adds a VM to a role
* @param role_name
* @param vmid
*
* @return 0 if VM was successfully added, -1 otherwise
*/
int add_vm(const std::string& role_name, int vmid)
{
return roles.add_vm(role_name, vmid);
}
/**
* Deletes a VM from a role
* @param role_name
* @param vmid
*
* @return 0 if VM was successfully added, -1 otherwise
*/
int del_vm(const std::string& role_name, int vmid)
{
return roles.del_vm(role_name, vmid);
}
// -------------------------------------------------------------------------
// DataBase implementation
// -------------------------------------------------------------------------

View File

@ -136,6 +136,11 @@ public:
*/
int del_vm(const std::string& role_name, int vmid);
/**
* @return the total number of VMs in the group
*/
int vm_size();
private:
/**
* A role map indexed by different key types
@ -230,12 +235,75 @@ private:
return true;
}
private:
/**
* Iterators for the map
*/
typedef typename std::map<T, VMGroupRole *>::iterator roles_it;
roles_it begin()
{
return roles.begin();
}
roles_it end()
{
return roles.end();
}
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

@ -1085,6 +1085,14 @@ public:
*/
void remove_security_group(int sgid);
// ------------------------------------------------------------------------
// Virtual Machine Groups
// ------------------------------------------------------------------------
/**
* Remove this VM from its role and VM group if any
*/
void release_vmgroup();
// ------------------------------------------------------------------------
// Imported VM interface
// ------------------------------------------------------------------------
@ -1999,7 +2007,7 @@ private:
int parse_context_variables(VectorAttribute ** context, string& error_str);
// -------------------------------------------------------------------------
// NIC & DISK Management Helpers
// Management helpers: NIC, DISK and VMGROUP
// -------------------------------------------------------------------------
/**
* Get all network leases for this Virtual Machine
@ -2014,6 +2022,13 @@ private:
*/
int get_disk_images(string &error_str);
/**
* Adds the VM to the VM group if needed
* @param error_str Returns the error reason, if any
* @return 0 if success
*/
int get_vmgroup(string& error);
// ------------------------------------------------------------------------
// Public cloud templates related functions
// ------------------------------------------------------------------------

View File

@ -223,6 +223,7 @@ void DispatchManager::free_vm_resources(VirtualMachine * vm)
int vmid;
vm->release_network_leases();
vm->release_vmgroup();
vm->release_disk_images(ds_quotas);
vm->set_exit_time(time(0));

View File

@ -230,6 +230,8 @@ void DispatchManager::done_action(int vid)
{
vm->release_network_leases();
vm->release_vmgroup();
vm->release_disk_images(ds_quotas);
vm->set_state(VirtualMachine::DONE);

View File

@ -741,12 +741,8 @@ int VirtualMachine::insert(SqlDB * db, string& error_str)
// ------------------------------------------------------------------------
// Set a name if the VM has not got one and VM_ID
// ------------------------------------------------------------------------
oss << oid;
value = oss.str();
user_obj_template->erase("VMID");
obj_template->add("VMID", value);
obj_template->add("VMID", oid);
user_obj_template->get("TEMPLATE_ID", value);
user_obj_template->erase("TEMPLATE_ID");
@ -1019,6 +1015,14 @@ int VirtualMachine::insert(SqlDB * db, string& error_str)
}
}
// ------------------------------------------------------------------------
// Associate to VM Group
// ------------------------------------------------------------------------
if ( get_vmgroup(error_str) == -1 )
{
goto error_rollback;
}
// ------------------------------------------------------------------------
parse_well_known_attributes();
@ -2883,6 +2887,145 @@ int VirtualMachine::set_detach_nic(int nic_id)
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* VirtualMachine VMGroup interface */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::get_vmgroup(string& error)
{
vector<Attribute *> vmgroups;
vector<Attribute*>::iterator it;
bool found;
VectorAttribute * thegroup = 0;
user_obj_template->remove("VMGROUP", vmgroups);
for (it = vmgroups.begin(), found = false; it != vmgroups.end(); )
{
if ( (*it)->type() != Attribute::VECTOR || found )
{
delete *it;
it = vmgroups.erase(it);
}
else
{
thegroup = dynamic_cast<VectorAttribute *>(*it);
found = true;
++it;
}
}
if ( thegroup == 0 )
{
return 0;
}
/* ------------------ Get the VMGroup by_name or by_id ------------------ */
VMGroupPool * vmgrouppool = Nebula::instance().get_vmgrouppool();
VMGroup * vmgroup;
string vmg_role = thegroup->vector_value("ROLE");
string vmg_name = thegroup->vector_value("VMGROUP");
int vmg_id;
if ( vmg_role.empty() )
{
error = "Missing role name in VM Group definition";
delete thegroup;
return -1;
}
if ( !vmg_name.empty() )
{
int vmg_uid;
if ( thegroup->vector_value("VMGROUP_UID", vmg_uid) == -1 )
{
vmg_uid = get_uid();
}
vmgroup = vmgrouppool->get(gname, vmg_uid, true);
}
else if ( thegroup->vector_value("VMGROUP_ID", vmg_id) == 0 )
{
vmgroup = vmgrouppool->get(vmg_id, true);
}
if ( vmgroup == 0 )
{
error = "Cannot find VM Group to associate the VM to";
delete thegroup;
return -1;
}
/* ------------------ Add VM to the role in the vm group ---------------- */
thegroup->replace("VMGROUP_ID", vmgroup->get_oid());
int rc = vmgroup->add_vm(vmg_role, get_oid());
if ( rc != 0 )
{
error = "Role does not exist in VM Group";
delete thegroup;
}
else
{
vmgrouppool->update(vmgroup);
obj_template->set(thegroup);
}
vmgroup->unlock();
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::release_vmgroup()
{
VectorAttribute * thegroup = obj_template->get("VMGROUP");
if ( thegroup == 0 )
{
return;
}
int vmg_id;
if ( thegroup->vector_value("VMGROUP_ID", vmg_id) == -1 )
{
return;
}
string vmg_role = thegroup->vector_value("ROLE");
if ( vmg_role.empty() )
{
return;
}
VMGroupPool * vmgrouppool = Nebula::instance().get_vmgrouppool();
VMGroup * vmgroup = vmgrouppool->get(vmg_id, true);
if ( vmgroup == 0 )
{
return;
}
vmgroup->del_vm(vmg_role, get_oid());
vmgrouppool->update(vmgroup);
vmgroup->unlock();
}

View File

@ -202,6 +202,18 @@ int VMGroupRoles::del_vm(const std::string& role_name, int 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;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* VMGroup */
@ -497,6 +509,18 @@ int VMGroup::insert(SqlDB *db, string& error_str)
int VMGroup::post_update_template(string& error)
{
int vms = roles.vm_size();
if ( vms > 0 )
{
ostringstream oss;
oss << "VM Group has " << vms << " VMs";
error = oss.str();
return -1;
}
if ( check_affinity("AFFINED", error) == -1 )
{
return -1;