mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-11 05:17:41 +03:00
Feature #1612: Add volatile disk quotas for attach/detach operations
This commit is contained in:
parent
37e065b7f7
commit
b7234a4c37
@ -56,6 +56,16 @@ protected:
|
|||||||
PoolObjectAuth * ds_perm,
|
PoolObjectAuth * ds_perm,
|
||||||
AuthRequest::Operation op);
|
AuthRequest::Operation op);
|
||||||
|
|
||||||
|
bool quota_resize_authorization(
|
||||||
|
Template * deltas,
|
||||||
|
RequestAttributes& att,
|
||||||
|
PoolObjectAuth& vm_perms);
|
||||||
|
|
||||||
|
bool quota_resize_authorization(
|
||||||
|
int oid,
|
||||||
|
Template * deltas,
|
||||||
|
RequestAttributes& att);
|
||||||
|
|
||||||
int get_host_information(
|
int get_host_information(
|
||||||
int hid,
|
int hid,
|
||||||
string& name,
|
string& name,
|
||||||
|
@ -1073,6 +1073,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
static bool isVolatile(const VectorAttribute * disk);
|
static bool isVolatile(const VectorAttribute * disk);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the template contains a volatile disk
|
||||||
|
*/
|
||||||
|
static bool isVolatile(const Template * tmpl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the total SIZE of volatile disks
|
* Return the total SIZE of volatile disks
|
||||||
*/
|
*/
|
||||||
|
@ -1346,12 +1346,21 @@ void LifeCycleManager::attach_failure_action(int vid)
|
|||||||
|
|
||||||
tmpl.set(disk);
|
tmpl.set(disk);
|
||||||
|
|
||||||
Quotas::quota_del(Quotas::IMAGE, uid, gid, &tmpl);
|
|
||||||
|
|
||||||
if ( disk->vector_value("IMAGE_ID", image_id) == 0 )
|
if ( disk->vector_value("IMAGE_ID", image_id) == 0 )
|
||||||
{
|
{
|
||||||
|
// Disk using an Image
|
||||||
|
Quotas::quota_del(Quotas::IMAGE, uid, gid, &tmpl);
|
||||||
|
|
||||||
imagem->release_image(oid, image_id, false);
|
imagem->release_image(oid, image_id, false);
|
||||||
}
|
}
|
||||||
|
else // Volatile disk
|
||||||
|
{
|
||||||
|
// It is an update of the volatile counter without
|
||||||
|
// shutting destroying a VM
|
||||||
|
tmpl.add("VMS", 0);
|
||||||
|
|
||||||
|
Quotas::quota_del(Quotas::VM, uid, gid, &tmpl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -96,6 +96,120 @@ bool RequestManagerVirtualMachine::vm_authorization(
|
|||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
bool RequestManagerVirtualMachine::quota_resize_authorization(
|
||||||
|
int oid,
|
||||||
|
Template * deltas,
|
||||||
|
RequestAttributes& att)
|
||||||
|
{
|
||||||
|
PoolObjectAuth vm_perms;
|
||||||
|
VirtualMachine * vm = Nebula::instance().get_vmpool()->get(oid, true);
|
||||||
|
|
||||||
|
if (vm == 0)
|
||||||
|
{
|
||||||
|
failure_response(NO_EXISTS,
|
||||||
|
get_error(object_name(PoolObjectSQL::VM),oid),
|
||||||
|
att);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vm->get_permissions(vm_perms);
|
||||||
|
|
||||||
|
vm->unlock();
|
||||||
|
|
||||||
|
return quota_resize_authorization(deltas, att, vm_perms);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
bool RequestManagerVirtualMachine::quota_resize_authorization(
|
||||||
|
Template * deltas,
|
||||||
|
RequestAttributes& att,
|
||||||
|
PoolObjectAuth& vm_perms)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
string error_str;
|
||||||
|
|
||||||
|
Nebula& nd = Nebula::instance();
|
||||||
|
UserPool* upool = nd.get_upool();
|
||||||
|
GroupPool* gpool = nd.get_gpool();
|
||||||
|
|
||||||
|
Quotas user_dquotas = nd.get_default_user_quota();
|
||||||
|
Quotas group_dquotas = nd.get_default_group_quota();
|
||||||
|
|
||||||
|
if (vm_perms.uid != UserPool::ONEADMIN_ID)
|
||||||
|
{
|
||||||
|
User * user = upool->get(vm_perms.uid, true);
|
||||||
|
|
||||||
|
if ( user != 0 )
|
||||||
|
{
|
||||||
|
rc = user->quota.quota_update(Quotas::VM, deltas, user_dquotas, error_str);
|
||||||
|
|
||||||
|
if (rc == false)
|
||||||
|
{
|
||||||
|
ostringstream oss;
|
||||||
|
|
||||||
|
oss << object_name(PoolObjectSQL::USER)
|
||||||
|
<< " [" << vm_perms.uid << "] "
|
||||||
|
<< error_str;
|
||||||
|
|
||||||
|
failure_response(AUTHORIZATION,
|
||||||
|
request_error(oss.str(), ""),
|
||||||
|
att);
|
||||||
|
|
||||||
|
user->unlock();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
upool->update(user);
|
||||||
|
|
||||||
|
user->unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vm_perms.gid != GroupPool::ONEADMIN_ID)
|
||||||
|
{
|
||||||
|
Group * group = gpool->get(vm_perms.gid, true);
|
||||||
|
|
||||||
|
if ( group != 0 )
|
||||||
|
{
|
||||||
|
rc = group->quota.quota_update(Quotas::VM, deltas, group_dquotas, error_str);
|
||||||
|
|
||||||
|
if (rc == false)
|
||||||
|
{
|
||||||
|
ostringstream oss;
|
||||||
|
RequestAttributes att_tmp(vm_perms.uid, -1, att);
|
||||||
|
|
||||||
|
oss << object_name(PoolObjectSQL::GROUP)
|
||||||
|
<< " [" << vm_perms.gid << "] "
|
||||||
|
<< error_str;
|
||||||
|
|
||||||
|
failure_response(AUTHORIZATION,
|
||||||
|
request_error(oss.str(), ""),
|
||||||
|
att);
|
||||||
|
|
||||||
|
group->unlock();
|
||||||
|
|
||||||
|
quota_rollback(deltas, Quotas::VM, att_tmp);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpool->update(group);
|
||||||
|
|
||||||
|
group->unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
int RequestManagerVirtualMachine::get_default_ds_information(
|
int RequestManagerVirtualMachine::get_default_ds_information(
|
||||||
int cluster_id,
|
int cluster_id,
|
||||||
int& ds_id,
|
int& ds_id,
|
||||||
@ -1226,10 +1340,13 @@ void VirtualMachineAttach::request_execute(xmlrpc_c::paramList const& paramList,
|
|||||||
DispatchManager * dm = nd.get_dm();
|
DispatchManager * dm = nd.get_dm();
|
||||||
|
|
||||||
VirtualMachineTemplate * tmpl = new VirtualMachineTemplate();
|
VirtualMachineTemplate * tmpl = new VirtualMachineTemplate();
|
||||||
|
VirtualMachineTemplate * deltas = 0;
|
||||||
PoolObjectAuth host_perms;
|
PoolObjectAuth host_perms;
|
||||||
|
PoolObjectAuth vm_perms;
|
||||||
|
|
||||||
int rc;
|
int rc;
|
||||||
string error_str;
|
string error_str;
|
||||||
|
bool volatile_disk;
|
||||||
|
|
||||||
int id = xmlrpc_c::value_int(paramList.getInt(1));
|
int id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||||
string str_tmpl = xmlrpc_c::value_string(paramList.getString(2));
|
string str_tmpl = xmlrpc_c::value_string(paramList.getString(2));
|
||||||
@ -1258,17 +1375,43 @@ void VirtualMachineAttach::request_execute(xmlrpc_c::paramList const& paramList,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
volatile_disk = VirtualMachine::isVolatile(tmpl);
|
||||||
|
|
||||||
|
if ( volatile_disk )
|
||||||
|
{
|
||||||
|
deltas = new VirtualMachineTemplate(*tmpl);
|
||||||
|
|
||||||
|
deltas->add("VMS", 0);
|
||||||
|
|
||||||
|
if (quota_resize_authorization(id, deltas, att) == false)
|
||||||
|
{
|
||||||
|
delete tmpl;
|
||||||
|
delete deltas;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if ( quota_authorization(tmpl, Quotas::IMAGE, att) == false )
|
if ( quota_authorization(tmpl, Quotas::IMAGE, att) == false )
|
||||||
{
|
{
|
||||||
delete tmpl;
|
delete tmpl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rc = dm->attach(id, tmpl, error_str);
|
rc = dm->attach(id, tmpl, error_str);
|
||||||
|
|
||||||
if ( rc != 0 )
|
if ( rc != 0 )
|
||||||
|
{
|
||||||
|
if ( volatile_disk )
|
||||||
|
{
|
||||||
|
quota_rollback(deltas, Quotas::VM, att);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
quota_rollback(tmpl, Quotas::IMAGE, att);
|
quota_rollback(tmpl, Quotas::IMAGE, att);
|
||||||
|
}
|
||||||
|
|
||||||
failure_response(ACTION,
|
failure_response(ACTION,
|
||||||
request_error(error_str, ""),
|
request_error(error_str, ""),
|
||||||
@ -1280,6 +1423,8 @@ void VirtualMachineAttach::request_execute(xmlrpc_c::paramList const& paramList,
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete tmpl;
|
delete tmpl;
|
||||||
|
delete deltas;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1338,13 +1483,7 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList,
|
|||||||
int nvcpu, ovcpu;
|
int nvcpu, ovcpu;
|
||||||
|
|
||||||
Nebula& nd = Nebula::instance();
|
Nebula& nd = Nebula::instance();
|
||||||
UserPool* upool = nd.get_upool();
|
|
||||||
GroupPool* gpool = nd.get_gpool();
|
|
||||||
HostPool * hpool = nd.get_hpool();
|
HostPool * hpool = nd.get_hpool();
|
||||||
|
|
||||||
Quotas user_dquotas = nd.get_default_user_quota();
|
|
||||||
Quotas group_dquotas = nd.get_default_group_quota();
|
|
||||||
|
|
||||||
Host * host;
|
Host * host;
|
||||||
|
|
||||||
Template deltas;
|
Template deltas;
|
||||||
@ -1494,71 +1633,11 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList,
|
|||||||
/* Check quotas */
|
/* Check quotas */
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
if (vm_perms.uid != UserPool::ONEADMIN_ID)
|
if (quota_resize_authorization(&deltas, att, vm_perms) == false)
|
||||||
{
|
{
|
||||||
User * user = upool->get(vm_perms.uid, true);
|
|
||||||
|
|
||||||
if ( user != 0 )
|
|
||||||
{
|
|
||||||
rc = user->quota.quota_update(Quotas::VM, &deltas, user_dquotas, error_str);
|
|
||||||
|
|
||||||
if (rc == false)
|
|
||||||
{
|
|
||||||
ostringstream oss;
|
|
||||||
|
|
||||||
oss << object_name(PoolObjectSQL::USER)
|
|
||||||
<< " [" << vm_perms.uid << "] "
|
|
||||||
<< error_str;
|
|
||||||
|
|
||||||
failure_response(AUTHORIZATION,
|
|
||||||
request_error(oss.str(), ""),
|
|
||||||
att);
|
|
||||||
|
|
||||||
user->unlock();
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
upool->update(user);
|
|
||||||
|
|
||||||
user->unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vm_perms.gid != GroupPool::ONEADMIN_ID)
|
|
||||||
{
|
|
||||||
Group * group = gpool->get(vm_perms.gid, true);
|
|
||||||
|
|
||||||
if ( group != 0 )
|
|
||||||
{
|
|
||||||
rc = group->quota.quota_update(Quotas::VM, &deltas, group_dquotas, error_str);
|
|
||||||
|
|
||||||
if (rc == false)
|
|
||||||
{
|
|
||||||
ostringstream oss;
|
|
||||||
RequestAttributes att_tmp(vm_perms.uid, -1, att);
|
|
||||||
|
|
||||||
oss << object_name(PoolObjectSQL::GROUP)
|
|
||||||
<< " [" << vm_perms.gid << "] "
|
|
||||||
<< error_str;
|
|
||||||
|
|
||||||
failure_response(AUTHORIZATION,
|
|
||||||
request_error(oss.str(), ""),
|
|
||||||
att);
|
|
||||||
|
|
||||||
group->unlock();
|
|
||||||
|
|
||||||
quota_rollback(&deltas, Quotas::VM, att_tmp);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpool->update(group);
|
|
||||||
|
|
||||||
group->unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
/* Check & update host capacity */
|
/* Check & update host capacity */
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
@ -150,7 +150,9 @@ bool QuotaVirtualMachine::update(Template * tmpl,
|
|||||||
vm_request.insert(make_pair("CPU", delta_cpu));
|
vm_request.insert(make_pair("CPU", delta_cpu));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( tmpl->get("VOLATILE_SIZE", delta_size) == true )
|
delta_size = VirtualMachine::get_volatile_disk_size(tmpl);
|
||||||
|
|
||||||
|
if ( delta_size != 0 )
|
||||||
{
|
{
|
||||||
vm_request.insert(make_pair("VOLATILE_SIZE", delta_size));
|
vm_request.insert(make_pair("VOLATILE_SIZE", delta_size));
|
||||||
}
|
}
|
||||||
|
@ -2018,6 +2018,7 @@ VectorAttribute * VirtualMachine::delete_attach_disk()
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
@ -2033,6 +2034,32 @@ bool VirtualMachine::isVolatile(const VectorAttribute * disk)
|
|||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
bool VirtualMachine::isVolatile(const Template * tmpl)
|
||||||
|
{
|
||||||
|
vector<const Attribute*> disks;
|
||||||
|
int num_disks = tmpl->get("DISK", disks);
|
||||||
|
|
||||||
|
for (int i = 0 ; i < num_disks ; i++)
|
||||||
|
{
|
||||||
|
const VectorAttribute * disk = dynamic_cast<const VectorAttribute*>(disks[i]);
|
||||||
|
|
||||||
|
if (disk == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VirtualMachine::isVolatile(disk))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
float VirtualMachine::get_volatile_disk_size(Template * tmpl)
|
float VirtualMachine::get_volatile_disk_size(Template * tmpl)
|
||||||
{
|
{
|
||||||
float size = 0;
|
float size = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user