1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-24 21:34:01 +03:00

feature #1288: Image Quotas

This commit is contained in:
Ruben S. Montero 2012-06-05 23:32:05 +02:00
parent 7e7dcf6eac
commit 5c7dc58c66
6 changed files with 216 additions and 5 deletions

66
include/QuotaImage.h Normal file
View File

@ -0,0 +1,66 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2012, 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 QUOTA_IMAGE_H_
#define QUOTA_IMAGE_H_
#include "Quota.h"
/**
* Image Quotas, defined as:
* IMAGE = [
* ID = <ID of the image>
* INSTANCES = <Max. number times the image can be instantiated>
* INSTANCES_USED = Current number of VMs using the image
* ]
*
* 0 = unlimited, default if missing
*/
class QuotaImage : public Quota
{
public:
QuotaImage():Quota("IMAGE_QUOTA",
"IMAGE",
IMAGE_METRICS,
NUM_IMAGE_METRICS)
{};
~QuotaImage(){};
/**
* Check if the resource allocation will exceed the quota limits. If not
* the usage counters are updated
* @param tmpl template for the resource
* @param error string
* @return true if the operation can be performed
*/
bool check(Template* tmpl, string& error);
/**
* Decrement usage counters when deallocating image
* @param tmpl template for the resource
*/
void del(Template* tmpl);
protected:
static const char * IMAGE_METRICS[];
static const int NUM_IMAGE_METRICS;
};
#endif /*QUOTA_IMAGE_H_*/

View File

@ -22,6 +22,7 @@
#include "QuotaDatastore.h" #include "QuotaDatastore.h"
#include "QuotaNetwork.h" #include "QuotaNetwork.h"
#include "QuotaVirtualMachine.h" #include "QuotaVirtualMachine.h"
#include "QuotaImage.h"
using namespace std; using namespace std;
@ -233,6 +234,27 @@ public:
return vm_quota.del(tmpl); return vm_quota.del(tmpl);
} }
/**
* Check IMAGE quotas, it updates usage counters if quotas are not
* exceeded.
* @param tmpl template for the VirtualMachine
* @param reason string describing the error
* @return true if image can be allocated, false otherwise
*/
bool image_quota_check(Template * tmpl, string& reason)
{
return image_quota.check(tmpl, reason);
}
/**
* Delete usage from quota counters.
* @param tmpl template for the image, with usage
*/
void image_quota_del(Template * tmpl)
{
return image_quota.del(tmpl);
}
private: private:
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Friends // Friends
@ -265,6 +287,7 @@ private:
QuotaDatastore datastore_quota; QuotaDatastore datastore_quota;
QuotaNetwork network_quota; QuotaNetwork network_quota;
QuotaVirtualMachine vm_quota; QuotaVirtualMachine vm_quota;
QuotaImage image_quota;
// ************************************************************************* // *************************************************************************
// Authentication session (Private) // Authentication session (Private)

View File

@ -143,6 +143,16 @@ bool Request::quota_authorization(Template * tmpl, RequestAttributes& att)
{ {
user->network_quota_del(tmpl); user->network_quota_del(tmpl);
} }
else
{
rc = user->image_quota_check(tmpl, error_str);
if ( rc == false )
{
user->network_quota_del(tmpl);
user->vm_quota_del(tmpl);
}
}
} }
break; break;
@ -194,6 +204,7 @@ void Request::quota_rollback(Template * tmpl, RequestAttributes& att)
case PoolObjectSQL::VM: case PoolObjectSQL::VM:
user->network_quota_del(tmpl); user->network_quota_del(tmpl);
user->vm_quota_del(tmpl); user->vm_quota_del(tmpl);
user->image_quota_del(tmpl);
break; break;
default: default:

97
src/um/QuotaImage.cc Normal file
View File

@ -0,0 +1,97 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2012, 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 "QuotaImage.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
const char * QuotaImage::IMAGE_METRICS[] = {"INSTANCES"};
const int QuotaImage::NUM_IMAGE_METRICS = 1;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool QuotaImage::check(Template * tmpl, string& error)
{
vector<Attribute*> disks;
VectorAttribute * disk;
string image_id;
int num;
map<string, int> image_request;
image_request.insert(make_pair("INSTANCES",1));
num = tmpl->get("DISK", disks);
for (int i = 0 ; i < num ; i++)
{
disk = dynamic_cast<VectorAttribute *>(disks[i]);
if ( disk == 0 )
{
continue;
}
image_id = disk->vector_value("IMAGE_ID");
if ( !check_quota(image_id, image_request, error) )
{
return false;
}
}
return true;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void QuotaImage::del(Template * tmpl)
{
vector<Attribute*> disks;
VectorAttribute * disk;
string image_id;
int num;
map<string, int> image_request;
image_request.insert(make_pair("INSTANCES",1));
num = tmpl->get("DISK", disks);
for (int i = 0 ; i < num ; i++)
{
disk = dynamic_cast<VectorAttribute *>(disks[i]);
if ( disk == 0 )
{
continue;
}
image_id = disk->vector_value("IMAGE_ID");
del_quota(image_id, image_request);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -28,6 +28,7 @@ source_files=[
'QuotaDatastore.cc', 'QuotaDatastore.cc',
'QuotaNetwork.cc', 'QuotaNetwork.cc',
'QuotaVirtualMachine.cc', 'QuotaVirtualMachine.cc',
'QuotaImage.cc'
] ]
# Build library # Build library

View File

@ -137,10 +137,12 @@ error_common:
string& User::to_xml(string& xml) const string& User::to_xml(string& xml) const
{ {
ostringstream oss; ostringstream oss;
string template_xml; string template_xml;
string ds_quota_xml; string ds_quota_xml;
string net_quota_xml; string net_quota_xml;
string vm_quota_xml; string vm_quota_xml;
string image_quota_xml;
int enabled_int = enabled?1:0; int enabled_int = enabled?1:0;
@ -157,6 +159,7 @@ string& User::to_xml(string& xml) const
datastore_quota.to_xml(ds_quota_xml) << datastore_quota.to_xml(ds_quota_xml) <<
network_quota.to_xml(net_quota_xml) << network_quota.to_xml(net_quota_xml) <<
vm_quota.to_xml(vm_quota_xml) << vm_quota.to_xml(vm_quota_xml) <<
image_quota.to_xml(image_quota_xml) <<
"</USER>"; "</USER>";
xml = oss.str(); xml = oss.str();
@ -233,6 +236,16 @@ int User::from_xml(const string& xml)
ObjectXML::free_nodes(content); ObjectXML::free_nodes(content);
content.clear(); content.clear();
ObjectXML::get_nodes("/USER/IMAGE_QUOTA", content);
if (!content.empty())
{
rc += image_quota.from_xml_node(content[0]);
}
ObjectXML::free_nodes(content);
content.clear();
if (rc != 0) if (rc != 0)
{ {
return -1; return -1;