1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-22 13:33:52 +03:00

F #2228: Added new VM quota - RUNNING_MEMORY, RUNNING_CPU and RUNNING_VMS.

These running quotas are for all states included in ACTIVE and VMS being
scheduled (PENDING and HOLD) as those states consume the same resources (in
terms of allocation) as running VMs.

Author: juanmont <juanmont@ucm.es>
This commit is contained in:
Ruben S. Montero 2018-09-05 15:14:39 +02:00
parent b3d4cb6a98
commit 1235866e51
18 changed files with 799 additions and 103 deletions

View File

@ -22,6 +22,7 @@
#include "VirtualMachinePool.h" #include "VirtualMachinePool.h"
#include "VirtualRouterPool.h" #include "VirtualRouterPool.h"
#include "ClusterPool.h" #include "ClusterPool.h"
#include "UserPool.h"
using namespace std; using namespace std;
@ -493,10 +494,15 @@ private:
HostPool * hpool; HostPool * hpool;
/** /**
* Pointer to the Virtual Machine Pool, to access hosts * Pointer to the Virtual Machine Pool, to access VMs
*/ */
VirtualMachinePool * vmpool; VirtualMachinePool * vmpool;
/**
* Pointer to the User Pool, to access user
*/
UserPool * upool;
/** /**
* Pointer to the Cluster Pool * Pointer to the Cluster Pool
*/ */
@ -568,6 +574,15 @@ private:
}; };
void user_action(const ActionRequest& ar); void user_action(const ActionRequest& ar);
/**
* Fill a template only with the necessary attributes to update the quotas
* @param vm with the attributes
* @param template that will be filled
* @param only_running true to not add CPU, MEMORY and VMS counters
*/
void get_quota_template(VirtualMachine * vm,
VirtualMachineTemplate& quota_tmpl, bool only_running);
}; };
#endif /*DISPATCH_MANAGER_H*/ #endif /*DISPATCH_MANAGER_H*/

View File

@ -23,12 +23,18 @@
* VM Quotas, defined as: * VM Quotas, defined as:
* VM = [ * VM = [
* VMS = <Max. number of VMs> * VMS = <Max. number of VMs>
* RUNNING_VMS = <Max. number of RUNNING VMS>
* MEMORY = <Max. number of MB requested by VMs> * MEMORY = <Max. number of MB requested by VMs>
* RUNNING_MEMORY = <Max. number of MB requested by RUNNING VMs>
* CPU = <Max. number of CPU units requested by VMs> * CPU = <Max. number of CPU units requested by VMs>
* RUNNING_CPU = <Max. number of running CPU units requested by VMs>
* SYSTEM_DISK_SIZE = <Max. number of system disk MB> * SYSTEM_DISK_SIZE = <Max. number of system disk MB>
* VMS_USED = Current number of VMs * VMS_USED = Current number of VMs
* RUNNING_VMS_USED = Current number of running VMs
* MEMORY_USED = Overall Memory requested * MEMORY_USED = Overall Memory requested
* RUNNING_MEMORY_USED = Overall running Memory requested
* CPU_USED = Overall CPU requested * CPU_USED = Overall CPU requested
* RUNNING_CPU_USED = Overall running CPU requested
* SYSTEM_DISK_SIZE_USED = Overall system disk requested * SYSTEM_DISK_SIZE_USED = Overall system disk requested
* ] * ]
* *
@ -121,6 +127,7 @@ protected:
static const char * VM_METRICS[]; static const char * VM_METRICS[];
static const int NUM_VM_METRICS; static const int NUM_VM_METRICS;
}; };
#endif /*QUOTA_VIRTUALMACHINE_H_*/ #endif /*QUOTA_VIRTUALMACHINE_H_*/

View File

