1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-23 22:50:09 +03:00

Merge branch 'feature-1223' of git.opennebula.org:one into feature-1223

This commit is contained in:
Tino Vazquez 2012-06-18 14:45:40 +02:00
commit 5337d4cb7d
15 changed files with 199 additions and 199 deletions

View File

@ -39,6 +39,17 @@ public:
virtual ~Quotas(){};
/**
* Different quota types
*/
enum QuotaType {
DATASTORE, /**< Checks Datastore usage */
VM, /**< Checks VM usage (MEMORY, CPU and VMS) */
NETWORK, /**< Checks Network usage (leases) */
IMAGE, /**< Checks Image usage (RVMs using it) */
VIRTUALMACHINE /**< Checks all VM associated resources VM, NETWORK, IMAGE */
};
/**
* Set the quotas
* @param tmpl contains the user quota limits
@ -66,7 +77,7 @@ public:
*/
void ds_del(Template * tmpl)
{
return datastore_quota.del(tmpl);
datastore_quota.del(tmpl);
}
/**
@ -78,26 +89,7 @@ public:
*/
bool vm_check(Template * tmpl, string& error_str)
{
if ( network_quota.check(tmpl, error_str) == false )
{
return false;
}
if ( vm_quota.check(tmpl, error_str) == false )
{
network_quota.del(tmpl);
return false;
}
if ( image_quota.check(tmpl, error_str) == false )
{
network_quota.del(tmpl);
vm_quota.del(tmpl);
return false;
}
return true;
return quota_check(VIRTUALMACHINE, tmpl, error_str);
}
/**
@ -111,6 +103,22 @@ public:
image_quota.del(tmpl);
}
/**
* Check quota, it updates usage counters if quotas are not exceeded.
* @param type the quota to work with
* @param tmpl template for the VirtualMachine
* @param error_str string describing the error
* @return true if VM can be allocated, false otherwise
*/
bool quota_check(QuotaType type, Template *tmpl, string& error_str);
/**
* Delete usage from the given quota counters.
* @param type the quota to work with
* @param tmpl template for the image, with usage
*/
void quota_del(QuotaType type, Template *tmpl);
/**
* Generates a string representation of the quotas in XML format
* @param xml the string to store the XML
@ -132,7 +140,10 @@ public:
* @param gid of the group
* @param tmpl template for the image, with usage
*/
static void vm_del(int uid, int gid, Template * tmpl);
static void vm_del(int uid, int gid, Template * tmpl)
{
quota_del(VIRTUALMACHINE, uid, gid, tmpl);
}
/**
* Delete Datastore related usage from quota counters.
@ -141,7 +152,20 @@ public:
* @param gid of the group
* @param tmpl template for the image, with usage
*/
static void ds_del(int uid, int gid, Template * tmpl);
static void ds_del(int uid, int gid, Template * tmpl)
{
quota_del(DATASTORE, uid, gid, tmpl);
}
/**
* Delete usage from the given quota counters.
* for the given user and group
* @param type the quota to work with
* @param uid of the user
* @param gid of the group
* @param tmpl template for the image, with usage
*/
static void quota_del(QuotaType type, int uid, int gid, Template * tmpl);
private:
//--------------------------------------------------------------------------

View File

@ -23,6 +23,7 @@
#include "RequestManager.h"
#include "AuthRequest.h"
#include "PoolObjectSQL.h"
#include "Quotas.h"
using namespace std;
@ -157,20 +158,6 @@ protected:
bool basic_authorization(int oid, AuthRequest::Operation op,
RequestAttributes& att);
/**
* Performs a basic quota check for this request using the uid/gid and
* object type from the request. Usage counters are updated for the
* user/group.
* @param tmpl describing the object
* @param att the specific request attributes
*
* @return true if the user is authorized.
*/
bool quota_authorization(Template * tmpl, RequestAttributes& att)
{
return quota_authorization(tmpl, auth_object, att);
}
/**
* Performs a basic quota check for this request using the uid/gid
* from the request. Usage counters are updated for the user/group.
@ -181,7 +168,7 @@ protected:
* @return true if the user is authorized.
*/
bool quota_authorization(Template * tmpl,
PoolObjectSQL::ObjectType object,
Quotas::QuotaType qtype,
RequestAttributes& att);
/**
* Performs rollback on usage counters for a previous quota check operation
@ -189,19 +176,8 @@ protected:
* @param tmpl describing the object
* @param att the specific request attributes
*/
void quota_rollback(Template * tmpl, RequestAttributes& att)
{
quota_rollback(tmpl, auth_object, att);
}
/**
* Performs rollback on usage counters for a previous quota check operation
* for the request.
* @param tmpl describing the object
* @param att the specific request attributes
*/
void quota_rollback(Template * tmpl,
PoolObjectSQL::ObjectType object,
void quota_rollback(Template * tmpl,
Quotas::QuotaType qtype,
RequestAttributes& att);
/**
@ -317,21 +293,21 @@ private:
/* ------------- Functions to manage user and group quotas -------------- */
bool user_quota_authorization(Template * tmpl,
PoolObjectSQL::ObjectType object,
Quotas::QuotaType qtype,
RequestAttributes& att,
string& error_str);
bool group_quota_authorization(Template * tmpl,
PoolObjectSQL::ObjectType object,
Quotas::QuotaType qtype,
RequestAttributes& att,
string& error_str);
void user_quota_rollback(Template * tmpl,
PoolObjectSQL::ObjectType object,
Quotas::QuotaType qtype,
RequestAttributes& att);
void group_quota_rollback(Template * tmpl,
PoolObjectSQL::ObjectType object,
Quotas::QuotaType qtype,
RequestAttributes& att);
};

