mirror of
https://github.com/OpenNebula/one.git
synced 2024-12-31 17:17:40 +03:00
F #6341: Generic Quotas
- Generic quotas are defined and read from oned.conf (QUOTA_VM_ATTRIBUTE) - Generic quotas react to the running mode (i.e. account only when the VM is running). For each quota oned also adds a RUNNIN_* metric - one.system.config API call has been updated so every user can read quota configuration: . Sensitive information is hidden (***) . Oneadmin group has no longer access to sensitive information through the API - CLI has been updated to render generic quotas - onedb fsck fixes generic quotas reading the configuration from oned.conf Other changes in this PR: - Refactor Quota metrics to use std::vector instead of C array Squashed commit of the following: - New methods to Template and Attribute classes to render hidden attributes as "***" - Update Quota calls to not include unneeded quotas co-authored-by:Ruben S. Montero <rsmontero@opennebula.org>
This commit is contained in:
parent
863ed452f7
commit
442041fd07
@ -81,6 +81,9 @@ public:
|
||||
|
||||
virtual void to_token(std::ostringstream& s) const = 0;
|
||||
|
||||
virtual void to_xml(std::ostringstream& s,
|
||||
const std::map<std::string, std::set<std::string>> &hidden) const = 0;
|
||||
|
||||
/**
|
||||
* Builds a new attribute from a string.
|
||||
*/
|
||||
@ -167,6 +170,9 @@ public:
|
||||
* <attribute_name>attribute_value</attribute_name>
|
||||
*
|
||||
* @paran s the stream to write the attribute.
|
||||
*
|
||||
* NOTE: For Simple attributes hidden are in the form { "PORT". {} }
|
||||
* A hidden attribute is rendered as ***
|
||||
*/
|
||||
void to_xml(std::ostringstream& s) const override
|
||||
{
|
||||
@ -175,6 +181,23 @@ public:
|
||||
|
||||
}
|
||||
|
||||
void to_xml(std::ostringstream& s,
|
||||
const std::map<std::string, std::set<std::string>> &hidden) const override
|
||||
{
|
||||
s << "<" << attribute_name << ">";
|
||||
|
||||
if (hidden.find(attribute_name) != hidden.end() )
|
||||
{
|
||||
s << "***";
|
||||
}
|
||||
else
|
||||
{
|
||||
s << one_util::escape_xml(attribute_value);
|
||||
}
|
||||
|
||||
s << "</"<< attribute_name << ">";
|
||||
}
|
||||
|
||||
void to_json(std::ostringstream& s) const override
|
||||
{
|
||||
one_util::escape_json(attribute_value, s);
|
||||
@ -422,9 +445,15 @@ public:
|
||||
* ...
|
||||
* <val_name_n>val_value_n</val_name_n>
|
||||
* </attribute_name>
|
||||
*
|
||||
* NOTE: For Vector attributes hidden are in the form { "DB", { "USER", "PASSWD"} }
|
||||
* A hidden attribute is rendered as ***
|
||||
*/
|
||||
void to_xml(std::ostringstream& s) const override;
|
||||
|
||||
void to_xml(std::ostringstream& s,
|
||||
const std::map<std::string, std::set<std::string>> &hidden) const override;
|
||||
|
||||
void to_json(std::ostringstream& s) const override;
|
||||
|
||||
void to_token(std::ostringstream& s) const override;
|
||||
|
@ -98,6 +98,12 @@ public:
|
||||
return va->to_token(s);
|
||||
};
|
||||
|
||||
void to_xml(std::ostringstream& s,
|
||||
const std::map<std::string, std::set<std::string>> &hidden) const override
|
||||
{
|
||||
return va->to_xml(s, hidden);
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Creates the attribute with a reference to a VectorAttribute. The object
|
||||
|
@ -175,10 +175,20 @@ public:
|
||||
* Gets an XML document with all of the configuration attributes
|
||||
* @return the XML
|
||||
*/
|
||||
std::string get_configuration_xml() const
|
||||
std::string get_configuration_xml(bool admin) const
|
||||
{
|
||||
std::string xml;
|
||||
return config->to_xml(xml);
|
||||
|
||||
if (admin)
|
||||
{
|
||||
config->to_xml(xml);
|
||||
}
|
||||
else
|
||||
{
|
||||
config->to_xml_hidden(xml);
|
||||
}
|
||||
|
||||
return xml;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
@ -30,7 +30,9 @@ public:
|
||||
NebulaTemplate(const std::string& etc_location, const char * _conf_name,
|
||||
const char * root_name)
|
||||
: Template(false, '=', root_name)
|
||||
, hidden_attributes{ { "DB", { "PASSWD" } } }
|
||||
, hidden_attributes{
|
||||
{"DB", {"BACKEND", "SERVER", "PORT", "USER", "PASSWD", "DB_NAME"}}
|
||||
}
|
||||
{
|
||||
if (_conf_name[0] == '/')
|
||||
{
|
||||
@ -51,11 +53,13 @@ public:
|
||||
|
||||
std::string& to_str(std::string& str) const override;
|
||||
|
||||
std::string& to_xml_hidden(std::string& str) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Full path to the configuration file
|
||||
*/
|
||||
std::string conf_file;
|
||||
std::string conf_file;
|
||||
|
||||
/**
|
||||
* Defaults for the configuration file
|
||||
@ -64,8 +68,8 @@ protected:
|
||||
|
||||
/**
|
||||
* Hidden attributes, which shouldn't be displayed to non-admin users
|
||||
* For Simple attributes use { "PORT". {} }
|
||||
* For Vector attributes use { "DB", { "USER", "PASSWD"} }
|
||||
* For Simple attributes use {"PORT", {}}
|
||||
* For Vector attributes use {"DB", {"USER", "PASSWD"}}
|
||||
*/
|
||||
std::map<std::string, std::set<std::string>> hidden_attributes;
|
||||
|
||||
|
@ -194,13 +194,11 @@ protected:
|
||||
|
||||
Quota(const char * quota_name,
|
||||
const char * _template_name,
|
||||
const char ** _metrics,
|
||||
int _num_metrics,
|
||||
const std::vector<std::string>& _metrics,
|
||||
bool _is_default)
|
||||
: Template(false, '=', quota_name),
|
||||
template_name(_template_name),
|
||||
metrics(_metrics),
|
||||
num_metrics(_num_metrics),
|
||||
is_default(_is_default){};
|
||||
|
||||
virtual ~Quota(){};
|
||||
@ -225,12 +223,7 @@ protected:
|
||||
/**
|
||||
* The name of the quota metrics
|
||||
*/
|
||||
const char ** metrics;
|
||||
|
||||
/**
|
||||
* Length
|
||||
*/
|
||||
int num_metrics;
|
||||
const std::vector<std::string>& metrics;
|
||||
|
||||
/**
|
||||
* Whether or not this is a default quota. Default quotas do not have usage,
|
||||
|
@ -40,7 +40,6 @@ public:
|
||||
Quota("DATASTORE_QUOTA",
|
||||
"DATASTORE",
|
||||
DS_METRICS,
|
||||
NUM_DS_METRICS,
|
||||
is_default)
|
||||
{};
|
||||
|
||||
@ -77,9 +76,7 @@ protected:
|
||||
Quotas& default_quotas,
|
||||
VectorAttribute **va) override;
|
||||
|
||||
static const char * DS_METRICS[];
|
||||
|
||||
static const int NUM_DS_METRICS;
|
||||
static const std::vector<std::string> DS_METRICS;
|
||||
};
|
||||
|
||||
#endif /*QUOTA_DATASTORE_H_*/
|
||||
|
@ -30,7 +30,7 @@
|
||||
* 0 = unlimited, default if missing
|
||||
*/
|
||||
|
||||
class QuotaImage : public Quota
|
||||
class QuotaImage : public Quota
|
||||
{
|
||||
public:
|
||||
|
||||
@ -38,7 +38,6 @@ public:
|
||||
Quota("IMAGE_QUOTA",
|
||||
"IMAGE",
|
||||
IMAGE_METRICS,
|
||||
NUM_IMAGE_METRICS,
|
||||
is_default)
|
||||
{};
|
||||
|
||||
@ -75,9 +74,7 @@ protected:
|
||||
Quotas& default_quotas,
|
||||
VectorAttribute **va) override;
|
||||
|
||||
static const char * IMAGE_METRICS[];
|
||||
|
||||
static const int NUM_IMAGE_METRICS;
|
||||
static const std::vector<std::string> IMAGE_METRICS;
|
||||
};
|
||||
|
||||
#endif /*QUOTA_IMAGE_H_*/
|
||||
|
@ -30,11 +30,12 @@
|
||||
*
|
||||
* 0 = unlimited, default if missing
|
||||
*/
|
||||
class QuotaNetwork : public Quota
|
||||
class QuotaNetwork : public Quota
|
||||
{
|
||||
public:
|
||||
QuotaNetwork(bool is_default): Quota("NETWORK_QUOTA", "NETWORK", NET_METRICS,
|
||||
NUM_NET_METRICS, is_default) {};
|
||||
QuotaNetwork(bool is_default)
|
||||
: Quota("NETWORK_QUOTA", "NETWORK", NET_METRICS, is_default)
|
||||
{}
|
||||
|
||||
virtual ~QuotaNetwork(){};
|
||||
|
||||
@ -75,9 +76,7 @@ protected:
|
||||
Quotas& default_quotas,
|
||||
VectorAttribute **va) override;
|
||||
|
||||
static const char * NET_METRICS[];
|
||||
|
||||
static const int NUM_NET_METRICS;
|
||||
static const std::vector<std::string> NET_METRICS;
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -41,7 +41,7 @@
|
||||
* 0 = unlimited, default if missing
|
||||
*/
|
||||
|
||||
class QuotaVirtualMachine : public Quota
|
||||
class QuotaVirtualMachine : public Quota
|
||||
{
|
||||
public:
|
||||
|
||||
@ -49,7 +49,6 @@ public:
|
||||
Quota("VM_QUOTA",
|
||||
"VM",
|
||||
VM_METRICS,
|
||||
NUM_VM_METRICS,
|
||||
is_default)
|
||||
{};
|
||||
|
||||
@ -96,6 +95,27 @@ public:
|
||||
*/
|
||||
int get_quota(const std::string& id, VectorAttribute **va) override;
|
||||
|
||||
/**
|
||||
* Add generic quota to metrics. It adds also RUNNING_ quota attribute
|
||||
* @param metric Name of the quota metri
|
||||
*
|
||||
* @return 0 success, -1 if metric already exists
|
||||
*/
|
||||
static int add_metric_generic(const std::string& metric);
|
||||
|
||||
/**
|
||||
* Return vector of generic quota metrics
|
||||
*/
|
||||
static const std::vector<std::string>& generic_metrics()
|
||||
{
|
||||
return VM_GENERIC;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add RUNNING_ quotas for generic metrics present in the template
|
||||
*/
|
||||
static void add_running_quota_generic(Template& tmpl);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
@ -130,10 +150,8 @@ protected:
|
||||
Quotas& default_quotas,
|
||||
VectorAttribute **va) override;
|
||||
|
||||
static const char * VM_METRICS[];
|
||||
|
||||
static const int NUM_VM_METRICS;
|
||||
|
||||
static std::vector<std::string> VM_METRICS;
|
||||
static std::vector<std::string> VM_GENERIC;
|
||||
};
|
||||
|
||||
#endif /*QUOTA_VIRTUALMACHINE_H_*/
|
||||
|
@ -60,6 +60,11 @@ protected:
|
||||
void request_execute(xmlrpc_c::paramList const& _paramList,
|
||||
RequestAttributes& att) override;
|
||||
|
||||
virtual void request_execute(int oid,
|
||||
const std::string& templ,
|
||||
int update_type,
|
||||
RequestAttributes& att);
|
||||
|
||||
virtual int replace_template(PoolObjectSQL * object,
|
||||
const std::string & tmpl,
|
||||
const RequestAttributes &att,
|
||||
@ -80,17 +85,6 @@ protected:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for extra checks on specific objects
|
||||
* @param obj to check conditions form update
|
||||
* @param error return reason of error
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int extra_preconditions_check(PoolObjectSQL * obj, std::string& error)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -164,21 +158,10 @@ protected:
|
||||
return vmpool->update_search(vm);
|
||||
}
|
||||
|
||||
int extra_preconditions_check(PoolObjectSQL * obj, std::string& error) override
|
||||
{
|
||||
auto vm = static_cast<VirtualMachine *>(obj);
|
||||
|
||||
// Check if the action is supported for imported VMs
|
||||
if (vm->is_imported() &&
|
||||
!vm->is_imported_action_supported(VMActions::UPDATE_ACTION))
|
||||
{
|
||||
error = "Action \"update\" is not supported for imported VMs";
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
void request_execute(int oid,
|
||||
const std::string& templ,
|
||||
int update_type,
|
||||
RequestAttributes& att) override;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -182,13 +182,21 @@ public:
|
||||
* ...
|
||||
* </template>
|
||||
* The name of the root element is set when the Template object is created
|
||||
* @param xml string that hold the xml template representation
|
||||
* @return a reference to the generated string
|
||||
*
|
||||
* Hidden attributes are defined as a map, where
|
||||
* - Simple attributes use an empty set { "PORT", {} }
|
||||
* - Vector attributes use a set of hidden subattributes { "DB", { "USER", "PASSWD"} }
|
||||
*
|
||||
* @param xml string that hold the xml template representation
|
||||
*
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
std::string& to_xml(std::string& xml) const;
|
||||
|
||||
std::string& to_xml(std::string& xml, const std::string& extra) const;
|
||||
|
||||
std::string& to_xml(std::string& xml, const std::map<std::string, std::set<std::string>>& hidden) const;
|
||||
|
||||
std::string& to_json(std::string& xml) const;
|
||||
|
||||
std::string& to_token(std::string& xml) const;
|
||||
|
@ -940,6 +940,15 @@ public:
|
||||
return std::make_unique<VirtualMachineTemplate>(*obj_template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the VirtualMachine User Template
|
||||
* @return A copy of the VirtualMachine User Template
|
||||
*/
|
||||
std::unique_ptr<VirtualMachineTemplate> clone_user_template() const
|
||||
{
|
||||
return std::make_unique<VirtualMachineTemplate>(*user_obj_template);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function replaces the *user template*.
|
||||
* @param tmpl_str new contents
|
||||
@ -967,10 +976,10 @@ public:
|
||||
* @param name of the attribute
|
||||
* @param value of the attribute
|
||||
*/
|
||||
void get_user_template_attribute(const std::string& name,
|
||||
std::string& value) const
|
||||
template<typename T>
|
||||
bool get_user_template_attribute(const std::string& name, T& value) const
|
||||
{
|
||||
user_obj_template->get(name, value);
|
||||
return user_obj_template->get(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1052,12 +1061,18 @@ public:
|
||||
*/
|
||||
bool is_pinned() const;
|
||||
|
||||
/**
|
||||
* @return true if Virtual Machine is in state, when running quota applies
|
||||
*/
|
||||
bool is_running_quota() const;
|
||||
|
||||
/**
|
||||
* Fill a template only with the necessary attributes to update the quotas
|
||||
* @param qtmpl template that will be filled
|
||||
* @param only_running true to not add CPU, MEMORY and VMS counters
|
||||
* @param basic_quota true to add basic quota attributes (from Template and User template)
|
||||
* @param running_quota true to add RUNNING_ quota attributes (for Template and User Template)
|
||||
*/
|
||||
void get_quota_template(VirtualMachineTemplate& qtmpl, bool only_running);
|
||||
void get_quota_template(VirtualMachineTemplate& quota_tmpl, bool basic_quota, bool running_quota);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Virtual Machine Disks
|
||||
|
@ -873,6 +873,15 @@ DEFAULT_VDC_CLUSTER_HOST_ACL = "MANAGE"
|
||||
DEFAULT_VDC_CLUSTER_NET_ACL = "USE"
|
||||
DEFAULT_VDC_CLUSTER_DATASTORE_ACL = "USE"
|
||||
|
||||
#*******************************************************************************
|
||||
# Generic VM Quotas Configuration
|
||||
#*******************************************************************************
|
||||
# The following attributes may be limited by quotas. Use any numeric attribute
|
||||
# from Template or User Template
|
||||
#*******************************************************************************
|
||||
|
||||
#QUOTA_VM_ATTRIBUTE = "VCPU"
|
||||
|
||||
#*******************************************************************************
|
||||
# Restricted Attributes Configuration
|
||||
#*******************************************************************************
|
||||
|
@ -328,7 +328,7 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
|
||||
default_quotas = elem
|
||||
}
|
||||
|
||||
helper = OneQuotaHelper.new
|
||||
helper = OneQuotaHelper.new(@client)
|
||||
helper.format_quota(group_hash['GROUP'], default_quotas, group.id)
|
||||
end
|
||||
end
|
||||
|
@ -75,6 +75,10 @@ class OneQuotaHelper
|
||||
#-----------------------------------------------------------------------
|
||||
EOT
|
||||
|
||||
def initialize(client = nil)
|
||||
@client=client
|
||||
end
|
||||
|
||||
# Edits the quota template of a resource
|
||||
# @param [XMLElement] resource to get the current info from
|
||||
# @param [String] path to the new contents. If nil a editor will be
|
||||
@ -207,6 +211,8 @@ class OneQuotaHelper
|
||||
|
||||
vm_quotas = [qh['VM_QUOTA']['VM']].flatten
|
||||
|
||||
generic_quotas = get_generic_quotas
|
||||
|
||||
# This initializes the VM quotas for users/groups that don't have any
|
||||
# resource usage yet. It not applied to oneamdin
|
||||
if vm_quotas[0].nil? && resource_id.to_i != 0
|
||||
@ -228,6 +234,13 @@ class OneQuotaHelper
|
||||
"SYSTEM_DISK_SIZE" => limit,
|
||||
"SYSTEM_DISK_SIZE_USED" => "0"
|
||||
}]
|
||||
|
||||
generic_quotas.each do |q|
|
||||
vm_quotas[0][q] = limit
|
||||
vm_quotas[0]["#{q}_USED"] = "0"
|
||||
vm_quotas[0]["RUNNING_#{q}"] = limit
|
||||
vm_quotas[0]["RUNNING_#{q}_USED"] = "0"
|
||||
end
|
||||
end
|
||||
|
||||
if !vm_quotas[0].nil?
|
||||
@ -378,6 +391,55 @@ class OneQuotaHelper
|
||||
puts
|
||||
end
|
||||
|
||||
if !generic_quotas.empty? && !vm_quotas[0].nil?
|
||||
CLIHelper.print_header(str_h1 % "VMS GENERIC QUOTAS",false)
|
||||
size = [80 / generic_quotas.length - 1, 18].min
|
||||
|
||||
CLIHelper::ShowTable.new(nil, self) do
|
||||
generic_quotas.each do |elem|
|
||||
column elem.to_sym, "", :right, :size=>size do |d|
|
||||
if !d.nil?
|
||||
limit = d[elem]
|
||||
limit = helper.get_default_limit(
|
||||
limit, "VM_QUOTA/VM/#{elem}")
|
||||
|
||||
if limit == LIMIT_UNLIMITED
|
||||
"%6s / -" % [d["#{elem}_USED"]]
|
||||
else
|
||||
"%6s / %6s" % [d["#{elem}_USED"], limit]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end.show(vm_quotas, {})
|
||||
|
||||
puts
|
||||
|
||||
CLIHelper.print_header(str_h1 % "VMS GENERIC RUNNING QUOTAS",false)
|
||||
size = [80 / generic_quotas.length - 1, 18].min
|
||||
|
||||
CLIHelper::ShowTable.new(nil, self) do
|
||||
generic_quotas.each do |q|
|
||||
elem = "RUNNING_#{q}"
|
||||
column elem.to_sym, "", :right, :size=>size do |d|
|
||||
if !d.nil?
|
||||
limit = d[elem]
|
||||
limit = helper.get_default_limit(
|
||||
limit, "VM_QUOTA/VM/#{elem}")
|
||||
|
||||
if limit == LIMIT_UNLIMITED
|
||||
"%6s / -" % [d["#{elem}_USED"]]
|
||||
else
|
||||
"%6s / %6s" % [d["#{elem}_USED"], limit]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end.show(vm_quotas, {})
|
||||
|
||||
puts
|
||||
end
|
||||
|
||||
CLIHelper.print_header(str_h1 % "DATASTORE USAGE & QUOTAS",false)
|
||||
|
||||
puts
|
||||
@ -503,4 +565,17 @@ class OneQuotaHelper
|
||||
|
||||
return limit
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_generic_quotas
|
||||
conf = OpenNebula::System.new(@client).get_configuration
|
||||
|
||||
return [] if OpenNebula.is_error?(conf)
|
||||
|
||||
conf.retrieve_elements('/OPENNEBULA_CONFIGURATION/QUOTA_VM_ATTRIBUTE')
|
||||
rescue StandardError
|
||||
[]
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -613,7 +613,7 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
|
||||
default_quotas = elem
|
||||
}
|
||||
|
||||
helper = OneQuotaHelper.new
|
||||
helper = OneQuotaHelper.new(@client)
|
||||
helper.format_quota(user_hash['USER'], default_quotas, user.id)
|
||||
end
|
||||
|
||||
|
@ -80,6 +80,38 @@ void VectorAttribute::to_xml(ostringstream &oss) const
|
||||
oss << "</"<< name() << ">";
|
||||
}
|
||||
|
||||
void VectorAttribute::to_xml(ostringstream &oss,
|
||||
const std::map<std::string, std::set<std::string>> &hidden) const
|
||||
{
|
||||
oss << "<" << name() << ">";
|
||||
|
||||
auto hidden_it = hidden.find(name());
|
||||
|
||||
for (auto it=attribute_value.begin(); it!=attribute_value.end(); it++)
|
||||
{
|
||||
if ( it->first.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
oss << "<" << it->first << ">";
|
||||
|
||||
if (hidden_it != hidden.end() &&
|
||||
hidden_it->second.find(it->first) != hidden_it->second.end())
|
||||
{
|
||||
oss << "***";
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << one_util::escape_xml(it->second);
|
||||
}
|
||||
|
||||
oss << "</" << it->first << ">";
|
||||
}
|
||||
|
||||
oss << "</"<< name() << ">";
|
||||
}
|
||||
|
||||
void VectorAttribute::to_json(std::ostringstream& s) const
|
||||
{
|
||||
if ( attribute_value.empty() )
|
||||
|
@ -76,7 +76,7 @@ int DispatchManager::deploy(unique_ptr<VirtualMachine> vm,
|
||||
uid = vm->get_uid();
|
||||
gid = vm->get_gid();
|
||||
|
||||
vm->get_quota_template(quota_tmpl, true);
|
||||
vm->get_quota_template(quota_tmpl, false, true);
|
||||
}
|
||||
|
||||
lcm->trigger_deploy(vid);
|
||||
@ -152,7 +152,7 @@ int DispatchManager::import(unique_ptr<VirtualMachine> vm, const RequestAttribut
|
||||
uid = vm->get_uid();
|
||||
gid = vm->get_gid();
|
||||
|
||||
vm->get_quota_template(quota_tmpl, true);
|
||||
vm->get_quota_template(quota_tmpl, false, true);
|
||||
|
||||
do_quotas = true;
|
||||
}
|
||||
@ -290,23 +290,9 @@ void DispatchManager::free_vm_resources(unique_ptr<VirtualMachine> vm,
|
||||
int vrid = -1;
|
||||
unsigned int port;
|
||||
|
||||
auto quota_tmpl = vm->clone_template();
|
||||
VirtualMachineTemplate quota_tmpl;
|
||||
|
||||
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->get_quota_template(quota_tmpl, true, vm->is_running_quota());
|
||||
|
||||
vm->release_network_leases();
|
||||
|
||||
@ -370,7 +356,7 @@ void DispatchManager::free_vm_resources(unique_ptr<VirtualMachine> vm,
|
||||
|
||||
vm.reset(); //force unlock of vm mutex
|
||||
|
||||
Quotas::vm_del(uid, gid, quota_tmpl.get());
|
||||
Quotas::vm_del(uid, gid, "a_tmpl);
|
||||
|
||||
if ( !ds_quotas.empty() )
|
||||
{
|
||||
@ -1240,7 +1226,7 @@ int DispatchManager::delete_recreate(unique_ptr<VirtualMachine> vm,
|
||||
|
||||
if ( do_quotas )
|
||||
{
|
||||
vm->get_quota_template(quota_tmpl, true);
|
||||
vm->get_quota_template(quota_tmpl, false, true);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -43,7 +43,7 @@ void DispatchManager::trigger_suspend_success(int vid)
|
||||
{
|
||||
VirtualMachineTemplate quota_tmpl;
|
||||
|
||||
vm->get_quota_template(quota_tmpl, true);
|
||||
vm->get_quota_template(quota_tmpl, false, true);
|
||||
|
||||
vm->set_state(VirtualMachine::SUSPENDED);
|
||||
|
||||
@ -96,7 +96,7 @@ void DispatchManager::trigger_stop_success(int vid)
|
||||
{
|
||||
VirtualMachineTemplate quota_tmpl;
|
||||
|
||||
vm->get_quota_template(quota_tmpl, true);
|
||||
vm->get_quota_template(quota_tmpl, false, true);
|
||||
|
||||
vm->set_state(VirtualMachine::STOPPED);
|
||||
|
||||
@ -151,7 +151,9 @@ void DispatchManager::trigger_undeploy_success(int vid)
|
||||
{
|
||||
VirtualMachineTemplate quota_tmpl;
|
||||
|
||||
vm->get_quota_template(quota_tmpl, true);
|
||||
// Bug: From the LCM state we don't know if we undeploy from RUNNING or POWEROFF
|
||||
// state. In first case we should remove RUNNING_* quotas, in the second not
|
||||
vm->get_quota_template(quota_tmpl, false, vm->is_running_quota());
|
||||
|
||||
vm->set_state(VirtualMachine::UNDEPLOYED);
|
||||
|
||||
@ -214,7 +216,7 @@ void DispatchManager::trigger_poweroff_success(int vid)
|
||||
{
|
||||
VirtualMachineTemplate quota_tmpl;
|
||||
|
||||
vm->get_quota_template(quota_tmpl, true);
|
||||
vm->get_quota_template(quota_tmpl, false, vm->is_running_quota());
|
||||
|
||||
vm->set_state(VirtualMachine::POWEROFF);
|
||||
|
||||
|
@ -202,9 +202,7 @@ void LifeCycleManager::trigger_stop(int vid, const RequestAttributes& ra)
|
||||
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);
|
||||
vm->get_quota_template(quota_tmpl, false, true);
|
||||
|
||||
vm->set_state(VirtualMachine::ACTIVE);
|
||||
vm->set_state(VirtualMachine::EPILOG_STOP);
|
||||
@ -220,7 +218,7 @@ void LifeCycleManager::trigger_stop(int vid, const RequestAttributes& ra)
|
||||
//----------------------------------------------------
|
||||
|
||||
tm->trigger_epilog_stop(vm.get());
|
||||
|
||||
|
||||
// Add running quota, it will be removed in DM::stop_success
|
||||
vm.reset();
|
||||
Quotas::vm_add(quota_uid, quota_gid, "a_tmpl);
|
||||
@ -465,9 +463,7 @@ void LifeCycleManager::trigger_shutdown(int vid, bool hard,
|
||||
(vm->get_state() == VirtualMachine::STOPPED) ||
|
||||
(vm->get_state() == VirtualMachine::UNDEPLOYED))
|
||||
{
|
||||
quota_tmpl.add("RUNNING_MEMORY", memory);
|
||||
quota_tmpl.add("RUNNING_CPU", cpu);
|
||||
quota_tmpl.add("RUNNING_VMS", 1);
|
||||
vm->get_quota_template(quota_tmpl, false, true);
|
||||
}
|
||||
|
||||
auto lcm_state = vm->get_lcm_state();
|
||||
@ -639,9 +635,7 @@ void LifeCycleManager::trigger_undeploy(int vid, bool hard,
|
||||
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);
|
||||
vm->get_quota_template(quota_tmpl, false, true);
|
||||
|
||||
vm->set_state(VirtualMachine::ACTIVE);
|
||||
vm->set_state(VirtualMachine::EPILOG_UNDEPLOY);
|
||||
|
@ -1226,7 +1226,7 @@ void LifeCycleManager::trigger_monitor_poweron(int vid)
|
||||
|
||||
vmpool->update(vm.get());
|
||||
|
||||
vm->get_quota_template(quota_tmpl, true);
|
||||
vm->get_quota_template(quota_tmpl, false, true);
|
||||
|
||||
vm.reset();
|
||||
|
||||
@ -1512,7 +1512,6 @@ void LifeCycleManager::trigger_snapshot_create_failure(int vid)
|
||||
Template quota_tmpl;
|
||||
|
||||
quota_tmpl.set(snap);
|
||||
quota_tmpl.replace("VMS", 0);
|
||||
|
||||
Quotas::quota_del(Quotas::VM, vm_uid, vm_gid, "a_tmpl);
|
||||
}
|
||||
@ -2622,7 +2621,7 @@ void LifeCycleManager::trigger_resize_failure(int vid)
|
||||
|
||||
deltas.add("MEMORY", nmem - omem);
|
||||
deltas.add("CPU", ncpu - ocpu);
|
||||
deltas.add("VMS", 0);
|
||||
deltas.add("VCPU", nvcpu - ovcpu);
|
||||
|
||||
auto state = vm->get_state();
|
||||
|
||||
@ -2632,6 +2631,7 @@ void LifeCycleManager::trigger_resize_failure(int vid)
|
||||
{
|
||||
deltas.add("RUNNING_MEMORY", nmem - omem);
|
||||
deltas.add("RUNNING_CPU", ncpu - ocpu);
|
||||
deltas.add("RUNNING_VCPU", nvcpu - ovcpu);
|
||||
}
|
||||
|
||||
vm->resize(ocpu, omem, ovcpu, error);
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
|
||||
msg.type(MonitorDriverMessages::START_MONITOR);
|
||||
msg.oid(oid);
|
||||
msg.payload(format_message(host_xml + ns.get_configuration_xml()));
|
||||
msg.payload(format_message(host_xml + ns.get_configuration_xml(true)));
|
||||
|
||||
write(msg);
|
||||
}
|
||||
@ -74,7 +74,7 @@ public:
|
||||
|
||||
msg.type(MonitorDriverMessages::STOP_MONITOR);
|
||||
msg.oid(oid);
|
||||
msg.payload(format_message(host_xml + ns.get_configuration_xml()));
|
||||
msg.payload(format_message(host_xml + ns.get_configuration_xml(true)));
|
||||
|
||||
write(msg);
|
||||
}
|
||||
|
@ -614,6 +614,24 @@ void Nebula::start(bool bootstrap_only)
|
||||
|
||||
ssl_util::SSLMutex::initialize();
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Generic Quotas
|
||||
// -----------------------------------------------------------
|
||||
{
|
||||
vector<const SingleAttribute *> qouta_vm_attrs;
|
||||
|
||||
nebula_configuration->get("QUOTA_VM_ATTRIBUTE", qouta_vm_attrs);
|
||||
|
||||
for (const auto* quota : qouta_vm_attrs)
|
||||
{
|
||||
if (QuotaVirtualMachine::add_metric_generic(quota->value()) != 0)
|
||||
{
|
||||
NebulaLog::warn("ONE", "Unable to add QUOTA_VM_ATTRIBUTE " + quota->value()
|
||||
+ ", it already exists");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
//Managers
|
||||
// -----------------------------------------------------------
|
||||
|
@ -171,6 +171,51 @@ EOT
|
||||
end
|
||||
end
|
||||
|
||||
def read_config
|
||||
begin
|
||||
# Suppress augeas require warning message
|
||||
$VERBOSE = nil
|
||||
|
||||
gem 'augeas', '~> 0.6'
|
||||
require 'augeas'
|
||||
rescue Gem::LoadError
|
||||
STDERR.puts(
|
||||
'Augeas gem is not installed, run `gem install ' \
|
||||
'augeas -v \'0.6\'` to install it'
|
||||
)
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
work_file_dir = File.dirname(ONED_CONF)
|
||||
work_file_name = File.basename(ONED_CONF)
|
||||
|
||||
aug = Augeas.create(:no_modl_autoload => true,
|
||||
:no_load => true,
|
||||
:root => work_file_dir,
|
||||
:loadpath => ONED_CONF)
|
||||
|
||||
aug.clear_transforms
|
||||
aug.transform(:lens => 'Oned.lns', :incl => work_file_name)
|
||||
aug.context = "/files/#{work_file_name}"
|
||||
aug.load
|
||||
|
||||
@generic_quotas = []
|
||||
|
||||
i = 0
|
||||
loop do
|
||||
i += 1
|
||||
|
||||
quota = aug.get("QUOTA_VM_ATTRIBUTE[#{i}]")
|
||||
|
||||
break if quota.nil?
|
||||
|
||||
@generic_quotas << quota.chomp('"').reverse.chomp('"').reverse
|
||||
end
|
||||
rescue StandardError => e
|
||||
STDERR.puts "Unable to parse oned.conf: #{e}"
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Acl
|
||||
########################################################################
|
||||
|
@ -56,7 +56,9 @@ module OneDBFsck
|
||||
# VM quotas
|
||||
query = "SELECT body FROM vm_pool WHERE #{filter} AND state<>6"
|
||||
|
||||
resources = { :cpu => 'CPU', :mem => 'MEMORY', :vms => 'VMS' }
|
||||
resources = { :CPU => 'CPU', :MEMORY => 'MEMORY', :VMS => 'VMS' }
|
||||
|
||||
@generic_quotas.each {|q| resources[q] = q }
|
||||
|
||||
vm_elem = calculate_vm_quotas(doc, query, resource, resources)
|
||||
|
||||
@ -95,9 +97,11 @@ module OneDBFsck
|
||||
|
||||
query = "SELECT body FROM vm_pool WHERE #{filter} AND #{running_states}"
|
||||
|
||||
resources = { :cpu => 'RUNNING_CPU',
|
||||
:mem => 'RUNNING_MEMORY',
|
||||
:vms => 'RUNNING_VMS' }
|
||||
resources = { :CPU => 'RUNNING_CPU',
|
||||
:MEMORY => 'RUNNING_MEMORY',
|
||||
:VMS => 'RUNNING_VMS' }
|
||||
|
||||
@generic_quotas.each {|q| resources[q] = "RUNNING_#{q}" }
|
||||
|
||||
calculate_vm_quotas(doc, query, resource, resources)
|
||||
end
|
||||
@ -344,12 +348,12 @@ module OneDBFsck
|
||||
oid = doc.root.at_xpath('ID').text.to_i
|
||||
|
||||
cpu_used = 0
|
||||
mem_used = 0
|
||||
vms_used = 0
|
||||
|
||||
cpu = resources[:cpu]
|
||||
mem = resources[:mem]
|
||||
vms = resources[:vms]
|
||||
cpu = resources[:CPU]
|
||||
vms = resources[:VMS]
|
||||
|
||||
quotas = {}
|
||||
resources.each {|_, q| quotas[q] = 0 }
|
||||
|
||||
@db.fetch(query) do |vm_row|
|
||||
vmdoc = nokogiri_doc(vm_row[:body], 'vm_pool')
|
||||
@ -359,11 +363,17 @@ module OneDBFsck
|
||||
cpu_used += (e.text.to_f * 100).to_i
|
||||
end
|
||||
|
||||
vmdoc.root.xpath('TEMPLATE/MEMORY').each do |e|
|
||||
mem_used += e.text.to_i
|
||||
resources.each do |att_name, quota_name|
|
||||
next if [:CPU, :VMS].include?(att_name)
|
||||
|
||||
value = vmdoc.root.at_xpath("TEMPLATE/#{att_name}") ||
|
||||
vmdoc.root.at_xpath("USER_TEMPLATE/#{att_name}")
|
||||
value = value.text unless value.nil?
|
||||
|
||||
quotas[quota_name] += value.to_i
|
||||
end
|
||||
|
||||
vms_used += 1
|
||||
quotas[vms] += 1
|
||||
end
|
||||
|
||||
vm_elem = nil
|
||||
@ -375,14 +385,10 @@ module OneDBFsck
|
||||
vm_quota = doc.root.add_child(doc.create_element('VM_QUOTA'))
|
||||
vm_elem = vm_quota.add_child(doc.create_element('VM'))
|
||||
|
||||
vm_elem.add_child(doc.create_element(cpu)).content = '-1'
|
||||
vm_elem.add_child(doc.create_element("#{cpu}_USED")).content = '0'
|
||||
|
||||
vm_elem.add_child(doc.create_element(mem)).content = '-1'
|
||||
vm_elem.add_child(doc.create_element("#{mem}_USED")).content = '0'
|
||||
|
||||
vm_elem.add_child(doc.create_element(vms)).content = '-1'
|
||||
vm_elem.add_child(doc.create_element("#{vms}_USED")).content = '0'
|
||||
resources.each do |_, quota_name|
|
||||
vm_elem.add_child(doc.create_element(quota_name)).content = '-1'
|
||||
vm_elem.add_child(doc.create_element("#{quota_name}_USED")).content = '0'
|
||||
end
|
||||
|
||||
system_disk_e = doc.create_element('SYSTEM_DISK_SIZE')
|
||||
system_disk_used_e = doc.create_element('SYSTEM_DISK_SIZE_USED')
|
||||
@ -408,20 +414,16 @@ module OneDBFsck
|
||||
e.content = cpu_used_str
|
||||
end
|
||||
|
||||
vm_elem.xpath("#{mem}_USED").each do |e|
|
||||
next if e.text == mem_used.to_s
|
||||
resources.each do |att_name, quota_name|
|
||||
next if att_name == :CPU
|
||||
|
||||
log_error("#{resource} #{oid} quotas: #{mem}_USED has " \
|
||||
"#{e.text} \tis\t#{mem_used}")
|
||||
e.content = mem_used.to_s
|
||||
end
|
||||
vm_elem.xpath("#{quota_name}_USED").each do |e|
|
||||
next if e.text.to_i == quotas[quota_name].to_i
|
||||
|
||||
vm_elem.xpath("#{vms}_USED").each do |e|
|
||||
next if e.text == vms_used.to_s
|
||||
|
||||
log_error("#{resource} #{oid} quotas: #{vms}_USED has " \
|
||||
"#{e.text} \tis\t#{vms_used}")
|
||||
e.content = vms_used.to_s
|
||||
log_error("#{resource} #{oid} quotas: #{quota_name}_USED has " \
|
||||
"#{e.text} \tis\t#{quotas[quota_name]}")
|
||||
e.content = quotas[quota_name].to_s
|
||||
end
|
||||
end
|
||||
|
||||
vm_elem
|
||||
|
@ -483,6 +483,8 @@ class OneDB
|
||||
|
||||
time0 = Time.now
|
||||
|
||||
@backend.read_config
|
||||
|
||||
result = @backend.fsck
|
||||
|
||||
if !result
|
||||
|
@ -129,6 +129,8 @@ bool VirtualMachineAllocate::allocate_authorization(
|
||||
aux_tmpl.add("RUNNING_VMS", 1);
|
||||
aux_tmpl.add("VMS", 1);
|
||||
|
||||
QuotaVirtualMachine::add_running_quota_generic(aux_tmpl);
|
||||
|
||||
if ( quota_authorization(&aux_tmpl, Quotas::VIRTUALMACHINE, att) == false )
|
||||
{
|
||||
return false;
|
||||
@ -372,6 +374,8 @@ error_drop_vm:
|
||||
tmpl_back.add("RUNNING_VMS", 1);
|
||||
tmpl_back.add("VMS", 1);
|
||||
|
||||
QuotaVirtualMachine::add_running_quota_generic(tmpl_back);
|
||||
|
||||
quota_rollback(&tmpl_back, Quotas::VIRTUALMACHINE, att);
|
||||
|
||||
VirtualMachineDisks::extended_info(att.uid, &tmpl_back);
|
||||
|
@ -39,8 +39,6 @@ unique_ptr<PoolObjectSQL> RequestManagerChown::get_and_quota(
|
||||
int old_uid;
|
||||
int old_gid;
|
||||
|
||||
std::string memory, cpu;
|
||||
|
||||
auto object = pool->get_ro<PoolObjectSQL>(oid);
|
||||
|
||||
if ( object == nullptr )
|
||||
@ -63,23 +61,9 @@ unique_ptr<PoolObjectSQL> RequestManagerChown::get_and_quota(
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto tmpl = vm->clone_template();
|
||||
auto tmpl = std::make_unique<VirtualMachineTemplate>();
|
||||
|
||||
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) )
|
||||
{
|
||||
vm->get_template_attribute("MEMORY", memory);
|
||||
vm->get_template_attribute("CPU", cpu);
|
||||
|
||||
tmpl->add("RUNNING_MEMORY", memory);
|
||||
tmpl->add("RUNNING_CPU", cpu);
|
||||
tmpl->add("RUNNING_VMS", 1);
|
||||
}
|
||||
|
||||
tmpl->add("VMS", 1);
|
||||
vm->get_quota_template(*tmpl, true, vm->is_running_quota());
|
||||
|
||||
VirtualMachineDisks::image_ds_quotas(tmpl.get(), ds_quotas);
|
||||
|
||||
|
@ -38,15 +38,9 @@ void SystemVersion::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
void SystemConfig::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
if ( att.gid != GroupPool::ONEADMIN_ID )
|
||||
{
|
||||
att.resp_msg = "The oned configuration can only be retrieved by users "
|
||||
"in the oneadmin group";
|
||||
failure_response(AUTHORIZATION, att);
|
||||
return;
|
||||
}
|
||||
|
||||
success_response(Nebula::instance().get_configuration_xml(), att);
|
||||
//bool is_admin = att.gid == GroupPool::ONEADMIN_ID;
|
||||
//Do not send sensitive configuration data over the wire
|
||||
success_response(Nebula::instance().get_configuration_xml(false), att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -63,8 +63,6 @@ void RequestManagerUpdateTemplate::request_execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
int rc;
|
||||
|
||||
int oid = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
string tmpl = xmlrpc_c::value_string(paramList.getString(2));
|
||||
|
||||
@ -87,6 +85,18 @@ void RequestManagerUpdateTemplate::request_execute(
|
||||
return;
|
||||
}
|
||||
|
||||
request_execute(oid, tmpl, update_type, att);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManagerUpdateTemplate::request_execute(int oid,
|
||||
const std::string& tmpl,
|
||||
int update_type,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
int rc;
|
||||
|
||||
auto object = pool->get<PoolObjectSQL>(oid);
|
||||
|
||||
@ -97,13 +107,6 @@ void RequestManagerUpdateTemplate::request_execute(
|
||||
return;
|
||||
}
|
||||
|
||||
if (extra_preconditions_check(object.get(), att.resp_msg))
|
||||
{
|
||||
failure_response(ACTION, att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (update_type == 0)
|
||||
{
|
||||
rc = replace_template(object.get(), tmpl, att, att.resp_msg);
|
||||
@ -126,8 +129,129 @@ void RequestManagerUpdateTemplate::request_execute(
|
||||
extra_updates(object.get());
|
||||
|
||||
success_response(oid, att);
|
||||
}
|
||||
|
||||
return;
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachineUpdateTemplate::request_execute(int oid,
|
||||
const std::string& tmpl,
|
||||
int update_type,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
int rc;
|
||||
|
||||
auto vm = pool->get<VirtualMachine>(oid);
|
||||
|
||||
if ( vm == nullptr )
|
||||
{
|
||||
att.resp_id = oid;
|
||||
failure_response(NO_EXISTS, att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the action is supported for imported VMs
|
||||
if (vm->is_imported() && !vm->is_imported_action_supported(VMActions::UPDATE_ACTION))
|
||||
{
|
||||
att.resp_msg = "Action \"update\" is not supported for imported VMs";
|
||||
failure_response(ACTION, att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply generic quota deltas
|
||||
auto new_tmpl = make_unique<VirtualMachineTemplate>(false,'=',"USER_TEMPLATE");
|
||||
|
||||
if ( new_tmpl->parse_str_or_xml(tmpl, att.resp_msg) != 0 )
|
||||
{
|
||||
failure_response(ACTION, att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( update_type == 1 ) //append mode
|
||||
{
|
||||
auto user_tmpl = vm->clone_user_template();
|
||||
|
||||
user_tmpl->merge(new_tmpl.get());
|
||||
|
||||
new_tmpl.swap(user_tmpl);
|
||||
}
|
||||
|
||||
// Compute quota deltas (only generic quota may appear in User template)
|
||||
bool do_quotas = false;
|
||||
|
||||
for ( const string& metric : QuotaVirtualMachine::generic_metrics())
|
||||
{
|
||||
float value_new, value_old;
|
||||
|
||||
bool exists_old = vm->get_user_template_attribute(metric, value_old);
|
||||
bool exists_new = new_tmpl->get(metric, value_new);
|
||||
|
||||
if ( exists_old || exists_new )
|
||||
{
|
||||
float delta = value_new - value_old;
|
||||
|
||||
new_tmpl->replace(metric, delta);
|
||||
|
||||
do_quotas |= delta != 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (vm->is_running_quota())
|
||||
{
|
||||
QuotaVirtualMachine::add_running_quota_generic(*new_tmpl);
|
||||
}
|
||||
|
||||
RequestAttributes att_quota(att);
|
||||
|
||||
att_quota.uid = vm->get_uid();
|
||||
att_quota.gid = vm->get_gid();
|
||||
|
||||
vm.reset();
|
||||
|
||||
if ( do_quotas )
|
||||
{
|
||||
if (!quota_authorization(new_tmpl.get(), Quotas::VIRTUALMACHINE, att_quota, att.resp_msg))
|
||||
{
|
||||
failure_response(ACTION, att);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
vm = pool->get<VirtualMachine>(oid);
|
||||
|
||||
if (update_type == 0)
|
||||
{
|
||||
rc = replace_template(vm.get(), tmpl, att, att.resp_msg);
|
||||
}
|
||||
else //if (update_type == 1)
|
||||
{
|
||||
rc = append_template(vm.get(), tmpl, att, att.resp_msg);
|
||||
}
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
vm.reset();
|
||||
|
||||
if (do_quotas)
|
||||
{
|
||||
quota_rollback(new_tmpl.get(), Quotas::VIRTUALMACHINE, att_quota);
|
||||
}
|
||||
|
||||
att.resp_msg = "Cannot update template. " + att.resp_msg;
|
||||
failure_response(INTERNAL, att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
pool->update(vm.get());
|
||||
|
||||
extra_updates(vm.get());
|
||||
|
||||
success_response(oid, att);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -238,6 +238,8 @@ Request::ErrorCode VMTemplateInstantiate::request_execute(int id, const string&
|
||||
extended_tmpl.add("RUNNING_VMS", 1);
|
||||
extended_tmpl.add("VMS", 1);
|
||||
|
||||
QuotaVirtualMachine::add_running_quota_generic(extended_tmpl);
|
||||
|
||||
if (quota_authorization(&extended_tmpl, Quotas::VIRTUALMACHINE, att,
|
||||
att.resp_msg) == false)
|
||||
{
|
||||
|
@ -517,18 +517,11 @@ Request::ErrorCode VirtualMachineAction::request_execute(RequestAttributes& att,
|
||||
rc = dm->suspend(vid, att, error);
|
||||
break;
|
||||
case VMActions::RESUME_ACTION:
|
||||
// Generate quota information for resume action
|
||||
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);
|
||||
vm->get_quota_template(quota_tmpl, false, true);
|
||||
|
||||
att_aux.uid = vm->get_uid();
|
||||
att_aux.gid = vm->get_gid();
|
||||
|
||||
|
||||
if (!quota_authorization("a_tmpl, Quotas::VIRTUALMACHINE, att_aux, att.resp_msg))
|
||||
{
|
||||
return ACTION;
|
||||
@ -1876,8 +1869,6 @@ Request::ErrorCode VirtualMachineAttach::request_execute(int id,
|
||||
VirtualMachineTemplate deltas(tmpl);
|
||||
VirtualMachineDisks::extended_info(att.uid, &deltas);
|
||||
|
||||
deltas.add("VMS", 0);
|
||||
|
||||
if (quota_resize_authorization(&deltas, att_quota, vm_perms) == false)
|
||||
{
|
||||
att.resp_msg = std::move(att_quota.resp_msg);
|
||||
@ -1980,7 +1971,7 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
|
||||
float ncpu, ocpu, dcpu;
|
||||
long nmemory, omemory, dmemory;
|
||||
int nvcpu, ovcpu;
|
||||
int nvcpu, ovcpu, dvcpu;
|
||||
bool update_running_quota;
|
||||
|
||||
Template deltas;
|
||||
@ -2109,15 +2100,18 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
}
|
||||
|
||||
dcpu = ncpu - ocpu;
|
||||
dvcpu = nvcpu - ovcpu;
|
||||
dmemory = nmemory - omemory;
|
||||
|
||||
deltas.add("MEMORY", dmemory);
|
||||
deltas.add("CPU", dcpu);
|
||||
deltas.add("VCPU", dvcpu);
|
||||
|
||||
if (update_running_quota)
|
||||
{
|
||||
deltas.add("RUNNING_MEMORY", dmemory);
|
||||
deltas.add("RUNNING_CPU", dcpu);
|
||||
deltas.add("RUNNING_VCPU", dvcpu);
|
||||
}
|
||||
|
||||
if (quota_resize_authorization(&deltas, att, vm_perms) == false)
|
||||
@ -2203,7 +2197,6 @@ Request::ErrorCode VirtualMachineSnapshotCreate::request_execute(RequestAttribut
|
||||
Template quota_tmpl;
|
||||
|
||||
quota_tmpl.set(snap);
|
||||
quota_tmpl.add("VMS", 0);
|
||||
|
||||
RequestAttributes att_quota(vm_perms.uid, vm_perms.gid, att);
|
||||
|
||||
|
@ -87,6 +87,14 @@ void NebulaTemplate::set_conf_single(const std::string& attr,
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
std::string& NebulaTemplate::to_xml_hidden(std::string& str) const
|
||||
{
|
||||
return Template::to_xml(str, hidden_attributes);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
std::string& NebulaTemplate::to_str(std::string& str) const
|
||||
{
|
||||
ostringstream os;
|
||||
@ -96,6 +104,7 @@ std::string& NebulaTemplate::to_str(std::string& str) const
|
||||
string s;
|
||||
|
||||
auto hidden_it = hidden_attributes.find(it->first);
|
||||
|
||||
if (hidden_it != hidden_attributes.end())
|
||||
{
|
||||
if (it->second->type() == Attribute::SIMPLE)
|
||||
|
@ -371,6 +371,24 @@ string& Template::to_xml(string& xml) const
|
||||
return xml;
|
||||
}
|
||||
|
||||
string& Template::to_xml(string& xml, const std::map<std::string, std::set<std::string>> &hidden) const
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "<" << xml_root << ">";
|
||||
|
||||
for ( auto it = attributes.begin(); it!=attributes.end(); it++)
|
||||
{
|
||||
it->second->to_xml(oss, hidden);
|
||||
}
|
||||
|
||||
oss << "</" << xml_root << ">";
|
||||
|
||||
xml = oss.str();
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
string& Template::to_xml(string& xml, const string& extra) const
|
||||
{
|
||||
ostringstream oss;
|
||||
|
@ -178,13 +178,11 @@ bool Quota::check_quota(const string& qid,
|
||||
{
|
||||
map<string, string> values;
|
||||
|
||||
for (int i=0; i < num_metrics; i++)
|
||||
for (const string& metric : metrics)
|
||||
{
|
||||
string metrics_used = metrics[i];
|
||||
string metrics_used = metric + "_USED";
|
||||
|
||||
metrics_used += "_USED";
|
||||
|
||||
values.insert(make_pair(metrics[i], DEFAULT_STR));
|
||||
values.insert(make_pair(metric, DEFAULT_STR));
|
||||
values.insert(make_pair(metrics_used, "0"));
|
||||
}
|
||||
|
||||
@ -201,27 +199,25 @@ bool Quota::check_quota(const string& qid,
|
||||
// -------------------------------------------------------------------------
|
||||
// Check the quotas for each usage request
|
||||
// -------------------------------------------------------------------------
|
||||
for (int i=0; i < num_metrics; i++)
|
||||
for (const string& metric : metrics)
|
||||
{
|
||||
string metrics_used = metrics[i];
|
||||
string metrics_used = metric + "_USED";
|
||||
|
||||
metrics_used += "_USED";
|
||||
|
||||
auto it = usage_req.find(metrics[i]);
|
||||
auto it = usage_req.find(metric);
|
||||
|
||||
if (it == usage_req.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
q->vector_value(metrics[i], limit);
|
||||
q->vector_value(metric, limit);
|
||||
q->vector_value(metrics_used, usage);
|
||||
|
||||
if ( limit == DEFAULT )
|
||||
{
|
||||
if ( default_q != 0 )
|
||||
{
|
||||
default_q->vector_value(metrics[i], limit);
|
||||
default_q->vector_value(metric, limit);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -235,7 +231,7 @@ bool Quota::check_quota(const string& qid,
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "limit of " << limit << " reached for " << metrics[i]
|
||||
oss << "limit of " << limit << " reached for " << metric
|
||||
<< " quota in " << template_name;
|
||||
|
||||
if ( !qid.empty() )
|
||||
@ -252,13 +248,11 @@ bool Quota::check_quota(const string& qid,
|
||||
// -------------------------------------------------------------------------
|
||||
// Add resource usage to quotas
|
||||
// -------------------------------------------------------------------------
|
||||
for (int i=0; i < num_metrics; i++)
|
||||
for (const string& metric : metrics)
|
||||
{
|
||||
string metrics_used = metrics[i];
|
||||
string metrics_used = metric + "_USED";
|
||||
|
||||
metrics_used += "_USED";
|
||||
|
||||
auto it = usage_req.find(metrics[i]);
|
||||
auto it = usage_req.find(metric);
|
||||
|
||||
if (it == usage_req.end())
|
||||
{
|
||||
@ -288,13 +282,13 @@ void Quota::add_quota(const string& qid, map<string, float>& usage_req)
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=0; i < num_metrics; i++)
|
||||
for (const string& metric : metrics)
|
||||
{
|
||||
string metrics_used = metrics[i];
|
||||
string metrics_used = metric;
|
||||
|
||||
metrics_used += "_USED";
|
||||
|
||||
auto it = usage_req.find(metrics[i]);
|
||||
auto it = usage_req.find(metric);
|
||||
|
||||
if (it == usage_req.end())
|
||||
{
|
||||
@ -322,13 +316,11 @@ void Quota::del_quota(const string& qid, map<string, float>& usage_req)
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=0; i < num_metrics; i++)
|
||||
for (const string& metric : metrics)
|
||||
{
|
||||
string metrics_used = metrics[i];
|
||||
string metrics_used = metric + "_USED";
|
||||
|
||||
metrics_used += "_USED";
|
||||
|
||||
auto it = usage_req.find(metrics[i]);
|
||||
auto it = usage_req.find(metric);
|
||||
|
||||
if (it == usage_req.end())
|
||||
{
|
||||
@ -370,13 +362,11 @@ void Quota::cleanup_quota(const string& qid)
|
||||
implicit_limit = DEFAULT;
|
||||
}
|
||||
|
||||
for (int i=0; i < num_metrics; i++)
|
||||
for (const string& metric : metrics)
|
||||
{
|
||||
string metrics_used = metrics[i];
|
||||
string metrics_used = metric + "_USED";
|
||||
|
||||
metrics_used += "_USED";
|
||||
|
||||
q->vector_value(metrics[i], limit);
|
||||
q->vector_value(metric, limit);
|
||||
q->vector_value(metrics_used, usage);
|
||||
|
||||
if ( usage != 0 || limit != implicit_limit )
|
||||
@ -399,9 +389,9 @@ int Quota::update_limits(
|
||||
{
|
||||
float limit_f;
|
||||
|
||||
for (int i=0; i < num_metrics; i++)
|
||||
for (const string& metric : metrics)
|
||||
{
|
||||
const string& limit = va->vector_value_str(metrics[i], limit_f);
|
||||
const string& limit = va->vector_value_str(metric, limit_f);
|
||||
|
||||
if (limit.empty())
|
||||
{
|
||||
@ -425,7 +415,7 @@ int Quota::update_limits(
|
||||
return -1;
|
||||
}
|
||||
|
||||
quota->replace(metrics[i], one_util::float_to_str(limit_f));
|
||||
quota->replace(metric, one_util::float_to_str(limit_f));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -440,13 +430,11 @@ VectorAttribute * Quota::new_quota(const VectorAttribute * va)
|
||||
|
||||
float limit_f;
|
||||
|
||||
for (int i=0; i < num_metrics; i++)
|
||||
for (const string& metric : metrics)
|
||||
{
|
||||
string metrics_used = metrics[i];
|
||||
string metrics_used = metric + "_USED";
|
||||
|
||||
metrics_used += "_USED";
|
||||
|
||||
const string& limit = va->vector_value_str(metrics[i], limit_f);
|
||||
const string& limit = va->vector_value_str(metric, limit_f);
|
||||
|
||||
if (limit.empty())
|
||||
{
|
||||
@ -469,7 +457,7 @@ VectorAttribute * Quota::new_quota(const VectorAttribute * va)
|
||||
return 0;
|
||||
}
|
||||
|
||||
limits.insert(make_pair(metrics[i], one_util::float_to_str(limit_f)));
|
||||
limits.insert(make_pair(metric, one_util::float_to_str(limit_f)));
|
||||
limits.insert(make_pair(metrics_used, "0"));
|
||||
}
|
||||
|
||||
|
@ -22,9 +22,7 @@ using namespace std;
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
const char * QuotaDatastore::DS_METRICS[] = {"SIZE", "IMAGES"};
|
||||
|
||||
const int QuotaDatastore::NUM_DS_METRICS = 2;
|
||||
const std::vector<std::string> QuotaDatastore::DS_METRICS = {"SIZE", "IMAGES"};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -22,9 +22,7 @@ using namespace std;
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
const char * QuotaImage::IMAGE_METRICS[] = {"RVMS"};
|
||||
|
||||
const int QuotaImage::NUM_IMAGE_METRICS = 1;
|
||||
const std::vector<std::string> QuotaImage::IMAGE_METRICS = {"RVMS"};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -23,9 +23,7 @@ using namespace std;
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
const char * QuotaNetwork::NET_METRICS[] = {"LEASES"};
|
||||
|
||||
const int QuotaNetwork::NUM_NET_METRICS = 1;
|
||||
const std::vector<std::string> QuotaNetwork::NET_METRICS = {"LEASES"};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -24,10 +24,10 @@ using namespace std;
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
const char * QuotaVirtualMachine::VM_METRICS[] = {"VMS", "RUNNING_VMS", "CPU",
|
||||
std::vector<std::string> QuotaVirtualMachine::VM_METRICS = {"VMS", "RUNNING_VMS", "CPU",
|
||||
"RUNNING_CPU", "MEMORY", "RUNNING_MEMORY", "SYSTEM_DISK_SIZE"};
|
||||
|
||||
const int QuotaVirtualMachine::NUM_VM_METRICS = 7;
|
||||
std::vector<std::string> QuotaVirtualMachine::VM_GENERIC;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -101,6 +101,20 @@ bool QuotaVirtualMachine::check(Template * tmpl,
|
||||
vm_request.insert(make_pair("RUNNING_VMS", running_vms));
|
||||
}
|
||||
|
||||
for (const auto& metric : VM_GENERIC)
|
||||
{
|
||||
float generic_quota;
|
||||
if ( tmpl->get(metric, generic_quota) )
|
||||
{
|
||||
vm_request.insert(make_pair(metric, generic_quota));
|
||||
}
|
||||
|
||||
if ( tmpl->get("RUNNING_" + metric, generic_quota) )
|
||||
{
|
||||
vm_request.insert(make_pair("RUNNING_" + metric, generic_quota));
|
||||
}
|
||||
}
|
||||
|
||||
return check_quota("", vm_request, default_quotas, error);
|
||||
}
|
||||
|
||||
@ -149,6 +163,20 @@ void QuotaVirtualMachine::add(Template * tmpl)
|
||||
|
||||
vm_request.insert(make_pair("SYSTEM_DISK_SIZE", size));
|
||||
|
||||
for (const auto& metric : VM_GENERIC)
|
||||
{
|
||||
float generic_quota;
|
||||
if ( tmpl->get(metric, generic_quota) )
|
||||
{
|
||||
vm_request.insert(make_pair(metric, generic_quota));
|
||||
}
|
||||
|
||||
if ( tmpl->get("RUNNING_" + metric, generic_quota) )
|
||||
{
|
||||
vm_request.insert(make_pair("RUNNING_" + metric, generic_quota));
|
||||
}
|
||||
}
|
||||
|
||||
add_quota("", vm_request);
|
||||
}
|
||||
|
||||
@ -199,12 +227,58 @@ void QuotaVirtualMachine::del(Template * tmpl)
|
||||
|
||||
vm_request.insert(make_pair("SYSTEM_DISK_SIZE", size));
|
||||
|
||||
for (const auto& metric : VM_GENERIC)
|
||||
{
|
||||
float generic_quota;
|
||||
if ( tmpl->get(metric, generic_quota) )
|
||||
{
|
||||
vm_request.insert(make_pair(metric, generic_quota));
|
||||
}
|
||||
|
||||
if ( tmpl->get("RUNNING_" + metric, generic_quota) )
|
||||
{
|
||||
vm_request.insert(make_pair("RUNNING_" + metric, generic_quota));
|
||||
}
|
||||
}
|
||||
|
||||
del_quota("", vm_request);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int QuotaVirtualMachine::add_metric_generic(const std::string& metric)
|
||||
{
|
||||
if (std::find(VM_METRICS.begin(), VM_METRICS.end(), metric) != VM_METRICS.end())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
VM_METRICS.push_back(metric);
|
||||
VM_METRICS.push_back("RUNNING_" + metric);
|
||||
VM_GENERIC.push_back(metric);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void QuotaVirtualMachine::add_running_quota_generic(Template& tmpl)
|
||||
{
|
||||
for (const string& metric : VM_GENERIC)
|
||||
{
|
||||
string value;
|
||||
if (tmpl.get(metric, value))
|
||||
{
|
||||
tmpl.add("RUNNING_" + metric, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int QuotaVirtualMachine::get_default_quota(
|
||||
const string& id,
|
||||
Quotas& default_quotas,
|
||||
@ -261,5 +335,19 @@ bool QuotaVirtualMachine::update(Template * tmpl,
|
||||
vm_request.insert(make_pair("SYSTEM_DISK_SIZE", delta_size));
|
||||
}
|
||||
|
||||
for (const auto& metric : VM_GENERIC)
|
||||
{
|
||||
float generic_quota;
|
||||
if ( tmpl->get(metric, generic_quota) )
|
||||
{
|
||||
vm_request.insert(make_pair(metric, generic_quota));
|
||||
}
|
||||
|
||||
if ( tmpl->get("RUNNING_" + metric, generic_quota) )
|
||||
{
|
||||
vm_request.insert(make_pair("RUNNING_" + metric, generic_quota));
|
||||
}
|
||||
}
|
||||
|
||||
return check_quota("", vm_request, default_quotas, error);
|
||||
}
|
||||
|
@ -3950,28 +3950,56 @@ void VirtualMachine::decrypt()
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void VirtualMachine::get_quota_template(VirtualMachineTemplate& quota_tmpl,
|
||||
bool only_running)
|
||||
bool VirtualMachine::is_running_quota() const
|
||||
{
|
||||
if ((state == VirtualMachine::PENDING) ||
|
||||
(state == VirtualMachine::CLONING) ||
|
||||
(state == VirtualMachine::CLONING_FAILURE) ||
|
||||
(state == VirtualMachine::HOLD) ||
|
||||
((state == VirtualMachine::ACTIVE &&
|
||||
(lcm_state != VirtualMachine::HOTPLUG_SAVEAS_POWEROFF &&
|
||||
lcm_state != VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED &&
|
||||
lcm_state != VirtualMachine::DISK_SNAPSHOT_POWEROFF &&
|
||||
lcm_state != VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF &&
|
||||
lcm_state != VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF &&
|
||||
lcm_state != VirtualMachine::DISK_SNAPSHOT_SUSPENDED &&
|
||||
lcm_state != VirtualMachine::DISK_SNAPSHOT_DELETE_SUSPENDED &&
|
||||
lcm_state != VirtualMachine::DISK_RESIZE_POWEROFF &&
|
||||
lcm_state != VirtualMachine::DISK_RESIZE_UNDEPLOYED &&
|
||||
lcm_state != VirtualMachine::HOTPLUG_NIC_POWEROFF &&
|
||||
lcm_state != VirtualMachine::HOTPLUG_SAVEAS_UNDEPLOYED &&
|
||||
lcm_state != VirtualMachine::HOTPLUG_SAVEAS_STOPPED ))))
|
||||
return (state == VirtualMachine::PENDING) ||
|
||||
(state == VirtualMachine::CLONING) ||
|
||||
(state == VirtualMachine::CLONING_FAILURE) ||
|
||||
(state == VirtualMachine::HOLD) ||
|
||||
((state == VirtualMachine::ACTIVE &&
|
||||
(lcm_state != VirtualMachine::HOTPLUG_SAVEAS_POWEROFF &&
|
||||
lcm_state != VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED &&
|
||||
lcm_state != VirtualMachine::DISK_SNAPSHOT_POWEROFF &&
|
||||
lcm_state != VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF &&
|
||||
lcm_state != VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF &&
|
||||
lcm_state != VirtualMachine::DISK_SNAPSHOT_SUSPENDED &&
|
||||
lcm_state != VirtualMachine::DISK_SNAPSHOT_DELETE_SUSPENDED &&
|
||||
lcm_state != VirtualMachine::DISK_RESIZE_POWEROFF &&
|
||||
lcm_state != VirtualMachine::DISK_RESIZE_UNDEPLOYED &&
|
||||
lcm_state != VirtualMachine::HOTPLUG_NIC_POWEROFF &&
|
||||
lcm_state != VirtualMachine::HOTPLUG_SAVEAS_UNDEPLOYED &&
|
||||
lcm_state != VirtualMachine::HOTPLUG_SAVEAS_STOPPED &&
|
||||
lcm_state != VirtualMachine::HOTPLUG_PROLOG_POWEROFF &&
|
||||
lcm_state != VirtualMachine::HOTPLUG_EPILOG_POWEROFF )));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void VirtualMachine::get_quota_template(VirtualMachineTemplate& quota_tmpl,
|
||||
bool basic_quota, bool running_quota)
|
||||
{
|
||||
if (basic_quota)
|
||||
{
|
||||
std::string memory, cpu;
|
||||
quota_tmpl.replace("VMS", 1);
|
||||
|
||||
for (const string& metric : QuotaVirtualMachine::generic_metrics())
|
||||
{
|
||||
string value;
|
||||
|
||||
// Use value from user template, if it's not already added from template
|
||||
if (user_obj_template->get(metric, value))
|
||||
{
|
||||
quota_tmpl.replace(metric, value);
|
||||
}
|
||||
}
|
||||
|
||||
quota_tmpl.merge(obj_template.get());
|
||||
}
|
||||
|
||||
if (running_quota)
|
||||
{
|
||||
string memory, cpu;
|
||||
|
||||
get_template_attribute("MEMORY", memory);
|
||||
get_template_attribute("CPU", cpu);
|
||||
@ -3980,11 +4008,17 @@ void VirtualMachine::get_quota_template(VirtualMachineTemplate& quota_tmpl,
|
||||
quota_tmpl.add("RUNNING_CPU", cpu);
|
||||
quota_tmpl.add("RUNNING_VMS", 1);
|
||||
|
||||
if (!only_running)
|
||||
for (const string& metric : QuotaVirtualMachine::generic_metrics())
|
||||
{
|
||||
quota_tmpl.add("MEMORY", memory);
|
||||
quota_tmpl.add("CPU", cpu);
|
||||
quota_tmpl.add("VMS", 1);
|
||||
string value;
|
||||
if (obj_template->get(metric, value))
|
||||
{
|
||||
quota_tmpl.add("RUNNING_" + metric, value);
|
||||
}
|
||||
else if (user_obj_template->get(metric, value))
|
||||
{
|
||||
quota_tmpl.add("RUNNING_" + metric, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -476,7 +476,6 @@ void VirtualMachineDisk::resize_quotas(long long new_size, Template& ds_deltas,
|
||||
delta_disk->replace("TYPE", "FS");
|
||||
delta_disk->replace("SIZE", delta_size);
|
||||
|
||||
vm_deltas.add("VMS", 0);
|
||||
vm_deltas.set(delta_disk);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user