1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-23 17:33:56 +03:00

feature #1288: Generic quota implementation

This commit is contained in:
Ruben S. Montero 2012-06-05 13:34:28 +02:00
parent e60efb1480
commit 2a33492ad8
5 changed files with 90 additions and 206 deletions

View File

@ -55,7 +55,14 @@ public:
protected:
Quota(const char * quota_name): Template(false, '=', quota_name) {};
Quota(const char * quota_name,
const char * _template_name,
const char ** _metrics,
int _num_metrics)
: Template(false, '=', quota_name),
template_name(_template_name),
metrics(_metrics),
num_metrics(_num_metrics){};
virtual ~Quota(){};
@ -74,15 +81,15 @@ protected:
/**
* Name of the quota used in the templates
*/
char * template_name;
const char * template_name;
/**
* The name of the quota metrics
*/
char ** metrics;
const char ** metrics;
/**
* Length o
* Length
*/
int num_metrics;
@ -105,27 +112,31 @@ protected:
void del_quota(const string& qid,
map<string, int>& usage_req);
/**
* Gets a quota identified by its ID.
* @param id of the quota
* @return a pointer to the quota or 0 if not found
*/
virtual int get_quota(const string& id, VectorAttribute **va);
private:
/**
* Creates an empty quota based on the given attribute. The attribute va
* contains the limits for the quota.
* @param va limits for the new quota if 0 limits will be 0
* @return a new attribute representing the quota
*/
virtual VectorAttribute * new_quota(VectorAttribute* va) = 0;
/**
* Gets a quota identified by its ID.
* @param id of the quota
* @return a pointer to the quota or 0 if not found
*/
virtual int get_quota(const string& id, VectorAttribute **va);
VectorAttribute * new_quota(VectorAttribute* va);
/**
* Adds a new quota, it also updates an internal index for fast accessing
* the quotas
* @param quota is the new quota, allocated in the HEAP
*/
virtual void add(VectorAttribute * quota);
void add(VectorAttribute * nq)
{
attributes.insert(make_pair(nq->name(), nq));
}
/**
* Adds a given value to the current quota (vector)
@ -144,9 +155,10 @@ protected:
int update_limits(VectorAttribute* quota, const VectorAttribute* va);
/**
* Extract the limits from a given attribute
* Extract the limits for the defined quota metrics from a given attribute
* @param va the attribute with the limits
* @param
* @param limits stores the known limits
* @return 0 on success
*/
int get_limits(const VectorAttribute * va, map<string, string>& limits);
};

View File

@ -36,7 +36,11 @@ class QuotaDatastore : public Quota
{
public:
QuotaDatastore():Quota("DATASTORE_QUOTA"){};
QuotaDatastore():Quota("DATASTORE_QUOTA",
"DATASTORE",
DS_METRICS,
NUM_DS_METRICS)
{};
~QuotaDatastore(){};
@ -56,39 +60,9 @@ public:
void del(Template* tmpl);
protected:
static const char * DS_METRICS[];
/**
* Sets new limit values for the quota
* @param quota to be updated
* @param va attribute with the new limits
* @return 0 on success or -1 if wrong limits
*/
/*int update_limits(VectorAttribute* quota,
const VectorAttribute* va);*/
/**
* Creates an empty quota based on the given attribute. The attribute va
* contains the limits for the quota.
* @param va limits for the new quota if 0 limits will be 0
* @return a new attribute representing the quota
*/
VectorAttribute * new_quota(VectorAttribute * va);
private:
/**
* Return the limits for image and size stored in the a given quota.
* @param va_ptr the attribute that stores the quota
* @param ds the id of the DATASTORE quota
* @param imgs the limit for the number of images
* @param size the limit for the total storage size
*
* @return -1 if the limits are wrong 0 otherwise
*/
int get_limits(const VectorAttribute* va,
string& ds,
string& imgs,
string& size);
static const int NUM_DS_METRICS;
};
#endif /*QUOTA_DATASTORE_H_*/

View File

