1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-08-25 21:49:29 +03:00

Merge remote-tracking branch 'origin/feature-2964'

This commit is contained in:
Carlos Martín
2014-07-04 12:10:48 +02:00
9 changed files with 344 additions and 65 deletions

View File

@ -390,7 +390,7 @@ public:
*/
static string local_db_version()
{
return "4.5.80";
return "4.7.80";
}
/**

View File

@ -91,6 +91,18 @@ public:
return get_quota(id, va, it);
}
/**
* Value for limit default
*/
static const int DEFAULT;
static const string DEFAULT_STR;
/**
* Value for "unlimited" limit
*/
static const int UNLIMITED;
protected:
Quota(const char * quota_name,

View File

@ -1109,7 +1109,7 @@ ONEDB_SHARED_MIGRATOR_FILES="src/onedb/shared/2.0_to_2.9.80.rb \
src/onedb/shared/4.4.1_to_4.5.80.rb\
src/onedb/shared/4.5.80_to_4.6.0.rb"
ONEDB_LOCAL_MIGRATOR_FILES=""
ONEDB_LOCAL_MIGRATOR_FILES="src/onedb/local/4.5.80_to_4.7.80.rb"
#-------------------------------------------------------------------------------
# Configuration files for OpenNebula, to be installed under $ETC_LOCATION

View File

@ -110,12 +110,16 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
q = quotas[d['ID']]
limit = q['VM_QUOTA']['VM']["VMS"]
if limit == "-1"
if limit == OneQuotaHelper::LIMIT_DEFAULT
limit = pool_default_quotas("VM_QUOTA/VM/VMS")
limit = "0" if limit.nil? || limit == ""
limit = OneQuotaHelper::LIMIT_UNLIMITED if limit.nil? || limit == ""
end
"%3d / %3d" % [q['VM_QUOTA']['VM']["VMS_USED"], limit]
if limit == OneQuotaHelper::LIMIT_UNLIMITED
"%3d / -" % [q['VM_QUOTA']['VM']["VMS_USED"]]
else
"%3d / %3d" % [q['VM_QUOTA']['VM']["VMS_USED"], limit]
end
rescue NoMethodError
"-"
@ -127,13 +131,19 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
q = quotas[d['ID']]
limit = q['VM_QUOTA']['VM']["MEMORY"]
if limit == "-1"
if limit == OneQuotaHelper::LIMIT_DEFAULT
limit = pool_default_quotas("VM_QUOTA/VM/MEMORY")
limit = "0" if limit.nil? || limit == ""
limit = OneQuotaHelper::LIMIT_UNLIMITED if limit.nil? || limit == ""
end
"%7s / %7s" % [OpenNebulaHelper.unit_to_str(q['VM_QUOTA']['VM']["MEMORY_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")]
if limit == OneQuotaHelper::LIMIT_UNLIMITED
"%7s / -" % [
OpenNebulaHelper.unit_to_str(q['VM_QUOTA']['VM']["MEMORY_USED"].to_i,{},"M")]
else
"%7s / %7s" % [
OpenNebulaHelper.unit_to_str(q['VM_QUOTA']['VM']["MEMORY_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")]
end
rescue NoMethodError
"-"
@ -145,12 +155,16 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
q = quotas[d['ID']]
limit = q['VM_QUOTA']['VM']["CPU"]
if limit == "-1"
if limit == OneQuotaHelper::LIMIT_DEFAULT
limit = pool_default_quotas("VM_QUOTA/VM/CPU")
limit = "0" if limit.nil? || limit == ""
limit = OneQuotaHelper::LIMIT_UNLIMITED if limit.nil? || limit == ""
end
"%3.1f / %3.1f" % [q['VM_QUOTA']['VM']["CPU_USED"], limit]
if limit == OneQuotaHelper::LIMIT_UNLIMITED
"%3.1f / -" % [q['VM_QUOTA']['VM']["CPU_USED"]]
else
"%3.1f / %3.1f" % [q['VM_QUOTA']['VM']["CPU_USED"], limit]
end
rescue NoMethodError
"-"

View File

@ -18,6 +18,9 @@ require 'cli_helper'
class OneQuotaHelper
LIMIT_DEFAULT = "-1"
LIMIT_UNLIMITED = "-2"
EDITOR_PATH='/usr/bin/vi'
HELP_QUOTA = <<-EOT.unindent
@ -52,7 +55,7 @@ class OneQuotaHelper
#
# In any quota:
# -1 means use the default limit (set with the 'defaultquota' command)
# 0 means unlimited.
# -2 means unlimited.
#
# The usage counters "*_USED" are shown for information
# purposes and will NOT be modified.
@ -62,7 +65,7 @@ class OneQuotaHelper
HELP_DEFAULT_QUOTA_FOOTER = <<-EOT.unindent
#
# In any quota:
# 0 means unlimited.
# -2 means unlimited.
#
# The usage counters "*_USED" will always be 0 for the default
# quotas, and can be ignored.
@ -209,7 +212,11 @@ class OneQuotaHelper
limit = helper.get_default_limit(
limit, "VM_QUOTA/VM/#{elem}")
"%7d / %7d" % [d["VMS_USED"], limit]
if limit == LIMIT_UNLIMITED
"%7d / -" % [d["VMS_USED"]]
else
"%7d / %7d" % [d["VMS_USED"], limit]
end
end
end
@ -220,10 +227,16 @@ class OneQuotaHelper
limit = helper.get_default_limit(
limit, "VM_QUOTA/VM/#{elem}")
"%8s / %8s" % [
OpenNebulaHelper.unit_to_str(d["MEMORY_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")
]
if limit == LIMIT_UNLIMITED
"%8s / -" % [
OpenNebulaHelper.unit_to_str(d["MEMORY_USED"].to_i,{},"M")
]
else
"%8s / %8s" % [
OpenNebulaHelper.unit_to_str(d["MEMORY_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")
]
end
end
end
@ -234,7 +247,11 @@ class OneQuotaHelper
limit = helper.get_default_limit(
limit, "VM_QUOTA/VM/#{elem}")
"%8.2f / %8.2f" % [d["CPU_USED"], limit]
if limit == LIMIT_UNLIMITED
"%8.2f / -" % [d["CPU_USED"]]
else
"%8.2f / %8.2f" % [d["CPU_USED"], limit]
end
end
end
@ -245,10 +262,16 @@ class OneQuotaHelper
limit = helper.get_default_limit(
limit, "VM_QUOTA/VM/#{elem}")
"%8s / %8s" % [
OpenNebulaHelper.unit_to_str(d["VOLATILE_SIZE_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")
]
if limit == LIMIT_UNLIMITED
"%8s / -" % [
OpenNebulaHelper.unit_to_str(d["VOLATILE_SIZE_USED"].to_i,{},"M")
]
else
"%8s / %8s" % [
OpenNebulaHelper.unit_to_str(d["VOLATILE_SIZE_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")
]
end
end
end
end.show(vm_quotas, {})
@ -271,7 +294,11 @@ class OneQuotaHelper
limit = helper.get_default_limit(
limit, "DATASTORE_QUOTA/DATASTORE[ID=#{d['ID']}]/#{elem}")
"%8d / %8d" % [d["IMAGES_USED"], limit]
if limit == LIMIT_UNLIMITED
"%8d / -" % [d["IMAGES_USED"]]
else
"%8d / %8d" % [d["IMAGES_USED"], limit]
end
end
end
@ -282,10 +309,16 @@ class OneQuotaHelper
limit = helper.get_default_limit(
limit, "DATASTORE_QUOTA/DATASTORE[ID=#{d['ID']}]/#{elem}")
"%8s / %8s" % [
OpenNebulaHelper.unit_to_str(d["SIZE_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")
]
if limit == LIMIT_UNLIMITED
"%8s / -" % [
OpenNebulaHelper.unit_to_str(d["SIZE_USED"].to_i,{},"M")
]
else
"%8s / %8s" % [
OpenNebulaHelper.unit_to_str(d["SIZE_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")
]
end
end
end
end.show(ds_quotas, {})
@ -308,7 +341,11 @@ class OneQuotaHelper
limit = helper.get_default_limit(
limit, "NETWORK_QUOTA/NETWORK[ID=#{d['ID']}]/#{elem}")
"%8d / %8d" % [d["LEASES_USED"], limit]
if limit == LIMIT_UNLIMITED
"%8d / -" % [d["LEASES_USED"]]
else
"%8d / %8d" % [d["LEASES_USED"], limit]
end
end
end
end.show(net_quotas, {})
@ -331,7 +368,11 @@ class OneQuotaHelper
limit = helper.get_default_limit(
limit, "IMAGE_QUOTA/IMAGE[ID=#{d['ID']}]/RVMS")
"%8d / %8d" % [d["RVMS_USED"], limit]
if limit == LIMIT_UNLIMITED
"%8d / -" % [d["RVMS_USED"]]
else
"%8d / %8d" % [d["RVMS_USED"], limit]
end
end
end
end.show(image_quotas, {})
@ -339,13 +380,13 @@ class OneQuotaHelper
end
def get_default_limit(limit, xpath)
if limit == "-1"
if limit == LIMIT_DEFAULT
if !@default_quotas.nil?
limit = @default_quotas[xpath]
limit = "0" if limit.nil? || limit == ""
limit = LIMIT_UNLIMITED if limit.nil? || limit == ""
else
limit = "0"
limit = LIMIT_UNLIMITED
end
end

View File

@ -190,12 +190,18 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
q = quotas[d['ID']]
limit = q['VM_QUOTA']['VM']["VMS"]
if limit == "-1"
if limit == OneQuotaHelper::LIMIT_DEFAULT
limit = pool_default_quotas("VM_QUOTA/VM/VMS")
limit = "0" if limit.nil? || limit == ""
if limit.nil? || limit == ""
limit = OneQuotaHelper::LIMIT_UNLIMITED
end
end
"%3d / %3d" % [q['VM_QUOTA']['VM']["VMS_USED"], limit]
if limit == OneQuotaHelper::LIMIT_UNLIMITED
"%3d / -" % [q['VM_QUOTA']['VM']["VMS_USED"]]
else
"%3d / %3d" % [q['VM_QUOTA']['VM']["VMS_USED"], limit]
end
rescue NoMethodError
"-"
@ -207,13 +213,21 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
q = quotas[d['ID']]
limit = q['VM_QUOTA']['VM']["MEMORY"]
if limit == "-1"
if limit == OneQuotaHelper::LIMIT_DEFAULT
limit = pool_default_quotas("VM_QUOTA/VM/MEMORY")
limit = "0" if limit.nil? || limit == ""
if limit.nil? || limit == ""
limit = OneQuotaHelper::LIMIT_UNLIMITED
end
end
"%7s / %7s" % [OpenNebulaHelper.unit_to_str(q['VM_QUOTA']['VM']["MEMORY_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")]
if limit == OneQuotaHelper::LIMIT_UNLIMITED
"%7s / -" % [
OpenNebulaHelper.unit_to_str(q['VM_QUOTA']['VM']["MEMORY_USED"].to_i,{},"M")]
else
"%7s / %7s" % [
OpenNebulaHelper.unit_to_str(q['VM_QUOTA']['VM']["MEMORY_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")]
end
rescue NoMethodError
"-"
@ -225,12 +239,18 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
q = quotas[d['ID']]
limit = q['VM_QUOTA']['VM']["CPU"]
if limit == "-1"
if limit == OneQuotaHelper::LIMIT_DEFAULT
limit = pool_default_quotas("VM_QUOTA/VM/CPU")
limit = "0" if limit.nil? || limit == ""
if limit.nil? || limit == ""
limit = OneQuotaHelper::LIMIT_UNLIMITED
end
end
"%3.1f / %3.1f" % [q['VM_QUOTA']['VM']["CPU_USED"], limit]
if limit == OneQuotaHelper::LIMIT_UNLIMITED
"%3.1f / -" % [q['VM_QUOTA']['VM']["CPU_USED"]]
else
"%3.1f / %3.1f" % [q['VM_QUOTA']['VM']["CPU_USED"], limit]
end
rescue NoMethodError
"-"

View File

@ -0,0 +1,170 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #
require 'nokogiri'
module Migrator
def db_version
"4.7.80"
end
def one_version
"OpenNebula 4.7.80"
end
def up
init_log_time()
@db.run "ALTER TABLE user_quotas RENAME TO old_user_quotas;"
@db.run "CREATE TABLE user_quotas (user_oid INTEGER PRIMARY KEY, body MEDIUMTEXT);"
@db.transaction do
# oneadmin does not have quotas
@db.fetch("SELECT * FROM old_user_quotas WHERE user_oid=0") do |row|
@db[:user_quotas].insert(row)
end
@db.fetch("SELECT * FROM old_user_quotas WHERE user_oid>0") do |row|
doc = Nokogiri::XML(row[:body]){|c| c.default_xml.noblanks}
redo_quota_limits(doc)
@db[:user_quotas].insert(
:user_oid => row[:user_oid],
:body => doc.root.to_s)
end
end
@db.run "DROP TABLE old_user_quotas;"
log_time()
@db.run "ALTER TABLE group_quotas RENAME TO old_group_quotas;"
@db.run "CREATE TABLE group_quotas (group_oid INTEGER PRIMARY KEY, body MEDIUMTEXT);"
@db.transaction do
# oneadmin does not have quotas
@db.fetch("SELECT * FROM old_group_quotas WHERE group_oid=0") do |row|
@db[:group_quotas].insert(row)
end
@db.fetch("SELECT * FROM old_group_quotas WHERE group_oid>0") do |row|
doc = Nokogiri::XML(row[:body]){|c| c.default_xml.noblanks}
redo_quota_limits(doc)
@db[:group_quotas].insert(
:group_oid => row[:group_oid],
:body => doc.root.to_s)
end
end
@db.run "DROP TABLE old_group_quotas;"
log_time()
default_user_quotas = nil
default_group_quotas = nil
@db.fetch("SELECT * FROM system_attributes WHERE name = 'DEFAULT_USER_QUOTAS'") do |row|
default_user_quotas = Nokogiri::XML(row[:body]){|c| c.default_xml.noblanks}
redo_quota_limits(default_user_quotas)
end
@db.fetch("SELECT * FROM system_attributes WHERE name = 'DEFAULT_GROUP_QUOTAS'") do |row|
default_group_quotas = Nokogiri::XML(row[:body]){|c| c.default_xml.noblanks}
redo_quota_limits(default_group_quotas)
end
@db[:system_attributes].where(:name => "DEFAULT_USER_QUOTAS").update(
:body => default_user_quotas.root.to_s)
@db[:system_attributes].where(:name => "DEFAULT_GROUP_QUOTAS").update(
:body => default_group_quotas.root.to_s)
log_time()
return true
end
def redo_quota_limits(doc)
# VM quotas
vm_elem = nil
doc.root.xpath("VM_QUOTA/VM").each { |e| vm_elem = e }
if !vm_elem.nil?
["CPU", "MEMORY", "VMS", "VOLATILE_SIZE"].each do |q_name|
vm_elem.xpath(q_name).each do |e|
if e.text.to_i == 0
e.content = "-2"
end
end
end
end
# VNet quotas
net_quota = nil
doc.root.xpath("NETWORK_QUOTA").each { |e| net_quota = e }
if !net_quota.nil?
net_quota.xpath("NETWORK").each do |net_elem|
net_elem.xpath("LEASES").each do |e|
if e.text.to_i == 0
e.content = "-2"
end
end
end
end
# Image quotas
img_quota = nil
doc.root.xpath("IMAGE_QUOTA").each { |e| img_quota = e }
if !img_quota.nil?
img_quota.xpath("IMAGE").each do |img_elem|
img_elem.xpath("RVMS").each do |e|
if e.text.to_i == 0
e.content = "-2"
end
end
end
end
# Datastore quotas
ds_quota = nil
doc.root.xpath("DATASTORE_QUOTA").each { |e| ds_quota = e }
if !ds_quota.nil?
ds_quota.xpath("DATASTORE").each do |ds_elem|
["IMAGES", "SIZE"].each do |q_name|
ds_elem.xpath(q_name).each do |e|
if e.text.to_i == 0
e.content = "-2"
end
end
end
end
end
end
end

View File

@ -43,6 +43,10 @@ panel_extended = false;
var top_interval = 10000; //ms
var top_interval_ids = {};
// global definitions
var QUOTA_LIMIT_DEFAULT = "-1";
var QUOTA_LIMIT_UNLIMITED = "-2";
//Sunstone configuration is formed by predifined "actions", main tabs
//and "info_panels". Each tab has "content" and "buttons". Each
//"info_panel" has "tabs" with "content".
@ -2389,10 +2393,10 @@ var Quotas = {
if ($.isEmptyObject(default_quotas.VM_QUOTA)){
default_quotas.VM_QUOTA = {
"VM" : {
"VMS" : "0",
"MEMORY" : "0",
"CPU" : "0",
"VOLATILE_SIZE" : "0"
"VMS" : QUOTA_LIMIT_UNLIMITED,
"MEMORY" : QUOTA_LIMIT_UNLIMITED,
"CPU" : QUOTA_LIMIT_UNLIMITED,
"VOLATILE_SIZE" : QUOTA_LIMIT_UNLIMITED
}
}
}
@ -3510,7 +3514,7 @@ function quotaBarMB(usage, limit, default_limit, not_html){
var int_limit = quotaIntLimit(limit, default_limit);
info_str = humanize_size(int_usage * 1024)+' / '
+((int_limit > 0) ? humanize_size(int_limit * 1024) : '-')
+((int_limit >= 0) ? humanize_size(int_limit * 1024) : '-')
return quotaBarHtml(int_usage, int_limit, info_str, not_html);
}
@ -3530,9 +3534,11 @@ function quotaBarHtml(usage, limit, info_str, not_html){
if (percentage > 100){
percentage = 100;
}
} else if (limit == 0 && usage > 0){
percentage = 100;
}
info_str = info_str || ( usage+' / '+((limit > 0) ? limit : '-') );
info_str = info_str || ( usage+' / '+((limit >= 0) ? limit : '-') );
if (not_html) {
return {
@ -3582,7 +3588,7 @@ function quotaIntLimit(limit, default_limit){
i_limit = parseInt(limit, 10);
i_default_limit = parseInt(default_limit, 10);
if (i_limit == -1){
if (limit == QUOTA_LIMIT_DEFAULT){
i_limit = i_default_limit;
}
@ -3598,7 +3604,7 @@ function quotaFloatLimit(limit, default_limit){
f_limit = parseFloat(limit, 10);
f_default_limit = parseFloat(default_limit, 10);
if (f_limit == -1){
if (f_limit == parseFloat(QUOTA_LIMIT_DEFAULT, 10)){
f_limit = f_default_limit;
}

View File

@ -20,6 +20,13 @@
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
const int Quota::DEFAULT = -1;
const string Quota::DEFAULT_STR = "-1";
const int Quota::UNLIMITED = -2;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Quota::get_quota(
const string& id,
VectorAttribute ** va,
@ -189,7 +196,7 @@ bool Quota::check_quota(const string& qid,
metrics_used += "_USED";
values.insert(make_pair(metrics[i], "-1"));
values.insert(make_pair(metrics[i], DEFAULT_STR));
values.insert(make_pair(metrics_used, "0"));
}
@ -222,7 +229,7 @@ bool Quota::check_quota(const string& qid,
q->vector_value(metrics[i], limit);
q->vector_value(metrics_used.c_str(), usage);
if ( limit == -1 )
if ( limit == DEFAULT )
{
if ( default_q != 0 )
{
@ -230,11 +237,11 @@ bool Quota::check_quota(const string& qid,
}
else
{
limit = 0;
limit = UNLIMITED;
}
}
check = ( limit == 0 ) || ( ( usage + it->second ) <= limit );
check = ( limit == UNLIMITED ) || ( ( usage + it->second ) <= limit );
if ( !check )
{
@ -335,11 +342,11 @@ void Quota::cleanup_quota(const string& qid)
if ( is_default )
{
implicit_limit = 0;
implicit_limit = UNLIMITED;
}
else
{
implicit_limit = -1;
implicit_limit = DEFAULT;
}
for (int i=0; i < num_metrics; i++)
@ -376,10 +383,14 @@ int Quota::update_limits(
{
limit = va->vector_value_str(metrics[i], limit_f);
//No quota, NaN or negative
if ((!is_default &&
( limit_f < -1 || ( limit_f == -1 && limit == "" ))) ||
(is_default && limit_f < 0) )
if (( limit_f == -1 && limit == "" ) // NaN
||
// Negative. Default & unlimited allowed
( !is_default && limit_f < 0 && limit_f != UNLIMITED && limit_f != DEFAULT )
||
// Negative. Unlimited allowed
( is_default && limit_f < 0 && limit_f != UNLIMITED )
)
{
return -1;
}
@ -408,9 +419,14 @@ VectorAttribute * Quota::new_quota(VectorAttribute * va)
limit = va->vector_value_str(metrics[i], limit_f);
//No quota, NaN or negative
if ( (!is_default && limit_f < -1) ||
(is_default && limit_f < 0) )
if (( limit_f == -1 && limit == "" ) // NaN
||
// Negative. Default & unlimited allowed
( !is_default && limit_f < 0 && limit_f != UNLIMITED && limit_f != DEFAULT )
||
// Negative. Unlimited allowed
( is_default && limit_f < 0 && limit_f != UNLIMITED )
)
{
return 0;
}