View File

@ -241,7 +241,7 @@ private:
const int oid,
const string& drv_msg) const
{
write_drv("ATTACH", oid, drv_msg);
write_drv("ATTACHDISK", oid, drv_msg);
}
/**
@ -253,7 +253,7 @@ private:
const int oid,
const string& drv_msg) const
{
write_drv("DETACH", oid, drv_msg);
write_drv("DETACHDISK", oid, drv_msg);
}
private:

View File

@ -889,7 +889,7 @@ void LifeCycleManager::attach_failure_action(int vid)
tmpl.set(disk);
Quotas::vm_del(uid, gid, &tmpl);
Quotas::quota_del(Quotas::IMAGE, uid, gid, &tmpl);
}
}
@ -927,7 +927,7 @@ void LifeCycleManager::detach_success_action(int vid)
tmpl.set(disk);
Quotas::vm_del(uid, gid, &tmpl);
Quotas::quota_del(Quotas::IMAGE, uid, gid, &tmpl);
}
}

View File

@ -113,7 +113,7 @@ bool Request::basic_authorization(int oid,
/* -------------------------------------------------------------------------- */
bool Request::user_quota_authorization (Template * tmpl,
PoolObjectSQL::ObjectType object,
Quotas::QuotaType qtype,
RequestAttributes& att,
string& error_str)
{
@ -131,20 +131,7 @@ bool Request::user_quota_authorization (Template * tmpl,
return false;
}
switch (object)
{
case PoolObjectSQL::IMAGE:
rc = user->quota.ds_check(tmpl, error_str);
break;
case PoolObjectSQL::VM:
case PoolObjectSQL::TEMPLATE:
rc = user->quota.vm_check(tmpl, error_str);
break;
default:
break;
}
rc = user->quota.quota_check(qtype, tmpl, error_str);
if (rc == true)
{
@ -159,7 +146,7 @@ bool Request::user_quota_authorization (Template * tmpl,
/* -------------------------------------------------------------------------- */
bool Request::group_quota_authorization (Template * tmpl,
PoolObjectSQL::ObjectType object,
Quotas::QuotaType qtype,
RequestAttributes& att,
string& error_str)
{
@ -177,20 +164,7 @@ bool Request::group_quota_authorization (Template * tmpl,
return false;
}
switch (object)
{
case PoolObjectSQL::IMAGE:
rc = group->quota.ds_check(tmpl, error_str);
break;
case PoolObjectSQL::VM:
case PoolObjectSQL::TEMPLATE:
rc = group->quota.vm_check(tmpl, error_str);
break;
default:
break;
}
rc = group->quota.quota_check(qtype, tmpl, error_str);
if (rc == true)
{
@ -204,8 +178,8 @@ bool Request::group_quota_authorization (Template * tmpl,
/* -------------------------------------------------------------------------- */
void Request::user_quota_rollback(Template * tmpl,
PoolObjectSQL::ObjectType object,
void Request::user_quota_rollback(Template * tmpl,
Quotas::QuotaType qtype,
RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
@ -220,20 +194,7 @@ void Request::user_quota_rollback(Template * tmpl,
return;
}
switch (object)
{
case PoolObjectSQL::IMAGE:
user->quota.ds_del(tmpl);
break;
case PoolObjectSQL::VM:
case PoolObjectSQL::TEMPLATE:
user->quota.vm_del(tmpl);
break;
default:
break;
}
user->quota.quota_del(qtype, tmpl);
upool->update(user);
@ -242,8 +203,8 @@ void Request::user_quota_rollback(Template * tmpl,
/* -------------------------------------------------------------------------- */
void Request::group_quota_rollback(Template * tmpl,
PoolObjectSQL::ObjectType object,
void Request::group_quota_rollback(Template * tmpl,
Quotas::QuotaType qtype,
RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
@ -258,19 +219,7 @@ void Request::group_quota_rollback(Template * tmpl,
return;
}
switch (object)
{
case PoolObjectSQL::IMAGE:
group->quota.ds_del(tmpl);
break;
case PoolObjectSQL::VM:
case PoolObjectSQL::TEMPLATE:
group->quota.vm_del(tmpl);
break;
default:
break;
}
group->quota.quota_del(qtype, tmpl);
gpool->update(group);
@ -280,23 +229,17 @@ void Request::group_quota_rollback(Template * tmpl,
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool Request::quota_authorization(Template * tmpl,
PoolObjectSQL::ObjectType object,
bool Request::quota_authorization(Template * tmpl,
Quotas::QuotaType qtype,
RequestAttributes& att)
{
string error_str;
if (object != PoolObjectSQL::IMAGE &&
object != PoolObjectSQL::VM &&
object != PoolObjectSQL::TEMPLATE)
{
return true;
}
// uid/gid == -1 means do not update user/group
if ( att.uid != UserPool::ONEADMIN_ID && att.uid != -1)
{
if ( user_quota_authorization(tmpl, object, att, error_str) == false )
if ( user_quota_authorization(tmpl, qtype, att, error_str) == false )
{
failure_response(AUTHORIZATION,
authorization_error(error_str, att),
@ -308,9 +251,9 @@ bool Request::quota_authorization(Template * tmpl,
if ( att.gid != GroupPool::ONEADMIN_ID && att.gid != -1)
{
if ( group_quota_authorization(tmpl, object, att, error_str) == false )
if ( group_quota_authorization(tmpl, qtype, att, error_str) == false )
{
user_quota_rollback(tmpl, object, att);
user_quota_rollback(tmpl, qtype, att);
failure_response(AUTHORIZATION,
authorization_error(error_str, att),
@ -326,26 +269,20 @@ bool Request::quota_authorization(Template * tmpl,
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Request::quota_rollback(Template * tmpl,
PoolObjectSQL::ObjectType object,
void Request::quota_rollback(Template * tmpl,
Quotas::QuotaType qtype,
RequestAttributes& att)
{
if (object != PoolObjectSQL::IMAGE &&
object != PoolObjectSQL::VM &&
object != PoolObjectSQL::TEMPLATE)
{
return;
}
// uid/gid == -1 means do not update user/group
if ( att.uid != UserPool::ONEADMIN_ID && att.uid != -1 )
{
user_quota_rollback(tmpl, object, att);
user_quota_rollback(tmpl, qtype, att);
}
if ( att.gid != GroupPool::ONEADMIN_ID && att.gid != -1 )
{
group_quota_rollback(tmpl, object, att);;
group_quota_rollback(tmpl, qtype, att);;
}
}

View File

@ -114,7 +114,7 @@ bool VirtualMachineAllocate::allocate_authorization(
// -------------------------- Check Quotas ----------------------------
if ( quota_authorization(tmpl, att) == false )
if ( quota_authorization(tmpl, Quotas::VIRTUALMACHINE, att) == false )
{
return false;
}
@ -281,7 +281,7 @@ int VirtualMachineAllocate::pool_allocate(xmlrpc_c::paramList const& paramList,
if ( rc < 0 )
{
quota_rollback(&tmpl_back, att);
quota_rollback(&tmpl_back, Quotas::VIRTUALMACHINE, att);
}
return rc;
@ -442,7 +442,7 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
// -------------------------- Check Quotas ----------------------------
if ( quota_authorization(&img_usage, att) == false )
if ( quota_authorization(&img_usage, Quotas::DATASTORE, att) == false )
{
delete tmpl;
return;
@ -462,7 +462,7 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
error_str);
if ( rc < 0 )
{
quota_rollback(&img_usage, att);
quota_rollback(&img_usage, Quotas::DATASTORE, att);
failure_response(INTERNAL, allocate_error(error_str), att);
return;

View File

@ -34,7 +34,8 @@ PoolObjectSQL * RequestManagerChown::get_and_quota(
int old_uid;
int old_gid;
PoolObjectSQL * object;
PoolObjectSQL * object;
Quotas::QuotaType qtype;
object = pool->get(oid,true);
@ -48,15 +49,18 @@ PoolObjectSQL * RequestManagerChown::get_and_quota(
if ( auth_object == PoolObjectSQL::VM )
{
tmpl = (static_cast<VirtualMachine*>(object))->clone_template();
tmpl = (static_cast<VirtualMachine*>(object))->clone_template();
qtype = Quotas::VIRTUALMACHINE;
}
else
else
{
Image * img = static_cast<Image *>(object);
tmpl = new Template;
tmpl->add("DATASTORE", img->get_ds_id());
tmpl->add("SIZE", img->get_size());
qtype = Quotas::DATASTORE;
}
if ( new_uid == -1 )
@ -82,28 +86,28 @@ PoolObjectSQL * RequestManagerChown::get_and_quota(
RequestAttributes att_new(new_uid, new_gid, att);
RequestAttributes att_old(old_uid, old_gid, att);
if ( quota_authorization(tmpl, att_new) == false )
if ( quota_authorization(tmpl, qtype, att_new) == false )
{
delete tmpl;
return 0;
}
quota_rollback(tmpl, att_old);
quota_rollback(tmpl, qtype, att_old);
object = pool->get(oid,true);
if ( object == 0 )
{
quota_rollback(tmpl, att_new);
quota_rollback(tmpl, qtype, att_new);
quota_authorization(tmpl, att_old);
quota_authorization(tmpl, qtype, att_old);
failure_response(NO_EXISTS,
get_error(object_name(auth_object), oid),
att);
}
delete tmpl;
delete tmpl;
return object;
}

View File

@ -99,7 +99,7 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
return;
}
if ( quota_authorization(tmpl, att) == false )
if ( quota_authorization(tmpl, Quotas::VIRTUALMACHINE, att) == false )
{
delete tmpl;
return;
@ -117,7 +117,7 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
allocate_error(PoolObjectSQL::VM,error_str),
att);
quota_rollback(&tmpl_back, att);
quota_rollback(&tmpl_back, Quotas::VIRTUALMACHINE, att);
return;
}

View File

@ -558,7 +558,7 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
return;
}
if ( quota_authorization(&img_usage, PoolObjectSQL::IMAGE, att) == false )
if ( quota_authorization(&img_usage, Quotas::DATASTORE, att) == false )
{
delete itemplate;
return;
@ -581,7 +581,7 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
error_str);
if (rc < 0)
{
quota_rollback(&img_usage, PoolObjectSQL::IMAGE, att);
quota_rollback(&img_usage, Quotas::DATASTORE, att);
failure_response(INTERNAL,
allocate_error(PoolObjectSQL::IMAGE, error_str), att);
@ -666,7 +666,7 @@ void VirtualMachineAttach::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
if ( quota_authorization(tmpl, att) == false )
if ( quota_authorization(tmpl, Quotas::IMAGE, att) == false )
{
delete tmpl;
return;
@ -676,7 +676,7 @@ void VirtualMachineAttach::request_execute(xmlrpc_c::paramList const& paramList,
if ( rc != 0 )
{
quota_rollback(tmpl, att);
quota_rollback(tmpl, Quotas::IMAGE, att);
failure_response(ACTION,
request_error(error_str, ""),

View File

@ -142,48 +142,82 @@ int Quotas::from_xml(ObjectXML * object_xml)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Quotas::vm_del(int uid, int gid, Template * tmpl)
void Quotas::quota_del(QuotaType type, Template *tmpl)
{
Nebula& nd = Nebula::instance();
UserPool * upool = nd.get_upool();
GroupPool * gpool = nd.get_gpool();
User * user;
Group * group;
if ( uid != UserPool::ONEADMIN_ID )
switch (type)
{
user = upool->get(uid, true);
case DATASTORE:
datastore_quota.del(tmpl);
break;
if ( user != 0 )
{
user->quota.vm_del(tmpl);
case NETWORK:
network_quota.del(tmpl);
break;
upool->update(user);
case IMAGE:
image_quota.del(tmpl);
break;
user->unlock();
}
case VM:
vm_quota.del(tmpl);
break;
case VIRTUALMACHINE:
network_quota.del(tmpl);
vm_quota.del(tmpl);
image_quota.del(tmpl);
break;
}
if ( gid != GroupPool::ONEADMIN_ID )
{
group = gpool->get(gid, true);
if ( group != 0 )
{
group->quota.vm_del(tmpl);
gpool->update(group);
group->unlock();
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Quotas::ds_del(int uid, int gid, Template * tmpl)
bool Quotas::quota_check(QuotaType type, Template *tmpl, string& error_str)
{
switch (type)
{
case DATASTORE:
return datastore_quota.check(tmpl, error_str);
case NETWORK:
return network_quota.check(tmpl, error_str);
case IMAGE:
return image_quota.check(tmpl, error_str);
case VM:
return vm_quota.check(tmpl, error_str);
case VIRTUALMACHINE:
if ( network_quota.check(tmpl, error_str) == false )
{
return false;
}
if ( vm_quota.check(tmpl, error_str) == false )
{
network_quota.del(tmpl);
return false;
}
if ( image_quota.check(tmpl, error_str) == false )
{
network_quota.del(tmpl);
vm_quota.del(tmpl);
return false;
}
return true;
}
return false;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Quotas::quota_del(QuotaType type, int uid, int gid, Template * tmpl)
{
Nebula& nd = Nebula::instance();
UserPool * upool = nd.get_upool();
@ -198,7 +232,7 @@ void Quotas::ds_del(int uid, int gid, Template * tmpl)
if ( user != 0 )
{
user->quota.ds_del(tmpl);
user->quota.quota_del(type, tmpl);
upool->update(user);
@ -212,7 +246,7 @@ void Quotas::ds_del(int uid, int gid, Template * tmpl)
if ( group != 0 )
{
group->quota.ds_del(tmpl);
group->quota.quota_del(type, tmpl);
gpool->update(group);

View File

@ -335,7 +335,7 @@ void VirtualMachineManagerDriver::protocol(
vmpool->update(vm);
}
}
else if ( action == "ATTACH" )
else if ( action == "ATTACHDISK" )
{
Nebula &ne = Nebula::instance();
LifeCycleManager *lcm = ne.get_lcm();
@ -354,7 +354,7 @@ void VirtualMachineManagerDriver::protocol(
lcm->trigger(LifeCycleManager::ATTACH_FAILURE, id);
}
}
else if ( action == "DETACH" )
else if ( action == "DETACHDISK" )
{
Nebula &ne = Nebula::instance();
LifeCycleManager *lcm = ne.get_lcm();

View File

@ -76,6 +76,14 @@ class DummyDriver < VirtualMachineDriver
send_message(ACTION[:migrate],RESULT[:success],id)
end
def attach_disk(id, drv_message)
send_message(ACTION[:attach_disk],RESULT[:success],id)
end
def detach_disk(id, drv_message)
send_message(ACTION[:detach_disk],RESULT[:success],id)
end
def poll(id, drv_message)
# monitor_info: string in the form "VAR=VAL VAR=VAL ... VAR=VAL"
# known VAR are in POLL_ATTRIBUTES. VM states VM_STATES

View File

@ -516,6 +516,8 @@ class ExecDriver < VirtualMachineDriver
disk_xpath = "VM/TEMPLATE/DISK[DISK_ID='#{disk_id}']/TARGET"
target = ensure_xpath(xml_data, id, action, disk_xpath) || return
target_index = target.downcase[-1..-1].unpack('c').first - 97
action = VmmAction.new(self, id, :attach_disk, drv_message)
steps = [
@ -529,7 +531,12 @@ class ExecDriver < VirtualMachineDriver
{
:driver => :vmm,
:action => :attach_disk,
:parameters => [:deploy_id, :disk_target_path, target]
:parameters => [
:deploy_id,
:disk_target_path,
target,
target_index
]
}
]
@ -549,6 +556,8 @@ class ExecDriver < VirtualMachineDriver
disk_xpath = "VM/TEMPLATE/DISK[DISK_ID='#{disk_id}']/TARGET"
target = ensure_xpath(xml_data, id, action, disk_xpath) || return
target_index = target.downcase[-1..-1].unpack('c').first - 97
action = VmmAction.new(self, id, :detach_disk, drv_message)
steps = [
@ -556,7 +565,12 @@ class ExecDriver < VirtualMachineDriver
{
:driver => :vmm,
:action => :attach_disk,
:parameters => [:deploy_id, target]
:parameters => [
:deploy_id,
:disk_target_path,
target,
target_index
]
},
# Perform an EPILOG on the disk
{

View File

@ -22,6 +22,7 @@ source $(dirname $0)/../../scripts_common.sh
DOMAIN="$1"
SOURCE="$2"
TARGET="$3"
TARGET_INDEX="$4"
ATTACH_PARAMS="--domain $DOMAIN --source $SOURCE --target $TARGET"

View File

@ -20,7 +20,9 @@ source $(dirname $0)/kvmrc
source $(dirname $0)/../../scripts_common.sh
DOMAIN="$1"
TARGET="$2"
SOURCE="$2"
TARGET="$3"
TARGET_INDEX="$4"
DETACH_PARAMS="--domain $DOMAIN --target $TARGET"