@ -48,14 +48,6 @@ int Quota::get_quota(const string& id, VectorAttribute ** va)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Quota::add(VectorAttribute * nq)
{
attributes.insert(make_pair(nq->name(), nq));
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Quota::add_to_quota(VectorAttribute * attr, const string& va_name, int num)
{
istringstream iss;
@ -304,3 +296,42 @@ int Quota::update_limits(VectorAttribute * quota, const VectorAttribute * va)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
VectorAttribute * Quota::new_quota(VectorAttribute * va)
{
map<string,string> limits;
string limit;
int limit_i;
for (int i=0; i < num_metrics; i++)
{
string metrics_used = metrics[i];
metrics_used += "_USED";
limit = va->vector_value(metrics[i], limit_i);
if ( limit.empty() )
{
limit = "0";
}
else if ( limit_i < 0 )
{
return 0;
}
limits.insert(make_pair(metrics[i], limit));
limits.insert(make_pair(metrics_used, "0"));
}
string id = va->vector_value("ID");
if ( !id.empty() )
{
limits.insert(make_pair("ID", id));
}
return new VectorAttribute(template_name,limits);
}

View File

@ -19,23 +19,20 @@
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
const char * QuotaDatastore::DS_METRICS[] = {"SIZE", "IMAGES"};
const int QuotaDatastore::NUM_DS_METRICS = 2;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool QuotaDatastore::check(Template * tmpl, string& error)
{
VectorAttribute * ds_quota;
int img_limit = 0;
int size_limit = 0;
int img_used = 0;
int size_used = 0;
bool img_ok;
bool size_ok;
map<string, int> ds_request;
string ds_id;
int size;
// --------------------- Get data from the Template --------------------
tmpl->get("DATASTORE", ds_id);
if ( ds_id.empty() )
@ -50,64 +47,10 @@ bool QuotaDatastore::check(Template * tmpl, string& error)
return false;
}
// ------ There are no quotas for this datastore, create a new one ------
ds_quota = get_quota(ds_id);
if ( ds_quota == 0 )
{
map<string,string> ds_quota;
ostringstream size_str;
size_str << size;
ds_quota.insert(make_pair("ID", ds_id));
ds_quota.insert(make_pair("IMAGES", "0"));
ds_quota.insert(make_pair("SIZE", "0"));
ds_quota.insert(make_pair("IMAGES_USED", "1"));
ds_quota.insert(make_pair("SIZE_USED", size_str.str()));
add(new VectorAttribute("DATASTORE", ds_quota));
return true;
}
// ------ Check usage limits ------
ds_quota->vector_value("IMAGES", img_limit);
ds_quota->vector_value("SIZE", size_limit);
ds_quota->vector_value("IMAGES_USED", img_used);
ds_quota->vector_value("SIZE_USED", size_used);
img_ok = (img_limit == 0) || ((img_used + 1) <= img_limit );
size_ok = (size_limit== 0) || ((size_used + size) <= size_limit);
if ( img_ok && size_ok )
{
add_to_quota(ds_quota, "IMAGES_USED", +1);
add_to_quota(ds_quota, "SIZE_USED", +size);
}
else if (!img_ok)
{
ostringstream oss;
oss << "Maximum number of images limit (" << img_limit << ")"
<< " reached for datastore " << ds_id;
error = oss.str();
}
else if (!size_ok)
{
ostringstream oss;
oss << "Maximum storage capacity limit (" << size_limit << ")"
<< " reached for datastore " << ds_id;
error = oss.str();
}
return img_ok && size_ok;
ds_request.insert(make_pair("IMAGES",1));
ds_request.insert(make_pair("SIZE", size));
return check_quota(ds_id, ds_request, error);
}
/* -------------------------------------------------------------------------- */
@ -115,7 +58,7 @@ bool QuotaDatastore::check(Template * tmpl, string& error)
void QuotaDatastore::del(Template * tmpl)
{
VectorAttribute * ds_quota;
map<string, int> ds_request;
string ds_id;
int size;
@ -132,86 +75,10 @@ void QuotaDatastore::del(Template * tmpl)
return;
}
ds_quota = get_quota(ds_id);
ds_request.insert(make_pair("IMAGES",1));
ds_request.insert(make_pair("SIZE", size));
if ( ds_quota == 0 )
{
return;
}
add_to_quota(ds_quota, "IMAGES_USED", -1);
add_to_quota(ds_quota, "SIZE_USED", -size);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int QuotaDatastore::update_limits(VectorAttribute * quota,
const VectorAttribute * va)
{
string images_limit;
string size_limit;
string ds_id;
if ( get_limits(va, ds_id, images_limit, size_limit) != 0 )
{
return -1;
}
quota->replace("IMAGES", images_limit);
quota->replace("SIZE", size_limit);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
VectorAttribute * QuotaDatastore::new_quota(VectorAttribute * va)
{
string images_limit = "0";
string size_limit = "0";
string ds_id;
if ( get_limits(va, ds_id, images_limit, size_limit) != 0 )
{
return 0;
}
map<string,string> limits;
limits.insert(make_pair("ID", ds_id));
limits.insert(make_pair("IMAGES", images_limit));
limits.insert(make_pair("SIZE", size_limit));
limits.insert(make_pair("IMAGES_USED", "0"));
limits.insert(make_pair("SIZE_USED", "0"));
return new VectorAttribute("DATASTORE",limits);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int QuotaDatastore::get_limits(const VectorAttribute * va,
string& ds_id,
string& images,
string& size)
{
int images_limit = 0;
int size_limit = 0;
images = va->vector_value("IMAGES", images_limit);
size = va->vector_value("SIZE", size_limit);
ds_id = va->vector_value("ID");
if ( images_limit < 0 || size_limit < 0 || ds_id.empty())
{
return -1;
}
return 0;
del_quota(ds_id, ds_request);
}
/* -------------------------------------------------------------------------- */

View File

@ -25,7 +25,7 @@ source_files=[
'User.cc',
'UserPool.cc',
'Quota.cc',
# 'QuotaDatastore.cc'
'QuotaDatastore.cc'
]
# Build library