@ -162,13 +162,26 @@ public:
* for the given user and group * for the given user and group
* @param uid of the user * @param uid of the user
* @param gid of the group * @param gid of the group
* @param tmpl template for the image, with usage * @param tmpl template for the vm 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); quota_del(VIRTUALMACHINE, uid, gid, tmpl);
} }
/**
* Check VM related usage (network, image and compute) from quota counters
* for the given user and group. Quotas are updated if not exceeded.
* @param uid of the user
* @param gid of the group
* @param tmpl template for the vm with usage
* @param error string
*/
static void vm_check(int uid, int gid, Template * tmpl, string& error)
{
quota_check(VIRTUALMACHINE, uid, gid, tmpl, error);
}
/** /**
* Delete Datastore related usage from quota counters. * Delete Datastore related usage from quota counters.
* for the given user and group * for the given user and group
@ -209,8 +222,7 @@ public:
static void ds_del_recreate(int uid, int gid, vector<Template *>& ds_quotas); static void ds_del_recreate(int uid, int gid, vector<Template *>& ds_quotas);
/** /**
* Delete usage from the given quota counters. * Delete usage from the given quota counters for the given user and group
* for the given user and group
* @param type the quota to work with * @param type the quota to work with
* @param uid of the user * @param uid of the user
* @param gid of the group * @param gid of the group
@ -218,6 +230,16 @@ public:
*/ */
static void quota_del(QuotaType type, int uid, int gid, Template * tmpl); static void quota_del(QuotaType type, int uid, int gid, Template * 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_check(QuotaType type, int uid, int gid, Template * tmpl,
string& error);
protected: protected:
/** /**
* This is an specialized constructor only for derived Quotas classes. * This is an specialized constructor only for derived Quotas classes.

View File

@ -117,6 +117,12 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
"CPU_USED" => "0", "CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT, "MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"MEMORY_USED" => "0", "MEMORY_USED" => "0",
"RUNNING_VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_VMS_USED" => "0",
"RUNNING_CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_CPU_USED" => "0",
"RUNNING_MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_MEMORY_USED" => "0",
"SYSTEM_DISK_SIZE" => OneQuotaHelper::LIMIT_DEFAULT, "SYSTEM_DISK_SIZE" => OneQuotaHelper::LIMIT_DEFAULT,
"SYSTEM_DISK_SIZE_USED" => "0" "SYSTEM_DISK_SIZE_USED" => "0"
} }
@ -154,6 +160,12 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
"CPU_USED" => "0", "CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT, "MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"MEMORY_USED" => "0", "MEMORY_USED" => "0",
"RUNNING_VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_VMS_USED" => "0",
"RUNNING_CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_CPU_USED" => "0",
"RUNNING_MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_MEMORY_USED" => "0",
"SYSTEM_DISK_SIZE" => OneQuotaHelper::LIMIT_DEFAULT, "SYSTEM_DISK_SIZE" => OneQuotaHelper::LIMIT_DEFAULT,
"SYSTEM_DISK_SIZE_USED" => "0" "SYSTEM_DISK_SIZE_USED" => "0"
} }
@ -194,6 +206,12 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
"CPU_USED" => "0", "CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT, "MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"MEMORY_USED" => "0", "MEMORY_USED" => "0",
"RUNNING_VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_VMS_USED" => "0",
"RUNNING_CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_CPU_USED" => "0",
"RUNNING_MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_MEMORY_USED" => "0",
"SYSTEM_DISK_SIZE" => OneQuotaHelper::LIMIT_DEFAULT, "SYSTEM_DISK_SIZE" => OneQuotaHelper::LIMIT_DEFAULT,
"SYSTEM_DISK_SIZE_USED" => "0" "SYSTEM_DISK_SIZE_USED" => "0"
} }

View File

@ -35,8 +35,11 @@ class OneQuotaHelper
# #
# VM = [ # VM = [
# VMS = <Max. number of VMs> # VMS = <Max. number of VMs>
# RUNNING_VMS = <Max. number of running VMs>
# MEMORY = <Max. allocated memory (MB)> # MEMORY = <Max. allocated memory (MB)>
# RUNNING_MEMORY = <Max. running memory (MB)>
# CPU = <Max. allocated CPU> # CPU = <Max. allocated CPU>
# RUNNING_CPU = <Max. running CPU>
# SYSTEM_DISK_SIZE = <Max. allocated system disk (MB)> # SYSTEM_DISK_SIZE = <Max. allocated system disk (MB)>
# ] # ]
# #
@ -196,7 +199,7 @@ class OneQuotaHelper
puts puts
CLIHelper.print_header(str_h1 % "RESOURCE USAGE & QUOTAS",false) CLIHelper.print_header(str_h1 % "VMS USAGE & QUOTAS",false)
puts puts
@ -216,6 +219,12 @@ class OneQuotaHelper
"CPU_USED" => "0", "CPU_USED" => "0",
"MEMORY" => limit, "MEMORY" => limit,
"MEMORY_USED" => "0", "MEMORY_USED" => "0",
"RUNNING_VMS" => limit,
"RUNNING_VMS_USED" => "0",
"RUNNING_CPU" => limit,
"RUNNING_CPU_USED" => "0",
"RUNNING_MEMORY" => limit,
"RUNNING_MEMORY_USED" => "0",
"SYSTEM_DISK_SIZE" => limit, "SYSTEM_DISK_SIZE" => limit,
"SYSTEM_DISK_SIZE_USED" => "0" "SYSTEM_DISK_SIZE_USED" => "0"
}] }]
@ -223,7 +232,7 @@ class OneQuotaHelper
if !vm_quotas[0].nil? if !vm_quotas[0].nil?
CLIHelper::ShowTable.new(nil, self) do CLIHelper::ShowTable.new(nil, self) do
column :"NUMBER OF VMS", "", :right, :size=>17 do |d| column :"VMS", "", :right, :size=>17 do |d|
if !d.nil? if !d.nil?
elem = 'VMS' elem = 'VMS'
limit = d[elem] limit = d[elem]
@ -297,11 +306,87 @@ class OneQuotaHelper
puts puts
end end
CLIHelper.print_header(str_h1 % "VMS USAGE & QUOTAS - RUNNING",false)
puts
if !vm_quotas[0].nil?
CLIHelper::ShowTable.new(nil, self) do
column :"RUNNING VMS", "", :right, :size=>17 do |d|
if !d.nil?
elem = 'RUNNING_VMS'
limit = d[elem] || LIMIT_UNLIMITED
limit = helper.get_default_limit(
limit, "VM_QUOTA/VM/#{elem}")
if d["RUNNING_VMS_USED"].nil?
d["RUNNING_VMS_USED"] = 0
end
if limit == LIMIT_UNLIMITED
"%7d / -" % [d["RUNNING_VMS_USED"]]
else
"%7d / %7d" % [d["RUNNING_VMS_USED"], limit]
end
end
end
column :"RUNNING MEMORY", "", :right, :size=>20 do |d|
if !d.nil?
elem = 'RUNNING_MEMORY'
limit = d[elem] || LIMIT_UNLIMITED
limit = helper.get_default_limit(
limit, "VM_QUOTA/VM/#{elem}")
if d["RUNNING_MEMORY_USED"].nil?
d["RUNNING_MEMORY_USED"] = 0
end
if limit == LIMIT_UNLIMITED
"%8s / -" % [
OpenNebulaHelper.unit_to_str(d["RUNNING_MEMORY_USED"].to_i,{},"M")
]
else
"%8s / %8s" % [
OpenNebulaHelper.unit_to_str(d["RUNNING_MEMORY_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")
]
end
end
end
column :"RUNNING CPU", "", :right, :size=>20 do |d|
if !d.nil?
elem = 'RUNNING_CPU'
limit = d[elem] || LIMIT_UNLIMITED
limit = helper.get_default_limit(
limit, "VM_QUOTA/VM/#{elem}")
if d["RUNNING_CPU_USED"].nil?
d["RUNNING_CPU_USED"] = 0
end
if limit == LIMIT_UNLIMITED
"%8.2f / -" % [d["RUNNING_CPU_USED"]]
else
"%8.2f / %8.2f" % [d["RUNNING_CPU_USED"], limit]
end
end
end
end.show(vm_quotas, {})
puts
end
CLIHelper.print_header(str_h1 % "DATASTORE USAGE & QUOTAS",false)
puts
ds_quotas = [qh['DATASTORE_QUOTA']['DATASTORE']].flatten ds_quotas = [qh['DATASTORE_QUOTA']['DATASTORE']].flatten
if !ds_quotas[0].nil? if !ds_quotas[0].nil?
CLIHelper::ShowTable.new(nil, self) do CLIHelper::ShowTable.new(nil, self) do
column :"DATASTORE ID", "", :size=>12 do |d| column :"ID", "", :size=>12 do |d|
d["ID"] if !d.nil? d["ID"] if !d.nil?
end end
@ -344,11 +429,15 @@ class OneQuotaHelper
puts puts
end end
CLIHelper.print_header(str_h1 % "NETWORK USAGE & QUOTAS",false)
puts
net_quotas = [qh['NETWORK_QUOTA']['NETWORK']].flatten net_quotas = [qh['NETWORK_QUOTA']['NETWORK']].flatten
if !net_quotas[0].nil? if !net_quotas[0].nil?
CLIHelper::ShowTable.new(nil, self) do CLIHelper::ShowTable.new(nil, self) do
column :"NETWORK ID", "", :size=>12 do |d| column :"ID", "", :size=>12 do |d|
d["ID"] if !d.nil? d["ID"] if !d.nil?
end end
@ -371,11 +460,15 @@ class OneQuotaHelper
puts puts
end end
CLIHelper.print_header(str_h1 % "IMAGE USAGE & QUOTAS",false)
puts
image_quotas = [qh['IMAGE_QUOTA']['IMAGE']].flatten image_quotas = [qh['IMAGE_QUOTA']['IMAGE']].flatten
if !image_quotas[0].nil? if !image_quotas[0].nil?
CLIHelper::ShowTable.new(nil, self) do CLIHelper::ShowTable.new(nil, self) do
column :"IMAGE ID", "", :size=>12 do |d| column :"ID", "", :size=>12 do |d|
d["ID"] if !d.nil? d["ID"] if !d.nil?
end end

View File

@ -300,6 +300,12 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
"CPU_USED" => "0", "CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT, "MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"MEMORY_USED" => "0", "MEMORY_USED" => "0",
"RUNNING_VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_VMS_USED" => "0",
"RUNNING_CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_CPU_USED" => "0",
"RUNNING_MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_MEMORY_USED" => "0",
"SYSTEM_DISK_SIZE" => OneQuotaHelper::LIMIT_DEFAULT, "SYSTEM_DISK_SIZE" => OneQuotaHelper::LIMIT_DEFAULT,
"SYSTEM_DISK_SIZE_USED" => "0" "SYSTEM_DISK_SIZE_USED" => "0"
} }
@ -339,6 +345,12 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
"CPU_USED" => "0", "CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT, "MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"MEMORY_USED" => "0", "MEMORY_USED" => "0",
"RUNNING_VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_VMS_USED" => "0",
"RUNNING_CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_CPU_USED" => "0",
"RUNNING_MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_MEMORY_USED" => "0",
"SYSTEM_DISK_SIZE" => OneQuotaHelper::LIMIT_DEFAULT, "SYSTEM_DISK_SIZE" => OneQuotaHelper::LIMIT_DEFAULT,
"SYSTEM_DISK_SIZE_USED" => "0" "SYSTEM_DISK_SIZE_USED" => "0"
} }
@ -381,6 +393,12 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
"CPU_USED" => "0", "CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT, "MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"MEMORY_USED" => "0", "MEMORY_USED" => "0",
"RUNNING_VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_VMS_USED" => "0",
"RUNNING_CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_CPU_USED" => "0",
"RUNNING_MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"RUNNING_MEMORY_USED" => "0",
"SYSTEM_DISK_SIZE" => OneQuotaHelper::LIMIT_DEFAULT, "SYSTEM_DISK_SIZE" => OneQuotaHelper::LIMIT_DEFAULT,
"SYSTEM_DISK_SIZE_USED" => "0" "SYSTEM_DISK_SIZE_USED" => "0"
} }

View File

@ -111,5 +111,45 @@ void DispatchManager::init_managers()
vmpool = nd.get_vmpool(); vmpool = nd.get_vmpool();
clpool = nd.get_clpool(); clpool = nd.get_clpool();
vrouterpool = nd.get_vrouterpool(); vrouterpool = nd.get_vrouterpool();
upool = nd.get_upool();
} }
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void DispatchManager::get_quota_template(VirtualMachine * vm,
VirtualMachineTemplate& quota_tmpl, bool only_running)
{
std::string memory, cpu;
vm->get_template_attribute("MEMORY", memory);
vm->get_template_attribute("CPU", cpu);
if ( (vm->get_state() == VirtualMachine::ACTIVE) ||
(vm->get_state() == VirtualMachine::PENDING) ||
(vm->get_state() == VirtualMachine::CLONING) ||
(vm->get_state() == VirtualMachine::CLONING_FAILURE) ||
(vm->get_state() == VirtualMachine::HOLD) )
{
quota_tmpl.add("RUNNING_MEMORY", memory);
quota_tmpl.add("RUNNING_CPU", cpu);
quota_tmpl.add("RUNNING_VMS", 1);
if (only_running)
{
quota_tmpl.add("MEMORY", 0);
quota_tmpl.add("CPU", 0);
quota_tmpl.add("VMS", 0);
}
else
{
quota_tmpl.add("MEMORY", memory);
quota_tmpl.add("CPU", cpu);
quota_tmpl.add("VMS", 1);
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -22,6 +22,7 @@
#include "ImageManager.h" #include "ImageManager.h"
#include "Quotas.h" #include "Quotas.h"
#include "Request.h" #include "Request.h"
#include "Nebula.h"
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -30,6 +31,13 @@ int DispatchManager::deploy (VirtualMachine * vm, const RequestAttributes& ra)
{ {
ostringstream oss; ostringstream oss;
int vid; int vid;
int uid;
int gid;
string error;
VirtualMachineTemplate quota_tmpl;
bool do_quotas = false;
if ( vm == 0 ) if ( vm == 0 )
{ {
@ -46,10 +54,21 @@ int DispatchManager::deploy (VirtualMachine * vm, const RequestAttributes& ra)
vm->get_state() == VirtualMachine::STOPPED || vm->get_state() == VirtualMachine::STOPPED ||
vm->get_state() == VirtualMachine::UNDEPLOYED ) vm->get_state() == VirtualMachine::UNDEPLOYED )
{ {
do_quotas = vm->get_state() == VirtualMachine::STOPPED ||
vm->get_state() == VirtualMachine::UNDEPLOYED;
vm->set_state(VirtualMachine::ACTIVE); vm->set_state(VirtualMachine::ACTIVE);
vmpool->update(vm); vmpool->update(vm);
if ( do_quotas )
{
uid = vm->get_uid();
gid = vm->get_gid();
get_quota_template(vm, quota_tmpl, true);
}
lcm->trigger(LCMAction::DEPLOY, vid, ra); lcm->trigger(LCMAction::DEPLOY, vid, ra);
} }
else else
@ -57,6 +76,13 @@ int DispatchManager::deploy (VirtualMachine * vm, const RequestAttributes& ra)
goto error; goto error;
} }
vm->unlock();
if ( do_quotas )
{
Quotas::vm_check(uid, gid, &quota_tmpl, error);
}
return 0; return 0;
error: error:
@ -65,6 +91,8 @@ error:
<< ", wrong state " << vm->state_str() << "."; << ", wrong state " << vm->state_str() << ".";
NebulaLog::log("DiM",Log::ERROR,oss); NebulaLog::log("DiM",Log::ERROR,oss);
vm->unlock();
return -1; return -1;
} }
@ -76,6 +104,14 @@ int DispatchManager::import(VirtualMachine * vm, const RequestAttributes& ra)
ostringstream oss; ostringstream oss;
string import_state; string import_state;
int uid;
int gid;
VirtualMachineTemplate quota_tmpl;
bool do_quotas = false;
string error;
if ( vm == 0 ) if ( vm == 0 )
{ {
return -1; return -1;
@ -110,6 +146,13 @@ int DispatchManager::import(VirtualMachine * vm, const RequestAttributes& ra)
{ {
vm->set_state(VirtualMachine::ACTIVE); vm->set_state(VirtualMachine::ACTIVE);
vm->set_state(VirtualMachine::RUNNING); vm->set_state(VirtualMachine::RUNNING);
uid = vm->get_uid();
gid = vm->get_gid();
get_quota_template(vm, quota_tmpl, true);
do_quotas = true;
} }
vm->set_stime(the_time); vm->set_stime(the_time);
@ -125,6 +168,13 @@ int DispatchManager::import(VirtualMachine * vm, const RequestAttributes& ra)
vmpool->update(vm); vmpool->update(vm);
vm->unlock();
if ( do_quotas )
{
Quotas::vm_check(uid, gid, &quota_tmpl, error);
}
return 0; return 0;
} }
@ -215,9 +265,10 @@ error:
void DispatchManager::free_vm_resources(VirtualMachine * vm) void DispatchManager::free_vm_resources(VirtualMachine * vm)
{ {
Template* tmpl;
vector<Template *> ds_quotas; vector<Template *> ds_quotas;
Template * quota_tmpl;
int vmid; int vmid;
int uid; int uid;
int gid; int gid;
@ -225,6 +276,24 @@ void DispatchManager::free_vm_resources(VirtualMachine * vm)
int vrid = -1; int vrid = -1;
unsigned int port; unsigned int port;
quota_tmpl = vm->clone_template();
if ( (vm->get_state() == VirtualMachine::ACTIVE) ||
(vm->get_state() == VirtualMachine::PENDING) ||
(vm->get_state() == VirtualMachine::HOLD) )
{
std::string memory, cpu;
quota_tmpl->get("MEMORY", memory);
quota_tmpl->get("CPU", cpu);
quota_tmpl->add("RUNNING_MEMORY", memory);
quota_tmpl->add("RUNNING_CPU", cpu);
quota_tmpl->add("RUNNING_VMS", 1);
}
quota_tmpl->add("VMS", 1);
vm->release_network_leases(); vm->release_network_leases();
vm->release_vmgroup(); vm->release_vmgroup();
@ -239,7 +308,8 @@ void DispatchManager::free_vm_resources(VirtualMachine * vm)
VectorAttribute * graphics = vm->get_template_attribute("GRAPHICS"); VectorAttribute * graphics = vm->get_template_attribute("GRAPHICS");
if ( graphics != 0 && (graphics->vector_value("PORT", port) == 0) && vm->hasHistory()) if ( graphics != 0 && graphics->vector_value("PORT", port) == 0
&& vm->hasHistory())
{ {
graphics->remove("PORT"); graphics->remove("PORT");
clpool->release_vnc_port(vm->get_cid(), port); clpool->release_vnc_port(vm->get_cid(), port);
@ -250,7 +320,6 @@ void DispatchManager::free_vm_resources(VirtualMachine * vm)
vmid = vm->get_oid(); vmid = vm->get_oid();
uid = vm->get_uid(); uid = vm->get_uid();
gid = vm->get_gid(); gid = vm->get_gid();
tmpl = vm->clone_template();
if (vm->is_imported()) if (vm->is_imported())
{ {
@ -264,9 +333,9 @@ void DispatchManager::free_vm_resources(VirtualMachine * vm)
vm->unlock(); vm->unlock();
Quotas::vm_del(uid, gid, tmpl); Quotas::vm_del(uid, gid, quota_tmpl);
delete tmpl; delete quota_tmpl;
if ( !ds_quotas.empty() ) if ( !ds_quotas.empty() )
{ {
@ -1096,6 +1165,9 @@ int DispatchManager::delete_recreate(VirtualMachine * vm,
Template * vm_quotas_snp = 0; Template * vm_quotas_snp = 0;
VirtualMachineTemplate quota_tmpl;
bool do_quotas = false;
vector<Template *> ds_quotas_snp; vector<Template *> ds_quotas_snp;
int vm_uid, vm_gid; int vm_uid, vm_gid;
@ -1128,6 +1200,8 @@ int DispatchManager::delete_recreate(VirtualMachine * vm,
vm->delete_non_persistent_disk_snapshots(&vm_quotas_snp, vm->delete_non_persistent_disk_snapshots(&vm_quotas_snp,
ds_quotas_snp); ds_quotas_snp);
do_quotas = true;
case VirtualMachine::HOLD: case VirtualMachine::HOLD:
if (vm->hasHistory()) if (vm->hasHistory())
{ {
@ -1142,6 +1216,11 @@ int DispatchManager::delete_recreate(VirtualMachine * vm,
vm->set_state(VirtualMachine::PENDING); vm->set_state(VirtualMachine::PENDING);
vmpool->update(vm); vmpool->update(vm);
if ( do_quotas )
{
get_quota_template(vm, quota_tmpl, true);
}
break; break;
case VirtualMachine::ACTIVE: //Cleanup VM resources before PENDING case VirtualMachine::ACTIVE: //Cleanup VM resources before PENDING
@ -1169,6 +1248,11 @@ int DispatchManager::delete_recreate(VirtualMachine * vm,
delete vm_quotas_snp; delete vm_quotas_snp;
} }
if ( do_quotas )
{
Quotas::vm_check(vm_uid, vm_gid, &quota_tmpl, error);
}
return rc; return rc;
} }

View File

@ -16,12 +16,16 @@
#include "DispatchManager.h" #include "DispatchManager.h"
#include "NebulaLog.h" #include "NebulaLog.h"
#include "Quotas.h"
#include "Nebula.h" #include "Nebula.h"
void DispatchManager::suspend_success_action(int vid) void DispatchManager::suspend_success_action(int vid)
{ {
VirtualMachine * vm; VirtualMachine * vm;
VirtualMachineTemplate quota_tmpl;
string error_str;
int uid, gid;
vm = vmpool->get(vid); vm = vmpool->get(vid);
@ -38,6 +42,8 @@ void DispatchManager::suspend_success_action(int vid)
vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_REVERT_SUSPENDED|| vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_REVERT_SUSPENDED||
vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_DELETE_SUSPENDED)) vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_DELETE_SUSPENDED))
{ {
get_quota_template(vm, quota_tmpl, true);
vm->set_state(VirtualMachine::SUSPENDED); vm->set_state(VirtualMachine::SUSPENDED);
vm->set_state(VirtualMachine::LCM_INIT); vm->set_state(VirtualMachine::LCM_INIT);
@ -51,9 +57,17 @@ void DispatchManager::suspend_success_action(int vid)
oss << "suspend_success action received but VM " << vid oss << "suspend_success action received but VM " << vid
<< " not in ACTIVE state"; << " not in ACTIVE state";
NebulaLog::log("DiM",Log::ERROR,oss); NebulaLog::log("DiM",Log::ERROR,oss);
}
vm->unlock(); vm->unlock();
return;
}
uid = vm->get_uid();
gid = vm->get_gid();
vm->unlock();
Quotas::vm_del(uid, gid, &quota_tmpl);
return; return;
} }
@ -64,6 +78,10 @@ void DispatchManager::suspend_success_action(int vid)
void DispatchManager::stop_success_action(int vid) void DispatchManager::stop_success_action(int vid)
{ {
VirtualMachine * vm; VirtualMachine * vm;
VirtualMachineTemplate quota_tmpl;
string error_str;
int uid, gid;
vm = vmpool->get(vid); vm = vmpool->get(vid);
@ -76,6 +94,8 @@ void DispatchManager::stop_success_action(int vid)
(vm->get_lcm_state() == VirtualMachine::EPILOG_STOP || (vm->get_lcm_state() == VirtualMachine::EPILOG_STOP ||
vm->get_lcm_state() == VirtualMachine::PROLOG_RESUME)) vm->get_lcm_state() == VirtualMachine::PROLOG_RESUME))
{ {
get_quota_template(vm, quota_tmpl, true);
vm->set_state(VirtualMachine::STOPPED); vm->set_state(VirtualMachine::STOPPED);
vm->set_state(VirtualMachine::LCM_INIT); vm->set_state(VirtualMachine::LCM_INIT);
@ -97,10 +117,17 @@ void DispatchManager::stop_success_action(int vid)
oss << "stop_success action received but VM " << vid oss << "stop_success action received but VM " << vid
<< " not in ACTIVE state"; << " not in ACTIVE state";
NebulaLog::log("DiM",Log::ERROR,oss); NebulaLog::log("DiM",Log::ERROR,oss);
vm->unlock();
return;
} }
uid = vm->get_uid();
gid = vm->get_gid();
vm->unlock(); vm->unlock();
Quotas::vm_del(uid, gid, &quota_tmpl);
return; return;
} }
@ -110,6 +137,10 @@ void DispatchManager::stop_success_action(int vid)
void DispatchManager::undeploy_success_action(int vid) void DispatchManager::undeploy_success_action(int vid)
{ {
VirtualMachine * vm; VirtualMachine * vm;
VirtualMachineTemplate quota_tmpl;
string error_str;
int uid, gid;
vm = vmpool->get(vid); vm = vmpool->get(vid);
@ -123,6 +154,8 @@ void DispatchManager::undeploy_success_action(int vid)
vm->get_lcm_state() == VirtualMachine::DISK_RESIZE_UNDEPLOYED || vm->get_lcm_state() == VirtualMachine::DISK_RESIZE_UNDEPLOYED ||
vm->get_lcm_state() == VirtualMachine::PROLOG_UNDEPLOY)) vm->get_lcm_state() == VirtualMachine::PROLOG_UNDEPLOY))
{ {
get_quota_template(vm, quota_tmpl, true);
vm->set_state(VirtualMachine::UNDEPLOYED); vm->set_state(VirtualMachine::UNDEPLOYED);
vm->set_state(VirtualMachine::LCM_INIT); vm->set_state(VirtualMachine::LCM_INIT);
@ -144,9 +177,18 @@ void DispatchManager::undeploy_success_action(int vid)
oss << "undeploy_success action received but VM " << vid oss << "undeploy_success action received but VM " << vid
<< " not in ACTIVE state"; << " not in ACTIVE state";
NebulaLog::log("DiM",Log::ERROR,oss); NebulaLog::log("DiM",Log::ERROR,oss);
}
vm->unlock(); vm->unlock();
return;
}
uid = vm->get_uid();
gid = vm->get_gid();
vm->unlock();
Quotas::vm_del(uid, gid, &quota_tmpl);
return; return;
} }
@ -157,6 +199,10 @@ void DispatchManager::undeploy_success_action(int vid)
void DispatchManager::poweroff_success_action(int vid) void DispatchManager::poweroff_success_action(int vid)
{ {
VirtualMachine * vm; VirtualMachine * vm;
VirtualMachineTemplate quota_tmpl;
string error_str;
int uid, gid;
vm = vmpool->get(vid); vm = vmpool->get(vid);
@ -176,6 +222,8 @@ void DispatchManager::poweroff_success_action(int vid)
vm->get_lcm_state() == VirtualMachine::DISK_RESIZE_POWEROFF || vm->get_lcm_state() == VirtualMachine::DISK_RESIZE_POWEROFF ||
vm->get_lcm_state() == VirtualMachine::PROLOG_MIGRATE_POWEROFF_FAILURE)) vm->get_lcm_state() == VirtualMachine::PROLOG_MIGRATE_POWEROFF_FAILURE))
{ {
get_quota_template(vm, quota_tmpl, true);
vm->set_state(VirtualMachine::POWEROFF); vm->set_state(VirtualMachine::POWEROFF);
vm->set_state(VirtualMachine::LCM_INIT); vm->set_state(VirtualMachine::LCM_INIT);
@ -189,9 +237,17 @@ void DispatchManager::poweroff_success_action(int vid)
oss << "poweroff_success action received but VM " << vid oss << "poweroff_success action received but VM " << vid
<< " not in ACTIVE state"; << " not in ACTIVE state";
NebulaLog::log("DiM",Log::ERROR,oss); NebulaLog::log("DiM",Log::ERROR,oss);
}
vm->unlock(); vm->unlock();
return;
}
uid = vm->get_uid();
gid = vm->get_gid();
vm->unlock();
Quotas::vm_del(uid, gid, &quota_tmpl);
return; return;
} }
@ -202,6 +258,7 @@ void DispatchManager::poweroff_success_action(int vid)
void DispatchManager::done_action(int vid) void DispatchManager::done_action(int vid)
{ {
VirtualMachine * vm; VirtualMachine * vm;
string error_str;
VirtualMachine::LcmState lcm_state; VirtualMachine::LcmState lcm_state;
VirtualMachine::VmState dm_state; VirtualMachine::VmState dm_state;

View File

@ -71,6 +71,8 @@ bool VirtualMachineAllocate::allocate_authorization(
string t64; string t64;
string aname; string aname;
std::string memory, cpu;
VirtualMachineTemplate * ttmpl = static_cast<VirtualMachineTemplate *>(tmpl); VirtualMachineTemplate * ttmpl = static_cast<VirtualMachineTemplate *>(tmpl);
// ------------ Check template for restricted attributes ------------------- // ------------ Check template for restricted attributes -------------------
@ -106,6 +108,14 @@ bool VirtualMachineAllocate::allocate_authorization(
VirtualMachineDisks::extended_info(att.uid, &aux_tmpl); VirtualMachineDisks::extended_info(att.uid, &aux_tmpl);
aux_tmpl.get("MEMORY", memory);
aux_tmpl.get("CPU", cpu);
aux_tmpl.add("RUNNING_MEMORY", memory);
aux_tmpl.add("RUNNING_CPU", cpu);
aux_tmpl.add("RUNNING_VMS", 1);
aux_tmpl.add("VMS", 1);
if ( quota_authorization(&aux_tmpl, Quotas::VIRTUALMACHINE, att) == false ) if ( quota_authorization(&aux_tmpl, Quotas::VIRTUALMACHINE, att) == false )
{ {
return false; return false;

View File

@ -140,7 +140,6 @@ Request::ErrorCode VMTemplateClone::clone(int source_id, const string &name,
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
ImageDelete img_delete; ImageDelete img_delete;
ImageClone img_clone; ImageClone img_clone;
ImagePersistent img_persistent;
TemplateDelete tmpl_delete; TemplateDelete tmpl_delete;

View File

@ -120,6 +120,7 @@ Request::ErrorCode VMTemplateInstantiate::request_execute(int id, string name,
RequestAttributes& att) RequestAttributes& att)
{ {
int rc; int rc;
std::string memory, cpu;
ostringstream sid; ostringstream sid;
@ -229,6 +230,14 @@ Request::ErrorCode VMTemplateInstantiate::request_execute(int id, string name,
return AUTHORIZATION; return AUTHORIZATION;
} }
extended_tmpl.get("MEMORY", memory);
extended_tmpl.get("CPU", cpu);
extended_tmpl.add("RUNNING_MEMORY", memory);
extended_tmpl.add("RUNNING_CPU", cpu);
extended_tmpl.add("RUNNING_VMS", 1);
extended_tmpl.add("VMS", 1);
if (quota_authorization(&extended_tmpl, Quotas::VIRTUALMACHINE, att, if (quota_authorization(&extended_tmpl, Quotas::VIRTUALMACHINE, att,
att.resp_msg) == false) att.resp_msg) == false)
{ {

View File

@ -478,6 +478,8 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList,
int rc; int rc;
std::string memory, cpu;
Nebula& nd = Nebula::instance(); Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm(); DispatchManager * dm = nd.get_dm();
@ -487,6 +489,8 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList,
AuthRequest::Operation op; AuthRequest::Operation op;
History::VMAction action; History::VMAction action;
VirtualMachineTemplate quota_tmpl;
VirtualMachine * vm; VirtualMachine * vm;
// Compatibility with 4.x // Compatibility with 4.x
@ -513,6 +517,21 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList,
return; return;
} }
vm->get_template_attribute("MEMORY", memory);
vm->get_template_attribute("CPU", cpu);
quota_tmpl.add("RUNNING_MEMORY", memory);
quota_tmpl.add("RUNNING_CPU", cpu);
quota_tmpl.add("RUNNING_VMS", 1);
quota_tmpl.add("VMS", 0);
quota_tmpl.add("MEMORY", 0);
quota_tmpl.add("CPU", 0);
RequestAttributes& att_aux(att);
att_aux.uid = vm->get_uid();
att_aux.gid = vm->get_gid();
if (vm->is_imported() && !vm->is_imported_action_supported(action)) if (vm->is_imported() && !vm->is_imported_action_supported(action))
{ {
att.resp_msg = "Action \"" + action_st + "\" is not supported for " att.resp_msg = "Action \"" + action_st + "\" is not supported for "
@ -537,6 +556,14 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList,
vm->unlock(); vm->unlock();
if ( action == History::RESUME_ACTION &&
!quota_authorization(&quota_tmpl, Quotas::VIRTUALMACHINE, att_aux,
att.resp_msg) )
{
failure_response(ACTION, att);
return;
}
switch (action) switch (action)
{ {
case History::TERMINATE_ACTION: case History::TERMINATE_ACTION:
@ -922,7 +949,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// deploy the VM // deploy the VM (import/deploy unlocks the vm object)
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
if (vm->is_imported()) if (vm->is_imported())
@ -934,8 +961,6 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
dm->deploy(vm, att); dm->deploy(vm, att);
} }
vm->unlock();
success_response(id, att); success_response(id, att);
} }

View File

@ -23,6 +23,9 @@ define(function(require) {
"MEMORY": QUOTA_LIMIT_UNLIMITED, "MEMORY": QUOTA_LIMIT_UNLIMITED,
"VMS": QUOTA_LIMIT_UNLIMITED, "VMS": QUOTA_LIMIT_UNLIMITED,
"SYSTEM_DISK_SIZE": QUOTA_LIMIT_UNLIMITED, "SYSTEM_DISK_SIZE": QUOTA_LIMIT_UNLIMITED,
"RUNNING_CPU": QUOTA_LIMIT_UNLIMITED,
"RUNNING_MEMORY": QUOTA_LIMIT_UNLIMITED,
"RUNNING_VMS": QUOTA_LIMIT_UNLIMITED,
} }
}, },
"DATASTORE_QUOTA": {}, "DATASTORE_QUOTA": {},
@ -37,6 +40,9 @@ define(function(require) {
"MEMORY": QUOTA_LIMIT_UNLIMITED, "MEMORY": QUOTA_LIMIT_UNLIMITED,
"VMS": QUOTA_LIMIT_UNLIMITED, "VMS": QUOTA_LIMIT_UNLIMITED,
"SYSTEM_DISK_SIZE": QUOTA_LIMIT_UNLIMITED, "SYSTEM_DISK_SIZE": QUOTA_LIMIT_UNLIMITED,
"RUNNING_CPU": QUOTA_LIMIT_UNLIMITED,
"RUNNING_MEMORY": QUOTA_LIMIT_UNLIMITED,
"RUNNING_VMS": QUOTA_LIMIT_UNLIMITED,
} }
}, },
"DATASTORE_QUOTA": {}, "DATASTORE_QUOTA": {},
@ -90,7 +96,10 @@ define(function(require) {
"VMS" : QUOTA_LIMIT_UNLIMITED, "VMS" : QUOTA_LIMIT_UNLIMITED,
"MEMORY" : QUOTA_LIMIT_UNLIMITED, "MEMORY" : QUOTA_LIMIT_UNLIMITED,
"CPU" : QUOTA_LIMIT_UNLIMITED, "CPU" : QUOTA_LIMIT_UNLIMITED,
"SYSTEM_DISK_SIZE" : QUOTA_LIMIT_UNLIMITED "SYSTEM_DISK_SIZE" : QUOTA_LIMIT_UNLIMITED,
"RUNNING_CPU" : QUOTA_LIMIT_UNLIMITED,
"RUNNING_MEMORY" : QUOTA_LIMIT_UNLIMITED,
"RUNNING_VMS" : QUOTA_LIMIT_UNLIMITED
} }
}; };
} }

View File

@ -56,7 +56,13 @@ define(function(require) {
MEMORY : QUOTA_LIMIT_DEFAULT, MEMORY : QUOTA_LIMIT_DEFAULT,
MEMORY_USED : 0, MEMORY_USED : 0,
SYSTEM_DISK_SIZE : QUOTA_LIMIT_DEFAULT, SYSTEM_DISK_SIZE : QUOTA_LIMIT_DEFAULT,
SYSTEM_DISK_SIZE_USED : 0 SYSTEM_DISK_SIZE_USED : 0,
RUNNING_VMS : QUOTA_LIMIT_DEFAULT,
RUNNING_VMS_USED : 0,
RUNNING_CPU : QUOTA_LIMIT_DEFAULT,
RUNNING_CPU_USED : 0,
RUNNING_MEMORY : QUOTA_LIMIT_DEFAULT,
RUNNING_MEMORY_USED : 0
} }
}; };
} }
@ -250,6 +256,147 @@ define(function(require) {
return quotas_tab_html; return quotas_tab_html;
} }
/**
* Returns a widget with the RUNNING VM quotas
* @param {Object} info User/Group object
* @param {Object} default_quotas default quotas for Users/Groups
* @return {string} html string
*/
function _runningVmsWidget(info, default_quotas){
var empty_quotas = $.isEmptyObject(info.VM_QUOTA);
var quotas_tab_html = "";
if (empty_quotas){
quotas_tab_html +=
'<fieldset style="display: none" class="editable_quota">';
} else {
quotas_tab_html +=
'<fieldset>';
}
var running_vms_bar;
if (!empty_quotas){
running_vms_bar = _editableQuotaBar(
info.VM_QUOTA.VM.RUNNING_VMS_USED,
info.VM_QUOTA.VM.RUNNING_VMS,
default_quotas.VM_QUOTA.VM.RUNNING_VMS,
{ quota_name: "RUNNING_VM_VMS"});
} else {
running_vms_bar = _editableQuotaBar(
0,
QUOTA_LIMIT_DEFAULT,
default_quotas.VM_QUOTA.VM.VMS,
{ quota_name: "RUNNING_VM_VMS"});
}
quotas_tab_html +=
'<legend>' + Locale.tr("Running VMs") + '</legend>\
<div>'+running_vms_bar+'</div>\
<br>\
</fieldset>'
return quotas_tab_html;
}
/**
* Returns a widget with the RUNNING CPU quotas
* @param {Object} info User/Group object
* @param {Object} default_quotas default quotas for Users/Groups
* @return {string} html string
*/
function _runningCpuWidget(info, default_quotas){
var empty_quotas = $.isEmptyObject(info.VM_QUOTA);
var quotas_tab_html = "";
if (empty_quotas){
quotas_tab_html +=
'<fieldset style="display: none" class="editable_quota">';
} else {
quotas_tab_html +=
'<fieldset>';
}
var running_cpu_bar;
if (!empty_quotas){
running_cpu_bar = _editableQuotaBar(
info.VM_QUOTA.VM.RUNNING_CPU_USED,
info.VM_QUOTA.VM.RUNNING_CPU,
default_quotas.VM_QUOTA.VM.RUNNING_CPU,
{ is_float: true,
quota_name: "RUNNING_VM_CPU"
});
} else {
running_cpu_bar = _editableQuotaBar(
0,
QUOTA_LIMIT_DEFAULT,
default_quotas.VM_QUOTA.VM.RUNNING_CPU,
{ is_float: true,
quota_name: "RUNNING_VM_CPU"
});
}
quotas_tab_html +=
'<legend>' + Locale.tr("Running CPU") + '</legend>\
<div>'+running_cpu_bar+'</div>\
<br>\
</fieldset>'
return quotas_tab_html;
}
/**
* Returns a widget with the RUNNING MEMORY quotas
* @param {Object} info User/Group object
* @param {Object} default_quotas default quotas for Users/Groups
* @return {string} html string
*/
function _runningMemoryWidget(info, default_quotas){
var empty_quotas = $.isEmptyObject(info.VM_QUOTA);
var quotas_tab_html = "";
if (empty_quotas){
quotas_tab_html +=
'<fieldset style="display: none" class="editable_quota">';
} else {
quotas_tab_html +=
'<fieldset>';
}
var running_memory_bar;
if (!empty_quotas){
running_memory_bar = _editableQuotaBar(
info.VM_QUOTA.VM.RUNNING_MEMORY_USED,
info.VM_QUOTA.VM.RUNNING_MEMORY,
default_quotas.VM_QUOTA.VM.RUNNING_MEMORY,
{ mb: true,
quota_name: "VM_MEMORY"
});
} else {
running_memory_bar = _editableQuotaBar(
0,
QUOTA_LIMIT_DEFAULT,
default_quotas.VM_QUOTA.VM.RUNNING_MEMORY,
{ mb: true,
quota_name: "RUNNING_VM_MEMORY"
});
}
quotas_tab_html +=
'<legend>' + Locale.tr("Running Memory") + '</legend>\
<div>'+running_memory_bar+'</div>\
<br>\
</fieldset>'
return quotas_tab_html;
}
/** /**
* Returns a widget with the image quotas * Returns a widget with the image quotas
* @param {Object} info User/Group object * @param {Object} info User/Group object
@ -714,6 +861,9 @@ define(function(require) {
var cpu_quota = _cpuWidget(resource_info, default_quotas); var cpu_quota = _cpuWidget(resource_info, default_quotas);
var memory_quota = _memoryWidget(resource_info, default_quotas); var memory_quota = _memoryWidget(resource_info, default_quotas);
var system_disk_size_quota = _systemDiskWidget(resource_info, default_quotas); var system_disk_size_quota = _systemDiskWidget(resource_info, default_quotas);
var running_vms_quota = _runningVmsWidget(resource_info, default_quotas);
var running_cpu_quota = _runningCpuWidget(resource_info, default_quotas);
var running_memory_quota = _runningMemoryWidget(resource_info, default_quotas);
var image_quota = _imageWidget(resource_info, default_quotas); var image_quota = _imageWidget(resource_info, default_quotas);
var network_quota = _networkWidget(resource_info, default_quotas); var network_quota = _networkWidget(resource_info, default_quotas);
@ -763,11 +913,18 @@ define(function(require) {
quotas_html += quotas_html +=
'<div class="row">\ '<div class="row">\
<div class="medium-6 columns">' + vms_quota + '</div>\ <div class="medium-6 columns">' + vms_quota + '</div>\
<div class="medium-6 columns">' + running_vms_quota + '</div>\
</div>\
<div class="row">\
<div class="medium-6 columns">' + cpu_quota + '</div>\ <div class="medium-6 columns">' + cpu_quota + '</div>\
<div class="medium-6 columns">' + running_cpu_quota+ '</div>\
</div>\ </div>\
<div class="row">\ <div class="row">\
<div class="medium-6 columns">' + memory_quota + '</div>\ <div class="medium-6 columns">' + memory_quota + '</div>\
<div class="medium-6 columns">' + system_disk_size_quota+ '</div>\ <div class="medium-6 columns">' + running_memory_quota+ '</div>\
</div>\
<div class="row">\
<div class="medium-6 columns">' + system_disk_size_quota + '</div>\
</div>\ </div>\
<br><br>\ <br><br>\
<div class="row">\ <div class="row">\
@ -872,7 +1029,10 @@ define(function(require) {
"CPU" : input_val( $("div[quota_name=VM_CPU] input", parent_container) ), "CPU" : input_val( $("div[quota_name=VM_CPU] input", parent_container) ),
"MEMORY" : input_val( $("div[quota_name=VM_MEMORY] input", parent_container) ), "MEMORY" : input_val( $("div[quota_name=VM_MEMORY] input", parent_container) ),
"VMS" : input_val( $("div[quota_name=VM_VMS] input", parent_container) ), "VMS" : input_val( $("div[quota_name=VM_VMS] input", parent_container) ),
"SYSTEM_DISK_SIZE" : input_val( $("div[quota_name=VM_SYSTEM_DISK_SIZE] input", parent_container) ) "SYSTEM_DISK_SIZE" : input_val( $("div[quota_name=VM_SYSTEM_DISK_SIZE] input", parent_container) ),
"RUNNING_CPU" : input_val( $("div[quota_name=RUNNING_VM_CPU] input", parent_container) ),
"RUNNING_MEMORY" : input_val( $("div[quota_name=RUNNING_VM_MEMORY] input", parent_container) ),
"RUNNING_VMS" : input_val( $("div[quota_name=RUNNING_VM_VMS] input", parent_container) ),
}; };
$.each($("tr.image_quota_tr", parent_container), function(){ $.each($("tr.image_quota_tr", parent_container), function(){
@ -953,6 +1113,18 @@ define(function(require) {
$("div[quota_name=VM_SYSTEM_DISK_SIZE] .progress-text", that.parent_container).text(Humanize.size(that.resource_info.VM_QUOTA.VM.SYSTEM_DISK_SIZE_USED * 1024) + " / " + Humanize.size(group_json.GROUP.VM_QUOTA.VM.SYSTEM_DISK_SIZE * 1024)); $("div[quota_name=VM_SYSTEM_DISK_SIZE] .progress-text", that.parent_container).text(Humanize.size(that.resource_info.VM_QUOTA.VM.SYSTEM_DISK_SIZE_USED * 1024) + " / " + Humanize.size(group_json.GROUP.VM_QUOTA.VM.SYSTEM_DISK_SIZE * 1024));
$("div[quota_name=VM_SYSTEM_DISK_SIZE] input", that.parent_container).val(group_json.GROUP.VM_QUOTA.VM.SYSTEM_DISK_SIZE); $("div[quota_name=VM_SYSTEM_DISK_SIZE] input", that.parent_container).val(group_json.GROUP.VM_QUOTA.VM.SYSTEM_DISK_SIZE);
} }
if (group_json.GROUP.VM_QUOTA.VM.RUNNING_VMS != "-1" && group_json.GROUP.VM_QUOTA.VM.RUNNING_VMS != "-2" && parseInt(group_json.GROUP.VM_QUOTA.VM.RUNNING_VMS) < parseInt(that.resource_info.VM_QUOTA.VM.RUNNING_VMS)){
$("div[quota_name=VM_RUNNING_VMS] .progress-text", that.parent_container).text(that.resource_info.VM_QUOTA.VM.RUNNING_VMS_USED + " / " + group_json.GROUP.VM_QUOTA.VM.RUNNING_VMS);
$("div[quota_name=VM_RUNNING_VMS] input", that.parent_container).val(group_json.GROUP.VM_QUOTA.VM.RUNNING_VMS);
}
if (group_json.GROUP.VM_QUOTA.VM.RUNNING_CPU != "-1" && group_json.GROUP.VM_QUOTA.VM.RUNNING_CPU != "-2" && parseInt(group_json.GROUP.VM_QUOTA.VM.RUNNING_CPU) < parseInt(that.resource_info.VM_QUOTA.VM.RUNNING_CPU)){
$("div[quota_name=VM_RUNNING_CPU] .progress-text", that.parent_container).text(that.resource_info.VM_QUOTA.VM.RUNNING_CPU_USED + " / " + group_json.GROUP.VM_QUOTA.VM.RUNNING_CPU);
$("div[quota_name=VM_RUNNING_CPU] input", that.parent_container).val(group_json.GROUP.VM_QUOTA.VM.RUNNING_CPU);
}
if (group_json.GROUP.VM_QUOTA.VM.RUNNING_MEMORY != "-1" && group_json.GROUP.VM_QUOTA.VM.RUNNING_MEMORY != "-2" && parseInt(group_json.GROUP.VM_QUOTA.VM.RUNNING_MEMORY) < parseInt(that.resource_info.VM_QUOTA.VM.RUNNING_MEMORY)){
$("div[quota_name=VM_RUNNING_MEMORY] .progress-text", that.parent_container).text(Humanize.size(that.resource_info.VM_QUOTA.VM.RUNNING_MEMORY_USED * 1024) + " / " + Humanize.size(group_json.GROUP.VM_QUOTA.VM.RUNNING_MEMORY * 1024));
$("div[quota_name=VM_RUNNING_MEMORY] input", that.parent_container).val(group_json.GROUP.VM_QUOTA.VM.RUNNING_MEMORY);
}
} }
/*Check Images*/ /*Check Images*/
@ -1321,6 +1493,9 @@ define(function(require) {
var cpu_quota = _cpuWidget(resource_info, default_quotas); var cpu_quota = _cpuWidget(resource_info, default_quotas);
var memory_quota = _memoryWidget(resource_info, default_quotas); var memory_quota = _memoryWidget(resource_info, default_quotas);
var system_disk_size_quota = _systemDiskWidget(resource_info, default_quotas); var system_disk_size_quota = _systemDiskWidget(resource_info, default_quotas);
var running_vms_quota = _runningVmsWidget(resource_info, default_quotas);
var running_cpu_quota = _runningCpuWidget(resource_info, default_quotas);
var running_memory_quota = _runningMemoryWidget(resource_info, default_quotas);
var image_quota = _imageWidget(resource_info, default_quotas); var image_quota = _imageWidget(resource_info, default_quotas);
var network_quota = _networkWidget(resource_info, default_quotas); var network_quota = _networkWidget(resource_info, default_quotas);
@ -1328,8 +1503,11 @@ define(function(require) {
$("#vm_quota", context).html( $("#vm_quota", context).html(
'<div class="medium-6 columns">' + vms_quota + '</div>\ '<div class="medium-6 columns">' + vms_quota + '</div>\
<div class="medium-6 columns">' + running_vms_quota + '</div>\
<div class="medium-6 columns">' + cpu_quota + '</div>\ <div class="medium-6 columns">' + cpu_quota + '</div>\
<div class="medium-6 columns">' + running_cpu_quota + '</div>\
<div class="medium-6 columns">' + memory_quota + '</div>\ <div class="medium-6 columns">' + memory_quota + '</div>\
<div class="medium-6 columns">' + running_memory_quota + '</div>\
<div class="medium-6 columns">' + system_disk_size_quota+ '</div>'); <div class="medium-6 columns">' + system_disk_size_quota+ '</div>');
$("#datastore_quota", context).html( $("#datastore_quota", context).html(

View File

@ -22,10 +22,10 @@
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
const char * QuotaVirtualMachine::VM_METRICS[] = const char * QuotaVirtualMachine::VM_METRICS[] = {"VMS", "RUNNING_VMS", "CPU",
{"VMS", "CPU", "MEMORY", "SYSTEM_DISK_SIZE"}; "RUNNING_CPU", "MEMORY", "RUNNING_MEMORY", "SYSTEM_DISK_SIZE"};
const int QuotaVirtualMachine::NUM_VM_METRICS = 4; const int QuotaVirtualMachine::NUM_VM_METRICS = 7;
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -46,17 +46,18 @@ bool QuotaVirtualMachine::check(Template * tmpl,
{ {
map<string, float> vm_request; map<string, float> vm_request;
int memory; int memory, running_memory;
float cpu; int vms, running_vms;
float cpu, running_cpu;
long long size; long long size;
if ( tmpl->get("MEMORY", memory) == false || memory <= 0 ) if ( tmpl->get("MEMORY", memory) == false || memory < 0 )
{ {
error = "MEMORY attribute must be a positive integer value"; error = "MEMORY attribute must be a positive integer value";
return false; return false;
} }
if ( tmpl->get("CPU", cpu) == false || cpu <= 0 ) if ( tmpl->get("CPU", cpu) == false || cpu < 0 )
{ {
error = "CPU attribute must be a positive float or integer value"; error = "CPU attribute must be a positive float or integer value";
return false; return false;
@ -64,7 +65,39 @@ bool QuotaVirtualMachine::check(Template * tmpl,
size = VirtualMachineDisks::system_ds_size(tmpl); size = VirtualMachineDisks::system_ds_size(tmpl);
vm_request.insert(make_pair("VMS",1)); if ( tmpl->get("VMS", vms) == false )
{
vms = 1;
}
if ( tmpl->get("RUNNING_MEMORY", running_memory) )
{
vm_request.insert(make_pair("RUNNING_MEMORY", running_memory));
}
else
{
vm_request.insert(make_pair("RUNNING_MEMORY", 0));
}
if ( tmpl->get("RUNNING_CPU", running_cpu) )
{
vm_request.insert(make_pair("RUNNING_CPU", running_cpu));
}
else
{
vm_request.insert(make_pair("RUNNING_CPU", 0));
}
if ( tmpl->get("RUNNING_VMS", running_vms) )
{
vm_request.insert(make_pair("RUNNING_VMS", running_vms));
}
else
{
vm_request.insert(make_pair("RUNNING_VMS", 0));
}
vm_request.insert(make_pair("VMS", vms));
vm_request.insert(make_pair("MEMORY", memory)); vm_request.insert(make_pair("MEMORY", memory));
vm_request.insert(make_pair("CPU", cpu)); vm_request.insert(make_pair("CPU", cpu));
vm_request.insert(make_pair("SYSTEM_DISK_SIZE", size)); vm_request.insert(make_pair("SYSTEM_DISK_SIZE", size));
@ -79,8 +112,8 @@ void QuotaVirtualMachine::del(Template * tmpl)
{ {
map<string, float> vm_request; map<string, float> vm_request;
int memory, vms; int memory, running_memory, running_vms, vms;
float cpu; float cpu, running_cpu;
long long size; long long size;
if ( tmpl->get("MEMORY", memory) == false ) if ( tmpl->get("MEMORY", memory) == false )
@ -98,11 +131,29 @@ void QuotaVirtualMachine::del(Template * tmpl)
vms = 1; vms = 1;
} }
if ( tmpl->get("RUNNING_MEMORY", running_memory) == false )
{
running_memory = 0;
}
if ( tmpl->get("RUNNING_CPU", running_cpu) == false )
{
running_cpu = 0;
}
if ( tmpl->get("RUNNING_VMS", running_vms) == false )
{
running_vms = 0;
}
size = VirtualMachineDisks::system_ds_size(tmpl); size = VirtualMachineDisks::system_ds_size(tmpl);
vm_request.insert(make_pair("VMS", vms)); vm_request.insert(make_pair("VMS", vms));
vm_request.insert(make_pair("MEMORY", memory)); vm_request.insert(make_pair("MEMORY", memory));
vm_request.insert(make_pair("CPU", cpu)); vm_request.insert(make_pair("CPU", cpu));
vm_request.insert(make_pair("RUNNING_VMS", running_vms));
vm_request.insert(make_pair("RUNNING_MEMORY", running_memory));
vm_request.insert(make_pair("RUNNING_CPU", running_cpu));
vm_request.insert(make_pair("SYSTEM_DISK_SIZE", size)); vm_request.insert(make_pair("SYSTEM_DISK_SIZE", size));
del_quota("", vm_request); del_quota("", vm_request);
@ -128,20 +179,36 @@ bool QuotaVirtualMachine::update(Template * tmpl,
{ {
map<string, float> vm_request; map<string, float> vm_request;
int delta_memory; int delta_memory, delta_running_memory, delta_running_vms;
float delta_cpu; float delta_cpu, delta_running_cpu;
long long delta_size; long long delta_size;
if ( tmpl->get("MEMORY", delta_memory) == true ) if ( tmpl->get("MEMORY", delta_memory) == true )
{ {
vm_request.insert(make_pair("MEMORY", delta_memory)); vm_request.insert(make_pair("MEMORY", delta_memory));
} }
if ( tmpl->get("RUNNING_MEMORY", delta_running_memory) == true )
{
vm_request.insert(make_pair("RUNNING_MEMORY", delta_running_memory));
}
if ( tmpl->get("RUNNING_VMS", delta_running_vms) == true )
{
vm_request.insert(make_pair("RUNNING_VMS", delta_running_vms));
}
if ( tmpl->get("CPU", delta_cpu) == true ) if ( tmpl->get("CPU", delta_cpu) == true )
{ {
vm_request.insert(make_pair("CPU", delta_cpu)); vm_request.insert(make_pair("CPU", delta_cpu));
} }
if ( tmpl->get("RUNNING_CPU", delta_running_cpu) == true )
{
vm_request.insert(make_pair("RUNNING_CPU", delta_running_cpu));
}
delta_size = VirtualMachineDisks::system_ds_size(tmpl); delta_size = VirtualMachineDisks::system_ds_size(tmpl);
if ( delta_size != 0 ) if ( delta_size != 0 )

View File

@ -292,6 +292,48 @@ void Quotas::quota_del(QuotaType type, int uid, int gid, Template * tmpl)
} }
} }
void Quotas::quota_check(QuotaType type, int uid, int gid, Template * tmpl,
string& error)
{
Nebula& nd = Nebula::instance();
UserPool * upool = nd.get_upool();
GroupPool * gpool = nd.get_gpool();
if ( uid != UserPool::ONEADMIN_ID )
{
User * user = upool->get(uid);
if ( user != 0 )
{
DefaultQuotas defaultq = nd.get_default_user_quota();
if ( user->quota.quota_check(type, tmpl, defaultq, error) )
{
upool->update_quotas(user);
}
user->unlock();
}
}
if ( gid != GroupPool::ONEADMIN_ID )
{
Group * group = gpool->get(gid);
if ( group != 0 )
{
DefaultQuotas defaultq = nd.get_default_group_quota();
if ( group->quota.quota_check(type, tmpl, defaultq, error) )
{
gpool->update_quotas(group);
}
group->unlock();
}
}
}
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */

View File

@ -3139,3 +3139,6 @@ int VirtualMachine::parse_sched_action(string& error_str)
return sactions.parse(error_str, false); return sactions.parse(error_str, false);
} }
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */