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:
parent
e60efb1480
commit
2a33492ad8
@ -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);
|
||||
};
|
||||
|
@ -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_*/
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -25,7 +25,7 @@ source_files=[
|
||||
'User.cc',
|
||||
'UserPool.cc',
|
||||
'Quota.cc',
|
||||
# 'QuotaDatastore.cc'
|
||||
'QuotaDatastore.cc'
|
||||
]
|
||||
|
||||
# Build library
|
||||
|
Loading…
Reference in New Issue
Block a user