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 "VirtualRouterPool.h"
#include "ClusterPool.h"
#include "UserPool.h"
using namespace std;
@ -493,10 +494,15 @@ private:
HostPool * hpool;
/**
* Pointer to the Virtual Machine Pool, to access hosts
* Pointer to the Virtual Machine Pool, to access VMs
*/
VirtualMachinePool * vmpool;
/**
* Pointer to the User Pool, to access user
*/
UserPool * upool;
/**
* Pointer to the Cluster Pool
*/
@ -568,6 +574,15 @@ private:
};
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*/

View File

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

View File

@ -162,13 +162,26 @@ public:
* for the given user and group
* @param uid of the user
* @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)
{
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.
* for the given user and group
@ -209,8 +222,7 @@ public:
static void ds_del_recreate(int uid, int gid, vector<Template *>& ds_quotas);
/**
* Delete usage from the given quota counters.
* for the given user and group
* 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
@ -218,6 +230,16 @@ public:
*/
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:
/**
* This is an specialized constructor only for derived Quotas classes.

View File

@ -111,12 +111,18 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
if q['VM_QUOTA']['VM'].nil? && d["ID"].to_i != 0
q['VM_QUOTA']['VM'] = {
"VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"VMS_USED" => "0",
"CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"MEMORY_USED" => "0",
"VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"VMS_USED" => "0",
"CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"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_USED" => "0"
}
@ -148,12 +154,18 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
if q['VM_QUOTA']['VM'].nil? && d["ID"].to_i != 0
q['VM_QUOTA']['VM'] = {
"VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"VMS_USED" => "0",
"CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"MEMORY_USED" => "0",
"VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"VMS_USED" => "0",
"CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"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_USED" => "0"
}
@ -188,12 +200,18 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
if q['VM_QUOTA']['VM'].nil? && d["ID"].to_i != 0
q['VM_QUOTA']['VM'] = {
"VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"VMS_USED" => "0",
"CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"MEMORY_USED" => "0",
"VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"VMS_USED" => "0",
"CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"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_USED" => "0"
}

View File

@ -35,8 +35,11 @@ class OneQuotaHelper
#
# VM = [
# VMS = <Max. number of VMs>
# RUNNING_VMS = <Max. number of running VMs>
# MEMORY = <Max. allocated memory (MB)>
# RUNNING_MEMORY = <Max. running memory (MB)>
# CPU = <Max. allocated CPU>
# RUNNING_CPU = <Max. running CPU>
# SYSTEM_DISK_SIZE = <Max. allocated system disk (MB)>
# ]
#
@ -196,7 +199,7 @@ class OneQuotaHelper
puts
CLIHelper.print_header(str_h1 % "RESOURCE USAGE & QUOTAS",false)
CLIHelper.print_header(str_h1 % "VMS USAGE & QUOTAS",false)
puts
@ -210,12 +213,18 @@ class OneQuotaHelper
limit = LIMIT_DEFAULT
vm_quotas = [{
"VMS" => limit,
"VMS_USED" => "0",
"CPU" => limit,
"CPU_USED" => "0",
"MEMORY" => limit,
"MEMORY_USED" => "0",
"VMS" => limit,
"VMS_USED" => "0",
"CPU" => limit,
"CPU_USED" => "0",
"MEMORY" => limit,
"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_USED" => "0"
}]
@ -223,7 +232,7 @@ class OneQuotaHelper
if !vm_quotas[0].nil?
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?
elem = 'VMS'
limit = d[elem]
@ -297,11 +306,87 @@ class OneQuotaHelper
puts
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
if !ds_quotas[0].nil?
CLIHelper::ShowTable.new(nil, self) do
column :"DATASTORE ID", "", :size=>12 do |d|
column :"ID", "", :size=>12 do |d|
d["ID"] if !d.nil?
end
@ -344,11 +429,15 @@ class OneQuotaHelper
puts
end
CLIHelper.print_header(str_h1 % "NETWORK USAGE & QUOTAS",false)
puts
net_quotas = [qh['NETWORK_QUOTA']['NETWORK']].flatten
if !net_quotas[0].nil?
CLIHelper::ShowTable.new(nil, self) do
column :"NETWORK ID", "", :size=>12 do |d|
column :"ID", "", :size=>12 do |d|
d["ID"] if !d.nil?
end
@ -371,11 +460,15 @@ class OneQuotaHelper
puts
end
CLIHelper.print_header(str_h1 % "IMAGE USAGE & QUOTAS",false)
puts
image_quotas = [qh['IMAGE_QUOTA']['IMAGE']].flatten
if !image_quotas[0].nil?
CLIHelper::ShowTable.new(nil, self) do
column :"IMAGE ID", "", :size=>12 do |d|
column :"ID", "", :size=>12 do |d|
d["ID"] if !d.nil?
end

View File

@ -294,12 +294,18 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
if q['VM_QUOTA']['VM'].nil? && d["ID"].to_i != 0
q['VM_QUOTA']['VM'] = {
"VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"VMS_USED" => "0",
"CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"MEMORY_USED" => "0",
"VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"VMS_USED" => "0",
"CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"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_USED" => "0"
}
@ -333,12 +339,18 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
if q['VM_QUOTA']['VM'].nil? && d["ID"].to_i != 0
q['VM_QUOTA']['VM'] = {
"VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"VMS_USED" => "0",
"CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"MEMORY_USED" => "0",
"VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"VMS_USED" => "0",
"CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"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_USED" => "0"
}
@ -375,12 +387,18 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
if q['VM_QUOTA']['VM'].nil? && d["ID"].to_i != 0
q['VM_QUOTA']['VM'] = {
"VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"VMS_USED" => "0",
"CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"MEMORY_USED" => "0",
"VMS" => OneQuotaHelper::LIMIT_DEFAULT,
"VMS_USED" => "0",
"CPU" => OneQuotaHelper::LIMIT_DEFAULT,
"CPU_USED" => "0",
"MEMORY" => OneQuotaHelper::LIMIT_DEFAULT,
"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_USED" => "0"
}

View File

@ -111,5 +111,45 @@ void DispatchManager::init_managers()
vmpool = nd.get_vmpool();
clpool = nd.get_clpool();
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 "Quotas.h"
#include "Request.h"
#include "Nebula.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -29,7 +30,14 @@
int DispatchManager::deploy (VirtualMachine * vm, const RequestAttributes& ra)
{
ostringstream oss;
int vid;
int vid;
int uid;
int gid;
string error;
VirtualMachineTemplate quota_tmpl;
bool do_quotas = false;
if ( vm == 0 )
{
@ -46,10 +54,21 @@ int DispatchManager::deploy (VirtualMachine * vm, const RequestAttributes& ra)
vm->get_state() == VirtualMachine::STOPPED ||
vm->get_state() == VirtualMachine::UNDEPLOYED )
{
do_quotas = vm->get_state() == VirtualMachine::STOPPED ||
vm->get_state() == VirtualMachine::UNDEPLOYED;
vm->set_state(VirtualMachine::ACTIVE);
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);
}
else
@ -57,6 +76,13 @@ int DispatchManager::deploy (VirtualMachine * vm, const RequestAttributes& ra)
goto error;
}
vm->unlock();
if ( do_quotas )
{
Quotas::vm_check(uid, gid, &quota_tmpl, error);
}
return 0;
error:
@ -65,6 +91,8 @@ error:
<< ", wrong state " << vm->state_str() << ".";
NebulaLog::log("DiM",Log::ERROR,oss);
vm->unlock();
return -1;
}
@ -76,6 +104,14 @@ int DispatchManager::import(VirtualMachine * vm, const RequestAttributes& ra)
ostringstream oss;
string import_state;
int uid;
int gid;
VirtualMachineTemplate quota_tmpl;
bool do_quotas = false;
string error;
if ( vm == 0 )
{
return -1;
@ -110,6 +146,13 @@ int DispatchManager::import(VirtualMachine * vm, const RequestAttributes& ra)
{
vm->set_state(VirtualMachine::ACTIVE);
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);
@ -125,6 +168,13 @@ int DispatchManager::import(VirtualMachine * vm, const RequestAttributes& ra)
vmpool->update(vm);
vm->unlock();
if ( do_quotas )
{
Quotas::vm_check(uid, gid, &quota_tmpl, error);
}
return 0;
}
@ -215,9 +265,10 @@ error:
void DispatchManager::free_vm_resources(VirtualMachine * vm)
{
Template* tmpl;
vector<Template *> ds_quotas;
Template * quota_tmpl;
int vmid;
int uid;
int gid;
@ -225,6 +276,24 @@ void DispatchManager::free_vm_resources(VirtualMachine * vm)
int vrid = -1;
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_vmgroup();
@ -239,7 +308,8 @@ void DispatchManager::free_vm_resources(VirtualMachine * vm)
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");
clpool->release_vnc_port(vm->get_cid(), port);
@ -250,7 +320,6 @@ void DispatchManager::free_vm_resources(VirtualMachine * vm)
vmid = vm->get_oid();
uid = vm->get_uid();
gid = vm->get_gid();
tmpl = vm->clone_template();
if (vm->is_imported())
{
@ -264,9 +333,9 @@ void DispatchManager::free_vm_resources(VirtualMachine * vm)
vm->unlock();
Quotas::vm_del(uid, gid, tmpl);
Quotas::vm_del(uid, gid, quota_tmpl);
delete tmpl;
delete quota_tmpl;
if ( !ds_quotas.empty() )
{
@ -1096,6 +1165,9 @@ int DispatchManager::delete_recreate(VirtualMachine * vm,
Template * vm_quotas_snp = 0;
VirtualMachineTemplate quota_tmpl;
bool do_quotas = false;
vector<Template *> ds_quotas_snp;
int vm_uid, vm_gid;
@ -1128,6 +1200,8 @@ int DispatchManager::delete_recreate(VirtualMachine * vm,
vm->delete_non_persistent_disk_snapshots(&vm_quotas_snp,
ds_quotas_snp);
do_quotas = true;
case VirtualMachine::HOLD:
if (vm->hasHistory())
{
@ -1142,6 +1216,11 @@ int DispatchManager::delete_recreate(VirtualMachine * vm,
vm->set_state(VirtualMachine::PENDING);
vmpool->update(vm);
if ( do_quotas )
{
get_quota_template(vm, quota_tmpl, true);
}
break;
case VirtualMachine::ACTIVE: //Cleanup VM resources before PENDING
@ -1169,6 +1248,11 @@ int DispatchManager::delete_recreate(VirtualMachine * vm,
delete vm_quotas_snp;
}
if ( do_quotas )
{
Quotas::vm_check(vm_uid, vm_gid, &quota_tmpl, error);
}
return rc;
}

View File

@ -16,12 +16,16 @@
#include "DispatchManager.h"
#include "NebulaLog.h"
#include "Quotas.h"
#include "Nebula.h"
void DispatchManager::suspend_success_action(int vid)
{
VirtualMachine * vm;
VirtualMachineTemplate quota_tmpl;
string error_str;
int uid, gid;
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_DELETE_SUSPENDED))
{
get_quota_template(vm, quota_tmpl, true);
vm->set_state(VirtualMachine::SUSPENDED);
vm->set_state(VirtualMachine::LCM_INIT);
@ -51,10 +57,18 @@ void DispatchManager::suspend_success_action(int vid)
oss << "suspend_success action received but VM " << vid
<< " not in ACTIVE state";
NebulaLog::log("DiM",Log::ERROR,oss);
vm->unlock();
return;
}
uid = vm->get_uid();
gid = vm->get_gid();
vm->unlock();
Quotas::vm_del(uid, gid, &quota_tmpl);
return;
}
@ -64,6 +78,10 @@ void DispatchManager::suspend_success_action(int vid)
void DispatchManager::stop_success_action(int vid)
{
VirtualMachine * vm;
VirtualMachineTemplate quota_tmpl;
string error_str;
int uid, gid;
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::PROLOG_RESUME))
{
get_quota_template(vm, quota_tmpl, true);
vm->set_state(VirtualMachine::STOPPED);
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
<< " not in ACTIVE state";
NebulaLog::log("DiM",Log::ERROR,oss);
vm->unlock();
return;
}
uid = vm->get_uid();
gid = vm->get_gid();
vm->unlock();
Quotas::vm_del(uid, gid, &quota_tmpl);
return;
}
@ -110,6 +137,10 @@ void DispatchManager::stop_success_action(int vid)
void DispatchManager::undeploy_success_action(int vid)
{
VirtualMachine * vm;
VirtualMachineTemplate quota_tmpl;
string error_str;
int uid, gid;
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::PROLOG_UNDEPLOY))
{
get_quota_template(vm, quota_tmpl, true);
vm->set_state(VirtualMachine::UNDEPLOYED);
vm->set_state(VirtualMachine::LCM_INIT);
@ -144,10 +177,19 @@ void DispatchManager::undeploy_success_action(int vid)
oss << "undeploy_success action received but VM " << vid
<< " not in ACTIVE state";
NebulaLog::log("DiM",Log::ERROR,oss);
vm->unlock();
return;
}
uid = vm->get_uid();
gid = vm->get_gid();
vm->unlock();
Quotas::vm_del(uid, gid, &quota_tmpl);
return;
}
@ -157,6 +199,10 @@ void DispatchManager::undeploy_success_action(int vid)
void DispatchManager::poweroff_success_action(int vid)
{
VirtualMachine * vm;
VirtualMachineTemplate quota_tmpl;
string error_str;
int uid, gid;
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::PROLOG_MIGRATE_POWEROFF_FAILURE))
{
get_quota_template(vm, quota_tmpl, true);
vm->set_state(VirtualMachine::POWEROFF);
vm->set_state(VirtualMachine::LCM_INIT);
@ -189,10 +237,18 @@ void DispatchManager::poweroff_success_action(int vid)
oss << "poweroff_success action received but VM " << vid
<< " not in ACTIVE state";
NebulaLog::log("DiM",Log::ERROR,oss);
vm->unlock();
return;
}
uid = vm->get_uid();
gid = vm->get_gid();
vm->unlock();
Quotas::vm_del(uid, gid, &quota_tmpl);
return;
}
@ -202,6 +258,7 @@ void DispatchManager::poweroff_success_action(int vid)
void DispatchManager::done_action(int vid)
{
VirtualMachine * vm;
string error_str;
VirtualMachine::LcmState lcm_state;
VirtualMachine::VmState dm_state;

View File

@ -71,6 +71,8 @@ bool VirtualMachineAllocate::allocate_authorization(
string t64;
string aname;
std::string memory, cpu;
VirtualMachineTemplate * ttmpl = static_cast<VirtualMachineTemplate *>(tmpl);
// ------------ Check template for restricted attributes -------------------
@ -106,6 +108,14 @@ bool VirtualMachineAllocate::allocate_authorization(
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 )
{
return false;

View File

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

View File

@ -120,6 +120,7 @@ Request::ErrorCode VMTemplateInstantiate::request_execute(int id, string name,
RequestAttributes& att)
{
int rc;
std::string memory, cpu;
ostringstream sid;
@ -229,6 +230,14 @@ Request::ErrorCode VMTemplateInstantiate::request_execute(int id, string name,
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,
att.resp_msg) == false)
{

View File

@ -478,6 +478,8 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList,
int rc;
std::string memory, cpu;
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
@ -487,6 +489,8 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList,
AuthRequest::Operation op;
History::VMAction action;
VirtualMachineTemplate quota_tmpl;
VirtualMachine * vm;
// Compatibility with 4.x
@ -513,6 +517,21 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList,
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))
{
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();
if ( action == History::RESUME_ACTION &&
!quota_authorization(&quota_tmpl, Quotas::VIRTUALMACHINE, att_aux,
att.resp_msg) )
{
failure_response(ACTION, att);
return;
}
switch (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())
@ -934,8 +961,6 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
dm->deploy(vm, att);
}
vm->unlock();
success_response(id, att);
}

View File

@ -19,10 +19,13 @@ define(function(require) {
var _defaultUserQuotas = {
"VM_QUOTA": {
"VM": {
"CPU": QUOTA_LIMIT_UNLIMITED,
"MEMORY": QUOTA_LIMIT_UNLIMITED,
"VMS": QUOTA_LIMIT_UNLIMITED,
"CPU": QUOTA_LIMIT_UNLIMITED,
"MEMORY": QUOTA_LIMIT_UNLIMITED,
"VMS": 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": {},
@ -33,10 +36,13 @@ define(function(require) {
var _defaultGroupQuotas = {
"VM_QUOTA": {
"VM": {
"CPU": QUOTA_LIMIT_UNLIMITED,
"MEMORY": QUOTA_LIMIT_UNLIMITED,
"VMS": QUOTA_LIMIT_UNLIMITED,
"CPU": QUOTA_LIMIT_UNLIMITED,
"MEMORY": QUOTA_LIMIT_UNLIMITED,
"VMS": 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": {},
@ -87,10 +93,13 @@ define(function(require) {
if ($.isEmptyObject(default_quotas.VM_QUOTA)){
default_quotas.VM_QUOTA = {
"VM" : {
"VMS" : QUOTA_LIMIT_UNLIMITED,
"MEMORY" : QUOTA_LIMIT_UNLIMITED,
"CPU" : QUOTA_LIMIT_UNLIMITED,
"SYSTEM_DISK_SIZE" : QUOTA_LIMIT_UNLIMITED
"VMS" : QUOTA_LIMIT_UNLIMITED,
"MEMORY" : QUOTA_LIMIT_UNLIMITED,
"CPU" : 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

@ -49,14 +49,20 @@ define(function(require) {
if ($.isEmptyObject(resource.VM_QUOTA) && resource.ID != 0){
resource.VM_QUOTA = {
VM: {
VMS : QUOTA_LIMIT_DEFAULT,
VMS_USED : 0,
CPU : QUOTA_LIMIT_DEFAULT,
CPU_USED : 0,
MEMORY : QUOTA_LIMIT_DEFAULT,
MEMORY_USED : 0,
VMS : QUOTA_LIMIT_DEFAULT,
VMS_USED : 0,
CPU : QUOTA_LIMIT_DEFAULT,
CPU_USED : 0,
MEMORY : QUOTA_LIMIT_DEFAULT,
MEMORY_USED : 0,
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;
}
/**
* 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
* @param {Object} info User/Group object
@ -714,6 +861,9 @@ define(function(require) {
var cpu_quota = _cpuWidget(resource_info, default_quotas);
var memory_quota = _memoryWidget(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 network_quota = _networkWidget(resource_info, default_quotas);
@ -763,11 +913,18 @@ define(function(require) {
quotas_html +=
'<div class="row">\
<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">' + running_cpu_quota+ '</div>\
</div>\
<div class="row">\
<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>\
<br><br>\
<div class="row">\
@ -869,10 +1026,13 @@ define(function(require) {
var obj = {};
obj["VM"] = {
"CPU" : input_val( $("div[quota_name=VM_CPU] 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) ),
"SYSTEM_DISK_SIZE" : input_val( $("div[quota_name=VM_SYSTEM_DISK_SIZE] 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) ),
"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) ),
"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(){
@ -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] 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*/
@ -1321,6 +1493,9 @@ define(function(require) {
var cpu_quota = _cpuWidget(resource_info, default_quotas);
var memory_quota = _memoryWidget(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 network_quota = _networkWidget(resource_info, default_quotas);
@ -1328,8 +1503,11 @@ define(function(require) {
$("#vm_quota", context).html(
'<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">' + running_cpu_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>');
$("#datastore_quota", context).html(

View File

@ -22,10 +22,10 @@
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
const char * QuotaVirtualMachine::VM_METRICS[] =
{"VMS", "CPU", "MEMORY", "SYSTEM_DISK_SIZE"};
const char * QuotaVirtualMachine::VM_METRICS[] = {"VMS", "RUNNING_VMS", "CPU",
"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;
int memory;
float cpu;
int memory, running_memory;
int vms, running_vms;
float cpu, running_cpu;
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";
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";
return false;
@ -64,7 +65,39 @@ bool QuotaVirtualMachine::check(Template * 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("CPU", cpu));
vm_request.insert(make_pair("SYSTEM_DISK_SIZE", size));
@ -79,8 +112,8 @@ void QuotaVirtualMachine::del(Template * tmpl)
{
map<string, float> vm_request;
int memory, vms;
float cpu;
int memory, running_memory, running_vms, vms;
float cpu, running_cpu;
long long size;
if ( tmpl->get("MEMORY", memory) == false )
@ -98,11 +131,29 @@ void QuotaVirtualMachine::del(Template * tmpl)
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);
vm_request.insert(make_pair("VMS", vms));
vm_request.insert(make_pair("MEMORY", memory));
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));
del_quota("", vm_request);
@ -128,20 +179,36 @@ bool QuotaVirtualMachine::update(Template * tmpl,
{
map<string, float> vm_request;
int delta_memory;
float delta_cpu;
int delta_memory, delta_running_memory, delta_running_vms;
float delta_cpu, delta_running_cpu;
long long delta_size;
if ( tmpl->get("MEMORY", delta_memory) == true )
{
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 )
{
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);
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);
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */