1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-02-02 09:47:00 +03:00

Merge branch 'feature-1611'

This commit is contained in:
Ruben S. Montero 2012-11-30 03:04:59 +01:00
commit f726a65309
34 changed files with 1951 additions and 388 deletions

81
include/DefaultQuotas.h Normal file
View File

@ -0,0 +1,81 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* 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. */
/* -------------------------------------------------------------------------- */
#ifndef DEFAULT_QUOTAS_H_
#define DEFAULT_QUOTAS_H_
#include "Quotas.h"
#include "SqlDB.h"
#include "ObjectSQL.h"
class DefaultQuotas : public Quotas
{
public:
DefaultQuotas(
const char * _root_elem,
const char * _ds_xpath,
const char * _net_xpath,
const char * _img_xpath,
const char * _vm_xpath):
Quotas(_ds_xpath, _net_xpath, _img_xpath, _vm_xpath, true),
root_elem(_root_elem)
{};
~DefaultQuotas(){};
/**
* Generates a string representation of the quotas in XML format
* @param xml the string to store the XML
* @return the same xml string to use it in << compounds
*/
string& to_xml(string& xml) const;
/**
* Writes the quotas in the database.
* @param db pointer to the db
* @return 0 on success
*/
int insert();
/**
* Writes/updates the quotas data fields in the database.
* @param db pointer to the db
* @return 0 on success
*/
int update();
/**
* Reads the Quotas from the database.
* @param db pointer to the db
* @return 0 on success
*/
int select();
private:
/**
* Name for the default quota attribute
*/
const char * root_elem;
/**
* Builds quota object from an ObjectXML
* @param xml The xml-formatted string
* @return 0 on success
*/
int from_xml(const string& xml);
};
#endif /*DEFAULT_QUOTAS_H_*/

View File

@ -18,6 +18,7 @@
#define NEBULA_H_
#include "SqlDB.h"
#include "SystemDB.h"
#include "NebulaTemplate.h"
@ -42,9 +43,17 @@
#include "AclManager.h"
#include "ImageManager.h"
#include "DefaultQuotas.h"
#include "Callbackable.h"
class Nebula : public Callbackable
/**
* This is the main class for the OpenNebula daemon oned. It stores references
* to the main modules and data pools. It also includes functions to bootstrap
* the system and start all its components.
*/
class Nebula
{
public:
@ -311,15 +320,103 @@ public:
return nebula_configuration->to_xml(xml);
};
const DefaultQuotas& get_default_user_quota()
{
return default_user_quota;
};
int set_default_user_quota(Template *tmpl, string& error)
{
int rc;
rc = default_user_quota.set(tmpl, error);
if ( rc == 0 )
{
rc = default_user_quota.update();
}
return rc;
};
const DefaultQuotas& get_default_group_quota()
{
return default_group_quota;
};
int set_default_group_quota(Template *tmpl, string& error)
{
int rc;
rc = default_group_quota.set(tmpl, error);
if ( rc == 0 )
{
rc = default_group_quota.update();
}
return rc;
};
// -----------------------------------------------------------------------
// System attributes
// -----------------------------------------------------------------------
/**
* Reads a System attribute from the DB
* @param attr_name name of the attribute
* @param cb Callback that will receive the attribute in XML
* @return 0 on success
*/
int select_sys_attribute(const string& attr_name, string& attr_xml)
{
return system_db->select_sys_attribute(attr_name, attr_xml);
};
/**
* Writes a system attribute in the database.
* @param db pointer to the db
* @return 0 on success
*/
int insert_sys_attribute(
const string& attr_name,
const string& xml_attr,
string& error_str)
{
return system_db->insert_sys_attribute(attr_name, xml_attr, error_str);
};
/**
* Updates the system attribute in the database.
* @param db pointer to the db
* @return 0 on success
*/
int update_sys_attribute(
const string& attr_name,
const string& xml_attr,
string& error_str)
{
return system_db->update_sys_attribute(attr_name, xml_attr, error_str);
};
private:
// -----------------------------------------------------------------------
//Constructors and = are private to only access the class through instance
// -----------------------------------------------------------------------
Nebula():nebula_configuration(0),db(0),vmpool(0),hpool(0),vnpool(0),
upool(0),ipool(0),gpool(0),tpool(0),dspool(0),clpool(0),docpool(0),
lcm(0),vmm(0),im(0),tm(0),dm(0),rm(0),hm(0),authm(0),aclm(0),imagem(0)
Nebula():nebula_configuration(0),
default_user_quota( "DEFAULT_USER_QUOTAS",
"/DEFAULT_USER_QUOTAS/DATASTORE_QUOTA",
"/DEFAULT_USER_QUOTAS/NETWORK_QUOTA",
"/DEFAULT_USER_QUOTAS/IMAGE_QUOTA",
"/DEFAULT_USER_QUOTAS/VM_QUOTA"),
default_group_quota("DEFAULT_GROUP_QUOTAS",
"/DEFAULT_GROUP_QUOTAS/DATASTORE_QUOTA",
"/DEFAULT_GROUP_QUOTAS/NETWORK_QUOTA",
"/DEFAULT_GROUP_QUOTAS/IMAGE_QUOTA",
"/DEFAULT_GROUP_QUOTAS/VM_QUOTA"),
system_db(0), db(0), vmpool(0), hpool(0), vnpool(0),
upool(0), ipool(0), gpool(0), tpool(0), dspool(0), clpool(0),
docpool(0), lcm(0), vmm(0), im(0), tm(0), dm(0), rm(0), hm(0), authm(0),
aclm(0), imagem(0)
{
const char * nl = getenv("ONE_LOCATION");
@ -465,9 +562,12 @@ private:
{
delete db;
}
};
Nebula(Nebula const&){};
if ( system_db != 0 )
{
delete system_db;
}
};
Nebula& operator=(Nebula const&){return *this;};
@ -492,7 +592,20 @@ private:
// Configuration
// ---------------------------------------------------------------
OpenNebulaTemplate * nebula_configuration;
OpenNebulaTemplate * nebula_configuration;
// ---------------------------------------------------------------
// Default quotas
// ---------------------------------------------------------------
DefaultQuotas default_user_quota;
DefaultQuotas default_group_quota;
// ---------------------------------------------------------------
// The system database
// ---------------------------------------------------------------
SystemDB * system_db;
// ---------------------------------------------------------------
// Nebula Pools
@ -530,34 +643,6 @@ private:
// ---------------------------------------------------------------
friend void nebula_signal_handler (int sig);
/**
* Bootstraps the database control tables
*
* @return 0 on success
*/
int bootstrap();
/**
* Callback function for the check_db_version method. Stores the read
* version in loaded_db_version
* @param _loaded_db_version returned columns
* @param num the number of columns read from the DB
* @param names the column names
* @param vaues the column values
* @return 0 on success
*/
int select_cb(void *_loaded_db_version, int num, char **values,
char **names);
/**
* Reads the current DB version.
*
* @return 0 on success,
* -1 if there is a version mismatch,
* -2 if the DB needs a bootstrap
*/
int check_db_version();
};
#endif /*NEBULA_H_*/

View File

@ -19,32 +19,37 @@
#include "Template.h"
// Forward declaration to avoid include cycle
class Quotas;
/**
* Base class for resource quotas, it provides basic storage and management of
* the quotas. Each resource MUST inherit from it to implement check and
* the quotas. Each resource MUST inherit from it to implement check and
* update methods. Quotas are stored in a template form, each class store the
* limits and usage in a resource specific format.
*/
class Quota: public Template
{
public:
/**
* Set the quotas. If the quota previously exists its limit is updated.
* @param quota_str the quota template in ASCII or XML formats
* @param error describe the error in case of error
*
* @return 0 on success -1 otherwise
*/
int set(vector<Attribute*> * quotas, string& error);
/**
* Check if the resource allocation will exceed the quota limits. If not
* Check if the resource allocation will exceed the quota limits. If not
* the usage counters are updated
* @param tmpl template for the resource
* @param error string
* @param default_quotas Quotas that contain the default limits
* @param error string
* @return true if the operation can be performed
*/
virtual bool check(Template* tmpl, string& error) = 0;
virtual bool check(Template* tmpl, Quotas& default_quotas, string& error) = 0;
/**
* Decrement usage counters when deallocating image
@ -61,22 +66,35 @@ public:
return template_name;
}
/**
* Gets a quota identified by its ID.
* @param id of the quota
* @param va The quota, if it is found
* @return 0 on success, -1 if not found
*/
virtual int get_quota(const string& id, VectorAttribute **va)
{
map<string, Attribute *>::iterator it;
return get_quota(id, va, it);
}
protected:
Quota(const char * quota_name,
const char * _template_name,
const char ** _metrics,
int _num_metrics)
int _num_metrics,
bool _is_default)
: Template(false, '=', quota_name),
template_name(_template_name),
metrics(_metrics),
num_metrics(_num_metrics){};
num_metrics(_num_metrics),
is_default(_is_default){};
virtual ~Quota(){};
/**
* Generic Quota Names
* Generic Quota Names
*
* template_name = [
* ID = "ID to identify the resource",
@ -102,15 +120,24 @@ protected:
*/
int num_metrics;
/**
* Check a given quota for an usage request and update counters if the
/**
* Whether or not this is a default quota. Default quotas do not have usage,
* and can't have a limit of -1
*/
bool is_default;
/**
* Check a given quota for an usage request and update counters if the
* request does not exceed quota limits
* @param qid id that identifies the quota, to be used by get_quota
* @param usage_req usage for each metric
* @param default_quotas Quotas that contain the default limits
* @param error string describing the error
* @return true if the request does not exceed current limits
*/
bool check_quota(const string& qid,
bool check_quota(const string& qid,
map<string, float>& usage_req,
Quotas& default_quotas,
string& error);
/**
@ -118,20 +145,21 @@ protected:
* @param qid id that identifies the quota, to be used by get_quota
* @param usage_req usage for each metric
*/
void del_quota(const string& qid,
void del_quota(const string& qid,
map<string, float>& usage_req);
/**
* Gets a quota identified by its ID.
* Gets the default quota identified by its ID.
*
* @param id of the quota
* @param default_quotas Quotas that contain the default limits
* @param va The quota, if it is found
*
* @return 0 on success, -1 if not found
*/
virtual int get_quota(const string& id, VectorAttribute **va)
{
map<string, Attribute *>::iterator it;
return get_quota(id, va, it);
}
virtual int get_default_quota(const string& id,
Quotas& default_quotas,
VectorAttribute **va) = 0;
/**
* Gets a quota identified by its ID.
@ -159,7 +187,8 @@ private:
* Creates an empty quota based on the given attribute. The attribute va
* contains the limits for the quota.
* @param va limits for the new quota if 0 limits will be 0
* @return a new attribute representing the quota
*
* @return a new attribute representing the quota, 0 on error
*/
VectorAttribute * new_quota(VectorAttribute* va);
@ -181,13 +210,15 @@ private:
*/
void add_to_quota(VectorAttribute * attr, const string& va_name, float num);
/**
/**
* Sets new limit values for the quota
* @param quota to be updated
* @param va attribute with the new limits
*
* @return 0 on success or -1 if wrong limits
*/
int update_limits(VectorAttribute* quota, const VectorAttribute* va);
int update_limits(VectorAttribute* quota,
const VectorAttribute* va);
/**
* Extract the limits for the defined quota metrics from a given attribute

View File

@ -35,23 +35,26 @@
class QuotaDatastore : public Quota
{
public:
QuotaDatastore():Quota("DATASTORE_QUOTA",
"DATASTORE",
DS_METRICS,
NUM_DS_METRICS)
QuotaDatastore(bool is_default):
Quota("DATASTORE_QUOTA",
"DATASTORE",
DS_METRICS,
NUM_DS_METRICS,
is_default)
{};
~QuotaDatastore(){};
/**
* Check if the resource allocation will exceed the quota limits. If not
* Check if the resource allocation will exceed the quota limits. If not
* the usage counters are updated
* @param tmpl template for the resource
* @param error string
* @param default_quotas Quotas that contain the default limits
* @param error string
* @return true if the operation can be performed
*/
bool check(Template* tmpl, string& error);
bool check(Template* tmpl, Quotas& default_quotas, string& error);
/**
* Decrement usage counters when deallocating image
@ -60,9 +63,23 @@ public:
void del(Template* tmpl);
protected:
/**
* Gets the default quota identified by its ID.
*
* @param id of the quota
* @param default_quotas Quotas that contain the default limits
* @param va The quota, if it is found
*
* @return 0 on success, -1 if not found
*/
int get_default_quota(const string& id,
Quotas& default_quotas,
VectorAttribute **va);
static const char * DS_METRICS[];
static const int NUM_DS_METRICS;
};
#endif /*QUOTA_DATASTORE_H_*/
#endif /*QUOTA_DATASTORE_H_*/

View File

@ -33,23 +33,26 @@
class QuotaImage : public Quota
{
public:
QuotaImage():Quota("IMAGE_QUOTA",
"IMAGE",
IMAGE_METRICS,
NUM_IMAGE_METRICS)
QuotaImage(bool is_default):
Quota("IMAGE_QUOTA",
"IMAGE",
IMAGE_METRICS,
NUM_IMAGE_METRICS,
is_default)
{};
~QuotaImage(){};
/**
* Check if the resource allocation will exceed the quota limits. If not
* Check if the resource allocation will exceed the quota limits. If not
* the usage counters are updated
* @param tmpl template for the resource
* @param error string
* @param default_quotas Quotas that contain the default limits
* @param error string
* @return true if the operation can be performed
*/
bool check(Template* tmpl, string& error);
bool check(Template* tmpl, Quotas& default_quotas, string& error);
/**
* Decrement usage counters when deallocating image
@ -58,6 +61,20 @@ public:
void del(Template* tmpl);
protected:
/**
* Gets the default quota identified by its ID.
*
* @param id of the quota
* @param default_quotas Quotas that contain the default limits
* @param va The quota, if it is found
*
* @return 0 on success, -1 if not found
*/
int get_default_quota(const string& id,
Quotas& default_quotas,
VectorAttribute **va);
static const char * IMAGE_METRICS[];
static const int NUM_IMAGE_METRICS;

View File

@ -33,23 +33,26 @@
class QuotaNetwork : public Quota
{
public:
QuotaNetwork():Quota("NETWORK_QUOTA",
"NETWORK",
NET_METRICS,
NUM_NET_METRICS)
QuotaNetwork(bool is_default):
Quota("NETWORK_QUOTA",
"NETWORK",
NET_METRICS,
NUM_NET_METRICS,
is_default)
{};
~QuotaNetwork(){};
/**
* Check if the resource allocation will exceed the quota limits. If not
* Check if the resource allocation will exceed the quota limits. If not
* the usage counters are updated
* @param tmpl template for the resource
* @param error string
* @param default_quotas Quotas that contain the default limits
* @param error string
* @return true if the operation can be performed
*/
bool check(Template* tmpl, string& error);
bool check(Template* tmpl, Quotas& default_quotas, string& error);
/**
* Decrement usage counters when deallocating image
@ -58,6 +61,20 @@ public:
void del(Template* tmpl);
protected:
/**
* Gets the default quota identified by its ID.
*
* @param id of the quota
* @param default_quotas Quotas that contain the default limits
* @param va The quota, if it is found
*
* @return 0 on success, -1 if not found
*/
int get_default_quota(const string& id,
Quotas& default_quotas,
VectorAttribute **va);
static const char * NET_METRICS[];
static const int NUM_NET_METRICS;

View File

@ -36,23 +36,26 @@
class QuotaVirtualMachine : public Quota
{
public:
QuotaVirtualMachine():Quota("VM_QUOTA",
"VM",
VM_METRICS,
NUM_VM_METRICS)
QuotaVirtualMachine(bool is_default):
Quota("VM_QUOTA",
"VM",
VM_METRICS,
NUM_VM_METRICS,
is_default)
{};
~QuotaVirtualMachine(){};
/**
* Check if the resource allocation will exceed the quota limits. If not
* Check if the resource allocation will exceed the quota limits. If not
* the usage counters are updated
* @param tmpl template for the resource
* @param error string
* @param default_quotas Quotas that contain the default limits
* @param error string
* @return true if the operation can be performed
*/
bool check(Template* tmpl, string& error);
bool check(Template* tmpl, Quotas& default_quotas, string& error);
/**
* Decrement usage counters when deallocating image
@ -60,7 +63,6 @@ public:
*/
void del(Template* tmpl);
protected:
/**
* Gets a quota, overrides base to not to use ID.
* @param id of the quota, ignored
@ -70,6 +72,8 @@ protected:
*/
int get_quota(const string& id, VectorAttribute **va);
protected:
/**
* Gets a quota, overrides base to not to use ID.
*
@ -88,6 +92,20 @@ protected:
return get_quota(id, va);
}
/**
* Gets the default quota identified by its ID.
*
* @param id of the quota
* @param default_quotas Quotas that contain the default limits
* @param va The quota, if it is found
*
* @return 0 on success, -1 if not found
*/
int get_default_quota(
const string& id,
Quotas& default_quotas,
VectorAttribute **va);
static const char * VM_METRICS[];
static const int NUM_VM_METRICS;

View File

@ -30,7 +30,11 @@ public:
Quotas(const char * _ds_xpath,
const char * _net_xpath,
const char * _img_xpath,
const char * _vm_xpath):
const char * _vm_xpath):
datastore_quota(false),
network_quota(false),
image_quota(false),
vm_quota(false),
ds_xpath(_ds_xpath),
net_xpath(_net_xpath),
img_xpath(_img_xpath),
@ -59,18 +63,6 @@ public:
*/
int set(Template *tmpl, string& error);
/**
* Check Datastore quotas, it updates usage counters if quotas are not
* exceeded.
* @param tmpl template for the image
* @param reason string describing the error
* @return true if image can be allocated, false otherwise
*/
bool ds_check(Template * tmpl, string& reason)
{
return datastore_quota.check(tmpl, reason);
}
/**
* Delete usage from quota counters.
* @param tmpl template for the image, with usage
@ -80,16 +72,17 @@ public:
datastore_quota.del(tmpl);
}
/**
* Check Virtual Machine quotas (network, image and compute), it updates
* usage counters if quotas are not exceeded.
* @param tmpl template for the VirtualMachine
* @param error_str string describing the error
* @return true if VM can be allocated, false otherwise
*/
bool vm_check(Template * tmpl, string& error_str)
/**
* Gets a Datastore quota identified by its ID.
*
* @param id of the quota
* @param va The quota, if it is found
*
* @return 0 on success, -1 if not found
*/
int ds_get(const string& id, VectorAttribute **va)
{
return quota_check(VIRTUALMACHINE, tmpl, error_str);
return datastore_quota.get_quota(id, va);
}
/**
@ -103,14 +96,57 @@ public:
image_quota.del(tmpl);
}
/**
* Gets a VM quota identified by its ID.
*
* @param id of the quota
* @param va The quota, if it is found
*
* @return 0 on success, -1 if not found
*/
int vm_get(const string& id, VectorAttribute **va)
{
return vm_quota.get_quota(id, va);
}
/**
* Gets a Network quota identified by its ID.
*
* @param id of the quota
* @param va The quota, if it is found
*
* @return 0 on success, -1 if not found
*/
int network_get(const string& id, VectorAttribute **va)
{
return network_quota.get_quota(id, va);
}
/**
* Gets an Image quota identified by its ID.
*
* @param id of the quota
* @param va The quota, if it is found
*
* @return 0 on success, -1 if not found
*/
int image_get(const string& id, VectorAttribute **va)
{
return image_quota.get_quota(id, va);
}
/**
* Check quota, it updates usage counters if quotas are not exceeded.
* @param type the quota to work with
* @param tmpl template for the VirtualMachine
* @param default_quotas Quotas that contain the default limits
* @param error_str string describing the error
* @return true if VM can be allocated, false otherwise
*/
bool quota_check(QuotaType type, Template *tmpl, string& error_str);
bool quota_check(QuotaType type,
Template *tmpl,
Quotas& default_quotas,
string& error_str);
/**
* Delete usage from the given quota counters.
@ -128,7 +164,7 @@ public:
/**
* Builds quota object from an ObjectXML
* @param object_xml pointer to the ObjectXML
* @param object_xml pointer to the ObjectXML
* @return 0 if success
*/
int from_xml(ObjectXML * object_xml);
@ -167,29 +203,49 @@ public:
*/
static void quota_del(QuotaType type, int uid, int gid, Template * tmpl);
protected:
/**
* This is an specialized constructor only for derived Quotas classes.
* It allows to set the defaultness attribute
*/
Quotas(const char * _ds_xpath,
const char * _net_xpath,
const char * _img_xpath,
const char * _vm_xpath,
bool is_deafult):
datastore_quota(is_deafult),
network_quota(is_deafult),
image_quota(is_deafult),
vm_quota(is_deafult),
ds_xpath(_ds_xpath),
net_xpath(_net_xpath),
img_xpath(_img_xpath),
vm_xpath(_vm_xpath)
{};
private:
//--------------------------------------------------------------------------
// Usage Counters and Quotas
// Usage Counters and Quotas
//--------------------------------------------------------------------------
/**
* Datastore Quotas
*/
* Datastore Quotas
*/
QuotaDatastore datastore_quota;
/**
* Network Quotas
* Network Quotas
*/
QuotaNetwork network_quota;
/**
* Image Quotas
*/
* Image Quotas
*/
QuotaImage image_quota;
/**
* Virtual Machine Quotas
*/
* Virtual Machine Quotas
*/
QuotaVirtualMachine vm_quota;
//--------------------------------------------------------------------------

View File

@ -18,6 +18,7 @@
#define REQUEST_MANAGER_SYSTEM_H
#include "Request.h"
#include "DefaultQuotas.h"
using namespace std;
@ -78,6 +79,107 @@ public:
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class UserQuotaInfo : public RequestManagerSystem
{
public:
UserQuotaInfo():
RequestManagerSystem("UserQuotaInfo",
"Returns the default user quota limits",
"A:s")
{
auth_op = AuthRequest::ADMIN;
};
~UserQuotaInfo(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class GroupQuotaInfo : public RequestManagerSystem
{
public:
GroupQuotaInfo():
RequestManagerSystem("GroupQuotaInfo",
"Returns the default group quota limits",
"A:s")
{
auth_op = AuthRequest::ADMIN;
};
~GroupQuotaInfo(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class QuotaUpdate : public RequestManagerSystem
{
public:
QuotaUpdate(const string& method_name,
const string& help):
RequestManagerSystem(method_name,
help,
"A:ss")
{
auth_op = AuthRequest::ADMIN;
};
~QuotaUpdate(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
virtual int set_default_quota(Template *tmpl, string& error) = 0;
const virtual DefaultQuotas* get_default_quota() = 0;
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class UserQuotaUpdate : public QuotaUpdate
{
public:
UserQuotaUpdate():
QuotaUpdate("UserQuotaUpdate",
"Updates the default user quota limits")
{
auth_op = AuthRequest::ADMIN;
};
int set_default_quota(Template *tmpl, string& error);
const DefaultQuotas* get_default_quota();
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class GroupQuotaUpdate : public QuotaUpdate
{
public:
GroupQuotaUpdate():
QuotaUpdate("GroupQuotaUpdate",
"Updates the default group quota limits")
{
auth_op = AuthRequest::ADMIN;
};
int set_default_quota(Template *tmpl, string& error);
const DefaultQuotas* get_default_quota();
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

147
include/SystemDB.h Normal file
View File

@ -0,0 +1,147 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* 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. */
/* -------------------------------------------------------------------------- */
#ifndef SYSTEM_DB_H_
#define SYSTEM_DB_H_
#include "SqlDB.h"
#include "Callbackable.h"
class Nebula;
/**
* This class represents the OpenNebula core system data tables:
* - pool_control
* - db_versioning
* - system attributes
*/
class SystemDB: public Callbackable
{
public:
/**
* Reads a System attribute from the DB
* @param attr_name name of the attribute
* @param attr_xml the attribute in a XML document
* @return 0 on success
*/
int select_sys_attribute(const string& attr_name, string& attr_zml);
/**
* Writes a system attribute in the database.
* @param db pointer to the db
* @return 0 on success
*/
int insert_sys_attribute(
const string& attr_name,
const string& xml_attr,
string& error_str)
{
return insert_replace(attr_name, xml_attr, false, error_str);
};
/**
* Updates the system attribute in the database.
* @param db pointer to the db
* @return 0 on success
*/
int update_sys_attribute(
const string& attr_name,
const string& xml_attr,
string& error_str)
{
return insert_replace(attr_name, xml_attr, true, error_str);
};
private:
friend class Nebula; //Only for Nebula class
SystemDB(SqlDB *_db):db(_db){};
~SystemDB(){};
// Pool control table
static const char * pc_names;
static const char * pc_bootstrap;
static const char * pc_table;
// DB versioning table
static const char * ver_names;
static const char * ver_bootstrap;
static const char * ver_table;
// System attributes table
static const char * sys_names;
static const char * sys_bootstrap;
static const char * sys_table;
// Pointer to the db database
SqlDB *db;
/**
* Execute an INSERT or REPLACE Sql query for a system attribute.
* @param db The SQL DB
* @param replace Execute an INSERT or a REPLACE
* @param error_str Returns the error reason, if any
* @return 0 one success
*/
int insert_replace(const string& attr_name,
const string& xml_attr,
bool replace,
string& error_str);
/**
* Bootstraps the database control tables
*
* @return 0 on success
*/
int bootstrap();
/**
* Callback function for the check_db_version method. Stores the read
* version in loaded_db_version
* @param _loaded_db_version returned columns
* @param num the number of columns read from the DB
* @param names the column names
* @param vaues the column values
* @return 0 on success
*/
int select_cb(void *_loaded_db_version,
int num,
char **values,
char **names);
/**
* Callback function for selecting system attributes
*/
int select_attr_cb(void *_attr_xml,
int num,
char **values,
char **names);
/**
* Reads the current DB version.
*
* @return 0 on success,
* -1 if there is a version mismatch,
* -2 if the DB needs a bootstrap
*/
int check_db_version();
};
#endif //SYSTEM_DB_H

View File

@ -1108,7 +1108,8 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/OpenNebula/Host.rb \
src/oca/ruby/OpenNebula/DatastorePool.rb \
src/oca/ruby/OpenNebula/Cluster.rb \
src/oca/ruby/OpenNebula/ClusterPool.rb \
src/oca/ruby/OpenNebula/XMLUtils.rb"
src/oca/ruby/OpenNebula/XMLUtils.rb \
src/oca/ruby/OpenNebula/System.rb"
#-------------------------------------------------------------------------------
# Common Cloud Files

View File

@ -48,6 +48,13 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
def format_pool(options)
config_file = self.class.table_conf
system = System.new(@client)
default_quotas = system.get_group_quotas()
if OpenNebula::is_error?(default_quotas)
raise "Error retrieving the default group quotas: #{default_quotas.message}"
end
table = CLIHelper::ShowTable.new(config_file, self) do
column :ID, "ONE identifier for the Group", :size=>4 do |d|
d["ID"]
@ -67,7 +74,14 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
column :VMS , "Number of VMS", :size=>9 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
"%3d / %3d" % [d['VM_QUOTA']['VM']["VMS_USED"], d['VM_QUOTA']['VM']["VMS"]]
limit = d['VM_QUOTA']['VM']["VMS"]
if limit == "-1"
limit = default_quotas['VM_QUOTA/VM/VMS']
limit = "0" if limit.nil? || limit == ""
end
"%3d / %3d" % [d['VM_QUOTA']['VM']["VMS_USED"], limit]
else
"-"
end
@ -75,8 +89,16 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
column :MEMORY, "Total memory allocated to user VMs", :size=>17 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
limit = d['VM_QUOTA']['VM']["MEMORY"]
if limit == "-1"
limit = default_quotas['VM_QUOTA/VM/MEMORY']
limit = "0" if limit.nil? || limit == ""
end
d['VM_QUOTA']['VM']['MEMORY_USED']
"%7s / %7s" % [OpenNebulaHelper.unit_to_str(d['VM_QUOTA']['VM']["MEMORY_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(d['VM_QUOTA']['VM']["MEMORY"].to_i,{},"M")]
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")]
else
"-"
end
@ -84,7 +106,14 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
column :CPU, "Total CPU allocated to user VMs", :size=>11 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
"%4.0f / %4.0f" % [d['VM_QUOTA']['VM']["CPU_USED"], d['VM_QUOTA']['VM']["CPU"]]
limit = d['VM_QUOTA']['VM']["CPU"]
if limit == "-1"
limit = default_quotas['VM_QUOTA/VM/CPU']
limit = "0" if limit.nil? || limit == ""
end
"%4.0f / %4.0f" % [d['VM_QUOTA']['VM']["CPU_USED"], limit]
else
"-"
end
@ -113,6 +142,13 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
end
def format_resource(group)
system = System.new(@client)
default_quotas = system.get_group_quotas()
if OpenNebula::is_error?(default_quotas)
raise "Error retrieving the default group quotas: #{default_quotas.message}"
end
str="%-15s: %-20s"
str_h1="%-80s"
@ -129,6 +165,7 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
group_hash = group.to_hash
OneQuotaHelper.format_quota(group_hash['GROUP'])
helper = OneQuotaHelper.new
helper.format_quota(group_hash['GROUP'], default_quotas)
end
end

View File

@ -20,60 +20,6 @@ class OneQuotaHelper
EDITOR_PATH='/usr/bin/vi'
#---------------------------------------------------------------------------
# Tables to format user quotas
#---------------------------------------------------------------------------
TABLE_DS = CLIHelper::ShowTable.new(nil, self) do
column :"DATASTORE ID", "", :size=>12 do |d|
d["ID"] if !d.nil?
end
column :"IMAGES", "", :right, :size=>20 do |d|
"%8d / %8d" % [d["IMAGES_USED"], d["IMAGES"]] if !d.nil?
end
column :"SIZE", "", :right, :size=>19 do |d|
"%8s / %8s" % [OpenNebulaHelper.unit_to_str(d["SIZE_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(d["SIZE"].to_i,{},"M")] if !d.nil?
end
end
TABLE_NET = CLIHelper::ShowTable.new(nil, self) do
column :"NETWORK ID", "", :size=>12 do |d|
d["ID"] if !d.nil?
end
column :"LEASES", "", :right, :size=>20 do |d|
"%8d / %8d" % [d["LEASES_USED"], d["LEASES"]] if !d.nil?
end
end
TABLE_VM = CLIHelper::ShowTable.new(nil, self) do
column :"NUMBER OF VMS", "", :right, :size=>20 do |d|
"%8d / %8d" % [d["VMS_USED"], d["VMS"]] if !d.nil?
end
column :"MEMORY", "", :right, :size=>20 do |d|
"%8s / %8s" % [OpenNebulaHelper.unit_to_str(d["MEMORY_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(d["MEMORY"].to_i,{},"M")] if !d.nil?
end
column :"CPU", "", :right, :size=>20 do |d|
"%8.2f / %8.2f" % [d["CPU_USED"], d["CPU"]] if !d.nil?
end
end
TABLE_IMG = CLIHelper::ShowTable.new(nil, self) do
column :"IMAGE ID", "", :size=>12 do |d|
d["ID"] if !d.nil?
end
column :"RUNNING VMS", "", :right, :size=>20 do |d|
"%8d / %8d" % [d["RVMS_USED"], d["RVMS"]] if !d.nil?
end
end
HELP_QUOTA = <<-EOT.unindent
#-----------------------------------------------------------------------
# Supported quota limits:
@ -96,18 +42,22 @@ class OneQuotaHelper
# ]
#
# IMAGE = [
# ID = <ID of the image>
# RVMS = <Max. number of VMs using the image>
# ID = <ID of the image>
# RVMS = <Max. number of VMs using the image>
# ]
#
# In any quota 0 means unlimited. The usage counters "*_USED" are
# shown for information purposes and will NOT be modified.
# In any quota:
# -1 means use the default limit ('defaultquota' command)
# 0 means unlimited.
#
# The usage counters "*_USED" are shown for information
# purposes and will NOT be modified.
#-----------------------------------------------------------------------
EOT
# Edits the quota template of a resource
# @param resource [PoolElement] to get the current info from
# @param path [String] path to the new contents. If nil a editor will be
# @param [XMLElement] resource to get the current info from
# @param [String] path to the new contents. If nil a editor will be
# used
# @return [String] contents of the new quotas
def self.set_quota(resource, path)
@ -119,13 +69,6 @@ class OneQuotaHelper
tmp = Tempfile.new('one-cli')
path = tmp.path
rc = resource.info
if OpenNebula.is_error?(rc)
puts rc.message
exit -1
end
tmp << HELP_QUOTA
tmp << resource.template_like_str("DATASTORE_QUOTA") << "\n"
tmp << resource.template_like_str("VM_QUOTA") << "\n"
@ -220,8 +163,9 @@ class OneQuotaHelper
# Outputs formated quota information to stdout
# @param qh [Hash] with the quotas for a given resource
# @param default_quotas_hash [XMLElement] with the default quota limits
#
def self.format_quota(qh)
def format_quota(qh, default_quotas)
str_h1="%-80s"
puts
@ -230,27 +174,145 @@ class OneQuotaHelper
puts
@default_quotas = default_quotas
vm_quotas = [qh['VM_QUOTA']['VM']].flatten
if !vm_quotas[0].nil?
TABLE_VM.show(vm_quotas, {})
CLIHelper::ShowTable.new(nil, self) do
column :"NUMBER OF VMS", "", :right, :size=>20 do |d|
if !d.nil?
elem = 'VMS'
limit = d[elem]
limit = helper.get_default_limit(
limit, "VM_QUOTA/VM/#{elem}")
"%8d / %8d" % [d["VMS_USED"], limit]
end
end
column :"MEMORY", "", :right, :size=>20 do |d|
if !d.nil?
elem = 'MEMORY'
limit = d[elem]
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")
]
end
end
column :"CPU", "", :right, :size=>20 do |d|
if !d.nil?
elem = 'CPU'
limit = d[elem]
limit = helper.get_default_limit(
limit, "VM_QUOTA/VM/#{elem}")
"%8.2f / %8.2f" % [d["CPU_USED"], limit]
end
end
end.show(vm_quotas, {})
puts
end
ds_quotas = [qh['DATASTORE_QUOTA']['DATASTORE']].flatten
if !ds_quotas[0].nil?
TABLE_DS.show(ds_quotas, {})
CLIHelper::ShowTable.new(nil, self) do
column :"DATASTORE ID", "", :size=>12 do |d|
d["ID"] if !d.nil?
end
column :"IMAGES", "", :right, :size=>20 do |d|
if !d.nil?
elem = 'IMAGES'
limit = d[elem]
limit = helper.get_default_limit(
limit, "DATASTORE_QUOTA/DATASTORE[ID=#{d['ID']}]/#{elem}")
"%8d / %8d" % [d["IMAGES_USED"], limit]
end
end
column :"SIZE", "", :right, :size=>19 do |d|
if !d.nil?
elem = 'SIZE'
limit = d[elem]
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")
]
end
end
end.show(ds_quotas, {})
puts
end
net_quotas = [qh['NETWORK_QUOTA']['NETWORK']].flatten
if !net_quotas[0].nil?
TABLE_NET.show(net_quotas, {})
CLIHelper::ShowTable.new(nil, self) do
column :"NETWORK ID", "", :size=>12 do |d|
d["ID"] if !d.nil?
end
column :"LEASES", "", :right, :size=>20 do |d|
if !d.nil?
elem = 'LEASES'
limit = d[elem]
limit = helper.get_default_limit(
limit, "NETWORK_QUOTA/NETWORK[ID=#{d['ID']}]/#{elem}")
"%8d / %8d" % [d["LEASES_USED"], limit]
end
end
end.show(net_quotas, {})
puts
end
image_quotas = [qh['IMAGE_QUOTA']['IMAGE']].flatten
if !image_quotas[0].nil?
TABLE_IMG.show(image_quotas, {})
CLIHelper::ShowTable.new(nil, self) do
column :"IMAGE ID", "", :size=>12 do |d|
d["ID"] if !d.nil?
end
column :"RUNNING VMS", "", :right, :size=>20 do |d|
if !d.nil?
elem = 'RVMS'
limit = d[elem]
limit = helper.get_default_limit(
limit, "IMAGE_QUOTA/IMAGE[ID=#{d['ID']}]/RVMS")
"%8d / %8d" % [d["RVMS_USED"], limit]
end
end
end.show(image_quotas, {})
end
end
def get_default_limit(limit, xpath)
if limit == "-1"
if !@default_quotas.nil?
limit = @default_quotas[xpath]
limit = "0" if limit.nil? || limit == ""
else
limit = "0"
end
end
return limit
end
end

View File

@ -147,6 +147,13 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
def format_pool(options)
config_file = self.class.table_conf
system = System.new(@client)
default_quotas = system.get_user_quotas()
if OpenNebula::is_error?(default_quotas)
raise "Error retrieving the default user quotas: #{default_quotas.message}"
end
table = CLIHelper::ShowTable.new(config_file, self) do
column :ID, "ONE identifier for the User", :size=>4 do |d|
d["ID"]
@ -166,7 +173,14 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
column :VMS , "Number of VMS", :size=>9 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
"%3d / %3d" % [d['VM_QUOTA']['VM']["VMS_USED"], d['VM_QUOTA']['VM']["VMS"]]
limit = d['VM_QUOTA']['VM']["VMS"]
if limit == "-1"
limit = default_quotas['VM_QUOTA/VM/VMS']
limit = "0" if limit.nil? || limit == ""
end
"%3d / %3d" % [d['VM_QUOTA']['VM']["VMS_USED"], limit]
else
"-"
end
@ -174,9 +188,16 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
column :MEMORY, "Total memory allocated to user VMs", :size=>17 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
limit = d['VM_QUOTA']['VM']["MEMORY"]
if limit == "-1"
limit = default_quotas['VM_QUOTA/VM/MEMORY']
limit = "0" if limit.nil? || limit == ""
end
d['VM_QUOTA']['VM']['MEMORY_USED']
"%7s / %7s" % [OpenNebulaHelper.unit_to_str(d['VM_QUOTA']['VM']["MEMORY_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(d['VM_QUOTA']['VM']["MEMORY"].to_i,{},"M")]
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")]
else
"-"
end
@ -184,7 +205,14 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
column :CPU, "Total CPU allocated to user VMs", :size=>11 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
"%4.0f / %4.0f" % [d['VM_QUOTA']['VM']["CPU_USED"], d['VM_QUOTA']['VM']["CPU"]]
limit = d['VM_QUOTA']['VM']["CPU"]
if limit == "-1"
limit = default_quotas['VM_QUOTA/VM/CPU']
limit = "0" if limit.nil? || limit == ""
end
"%4.0f / %4.0f" % [d['VM_QUOTA']['VM']["CPU_USED"], limit]
else
"-"
end
@ -217,6 +245,13 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
end
def format_resource(user)
system = System.new(@client)
default_quotas = system.get_user_quotas()
if OpenNebula::is_error?(default_quotas)
raise "Error retrieving the default user quotas: #{default_quotas.message}"
end
str="%-15s: %-20s"
str_h1="%-80s"
@ -237,6 +272,7 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
user_hash = user.to_hash
OneQuotaHelper.format_quota(user_hash['USER'])
helper = OneQuotaHelper.new
helper.format_quota(user_hash['USER'], default_quotas)
end
end

View File

@ -109,6 +109,13 @@ cmd=CommandParser::CmdParser.new(ARGV) do
command :quota, quota_desc, :groupid, [:file, nil] do
helper.perform_action(args[0], options, "modified") do |group|
rc = group.info
if OpenNebula.is_error?(rc)
puts rc.message
exit -1
end
str = OneQuotaHelper.set_quota(group, args[1])
rc = group.set_quota(str)
@ -138,4 +145,32 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
end
defaultquota_desc = <<-EOT.unindent
Sets the default quota limits for the groups. If a path is not provided
the editor will be launched to modify the current default quotas.
EOT
command :defaultquota, defaultquota_desc, [:file, nil] do
system = System.new(OneGroupHelper.get_client(options))
default_quotas = system.get_group_quotas()
if OpenNebula.is_error?(default_quotas)
puts default_quotas.message
exit(-1)
end
str = OneQuotaHelper.set_quota(default_quotas, args[0])
rc = system.set_group_quotas(str)
if OpenNebula.is_error?(rc)
puts rc.message
exit(-1)
end
exit 0
end
end

View File

@ -206,6 +206,13 @@ cmd=CommandParser::CmdParser.new(ARGV) do
command :quota, quota_desc, :userid, [:file, nil] do
helper.perform_action(args[0], options, "modified") do |user|
rc = user.info
if OpenNebula.is_error?(rc)
puts rc.message
exit -1
end
str = OneQuotaHelper.set_quota(user, args[1])
rc = user.set_quota(str)
@ -213,7 +220,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do
puts rc.message
exit -1
end
end
end
@ -237,6 +243,33 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
defaultquota_desc = <<-EOT.unindent
Sets the default quota limits for the users. If a path is not provided
the editor will be launched to modify the current default quotas.
EOT
command :defaultquota, defaultquota_desc, [:file, nil] do
system = System.new(OneUserHelper.get_client(options))
default_quotas = system.get_user_quotas()
if OpenNebula.is_error?(default_quotas)
puts default_quotas.message
exit(-1)
end
str = OneQuotaHelper.set_quota(default_quotas, args[0])
rc = system.set_user_quotas(str)
if OpenNebula.is_error?(rc)
puts rc.message
exit(-1)
end
exit 0
end
login_desc = <<-EOT.unindent
Creates the Login token for authentication
Examples:

View File

@ -545,6 +545,9 @@ int Image::disk_attribute( VectorAttribute * disk,
disk_attr_type = "CDROM";
disk->replace("READONLY","YES");
break;
default: //Other file types should not be never a DISK
break;
}
disk->replace("TYPE",disk_attr_type);

View File

@ -33,6 +33,238 @@
using namespace std;
// Pool control table
const char * SystemDB::pc_table = "pool_control";
const char * SystemDB::pc_names = "tablename, last_oid";
const char * SystemDB::pc_bootstrap = "CREATE TABLE pool_control "
"(tablename VARCHAR(32) PRIMARY KEY, last_oid BIGINT UNSIGNED)";
// DB versioning table
const char * SystemDB::ver_table = "db_versioning";
const char * SystemDB::ver_names = "oid, version, timestamp, comment";
const char * SystemDB::ver_bootstrap = "CREATE TABLE db_versioning "
"(oid INTEGER PRIMARY KEY, version VARCHAR(256), timestamp INTEGER, "
"comment VARCHAR(256))";
// System attributes table
const char * SystemDB::sys_table = "system_attributes";
const char * SystemDB::sys_names = "name, body";
const char * SystemDB::sys_bootstrap = "CREATE TABLE IF NOT EXISTS"
" system_attributes (name VARCHAR(128) PRIMARY KEY, body TEXT)";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::bootstrap()
{
int rc;
ostringstream oss;
// ------------------------------------------------------------------------
// pool control, tracks the last ID's assigned to objects
// ------------------------------------------------------------------------
oss.str(pc_bootstrap);
rc = db->exec(oss);
// ------------------------------------------------------------------------
// db versioning, version of OpenNebula. Insert this version number
// ------------------------------------------------------------------------
oss.str(ver_bootstrap);
rc += db->exec(oss);
oss.str("");
oss << "INSERT INTO " << ver_table << " (" << ver_names << ") "
<< "VALUES (0, '" << Nebula::db_version() << "', " << time(0)
<< ", '" << Nebula::version() << " daemon bootstrap')";
rc += db->exec(oss);
// ------------------------------------------------------------------------
// system , version of OpenNebula. Insert this version number
// ------------------------------------------------------------------------
oss.str(sys_bootstrap);
rc += db->exec(oss);
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::select_cb(void *_loaded_db_version, int num, char **values,
char **names)
{
istringstream iss;
string * loaded_db_version;
loaded_db_version = static_cast<string *>(_loaded_db_version);
if ( (values[0]) && (num == 1) )
{
*loaded_db_version = values[0];
}
return 0;
};
/* -------------------------------------------------------------------------- */
int SystemDB::check_db_version()
{
int rc;
ostringstream oss;
string loaded_db_version = "";
// Try to read latest version
set_callback( static_cast<Callbackable::Callback>(&SystemDB::select_cb),
static_cast<void *>(&loaded_db_version) );
oss << "SELECT version FROM " << ver_table
<< " WHERE oid=(SELECT MAX(oid) FROM " << ver_table << ")";
db->exec(oss, this);
oss.str("");
unset_callback();
if( loaded_db_version == "" )
{
// Table user_pool is present for all OpenNebula versions, and it
// always contains at least the oneadmin user.
oss << "SELECT MAX(oid) FROM user_pool";
rc = db->exec(oss);
oss.str("");
if( rc != 0 ) // Database needs bootstrap
{
return -2;
}
}
if( Nebula::db_version() != loaded_db_version )
{
oss << "Database version mismatch. "
<< "Installed " << Nebula::version() << " uses DB version '"
<< Nebula::db_version() << "', and existing DB version is '"
<< loaded_db_version << "'.";
NebulaLog::log("ONE",Log::ERROR,oss);
return -1;
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::insert_replace(
const string& attr_name,
const string& xml_attr,
bool replace,
string& err)
{
ostringstream oss;
int rc;
char * sql_xml;
sql_xml = db->escape_str(xml_attr.c_str());
if ( sql_xml == 0 )
{
goto error_body;
}
if ( ObjectXML::validate_xml(sql_xml) != 0 )
{
goto error_xml;
}
if ( replace )
{
oss << "REPLACE";
}
else
{
oss << "INSERT";
}
// Construct the SQL statement to Insert or Replace
oss <<" INTO "<< sys_table <<
" ("<< sys_names <<") VALUES ("
<< "'" << attr_name << "',"
<< "'" << sql_xml << "')";
rc = db->exec(oss);
db->free_str(sql_xml);
return rc;
error_xml:
db->free_str(sql_xml);
error_body:
err = "Error inserting system attribute in DB.";
return -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::select_attr_cb(void * _xml_attr,
int num,
char ** values,
char ** names)
{
istringstream iss;
string * xml_attr;
xml_attr = static_cast<string *>(_xml_attr);
if ( (values[0]) && (num == 1) )
{
*xml_attr = values[0];
}
return 0;
};
/* -------------------------------------------------------------------------- */
int SystemDB::select_sys_attribute(const string& attr_name, string& attr_xml)
{
ostringstream oss;
int rc;
set_callback(static_cast<Callbackable::Callback>(&SystemDB::select_attr_cb),
static_cast<void *>(&attr_xml) );
oss << "SELECT body FROM " << sys_table << " WHERE name = '"
<< attr_name << "'";
rc = db->exec(oss, this);
unset_callback();
if (rc != 0)
{
return -1;
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -219,8 +451,15 @@ void Nebula::start()
}
}
// ---------------------------------------------------------------------
// Prepare the SystemDB and check versions
// ---------------------------------------------------------------------
NebulaLog::log("ONE",Log::INFO,"Checking database version.");
rc = check_db_version();
system_db = new SystemDB(db);
rc = system_db->check_db_version();
if( rc == -1 )
{
@ -245,12 +484,16 @@ void Nebula::start()
rc += ClusterPool::bootstrap(db);
rc += DocumentPool::bootstrap(db);
// Create the versioning table only if bootstrap went well
// Create the system tables only if bootstrap went well
if ( rc == 0 )
{
rc += bootstrap();
rc += system_db->bootstrap();
}
// Insert default system attributes
rc += default_user_quota.insert();
rc += default_group_quota.insert();
if ( rc != 0 )
{
throw runtime_error("Error bootstrapping database.");
@ -340,6 +583,9 @@ void Nebula::start()
tpool = new VMTemplatePool(db);
dspool = new DatastorePool(db);
default_user_quota.select();
default_group_quota.select();
}
catch (exception&)
{
@ -674,99 +920,3 @@ void Nebula::start()
NebulaLog::log("ONE", Log::INFO, "All modules finalized, exiting.\n");
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Nebula::bootstrap()
{
int rc;
ostringstream oss;
oss << "CREATE TABLE pool_control (tablename VARCHAR(32) PRIMARY KEY, "
"last_oid BIGINT UNSIGNED)";
rc = db->exec(oss);
oss.str("");
oss << "CREATE TABLE db_versioning (oid INTEGER PRIMARY KEY, "
"version VARCHAR(256), timestamp INTEGER, comment VARCHAR(256))";
rc += db->exec(oss);
oss.str("");
oss << "INSERT INTO db_versioning (oid, version, timestamp, comment) "
<< "VALUES (0, '" << db_version() << "', " << time(0)
<< ", '" << version() << " daemon bootstrap')";
rc += db->exec(oss);
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Nebula::check_db_version()
{
int rc;
ostringstream oss;
string loaded_db_version = "";
// Try to read latest version
set_callback( static_cast<Callbackable::Callback>(&Nebula::select_cb),
static_cast<void *>(&loaded_db_version) );
oss << "SELECT version FROM db_versioning "
<< "WHERE oid=(SELECT MAX(oid) FROM db_versioning)";
db->exec(oss, this);
oss.str("");
unset_callback();
if( loaded_db_version == "" )
{
// Table user_pool is present for all OpenNebula versions, and it
// always contains at least the oneadmin user.
oss << "SELECT MAX(oid) FROM user_pool";
rc = db->exec(oss);
oss.str("");
if( rc != 0 ) // Database needs bootstrap
{
return -2;
}
}
if( db_version() != loaded_db_version )
{
oss << "Database version mismatch. "
<< "Installed " << version() << " uses DB version '" << db_version()
<< "', and existing DB version is '"
<< loaded_db_version << "'.";
NebulaLog::log("ONE",Log::ERROR,oss);
return -1;
}
return 0;
}
int Nebula::select_cb(void *_loaded_db_version, int num, char **values,
char **names)
{
istringstream iss;
string * loaded_db_version;
loaded_db_version = static_cast<string *>(_loaded_db_version);
if ( (values[0]) && (num == 1) )
{
*loaded_db_version = values[0];
}
return 0;
};

View File

@ -23,6 +23,7 @@ lib_name='nebula_core'
# Sources to generate the library
source_files=[
'SystemDB.cc',
'Nebula.cc',
'NebulaTemplate.cc',
]

252
src/nebula/SystemDB.cc Normal file
View File

@ -0,0 +1,252 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* 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. */
/* -------------------------------------------------------------------------- */
#include "Nebula.h"
#include "SystemDB.h"
using namespace std;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
// Pool control table
const char * SystemDB::pc_table = "pool_control";
const char * SystemDB::pc_names = "tablename, last_oid";
const char * SystemDB::pc_bootstrap = "CREATE TABLE pool_control "
"(tablename VARCHAR(32) PRIMARY KEY, last_oid BIGINT UNSIGNED)";
// DB versioning table
const char * SystemDB::ver_table = "db_versioning";
const char * SystemDB::ver_names = "oid, version, timestamp, comment";
const char * SystemDB::ver_bootstrap = "CREATE TABLE db_versioning "
"(oid INTEGER PRIMARY KEY, version VARCHAR(256), timestamp INTEGER, "
"comment VARCHAR(256))";
// System attributes table
const char * SystemDB::sys_table = "system_attributes";
const char * SystemDB::sys_names = "name, body";
const char * SystemDB::sys_bootstrap = "CREATE TABLE IF NOT EXISTS"
" system_attributes (name VARCHAR(128) PRIMARY KEY, body TEXT)";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::bootstrap()
{
int rc;
ostringstream oss;
// ------------------------------------------------------------------------
// pool control, tracks the last ID's assigned to objects
// ------------------------------------------------------------------------
oss.str(pc_bootstrap);
rc = db->exec(oss);
// ------------------------------------------------------------------------
// db versioning, version of OpenNebula. Insert this version number
// ------------------------------------------------------------------------
oss.str(ver_bootstrap);
rc += db->exec(oss);
oss.str("");
oss << "INSERT INTO " << ver_table << " (" << ver_names << ") "
<< "VALUES (0, '" << Nebula::db_version() << "', " << time(0)
<< ", '" << Nebula::version() << " daemon bootstrap')";
rc += db->exec(oss);
// ------------------------------------------------------------------------
// system , version of OpenNebula. Insert this version number
// ------------------------------------------------------------------------
oss.str(sys_bootstrap);
rc += db->exec(oss);
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::select_cb(void *_loaded_db_version, int num, char **values,
char **names)
{
istringstream iss;
string * loaded_db_version;
loaded_db_version = static_cast<string *>(_loaded_db_version);
if ( (values[0]) && (num == 1) )
{
*loaded_db_version = values[0];
}
return 0;
};
/* -------------------------------------------------------------------------- */
int SystemDB::check_db_version()
{
int rc;
ostringstream oss;
string loaded_db_version = "";
// Try to read latest version
set_callback( static_cast<Callbackable::Callback>(&SystemDB::select_cb),
static_cast<void *>(&loaded_db_version) );
oss << "SELECT version FROM " << ver_table
<< " WHERE oid=(SELECT MAX(oid) FROM " << ver_table << ")";
db->exec(oss, this);
oss.str("");
unset_callback();
if( loaded_db_version == "" )
{
// Table user_pool is present for all OpenNebula versions, and it
// always contains at least the oneadmin user.
oss << "SELECT MAX(oid) FROM user_pool";
rc = db->exec(oss);
oss.str("");
if( rc != 0 ) // Database needs bootstrap
{
return -2;
}
}
if( Nebula::db_version() != loaded_db_version )
{
oss << "Database version mismatch. "
<< "Installed " << Nebula::version() << " uses DB version '"
<< Nebula::db_version() << "', and existing DB version is '"
<< loaded_db_version << "'.";
NebulaLog::log("ONE",Log::ERROR,oss);
return -1;
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::insert_replace(
const string& attr_name,
const string& xml_attr,
bool replace,
string& err)
{
ostringstream oss;
int rc;
char * sql_xml;
sql_xml = db->escape_str(xml_attr.c_str());
if ( sql_xml == 0 )
{
goto error_body;
}
if ( ObjectXML::validate_xml(sql_xml) != 0 )
{
goto error_xml;
}
if ( replace )
{
oss << "REPLACE";
}
else
{
oss << "INSERT";
}
// Construct the SQL statement to Insert or Replace
oss <<" INTO "<< sys_table << " ("<< sys_names <<") VALUES ("
<< "'" << attr_name << "'," << "'" << sql_xml << "')";
rc = db->exec(oss);
db->free_str(sql_xml);
return rc;
error_xml:
db->free_str(sql_xml);
error_body:
err = "Error inserting system attribute in DB.";
return -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SystemDB::select_attr_cb(void * _xml_attr,
int num,
char ** values,
char ** names)
{
istringstream iss;
string * xml_attr;
xml_attr = static_cast<string *>(_xml_attr);
if ( (values[0]) && (num == 1) )
{
*xml_attr = values[0];
}
return 0;
};
/* -------------------------------------------------------------------------- */
int SystemDB::select_sys_attribute(const string& attr_name, string& attr_xml)
{
ostringstream oss;
int rc;
set_callback(static_cast<Callbackable::Callback>(&SystemDB::select_attr_cb),
static_cast<void *>(&attr_xml) );
oss << "SELECT body FROM " << sys_table << " WHERE name = '"
<< attr_name << "'";
rc = db->exec(oss, this);
unset_callback();
if (rc != 0)
{
return -1;
}
return 0;
}

View File

@ -48,6 +48,7 @@ require 'OpenNebula/Cluster'
require 'OpenNebula/ClusterPool'
require 'OpenNebula/Document'
require 'OpenNebula/DocumentPool'
require 'OpenNebula/System'
module OpenNebula

View File

@ -0,0 +1,99 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) #
# #
# 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 'OpenNebula/Pool'
module OpenNebula
class System
#######################################################################
# Constants and Class attribute accessors
#######################################################################
SYSTEM_METHODS = {
:userquotainfo => "userquota.info",
:userquotaupdate => "userquota.update",
:groupquotainfo => "groupquota.info",
:groupquotaupdate => "groupquota.update"
}
#######################################################################
# Class constructor
#######################################################################
# Constructor
# @param [Client] client that represents a XML-RPC connection
def initialize(client)
@client = client
end
#######################################################################
# XML-RPC Methods
#######################################################################
# Gets the default user quota limits
#
# @return [XMLElement, OpenNebula::Error] the default user quota in case
# of success, Error otherwise
def get_user_quotas()
rc = @client.call(SYSTEM_METHODS[:userquotainfo])
if OpenNebula.is_error?(rc)
return rc
end
default_quotas = XMLElement.new
default_quotas.initialize_xml(rc, 'DEFAULT_USER_QUOTAS')
return default_quotas
end
# Sets the default user quota limits
# @param quota [String] a template (XML or txt) with the new quota limits
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def set_user_quotas(quota)
return @client.call(SYSTEM_METHODS[:userquotaupdate], quota)
end
# Gets the default group quota limits
#
# @return [XMLElement, OpenNebula::Error] the default group quota in case
# of success, Error otherwise
def get_group_quotas()
rc = @client.call(SYSTEM_METHODS[:groupquotainfo])
if OpenNebula.is_error?(rc)
return rc
end
default_quotas = XMLElement.new
default_quotas.initialize_xml(rc, 'DEFAULT_GROUP_QUOTAS')
return default_quotas
end
# Sets the default group quota limits
# @param quota [String] a template (XML or txt) with the new quota limits
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def set_group_quotas(quota)
return @client.call(SYSTEM_METHODS[:groupquotaupdate], quota)
end
end
end

View File

@ -79,12 +79,18 @@ module OpenNebula
return doc
end
# Extract an element from the XML description of the PoolElement.
# key::_String_ The name of the element
# [return] _String_ the value of the element
# Examples:
# ['VID'] # gets VM id
# ['HISTORY/HOSTNAME'] # get the hostname from the history
# Extract a text element from the XML description of the PoolElement.
#
# @param [String] key Xpath expression
#
# @return [String, nil] If a text element is found, the element's
# text value. Otherwise, an empty string or nil, depending
# on the backend
#
# @example
# vm['VID'] # gets VM id
# vm['HISTORY/HOSTNAME'] # get the hostname from the history
def [](key)
if NOKOGIRI
element=@xml.xpath(key.to_s)

View File

@ -278,7 +278,9 @@ bool Request::user_quota_authorization (Template * tmpl,
return false;
}
rc = user->quota.quota_check(qtype, tmpl, error_str);
Quotas default_user_quotas = nd.get_default_user_quota();
rc = user->quota.quota_check(qtype, tmpl, default_user_quotas, error_str);
if (rc == true)
{
@ -320,7 +322,9 @@ bool Request::group_quota_authorization (Template * tmpl,
return false;
}
rc = group->quota.quota_check(qtype, tmpl, error_str);
Quotas default_group_quotas = nd.get_default_group_quota();
rc = group->quota.quota_check(qtype, tmpl, default_group_quotas, error_str);
if (rc == true)
{

View File

@ -368,6 +368,12 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr system_version(new SystemVersion());
xmlrpc_c::methodPtr system_config(new SystemConfig());
xmlrpc_c::methodPtr user_get_default_quota(new UserQuotaInfo());
xmlrpc_c::methodPtr user_set_default_quota(new UserQuotaUpdate());
xmlrpc_c::methodPtr group_get_default_quota(new GroupQuotaInfo());
xmlrpc_c::methodPtr group_set_default_quota(new GroupQuotaUpdate());
/* VM related methods */
RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy);
RequestManagerRegistry.addMethod("one.vm.action", vm_action);
@ -416,6 +422,9 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.grouppool.info", grouppool_info);
RequestManagerRegistry.addMethod("one.groupquota.info", group_get_default_quota);
RequestManagerRegistry.addMethod("one.groupquota.update", group_set_default_quota);
/* Network related methods*/
RequestManagerRegistry.addMethod("one.vn.addleases", vn_addleases);
RequestManagerRegistry.addMethod("one.vn.rmleases", vn_rmleases);
@ -441,6 +450,9 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.user.quota", user_set_quota);
RequestManagerRegistry.addMethod("one.userpool.info", userpool_info);
RequestManagerRegistry.addMethod("one.userquota.info", user_get_default_quota);
RequestManagerRegistry.addMethod("one.userquota.update", user_set_default_quota);
/* Image related methods*/
RequestManagerRegistry.addMethod("one.image.persistent", image_persistent);
@ -500,8 +512,6 @@ void RequestManager::register_xml_methods()
/* System related methods */
RequestManagerRegistry.addMethod("one.system.version", system_version);
RequestManagerRegistry.addMethod("one.system.config", system_config);
};
/* -------------------------------------------------------------------------- */

View File

@ -56,3 +56,102 @@ void SystemConfig::request_execute(xmlrpc_c::paramList const& paramList,
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void UserQuotaInfo::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
string xml;
success_response(Nebula::instance().get_default_user_quota().to_xml(xml), att);
return;
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void GroupQuotaInfo::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
string xml;
success_response(Nebula::instance().get_default_group_quota().to_xml(xml), att);
return;
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void QuotaUpdate::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
string quota_str = xmlrpc_c::value_string(paramList.getString(1));
string error_str, xml;
Template quota_tmpl;
int rc;
if ( att.gid != GroupPool::ONEADMIN_ID )
{
failure_response(AUTHORIZATION,
"The default quotas can only be updated by users in the oneadmin group",
att);
return;
}
rc = quota_tmpl.parse_str_or_xml(quota_str, error_str);
if ( rc != 0 )
{
failure_response(ACTION, request_error(error_str,""), att);
return;
}
rc = set_default_quota(&quota_tmpl, error_str);
if ( rc != 0 )
{
failure_response(ACTION, request_error(error_str,""), att);
return;
}
success_response(get_default_quota()->to_xml(xml), att);
return;
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
int UserQuotaUpdate::set_default_quota(Template *tmpl, string& error)
{
return Nebula::instance().set_default_user_quota(tmpl, error);
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
const DefaultQuotas * UserQuotaUpdate::get_default_quota()
{
return &Nebula::instance().get_default_user_quota();
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
int GroupQuotaUpdate::set_default_quota(Template *tmpl, string& error)
{
return Nebula::instance().set_default_group_quota(tmpl, error);
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
const DefaultQuotas * GroupQuotaUpdate::get_default_quota()
{
return &Nebula::instance().get_default_group_quota();
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */

92
src/um/DefaultQuotas.cc Normal file
View File

@ -0,0 +1,92 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* 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. */
/* -------------------------------------------------------------------------- */
#include "DefaultQuotas.h"
#include "ObjectXML.h"
#include "Nebula.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& DefaultQuotas::to_xml(string& xml) const
{
ostringstream oss;
string aux_xml;
oss << "<" << root_elem << ">"
<< Quotas::to_xml(aux_xml)
<< "</" << root_elem << ">";
xml = oss.str();
return xml;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DefaultQuotas::from_xml(const string& xml)
{
ObjectXML *object_xml = new ObjectXML(xml);
int rc = Quotas::from_xml(object_xml);
delete object_xml;
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DefaultQuotas::select()
{
string xml_body;
Nebula& nd = Nebula::instance();
if ( nd.select_sys_attribute(root_elem, xml_body) != 0 )
{
return -1;
}
return from_xml(xml_body);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DefaultQuotas::insert()
{
string xml_body;
string error;
Nebula& nd = Nebula::instance();
return nd.insert_sys_attribute(root_elem, to_xml(xml_body), error);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DefaultQuotas::update()
{
string xml_body;
string error;
Nebula& nd = Nebula::instance();
return nd.update_sys_attribute(root_elem, to_xml(xml_body), error);
}

View File

@ -120,12 +120,12 @@ int Quota::set(vector<Attribute*> * new_quotas, string& error)
if (update_limits(tq, iq) != 0)
{
goto error_limits;
}
}
}
cleanup_quota(id);
}
return 0;
error_limits:
@ -141,20 +141,22 @@ error_limits:
delete quota_str;
}
error = oss.str();
return -1;
return -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool Quota::check_quota(const string& qid,
bool Quota::check_quota(const string& qid,
map<string, float>& usage_req,
Quotas& default_quotas,
string& error)
{
VectorAttribute * q;
VectorAttribute * default_q;
map<string, float>::iterator it;
bool check;
@ -171,43 +173,36 @@ bool Quota::check_quota(const string& qid,
return false;
}
if ( get_default_quota(qid, default_quotas, &default_q) == -1 )
{
default_q = 0;
}
// -------------------------------------------------------------------------
// Quota does not exist, create a new one
// -------------------------------------------------------------------------
if ( q == 0 )
{
map<string, string> values;
for (int i=0; i < num_metrics; i++)
{
ostringstream usage_req_str;
string metrics_used = metrics[i];
string metrics_used = metrics[i];
metrics_used += "_USED";
it = usage_req.find(metrics[i]);
if (it == usage_req.end())
{
usage_req_str << "0";
}
else
{
usage_req_str << it->second;
}
values.insert(make_pair(metrics[i], "0"));
values.insert(make_pair(metrics_used, usage_req_str.str()));
values.insert(make_pair(metrics[i], "-1"));
values.insert(make_pair(metrics_used, "0"));
}
if (!qid.empty())
{
values.insert(make_pair("ID", qid));
}
add(new VectorAttribute(template_name, values));
q = new VectorAttribute(template_name, values);
return true;
add(q);
}
// -------------------------------------------------------------------------
@ -216,7 +211,7 @@ bool Quota::check_quota(const string& qid,
for (int i=0; i < num_metrics; i++)
{
string metrics_used = metrics[i];
metrics_used += "_USED";
it = usage_req.find(metrics[i]);
@ -229,6 +224,18 @@ 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 ( default_q != 0 )
{
default_q->vector_value(metrics[i], limit);
}
else
{
limit = 0;
}
}
check = ( limit == 0 ) || ( ( usage + it->second ) <= limit );
if ( !check )
@ -238,7 +245,7 @@ bool Quota::check_quota(const string& qid,
oss << "limit of " << limit << " reached for " << metrics[i]
<< " quota in " << template_name;
if ( !qid.empty() )
if ( !qid.empty() )
{
oss << " with ID: " << qid;
}
@ -255,7 +262,7 @@ bool Quota::check_quota(const string& qid,
for (int i=0; i < num_metrics; i++)
{
string metrics_used = metrics[i];
metrics_used += "_USED";
it = usage_req.find(metrics[i]);
@ -287,12 +294,12 @@ void Quota::del_quota(const string& qid, map<string, float>& usage_req)
if ( q == 0 )
{
return;
}
}
for (int i=0; i < num_metrics; i++)
{
string metrics_used = metrics[i];
metrics_used += "_USED";
it = usage_req.find(metrics[i]);
@ -316,8 +323,7 @@ void Quota::cleanup_quota(const string& qid)
VectorAttribute * q;
map<string, Attribute *>::iterator q_it;
float limit, limit_tmp;
float usage, usage_tmp;
float usage, limit, implicit_limit;
if ( get_quota(qid, &q, q_it) == -1)
{
@ -329,8 +335,14 @@ void Quota::cleanup_quota(const string& qid)
return;
}
limit = 0;
usage = 0;
if ( is_default )
{
implicit_limit = 0;
}
else
{
implicit_limit = -1;
}
for (int i=0; i < num_metrics; i++)
{
@ -338,26 +350,27 @@ void Quota::cleanup_quota(const string& qid)
metrics_used += "_USED";
q->vector_value(metrics[i], limit_tmp);
q->vector_value(metrics_used.c_str(), usage_tmp);
q->vector_value(metrics[i], limit);
q->vector_value(metrics_used.c_str(), usage);
limit += limit_tmp;
usage += usage_tmp;
if ( usage != 0 || limit != implicit_limit )
{
return;
}
}
if ( limit == 0 && usage == 0 )
{
delete static_cast<Attribute *>(q_it->second);
delete static_cast<Attribute *>(q_it->second);
attributes.erase(q_it);
}
attributes.erase(q_it);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Quota::update_limits(VectorAttribute * quota, const VectorAttribute * va)
{
int Quota::update_limits(
VectorAttribute * quota,
const VectorAttribute * va)
{
string limit;
float limit_i;
@ -365,7 +378,10 @@ int Quota::update_limits(VectorAttribute * quota, const VectorAttribute * va)
{
limit = va->vector_value_str(metrics[i], limit_i);
if ( limit_i < 0 ) //No quota, NaN or negative
//No quota, NaN or negative
if ((!is_default &&
( limit_i < -1 || ( limit_i == -1 && limit == "" ))) ||
(is_default && limit_i < 0) )
{
return -1;
}
@ -374,7 +390,7 @@ int Quota::update_limits(VectorAttribute * quota, const VectorAttribute * va)
quota->replace(metrics[i], limit);
}
}
return 0;
}
@ -391,14 +407,16 @@ VectorAttribute * Quota::new_quota(VectorAttribute * va)
for (int i=0; i < num_metrics; i++)
{
string metrics_used = metrics[i];
metrics_used += "_USED";
limit = va->vector_value_str(metrics[i], limit_i);
if ( limit_i < 0 ) //No quota, NaN or negative
//No quota, NaN or negative
if ( (!is_default && limit_i < -1) ||
(is_default && limit_i < 0) )
{
limit = "0";
return 0;
}
limits.insert(make_pair(metrics[i], limit));

View File

@ -15,6 +15,7 @@
/* -------------------------------------------------------------------------- */
#include "QuotaDatastore.h"
#include "Quotas.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -26,7 +27,7 @@ const int QuotaDatastore::NUM_DS_METRICS = 2;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool QuotaDatastore::check(Template * tmpl, string& error)
bool QuotaDatastore::check(Template * tmpl, Quotas& default_quotas, string& error)
{
map<string, float> ds_request;
@ -49,8 +50,8 @@ bool QuotaDatastore::check(Template * tmpl, string& error)
ds_request.insert(make_pair("IMAGES",1));
ds_request.insert(make_pair("SIZE", size));
return check_quota(ds_id, ds_request, error);
return check_quota(ds_id, ds_request, default_quotas, error);
}
/* -------------------------------------------------------------------------- */
@ -83,3 +84,14 @@ void QuotaDatastore::del(Template * tmpl)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int QuotaDatastore::get_default_quota(
const string& id,
Quotas& default_quotas,
VectorAttribute **va)
{
return default_quotas.ds_get(id, va);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -15,6 +15,7 @@
/* -------------------------------------------------------------------------- */
#include "QuotaImage.h"
#include "Quotas.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -26,7 +27,7 @@ const int QuotaImage::NUM_IMAGE_METRICS = 1;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool QuotaImage::check(Template * tmpl, string& error)
bool QuotaImage::check(Template * tmpl, Quotas& default_quotas, string& error)
{
vector<Attribute*> disks;
VectorAttribute * disk;
@ -50,10 +51,10 @@ bool QuotaImage::check(Template * tmpl, string& error)
}
image_id = disk->vector_value("IMAGE_ID");
if ( !image_id.empty() )
{
if ( !check_quota(image_id, image_request, error) )
if ( !check_quota(image_id, image_request, default_quotas, error) )
{
return false;
}
@ -91,10 +92,21 @@ void QuotaImage::del(Template * tmpl)
}
image_id = disk->vector_value("IMAGE_ID");
del_quota(image_id, image_request);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int QuotaImage::get_default_quota(
const string& id,
Quotas& default_quotas,
VectorAttribute **va)
{
return default_quotas.image_get(id, va);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -15,6 +15,7 @@
/* -------------------------------------------------------------------------- */
#include "QuotaNetwork.h"
#include "Quotas.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -26,7 +27,7 @@ const int QuotaNetwork::NUM_NET_METRICS = 1;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool QuotaNetwork::check(Template * tmpl, string& error)
bool QuotaNetwork::check(Template * tmpl, Quotas& default_quotas, string& error)
{
vector<Attribute*> nics;
VectorAttribute * nic;
@ -53,7 +54,7 @@ bool QuotaNetwork::check(Template * tmpl, string& error)
if ( !net_id.empty() )
{
if ( !check_quota(net_id, net_request, error) )
if ( !check_quota(net_id, net_request, default_quotas, error) )
{
return false;
}
@ -91,10 +92,21 @@ void QuotaNetwork::del(Template * tmpl)
}
net_id = nic->vector_value("NETWORK_ID");
del_quota(net_id, net_request);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int QuotaNetwork::get_default_quota(
const string& id,
Quotas& default_quotas,
VectorAttribute **va)
{
return default_quotas.network_get(id, va);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -15,6 +15,7 @@
/* -------------------------------------------------------------------------- */
#include "QuotaVirtualMachine.h"
#include "Quotas.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -48,7 +49,9 @@ int QuotaVirtualMachine::get_quota(const string& id, VectorAttribute **va)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool QuotaVirtualMachine::check(Template * tmpl, string& error)
bool QuotaVirtualMachine::check(Template * tmpl,
Quotas& default_quotas,
string& error)
{
map<string, float> vm_request;
@ -70,8 +73,8 @@ bool QuotaVirtualMachine::check(Template * tmpl, string& error)
vm_request.insert(make_pair("VMS",1));
vm_request.insert(make_pair("MEMORY", memory));
vm_request.insert(make_pair("CPU", cpu));
return check_quota("", vm_request, error);
return check_quota("", vm_request, default_quotas, error);
}
/* -------------------------------------------------------------------------- */
@ -97,9 +100,20 @@ void QuotaVirtualMachine::del(Template * tmpl)
vm_request.insert(make_pair("VMS",1));
vm_request.insert(make_pair("MEMORY", memory));
vm_request.insert(make_pair("CPU", cpu));
del_quota("", vm_request);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int QuotaVirtualMachine::get_default_quota(
const string& id,
Quotas& default_quotas,
VectorAttribute **va)
{
return default_quotas.vm_get(id, va);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -19,7 +19,6 @@
#include "ObjectXML.h"
int Quotas::set(Template *tmpl, string& error)
{
vector<Attribute *> vquotas;
@ -173,35 +172,38 @@ void Quotas::quota_del(QuotaType type, Template *tmpl)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool Quotas::quota_check(QuotaType type, Template *tmpl, string& error_str)
bool Quotas::quota_check(QuotaType type,
Template *tmpl,
Quotas &default_quotas,
string &error_str)
{
switch (type)
{
case DATASTORE:
return datastore_quota.check(tmpl, error_str);
return datastore_quota.check(tmpl, default_quotas, error_str);
case NETWORK:
return network_quota.check(tmpl, error_str);
return network_quota.check(tmpl, default_quotas, error_str);
case IMAGE:
return image_quota.check(tmpl, error_str);
return image_quota.check(tmpl, default_quotas, error_str);
case VM:
return vm_quota.check(tmpl, error_str);
return vm_quota.check(tmpl, default_quotas, error_str);
case VIRTUALMACHINE:
if ( network_quota.check(tmpl, error_str) == false )
if ( network_quota.check(tmpl, default_quotas, error_str) == false )
{
return false;
}
if ( vm_quota.check(tmpl, error_str) == false )
if ( vm_quota.check(tmpl, default_quotas, error_str) == false )
{
network_quota.del(tmpl);
return false;
}
if ( image_quota.check(tmpl, error_str) == false )
if ( image_quota.check(tmpl, default_quotas, error_str) == false )
{
network_quota.del(tmpl);
vm_quota.del(tmpl);

View File

@ -29,7 +29,8 @@ source_files=[
'QuotaNetwork.cc',
'QuotaVirtualMachine.cc',
'QuotaImage.cc',
'Quotas.cc'
'Quotas.cc',
'DefaultQuotas.cc'
]
# Build library