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

Merge branch 'master' into feature-1291. It also implements a new state machine for images to fix #1297

Conflicts:
	include/Template.h
	src/image/Image.cc
	src/image/ImageManagerActions.cc
	src/image/ImageManagerDriver.cc
	src/rm/RequestManagerAllocate.cc
This commit is contained in:
Ruben S. Montero 2012-06-12 18:59:23 +02:00
commit c503cea9a6
253 changed files with 28187 additions and 9545 deletions

View File

@ -212,7 +212,9 @@ build_scripts=[
'src/authm/SConstruct',
'src/acl/SConstruct',
'src/xml/SConstruct',
'share/man/SConstruct'
'share/man/SConstruct',
'src/sunstone/locale/languages/SConstruct',
'src/cloud/occi/lib/ui/locale/languages/SConstruct'
]
# Testing

View File

@ -18,6 +18,7 @@
#define ACL_MANAGER_H_
#include "AuthManager.h"
#include "AuthRequest.h"
#include "PoolObjectSQL.h"
#include "AclRule.h"

View File

@ -239,7 +239,10 @@ public:
};
/**
* Returns the string value
* @param name of the attribute
*
* @return the value of the attribute if found, empty otherwise
*/
string vector_value(const char *name) const;
@ -253,6 +256,17 @@ public:
*/
int vector_value(const char *name, int& value) const;
/**
* Returns the integer value
*
* @param name Name of the attribute
* @param value Integer value, if an error ocurred the string returned is
* empty and value set to -1;
*
* @return the value in string form on success, "" otherwise
*/
string vector_value_str(const char *name, int& value) const;
/**
* Marshall the attribute in a single string. The string MUST be freed
* by the calling function. The string is in the form:
@ -291,6 +305,18 @@ public:
*/
void replace(const string& name, const string& value);
/**
* Replace the value of the given vector attribute
*/
void replace(const string& name, int value)
{
ostringstream oss;
oss << value;
replace(name, oss.str());
}
/**
* Returns the attribute type
*/

View File

@ -21,11 +21,8 @@
#include "MadManager.h"
#include "ActionManager.h"
#include "SSLTools.h"
#include "AuthManagerDriver.h"
#include "PoolObjectSQL.h"
#include "PoolObjectAuth.h"
using namespace std;
@ -44,15 +41,10 @@ public:
AuthManager(
time_t timer,
time_t __time_out,
vector<const Attribute*>& _mads):
MadManager(_mads), timer_period(timer)
{
_time_out = __time_out;
am.addListener(this);
pthread_mutex_init(&mutex,0);
};
~AuthManager(){};
@ -99,32 +91,6 @@ public:
return authm_thread;
};
/**
* Notify the result of an auth request
*/
void notify_request(int auth_id, bool result, const string& message);
/**
* Discards a pending request. Call this before freeing not notified or
* timeout requests.
*/
void discard_request(int auth_id)
{
lock();
auth_requests.erase(auth_id);
unlock();
}
/**
* Gets default timeout for Auth requests
*/
static time_t time_out()
{
return _time_out;
}
/**
* Returns true if there is an authorization driver enabled
*
@ -146,21 +112,6 @@ private:
*/
ActionManager am;
/**
* List of pending requests
*/
map<int, AuthRequest *> auth_requests;
/**
* Mutex to access the auth_requests
*/
pthread_mutex_t mutex;
/**
* Default timeout for Auth requests
*/
static time_t _time_out;
/**
* Timer for the Manager (periocally triggers timer action)
*/
@ -230,287 +181,6 @@ private:
* This function authorizes a user request
*/
void authorize_action(AuthRequest * ar);
/**
* This function is periodically executed to check time_outs on requests
*/
void timer_action();
/**
* Function to lock the pool
*/
void lock()
{
pthread_mutex_lock(&mutex);
};
/**
* Function to unlock the pool
*/
void unlock()
{
pthread_mutex_unlock(&mutex);
};
/**
* Add a new request to the Request map
* @param ar pointer to the AuthRequest
* @return the id for the request
*/
int add_request(AuthRequest *ar);
/**
* Gets request from the Request map
* @param id for the request
* @return pointer to the AuthRequest
*/
AuthRequest * get_request(int id);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/**
* The AuthRequest class is used to pass an Authorization or Authentication
* request to the AuthManager. The result of the request will be stored
* in the result and message attributes of this class.
*/
class AuthRequest : public ActionListener
{
public:
AuthRequest(int _uid, int _gid):
result(false),
timeout(false),
uid(_uid),
gid(_gid),
time_out(0),
self_authorize(true)
{
am.addListener(this);
};
~AuthRequest(){};
/**
* Authorization Request Type
*/
enum Operation
{
USE = 0x1LL, /**< Auth. to use an object */
MANAGE = 0x2LL, /**< Auth. to perform management actions */
ADMIN = 0x4LL, /**< Auth. to perform administrative actions */
CREATE = 0x8LL /**< Auth. to create an object */
};
static string operation_to_str(Operation op)
{
switch (op)
{
case USE: return "USE";
case MANAGE: return "MANAGE";
case ADMIN: return "ADMIN";
case CREATE: return "CREATE";
default: return "";
}
};
/**
* Sets the challenge to authenticate an user
* @param challenge a driver specific authentication challenge
*/
void add_authenticate(const string &_driver,
const string &_username,
const string &_password,
const string &_session)
{
username = _username;
password = _password;
session = _session;
driver = _driver;
}
/**
* Adds a CREATE authorization request.
*
* OBJECT:<-1|OBJECT_TMPL_XML64>:CREATE:UID:AUTH
*
* @param type of the object to be created
* @param template (base64 encoded) of the new object
*/
void add_create_auth(PoolObjectSQL::ObjectType type, const string& txml_64)
{
PoolObjectAuth perms; //oid & gid set to -1
perms.uid = uid;
perms.obj_type = type;
add_auth(AuthRequest::CREATE, perms, txml_64);
}
/**
* Adds a new authorization item to this request
*
* OBJECT:OBJECT_ID:ACTION:OWNER:AUTH
*
* @param op the operation to be authorized
* @param ob_perms object's permission attributes
*/
void add_auth(Operation op,
const PoolObjectAuth& ob_perms)
{
add_auth(op, ob_perms, "");
}
/**
* Gets the authorization requests in a single string
* @return a space separated list of auth requests, or an empty string if
* no auth requests were added
*/
string get_auths()
{
ostringstream oss;
unsigned int i;
if ( auths.empty() )
{
return string();
}
for (i=0; i<auths.size()-1; i++)
{
oss << auths[i] << " ";
}
oss << auths[i];
return oss.str();
};
/**
* Notify client that we have an answer for the request
*/
void notify()
{
am.trigger(ActionListener::ACTION_FINALIZE,0);
};
/**
* Wait for the AuthRequest to be completed
*/
void wait()
{
time_out = time(0) + AuthManager::time_out();
am.loop(0,0);
};
bool core_authorize()
{
return ( uid == 0 || self_authorize );
}
bool core_authenticate()
{
string sha1_session = SSLTools::sha1_digest(session);
return (password == sha1_session);
}
/**
* The result of the request, true if authorized or authenticated
*/
bool result;
/**
* Error message for negative results
*/
string message;
/**
* Time out
*/
bool timeout;
/**
* Identification of this request
*/
int id;
private:
friend class AuthManager;
/**
* The ActionManager that will be notify when the request is ready.
*/
ActionManager am;
/**
* The user id for this request
*/
int uid;
/**
* The user group ID
*/
int gid;
/**
* Timeout for this request
*/
time_t time_out;
/**
* Username to authenticate the user
*/
string username;
/**
* User password to authenticate the user
*/
string password;
/**
* Authentication token as sent in the XML-RPC call (user:session)
*/
string session;
/**
* Authentication driver to be used with this request
*/
string driver;
/**
* A list of authorization requests
*/
vector<string> auths;
/**
* Plain authorization for the request
*/
bool self_authorize;
/**
* No actions defined for the Auth request, just FINALIZE when done
*/
void do_action(const string &name, void *args){};
/**
* Adds a new authorization item to this request, with a template for
* a new object
*
* OBJECT:<OBJECT_ID|OBJECT_TMPL_XML64>:ACTION:OWNER:AUTH
*
* @param op the operation to be authorized
* @param ob_perms object's permission attributes
* @param ob_template new object's template. If it is empty,
* it will be ignored
*/
void add_auth(Operation op,
const PoolObjectAuth& ob_perms,
string ob_template);
};
#endif /*AUTH_MANAGER_H*/

211
include/AuthRequest.h Normal file
View File

@ -0,0 +1,211 @@
/* -------------------------------------------------------------------------- */
/* 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 AUTH_REQUEST_H_
#define AUTH_REQUEST_H_
#include <time.h>
#include "ActionManager.h"
#include "PoolObjectAuth.h"
#include "SSLTools.h"
#include "AuthManager.h"
#include "SyncRequest.h"
using namespace std;
/**
* The AuthRequest class is used to pass an Authorization or Authentication
* request to the AuthManager. The result of the request will be stored
* in the result and message attributes of this class.
*/
class AuthRequest : public SyncRequest
{
public:
AuthRequest(int _uid, int _gid): uid(_uid),gid(_gid),self_authorize(true){};
~AuthRequest(){};
/**
* Authorization Request Type
*/
enum Operation
{
USE = 0x1LL, /**< Auth. to use an object */
MANAGE = 0x2LL, /**< Auth. to perform management actions */
ADMIN = 0x4LL, /**< Auth. to perform administrative actions */
CREATE = 0x8LL /**< Auth. to create an object */
};
static string operation_to_str(Operation op)
{
switch (op)
{
case USE: return "USE";
case MANAGE: return "MANAGE";
case ADMIN: return "ADMIN";
case CREATE: return "CREATE";
default: return "";
}
};
/**
* Sets the challenge to authenticate an user
* @param challenge a driver specific authentication challenge
*/
void add_authenticate(const string &_driver,
const string &_username,
const string &_password,
const string &_session)
{
username = _username;
password = _password;
session = _session;
driver = _driver;
}
/**
* Adds a CREATE authorization request.
*
* OBJECT:<-1|OBJECT_TMPL_XML64>:CREATE:UID:AUTH
*
* @param type of the object to be created
* @param template (base64 encoded) of the new object
*/
void add_create_auth(PoolObjectSQL::ObjectType type, const string& txml_64)
{
PoolObjectAuth perms; //oid & gid set to -1
perms.uid = uid;
perms.obj_type = type;
add_auth(AuthRequest::CREATE, perms, txml_64);
}
/**
* Adds a new authorization item to this request
*
* OBJECT:OBJECT_ID:ACTION:OWNER:AUTH
*
* @param op the operation to be authorized
* @param ob_perms object's permission attributes
*/
void add_auth(Operation op,
const PoolObjectAuth& ob_perms)
{
add_auth(op, ob_perms, "");
}
/**
* Gets the authorization requests in a single string
* @return a space separated list of auth requests, or an empty string if
* no auth requests were added
*/
string get_auths()
{
ostringstream oss;
unsigned int i;
if ( auths.empty() )
{
return string();
}
for (i=0; i<auths.size()-1; i++)
{
oss << auths[i] << " ";
}
oss << auths[i];
return oss.str();
};
bool core_authorize()
{
return ( uid == 0 || self_authorize );
}
bool core_authenticate()
{
string sha1_session = SSLTools::sha1_digest(session);
return (password == sha1_session);
}
private:
friend class AuthManager;
/**
* The user id for this request
*/
int uid;
/**
* The user group ID
*/
int gid;
/**
* Username to authenticate the user
*/
string username;
/**
* User password to authenticate the user
*/
string password;
/**
* Authentication token as sent in the XML-RPC call (user:session)
*/
string session;
/**
* Authentication driver to be used with this request
*/
string driver;
/**
* A list of authorization requests
*/
vector<string> auths;
/**
* Plain authorization for the request
*/
bool self_authorize;
/**
* Adds a new authorization item to this request, with a template for
* a new object
*
* OBJECT:<OBJECT_ID|OBJECT_TMPL_XML64>:ACTION:OWNER:AUTH
*
* @param op the operation to be authorized
* @param ob_perms object's permission attributes
* @param ob_template new object's template. If it is empty,
* it will be ignored
*/
void add_auth(Operation op,
const PoolObjectAuth& ob_perms,
string ob_template);
};
#endif

View File

@ -20,6 +20,7 @@
#include "PoolSQL.h"
#include "ObjectCollection.h"
#include "User.h"
#include "Quotas.h"
using namespace std;
@ -65,6 +66,11 @@ public:
return del_collection_id(id);
}
/**
* Object quotas, provides set and check interface
*/
Quotas quota;
private:
// -------------------------------------------------------------------------
@ -79,7 +85,11 @@ private:
Group(int id, const string& name):
PoolObjectSQL(id,GROUP,name,-1,-1,"","",table),
ObjectCollection("USERS")
ObjectCollection("USERS"),
quota("/GROUP/DATASTORE_QUOTA",
"/GROUP/NETWORK_QUOTA",
"/GROUP/IMAGE_QUOTA",
"/GROUP/VM_QUOTA")
{
// Allow users in this group to see it
group_u = 1;

View File

@ -123,6 +123,14 @@ public:
**/
int update_info(string &parse_str);
/**
* Inserts the last monitoring, and deletes old monitoring entries.
*
* @param db pointer to the db
* @return 0 on success
*/
int update_monitoring(SqlDB * db);
/**
* Retrives host state
* @return HostState code number
@ -377,6 +385,12 @@ private:
static const char * table;
static const char * monit_db_names;
static const char * monit_db_bootstrap;
static const char * monit_table;
/**
* Execute an INSERT or REPLACE Sql query.
* @param db The SQL DB
@ -392,9 +406,15 @@ private:
*/
static int bootstrap(SqlDB * db)
{
ostringstream oss_host(Host::db_bootstrap);
int rc;
return db->exec(oss_host);
ostringstream oss_host(Host::db_bootstrap);
ostringstream oss_monit(Host::monit_db_bootstrap);
rc = db->exec(oss_host);
rc += db->exec(oss_monit);
return rc;
};
/**

View File

@ -38,7 +38,8 @@ public:
HostPool(SqlDB * db,
vector<const Attribute *> hook_mads,
const string& hook_location,
const string& remotes_location);
const string& remotes_location,
time_t expire_time);
~HostPool(){};
@ -196,6 +197,60 @@ public:
return PoolSQL::search(oids, Host::table, where);
};
/**
* Dumps the host monitoring information entries in XML format. A filter
* can be also added to the query.
*
* @param oss the output stream to dump the pool contents
* @param where filter for the objects, defaults to all
*
* @return 0 on success
*/
int dump_monitoring(ostringstream& oss,
const string& where);
/**
* Dumps the HOST monitoring information for a single HOST
*
* @param oss the output stream to dump the pool contents
* @param hostid id of the target HOST
*
* @return 0 on success
*/
int dump_monitoring(ostringstream& oss,
int hostid)
{
ostringstream filter;
filter << "oid = " << hostid;
return dump_monitoring(oss, filter.str());
}
/**
* Inserts the last monitoring, and deletes old monitoring entries for this
* host
*
* @param host pointer to the host object
* @return 0 on success
*/
int update_monitoring(Host * host)
{
if ( _monitor_expiration <= 0 )
{
return 0;
}
return host->update_monitoring(db);
};
/**
* Deletes the expired monitoring entries for all hosts
*
* @return 0 on success
*/
int clean_expired_monitoring();
private:
/**
@ -216,6 +271,18 @@ private:
* @return 0 on success
*/
int discover_cb(void * _map, int num, char **values, char **names);
/**
* Deletes all monitoring entries for all hosts
*
* @return 0 on success
*/
int clean_all_monitoring();
/**
* Size, in seconds, of the historical monitoring information
*/
static time_t _monitor_expiration;
};
#endif /*HOST_POOL_H_*/

View File

@ -55,6 +55,13 @@ public:
}
};
/**
* Return the string representation of an ImageType
* @param ob the type
* @return the string
*/
static ImageType str_to_type(string& str_type);
/**
* Type of Disks (used by the VMM_MAD). Values: BLOCK, CDROM or
* FILE
@ -92,7 +99,10 @@ public:
USED = 2, /** < Image in use */
DISABLED = 3, /** < Image can not be instantiated by a VM */
LOCKED = 4, /** < FS operation for the Image in process */
ERROR = 5 /** < Error state the operation FAILED*/
ERROR = 5, /** < Error state the operation FAILED*/
CLONE = 6, /** < Image is being cloned */
DELETE = 7, /** < DS is deleting the image */
USED_PERS = 8 /** < Image is in use and persistent */
};
/**
@ -110,6 +120,9 @@ public:
case DISABLED: return "DISABLED"; break;
case LOCKED: return "LOCKED"; break;
case ERROR: return "ERROR"; break;
case CLONE: return "CLONE"; break;
case DELETE: return "DELETE"; break;
case USED_PERS: return "USED"; break;
default: return "";
}
};
@ -198,7 +211,7 @@ public:
* Returns the type of the image
* @return type
*/
ImageType get_type()
ImageType get_type() const
{
return type;
}
@ -221,30 +234,49 @@ public:
}
/**
*
* Return the ID of the image we are cloning this one from (if any)
*/
int get_cloning_id() const
{
return cloning_id;
}
/**
* Sets the ID of the image we are cloning this one from (if any)
*/
void set_cloning_id(int id)
{
cloning_id = id;
}
/**
* Clear the cloning state of the image
*/
void clear_cloning_id()
{
cloning_id = -1;
}
/* ---------------------------------------------------------------------- */
/* Acess Image Counters (running vms and clonning operations ) */
/* ---------------------------------------------------------------------- */
int dec_running ()
{
return --running_vms;
}
/**
*
*/
int inc_running()
{
return ++running_vms;
}
/**
*
*/
int get_running()
int get_running() const
{
return running_vms;
}
int get_cloning()
int get_cloning() const
{
return cloning_ops;
}
@ -259,21 +291,6 @@ public:
return ++cloning_ops;
}
int get_source_img()
{
return source_img_id;
}
void set_source_img(int id)
{
source_img_id = id;
}
void unset_source_img()
{
source_img_id = -1;
}
/**
* Sets the Image type.
*
@ -416,15 +433,12 @@ public:
};
/**
* Prepares a template to allocate a clone of this Image
*
* Clones this image template including image specific attributes: NAME,
* TYPE, PATH, FSTYPE, SIZE and PERSISTENT
* @param new_name Value for the NAME attribute
* @param tmpl Will contain the resulting template, if any
* @param error_str Returns the error reason, if any
* @return 0 in case of success, -1 otherwise
* @return Pointer to the new tempalte 0 in case of success
*/
int clone_template(string& new_name,
ImageTemplate * &tmpl, string& error_str) const;
ImageTemplate * clone_template(const string& new_name) const;
private:
@ -497,7 +511,7 @@ private:
* Indicates if this Image is a clone of another one.
* Once the clone process is complete, it should be set to -1
*/
int source_img_id;
int cloning_id;
/**
* Datastore ID

View File

@ -26,6 +26,7 @@ using namespace std;
extern "C" void * image_action_loop(void *arg);
class Image;
class Template;
class ImageManager : public MadManager, public ActionListener
{
@ -103,6 +104,12 @@ public:
*/
void release_image(int iid, bool failed);
/**
* Closes any cloning operation on the image, updating the state if needed
* @param iid image id of the image to be released
*/
void release_cloning_image(int iid);
/**
* Enables the image
* @param to_enable true will enable the image.
@ -125,6 +132,18 @@ public:
*/
int delete_image(int iid, const string& ds_data);
/**
* Gets the size of an image by calling the STAT action of the associated
* datastore driver.
*
* @param img_tmpl the template for the image
* @param ds_tmpl the template for the datastore
* @oaram result with a string representation of the size or if an error
* occurred describing the error.
* @result 0 on success
*/
int stat_image(Template* img_tmpl, const string& ds_tmpl, string& res);
private:
/**
* Generic name for the Image driver
@ -196,4 +215,3 @@ private:
};
#endif /*IMAGE_MANAGER_H*/

View File

@ -71,27 +71,26 @@ private:
//Template driver_conf;
/**
* Sends a copy request to the MAD
* Sends a copy request to the MAD.
* @param oid the image id.
* @param drv_msg xml data for the mad operation.
*/
void cp(int oid, const string& drv_msg) const;
/**
* Sends a move request to the MAD: "MV IMAGE_ID SRC_PATH DST_PATH"
* @param oid the image id.
* @param destination is a driver specific location or "-" if not
* initialized
* @param size_mb of the image to be created
* Sends a stat request to the MAD.
* @param oid the id of the stat request
* @param drv_msg xml data for the mad operation.
*/
void mv(int oid, const string& source, const string& destination) const;
void stat(int oid, const string& drv_msg) const;
/**
* Sends a make filesystem request to the MAD: "MKFS IMAGE_ID PATH SIZE_MB"
* Sends a make filesystem request to the MAD.
* @param oid the image id.
* @param drv_msg xml data for the mad operation.
*/
void mkfs(int oid, const string& drv_msg) const;
/**
* Sends a delete request to the MAD: "DELETE IMAGE_ID PATH"
* @param oid the image id.

View File

@ -29,7 +29,7 @@ class ImageTemplate : public Template
public:
ImageTemplate() : Template(true,'=',"TEMPLATE"){};
ImageTemplate(ImageTemplate& tmpl):Template(tmpl){};
ImageTemplate(const ImageTemplate& tmpl):Template(tmpl){};
~ImageTemplate(){};

View File

@ -30,6 +30,8 @@
using namespace std;
class SyncRequest;
extern "C" void * mad_manager_listener(void * _mm);
/**
@ -55,6 +57,11 @@ public:
*/
virtual void load_mads(int uid) = 0;
/**
* Notify the result of an auth request
*/
void notify_request(int id, bool result, const string& message);
protected:
MadManager(vector<const Attribute *>& _mads);
@ -94,6 +101,27 @@ protected:
*/
int add(Mad *mad);
/**
* This function can be periodically executed to check time_outs on
* request. It will fail requests with an expired timeout and will notify
* the clients.
*/
void check_time_outs_action();
/**
* Add a new request to the Request map
* @param ar pointer to the request
* @return the id for the request
*/
void add_request(SyncRequest *ar);
/**
* Gets request from the Request map
* @param id for the request
* @return pointer to the Request
*/
SyncRequest * get_request(int id);
private:
/**
* Function to lock the Manager
@ -156,6 +184,11 @@ private:
*/
ostringstream buffer;
/**
* List of pending requests
*/
map<int, SyncRequest *> sync_requests;
/**
* Listener thread implementation.
*/

175
include/Quota.h Normal file
View File

@ -0,0 +1,175 @@
/* -------------------------------------------------------------------------- */
/* 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 QUOTA_H_
#define QUOTA_H_
#include "Template.h"
/**
* Base class for resource quotas, it provides basic storage and management of
* 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
* the usage counters are updated
* @param tmpl template for the resource
* @param error string
* @return true if the operation can be performed
*/
virtual bool check(Template* tmpl, string& error) = 0;
/**
* Decrement usage counters when deallocating image
* @param tmpl template for the resource
*/
virtual void del(Template* tmpl) = 0;
/**
* Returns the name that identifies the quota in a template
*/
const char * get_quota_name()
{
return template_name;
}
protected:
Quota(const char * quota_name,
const char * _template_name,
const char ** _metrics,
int _num_metrics)
: Template(false, '=', quota_name),
template_name(_template_name),
metrics(_metrics),
num_metrics(_num_metrics){};
virtual ~Quota(){};
/**
* Generic Quota Names
*
* template_name = [
* ID = "ID to identify the resource",
* metrics[0] = "Limit for the first metric"
* metrics[0]_USED = "Usage for metric"
* ]
*
* ID & counter fields are optional
*/
/**
* Name of the quota used in the templates
*/
const char * template_name;
/**
* The name of the quota metrics
*/
const char ** metrics;
/**
* Length
*/
int num_metrics;
/**
* 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
* @return true if the request does not exceed current limits
*/
bool check_quota(const string& qid,
map<string, int>& usage_req,
string& error);
/**
* Reduce usage from a given quota based on the current consumption
* @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,
map<string, int>& usage_req);
/**
* Gets a quota identified by its ID.
* @param id of the quota
* @return a pointer to the quota or 0 if not found
*/
virtual int get_quota(const string& id, VectorAttribute **va);
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
*/
VectorAttribute * new_quota(VectorAttribute* va);
/**
* Adds a new quota, it also updates an internal index for fast accessing
* the quotas
* @param quota is the new quota, allocated in the HEAP
*/
void add(VectorAttribute * nq)
{
attributes.insert(make_pair(nq->name(), nq));
}
/**
* Adds a given value to the current quota (vector)
* @param attr the quota;
* @param va_name name of the quota in the vector attribute
* @param num value to add to the current quota;
*/
void add_to_quota(VectorAttribute * attr, const string& va_name, int 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);
/**
* Extract the limits for the defined quota metrics from a given attribute
* @param va the attribute with the limits
* @param limits stores the known limits
* @return 0 on success
*/
int get_limits(const VectorAttribute * va, map<string, string>& limits);
};
#endif /*QUOTA_H_*/

68
include/QuotaDatastore.h Normal file
View File

@ -0,0 +1,68 @@
/* -------------------------------------------------------------------------- */
/* 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 QUOTA_DATASTORE_H_
#define QUOTA_DATASTORE_H_
#include "Quota.h"
/**
* DataStore Quotas, defined as:
* DATASTORE = [
* ID = <ID of the datastore>
* IMAGES = <Max. number of images allowed in the datastore>
* SIZE = <Max. number of MB used in the datastore>
* IMAGES_USED = Current number of images in the datastore
* SIZE_USED = Current storage capacity un the datastore
* ]
*
* 0 = unlimited, default if missing
*/
class QuotaDatastore : public Quota
{
public:
QuotaDatastore():Quota("DATASTORE_QUOTA",
"DATASTORE",
DS_METRICS,
NUM_DS_METRICS)
{};
~QuotaDatastore(){};
/**
* 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
* @return true if the operation can be performed
*/
bool check(Template* tmpl, string& error);
/**
* Decrement usage counters when deallocating image
* @param tmpl template for the resource
*/
void del(Template* tmpl);
protected:
static const char * DS_METRICS[];
static const int NUM_DS_METRICS;
};
#endif /*QUOTA_DATASTORE_H_*/

View File

@ -1,4 +1,3 @@
#!/usr/bin/js
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */
/* */
@ -15,38 +14,53 @@
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
if (!arguments[0] || !arguments[1]){
print("Usage: upgrade_translation.js <old_translation> <empty_template> > <new_translation>");
quit();
#ifndef QUOTA_IMAGE_H_
#define QUOTA_IMAGE_H_
#include "Quota.h"
/**
* Image Quotas, defined as:
* IMAGE = [
* ID = <ID of the image>
* RVMS = <Max. number times the image can be instantiated>
* RVMS _USED = Current number of VMs using the image
* ]
*
* 0 = unlimited, default if missing
*/
class QuotaImage : public Quota
{
public:
QuotaImage():Quota("IMAGE_QUOTA",
"IMAGE",
IMAGE_METRICS,
NUM_IMAGE_METRICS)
{};
~QuotaImage(){};
/**
* 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
* @return true if the operation can be performed
*/
bool check(Template* tmpl, string& error);
/**
* Decrement usage counters when deallocating image
* @param tmpl template for the resource
*/
void del(Template* tmpl);
protected:
static const char * IMAGE_METRICS[];
static const int NUM_IMAGE_METRICS;
};
var from = arguments[0];
var to = arguments[1];
load(from);
var tr="";
var locale_old= {};
for (tr in locale){
locale_old[tr] = locale[tr];
};
var lang_old = lang;
var dt_lang_old = datatable_lang
load(to);
for (tr in locale){
if (locale_old[tr]){
locale[tr] = locale_old[tr]
};
};
print("//Translated by");
print('lang="'+lang_old+'"');
print('datatable_lang="'+dt_lang_old+'"');
print("locale={");
for (tr in locale){
print(' "'+tr+'":"'+locale[tr]+'",');
};
print("};");
#endif /*QUOTA_IMAGE_H_*/

View File

@ -1,4 +1,3 @@
#!/usr/bin/js
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */
/* */
@ -15,38 +14,53 @@
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
if (!arguments[0] || !arguments[1]){
print("Usage: upgrade_translation.js <old_translation> <empty_template> > <new_translation>");
quit();
#ifndef QUOTA_NETWORK_H_
#define QUOTA_NETWORK_H_
#include "Quota.h"
/**
* DataStore Quotas, defined as:
* NETWORK = [
* ID = <ID of the datastore>
* LEASES = <Max. number of IPs that can be leased from net>
* LEASES_USED = Current number of IPs
* ]
*
* 0 = unlimited, default if missing
*/
class QuotaNetwork : public Quota
{
public:
QuotaNetwork():Quota("NETWORK_QUOTA",
"NETWORK",
NET_METRICS,
NUM_NET_METRICS)
{};
~QuotaNetwork(){};
/**
* 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
* @return true if the operation can be performed
*/
bool check(Template* tmpl, string& error);
/**
* Decrement usage counters when deallocating image
* @param tmpl template for the resource
*/
void del(Template* tmpl);
protected:
static const char * NET_METRICS[];
static const int NUM_NET_METRICS;
};
var from = arguments[0];
var to = arguments[1];
load(from);
var tr="";
var locale_old= {};
for (tr in locale){
locale_old[tr] = locale[tr];
};
var lang_old = lang;
var dt_lang_old = datatable_lang
load(to);
for (tr in locale){
if (locale_old[tr]){
locale[tr] = locale_old[tr]
};
};
print("//Translated by");
print('lang="'+lang_old+'"');
print('datatable_lang="'+dt_lang_old+'"');
print("locale={");
for (tr in locale){
print(' "'+tr+'":"'+locale[tr]+'",');
};
print("};");
#endif /*QUOTA_NETWORK_H_*/

View File

@ -0,0 +1,76 @@
/* -------------------------------------------------------------------------- */
/* 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 QUOTA_VIRTUALMACHINE_H_
#define QUOTA_VIRTUALMACHINE_H_
#include "Quota.h"
/**
* VM Quotas, defined as:
* VM = [
* VMS = <Max. number of VMs>
* MEMORY = <Max. number of MB requested by VMs>
* CPU = <Max. number of CPU units requested by VMs>
* VMS_USED = Current number of VMs
* MEMORY_USED = Overall Memory requested
* CPU_USED = Overall CPU requested
* ]
*
* 0 = unlimited, default if missing
*/
class QuotaVirtualMachine : public Quota
{
public:
QuotaVirtualMachine():Quota("VM_QUOTA",
"VM",
VM_METRICS,
NUM_VM_METRICS)
{};
~QuotaVirtualMachine(){};
/**
* 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
* @return true if the operation can be performed
*/
bool check(Template* tmpl, string& error);
/**
* Decrement usage counters when deallocating image
* @param tmpl template for the resource
*/
void del(Template* tmpl);
/**
* Gets a quota, overrides base to not to use ID.
* @param id of the quota
* @return a pointer to the quota or 0 if not found
*/
int get_quota(const string& id, VectorAttribute **va);
protected:
static const char * VM_METRICS[];
static const int NUM_VM_METRICS;
};
#endif /*QUOTA_VIRTUALMACHINE_H_*/

284
include/Quotas.h Normal file
View File

@ -0,0 +1,284 @@
/* -------------------------------------------------------------------------- */
/* 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 QUOTAS_H_
#define QUOTAS_H_
#include "QuotaDatastore.h"
#include "QuotaNetwork.h"
#include "QuotaVirtualMachine.h"
#include "QuotaImage.h"
class Quotas
{
public:
Quotas(const char * _ds_xpath,
const char * _net_xpath,
const char * _img_xpath,
const char * _vm_xpath):
ds_xpath(_ds_xpath),
net_xpath(_net_xpath),
img_xpath(_img_xpath),
vm_xpath(_vm_xpath)
{};
virtual ~Quotas(){};
/**
* Set the quotas
* @param tmpl contains the user quota limits
* @param error describes error when setting the quotas
*
* @return 0 on success, -1 otherwise
*/
int set(Template *tmpl, string& error)
{
vector<Attribute *> vquotas;
if ( tmpl->get(datastore_quota.get_quota_name(), vquotas) > 0 )
{
if ( datastore_quota.set(&vquotas, error) != 0 )
{
return -1;
}
vquotas.clear();
}
if ( tmpl->get(network_quota.get_quota_name(), vquotas) > 0 )
{
if ( network_quota.set(&vquotas, error) != 0 )
{
return -1;
}
vquotas.clear();
}
if ( tmpl->get(image_quota.get_quota_name(), vquotas) > 0 )
{
if ( image_quota.set(&vquotas, error) != 0 )
{
return -1;
}
vquotas.clear();
}
if ( tmpl->get(vm_quota.get_quota_name(), vquotas) > 0 )
{
if ( vm_quota.set(&vquotas, error) != 0 )
{
return -1;
}
vquotas.clear();
}
return 0;
}
/**
* 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
*/
void ds_del(Template * tmpl)
{
return 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)
{
if ( network_quota.check(tmpl, error_str) == false )
{
return false;
}
if ( vm_quota.check(tmpl, error_str) == false )
{
network_quota.del(tmpl);
return false;
}
if ( image_quota.check(tmpl, error_str) == false )
{
network_quota.del(tmpl);
vm_quota.del(tmpl);
return false;
}
return true;
}
/**
* Delete VM related usage (network, image and compute) from quota counters.
* @param tmpl template for the image, with usage
*/
void vm_del(Template * tmpl)
{
network_quota.del(tmpl);
vm_quota.del(tmpl);
image_quota.del(tmpl);
}
/**
* 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
{
ostringstream oss;
string ds_quota_xml;
string net_quota_xml;
string vm_quota_xml;
string image_quota_xml;
oss << datastore_quota.to_xml(ds_quota_xml)
<< network_quota.to_xml(net_quota_xml)
<< vm_quota.to_xml(vm_quota_xml)
<< image_quota.to_xml(image_quota_xml);
xml = oss.str();
return xml;
}
/**
* Builds quota object from an ObjectXML
* @param object_xml pointer to the ObjectXML
* @return 0 if success
*/
int from_xml(ObjectXML * object_xml)
{
vector<xmlNodePtr> content;
int rc = 0;
object_xml->get_nodes(ds_xpath, content);
if (!content.empty())
{
rc += datastore_quota.from_xml_node(content[0]);
}
object_xml->free_nodes(content);
content.clear();
object_xml->get_nodes(net_xpath, content);
if (!content.empty())
{
rc += network_quota.from_xml_node(content[0]);
}
object_xml->free_nodes(content);
content.clear();
object_xml->get_nodes(vm_xpath, content);
if (!content.empty())
{
rc += vm_quota.from_xml_node(content[0]);
}
object_xml->free_nodes(content);
content.clear();
object_xml->get_nodes(img_xpath, content);
if (!content.empty())
{
rc += image_quota.from_xml_node(content[0]);
}
object_xml->free_nodes(content);
return rc;
}
private:
//--------------------------------------------------------------------------
// Usage Counters and Quotas
//--------------------------------------------------------------------------
/**
* Datastore Quotas
*/
QuotaDatastore datastore_quota;
/**
* Network Quotas
*/
QuotaNetwork network_quota;
/**
* Image Quotas
*/
QuotaImage image_quota;
/**
* Virtual Machine Quotas
*/
QuotaVirtualMachine vm_quota;
//--------------------------------------------------------------------------
// XPaths
//--------------------------------------------------------------------------
/**
* Path for the datastore quota object
*/
const char * ds_xpath;
/**
* Path for the network quota object
*/
const char * net_xpath;
/**
* Path for the image quota object
*/
const char * img_xpath;
/**
* Path for the vm quota object
*/
const char * vm_xpath;
};
#endif /*QUOTABLE_H_*/

View File

@ -21,7 +21,7 @@
#include <xmlrpc-c/registry.hpp>
#include "RequestManager.h"
#include "AuthManager.h"
#include "AuthRequest.h"
#include "PoolObjectSQL.h"
using namespace std;
@ -75,6 +75,32 @@ protected:
string session; /**< Session from ONE XML-RPC API */
xmlrpc_c::value * retval; /**< Return value from libxmlrpc-c */
RequestAttributes(){};
RequestAttributes(const RequestAttributes& ra)
{
uid = ra.uid;
gid = ra.gid;
uname = ra.uname;
gname = ra.gname;
session = ra.session;
retval = ra.retval;
};
RequestAttributes(int _uid, int _gid, const RequestAttributes& ra)
{
uid = _uid;
gid = _gid;
uname = "";
gname = "";
session = ra.session;
retval = ra.retval;
};
};
/* -------- Static (shared among request of the same method) -------- */
@ -131,6 +157,53 @@ protected:
bool basic_authorization(int oid, AuthRequest::Operation op,
RequestAttributes& att);
/**
* Performs a basic quota check for this request using the uid/gid and
* object type from the request. Usage counters are updated for the
* user/group.
* @param tmpl describing the object
* @param att the specific request attributes
*
* @return true if the user is authorized.
*/
bool quota_authorization(Template * tmpl, RequestAttributes& att)
{
return quota_authorization(tmpl, auth_object, att);
}
/**
* Performs a basic quota check for this request using the uid/gid
* from the request. Usage counters are updated for the user/group.
* @param tmpl describing the object
* @param object type of the object
* @param att the specific request attributes
*
* @return true if the user is authorized.
*/
bool quota_authorization(Template * tmpl,
PoolObjectSQL::ObjectType object,
RequestAttributes& att);
/**
* Performs rollback on usage counters for a previous quota check operation
* for the request.
* @param tmpl describing the object
* @param att the specific request attributes
*/
void quota_rollback(Template * tmpl, RequestAttributes& att)
{
quota_rollback(tmpl, auth_object, att);
}
/**
* Performs rollback on usage counters for a previous quota check operation
* for the request.
* @param tmpl describing the object
* @param att the specific request attributes
*/
void quota_rollback(Template * tmpl,
PoolObjectSQL::ObjectType object,
RequestAttributes& att);
/**
* Actual Execution method for the request. Must be implemented by the
* XML-RPC requests
@ -239,6 +312,27 @@ protected:
RequestAttributes& att,
PoolObjectAuth& perms,
string& name);
private:
/* ------------- Functions to manage user and group quotas -------------- */
bool user_quota_authorization(Template * tmpl,
PoolObjectSQL::ObjectType object,
RequestAttributes& att,
string& error_str);
bool group_quota_authorization(Template * tmpl,
PoolObjectSQL::ObjectType object,
RequestAttributes& att,
string& error_str);
void user_quota_rollback(Template * tmpl,
PoolObjectSQL::ObjectType object,
RequestAttributes& att);
void group_quota_rollback(Template * tmpl,
PoolObjectSQL::ObjectType object,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */

View File

@ -196,7 +196,6 @@ public:
{
Nebula& nd = Nebula::instance();
pool = nd.get_ipool();
dspool = nd.get_dspool();
auth_object = PoolObjectSQL::IMAGE;
};
@ -210,9 +209,6 @@ public:
bool allocate_authorization(Template * obj_template,
RequestAttributes& att,
PoolObjectAuth * cluster_perms);
private:
DatastorePool * dspool;
};
/* ------------------------------------------------------------------------- */

View File

@ -52,6 +52,11 @@ protected:
virtual void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
PoolObjectSQL * get_and_quota(int oid,
int new_uid,
int new_gid,
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */

View File

@ -0,0 +1,72 @@
/* -------------------------------------------------------------------------- */
/* 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 REQUEST_MANAGER_GROUP_H
#define REQUEST_MANAGER_GROUP_H
#include "Request.h"
#include "Nebula.h"
using namespace std;
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class RequestManagerGroup: public Request
{
protected:
RequestManagerGroup(const string& method_name,
const string& help,
const string& params)
:Request(method_name,params,help)
{
Nebula& nd = Nebula::instance();
pool = nd.get_gpool();
auth_object = PoolObjectSQL::GROUP;
};
virtual ~RequestManagerGroup(){};
virtual void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att) = 0;
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class GroupSetQuota : public RequestManagerGroup
{
public:
GroupSetQuota():
RequestManagerGroup("GroupSetQuota",
"Sets group quota limits",
"A:sis")
{
auth_op = AuthRequest::ADMIN;
};
~GroupSetQuota(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#endif

View File

@ -68,6 +68,26 @@ public:
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class HostMonitoring : public RequestManagerHost
{
public:
HostMonitoring():
RequestManagerHost("HostMonitoring",
"Returns the host monitoring records",
"A:si")
{
auth_op = AuthRequest::USE;
};
~HostMonitoring(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -111,18 +111,12 @@ public:
"A:sis")
{
auth_op = AuthRequest::USE;
Nebula& nd = Nebula::instance();
dspool = nd.get_dspool();
};
~ImageClone(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
private:
DatastorePool * dspool;
};
/* -------------------------------------------------------------------------- */

View File

@ -132,6 +132,31 @@ public:
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class VirtualMachinePoolMonitoring : public RequestManagerPoolInfoFilter
{
public:
VirtualMachinePoolMonitoring():
RequestManagerPoolInfoFilter("VirtualMachinePoolMonitoring",
"Returns the virtual machine monitoring records",
"A:si")
{
Nebula& nd = Nebula::instance();
pool = nd.get_vmpool();
auth_object = PoolObjectSQL::VM;
};
~VirtualMachinePoolMonitoring(){};
/* -------------------------------------------------------------------- */
void request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class TemplatePoolInfo : public RequestManagerPoolInfoFilter
{
public:
@ -213,6 +238,31 @@ public:
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class HostPoolMonitoring : public RequestManagerPoolInfoFilter
{
public:
HostPoolMonitoring():
RequestManagerPoolInfoFilter("HostPoolMonitoring",
"Returns the host monitoring records",
"A:s")
{
Nebula& nd = Nebula::instance();
pool = nd.get_hpool();
auth_object = PoolObjectSQL::HOST;
};
~HostPoolMonitoring(){};
/* -------------------------------------------------------------------- */
void request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class GroupPoolInfo: public RequestManagerPoolInfoFilter
{
public:

View File

@ -97,6 +97,27 @@ public:
string& err);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class UserSetQuota : public RequestManagerUser
{
public:
UserSetQuota():
RequestManagerUser("UserSetQuota",
"Sets user quota limits",
"A:sis")
{
auth_op = AuthRequest::ADMIN;
};
~UserSetQuota(){};
int user_action(int user_id,
xmlrpc_c::paramList const& _paramList,
string& err);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -143,6 +143,29 @@ public:
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class VirtualMachineMonitoring : public RequestManagerVirtualMachine
{
public:
VirtualMachineMonitoring():
RequestManagerVirtualMachine("VirtualMachineMonitoring",
"Returns the virtual machine monitoring records",
"A:si")
{
auth_op = AuthRequest::USE;
};
~VirtualMachineMonitoring(){};
/* -------------------------------------------------------------------- */
void request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

101
include/SyncRequest.h Normal file
View File

@ -0,0 +1,101 @@
/* -------------------------------------------------------------------------- */
/* 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 SYNC_REQUEST_H_
#define SYNC_REQUEST_H_
#include <time.h>
#include "ActionManager.h"
/**
* Base class to implement synchronous operation in the MadManagers. This class
* cannot be directly instantiated.
*/
class SyncRequest: public ActionListener
{
public:
SyncRequest():
result(false),
message(""),
timeout(false),
id(-1),
time_out(0)
{
am.addListener(this);
};
virtual ~SyncRequest(){};
/**
* The result of the request, true if the operation succeeded
*/
bool result;
/**
* Error message for negative results
*/
string message;
/**
* Time out, true if the request ended because of a time out
*/
bool timeout;
/**
* Identification of this request
*/
int id;
/**
* Notify client that we have an answer for the request
*/
void notify()
{
am.trigger(ActionListener::ACTION_FINALIZE,0);
};
/**
* Wait for the AuthRequest to be completed
*/
void wait()
{
time_out = time(0) + 90;//Requests will expire in 1.5 minutes
am.loop(0,0);
};
protected:
friend class MadManager;
/**
* Time in seconds when this request will expire
*/
time_t time_out;
/**
* The ActionManager that will be notify when the request is ready.
*/
ActionManager am;
/**
* No actions defined for the request, just FINALIZE when done
*/
void do_action(const string &name, void *args){};
};
#endif /*SYNC_REQUEST_H_*/

View File

@ -143,6 +143,47 @@ public:
*/
int replace(const string& name, const string& value);
/**
* Adds a new attribute to the template (replacing it if
* already defined)
* @param name of the new attribute
* @param value of the new attribute
* @return 0 on success
*/
int replace(const string& name, int value)
{
ostringstream oss;
oss << value;
return replace(name, oss.str());
}
/*
* Adds a new single attribute to the template. It will replace an existing
* one if replace_mode was set to true
* @param name of the attribute
* @param value of the attribute
*/
void add(const string& name, const string& value)
{
set(new SingleAttribute(name, value));
}
/**
* Adds a new single attribute to the template.
* @param name of the attribute
* @param value of the attribute
*/
void add(const string& name, int value)
{
ostringstream oss;
oss << value;
set(new SingleAttribute(name, oss.str()));
}
/**
* Removes an attribute from the template. The attributes are returned. The
* attributes MUST be freed by the calling funtion

View File

@ -19,6 +19,7 @@
#include "PoolSQL.h"
#include "UserTemplate.h"
#include "Quotas.h"
using namespace std;
@ -167,6 +168,11 @@ public:
return new UserTemplate;
}
/**
* Object quotas, provides set and check interface
*/
Quotas quota;
private:
// -------------------------------------------------------------------------
// Friends
@ -289,6 +295,10 @@ protected:
const string& _auth_driver,
bool _enabled):
PoolObjectSQL(id,USER,_uname,-1,_gid,"",_gname,table),
quota("/USER/DATASTORE_QUOTA",
"/USER/NETWORK_QUOTA",
"/USER/IMAGE_QUOTA",
"/USER/VM_QUOTA"),
password(_password),
auth_driver(_auth_driver),
enabled(_enabled),

View File

@ -131,7 +131,8 @@ public:
string& uname,
string& gname);
/**
* Returns whether there is a user with given username/password or not
* Returns whether the operations described in a authorization request are
* authorized ot not.
* @param ar, an Authorization Request
* @return -1 if authz failed, 0 otherwise
*/

View File

@ -569,6 +569,17 @@ public:
return new VirtualMachineTemplate;
}
/**
* Returns a copy of the VirtualMachineTemplate
* @return A copy of the VirtualMachineTemplate
*/
VirtualMachineTemplate * clone_template() const
{
return new VirtualMachineTemplate(
*(static_cast<VirtualMachineTemplate *>(obj_template)));
};
// ------------------------------------------------------------------------
// States
// ------------------------------------------------------------------------
@ -838,9 +849,11 @@ private:
int rc;
ostringstream oss_vm(VirtualMachine::db_bootstrap);
ostringstream oss_monit(VirtualMachine::monit_db_bootstrap);
ostringstream oss_hist(History::db_bootstrap);
rc = db->exec(oss_vm);
rc += db->exec(oss_monit);
rc += db->exec(oss_hist);
return rc;
@ -895,6 +908,14 @@ private:
return -1;
};
/**
* Inserts the last monitoring, and deletes old monitoring entries.
*
* @param db pointer to the db
* @return 0 on success
*/
int update_monitoring(SqlDB * db);
// -------------------------------------------------------------------------
// Attribute Parser
// -------------------------------------------------------------------------
@ -971,6 +992,12 @@ protected:
static const char * db_bootstrap;
static const char * monit_table;
static const char * monit_db_names;
static const char * monit_db_bootstrap;
/**
* Reads the Virtual Machine (identified with its OID) from the database.
* @param db pointer to the db

View File

@ -36,7 +36,8 @@ public:
vector<const Attribute *> hook_mads,
const string& hook_location,
const string& remotes_location,
vector<const Attribute *>& restricted_attrs);
vector<const Attribute *>& restricted_attrs,
time_t expire_time);
~VirtualMachinePool(){};
@ -75,6 +76,26 @@ public:
return static_cast<VirtualMachine *>(PoolSQL::get(oid,lock));
};
/**
* Function to get a VM from the pool, string version for VM ID
*/
VirtualMachine * get(
const string& oid_s,
bool lock)
{
istringstream iss(oid_s);
int oid;
iss >> oid;
if ( iss.fail() )
{
return 0;
}
return static_cast<VirtualMachine *>(PoolSQL::get(oid,lock));
};
/**
* Function to get the IDs of running VMs
* @param oids a vector that contains the IDs
@ -122,6 +143,38 @@ public:
return vm->update_previous_history(db);
}
/**
* Inserts the last monitoring, and deletes old monitoring entries for this
* VM
*
* @param vm pointer to the virtual machine object
* @return 0 on success
*/
int update_monitoring(
VirtualMachine * vm)
{
if ( _monitor_expiration <= 0 )
{
return 0;
}
return vm->update_monitoring(db);
};
/**
* Deletes the expired monitoring entries for all VMs
*
* @return 0 on success
*/
int clean_expired_monitoring();
/**
* Deletes all monitoring entries for all VMs
*
* @return 0 on success
*/
int clean_all_monitoring();
/**
* Bootstraps the database table(s) associated to the VirtualMachine pool
* @return 0 on success
@ -157,6 +210,37 @@ public:
const string& where,
int time_start,
int time_end);
/**
* Dumps the VM monitoring information entries in XML format. A filter
* can be also added to the query.
*
* @param oss the output stream to dump the pool contents
* @param where filter for the objects, defaults to all
*
* @return 0 on success
*/
int dump_monitoring(ostringstream& oss,
const string& where);
/**
* Dumps the VM monitoring information for a single VM
*
* @param oss the output stream to dump the pool contents
* @param vmid id of the target VM
*
* @return 0 on success
*/
int dump_monitoring(ostringstream& oss,
int vmid)
{
ostringstream filter;
filter << "oid = " << vmid;
return dump_monitoring(oss, filter.str());
}
private:
/**
* Factory method to produce VM objects
@ -166,6 +250,11 @@ private:
{
return new VirtualMachine(-1,-1,-1,"","",0);
};
/**
* Size, in seconds, of the historical monitoring information
*/
static time_t _monitor_expiration;
};
#endif /*VIRTUAL_MACHINE_POOL_H_*/

View File

@ -203,8 +203,7 @@ LIB_DIRS="$LIB_LOCATION/ruby \
$LIB_LOCATION/mads \
$LIB_LOCATION/sh \
$LIB_LOCATION/ruby/cli \
$LIB_LOCATION/ruby/cli/one_helper \
$LIB_LOCATION/ruby/acct"
$LIB_LOCATION/ruby/cli/one_helper"
VAR_DIRS="$VAR_LOCATION/remotes \
$VAR_LOCATION/remotes/im \
@ -246,7 +245,6 @@ VAR_DIRS="$VAR_LOCATION/remotes \
$VAR_LOCATION/remotes/auth/ldap \
$VAR_LOCATION/remotes/auth/server_x509 \
$VAR_LOCATION/remotes/auth/server_cipher \
$VAR_LOCATION/remotes/auth/quota \
$VAR_LOCATION/remotes/auth/dummy"
SUNSTONE_DIRS="$SUNSTONE_LOCATION/models \
@ -271,6 +269,9 @@ SUNSTONE_DIRS="$SUNSTONE_LOCATION/models \
$SUNSTONE_LOCATION/public/vendor/jGrowl \
$SUNSTONE_LOCATION/public/vendor/flot \
$SUNSTONE_LOCATION/public/vendor/fileuploader \
$SUNSTONE_LOCATION/public/vendor/FontAwesome \
$SUNSTONE_LOCATION/public/vendor/FontAwesome/css \
$SUNSTONE_LOCATION/public/vendor/FontAwesome/font \
$SUNSTONE_LOCATION/public/images \
$SUNSTONE_LOCATION/templates \
$SUNSTONE_LOCATION/views"
@ -287,6 +288,9 @@ OZONES_DIRS="$OZONES_LOCATION/lib \
$OZONES_LOCATION/public/vendor/jQueryUI \
$OZONES_LOCATION/public/vendor/jQueryUI/images \
$OZONES_LOCATION/public/vendor/jGrowl \
$OZONES_LOCATION/public/vendor/FontAwesome \
$OZONES_LOCATION/public/vendor/FontAwesome/css \
$OZONES_LOCATION/public/vendor/FontAwesome/font \
$OZONES_LOCATION/public/js \
$OZONES_LOCATION/public/js/plugins \
$OZONES_LOCATION/public/images \
@ -317,7 +321,10 @@ SELF_SERVICE_DIRS="\
$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/flot \
$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/crypto-js \
$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/fileuploader \
$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/xml2json"
$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/xml2json \
$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/FontAwesome \
$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/FontAwesome/css \
$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/FontAwesome/font"
OZONES_CLIENT_DIRS="$LIB_LOCATION/ruby \
$LIB_LOCATION/ruby/OpenNebula \
@ -384,7 +391,6 @@ INSTALL_FILES=(
AUTH_SERVER_CIPHER_FILES:$VAR_LOCATION/remotes/auth/server_cipher
AUTH_DUMMY_FILES:$VAR_LOCATION/remotes/auth/dummy
AUTH_PLAIN_FILES:$VAR_LOCATION/remotes/auth/plain
AUTH_QUOTA_FILES:$VAR_LOCATION/remotes/auth/quota
VMM_EXEC_KVM_SCRIPTS:$VAR_LOCATION/remotes/vmm/kvm
VMM_EXEC_XEN_SCRIPTS:$VAR_LOCATION/remotes/vmm/xen
VMM_EXEC_VMWARE_SCRIPTS:$VAR_LOCATION/remotes/vmm/vmware
@ -423,8 +429,6 @@ INSTALL_FILES=(
MAN_FILES:$MAN_LOCATION
CLI_LIB_FILES:$LIB_LOCATION/ruby/cli
ONE_CLI_LIB_FILES:$LIB_LOCATION/ruby/cli/one_helper
ACCT_LIB_FILES:$LIB_LOCATION/ruby/acct
ACCT_BIN_FILES:$BIN_LOCATION
)
INSTALL_CLIENT_FILES=(
@ -471,6 +475,9 @@ INSTALL_SUNSTONE_FILES=(
SUNSTONE_PUBLIC_VENDOR_JQUERYLAYOUT:$SUNSTONE_LOCATION/public/vendor/jQueryLayout
SUNSTONE_PUBLIC_VENDOR_FLOT:$SUNSTONE_LOCATION/public/vendor/flot
SUNSTONE_PUBLIC_VENDOR_FILEUPLOADER:$SUNSTONE_LOCATION/public/vendor/fileuploader
SUNSTONE_PUBLIC_VENDOR_FONTAWESOME:$SUNSTONE_LOCATION/public/vendor/FontAwesome
SUNSTONE_PUBLIC_VENDOR_FONTAWESOME_FONT:$SUNSTONE_LOCATION/public/vendor/FontAwesome/font
SUNSTONE_PUBLIC_VENDOR_FONTAWESOME_CSS:$SUNSTONE_LOCATION/public/vendor/FontAwesome/css
SUNSTONE_PUBLIC_IMAGES_FILES:$SUNSTONE_LOCATION/public/images
SUNSTONE_PUBLIC_LOCALE_EN_US:$SUNSTONE_LOCATION/public/locale/en_US
SUNSTONE_PUBLIC_LOCALE_RU:$SUNSTONE_LOCATION/public/locale/ru
@ -501,6 +508,9 @@ INSTALL_OZONES_FILES=(
OZONES_PUBLIC_VENDOR_JQUERYUI:$OZONES_LOCATION/public/vendor/jQueryUI
OZONES_PUBLIC_VENDOR_JQUERYUIIMAGES:$OZONES_LOCATION/public/vendor/jQueryUI/images
OZONES_PUBLIC_VENDOR_JQUERYLAYOUT:$OZONES_LOCATION/public/vendor/jQueryLayout
OZONES_PUBLIC_VENDOR_FONTAWESOME:$OZONES_LOCATION/public/vendor/FontAwesome
OZONES_PUBLIC_VENDOR_FONTAWESOME_FONT:$OZONES_LOCATION/public/vendor/FontAwesome/font
OZONES_PUBLIC_VENDOR_FONTAWESOME_CSS:$OZONES_LOCATION/public/vendor/FontAwesome/css
OZONES_PUBLIC_JS_FILES:$OZONES_LOCATION/public/js
OZONES_PUBLIC_IMAGES_FILES:$OZONES_LOCATION/public/images
OZONES_PUBLIC_CSS_FILES:$OZONES_LOCATION/public/css
@ -533,6 +543,9 @@ INSTALL_SELF_SERVICE_FILES=(
SELF_SERVICE_PUBLIC_VENDOR_CRYPTOJS:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/crypto-js
SELF_SERVICE_PUBLIC_VENDOR_FILEUPLOADER:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/fileuploader
SELF_SERVICE_PUBLIC_VENDOR_XML2JSON:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/xml2json
SELF_SERVICE_PUBLIC_VENDOR_FONTAWESOME:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/FontAwesome
SELF_SERVICE_PUBLIC_VENDOR_FONTAWESOME_CSS:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/FontAwesome/css
SELF_SERVICE_PUBLIC_VENDOR_FONTAWESOME_FONT:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/FontAwesome/font
SELF_SERVICE_PUBLIC_IMAGES_FILES:$LIB_LOCATION/ruby/cloud/occi/ui/public/images
SELF_SERVICE_PUBLIC_LOCALE_EN_US:$LIB_LOCATION/ruby/cloud/occi/ui/public/locale/en_US
SELF_SERVICE_PUBLIC_LOCALE_ES_ES:$LIB_LOCATION/ruby/cloud/occi/ui/public/locale/es_ES
@ -553,7 +566,6 @@ INSTALL_ETC_FILES=(
OCCI_ETC_FILES:$ETC_LOCATION
OCCI_ETC_TEMPLATE_FILES:$ETC_LOCATION/occi_templates
CLI_CONF_FILES:$ETC_LOCATION/cli
ACCT_ETC_FILES:$ETC_LOCATION
)
#-------------------------------------------------------------------------------
@ -574,7 +586,7 @@ BIN_FILES="src/nebula/oned \
src/cli/onedatastore \
src/cli/onecluster \
src/onedb/onedb \
src/authm_mad/remotes/quota/onequota \
src/onedb/onezonedb/onezonedb \
src/mad/utils/tty_expect \
share/scripts/one"
@ -601,7 +613,6 @@ RUBY_LIB_FILES="src/mad/ruby/ActionManager.rb \
src/mad/ruby/Ganglia.rb \
src/oca/ruby/OpenNebula.rb \
src/authm_mad/remotes/ssh/ssh_auth.rb \
src/authm_mad/remotes/quota/quota.rb \
src/authm_mad/remotes/server_x509/server_x509_auth.rb \
src/authm_mad/remotes/server_cipher/server_cipher_auth.rb \
src/authm_mad/remotes/ldap/ldap_auth.rb \
@ -732,8 +743,6 @@ AUTH_DUMMY_FILES="src/authm_mad/remotes/dummy/authenticate"
AUTH_PLAIN_FILES="src/authm_mad/remotes/plain/authenticate"
AUTH_QUOTA_FILES="src/authm_mad/remotes/quota/authorize"
#-------------------------------------------------------------------------------
# Virtual Network Manager drivers to be installed under $REMOTES_LOCATION/vnm
#-------------------------------------------------------------------------------
@ -854,23 +863,28 @@ DATASTORE_DRIVER_COMMON_SCRIPTS="src/datastore_mad/remotes/xpath.rb \
DATASTORE_DRIVER_DUMMY_SCRIPTS="src/datastore_mad/remotes/dummy/cp \
src/datastore_mad/remotes/dummy/mkfs \
src/datastore_mad/remotes/dummy/stat \
src/datastore_mad/remotes/dummy/rm"
DATASTORE_DRIVER_FS_SCRIPTS="src/datastore_mad/remotes/fs/cp \
src/datastore_mad/remotes/fs/mkfs \
src/datastore_mad/remotes/fs/stat \
src/datastore_mad/remotes/fs/rm"
DATASTORE_DRIVER_VMWARE_SCRIPTS="src/datastore_mad/remotes/vmware/cp \
src/datastore_mad/remotes/vmware/mkfs \
src/datastore_mad/remotes/vmware/stat \
src/datastore_mad/remotes/vmware/rm"
DATASTORE_DRIVER_ISCSI_SCRIPTS="src/datastore_mad/remotes/iscsi/cp \
src/datastore_mad/remotes/iscsi/mkfs \
src/datastore_mad/remotes/iscsi/stat \
src/datastore_mad/remotes/iscsi/rm \
src/datastore_mad/remotes/iscsi/iscsi.conf"
DATASTORE_DRIVER_LVM_SCRIPTS="src/datastore_mad/remotes/lvm/cp \
src/datastore_mad/remotes/lvm/mkfs \
src/datastore_mad/remotes/lvm/stat \
src/datastore_mad/remotes/lvm/rm \
src/datastore_mad/remotes/lvm/lvm.conf"
@ -937,7 +951,6 @@ HM_ETC_FILES="src/hm_mad/hmrc"
#-------------------------------------------------------------------------------
AUTH_ETC_FILES="src/authm_mad/remotes/server_x509/server_x509_auth.conf \
src/authm_mad/remotes/quota/quota.conf \
src/authm_mad/remotes/ldap/ldap_auth.conf \
src/authm_mad/remotes/x509/x509_auth.conf"
@ -1109,6 +1122,7 @@ ONE_CLI_LIB_FILES="src/cli/one_helper/onegroup_helper.rb \
src/cli/one_helper/onehost_helper.rb \
src/cli/one_helper/oneimage_helper.rb \
src/cli/one_helper/onetemplate_helper.rb \
src/cli/one_helper/onequota_helper.rb \
src/cli/one_helper/oneuser_helper.rb \
src/cli/one_helper/onevm_helper.rb \
src/cli/one_helper/onevnet_helper.rb \
@ -1136,7 +1150,8 @@ CLI_CONF_FILES="src/cli/etc/onegroup.yaml \
src/cli/etc/onevnet.yaml \
src/cli/etc/oneacl.yaml \
src/cli/etc/onedatastore.yaml \
src/cli/etc/onecluster.yaml"
src/cli/etc/onecluster.yaml \
src/cli/etc/oneacct.yaml"
ETC_CLIENT_FILES="src/cli/etc/group.default"
@ -1179,6 +1194,7 @@ SUNSTONE_PUBLIC_JS_FILES="src/sunstone/public/js/layout.js \
src/sunstone/public/js/sunstone.js \
src/sunstone/public/js/sunstone-util.js \
src/sunstone/public/js/opennebula.js \
src/sunstone/public/js/monitoring.js \
src/sunstone/public/js/locale.js"
SUNSTONE_PUBLIC_JS_PLUGINS_FILES="\
@ -1253,6 +1269,7 @@ SUNSTONE_PUBLIC_VENDOR_JQUERYLAYOUT="\
SUNSTONE_PUBLIC_VENDOR_FLOT="\
src/sunstone/public/vendor/flot/jquery.flot.min.js \
src/sunstone/public/vendor/flot/jquery.flot.navigate.min.js \
src/sunstone/public/vendor/flot/jquery.flot.pie.min.js \
src/sunstone/public/vendor/flot/LICENSE.txt \
src/sunstone/public/vendor/flot/NOTICE \
src/sunstone/public/vendor/flot/README.txt"
@ -1270,6 +1287,22 @@ SUNSTONE_PUBLIC_VENDOR_XML2JSON="\
src/sunstone/public/vendor/xml2json/NOTICE \
src/sunstone/public/vendor/xml2json/jquery.xml2json.pack.js"
SUNSTONE_PUBLIC_VENDOR_FONTAWESOME="\
src/sunstone/public/vendor/FontAwesome/NOTICE \
"
SUNSTONE_PUBLIC_VENDOR_FONTAWESOME_CSS="\
src/sunstone/public/vendor/FontAwesome/css/font-awesome.css \
"
SUNSTONE_PUBLIC_VENDOR_FONTAWESOME_FONT="\
src/sunstone/public/vendor/FontAwesome/font/fontawesome-webfont.eot \
src/sunstone/public/vendor/FontAwesome/font/fontawesome-webfont.woff \
src/sunstone/public/vendor/FontAwesome/font/fontawesome-webfont.ttf \
src/sunstone/public/vendor/FontAwesome/font/fontawesome-webfont.svgz \
src/sunstone/public/vendor/FontAwesome/font/fontawesome-webfont.svg \
"
SUNSTONE_PUBLIC_IMAGES_FILES="src/sunstone/public/images/ajax-loader.gif \
src/sunstone/public/images/login_over.png \
src/sunstone/public/images/login.png \
@ -1290,27 +1323,25 @@ SUNSTONE_PUBLIC_IMAGES_FILES="src/sunstone/public/images/ajax-loader.gif \
"
SUNSTONE_PUBLIC_LOCALE_EN_US="\
src/sunstone/public/locale/en_US/en_US.js \
src/sunstone/public/locale/en_US/en_datatable.txt \
src/sunstone/locale/languages/en_US.js \
src/sunstone/locale/languages/en_datatable.txt \
"
SUNSTONE_PUBLIC_LOCALE_RU="
src/sunstone/public/locale/ru/ru.js \
src/sunstone/public/locale/ru/ru_datatable.txt"
src/sunstone/locale/languages/ru.js \
src/sunstone/locale/languages/ru_datatable.txt"
SUNSTONE_PUBLIC_LOCALE_IT_IT="
src/sunstone/public/locale/it_IT/it_IT.js \
src/sunstone/public/locale/it_IT/it_datatable.txt"
src/sunstone/locale/languages/it_IT.js \
src/sunstone/locale/languages/it_datatable.txt"
SUNSTONE_PUBLIC_LOCALE_PT_PT="
src/sunstone/public/locale/pt_PT/pt_PT.js \
src/sunstone/public/locale/pt_PT/pt_datatable.txt"
src/sunstone/locale/languages/pt_PT.js \
src/sunstone/locale/languages/pt_datatable.txt"
SUNSTONE_PUBLIC_LOCALE_FR_FR="
src/sunstone/public/locale/fr_FR/fr_FR.js \
src/sunstone/public/locale/fr_FR/fr_datatable.txt"
src/sunstone/locale/languages/fr_FR.js \
src/sunstone/locale/languages/fr_datatable.txt"
#-----------------------------------------------------------------------------
# Ozones files
@ -1367,6 +1398,12 @@ OZONES_PUBLIC_VENDOR_JQUERYUIIMAGES=$SUNSTONE_PUBLIC_VENDOR_JQUERYUIIMAGES
OZONES_PUBLIC_VENDOR_JQUERYLAYOUT=$SUNSTONE_PUBLIC_VENDOR_JQUERYLAYOUT
OZONES_PUBLIC_VENDOR_FONTAWESOME=$SUNSTONE_PUBLIC_VENDOR_FONTAWESOME
OZONES_PUBLIC_VENDOR_FONTAWESOME_FONT=$SUNSTONE_PUBLIC_VENDOR_FONTAWESOME_FONT
OZONES_PUBLIC_VENDOR_FONTAWESOME_CSS=$SUNSTONE_PUBLIC_VENDOR_FONTAWESOME_CSS
OZONES_PUBLIC_JS_FILES="src/ozones/Server/public/js/ozones.js \
src/ozones/Server/public/js/login.js \
src/ozones/Server/public/js/ozones-util.js \
@ -1441,6 +1478,9 @@ SELF_SERVICE_PUBLIC_VENDOR_FLOT=$SUNSTONE_PUBLIC_VENDOR_FLOT
SELF_SERVICE_PUBLIC_VENDOR_CRYPTOJS=$SUNSTONE_PUBLIC_VENDOR_CRYPTOJS
SELF_SERVICE_PUBLIC_VENDOR_FILEUPLOADER=$SUNSTONE_PUBLIC_VENDOR_FILEUPLOADER
SELF_SERVICE_PUBLIC_VENDOR_XML2JSON=$SUNSTONE_PUBLIC_VENDOR_XML2JSON
SELF_SERVICE_PUBLIC_VENDOR_FONTAWESOME=$SUNSTONE_PUBLIC_VENDOR_FONTAWESOME
SELF_SERVICE_PUBLIC_VENDOR_FONTAWESOME_FONT=$SUNSTONE_PUBLIC_VENDOR_FONTAWESOME_FONT
SELF_SERVICE_PUBLIC_VENDOR_FONTAWESOME_CSS=$SUNSTONE_PUBLIC_VENDOR_FONTAWESOME_CSS
SELF_SERVICE_PUBLIC_IMAGES_FILES="\
src/cloud/occi/lib/ui/public/images/ajax-loader.gif \
@ -1465,28 +1505,13 @@ src/cloud/occi/lib/ui/public/images/vnc_off.png \
src/cloud/occi/lib/ui/public/images/vnc_on.png \
src/cloud/occi/lib/ui/public/images/yellow_bullet.png"
SELF_SERVICE_PUBLIC_LOCALE_EN_US="src/cloud/occi/lib/ui/public/locale/en_US/en_US.js"
SELF_SERVICE_PUBLIC_LOCALE_ES_ES="src/cloud/occi/lib/ui/public/locale/es_ES/es_ES.js \
src/cloud/occi/lib/ui/public/locale/es_ES/es_datatable.txt"
SELF_SERVICE_PUBLIC_LOCALE_FR_FR="src/cloud/occi/lib/ui/public/locale/fr_FR/fr_FR.js \
src/cloud/occi/lib/ui/public/locale/fr_FR/fr_datatable.txt"
SELF_SERVICE_PUBLIC_LOCALE_FR_CA="src/cloud/occi/lib/ui/public/locale/fr_CA/fr_CA.js \
src/cloud/occi/lib/ui/public/locale/fr_CA/fr_datatable.txt"
#-----------------------------------------------------------------------------
# ACCT files
#-----------------------------------------------------------------------------
ACCT_BIN_FILES="src/acct/oneacctd"
ACCT_LIB_FILES="src/acct/monitoring.rb \
src/acct/accounting.rb \
src/acct/acctd.rb \
src/acct/oneacct.rb \
src/acct/watch_helper.rb \
src/acct/watch_client.rb"
ACCT_ETC_FILES="src/acct/etc/acctd.conf"
SELF_SERVICE_PUBLIC_LOCALE_EN_US="src/cloud/occi/lib/ui/locale/languages/en_US.js"
SELF_SERVICE_PUBLIC_LOCALE_ES_ES="src/cloud/occi/lib/ui/locale/languages/es_ES.js \
src/cloud/occi/lib/ui/locale/languages/es_datatable.txt"
SELF_SERVICE_PUBLIC_LOCALE_FR_FR="src/cloud/occi/lib/ui/locale/languages/fr_FR.js \
src/cloud/occi/lib/ui/locale/languages/fr_datatable.txt"
SELF_SERVICE_PUBLIC_LOCALE_FR_CA="src/cloud/occi/lib/ui/locale/languages/fr_CA.js \
src/cloud/occi/lib/ui/locale/languages/fr_datatable.txt"
#-----------------------------------------------------------------------------
# MAN files

View File

@ -13,6 +13,63 @@
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="DATASTORE_QUOTA" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:element name="DATASTORE" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" type="xs:string"/>
<xs:element name="IMAGES" type="xs:string"/>
<xs:element name="IMAGES_USED" type="xs:string"/>
<xs:element name="SIZE" type="xs:string"/>
<xs:element name="SIZE_USED" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:complexType>
</xs:element>
<xs:element name="VM_QUOTA" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:element name="VM" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="VMS" type="xs:string"/>
<xs:element name="VMS_USED" type="xs:string"/>
<xs:element name="MEMORY" type="xs:string"/>
<xs:element name="MEMORY_USED" type="xs:string"/>
<xs:element name="CPU" type="xs:string"/>
<xs:element name="CPU_USED" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:complexType>
</xs:element>
<xs:element name="NETWORK_QUOTA" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:element name="NETWORK" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" type="xs:string"/>
<xs:element name="LEASES" type="xs:string"/>
<xs:element name="LEASES_USED" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:complexType>
</xs:element>
<xs:element name="IMAGE_QUOTA" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:element name="IMAGE" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" type="xs:string"/>
<xs:element name="RVMS" type="xs:string"/>
<xs:element name="RVMS_USED" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>

View File

@ -12,6 +12,63 @@
<xs:element name="AUTH_DRIVER" type="xs:string"/>
<xs:element name="ENABLED" type="xs:integer"/>
<xs:element name="TEMPLATE" type="xs:anyType"/>
<xs:element name="DATASTORE_QUOTA" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:element name="DATASTORE" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" type="xs:string"/>
<xs:element name="IMAGES" type="xs:string"/>
<xs:element name="IMAGES_USED" type="xs:string"/>
<xs:element name="SIZE" type="xs:string"/>
<xs:element name="SIZE_USED" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:complexType>
</xs:element>
<xs:element name="VM_QUOTA" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:element name="VM" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="VMS" type="xs:string"/>
<xs:element name="VMS_USED" type="xs:string"/>
<xs:element name="MEMORY" type="xs:string"/>
<xs:element name="MEMORY_USED" type="xs:string"/>
<xs:element name="CPU" type="xs:string"/>
<xs:element name="CPU_USED" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:complexType>
</xs:element>
<xs:element name="NETWORK_QUOTA" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:element name="NETWORK" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" type="xs:string"/>
<xs:element name="LEASES" type="xs:string"/>
<xs:element name="LEASES_USED" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:complexType>
</xs:element>
<xs:element name="IMAGE_QUOTA" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:element name="IMAGE" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" type="xs:string"/>
<xs:element name="RVMS" type="xs:string"/>
<xs:element name="RVMS_USED" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>

View File

@ -11,10 +11,14 @@
#
# HOST_MONITORING_INTERVAL: Time in seconds between host monitorization.
# HOST_PER_INTERVAL: Number of hosts monitored in each interval.
# HOST_MONITORING_EXPIRATION_TIME: Time, in seconds, to expire monitoring
# information. Use 0 to disable HOST monitoring recording.
#
# VM_POLLING_INTERVAL: Time in seconds between virtual machine monitorization.
# (use 0 to disable VM monitoring).
# Use 0 to disable VM monitoring.
# VM_PER_INTERVAL: Number of VMs monitored in each interval.
# VM_MONITORING_EXPIRATION_TIME: Time, in seconds, to expire monitoring
# information. Use 0 to disable VM monitoring recording.
#
# SCRIPTS_REMOTE_DIR: Remote path to store the monitoring and VM management
# scripts.
@ -40,10 +44,11 @@
HOST_MONITORING_INTERVAL = 600
#HOST_PER_INTERVAL = 15
#HOST_MONITORING_EXPIRATION_TIME = 86400
VM_POLLING_INTERVAL = 600
#VM_PER_INTERVAL = 5
#VM_MONITORING_EXPIRATION_TIME = 86400
SCRIPTS_REMOTE_DIR=/var/tmp/one
@ -414,22 +419,20 @@ HM_MAD = [
# valid. During this time, the driver is not used. Use 0 to disable session
# caching
#
# ENABLE_OTHER_PERMISSIONS: Whether or not to enable the permissions for
# 'other'. Users in the oneadmin group will still be able to change
# these permissions. Values: YES or NO
# ENABLE_OTHER_PERMISSIONS: Whether or not users can set the permissions for
# 'other', so publishing or sharing resources with others. Users in the oneadmin
# group will still be able to change these permissions. Values: YES or NO.
#*******************************************************************************
AUTH_MAD = [
executable = "one_auth_mad",
authn = "ssh,x509,ldap,server_cipher,server_x509"
# , authz = "quota"
]
SESSION_EXPIRATION_TIME = 900
#ENABLE_OTHER_PERMISSIONS = "YES"
#*******************************************************************************
# Restricted Attributes Configuration
#*******************************************************************************

View File

@ -2,29 +2,26 @@
require 'pp'
DEFAULT=%w{optional sunstone quota cloud ozones_server acct auth_ldap}
$nokogiri='nokogiri'
DEFAULT=%w{sunstone quota cloud ozones_server auth_ldap}
if defined?(RUBY_VERSION) && RUBY_VERSION>="1.8.7"
SQLITE='sqlite3'
else
SQLITE='sqlite3-ruby --version 1.2.0'
end
GROUPS={
:optional => ['nokogiri'],
:quota => [SQLITE, 'sequel'],
:sunstone => ['json', 'rack', 'sinatra', 'thin', 'sequel', SQLITE],
:cloud => %w{amazon-ec2 rack sinatra thin uuidtools curb json},
:ozones_client => %w{json},
:ozones_server => %w{json data_mapper dm-sqlite-adapter dm-mysql-adapter}+[
:ozones_server => %w{json sequel}+[
SQLITE, 'mysql'
],
:ozones_server_sqlite => %w{json data_mapper dm-sqlite-adapter}<<SQLITE,
:ozones_server_mysql => %w{json data_mapper dm-mysql-adapter mysql},
:acct => ['sequel', SQLITE, 'mysql'],
:acct_sqlite => ['sequel', SQLITE],
:acct_mysql => ['sequel', 'mysql'],
:ozones_server_sqlite => %w{json sequel}<<SQLITE,
:ozones_server_mysql => %w{json sequel mysql},
:auth_ldap => 'net-ldap'
}
@ -223,12 +220,14 @@ def help
puts DEFAULT.join(' ')
puts
puts "Use --check parameter to search for non installed libraries."
puts "Use --no-nokogiri parameter if you don't want to install"
puts "nokogiri gem."
end
def get_gems(packages)
packages.map do |package|
(packages.map do |package|
GROUPS[package.to_sym]
end.flatten.uniq-installed_gems
end+[$nokogiri]).flatten.uniq-installed_gems
end
def detect_distro
@ -430,6 +429,11 @@ install_rubygems
command=''
params=ARGV
if params.include?('--no-nokogiri')
params-=['--no-nokogiri']
$nokogiri=nil
end
if params.include?('-h')
params-=['-h']
command='help'

View File

@ -1,4 +1,5 @@
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
# -------------------------------------------------------------------------- #
# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) #
@ -16,54 +17,42 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
ONE_LOCATION=ENV["ONE_LOCATION"]
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby"
ETC_LOCATION="/etc/one/"
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
ETC_LOCATION=ONE_LOCATION+"/etc/"
if RUBY_VERSION =~ /1.9/
Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8
end
$: << RUBY_LIB_LOCATION
require 'scripts_common'
require 'OpenNebula'
require 'quota'
user_id = ARGV.shift
overall_evalutation = ARGV.pop
exit -1 if overall_evalutation.to_i == 0
quota = Quota.new
#q = {
# :cpu => 10,
# :memory => 2048,
# :storage => 100000,
# :num_vms => 5
#}
#
#quota.set(1, q)
#OpenNebula.log_debug("quotas: #{quota.get(1)}")
ARGV.each {|request|
obj, template_or_id, op, owner, acl_eval = request.split(':')
if ( obj == "TEMPLATE" && op == "USE" && ARGV.size == 1 )
rc = false
else
rc = quota.authorize(user_id, request)
if !ARGV[0]
puts "Usage ./po2json.rb <file.po> > <output.js>"
exit 1
end
if rc
OpenNebula.error_message rc
exit -1
po_file = File.open(ARGV[0])
lang = File.basename(ARGV[0]).split('.')[0]
datatable_lang = lang.split("_")[0]
puts "lang=\"#{lang}\""
puts "datatable_lang=\"#{datatable_lang}_datatable.txt\""
puts "locale={"
msgid = nil
po_file.each do |line|
if msgid
msgstr = line.sub("msgstr ", "").chomp
puts " #{msgid}:#{msgstr},"
msgid = nil
next
end
}
#OpenNebula.log_debug("AUTHORIZE ARGS: #{ARGV.join(' ')}")
if line.include?("msgid")
msgid = line.sub("msgid ", "").chomp
exit 0
if msgid.length == 0 || msgid.slice(0,1) == '#'
msgid = nil
end
end
end
puts "}"

View File

@ -1,131 +0,0 @@
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
module OneWatch
require 'watch_helper'
class Accounting
def initialize(client)
@client = client
@active_vms = Array.new
end
def insert(hash)
@ptimestamp = @timestamp
@timestamp = generate_timestamp
new_active_vms = Array.new
last_active_vm = @active_vms.empty? ? -1 : @active_vms.last
if (vmpool_hash = hash['VM_POOL']) && !vmpool_hash.empty?
[vmpool_hash['VM']].flatten.each { |vm|
vm_id = vm['ID'].to_i
if vm['STATE'] == 3
new_active_vms << vm_id
end
# ACTIVE VMs (including those that are stopped in this step)
# in the last step and NEW VMs
if @active_vms.include?(vm_id) || vm['STATE'].to_i == 3
insert_vm(vm)
@active_vms.delete(vm_id)
else
# DONE/STOP VMs and non ACTIVE in the last step
next
end
}
end
# DONE VMs that were ACTIVE in the last step
@active_vms.each { |id|
vm = OpenNebula::VirtualMachine.new_with_id(id, @client)
vm.info
vm_hash = vm.to_hash
insert_vm(vm_hash)
}
# DONE VMs that did not exist in the last step
vmpool = OpenNebula::VirtualMachinePool.new(@client)
vmpool.info(-2, last_active_vm, -1, 6)
done_hash = vmpool.to_hash
if (done_vm_hash = done_hash['VM_POOL']) && !done_vm_hash.empty?
[done_vm_hash['VM']].flatten.each { |vm|
insert_vm(vm)
}
end
# Upate the active VMs
@active_vms = new_active_vms.sort
WatchHelper::Vm.flush
end
private
def generate_timestamp
Time.now.to_i
end
def insert_register(vm, register, history)
if register && register.seq == history['SEQ'].to_i
register.update_from_history(history)
else
vm.add_register_from_resource(history)
end
end
def update_history(vm, vm_sql)
last_register = vm_sql.registers.last
seq = last_register ? last_register.seq : 0
hr = vm['HISTORY_RECORDS']
if hr and !hr.empty?
if hr['HISTORY']['SEQ'] == seq
# The VM has not moved from the Host
insert_register(vm_sql, last_register, hr['HISTORY'])
return
else
unless hr['HISTORY'].instance_of?(Array)
# Get the full HISTORY
vm = OpenNebula::VirtualMachine.new_with_id(vm['ID'], @client)
vm.info
vm_hash = vm.to_hash['VM']
hr = vm_hash['HISTORY_RECORDS']
end
# Insert a new entry for each new history record
[hr['HISTORY']].flatten.each { |history|
if history['SEQ'].to_i < seq
next
else
insert_register(vm_sql, last_register, history)
end
}
end
end
end
def insert_vm(vm)
vm_sql = WatchHelper::Vm.info(vm)
vm_sql.add_delta_from_resource(vm, @timestamp)
update_history(vm, vm_sql)
end
end
end

View File

@ -1,139 +0,0 @@
#!/usr/bin/env ruby
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
ONE_LOCATION=ENV["ONE_LOCATION"]
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby"
ACCTD_CONF="/etc/one/acctd.conf"
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
ACCTD_CONF=ONE_LOCATION+"/etc/acctd.conf"
end
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+"/acct"
require 'yaml'
require 'OpenNebula'
require 'watch_helper'
class Watcher
def initialize
@monitors = Array.new
end
def add(resource, steps, pools)
@monitors << { :resource => resource,
:steps => steps,
:pools => [pools].flatten
}
end
def log(msg)
STDERR.puts "#{Time.now} #{msg}"
end
def update(step)
# clear pool cache
@pool_cache = Hash.new
@monitors.each do |monitor|
if monitor[:steps] > 0 and step % monitor[:steps] == 0
monitor[:pools].each do |pool|
resource = monitor[:resource]
log "#{resource.class}"
if pool_hash = @pool_cache[pool]
else
rc = pool.info
if OpenNebula.is_error?(rc)
log "Error: " + rc.message
log "Shutting down"
exit 1
end
pool_hash = pool.to_hash
@pool_cache[pool] = pool_hash
end
resource.insert(pool_hash)
end
end
end
end
end
watcher = Watcher.new
# OpenNebula variables
one_client = OpenNebula::Client.new
vm_pool = nil # common for accounting and monitoring
host_pool = nil
# Initialize VM monitoring
if vm_steps = WatchHelper::get_config(:VM_MONITORING, :STEPS) and
vm_steps > 0
require 'monitoring'
vm_monitoring = OneWatch::VmMonitoring.new
vm_pool ||= OpenNebula::VirtualMachinePool.new(one_client, -2)
watcher.add(vm_monitoring, vm_steps, vm_pool)
end
# Initialize Host monitoring
if host_steps = WatchHelper::get_config(:HOST_MONITORING, :STEPS) and
host_steps > 0
require 'monitoring'
host_monitoring = OneWatch::HostMonitoring.new
host_pool ||= OpenNebula::HostPool.new(one_client)
watcher.add(host_monitoring, host_steps, host_pool)
end
# Initialize accounting
if accounting_steps = WatchHelper::get_config(:ACCOUNTING, :STEPS) and
accounting_steps > 0
require 'accounting'
accounting = OneWatch::Accounting.new(one_client)
vm_pool ||= OpenNebula::VirtualMachinePool.new(one_client, -2)
watcher.add(accounting, accounting_steps, vm_pool)
end
step_time = WatchHelper::get_config(:STEP)
step = 0
loop do
start_time = Time.now
expected_end_time = start_time + step_time
step += 1
watcher.update(step)
end_time = Time.now
sleep_time = start_time + step_time - end_time
if sleep_time >= 1
sleep sleep_time
else
sleep 1
end
end

View File

@ -1,55 +0,0 @@
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
# Database URI
#:DB: sqlite:///var/one/oneacct.db
# Duration of each daemon loop in seconds
:STEP: 300 # 5 minutes
#-------------------------------------------------------------------------------
# VM Monitoring
#-------------------------------------------------------------------------------
:VM_MONITORING:
# Number of daemon loops until a VM monitoring watch
:STEPS: 1
# Number of VM records to preserve
:WINDOW_SIZE: 5
#-------------------------------------------------------------------------------
# HOST Monitoring
#-------------------------------------------------------------------------------
:HOST_MONITORING:
# Number of daemon loops until a Hosts monitoring watch
:STEPS: 3
# Number of HOST records to preserve
:WINDOW_SIZE: 5
#-------------------------------------------------------------------------------
# Accounting
#-------------------------------------------------------------------------------
:ACCOUNTING:
# Number of daemon loops until an accounting watch
:STEPS: 10

View File

@ -1,91 +0,0 @@
# -------------------------------------------------------------------------- #
# 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 'watch_helper'
class AcctClient
def prolog_time(t1, t2, opts={})
times(t1, t2, opts) { |reg|
calculate_time(t1, t2, reg.pstime, reg.petime)
}
end
def running_time(t1, t2, opts={})
# TBD Suspened VMs
times(t1, t2, opts) { |reg|
calculate_time(t1, t2, reg.rstime, reg.retime)
}
end
def epilog_time(t1, t2, opts={})
times(t1, t2, opts) { |reg|
calculate_time(t1, t2, reg.estime, reg.eetime)
}
end
private
def times(t1, t2, opts={}, &block)
time = 0
vms = filter_vms(opts)
if vms && !vms.empty?
vms.each { |vm|
vm.registers.each { |reg|
time += block.call(reg)
}
}
end
time
end
def calculate_time(t1, t2, stime, etime)
if etime < t1 && etime != 0
return 0
elsif stime < t2 && stime != 0
if etime < t2 && etime != 0
e = etime
else
e = t2
end
s = stime > t1 ? stime : t1
return e - s
end
return 0
end
def filter_vms(opts={})
opts ||= {}
if opts[:uid]
vms = WatchHelper::Vm.filter(:uid=>opts[:uid])
elsif opts[:gid]
vms = WatchHelper::Vm.filter(:gid=>opts[:gid])
elsif opts[:hid]
vms = WatchHelper::Vm.filter(
:registers=>WatchHelper::Register.filter(:hid => opts[:hid]))
elsif opts[:vmid]
vms = WatchHelper::Vm.filter(:id=>opts[:vmid])
else
vms = WatchHelper::Vm
end
end
end

View File

@ -1,78 +0,0 @@
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
module OneWatch
require 'watch_helper'
class Monitoring
def insert(hash)
timestamp = generate_timestamp
if (pool_hash = hash["#{resource}_POOL"]) && !pool_hash.empty?
[pool_hash["#{resource}"]].flatten.each { |elem|
sql = sql_elem(elem)
sql.add_sample_from_resource(elem, timestamp)
}
end
sql_elem.flush
end
private
def generate_timestamp
Time.now.to_i
end
end
class VmMonitoring < Monitoring
def resource
'VM'
end
def sql_elem(elem=nil)
if elem
WatchHelper::Vm.info(elem)
else
WatchHelper::Vm
end
end
def generate_timestamp
ts = super
WatchHelper::VmTimestamp.find_or_create(:id=>ts)
end
end
class HostMonitoring < Monitoring
def resource
'HOST'
end
def sql_elem(elem=nil)
if elem
WatchHelper::Host.info(elem)
else
WatchHelper::Host
end
end
def generate_timestamp
ts = super
WatchHelper::HostTimestamp.find_or_create(:id=>ts)
end
end
end

View File

@ -1,183 +0,0 @@
# --------------------------------------------------------------------------
# Copyright 2010-2012, C12G Labs S.L.
#
# This file is part of OpenNebula addons.
#
# OpenNebula addons are free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 3 of
# the License, or the hope That it will be useful, but (at your
# option) any later version.
#
# OpenNebula addons are distributed in WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License
# along with OpenNebula addons. If not, see
# <http://www.gnu.org/licenses/>
# --------------------------------------------------------------------------
require 'acct/watch_helper'
class AcctClient
def initialize(filters={})
@filters=filters
@deltas=[]
@users={}
end
def account(time_start=nil, time_end=nil, user_id=nil)
@filters[:start]=time_start if time_start
@filters[:end]=time_end if time_end
@filters[:user]=user_id if user_id
get_users_consumption
@users
end
private
def get_users_consumption
# Get all the deltas that match the filters
@deltas=calculate_deltas.map {|q| q.values }
@users=slices_by_user
user_slices_and_deltas_to_vms
end
def slices_by_user
# Get all VM slices that match the filters
query=get_vm_slices(@filters)
# This hash will hold the users with the resources consumed
users={}
query.each do |reg|
vm=reg.vm
uid=vm.uid.to_i
# Create a new user register if it still does not exist
user=users[uid]||={
:vm_slices => [],
}
user[:vm_slices] << reg.values
end
users
end
def user_slices_and_deltas_to_vms
@users.each do |user, data|
# Get the VM ids array for this user
vms=data[:vm_slices].map {|vm| vm[:id] }.sort.uniq
data[:vms]={}
vms.each do |vm|
# Get the slices array for this VM
slices=data[:vm_slices].select {|slice| slice[:id]==vm }
data[:vms][vm]={
:slices => [],
:time => 0,
}
# Get the deltas sum for this VM
vm_delta=@deltas.find {|d| d[:vm_id]==vm }
data[:vms][vm][:network]=vm_delta
data[:vms][vm][:vmid]=vm
# Calculate the time consumed by the VM
slices.each do |slice|
data[:vms][vm][:slices] << slice
time=calculate_time(slice,
@filters[:start], @filters[:end])
data[:vms][vm][:time]+=time
end
end
# Delete redundant slices data
data.delete(:vm_slices)
end
end
def get_vm_slices(filters={})
vms=WatchHelper::Register
query=vms.join(:vms, :id => :vm_id)
query=query.filter({:vms__uid => filters[:user]}) if filters[:user]
query=query.filter(
{:retime => 0} | (:retime > filters[:start])) if filters[:start]
query=query.filter(:rstime <= filters[:end]) if filters[:end]
query
end
def get_deltas(filters={})
if filters[:data]
query=filters[:data]
else
query=WatchHelper::VmDelta
end
query=query.filter( :ptimestamp >= filters[:start] ) if filters[:start]
query=query.filter( :ptimestamp <= filters[:end] ) if filters[:end]
query=query.filter( { :vm_id => filters[:vmid] } ) if filters[:vmid]
query
end
def calculate_deltas
query=WatchHelper::VmDelta.select(
:ptimestamp, :vm_id,
'sum(net_tx) AS net_tx'.lit, 'sum(net_rx) AS net_rx'.lit)
query=query.group(:vm_id)
new_filters=@filters.merge(:data => query)
get_deltas(new_filters)
end
def calculate_time(slice, period_start, period_end)
ts=slice[:rstime].to_i
te=slice[:retime].to_i
pstart=period_start.to_i
pend=period_end.to_i
pend=Time.now.to_i if pend==0
ts=pstart if ts<pstart
if te>pend or te==0
te=pend
end
te-ts
end
end
if $0 == __FILE__
require 'json'
acct=AcctClient.new(
:start => 1319476322,
:end => 1319637455
)
a=acct.account()
puts JSON.pretty_generate(a)
end

View File

@ -1,105 +0,0 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
if [ -z "$ONE_LOCATION" ]; then
ONE_PID=/var/run/one/oned.pid
LOCK_FILE=/var/lock/one/one
ACCTD_CMD=/usr/lib/one/ruby/acct/acctd.rb
ACCTD_LOG=/var/log/one/oneacctd.log
ACCTD_PID_FILE=/var/run/one/oneacctd.pid
else
ONE_PID=$ONE_LOCATION/var/oned.pid
LOCK_FILE=$ONE_LOCATION/var/.lock
ACCTD_CMD=$ONE_LOCATION/lib/ruby/acct/acctd.rb
ACCTD_LOG=$ONE_LOCATION/var/oneacctd.log
ACCTD_PID_FILE=$ONE_LOCATION/var/oneacctd.pid
fi
function oned_running {
ONEPID=`cat $ONE_PID 2> /dev/null`
ps $ONEPID > /dev/null 2>&1
if [ ! -f "$LOCK_FILE" -o ! -f "$ONE_PID" -o $? -ne 0 ]; then
echo oned not running
exit 1
fi
}
function acctd_running {
ACCTD_PID=`cat $ACCTD_PID_FILE 2>/dev/null`
ps "$ACCTD_PID" &> /dev/null
}
COMMAND=$1
case $COMMAND in
start)
# check if OpenNebula running
oned_running
# check if acct already running
acctd_running
if [ "$?" = "0" ]; then
echo "oneacctd already running."
exit 1
fi
# acctd not running, safe to start
$ACCTD_CMD &> $ACCTD_LOG &
LASTRC=$?
LASTPID=$!
if [ $LASTRC -ne 0 ]; then
echo "Error executing oneacctd."
echo "Check $ACCTD_LOG for more information"
exit 1
else
echo $LASTPID > $ACCTD_PID_FILE
fi
sleep 2
ps $LASTPID > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error executing oneacctd."
echo "Check $ACCTD_LOG for more information"
exit 1
fi
echo "oneacctd started"
;;
stop)
# check if running
acctd_running
if [ "$?" != "0" ]; then
echo "oneacctd not running."
exit 1
fi
# acctd running, safe to stop
ACCTD_PID=`cat $ACCTD_PID_FILE 2>/dev/null`
kill $ACCTD_PID &> /dev/null
rm -f $ACCTD_PID_FILE &> /dev/null
echo "oneacctd stop"
;;
*)
echo "Usage: oneacctd {start|stop}" >&2
exit 3
;;
esac

View File

@ -1,335 +0,0 @@
$: << '.'
require 'helper/test_helper.rb'
describe "1 Vm 1 History" do
before(:each) do
clean_db
@mock_client = MockClient.new
@accounting = OneWatch::Accounting.new(@mock_client)
@watch_client = AcctClient.new
@db = WatchHelper::DB
check_lines(0,0)
end
it "Prolog testing" do
ts1 = 100
@accounting.set_mock_timestamp(ts1)
@accounting.insert(create_vmpool_hash)
check_lines(0,0)
ts2 = 200
@accounting.set_mock_timestamp(ts2)
values = {
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 0,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(1, values)
@accounting.insert(create_vmpool_hash)
check_lines(1,1)
history = values[:history].first
sum = ts2 - history[:pstime]
warn "* T1 PSTIME T2"
@watch_client.prolog_time(ts1, ts2).to_i.should eql(sum)
warn " - By User"
@watch_client.prolog_time(ts1, ts2, :uid => 2).to_i.should eql(sum)
warn " - By Host"
@watch_client.prolog_time(ts1, ts2, :hid => 7).to_i.should eql(sum)
warn " - By Vm"
@watch_client.prolog_time(ts1, ts2, :vmid => 1).to_i.should eql(sum)
warn " - Non existent User"
@watch_client.prolog_time(ts1, ts2, :uid => 555).to_i.should eql(0)
warn " - Non existent Host"
@watch_client.prolog_time(ts1, ts2, :hid => 555).to_i.should eql(0)
warn " - Non existent Vm"
@watch_client.prolog_time(ts1, ts2, :vmid => 555).to_i.should eql(0)
warn "* PSTIME T1 T2"
@watch_client.prolog_time(160, ts2).to_i.should eql(sum-10)
warn "* T1 PSTIME T2-10"
@watch_client.prolog_time(ts1, ts2-10).to_i.should eql(sum-10)
warn "* T1 T2 PSTIME"
@watch_client.prolog_time(110, 130).to_i.should eql(0)
warn "* Non Epilog time"
@watch_client.epilog_time(ts1, ts2).to_i.should eql(0)
warn "* Non Running time"
@watch_client.running_time(ts1, ts2).to_i.should eql(0)
ts3 = 300
@accounting.set_mock_timestamp(ts3)
values = {
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 240,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(1, values)
@accounting.insert(create_vmpool_hash)
check_lines(1,1)
history = values[:history].first
sum = history[:petime] - history[:pstime]
warn "* T1 PSTIME PETIME T3"
@watch_client.prolog_time(ts1, ts3).to_i.should eql(sum)
warn " - By User"
@watch_client.prolog_time(ts1, ts3, :uid => 2).to_i.should eql(sum)
warn " - By Host"
@watch_client.prolog_time(ts1, ts3, :hid => 7).to_i.should eql(sum)
warn " - By Vm"
@watch_client.prolog_time(ts1, ts3, :vmid => 1).to_i.should eql(sum)
warn "* T1 PSTIME T3 PETIME"
@watch_client.prolog_time(ts1, 230).to_i.should eql(230 - history[:pstime])
warn "* PSTIME T1 PETIME T3"
@watch_client.prolog_time(160, ts3).to_i.should eql(history[:petime] - 160)
warn "* PSTIME T1 T3 PETIME"
@watch_client.prolog_time(160, 230).to_i.should eql(230 - 160)
end
it "Running testing" do
ts1 = 100
@accounting.set_mock_timestamp(ts1)
@accounting.insert(create_vmpool_hash)
check_lines(0,0)
ts2 = 200
@accounting.set_mock_timestamp(ts2)
values = {
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 155,
:rstime => 155,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(1, values)
@accounting.insert(create_vmpool_hash)
check_lines(1,1)
history = values[:history].first
sum = ts2 - history[:rstime]
warn "* T1 RSTIME T2"
@watch_client.running_time(ts1, ts2).to_i.should eql(sum)
warn " - By User"
@watch_client.running_time(ts1, ts2, :uid => 2).to_i.should eql(sum)
warn " - By Host"
@watch_client.running_time(ts1, ts2, :hid => 7).to_i.should eql(sum)
warn " - By Vm"
@watch_client.running_time(ts1, ts2, :vmid => 1).to_i.should eql(sum)
warn " - Non existent User"
@watch_client.running_time(ts1, ts2, :uid => 555).to_i.should eql(0)
warn " - Non existent Host"
@watch_client.running_time(ts1, ts2, :hid => 555).to_i.should eql(0)
warn " - Non existent Vm"
@watch_client.running_time(ts1, ts2, :vmid => 555).to_i.should eql(0)
warn "* RSTIME T1 T2"
@watch_client.running_time(160, ts2).to_i.should eql(ts2-160)
warn "* T1 RSTIME T2-10"
@watch_client.running_time(ts1, ts2-10).to_i.should eql(sum-10)
warn "* T1 T2 RSTIME"
@watch_client.running_time(110, 130).to_i.should eql(0)
warn "* Non Epilog time"
@watch_client.epilog_time(ts1, ts2).to_i.should eql(0)
warn "* Non Prolog time"
@watch_client.prolog_time(ts1, ts2).to_i.should eql(5)
ts3 = 300
@accounting.set_mock_timestamp(ts3)
values = {
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 155,
:rstime => 155,
:retime => 230,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(1, values)
@accounting.insert(create_vmpool_hash)
check_lines(1,1)
history = values[:history].first
sum = history[:retime] - history[:rstime]
warn "* T1 PSTIME PETIME T3"
@watch_client.running_time(ts1, ts3).to_i.should eql(sum)
warn " - By User"
@watch_client.running_time(ts1, ts3, :uid => 2).to_i.should eql(sum)
warn " - By Host"
@watch_client.running_time(ts1, ts3, :hid => 7).to_i.should eql(sum)
warn " - By Vm"
@watch_client.running_time(ts1, ts3, :vmid => 1).to_i.should eql(sum)
warn "* T1 PSTIME T3 PETIME"
@watch_client.running_time(ts1, 230).to_i.should eql(230 - history[:rstime])
warn "* PSTIME T1 PETIME T3"
@watch_client.running_time(160, ts3).to_i.should eql(history[:retime] - 160)
warn "* PSTIME T1 T3 PETIME"
@watch_client.running_time(160, 230).to_i.should eql(230 - 160)
end
it "Epilog testing" do
ts1 = 100
@accounting.set_mock_timestamp(ts1)
@accounting.insert(create_vmpool_hash)
check_lines(0,0)
ts2 = 200
@accounting.set_mock_timestamp(ts2)
values = {
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 155,
:rstime => 155,
:retime => 170,
:estime => 180,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(1, values)
@accounting.insert(create_vmpool_hash)
check_lines(1,1)
history = values[:history].first
sum = ts2 - history[:estime]
warn "* T1 ESTIME T2"
@watch_client.epilog_time(ts1, ts2).to_i.should eql(sum)
warn " - By User"
@watch_client.epilog_time(ts1, ts2, :uid => 2).to_i.should eql(sum)
warn " - By Host"
@watch_client.epilog_time(ts1, ts2, :hid => 7).to_i.should eql(sum)
warn " - By Vm"
@watch_client.epilog_time(ts1, ts2, :vmid => 1).to_i.should eql(sum)
warn " - Non existent User"
@watch_client.epilog_time(ts1, ts2, :uid => 555).to_i.should eql(0)
warn " - Non existent Host"
@watch_client.epilog_time(ts1, ts2, :hid => 555).to_i.should eql(0)
warn " - Non existent Vm"
@watch_client.epilog_time(ts1, ts2, :vmid => 555).to_i.should eql(0)
warn "* ESTIME T1 T2"
@watch_client.epilog_time(190, ts2).to_i.should eql(ts2-190)
warn "* T1 ESTIME T2-10"
@watch_client.epilog_time(ts1, ts2-10).to_i.should eql(sum-10)
warn "* T1 T2 ESTIME"
@watch_client.epilog_time(110, 130).to_i.should eql(0)
warn "* Non Running time"
@watch_client.running_time(ts1, ts2).to_i.should eql(15)
warn "* Non Prolog time"
@watch_client.prolog_time(ts1, ts2).to_i.should eql(5)
ts3 = 300
@accounting.set_mock_timestamp(ts3)
values = {
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 155,
:rstime => 155,
:retime => 170,
:estime => 180,
:eetime => 230,
:reason => 0
]
}
@mock_client.add_vm(1, values)
@accounting.insert(create_vmpool_hash)
check_lines(1,1)
history = values[:history].first
sum = history[:eetime] - history[:estime]
warn "* T1 PSTIME PETIME T3"
@watch_client.epilog_time(ts1, ts3).to_i.should eql(sum)
warn " - By User"
@watch_client.epilog_time(ts1, ts3, :uid => 2).to_i.should eql(sum)
warn " - By Host"
@watch_client.epilog_time(ts1, ts3, :hid => 7).to_i.should eql(sum)
warn " - By Vm"
@watch_client.epilog_time(ts1, ts3, :vmid => 1).to_i.should eql(sum)
warn "* T1 PSTIME T3 PETIME"
@watch_client.epilog_time(ts1, 230).to_i.should eql(230 - history[:estime])
warn "* PSTIME T1 PETIME T3"
@watch_client.epilog_time(190, ts3).to_i.should eql(history[:eetime] - 190)
warn "* PSTIME T1 T3 PETIME"
@watch_client.epilog_time(190, 220).to_i.should eql(220 - 190)
end
end

View File

@ -1,101 +0,0 @@
$: << '.'
require 'helper/test_helper.rb'
describe "1 Vm X History" do
before(:each) do
clean_db
@mock_client = MockClient.new
@accounting = OneWatch::Accounting.new(@mock_client)
@watch_client = AcctClient.new
@db = WatchHelper::DB
check_lines(0,0)
end
it "Running testing" do
ts1 = 100
@accounting.set_mock_timestamp(ts1)
@accounting.insert(create_vmpool_hash)
check_lines(0,0)
ts2 = 200
@accounting.set_mock_timestamp(ts2)
values = {
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:seq => 0,
:pstime => 150,
:petime => 155,
:rstime => 155,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(1, values)
@accounting.insert(create_vmpool_hash)
check_lines(1,1)
history = values[:history].first
sum = ts2 - history[:rstime]
warn "* T1 RSTIME T2"
@watch_client.running_time(ts1, ts2).to_i.should eql(sum)
ts3 = 300
@accounting.set_mock_timestamp(ts3)
values = {
:uid => 2,
:gid => 4,
:history => [
{
:hid => 7,
:seq => 0,
:pstime => 150,
:petime => 155,
:rstime => 155,
:retime => 230,
:estime => 230,
:eetime => 260,
:reason => 2
},
{
:hid => 8,
:seq => 1,
:pstime => 270,
:petime => 275,
:rstime => 275,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
}
]
}
@mock_client.add_vm(1, values)
@accounting.insert(create_vmpool_hash)
check_lines(1,2)
h1 = values[:history].first
sum1 = h1[:retime] - h1[:rstime]
h2 = values[:history].last
sum2 = ts3 - h2[:rstime]
warn "* T1 RSTIME1 RETIME1 RSTIME1 T2"
@watch_client.running_time(ts1, ts3).to_i.should eql(sum1 + sum2)
end
end

View File

@ -1,93 +0,0 @@
$: << '.'
require 'helper/test_helper.rb'
describe "X Vm 1 History" do
before(:each) do
clean_db
@mock_client = MockClient.new
@accounting = OneWatch::Accounting.new(@mock_client)
@watch_client = AcctClient.new
@db = WatchHelper::DB
check_lines(0,0)
end
it "Running testing" do
ts1 = 100
@accounting.set_mock_timestamp(ts1)
@accounting.insert(create_vmpool_hash)
check_lines(0,0)
ts2 = 200
@accounting.set_mock_timestamp(ts2)
values = {
:uid => 2,
:gid => 4,
:history => [
:hid => 6,
:seq => 0,
:pstime => 150,
:petime => 155,
:rstime => 155,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(1, values)
@accounting.insert(create_vmpool_hash)
check_lines(1,1)
history = values[:history].first
sum = ts2 - history[:rstime]
warn "* T1 RSTIME T2"
@watch_client.running_time(ts1, ts2).to_i.should eql(sum)
ts3 = 300
@accounting.set_mock_timestamp(ts3)
values2 = {
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:seq => 0,
:pstime => 220,
:petime => 260,
:rstime => 260,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(2, values2)
@accounting.insert(create_vmpool_hash)
check_lines(2,2)
history1 = values[:history].first
sum1 = ts3 - history1[:rstime]
history2 = values2[:history].first
sum2 = ts3 - history2[:rstime]
warn "* T1 RSTIME T2"
@watch_client.running_time(ts1, ts3).to_i.should eql(sum1 + sum2)
@watch_client.running_time(ts1, ts3, :vmid=>1).to_i.should eql(sum1)
@watch_client.running_time(ts1, ts3, :vmid=>2).to_i.should eql(sum2)
@watch_client.running_time(ts1, ts3, :uid=>2).to_i.should eql(sum1 + sum2)
@watch_client.running_time(ts1, ts3, :hid=>6).to_i.should eql(sum1)
@watch_client.running_time(ts1, ts3, :hid=>7).to_i.should eql(sum2)
end
end

View File

@ -1,529 +0,0 @@
$: << '.'
require 'helper/test_helper.rb'
require 'watch_client'
describe "VmWatchClient tests" do
before(:all) do
clean_db
@mock_client = MockClient.new
@monitoring = OneWatch::VmMonitoring.new
@watch_client = OneWatchClient::VmWatchClient.new
@db = WatchHelper::DB
@db[:vms].count.should eql(0)
end
it "Create a VM: uid=2 gid=4, timestamp=100" do
@monitoring.set_mock_timestamp(100)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(0)
values = {
:cpu => 1,
:memory => 128,
:net_tx => 200,
:net_rx => 400,
:last_poll => 100,
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 0,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(1, values)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(1)
end
it "should check all the monitoring resources are shown by default" do
mon = @watch_client.resource_monitoring(1)
mon[:id].should eql(1)
mon[:resource].should eql("VM")
monitoring = mon[:monitoring]
monitoring.keys.size.should eql(4)
monitoring[:cpu_usage].size.should eql(1)
monitoring[:cpu_usage].first.should eql([100,1])
monitoring[:mem_usage].size.should eql(1)
monitoring[:mem_usage].first.should eql([100,128])
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([100,200])
monitoring[:net_rx].size.should eql(1)
monitoring[:net_rx].first.should eql([100,400])
end
it "should check all the monitoring resources are shown by default and filtered" do
mon = @watch_client.resource_monitoring(1, nil, :uid=>2)
mon[:id].should eql(1)
mon[:resource].should eql("VM")
monitoring = mon[:monitoring]
monitoring.keys.size.should eql(4)
monitoring[:cpu_usage].size.should eql(1)
monitoring[:cpu_usage].first.should eql([100,1])
monitoring[:mem_usage].size.should eql(1)
monitoring[:mem_usage].first.should eql([100,128])
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([100,200])
monitoring[:net_rx].size.should eql(1)
monitoring[:net_rx].first.should eql([100,400])
end
it "should check no info for non exisiting user" do
mon = @watch_client.resource_monitoring(1, nil, :uid=>1)
mon.should eql(nil)
end
it "should check only one monitoring resource is shown if specified" do
mon = @watch_client.resource_monitoring(1, [:net_tx])
monitoring = mon[:monitoring]
monitoring.keys.size.should eql(1)
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([100,200])
end
it "should check only two monitoring resources are shown if specified" do
mon = @watch_client.resource_monitoring(1, [:net_tx, :cpu_usage])
monitoring = mon[:monitoring]
monitoring.keys.size.should eql(2)
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([100,200])
monitoring[:cpu_usage].size.should eql(1)
monitoring[:cpu_usage].first.should eql([100,1])
end
it "should check all the total monitoring resources are shown by default" do
mon = @watch_client.total_monitoring
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring[:total].size.should eql(1)
monitoring[:total].first.should eql([100,1])
monitoring[:active].size.should eql(1)
monitoring[:active].first.should eql([100,1])
monitoring[:error].size.should eql(1)
monitoring[:error].first.should eql([100,0])
monitoring[:cpu_usage].size.should eql(1)
monitoring[:cpu_usage].first.should eql([100,1])
monitoring[:mem_usage].size.should eql(1)
monitoring[:mem_usage].first.should eql([100,128])
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([100,200])
monitoring[:net_rx].size.should eql(1)
monitoring[:net_rx].first.should eql([100,400])
end
it "should check only one total monitoring resources is shown if specified" do
mon = @watch_client.total_monitoring([:total])
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring.keys.size.should eql(1)
monitoring[:total].size.should eql(1)
monitoring[:total].first.should eql([100,1])
end
it "should return an empty Hash if no valid monitoring resource" do
mon = @watch_client.resource_monitoring(1, [:oranges])
mon[:monitoring].empty?.should eql(true)
end
it "should return nil if the VM does not exist" do
mon = @watch_client.resource_monitoring(100, [:oranges])
mon.should eql(nil)
end
it "Create a second VM: uid=2 gid=4, timestamp=200" do
@monitoring.set_mock_timestamp(200)
values = {
:cpu => 1,
:memory => 128,
:net_tx => 200,
:net_rx => 400,
:last_poll => 100,
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 0,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(2, values)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(2)
end
it "should check all the monitoring resources are shown by default" do
mon = @watch_client.resource_monitoring(1)
mon[:id].should eql(1)
mon[:resource].should eql("VM")
monitoring = mon[:monitoring]
monitoring.keys.size.should eql(4)
monitoring[:cpu_usage].size.should eql(2)
monitoring[:cpu_usage].first.should eql([100,1])
monitoring[:mem_usage].size.should eql(2)
monitoring[:mem_usage].first.should eql([100,128])
monitoring[:net_tx].size.should eql(2)
monitoring[:net_tx].first.should eql([100,200])
monitoring[:net_rx].size.should eql(2)
monitoring[:net_rx].first.should eql([100,400])
mon = @watch_client.resource_monitoring(2)
mon[:id].should eql(2)
mon[:resource].should eql("VM")
monitoring = mon[:monitoring]
monitoring.keys.size.should eql(4)
monitoring[:cpu_usage].size.should eql(1)
monitoring[:cpu_usage].first.should eql([100,1])
monitoring[:mem_usage].size.should eql(1)
monitoring[:mem_usage].first.should eql([100,128])
monitoring[:net_tx].size.should eql(1)
monitoring[:net_tx].first.should eql([100,200])
monitoring[:net_rx].size.should eql(1)
monitoring[:net_rx].first.should eql([100,400])
end
it "should check all the total monitoring resources are shown by default" do
mon = @watch_client.total_monitoring
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring[:total].size.should eql(2)
monitoring[:total].first.should eql([100,1])
monitoring[:total][1].should eql([200,2])
monitoring[:active].size.should eql(2)
monitoring[:active].first.should eql([100,1])
monitoring[:active][1].should eql([200,2])
monitoring[:error].size.should eql(2)
monitoring[:error].first.should eql([100,0])
monitoring[:error][1].should eql([200,0])
monitoring[:cpu_usage].size.should eql(2)
monitoring[:cpu_usage].first.should eql([100,1])
monitoring[:cpu_usage][1].should eql([200,1*2])
monitoring[:mem_usage].size.should eql(2)
monitoring[:mem_usage].first.should eql([100,128])
monitoring[:mem_usage][1].should eql([200,128*2])
monitoring[:net_tx].size.should eql(2)
monitoring[:net_tx].first.should eql([100,200])
monitoring[:net_tx][1].should eql([200,200*2])
monitoring[:net_rx].size.should eql(2)
monitoring[:net_rx].first.should eql([100,400])
monitoring[:net_rx][1].should eql([200,400*2])
end
it "Create a third VM: uid=3 gid=5, timestamp=300" do
@monitoring.set_mock_timestamp(300)
values = {
:cpu => 1,
:memory => 128,
:net_tx => 200,
:net_rx => 400,
:last_poll => 270,
:uid => 3,
:gid => 5,
:history => [
:hid => 7,
:pstime => 150,
:petime => 0,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(3, values)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(3)
end
it "should check the total monitoring resources are filtered by uid(3)" do
mon = @watch_client.total_monitoring(nil, :uid=>3)
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring[:total].size.should eql(3)
monitoring[:total].first.should eql([100,0])
monitoring[:total][1].should eql([200,0])
monitoring[:total][2].should eql([300,1])
monitoring[:active].size.should eql(3)
monitoring[:active].first.should eql([100,0])
monitoring[:active][1].should eql([200,0])
monitoring[:active][2].should eql([300,1])
monitoring[:error].size.should eql(3)
monitoring[:error].first.should eql([100,0])
monitoring[:error][1].should eql([200,0])
monitoring[:error][2].should eql([300,0])
monitoring[:cpu_usage].size.should eql(3)
monitoring[:cpu_usage].first.should eql([100,0])
monitoring[:cpu_usage][1].should eql([200,0])
monitoring[:cpu_usage][2].should eql([300,1])
monitoring[:mem_usage].size.should eql(3)
monitoring[:mem_usage].first.should eql([100,0])
monitoring[:mem_usage][1].should eql([200,0])
monitoring[:mem_usage][2].should eql([300,128])
monitoring[:net_tx].size.should eql(3)
monitoring[:net_tx].first.should eql([100,0])
monitoring[:net_tx][1].should eql([200,0])
monitoring[:net_tx][2].should eql([300,200])
monitoring[:net_rx].size.should eql(3)
monitoring[:net_rx].first.should eql([100,0])
monitoring[:net_rx][1].should eql([200,0])
monitoring[:net_rx][2].should eql([300,400])
end
it "should check the total monitoring resources are filtered by gid(5)" do
mon = @watch_client.total_monitoring(nil, :gid=>5)
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring[:total].size.should eql(3)
monitoring[:total].first.should eql([100,0])
monitoring[:total][1].should eql([200,0])
monitoring[:total][2].should eql([300,1])
monitoring[:active].size.should eql(3)
monitoring[:active].first.should eql([100,0])
monitoring[:active][1].should eql([200,0])
monitoring[:active][2].should eql([300,1])
monitoring[:error].size.should eql(3)
monitoring[:error].first.should eql([100,0])
monitoring[:error][1].should eql([200,0])
monitoring[:error][2].should eql([300,0])
monitoring[:cpu_usage].size.should eql(3)
monitoring[:cpu_usage].first.should eql([100,0])
monitoring[:cpu_usage][1].should eql([200,0])
monitoring[:cpu_usage][2].should eql([300,1])
monitoring[:mem_usage].size.should eql(3)
monitoring[:mem_usage].first.should eql([100,0])
monitoring[:mem_usage][1].should eql([200,0])
monitoring[:mem_usage][2].should eql([300,128])
monitoring[:net_tx].size.should eql(3)
monitoring[:net_tx].first.should eql([100,0])
monitoring[:net_tx][1].should eql([200,0])
monitoring[:net_tx][2].should eql([300,200])
monitoring[:net_rx].size.should eql(3)
monitoring[:net_rx].first.should eql([100,0])
monitoring[:net_rx][1].should eql([200,0])
monitoring[:net_rx][2].should eql([300,400])
end
it "should check the total monitoring resources are filtered by uid(2)" do
mon = @watch_client.total_monitoring(nil, :uid=>2)
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring[:total].size.should eql(3)
monitoring[:total].first.should eql([100,1])
monitoring[:total][1].should eql([200,2])
monitoring[:active].last.should eql([300,2])
monitoring[:active].size.should eql(3)
monitoring[:active].first.should eql([100,1])
monitoring[:active][1].should eql([200,2])
monitoring[:active].last.should eql([300,2])
monitoring[:error].size.should eql(3)
monitoring[:error].first.should eql([100,0])
monitoring[:error][1].should eql([200,0])
monitoring[:error][2].should eql([300,0])
monitoring[:cpu_usage].size.should eql(3)
monitoring[:cpu_usage].first.should eql([100,1])
monitoring[:cpu_usage][1].should eql([200,2])
monitoring[:cpu_usage][2].should eql([300,2])
monitoring[:mem_usage].size.should eql(3)
monitoring[:mem_usage].first.should eql([100,128])
monitoring[:mem_usage][1].should eql([200,256])
monitoring[:mem_usage][2].should eql([300,256])
monitoring[:net_tx].size.should eql(3)
monitoring[:net_tx].first.should eql([100,200])
monitoring[:net_tx][1].should eql([200,400])
monitoring[:net_tx][2].should eql([300,400])
monitoring[:net_rx].size.should eql(3)
monitoring[:net_rx].first.should eql([100,400])
monitoring[:net_rx][1].should eql([200,800])
monitoring[:net_rx][2].should eql([300,800])
end
it "should check the total monitoring resources are filtered by gid(4)" do
mon = @watch_client.total_monitoring(nil, :gid=>4)
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring[:total].size.should eql(3)
monitoring[:total].first.should eql([100,1])
monitoring[:total][1].should eql([200,2])
monitoring[:total].last.should eql([300,2])
monitoring[:active].size.should eql(3)
monitoring[:active].first.should eql([100,1])
monitoring[:active][1].should eql([200,2])
monitoring[:active].last.should eql([300,2])
monitoring[:error].size.should eql(3)
monitoring[:error].first.should eql([100,0])
monitoring[:error][1].should eql([200,0])
monitoring[:error][2].should eql([300,0])
monitoring[:cpu_usage].size.should eql(3)
monitoring[:cpu_usage].first.should eql([100,1])
monitoring[:cpu_usage][1].should eql([200,2])
monitoring[:cpu_usage][2].should eql([300,2])
monitoring[:mem_usage].size.should eql(3)
monitoring[:mem_usage].first.should eql([100,128])
monitoring[:mem_usage][1].should eql([200,256])
monitoring[:mem_usage][2].should eql([300,256])
monitoring[:net_tx].size.should eql(3)
monitoring[:net_tx].first.should eql([100,200])
monitoring[:net_tx][1].should eql([200,400])
monitoring[:net_tx][2].should eql([300,400])
monitoring[:net_rx].size.should eql(3)
monitoring[:net_rx].first.should eql([100,400])
monitoring[:net_rx][1].should eql([200,800])
monitoring[:net_rx][2].should eql([300,800])
end
it "should check no total info for non existing user" do
mon = @watch_client.total_monitoring(nil, :uid=>5)
mon[:resource].should eql("VM_POOL")
monitoring = mon[:monitoring]
monitoring[:total].size.should eql(3)
monitoring[:total].first.should eql([100,0])
monitoring[:total][1].should eql([200,0])
monitoring[:total].last.should eql([300,0])
monitoring[:active].size.should eql(3)
monitoring[:active].first.should eql([100,0])
monitoring[:active][1].should eql([200,0])
monitoring[:active].last.should eql([300,0])
monitoring[:error].size.should eql(3)
monitoring[:error].first.should eql([100,0])
monitoring[:error][1].should eql([200,0])
monitoring[:error][2].should eql([300,0])
monitoring[:cpu_usage].size.should eql(3)
monitoring[:cpu_usage].first.should eql([100,0])
monitoring[:cpu_usage][1].should eql([200,0])
monitoring[:cpu_usage][2].should eql([300,0])
monitoring[:mem_usage].size.should eql(3)
monitoring[:mem_usage].first.should eql([100,0])
monitoring[:mem_usage][1].should eql([200,0])
monitoring[:mem_usage][2].should eql([300,0])
monitoring[:net_tx].size.should eql(3)
monitoring[:net_tx].first.should eql([100,0])
monitoring[:net_tx][1].should eql([200,0])
monitoring[:net_tx][2].should eql([300,0])
monitoring[:net_rx].size.should eql(3)
monitoring[:net_rx].first.should eql([100,0])
monitoring[:net_rx][1].should eql([200,0])
monitoring[:net_rx][2].should eql([300,0])
end
end

View File

@ -1 +0,0 @@
<VM_POOL/>

View File

@ -1,46 +0,0 @@
<VM>
<ID><%= id %></ID>
<UID><%= vm[:uid] ? vm[:uid] : 0 %></UID>
<GID><%= vm[:gid] ? vm[:gid] : 0 %></GID>
<NAME><%= vm[:name] ? vm[:uid] : 'pepe' %></NAME>
<LAST_POLL><%= vm[:last_poll] ? vm[:last_poll] : '1309275256' %></LAST_POLL>
<STATE><%= vm[:state] ? vm[:state] : 3 %></STATE>
<LCM_STATE>3</LCM_STATE>
<STIME>1309275252</STIME>
<ETIME>0</ETIME>
<DEPLOY_ID>dummy</DEPLOY_ID>
<MEMORY><%= vm[:memory] ? vm[:memory] : 128 %></MEMORY>
<CPU><%= vm[:cpu] ? vm[:cpu] : 1 %></CPU>
<NET_TX><%= vm[:net_tx] ? vm[:net_tx] : 0 %></NET_TX>
<NET_RX><%= vm[:net_rx] ? vm[:net_rx] : 0 %></NET_RX>
<TEMPLATE>
<CPU><![CDATA[1]]></CPU>
<MEMORY><![CDATA[1024]]></MEMORY>
<NAME><![CDATA[PEPEPE]]></NAME>
<VCPU><![CDATA[1]]></VCPU>
<VMID><![CDATA[4]]></VMID>
</TEMPLATE>
<% if history = vm[:history] %>
<HISTORY_RECORDS>
<% history.each do |h| %>
<HISTORY>
<SEQ><%= h[:seq] ? h[:seq] : 0 %></SEQ>
<HOSTNAME><%= h[:hostname] ? h[:hostname] : "kvxen" %></HOSTNAME>
<VM_DIR>/Users/dmolina/trabajo/acctmoni/install/var/</VM_DIR>
<HID><%= h[:hid] ? h[:hid] : 0 %></HID>
<STIME>1309275256</STIME>
<ETIME>0</ETIME>
<VMMMAD>vmm_dummy</VMMMAD>
<TMMAD>tm_dummy</TMMAD>
<PSTIME><%= h[:pstime] ? h[:pstime] : 0 %></PSTIME>
<PETIME><%= h[:petime] ? h[:petime] : 0 %></PETIME>
<RSTIME><%= h[:rstime] ? h[:rstime] : 0 %></RSTIME>
<RETIME><%= h[:retime] ? h[:retime] : 0 %></RETIME>
<ESTIME><%= h[:estime] ? h[:estime] : 0 %></ESTIME>
<EETIME><%= h[:eetime] ? h[:eetime] : 0 %></EETIME>
<REASON><%= h[:reason] ? h[:reason] : 0 %></REASON>
</HISTORY>
<% end %>
</HISTORY_RECORDS>
<% end %>
</VM>

View File

@ -1,49 +0,0 @@
<VM_POOL>
<% vms.each do |id,vm| %>
<VM>
<ID><%= id %></ID>
<UID><%= vm[:uid] ? vm[:uid] : 0 %></UID>
<GID><%= vm[:gid] ? vm[:gid] : 0 %></GID>
<NAME><%= vm[:name] ? vm[:uid] : 'pepe' %></NAME>
<LAST_POLL><%= vm[:last_poll] ? vm[:last_poll] : '1309275256' %></LAST_POLL>
<STATE><%= vm[:state] ? vm[:state] : 3 %></STATE>
<LCM_STATE>3</LCM_STATE>
<STIME>1309275252</STIME>
<ETIME>0</ETIME>
<DEPLOY_ID>dummy</DEPLOY_ID>
<MEMORY><%= vm[:memory] ? vm[:memory] : 128 %></MEMORY>
<CPU><%= vm[:cpu] ? vm[:cpu] : 1 %></CPU>
<NET_TX><%= vm[:net_tx] ? vm[:net_tx] : 0 %></NET_TX>
<NET_RX><%= vm[:net_rx] ? vm[:net_rx] : 0 %></NET_RX>
<TEMPLATE>
<CPU><![CDATA[1]]></CPU>
<MEMORY><![CDATA[1024]]></MEMORY>
<NAME><![CDATA[PEPEPE]]></NAME>
<VCPU><![CDATA[1]]></VCPU>
<VMID><![CDATA[4]]></VMID>
</TEMPLATE>
<% if history = vm[:history] %>
<HISTORY_RECORDS>
<% h = history.last %>
<HISTORY>
<SEQ><%= h[:seq] ? h[:seq] : 0 %></SEQ>
<HOSTNAME><%= h[:hostname] ? h[:hostname] : "kvxen" %></HOSTNAME>
<VM_DIR>/Users/dmolina/trabajo/acctmoni/install/var/</VM_DIR>
<HID><%= h[:hid] ? h[:hid] : 0 %></HID>
<STIME>1309275256</STIME>
<ETIME>0</ETIME>
<VMMMAD>vmm_dummy</VMMMAD>
<TMMAD>tm_dummy</TMMAD>
<PSTIME><%= h[:pstime] ? h[:pstime] : 0 %></PSTIME>
<PETIME><%= h[:petime] ? h[:petime] : 0 %></PETIME>
<RSTIME><%= h[:rstime] ? h[:rstime] : 0 %></RSTIME>
<RETIME><%= h[:retime] ? h[:retime] : 0 %></RETIME>
<ESTIME><%= h[:estime] ? h[:estime] : 0 %></ESTIME>
<EETIME><%= h[:eetime] ? h[:eetime] : 0 %></EETIME>
<REASON><%= h[:reason] ? h[:reason] : 0 %></REASON>
</HISTORY>
</HISTORY_RECORDS>
<% end %>
</VM>
<% end %>
</VM_POOL>

View File

@ -1,49 +0,0 @@
require 'erb'
FPATH = "./fixtures/"
class MockClient
def initialize
@vmpool = File.read("./fixtures/empty_pool.xml")
@done_vmpool = File.read("./fixtures/empty_pool.xml")
@vms = Hash.new
@done_vms = Hash.new
end
def call(action, *args)
xmlrpc_action = "one."+action
case xmlrpc_action
when "one.vm.info"
id = args[0]
vm = @vms[id]
return ERB.new(File.read(FPATH+'vm.xml')).result(binding)
when "one.vmpool.info"
case args[3]
when -1
return File.read("./fixtures/empty_pool.xml") if @vms.empty?
vms = @vms
return ERB.new(File.read(FPATH+'vmpool.xml')).result(binding)
when 6 then
return File.read("./fixtures/empty_pool.xml") if @done_vms.empty?
vms = @done_vms
return ERB.new(File.read(FPATH+'vmpool.xml')).result(binding)
end
end
end
def add_vm(id, values)
if values[:state] == 6
@done_vms[id] = values.clone
else
@vms[id] = values.clone
end
end
def delete_vm(id)
@vms.delete(id)
@vms_done.delete(id)
end
end

View File

@ -1,72 +0,0 @@
require 'rubygems'
require 'sequel'
ONE_LOCATION = ENV['ONE_LOCATION']
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby"
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
end
$: << RUBY_LIB_LOCATION
require 'OpenNebula'
$: << './helper'
$: << '.'
$: << '..'
require 'examples/acct_client'
require 'mock_client'
require 'accounting'
require 'monitoring'
module OneWatch
class Accounting
def set_mock_timestamp(t)
@mock_timestamp = t
end
def generate_timestamp
@mock_timestamp
end
end
class Monitoring
def set_mock_timestamp(t)
@mock_timestamp = t
end
def generate_timestamp
@mock_timestamp
end
end
end
def create_vmpool_hash
@vm_pool = OpenNebula::VirtualMachinePool.new(@mock_client, -2)
@vm_pool.info
hash = @vm_pool.to_hash
end
def clean_db
begin
WatchHelper::Register.destroy
WatchHelper::VmDelta.destroy
WatchHelper::VmSample.destroy
WatchHelper::HostSample.destroy
WatchHelper::VmTimestamp.destroy
WatchHelper::HostTimestamp.destroy
WatchHelper::Vm.destroy
WatchHelper::Host.destroy
rescue Exception => e
warn e.message
end
end
def check_lines(*args)
@db[:vms].count.should eql(args[0])
@db[:registers].count.should eql(args[1])
end

View File

@ -1,299 +0,0 @@
$: << '.'
require 'helper/test_helper.rb'
describe "VM Monitoring tests" do
before(:all) do
clean_db
@mock_client = MockClient.new
@monitoring = OneWatch::VmMonitoring.new
#@watch_client = OneWatchClient::WatchClient.new
@db = WatchHelper::DB
@db[:vms].count.should eql(0)
@db[:vm_samples].count.should eql(0)
@db[:vm_timestamps].count.should eql(0)
end
it "after monitoring an empty pool: 0 VMs, 0 Samples, 1 Timestamp" do
ts1 = 100
@monitoring.set_mock_timestamp(ts1)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(0)
@db[:vm_samples].count.should eql(0)
@db[:vm_timestamps].count.should eql(1)
end
it "after monitoring a pool of 1 VM: 1 VMs, 1 Samples, 2 Timestamp" do
values = {
:cpu => 80,
:memory => 122,
:net_tx => 200,
:net_rx => 134,
:last_poll => 1309275256,
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 0,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(0, values)
ts2 = 200
@monitoring.set_mock_timestamp(ts2)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(1)
@db[:vm_samples].count.should eql(1)
@db[:vm_timestamps].count.should eql(2)
end
it "after monitoring a pool of 1 VM: 1 VMs, 2 Samples, 3 Timestamp" do
values = {
:cpu => 80,
:memory => 122,
:net_tx => 200,
:net_rx => 134,
:last_poll => 1309275256,
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 0,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(0, values)
ts = 300
@monitoring.set_mock_timestamp(ts)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(1)
@db[:vm_samples].count.should eql(2)
@db[:vm_timestamps].count.should eql(3)
end
it "after monitoring a pool of 2 VM: 2 VMs, 4 Samples, 4 Timestamp" do
values = {
:cpu => 80,
:memory => 122,
:net_tx => 200,
:net_rx => 134,
:last_poll => 1309275256,
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 0,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(1, values)
ts = 400
@monitoring.set_mock_timestamp(ts)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(2)
@db[:vm_samples].count.should eql(4)
@db[:vm_timestamps].count.should eql(4)
end
it "after monitoring a pool of 2 VM: 2 VMs, 6 Samples, 5 Timestamp" do
values = {
:cpu => 80,
:memory => 122,
:net_tx => 200,
:net_rx => 134,
:last_poll => 1309275256,
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 0,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(1, values)
ts = 500
@monitoring.set_mock_timestamp(ts)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(2)
@db[:vm_samples].count.should eql(6)
@db[:vm_timestamps].count.should eql(5)
end
it "after monitoring a pool of 3 VM: 3 VMs, 9 Samples, 5 Timestamp" do
values = {
:cpu => 80,
:memory => 122,
:net_tx => 200,
:net_rx => 134,
:last_poll => 1309275256,
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 0,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(2, values)
ts = 600
@monitoring.set_mock_timestamp(ts)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(3)
@db[:vm_samples].count.should eql(9)
@db[:vm_timestamps].count.should eql(5)
end
it "after monitoring a pool of 3 VM: 3 VMs, 11 Samples, 5 Timestamp" do
values = {
:cpu => 80,
:memory => 122,
:net_tx => 200,
:net_rx => 134,
:last_poll => 1309275256,
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 0,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(2, values)
ts = 700
@monitoring.set_mock_timestamp(ts)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(3)
@db[:vm_samples].count.should eql(11)
@db[:vm_timestamps].count.should eql(5)
end
it "after monitoring a pool of 3 VM: 3 VMs, 13 Samples, 5 Timestamp" do
values = {
:cpu => 80,
:memory => 122,
:net_tx => 200,
:net_rx => 134,
:last_poll => 1309275256,
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 0,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(2, values)
ts = 800
@monitoring.set_mock_timestamp(ts)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(3)
@db[:vm_samples].count.should eql(13)
@db[:vm_timestamps].count.should eql(5)
end
it "after monitoring a pool of 4 VM: 4 VMs, 16 Samples, 5 Timestamp" do
values = {
:cpu => 80,
:memory => 122,
:net_tx => 200,
:net_rx => 134,
:last_poll => 1309275256,
:uid => 2,
:gid => 4,
:history => [
:hid => 7,
:pstime => 150,
:petime => 0,
:rstime => 0,
:retime => 0,
:estime => 0,
:eetime => 0,
:reason => 0
]
}
@mock_client.add_vm(3, values)
ts = 900
@monitoring.set_mock_timestamp(ts)
@monitoring.insert(create_vmpool_hash)
@db[:vms].count.should eql(4)
@db[:vm_samples].count.should eql(15)
@db[:vm_timestamps].count.should eql(5)
end
it "after (10)monitoring a pool of 4 VM: 4 VMs, 20 Samples, 5 Timestamp" do
10.times { |i|
ts = 1000+i*100
@monitoring.set_mock_timestamp(ts)
@monitoring.insert(create_vmpool_hash)
}
@db[:vms].count.should eql(4)
@db[:vm_samples].count.should eql(20)
@db[:vm_timestamps].count.should eql(5)
end
end

View File

@ -1,229 +0,0 @@
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
module OneWatchClient
require 'acct/watch_helper'
class WatchClient
TOTAL_COUNT = [:total, :active, :error]
def resource_monitoring(id, monitoring_resources=[], filter={})
# Retrieve Sequel resource
rsql = filter_resource(id, filter)
return nil if rsql.nil?
# By default show all the available monitoring resources.
# If a set of monitoring resources is specified
# select only the allowed ones
allowed_keys = allowed_samples.keys
if monitoring_resources && !monitoring_resources.empty?
monitoring_resources = allowed_keys & monitoring_resources
else
monitoring_resources = allowed_keys
end
# Initialize monitoring information
mon = Hash.new
monitoring_resources.each { |mr|
mon[mr] = Array.new
}
# Retrieve information
rsql.samples_dataset.map { |sample|
monitoring_resources.each { |mr|
if sample.last_poll && sample.last_poll != 0
mon[mr] << [sample.last_poll, sample.send(mr.to_sym)]
end
}
}
# Format response in a Hash
hash = Hash.new
hash[:resource] = kind
hash[:id] = rsql.id
hash[:monitoring] = mon
hash
end
def total_monitoring(monitoring_resources=[], filter={})
# Retrieve Sequel resource
rsql = filter_pool(filter)
return nil if rsql.nil?
# By default show all the available monitoring resources.
# If a set of monitoring resources is specified
# select only the allowed ones
allowed_keys = allowed_samples.keys + TOTAL_COUNT
if monitoring_resources && !monitoring_resources.empty?
monitoring_resources = allowed_keys & monitoring_resources
else
monitoring_resources = allowed_keys
end
# Retrieve information
mon = Hash.new
monitoring_resources.each { |opt|
opt = opt.to_sym
if allowed_samples.has_key?(opt)
mon[opt] = sum_monitoring(rsql, opt)
elsif TOTAL_COUNT.include?(opt)
mon[opt] = count_monitoring(rsql, opt)
end
}
# Format response in a Hash
hash = Hash.new
hash[:resource] = "#{kind.upcase}_POOL"
hash[:monitoring] = mon
hash
end
private
def sum_monitoring(rsql, mr)
# Get the MAX for each VM and last_poll value
max_per_vm =
rsql.
group(:timestamp).
select{[:timestamp, sum(mr.to_sym).as(:sum_mr)]}
# Add all the existing timestamps
with_ts = timestamps.left_join(max_per_vm, :timestamp=>:id)
with_ts.collect do |row|
[row[:id], row[:sum_mr].to_i]
end
end
def count_monitoring(rsql, opt)
resources = case opt
when :total then rsql
when :active then active(rsql)
when :error then error(rsql)
else return nil
end
count = resources.group_and_count(:timestamp)
# Add all the existing timestamps
with_ts = timestamps.left_join(count, :timestamp=>:id)
with_ts.collect do |row|
[row[:id], row[:count].to_i]
end
end
end
class HostWatchClient < WatchClient
def pool
WatchHelper::Host
end
def allowed_samples
WatchHelper::HOST_SAMPLE
end
def kind
"HOST"
end
def active(pool)
pool.filter('state < 3')
end
def error(pool)
pool.filter(:state=>3)
end
def timestamps
WatchHelper::HostTimestamp
end
def filter_pool(filter)
if filter[:uid]
filter[:uid]==0 ? (hosts = pool) : (return nil)
elsif filter[:gid]
filter[:gid]==0 ? (hosts = pool) : (return nil)
else
hosts = pool
end
WatchHelper::HostSample.join(hosts.select(:id.as(:host_id)), [:host_id])
end
def filter_resource(id, filter)
rsql = pool[id]
return nil if rsql.nil?
if filter[:uid]
filter[:uid]==0 ? rsql : nil
elsif filter[:gid]
filter[:gid]==0 ? rsql : nil
else
rsql
end
end
end
class VmWatchClient < WatchClient
def pool
WatchHelper::Vm
end
def allowed_samples
WatchHelper::VM_SAMPLE
end
def kind
"VM"
end
def active(pool)
pool.filter(:state=>3)
end
def error(pool)
pool.filter(:state=>7)
end
def timestamps
WatchHelper::VmTimestamp
end
def filter_pool(filter)
if filter[:uid]
vms = pool.filter(:uid=>filter[:uid])
elsif filter[:gid]
vms = pool.filter(:gid=>filter[:gid])
else
vms = pool
end
WatchHelper::VmSample.join(vms.select(:id.as(:vm_id)), [:vm_id])
end
def filter_resource(id, filter)
rsql = pool[id]
return nil if rsql.nil?
if filter[:uid]
filter[:uid]==rsql.uid ? rsql : nil
elsif filter[:gid]
filter[:gid]==rsql.gid ? rsql : nil
else
rsql
end
end
end
end

View File

@ -1,455 +0,0 @@
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
module WatchHelper
require 'sequel'
require 'yaml'
ONE_LOCATION=ENV["ONE_LOCATION"]
if !ONE_LOCATION
VAR_LOCATION = "/var/lib/one"
ETC_LOCATION = "/etc/one"
else
VAR_LOCATION = ONE_LOCATION + "/var"
ETC_LOCATION = ONE_LOCATION + "/etc"
end
ACCTD_CONF = ETC_LOCATION + "/acctd.conf"
ACCT_DB = VAR_LOCATION + "/oneacct.db"
CONF = YAML.load_file(ACCTD_CONF)
if CONF[:DB]
DB = Sequel.connect(CONF[:DB])
else
DB = Sequel.connect("sqlite://#{ACCT_DB}")
end
VM_DELTA = {
:net_rx => {
:type => Integer,
:path => 'NET_RX'
},
:net_tx => {
:type => Integer,
:path => 'NET_TX'
}
}
VM_SAMPLE = {
:cpu_usage => {
:type => Integer,
:path => 'CPU'
},
:mem_usage => {
:type => Integer,
:path => 'MEMORY'
},
:net_tx => {
:type => Integer,
:path => 'NET_TX'
},
:net_rx => {
:type => Integer,
:path => 'NET_RX'
}
}
HOST_SAMPLE = {
:disk_usage => {
:type => Integer,
:path => 'DISK_USAGE'
},
:mem_usage => {
:type => Integer,
:path => 'MEM_USAGE'
},
:cpu_usage => {
:type => Integer,
:path => 'CPU_USAGE'
},
:max_disk => {
:type => Integer,
:path => 'MAX_DISK'
},
:max_mem => {
:type => Integer,
:path => 'MAX_MEM'
},
:max_cpu => {
:type => Integer,
:path => 'MAX_CPU'
},
:free_disk => {
:type => Integer,
:path => 'FREE_DISK'
},
:free_mem => {
:type => Integer,
:path => 'FREE_MEM'
},
:free_cpu => {
:type => Integer,
:path => 'FREE_CPU'
},
:used_disk => {
:type => Integer,
:path => 'USED_DISK'
},
:used_mem => {
:type => Integer,
:path => 'USED_MEM'
},
:used_cpu => {
:type => Integer,
:path => 'USED_CPU'
},
:rvms => {
:type => Integer,
:path => 'RUNNING_VMS'
}
}
def self.get_config(*params)
conf = CONF
while param = params.shift
conf = conf[param]
break if conf.nil?
end
conf
end
def self.bootstrap
DB.create_table? :vms do
Integer :id, :primary_key=>true
String :name
Integer :uid
Integer :gid
Integer :mem
Float :cpu
Integer :vcpu
Integer :stime
Integer :etime
end
DB.create_table? :hosts do
Integer :id, :primary_key=>true
String :name
String :im_mad
String :vm_mad
String :vn_mad
end
DB.create_table? :vm_timestamps do
Integer :id, :primary_key=>true
end
DB.create_table? :vm_samples do
foreign_key :vm_id, :vms, :key=>:id
foreign_key :timestamp, :vm_timestamps, :key=>:id
Integer :state
Integer :lcm_state
Integer :last_poll
VM_SAMPLE.each { |key,value|
column key, value[:type]
}
primary_key [:vm_id, :timestamp]
end
DB.create_table? :host_timestamps do
Integer :id, :primary_key=>true
end
DB.create_table? :host_samples do
foreign_key :host_id, :hosts, :key=>:id
foreign_key :timestamp, :host_timestamps, :key=>:id
Integer :last_poll
Integer :state
HOST_SAMPLE.each { |key,value|
column key, value[:type]
}
primary_key [:host_id, :timestamp]
end
DB.create_table? :registers do
foreign_key :vm_id, :vms, :key=>:id
Integer :hid
String :hostname
Integer :seq
Integer :pstime
Integer :petime
Integer :rstime
Integer :retime
Integer :estime
Integer :eetime
Integer :reason
primary_key [:vm_id, :seq]
end
DB.create_table? :vm_deltas do
foreign_key :vm_id, :vms, :key=>:id
Integer :timestamp
Integer :ptimestamp
VM_DELTA.each { |key,value|
column key, value[:type]
}
primary_key [:vm_id, :timestamp]
end
end
self.bootstrap
class VmSample < Sequel::Model
unrestrict_primary_key
many_to_one :vm
many_to_one :timestamp,
:class=>"WatchHelper::VmTimestamp",
:key=>:id
end
class VmTimestamp < Sequel::Model
unrestrict_primary_key
one_to_many :samples,
:order=>:timestamp,
:class=>"WatchHelper::VmSample",
:key=>:timestamp
@@window_size = WatchHelper::get_config(
:VM_MONITORING,
:WINDOW_SIZE
)
def self.fix_size
if self.count > @@window_size
last_timestamp = self.all.first
last_timestamp.samples_dataset.destroy
last_timestamp.destroy
end
end
end
class HostSample < Sequel::Model
unrestrict_primary_key
many_to_one :host
many_to_one :timestamp,
:class=>"WatchHelper::HostTimestamp",
:key=>:id
end
class HostTimestamp < Sequel::Model
unrestrict_primary_key
one_to_many :samples,
:order=>:timestamp,
:class=>"WatchHelper::HostSample",
:key=>:timestamp
@@window_size = WatchHelper::get_config(
:HOST_MONITORING,
:WINDOW_SIZE
)
def self.fix_size
if self.count > @@window_size
last_timestamp = self.all.first
last_timestamp.samples_dataset.destroy
last_timestamp.destroy
end
end
end
class Register < Sequel::Model
unrestrict_primary_key
many_to_one :vm
def update_from_history(history)
self.seq = history['SEQ']
self.hostname = history['HOSTNAME']
self.hid = history['HID']
self.pstime = history['PSTIME']
self.petime = history['PETIME']
self.rstime = history['RSTIME']
self.retime = history['RETIME']
self.estime = history['ESTIME']
self.eetime = history['EETIME']
self.reason = history['REASON']
self.save
end
end
class VmDelta < Sequel::Model
unrestrict_primary_key
many_to_one :vm
end
class Vm < Sequel::Model
unrestrict_primary_key
# Accounting
one_to_many :registers, :order=>:seq
one_to_many :deltas, :order=>:timestamp, :class=>"WatchHelper::VmDelta"
# Monitoring
one_to_many :samples, :order=>:timestamp, :class=>"WatchHelper::VmSample"
@@samples_cache = []
@@deltas_cache = []
def self.info(vm)
Vm.find_or_create(:id=>vm['ID']) { |v|
v.name = vm['NAME']
v.uid = vm['UID'].to_i
v.gid = vm['GID'].to_i
v.mem = vm['TEMPLATE']['MEMORY'].to_i
v.cpu = vm['TEMPLATE']['CPU'].to_f
v.vcpu = vm['TEMPLATE']['VCPU'].to_i
v.stime = vm['STIME'].to_i
v.etime = vm['ETIME'].to_i
}
end
def add_register_from_resource(history)
self.add_register(
:seq => history['SEQ'],
:hostname => history['HOSTNAME'],
:hid => history['HID'],
:pstime => history['PSTIME'],
:petime => history['PETIME'],
:rstime => history['RSTIME'],
:retime => history['RETIME'],
:estime => history['ESTIME'],
:eetime => history['EETIME'],
:reason => history['REASON']
)
end
def add_sample_from_resource(vm, timestamp)
hash = {
:vm_id => vm['ID'],
:timestamp => timestamp.id,
:last_poll => vm['LAST_POLL'],
:state => vm['STATE'],
:lcm_state => vm['LCM_STATE']
}
VM_SAMPLE.each { |key,value|
hash[key] = vm[value[:path]]
}
@@samples_cache << hash
end
def add_delta_from_resource(vm, timestamp)
hash = Hash.new
hash[:vm_id] = vm['ID']
hash[:timestamp] = timestamp
if last_delta = self.deltas.first
hash[:ptimestamp] = last_delta.send(:timestamp)
VM_DELTA.each { |key,value|
old_value = last_delta.send("#{key}".to_sym)
new_value = vm[value[:path]].to_i
if old_value > new_value
hash[key] = new_value
else
hash[key] = new_value - old_value
end
}
else
hash[:ptimestamp] = 0
VM_DELTA.each { |key,value|
hash[key] = vm[value[:path]]
}
end
@@deltas_cache << hash
end
def self.flush
DB.transaction do
VmDelta.multi_insert(@@deltas_cache)
VmSample.multi_insert(@@samples_cache)
VmTimestamp.fix_size
end
@@samples_cache = []
@@deltas_cache = []
end
end
class Host < Sequel::Model
unrestrict_primary_key
# Monitoring
one_to_many :samples, :order=>:timestamp, :class=>"WatchHelper::HostSample"
@@samples_cache = []
def self.info(host)
Host.find_or_create(:id=>host['ID']) { |h|
h.name = host['NAME']
h.im_mad = host['IM_MAD']
h.vm_mad = host['VM_MAD']
h.vn_mad = host['VN_MAD']
}
end
def add_sample_from_resource(host, timestamp)
hash = {
:host_id => host['ID'],
:timestamp => timestamp.id,
:last_poll => host['LAST_MON_TIME'],
:state => host['STATE'],
}
host_share = host['HOST_SHARE']
HOST_SAMPLE.each { |key,value|
hash[key] = host_share[value[:path]]
}
@@samples_cache << hash
end
def self.flush
DB.transaction do
HostSample.multi_insert(@@samples_cache)
HostTimestamp.fix_size
end
@@samples_cache = []
end
end
end

View File

@ -15,7 +15,7 @@
/* -------------------------------------------------------------------------- */
#include "AclRule.h"
#include "AuthManager.h"
#include "AuthRequest.h"
#include "PoolObjectSQL.h"
/* -------------------------------------------------------------------------- */

View File

@ -15,6 +15,7 @@
/* -------------------------------------------------------------------------- */
#include "AuthManager.h"
#include "AuthRequest.h"
#include "NebulaLog.h"
#include "SSLTools.h"
#include "PoolObjectAuth.h"
@ -23,8 +24,6 @@
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
time_t AuthManager::_time_out;
const char * AuthManager::auth_driver_name = "auth_exe";
/* -------------------------------------------------------------------------- */
@ -203,7 +202,7 @@ void AuthManager::do_action(const string &action, void * arg)
}
else if (action == ACTION_TIMER)
{
timer_action();
check_time_outs_action();
}
else if (action == ACTION_FINALIZE)
{
@ -242,13 +241,12 @@ void AuthManager::authenticate_action(AuthRequest * ar)
// Queue the request
// ------------------------------------------------------------------------
ar->id = add_request(ar);
add_request(ar);
// ------------------------------------------------------------------------
// Make the request to the driver
// ---- --------------------------------------------------------------------
authm_md->authenticate(ar->id,
ar->uid,
ar->driver,
@ -287,7 +285,7 @@ void AuthManager::authorize_action(AuthRequest * ar)
// Queue the request
// ------------------------------------------------------------------------
ar->id = add_request(ar);
add_request(ar);
// ------------------------------------------------------------------------
// Make the request to the driver
@ -312,116 +310,6 @@ error:
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AuthManager::timer_action()
{
map<int,AuthRequest *>::iterator it;
time_t the_time = time(0);
lock();
it = auth_requests.begin();
while ( it !=auth_requests.end())
{
if ((it->second->time_out != 0) && (the_time > it->second->time_out))
{
AuthRequest * ar = it->second;
auth_requests.erase(it++);
ar->result = false;
ar->timeout = true;
ar->message = "Auth request timeout";
ar->notify();
}
else
{
++it;
}
}
unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int AuthManager::add_request(AuthRequest *ar)
{
static int auth_id = 0;
int id;
lock();
id = auth_id++;
auth_requests.insert(auth_requests.end(),make_pair(id,ar));
unlock();
return id;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
AuthRequest * AuthManager::get_request(int id)
{
AuthRequest * ar = 0;
map<int,AuthRequest *>::iterator it;
ostringstream oss;
lock();
it=auth_requests.find(id);
if ( it != auth_requests.end())
{
ar = it->second;
auth_requests.erase(it);
}
unlock();
return ar;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AuthManager::notify_request(int auth_id,bool result,const string& message)
{
AuthRequest * ar;
ar = get_request(auth_id);
if ( ar == 0 )
{
return;
}
ar->result = result;
if ( message != "-" )
{
if ( !ar->message.empty() )
{
ar->message.append("; ");
}
ar->message.append(message);
}
ar->notify();
}
/* ************************************************************************** */
/* MAD Loading */
/* ************************************************************************** */

View File

@ -65,7 +65,7 @@ public:
t->get("AUTH_MAD", am_mads);
return new AuthManager(1,3,am_mads);
return new AuthManager(1,am_mads);
};
};
@ -144,7 +144,7 @@ public:
/* ********************************************************************* */
/* ********************************************************************* */
//This test needs a driver that takes more than 3 secs to AUTHENTICATE
//This test needs a driver that takes more than 90 secs to AUTHENTICATE
void timeout()
{
AuthRequest ar(2, 2);
@ -157,8 +157,6 @@ public:
CPPUNIT_ASSERT(ar.result==false);
CPPUNIT_ASSERT(ar.timeout==true);
am->discard_request(ar.id);
}
void authenticate()

View File

@ -45,4 +45,6 @@ env.Prepend(LIBS=[
'crypto'
])
env.Program('test','AuthManagerTest.cc')
nt = env.Object('NebulaTemplate.o','../../nebula/NebulaTemplate.cc')
env.Program('test',[nt,'AuthManagerTest.cc'])

View File

@ -36,7 +36,7 @@ do
"AUTHENTICATE")
date 1>&2 >> mad.log
if [ "$ARG4" = "timeout" ] ; then
sleep 4
sleep 95
fi
date 1>&2 >> mad.log

View File

@ -1,189 +0,0 @@
#!/usr/bin/env ruby
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
ONE_LOCATION=ENV["ONE_LOCATION"]
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby"
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
end
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+"/cli"
require 'command_parser'
require 'cli_helper'
require 'one_helper'
require 'quota'
require 'pp'
QUOTA_KEYS = Quota::DB_QUOTA_SCHEMA.keys
def show_table(values, usage=nil)
size = usage ? 12 : 8
values.sort!{|v1, v2| v1[:UID]<=>v2[:UID] }
table=CLIHelper::ShowTable.new(nil, self) do
column :UID, "ONE identifier for the User", :size=>4 do |d|
d[:UID]
end
QUOTA_KEYS.each { |key|
column key, "#{key} quota", :size=>size do |d|
if usage
"#{usage[key].to_i}/#{d[key].to_i}"
else
"#{d[key].to_i}"
end
end
}
default :UID, *QUOTA_KEYS
end
table.show(values)
end
cmd=CommandParser::CmdParser.new(ARGV) do
usage "`onequota` <command> [<args>] [<options>]"
version OpenNebulaHelper::ONE_VERSION
quota = Quota.new
########################################################################
# Global Options
########################################################################
set :option, CommandParser::OPTIONS
########################################################################
# Argument Formats
########################################################################
quota_list_desc = <<-EOT.unindent
List of quota keys, comma separated.
Available quotas: #{QUOTA_KEYS.join(', ')}
EOT
set :format, :quota_list, quota_list_desc do |arg|
arg_list = arg.split(',')
rc = nil
arg_list.collect! do |elem|
sym = elem.upcase.to_sym
if !QUOTA_KEYS.include?(sym)
rc = -1, "#{elem} is not a valid quota"
break
end
sym
end
rc ? rc : [0, arg_list]
end
set :format, :value_list, "List of quota values, comma separated." do |arg|
arg_list = arg.split(',')
arg_list.map! {|a| a.to_i }
[0, arg_list]
end
set :format, :userid, OpenNebulaHelper.rname_to_id_desc("USER") do |arg|
OpenNebulaHelper.rname_to_id(arg, "USER")
end
########################################################################
# Commands
########################################################################
set_desc = <<-EOT.unindent
Set a quota for a given user.
Examples:
onequota set 3 cpu 12
onequota set 4 cpu,memory,storage 8,4096,10000
EOT
command :set, set_desc, :userid, :quota_list, :value_list do
user_id, keys, values = args
if keys.length != values.length
exit_with_code -1, "The number of keys and values does not match"
end
values_hash = Hash.new
keys.each_with_index { |k,i|
values_hash[k] = values[i]
}
quota.set_quota(user_id, values_hash)
exit_with_code 0
end
########################################################################
unset_desc = <<-EOT.unindent
Unset a quota for a given user.
Examples:
onequota unset 3 cpu
onequota unset 4 cpu,memory,storage
EOT
command :unset, unset_desc, :userid, :quota_list do
user_id, keys = args
values_hash = Hash.new
keys.each_with_index { |k,i|
values_hash[k] = 0
}
quota.set_quota(user_id, values_hash)
exit_with_code 0
end
########################################################################
delete_desc = "Delete the defined quotas for the given user"
command :delete, delete_desc, :userid do
quota.delete_quota(args[0])
exit_with_code 0
end
########################################################################
show_desc = "Show the user's quota and usage. (usage/quota)"
FORCE={
:name => "force",
:short => "-f",
:large => "--force",
:description => "Force the usage calculation instead of using the cache"
}
command :show, show_desc, :userid, :options=>[FORCE] do
user_usage = quota.get_usage(args[0],nil,options[:force])
user_quota = quota.get_quota(args[0])
show_table([user_quota], user_usage)
exit_with_code 0
end
########################################################################
list_desc = "List the defined quotas for all the users"
command :list, list_desc do
show_table(quota.get_quota)
exit_with_code 0
end
end

View File

@ -1,374 +0,0 @@
# -------------------------------------------------------------------------- #
# 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 'sequel'
require 'base64'
require 'yaml'
require 'uri'
require 'net/http'
class Quota
###########################################################################
# Constants with paths to relevant files and defaults
###########################################################################
ONE_LOCATION=ENV["ONE_LOCATION"]
if !ONE_LOCATION
VAR_LOCATION = "/var/lib/one"
ETC_LOCATION = "/etc/one"
else
VAR_LOCATION = ONE_LOCATION + "/var"
ETC_LOCATION = ONE_LOCATION + "/etc"
end
CONF_FILE = ETC_LOCATION + "/auth/quota.conf"
CONF = {
:db => "sqlite://#{VAR_LOCATION}/onequota.db",
:defaults => {
:CPU => nil,
:MEMORY => nil,
:NUM_VMS => nil,
:STORAGE => nil
}
}
###########################################################################
# Schema for the USAGE and QUOTA tables
###########################################################################
DB_QUOTA_SCHEMA = {
:CPU => Float,
:MEMORY => Integer,
:NUM_VMS => Integer,
:STORAGE => Integer
}
QUOTA_TABLE = :quotas
USAGE_TABLE = :usage
###########################################################################
# Usage params to calculate each quota
###########################################################################
VM_USAGE = {
:CPU => {
:proc_info => lambda {|template| template['CPU']},
:xpath => 'TEMPLATE/CPU'
},
:MEMORY => {
:proc_info => lambda {|template| template['MEMORY']},
:xpath => 'TEMPLATE/MEMORY'
},
:NUM_VMS => {
:proc_info => lambda {|template| 1 },
:xpath => 'ID',
:count => true
}
}
IMAGE_USAGE = {
:STORAGE => {
:proc_info => lambda {|template|
if template['TYPE'] == 'DATABLOCK'
template['SIZE'].to_i
elsif template['PATH']
uri = URI.parse(template['PATH'])
size = if uri.scheme.nil?
File.size(template['PATH'])
else
Net::HTTP.start(uri.host,uri.port) { |http|
http.head(uri.path)
}.content_length
end
(size.to_f / 2**20).round
elsif template['SAVED_VM_ID']
vm_id = template['SAVED_VM_ID'].to_i
disk_id = template['SAVED_DISK_ID'].to_i
client = OpenNebula::Client.new
vm = OpenNebula::VirtualMachine.new_with_id(vm_id, client)
vm.info
im_id = vm["DISK[DISK_ID=#{disk_id}]/IMAGE_ID"].to_i
im = OpenNebula::Image.new_with_id(im_id, client)
im.info
im['SIZE'].to_i
else
0
end
},
:xpath => 'SIZE'
}
}
RESOURCES = ["VM", "IMAGE"]
###########################################################################
# DB handling
###########################################################################
def initialize
conf = YAML.load_file(CONF_FILE)
@conf=CONF.merge(conf) {|key,h1,h2|
if h1.instance_of?(Hash) && h2.instance_of?(Hash)
h1.merge(h2)
else
if h2
h2
else
h1
end
end
}
@client = OpenNebula::Client.new
@db=Sequel.connect(@conf[:db])
create_table(QUOTA_TABLE)
create_table(USAGE_TABLE)
end
# Creates database quota table if it does not exist
def create_table(table)
@db.create_table?(table) do
Integer :UID
DB_QUOTA_SCHEMA.each { |key,value|
column key, value
}
primary_key :UID
index :UID
end
end
# Adds new user limits
def set(table, uid, quota={})
data=quota.delete_if{|key,value| !DB_QUOTA_SCHEMA.keys.include?(key)}
quotas=@db[table].filter(:UID => uid)
if quotas.first
quotas.update(data)
else
@db[table].insert(data.merge!(:UID => uid))
end
end
# Gets user limits
def get(table, uid=nil)
if uid
@db[table].filter(:UID => uid).first
else
@db[table].all
end
end
# Delete user limits
def delete(table, uid)
quotas=@db[table].filter(:UID => uid)
if quotas.first
quotas.delete
end
end
###########################################################################
# Quota Client
###########################################################################
def set_quota(uid, quota={})
set(QUOTA_TABLE, uid, quota)
end
# Retrieves quota information for a given user
#
# @param [Integer, nil] uid the user id from which get the quota
# information, if nil will retrieve the quotas for all users.
# @return [Hash] Hash containing the quota information and the user id
#
# {
# :uid => 4,
# :cpu => 8,
# :memory => 8064,
# :num_vms => 4,
# :storage => 1240019
# }
def get_quota(uid=nil)
limit = get(QUOTA_TABLE, uid)
limit ? limit : @conf[:defaults].merge!(:UID => uid)
end
def delete_quota(uid)
delete(QUOTA_TABLE, uid)
end
###########################################################################
# Authorization
###########################################################################
def authorize(user_id, request)
obj, template_or_id, op, owner, acl_eval = request.split(':')
if acl_eval.to_i == 0
return "ACL evaluation denied"
end
# Check if this op needs to check the quota
return false unless with_quota?(obj, op)
template = ""
if ( obj == "TEMPLATE" )
obj = "VM"
vm_template = OpenNebula::Template.new_with_id(template_or_id, @client)
vm_template.info
vm_template.each("TEMPLATE") { |xml_elem|
template = xml_elem.to_xml
}
else
template = Base64::decode64(template_or_id)
end
check_quotas(user_id.to_i, obj, template)
end
def check_quotas(user_id, obj, template)
info = get_resources(obj, template)
total = get_usage(user_id, obj, true)
quota = get_quota(user_id)
msg = ""
separator = ""
info.each { |qname, quota_requested|
unless quota[qname] || quota[qname]==0
next
end
type = DB_QUOTA_SCHEMA[qname].name.to_sym
used = send(type, total[qname])
request = send(type, quota_requested)
limit = send(type, quota[qname])
spent = used + request
if spent > limit
msg << separator
msg << " #{qname.to_s.upcase} quota exceeded "
msg << "(Quota: #{limit}, "
msg << "Used: #{used}, "
msg << "Requested: #{request})"
separator = ";"
end
}
if msg==""
return false
else
return msg.strip
end
end
def with_quota?(obj, op)
return (obj == "VM" && op == "CREATE") ||
(obj == "IMAGE" && op == "CREATE") ||
(obj == "TEMPLATE" && op == "USE")
end
###########################################################################
# Usage
###########################################################################
# Retrieves usage information for a given user
#
# @param [Integer] uid the user id from which get the usage information.
# @param ["VM", "IMAGE"] resource kind of resource. If nil will return
# the usage for all kinds of resources
# @param [true, false] force If true will force the usage calculation
# instead of retrieving it from the cache
# @return [Hash] Hash containing the usage information and the user id
#
# {
# :uid => 4,
# :cpu => 8,
# :memory => 8064,
# :num_vms => 4,
# :storage => 1240019
# }
def get_usage(user_id, resource=nil, force=false)
if force
if RESOURCES.include?(resource)
resources = [resource]
else
resources = RESOURCES
end
usage = Hash.new
resources.each{ |res|
pool = get_pool(res, user_id)
base_xpath = "/#{res}_POOL/#{resource}"
Quota.const_get("#{res}_USAGE".to_sym).each { |key, params|
usage[key] ||= 0
pool.each_xpath("#{base_xpath}/#{params[:xpath]}") { |elem|
if elem
if params[:count]
usage[key] += 1
else
usage[key] += send(DB_QUOTA_SCHEMA[key].name.to_sym, elem)
end
end
}
}
set(USAGE_TABLE, user_id, usage) unless usage.empty?
usage.merge!(:UID => user_id)
}
else
usage = get(USAGE_TABLE, user_id)
usage ||= {:UID => user_id}
end
usage
end
# Retrieve the useful information of the template for the specified
# kind of resource
def get_resources(resource, xml_template)
template = OpenNebula::XMLElement.new
template.initialize_xml(xml_template, 'TEMPLATE')
info = Hash.new
self.class.const_get("#{resource}_USAGE").each { |key, params|
info[key] = params[:proc_info].call(template).to_i
}
info
end
# Returns a an Array than contains the elements of the resource Pool
def get_pool(resource, user_id)
pool = case resource
when "VM" then OpenNebula::VirtualMachinePool.new(@client, user_id)
when "IMAGE" then OpenNebula::ImagePool.new(@client, user_id)
end
rc = pool.info
return pool
end
end

View File

@ -1,26 +0,0 @@
<IMAGE_POOL>
<% images.each do |id,image| %>
<IMAGE>
<ID><%= id %></ID>
<UID><%= image[:uid] ? image[:uid] : 0 %></UID>
<GID><%= image[:gid] ? image[:gid] : 0 %></GID>
<UNAME><%= image[:uname] ? image[:uname] : 'oneadmin' %></UNAME>
<GNAME><%= image[:gname] ? image[:gname] : 'oneadmin' %></GNAME>
<NAME><%= image[:name] ? image[:name] : 'ttylinux' %></NAME>
<TYPE><%= image[:type] ? image[:type] : 0 %></TYPE>
<PUBLIC><%= image[:pub] ? image[:pub] : 0 %></PUBLIC>
<PERSISTENT><%= image[:persistent] ? image[:persistent] : 0 %></PERSISTENT>
<REGTIME>1314875019</REGTIME>
<SOURCE><%= image[:source] ? image[:source] : '/etc/hosts' %></SOURCE>
<STATE><%= image[:state] ? image[:state] : 1 %></STATE>
<SIZE><%= image[:size] ? image[:size] : 100 %></SIZE>
<RUNNING_VMS>0</RUNNING_VMS>
<TEMPLATE>
<DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX>
<NAME><![CDATA[PEPE]]></NAME>
<PATH><![CDATA[/etc/hosts]]></PATH>
<TYPE><![CDATA[OS]]></TYPE>
</TEMPLATE>
</IMAGE>
<% end %>
</IMAGE_POOL>

View File

@ -1,46 +0,0 @@
<VM>
<ID><%= id %></ID>
<UID><%= vm[:uid] ? vm[:uid] : 0 %></UID>
<GID><%= vm[:gid] ? vm[:gid] : 0 %></GID>
<NAME><%= vm[:name] ? vm[:uid] : 'pepe' %></NAME>
<LAST_POLL><%= vm[:last_poll] ? vm[:last_poll] : '1309275256' %></LAST_POLL>
<STATE><%= vm[:state] ? vm[:state] : 3 %></STATE>
<LCM_STATE>3</LCM_STATE>
<STIME>1309275252</STIME>
<ETIME>0</ETIME>
<DEPLOY_ID>dummy</DEPLOY_ID>
<MEMORY><%= vm[:memory] ? vm[:memory] : 128 %></MEMORY>
<CPU><%= vm[:cpu] ? vm[:cpu] : 1 %></CPU>
<NET_TX><%= vm[:net_tx] ? vm[:net_tx] : 0 %></NET_TX>
<NET_RX><%= vm[:net_rx] ? vm[:net_rx] : 0 %></NET_RX>
<TEMPLATE>
<CPU><![CDATA[1]]></CPU>
<MEMORY><![CDATA[1024]]></MEMORY>
<NAME><![CDATA[PEPEPE]]></NAME>
<VCPU><![CDATA[1]]></VCPU>
<VMID><![CDATA[4]]></VMID>
</TEMPLATE>
<% if history = vm[:history] %>
<HISTORY_RECORDS>
<% history.each do |h| %>
<HISTORY>
<SEQ><%= h[:seq] ? h[:seq] : 0 %></SEQ>
<HOSTNAME><%= h[:hostname] ? h[:hostname] : "kvxen" %></HOSTNAME>
<VM_DIR>/Users/dmolina/trabajo/acctmoni/install/var/</VM_DIR>
<HID><%= h[:hid] ? h[:hid] : 0 %></HID>
<STIME>1309275256</STIME>
<ETIME>0</ETIME>
<VMMMAD>vmm_dummy</VMMMAD>
<TMMAD>tm_dummy</TMMAD>
<PSTIME><%= h[:pstime] ? h[:pstime] : 0 %></PSTIME>
<PETIME><%= h[:petime] ? h[:petime] : 0 %></PETIME>
<RSTIME><%= h[:rstime] ? h[:rstime] : 0 %></RSTIME>
<RETIME><%= h[:retime] ? h[:retime] : 0 %></RETIME>
<ESTIME><%= h[:estime] ? h[:estime] : 0 %></ESTIME>
<EETIME><%= h[:eetime] ? h[:eetime] : 0 %></EETIME>
<REASON><%= h[:reason] ? h[:reason] : 0 %></REASON>
</HISTORY>
<% end %>
</HISTORY_RECORDS>
<% end %>
</VM>

View File

@ -1,49 +0,0 @@
<VM_POOL>
<% vms.each do |id,vm| %>
<VM>
<ID><%= id %></ID>
<UID><%= vm[:uid] ? vm[:uid] : 0 %></UID>
<GID><%= vm[:gid] ? vm[:gid] : 0 %></GID>
<NAME><%= vm[:name] ? vm[:uid] : 'pepe' %></NAME>
<LAST_POLL><%= vm[:last_poll] ? vm[:last_poll] : '1309275256' %></LAST_POLL>
<STATE><%= vm[:state] ? vm[:state] : 3 %></STATE>
<LCM_STATE>3</LCM_STATE>
<STIME>1309275252</STIME>
<ETIME>0</ETIME>
<DEPLOY_ID>dummy</DEPLOY_ID>
<MEMORY><%= vm[:memory] ? vm[:memory] : 128 %></MEMORY>
<CPU><%= vm[:cpu] ? vm[:cpu] : 1 %></CPU>
<NET_TX><%= vm[:net_tx] ? vm[:net_tx] : 0 %></NET_TX>
<NET_RX><%= vm[:net_rx] ? vm[:net_rx] : 0 %></NET_RX>
<TEMPLATE>
<CPU><![CDATA[<%= vm[:cpu] ? vm[:cpu] : 1 %>]]></CPU>
<MEMORY><![CDATA[<%= vm[:memory] ? vm[:memory] : 128 %>]]></MEMORY>
<NAME><![CDATA[PEPEPE]]></NAME>
<VCPU><![CDATA[1]]></VCPU>
<VMID><![CDATA[4]]></VMID>
</TEMPLATE>
<% if history = vm[:history] %>
<HISTORY_RECORDS>
<% h = history.last %>
<HISTORY>
<SEQ><%= h[:seq] ? h[:seq] : 0 %></SEQ>
<HOSTNAME><%= h[:hostname] ? h[:hostname] : "kvxen" %></HOSTNAME>
<VM_DIR>/Users/dmolina/trabajo/acctmoni/install/var/</VM_DIR>
<HID><%= h[:hid] ? h[:hid] : 0 %></HID>
<STIME>1309275256</STIME>
<ETIME>0</ETIME>
<VMMMAD>vmm_dummy</VMMMAD>
<TMMAD>tm_dummy</TMMAD>
<PSTIME><%= h[:pstime] ? h[:pstime] : 0 %></PSTIME>
<PETIME><%= h[:petime] ? h[:petime] : 0 %></PETIME>
<RSTIME><%= h[:rstime] ? h[:rstime] : 0 %></RSTIME>
<RETIME><%= h[:retime] ? h[:retime] : 0 %></RETIME>
<ESTIME><%= h[:estime] ? h[:estime] : 0 %></ESTIME>
<EETIME><%= h[:eetime] ? h[:eetime] : 0 %></EETIME>
<REASON><%= h[:reason] ? h[:reason] : 0 %></REASON>
</HISTORY>
</HISTORY_RECORDS>
<% end %>
</VM>
<% end %>
</VM_POOL>

View File

@ -1,53 +0,0 @@
require 'erb'
FPATH = "./fixtures/"
class MockClient
def initialize
@vms = Hash.new
@done_vms = Hash.new
@images = Hash.new
end
def call(action, *args)
xmlrpc_action = "one."+action
case xmlrpc_action
when "one.vm.info"
id = args[0]
vm = @vms[id]
return ERB.new(File.read(FPATH+'vm.xml')).result(binding)
when "one.vmpool.info"
case args[3]
when -1
vms = @vms
return ERB.new(File.read(FPATH+'vmpool.xml')).result(binding)
when 6 then
vms = @done_vms
return ERB.new(File.read(FPATH+'vmpool.xml')).result(binding)
end
when "one.imagepool.info"
images = @images
return ERB.new(File.read(FPATH+'imagepool.xml')).result(binding)
end
end
def add_vm(id, values)
if values[:state] == 6
@done_vms[id] = values.clone
else
@vms[id] = values.clone
end
end
def delete_vm(id)
@vms.delete(id)
@vms_done.delete(id)
end
def add_image(id, values)
@images[id] = values
end
end

View File

@ -1,31 +0,0 @@
ONE_LOCATION = ENV['ONE_LOCATION']
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby"
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
end
$: << RUBY_LIB_LOCATION
$: << './helper'
$: << '.'
$: << '..'
require 'mock_client'
require 'OpenNebula'
require 'quota'
class Quota
def set_client(client)
@client = client
end
def rm_and_set_testdb
`rm -f /tmp/onequota_test.db`
@db=Sequel.connect("sqlite:///tmp/onequota_test.db")
create_table(QUOTA_TABLE)
create_table(USAGE_TABLE)
end
end

View File

@ -1,343 +0,0 @@
$: << '.'
require 'helper/test_helper'
describe "Quota testing" do
before(:all) do
@mock_client = MockClient.new
@quota = Quota.new
@quota.set_client(@mock_client)
@quota.rm_and_set_testdb
@uid1 = 0
@quota1 = {
:CPU => 2.4,
:MEMORY => 1024,
:NUM_VMS => 4,
:STORAGE => 10000
}
@uid2 = 1
@quota2 = {
:CPU => 1.2,
:MEMORY => 512,
:NUM_VMS => 2,
:STORAGE => 5000
}
# Generate VM ACL request
vm_template = <<-EOT
<TEMPLATE>
<CPU>2</CPU>
<MEMORY>128</MEMORY>
</TEMPLATE>
EOT
vm_base64 = Base64::encode64(vm_template)
@acl_vm_create = "VM:#{vm_base64}:CREATE:0:1:1"
# Generate IMAGE ACL request
image_template = <<-EOT
<TEMPLATE>
<PATH>/etc/hosts</PATH>
</TEMPLATE>
EOT
image_base64 = Base64::encode64(image_template)
@acl_image_create = "IMAGE:#{image_base64}:CREATE:0:1:1"
# Generate TEMPLATE ACL request
temp_template = <<-EOT
<TEMPLATE>
<CPU>2</CPU>
<MEMORY>128</MEMORY>
</TEMPLATE>
EOT
temp_base64 = Base64::encode64(temp_template)
@acl_template_instantiate = "TEMPLATE:#{temp_base64}:INSTANTIATE:0:1:1"
end
it "should check default quotas" do
quota1 = @quota.get_quota(@uid1)
quota1[:UID].should eql(0)
quota1[:NUM_VMS].should eql(nil)
quota1[:CPU].should eql(nil)
quota1[:MEMORY].should eql(nil)
quota1[:STORAGE].should eql(nil)
end
it "should check default usage cache" do
usage1cache = @quota.get_usage(@uid1)
usage1cache[:UID].should eql(0)
usage1cache[:NUM_VMS].should eql(nil)
usage1cache[:CPU].should eql(nil)
usage1cache[:MEMORY].should eql(nil)
usage1cache[:STORAGE].should eql(nil)
end
it "should check default cache (force)" do
usage1force = @quota.get_usage(@uid1, nil, true)
usage1force[:UID].should eql(0)
usage1force[:NUM_VMS].should eql(0)
usage1force[:CPU].should eql(0)
usage1force[:MEMORY].should eql(0)
usage1force[:STORAGE].should eql(0)
end
it "should authorize the user because there is no quota defined" do
@quota.authorize(@uid1, @acl_vm_create).should eql(false)
@quota.authorize(@uid1, @acl_image_create).should eql(false)
@quota.authorize(@uid1, @acl_template_instantiate).should eql(false)
end
it "should add a new VM" do
values = {
:CPU => 2,
:MEMORY => 128,
:UID => 2,
:GID => 4,
}
@mock_client.add_vm(0, values)
end
it "should check the usage cache is not updated" do
usage1cache = @quota.get_usage(@uid1)
usage1cache[:UID].should eql(0)
usage1cache[:NUM_VMS].should eql(0)
usage1cache[:CPU].should eql(0.0)
usage1cache[:MEMORY].should eql(0)
usage1cache[:STORAGE].should eql(0)
end
it "should check the cache (force)" do
usage1force = @quota.get_usage(@uid1, nil, true)
usage1force[:UID].should eql(0)
usage1force[:NUM_VMS].should eql(1)
usage1force[:CPU].should eql(2.0)
usage1force[:MEMORY].should eql(128)
usage1force[:STORAGE].should eql(0)
end
it "should check the usage cache is updated and contains the last usage" do
usage1cache = @quota.get_usage(@uid1)
usage1cache[:UID].should eql(0)
usage1cache[:NUM_VMS].should eql(1)
usage1cache[:CPU].should eql(2.0)
usage1cache[:MEMORY].should eql(128)
usage1cache[:STORAGE].should eql(0)
end
it "should add a new Image" do
values = {
:UID => 2,
:GID => 4,
:SIZE => 1000
}
@mock_client.add_image(0, values)
end
it "should check the usage cache is not updated" do
usage1cache = @quota.get_usage(@uid1)
usage1cache[:UID].should eql(0)
usage1cache[:NUM_VMS].should eql(1)
usage1cache[:CPU].should eql(2.0)
usage1cache[:MEMORY].should eql(128)
usage1cache[:STORAGE].should eql(0)
end
it "should check the cache (force)" do
usage1force = @quota.get_usage(@uid1, nil, true)
usage1force[:UID].should eql(0)
usage1force[:NUM_VMS].should eql(1)
usage1force[:CPU].should eql(2.0)
usage1force[:MEMORY].should eql(128)
usage1force[:STORAGE].should eql(1000)
end
it "should check the usage cache is updated and contains the last usage" do
usage1cache = @quota.get_usage(@uid1)
usage1cache[:UID].should eql(0)
usage1cache[:NUM_VMS].should eql(1)
usage1cache[:CPU].should eql(2.0)
usage1cache[:MEMORY].should eql(128)
usage1cache[:STORAGE].should eql(1000)
end
it "should add a second VM" do
values = {
:CPU => 2,
:MEMORY => 128,
:UID => 2,
:GID => 4,
}
@mock_client.add_vm(1, values)
end
it "should check the usage cache is not updated" do
usage1cache = @quota.get_usage(@uid1)
usage1cache[:UID].should eql(0)
usage1cache[:NUM_VMS].should eql(1)
usage1cache[:CPU].should eql(2.0)
usage1cache[:MEMORY].should eql(128)
usage1cache[:STORAGE].should eql(1000)
end
it "should check the cache (force)" do
usage1force = @quota.get_usage(@uid1, nil, true)
usage1force[:UID].should eql(0)
usage1force[:NUM_VMS].should eql(1*2)
usage1force[:CPU].should eql(2.0*2)
usage1force[:MEMORY].should eql(128*2)
usage1force[:STORAGE].should eql(1000)
end
it "should check the usage cache is updated and contains the last usage" do
usage1cache = @quota.get_usage(@uid1)
usage1cache[:UID].should eql(0)
usage1cache[:NUM_VMS].should eql(1*2)
usage1cache[:CPU].should eql(2.0*2)
usage1cache[:MEMORY].should eql(128*2)
usage1cache[:STORAGE].should eql(1000)
end
it "should add a second Image" do
values = {
:UID => 2,
:GID => 4,
:SIZE => 1000
}
@mock_client.add_image(1, values)
end
it "should check the usage cache is not updated" do
usage1cache = @quota.get_usage(@uid1)
usage1cache[:UID].should eql(0)
usage1cache[:NUM_VMS].should eql(1*2)
usage1cache[:CPU].should eql(2.0*2)
usage1cache[:MEMORY].should eql(128*2)
usage1cache[:STORAGE].should eql(1000)
end
it "should check the cache (force)" do
usage1force = @quota.get_usage(@uid1, nil, true)
usage1force[:UID].should eql(0)
usage1force[:NUM_VMS].should eql(1*2)
usage1force[:CPU].should eql(2.0*2)
usage1force[:MEMORY].should eql(128*2)
usage1force[:STORAGE].should eql(1000*2)
end
it "should check the usage cache is updated and contains the last usage" do
usage1cache = @quota.get_usage(@uid1)
usage1cache[:UID].should eql(0)
usage1cache[:NUM_VMS].should eql(1*2)
usage1cache[:CPU].should eql(2.0*2)
usage1cache[:MEMORY].should eql(128*2)
usage1cache[:STORAGE].should eql(1000*2)
end
it "should add a new quota and check it" do
@quota.set_quota(@uid1, @quota1)
quota = @quota.get_quota(@uid1)
@quota1.each{ |key,value|
quota[key].should eql(value)
}
end
it "should not authorize the user because the vm quota is spent" do
err_msg = "CPU quota exceeded (Quota: 2.4, Used: 4.0, Requested: 2.0)"
@quota.authorize(@uid1, @acl_vm_create).should eql(err_msg)
@quota.authorize(@uid1, @acl_template_instantiate).should eql(err_msg)
@quota.authorize(@uid1, @acl_image_create).should eql(false)
end
it "should add a new quota for another user and check it" do
@quota.set_quota(@uid2, @quota2)
quota = @quota.get_quota(@uid2)
@quota2.each{ |key,value|
quota[key].should eql(value)
}
end
it "should list all the defined quotas" do
quotas = @quota.get_quota
quotas.each { |quota|
if quota[:UID] == @uid1
@quota1.each{ |key,value|
quota[key].should eql(value)
}
elsif quota[:UID] == @uid2
@quota2.each{ |key,value|
quota[key].should eql(value)
}
end
}
end
it "should update the first user quota and check it" do
new_quota = Hash.new
@quota1.each { |key,value|
new_quota[key] = value*3
}
@quota.set_quota(@uid1, new_quota)
quota = @quota.get_quota(@uid1)
new_quota.each{ |key,value|
quota[key] == value
}
end
it "should authorize the user because the quota is not spent" do
@quota.authorize(@uid1, @acl_vm_create).should eql(false)
@quota.authorize(@uid1, @acl_image_create).should eql(false)
@quota.authorize(@uid1, @acl_template_instantiate).should eql(false)
end
it "should update the first user quota and check it" do
new_quota = {
:STORAGE => 0
}
@quota.set_quota(@uid1, new_quota)
quota = @quota.get_quota(@uid1)
quota[:STORAGE].should eql(new_quota[:STORAGE])
end
it "should not authorize the user because the image quota is spent" do
@quota.authorize(@uid1, @acl_vm_create).should eql(false)
@quota.authorize(@uid1, @acl_template_instantiate).should eql(false)
err_msg = "STORAGE quota exceeded (Quota: 0, Used: 2000, Requested: 271)"
@quota.authorize(@uid1, @acl_image_create).should eql(err_msg)
end
it "should delete the quota and check it" do
@quota.delete_quota(@uid1)
quota1 = @quota.get_quota(@uid1)
quota1[:UID].should eql(0)
quota1[:NUM_VMS].should eql(nil)
quota1[:CPU].should eql(nil)
quota1[:MEMORY].should eql(nil)
quota1[:STORAGE].should eql(nil)
end
it "should authorize the user because the quota was deleted" do
@quota.authorize(@uid1, @acl_vm_create).should eql(false)
@quota.authorize(@uid1, @acl_image_create).should eql(false)
@quota.authorize(@uid1, @acl_template_instantiate).should eql(false)
end
end

View File

@ -84,10 +84,14 @@ module CLIHelper
# Print header
def CLIHelper.print_header(str, underline=true)
if $stdout.tty?
scr_bold
scr_underline if underline
print str
scr_restore
else
print str
end
puts
end

53
src/cli/etc/oneacct.yaml Normal file
View File

@ -0,0 +1,53 @@
---
:VID:
:desc: Virtual Machine ID
:size: 4
:SEQ:
:desc: History record sequence number
:size: 3
:HOSTNAME:
:desc: Host name
:size: 15
:left: true
:REASON:
:desc: VM state change reason
:size: 4
:left: true
:START_TIME:
:desc: Start time
:size: 14
:END_TIME:
:desc: End time
:size: 14
:MEMORY:
:desc: Assigned memory
:size: 6
:CPU:
:desc: Number of CPUs
:size: 3
:NET_RX:
:desc: Data received from the network
:size: 6
:NET_TX:
:desc: Data sent to the network
:size: 6
:default:
- :VID
- :HOSTNAME
- :REASON
- :START_TIME
- :END_TIME
- :MEMORY
- :CPU
- :NET_RX
- :NET_TX

View File

@ -8,7 +8,21 @@
:size: 15
:left: true
:VMS:
:desc: Number of VMS
:size: 8
:MEMORY:
:desc: Total memory allocated to user VMs
:size: 8
:CPU:
:desc: Total CPU allocated to user VMs
:size: 8
:default:
- :ID
- :NAME
- :VMS
- :MEMORY
- :CPU

View File

@ -18,6 +18,18 @@
:size: 8
:left: true
:VMS:
:desc: Number of VMS
:size: 8
:MEMORY:
:desc: Total memory allocated to user VMs
:size: 8
:CPU:
:desc: Total CPU allocated to user VMs
:size: 8
:PASSWORD:
:desc: Password of the User
:size: 50
@ -27,4 +39,7 @@
- :GROUP
- :NAME
- :AUTH
- :PASSWORD
- :VMS
- :MEMORY
- :CPU

View File

@ -15,6 +15,7 @@
#--------------------------------------------------------------------------- #
require 'one_helper'
require 'one_helper/onequota_helper'
class OneGroupHelper < OpenNebulaHelper::OneHelper
def self.rname
@ -56,7 +57,31 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
d["NAME"]
end
default :ID, :NAME
column :VMS, "Total number of VMS", :size=>8 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
d['VM_QUOTA']['VM']['VMS']
else
"-"
end
end
column :MEMORY, "Total memory allocated to group VMs", :size=>8 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
d['VM_QUOTA']['VM']['MEMORY_USED']
else
"-"
end
end
column :CPU, "Total CPU allocated to group VMs", :size=>8 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
d['VM_QUOTA']['VM']['CPU_USED']
else
"-"
end
end
default :ID, :NAME, :VMS, :MEMORY, :CPU
end
table
@ -92,5 +117,9 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
group.user_ids.each do |uid|
puts "%-15s" % [uid]
end
group_hash = group.to_hash
OneQuotaHelper.format_quota(group_hash['GROUP'])
end
end

View File

@ -0,0 +1,209 @@
# -------------------------------------------------------------------------- #
# 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 'cli_helper'
class OneQuotaHelper
#---------------------------------------------------------------------------
# Tables to format user quotas
#---------------------------------------------------------------------------
TABLE_DS = CLIHelper::ShowTable.new(nil, self) do
column :"DATASTORE ID", "", :left, :size=>12 do |d|
d["ID"] if !d.nil?
end
column :"IMAGES (used)", "", :right, :size=>14 do |d|
d["IMAGES_USED"] if !d.nil?
end
column :"IMAGES (limit)", "", :right, :size=>14 do |d|
d["IMAGES"] if !d.nil?
end
column :"SIZE (used)", "", :right, :size=>14 do |d|
d["SIZE_USED"] if !d.nil?
end
column :"SIZE (limit)", "", :right, :size=>14 do |d|
d["SIZE"] if !d.nil?
end
end
TABLE_NET = CLIHelper::ShowTable.new(nil, self) do
column :"NETWORK ID", "", :left, :size=>12 do |d|
d["ID"] if !d.nil?
end
column :"LEASES (used)", "", :right, :size=>14 do |d|
d["LEASES_USED"] if !d.nil?
end
column :"LEASES (limit)", "", :right, :size=>14 do |d|
d["LEASES"] if !d.nil?
end
end
TABLE_VM = CLIHelper::ShowTable.new(nil, self) do
column :"VMS", "", :left, :size=>12 do |d|
d["VMS"] if !d.nil?
end
column :"MEMORY (used)", "", :right, :size=>14 do |d|
d["MEMORY_USED"] if !d.nil?
end
column :"MEMORY (limit)", "", :right, :size=>14 do |d|
d["MEMORY"] if !d.nil?
end
column :"CPU (used)", "", :right, :size=>14 do |d|
d["CPU_USED"] if !d.nil?
end
column :"CPU (limit)", "", :right, :size=>14 do |d|
d["CPU"] if !d.nil?
end
end
TABLE_IMG = CLIHelper::ShowTable.new(nil, self) do
column :"IMAGE ID", "", :left, :size=>12 do |d|
d["ID"] if !d.nil?
end
column :"RVMS (used)", "", :right, :size=>14 do |d|
d["RVMS_USED"] if !d.nil?
end
column :"RVMS (limit)", "", :right, :size=>14 do |d|
d["RVMS"] if !d.nil?
end
end
HELP_QUOTA = <<-EOT.unindent
#-----------------------------------------------------------------------
# Supported quota limits:
#
# DATASTORE = [
# ID = <ID of the datastore>
# IMAGES = <Max. number of images in the datastore>
# SIZE = <Max. storage capacity (Mb) used in the datastore>
# ]
#
# VM = [
# VMS = <Max. number of VMs>
# MEMORY = <Max. allocated memory (Mb)>
# CPU = <Max. allocated CPU>
# ]
#
# NETWORK = [
# ID = <ID of the network>
# LEASES = <Max. number of IP leases from the network>
# ]
#
# 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.
#-----------------------------------------------------------------------
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
# used
# @return [String] contents of the new quotas
def self.set_quota(resource, path)
str = ""
if path.nil?
require 'tempfile'
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"
tmp << resource.template_like_str("NETWORK_QUOTA") << "\n"
tmp << resource.template_like_str("IMAGE_QUOTA") << "\n"
tmp.close
editor_path = ENV["EDITOR"] ? ENV["EDITOR"] : EDITOR_PATH
system("#{editor_path} #{path}")
unless $?.exitstatus == 0
puts "Editor not defined"
exit -1
end
str = File.read(path)
File.unlink(path)
else
str = File.read(path)
end
str
end
# Outputs formated quota information to stdout
# @param qh [Hash] with the quotas for a given resource
#
def self.format_quota(qh)
str_h1="%-80s"
puts
CLIHelper.print_header(str_h1 % "RESOURCE USAGE & QUOTAS",false)
puts
ds_quotas = [qh['DATASTORE_QUOTA']['DATASTORE']].flatten
if !ds_quotas[0].nil?
TABLE_DS.show(ds_quotas, {})
puts
end
vm_quotas = [qh['VM_QUOTA']['VM']].flatten
if !vm_quotas[0].nil?
TABLE_VM.show(vm_quotas, {})
puts
end
net_quotas = [qh['NETWORK_QUOTA']['NETWORK']].flatten
if !net_quotas[0].nil?
TABLE_NET.show(net_quotas, {})
puts
end
image_quotas = [qh['IMAGE_QUOTA']['IMAGE']].flatten
if !image_quotas[0].nil?
TABLE_IMG.show(image_quotas, {})
end
end
end

View File

@ -15,6 +15,7 @@
#--------------------------------------------------------------------------- #
require 'one_helper'
require 'one_helper/onequota_helper'
class OneUserHelper < OpenNebulaHelper::OneHelper
def self.rname
@ -163,11 +164,35 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
d["AUTH_DRIVER"]
end
column :VMS, "Number of VMS", :size=>8 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
d['VM_QUOTA']['VM']['VMS']
else
"-"
end
end
column :MEMORY, "Total memory allocated to user VMs", :size=>8 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
d['VM_QUOTA']['VM']['MEMORY_USED']
else
"-"
end
end
column :CPU, "Total CPU allocated to user VMs", :size=>8 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
d['VM_QUOTA']['VM']['CPU_USED']
else
"-"
end
end
column :PASSWORD, "Password of the User", :size=>50 do |d|
d['PASSWORD']
end
default :ID, :GROUP, :NAME, :AUTH, :PASSWORD
default :ID, :GROUP, :NAME, :AUTH, :VMS, :MEMORY, :CPU
end
table
@ -207,5 +232,9 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
CLIHelper.print_header(str_h1 % "USER TEMPLATE",false)
puts user.template_str
user_hash = user.to_hash
OneQuotaHelper.format_quota(user_hash['USER'])
end
end

View File

@ -37,10 +37,15 @@ require 'json'
require 'optparse'
require 'optparse/time'
class AcctHelper
def initialize(client)
@client = client
################################################################################
# CLI Helper
################################################################################
class AcctHelper < OpenNebulaHelper::OneHelper
def self.conf_file
"oneacct.yaml"
end
=begin
@ -64,7 +69,7 @@ class AcctHelper
=end
def list_history(data)
table = CLIHelper::ShowTable.new(nil, self) do
table = CLIHelper::ShowTable.new(self.class.table_conf, self) do
column :VID, "Virtual Machine ID", :size=>4 do |d|
d["OID"]
end
@ -73,11 +78,11 @@ class AcctHelper
d["SEQ"]
end
column :HOSTNAME, "Host name", :size=>15 do |d|
column :HOSTNAME, "Host name", :left, :size=>15 do |d|
d["HOSTNAME"]
end
column :REASON, "VM state change reason", :size=>4 do |d|
column :REASON, "VM state change reason", :left, :size=>4 do |d|
VirtualMachine.get_reason d["REASON"]
end
@ -89,20 +94,20 @@ class AcctHelper
OpenNebulaHelper.time_to_str(d['ETIME'])
end
column :MEMORY, "Assigned memory", :right, :size=>6 do |d|
column :MEMORY, "Assigned memory", :size=>6 do |d|
OpenNebulaHelper.unit_to_str(d["VM/TEMPLATE/MEMORY"].to_i, {}, 'M')
end
column :CPU, "Number of CPUs", :right, :size=>3 do |d|
column :CPU, "Number of CPUs", :size=>3 do |d|
d["VM/TEMPLATE/CPU"]
end
column :NET_RX, "Data received from the network", :right, :size=>6 do |d|
column :NET_RX, "Data received from the network", :size=>6 do |d|
# NET is measured in bytes, unit_to_str expects KBytes
OpenNebulaHelper.unit_to_str(d["VM/NET_RX"].to_i / 1024.0, {})
end
column :NET_TX, "Data sent to the network", :right, :size=>6 do |d|
column :NET_TX, "Data sent to the network", :size=>6 do |d|
# NET is measured in bytes, unit_to_str expects KBytes
OpenNebulaHelper.unit_to_str(d["VM/NET_TX"].to_i / 1024.0, {})
end
@ -114,10 +119,7 @@ class AcctHelper
end
public
def list_users(xml_info, options=nil)
xmldoc = XMLElement.new
xmldoc.initialize_xml(xml_info, 'HISTORY_RECORDS')
def list_users(xmldoc, options=nil)
uids = xmldoc.retrieve_elements('HISTORY/VM/UID')
@ -133,8 +135,10 @@ public
uids.each do |uid|
CLIHelper.scr_bold
CLIHelper.scr_underline
# TODO: username?
puts "# User #{uid} "
username =
xmldoc.retrieve_elements(["HISTORY/VM[UID=#{uid}]/UNAME"]).uniq;
puts "# User #{uid} #{username} "
CLIHelper.scr_restore
puts
@ -167,6 +171,28 @@ public
end
end
################################################################################
# Helper methods
################################################################################
def redo_xmldoc(xmldoc, xpath_str)
xml_str = "<HISTORY_RECORDS>"
xmldoc.each(xpath_str) do |history|
xml_str << history.to_xml
end
xml_str << "</HISTORY_RECORDS>"
xmldoc = XMLElement.new
xmldoc.initialize_xml(xml_str, 'HISTORY_RECORDS')
return xmldoc
end
################################################################################
# Main command
################################################################################
options = Hash.new
@ -183,10 +209,24 @@ opts = OptionParser.new do |opts|
options[:end]=ext
end
# TODO: Allow username
opts.on("-u", "--user user", Integer,
"User id to make accounting" ) do |ext|
options[:user]=ext.to_i
opts.on("-u", "--user user", String,
"User id to filter the results" ) do |ext|
options[:user]=ext
end
opts.on("-g", "--group group", String,
"Group id to filter the results" ) do |ext|
options[:group]=ext
end
opts.on("-H", "--host hostname", String,
"Host id to filter the results" ) do |ext|
options[:host]=ext
end
opts.on("--xpath expression", String,
"Xpath expression to filter the results. For example: oneacct --xpath 'HISTORY[ETIME>0]'" ) do |ext|
options[:xpath]=ext
end
opts.on("-j", "--json",
@ -204,6 +244,11 @@ opts = OptionParser.new do |opts|
options[:split]=ext
end
opts.on("-h", "--help", "Show this message" ) do
puts opts
exit
end
opts.on()
end
@ -218,7 +263,7 @@ end
client = OpenNebula::Client.new
acct_helper = AcctHelper.new(client)
acct_helper = AcctHelper.new()
time_start = -1
time_end = -1
@ -226,19 +271,72 @@ filter_flag = VirtualMachinePool::INFO_ALL
time_start = options[:start].to_i if options[:start]
time_end = options[:end].to_i if options[:end]
filter_flag = options[:user].to_i if options[:user]
if options[:user]
rc = OpenNebulaHelper.rname_to_id(options[:user], "USER")
ret = client.call("vmpool.accounting",
if rc[0] == 0
filter_flag = rc[1]
else
puts rc[1]
exit -1
end
end
xml_str = client.call("vmpool.accounting",
filter_flag,
time_start,
time_end)
if OpenNebula.is_error?(ret)
puts ret.message
if OpenNebula.is_error?(xml_str)
puts xml_str.message
exit -1
end
xmldoc = XMLElement.new
xmldoc.initialize_xml(xml_str, 'HISTORY_RECORDS')
xpath = nil
hid = nil
gid = nil
if options[:host]
rc = OpenNebulaHelper.rname_to_id(options[:host], "HOST")
if rc[0] == 0
hid = rc[1]
else
puts rc[1]
exit -1
end
end
if options[:group]
rc = OpenNebulaHelper.rname_to_id(options[:group], "GROUP")
if rc[0] == 0
gid = rc[1]
else
puts rc[1]
exit -1
end
end
if options[:host] && options[:group]
xpath = "HISTORY[VM/GID=#{gid} and HID=#{hid}]"
elsif options[:host]
xpath = "HISTORY[HID=#{hid}]"
elsif options[:group]
xpath = "HISTORY[VM/GID=#{gid}]"
end
xmldoc = redo_xmldoc(xmldoc, xpath) if !xpath.nil?
if options[:xpath]
xmldoc = redo_xmldoc(xmldoc, options[:xpath])
end
case options[:format]
when :table
@ -270,14 +368,12 @@ when :table
puts
end
acct_helper.list_users(ret, options)
acct_helper.list_users(xmldoc, options)
when :xml
puts ret
puts xmldoc.to_xml
when :json
xmldoc = XMLElement.new
xmldoc.initialize_xml(ret, 'HISTORY_RECORDS')
puts xmldoc.to_hash.to_json
end

View File

@ -97,4 +97,20 @@ cmd=CommandParser::CmdParser.new(ARGV) do
helper.show_resource(group,options)
end
quota_desc = <<-EOT.unindent
Set the quota limits for the group. If a path is not provided the editor
will be launched to modify the current quotas.
EOT
command :quota, quota_desc, :groupid, [:file, nil] do
helper.perform_action(args[0], options, "modified") do |group|
str = OneQuotaHelper.set_quota(group, args[1])
rc = group.set_quota(str)
if OpenNebula.is_error?(rc)
puts rc.message
exit -1
end
end
end
end

View File

@ -29,6 +29,7 @@ $: << RUBY_LIB_LOCATION+"/cli"
require 'command_parser'
require 'one_helper/oneuser_helper'
require 'one_helper/onequota_helper'
require 'uri'
@ -196,6 +197,26 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
quota_desc = <<-EOT.unindent
Set the quota limits for the user. If a path is not provided the editor
will be launched to modify the current quotas.
EOT
command :quota, quota_desc, :userid, [:file, nil] do
helper = OneUserHelper.new
helper.perform_action(args[0], options, "modified") do |user|
str = OneQuotaHelper.set_quota(user, args[1])
rc = user.set_quota(str)
if OpenNebula.is_error?(rc)
puts rc.message
exit -1
end
end
end
login_desc = <<-EOT.unindent
Creates the Login token for authentication
Examples:

View File

@ -0,0 +1,25 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
find ../public/js -name \*.js > file_list.txt
echo "../../../../../sunstone/public/js/sunstone.js" >> file_list.txt
echo "../../../../../sunstone/public/js/sunstone-util.js" >> file_list.txt
echo "../public/customize/custom.js" >> file_list.txt
xgettext --from-code=utf-8 --no-wrap --keyword=tr -L python -f file_list.txt -p .
mv messages.po messages.pot
rm file_list.txt

View File

@ -1,5 +1,4 @@
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
# SConstruct for share/man
# -------------------------------------------------------------------------- #
# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) #
@ -17,15 +16,15 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
tr_strings = `grep -h -o -R -e 'tr("[[:print:]]*")' ../js/* | cut -d'"' -f 2 | sort -u`
Import('env')
puts "//Translated by"
puts 'lang="en_US"'
puts 'datatable_lang=""'
puts "locale={"
po_bld = Builder(action = 'share/scons/po2json.rb $SOURCE > $TARGET',
suffix = '.js',
src_suffix = '.po')
tr_strings.each_line do | line |
puts " \"#{line.chomp}\":\"\","
end
env.Append(BUILDERS = {'Po' : po_bld})
puts "};"
env.Po('en_US.po')
env.Po('es_ES.po')
env.Po('fr_CA.po')
env.Po('fr_FR.po')

View File

@ -0,0 +1,674 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-05-21 15:11+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: en_US\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../public/js/locale.js:34
msgid "Changing language"
msgstr ""
#: ../public/js/locale.js:35
msgid "Loading new language... please wait"
msgstr ""
#: ../public/js/locale.js:53 ../public/customize/custom.js:51
msgid "Documentation"
msgstr ""
#: ../public/js/locale.js:54 ../public/customize/custom.js:54
msgid "Support"
msgstr ""
#: ../public/js/locale.js:55 ../public/customize/custom.js:57
msgid "Community"
msgstr ""
#: ../public/js/locale.js:56
msgid "Welcome"
msgstr ""
#: ../public/js/locale.js:57
msgid "Sign out"
msgstr ""
#: ../public/js/plugins/storage.js:26 ../public/js/plugins/network.js:26
#: ../public/js/plugins/compute.js:63
msgid "All"
msgstr ""
#: ../public/js/plugins/storage.js:27 ../public/js/plugins/storage.js:345
#: ../public/js/plugins/network.js:27 ../public/js/plugins/network.js:278
#: ../public/js/plugins/compute.js:64 ../public/js/plugins/compute.js:510
#: ../public/js/plugins/compute.js:555 ../public/js/plugins/compute.js:600
msgid "ID"
msgstr ""
#: ../public/js/plugins/storage.js:28 ../public/js/plugins/storage.js:45
#: ../public/js/plugins/storage.js:349 ../public/js/plugins/network.js:28
#: ../public/js/plugins/network.js:41 ../public/js/plugins/network.js:282
#: ../public/js/plugins/compute.js:65 ../public/js/plugins/compute.js:514
#: ../public/js/plugins/compute.js:559 ../public/js/plugins/compute.js:604
msgid "Name"
msgstr ""
#: ../public/js/plugins/storage.js:41
msgid "Fields marked with"
msgstr ""
#: ../public/js/plugins/storage.js:42
msgid "are mandatory"
msgstr ""
#: ../public/js/plugins/storage.js:47
msgid "Name that the Image will get."
msgstr ""
#: ../public/js/plugins/storage.js:50 ../public/js/plugins/storage.js:353
msgid "Description"
msgstr ""
#: ../public/js/plugins/storage.js:52
msgid "Human readable description of the image."
msgstr ""
#: ../public/js/plugins/storage.js:57 ../public/js/plugins/storage.js:357
#: ../public/js/plugins/compute.js:567
msgid "Type"
msgstr ""
#: ../public/js/plugins/storage.js:59
msgid "OS"
msgstr ""
#: ../public/js/plugins/storage.js:60
msgid "CD-ROM"
msgstr ""
#: ../public/js/plugins/storage.js:61
msgid "Datablock"
msgstr ""
#: ../public/js/plugins/storage.js:63
msgid "Type of the image"
msgstr ""
#: ../public/js/plugins/storage.js:66 ../public/js/plugins/network.js:297
msgid "Size"
msgstr ""
#: ../public/js/plugins/storage.js:68
msgid "Size of the datablock in MB."
msgstr ""
#: ../public/js/plugins/storage.js:71
msgid "FS type"
msgstr ""
#: ../public/js/plugins/storage.js:73
msgid "Type of file system to be built. This can be any value understood by mkfs unix command."
msgstr ""
#: ../public/js/plugins/storage.js:76
msgid "Select image to upload"
msgstr ""
#: ../public/js/plugins/storage.js:83
msgid "Public"
msgstr ""
#: ../public/js/plugins/storage.js:85
msgid "Public scope of the image"
msgstr ""
#: ../public/js/plugins/storage.js:88 ../public/js/plugins/storage.js:361
msgid "Persistent"
msgstr ""
#: ../public/js/plugins/storage.js:90
msgid "Persistence of the image"
msgstr ""
#: ../public/js/plugins/storage.js:95 ../public/js/plugins/network.js:56
#: ../public/js/plugins/compute.js:103
msgid "Close"
msgstr ""
#: ../public/js/plugins/storage.js:96 ../public/js/plugins/network.js:57
#: ../public/js/plugins/compute.js:104
msgid "Create"
msgstr ""
#: ../public/js/plugins/storage.js:214 ../public/js/plugins/network.js:158
#: ../public/js/plugins/compute.js:305
msgid "Refresh list"
msgstr ""
#: ../public/js/plugins/storage.js:219 ../public/js/plugins/network.js:164
#: ../public/js/plugins/compute.js:311
msgid "+ New"
msgstr ""
#: ../public/js/plugins/storage.js:223
msgid "Make persistent"
msgstr ""
#: ../public/js/plugins/storage.js:227
msgid "Make non persistent"
msgstr ""
#: ../public/js/plugins/storage.js:234 ../public/js/plugins/network.js:169
msgid "Publish"
msgstr ""
#: ../public/js/plugins/storage.js:238 ../public/js/plugins/network.js:174
msgid "Unpublish"
msgstr ""
#: ../public/js/plugins/storage.js:244 ../public/js/plugins/network.js:179
#: ../public/js/plugins/compute.js:353
msgid "Delete"
msgstr ""
#: ../public/js/plugins/storage.js:250 ../public/js/plugins/storage.js:337
msgid "Image information"
msgstr ""
#: ../public/js/plugins/storage.js:258
msgid "Add storage"
msgstr ""
#: ../public/js/plugins/storage.js:264 ../public/js/plugins/dashboard.js:46
#: ../public/customize/custom.js:68
msgid "Storage"
msgstr ""
#: ../public/js/plugins/storage.js:341
msgid "Image"
msgstr ""
#: ../public/js/plugins/storage.js:342 ../public/js/plugins/network.js:275
msgid "information"
msgstr ""
#: ../public/js/plugins/storage.js:365
msgid "Filesystem type"
msgstr ""
#: ../public/js/plugins/storage.js:369
msgid "Size (Mb)"
msgstr ""
#: ../public/js/plugins/storage.js:503
msgid "You must specify a name"
msgstr ""
#: ../public/js/plugins/storage.js:521
msgid "You must specify size and FS type"
msgstr ""
#: ../public/js/plugins/storage.js:528
msgid "You must select a file to upload"
msgstr ""
#: ../public/js/plugins/network.js:47
msgid "Network Address"
msgstr ""
#: ../public/js/plugins/network.js:49
msgid "Network Size"
msgstr ""
#: ../public/js/plugins/network.js:185
msgid "Network information"
msgstr ""
#: ../public/js/plugins/network.js:193
msgid "Create network"
msgstr ""
#: ../public/js/plugins/network.js:199 ../public/js/plugins/compute.js:91
#: ../public/js/plugins/compute.js:368 ../public/js/plugins/compute.js:627
msgid "Networks"
msgstr ""
#: ../public/js/plugins/network.js:274
msgid "Virtual Network"
msgstr ""
#: ../public/js/plugins/network.js:286
msgid "Used leases"
msgstr ""
#: ../public/js/plugins/network.js:293
msgid "Address"
msgstr ""
#: ../public/js/plugins/network.js:307
msgid "Virtual Network information"
msgstr ""
#: ../public/js/plugins/network.js:353
msgid "Virtual Network name missing!"
msgstr ""
#: ../public/js/plugins/network.js:365
msgid "Please provide a network address"
msgstr ""
#: ../public/js/plugins/dashboard.js:37
msgid "Current resources"
msgstr ""
#: ../public/js/plugins/dashboard.js:42 ../public/js/plugins/compute.js:381
#: ../public/customize/custom.js:64
msgid "Compute"
msgstr ""
#: ../public/js/plugins/dashboard.js:50 ../public/customize/custom.js:72
msgid "Network"
msgstr ""
#: ../public/js/plugins/dashboard.js:62
msgid "Useful links"
msgstr ""
#: ../public/js/plugins/dashboard.js:81
msgid "Create new compute resource"
msgstr ""
#: ../public/js/plugins/dashboard.js:82 ../public/js/plugins/dashboard.js:96
#: ../public/js/plugins/dashboard.js:110
msgid "See more"
msgstr ""
#: ../public/js/plugins/dashboard.js:95
msgid "Create new storage resource"
msgstr ""
#: ../public/js/plugins/dashboard.js:109
msgid "Create new network resource"
msgstr ""
#: ../public/js/plugins/dashboard.js:120
msgid "Dashboard"
msgstr ""
#: ../public/js/plugins/compute.js:32 ../public/js/plugins/compute.js:526
msgid "CPU"
msgstr ""
#: ../public/js/plugins/compute.js:37 ../public/js/plugins/compute.js:530
msgid "Memory"
msgstr ""
#: ../public/js/plugins/compute.js:42
msgid "Network transmission"
msgstr ""
#: ../public/js/plugins/compute.js:47
msgid "Network reception"
msgstr ""
#: ../public/js/plugins/compute.js:65 ../public/js/plugins/compute.js:522
msgid "State"
msgstr ""
#: ../public/js/plugins/compute.js:66 ../public/js/plugins/compute.js:608
msgid "IP"
msgstr ""
#: ../public/js/plugins/compute.js:76
msgid "VM Name"
msgstr ""
#: ../public/js/plugins/compute.js:80 ../public/js/plugins/compute.js:518
msgid "Instance type"
msgstr ""
#: ../public/js/plugins/compute.js:82 ../public/js/plugins/compute.js:982
msgid "Loading"
msgstr ""
#: ../public/js/plugins/compute.js:86
msgid "Images"
msgstr ""
#: ../public/js/plugins/compute.js:97
msgid "Create # VMs"
msgstr ""
#: ../public/js/plugins/compute.js:99
msgid "You can use the wildcard &#37;. When creating several VMs, &#37; will be replaced with a different number starting from 0 in each of them"
msgstr ""
#: ../public/js/plugins/compute.js:317
msgid "Shutdown"
msgstr ""
#: ../public/js/plugins/compute.js:318
msgid "This will shutdown the selected VMs"
msgstr ""
#: ../public/js/plugins/compute.js:326
msgid "Suspend"
msgstr ""
#: ../public/js/plugins/compute.js:327
msgid "This will suspend the selected VMs"
msgstr ""
#: ../public/js/plugins/compute.js:331
msgid "Resume"
msgstr ""
#: ../public/js/plugins/compute.js:332
msgid "This will resume the selected VMs in stopped or suspended states"
msgstr ""
#: ../public/js/plugins/compute.js:336
msgid "Stop"
msgstr ""
#: ../public/js/plugins/compute.js:341 ../public/js/plugins/compute.js:809
#: ../../../../../sunstone/public/js/sunstone.js:661
#: ../../../../../sunstone/public/js/sunstone.js:693
msgid "Cancel"
msgstr ""
#: ../public/js/plugins/compute.js:342
msgid "This will cancel selected VMs"
msgstr ""
#: ../public/js/plugins/compute.js:346 ../public/js/plugins/compute.js:798
msgid "Take snapshot"
msgstr ""
#: ../public/js/plugins/compute.js:354
msgid "This will delete the selected VMs from the database"
msgstr ""
#: ../public/js/plugins/compute.js:360
msgid "Compute resource"
msgstr ""
#: ../public/js/plugins/compute.js:364 ../public/js/plugins/compute.js:582
msgid "Disks"
msgstr ""
#: ../public/js/plugins/compute.js:375
msgid "Create Virtual Machine"
msgstr ""
#: ../public/js/plugins/compute.js:502
msgid "VM information"
msgstr ""
#: ../public/js/plugins/compute.js:506
msgid "Virtual Machine information"
msgstr ""
#: ../public/js/plugins/compute.js:534
msgid "Launch VNC session"
msgstr ""
#: ../public/js/plugins/compute.js:545
msgid "Disks information"
msgstr ""
#: ../public/js/plugins/compute.js:563
msgid "Target"
msgstr ""
#: ../public/js/plugins/compute.js:574 ../public/js/plugins/compute.js:905
msgid "No disks defined"
msgstr ""
#: ../public/js/plugins/compute.js:588
msgid "Networks information"
msgstr ""
#: ../public/js/plugins/compute.js:612
msgid "MAC"
msgstr ""
#: ../public/js/plugins/compute.js:619
msgid "No networks defined"
msgstr ""
#: ../public/js/plugins/compute.js:633
msgid "Monitoring information"
msgstr ""
#: ../public/js/plugins/compute.js:808
#: ../../../../../sunstone/public/js/sunstone.js:660
#: ../../../../../sunstone/public/js/sunstone.js:692
msgid "OK"
msgstr ""
#: ../public/js/plugins/compute.js:831
msgid "Skipping VM "
msgstr ""
#: ../public/js/plugins/compute.js:832
msgid "No disk id or image name specified"
msgstr ""
#: ../public/js/plugins/compute.js:868
msgid "Saveas for VM with ID"
msgstr ""
#: ../public/js/plugins/compute.js:871
msgid "Select disk"
msgstr ""
#: ../public/js/plugins/compute.js:873
msgid "Retrieving"
msgstr ""
#: ../public/js/plugins/compute.js:877
msgid "Image name"
msgstr ""
#: ../public/js/plugins/compute.js:897 ../public/js/plugins/compute.js:900
msgid "disk id"
msgstr ""
#: ../public/js/plugins/compute.js:975
msgid "VNC connection"
msgstr ""
#: ../public/js/plugins/compute.js:990
msgid "Canvas not supported."
msgstr ""
#: ../public/js/plugins/compute.js:1051 ../public/js/plugins/compute.js:1067
msgid "Open VNC Session"
msgstr ""
#: ../public/js/plugins/compute.js:1054 ../public/js/plugins/compute.js:1070
msgid "VNC Disabled"
msgstr ""
#: ../public/js/plugins/configuration.js:23
msgid "Self-Service UI Configuration"
msgstr ""
#: ../public/js/plugins/configuration.js:28
msgid "Language"
msgstr ""
#: ../public/js/plugins/configuration.js:31
msgid "English"
msgstr ""
#: ../public/js/plugins/configuration.js:32
msgid "Spanish"
msgstr ""
#: ../public/js/plugins/configuration.js:33
msgid "French (FR)"
msgstr ""
#: ../public/js/plugins/configuration.js:34
msgid "French (CA)"
msgstr ""
#: ../public/js/plugins/configuration.js:56
msgid "Configuration"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone.js:586
msgid "Previous action"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone.js:649
#: ../../../../../sunstone/public/js/sunstone.js:683
msgid "Confirmation of action"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone.js:655
msgid "You have to confirm this action."
msgstr ""
#: ../../../../../sunstone/public/js/sunstone.js:657
msgid "Do you want to proceed?"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone.js:688
msgid "You need to select something."
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:203
msgid "Submitted"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:220
msgid "Error"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:226
msgid "Info"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:358
msgid "Cannot contact server: is it running and reachable?"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:366
msgid "Network is unreachable: is OpenNebula running?"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:387
msgid "Unauthorized"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:561
#: ../../../../../sunstone/public/js/sunstone-util.js:772
msgid "Please select"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:695
msgid "Update template"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:701
msgid "Please, choose and modify the template you want to update"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:703
#: ../../../../../sunstone/public/js/sunstone-util.js:706
msgid "Select a template"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:711
msgid "Update"
msgstr ""
#: ../public/customize/custom.js:18
msgid "String"
msgstr ""
#: ../public/customize/custom.js:39
msgid "Welcome to OpenNebula Self-Service"
msgstr ""
#: ../public/customize/custom.js:41
msgid "OpenNebula Self-Service is a simplified user interface to manage OpenNebula compute, storage and network resources. It is focused on easiness and usability and features a limited set of operations directed towards end-users."
msgstr ""
#: ../public/customize/custom.js:42
msgid "Additionally, OpenNebula Self-Service allows easy customization of the interface (e.g. this text) and brings multi-language support."
msgstr ""
#: ../public/customize/custom.js:43
msgid "Have a cloudy experience!"
msgstr ""
#: ../public/customize/custom.js:66
msgid "Compute resources are Virtual Machines attached to storage and network resources. OpenNebula Self-Service allows you to easily create, remove and manage them, including the possibility of pausing a Virtual Machine or taking a snapshot of one of their disks."
msgstr ""
#: ../public/customize/custom.js:70
msgid "Storage pool is formed by several images. These images can contain from full operating systems to be used as base for compute resources, to simple data. OpenNebula Self-Service offers you the possibility to create or upload your own images."
msgstr ""
#: ../public/customize/custom.js:74
msgid "Your compute resources connectivity is performed using pre-defined virtual networks. You can create and manage these networks using OpenNebula Self-Service."
msgstr ""
#: ../public/customize/custom.js:81
msgid "This is a list of your current compute resources. Virtual Machines use previously defined images and networks. You can easily create a new compute element by cliking 'new' and filling-in an easy wizard."
msgstr ""
#: ../public/customize/custom.js:82
msgid "You can also manage compute resources and perform actions such as stop, resume, shutdown or cancel."
msgstr ""
#: ../public/customize/custom.js:83
msgid "Additionally, you can take a 'snapshot' of the storage attached to these resources. They will be saved as new resources, visible from the Storage view and re-usable."
msgstr ""
#: ../public/customize/custom.js:84 ../public/customize/custom.js:94
#: ../public/customize/custom.js:104
msgid "There are currently"
msgstr ""
#: ../public/customize/custom.js:85
msgid "virtual machines"
msgstr ""
#: ../public/customize/custom.js:91
msgid "The Storage view offers you an overview of your current images. Storage elements are attached to compute resources at creation time. They can also be extracted from running virtual machines by taking an snapshot."
msgstr ""
#: ../public/customize/custom.js:92
msgid "You can add new storages by clicking 'new'. Image files will be uploaded to OpenNebula and set ready to be used."
msgstr ""
#: ../public/customize/custom.js:93
msgid "Additionally, you can run several operations on defined storages, such as defining their persistance. Persistent images can only be used by 1 virtual machine, and the changes made by it have effect on the base image. Non-persistent images are cloned before being used in a Virtual Machine, therefore changes are lost unless a snapshot is taken prior to Virtual Machine shutdown."
msgstr ""
#: ../public/customize/custom.js:95
msgid "images"
msgstr ""
#: ../public/customize/custom.js:101
msgid "In this view you can easily manage OpenNebula Network resources. You can add or remove virtual networks."
msgstr ""
#: ../public/customize/custom.js:102
msgid "Compute resources can be attached to these networks at creation time. Virtual machines will be provided with an IP and the correct parameters to ensure connectivity."
msgstr ""
#: ../public/customize/custom.js:105
msgid "networks"
msgstr ""

View File

@ -0,0 +1,678 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-05-21 15:11+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: es_ES\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../public/js/locale.js:34
msgid "Changing language"
msgstr "Cambiando el lenguaje"
#: ../public/js/locale.js:35
msgid "Loading new language... please wait"
msgstr "Cargando nuevo lenguaje... espere, por favor"
#: ../public/js/locale.js:53 ../public/customize/custom.js:51
msgid "Documentation"
msgstr "Documentación"
#: ../public/js/locale.js:54 ../public/customize/custom.js:54
msgid "Support"
msgstr "Soporte"
#: ../public/js/locale.js:55 ../public/customize/custom.js:57
msgid "Community"
msgstr "Comunidad"
#: ../public/js/locale.js:56
msgid "Welcome"
msgstr "Bienvenid@"
#: ../public/js/locale.js:57
msgid "Sign out"
msgstr "Desconectar"
#: ../public/js/plugins/storage.js:26 ../public/js/plugins/network.js:26
#: ../public/js/plugins/compute.js:63
msgid "All"
msgstr "Todos"
#: ../public/js/plugins/storage.js:27 ../public/js/plugins/storage.js:345
#: ../public/js/plugins/network.js:27 ../public/js/plugins/network.js:278
#: ../public/js/plugins/compute.js:64 ../public/js/plugins/compute.js:510
#: ../public/js/plugins/compute.js:555 ../public/js/plugins/compute.js:600
msgid "ID"
msgstr "ID"
#: ../public/js/plugins/storage.js:28 ../public/js/plugins/storage.js:45
#: ../public/js/plugins/storage.js:349 ../public/js/plugins/network.js:28
#: ../public/js/plugins/network.js:41 ../public/js/plugins/network.js:282
#: ../public/js/plugins/compute.js:65 ../public/js/plugins/compute.js:514
#: ../public/js/plugins/compute.js:559 ../public/js/plugins/compute.js:604
msgid "Name"
msgstr "Nombre"
#: ../public/js/plugins/storage.js:41
msgid "Fields marked with"
msgstr "Campos marcados con"
#: ../public/js/plugins/storage.js:42
msgid "are mandatory"
msgstr "son obligatorios"
#: ../public/js/plugins/storage.js:47
msgid "Name that the Image will get."
msgstr "Nombre para la imagen."
#: ../public/js/plugins/storage.js:50 ../public/js/plugins/storage.js:353
msgid "Description"
msgstr "Descripción"
#: ../public/js/plugins/storage.js:52
msgid "Human readable description of the image."
msgstr "Descripción de la imagen."
#: ../public/js/plugins/storage.js:57 ../public/js/plugins/storage.js:357
#: ../public/js/plugins/compute.js:567
msgid "Type"
msgstr "Tipo"
#: ../public/js/plugins/storage.js:59
msgid "OS"
msgstr "OS"
#: ../public/js/plugins/storage.js:60
msgid "CD-ROM"
msgstr "CD-ROM"
#: ../public/js/plugins/storage.js:61
msgid "Datablock"
msgstr "Datablock"
#: ../public/js/plugins/storage.js:63
msgid "Type of the image"
msgstr "Tipo de la imagen"
#: ../public/js/plugins/storage.js:66 ../public/js/plugins/network.js:297
msgid "Size"
msgstr "Tamaño"
#: ../public/js/plugins/storage.js:68
msgid "Size of the datablock in MB."
msgstr "Tamaño del datablcok en MB"
#: ../public/js/plugins/storage.js:71
msgid "FS type"
msgstr "tipo de FS"
#: ../public/js/plugins/storage.js:73
msgid "Type of file system to be built. This can be any value understood by mkfs unix command."
msgstr "Tipo de sistema de archivos a generar. Es válido cualquier valor entendido por el comando mkfs"
#: ../public/js/plugins/storage.js:76
msgid "Select image to upload"
msgstr "Seleccione una imagen para subir"
#: ../public/js/plugins/storage.js:83
msgid "Public"
msgstr "Público"
#: ../public/js/plugins/storage.js:85
msgid "Public scope of the image"
msgstr "Imagen pública"
#: ../public/js/plugins/storage.js:88 ../public/js/plugins/storage.js:361
msgid "Persistent"
msgstr "Persistente"
#: ../public/js/plugins/storage.js:90
msgid "Persistence of the image"
msgstr "Persistencia de la imagen"
#: ../public/js/plugins/storage.js:95 ../public/js/plugins/network.js:56
#: ../public/js/plugins/compute.js:103
msgid "Close"
msgstr "Cerrar"
#: ../public/js/plugins/storage.js:96 ../public/js/plugins/network.js:57
#: ../public/js/plugins/compute.js:104
msgid "Create"
msgstr "Crear"
#: ../public/js/plugins/storage.js:214 ../public/js/plugins/network.js:158
#: ../public/js/plugins/compute.js:305
msgid "Refresh list"
msgstr "Refrescar lista"
#: ../public/js/plugins/storage.js:219 ../public/js/plugins/network.js:164
#: ../public/js/plugins/compute.js:311
msgid "+ New"
msgstr "+ Nuevo"
#: ../public/js/plugins/storage.js:223
msgid "Make persistent"
msgstr "Hacer persistente"
#: ../public/js/plugins/storage.js:227
msgid "Make non persistent"
msgstr "Hacer no persistente"
#: ../public/js/plugins/storage.js:234 ../public/js/plugins/network.js:169
msgid "Publish"
msgstr "Publicar"
#: ../public/js/plugins/storage.js:238 ../public/js/plugins/network.js:174
msgid "Unpublish"
msgstr "Despublicar"
#: ../public/js/plugins/storage.js:244 ../public/js/plugins/network.js:179
#: ../public/js/plugins/compute.js:353
msgid "Delete"
msgstr "Borrar"
#: ../public/js/plugins/storage.js:250 ../public/js/plugins/storage.js:337
msgid "Image information"
msgstr "Información de la imagen"
#: ../public/js/plugins/storage.js:258
msgid "Add storage"
msgstr "Añadir almacenamiento"
#: ../public/js/plugins/storage.js:264 ../public/js/plugins/dashboard.js:46
#: ../public/customize/custom.js:68
msgid "Storage"
msgstr "Almacenamiento"
#: ../public/js/plugins/storage.js:341
msgid "Image"
msgstr "Imagen"
#: ../public/js/plugins/storage.js:342 ../public/js/plugins/network.js:275
msgid "information"
msgstr "Información"
#: ../public/js/plugins/storage.js:365
msgid "Filesystem type"
msgstr "Sistema de ficheros"
#: ../public/js/plugins/storage.js:369
msgid "Size (Mb)"
msgstr "Tamaño (Mb)"
#: ../public/js/plugins/storage.js:503
msgid "You must specify a name"
msgstr "Debe especificar un nombre"
#: ../public/js/plugins/storage.js:521
msgid "You must specify size and FS type"
msgstr "Debe especificar un tamaño y un tipo de FS"
#: ../public/js/plugins/storage.js:528
msgid "You must select a file to upload"
msgstr "Debe seleccionar un fichero para subir"
#: ../public/js/plugins/network.js:47
msgid "Network Address"
msgstr "Dirección de red"
#: ../public/js/plugins/network.js:49
msgid "Network Size"
msgstr "Tamaño de red"
#: ../public/js/plugins/network.js:185
msgid "Network information"
msgstr "Información de red"
#: ../public/js/plugins/network.js:193
msgid "Create network"
msgstr "Crear red"
#: ../public/js/plugins/network.js:199 ../public/js/plugins/compute.js:91
#: ../public/js/plugins/compute.js:368 ../public/js/plugins/compute.js:627
msgid "Networks"
msgstr "Redes"
#: ../public/js/plugins/network.js:274
msgid "Virtual Network"
msgstr "Red virtual"
#: ../public/js/plugins/network.js:286
msgid "Used leases"
msgstr "Leases usados"
#: ../public/js/plugins/network.js:293
msgid "Address"
msgstr "Dirección"
#: ../public/js/plugins/network.js:307
msgid "Virtual Network information"
msgstr "Información de red virtual"
#: ../public/js/plugins/network.js:353
msgid "Virtual Network name missing!"
msgstr "¡Falta el nombre de la red!"
#: ../public/js/plugins/network.js:365
msgid "Please provide a network address"
msgstr "Por favor, proporcione una dirección de red"
#: ../public/js/plugins/dashboard.js:37
msgid "Current resources"
msgstr "Recursos actuales"
#: ../public/js/plugins/dashboard.js:42 ../public/js/plugins/compute.js:381
#: ../public/customize/custom.js:64
msgid "Compute"
msgstr "Máquinas Virtuales"
#: ../public/js/plugins/dashboard.js:50 ../public/customize/custom.js:72
msgid "Network"
msgstr "Red"
#: ../public/js/plugins/dashboard.js:62
msgid "Useful links"
msgstr "Enlances útiles"
#: ../public/js/plugins/dashboard.js:81
msgid "Create new compute resource"
msgstr "Crear nueva máquina virtual"
#: ../public/js/plugins/dashboard.js:82 ../public/js/plugins/dashboard.js:96
#: ../public/js/plugins/dashboard.js:110
msgid "See more"
msgstr "Ver más"
#: ../public/js/plugins/dashboard.js:95
msgid "Create new storage resource"
msgstr "Crear nuevo almacenamiento"
#: ../public/js/plugins/dashboard.js:109
msgid "Create new network resource"
msgstr "Crear nueva red"
#: ../public/js/plugins/dashboard.js:120
msgid "Dashboard"
msgstr "Portada"
#: ../public/js/plugins/compute.js:32 ../public/js/plugins/compute.js:526
msgid "CPU"
msgstr "CPU"
#: ../public/js/plugins/compute.js:37 ../public/js/plugins/compute.js:530
msgid "Memory"
msgstr "Memoria"
#: ../public/js/plugins/compute.js:42
msgid "Network transmission"
msgstr "Transmisión de red"
#: ../public/js/plugins/compute.js:47
msgid "Network reception"
msgstr "Recepción de red"
#: ../public/js/plugins/compute.js:65 ../public/js/plugins/compute.js:522
msgid "State"
msgstr "Estado"
#: ../public/js/plugins/compute.js:66 ../public/js/plugins/compute.js:608
msgid "IP"
msgstr "IP"
#: ../public/js/plugins/compute.js:76
msgid "VM Name"
msgstr "Nombre"
#: ../public/js/plugins/compute.js:80 ../public/js/plugins/compute.js:518
msgid "Instance type"
msgstr "Tipo de instancia"
#: ../public/js/plugins/compute.js:82 ../public/js/plugins/compute.js:982
msgid "Loading"
msgstr "Cargando"
#: ../public/js/plugins/compute.js:86
msgid "Images"
msgstr "Imágenes"
#: ../public/js/plugins/compute.js:97
msgid "Create # VMs"
msgstr "Crear # MVs"
#: ../public/js/plugins/compute.js:99
#, fuzzy
msgid "You can use the wildcard &#37;. When creating several VMs, &#37; will be replaced with a different number starting from 0 in each of them"
msgstr "Puede utilizar el comodín %i. Durante la creación de varias máquinas virtuales, %i será reemplazado por un número distinto en cada una de ellas, empezando por 0"
#: ../public/js/plugins/compute.js:317
msgid "Shutdown"
msgstr "Apagar"
#: ../public/js/plugins/compute.js:318
msgid "This will shutdown the selected VMs"
msgstr "Esto apagará las MVs seleccionadas"
#: ../public/js/plugins/compute.js:326
msgid "Suspend"
msgstr "Suspender"
#: ../public/js/plugins/compute.js:327
msgid "This will suspend the selected VMs"
msgstr "Esto suspenderá las MVs seleccionadas"
#: ../public/js/plugins/compute.js:331
msgid "Resume"
msgstr "Reanudar"
#: ../public/js/plugins/compute.js:332
msgid "This will resume the selected VMs in stopped or suspended states"
msgstr "Esto reanudará las MVs seleccionadas paradas o suspendidas"
#: ../public/js/plugins/compute.js:336
msgid "Stop"
msgstr "Detener"
#: ../public/js/plugins/compute.js:341 ../public/js/plugins/compute.js:809
#: ../../../../../sunstone/public/js/sunstone.js:661
#: ../../../../../sunstone/public/js/sunstone.js:693
msgid "Cancel"
msgstr "Cancelar"
#: ../public/js/plugins/compute.js:342
msgid "This will cancel selected VMs"
msgstr "Esto cancelará las MVs seleccionadas"
#: ../public/js/plugins/compute.js:346 ../public/js/plugins/compute.js:798
msgid "Take snapshot"
msgstr "Tomar instantánea"
#: ../public/js/plugins/compute.js:354
msgid "This will delete the selected VMs from the database"
msgstr "Esto borrará las MVs seleccionadas de la base de datos"
#: ../public/js/plugins/compute.js:360
msgid "Compute resource"
msgstr "máquina virtual"
#: ../public/js/plugins/compute.js:364 ../public/js/plugins/compute.js:582
msgid "Disks"
msgstr "Discos"
#: ../public/js/plugins/compute.js:375
msgid "Create Virtual Machine"
msgstr "Crear máquina virtual"
#: ../public/js/plugins/compute.js:502
msgid "VM information"
msgstr "Información de MV"
#: ../public/js/plugins/compute.js:506
msgid "Virtual Machine information"
msgstr "Información de máquina virtual"
#: ../public/js/plugins/compute.js:534
msgid "Launch VNC session"
msgstr "Lanzar sesión VNC"
#: ../public/js/plugins/compute.js:545
msgid "Disks information"
msgstr "Información de discos"
#: ../public/js/plugins/compute.js:563
msgid "Target"
msgstr "Target"
#: ../public/js/plugins/compute.js:574 ../public/js/plugins/compute.js:905
msgid "No disks defined"
msgstr "No hay discos definidos"
#: ../public/js/plugins/compute.js:588
msgid "Networks information"
msgstr "Información de redes"
#: ../public/js/plugins/compute.js:612
msgid "MAC"
msgstr "MAC"
#: ../public/js/plugins/compute.js:619
msgid "No networks defined"
msgstr "No hay redes definidas"
#: ../public/js/plugins/compute.js:633
msgid "Monitoring information"
msgstr "Información de monitorización"
#: ../public/js/plugins/compute.js:808
#: ../../../../../sunstone/public/js/sunstone.js:660
#: ../../../../../sunstone/public/js/sunstone.js:692
msgid "OK"
msgstr "OK"
#: ../public/js/plugins/compute.js:831
msgid "Skipping VM "
msgstr "Saltando MV"
#: ../public/js/plugins/compute.js:832
msgid "No disk id or image name specified"
msgstr "No se ha especificado ID de disco o nombre de la imagen"
#: ../public/js/plugins/compute.js:868
msgid "Saveas for VM with ID"
msgstr "Instantánea a MV con ID"
#: ../public/js/plugins/compute.js:871
msgid "Select disk"
msgstr "Seleccione un disco"
#: ../public/js/plugins/compute.js:873
msgid "Retrieving"
msgstr "Cargando"
#: ../public/js/plugins/compute.js:877
msgid "Image name"
msgstr "Nombre de la imagen"
#: ../public/js/plugins/compute.js:897 ../public/js/plugins/compute.js:900
msgid "disk id"
msgstr "id del disco"
#: ../public/js/plugins/compute.js:975
msgid "VNC connection"
msgstr "Conexión VNC"
#: ../public/js/plugins/compute.js:990
msgid "Canvas not supported."
msgstr "Canvas no soportado"
#: ../public/js/plugins/compute.js:1051 ../public/js/plugins/compute.js:1067
msgid "Open VNC Session"
msgstr "Abrir sesión VNC"
#: ../public/js/plugins/compute.js:1054 ../public/js/plugins/compute.js:1070
msgid "VNC Disabled"
msgstr "VNC Desabilitado"
#: ../public/js/plugins/configuration.js:23
msgid "Self-Service UI Configuration"
msgstr "Configuración de la interfaz Self-Service"
#: ../public/js/plugins/configuration.js:28
msgid "Language"
msgstr "Lenguaje"
#: ../public/js/plugins/configuration.js:31
msgid "English"
msgstr "Inglés"
#: ../public/js/plugins/configuration.js:32
msgid "Spanish"
msgstr "Español"
#: ../public/js/plugins/configuration.js:33
msgid "French (FR)"
msgstr ""
#: ../public/js/plugins/configuration.js:34
msgid "French (CA)"
msgstr ""
#: ../public/js/plugins/configuration.js:56
msgid "Configuration"
msgstr "Configuración"
#: ../../../../../sunstone/public/js/sunstone.js:586
msgid "Previous action"
msgstr "Acción anterior"
#: ../../../../../sunstone/public/js/sunstone.js:649
#: ../../../../../sunstone/public/js/sunstone.js:683
msgid "Confirmation of action"
msgstr "Confirmar operación"
#: ../../../../../sunstone/public/js/sunstone.js:655
msgid "You have to confirm this action."
msgstr "Necesita confirmar esta acción"
#: ../../../../../sunstone/public/js/sunstone.js:657
msgid "Do you want to proceed?"
msgstr "¿Desea continuar?"
#: ../../../../../sunstone/public/js/sunstone.js:688
msgid "You need to select something."
msgstr "Debe seleccionar algo"
#: ../../../../../sunstone/public/js/sunstone-util.js:203
msgid "Submitted"
msgstr "Hecho"
#: ../../../../../sunstone/public/js/sunstone-util.js:220
msgid "Error"
msgstr "Error"
#: ../../../../../sunstone/public/js/sunstone-util.js:226
msgid "Info"
msgstr "Información"
#: ../../../../../sunstone/public/js/sunstone-util.js:358
msgid "Cannot contact server: is it running and reachable?"
msgstr "No se puede contactar con el servidor: ¿está funcionando y es alcanzable?"
#: ../../../../../sunstone/public/js/sunstone-util.js:366
msgid "Network is unreachable: is OpenNebula running?"
msgstr "No se puede alcanzar la red: ¿está OpenNebula funcionando?"
#: ../../../../../sunstone/public/js/sunstone-util.js:387
msgid "Unauthorized"
msgstr "No autorizado"
#: ../../../../../sunstone/public/js/sunstone-util.js:561
#: ../../../../../sunstone/public/js/sunstone-util.js:772
msgid "Please select"
msgstr "Por favor escoja"
#: ../../../../../sunstone/public/js/sunstone-util.js:695
msgid "Update template"
msgstr "Actualizar plantilla"
#: ../../../../../sunstone/public/js/sunstone-util.js:701
msgid "Please, choose and modify the template you want to update"
msgstr "Por favor, escoja y modifique la plantilla que desea actualizar"
#: ../../../../../sunstone/public/js/sunstone-util.js:703
#: ../../../../../sunstone/public/js/sunstone-util.js:706
msgid "Select a template"
msgstr "Seleccione una plantilla"
#: ../../../../../sunstone/public/js/sunstone-util.js:711
msgid "Update"
msgstr "Actualizar"
#: ../public/customize/custom.js:18
msgid "String"
msgstr "String"
#: ../public/customize/custom.js:39
msgid "Welcome to OpenNebula Self-Service"
msgstr "Bienvenid@ a OpenNebula Self-Service"
#: ../public/customize/custom.js:41
msgid "OpenNebula Self-Service is a simplified user interface to manage OpenNebula compute, storage and network resources. It is focused on easiness and usability and features a limited set of operations directed towards end-users."
msgstr "OpenNebula Self-Service es una interfaz de usuario simplificada para administrar máquinas virtuales, almacenamiento y red de OpenNebula. Está basada en la facilidad de uso y cuenta con un número limitado de operaciones dirigidas a los usuarios finales."
#: ../public/customize/custom.js:42
msgid "Additionally, OpenNebula Self-Service allows easy customization of the interface (e.g. this text) and brings multi-language support."
msgstr "Además, OpenNebula Self-Service permite una fácil personalización de la interfaz (por ejemplo, de este mismo texto) y viene con soporte para múltiples lenguajes."
#: ../public/customize/custom.js:43
msgid "Have a cloudy experience!"
msgstr "¡Nos vemos en las nubes!"
#: ../public/customize/custom.js:66
msgid "Compute resources are Virtual Machines attached to storage and network resources. OpenNebula Self-Service allows you to easily create, remove and manage them, including the possibility of pausing a Virtual Machine or taking a snapshot of one of their disks."
msgstr "Las máquinas virtuales están asociadas a recursos de almacenamiento y de red. OpenNebula Self-Service le permite crearlos, borrarlos y administrarlos fácilmente, incluyendo la posibilidad de pausar una máquina virtual o de tomar una instantánea de alguno de sus discos."
#: ../public/customize/custom.js:70
msgid "Storage pool is formed by several images. These images can contain from full operating systems to be used as base for compute resources, to simple data. OpenNebula Self-Service offers you the possibility to create or upload your own images."
msgstr "La lista de almacenamiento está formada por varias imágenes. Estas imágenes pueden contener desde sistemas operativos completos para ser usados como base en máquinas virtuales, hasta simples datos. OpenNebula Self-Service ofrece la posibilidad de crear o subir sus propias imágenes."
#: ../public/customize/custom.js:74
msgid "Your compute resources connectivity is performed using pre-defined virtual networks. You can create and manage these networks using OpenNebula Self-Service."
msgstr "La conectividad de sus máquinas virtuales se realiza usando redes virtuales pre-definidas. Puede crear y administrar estas redes usando OpenNebula Self-Service."
#: ../public/customize/custom.js:81
msgid "This is a list of your current compute resources. Virtual Machines use previously defined images and networks. You can easily create a new compute element by cliking 'new' and filling-in an easy wizard."
msgstr "Esta es una lista de sus máquinas virtuales actuales. Las máquinas virtuales utilizan imagenes y redes definidas previamente. Puede crear fácilmente una nueva máquina virtual haciendo click en 'New' y rellenado un sencillo formulario."
#: ../public/customize/custom.js:82
msgid "You can also manage compute resources and perform actions such as stop, resume, shutdown or cancel."
msgstr "También puede administrar las máquinas virtuales y realizar acciones como detener, reanudar, apagar o cancelar."
#: ../public/customize/custom.js:83
msgid "Additionally, you can take a 'snapshot' of the storage attached to these resources. They will be saved as new resources, visible from the Storage view and re-usable."
msgstr "Además, puede tomar una 'instantánea' de los almacenamientos asociado a estos recursos. Ésta será salvaguardada como un nuevo recurso, visible y reutilizable desde la vista de almacenamientos."
#: ../public/customize/custom.js:84 ../public/customize/custom.js:94
#: ../public/customize/custom.js:104
msgid "There are currently"
msgstr "Actualmente hay"
#: ../public/customize/custom.js:85
msgid "virtual machines"
msgstr "máquinas virtuales"
#: ../public/customize/custom.js:91
msgid "The Storage view offers you an overview of your current images. Storage elements are attached to compute resources at creation time. They can also be extracted from running virtual machines by taking an snapshot."
msgstr "La vista de almacenamiento le ofrece la visión general de sus imágenes. Los elementos de almacenamiento se asocian a máquinas virtuales en el momento de la creación. También pueden ser extraídos de una máquina virtual en ejecución tomando una instantánea"
#: ../public/customize/custom.js:92
msgid "You can add new storages by clicking 'new'. Image files will be uploaded to OpenNebula and set ready to be used."
msgstr "Puede añadir nuevos almacenamientos haciendo click en 'new'. Los ficheros de imagen pueden ser subidos a OpenNebula y preparados para ser usado."
#: ../public/customize/custom.js:93
msgid "Additionally, you can run several operations on defined storages, such as defining their persistance. Persistent images can only be used by 1 virtual machine, and the changes made by it have effect on the base image. Non-persistent images are cloned before being used in a Virtual Machine, therefore changes are lost unless a snapshot is taken prior to Virtual Machine shutdown."
msgstr "Además, puede ejecutar varias operaciones en los almacenamientos presentes, como definir su persistencia. Las imágenes persistentes sólo pueden ser usadas por 1 máquina virtual, y los cambios realizados por ella tiene efecto en la imágen base. Las imágenes no persistentes son clonadas antes de ser utilizadas en una máquina virtual, por tanto los cambios se pierden a menos que se tome una instantánea antes de apagar la máquina virtual."
#: ../public/customize/custom.js:95
msgid "images"
msgstr "imágenes"
#: ../public/customize/custom.js:101
msgid "In this view you can easily manage OpenNebula Network resources. You can add or remove virtual networks."
msgstr "En esta vista puede gestionar fácilmente los recursos de red de OpenNebula. Puede añadir o borrar redes virtuales."
#: ../public/customize/custom.js:102
msgid "Compute resources can be attached to these networks at creation time. Virtual machines will be provided with an IP and the correct parameters to ensure connectivity."
msgstr "Las máquinas virtuales pueden asociarse a estas redes en el momento de su creación. Las máquinas virtuales serán provistas de una IP y de los parámetros correctos para asegurar conectividad."
#: ../public/customize/custom.js:105
msgid "networks"
msgstr "redes"
#~ msgid "style"
#~ msgstr "estilo"

View File

@ -0,0 +1,683 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-05-21 15:11+0200\n"
"PO-Revision-Date: 2012-05-21 15:32+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: fr_CA\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../public/js/locale.js:34
msgid "Changing language"
msgstr "Modification de la langue"
#: ../public/js/locale.js:35
msgid "Loading new language... please wait"
msgstr "Chargement d'une nouvelle langue... veuillez patienter"
#: ../public/js/locale.js:53 ../public/customize/custom.js:51
msgid "Documentation"
msgstr "Documentation"
#: ../public/js/locale.js:54 ../public/customize/custom.js:54
msgid "Support"
msgstr "Support"
#: ../public/js/locale.js:55 ../public/customize/custom.js:57
msgid "Community"
msgstr "Communauté"
#: ../public/js/locale.js:56
msgid "Welcome"
msgstr "Bienvenue"
#: ../public/js/locale.js:57
msgid "Sign out"
msgstr "Déconnecter"
#: ../public/js/plugins/storage.js:26 ../public/js/plugins/network.js:26
#: ../public/js/plugins/compute.js:63
msgid "All"
msgstr "Tout "
#: ../public/js/plugins/storage.js:27 ../public/js/plugins/storage.js:345
#: ../public/js/plugins/network.js:27 ../public/js/plugins/network.js:278
#: ../public/js/plugins/compute.js:64 ../public/js/plugins/compute.js:510
#: ../public/js/plugins/compute.js:555 ../public/js/plugins/compute.js:600
msgid "ID"
msgstr "ID"
#: ../public/js/plugins/storage.js:28 ../public/js/plugins/storage.js:45
#: ../public/js/plugins/storage.js:349 ../public/js/plugins/network.js:28
#: ../public/js/plugins/network.js:41 ../public/js/plugins/network.js:282
#: ../public/js/plugins/compute.js:65 ../public/js/plugins/compute.js:514
#: ../public/js/plugins/compute.js:559 ../public/js/plugins/compute.js:604
msgid "Name"
msgstr "Nom"
#: ../public/js/plugins/storage.js:41
msgid "Fields marked with"
msgstr "Champs marqués par"
#: ../public/js/plugins/storage.js:42
msgid "are mandatory"
msgstr "sont obligatoire"
#: ../public/js/plugins/storage.js:47
msgid "Name that the Image will get."
msgstr "Nom que l'Image va avoir."
#: ../public/js/plugins/storage.js:50 ../public/js/plugins/storage.js:353
msgid "Description"
msgstr "Description"
#: ../public/js/plugins/storage.js:52
msgid "Human readable description of the image."
msgstr "Description humainement lisible de l'image."
#: ../public/js/plugins/storage.js:57 ../public/js/plugins/storage.js:357
#: ../public/js/plugins/compute.js:567
msgid "Type"
msgstr "Type"
#: ../public/js/plugins/storage.js:59
msgid "OS"
msgstr "OS"
#: ../public/js/plugins/storage.js:60
msgid "CD-ROM"
msgstr "CD-ROM"
#: ../public/js/plugins/storage.js:61
msgid "Datablock"
msgstr "Block de données"
#: ../public/js/plugins/storage.js:63
msgid "Type of the image"
msgstr "Type de l'image"
#: ../public/js/plugins/storage.js:66 ../public/js/plugins/network.js:297
msgid "Size"
msgstr "Taille"
#: ../public/js/plugins/storage.js:68
msgid "Size of the datablock in MB."
msgstr "Taille du bloc de données en MB."
#: ../public/js/plugins/storage.js:71
msgid "FS type"
msgstr "Type de FS"
#: ../public/js/plugins/storage.js:73
msgid "Type of file system to be built. This can be any value understood by mkfs unix command."
msgstr "Type de système de fichier à créer. Ce peut être n'importe quelle valeur comprise par la commande unix mkfs."
#: ../public/js/plugins/storage.js:76
msgid "Select image to upload"
msgstr "Sélectionner une image à téléverser"
#: ../public/js/plugins/storage.js:83
msgid "Public"
msgstr "Publique"
#: ../public/js/plugins/storage.js:85
msgid "Public scope of the image"
msgstr "Visibilité publique de l'image"
#: ../public/js/plugins/storage.js:88 ../public/js/plugins/storage.js:361
msgid "Persistent"
msgstr "Persistant"
#: ../public/js/plugins/storage.js:90
msgid "Persistence of the image"
msgstr "Persistance de l'image"
#: ../public/js/plugins/storage.js:95 ../public/js/plugins/network.js:56
#: ../public/js/plugins/compute.js:103
msgid "Close"
msgstr "Fermer"
#: ../public/js/plugins/storage.js:96 ../public/js/plugins/network.js:57
#: ../public/js/plugins/compute.js:104
msgid "Create"
msgstr "Créer"
#: ../public/js/plugins/storage.js:214 ../public/js/plugins/network.js:158
#: ../public/js/plugins/compute.js:305
msgid "Refresh list"
msgstr "Rafraîchir la liste"
#: ../public/js/plugins/storage.js:219 ../public/js/plugins/network.js:164
#: ../public/js/plugins/compute.js:311
msgid "+ New"
msgstr "+ Nouveau"
#: ../public/js/plugins/storage.js:223
msgid "Make persistent"
msgstr "Rendre persistant"
#: ../public/js/plugins/storage.js:227
msgid "Make non persistent"
msgstr "Rendre non-persistant"
#: ../public/js/plugins/storage.js:234 ../public/js/plugins/network.js:169
msgid "Publish"
msgstr "Publier"
#: ../public/js/plugins/storage.js:238 ../public/js/plugins/network.js:174
msgid "Unpublish"
msgstr "Retirer"
#: ../public/js/plugins/storage.js:244 ../public/js/plugins/network.js:179
#: ../public/js/plugins/compute.js:353
msgid "Delete"
msgstr "Supprimer"
#: ../public/js/plugins/storage.js:250 ../public/js/plugins/storage.js:337
msgid "Image information"
msgstr "Information de l'image"
#: ../public/js/plugins/storage.js:258
msgid "Add storage"
msgstr "Ajouter des images"
#: ../public/js/plugins/storage.js:264 ../public/js/plugins/dashboard.js:46
#: ../public/customize/custom.js:68
msgid "Storage"
msgstr "Stockage"
#: ../public/js/plugins/storage.js:341
msgid "Image"
msgstr "Image"
#: ../public/js/plugins/storage.js:342 ../public/js/plugins/network.js:275
msgid "information"
msgstr "information"
#: ../public/js/plugins/storage.js:365
msgid "Filesystem type"
msgstr "Type de système de fichiers"
#: ../public/js/plugins/storage.js:369
msgid "Size (Mb)"
msgstr "Taille (Mb)"
#: ../public/js/plugins/storage.js:503
msgid "You must specify a name"
msgstr "Vous devez spécifier un nom"
#: ../public/js/plugins/storage.js:521
msgid "You must specify size and FS type"
msgstr "Vous devez spécifier une taille et un type de Système de Fichiers"
#: ../public/js/plugins/storage.js:528
msgid "You must select a file to upload"
msgstr "Vous devez sélectionner un fichier à téléverser"
#: ../public/js/plugins/network.js:47
msgid "Network Address"
msgstr "Adresse réseau"
#: ../public/js/plugins/network.js:49
msgid "Network Size"
msgstr "Taille du réseau"
#: ../public/js/plugins/network.js:185
msgid "Network information"
msgstr "Information réseau"
#: ../public/js/plugins/network.js:193
msgid "Create network"
msgstr "Créer le réseau"
#: ../public/js/plugins/network.js:199 ../public/js/plugins/compute.js:91
#: ../public/js/plugins/compute.js:368 ../public/js/plugins/compute.js:627
msgid "Networks"
msgstr "Réseaux"
#: ../public/js/plugins/network.js:274
msgid "Virtual Network"
msgstr "Réseau Virtuel"
#: ../public/js/plugins/network.js:286
msgid "Used leases"
msgstr "Baux utilisés"
#: ../public/js/plugins/network.js:293
msgid "Address"
msgstr "Adresse "
#: ../public/js/plugins/network.js:307
msgid "Virtual Network information"
msgstr "Informations sur le Réseau Virtuel"
#: ../public/js/plugins/network.js:353
msgid "Virtual Network name missing!"
msgstr "Le nom du Réseau Virtuel est manquant!"
#: ../public/js/plugins/network.js:365
msgid "Please provide a network address"
msgstr "Veuillez renseigner une adresse réseau"
#: ../public/js/plugins/dashboard.js:37
msgid "Current resources"
msgstr "Ressources actuelles"
#: ../public/js/plugins/dashboard.js:42 ../public/js/plugins/compute.js:381
#: ../public/customize/custom.js:64
msgid "Compute"
msgstr "Machines&nbsp;virtuelles"
#: ../public/js/plugins/dashboard.js:50 ../public/customize/custom.js:72
msgid "Network"
msgstr "Réseau"
#: ../public/js/plugins/dashboard.js:62
msgid "Useful links"
msgstr "Liens utiles"
#: ../public/js/plugins/dashboard.js:81
msgid "Create new compute resource"
msgstr "Créer une nouvelle ressource de calcul"
#: ../public/js/plugins/dashboard.js:82 ../public/js/plugins/dashboard.js:96
#: ../public/js/plugins/dashboard.js:110
msgid "See more"
msgstr "Voir plus"
#: ../public/js/plugins/dashboard.js:95
msgid "Create new storage resource"
msgstr "Créer une nouvelle ressource de stockage"
#: ../public/js/plugins/dashboard.js:109
msgid "Create new network resource"
msgstr "Créer une nouvelle ressource réseau"
#: ../public/js/plugins/dashboard.js:120
msgid "Dashboard"
msgstr "Tableau de bord"
#: ../public/js/plugins/compute.js:32 ../public/js/plugins/compute.js:526
msgid "CPU"
msgstr "CPU"
#: ../public/js/plugins/compute.js:37 ../public/js/plugins/compute.js:530
msgid "Memory"
msgstr "Mémoire"
#: ../public/js/plugins/compute.js:42
msgid "Network transmission"
msgstr "Transmission réseau"
#: ../public/js/plugins/compute.js:47
msgid "Network reception"
msgstr "Réception réseau"
#: ../public/js/plugins/compute.js:65 ../public/js/plugins/compute.js:522
msgid "State"
msgstr "État"
#: ../public/js/plugins/compute.js:66 ../public/js/plugins/compute.js:608
msgid "IP"
msgstr "IP"
#: ../public/js/plugins/compute.js:76
msgid "VM Name"
msgstr "Nom MV"
#: ../public/js/plugins/compute.js:80 ../public/js/plugins/compute.js:518
msgid "Instance type"
msgstr "Type d'instance"
#: ../public/js/plugins/compute.js:82 ../public/js/plugins/compute.js:982
msgid "Loading"
msgstr "Chargement"
#: ../public/js/plugins/compute.js:86
msgid "Images"
msgstr "Images"
#: ../public/js/plugins/compute.js:97
msgid "Create # VMs"
msgstr "Créer # MVs"
#: ../public/js/plugins/compute.js:99
#, fuzzy
msgid "You can use the wildcard &#37;. When creating several VMs, &#37; will be replaced with a different number starting from 0 in each of them"
msgstr "Vous pouvez utiliser le joker %i. Lors de la création de plusieurs MVs, %i sera remplacé par un nombre commençant à 0 dans chaqu'une d'entre elles."
#: ../public/js/plugins/compute.js:317
msgid "Shutdown"
msgstr "Éteindre"
#: ../public/js/plugins/compute.js:318
msgid "This will shutdown the selected VMs"
msgstr "Ceci va éteindre les MVs sélectionnées"
#: ../public/js/plugins/compute.js:326
msgid "Suspend"
msgstr "Suspendre"
#: ../public/js/plugins/compute.js:327
msgid "This will suspend the selected VMs"
msgstr "Ceci va mettre en pause les MVs sélectionnées"
#: ../public/js/plugins/compute.js:331
msgid "Resume"
msgstr "Reprendre"
#: ../public/js/plugins/compute.js:332
msgid "This will resume the selected VMs in stopped or suspended states"
msgstr "Ceci va reprendre les MVs sélectionnées qui sont stoppées ou en pause"
#: ../public/js/plugins/compute.js:336
msgid "Stop"
msgstr "Arrêter"
#: ../public/js/plugins/compute.js:341 ../public/js/plugins/compute.js:809
#: ../../../../../sunstone/public/js/sunstone.js:661
#: ../../../../../sunstone/public/js/sunstone.js:693
msgid "Cancel"
msgstr "Annuler"
#: ../public/js/plugins/compute.js:342
msgid "This will cancel selected VMs"
msgstr "Ceci va annuler les MVs sélectionnées"
#: ../public/js/plugins/compute.js:346 ../public/js/plugins/compute.js:798
msgid "Take snapshot"
msgstr "Prendre un instantané"
#: ../public/js/plugins/compute.js:354
msgid "This will delete the selected VMs from the database"
msgstr "Ceci va supprimer les MVs sélectionnées de la base de données"
#: ../public/js/plugins/compute.js:360
msgid "Compute resource"
msgstr "Ressource de calcul"
#: ../public/js/plugins/compute.js:364 ../public/js/plugins/compute.js:582
msgid "Disks"
msgstr "Disques"
#: ../public/js/plugins/compute.js:375
msgid "Create Virtual Machine"
msgstr "Créer une machine virtuelle"
#: ../public/js/plugins/compute.js:502
msgid "VM information"
msgstr "Information MV"
#: ../public/js/plugins/compute.js:506
msgid "Virtual Machine information"
msgstr "Informations sur la machine virtuelle"
#: ../public/js/plugins/compute.js:534
msgid "Launch VNC session"
msgstr "Exécuter une session VNC"
#: ../public/js/plugins/compute.js:545
msgid "Disks information"
msgstr "Informations des disques"
#: ../public/js/plugins/compute.js:563
msgid "Target"
msgstr "Cible"
#: ../public/js/plugins/compute.js:574 ../public/js/plugins/compute.js:905
msgid "No disks defined"
msgstr "Aucun disque défini"
#: ../public/js/plugins/compute.js:588
msgid "Networks information"
msgstr "Informations réseaux"
#: ../public/js/plugins/compute.js:612
msgid "MAC"
msgstr "MAC"
#: ../public/js/plugins/compute.js:619
msgid "No networks defined"
msgstr "Aucun réseau défini"
#: ../public/js/plugins/compute.js:633
msgid "Monitoring information"
msgstr "Information de surveillance"
#: ../public/js/plugins/compute.js:808
#: ../../../../../sunstone/public/js/sunstone.js:660
#: ../../../../../sunstone/public/js/sunstone.js:692
msgid "OK"
msgstr "OK"
#: ../public/js/plugins/compute.js:831
msgid "Skipping VM "
msgstr "Passer la MV"
#: ../public/js/plugins/compute.js:832
msgid "No disk id or image name specified"
msgstr "Aucun identifiant de disque ou nom d'image"
#: ../public/js/plugins/compute.js:868
msgid "Saveas for VM with ID"
msgstr "Sauvegarder sous pour une MV avec ID"
#: ../public/js/plugins/compute.js:871
msgid "Select disk"
msgstr "Sélectionner un disque"
#: ../public/js/plugins/compute.js:873
msgid "Retrieving"
msgstr "Récupération"
#: ../public/js/plugins/compute.js:877
msgid "Image name"
msgstr "Nom de l'image"
#: ../public/js/plugins/compute.js:897 ../public/js/plugins/compute.js:900
msgid "disk id"
msgstr "identifiant disque"
#: ../public/js/plugins/compute.js:975
msgid "VNC connection"
msgstr "Connexion VNC"
#: ../public/js/plugins/compute.js:990
msgid "Canvas not supported."
msgstr "Modèle non supporté."
#: ../public/js/plugins/compute.js:1051 ../public/js/plugins/compute.js:1067
msgid "Open VNC Session"
msgstr "Ouvrir une session VNC"
#: ../public/js/plugins/compute.js:1054 ../public/js/plugins/compute.js:1070
msgid "VNC Disabled"
msgstr "VNC désactivé"
#: ../public/js/plugins/configuration.js:23
msgid "Self-Service UI Configuration"
msgstr "Configuration de l'interface utilisateur du Libre-Service"
#: ../public/js/plugins/configuration.js:28
msgid "Language"
msgstr "Langue"
#: ../public/js/plugins/configuration.js:31
msgid "English"
msgstr "Anglais"
#: ../public/js/plugins/configuration.js:32
msgid "Spanish"
msgstr "Espagnol"
#: ../public/js/plugins/configuration.js:33
#, fuzzy
msgid "French (FR)"
msgstr "Français"
#: ../public/js/plugins/configuration.js:34
#, fuzzy
msgid "French (CA)"
msgstr "Quebecois"
#: ../public/js/plugins/configuration.js:56
msgid "Configuration"
msgstr "Configuration"
#: ../../../../../sunstone/public/js/sunstone.js:586
msgid "Previous action"
msgstr "Action précédente"
#: ../../../../../sunstone/public/js/sunstone.js:649
#: ../../../../../sunstone/public/js/sunstone.js:683
msgid "Confirmation of action"
msgstr "Confirmation de l'action"
#: ../../../../../sunstone/public/js/sunstone.js:655
msgid "You have to confirm this action."
msgstr "Vous devez confirmer cette action."
#: ../../../../../sunstone/public/js/sunstone.js:657
msgid "Do you want to proceed?"
msgstr "Souhaitez-vous continuer ?"
#: ../../../../../sunstone/public/js/sunstone.js:688
msgid "You need to select something."
msgstr "Vous devez sélectionner quelque chose."
#: ../../../../../sunstone/public/js/sunstone-util.js:203
msgid "Submitted"
msgstr "Soumis"
#: ../../../../../sunstone/public/js/sunstone-util.js:220
msgid "Error"
msgstr "Erreur"
#: ../../../../../sunstone/public/js/sunstone-util.js:226
msgid "Info"
msgstr "Info."
#: ../../../../../sunstone/public/js/sunstone-util.js:358
msgid "Cannot contact server: is it running and reachable?"
msgstr "Impossible de contacter le serveur: est-il en cours d'exécution et accessible ?"
#: ../../../../../sunstone/public/js/sunstone-util.js:366
msgid "Network is unreachable: is OpenNebula running?"
msgstr "Le réseau est injoignable: est-ce qu'OpenNebula tourne ?"
#: ../../../../../sunstone/public/js/sunstone-util.js:387
msgid "Unauthorized"
msgstr "Non autorisé"
#: ../../../../../sunstone/public/js/sunstone-util.js:561
#: ../../../../../sunstone/public/js/sunstone-util.js:772
msgid "Please select"
msgstr "Veuillez sélectionner"
#: ../../../../../sunstone/public/js/sunstone-util.js:695
msgid "Update template"
msgstr "Mettre à jour le modèle"
#: ../../../../../sunstone/public/js/sunstone-util.js:701
msgid "Please, choose and modify the template you want to update"
msgstr "Veuillez choisir et modifier le modèle que vous souhaitez mettre à jour"
#: ../../../../../sunstone/public/js/sunstone-util.js:703
#: ../../../../../sunstone/public/js/sunstone-util.js:706
msgid "Select a template"
msgstr "Sélectionner un modèle"
#: ../../../../../sunstone/public/js/sunstone-util.js:711
msgid "Update"
msgstr "Mettre à jour"
#: ../public/customize/custom.js:18
msgid "String"
msgstr "Chaîne"
#: ../public/customize/custom.js:39
msgid "Welcome to OpenNebula Self-Service"
msgstr "Bienvenue au Libre-Service OpenNebula"
#: ../public/customize/custom.js:41
msgid "OpenNebula Self-Service is a simplified user interface to manage OpenNebula compute, storage and network resources. It is focused on easiness and usability and features a limited set of operations directed towards end-users."
msgstr "OpenNebula Libre-Service est une interface utilisateur simplifiée pour gérer les ressources de calcul, stockage et réseau OpenNebula. Il est axé sur la facilité et la convivialité d'un nombre limité d'opérations destinées aux utilisateurs finaux."
#: ../public/customize/custom.js:42
msgid "Additionally, OpenNebula Self-Service allows easy customization of the interface (e.g. this text) and brings multi-language support."
msgstr "Aditionnellement, OpenNebula Libre-Service permet une personalisation aisée de l'interface (ex.: ce texte) et apporte un support multilingue."
#: ../public/customize/custom.js:43
msgid "Have a cloudy experience!"
msgstr "Ayez une expérience dans le Nuage!"
#: ../public/customize/custom.js:66
msgid "Compute resources are Virtual Machines attached to storage and network resources. OpenNebula Self-Service allows you to easily create, remove and manage them, including the possibility of pausing a Virtual Machine or taking a snapshot of one of their disks."
msgstr "Les ressources de calculs sont des machines virtuelles attachées aux ressources de stockage et de réseau. OpenNebula Libre-Service vous permet d'aiséement les créer, supprimer et gérer, incluant la possibilité de mettre en pause une machine virtuelle ou de prendre un instantané d'un de leur disques."
#: ../public/customize/custom.js:70
msgid "Storage pool is formed by several images. These images can contain from full operating systems to be used as base for compute resources, to simple data. OpenNebula Self-Service offers you the possibility to create or upload your own images."
msgstr "Le dépot de stockage est formé par plusieurs images. Ces images peuvent contenir du système d'exploitation complet pour être utilisé comme base pour les ressources de calculs, à de simple données. Open-Nebula Libre-Service vous offre la possibilité de créer ou de téléverser vos propres images."
#: ../public/customize/custom.js:74
msgid "Your compute resources connectivity is performed using pre-defined virtual networks. You can create and manage these networks using OpenNebula Self-Service."
msgstr "Votre connectivité de ressources de calculs est effectuée des réseaux virtuels pré-définis. Vous pouvez créer et gérer ces réseaux en utilisant OpenNebula Libre-Service"
#: ../public/customize/custom.js:81
msgid "This is a list of your current compute resources. Virtual Machines use previously defined images and networks. You can easily create a new compute element by cliking 'new' and filling-in an easy wizard."
msgstr "Ceci est une liste de vos ressources de calculs actuelles. Les machines virtuelles utilisent des images et réseaux prédéfinis. Vous pouvez facilement créer un nouvel élément de calcul en cliquant sur 'Nouveau' et en remplissant un assistant."
#: ../public/customize/custom.js:82
msgid "You can also manage compute resources and perform actions such as stop, resume, shutdown or cancel."
msgstr "Vous pouvez aussi gérer les ressources de calculs et exécuter des actions telles qu'arrêter, reprendre, éteindre ou annuler."
#: ../public/customize/custom.js:83
msgid "Additionally, you can take a 'snapshot' of the storage attached to these resources. They will be saved as new resources, visible from the Storage view and re-usable."
msgstr "De plus, vous pouvez prendre un 'instantané' d'une image raccordée à ces ressources. Elles seront sauvegardées en tant que nouvelles ressources, visibles depuis la vue 'Images' et réutilisables."
#: ../public/customize/custom.js:84 ../public/customize/custom.js:94
#: ../public/customize/custom.js:104
msgid "There are currently"
msgstr "Il y a présentement"
#: ../public/customize/custom.js:85
msgid "virtual machines"
msgstr "machines virtuelles"
#: ../public/customize/custom.js:91
msgid "The Storage view offers you an overview of your current images. Storage elements are attached to compute resources at creation time. They can also be extracted from running virtual machines by taking an snapshot."
msgstr "La vue de stockage vous offre un aperçu de vos images actuelles. Les éléments de stockage sont attachés aux ressources de calculs lors de la création. Ils peuvent également être extrait d'une machine virtuelle en cours d'exécution en prenant un instantané."
#: ../public/customize/custom.js:92
msgid "You can add new storages by clicking 'new'. Image files will be uploaded to OpenNebula and set ready to be used."
msgstr "Vous pouvez ajouter de nouveaux stockages en cliquant sur 'Nouveau'. Les fichiers image seront téléversés à OpenNebula et prêts à être utilisés."
#: ../public/customize/custom.js:93
msgid "Additionally, you can run several operations on defined storages, such as defining their persistance. Persistent images can only be used by 1 virtual machine, and the changes made by it have effect on the base image. Non-persistent images are cloned before being used in a Virtual Machine, therefore changes are lost unless a snapshot is taken prior to Virtual Machine shutdown."
msgstr "En outre, vous pouvez exécuter plusieurs opérations sur une image définie, tel que définir leur persistance. Les images persistantes peuvent seulement être utilisées par une machine virtuelle et les changements effectués auront un effet sur l'image de base. Les images non-persistantes sont clonées avant d'être utilisées dans une machine virtuelle, mais les changements sont perdus en moins qu'un instantané soit pris avant l'extinction de la machine virtuelle."
#: ../public/customize/custom.js:95
msgid "images"
msgstr "images"
#: ../public/customize/custom.js:101
msgid "In this view you can easily manage OpenNebula Network resources. You can add or remove virtual networks."
msgstr "Dans cette vue vous pouvez aisément gérer les ressources Réseau d'OpenNebula. Vous pouvez ajouter ou supprimer des réseaux virtuels."
#: ../public/customize/custom.js:102
msgid "Compute resources can be attached to these networks at creation time. Virtual machines will be provided with an IP and the correct parameters to ensure connectivity."
msgstr "Les ressources de calculs peuvent être rattachées à ces réseaux lors de la création. Une adresse IP ainsi que les paramètres corrects afin d'assurer une connectivité seront fournis aux machines virtuelles."
#: ../public/customize/custom.js:105
msgid "networks"
msgstr "réseaux"
#~ msgid "style"
#~ msgstr "style"
#~ msgid "French Canadian"
#~ msgstr "Québécois"

View File

@ -0,0 +1,683 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-05-21 15:11+0200\n"
"PO-Revision-Date: 2012-05-21 15:33+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../public/js/locale.js:34
msgid "Changing language"
msgstr "Modification de la langue"
#: ../public/js/locale.js:35
msgid "Loading new language... please wait"
msgstr "Chargement d'une nouvelle langue... veuillez patienter"
#: ../public/js/locale.js:53 ../public/customize/custom.js:51
msgid "Documentation"
msgstr "Documentation"
#: ../public/js/locale.js:54 ../public/customize/custom.js:54
msgid "Support"
msgstr "Support"
#: ../public/js/locale.js:55 ../public/customize/custom.js:57
msgid "Community"
msgstr "Communauté"
#: ../public/js/locale.js:56
msgid "Welcome"
msgstr "Bienvenue"
#: ../public/js/locale.js:57
msgid "Sign out"
msgstr "Déconnecter"
#: ../public/js/plugins/storage.js:26 ../public/js/plugins/network.js:26
#: ../public/js/plugins/compute.js:63
msgid "All"
msgstr "Tout "
#: ../public/js/plugins/storage.js:27 ../public/js/plugins/storage.js:345
#: ../public/js/plugins/network.js:27 ../public/js/plugins/network.js:278
#: ../public/js/plugins/compute.js:64 ../public/js/plugins/compute.js:510
#: ../public/js/plugins/compute.js:555 ../public/js/plugins/compute.js:600
msgid "ID"
msgstr "ID"
#: ../public/js/plugins/storage.js:28 ../public/js/plugins/storage.js:45
#: ../public/js/plugins/storage.js:349 ../public/js/plugins/network.js:28
#: ../public/js/plugins/network.js:41 ../public/js/plugins/network.js:282
#: ../public/js/plugins/compute.js:65 ../public/js/plugins/compute.js:514
#: ../public/js/plugins/compute.js:559 ../public/js/plugins/compute.js:604
msgid "Name"
msgstr "Nom"
#: ../public/js/plugins/storage.js:41
msgid "Fields marked with"
msgstr "Champs marqués par"
#: ../public/js/plugins/storage.js:42
msgid "are mandatory"
msgstr "sont obligatoire"
#: ../public/js/plugins/storage.js:47
msgid "Name that the Image will get."
msgstr "Nom que l'Image va avoir."
#: ../public/js/plugins/storage.js:50 ../public/js/plugins/storage.js:353
msgid "Description"
msgstr "Description"
#: ../public/js/plugins/storage.js:52
msgid "Human readable description of the image."
msgstr "Description humainement lisible de l'image."
#: ../public/js/plugins/storage.js:57 ../public/js/plugins/storage.js:357
#: ../public/js/plugins/compute.js:567
msgid "Type"
msgstr "Type"
#: ../public/js/plugins/storage.js:59
msgid "OS"
msgstr "OS"
#: ../public/js/plugins/storage.js:60
msgid "CD-ROM"
msgstr "CD-ROM"
#: ../public/js/plugins/storage.js:61
msgid "Datablock"
msgstr "Block de données"
#: ../public/js/plugins/storage.js:63
msgid "Type of the image"
msgstr "Type de l'image"
#: ../public/js/plugins/storage.js:66 ../public/js/plugins/network.js:297
msgid "Size"
msgstr "Taille"
#: ../public/js/plugins/storage.js:68
msgid "Size of the datablock in MB."
msgstr "Taille du bloc de données en Mo."
#: ../public/js/plugins/storage.js:71
msgid "FS type"
msgstr "Type de FS"
#: ../public/js/plugins/storage.js:73
msgid "Type of file system to be built. This can be any value understood by mkfs unix command."
msgstr "Type de système de fichier à créer. Ce peut être n'importe quelle valeur comprise par la commande unix mkfs."
#: ../public/js/plugins/storage.js:76
msgid "Select image to upload"
msgstr "Sélectionner une image à envoyer"
#: ../public/js/plugins/storage.js:83
msgid "Public"
msgstr "Publique"
#: ../public/js/plugins/storage.js:85
msgid "Public scope of the image"
msgstr "Visibilité publique de l'image"
#: ../public/js/plugins/storage.js:88 ../public/js/plugins/storage.js:361
msgid "Persistent"
msgstr "Persistant"
#: ../public/js/plugins/storage.js:90
msgid "Persistence of the image"
msgstr "Persistance de l'image"
#: ../public/js/plugins/storage.js:95 ../public/js/plugins/network.js:56
#: ../public/js/plugins/compute.js:103
msgid "Close"
msgstr "Fermer"
#: ../public/js/plugins/storage.js:96 ../public/js/plugins/network.js:57
#: ../public/js/plugins/compute.js:104
msgid "Create"
msgstr "Créer"
#: ../public/js/plugins/storage.js:214 ../public/js/plugins/network.js:158
#: ../public/js/plugins/compute.js:305
msgid "Refresh list"
msgstr "Rafraîchir la liste"
#: ../public/js/plugins/storage.js:219 ../public/js/plugins/network.js:164
#: ../public/js/plugins/compute.js:311
msgid "+ New"
msgstr "+ Nouveau"
#: ../public/js/plugins/storage.js:223
msgid "Make persistent"
msgstr "Rendre persistant"
#: ../public/js/plugins/storage.js:227
msgid "Make non persistent"
msgstr "Rendre non-persistant"
#: ../public/js/plugins/storage.js:234 ../public/js/plugins/network.js:169
msgid "Publish"
msgstr "Publier"
#: ../public/js/plugins/storage.js:238 ../public/js/plugins/network.js:174
msgid "Unpublish"
msgstr "Retirer"
#: ../public/js/plugins/storage.js:244 ../public/js/plugins/network.js:179
#: ../public/js/plugins/compute.js:353
msgid "Delete"
msgstr "Supprimer"
#: ../public/js/plugins/storage.js:250 ../public/js/plugins/storage.js:337
msgid "Image information"
msgstr "Information de l'image"
#: ../public/js/plugins/storage.js:258
msgid "Add storage"
msgstr "Ajouter du stockage "
#: ../public/js/plugins/storage.js:264 ../public/js/plugins/dashboard.js:46
#: ../public/customize/custom.js:68
msgid "Storage"
msgstr "Disques"
#: ../public/js/plugins/storage.js:341
msgid "Image"
msgstr "Image"
#: ../public/js/plugins/storage.js:342 ../public/js/plugins/network.js:275
msgid "information"
msgstr "information"
#: ../public/js/plugins/storage.js:365
msgid "Filesystem type"
msgstr "Type de système de fichiers"
#: ../public/js/plugins/storage.js:369
msgid "Size (Mb)"
msgstr "Taille (Mb)"
#: ../public/js/plugins/storage.js:503
msgid "You must specify a name"
msgstr "Vous devez spécifier un nom"
#: ../public/js/plugins/storage.js:521
msgid "You must specify size and FS type"
msgstr "Vous devez spécifier une taille et un type de FS"
#: ../public/js/plugins/storage.js:528
msgid "You must select a file to upload"
msgstr "Vous devez sélectionner un fichier à envoyer"
#: ../public/js/plugins/network.js:47
msgid "Network Address"
msgstr "Adresse réseau"
#: ../public/js/plugins/network.js:49
msgid "Network Size"
msgstr "Taille du réseau"
#: ../public/js/plugins/network.js:185
msgid "Network information"
msgstr "Information réseau"
#: ../public/js/plugins/network.js:193
msgid "Create network"
msgstr "Créer le réseau"
#: ../public/js/plugins/network.js:199 ../public/js/plugins/compute.js:91
#: ../public/js/plugins/compute.js:368 ../public/js/plugins/compute.js:627
msgid "Networks"
msgstr "Réseaux"
#: ../public/js/plugins/network.js:274
msgid "Virtual Network"
msgstr "Réseau Virtuel"
#: ../public/js/plugins/network.js:286
msgid "Used leases"
msgstr "IP utilisées"
#: ../public/js/plugins/network.js:293
msgid "Address"
msgstr "Adresse IP"
#: ../public/js/plugins/network.js:307
msgid "Virtual Network information"
msgstr "Informations sur le Réseau Virtuel"
#: ../public/js/plugins/network.js:353
msgid "Virtual Network name missing!"
msgstr "Le nom du Réseau Virtuel est manquant !"
#: ../public/js/plugins/network.js:365
msgid "Please provide a network address"
msgstr "Veuillez renseigner une adresse réseau"
#: ../public/js/plugins/dashboard.js:37
msgid "Current resources"
msgstr "Ressources actuelles"
#: ../public/js/plugins/dashboard.js:42 ../public/js/plugins/compute.js:381
#: ../public/customize/custom.js:64
msgid "Compute"
msgstr "Machines&nbsp;virtuelles"
#: ../public/js/plugins/dashboard.js:50 ../public/customize/custom.js:72
msgid "Network"
msgstr "Réseau"
#: ../public/js/plugins/dashboard.js:62
msgid "Useful links"
msgstr "Liens utiles"
#: ../public/js/plugins/dashboard.js:81
msgid "Create new compute resource"
msgstr "Créer une nouvelle machine virtuelle"
#: ../public/js/plugins/dashboard.js:82 ../public/js/plugins/dashboard.js:96
#: ../public/js/plugins/dashboard.js:110
msgid "See more"
msgstr "Voir plus"
#: ../public/js/plugins/dashboard.js:95
msgid "Create new storage resource"
msgstr "Créer une nouvelle image"
#: ../public/js/plugins/dashboard.js:109
msgid "Create new network resource"
msgstr "Créer un nouveau réseau"
#: ../public/js/plugins/dashboard.js:120
msgid "Dashboard"
msgstr "Tableau de bord"
#: ../public/js/plugins/compute.js:32 ../public/js/plugins/compute.js:526
msgid "CPU"
msgstr "CPU"
#: ../public/js/plugins/compute.js:37 ../public/js/plugins/compute.js:530
msgid "Memory"
msgstr "Mémoire"
#: ../public/js/plugins/compute.js:42
msgid "Network transmission"
msgstr "Transmission réseau"
#: ../public/js/plugins/compute.js:47
msgid "Network reception"
msgstr "Réception réseau"
#: ../public/js/plugins/compute.js:65 ../public/js/plugins/compute.js:522
msgid "State"
msgstr "État"
#: ../public/js/plugins/compute.js:66 ../public/js/plugins/compute.js:608
msgid "IP"
msgstr "IP"
#: ../public/js/plugins/compute.js:76
msgid "VM Name"
msgstr "Nom VM"
#: ../public/js/plugins/compute.js:80 ../public/js/plugins/compute.js:518
msgid "Instance type"
msgstr "Type d'instance"
#: ../public/js/plugins/compute.js:82 ../public/js/plugins/compute.js:982
msgid "Loading"
msgstr "Chargement"
#: ../public/js/plugins/compute.js:86
msgid "Images"
msgstr "Images"
#: ../public/js/plugins/compute.js:97
msgid "Create # VMs"
msgstr "Créer # VMs"
#: ../public/js/plugins/compute.js:99
#, fuzzy
msgid "You can use the wildcard &#37;. When creating several VMs, &#37; will be replaced with a different number starting from 0 in each of them"
msgstr "Vous pouvez utiliser le joker %i. Lors de la création de plusieurs VMs, %i sera remplacé par un nombre commençant à 0 dans chaqu'une d'entre elles."
#: ../public/js/plugins/compute.js:317
msgid "Shutdown"
msgstr "Éteindre"
#: ../public/js/plugins/compute.js:318
msgid "This will shutdown the selected VMs"
msgstr "Ceci va éteindre les VMs sélectionnées"
#: ../public/js/plugins/compute.js:326
msgid "Suspend"
msgstr "Suspendre"
#: ../public/js/plugins/compute.js:327
msgid "This will suspend the selected VMs"
msgstr "Ceci va mettre en pause les VMs sélectionnées"
#: ../public/js/plugins/compute.js:331
msgid "Resume"
msgstr "Reprendre"
#: ../public/js/plugins/compute.js:332
msgid "This will resume the selected VMs in stopped or suspended states"
msgstr "Ceci va reprendre les VMs sélectionnées qui sont stoppées ou en pause"
#: ../public/js/plugins/compute.js:336
msgid "Stop"
msgstr "Stop"
#: ../public/js/plugins/compute.js:341 ../public/js/plugins/compute.js:809
#: ../../../../../sunstone/public/js/sunstone.js:661
#: ../../../../../sunstone/public/js/sunstone.js:693
msgid "Cancel"
msgstr "Annuler"
#: ../public/js/plugins/compute.js:342
msgid "This will cancel selected VMs"
msgstr "Ceci va annuler les VMs sélectionnées"
#: ../public/js/plugins/compute.js:346 ../public/js/plugins/compute.js:798
msgid "Take snapshot"
msgstr "Prendre un snapshot"
#: ../public/js/plugins/compute.js:354
msgid "This will delete the selected VMs from the database"
msgstr "Ceci va supprimer les VMs sélectionnées de la base de données"
#: ../public/js/plugins/compute.js:360
msgid "Compute resource"
msgstr "Ressource de calcul"
#: ../public/js/plugins/compute.js:364 ../public/js/plugins/compute.js:582
msgid "Disks"
msgstr "Disques"
#: ../public/js/plugins/compute.js:375
msgid "Create Virtual Machine"
msgstr "Créer une machine virtuelle"
#: ../public/js/plugins/compute.js:502
msgid "VM information"
msgstr "Information VM"
#: ../public/js/plugins/compute.js:506
msgid "Virtual Machine information"
msgstr "Informations sur la machine virtuelle"
#: ../public/js/plugins/compute.js:534
msgid "Launch VNC session"
msgstr "Exécuter une session VNC"
#: ../public/js/plugins/compute.js:545
msgid "Disks information"
msgstr "Informations des disques"
#: ../public/js/plugins/compute.js:563
msgid "Target"
msgstr "Cible"
#: ../public/js/plugins/compute.js:574 ../public/js/plugins/compute.js:905
msgid "No disks defined"
msgstr "Aucun disque défini"
#: ../public/js/plugins/compute.js:588
msgid "Networks information"
msgstr "Informations réseaux"
#: ../public/js/plugins/compute.js:612
msgid "MAC"
msgstr "MAC"
#: ../public/js/plugins/compute.js:619
msgid "No networks defined"
msgstr "Aucun réseau défini"
#: ../public/js/plugins/compute.js:633
msgid "Monitoring information"
msgstr "Information de surveillance"
#: ../public/js/plugins/compute.js:808
#: ../../../../../sunstone/public/js/sunstone.js:660
#: ../../../../../sunstone/public/js/sunstone.js:692
msgid "OK"
msgstr "OK"
#: ../public/js/plugins/compute.js:831
msgid "Skipping VM "
msgstr "Passer la VM"
#: ../public/js/plugins/compute.js:832
msgid "No disk id or image name specified"
msgstr "Aucun identifiant de disque ou nom d'image"
#: ../public/js/plugins/compute.js:868
msgid "Saveas for VM with ID"
msgstr "Sauvegarder sous pour une VM avec ID"
#: ../public/js/plugins/compute.js:871
msgid "Select disk"
msgstr "Sélectionner un disque"
#: ../public/js/plugins/compute.js:873
msgid "Retrieving"
msgstr "Récupération"
#: ../public/js/plugins/compute.js:877
msgid "Image name"
msgstr "Nom de l'image"
#: ../public/js/plugins/compute.js:897 ../public/js/plugins/compute.js:900
msgid "disk id"
msgstr "identifiant disque"
#: ../public/js/plugins/compute.js:975
msgid "VNC connection"
msgstr "Connexion VNC"
#: ../public/js/plugins/compute.js:990
msgid "Canvas not supported."
msgstr "Canvas non supporté"
#: ../public/js/plugins/compute.js:1051 ../public/js/plugins/compute.js:1067
msgid "Open VNC Session"
msgstr "Ouvrir une session VNC"
#: ../public/js/plugins/compute.js:1054 ../public/js/plugins/compute.js:1070
msgid "VNC Disabled"
msgstr "VNC désactivé"
#: ../public/js/plugins/configuration.js:23
msgid "Self-Service UI Configuration"
msgstr "Configuration de l'interface de Self-Service"
#: ../public/js/plugins/configuration.js:28
msgid "Language"
msgstr "Langue"
#: ../public/js/plugins/configuration.js:31
msgid "English"
msgstr "Anglais"
#: ../public/js/plugins/configuration.js:32
msgid "Spanish"
msgstr "Espagnol"
#: ../public/js/plugins/configuration.js:33
#, fuzzy
msgid "French (FR)"
msgstr "Français"
#: ../public/js/plugins/configuration.js:34
#, fuzzy
msgid "French (CA)"
msgstr "Quebecois"
#: ../public/js/plugins/configuration.js:56
msgid "Configuration"
msgstr "Configuration"
#: ../../../../../sunstone/public/js/sunstone.js:586
msgid "Previous action"
msgstr "Action précédente"
#: ../../../../../sunstone/public/js/sunstone.js:649
#: ../../../../../sunstone/public/js/sunstone.js:683
msgid "Confirmation of action"
msgstr "Confirmation de l'action"
#: ../../../../../sunstone/public/js/sunstone.js:655
msgid "You have to confirm this action."
msgstr "Vous devez confirmer cette action."
#: ../../../../../sunstone/public/js/sunstone.js:657
msgid "Do you want to proceed?"
msgstr "Souhaitez-vous continuer ?"
#: ../../../../../sunstone/public/js/sunstone.js:688
msgid "You need to select something."
msgstr "Vous devez sélectionner quelque chose."
#: ../../../../../sunstone/public/js/sunstone-util.js:203
msgid "Submitted"
msgstr "Soumis"
#: ../../../../../sunstone/public/js/sunstone-util.js:220
msgid "Error"
msgstr "Erreur"
#: ../../../../../sunstone/public/js/sunstone-util.js:226
msgid "Info"
msgstr "Info."
#: ../../../../../sunstone/public/js/sunstone-util.js:358
msgid "Cannot contact server: is it running and reachable?"
msgstr "Impossible de contacter le serveur : est-il en cours d'exécution et accessible ?"
#: ../../../../../sunstone/public/js/sunstone-util.js:366
msgid "Network is unreachable: is OpenNebula running?"
msgstr "Le réseau est injoignable : est-ce qu'OpenNebula tourne ?"
#: ../../../../../sunstone/public/js/sunstone-util.js:387
msgid "Unauthorized"
msgstr "Non autorisé"
#: ../../../../../sunstone/public/js/sunstone-util.js:561
#: ../../../../../sunstone/public/js/sunstone-util.js:772
msgid "Please select"
msgstr "Veuillez sélectionner"
#: ../../../../../sunstone/public/js/sunstone-util.js:695
msgid "Update template"
msgstr "Mettre à jour le modèle"
#: ../../../../../sunstone/public/js/sunstone-util.js:701
msgid "Please, choose and modify the template you want to update"
msgstr "Veuillez choisir et modifier le modèle que vous souhaitez mettre à jour"
#: ../../../../../sunstone/public/js/sunstone-util.js:703
#: ../../../../../sunstone/public/js/sunstone-util.js:706
msgid "Select a template"
msgstr "Sélectionner un modèle"
#: ../../../../../sunstone/public/js/sunstone-util.js:711
msgid "Update"
msgstr "Mettre à jour"
#: ../public/customize/custom.js:18
msgid "String"
msgstr "Chaîne"
#: ../public/customize/custom.js:39
msgid "Welcome to OpenNebula Self-Service"
msgstr "Bienvenue dans OpenNebula Self-Service"
#: ../public/customize/custom.js:41
msgid "OpenNebula Self-Service is a simplified user interface to manage OpenNebula compute, storage and network resources. It is focused on easiness and usability and features a limited set of operations directed towards end-users."
msgstr "OpenNebula Self-Service est une interface utilisateur simplifiée pour gérer les machines virtuelles, les images disques et les réseaux d'OpenNebula. Il est axé sur la facilité et la convivialité d'un nombre limité d'opérations destinées aux utilisateurs finaux."
#: ../public/customize/custom.js:42
msgid "Additionally, OpenNebula Self-Service allows easy customization of the interface (e.g. this text) and brings multi-language support."
msgstr "Aditionnellement, OpenNebula Self-Service permet une personalisation aisée de l'interface (ex.: ce texte) et apporte un support multi-lingue."
#: ../public/customize/custom.js:43
msgid "Have a cloudy experience!"
msgstr "Ayez une expérience dans le Cloud !"
#: ../public/customize/custom.js:66
msgid "Compute resources are Virtual Machines attached to storage and network resources. OpenNebula Self-Service allows you to easily create, remove and manage them, including the possibility of pausing a Virtual Machine or taking a snapshot of one of their disks."
msgstr "Les ressources de calculs sont des machines virtuelles attachées aux ressources de stockage et de réseau. OpenNebula Self-Service vous permet d'aiséement les créer, supprimer et gérer, incluant la possibilité de mettre en pause une machine virtuelle ou de prendre un snapshot d'un de leur disques."
#: ../public/customize/custom.js:70
msgid "Storage pool is formed by several images. These images can contain from full operating systems to be used as base for compute resources, to simple data. OpenNebula Self-Service offers you the possibility to create or upload your own images."
msgstr "Le dépot de stockage est formé par plusieurs images disques. Ces images peuvent contenir un système d'exploitation complet pour être utilisé comme base pour les machines virtuelles, ou de simples données. Open-Nebula Self-Service vous offre la possibilité de créer ou d'envoyer vos propres images."
#: ../public/customize/custom.js:74
msgid "Your compute resources connectivity is performed using pre-defined virtual networks. You can create and manage these networks using OpenNebula Self-Service."
msgstr "La connectivité des machines virtuelles est effectuée par des réseaux virtuels pré-définis. Vous pouvez créer et gérer ces réseaux en utilisant OpenNebula Self-Service"
#: ../public/customize/custom.js:81
msgid "This is a list of your current compute resources. Virtual Machines use previously defined images and networks. You can easily create a new compute element by cliking 'new' and filling-in an easy wizard."
msgstr "Ceci est la liste de vos machines virtuelles actuelles. Ces machines virtuelles utilisent des images et réseaux prédéfinis. Vous pouvez facilement créer une nouvelle machine virtuelle en cliquant sur « nouveau » et en remplissant le formulaire."
#: ../public/customize/custom.js:82
msgid "You can also manage compute resources and perform actions such as stop, resume, shutdown or cancel."
msgstr "Vous pouvez aussi gérer les machines virtuelles et exécuter des actions telles que arrêter, reprendre, éteindre ou annuler."
#: ../public/customize/custom.js:83
msgid "Additionally, you can take a 'snapshot' of the storage attached to these resources. They will be saved as new resources, visible from the Storage view and re-usable."
msgstr "De plus, vous pouvez prendre un « snapshot » des images attachées à ces ressources. Elles seront sauvegardées en tant que nouvelles images, visibles depuis l'onglet « Disques » et réutilisables."
#: ../public/customize/custom.js:84 ../public/customize/custom.js:94
#: ../public/customize/custom.js:104
msgid "There are currently"
msgstr "Il y a actuellement"
#: ../public/customize/custom.js:85
msgid "virtual machines"
msgstr "machines virtuelles"
#: ../public/customize/custom.js:91
msgid "The Storage view offers you an overview of your current images. Storage elements are attached to compute resources at creation time. They can also be extracted from running virtual machines by taking an snapshot."
msgstr "L'onglet Disques vous offre un aperçu de vos images disques actuelles. Les images sont attachées aux machines virtuelles lors de la création. Elles peuvent également être sauvegardées en prenant un snapshot."
#: ../public/customize/custom.js:92
msgid "You can add new storages by clicking 'new'. Image files will be uploaded to OpenNebula and set ready to be used."
msgstr "Vous pouvez ajouter de nouvelles images en cliquant sur « nouveau ». Les fichiers image seront envoyés à OpenNebula et prêts à être utilisés."
#: ../public/customize/custom.js:93
msgid "Additionally, you can run several operations on defined storages, such as defining their persistance. Persistent images can only be used by 1 virtual machine, and the changes made by it have effect on the base image. Non-persistent images are cloned before being used in a Virtual Machine, therefore changes are lost unless a snapshot is taken prior to Virtual Machine shutdown."
msgstr "En outre, vous pouvez exécuter plusieurs opérations sur une image donnée, tel que définir sa persistance. Les images persistantes peuvent seulement être utilisées par une machine virtuelle et les changements effectués auront un effet sur l'image de base. Les images non-persistantes sont clonées avant d'être utilisées dans une machine virtuelle, mais les changements sont perdus à moins qu'un snapshot soit pris avant l'extinction de la machine virtuelle."
#: ../public/customize/custom.js:95
msgid "images"
msgstr "images"
#: ../public/customize/custom.js:101
msgid "In this view you can easily manage OpenNebula Network resources. You can add or remove virtual networks."
msgstr "Dans cette vue vous pouvez aisément gérer les réseaux d'OpenNebula. Vous pouvez ajouter ou supprimer des réseaux virtuels."
#: ../public/customize/custom.js:102
msgid "Compute resources can be attached to these networks at creation time. Virtual machines will be provided with an IP and the correct parameters to ensure connectivity."
msgstr "Les machines virtuelles peuvent être rattachées à ces réseaux lors de la création. Une adresse IP ainsi que les paramètres corrects afin d'assurer une connectivité seront fournis aux machines virtuelles."
#: ../public/customize/custom.js:105
msgid "networks"
msgstr "réseaux"
#~ msgid "style"
#~ msgstr "style"
#~ msgid "French Canadian"
#~ msgstr "Québécois"

View File

@ -0,0 +1,680 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-05-21 15:11+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../public/js/locale.js:34
msgid "Changing language"
msgstr ""
#: ../public/js/locale.js:35
msgid "Loading new language... please wait"
msgstr ""
#: ../public/js/locale.js:53 ../public/customize/custom.js:51
msgid "Documentation"
msgstr ""
#: ../public/js/locale.js:54 ../public/customize/custom.js:54
msgid "Support"
msgstr ""
#: ../public/js/locale.js:55 ../public/customize/custom.js:57
msgid "Community"
msgstr ""
#: ../public/js/locale.js:56
msgid "Welcome"
msgstr ""
#: ../public/js/locale.js:57
msgid "Sign out"
msgstr ""
#: ../public/js/plugins/storage.js:26 ../public/js/plugins/network.js:26
#: ../public/js/plugins/compute.js:63
msgid "All"
msgstr ""
#: ../public/js/plugins/storage.js:27 ../public/js/plugins/storage.js:345
#: ../public/js/plugins/network.js:27 ../public/js/plugins/network.js:278
#: ../public/js/plugins/compute.js:64 ../public/js/plugins/compute.js:510
#: ../public/js/plugins/compute.js:555 ../public/js/plugins/compute.js:600
msgid "ID"
msgstr ""
#: ../public/js/plugins/storage.js:28 ../public/js/plugins/storage.js:45
#: ../public/js/plugins/storage.js:349 ../public/js/plugins/network.js:28
#: ../public/js/plugins/network.js:41 ../public/js/plugins/network.js:282
#: ../public/js/plugins/compute.js:65 ../public/js/plugins/compute.js:514
#: ../public/js/plugins/compute.js:559 ../public/js/plugins/compute.js:604
msgid "Name"
msgstr ""
#: ../public/js/plugins/storage.js:41
msgid "Fields marked with"
msgstr ""
#: ../public/js/plugins/storage.js:42
msgid "are mandatory"
msgstr ""
#: ../public/js/plugins/storage.js:47
msgid "Name that the Image will get."
msgstr ""
#: ../public/js/plugins/storage.js:50 ../public/js/plugins/storage.js:353
msgid "Description"
msgstr ""
#: ../public/js/plugins/storage.js:52
msgid "Human readable description of the image."
msgstr ""
#: ../public/js/plugins/storage.js:57 ../public/js/plugins/storage.js:357
#: ../public/js/plugins/compute.js:567
msgid "Type"
msgstr ""
#: ../public/js/plugins/storage.js:59
msgid "OS"
msgstr ""
#: ../public/js/plugins/storage.js:60
msgid "CD-ROM"
msgstr ""
#: ../public/js/plugins/storage.js:61
msgid "Datablock"
msgstr ""
#: ../public/js/plugins/storage.js:63
msgid "Type of the image"
msgstr ""
#: ../public/js/plugins/storage.js:66 ../public/js/plugins/network.js:297
msgid "Size"
msgstr ""
#: ../public/js/plugins/storage.js:68
msgid "Size of the datablock in MB."
msgstr ""
#: ../public/js/plugins/storage.js:71
msgid "FS type"
msgstr ""
#: ../public/js/plugins/storage.js:73
msgid "Type of file system to be built. This can be any value understood by mkfs unix command."
msgstr ""
#: ../public/js/plugins/storage.js:76
msgid "Select image to upload"
msgstr ""
#: ../public/js/plugins/storage.js:83
msgid "Public"
msgstr ""
#: ../public/js/plugins/storage.js:85
msgid "Public scope of the image"
msgstr ""
#: ../public/js/plugins/storage.js:88 ../public/js/plugins/storage.js:361
msgid "Persistent"
msgstr ""
#: ../public/js/plugins/storage.js:90
msgid "Persistence of the image"
msgstr ""
#: ../public/js/plugins/storage.js:95 ../public/js/plugins/network.js:56
#: ../public/js/plugins/compute.js:103
msgid "Close"
msgstr ""
#: ../public/js/plugins/storage.js:96 ../public/js/plugins/network.js:57
#: ../public/js/plugins/compute.js:104
msgid "Create"
msgstr ""
#: ../public/js/plugins/storage.js:214 ../public/js/plugins/network.js:158
#: ../public/js/plugins/compute.js:305
msgid "Refresh list"
msgstr ""
#: ../public/js/plugins/storage.js:219 ../public/js/plugins/network.js:164
#: ../public/js/plugins/compute.js:311
msgid "+ New"
msgstr ""
#: ../public/js/plugins/storage.js:223
msgid "Make persistent"
msgstr ""
#: ../public/js/plugins/storage.js:227
msgid "Make non persistent"
msgstr ""
#: ../public/js/plugins/storage.js:234 ../public/js/plugins/network.js:169
msgid "Publish"
msgstr ""
#: ../public/js/plugins/storage.js:238 ../public/js/plugins/network.js:174
msgid "Unpublish"
msgstr ""
#: ../public/js/plugins/storage.js:244 ../public/js/plugins/network.js:179
#: ../public/js/plugins/compute.js:353
msgid "Delete"
msgstr ""
#: ../public/js/plugins/storage.js:250 ../public/js/plugins/storage.js:337
msgid "Image information"
msgstr ""
#: ../public/js/plugins/storage.js:258
msgid "Add storage"
msgstr ""
#: ../public/js/plugins/storage.js:264 ../public/js/plugins/dashboard.js:46
#: ../public/customize/custom.js:68
msgid "Storage"
msgstr ""
#: ../public/js/plugins/storage.js:341
msgid "Image"
msgstr ""
#: ../public/js/plugins/storage.js:342 ../public/js/plugins/network.js:275
msgid "information"
msgstr ""
#: ../public/js/plugins/storage.js:365
msgid "Filesystem type"
msgstr ""
#: ../public/js/plugins/storage.js:369
msgid "Size (Mb)"
msgstr ""
#: ../public/js/plugins/storage.js:503
msgid "You must specify a name"
msgstr ""
#: ../public/js/plugins/storage.js:521
msgid "You must specify size and FS type"
msgstr ""
#: ../public/js/plugins/storage.js:528
msgid "You must select a file to upload"
msgstr ""
#: ../public/js/plugins/network.js:47
msgid "Network Address"
msgstr ""
#: ../public/js/plugins/network.js:49
msgid "Network Size"
msgstr ""
#: ../public/js/plugins/network.js:185
msgid "Network information"
msgstr ""
#: ../public/js/plugins/network.js:193
msgid "Create network"
msgstr ""
#: ../public/js/plugins/network.js:199 ../public/js/plugins/compute.js:91
#: ../public/js/plugins/compute.js:368 ../public/js/plugins/compute.js:627
msgid "Networks"
msgstr ""
#: ../public/js/plugins/network.js:274
msgid "Virtual Network"
msgstr ""
#: ../public/js/plugins/network.js:286
msgid "Used leases"
msgstr ""
#: ../public/js/plugins/network.js:293
msgid "Address"
msgstr ""
#: ../public/js/plugins/network.js:307
msgid "Virtual Network information"
msgstr ""
#: ../public/js/plugins/network.js:353
msgid "Virtual Network name missing!"
msgstr ""
#: ../public/js/plugins/network.js:365
msgid "Please provide a network address"
msgstr ""
#: ../public/js/plugins/dashboard.js:37
msgid "Current resources"
msgstr ""
#: ../public/js/plugins/dashboard.js:42 ../public/js/plugins/compute.js:381
#: ../public/customize/custom.js:64
msgid "Compute"
msgstr ""
#: ../public/js/plugins/dashboard.js:50 ../public/customize/custom.js:72
msgid "Network"
msgstr ""
#: ../public/js/plugins/dashboard.js:62
msgid "Useful links"
msgstr ""
#: ../public/js/plugins/dashboard.js:81
msgid "Create new compute resource"
msgstr ""
#: ../public/js/plugins/dashboard.js:82 ../public/js/plugins/dashboard.js:96
#: ../public/js/plugins/dashboard.js:110
msgid "See more"
msgstr ""
#: ../public/js/plugins/dashboard.js:95
msgid "Create new storage resource"
msgstr ""
#: ../public/js/plugins/dashboard.js:109
msgid "Create new network resource"
msgstr ""
#: ../public/js/plugins/dashboard.js:120
msgid "Dashboard"
msgstr ""
#: ../public/js/plugins/compute.js:32 ../public/js/plugins/compute.js:526
msgid "CPU"
msgstr ""
#: ../public/js/plugins/compute.js:37 ../public/js/plugins/compute.js:530
msgid "Memory"
msgstr ""
#: ../public/js/plugins/compute.js:42
msgid "Network transmission"
msgstr ""
#: ../public/js/plugins/compute.js:47
msgid "Network reception"
msgstr ""
#: ../public/js/plugins/compute.js:65 ../public/js/plugins/compute.js:522
msgid "State"
msgstr ""
#: ../public/js/plugins/compute.js:66 ../public/js/plugins/compute.js:608
msgid "IP"
msgstr ""
#: ../public/js/plugins/compute.js:76
msgid "VM Name"
msgstr ""
#: ../public/js/plugins/compute.js:80 ../public/js/plugins/compute.js:518
msgid "Instance type"
msgstr ""
#: ../public/js/plugins/compute.js:82 ../public/js/plugins/compute.js:982
msgid "Loading"
msgstr ""
#: ../public/js/plugins/compute.js:86
msgid "Images"
msgstr ""
#: ../public/js/plugins/compute.js:97
msgid "Create # VMs"
msgstr ""
#: ../public/js/plugins/compute.js:99
msgid "You can use the wildcard &#37;. When creating several VMs, &#37; will be replaced with a different number starting from 0 in each of them"
msgstr ""
#: ../public/js/plugins/compute.js:317
msgid "Shutdown"
msgstr ""
#: ../public/js/plugins/compute.js:318
msgid "This will shutdown the selected VMs"
msgstr ""
#: ../public/js/plugins/compute.js:326
msgid "Suspend"
msgstr ""
#: ../public/js/plugins/compute.js:327
msgid "This will suspend the selected VMs"
msgstr ""
#: ../public/js/plugins/compute.js:331
msgid "Resume"
msgstr ""
#: ../public/js/plugins/compute.js:332
msgid "This will resume the selected VMs in stopped or suspended states"
msgstr ""
#: ../public/js/plugins/compute.js:336
msgid "Stop"
msgstr ""
#: ../public/js/plugins/compute.js:341 ../public/js/plugins/compute.js:809
#: ../../../../../sunstone/public/js/sunstone.js:661
#: ../../../../../sunstone/public/js/sunstone.js:693
msgid "Cancel"
msgstr ""
#: ../public/js/plugins/compute.js:342
msgid "This will cancel selected VMs"
msgstr ""
#: ../public/js/plugins/compute.js:346 ../public/js/plugins/compute.js:798
msgid "Take snapshot"
msgstr ""
#: ../public/js/plugins/compute.js:354
msgid "This will delete the selected VMs from the database"
msgstr ""
#: ../public/js/plugins/compute.js:360
msgid "Compute resource"
msgstr ""
#: ../public/js/plugins/compute.js:364 ../public/js/plugins/compute.js:582
msgid "Disks"
msgstr ""
#: ../public/js/plugins/compute.js:375
msgid "Create Virtual Machine"
msgstr ""
#: ../public/js/plugins/compute.js:502
msgid "VM information"
msgstr ""
#: ../public/js/plugins/compute.js:506
msgid "Virtual Machine information"
msgstr ""
#: ../public/js/plugins/compute.js:534
msgid "Launch VNC session"
msgstr ""
#: ../public/js/plugins/compute.js:545
msgid "Disks information"
msgstr ""
#: ../public/js/plugins/compute.js:563
msgid "Target"
msgstr ""
#: ../public/js/plugins/compute.js:574 ../public/js/plugins/compute.js:905
msgid "No disks defined"
msgstr ""
#: ../public/js/plugins/compute.js:588
msgid "Networks information"
msgstr ""
#: ../public/js/plugins/compute.js:612
msgid "MAC"
msgstr ""
#: ../public/js/plugins/compute.js:619
msgid "No networks defined"
msgstr ""
#: ../public/js/plugins/compute.js:633
msgid "Monitoring information"
msgstr ""
#: ../public/js/plugins/compute.js:808
#: ../../../../../sunstone/public/js/sunstone.js:660
#: ../../../../../sunstone/public/js/sunstone.js:692
msgid "OK"
msgstr ""
#: ../public/js/plugins/compute.js:831
msgid "Skipping VM "
msgstr ""
#: ../public/js/plugins/compute.js:832
msgid "No disk id or image name specified"
msgstr ""
#: ../public/js/plugins/compute.js:868
msgid "Saveas for VM with ID"
msgstr ""
#: ../public/js/plugins/compute.js:871
msgid "Select disk"
msgstr ""
#: ../public/js/plugins/compute.js:873
msgid "Retrieving"
msgstr ""
#: ../public/js/plugins/compute.js:877
msgid "Image name"
msgstr ""
#: ../public/js/plugins/compute.js:897 ../public/js/plugins/compute.js:900
msgid "disk id"
msgstr ""
#: ../public/js/plugins/compute.js:975
msgid "VNC connection"
msgstr ""
#: ../public/js/plugins/compute.js:990
msgid "Canvas not supported."
msgstr ""
#: ../public/js/plugins/compute.js:1051 ../public/js/plugins/compute.js:1067
msgid "Open VNC Session"
msgstr ""
#: ../public/js/plugins/compute.js:1054 ../public/js/plugins/compute.js:1070
msgid "VNC Disabled"
msgstr ""
#: ../public/js/plugins/configuration.js:23
msgid "Self-Service UI Configuration"
msgstr ""
#: ../public/js/plugins/configuration.js:28
msgid "Language"
msgstr ""
#: ../public/js/plugins/configuration.js:31
msgid "English"
msgstr ""
#: ../public/js/plugins/configuration.js:32
msgid "Spanish"
msgstr ""
#: ../public/js/plugins/configuration.js:33
msgid "French (FR)"
msgstr ""
#: ../public/js/plugins/configuration.js:34
msgid "French (CA)"
msgstr ""
#: ../public/js/plugins/configuration.js:56
msgid "Configuration"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone.js:586
msgid "Previous action"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone.js:649
#: ../../../../../sunstone/public/js/sunstone.js:683
msgid "Confirmation of action"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone.js:655
msgid "You have to confirm this action."
msgstr ""
#: ../../../../../sunstone/public/js/sunstone.js:657
msgid "Do you want to proceed?"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone.js:688
msgid "You need to select something."
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:203
msgid "Submitted"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:220
msgid "Error"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:226
msgid "Info"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:358
msgid "Cannot contact server: is it running and reachable?"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:366
msgid "Network is unreachable: is OpenNebula running?"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:387
msgid "Unauthorized"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:561
#: ../../../../../sunstone/public/js/sunstone-util.js:772
msgid "Please select"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:695
msgid "Update template"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:701
msgid "Please, choose and modify the template you want to update"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:703
#: ../../../../../sunstone/public/js/sunstone-util.js:706
msgid "Select a template"
msgstr ""
#: ../../../../../sunstone/public/js/sunstone-util.js:711
msgid "Update"
msgstr ""
#: ../public/customize/custom.js:18
msgid "String"
msgstr ""
#: ../public/customize/custom.js:39
msgid "Welcome to OpenNebula Self-Service"
msgstr ""
#: ../public/customize/custom.js:41
msgid "OpenNebula Self-Service is a simplified user interface to manage OpenNebula compute, storage and network resources. It is focused on easiness and usability and features a limited set of operations directed towards end-users."
msgstr ""
#: ../public/customize/custom.js:42
msgid "Additionally, OpenNebula Self-Service allows easy customization of the interface (e.g. this text) and brings multi-language support."
msgstr ""
#: ../public/customize/custom.js:43
msgid "Have a cloudy experience!"
msgstr ""
#: ../public/customize/custom.js:66
msgid "Compute resources are Virtual Machines attached to storage and network resources. OpenNebula Self-Service allows you to easily create, remove and manage them, including the possibility of pausing a Virtual Machine or taking a snapshot of one of their disks."
msgstr ""
#: ../public/customize/custom.js:70
msgid "Storage pool is formed by several images. These images can contain from full operating systems to be used as base for compute resources, to simple data. OpenNebula Self-Service offers you the possibility to create or upload your own images."
msgstr ""
#: ../public/customize/custom.js:74
msgid "Your compute resources connectivity is performed using pre-defined virtual networks. You can create and manage these networks using OpenNebula Self-Service."
msgstr ""
#: ../public/customize/custom.js:81
msgid "This is a list of your current compute resources. Virtual Machines use previously defined images and networks. You can easily create a new compute element by cliking 'new' and filling-in an easy wizard."
msgstr ""
#: ../public/customize/custom.js:82
msgid "You can also manage compute resources and perform actions such as stop, resume, shutdown or cancel."
msgstr ""
#: ../public/customize/custom.js:83
msgid "Additionally, you can take a 'snapshot' of the storage attached to these resources. They will be saved as new resources, visible from the Storage view and re-usable."
msgstr ""
#: ../public/customize/custom.js:84 ../public/customize/custom.js:94
#: ../public/customize/custom.js:104
msgid "There are currently"
msgstr ""
#: ../public/customize/custom.js:85
msgid "virtual machines"
msgstr ""
#: ../public/customize/custom.js:91
msgid "The Storage view offers you an overview of your current images. Storage elements are attached to compute resources at creation time. They can also be extracted from running virtual machines by taking an snapshot."
msgstr ""
#: ../public/customize/custom.js:92
msgid "You can add new storages by clicking 'new'. Image files will be uploaded to OpenNebula and set ready to be used."
msgstr ""
#: ../public/customize/custom.js:93
msgid "Additionally, you can run several operations on defined storages, such as defining their persistance. Persistent images can only be used by 1 virtual machine, and the changes made by it have effect on the base image. Non-persistent images are cloned before being used in a Virtual Machine, therefore changes are lost unless a snapshot is taken prior to Virtual Machine shutdown."
msgstr ""
#: ../public/customize/custom.js:95
msgid "images"
msgstr ""
#: ../public/customize/custom.js:101
msgid "In this view you can easily manage OpenNebula Network resources. You can add or remove virtual networks."
msgstr ""
#: ../public/customize/custom.js:102
msgid "Compute resources can be attached to these networks at creation time. Virtual machines will be provided with an IP and the correct parameters to ensure connectivity."
msgstr ""
#: ../public/customize/custom.js:105
msgid "networks"
msgstr ""

View File

@ -1,3 +1,5 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) #
# #
@ -14,16 +16,8 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
# Database URI
#:db: sqlite:///var/one/onequota.db
#-------------------------------------------------------------------------------
# Default quotas, these apply to all users. Leave empty to disable quota for
# a given metric.
#-------------------------------------------------------------------------------
:defaults:
:CPU:
:MEMORY:
:NUM_VMS:
:STORAGE:
#msgmerge [option] def.po ref.pot
for lang in $(ls languages/*); do
msgmerge --backup=off --no-wrap --update $lang messages.pot
done

View File

@ -107,24 +107,25 @@ body {
padding-left: 0;
border:0;
border-right: 1px solid #353735;
background-image: -webkit-gradient(
linear,
left top,
right top,
color-stop(0.95, rgb(99,102,99)),
color-stop(1, rgb(53,55,53))
);
background-image: -moz-linear-gradient(
left center,
rgb(99,102,99) 95%,
rgb(53,55,53) 100%
);
background: #636663; /* Old browsers */
background: -moz-linear-gradient(left, #636663 95%, #353735 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, right top, color-stop(95%,#636663), color-stop(100%,#353735)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(left, #636663 95%,#353735 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(left, #636663 95%,#353735 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(left, #636663 95%,#353735 100%); /* IE10+ */
background: linear-gradient(left, #636663 95%,#353735 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#636663', endColorstr='#353735',GradientType=1 ); /* IE6-9 */
}
#navigation {
.navigation {
list-style: none;
padding: 0;
}
.navigation i {
margin-right: 5px;
}
.navigation li.topTab {
line-height: 2em;
text-align: left;
@ -166,32 +167,14 @@ background-image: -moz-linear-gradient(
}
#navigation li:hover, .navigation-active-li {
background-image: -webkit-gradient(
linear,
left top,
right top,
color-stop(0.95, #0098C3),
color-stop(1, rgb(53,55,53))
);
background-image: -moz-linear-gradient(
left center,
#0098C3 95%,
rgb(53,55,53) 100%
);
/*
background-image: -webkit-gradient(
linear,
right top,
left top,
color-stop(0, rgb(0,152,192)),
color-stop(1, rgb(255,255,255))
);
background-image: -moz-linear-gradient(
right center,
rgb(0,152,192) 0%,
rgb(255,255,255) 100%
);
*/
background: #0098c3; /* Old browsers */
background: -moz-linear-gradient(left, #0098c3 95%, #353735 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, right top, color-stop(95%,#0098c3), color-stop(100%,#353735)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(left, #0098c3 95%,#353735 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(left, #0098c3 95%,#353735 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(left, #0098c3 95%,#353735 100%); /* IE10+ */
background: linear-gradient(left, #0098c3 95%,#353735 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0098c3', endColorstr='#353735',GradientType=1 ); /* IE6-9 */
}
.navigation-active-li {
font-weight: bold;

View File

@ -96,7 +96,7 @@ var create_vm_tmpl ='<form id="create_vm_form" action="">\
<div>\
<label for="vm_n_times">'+tr("Create # VMs")+':</label>\
<input type="text" name="vm_n_times" id="vm_n_times" value="1">\
<div class="tip">'+tr("You can use the wildcard %i. When creating several VMs, %i will be replaced with a different number starting from 0 in each of them")+'.</div>\
<div class="tip">'+tr("You can use the wildcard &#37;. When creating several VMs, &#37; will be replaced with a different number starting from 0 in each of them")+'.</div>\
</div>\
</fieldset>\
<div class="form_buttons">\
@ -406,7 +406,7 @@ var vm_create_panel = {
};
var vms_tab = {
title: tr("Compute"),
title: '<i class="icon-bar-chart"></i>'+tr("Compute"),
content: vms_tab_content,
buttons: vm_buttons
}

View File

@ -53,7 +53,7 @@ var config_actions = {
};
var config_tab = {
title: tr("Configuration"),
title: '<i class="icon-cogs"></i>'+tr("Configuration"),
content: config_tab_content
}

View File

@ -117,7 +117,7 @@ var dashboard_tab_content =
</tr></table>';
var dashboard_tab = {
title: tr("Dashboard"),
title: '<i class="icon-home"></i>'+tr("Dashboard"),
content: dashboard_tab_content
}

View File

@ -196,7 +196,7 @@ var vnet_create_panel = {
}
var vnets_tab = {
title: tr("Networks"),
title: '<i class="icon-resize-small"></i>'+tr("Networks"),
content: vnets_tab_content,
buttons: vnet_buttons
}

View File

@ -261,7 +261,7 @@ var image_create_panel = {
};
var images_tab = {
title: tr("Storage"),
title: '<i class="icon-folder-open"></i>'+tr("Storage"),
content: images_tab_content,
buttons: image_buttons
}

View File

@ -1,163 +0,0 @@
//Translated by
lang="en_US"
datatable_lang=""
locale={
"Additionally, OpenNebula Self-Service allows easy customization of the interface (e.g. this text) and brings multi-language support.":"",
"Additionally, you can run several operations on defined storages, such as defining their persistance. Persistent images can only be used by 1 virtual machine, and the changes made by it have effect on the base image. Non-persistent images are cloned before being used in a Virtual Machine, therefore changes are lost unless a snapshot is taken prior to Virtual Machine shutdown.":"",
"Additionally, you can take a \'snapshot\' of the storage attached to these resources. They will be saved as new resources, visible from the Storage view and re-usable.":"",
"Address":"",
"Add storage":"",
"All":"",
"are mandatory":"",
"Cancel":"",
"Cannot contact server: is it running and reachable?":"",
"Canvas not supported.":"",
"CD-ROM":"",
"Changing language":"",
"Close":"",
"Community":"",
"Compute":"",
"Compute resource":"",
"Compute resources are Virtual Machines attached to storage and network resources. OpenNebula Self-Service allows you to easily create, remove and manage them, including the possibility of pausing a Virtual Machine or taking a snapshot of one of their disks.":"",
"Compute resources can be attached to these networks at creation time. Virtual machines will be provided with an IP and the correct parameters to ensure connectivity.":"",
"Configuration":"",
"Confirmation of action":"",
"CPU":"",
"Create":"",
"Create network":"",
"Create new compute resource":"",
"Create new network resource":"",
"Create new storage resource":"",
"Create Virtual Machine":"",
"Create # VMs":"",
"Current resources":"",
"Dashboard":"",
"Datablock":"",
"Delete":"",
"Description":"",
"disk id":"",
"Disks":"",
"Disks information":"",
"Documentation":"",
"Do you want to proceed?":"",
"English":"",
"Error":"",
"Fields marked with":"",
"Filesystem type":"",
"FS type":"",
"Have a cloudy experience!":"",
"Human readable description of the image.":"",
"ID":"",
"Image":"",
"Image information":"",
"Image name":"",
"images":"",
"Images":"",
"Info":"",
"information":"",
"Instance type":"",
"In this view you can easily manage OpenNebula Network resources. You can add or remove virtual networks.":"",
"IP":"",
"Language":"",
"Launch VNC session":"",
"Loading":"",
"Loading new language... please wait":"",
"MAC":"",
"Make non persistent":"",
"Make persistent":"",
"Memory":"",
"Monitoring information":"",
"Name":"",
"Name that the Image will get.":"",
"Network":"",
"Network Address":"",
"Network information":"",
"Network is unreachable: is OpenNebula running?":"",
"Network reception":"",
"networks":"",
"Networks":"",
"Networks information":"",
"Network Size":"",
"Network transmission":"",
"+ New":"",
"No disk id or image name specified":"",
"No disks defined":"",
"No networks defined":"",
"OK":"",
"OpenNebula Self-Service is a simplified user interface to manage OpenNebula compute, storage and network resources. It is focused on easiness and usability and features a limited set of operations directed towards end-users.":"",
"Open VNC Session":"",
"OS":"",
"Persistence of the image":"",
"Persistent":"",
"Please, choose and modify the template you want to update":"",
"Please provide a network address":"",
"Please select":"",
"Previous action":"",
"Public":"",
"Public scope of the image":"",
"Publish":"",
"Refresh list":"",
"Resume":"",
"Retrieving":"",
"Saveas for VM with ID":"",
"See more":"",
"Select a template":"",
"Select disk":"",
"Select image to upload":"",
"Self-Service UI Configuration":"",
"Shutdown":"",
"Sign out":"",
"Size":"",
"Size (Mb)":"",
"Size of the datablock in MB.":"",
"Skipping VM ":"",
"Spanish":"",
"State":"",
"Stop":"",
"Storage":"",
"Storage pool is formed by several images. These images can contain from full operating systems to be used as base for compute resources, to simple data. OpenNebula Self-Service offers you the possibility to create or upload your own images.":"",
"String":"",
"style":"",
"Submitted":"",
"Support":"",
"Suspend":"",
"Take snapshot":"",
"Target":"",
"There are currently":"",
"The Storage view offers you an overview of your current images. Storage elements are attached to compute resources at creation time. They can also be extracted from running virtual machines by taking an snapshot.":"",
"This is a list of your current compute resources. Virtual Machines use previously defined images and networks. You can easily create a new compute element by cliking \'new\' and filling-in an easy wizard.":"",
"This will cancel selected VMs":"",
"This will delete the selected VMs from the database":"",
"This will resume the selected VMs in stopped or suspended states":"",
"This will shutdown the selected VMs":"",
"This will suspend the selected VMs":"",
"Type":"",
"Type of file system to be built. This can be any value understood by mkfs unix command.":"",
"Type of the image":"",
"Unauthorized":"",
"Unpublish":"",
"Update":"",
"Update template":"",
"Used leases":"",
"Useful links":"",
"Virtual Machine information":"",
"virtual machines":"",
"Virtual Network":"",
"Virtual Network information":"",
"Virtual Network name missing!":"",
"VM information":"",
"VM Name":"",
"VNC connection":"",
"VNC Disabled":"",
"Welcome":"",
"Welcome to OpenNebula Self-Service":"",
"You can add new storages by clicking \'new\'. Image files will be uploaded to OpenNebula and set ready to be used.":"",
"You can also manage compute resources and perform actions such as stop, resume, shutdown or cancel.":"",
"You can use the wildcard %i. When creating several VMs, %i will be replaced with a different number starting from 0 in each of them":"",
"You have to confirm this action.":"",
"You must select a file to upload":"",
"You must specify a name":"",
"You must specify size and FS type":"",
"You need to select something.":"",
"Your compute resources connectivity is performed using pre-defined virtual networks. You can create and manage these networks using OpenNebula Self-Service.":"",
};

View File

@ -1,163 +0,0 @@
//Translated by Hector Sanjuan
lang="es_ES"
datatable_lang="es_datatable.txt"
locale={
"Additionally, OpenNebula Self-Service allows easy customization of the interface (e.g. this text) and brings multi-language support.":"Además, OpenNebula Self-Service permite una fácil personalización de la interfaz (por ejemplo, de este mismo texto) y viene con soporte para múltiples lenguajes.",
"Additionally, you can run several operations on defined storages, such as defining their persistance. Persistent images can only be used by 1 virtual machine, and the changes made by it have effect on the base image. Non-persistent images are cloned before being used in a Virtual Machine, therefore changes are lost unless a snapshot is taken prior to Virtual Machine shutdown.":"Además, puede ejecutar varias operaciones en los almacenamientos presentes, como definir su persistencia. Las imágenes persistentes sólo pueden ser usadas por 1 máquina virtual, y los cambios realizados por ella tiene efecto en la imágen base. Las imágenes no persistentes son clonadas antes de ser utilizadas en una máquina virtual, por tanto los cambios se pierden a menos que se tome una instantánea antes de apagar la máquina virtual.",
"Additionally, you can take a 'snapshot' of the storage attached to these resources. They will be saved as new resources, visible from the Storage view and re-usable.":"Además, puede tomar una 'instantánea' de los almacenamientos asociado a estos recursos. Ésta será salvaguardada como un nuevo recurso, visible y reutilizable desde la vista de almacenamientos.",
"Address":"Dirección",
"Add storage":"Añadir almacenamiento",
"All":"Todos",
"are mandatory":"son obligatorios",
"Cancel":"Cancelar",
"Cannot contact server: is it running and reachable?":"No se puede contactar con el servidor: ¿está funcionando y es alcanzable?",
"Canvas not supported.":"Canvas no soportado",
"CD-ROM":"CD-ROM",
"Changing language":"Cambiando el lenguaje",
"Close":"Cerrar",
"Community":"Comunidad",
"Compute":"Máquinas Virtuales",
"Compute resource":"máquina virtual",
"Compute resources are Virtual Machines attached to storage and network resources. OpenNebula Self-Service allows you to easily create, remove and manage them, including the possibility of pausing a Virtual Machine or taking a snapshot of one of their disks.":"Las máquinas virtuales están asociadas a recursos de almacenamiento y de red. OpenNebula Self-Service le permite crearlos, borrarlos y administrarlos fácilmente, incluyendo la posibilidad de pausar una máquina virtual o de tomar una instantánea de alguno de sus discos.",
"Compute resources can be attached to these networks at creation time. Virtual machines will be provided with an IP and the correct parameters to ensure connectivity.":"Las máquinas virtuales pueden asociarse a estas redes en el momento de su creación. Las máquinas virtuales serán provistas de una IP y de los parámetros correctos para asegurar conectividad.",
"Configuration":"Configuración",
"Confirmation of action":"Confirmar operación",
"CPU":"CPU",
"Create":"Crear",
"Create network":"Crear red",
"Create new compute resource":"Crear nueva máquina virtual",
"Create new network resource":"Crear nueva red",
"Create new storage resource":"Crear nuevo almacenamiento",
"Create Virtual Machine":"Crear máquina virtual",
"Create # VMs":"Crear # MVs",
"Current resources":"Recursos actuales",
"Dashboard":"Portada",
"Datablock":"Datablock",
"Delete":"Borrar",
"Description":"Descripción",
"disk id":"id del disco",
"Disks":"Discos",
"Disks information":"Información de discos",
"Documentation":"Documentación",
"Do you want to proceed?":"¿Desea continuar?",
"English":"Inglés",
"Error":"Error",
"Fields marked with":"Campos marcados con",
"Filesystem type":"Sistema de ficheros",
"FS type":"tipo de FS",
"Have a cloudy experience!":"¡Nos vemos en las nubes!",
"Human readable description of the image.":"Descripción de la imagen.",
"ID":"ID",
"Image":"Imagen",
"Image information":"Información de la imagen",
"Image name":"Nombre de la imagen",
"images":"imágenes",
"Images":"Imágenes",
"Info":"Información",
"information":"Información",
"Instance type":"Tipo de instancia",
"In this view you can easily manage OpenNebula Network resources. You can add or remove virtual networks.":"En esta vista puede gestionar fácilmente los recursos de red de OpenNebula. Puede añadir o borrar redes virtuales.",
"IP":"IP",
"Language":"Lenguaje",
"Launch VNC session":"Lanzar sesión VNC",
"Loading":"Cargando",
"Loading new language... please wait":"Cargando nuevo lenguaje... espere, por favor",
"MAC":"MAC",
"Make non persistent":"Hacer no persistente",
"Make persistent":"Hacer persistente",
"Memory":"Memoria",
"Monitoring information":"Información de monitorización",
"Name":"Nombre",
"Name that the Image will get.":"Nombre para la imagen.",
"Network":"Red",
"Network Address":"Dirección de red",
"Network information":"Información de red",
"Network is unreachable: is OpenNebula running?":"No se puede alcanzar la red: ¿está OpenNebula funcionando?",
"Network reception":"Recepción de red",
"networks":"redes",
"Networks":"Redes",
"Networks information":"Información de redes",
"Network Size":"Tamaño de red",
"Network transmission":"Transmisión de red",
"+ New":"+ Nuevo",
"No disk id or image name specified":"No se ha especificado ID de disco o nombre de la imagen",
"No disks defined":"No hay discos definidos",
"No networks defined":"No hay redes definidas",
"OK":"OK",
"OpenNebula Self-Service is a simplified user interface to manage OpenNebula compute, storage and network resources. It is focused on easiness and usability and features a limited set of operations directed towards end-users.":"OpenNebula Self-Service es una interfaz de usuario simplificada para administrar máquinas virtuales, almacenamiento y red de OpenNebula. Está basada en la facilidad de uso y cuenta con un número limitado de operaciones dirigidas a los usuarios finales.",
"Open VNC Session":"Abrir sesión VNC",
"OS":"OS",
"Persistence of the image":"Persistencia de la imagen",
"Persistent":"Persistente",
"Please, choose and modify the template you want to update":"Por favor, escoja y modifique la plantilla que desea actualizar",
"Please provide a network address":"Por favor, proporcione una dirección de red",
"Please select":"Por favor escoja",
"Previous action":"Acción anterior",
"Public":"Público",
"Public scope of the image":"Imagen pública",
"Publish":"Publicar",
"Refresh list":"Refrescar lista",
"Resume":"Reanudar",
"Retrieving":"Cargando",
"Saveas for VM with ID":"Instantánea a MV con ID",
"See more":"Ver más",
"Select a template":"Seleccione una plantilla",
"Select disk":"Seleccione un disco",
"Select image to upload":"Seleccione una imagen para subir",
"Self-Service UI Configuration":"Configuración de la interfaz Self-Service",
"Shutdown":"Apagar",
"Sign out":"Desconectar",
"Size":"Tamaño",
"Size (Mb)":"Tamaño (Mb)",
"Size of the datablock in MB.":"Tamaño del datablcok en MB",
"Skipping VM ":"Saltando MV",
"Spanish":"Español",
"State":"Estado",
"Stop":"Detener",
"Storage":"Almacenamiento",
"Storage pool is formed by several images. These images can contain from full operating systems to be used as base for compute resources, to simple data. OpenNebula Self-Service offers you the possibility to create or upload your own images.":"La lista de almacenamiento está formada por varias imágenes. Estas imágenes pueden contener desde sistemas operativos completos para ser usados como base en máquinas virtuales, hasta simples datos. OpenNebula Self-Service ofrece la posibilidad de crear o subir sus propias imágenes.",
"String":"String",
"style":"estilo",
"Submitted":"Hecho",
"Support":"Soporte",
"Suspend":"Suspender",
"Take snapshot":"Tomar instantánea",
"Target":"Target",
"There are currently":"Actualmente hay",
"The Storage view offers you an overview of your current images. Storage elements are attached to compute resources at creation time. They can also be extracted from running virtual machines by taking an snapshot.":"La vista de almacenamiento le ofrece la visión general de sus imágenes. Los elementos de almacenamiento se asocian a máquinas virtuales en el momento de la creación. También pueden ser extraídos de una máquina virtual en ejecución tomando una instantánea",
"This is a list of your current compute resources. Virtual Machines use previously defined images and networks. You can easily create a new compute element by cliking 'new' and filling-in an easy wizard.":"Esta es una lista de sus máquinas virtuales actuales. Las máquinas virtuales utilizan imagenes y redes definidas previamente. Puede crear fácilmente una nueva máquina virtual haciendo click en 'New' y rellenado un sencillo formulario.",
"This will cancel selected VMs":"Esto cancelará las MVs seleccionadas",
"This will delete the selected VMs from the database":"Esto borrará las MVs seleccionadas de la base de datos",
"This will resume the selected VMs in stopped or suspended states":"Esto reanudará las MVs seleccionadas paradas o suspendidas",
"This will shutdown the selected VMs":"Esto apagará las MVs seleccionadas",
"This will suspend the selected VMs":"Esto suspenderá las MVs seleccionadas",
"Type":"Tipo",
"Type of file system to be built. This can be any value understood by mkfs unix command.":"Tipo de sistema de archivos a generar. Es válido cualquier valor entendido por el comando mkfs",
"Type of the image":"Tipo de la imagen",
"Unauthorized":"No autorizado",
"Unpublish":"Despublicar",
"Update":"Actualizar",
"Update template":"Actualizar plantilla",
"Used leases":"Leases usados",
"Useful links":"Enlances útiles",
"Virtual Machine information":"Información de máquina virtual",
"virtual machines":"máquinas virtuales",
"Virtual Network":"Red virtual",
"Virtual Network information":"Información de red virtual",
"Virtual Network name missing!":"¡Falta el nombre de la red!",
"VM information":"Información de MV",
"VM Name":"Nombre",
"VNC connection":"Conexión VNC",
"VNC Disabled":"VNC Desabilitado",
"Welcome":"Bienvenid@",
"Welcome to OpenNebula Self-Service":"Bienvenid@ a OpenNebula Self-Service",
"You can add new storages by clicking 'new'. Image files will be uploaded to OpenNebula and set ready to be used.":"Puede añadir nuevos almacenamientos haciendo click en 'new'. Los ficheros de imagen pueden ser subidos a OpenNebula y preparados para ser usado.",
"You can also manage compute resources and perform actions such as stop, resume, shutdown or cancel.":"También puede administrar las máquinas virtuales y realizar acciones como detener, reanudar, apagar o cancelar.",
"You can use the wildcard %i. When creating several VMs, %i will be replaced with a different number starting from 0 in each of them":"Puede utilizar el comodín %i. Durante la creación de varias máquinas virtuales, %i será reemplazado por un número distinto en cada una de ellas, empezando por 0",
"You have to confirm this action.":"Necesita confirmar esta acción",
"You must select a file to upload":"Debe seleccionar un fichero para subir",
"You must specify a name":"Debe especificar un nombre",
"You must specify size and FS type":"Debe especificar un tamaño y un tipo de FS",
"You need to select something.":"Debe seleccionar algo",
"Your compute resources connectivity is performed using pre-defined virtual networks. You can create and manage these networks using OpenNebula Self-Service.":"La conectividad de sus máquinas virtuales se realiza usando redes virtuales pre-definidas. Puede crear y administrar estas redes usando OpenNebula Self-Service.",
};

Some files were not shown because too many files have changed in this diff Show More