mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-22 18:50:08 +03:00
Merge branch 'feature-2347'
This commit is contained in:
commit
13ed081f14
@ -65,6 +65,7 @@ main_env.Append(LIBPATH=[
|
||||
cwd+'/src/pool',
|
||||
cwd+'/src/template',
|
||||
cwd+'/src/vm',
|
||||
cwd+'/src/vm_group',
|
||||
cwd+'/src/vm_template',
|
||||
cwd+'/src/vmm',
|
||||
cwd+'/src/lcm',
|
||||
@ -221,6 +222,7 @@ build_scripts=[
|
||||
'src/nebula/SConstruct',
|
||||
'src/pool/SConstruct',
|
||||
'src/vm/SConstruct',
|
||||
'src/vm_group/SConstruct',
|
||||
'src/vm_template/SConstruct',
|
||||
'src/vmm/SConstruct',
|
||||
'src/lcm/SConstruct',
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "VirtualRouterPool.h"
|
||||
#include "MarketPlacePool.h"
|
||||
#include "MarketPlaceAppPool.h"
|
||||
#include "VMGroupPool.h"
|
||||
|
||||
#include "VirtualMachineManager.h"
|
||||
#include "LifeCycleManager.h"
|
||||
@ -156,6 +157,11 @@ public:
|
||||
return apppool;
|
||||
};
|
||||
|
||||
VMGroupPool * get_vmgrouppool()
|
||||
{
|
||||
return vmgrouppool;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Manager Accessors
|
||||
// --------------------------------------------------------------
|
||||
@ -580,10 +586,10 @@ private:
|
||||
"/DEFAULT_GROUP_QUOTAS/VM_QUOTA"),
|
||||
system_db(0), db(0),
|
||||
vmpool(0), hpool(0), vnpool(0), upool(0), ipool(0), gpool(0), tpool(0),
|
||||
dspool(0), clpool(0), docpool(0), zonepool(0),
|
||||
secgrouppool(0), vdcpool(0), vrouterpool(0), marketpool(0), apppool(0),
|
||||
lcm(0), vmm(0), im(0), tm(0), dm(0), rm(0), hm(0), authm(0),
|
||||
aclm(0), imagem(0), marketm(0), ipamm(0)
|
||||
dspool(0), clpool(0), docpool(0), zonepool(0), secgrouppool(0),
|
||||
vdcpool(0), vrouterpool(0), marketpool(0), apppool(0), vmgrouppool(0),
|
||||
lcm(0), vmm(0), im(0), tm(0), dm(0), rm(0), hm(0), authm(0), aclm(0),
|
||||
imagem(0), marketm(0), ipamm(0)
|
||||
{
|
||||
const char * nl = getenv("ONE_LOCATION");
|
||||
|
||||
@ -634,6 +640,7 @@ private:
|
||||
delete vrouterpool;
|
||||
delete marketpool;
|
||||
delete apppool;
|
||||
delete vmgrouppool;
|
||||
delete vmm;
|
||||
delete lcm;
|
||||
delete im;
|
||||
@ -718,6 +725,7 @@ private:
|
||||
VirtualRouterPool * vrouterpool;
|
||||
MarketPlacePool * marketpool;
|
||||
MarketPlaceAppPool * apppool;
|
||||
VMGroupPool * vmgrouppool;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Nebula Managers
|
||||
|
@ -96,22 +96,14 @@ namespace one_util
|
||||
* @param st string to split
|
||||
* @param delim delimiter character
|
||||
* @param result where the result will be saved
|
||||
* @param clean_empty true to clean empty split parts.
|
||||
* Example for st "a::b:c"
|
||||
* clean_empty true will return ["a", "b", "c"]
|
||||
* clean_empty fase will return ["a", "", "b", "c"]
|
||||
*/
|
||||
template <class T>
|
||||
void split_unique(
|
||||
const std::string& st,
|
||||
char delim,
|
||||
std::set<T>& result,
|
||||
bool clean_empty=true)
|
||||
void split_unique(const std::string& st, char delim, std::set<T>& result)
|
||||
{
|
||||
T elem;
|
||||
std::vector<std::string>::const_iterator it;
|
||||
|
||||
std::vector<std::string> strings = split(st, delim, clean_empty);
|
||||
std::vector<std::string> strings = split(st, delim, true);
|
||||
|
||||
for (it = strings.begin(); it != strings.end(); it++)
|
||||
{
|
||||
@ -127,6 +119,13 @@ namespace one_util
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicit specialization for strings
|
||||
*/
|
||||
template <>
|
||||
void split_unique(const std::string& st, char delim,
|
||||
std::set<std::string>& result);
|
||||
|
||||
/**
|
||||
* Joins the given element with the delimiter
|
||||
*
|
||||
|
@ -66,7 +66,8 @@ public:
|
||||
VDC = 0x0002000000000000LL,
|
||||
VROUTER = 0x0004000000000000LL,
|
||||
MARKETPLACE = 0x0008000000000000LL,
|
||||
MARKETPLACEAPP = 0x0010000000000000LL
|
||||
MARKETPLACEAPP = 0x0010000000000000LL,
|
||||
VMGROUP = 0x0020000000000000LL
|
||||
};
|
||||
|
||||
static string type_to_str(ObjectType ob)
|
||||
@ -90,6 +91,7 @@ public:
|
||||
case VROUTER: return "VROUTER" ; break;
|
||||
case MARKETPLACE: return "MARKETPLACE" ; break;
|
||||
case MARKETPLACEAPP: return "MARKETPLACEAPP" ; break;
|
||||
case VMGROUP: return "VMGROUP" ; break;
|
||||
default: return "";
|
||||
}
|
||||
};
|
||||
|
@ -679,4 +679,33 @@ private:
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class VMGroupAllocate : public RequestManagerAllocate
|
||||
{
|
||||
public:
|
||||
VMGroupAllocate():
|
||||
RequestManagerAllocate("VMGroupAllocate",
|
||||
"Allocates a new vm group",
|
||||
"A:ss",
|
||||
true)
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
pool = nd.get_vmgrouppool();
|
||||
auth_object = PoolObjectSQL::VMGROUP;
|
||||
};
|
||||
|
||||
~VMGroupAllocate(){};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
Template * get_object_template()
|
||||
{
|
||||
return new Template;
|
||||
};
|
||||
|
||||
Request::ErrorCode pool_allocate(xmlrpc_c::paramList const& paramList,
|
||||
Template * tmpl,
|
||||
int& id,
|
||||
RequestAttributes& att);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -250,4 +250,19 @@ public:
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class VMGroupChmod: public RequestManagerChmod
|
||||
{
|
||||
public:
|
||||
VMGroupChmod():
|
||||
RequestManagerChmod("VMGroupChmod",
|
||||
"Changes permission bits of a vm group")
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
pool = nd.get_vmgrouppool();
|
||||
auth_object = PoolObjectSQL::VMGROUP;
|
||||
};
|
||||
|
||||
~VMGroupChmod(){};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -341,4 +341,24 @@ public:
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class VMGroupChown: public RequestManagerChown
|
||||
{
|
||||
public:
|
||||
VMGroupChown():
|
||||
RequestManagerChown("VMGroupChown",
|
||||
"Changes ownership of a vm group")
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
pool = nd.get_vmgrouppool();
|
||||
auth_object = PoolObjectSQL::VMGROUP;
|
||||
};
|
||||
|
||||
~VMGroupChown(){};
|
||||
|
||||
PoolObjectSQL * get(const string& name, int uid, bool lock)
|
||||
{
|
||||
return static_cast<VMGroupPool*>(pool)->get(name, uid, lock);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -449,7 +449,24 @@ protected:
|
||||
|
||||
int drop(PoolObjectSQL * obj, bool resive, RequestAttributes& att);
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
class VMGroupDelete : public RequestManagerDelete
|
||||
{
|
||||
public:
|
||||
VMGroupDelete():
|
||||
RequestManagerDelete("VMGroupDelete",
|
||||
"Deletes a vm group")
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
pool = nd.get_vmgrouppool();
|
||||
auth_object = PoolObjectSQL::VMGROUP;
|
||||
};
|
||||
|
||||
~VMGroupDelete(){};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -371,7 +371,23 @@ public:
|
||||
|
||||
~MarketPlaceAppInfo(){};
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class VMGroupInfo : public RequestManagerInfo
|
||||
{
|
||||
public:
|
||||
VMGroupInfo():
|
||||
RequestManagerInfo("VMGroupInfo",
|
||||
"Returns vm group information")
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
pool = nd.get_vmgrouppool();
|
||||
auth_object = PoolObjectSQL::VMGROUP;
|
||||
};
|
||||
|
||||
~VMGroupInfo(){};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -553,4 +553,23 @@ public:
|
||||
~MarketPlaceAppPoolInfo(){};
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
class VMGroupPoolInfo : public RequestManagerPoolInfoFilter
|
||||
{
|
||||
public:
|
||||
VMGroupPoolInfo():
|
||||
RequestManagerPoolInfoFilter("VMGroupPoolInfo",
|
||||
"Returns the vm group pool",
|
||||
"A:siii")
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
pool = nd.get_vmgrouppool();
|
||||
auth_object = PoolObjectSQL::VMGROUP;
|
||||
};
|
||||
|
||||
~VMGroupPoolInfo(){};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -405,4 +405,23 @@ public:
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class VMGroupRename: public RequestManagerRename
|
||||
{
|
||||
public:
|
||||
VMGroupRename():
|
||||
RequestManagerRename("VMGroupRename", "Renames a vm group")
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
pool = nd.get_vmgrouppool();
|
||||
auth_object = PoolObjectSQL::VMGROUP;
|
||||
};
|
||||
|
||||
~VMGroupRename(){};
|
||||
|
||||
PoolObjectSQL * get(const string& name, int uid, bool lock)
|
||||
{
|
||||
return static_cast<VMGroupPool*>(pool)->get(name, uid, lock);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -343,4 +343,19 @@ public:
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class VMGroupUpdateTemplate : public RequestManagerUpdateTemplate
|
||||
{
|
||||
public:
|
||||
VMGroupUpdateTemplate():
|
||||
RequestManagerUpdateTemplate("VMGroupUpdateTemplate",
|
||||
"Updates a vm group template")
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
pool = nd.get_vmgrouppool();
|
||||
auth_object = PoolObjectSQL::VMGROUP;
|
||||
};
|
||||
|
||||
~VMGroupUpdateTemplate(){};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -326,15 +326,15 @@ public:
|
||||
* @param name the attribute name.
|
||||
* @return true first attribute or 0 if not found or wrong type
|
||||
*/
|
||||
inline const VectorAttribute * get(const string& name) const
|
||||
{
|
||||
return __get<VectorAttribute>(name);
|
||||
}
|
||||
inline const VectorAttribute * get(const string& name) const
|
||||
{
|
||||
return __get<VectorAttribute>(name);
|
||||
}
|
||||
|
||||
inline VectorAttribute * get(const string& name)
|
||||
{
|
||||
return __get<VectorAttribute>(name);
|
||||
}
|
||||
inline VectorAttribute * get(const string& name)
|
||||
{
|
||||
return __get<VectorAttribute>(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of a SingleAttribute with the given name and converts
|
||||
|
215
include/VMGroup.h
Normal file
215
include/VMGroup.h
Normal file
@ -0,0 +1,215 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* 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. */
|
||||
/* -------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef VMGROUP_H_
|
||||
#define VMGROUP_H_
|
||||
|
||||
#include "PoolObjectSQL.h"
|
||||
#include "VMGroupRole.h"
|
||||
#include "VMGroupRule.h"
|
||||
|
||||
class VMGroupPool;
|
||||
|
||||
enum class VMGroupPolicy;
|
||||
|
||||
/**
|
||||
* A VM group is a set of related VMs that may impose placement constraints.
|
||||
*
|
||||
* Data model:
|
||||
*
|
||||
* NAME = "Web server"
|
||||
* DESCRIPTION = "A multi-tier web server: frontend, apps servers, db"
|
||||
*
|
||||
* ROLE = [
|
||||
* NAME = "frontend",
|
||||
* ID = 0,
|
||||
* VMS = "0,1"
|
||||
* ]
|
||||
*
|
||||
* ROLE = [
|
||||
* NAME = "db",
|
||||
* ID = 1,
|
||||
* POLICY = ANTI_AFFINED,
|
||||
* VMS = "2,3,4,5"
|
||||
* ]
|
||||
*
|
||||
* ANTI_AFFINED = "db, front_end"
|
||||
*/
|
||||
class VMGroup : public PoolObjectSQL
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Function to print the VMGroup object into a string in XML format
|
||||
* @param xml the resulting XML string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
/**
|
||||
* Rebuilds the object from an xml formatted string
|
||||
* @param xml_str The xml-formatted string
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int from_xml(const string &xml_str);
|
||||
|
||||
/**
|
||||
* Returns a copy of the Template
|
||||
* @return A copy of the Template
|
||||
*/
|
||||
Template * clone_template() const
|
||||
{
|
||||
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
|
||||
// -------------------------------------------------------------------------
|
||||
friend class VMGroupPool;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
VMGroup(int _uid, int _gid, const string& _uname, const string& _gname,
|
||||
int _umask, Template * group_template);
|
||||
|
||||
~VMGroup();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Role Management
|
||||
// -------------------------------------------------------------------------
|
||||
/**
|
||||
* Check if all the roles in a AFFINED/ANTI_AFFINED rules are defined in
|
||||
* the group
|
||||
* @param policy attribute with a list (comma-separated) of role names
|
||||
* @param error_str if any
|
||||
*
|
||||
* @return 0 if all roles are defined -1 otherwise
|
||||
*/
|
||||
int check_rule_names(VMGroupPolicy policy, std::string& error_str);
|
||||
|
||||
/**
|
||||
* Generate a rule_set from the AFFINED/ANTI_AFFINED rules
|
||||
* @param p policy AFFINED or ANTIAFFINED
|
||||
* @param rs rule_set with the rules
|
||||
* @param error if some of the roles are not defined
|
||||
*
|
||||
* @return 0 if success -1 otherwise
|
||||
*/
|
||||
int get_rules(VMGroupPolicy p, VMGroupRule::rule_set& rs, std::string& err);
|
||||
|
||||
int check_rule_consistency(std::string& error);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// DataBase implementation
|
||||
// -------------------------------------------------------------------------
|
||||
static const char * db_names;
|
||||
|
||||
static const char * db_bootstrap;
|
||||
|
||||
static const char * table;
|
||||
|
||||
/**
|
||||
* Execute an INSERT or REPLACE Sql query.
|
||||
* @param db The SQL DB
|
||||
* @param replace Execute an INSERT or a REPLACE
|
||||
* @param error_str Returns the error reason, if any
|
||||
* @return 0 one success
|
||||
*/
|
||||
int insert_replace(SqlDB *db, bool replace, string& error_str);
|
||||
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the VMGroup
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int bootstrap(SqlDB * db)
|
||||
{
|
||||
ostringstream oss(VMGroup::db_bootstrap);
|
||||
|
||||
return db->exec(oss);
|
||||
};
|
||||
|
||||
/**
|
||||
* Writes the VMGroup in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int insert(SqlDB *db, string& error_str);
|
||||
|
||||
/**
|
||||
* Writes/updates the VMGroup's data fields in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update(SqlDB *db)
|
||||
{
|
||||
string error_str;
|
||||
return insert_replace(db, true, error_str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the new roles and affined/anti-affined cross-references
|
||||
* @param error string describing the error if any
|
||||
* @return 0 on success
|
||||
*/
|
||||
int post_update_template(string& error);
|
||||
|
||||
/**
|
||||
* Factory method for VMGroup templates
|
||||
*/
|
||||
Template * get_new_template() const
|
||||
{
|
||||
return new Template;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// VMGroup attributes
|
||||
// -------------------------------------------------------------------------
|
||||
/**
|
||||
* The role set
|
||||
*/
|
||||
VMGroupRoles roles;
|
||||
};
|
||||
|
||||
#endif /*VMGROUP_H_*/
|
||||
|
158
include/VMGroupPool.h
Normal file
158
include/VMGroupPool.h
Normal file
@ -0,0 +1,158 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef VMGROUP_POOL_H_
|
||||
#define VMGROUP_POOL_H_
|
||||
|
||||
#include "PoolSQL.h"
|
||||
#include "VMGroup.h"
|
||||
|
||||
class AuthRequest;
|
||||
|
||||
class VMGroupPool : public PoolSQL
|
||||
{
|
||||
public:
|
||||
VMGroupPool(SqlDB * db):PoolSQL(db, VMGroup::table, true, true){};
|
||||
|
||||
~VMGroupPool(){};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Methods for DB management */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/**
|
||||
* Allocates a new VMGroup, writing it in the pool database. No memory is
|
||||
* allocated for the object.
|
||||
*
|
||||
* @param uid user identifier
|
||||
* @param gid the id of the group this object is assigned to
|
||||
* @param uname user name
|
||||
* @param gname group name
|
||||
* @param umask permissions umask
|
||||
* @param vmgroup_template a Template object
|
||||
* @param oid the id assigned to the new VMGroup
|
||||
* @param error_str Returns the error reason, if any
|
||||
*
|
||||
* @return the oid assigned to the object, -1 in case of failure
|
||||
*/
|
||||
int allocate(int uid, int gid, const std::string& uname,
|
||||
const std::string& gname, int umask, Template * vmgrp_tmpl, int * oid,
|
||||
std::string& error_str);
|
||||
|
||||
/**
|
||||
* Function to get a VMGroup from the pool, if the object is not in memory
|
||||
* it is loaded from the DB
|
||||
* @param oid VMGroup unique id
|
||||
* @param lock locks the VMGroup mutex
|
||||
* @return a pointer to the VMGroup, 0 if the VMGroup could not be loaded
|
||||
*/
|
||||
VMGroup * get(int oid, bool lock)
|
||||
{
|
||||
return static_cast<VMGroup *>(PoolSQL::get(oid, lock));
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets an object from the pool (if needed the object is loaded from the
|
||||
* database).
|
||||
* @param name of the object
|
||||
* @param uid id of owner
|
||||
* @param lock locks the object if true
|
||||
*
|
||||
* @return a pointer to the object, 0 in case of failure
|
||||
*/
|
||||
VMGroup * get(const std::string& name, int uid, bool lock)
|
||||
{
|
||||
return static_cast<VMGroup *>(PoolSQL::get(name, uid, lock));
|
||||
};
|
||||
|
||||
/** Update a VMGroup
|
||||
* @param vmgroup pointer to VMGroup
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update(VMGroup * vmgroup)
|
||||
{
|
||||
return vmgroup->update(db);
|
||||
};
|
||||
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the VMGroup pool
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int bootstrap(SqlDB * _db)
|
||||
{
|
||||
return VMGroup::bootstrap(_db);
|
||||
};
|
||||
|
||||
/**
|
||||
* Dumps the VMGroup pool in XML format. A filter can be added to the query
|
||||
* @param os the output stream to dump the pool contents
|
||||
* @param where filter for the objects, defaults to all
|
||||
* @param limit parameters used for pagination
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump(std::ostringstream& os, const std::string& where,
|
||||
const std::string& limit)
|
||||
{
|
||||
return PoolSQL::dump(os, "VM_GROUP_POOL", VMGroup::table, where, limit);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the VMGROUP definition in a VM and fills the ROLE attributes. It
|
||||
* also adds the VM to the role if found.
|
||||
* @param va the vector attribute
|
||||
* @param uid VM owner, used as default to look for the VMGroup
|
||||
* @param vid of the VM
|
||||
* @param err if any
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int vmgroup_attribute(VectorAttribute * va, int uid, int vid, string& err);
|
||||
|
||||
/**
|
||||
* Removes VM from the VMGroup
|
||||
* @param va with VMGROUP
|
||||
* @param vid of the VM to be removed
|
||||
*/
|
||||
void del_vm(const VectorAttribute * va, int vid);
|
||||
|
||||
/**
|
||||
* Builds the AuthRequest for the VMGroup
|
||||
* @param va with the VMGROUP
|
||||
* @param uid VM owber, used as default to look for the VMGroup
|
||||
* @param ar the authrequest
|
||||
*/
|
||||
void authorize(const VectorAttribute * va, int uid, AuthRequest* ar);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Factory method to produce objects
|
||||
* @return a pointer to the new object
|
||||
*/
|
||||
PoolObjectSQL * create()
|
||||
{
|
||||
return new VMGroup(-1,-1,"","",0,0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gest a VMGroup from its vector attribute description
|
||||
* @param va the VectorAttribute
|
||||
* @param _uid default uid to look for the VMGroup
|
||||
*/
|
||||
VMGroup * get_from_attribute(const VectorAttribute *va, int _uid);
|
||||
};
|
||||
|
||||
#endif /*VMGROUP_POOL_H_*/
|
||||
|
417
include/VMGroupRole.h
Normal file
417
include/VMGroupRole.h
Normal file
@ -0,0 +1,417 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* 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. */
|
||||
/* -------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef VMGROUP_ROLE_H_
|
||||
#define VMGROUP_ROLE_H_
|
||||
|
||||
#include "PoolObjectSQL.h"
|
||||
#include "NebulaUtil.h"
|
||||
|
||||
class VMGroupPool;
|
||||
|
||||
enum class VMGroupPolicy;
|
||||
|
||||
/**
|
||||
* A VMGroupRole defines a VM type that typically implements a role in a
|
||||
* multi-vm application.
|
||||
*
|
||||
* ROLE = [
|
||||
* NAME = "Web application servers",
|
||||
* ID = 12,
|
||||
* POLICY = AFFINED,
|
||||
* VMS = "1,2,45,21"
|
||||
* ]
|
||||
*
|
||||
*/
|
||||
class VMGroupRole
|
||||
{
|
||||
public:
|
||||
VMGroupRole(VectorAttribute *_va);
|
||||
|
||||
virtual ~VMGroupRole(){};
|
||||
|
||||
/**
|
||||
* @return the role id
|
||||
*/
|
||||
int id()
|
||||
{
|
||||
int rid;
|
||||
|
||||
va->vector_value("ID", rid);
|
||||
|
||||
return rid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the role name
|
||||
*/
|
||||
std::string name()
|
||||
{
|
||||
return va->vector_value("NAME");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the set of VMs in a string in a comma separated list
|
||||
*/
|
||||
std::string vms_s()
|
||||
{
|
||||
return va->vector_value("VMS");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the policy of this role
|
||||
*/
|
||||
VMGroupPolicy policy();
|
||||
|
||||
std::string policy_s()
|
||||
{
|
||||
return va->vector_value("POLICY");
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* VMS set Interface */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
const std::set<int>& get_vms()
|
||||
{
|
||||
return vms;
|
||||
};
|
||||
|
||||
int size_vms()
|
||||
{
|
||||
return vms.size();
|
||||
}
|
||||
|
||||
void add_vm(int vm_id);
|
||||
|
||||
void del_vm(int vm_id);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Placement constraints */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/**
|
||||
* 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_role_requirements(int vm_id, std::string& requirements);
|
||||
|
||||
/**
|
||||
* Generates a string with the boolean expression to conform an affinity
|
||||
* constraint policy
|
||||
* @param p policy to place VMs respect to this role VMs
|
||||
* @param requirements
|
||||
*/
|
||||
void role_requirements(VMGroupPolicy p, std::string& requirements);
|
||||
|
||||
/**
|
||||
* Gets the placement requirements for the affined HOSTS
|
||||
* @param reqs string with the requirements expression
|
||||
*/
|
||||
void affined_host_requirements(std::string& reqs);
|
||||
|
||||
/**
|
||||
* Gets the placement requirements for the antiaffined HOSTS
|
||||
* @param reqs string with the requirements expression
|
||||
*/
|
||||
void antiaffined_host_requirements(std::string& reqs);
|
||||
|
||||
/**
|
||||
* Generate generic requirements for a set of hosts
|
||||
* @param hosts the set
|
||||
* @param op1 operator for each host requirement = or !=
|
||||
* @param op2 operator to join host requirements & or |
|
||||
* @param oss stream where the requirement expression is output
|
||||
*/
|
||||
static void host_requirements(std::set<int>& hosts, const std::string& op1,
|
||||
const std::string& op2, std::ostringstream& oss);
|
||||
|
||||
private:
|
||||
/**
|
||||
* The set of vms in the role
|
||||
*/
|
||||
std::set<int> vms;
|
||||
|
||||
/**
|
||||
* The associated vector attribute
|
||||
*/
|
||||
VectorAttribute * va;
|
||||
|
||||
/**
|
||||
* Set the VMS attribute for the role (list of VM IDs)
|
||||
*/
|
||||
void set_vms();
|
||||
};
|
||||
|
||||
/**
|
||||
* The VMGroupRoles class represents a set of ROLES stored in a Template
|
||||
*/
|
||||
class VMGroupRoles
|
||||
{
|
||||
public:
|
||||
VMGroupRoles():roles_template(false,'=',"ROLES"), next_role(0){};
|
||||
|
||||
~VMGroupRoles()
|
||||
{
|
||||
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
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
std::string& to_xml(std::string& xml_str) const
|
||||
{
|
||||
return roles_template.to_xml(xml_str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the object from an xml node
|
||||
* @param node for the ROLES template
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int from_xml_node(const xmlNodePtr node);
|
||||
|
||||
/**
|
||||
* Adds a new role to the set
|
||||
* @param vrole VectorAttribute of the role
|
||||
* @param error string if any
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int add_role(VectorAttribute * vrole, string& error);
|
||||
|
||||
/**
|
||||
* Generates the ids corresponding to a set of role 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::string& rnames, std::set<int>& keyi);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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 the total number of VMs in the group
|
||||
*/
|
||||
int vm_size();
|
||||
|
||||
/**
|
||||
* @return the a VMGroupRole by its name
|
||||
* @param rname role name
|
||||
*/
|
||||
VMGroupRole * get(const std::string& rname)
|
||||
{
|
||||
return by_name.get(rname);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the a VMGroupRole by its id
|
||||
* @param rname role name
|
||||
*/
|
||||
VMGroupRole * get(int id)
|
||||
{
|
||||
return by_id.get(id);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/**
|
||||
* Iterator for the roles in the group
|
||||
*/
|
||||
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:
|
||||
/**
|
||||
* A role map indexed by different key types
|
||||
*/
|
||||
template<class T>
|
||||
class RoleMap
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Inserts a new role in the map
|
||||
* @param k the key
|
||||
* @param r pointer to yhe VMGroupRole
|
||||
* @return true if the role was successfully inserted
|
||||
*/
|
||||
bool insert(const T& k, VMGroupRole * r)
|
||||
{
|
||||
std::pair<T, VMGroupRole *> rpair(k, r);
|
||||
std::pair<roles_it, bool> rc;
|
||||
|
||||
rc = roles.insert(rpair);
|
||||
|
||||
return rc.second;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the memory associated to the map and clears it
|
||||
*/
|
||||
void delete_roles()
|
||||
{
|
||||
for (roles_it it = roles.begin() ; it != roles.end() ; ++it )
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
VMGroupRole * get(T k)
|
||||
{
|
||||
typename std::map<T, VMGroupRole *>::iterator it;
|
||||
|
||||
it = roles.find(k);
|
||||
|
||||
if ( it == roles.end() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the contents of the map
|
||||
*/
|
||||
void clear()
|
||||
{
|
||||
roles.clear();
|
||||
}
|
||||
|
||||
size_t erase(const T& k)
|
||||
{
|
||||
return roles.erase(k);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* The role template to store the VMGroupRole
|
||||
*/
|
||||
Template roles_template;
|
||||
|
||||
/**
|
||||
* The next role id
|
||||
*/
|
||||
int next_role;
|
||||
|
||||
/**
|
||||
* Map to access the roles by their name
|
||||
*/
|
||||
RoleMap<std::string> by_name;
|
||||
|
||||
/**
|
||||
* Map to access the roles by their id
|
||||
*/
|
||||
RoleMap<int> by_id;
|
||||
};
|
||||
|
||||
#endif /*VMGROUP_ROLE_H*/
|
||||
|
189
include/VMGroupRule.h
Normal file
189
include/VMGroupRule.h
Normal file
@ -0,0 +1,189 @@
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* 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. */
|
||||
/* -------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef VMGROUP_RULE_H_
|
||||
#define VMGROUP_RULE_H_
|
||||
|
||||
#include <bitset>
|
||||
#include "VMGroupRole.h"
|
||||
|
||||
struct VMGroupRule_compare;
|
||||
|
||||
/**
|
||||
* Placement policy rules for roles
|
||||
* AFFINED: VMs of all roles are placed in the same hypervisor
|
||||
* ANTI_AFFINED: VMs are placed in different hypervisors (role-wise)
|
||||
* NONE: No additional placement constraints
|
||||
*/
|
||||
enum class VMGroupPolicy
|
||||
{
|
||||
NONE = 0x00,
|
||||
AFFINED = 0x01,
|
||||
ANTI_AFFINED= 0x02
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, VMGroupPolicy policy);
|
||||
|
||||
/**
|
||||
* A rule represents a role placement policy
|
||||
*/
|
||||
class VMGroupRule
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* A specialized set for rules
|
||||
*/
|
||||
typedef std::set<VMGroupRule, VMGroupRule_compare> rule_set;
|
||||
|
||||
typedef std::bitset<VMGroupRoles::MAX_ROLES> role_bitset;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Rule Constructors */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
VMGroupRule():policy(VMGroupPolicy::NONE),roles(){};
|
||||
|
||||
VMGroupRule(VMGroupPolicy p, std::set<int> roles_id):policy(p)
|
||||
{
|
||||
std::set<int>::iterator it;
|
||||
|
||||
for ( it = roles_id.begin(); it != roles_id.end(); ++it )
|
||||
{
|
||||
if ( *it < VMGroupRoles::MAX_ROLES )
|
||||
{
|
||||
roles[*it] = 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
VMGroupRule(VMGroupPolicy p, role_bitset _roles):policy(p), roles(_roles){};
|
||||
|
||||
VMGroupRule(const VMGroupRule& other)
|
||||
{
|
||||
policy = other.policy;
|
||||
roles = other.roles;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Rule operators */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
VMGroupRule& operator=(const VMGroupRule& other)
|
||||
{
|
||||
if ( this != &other )
|
||||
{
|
||||
policy = other.policy;
|
||||
roles = other.roles;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
VMGroupRule& operator&= (const VMGroupRule& other)
|
||||
{
|
||||
roles &= other.roles;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VMGroupRule operator& (const VMGroupRule& other) const
|
||||
{
|
||||
return VMGroupRule(policy, other.roles & roles );
|
||||
}
|
||||
|
||||
VMGroupRule& operator|= (const VMGroupRule& other)
|
||||
{
|
||||
roles |= other.roles;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VMGroupRule operator| (const VMGroupRule& other) const
|
||||
{
|
||||
return VMGroupRule(policy, other.roles | roles );
|
||||
}
|
||||
|
||||
bool none()
|
||||
{
|
||||
return roles.none();
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Rule interface */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/**
|
||||
* Check if an affined and anti-affined rule set are compatible. Sets are
|
||||
* compatible if there isn't a role in the affined and anti-affined sets
|
||||
* at the same time
|
||||
* @param affined rule set
|
||||
* @param anti affined rule set
|
||||
* @param err a rule with the roles in both sets
|
||||
*
|
||||
* @return true if sets are compatible
|
||||
*/
|
||||
static bool compatible(rule_set& affined, rule_set& anti, VMGroupRule& err);
|
||||
|
||||
/**
|
||||
* Reduce a set of affinity rules merging rules affecting the same roles
|
||||
* Example:
|
||||
* AFFINED = a, b
|
||||
* AFFINED = b, c -------> AFFINED = a, b, c
|
||||
* AFFINED = e, d AFFINED = e, d
|
||||
*
|
||||
* @param affined set of rules to be reduced
|
||||
* @param reduced set
|
||||
*/
|
||||
static void reduce(rule_set affined, rule_set& reduced);
|
||||
|
||||
/**
|
||||
* @return the roles in the rule as a bitset (1 roles is in)
|
||||
*/
|
||||
const role_bitset& get_roles() const
|
||||
{
|
||||
return roles;
|
||||
}
|
||||
|
||||
VMGroupPolicy get_policy() const
|
||||
{
|
||||
return policy;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
friend class VMGroupRule_compare;
|
||||
|
||||
/**
|
||||
* Type of the rule
|
||||
*/
|
||||
VMGroupPolicy policy;
|
||||
|
||||
/**
|
||||
* Roles participating in the rule
|
||||
*/
|
||||
std::bitset<VMGroupRoles::MAX_ROLES> roles;
|
||||
};
|
||||
|
||||
/**
|
||||
* Functor to compre two rules. Two rules are considered equivalent if the
|
||||
* include the same roles.
|
||||
*/
|
||||
struct VMGroupRule_compare
|
||||
{
|
||||
bool operator() (const VMGroupRule& lhs, const VMGroupRule& rhs) const
|
||||
{
|
||||
return lhs.roles.to_ullong() < rhs.roles.to_ullong();
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*VMGROUP_RULE_H_*/
|
||||
|
@ -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
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -550,6 +550,7 @@ BIN_FILES="src/nebula/oned \
|
||||
src/cli/oneflow \
|
||||
src/cli/oneflow-template \
|
||||
src/cli/onesecgroup \
|
||||
src/cli/onevmgroup \
|
||||
src/cli/onevdc \
|
||||
src/cli/onevrouter \
|
||||
src/cli/onemarket \
|
||||
@ -1280,6 +1281,8 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/opennebula/acl_pool.rb \
|
||||
src/oca/ruby/opennebula/pool.rb \
|
||||
src/oca/ruby/opennebula/security_group_pool.rb \
|
||||
src/oca/ruby/opennebula/security_group.rb \
|
||||
src/oca/ruby/opennebula/vm_group_pool.rb \
|
||||
src/oca/ruby/opennebula/vm_group.rb \
|
||||
src/oca/ruby/opennebula/system.rb \
|
||||
src/oca/ruby/opennebula/template_pool.rb \
|
||||
src/oca/ruby/opennebula/template.rb \
|
||||
@ -1440,6 +1443,7 @@ ONE_CLI_LIB_FILES="src/cli/one_helper/onegroup_helper.rb \
|
||||
src/cli/one_helper/onevdc_helper.rb \
|
||||
src/cli/one_helper/oneacct_helper.rb \
|
||||
src/cli/one_helper/onesecgroup_helper.rb \
|
||||
src/cli/one_helper/onevmgroup_helper.rb \
|
||||
src/cli/one_helper/onevrouter_helper.rb \
|
||||
src/cli/one_helper/onemarketapp_helper.rb \
|
||||
src/cli/one_helper/onemarket_helper.rb"
|
||||
@ -1459,6 +1463,7 @@ CLI_BIN_FILES="src/cli/onevm \
|
||||
src/cli/oneflow-template \
|
||||
src/cli/oneacct \
|
||||
src/cli/onesecgroup \
|
||||
src/cli/onevmgroup \
|
||||
src/cli/oneshowback \
|
||||
src/cli/onevdc \
|
||||
src/cli/onevrouter \
|
||||
@ -1478,6 +1483,7 @@ CLI_CONF_FILES="src/cli/etc/onegroup.yaml \
|
||||
src/cli/etc/onezone.yaml \
|
||||
src/cli/etc/oneacct.yaml \
|
||||
src/cli/etc/onesecgroup.yaml \
|
||||
src/cli/etc/onevmgroup.yaml \
|
||||
src/cli/etc/oneshowback.yaml \
|
||||
src/cli/etc/onevdc.yaml \
|
||||
src/cli/etc/onevrouter.yaml \
|
||||
|
@ -83,7 +83,7 @@ AclManager::AclManager(
|
||||
string error_str;
|
||||
|
||||
// Users in group USERS can create standard resources
|
||||
// @1 VM+IMAGE+TEMPLATE+DOCUMENT/* CREATE *
|
||||
// @1 VM+IMAGE+TEMPLATE+DOCUMENT+SECGROUP+VMGROUP/* CREATE *
|
||||
add_rule(AclRule::GROUP_ID |
|
||||
1,
|
||||
AclRule::ALL_ID |
|
||||
@ -91,7 +91,8 @@ AclManager::AclManager(
|
||||
PoolObjectSQL::IMAGE |
|
||||
PoolObjectSQL::TEMPLATE |
|
||||
PoolObjectSQL::DOCUMENT |
|
||||
PoolObjectSQL::SECGROUP,
|
||||
PoolObjectSQL::SECGROUP |
|
||||
PoolObjectSQL::VMGROUP,
|
||||
AuthRequest::CREATE,
|
||||
AclRule::ALL_ID,
|
||||
error_str);
|
||||
|
@ -28,7 +28,7 @@ const long long AclRule::CLUSTER_ID = 0x0000000800000000LL;
|
||||
|
||||
const long long AclRule::NONE_ID = 0x1000000000000000LL;
|
||||
|
||||
const int AclRule::num_pool_objects = 16;
|
||||
const int AclRule::num_pool_objects = 17;
|
||||
const PoolObjectSQL::ObjectType AclRule::pool_objects[] = {
|
||||
PoolObjectSQL::VM,
|
||||
PoolObjectSQL::HOST,
|
||||
@ -45,7 +45,8 @@ const PoolObjectSQL::ObjectType AclRule::pool_objects[] = {
|
||||
PoolObjectSQL::VDC,
|
||||
PoolObjectSQL::VROUTER,
|
||||
PoolObjectSQL::MARKETPLACE,
|
||||
PoolObjectSQL::MARKETPLACEAPP
|
||||
PoolObjectSQL::MARKETPLACEAPP,
|
||||
PoolObjectSQL::VMGROUP
|
||||
};
|
||||
|
||||
const int AclRule::num_auth_operations = 4;
|
||||
@ -61,7 +62,8 @@ const long long AclRule::INVALID_CLUSTER_OBJECTS =
|
||||
PoolObjectSQL::TEMPLATE | PoolObjectSQL::GROUP | PoolObjectSQL::ACL |
|
||||
PoolObjectSQL::CLUSTER | PoolObjectSQL::DOCUMENT | PoolObjectSQL::ZONE |
|
||||
PoolObjectSQL::SECGROUP | PoolObjectSQL::VDC | PoolObjectSQL::VROUTER |
|
||||
PoolObjectSQL::MARKETPLACE | PoolObjectSQL::MARKETPLACEAPP;
|
||||
PoolObjectSQL::MARKETPLACE | PoolObjectSQL::MARKETPLACEAPP |
|
||||
PoolObjectSQL::VMGROUP;
|
||||
|
||||
const long long AclRule::INVALID_GROUP_OBJECTS =
|
||||
PoolObjectSQL::HOST | PoolObjectSQL::GROUP | PoolObjectSQL::CLUSTER |
|
||||
@ -237,7 +239,7 @@ bool AclRule::malformed(string& error_str) const
|
||||
oss << "[resource] type is missing";
|
||||
}
|
||||
|
||||
if ( (resource & 0xFFE0000000000000LL) != 0 )
|
||||
if ( (resource & 0xFFC0000000000000LL) != 0 )
|
||||
{
|
||||
if ( error )
|
||||
{
|
||||
|
@ -9,9 +9,9 @@
|
||||
:size: 8
|
||||
:right: true
|
||||
|
||||
:RES_VHNIUTGDCOZSvRMA:
|
||||
:RES_VHNIUTGDCOZSvRMAP:
|
||||
:desc: Which resource the rule applies to
|
||||
:size: 20
|
||||
:size: 21
|
||||
|
||||
:RID:
|
||||
:desc: Resource ID
|
||||
@ -31,7 +31,7 @@
|
||||
:default:
|
||||
- :ID
|
||||
- :USER
|
||||
- :RES_VHNIUTGDCOZSvRMA
|
||||
- :RES_VHNIUTGDCOZSvRMAP
|
||||
- :RID
|
||||
- :OPE_UMAC
|
||||
- :ZONE
|
||||
|
37
src/cli/etc/onevmgroup.yaml
Normal file
37
src/cli/etc/onevmgroup.yaml
Normal file
@ -0,0 +1,37 @@
|
||||
---
|
||||
:ID:
|
||||
:desc: ONE identifier for the VM Group
|
||||
:size: 4
|
||||
|
||||
:NAME:
|
||||
:desc: Name of the VM Group
|
||||
:size: 15
|
||||
:left: true
|
||||
|
||||
:USER:
|
||||
:desc: Username of the VM Group owner
|
||||
:size: 8
|
||||
:left: true
|
||||
|
||||
:GROUP:
|
||||
:desc: Group of the VM Group
|
||||
:size: 8
|
||||
:left: true
|
||||
|
||||
:VMS:
|
||||
:desc: Number of VMs in the VM Group
|
||||
:size: 4
|
||||
:lef: true
|
||||
|
||||
:ROLES:
|
||||
:desc: Roles in the VM Group
|
||||
:size: 36
|
||||
:left: true
|
||||
|
||||
:default:
|
||||
- :ID
|
||||
- :USER
|
||||
- :GROUP
|
||||
- :NAME
|
||||
- :VMS
|
||||
- :ROLES
|
@ -44,7 +44,7 @@ private
|
||||
def self.resource_mask(str)
|
||||
resource_type=str.split("/")[0]
|
||||
|
||||
mask = "----------------"
|
||||
mask = "-----------------"
|
||||
|
||||
resource_type.split("+").each{|type|
|
||||
case type
|
||||
@ -80,6 +80,8 @@ private
|
||||
mask[14] = "M"
|
||||
when "MARKETPLACEAPP"
|
||||
mask[15] = "A"
|
||||
when "VMGROUP"
|
||||
mask[16] = "P"
|
||||
end
|
||||
}
|
||||
mask
|
||||
@ -119,8 +121,8 @@ private
|
||||
d['STRING'].split(" ")[0]
|
||||
end
|
||||
|
||||
column :RES_VHNIUTGDCOZSvRMA, "Resource to which the rule applies",
|
||||
:size => 20 do |d|
|
||||
column :RES_VHNIUTGDCOZSvRMAP, "Resource to which the rule applies",
|
||||
:size => 21 do |d|
|
||||
OneAclHelper::resource_mask d['STRING'].split(" ")[1]
|
||||
end
|
||||
|
||||
@ -137,7 +139,7 @@ private
|
||||
OneAclHelper::right_mask d['STRING'].split(" ")[2]
|
||||
end
|
||||
|
||||
default :ID, :USER, :RES_VHNIUTGDCOZSvRMA, :RID, :OPE_UMAC, :ZONE
|
||||
default :ID, :USER, :RES_VHNIUTGDCOZSvRMAP, :RID, :OPE_UMAC, :ZONE
|
||||
end
|
||||
|
||||
table
|
||||
|
170
src/cli/one_helper/onevmgroup_helper.rb
Normal file
170
src/cli/one_helper/onevmgroup_helper.rb
Normal file
@ -0,0 +1,170 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'one_helper'
|
||||
|
||||
class OneVMGroupHelper < OpenNebulaHelper::OneHelper
|
||||
def self.rname
|
||||
"VM_GROUP"
|
||||
end
|
||||
|
||||
def self.conf_file
|
||||
"onevmgroup.yaml"
|
||||
end
|
||||
|
||||
def format_pool(options)
|
||||
config_file = self.class.table_conf
|
||||
|
||||
table = CLIHelper::ShowTable.new(config_file, self) do
|
||||
column :ID, "ONE identifier for the VM Group", :size=>4 do |d|
|
||||
d["ID"]
|
||||
end
|
||||
|
||||
column :NAME, "Name of the VM Group", :left, :size=>15 do |d|
|
||||
d["NAME"]
|
||||
end
|
||||
|
||||
column :USER, "Username of the VM Group owner", :left,
|
||||
:size=>8 do |d|
|
||||
helper.user_name(d, options)
|
||||
end
|
||||
|
||||
column :GROUP, "Group of the VM Group", :left, :size=>8 do |d|
|
||||
helper.group_name(d, options)
|
||||
end
|
||||
|
||||
column :VMS, "Number of VMs in the VM Group", :left, :size=>4 do |d|
|
||||
roles = [d["ROLES"]["ROLE"]].flatten
|
||||
vms = 0
|
||||
|
||||
if !roles.nil?
|
||||
roles.each { |r|
|
||||
vms += r["VMS"].split(',').size if !r["VMS"].nil?
|
||||
}
|
||||
end
|
||||
|
||||
vms
|
||||
end
|
||||
|
||||
column :ROLES, "Roles in the VM Group", :left, :size=>36 do |d|
|
||||
roles = [d["ROLES"]["ROLE"]].flatten
|
||||
roles_names = ""
|
||||
|
||||
if !roles.nil?
|
||||
rnames = roles.collect { |i| i["NAME"] }
|
||||
roles_names = rnames.join(", ") if !rnames.empty?
|
||||
end
|
||||
|
||||
roles_names
|
||||
end
|
||||
|
||||
default :ID, :USER, :GROUP, :NAME, :VMS, :ROLES
|
||||
end
|
||||
|
||||
table
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def factory(id=nil)
|
||||
if id
|
||||
OpenNebula::VMGroup.new_with_id(id, @client)
|
||||
else
|
||||
xml=OpenNebula::VMGroup.build_xml
|
||||
OpenNebula::VMGroup.new(xml, @client)
|
||||
end
|
||||
end
|
||||
|
||||
def factory_pool(user_flag=-2)
|
||||
OpenNebula::VMGroupPool.new(@client, user_flag)
|
||||
end
|
||||
|
||||
def format_resource(vmgroup, options = {})
|
||||
str="%-15s: %-20s"
|
||||
str_h1="%-80s"
|
||||
|
||||
CLIHelper.print_header(
|
||||
str_h1 % "VM GROUP #{vmgroup['ID']} INFORMATION")
|
||||
puts str % ["ID", vmgroup.id.to_s]
|
||||
puts str % ["NAME", vmgroup.name]
|
||||
puts str % ["USER", vmgroup['UNAME']]
|
||||
puts str % ["GROUP", vmgroup['GNAME']]
|
||||
|
||||
CLIHelper.print_header(str_h1 % "PERMISSIONS",false)
|
||||
|
||||
puts
|
||||
|
||||
["OWNER", "GROUP", "OTHER"].each { |e|
|
||||
mask = "---"
|
||||
mask[0] = "u" if vmgroup["PERMISSIONS/#{e}_U"] == "1"
|
||||
mask[1] = "m" if vmgroup["PERMISSIONS/#{e}_M"] == "1"
|
||||
mask[2] = "a" if vmgroup["PERMISSIONS/#{e}_A"] == "1"
|
||||
|
||||
puts str % [e, mask]
|
||||
}
|
||||
|
||||
puts
|
||||
|
||||
CLIHelper.print_header(str_h1 % "ROLES", false)
|
||||
|
||||
if !vmgroup.to_hash['VM_GROUP']['ROLES']['ROLE'].nil?
|
||||
roles = [vmgroup.to_hash['VM_GROUP']['ROLES']['ROLE']].flatten
|
||||
end
|
||||
|
||||
CLIHelper::ShowTable.new(nil, self) do
|
||||
column :ID, "", :left, :size=>4 do |d|
|
||||
d["ID"]
|
||||
end
|
||||
|
||||
column :NAME, "", :left, :size=>8 do |d|
|
||||
d["NAME"]
|
||||
end
|
||||
|
||||
column :POLICY, "", :left, :size=>12 do |d|
|
||||
if d["POLICY"].nil?
|
||||
'-'
|
||||
else
|
||||
d["POLICY"]
|
||||
end
|
||||
end
|
||||
|
||||
column :AFFINED_HOSTS, "", :left, :size=>18 do |d|
|
||||
if d["HOST_AFFINED"].nil?
|
||||
'-'
|
||||
else
|
||||
d["HOST_AFFINED"]
|
||||
end
|
||||
end
|
||||
|
||||
column :ANTI_AFFINED_HOST, "", :left, :size=>18 do |d|
|
||||
if d["HOST_ANTI_AFFINED"].nil?
|
||||
'-'
|
||||
else
|
||||
d["HOST_ANTI_AFFINED"]
|
||||
end
|
||||
end
|
||||
|
||||
column :VIRTUAL_MACHINES, "", :left, :size=>20 do |d|
|
||||
d["VMS"]
|
||||
end
|
||||
end.show(roles, {})
|
||||
|
||||
puts
|
||||
|
||||
CLIHelper.print_header(str_h1 % "TEMPLATE CONTENTS",false)
|
||||
puts vmgroup.template_str
|
||||
end
|
||||
end
|
185
src/cli/onevmgroup
Executable file
185
src/cli/onevmgroup
Executable file
@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"]
|
||||
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION="/usr/lib/one/ruby"
|
||||
else
|
||||
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << RUBY_LIB_LOCATION+"/cli"
|
||||
|
||||
require 'command_parser'
|
||||
require 'one_helper/onevmgroup_helper'
|
||||
|
||||
cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
usage "`onevmgroup` <command> [<args>] [<options>]"
|
||||
version OpenNebulaHelper::ONE_VERSION
|
||||
|
||||
helper = OneVMGroupHelper.new
|
||||
|
||||
before_proc do
|
||||
helper.set_client(options)
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Global Options
|
||||
########################################################################
|
||||
set :option, CommandParser::OPTIONS+OpenNebulaHelper::CLIENT_OPTIONS
|
||||
|
||||
list_options = CLIHelper::OPTIONS
|
||||
list_options << OpenNebulaHelper::XML
|
||||
list_options << OpenNebulaHelper::NUMERIC
|
||||
list_options << OpenNebulaHelper::DESCRIBE
|
||||
|
||||
########################################################################
|
||||
# Formatters for arguments
|
||||
########################################################################
|
||||
set :format, :groupid, OpenNebulaHelper.rname_to_id_desc("GROUP") do |arg|
|
||||
OpenNebulaHelper.rname_to_id(arg, "GROUP")
|
||||
end
|
||||
|
||||
set :format, :userid, OpenNebulaHelper.rname_to_id_desc("USER") do |arg|
|
||||
OpenNebulaHelper.rname_to_id(arg, "USER")
|
||||
end
|
||||
|
||||
set :format, :vmgroupid, OneVMGroupHelper.to_id_desc do |arg|
|
||||
helper.to_id(arg)
|
||||
end
|
||||
|
||||
set :format, :vmgroupid_list, OneVMGroupHelper.list_to_id_desc do |arg|
|
||||
helper.list_to_id(arg)
|
||||
end
|
||||
|
||||
set :format, :filterflag, OneVMGroupHelper.filterflag_to_i_desc do |arg|
|
||||
helper.filterflag_to_i(arg)
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Commands
|
||||
########################################################################
|
||||
|
||||
create_desc = <<-EOT.unindent
|
||||
Creates a new VM Group from the given description
|
||||
EOT
|
||||
|
||||
command :create, create_desc, :file do
|
||||
helper.create_resource(options) do |obj|
|
||||
begin
|
||||
template = File.read(args[0])
|
||||
|
||||
obj.allocate(template)
|
||||
rescue => e
|
||||
STDERR.puts e.messsage
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
delete_desc = <<-EOT.unindent
|
||||
Deletes the VM Group
|
||||
EOT
|
||||
|
||||
command :delete, delete_desc, [:range, :vmgroupid_list] do
|
||||
helper.perform_actions(args[0],options,"deleted") do |obj|
|
||||
obj.delete
|
||||
end
|
||||
end
|
||||
|
||||
list_desc = <<-EOT.unindent
|
||||
Lists VM Group in the pool
|
||||
EOT
|
||||
|
||||
command :list, list_desc, [:filterflag, nil], :options=>list_options do
|
||||
helper.list_pool(options, false, args[0])
|
||||
end
|
||||
|
||||
show_desc = <<-EOT.unindent
|
||||
Shows information for the given VM Group
|
||||
EOT
|
||||
|
||||
command :show, show_desc, :vmgroupid, :options=>OpenNebulaHelper::XML do
|
||||
helper.show_resource(args[0],options)
|
||||
end
|
||||
|
||||
chgrp_desc = <<-EOT.unindent
|
||||
Changes the VM Group's group
|
||||
EOT
|
||||
|
||||
command :chgrp, chgrp_desc,[:range, :vmgroupid_list], :groupid do
|
||||
helper.perform_actions(args[0],options,"Group changed") do |obj|
|
||||
obj.chown(-1, args[1].to_i)
|
||||
end
|
||||
end
|
||||
|
||||
chown_desc = <<-EOT.unindent
|
||||
Changes the VM Group's owner and group
|
||||
EOT
|
||||
|
||||
command :chown, chown_desc, [:range, :vmgroupid_list], :userid,
|
||||
[:groupid,nil] do
|
||||
gid = args[2].nil? ? -1 : args[2].to_i
|
||||
helper.perform_actions(args[0],options,"Owner/Group changed") do |obj|
|
||||
obj.chown(args[1].to_i, gid)
|
||||
end
|
||||
end
|
||||
|
||||
chmod_desc = <<-EOT.unindent
|
||||
Changes the VM Group permissions
|
||||
EOT
|
||||
|
||||
command :chmod, chmod_desc, [:range, :vmgroupid_list], :octet do
|
||||
helper.perform_actions(args[0],options, "Permissions changed") do |t|
|
||||
t.chmod_octet(args[1])
|
||||
end
|
||||
end
|
||||
|
||||
update_desc = <<-EOT.unindent
|
||||
Update the template contents. If a path is not provided the editor will
|
||||
be launched to modify the current content.
|
||||
EOT
|
||||
|
||||
command :update, update_desc, :vmgroupid, [:file, nil],
|
||||
:options=>OpenNebulaHelper::APPEND do
|
||||
helper.perform_action(args[0],options,"modified") do |obj|
|
||||
if options[:append]
|
||||
str = OpenNebulaHelper.append_template(args[0], obj, args[1])
|
||||
else
|
||||
str = OpenNebulaHelper.update_template(args[0], obj, args[1])
|
||||
end
|
||||
|
||||
helper.set_client(options)
|
||||
obj = helper.retrieve_resource(obj.id)
|
||||
|
||||
obj.update(str, options[:append])
|
||||
end
|
||||
end
|
||||
|
||||
rename_desc = <<-EOT.unindent
|
||||
Renames the VM Group
|
||||
EOT
|
||||
|
||||
command :rename, rename_desc, :vmgroupid, :name do
|
||||
helper.perform_action(args[0],options,"renamed") do |o|
|
||||
o.rename(args[1])
|
||||
end
|
||||
end
|
||||
end
|
@ -339,6 +339,25 @@ std::string one_util::gsub(const std::string& st, const std::string& sfind,
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
namespace one_util
|
||||
{
|
||||
template<>
|
||||
void split_unique(const std::string& st, char delim, std::set<std::string>& res)
|
||||
{
|
||||
std::vector<std::string>::const_iterator it;
|
||||
|
||||
std::vector<std::string> strings = split(st, delim, true);
|
||||
|
||||
for (it = strings.begin(); it != strings.end(); it++)
|
||||
{
|
||||
res.insert(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Buffer length for zlib inflate/deflate
|
||||
*/
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -353,7 +353,7 @@ void Group::add_admin_rules(int user_id)
|
||||
NebulaLog::log("GROUP",Log::ERROR,error_msg);
|
||||
}
|
||||
|
||||
// #<uid> VM+NET+IMAGE+TEMPLATE+DOCUMENT+SECGROUP+VROUTER/@<gid> USE+MANAGE *
|
||||
// #<uid> VM+NET+IMAGE+TEMPLATE+DOCUMENT+SECGROUP+VROUTER+VMGROUP/@<gid> USE+MANAGE *
|
||||
if ( aclm->add_rule(
|
||||
AclRule::INDIVIDUAL_ID |
|
||||
user_id,
|
||||
@ -365,6 +365,7 @@ void Group::add_admin_rules(int user_id)
|
||||
PoolObjectSQL::DOCUMENT |
|
||||
PoolObjectSQL::SECGROUP |
|
||||
PoolObjectSQL::VROUTER |
|
||||
PoolObjectSQL::VMGROUP |
|
||||
AclRule::GROUP_ID |
|
||||
oid,
|
||||
|
||||
@ -449,7 +450,7 @@ void Group::del_admin_rules(int user_id)
|
||||
NebulaLog::log("GROUP",Log::ERROR,error_msg);
|
||||
}
|
||||
|
||||
// #<uid> VM+NET+IMAGE+TEMPLATE+DOCUMENT+SECGROUP+VROUTER/@<gid> USE+MANAGE *
|
||||
// #<uid> VM+NET+IMAGE+TEMPLATE+DOCUMENT+SECGROUP+VROUTER+VMGROUP/@<gid> USE+MANAGE *
|
||||
if ( aclm->del_rule(
|
||||
AclRule::INDIVIDUAL_ID |
|
||||
user_id,
|
||||
@ -461,6 +462,7 @@ void Group::del_admin_rules(int user_id)
|
||||
PoolObjectSQL::DOCUMENT |
|
||||
PoolObjectSQL::SECGROUP |
|
||||
PoolObjectSQL::VROUTER |
|
||||
PoolObjectSQL::VMGROUP |
|
||||
AclRule::GROUP_ID |
|
||||
oid,
|
||||
|
||||
|
@ -323,6 +323,7 @@ void Nebula::start(bool bootstrap_only)
|
||||
rc += GroupQuotas::bootstrap(db);
|
||||
rc += SecurityGroupPool::bootstrap(db);
|
||||
rc += VirtualRouterPool::bootstrap(db);
|
||||
rc += VMGroupPool::bootstrap(db);
|
||||
|
||||
// Create the system tables only if bootstrap went well
|
||||
if (rc == 0)
|
||||
@ -597,6 +598,8 @@ void Nebula::start(bool bootstrap_only)
|
||||
marketpool = new MarketPlacePool(db, is_federation_slave());
|
||||
apppool = new MarketPlaceAppPool(db, is_federation_slave());
|
||||
|
||||
vmgrouppool = new VMGroupPool(db);
|
||||
|
||||
default_user_quota.select();
|
||||
default_group_quota.select();
|
||||
}
|
||||
|
@ -67,6 +67,7 @@ env.Prepend(LIBS=[
|
||||
'nebula_vrouter',
|
||||
'nebula_marketplace',
|
||||
'nebula_ipamm',
|
||||
'nebula_vmgroup',
|
||||
'crypto',
|
||||
'xml2'
|
||||
])
|
||||
|
@ -62,6 +62,8 @@ require 'opennebula/marketplace'
|
||||
require 'opennebula/marketplace_pool'
|
||||
require 'opennebula/marketplaceapp'
|
||||
require 'opennebula/marketplaceapp_pool'
|
||||
require 'opennebula/vm_group'
|
||||
require 'opennebula/vm_group_pool'
|
||||
|
||||
module OpenNebula
|
||||
|
||||
|
@ -23,19 +23,23 @@ module OpenNebula
|
||||
# @<num>
|
||||
# ALL
|
||||
# RESOURCE -> + separated list and "/{#,@,%}<num>|ALL"
|
||||
# VM,
|
||||
# VM
|
||||
# HOST
|
||||
# NET
|
||||
# IMAGE
|
||||
# USER
|
||||
# TEMPLATE
|
||||
# GROUP
|
||||
# ACL
|
||||
# DATASTORE
|
||||
# CLUSTER
|
||||
# DOCUMENT
|
||||
# ZONE
|
||||
# SECGROUP
|
||||
# VDC
|
||||
# VROUTER
|
||||
# MARKETPLACE
|
||||
# MARKETPLACEAPP
|
||||
# VMGROUP
|
||||
# RIGHTS -> + separated list
|
||||
# USE
|
||||
# MANAGE
|
||||
@ -67,7 +71,8 @@ module OpenNebula
|
||||
"VDC" => 0x2000000000000,
|
||||
"VROUTER" => 0x4000000000000,
|
||||
"MARKETPLACE" => 0x8000000000000,
|
||||
"MARKETPLACEAPP"=> 0x10000000000000
|
||||
"MARKETPLACEAPP"=> 0x10000000000000,
|
||||
"VMGROUP" => 0x20000000000000
|
||||
}
|
||||
|
||||
RIGHTS =
|
||||
|
@ -37,7 +37,7 @@ module OpenNebula
|
||||
SELF = -1
|
||||
|
||||
# Default resource ACL's for group users (create)
|
||||
GROUP_DEFAULT_ACLS = "VM+IMAGE+TEMPLATE+DOCUMENT+SECGROUP+VROUTER"
|
||||
GROUP_DEFAULT_ACLS = "VM+IMAGE+TEMPLATE+DOCUMENT+SECGROUP+VROUTER+VMGROUP"
|
||||
|
||||
# The default view for group and group admins, must be defined in
|
||||
# sunstone_views.yaml
|
||||
|
151
src/oca/ruby/opennebula/vm_group.rb
Normal file
151
src/oca/ruby/opennebula/vm_group.rb
Normal file
@ -0,0 +1,151 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'opennebula/pool_element'
|
||||
|
||||
module OpenNebula
|
||||
class VMGroup < PoolElement
|
||||
#######################################################################
|
||||
# Constants and Class Methods
|
||||
#######################################################################
|
||||
VMGROUP_METHODS = {
|
||||
:allocate => "vmgroup.allocate",
|
||||
:info => "vmgroup.info",
|
||||
:update => "vmgroup.update",
|
||||
:delete => "vmgroup.delete",
|
||||
:chown => "vmgroup.chown",
|
||||
:chmod => "vmgroup.chmod",
|
||||
:rename => "vmgroup.rename"
|
||||
}
|
||||
|
||||
# Creates a VMGroup description with just its identifier
|
||||
# this method should be used to create plain VMGroup objects.
|
||||
# @param pe_id [Integer] the id of the object
|
||||
def VMGroup.build_xml(pe_id=nil)
|
||||
if pe_id
|
||||
obj_xml = "<VM_GROUP><ID>#{pe_id}</ID></VM_GROUP>"
|
||||
else
|
||||
obj_xml = "<VM_GROUP></VM_GROUP>"
|
||||
end
|
||||
|
||||
XMLElement.build_xml(obj_xml,'VM_GROUP')
|
||||
end
|
||||
|
||||
# Class constructor
|
||||
def initialize(xml, client)
|
||||
super(xml,client)
|
||||
|
||||
@client = client
|
||||
end
|
||||
|
||||
#######################################################################
|
||||
# XML-RPC Methods for the VMGroup Object
|
||||
#######################################################################
|
||||
|
||||
# Retrieves the information of the VMGroup.
|
||||
def info()
|
||||
super(VMGROUP_METHODS[:info], 'VM_GROUP')
|
||||
end
|
||||
|
||||
alias_method :info!, :info
|
||||
|
||||
# Allocates a new VMGroup in OpenNebula
|
||||
#
|
||||
# @param description [String] The contents of the VMGroup.
|
||||
#
|
||||
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
||||
# otherwise
|
||||
def allocate(description)
|
||||
super(VMGROUP_METHODS[:allocate], description)
|
||||
end
|
||||
|
||||
# Deletes the SecurityGroup
|
||||
def delete()
|
||||
super(VMGROUP_METHODS[:delete])
|
||||
end
|
||||
|
||||
# Replaces the vm group contents
|
||||
#
|
||||
# @param new_vmgroup [String] New vmgroup contents
|
||||
# @param append [true, false] True to append new attributes instead of
|
||||
# replace the whole securitygroup
|
||||
#
|
||||
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
||||
# otherwise
|
||||
def update(new_vmgroup, append=false)
|
||||
super(VMGROUP_METHODS[:update], new_vmgroup, append ? 1 : 0)
|
||||
end
|
||||
|
||||
# Changes the owner/group
|
||||
#
|
||||
# @param uid [Integer] the new owner id. Set to -1 to leave the current one
|
||||
# @param gid [Integer] the new group id. Set to -1 to leave the current one
|
||||
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
||||
# otherwise
|
||||
def chown(uid, gid)
|
||||
super(VMGROUP_METHODS[:chown], uid, gid)
|
||||
end
|
||||
|
||||
# Changes the SecurityGroup permissions.
|
||||
#
|
||||
# @param octet [String] Permissions octed , e.g. 640
|
||||
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
||||
# otherwise
|
||||
def chmod_octet(octet)
|
||||
super(VMGROUP_METHODS[:chmod], octet)
|
||||
end
|
||||
|
||||
# Changes the SecurityGroup permissions.
|
||||
# Each [Integer] argument must be 1 to allow, 0 deny, -1 do not change
|
||||
#
|
||||
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
||||
# otherwise
|
||||
def chmod(owner_u, owner_m, owner_a, group_u, group_m, group_a, other_u,
|
||||
other_m, other_a)
|
||||
super(VMGROUP_METHODS[:chmod], owner_u, owner_m, owner_a, group_u,
|
||||
group_m, group_a, other_u, other_m, other_a)
|
||||
end
|
||||
|
||||
# Renames this VMGroup
|
||||
#
|
||||
# @param name [String] New name for the VMGroup.
|
||||
#
|
||||
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
||||
# otherwise
|
||||
def rename(name)
|
||||
return call(VMGROUP_METHODS[:rename], @pe_id, name)
|
||||
end
|
||||
|
||||
#######################################################################
|
||||
# Helpers to get VMGroup information
|
||||
#######################################################################
|
||||
|
||||
# Returns the group identifier
|
||||
# [return] _Integer_ the element's group ID
|
||||
def gid
|
||||
self['GID'].to_i
|
||||
end
|
||||
|
||||
def owner_id
|
||||
self['UID'].to_i
|
||||
end
|
||||
|
||||
# [return] _Array_ with the name of roles
|
||||
def role_names
|
||||
self.retrieve_elements('ROLES/ROLE/NAME')
|
||||
end
|
||||
end
|
||||
end
|
78
src/oca/ruby/opennebula/vm_group_pool.rb
Normal file
78
src/oca/ruby/opennebula/vm_group_pool.rb
Normal file
@ -0,0 +1,78 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'opennebula/pool'
|
||||
|
||||
module OpenNebula
|
||||
class VMGroupPool < Pool
|
||||
#######################################################################
|
||||
# Constants and Class attribute accessors
|
||||
#######################################################################
|
||||
VMGROUP_POOL_METHODS = {
|
||||
:info => "vmgrouppool.info"
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# Class constructor & Pool Methods
|
||||
#######################################################################
|
||||
|
||||
# +client+ a Client object that represents an XML-RPC connection
|
||||
# +user_id+ used to refer to a Pool with Templates from that user
|
||||
def initialize(client, user_id=-1)
|
||||
super('VM_GROUP_POOL','VM_GROUP',client)
|
||||
|
||||
@user_id = user_id
|
||||
end
|
||||
|
||||
# Factory method to create Template objects
|
||||
def factory(element_xml)
|
||||
OpenNebula::VMGroup.new(element_xml,@client)
|
||||
end
|
||||
|
||||
#######################################################################
|
||||
# XML-RPC Methods for the Template Object
|
||||
#######################################################################
|
||||
|
||||
# Retrieves all or part of the objects in the pool.
|
||||
def info(*args)
|
||||
case args.size
|
||||
when 0
|
||||
info_filter(VMGROUP_POOL_METHODS[:info], @user_id, -1, -1)
|
||||
when 3
|
||||
info_filter(VMGROUP_POOL_METHODS[:info], args[0], args[1],
|
||||
args[2])
|
||||
end
|
||||
end
|
||||
|
||||
def info_all()
|
||||
return super(VMGROUP_POOL_METHODS[:info])
|
||||
end
|
||||
|
||||
def info_mine()
|
||||
return super(VMGROUP_POOL_METHODS[:info])
|
||||
end
|
||||
|
||||
def info_group()
|
||||
return super(VMGROUP_POOL_METHODS[:info])
|
||||
end
|
||||
|
||||
alias_method :info!, :info
|
||||
alias_method :info_all!, :info_all
|
||||
alias_method :info_mine!, :info_mine
|
||||
alias_method :info_group!, :info_group
|
||||
end
|
||||
end
|
||||
|
@ -63,6 +63,8 @@ string Request::object_name(PoolObjectSQL::ObjectType ob)
|
||||
return "marketplace";
|
||||
case PoolObjectSQL::MARKETPLACEAPP:
|
||||
return "marketplaceapp";
|
||||
case PoolObjectSQL::VMGROUP:
|
||||
return "vm group";
|
||||
default:
|
||||
return "-";
|
||||
}
|
||||
|
@ -366,6 +366,7 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::methodPtr cluster_update(new ClusterUpdateTemplate());
|
||||
xmlrpc_c::methodPtr secg_update(new SecurityGroupUpdateTemplate());
|
||||
xmlrpc_c::methodPtr vrouter_update(new VirtualRouterUpdateTemplate());
|
||||
xmlrpc_c::methodPtr vmg_update(new VMGroupUpdateTemplate());
|
||||
|
||||
// Allocate Methods
|
||||
xmlrpc_c::methodPtr vm_allocate(new VirtualMachineAllocate());
|
||||
@ -378,6 +379,7 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::methodPtr doc_allocate(new DocumentAllocate());
|
||||
xmlrpc_c::methodPtr secg_allocate(new SecurityGroupAllocate());
|
||||
xmlrpc_c::methodPtr vrouter_allocate(new VirtualRouterAllocate());
|
||||
xmlrpc_c::methodPtr vmg_allocate(new VMGroupAllocate());
|
||||
|
||||
// Clone Methods
|
||||
xmlrpc_c::methodPtr template_clone(new VMTemplateClone());
|
||||
@ -394,6 +396,7 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::methodPtr doc_delete(new DocumentDelete());
|
||||
xmlrpc_c::methodPtr secg_delete(new SecurityGroupDelete());
|
||||
xmlrpc_c::methodPtr vrouter_delete(new VirtualRouterDelete());
|
||||
xmlrpc_c::methodPtr vmg_delete(new VMGroupDelete());
|
||||
|
||||
// Info Methods
|
||||
xmlrpc_c::methodPtr vm_info(new VirtualMachineInfo());
|
||||
@ -406,6 +409,7 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::methodPtr doc_info(new DocumentInfo());
|
||||
xmlrpc_c::methodPtr secg_info(new SecurityGroupInfo());
|
||||
xmlrpc_c::methodPtr vrouter_info(new VirtualRouterInfo());
|
||||
xmlrpc_c::methodPtr vmg_info(new VMGroupInfo());
|
||||
|
||||
// Lock Methods
|
||||
xmlrpc_c::methodPtr doc_lock(new DocumentLock());
|
||||
@ -421,6 +425,7 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::methodPtr clusterpool_info(new ClusterPoolInfo());
|
||||
xmlrpc_c::methodPtr docpool_info(new DocumentPoolInfo());
|
||||
xmlrpc_c::methodPtr secgpool_info(new SecurityGroupPoolInfo());
|
||||
xmlrpc_c::methodPtr vmgpool_info(new VMGroupPoolInfo());
|
||||
xmlrpc_c::methodPtr vrouter_pool_info(new VirtualRouterPoolInfo());
|
||||
|
||||
// Host Methods
|
||||
@ -449,6 +454,7 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::methodPtr doc_chown(new DocumentChown());
|
||||
xmlrpc_c::methodPtr secg_chown(new SecurityGroupChown());
|
||||
xmlrpc_c::methodPtr vrouter_chown(new VirtualRouterChown());
|
||||
xmlrpc_c::methodPtr vmg_chown(new VMGroupChown());
|
||||
|
||||
// Chmod Methods
|
||||
xmlrpc_c::methodPtr vm_chmod(new VirtualMachineChmod());
|
||||
@ -459,6 +465,7 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::methodPtr doc_chmod(new DocumentChmod());
|
||||
xmlrpc_c::methodPtr secg_chmod(new SecurityGroupChmod());
|
||||
xmlrpc_c::methodPtr vrouter_chmod(new VirtualRouterChmod());
|
||||
xmlrpc_c::methodPtr vmg_chmod(new VMGroupChmod());
|
||||
|
||||
// Cluster Methods
|
||||
xmlrpc_c::methodPtr cluster_addhost(new ClusterAddHost());
|
||||
@ -483,6 +490,7 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::methodPtr host_rename(new HostRename());
|
||||
xmlrpc_c::methodPtr secg_rename(new SecurityGroupRename());
|
||||
xmlrpc_c::methodPtr vrouter_rename(new VirtualRouterRename());
|
||||
xmlrpc_c::methodPtr vmg_rename(new VMGroupRename());
|
||||
|
||||
// Virtual Router Methods
|
||||
xmlrpc_c::methodPtr vrouter_instantiate(new VirtualRouterInstantiate());
|
||||
@ -829,6 +837,18 @@ void RequestManager::register_xml_methods()
|
||||
|
||||
RequestManagerRegistry.addMethod("one.secgrouppool.info",secgpool_info);
|
||||
|
||||
/* VM Group objects related methods*/
|
||||
|
||||
RequestManagerRegistry.addMethod("one.vmgroup.allocate", vmg_allocate);
|
||||
RequestManagerRegistry.addMethod("one.vmgroup.delete", vmg_delete);
|
||||
RequestManagerRegistry.addMethod("one.vmgroup.info", vmg_info);
|
||||
RequestManagerRegistry.addMethod("one.vmgroup.chown", vmg_chown);
|
||||
RequestManagerRegistry.addMethod("one.vmgroup.chmod", vmg_chmod);
|
||||
RequestManagerRegistry.addMethod("one.vmgroup.rename", vmg_rename);
|
||||
RequestManagerRegistry.addMethod("one.vmgroup.update", vmg_update);
|
||||
|
||||
RequestManagerRegistry.addMethod("one.vmgrouppool.info", vmgpool_info);
|
||||
|
||||
/* Vdc related methods */
|
||||
|
||||
xmlrpc_c::method * vdc_allocate_pt;
|
||||
|
@ -1195,3 +1195,25 @@ Request::ErrorCode MarketPlaceAppAllocate::pool_allocate(
|
||||
return Request::SUCCESS;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
Request::ErrorCode VMGroupAllocate::pool_allocate(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
Template * tmpl,
|
||||
int& id,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
VMGroupPool * vmgpool = static_cast<VMGroupPool *>(pool);
|
||||
|
||||
int rc = vmgpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask
|
||||
,tmpl, &id, att.resp_msg);
|
||||
|
||||
if (rc < 0)
|
||||
{
|
||||
return Request::INTERNAL;
|
||||
}
|
||||
|
||||
return Request::SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#define HOST_XML_H_
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "ObjectXML.h"
|
||||
#include "HostShare.h"
|
||||
#include "PoolObjectAuth.h"
|
||||
@ -48,6 +49,11 @@ public:
|
||||
return cluster_id;
|
||||
};
|
||||
|
||||
unsigned int dispatched() const
|
||||
{
|
||||
return dispatched_vms.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a new VM can be hosted by the host or not
|
||||
* @param cpu needed by the VM (percentage)
|
||||
@ -56,8 +62,8 @@ public:
|
||||
* @param error error message
|
||||
* @return true if the share can host the VM
|
||||
*/
|
||||
bool test_capacity(long long cpu, long long mem, vector<VectorAttribute *> &pci,
|
||||
string & error);
|
||||
bool test_capacity(long long cpu, long long mem,
|
||||
vector<VectorAttribute *> &pci, string & error);
|
||||
|
||||
/**
|
||||
* Tests whether a new VM can be hosted by the host or not
|
||||
@ -87,6 +93,8 @@ public:
|
||||
|
||||
pci.add(p, vmid);
|
||||
|
||||
dispatched_vms.insert(vmid);
|
||||
|
||||
running_vms++;
|
||||
};
|
||||
|
||||
@ -171,28 +179,51 @@ private:
|
||||
int cluster_id;
|
||||
|
||||
// Host share values
|
||||
long long mem_usage; /**< Memory allocated to VMs (in KB) */
|
||||
long long cpu_usage; /**< CPU allocated to VMs (in percentage) */
|
||||
long long mem_usage; /**< Memory allocated to VMs (in KB) */
|
||||
long long cpu_usage; /**< CPU allocated to VMs (in percentage)*/
|
||||
|
||||
long long max_mem; /**< Total memory capacity (in KB) */
|
||||
long long max_cpu; /**< Total cpu capacity (in percentage) */
|
||||
long long max_mem; /**< Total memory capacity (in KB) */
|
||||
long long max_cpu; /**< Total cpu capacity (in percentage)*/
|
||||
|
||||
long long free_disk; /**< Free disk capacity (in MB) */
|
||||
HostSharePCI pci; /**< PCI devices of the host */
|
||||
|
||||
long long free_disk; /**< Free disk capacity (in MB)*/
|
||||
|
||||
map<int, long long> ds_free_disk; /**< Free MB for local system DS */
|
||||
|
||||
long long running_vms; /**< Number of running VMs in this Host */
|
||||
long long running_vms; /**< Number of running VMs in this Host */
|
||||
set<int> dispatched_vms; /**< Dispatched VMs to this host in this cycle */
|
||||
|
||||
bool public_cloud;
|
||||
|
||||
HostSharePCI pci;
|
||||
bool public_cloud; /**< This host is a public cloud */
|
||||
|
||||
// Configuration attributes
|
||||
static const char *host_paths[]; /**< paths for search function */
|
||||
static int host_num_paths; /**< number of paths */
|
||||
|
||||
static int host_num_paths; /**< number of paths*/
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Functions to search for values in the HostXML object */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
bool is_dispatched(const std::string& vm_id) const
|
||||
{
|
||||
std::istringstream iss(vm_id);
|
||||
|
||||
void init_attributes();
|
||||
int vm_id_i;
|
||||
|
||||
iss >> vm_id_i;
|
||||
|
||||
return dispatched_vms.find(vm_id_i) != dispatched_vms.end();
|
||||
}
|
||||
|
||||
bool is_dispatched(int vm_id) const
|
||||
{
|
||||
return dispatched_vms.find(vm_id) != dispatched_vms.end();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool is_dispatched(const T& vm_id) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the Object for a given attribute in a set of object specific
|
||||
@ -221,6 +252,11 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_dispatched(value) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
value = -1; //VMID not found in VMS value is -1
|
||||
|
||||
return 0;
|
||||
@ -230,6 +266,11 @@ private:
|
||||
return ObjectXML::search(name, value);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Bootstrap the HostXML internal attributes
|
||||
*/
|
||||
void init_attributes();
|
||||
};
|
||||
|
||||
#endif /* HOST_XML_H_ */
|
||||
|
@ -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_ */
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "Log.h"
|
||||
#include "HostPoolXML.h"
|
||||
#include "VMGroupPoolXML.h"
|
||||
#include "UserPoolXML.h"
|
||||
#include "ClusterPoolXML.h"
|
||||
#include "DatastorePoolXML.h"
|
||||
@ -49,14 +50,16 @@ public:
|
||||
protected:
|
||||
|
||||
Scheduler():
|
||||
acls(0),
|
||||
upool(0),
|
||||
hpool(0),
|
||||
clpool(0),
|
||||
vmpool(0),
|
||||
vmapool(0),
|
||||
dspool(0),
|
||||
img_dspool(0),
|
||||
upool(0),
|
||||
acls(0),
|
||||
vmpool(0),
|
||||
vm_roles_pool(0),
|
||||
vmgpool(0),
|
||||
vmapool(0),
|
||||
timer(0),
|
||||
one_xmlrpc(""),
|
||||
machines_limit(0),
|
||||
@ -72,12 +75,14 @@ protected:
|
||||
delete clpool;
|
||||
|
||||
delete vmpool;
|
||||
delete vm_roles_pool;
|
||||
delete vmapool;
|
||||
|
||||
delete dspool;
|
||||
delete img_dspool;
|
||||
|
||||
delete upool;
|
||||
delete vmgpool;
|
||||
|
||||
delete acls;
|
||||
};
|
||||
@ -85,17 +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;
|
||||
|
||||
AclXML * acls;
|
||||
VirtualMachinePoolXML * vmpool;
|
||||
VirtualMachineRolePoolXML * vm_roles_pool;
|
||||
|
||||
VMGroupPoolXML * vmgpool;
|
||||
|
||||
VirtualMachineActionsPoolXML* vmapool;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Scheduler Policies
|
||||
@ -135,6 +144,8 @@ protected:
|
||||
|
||||
virtual int do_scheduled_actions();
|
||||
|
||||
virtual void do_vm_groups();
|
||||
|
||||
private:
|
||||
Scheduler(Scheduler const&){};
|
||||
|
||||
|
51
src/scheduler/include/VMGroupPoolXML.h
Normal file
51
src/scheduler/include/VMGroupPoolXML.h
Normal file
@ -0,0 +1,51 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2016, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef VMGROUP_POOL_XML_H_
|
||||
#define VMGROUP_POOL_XML_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PoolXML.h"
|
||||
#include "VMGroupXML.h"
|
||||
|
||||
class VMGroupPoolXML : public PoolXML
|
||||
{
|
||||
public:
|
||||
|
||||
VMGroupPoolXML(Client* client):PoolXML(client){};
|
||||
|
||||
~VMGroupPoolXML(){};
|
||||
|
||||
VMGroupXML * get(int oid) const
|
||||
{
|
||||
return static_cast<VMGroupXML *>(PoolXML::get(oid));
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
int get_suitable_nodes(std::vector<xmlNodePtr>& content)
|
||||
{
|
||||
return get_nodes("/VM_GROUP_POOL/VM_GROUP", content);
|
||||
};
|
||||
|
||||
void add_object(xmlNodePtr node);
|
||||
|
||||
int load_info(xmlrpc_c::value &result);
|
||||
};
|
||||
|
||||
#endif /* VMGROUP_POOL_XML_H_ */
|
103
src/scheduler/include/VMGroupXML.h
Normal file
103
src/scheduler/include/VMGroupXML.h
Normal file
@ -0,0 +1,103 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2016, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef VMGROUP_XML_H_
|
||||
#define VMGROUP_XML_H_
|
||||
|
||||
#include "ObjectXML.h"
|
||||
#include "VMGroupRole.h"
|
||||
#include "VMGroupRule.h"
|
||||
|
||||
class VirtualMachinePoolXML;
|
||||
class VirtualMachineRolePoolXML;
|
||||
|
||||
class VMGroupXML : public ObjectXML
|
||||
{
|
||||
public:
|
||||
VMGroupXML(const std::string &xml_doc):ObjectXML(xml_doc)
|
||||
{
|
||||
init_attributes();
|
||||
};
|
||||
|
||||
VMGroupXML(const xmlNodePtr node):ObjectXML(node)
|
||||
{
|
||||
init_attributes();
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
int get_oid() const
|
||||
{
|
||||
return oid;
|
||||
};
|
||||
|
||||
const std::string& get_name() const
|
||||
{
|
||||
return name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dumps a Group, its roles and affinity rules to an output stream
|
||||
*/
|
||||
friend ostream& operator<<(ostream& os, VMGroupXML& vmg);
|
||||
|
||||
/**
|
||||
* Adds the internal role placement rules to each VM in the role
|
||||
* @params vmpool VM set of pending VMs
|
||||
* @params oss stream to output debug information
|
||||
*/
|
||||
void set_antiaffinity_requirements(VirtualMachinePoolXML * vmpool,
|
||||
std::ostringstream& oss);
|
||||
|
||||
/**
|
||||
* Adds the internal role placement rules to each VM in the role
|
||||
* @params vmpool VM set of pending VMs
|
||||
* @params oss stream to output debug information
|
||||
*/
|
||||
void set_affinity_requirements(VirtualMachinePoolXML * vmpool,
|
||||
VirtualMachineRolePoolXML * vm_roles_pool, std::ostringstream& oss);
|
||||
|
||||
/**
|
||||
* Adds host affinity rules to each VM in the roles
|
||||
* @params vmp the VM set of pending VMs
|
||||
* @params oss stream to output debug information
|
||||
*/
|
||||
void set_host_requirements(VirtualMachinePoolXML * vmp,
|
||||
std::ostringstream& oss);
|
||||
|
||||
|
||||
private:
|
||||
// ------------------------------------------------------------------------
|
||||
// VMGroup Attributes
|
||||
// ------------------------------------------------------------------------
|
||||
int oid;
|
||||
|
||||
std::string name;
|
||||
|
||||
VMGroupRoles roles;
|
||||
|
||||
VMGroupRule::rule_set affined;
|
||||
VMGroupRule::rule_set anti_affined;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
/**
|
||||
* Bootstrap VMGroup roles ans rules
|
||||
*/
|
||||
void init_attributes();
|
||||
};
|
||||
|
||||
#endif /* VMGROUP_XML_H_ */
|
@ -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)
|
||||
@ -149,4 +158,36 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class VirtualMachineRolePoolXML : public VirtualMachinePoolXML
|
||||
{
|
||||
public:
|
||||
|
||||
VirtualMachineRolePoolXML(Client * client, unsigned int machines_limit):
|
||||
VirtualMachinePoolXML(client, machines_limit, false){};
|
||||
|
||||
virtual ~VirtualMachineRolePoolXML(){};
|
||||
|
||||
/**
|
||||
* Retrieves the VMs part of a role
|
||||
*
|
||||
* @return 0 on success
|
||||
* -1 on error
|
||||
* -2 if no VMs in a role
|
||||
*/
|
||||
int set_up();
|
||||
|
||||
protected:
|
||||
|
||||
int get_suitable_nodes(vector<xmlNodePtr>& content)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "/VM_POOL/VM[TEMPLATE/VMGROUP/ROLE]";
|
||||
|
||||
return get_nodes(oss.str().c_str(), content);
|
||||
}
|
||||
};
|
||||
#endif /* VM_POOL_XML_H_ */
|
||||
|
@ -60,7 +60,6 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
// Get Methods for VirtualMachineXML class
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
int get_oid() const
|
||||
{
|
||||
return oid;
|
||||
@ -116,9 +115,23 @@ public:
|
||||
return ds_requirements;
|
||||
}
|
||||
|
||||
void get_requirements (int& cpu, int& memory, long long& disk,
|
||||
/**
|
||||
* Return VM usage requirments
|
||||
*/
|
||||
void get_requirements(int& cpu, int& memory, long long& disk,
|
||||
vector<VectorAttribute *> &pci);
|
||||
|
||||
/**
|
||||
* Return the requirements of this VM (as is) and reset them
|
||||
* @param cpu in unit
|
||||
* @param memory in kb
|
||||
* @param disk in mb (system ds usage)
|
||||
*/
|
||||
void reset_requirements(float& cpu, int& memory, long long& disk);
|
||||
|
||||
/**
|
||||
* @return the usage requirements in image ds.
|
||||
*/
|
||||
map<int,long long> get_storage_usage();
|
||||
|
||||
/**
|
||||
@ -130,10 +143,45 @@ public:
|
||||
return public_cloud;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds usage requirements to this VM
|
||||
* @param cpu in unit form
|
||||
* @param m memory in kb
|
||||
* @param d in mb (system ds usage)
|
||||
*/
|
||||
void add_requirements(float c, int m, long long d);
|
||||
|
||||
/**
|
||||
* Adds (logical AND) new placement requirements to the current ones
|
||||
* @param reqs additional requirements
|
||||
*/
|
||||
void add_requirements(const string& reqs)
|
||||
{
|
||||
if ( reqs.empty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if ( requirements.empty() )
|
||||
{
|
||||
requirements = reqs;
|
||||
}
|
||||
else
|
||||
{
|
||||
requirements += " & (" + reqs + ")";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the VM is ACTIVE state
|
||||
*/
|
||||
bool is_active() const
|
||||
{
|
||||
return state == 3;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Matched Resources Interface
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Adds a matching host if it is not equal to the actual one
|
||||
* @param oid of the host
|
||||
@ -214,6 +262,23 @@ public:
|
||||
*/
|
||||
bool is_only_public_cloud() const;
|
||||
|
||||
/**
|
||||
* Add a VM to the set of affined VMs. This is used for the VM leader
|
||||
* when scheduling a group.
|
||||
*
|
||||
* @param vmid of the affined vm
|
||||
*
|
||||
*/
|
||||
void add_affined(int vmid)
|
||||
{
|
||||
affined_vms.insert(vmid);
|
||||
}
|
||||
|
||||
const set<int>& get_affined_vms() const
|
||||
{
|
||||
return affined_vms;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Capacity Interface
|
||||
//--------------------------------------------------------------------------
|
||||
@ -313,12 +378,16 @@ protected:
|
||||
|
||||
void init_storage_usage();
|
||||
|
||||
/* ------------------- SCHEDULER INFORMATION --------------------------- */
|
||||
|
||||
ResourceMatch match_hosts;
|
||||
|
||||
ResourceMatch match_datastores;
|
||||
|
||||
bool only_public_cloud;
|
||||
|
||||
set<int> affined_vms;
|
||||
|
||||
/* ----------------------- VIRTUAL MACHINE ATTRIBUTES ------------------- */
|
||||
int oid;
|
||||
|
||||
@ -331,6 +400,8 @@ protected:
|
||||
int resched;
|
||||
bool resume;
|
||||
|
||||
int state;
|
||||
|
||||
int memory;
|
||||
float cpu;
|
||||
long long system_ds_usage;
|
||||
@ -347,6 +418,7 @@ protected:
|
||||
|
||||
VirtualMachineTemplate * vm_template; /**< The VM template */
|
||||
VirtualMachineTemplate * user_template; /**< The VM user template */
|
||||
|
||||
};
|
||||
|
||||
#endif /* VM_XML_H_ */
|
||||
|
@ -28,6 +28,8 @@ source_files=[
|
||||
'VirtualMachineXML.cc',
|
||||
'ClusterPoolXML.cc',
|
||||
'UserPoolXML.cc',
|
||||
'VMGroupPoolXML.cc',
|
||||
'VMGroupXML.cc',
|
||||
'DatastorePoolXML.cc',
|
||||
'DatastoreXML.cc']
|
||||
|
||||
|
50
src/scheduler/src/pool/VMGroupPoolXML.cc
Normal file
50
src/scheduler/src/pool/VMGroupPoolXML.cc
Normal file
@ -0,0 +1,50 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2016, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* 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 "VMGroupPoolXML.h"
|
||||
|
||||
void VMGroupPoolXML::add_object(xmlNodePtr node)
|
||||
{
|
||||
if ( node == 0 || node->children == 0 )
|
||||
{
|
||||
NebulaLog::log("VM_GROUP", Log::ERROR, "XML Node does not represent a "
|
||||
"valid user");
|
||||
return;
|
||||
}
|
||||
|
||||
VMGroupXML * vmg = new VMGroupXML(node);
|
||||
|
||||
objects.insert( pair<int,ObjectXML*>(vmg->get_oid(), vmg) );
|
||||
}
|
||||
|
||||
int VMGroupPoolXML::load_info(xmlrpc_c::value &result)
|
||||
{
|
||||
try
|
||||
{
|
||||
client->call("one.vmgrouppool.info", "iii", &result, -2, -1, -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch (exception const& e)
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << "Exception raised: " << e.what();
|
||||
|
||||
NebulaLog::log("VMGROUP", Log::ERROR, oss);
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
524
src/scheduler/src/pool/VMGroupXML.cc
Normal file
524
src/scheduler/src/pool/VMGroupXML.cc
Normal file
@ -0,0 +1,524 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2016, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* 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 "VMGroupXML.h"
|
||||
#include "VirtualMachinePoolXML.h"
|
||||
#include <iomanip>
|
||||
|
||||
static ostream& operator<<(ostream& os, VMGroupRule::rule_set rules);
|
||||
|
||||
void VMGroupXML::init_attributes()
|
||||
{
|
||||
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);
|
||||
|
||||
if (!content.empty())
|
||||
{
|
||||
roles.from_xml_node(content[0]);
|
||||
}
|
||||
|
||||
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(VMGroupPolicy::AFFINED, id_set);
|
||||
|
||||
affined.insert(rule);
|
||||
}
|
||||
|
||||
srules.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(VMGroupPolicy::ANTI_AFFINED, id_set);
|
||||
|
||||
anti_affined.insert(rule);
|
||||
}
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VMGroupXML::set_antiaffinity_requirements(VirtualMachinePoolXML * vmpool,
|
||||
std::ostringstream& oss)
|
||||
{
|
||||
VMGroupRoles::role_iterator it;
|
||||
|
||||
oss << "\n";
|
||||
oss << setfill('-') << setw(80) << '-' << setfill(' ') << "\n";
|
||||
oss << "Intra-role Anti-affinity rules \n";
|
||||
oss << left << setw(8)<< "ROLE" << " " << left << setw(8) <<"VM"
|
||||
<< " " << left << "ANTI_AFFINITY REQUIRMENTS\n"
|
||||
<< setfill('-') << setw(80) << '-' << setfill(' ') << "\n";
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Intra-role anti-affinity placement rule */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
for ( it = roles.begin(); it != roles.end() ; ++it )
|
||||
{
|
||||
VMGroupRole * r = *it;
|
||||
|
||||
if ( r->policy() != VMGroupPolicy::ANTI_AFFINED || r->size_vms() <= 1 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::set<int>& vms = r->get_vms();
|
||||
std::set<int>::const_iterator jt;
|
||||
|
||||
for ( jt = vms.begin() ; jt != vms.end(); ++jt )
|
||||
{
|
||||
std::string reqs;
|
||||
|
||||
VirtualMachineXML * vm = vmpool->get(*jt);
|
||||
|
||||
if ( vm == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
r->vm_role_requirements(*jt, reqs);
|
||||
|
||||
if ( !reqs.empty() )
|
||||
{
|
||||
vm->add_requirements(reqs);
|
||||
}
|
||||
|
||||
oss << left << setw(8) << r->id() << left << setw(8) << *jt << reqs
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Inter-role anti-affinity placement rule */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
oss << "\n";
|
||||
oss << setfill('-') << setw(80) << '-' << setfill(' ') << "\n";
|
||||
oss << "Inter-role Anti-affinity rules \n";
|
||||
oss << left << setw(8)<< "ROLE" << " " << left << setw(8) <<"VM"
|
||||
<< " " << left << "ANTI_AFFINITY REQUIRMENTS\n"
|
||||
<< setfill('-') << setw(80) << '-' << setfill(' ') << "\n";
|
||||
VMGroupRule::rule_set::iterator rt;
|
||||
|
||||
for ( rt = anti_affined.begin() ; rt != anti_affined.end() ; ++rt )
|
||||
{
|
||||
VMGroupRule::role_bitset rroles = (*rt).get_roles();
|
||||
|
||||
for ( int i=0 ; i < VMGroupRoles::MAX_ROLES; ++i)
|
||||
{
|
||||
string role_reqs;
|
||||
|
||||
if ( rroles[i] == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( int j = 0 ; j < VMGroupRoles::MAX_ROLES ; ++j )
|
||||
{
|
||||
if ( j == i || rroles[j] == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
VMGroupRole * r = roles.get(j);
|
||||
|
||||
if ( r == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string reqs;
|
||||
|
||||
r->role_requirements(VMGroupPolicy::ANTI_AFFINED, reqs);
|
||||
|
||||
if ( reqs.empty() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( role_reqs.empty() )
|
||||
{
|
||||
role_reqs = reqs;
|
||||
}
|
||||
else
|
||||
{
|
||||
role_reqs += " & " + reqs;
|
||||
}
|
||||
}
|
||||
|
||||
VMGroupRole * r = roles.get(i);
|
||||
|
||||
const std::set<int>& vms = r->get_vms();
|
||||
std::set<int>::const_iterator vt;
|
||||
|
||||
for ( vt=vms.begin() ; vt!=vms.end(); ++vt )
|
||||
{
|
||||
VirtualMachineXML * vm = vmpool->get(*vt);
|
||||
|
||||
if ( vm == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
vm->add_requirements(role_reqs);
|
||||
|
||||
oss << left << setw(8) << r->id() << left << setw(8) << *vt
|
||||
<< vm->get_requirements() << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VMGroupXML::set_host_requirements(VirtualMachinePoolXML * vmpool,
|
||||
std::ostringstream& oss)
|
||||
{
|
||||
VMGroupRoles::role_iterator it;
|
||||
|
||||
oss << "\n";
|
||||
oss << setfill('-') << setw(80) << '-' << setfill(' ') << "\n";
|
||||
oss << "Host affinity rules \n";
|
||||
oss << left << setw(8)<< "ROLE" << " " << left << setw(8) <<"VM"
|
||||
<< " " << left << "AFFINITY REQUIRMENTS\n"
|
||||
<< setfill('-') << setw(80) << '-' << setfill(' ') << "\n";
|
||||
|
||||
for ( it = roles.begin(); it != roles.end() ; ++it )
|
||||
{
|
||||
std::string areqs, aareqs;
|
||||
|
||||
VMGroupRole * r = *it;
|
||||
|
||||
r->affined_host_requirements(areqs);
|
||||
|
||||
r->antiaffined_host_requirements(aareqs);
|
||||
|
||||
if ( r->size_vms() == 0 || (areqs.empty() && aareqs.empty()) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::set<int>& vms = r->get_vms();
|
||||
|
||||
for (std::set<int>::const_iterator jt=vms.begin(); jt!=vms.end(); ++jt)
|
||||
{
|
||||
VirtualMachineXML * vm = vmpool->get(*jt);
|
||||
|
||||
if ( vm == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !areqs.empty() )
|
||||
{
|
||||
vm->add_requirements(areqs);
|
||||
}
|
||||
|
||||
if ( !aareqs.empty() )
|
||||
{
|
||||
vm->add_requirements(aareqs);
|
||||
}
|
||||
|
||||
oss << left << setw(8) << r->id() << left << setw(8) << *jt
|
||||
<< vm->get_requirements() << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static void schecule_affined_set(const std::set<int>& vms,
|
||||
VirtualMachinePoolXML * vmpool, VirtualMachineRolePoolXML * vm_roles_pool,
|
||||
std::ostringstream& oss)
|
||||
{
|
||||
std::set<int>::iterator it;
|
||||
std::set<int> hosts;
|
||||
|
||||
if ( vms.size() <= 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Get hosts where the affined set is running */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
for ( it = vms.begin() ; it != vms.end() ; ++it )
|
||||
{
|
||||
VirtualMachineXML * vm = vm_roles_pool->get(*it);
|
||||
|
||||
if ( vm == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int hid = vm->get_hid();
|
||||
|
||||
if ( vm->is_active() && hid != -1 )
|
||||
{
|
||||
hosts.insert(hid);
|
||||
}
|
||||
}
|
||||
|
||||
if ( hosts.size() == 0 )
|
||||
{
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* No VMs of the set are running: */
|
||||
/* 1. Select a set leader */
|
||||
/* 2. Allocate VMs in the same host as the leader */
|
||||
/* 3. Aggregate requirements in the leader for scheduling */
|
||||
/* ------------------------------------------------------------------ */
|
||||
VirtualMachineXML * vm;
|
||||
|
||||
for ( it = vms.begin(); it != vms.end() ; ++it )
|
||||
{
|
||||
vm = vmpool->get(*it);
|
||||
|
||||
if ( vm != 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( vm == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::ostringstream areqs;
|
||||
std::string areqs_s;
|
||||
|
||||
areqs << "CURRENT_VMS = " << *it;
|
||||
areqs_s = areqs.str();
|
||||
|
||||
for ( ++it ; it != vms.end() ; ++it )
|
||||
{
|
||||
float cpu;
|
||||
int memory;
|
||||
|
||||
long long disk;
|
||||
|
||||
VirtualMachineXML * tmp = vmpool->get(*it);
|
||||
|
||||
if ( tmp == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp->reset_requirements(cpu, memory, disk);
|
||||
|
||||
vm->add_requirements(cpu, memory, disk);
|
||||
vm->add_requirements(tmp->get_requirements());
|
||||
vm->add_affined(*it);
|
||||
|
||||
tmp->add_requirements(areqs_s);
|
||||
|
||||
oss << left << setw(8) << tmp->get_oid() << " "
|
||||
<< tmp->get_requirements() << "\n";
|
||||
}
|
||||
|
||||
oss << left << setw(8) << vm->get_oid() << " "
|
||||
<< vm->get_requirements() << "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* VMs in the group already running */
|
||||
/* 1. Assign VMs to one of the hosts used by the affined set */
|
||||
/* ------------------------------------------------------------------ */
|
||||
std::ostringstream oss_reqs;
|
||||
std::string reqs;
|
||||
|
||||
VMGroupRole::host_requirements(hosts, "=", "|", oss_reqs);
|
||||
|
||||
reqs = oss_reqs.str();
|
||||
|
||||
for ( it = vms.begin() ; it != vms.end() ; ++it )
|
||||
{
|
||||
VirtualMachineXML * vm = vmpool->get(*it);
|
||||
|
||||
if ( vm == 0 || reqs.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
vm->add_requirements(reqs);
|
||||
|
||||
oss << left << setw(8) << vm->get_oid() << " "
|
||||
<< vm->get_requirements() << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VMGroupXML::set_affinity_requirements(VirtualMachinePoolXML * vmpool,
|
||||
VirtualMachineRolePoolXML * vm_roles_pool, std::ostringstream& oss)
|
||||
{
|
||||
VMGroupRoles::role_iterator it;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Intra-role affinity placement rule */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
oss << "\n";
|
||||
oss << setfill('-') << setw(80) << '-' << setfill(' ') << "\n";
|
||||
oss << "Intra-role affinity requirements\n";
|
||||
oss << left << setw(8) << "VMID" << " " << left << "REQUIREMENTS\n";
|
||||
oss << setfill('-') << setw(80) << '-' << setfill(' ') << "\n";
|
||||
|
||||
for ( it = roles.begin(); it != roles.end() ; ++it )
|
||||
{
|
||||
VMGroupRole * r = *it;
|
||||
|
||||
if ( r->policy() != VMGroupPolicy::AFFINED || r->size_vms() <= 1 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::set<int>& vms = r->get_vms();
|
||||
|
||||
schecule_affined_set(vms, vmpool, vm_roles_pool, oss);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Inter-role affinity placement rule */
|
||||
/* 1. Build the reduced set of affinity rules */
|
||||
/* 2. Build the set of VMs affected by each rule */
|
||||
/* 3. Schedule the resulting set */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
VMGroupRule::rule_set reduced;
|
||||
VMGroupRule::rule_set::iterator rit;
|
||||
|
||||
oss << "\n";
|
||||
oss << setfill('-') << setw(80) << '-' << setfill(' ') << "\n";
|
||||
oss << "Inter-role affinity requirements\n";
|
||||
oss << left << setw(8) << "VMID" << " " << left << "REQUIREMENTS\n";
|
||||
oss << setfill('-') << setw(80) << '-' << setfill(' ') << "\n";
|
||||
|
||||
VMGroupRule::reduce(affined, reduced);
|
||||
|
||||
for ( rit = reduced.begin() ; rit != reduced.end(); ++rit )
|
||||
{
|
||||
const VMGroupRule::role_bitset rroles = (*rit).get_roles();
|
||||
std::set<int> rule_vms;
|
||||
|
||||
for (int i = 0 ; i <VMGroupRoles::MAX_ROLES ; ++i)
|
||||
{
|
||||
if ( rroles[i] == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
VMGroupRole * r = roles.get(i);
|
||||
|
||||
if ( r == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::set<int>& role_vms = r->get_vms();
|
||||
|
||||
rule_vms.insert(role_vms.begin(), role_vms.end());
|
||||
}
|
||||
|
||||
schecule_affined_set(rule_vms, vmpool, vm_roles_pool, oss);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static ostream& operator<<(ostream& os, VMGroupRule::rule_set rules)
|
||||
{
|
||||
VMGroupRule::rule_set::iterator rit;
|
||||
|
||||
for ( rit = rules.begin() ; rit != rules.end(); ++rit )
|
||||
{
|
||||
const VMGroupRule::role_bitset rroles = (*rit).get_roles();
|
||||
|
||||
os << left << setw(14) << (*rit).get_policy() << " ";
|
||||
|
||||
for (int i = 0 ; i <VMGroupRoles::MAX_ROLES ; ++i)
|
||||
{
|
||||
if ( rroles[i] == 1 )
|
||||
{
|
||||
os << right << setw(2) << i << " ";
|
||||
}
|
||||
}
|
||||
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
ostream& operator<<(ostream& os, VMGroupXML& vmg)
|
||||
{
|
||||
VMGroupRoles::role_iterator it;
|
||||
|
||||
os << left << setw(7)<< "ROLE ID" << " " << left << setw(8) << "NAME" << " "
|
||||
<< setw(12) << "POLICY" << " " << left << "VMS\n"
|
||||
<< setfill('-') << setw(80) << '-' << setfill(' ') << "\n";
|
||||
|
||||
for ( it = vmg.roles.begin() ; it != vmg.roles.end() ; ++it )
|
||||
{
|
||||
os << left << setw(7) << (*it)->id() << " "
|
||||
<< left << setw(8) << (*it)->name() << " "
|
||||
<< left << setw(12)<< (*it)->policy_s() << " "
|
||||
<< left << (*it)->vms_s() << "\n";
|
||||
}
|
||||
|
||||
os << "\n";
|
||||
os << left << "RULES" << "\n"
|
||||
<< setfill('-') << setw(80) << '-' << setfill(' ') << "\n";
|
||||
|
||||
os << vmg.affined;
|
||||
|
||||
os << vmg.anti_affined;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -33,6 +33,8 @@ int VirtualMachinePoolXML::set_up()
|
||||
|
||||
if (NebulaLog::log_level() >= Log::DDDEBUG)
|
||||
{
|
||||
map<int,ObjectXML*>::iterator it;
|
||||
|
||||
oss << "Pending/rescheduling VM and capacity requirements:" << endl;
|
||||
|
||||
oss << right << setw(8) << "ACTION" << " "
|
||||
@ -44,7 +46,7 @@ int VirtualMachinePoolXML::set_up()
|
||||
<< " Image DS" << endl
|
||||
<< setw(60) << setfill('-') << "-" << setfill(' ') << endl;
|
||||
|
||||
for (map<int,ObjectXML*>::iterator it=objects.begin();it!=objects.end();it++)
|
||||
for (it = objects.begin() ; it != objects.end() ; ++it)
|
||||
{
|
||||
int cpu, mem;
|
||||
long long disk;
|
||||
@ -52,7 +54,9 @@ int VirtualMachinePoolXML::set_up()
|
||||
|
||||
string action = "DEPLOY";
|
||||
|
||||
VirtualMachineXML * vm = static_cast<VirtualMachineXML *>(it->second);
|
||||
VirtualMachineXML * vm;
|
||||
|
||||
vm = static_cast<VirtualMachineXML *>(it->second);
|
||||
|
||||
vm->get_requirements(cpu, mem, disk, pci);
|
||||
|
||||
@ -73,11 +77,11 @@ int VirtualMachinePoolXML::set_up()
|
||||
<< right << setw(11) << disk << " ";
|
||||
|
||||
map<int,long long> ds_usage = vm->get_storage_usage();
|
||||
map<int,long long>::const_iterator ds_it;
|
||||
|
||||
for (map<int,long long>::const_iterator ds_it = ds_usage.begin();
|
||||
ds_it != ds_usage.end(); ds_it++)
|
||||
for ( ds_it = ds_usage.begin(); ds_it != ds_usage.end(); ds_it++)
|
||||
{
|
||||
oss << " DS " << ds_it->first << ": " << ds_it->second << " ";
|
||||
oss << " DS " << ds_it->first << ": " << ds_it->second <<" ";
|
||||
}
|
||||
|
||||
oss << endl;
|
||||
@ -231,6 +235,7 @@ int VirtualMachinePoolXML::update(int vid, const string &st) const
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@ -263,6 +268,7 @@ int VirtualMachineActionsPoolXML::set_up()
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@ -304,3 +310,30 @@ int VirtualMachineActionsPoolXML::action(
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachineRolePoolXML::set_up()
|
||||
{
|
||||
int rc = PoolXML::set_up();
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "VMs in VMGroups:" << endl;
|
||||
|
||||
map<int,ObjectXML*>::iterator it;
|
||||
|
||||
for (it=objects.begin();it!=objects.end();it++)
|
||||
{
|
||||
oss << " " << it->first;
|
||||
}
|
||||
|
||||
NebulaLog::log("VM", Log::DEBUG, oss);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,8 @@ void VirtualMachineXML::init_attributes()
|
||||
xpath(uid, "/VM/UID", -1);
|
||||
xpath(gid, "/VM/GID", -1);
|
||||
|
||||
xpath(state, "/VM/STATE", -1);
|
||||
|
||||
xpath(memory, "/VM/TEMPLATE/MEMORY", 0);
|
||||
xpath<float>(cpu, "/VM/TEMPLATE/CPU", 0);
|
||||
|
||||
@ -202,6 +204,30 @@ ostream& operator<<(ostream& os, VirtualMachineXML& vm)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachineXML::add_requirements(float c, int m, long long d)
|
||||
{
|
||||
cpu += c;
|
||||
memory += m;
|
||||
system_ds_usage += d;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachineXML::reset_requirements(float& c, int& m, long long& d)
|
||||
{
|
||||
c = cpu;
|
||||
m = memory;
|
||||
d = system_ds_usage;
|
||||
|
||||
cpu = 0;
|
||||
memory = 0;
|
||||
system_ds_usage = 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachineXML::get_requirements (int& cpu, int& memory,
|
||||
long long& disk, vector<VectorAttribute *> &pci)
|
||||
{
|
||||
@ -406,14 +432,14 @@ int VirtualMachineXML::parse_action_name(string& action_st)
|
||||
bool VirtualMachineXML::test_image_datastore_capacity(
|
||||
ImageDatastorePoolXML * img_dspool, string & error_msg) const
|
||||
{
|
||||
map<int,long long>::const_iterator ds_usage_it;
|
||||
map<int,long long>::const_iterator ds_it;
|
||||
DatastoreXML* ds;
|
||||
|
||||
for (ds_usage_it = ds_usage.begin(); ds_usage_it != ds_usage.end(); ds_usage_it++)
|
||||
for (ds_it = ds_usage.begin(); ds_it != ds_usage.end(); ++ds_it)
|
||||
{
|
||||
ds = img_dspool->get(ds_usage_it->first);
|
||||
ds = img_dspool->get(ds_it->first);
|
||||
|
||||
if (ds == 0 || !ds->test_capacity(ds_usage_it->second))
|
||||
if (ds == 0 || !ds->test_capacity(ds_it->second))
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
@ -434,20 +460,20 @@ bool VirtualMachineXML::test_image_datastore_capacity(
|
||||
void VirtualMachineXML::add_image_datastore_capacity(
|
||||
ImageDatastorePoolXML * img_dspool)
|
||||
{
|
||||
map<int,long long>::const_iterator ds_usage_it;
|
||||
map<int,long long>::const_iterator ds_it;
|
||||
|
||||
DatastoreXML *ds;
|
||||
|
||||
for (ds_usage_it = ds_usage.begin(); ds_usage_it != ds_usage.end(); ds_usage_it++)
|
||||
for (ds_it = ds_usage.begin(); ds_it != ds_usage.end(); ++ds_it)
|
||||
{
|
||||
ds = img_dspool->get(ds_usage_it->first);
|
||||
ds = img_dspool->get(ds_it->first);
|
||||
|
||||
if (ds == 0) //Should never reach here
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ds->add_capacity(ds_usage_it->second);
|
||||
ds->add_capacity(ds_it->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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',
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <pthread.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <iomanip>
|
||||
|
||||
#include "Scheduler.h"
|
||||
#include "SchedulerTemplate.h"
|
||||
@ -308,19 +309,23 @@ void Scheduler::start()
|
||||
// -------------------------------------------------------------------------
|
||||
// Pools
|
||||
// -------------------------------------------------------------------------
|
||||
Client * client = 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);
|
||||
acls = new AclXML(client, zone_id);
|
||||
upool = new UserPoolXML(client);
|
||||
|
||||
vmapool = new VirtualMachineActionsPoolXML(Client::client(), machines_limit);
|
||||
hpool = new HostPoolXML(client);
|
||||
clpool = new ClusterPoolXML(client);
|
||||
|
||||
dspool = new SystemDatastorePoolXML(Client::client());
|
||||
img_dspool = new ImageDatastorePoolXML(Client::client());
|
||||
dspool = new SystemDatastorePoolXML(client);
|
||||
img_dspool = new ImageDatastorePoolXML(client);
|
||||
|
||||
acls = new AclXML(Client::client(), zone_id);
|
||||
vm_roles_pool = new VirtualMachineRolePoolXML(client, machines_limit);
|
||||
vmpool = new VirtualMachinePoolXML(client, machines_limit, live_rescheds==1);
|
||||
|
||||
vmgpool = new VMGroupPoolXML(client);
|
||||
|
||||
vmapool = new VirtualMachineActionsPoolXML(client, machines_limit);
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Load scheduler policies
|
||||
@ -407,7 +412,7 @@ int Scheduler::set_up_pools()
|
||||
map<int, int> shares;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//Cleans the cache and get the pending VMs
|
||||
//Cleans the cache and get the pools
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
rc = vmpool->set_up();
|
||||
@ -417,10 +422,6 @@ int Scheduler::set_up_pools()
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//Cleans the cache and get the datastores
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
rc = dspool->set_up();
|
||||
|
||||
if ( rc != 0 )
|
||||
@ -435,10 +436,6 @@ int Scheduler::set_up_pools()
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//Cleans the cache and get the hosts ids
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
rc = upool->set_up();
|
||||
|
||||
if ( rc != 0 )
|
||||
@ -446,10 +443,6 @@ int Scheduler::set_up_pools()
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//Cleans the cache and get the hosts ids
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
rc = hpool->set_up();
|
||||
|
||||
if ( rc != 0 )
|
||||
@ -457,10 +450,6 @@ int Scheduler::set_up_pools()
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//Cleans the cache and get the cluster information
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
rc = clpool->set_up();
|
||||
|
||||
if ( rc != 0 )
|
||||
@ -468,16 +457,8 @@ int Scheduler::set_up_pools()
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//Add to each host the corresponding cluster template
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
hpool->merge_clusters(clpool);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//Cleans the cache and get the ACLs
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
rc = acls->set_up();
|
||||
|
||||
if ( rc != 0 )
|
||||
@ -485,6 +466,20 @@ int Scheduler::set_up_pools()
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = vmgpool->set_up();
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = vm_roles_pool->set_up();
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
@ -603,7 +598,8 @@ static bool match_host(AclXML * acls, UserPoolXML * upool, VirtualMachineXML* vm
|
||||
|
||||
if (matched == false)
|
||||
{
|
||||
error = "It does not fulfill SCHED_REQUIREMENTS.";
|
||||
error = "It does not fulfill SCHED_REQUIREMENTS: " +
|
||||
vm->get_requirements();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -878,7 +874,8 @@ void Scheduler::match_schedule()
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
log_match(vm->get_oid(), "Cannot schedule VM, there is no suitable host.");
|
||||
log_match(vm->get_oid(),
|
||||
"Cannot schedule VM, there is no suitable host.");
|
||||
|
||||
continue;
|
||||
}
|
||||
@ -1022,13 +1019,20 @@ void Scheduler::match_schedule()
|
||||
ostringstream oss;
|
||||
|
||||
oss << "Match Making statistics:\n"
|
||||
<< "\tNumber of VMs: " << pending_vms.size() << endl
|
||||
<< "\tTotal time: " << one_util::float_to_str(time(0) - stime) << "s" << endl
|
||||
<< "\tTotal Cluster Match time: " << one_util::float_to_str(total_cl_match_time) << "s" << endl
|
||||
<< "\tTotal Host Match time: " << one_util::float_to_str(total_host_match_time) << "s" << endl
|
||||
<< "\tTotal Host Ranking time: " << one_util::float_to_str(total_host_rank_time) << "s" << endl
|
||||
<< "\tTotal DS Match time: " << one_util::float_to_str(total_ds_match_time) << "s" << endl
|
||||
<< "\tTotal DS Ranking time: " << one_util::float_to_str(total_ds_rank_time) << "s" << endl;
|
||||
<< "\tNumber of VMs: "
|
||||
<< pending_vms.size() << endl
|
||||
<< "\tTotal time: "
|
||||
<< one_util::float_to_str(time(0) - stime) << "s" << endl
|
||||
<< "\tTotal Cluster Match time: "
|
||||
<< one_util::float_to_str(total_cl_match_time) << "s" << endl
|
||||
<< "\tTotal Host Match time: "
|
||||
<< one_util::float_to_str(total_host_match_time) << "s" << endl
|
||||
<< "\tTotal Host Ranking time: "
|
||||
<< one_util::float_to_str(total_host_rank_time) << "s" << endl
|
||||
<< "\tTotal DS Match time: "
|
||||
<< one_util::float_to_str(total_ds_match_time) << "s" << endl
|
||||
<< "\tTotal DS Ranking time: "
|
||||
<< one_util::float_to_str(total_ds_rank_time) << "s" << endl;
|
||||
|
||||
NebulaLog::log("SCHED", Log::DDEBUG, oss);
|
||||
}
|
||||
@ -1070,10 +1074,8 @@ void Scheduler::dispatch()
|
||||
int hid, dsid, cid;
|
||||
|
||||
unsigned int dispatched_vms = 0;
|
||||
bool dispatched;
|
||||
|
||||
map<int, unsigned int> host_vms;
|
||||
pair<map<int,unsigned int>::iterator, bool> rc;
|
||||
bool dispatched, matched;
|
||||
char * estr;
|
||||
|
||||
map<int, ObjectXML*>::const_iterator vm_it;
|
||||
|
||||
@ -1138,6 +1140,32 @@ void Scheduler::dispatch()
|
||||
|
||||
cid = host->get_cid();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Check host still match requirements with CURRENT_VMS
|
||||
//------------------------------------------------------------------
|
||||
matched = true;
|
||||
|
||||
if ( one_util::regex_match("CURRENT_VMS",
|
||||
vm->get_requirements().c_str()) == 0 )
|
||||
{
|
||||
if (host->eval_bool(vm->get_requirements(), matched, &estr)!=0)
|
||||
{
|
||||
free(estr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (matched == false)
|
||||
{
|
||||
std::ostringstream mss;
|
||||
|
||||
mss << "Host " << hid << " no longer meets requirements for VM "
|
||||
<< vm->get_oid();
|
||||
|
||||
NebulaLog::log("SCHED", Log::DEBUG, mss);
|
||||
continue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Test host capacity
|
||||
//------------------------------------------------------------------
|
||||
@ -1155,11 +1183,9 @@ void Scheduler::dispatch()
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Test host dispatch limit (init counter if needed)
|
||||
// Test host dispatch limit
|
||||
//------------------------------------------------------------------
|
||||
rc = host_vms.insert(make_pair(hid,0));
|
||||
|
||||
if (rc.first->second >= host_dispatch_limit)
|
||||
if (host->dispatched() >= host_dispatch_limit)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -1277,9 +1303,33 @@ void Scheduler::dispatch()
|
||||
}
|
||||
}
|
||||
|
||||
host->add_capacity(vm->get_oid(), cpu, mem, pci);
|
||||
//------------------------------------------------------------------
|
||||
// VM leaders needs to add the select host to the affined VMs
|
||||
//------------------------------------------------------------------
|
||||
const set<int>& affined_vms = vm->get_affined_vms();
|
||||
|
||||
host_vms[hid]++;
|
||||
if ( affined_vms.size() > 0 )
|
||||
{
|
||||
set<int>::const_iterator it;
|
||||
|
||||
for ( it = affined_vms.begin(); it != affined_vms.end(); ++it )
|
||||
{
|
||||
VirtualMachineXML * avm = vmpool->get(*it);
|
||||
|
||||
if ( avm == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
avm->add_match_host(hid);
|
||||
avm->add_match_datastore(dsid);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Update usage and statistics counters
|
||||
//------------------------------------------------------------------
|
||||
host->add_capacity(vm->get_oid(), cpu, mem, pci);
|
||||
|
||||
dispatched_vms++;
|
||||
|
||||
@ -1405,6 +1455,39 @@ int Scheduler::do_scheduled_actions()
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void Scheduler::do_vm_groups()
|
||||
{
|
||||
map<int, ObjectXML*>::const_iterator it;
|
||||
const map<int, ObjectXML*> vmgrps = vmgpool->get_objects();
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
oss << "VM Group Scheduling information\n";
|
||||
|
||||
for (it = vmgrps.begin(); it != vmgrps.end() ; ++it)
|
||||
{
|
||||
VMGroupXML * grp = static_cast<VMGroupXML*>(it->second);
|
||||
|
||||
oss << setfill('*') << setw(80) << '*' << setfill(' ') << "\n"
|
||||
<< "SCHEDULING RESULTS FOR VM GROUP " << grp->get_oid() << ", "
|
||||
<< grp->get_name() <<"\n"
|
||||
<< setfill('*') << setw(80) << '*' << setfill(' ') << "\n";
|
||||
|
||||
oss << *grp << "\n";
|
||||
|
||||
grp->set_affinity_requirements(vmpool, vm_roles_pool, oss);
|
||||
|
||||
grp->set_antiaffinity_requirements(vmpool, oss);
|
||||
|
||||
grp->set_host_requirements(vmpool, oss);
|
||||
}
|
||||
|
||||
NebulaLog::log("VMGRP", Log::DDDEBUG, oss);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void Scheduler::do_action(const string &name, void *args)
|
||||
{
|
||||
int rc;
|
||||
@ -1431,6 +1514,10 @@ void Scheduler::do_action(const string &name, void *args)
|
||||
return;
|
||||
}
|
||||
|
||||
profile(true);
|
||||
do_vm_groups();
|
||||
profile(false,"Setting VM groups placement constraints.");
|
||||
|
||||
match_schedule();
|
||||
|
||||
profile(true);
|
||||
|
@ -56,6 +56,8 @@ SecurityGroup::SecurityGroup(
|
||||
{
|
||||
obj_template = new Template;
|
||||
}
|
||||
|
||||
set_umask(_umask);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -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();
|
||||
@ -1909,6 +1913,15 @@ void VirtualMachine::set_auth_request(int uid,
|
||||
{
|
||||
(*nic)->authorize(uid, &ar);
|
||||
}
|
||||
|
||||
const VectorAttribute * vmgroup = tmpl->get("VMGROUP");
|
||||
|
||||
if ( vmgroup != 0 )
|
||||
{
|
||||
VMGroupPool * vmgrouppool = Nebula::instance().get_vmgrouppool();
|
||||
|
||||
vmgrouppool->authorize(vmgroup, uid, &ar);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -2883,6 +2896,74 @@ 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;
|
||||
}
|
||||
|
||||
VMGroupPool * vmgrouppool = Nebula::instance().get_vmgrouppool();
|
||||
int rc;
|
||||
|
||||
rc = vmgrouppool->vmgroup_attribute(thegroup, get_uid(), get_oid(), error);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
delete thegroup;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
obj_template->set(thegroup);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachine::release_vmgroup()
|
||||
{
|
||||
VectorAttribute * thegroup = obj_template->get("VMGROUP");
|
||||
|
||||
if ( thegroup == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VMGroupPool * vmgrouppool = Nebula::instance().get_vmgrouppool();
|
||||
|
||||
vmgrouppool->del_vm(thegroup, get_oid());
|
||||
}
|
||||
|
||||
|
42
src/vm_group/SConstruct
Normal file
42
src/vm_group/SConstruct
Normal file
@ -0,0 +1,42 @@
|
||||
# SConstruct for src/secgroup
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
Import('env')
|
||||
|
||||
lib_name='nebula_vmgroup'
|
||||
|
||||
# Sources to generate the library
|
||||
source_files=[
|
||||
'VMGroupPool.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)
|
485
src/vm_group/VMGroup.cc
Normal file
485
src/vm_group/VMGroup.cc
Normal file
@ -0,0 +1,485 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* 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"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* VMGroup */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
const char * VMGroup::table = "vmgroup_pool";
|
||||
|
||||
const char * VMGroup::db_names = "oid, name, body, uid, gid, owner_u, group_u, "
|
||||
"other_u";
|
||||
|
||||
const char * VMGroup::db_bootstrap = "CREATE TABLE IF NOT EXISTS vmgroup_pool "
|
||||
"(oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, "
|
||||
"uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, "
|
||||
"other_u INTEGER, UNIQUE(name,uid))";
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
VMGroup::VMGroup(int _uid, int _gid, const string& _uname, const string& _gname,
|
||||
int _umask, Template * group_template):
|
||||
PoolObjectSQL(-1, VMGROUP, "", _uid, _gid, _uname, _gname, table)
|
||||
{
|
||||
if (group_template != 0)
|
||||
{
|
||||
obj_template = group_template;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj_template = new Template;
|
||||
}
|
||||
|
||||
set_umask(_umask);
|
||||
}
|
||||
|
||||
VMGroup::~VMGroup()
|
||||
{
|
||||
delete obj_template;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
string& VMGroup::to_xml(string& xml) const
|
||||
{
|
||||
ostringstream oss;
|
||||
string template_xml;
|
||||
string perms_xml;
|
||||
string roles_xml;
|
||||
|
||||
oss <<
|
||||
"<VM_GROUP>" <<
|
||||
"<ID>" << oid << "</ID>" <<
|
||||
"<UID>" << uid << "</UID>" <<
|
||||
"<GID>" << gid << "</GID>" <<
|
||||
"<UNAME>" << uname << "</UNAME>" <<
|
||||
"<GNAME>" << gname << "</GNAME>" <<
|
||||
"<NAME>" << name << "</NAME>" <<
|
||||
perms_to_xml(perms_xml) <<
|
||||
roles.to_xml(roles_xml) <<
|
||||
obj_template->to_xml(template_xml) <<
|
||||
"</VM_GROUP>";
|
||||
|
||||
xml = oss.str();
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VMGroup::from_xml(const string &xml_str)
|
||||
{
|
||||
vector<xmlNodePtr> content;
|
||||
int rc = 0;
|
||||
|
||||
// Initialize the internal XML object
|
||||
update_from_str(xml_str);
|
||||
|
||||
// Get class base attributes
|
||||
rc += xpath(oid, "/VM_GROUP/ID", -1);
|
||||
rc += xpath(uid, "/VM_GROUP/UID", -1);
|
||||
rc += xpath(gid, "/VM_GROUP/GID", -1);
|
||||
rc += xpath(uname, "/VM_GROUP/UNAME","not_found");
|
||||
rc += xpath(gname, "/VM_GROUP/GNAME","not_found");
|
||||
rc += xpath(name, "/VM_GROUP/NAME", "not_found");
|
||||
|
||||
// Permissions
|
||||
rc += perms_from_xml();
|
||||
|
||||
// Get associated template
|
||||
ObjectXML::get_nodes("/VM_GROUP/TEMPLATE", content);
|
||||
|
||||
if (content.empty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc += obj_template->from_xml_node(content[0]);
|
||||
|
||||
ObjectXML::free_nodes(content);
|
||||
|
||||
content.clear();
|
||||
|
||||
// VMGroup roles
|
||||
ObjectXML::get_nodes("/VM_GROUP/ROLES", content);
|
||||
|
||||
if (!content.empty())
|
||||
{
|
||||
rc += roles.from_xml_node(content[0]);
|
||||
}
|
||||
|
||||
ObjectXML::free_nodes(content);
|
||||
|
||||
content.clear();
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VMGroup::insert_replace(SqlDB *db, bool replace, string& error_str)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
int rc;
|
||||
string xml_body;
|
||||
|
||||
char * sql_name;
|
||||
char * sql_xml;
|
||||
|
||||
sql_name = db->escape_str(name.c_str());
|
||||
|
||||
if ( sql_name == 0 )
|
||||
{
|
||||
goto error_name;
|
||||
}
|
||||
|
||||
sql_xml = db->escape_str(to_xml(xml_body).c_str());
|
||||
|
||||
if ( sql_xml == 0 )
|
||||
{
|
||||
goto error_body;
|
||||
}
|
||||
|
||||
if ( validate_xml(sql_xml) != 0 )
|
||||
{
|
||||
goto error_xml;
|
||||
}
|
||||
|
||||
if ( replace )
|
||||
{
|
||||
oss << "REPLACE";
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << "INSERT";
|
||||
}
|
||||
|
||||
// Construct the SQL statement to Insert or Replace
|
||||
oss <<" INTO "<<table <<" ("<< db_names <<") VALUES ("
|
||||
<< oid << ","
|
||||
<< "'" << sql_name << "',"
|
||||
<< "'" << sql_xml << "',"
|
||||
<< uid << ","
|
||||
<< gid << ","
|
||||
<< owner_u << ","
|
||||
<< group_u << ","
|
||||
<< other_u << ")";
|
||||
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
db->free_str(sql_name);
|
||||
db->free_str(sql_xml);
|
||||
|
||||
return rc;
|
||||
|
||||
error_xml:
|
||||
db->free_str(sql_name);
|
||||
db->free_str(sql_xml);
|
||||
|
||||
error_str = "Error transforming the VM group to XML.";
|
||||
|
||||
goto error_common;
|
||||
|
||||
error_body:
|
||||
db->free_str(sql_name);
|
||||
goto error_generic;
|
||||
|
||||
error_name:
|
||||
goto error_generic;
|
||||
|
||||
error_generic:
|
||||
error_str = "Error inserting VM group in DB.";
|
||||
error_common:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VMGroup::check_rule_names(VMGroupPolicy policy, std::string& error)
|
||||
{
|
||||
vector<const SingleAttribute *> affined;
|
||||
vector<const SingleAttribute *>::const_iterator jt;
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << policy;
|
||||
|
||||
std::string aname = oss.str();
|
||||
|
||||
obj_template->get(aname, affined);
|
||||
|
||||
for ( jt = affined.begin() ; jt != affined.end() ; ++jt )
|
||||
{
|
||||
std::set<int> id_set;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VMGroup::get_rules(VMGroupPolicy policy, VMGroupRule::rule_set& rules,
|
||||
std::string& error_str)
|
||||
{
|
||||
vector<const SingleAttribute *> affined;
|
||||
vector<const SingleAttribute *>::const_iterator jt;
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << policy;
|
||||
|
||||
std::string aname = oss.str();
|
||||
|
||||
obj_template->get(aname, affined);
|
||||
|
||||
for ( jt = affined.begin() ; jt != affined.end() ; ++jt )
|
||||
{
|
||||
std::set<int> id_set;
|
||||
|
||||
std::pair<std::set<VMGroupRule>::iterator, bool> rc;
|
||||
|
||||
roles.names_to_ids((*jt)->value(), id_set);
|
||||
|
||||
VMGroupRule rule(policy, id_set);
|
||||
|
||||
rc = rules.insert(rule);
|
||||
|
||||
if ( rc.second == false )
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
||||
oss << "Duplicated " << aname << " rule (" << (*jt)->value()
|
||||
<< ") detected.";
|
||||
|
||||
error_str = oss.str();
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VMGroup::check_rule_consistency(std::string& error)
|
||||
{
|
||||
VMGroupRule::rule_set affined, anti;
|
||||
|
||||
VMGroupRule::rule_set::iterator it;
|
||||
|
||||
VMGroupRule error_rule;
|
||||
|
||||
if ( get_rules(VMGroupPolicy::AFFINED, affined, error) == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (it=affined.begin() ; it != affined.end(); ++it)
|
||||
{
|
||||
const VMGroupRule::role_bitset rs = (*it).get_roles();
|
||||
|
||||
for (int i = 0; i < VMGroupRoles::MAX_ROLES; ++i)
|
||||
{
|
||||
if ( rs[i] == 1 )
|
||||
{
|
||||
VMGroupRole * role = roles.get(i);
|
||||
|
||||
if ( role != 0 && role->policy() == VMGroupPolicy::ANTI_AFFINED )
|
||||
{
|
||||
error = "Role " + role->name() + " is in an AFFINED rule "
|
||||
"but the role policy is ANTI_AFFINED";
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( get_rules(VMGroupPolicy::ANTI_AFFINED, anti, error) == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( !VMGroupRule::compatible(affined, anti, error_rule) )
|
||||
{
|
||||
ostringstream oss;
|
||||
const VMGroupRule::role_bitset rs = error_rule.get_roles();
|
||||
|
||||
oss << "Roles defined in AFFINED and ANTI_AFFINED rules:";
|
||||
|
||||
for (int i = 0; i < VMGroupRoles::MAX_ROLES; ++i)
|
||||
{
|
||||
if ( rs[i] == 1 )
|
||||
{
|
||||
VMGroupRole * role = roles.get(i);
|
||||
|
||||
if ( role != 0 )
|
||||
{
|
||||
oss << " " << role->name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error = oss.str();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VMGroup::insert(SqlDB *db, string& error_str)
|
||||
{
|
||||
vector<Attribute*> va_roles;
|
||||
vector<Attribute*>::iterator it;
|
||||
|
||||
erase_template_attribute("NAME", name);
|
||||
|
||||
if (name.empty())
|
||||
{
|
||||
error_str = "No NAME in template for VM group.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
int num_role = obj_template->remove("ROLE", va_roles);
|
||||
|
||||
if ( num_role > VMGroupRoles::MAX_ROLES )
|
||||
{
|
||||
for ( it = va_roles.begin(); it != va_roles.end(); ++it )
|
||||
{
|
||||
delete *it;
|
||||
}
|
||||
|
||||
error_str = "Maximum number of roles in a VM Group reached";
|
||||
}
|
||||
|
||||
bool error = false;
|
||||
|
||||
for ( it = va_roles.begin(); it != va_roles.end(); ++it )
|
||||
{
|
||||
VectorAttribute * vatt = dynamic_cast<VectorAttribute *>(*it);
|
||||
|
||||
if (vatt == 0 || error)
|
||||
{
|
||||
delete *it;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( roles.add_role(vatt, error_str) == -1 )
|
||||
{
|
||||
delete *it;
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( error )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( check_rule_names(VMGroupPolicy::AFFINED, error_str) == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( check_rule_names(VMGroupPolicy::ANTI_AFFINED, error_str) == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( check_rule_consistency(error_str) == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( insert_replace(db, false, error_str) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
obj_template->erase("ROLE");
|
||||
|
||||
if ( check_rule_names(VMGroupPolicy::AFFINED, error) == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( check_rule_names(VMGroupPolicy::ANTI_AFFINED, error) == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( check_rule_consistency(error) == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
185
src/vm_group/VMGroupPool.cc
Normal file
185
src/vm_group/VMGroupPool.cc
Normal file
@ -0,0 +1,185 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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 "VMGroupPool.h"
|
||||
#include "AuthRequest.h"
|
||||
|
||||
int VMGroupPool::allocate(int uid, int gid, const string& uname,
|
||||
const string& gname, int umask, Template * vmgroup_template, int * oid,
|
||||
string& error_str)
|
||||
{
|
||||
VMGroup * vmgrp;
|
||||
VMGroup * vmgrp_aux = 0;
|
||||
|
||||
string name;
|
||||
|
||||
ostringstream os;
|
||||
|
||||
vmgrp = new VMGroup(uid, gid, uname, gname, umask, vmgroup_template);
|
||||
|
||||
vmgrp->get_template_attribute("NAME", name);
|
||||
|
||||
if ( !PoolObjectSQL::name_is_valid(name, error_str) )
|
||||
{
|
||||
goto error_name;
|
||||
}
|
||||
|
||||
vmgrp_aux = get(name, uid, false);
|
||||
|
||||
if( vmgrp_aux != 0 )
|
||||
{
|
||||
goto error_duplicated;
|
||||
}
|
||||
|
||||
*oid = PoolSQL::allocate(vmgrp, error_str);
|
||||
|
||||
return *oid;
|
||||
|
||||
error_duplicated:
|
||||
os << "NAME is already taken by VMGroup " << vmgrp_aux->get_oid() << ".";
|
||||
error_str = os.str();
|
||||
|
||||
error_name:
|
||||
delete vmgrp;
|
||||
*oid = -1;
|
||||
|
||||
return *oid;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
VMGroup * VMGroupPool::get_from_attribute(const VectorAttribute *va, int _uid)
|
||||
{
|
||||
VMGroup * vmgroup = 0;
|
||||
|
||||
string vmg_name = va->vector_value("VMGROUP_NAME");
|
||||
int vmg_id;
|
||||
|
||||
if ( !vmg_name.empty() )
|
||||
{
|
||||
int vmg_uid;
|
||||
|
||||
if ( va->vector_value("VMGROUP_UID", vmg_uid) == -1 )
|
||||
{
|
||||
vmg_uid = _uid;
|
||||
}
|
||||
|
||||
vmgroup = get(vmg_name, vmg_uid, true);
|
||||
}
|
||||
else if ( va->vector_value("VMGROUP_ID", vmg_id) == 0 )
|
||||
{
|
||||
vmgroup = get(vmg_id, true);
|
||||
}
|
||||
|
||||
return vmgroup;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VMGroupPool::vmgroup_attribute(VectorAttribute * va, int uid, int vid,
|
||||
string& error)
|
||||
{
|
||||
string vmg_role = va->vector_value("ROLE");
|
||||
|
||||
if ( vmg_role.empty() )
|
||||
{
|
||||
error = "Missing role name in VM Group definition";
|
||||
return -1;
|
||||
}
|
||||
|
||||
VMGroup * vmgroup = get_from_attribute(va, uid);
|
||||
|
||||
if ( vmgroup == 0 )
|
||||
{
|
||||
error = "Cannot find VM Group to associate the VM";
|
||||
return -1;
|
||||
}
|
||||
|
||||
va->replace("VMGROUP_ID", vmgroup->get_oid());
|
||||
|
||||
int rc = vmgroup->add_vm(vmg_role, vid);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
error = "Role does not exist in VM Group";
|
||||
}
|
||||
else
|
||||
{
|
||||
update(vmgroup);
|
||||
}
|
||||
|
||||
vmgroup->unlock();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VMGroupPool::del_vm(const VectorAttribute * va, int vid)
|
||||
{
|
||||
int vmg_id;
|
||||
|
||||
if ( va->vector_value("VMGROUP_ID", vmg_id) == -1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string vmg_role = va->vector_value("ROLE");
|
||||
|
||||
if ( vmg_role.empty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VMGroup * vmgroup = get(vmg_id, true);
|
||||
|
||||
if ( vmgroup == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vmgroup->del_vm(vmg_role, vid);
|
||||
|
||||
update(vmgroup);
|
||||
|
||||
vmgroup->unlock();
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VMGroupPool::authorize(const VectorAttribute * va, int uid,AuthRequest* ar)
|
||||
{
|
||||
PoolObjectAuth perm;
|
||||
|
||||
VMGroup * vmgroup = get_from_attribute(va, uid);
|
||||
|
||||
if ( vmgroup == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vmgroup->get_permissions(perm);
|
||||
|
||||
vmgroup->unlock();
|
||||
|
||||
ar->add_auth(AuthRequest::USE, perm);
|
||||
}
|
||||
|
||||
|
405
src/vm_group/VMGroupRole.cc
Normal file
405
src/vm_group/VMGroupRole.cc
Normal file
@ -0,0 +1,405 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* 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"
|
||||
#include "VMGroupRule.h"
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
VMGroupPolicy VMGroupRole::policy()
|
||||
{
|
||||
string p = va->vector_value("POLICY");
|
||||
|
||||
one_util::toupper(p);
|
||||
|
||||
if ( p == "AFFINED" )
|
||||
{
|
||||
return VMGroupPolicy::AFFINED;
|
||||
}
|
||||
else if ( p == "ANTI_AFFINED" )
|
||||
{
|
||||
return VMGroupPolicy::ANTI_AFFINED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return VMGroupPolicy::NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VMGroupRole::add_vm(int vm_id)
|
||||
{
|
||||
std::pair<std::set<int>::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);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static void affinity_requirements(int vm_id, std::string& requirements,
|
||||
VMGroupPolicy policy, const std::set<int>& vms)
|
||||
{
|
||||
string op, op2;
|
||||
|
||||
requirements = "";
|
||||
|
||||
switch(policy)
|
||||
{
|
||||
case VMGroupPolicy::AFFINED:
|
||||
op = "=";
|
||||
op2= " | ";
|
||||
break;
|
||||
case VMGroupPolicy::ANTI_AFFINED:
|
||||
op = "!=";
|
||||
op2= " & ";
|
||||
break;
|
||||
case VMGroupPolicy::NONE:
|
||||
return;
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
std::set<int>::const_iterator it;
|
||||
|
||||
bool first = true;
|
||||
|
||||
for ( it = vms.begin(); it != vms.end(); ++it )
|
||||
{
|
||||
if ( vm_id == -1 || vm_id != *it )
|
||||
{
|
||||
if ( !first )
|
||||
{
|
||||
oss << op2;
|
||||
}
|
||||
|
||||
first = false;
|
||||
|
||||
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(VMGroupPolicy pol, std::string& reqs)
|
||||
{
|
||||
affinity_requirements(-1, reqs, pol, vms);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VMGroupRole::host_requirements(std::set<int>& hosts, const std::string& op1,
|
||||
const std::string& op2, std::ostringstream& oss)
|
||||
{
|
||||
std::set<int>::const_iterator jt;
|
||||
bool empty = true;
|
||||
|
||||
for ( jt = hosts.begin() ; jt != hosts.end() ; ++jt )
|
||||
{
|
||||
if ( empty == true )
|
||||
{
|
||||
empty = false;
|
||||
|
||||
oss << "(ID" << op1 << *jt << ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << " " << op2 << " (ID" << op1 << *jt << ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VMGroupRole::affined_host_requirements(std::string& reqs)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
std::set<int> hosts;
|
||||
|
||||
string shosts = va->vector_value("HOST_AFFINED");
|
||||
|
||||
if ( !shosts.empty() )
|
||||
{
|
||||
one_util::split_unique(shosts, ',', hosts);
|
||||
}
|
||||
|
||||
host_requirements(hosts, "=", "|", oss);
|
||||
|
||||
reqs = oss.str();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VMGroupRole::antiaffined_host_requirements(std::string& reqs)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
std::set<int> hosts;
|
||||
|
||||
string shosts = va->vector_value("HOST_ANTI_AFFINED");
|
||||
|
||||
if ( !shosts.empty() )
|
||||
{
|
||||
one_util::split_unique(shosts, ',', hosts);
|
||||
}
|
||||
|
||||
host_requirements(hosts, "!=", "&", oss);
|
||||
|
||||
reqs = oss.str();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* VMGroupRoles */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VMGroupRoles::from_xml_node(const xmlNodePtr node)
|
||||
{
|
||||
std::vector<VectorAttribute *> roles;
|
||||
std::vector<VectorAttribute *>::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::string& rnames, std::set<int>& keyi)
|
||||
{
|
||||
std::set<std::string> a_set, key_set;
|
||||
std::set<std::string>::iterator 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);
|
||||
|
||||
if ( r == 0 )
|
||||
{
|
||||
keyi.clear();
|
||||
return -1;
|
||||
}
|
||||
|
||||
keyi.insert(r->id());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
114
src/vm_group/VMGroupRule.cc
Normal file
114
src/vm_group/VMGroupRule.cc
Normal file
@ -0,0 +1,114 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* 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"
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* VMGroupRule */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
bool VMGroupRule::compatible(rule_set& affined, 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();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VMGroupRule::reduce(rule_set affined, rule_set& reduced_set)
|
||||
{
|
||||
VMGroupRule::rule_set::iterator it, jt;
|
||||
|
||||
VMGroupRule reduced_rule;
|
||||
|
||||
for ( it = affined.begin(), reduced_rule = (*it) ; it != affined.end() ; )
|
||||
{
|
||||
bool reduced = false;
|
||||
|
||||
for ( jt = affined.begin() ; jt != affined.end() ; )
|
||||
{
|
||||
VMGroupRule tmp = *it;
|
||||
|
||||
tmp &= *jt;
|
||||
|
||||
if ( it == jt || (reduced_rule & *jt).none() )
|
||||
{
|
||||
++jt;
|
||||
}
|
||||
else
|
||||
{
|
||||
reduced_rule |= *jt;
|
||||
|
||||
jt = affined.erase(jt);
|
||||
|
||||
reduced = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!reduced)
|
||||
{
|
||||
reduced_set.insert(reduced_rule);
|
||||
|
||||
reduced_rule = *(++it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, VMGroupPolicy policy)
|
||||
{
|
||||
switch(policy)
|
||||
{
|
||||
case VMGroupPolicy::AFFINED:
|
||||
os << "AFFINED";
|
||||
break;
|
||||
|
||||
case VMGroupPolicy::ANTI_AFFINED:
|
||||
os << "ANTI_AFFINED";
|
||||
break;
|
||||
|
||||
case VMGroupPolicy::NONE:
|
||||
os << "NONE";
|
||||
break;
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user