mirror of
https://github.com/OpenNebula/one.git
synced 2025-04-02 10:50:07 +03:00
feature #1288: Better interface for Quotas
This commit is contained in:
parent
ce3609c28c
commit
e73c78869b
@ -35,7 +35,7 @@ public:
|
||||
* @param error describe the error in case of error
|
||||
* @return 0 on success -1 otherwise
|
||||
*/
|
||||
int set(const string& quota_str, string& error);
|
||||
int set(vector<VectorAttribute*> * quotas, string& error);
|
||||
|
||||
/**
|
||||
* Check if the resource allocation will exceed the quota limits. If not
|
||||
@ -44,19 +44,14 @@ public:
|
||||
* @param error string
|
||||
* @return true if the operation can be performed
|
||||
*/
|
||||
virtual bool check_add(Template* tmpl, string& error)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool check(Template* tmpl, string& error) = 0;
|
||||
|
||||
/**
|
||||
* Decrement usage counters when deallocating image
|
||||
* @param tmpl template for the resource
|
||||
*/
|
||||
virtual void del(Template* tmpl)
|
||||
{
|
||||
return;
|
||||
}
|
||||
virtual void del(Template* tmpl) = 0;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
@ -70,10 +65,8 @@ protected:
|
||||
* @param va attribute with the new limits
|
||||
* @return 0 on success or -1 if wrong limits
|
||||
*/
|
||||
virtual int update_limits(Attribute* quota, const Attribute* va)
|
||||
{
|
||||
return -1;
|
||||
};
|
||||
virtual int update_limits(VectorAttribute* quota,
|
||||
const VectorAttribute* va) = 0;
|
||||
|
||||
/**
|
||||
* Creates an empty quota based on the given attribute. The attribute va
|
||||
@ -81,29 +74,21 @@ protected:
|
||||
* @param va limits for the new quota if 0 limits will be 0
|
||||
* @return a new attribute representing the quota
|
||||
*/
|
||||
virtual Attribute * new_quota(Attribute* va)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a quota for a given resource. The resource is specified as a
|
||||
* Template attribute. Derived class should return a quota that matches the
|
||||
* resource.
|
||||
* @param base_attribute describing the quota with the new limits
|
||||
* @return pointer to the quota on success or 0 otherwise
|
||||
*/
|
||||
virtual Attribute * get_quota(const Attribute* base_attribute)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
virtual VectorAttribute * new_quota(VectorAttribute* va) = 0;
|
||||
|
||||
/**
|
||||
* Adds a given value to the current quota (single)
|
||||
* @param attr the quota with a numeric value
|
||||
* @param num value to add to the current quota
|
||||
* Gets a quota identified by its ID.
|
||||
* @param id of the quota
|
||||
* @return a pointer to the quota or 0 if not found
|
||||
*/
|
||||
void add_to_quota(SingleAttribute * attr, float num);
|
||||
virtual VectorAttribute * get_quota(const string& id);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Adds a given value to the current quota (vector)
|
||||
|
@ -22,7 +22,7 @@
|
||||
/**
|
||||
* DataStore Quotas, defined as:
|
||||
* DATASTORE = [
|
||||
* NAME = <Name of the datastore>
|
||||
* ID = <ID of the datastore>
|
||||
* IMAGES = <Max. number of images allowed in the datastore>
|
||||
* SIZE = <Max. number of MB used in the datastore>
|
||||
* IMAGES_USED = Current number of images in the datastore
|
||||
@ -47,7 +47,7 @@ public:
|
||||
* @param error string
|
||||
* @return true if the operation can be performed
|
||||
*/
|
||||
bool check_add(Template* tmpl, string& error);
|
||||
bool check(Template* tmpl, string& error);
|
||||
|
||||
/**
|
||||
* Decrement usage counters when deallocating image
|
||||
@ -63,7 +63,8 @@ protected:
|
||||
* @param va attribute with the new limits
|
||||
* @return 0 on success or -1 if wrong limits
|
||||
*/
|
||||
int update_limits(Attribute * quota, Attribute * va);
|
||||
int update_limits(VectorAttribute* quota,
|
||||
const VectorAttribute* va);
|
||||
|
||||
/**
|
||||
* Creates an empty quota based on the given attribute. The attribute va
|
||||
@ -71,34 +72,23 @@ protected:
|
||||
* @param va limits for the new quota if 0 limits will be 0
|
||||
* @return a new attribute representing the quota
|
||||
*/
|
||||
Attribute * new_quota(Attribute * va);
|
||||
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 name of the DATASTORE quota
|
||||
* @param images the limit for the number of images
|
||||
* @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(Attribute* va_ptr, string& ds, string& images, string& size);
|
||||
|
||||
/**
|
||||
* Return the attribute with the datastore quotas
|
||||
* @param ds_name name of the datastore
|
||||
* @return pointer to the datastore quota or 0 if not found
|
||||
*/
|
||||
VectorAttribute * get_datastore_quota(const string& ds_name);
|
||||
|
||||
/**
|
||||
* Return the attribute with the datastore quotas
|
||||
* @param resource attribute describing a datastore quota
|
||||
* @return pointer to the datastore quota or 0 if not found
|
||||
*/
|
||||
Attribute * get_quota(Attribute * resource);
|
||||
int get_limits(const VectorAttribute* va,
|
||||
string& ds,
|
||||
string& imgs,
|
||||
string& size);
|
||||
};
|
||||
|
||||
#endif /*QUOTA_DATASTORE_H_*/
|
@ -177,7 +177,7 @@ public:
|
||||
*/
|
||||
bool datastore_quota_check(Template * tmpl, string& reason)
|
||||
{
|
||||
return datastore_quota.check_add(tmpl, reason);
|
||||
return datastore_quota.check(tmpl, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -402,7 +402,7 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
|
||||
string tmpl_str;
|
||||
|
||||
// ------------------ Check permissions and ACLs ----------------------
|
||||
tmpl->add("DATASTORE", ds_name);
|
||||
tmpl->add("DATASTORE", ds_id);
|
||||
|
||||
tmpl->to_xml(tmpl_str);
|
||||
|
||||
@ -446,7 +446,7 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
|
||||
{
|
||||
Template img_usage;
|
||||
|
||||
img_usage.add("DATASTORE", ds_name);
|
||||
img_usage.add("DATASTORE", ds_id);
|
||||
img_usage.add("SIZE", size_str);
|
||||
|
||||
quota_rollback(&img_usage, att);
|
||||
|
114
src/um/Quota.cc
114
src/um/Quota.cc
@ -19,73 +19,44 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int Quota::set(const string& quota_str, string& error)
|
||||
VectorAttribute * Quota::get_quota(const string& id)
|
||||
{
|
||||
Quota tmp("GENERIC_QUOTA");
|
||||
map<string, Attribute *>::iterator it;
|
||||
VectorAttribute * q;
|
||||
|
||||
if ( tmp.parse_str_or_xml(quota_str, error) != 0 )
|
||||
if ( id.empty() )
|
||||
{
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
multimap<string, Attribute *>::iterator it;
|
||||
|
||||
pair<multimap<string, Attribute *>::iterator,
|
||||
multimap<string, Attribute *>::iterator> actual;
|
||||
|
||||
Attribute * quota;
|
||||
|
||||
for ( it = tmp.attributes.begin(); it != tmp.attributes.end(); it++)
|
||||
for ( it = attributes.begin(); it != attributes.end(); it++)
|
||||
{
|
||||
quota = get_quota(it->second);
|
||||
q = static_cast<VectorAttribute *>(it->second);
|
||||
|
||||
if ( quota == 0 ) //Quota not set yet.
|
||||
if (q->vector_value("ID") == id)
|
||||
{
|
||||
Attribute * nq;
|
||||
|
||||
if ((nq = new_quota(it->second)) == 0)
|
||||
{
|
||||
goto error_limits;
|
||||
}
|
||||
|
||||
attributes.insert(make_pair(nq->name(),nq));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (update_limits(quota, it->second))
|
||||
{
|
||||
goto error_limits;
|
||||
}
|
||||
return q;
|
||||
}
|
||||
}
|
||||
|
||||
error_limits:
|
||||
ostringstream oss;
|
||||
oss << "Negative limits or bad format in quota " << it->first
|
||||
<< " = " << it->second->marshall();
|
||||
|
||||
error = oss.str();
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void Quota::add_to_quota(SingleAttribute * attr, float num)
|
||||
void Quota::add(VectorAttribute * nq)
|
||||
{
|
||||
istringstream iss;
|
||||
ostringstream oss;
|
||||
float total;
|
||||
string id;
|
||||
|
||||
iss.str(attr->value());
|
||||
id = nq->vector_value("ID");
|
||||
|
||||
iss >> total;
|
||||
if ( id.empty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
total += num;
|
||||
|
||||
oss << total;
|
||||
|
||||
attr->replace(oss.str());
|
||||
attributes.insert(make_pair(nq->name(), nq));
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -107,3 +78,52 @@ void Quota::add_to_quota(VectorAttribute * attr, const string& va_name, int num)
|
||||
|
||||
attr->replace(va_name, oss.str());
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int Quota::set(vector<VectorAttribute*> * new_quotas, string& error)
|
||||
{
|
||||
vector<VectorAttribute *>::iterator it;
|
||||
|
||||
VectorAttribute * tq;
|
||||
string id;
|
||||
|
||||
for ( it = new_quotas->begin(); it != new_quotas->end(); it++)
|
||||
{
|
||||
id = (*it)->vector_value("ID");
|
||||
|
||||
tq = get_quota(id);
|
||||
|
||||
if ( tq == 0 )
|
||||
{
|
||||
VectorAttribute * nq;
|
||||
|
||||
if ((nq = new_quota(*it)) == 0)
|
||||
{
|
||||
goto error_limits;
|
||||
}
|
||||
|
||||
add(nq);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (update_limits(tq, *it))
|
||||
{
|
||||
goto error_limits;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_limits:
|
||||
ostringstream oss;
|
||||
oss << "Negative limits or bad format in quota " << (*it)->marshall();
|
||||
|
||||
error = oss.str();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -16,58 +16,10 @@
|
||||
|
||||
#include "QuotaDatastore.h"
|
||||
|
||||
VectorAttribute * QuotaDatastore::get_datastore_quota(const string& ds_name)
|
||||
{
|
||||
vector<Attribute *> vquota;
|
||||
VectorAttribute * ds_quota = 0;
|
||||
|
||||
int num = get("DATASTORE", vquota);
|
||||
|
||||
for (int i = 0; i< num ; i++)
|
||||
{
|
||||
ds_quota = dynamic_cast<VectorAttribute *>(vquota[i]);
|
||||
|
||||
if (ds_quota == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ds_quota->vector_value("NAME") == ds_name )
|
||||
{
|
||||
return ds_quota;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
Attribute * QuotaDatastore::get_quota(Attribute * resource)
|
||||
{
|
||||
VectorAttribute * vresource = dynamic_cast<VectorAttribute *>(resource);
|
||||
string ds_name;
|
||||
|
||||
if (vresource == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ds_name = vresource->vector_value("NAME");
|
||||
|
||||
if (ds_name.empty())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return get_datastore_quota(ds_name);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
bool QuotaDatastore::check_add(Template * tmpl, string& error)
|
||||
bool QuotaDatastore::check(Template * tmpl, string& error)
|
||||
{
|
||||
VectorAttribute * ds_quota;
|
||||
|
||||
@ -79,14 +31,14 @@ bool QuotaDatastore::check_add(Template * tmpl, string& error)
|
||||
bool img_ok;
|
||||
bool size_ok;
|
||||
|
||||
string ds_name;
|
||||
string ds_id;
|
||||
int size;
|
||||
|
||||
// --------------------- Get data from the Template --------------------
|
||||
|
||||
tmpl->get("DATASTORE", ds_name);
|
||||
tmpl->get("DATASTORE", ds_id);
|
||||
|
||||
if ( ds_name.empty() )
|
||||
if ( ds_id.empty() )
|
||||
{
|
||||
error = "Datastore not defined for image";
|
||||
return false;
|
||||
@ -100,25 +52,22 @@ bool QuotaDatastore::check_add(Template * tmpl, string& error)
|
||||
|
||||
// ------ There are no quotas for this datastore, create a new one ------
|
||||
|
||||
ds_quota = get_datastore_quota(ds_name);
|
||||
ds_quota = get_quota(ds_id);
|
||||
|
||||
if ( ds_quota == 0 )
|
||||
{
|
||||
map<string,string> ds_quota;
|
||||
VectorAttribute * attr;
|
||||
ostringstream size_str;
|
||||
|
||||
size_str << size;
|
||||
|
||||
ds_quota.insert(make_pair("NAME", ds_name));
|
||||
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()));
|
||||
|
||||
attr = new VectorAttribute("DATASTORE", ds_quota);
|
||||
|
||||
attributes.insert(make_pair("DATASTORE", attr));
|
||||
add(new VectorAttribute("DATASTORE", ds_quota));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -144,7 +93,7 @@ bool QuotaDatastore::check_add(Template * tmpl, string& error)
|
||||
ostringstream oss;
|
||||
|
||||
oss << "Maximum number of images limit (" << img_limit << ")"
|
||||
<< " reached for datastore " << ds_name;
|
||||
<< " reached for datastore " << ds_id;
|
||||
|
||||
error = oss.str();
|
||||
}
|
||||
@ -153,7 +102,7 @@ bool QuotaDatastore::check_add(Template * tmpl, string& error)
|
||||
ostringstream oss;
|
||||
|
||||
oss << "Maximum storage capacity limit (" << size_limit << ")"
|
||||
<< " reached for datastore " << ds_name;
|
||||
<< " reached for datastore " << ds_id;
|
||||
|
||||
error = oss.str();
|
||||
}
|
||||
@ -168,12 +117,12 @@ void QuotaDatastore::del(Template * tmpl)
|
||||
{
|
||||
VectorAttribute * ds_quota;
|
||||
|
||||
string ds_name;
|
||||
string ds_id;
|
||||
int size;
|
||||
|
||||
tmpl->get("DATASTORE", ds_name);
|
||||
tmpl->get("DATASTORE", ds_id);
|
||||
|
||||
if ( ds_name.empty() )
|
||||
if ( ds_id.empty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -183,7 +132,7 @@ void QuotaDatastore::del(Template * tmpl)
|
||||
return;
|
||||
}
|
||||
|
||||
ds_quota = get_datastore_quota(ds_name);
|
||||
ds_quota = get_quota(ds_id);
|
||||
|
||||
if ( ds_quota == 0 )
|
||||
{
|
||||
@ -197,22 +146,20 @@ void QuotaDatastore::del(Template * tmpl)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int QuotaDatastore::update_limits(Attribute * quota, Attribute * va)
|
||||
int QuotaDatastore::update_limits(VectorAttribute * quota,
|
||||
const VectorAttribute * va)
|
||||
{
|
||||
string images_limit;
|
||||
string size_limit;
|
||||
string ds;
|
||||
string ds_id;
|
||||
|
||||
VectorAttribute * vquota = dynamic_cast<VectorAttribute *>(quota);
|
||||
int rc = get_limits(va, ds, images_limit, size_limit);
|
||||
|
||||
if ( vquota == 0 || rc != 0 )
|
||||
if ( get_limits(va, ds_id, images_limit, size_limit) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
vquota->replace("IMAGES", images_limit);
|
||||
vquota->replace("SIZE", size_limit);
|
||||
quota->replace("IMAGES", images_limit);
|
||||
quota->replace("SIZE", size_limit);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -220,22 +167,20 @@ int QuotaDatastore::update_limits(Attribute * quota, Attribute * va)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
Attribute * QuotaDatastore::new_quota(Attribute * va)
|
||||
VectorAttribute * QuotaDatastore::new_quota(VectorAttribute * va)
|
||||
{
|
||||
string images_limit = "0";
|
||||
string size_limit = "0";
|
||||
string ds_name;
|
||||
string ds_id;
|
||||
|
||||
int rc = get_limits(va, ds_name, images_limit, size_limit);
|
||||
|
||||
if ( rc != 0 || ds_name.empty())
|
||||
if ( get_limits(va, ds_id, images_limit, size_limit) != 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
map<string,string> limits;
|
||||
|
||||
limits.insert(make_pair("NAME", ds_name));
|
||||
limits.insert(make_pair("ID", ds_id));
|
||||
|
||||
limits.insert(make_pair("IMAGES", images_limit));
|
||||
limits.insert(make_pair("SIZE", size_limit));
|
||||
@ -249,26 +194,19 @@ Attribute * QuotaDatastore::new_quota(Attribute * va)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int QuotaDatastore::get_limits(Attribute * va_ptr,
|
||||
string& ds_name,
|
||||
string& images,
|
||||
string& size)
|
||||
int QuotaDatastore::get_limits(const VectorAttribute * va,
|
||||
string& ds_id,
|
||||
string& images,
|
||||
string& size)
|
||||
{
|
||||
int images_limit = 0;
|
||||
int size_limit = 0;
|
||||
|
||||
VectorAttribute * va = dynamic_cast<VectorAttribute *>(va_ptr);
|
||||
images = va->vector_value("IMAGES", images_limit);
|
||||
size = va->vector_value("SIZE", size_limit);
|
||||
ds_id = va->vector_value("ID");
|
||||
|
||||
if ( va == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
images = va->vector_value("IMAGES", images_limit);
|
||||
size = va->vector_value("SIZE", size_limit);
|
||||
ds_name = va->vector_value("NAME");
|
||||
|
||||
if ( images_limit < 0 || size_limit < 0 )
|
||||
if ( images_limit < 0 || size_limit < 0 || ds_id.empty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user