mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-22 18:50:08 +03:00
Merge branch 'master' of git.opennebula.org:one
This commit is contained in:
commit
14d2e9a988
@ -57,6 +57,7 @@ main_env.Append(LIBPATH=[
|
||||
cwd+'/src/log',
|
||||
cwd+'/src/sql',
|
||||
cwd+'/src/host',
|
||||
cwd+'/src/cluster',
|
||||
cwd+'/src/mad',
|
||||
cwd+'/src/nebula',
|
||||
cwd+'/src/pool',
|
||||
@ -73,6 +74,7 @@ main_env.Append(LIBPATH=[
|
||||
cwd+'/src/hm',
|
||||
cwd+'/src/um',
|
||||
cwd+'/src/authm',
|
||||
cwd+'/src/xml',
|
||||
])
|
||||
|
||||
# Compile flags
|
||||
@ -171,6 +173,7 @@ build_scripts=[
|
||||
'src/common/SConstruct',
|
||||
'src/template/SConstruct',
|
||||
'src/host/SConstruct',
|
||||
'src/cluster/SConstruct',
|
||||
'src/mad/SConstruct',
|
||||
'src/nebula/SConstruct',
|
||||
'src/pool/SConstruct',
|
||||
@ -187,6 +190,7 @@ build_scripts=[
|
||||
'src/hm/SConstruct',
|
||||
'src/um/SConstruct',
|
||||
'src/authm/SConstruct',
|
||||
'src/xml/SConstruct',
|
||||
]
|
||||
|
||||
# Testing
|
||||
@ -214,6 +218,7 @@ if testing=='yes':
|
||||
'src/authm/test/SConstruct',
|
||||
'src/common/test/SConstruct',
|
||||
'src/host/test/SConstruct',
|
||||
'src/cluster/test/SConstruct',
|
||||
'src/image/test/SConstruct',
|
||||
'src/lcm/test/SConstruct',
|
||||
'src/pool/test/SConstruct',
|
||||
@ -222,6 +227,7 @@ if testing=='yes':
|
||||
'src/um/test/SConstruct',
|
||||
'src/vm/test/SConstruct',
|
||||
'src/vnm/test/SConstruct',
|
||||
'src/xml/test/SConstruct',
|
||||
])
|
||||
else:
|
||||
main_env.Append(testing='no')
|
||||
|
132
include/Cluster.h
Normal file
132
include/Cluster.h
Normal file
@ -0,0 +1,132 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* Copyright 2002-2010, 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 CLUSTER_H_
|
||||
#define CLUSTER_H_
|
||||
|
||||
#include "PoolSQL.h"
|
||||
#include "Host.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* The Cluster class.
|
||||
*/
|
||||
class Cluster : public PoolObjectSQL
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Adds the host to this cluster
|
||||
* @param host The host to add
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
/*
|
||||
int add_host(Host * host)
|
||||
{
|
||||
return host->set_cluster(name);
|
||||
};
|
||||
*/
|
||||
|
||||
/**
|
||||
* Removes the host from this cluster
|
||||
* @param host The host to add
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
// May be needed in a future
|
||||
// int remove_host(Host * host);
|
||||
|
||||
/**
|
||||
* Function to write a Cluster on an output stream
|
||||
*/
|
||||
friend ostream& operator<<(ostream& os, Cluster& cluster);
|
||||
|
||||
/**
|
||||
* Function to print the Cluster object into a string in XML format
|
||||
* @param xml the resulting XML string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
/**
|
||||
* Rebuilds the object from an xml formatted string
|
||||
* @param xml_str The xml-formatted string
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int from_xml(const string &xml_str);
|
||||
|
||||
private:
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Friends
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
friend class ClusterPool;
|
||||
|
||||
// *************************************************************************
|
||||
// Constructor
|
||||
// *************************************************************************
|
||||
|
||||
Cluster(int id, const string& name);
|
||||
|
||||
virtual ~Cluster();
|
||||
|
||||
// *************************************************************************
|
||||
// DataBase implementation (Private)
|
||||
// *************************************************************************
|
||||
|
||||
static const char * db_names;
|
||||
|
||||
static const char * db_bootstrap;
|
||||
|
||||
static const char * table;
|
||||
|
||||
/**
|
||||
* Execute an INSERT or REPLACE Sql query.
|
||||
* @param db The SQL DB
|
||||
* @param replace Execute an INSERT or a REPLACE
|
||||
* @return 0 one success
|
||||
*/
|
||||
int insert_replace(SqlDB *db, bool replace);
|
||||
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the Cluster
|
||||
*/
|
||||
static void bootstrap(SqlDB * db)
|
||||
{
|
||||
ostringstream oss_cluster(Cluster::db_bootstrap);
|
||||
|
||||
db->exec(oss_cluster);
|
||||
};
|
||||
|
||||
/**
|
||||
* Writes the Cluster in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int insert(SqlDB *db, string& error_str);
|
||||
|
||||
/**
|
||||
* Writes/updates the Cluster's data fields in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update(SqlDB *db);
|
||||
};
|
||||
|
||||
#endif /*CLUSTER_H_*/
|
@ -17,124 +17,123 @@
|
||||
#ifndef CLUSTER_POOL_H_
|
||||
#define CLUSTER_POOL_H_
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
|
||||
#include "Cluster.h"
|
||||
#include "Host.h"
|
||||
#include "SqlDB.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
/**
|
||||
* A cluster helper class. It is not a normal PoolSQL,
|
||||
* but a series of static methods related to clusters.
|
||||
*/
|
||||
class ClusterPool
|
||||
class ClusterPool : public PoolSQL
|
||||
{
|
||||
public:
|
||||
ClusterPool(SqlDB * db);
|
||||
|
||||
~ClusterPool(){};
|
||||
|
||||
/**
|
||||
* Removes the host from the given cluster setting the default one.
|
||||
* @param host The host to assign
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int set_default_cluster(Host * host)
|
||||
{
|
||||
return host->set_cluster(ClusterPool::DEFAULT_CLUSTER_NAME);
|
||||
};
|
||||
|
||||
/**
|
||||
* Cluster name for the default cluster
|
||||
*/
|
||||
static const string DEFAULT_CLUSTER_NAME;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------------
|
||||
// Friends
|
||||
// -------------------------------------------------------------------------
|
||||
friend class HostPool;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Attributes */
|
||||
/* Methods for DB management */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/**
|
||||
* This map stores the clusters
|
||||
*/
|
||||
map<int, string> cluster_names;
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Methods for cluster management */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Returns true if the clid is an id for an existing cluster
|
||||
* @param clid ID of the cluster
|
||||
*
|
||||
* @return true if the clid is an id for an existing cluster
|
||||
*/
|
||||
bool exists(int clid)
|
||||
{
|
||||
return cluster_names.count(clid) > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Allocates a new cluster in the pool
|
||||
* @param clid the id assigned to the cluster
|
||||
* @return the id assigned to the cluster or -1 in case of failure
|
||||
*/
|
||||
int allocate(int * clid, string name, SqlDB *db, string& error_str);
|
||||
int allocate(int * oid, string name, string& error_str);
|
||||
|
||||
/**
|
||||
* Returns the xml representation of the given cluster
|
||||
* @param clid ID of the cluster
|
||||
*
|
||||
* @return the xml representation of the given cluster
|
||||
* Function to get a Cluster from the pool, if the object is not in memory
|
||||
* it is loaded from the DB
|
||||
* @param oid Cluster unique id
|
||||
* @param lock locks the Cluster mutex
|
||||
* @return a pointer to the Cluster, 0 if the Cluster could not be loaded
|
||||
*/
|
||||
string info(int clid);
|
||||
|
||||
/**
|
||||
* Removes the given cluster from the pool and the DB
|
||||
* @param clid ID of the cluster
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int drop(int clid, SqlDB *db);
|
||||
|
||||
/**
|
||||
* Dumps the cluster pool in XML format.
|
||||
* @param oss the output stream to dump the pool contents
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump(ostringstream& oss);
|
||||
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the Cluster
|
||||
*/
|
||||
static void bootstrap(SqlDB * db)
|
||||
Cluster * get(int oid, bool lock)
|
||||
{
|
||||
ostringstream oss(ClusterPool::db_bootstrap);
|
||||
db->exec(oss);
|
||||
return static_cast<Cluster *>(PoolSQL::get(oid,lock));
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to insert new Cluster in the pool
|
||||
* @param oid the id assigned to the Cluster
|
||||
* @param name the Cluster's name
|
||||
* @return 0 on success, -1 in case of failure
|
||||
*/
|
||||
int insert (int oid, string name, SqlDB *db);
|
||||
|
||||
/**
|
||||
* Formats as XML the given id and name.
|
||||
* @param oss the output stream to dump the pool contents
|
||||
* Gets an object from the pool (if needed the object is loaded from the
|
||||
* database).
|
||||
* @param name of the object
|
||||
* @param lock locks the object if true
|
||||
*
|
||||
* @return a pointer to the object, 0 in case of failure
|
||||
*/
|
||||
Cluster * get(const string& name, bool lock)
|
||||
{
|
||||
return static_cast<Cluster *>(PoolSQL::get(name,-1,lock));
|
||||
};
|
||||
|
||||
/** Update a particular Cluster
|
||||
* @param user pointer to Cluster
|
||||
* @return 0 on success
|
||||
*/
|
||||
void dump_cluster(ostringstream& oss, int id, string name);
|
||||
int update(Cluster * cluster)
|
||||
{
|
||||
return cluster->update(db);
|
||||
};
|
||||
|
||||
/**
|
||||
* Drops the Cluster from the data base. The object mutex SHOULD be
|
||||
* locked.
|
||||
* @param cluster a pointer to the object
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int drop(Cluster * cluster);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* DB manipulation */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the Cluster pool
|
||||
*/
|
||||
static void bootstrap(SqlDB * _db)
|
||||
{
|
||||
Cluster::bootstrap(_db);
|
||||
};
|
||||
|
||||
static const char * db_names;
|
||||
/**
|
||||
* Dumps the Cluster pool 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(ostringstream& oss, const string& where)
|
||||
{
|
||||
return PoolSQL::dump(oss, "CLUSTER_POOL", Cluster::table, where);
|
||||
};
|
||||
|
||||
static const char * db_bootstrap;
|
||||
|
||||
static const char * table;
|
||||
private:
|
||||
|
||||
/**
|
||||
* Factory method to produce objects
|
||||
* @return a pointer to the new object
|
||||
*/
|
||||
PoolObjectSQL * create()
|
||||
{
|
||||
return new Cluster(-1,"");
|
||||
};
|
||||
};
|
||||
|
||||
#endif /*CLUSTER_POOL_H_*/
|
||||
|
@ -150,6 +150,13 @@ private:
|
||||
* @return 0 if success
|
||||
*/
|
||||
int unset(const string& ip);
|
||||
|
||||
/**
|
||||
* Updates the DB entry for this lease
|
||||
* @param lease Lease to be updated
|
||||
* @return 0 if success
|
||||
*/
|
||||
int update_lease(Lease * lease);
|
||||
};
|
||||
|
||||
#endif /*FIXED_LEASES_H_*/
|
||||
|
@ -25,7 +25,7 @@ using namespace std;
|
||||
* The History class, it represents an execution record of a Virtual Machine.
|
||||
*/
|
||||
|
||||
class History:public ObjectSQL
|
||||
class History:public ObjectSQL, public ObjectXML
|
||||
{
|
||||
public:
|
||||
enum MigrationReason
|
||||
@ -40,13 +40,13 @@ public:
|
||||
History(int oid, int _seq = -1);
|
||||
|
||||
History(
|
||||
int oid,
|
||||
int seq,
|
||||
int hid,
|
||||
string& hostname,
|
||||
string& vm_dir,
|
||||
string& vmm,
|
||||
string& tm);
|
||||
int oid,
|
||||
int seq,
|
||||
int hid,
|
||||
const string& hostname,
|
||||
const string& vm_dir,
|
||||
const string& vmm,
|
||||
const string& tm);
|
||||
|
||||
~History(){};
|
||||
|
||||
@ -55,14 +55,6 @@ public:
|
||||
*/
|
||||
friend ostream& operator<<(ostream& os, const History& history);
|
||||
|
||||
/**
|
||||
* Function to print the History object into a string in
|
||||
* plain text
|
||||
* @param str the resulting string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_str(string& str) const;
|
||||
|
||||
/**
|
||||
* Function to print the History object into a string in
|
||||
* XML format
|
||||
@ -78,52 +70,15 @@ private:
|
||||
// ----------------------------------------
|
||||
// DataBase implementation variables
|
||||
// ----------------------------------------
|
||||
enum ColNames
|
||||
{
|
||||
VID = 0,
|
||||
SEQ = 1,
|
||||
HOSTNAME = 2,
|
||||
VM_DIR = 3,
|
||||
HID = 4,
|
||||
VMMMAD = 5,
|
||||
TMMAD = 6,
|
||||
STIME = 7,
|
||||
ETIME = 8,
|
||||
PROLOG_STIME = 9,
|
||||
PROLOG_ETIME = 10,
|
||||
RUNNING_STIME = 11,
|
||||
RUNNING_ETIME = 12,
|
||||
EPILOG_STIME = 13,
|
||||
EPILOG_ETIME = 14,
|
||||
REASON = 15,
|
||||
LIMIT = 16
|
||||
};
|
||||
|
||||
static const char * table;
|
||||
|
||||
static const char * db_names;
|
||||
|
||||
static const char * extended_db_names;
|
||||
|
||||
static const char * db_bootstrap;
|
||||
|
||||
void non_persistent_data();
|
||||
|
||||
static string column_name(const ColNames column)
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
case HID:
|
||||
return "hid";
|
||||
case ETIME:
|
||||
return "etime";
|
||||
case RUNNING_ETIME:
|
||||
return "retime";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------
|
||||
// History fields
|
||||
// ----------------------------------------
|
||||
@ -167,7 +122,12 @@ private:
|
||||
* @param db pointer to the database.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int insert(SqlDB * db, string& error_str);
|
||||
int insert(SqlDB * db, string& error_str)
|
||||
{
|
||||
error_str.clear();
|
||||
|
||||
return insert_replace(db, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the history record from the DB
|
||||
@ -181,7 +141,10 @@ private:
|
||||
* @param db pointer to the database.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int update(SqlDB * db);
|
||||
int update(SqlDB * db)
|
||||
{
|
||||
return insert_replace(db, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the all history records from the DB
|
||||
@ -208,15 +171,35 @@ private:
|
||||
int select_cb(void *nil, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Function to unmarshall a History object into an output stream with XML
|
||||
* format.
|
||||
* @param oss the output stream
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
* Rebuilds the object from an xml node
|
||||
* @param node The xml node pointer
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
static int dump(ostringstream& oss, int num, char **names, char **values);
|
||||
int from_xml_node(const xmlNodePtr node)
|
||||
{
|
||||
ObjectXML::update_from_node(node);
|
||||
|
||||
return rebuild_attributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuilds the object from an xml formatted string
|
||||
* @param xml_str The xml-formatted string
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int from_xml(const string &xml_str)
|
||||
{
|
||||
ObjectXML::update_from_str(xml_str);
|
||||
|
||||
return rebuild_attributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuilds the internal attributes using xpath
|
||||
*/
|
||||
int rebuild_attributes();
|
||||
};
|
||||
|
||||
#endif /*HISTORY_H_*/
|
||||
|
141
include/Host.h
141
include/Host.h
@ -20,7 +20,6 @@
|
||||
#include "PoolSQL.h"
|
||||
#include "HostTemplate.h"
|
||||
#include "HostShare.h"
|
||||
#include "ClusterPool.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -49,28 +48,20 @@ public:
|
||||
*/
|
||||
friend ostream& operator<<(ostream& os, Host& h);
|
||||
|
||||
/**
|
||||
* Function to print the Host object into a string in plain text
|
||||
* @param str the resulting string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_str(string& str) const;
|
||||
|
||||
/**
|
||||
* Function to print the Host object into a string in XML format
|
||||
* @param xml the resulting XML string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
/**
|
||||
* Function to print the Host object into a string in XML format
|
||||
* @param xml the resulting XML string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
/**
|
||||
* Get the Host unique identifier HID, that matches the OID of the object
|
||||
* @return HID Host identifier
|
||||
* Rebuilds the object from an xml formatted string
|
||||
* @param xml_str The xml-formatted string
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int get_hid() const
|
||||
{
|
||||
return oid;
|
||||
};
|
||||
int from_xml(const string &xml_str);
|
||||
|
||||
/**
|
||||
* Check if the host is enabled
|
||||
@ -120,15 +111,6 @@ public:
|
||||
state = INIT;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns host host_name
|
||||
* @return host_name Host's hostname
|
||||
*/
|
||||
const string& get_hostname() const
|
||||
{
|
||||
return hostname;
|
||||
};
|
||||
|
||||
/** Update host counters and update the whole host on the DB
|
||||
* @param parse_str string with values to be parsed
|
||||
* @return 0 on success
|
||||
@ -378,9 +360,6 @@ private:
|
||||
// -------------------------------------------------------------------------
|
||||
// Host Description
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
string hostname;
|
||||
|
||||
/**
|
||||
* The state of the Host
|
||||
*/
|
||||
@ -402,7 +381,7 @@ private:
|
||||
string tm_mad_name;
|
||||
|
||||
/**
|
||||
* If Host State = MONITORED last time it got fully monitored or 1 Jan 1970
|
||||
* If Host State= MONITORED last time it got fully monitored or 1 Jan 1970
|
||||
* Host State = MONITORING last time it got a signal to be monitored
|
||||
*/
|
||||
time_t last_monitored;
|
||||
@ -426,10 +405,29 @@ private:
|
||||
*/
|
||||
HostShare host_share;
|
||||
|
||||
// *************************************************************************
|
||||
// Constructor
|
||||
// *************************************************************************
|
||||
|
||||
Host(int id=-1,
|
||||
const string& hostname="",
|
||||
const string& im_mad_name="",
|
||||
const string& vmm_mad_name="",
|
||||
const string& tm_mad_name="",
|
||||
const string& cluster="");
|
||||
|
||||
virtual ~Host();
|
||||
|
||||
// *************************************************************************
|
||||
// DataBase implementation (Private)
|
||||
// *************************************************************************
|
||||
|
||||
static const char * db_names;
|
||||
|
||||
static const char * db_bootstrap;
|
||||
|
||||
static const char * table;
|
||||
|
||||
/**
|
||||
* Execute an INSERT or REPLACE Sql query.
|
||||
* @param db The SQL DB
|
||||
@ -438,102 +436,29 @@ private:
|
||||
*/
|
||||
int insert_replace(SqlDB *db, bool replace);
|
||||
|
||||
/**
|
||||
* Callback function to unmarshall a Host object (Host::select)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int select_cb(void *nil, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the Host
|
||||
*/
|
||||
static void bootstrap(SqlDB * db)
|
||||
{
|
||||
ostringstream oss_host(Host::db_bootstrap);
|
||||
ostringstream oss_share(HostShare::db_bootstrap);
|
||||
|
||||
db->exec(oss_host);
|
||||
db->exec(oss_share);
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
// *************************************************************************
|
||||
// Constructor
|
||||
// *************************************************************************
|
||||
|
||||
Host(int id=-1,
|
||||
string _hostname="",
|
||||
string _im_mad_name="",
|
||||
string _vmm_mad_name="",
|
||||
string _tm_mad_name="");
|
||||
|
||||
virtual ~Host();
|
||||
|
||||
// *************************************************************************
|
||||
// DataBase implementation
|
||||
// *************************************************************************
|
||||
|
||||
enum ColNames
|
||||
{
|
||||
OID = 0,
|
||||
HOST_NAME = 1,
|
||||
STATE = 2,
|
||||
IM_MAD = 3,
|
||||
VM_MAD = 4,
|
||||
TM_MAD = 5,
|
||||
LAST_MON_TIME = 6,
|
||||
CLUSTER = 7,
|
||||
TEMPLATE = 8,
|
||||
LIMIT = 9
|
||||
};
|
||||
|
||||
static const char * db_names;
|
||||
|
||||
static const char * db_bootstrap;
|
||||
|
||||
static const char * table;
|
||||
|
||||
/**
|
||||
* Reads the Host (identified with its OID=HID) from the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int select(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Writes the Host and its associated HostShares in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int insert(SqlDB *db, string& error_str);
|
||||
int insert(SqlDB *db, string& error_str);
|
||||
|
||||
/**
|
||||
* Writes/updates the Hosts data fields in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int update(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Drops host from the database
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int drop(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Function to output a Host object in to an stream in XML format
|
||||
* @param oss the output stream
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int dump(ostringstream& oss, int num, char **values, char **names);
|
||||
int update(SqlDB *db);
|
||||
};
|
||||
|
||||
#endif /*HOST_H_*/
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
#include "PoolSQL.h"
|
||||
#include "Host.h"
|
||||
#include "ClusterPool.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <sstream>
|
||||
@ -69,14 +68,24 @@ public:
|
||||
return static_cast<Host *>(PoolSQL::get(oid,lock));
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to get a Host from the pool, if the object is not in memory
|
||||
* it is loaded from the DB
|
||||
* @param hostname
|
||||
* @param lock locks the Host mutex
|
||||
* @return a pointer to the Host, 0 if the Host could not be loaded
|
||||
*/
|
||||
Host * get(string name, bool lock)
|
||||
{
|
||||
return static_cast<Host *>(PoolSQL::get(name,-1,lock));
|
||||
};
|
||||
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the Host pool
|
||||
*/
|
||||
static void bootstrap(SqlDB *_db)
|
||||
{
|
||||
Host::bootstrap(_db);
|
||||
|
||||
ClusterPool::bootstrap(_db);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -138,102 +147,25 @@ public:
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump(ostringstream& oss, const string& where);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Methods for cluster management */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Returns true if the clid is an id for an existing cluster
|
||||
* @param clid ID of the cluster
|
||||
*
|
||||
* @return true if the clid is an id for an existing cluster
|
||||
*/
|
||||
/* bool exists_cluster(int clid)
|
||||
int dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
return cluster_pool.exists(clid);
|
||||
};*/
|
||||
|
||||
/**
|
||||
* Allocates a new cluster in the pool
|
||||
* @param clid the id assigned to the cluster
|
||||
* @return the id assigned to the cluster or -1 in case of failure
|
||||
*/
|
||||
int allocate_cluster(int * clid, const string& name, string& error_str)
|
||||
{
|
||||
return cluster_pool.allocate(clid, name, db, error_str);
|
||||
return PoolSQL::dump(oss, "HOST_POOL", Host::table, where);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the xml representation of the given cluster
|
||||
* @param clid ID of the cluster
|
||||
* Finds a set objects that satisfies a given condition
|
||||
* @param oids a vector with the oids of the objects.
|
||||
* @param the name of the DB table.
|
||||
* @param where condition in SQL format.
|
||||
*
|
||||
* @return the xml representation of the given cluster
|
||||
* @return 0 on success
|
||||
*/
|
||||
string info_cluster(int clid)
|
||||
int search(vector<int>& oids, const string& where)
|
||||
{
|
||||
return cluster_pool.info(clid);
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the given cluster from the pool and the DB
|
||||
* @param clid ID of the cluster
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int drop_cluster(int clid);
|
||||
|
||||
/**
|
||||
* Dumps the cluster pool in XML format.
|
||||
* @param oss the output stream to dump the pool contents
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_cluster(ostringstream& oss)
|
||||
{
|
||||
return cluster_pool.dump(oss);
|
||||
};
|
||||
|
||||
/**
|
||||
* Assigns the host to the given cluster
|
||||
* @param host The host to assign
|
||||
* @param clid ID of the cluster
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int set_cluster(Host* host, int clid)
|
||||
{
|
||||
map<int, string>::iterator it;
|
||||
|
||||
it = cluster_pool.cluster_names.find(clid);
|
||||
|
||||
if (it == cluster_pool.cluster_names.end())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return host->set_cluster( it->second );
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the host from the given cluster setting the default one.
|
||||
* @param host The host to assign
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int set_default_cluster(Host* host)
|
||||
{
|
||||
return host->set_cluster(ClusterPool::DEFAULT_CLUSTER_NAME);
|
||||
return PoolSQL::search(oids, Host::table, where);
|
||||
};
|
||||
|
||||
private:
|
||||
/**
|
||||
* ClusterPool, clusters defined and persistance functionality
|
||||
*/
|
||||
ClusterPool cluster_pool;
|
||||
|
||||
/**
|
||||
* Factory method to produce Host objects
|
||||
@ -244,15 +176,6 @@ private:
|
||||
return new Host;
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback function to build the cluster pool
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int init_cb(void *nil, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Callback function to get the IDs of the hosts to be monitored
|
||||
* (Host::discover)
|
||||
@ -262,16 +185,6 @@ private:
|
||||
* @return 0 on success
|
||||
*/
|
||||
int discover_cb(void * _map, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Callback function to get output the host pool in XML format
|
||||
* (Host::dump)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_cb(void * _oss, int num, char **values, char **names);
|
||||
};
|
||||
|
||||
#endif /*HOST_POOL_H_*/
|
||||
|
@ -17,8 +17,7 @@
|
||||
#ifndef HOST_SHARE_H_
|
||||
#define HOST_SHARE_H_
|
||||
|
||||
#include "SqlDB.h"
|
||||
#include "ObjectSQL.h"
|
||||
#include "ObjectXML.h"
|
||||
#include <time.h>
|
||||
|
||||
using namespace std;
|
||||
@ -29,12 +28,11 @@ using namespace std;
|
||||
/**
|
||||
* The HostShare class. It represents a logical partition of a host...
|
||||
*/
|
||||
class HostShare : public ObjectSQL
|
||||
class HostShare : public ObjectXML
|
||||
{
|
||||
public:
|
||||
|
||||
HostShare(
|
||||
int _hsid=-1,
|
||||
int _max_disk=0,
|
||||
int _max_mem=0,
|
||||
int _max_cpu=0);
|
||||
@ -92,14 +90,6 @@ public:
|
||||
*/
|
||||
friend ostream& operator<<(ostream& os, HostShare& hs);
|
||||
|
||||
/**
|
||||
* Function to print the HostShare object into a string in
|
||||
* plain text
|
||||
* @param str the resulting string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_str(string& str) const;
|
||||
|
||||
/**
|
||||
* Function to print the HostShare object into a string in
|
||||
* XML format
|
||||
@ -110,8 +100,6 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
int hsid; /**< HostShare identifier */
|
||||
|
||||
int disk_usage; /**< Disk allocated to VMs (in Mb). */
|
||||
int mem_usage; /**< Memory allocated to VMs (in Mb) */
|
||||
int cpu_usage; /**< CPU allocated to VMs (in percentage) */
|
||||
@ -128,7 +116,7 @@ private:
|
||||
int used_mem; /**< Used memory from the IM monitor */
|
||||
int used_cpu; /**< Used cpu from the IM monitor */
|
||||
|
||||
int running_vms; /**< Number of running VMs in this Host */
|
||||
int running_vms;/**< Number of running VMs in this Host */
|
||||
|
||||
// ----------------------------------------
|
||||
// Friends
|
||||
@ -137,95 +125,13 @@ private:
|
||||
friend class Host;
|
||||
friend class HostPool;
|
||||
|
||||
// ----------------------------------------
|
||||
// DataBase implementation variables
|
||||
// ----------------------------------------
|
||||
|
||||
enum ColNames
|
||||
{
|
||||
HID = 0,
|
||||
DISK_USAGE = 1,
|
||||
MEM_USAGE = 2,
|
||||
CPU_USAGE = 3,
|
||||
MAX_DISK = 4,
|
||||
MAX_MEMORY = 5,
|
||||
MAX_CPU = 6,
|
||||
FREE_DISK = 7,
|
||||
FREE_MEMORY = 8,
|
||||
FREE_CPU = 9,
|
||||
USED_DISK = 10,
|
||||
USED_MEMORY = 11,
|
||||
USED_CPU = 12,
|
||||
RUNNING_VMS = 13,
|
||||
LIMIT = 14
|
||||
};
|
||||
|
||||
static const char * table;
|
||||
|
||||
static const char * db_names;
|
||||
|
||||
static const char * db_bootstrap;
|
||||
|
||||
// ----------------------------------------
|
||||
// Database methods
|
||||
// ----------------------------------------
|
||||
|
||||
/**
|
||||
* Reads the HostShare (identified with its HSID) from the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
* Rebuilds the object from an xml node
|
||||
* @param node The xml node pointer
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int select(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Writes the HostShare in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int insert(SqlDB * db, string& error_str);
|
||||
|
||||
/**
|
||||
* Writes/updates the HostShare data fields in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Drops hostshare from the database
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int drop(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Execute an INSERT or REPLACE Sql query.
|
||||
* @param db The SQL DB
|
||||
* @param replace Execute an INSERT or a REPLACE
|
||||
* @return 0 one success
|
||||
*/
|
||||
int insert_replace(SqlDB *db, bool replace);
|
||||
|
||||
/**
|
||||
* Callback function to unmarshall a HostShare object (HostShare::select)
|
||||
* @param num the number of columns read from the DB
|
||||
* @para names the column names
|
||||
* @para vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int select_cb(void * nil, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Function to unmarshall a HostShare object in to an output stream in XML
|
||||
* @param oss the output stream
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int dump(ostringstream& oss, int num, char **values, char **names);
|
||||
|
||||
int from_xml_node(const xmlNodePtr node);
|
||||
};
|
||||
|
||||
|
||||
#endif /*HOST_SHARE_H_*/
|
||||
|
108
include/Image.h
108
include/Image.h
@ -59,13 +59,6 @@ public:
|
||||
// Image Public Methods
|
||||
// *************************************************************************
|
||||
|
||||
/**
|
||||
* Function to print the Image object into a string in plain text
|
||||
* @param str the resulting string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_str(string& str) const;
|
||||
|
||||
/**
|
||||
* Function to print the Image object into a string in XML format
|
||||
* @param xml the resulting XML string
|
||||
@ -74,31 +67,12 @@ public:
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
/**
|
||||
* Get the Image unique identifier IID, that matches the OID of the object
|
||||
* @return IID Image identifier
|
||||
* Rebuilds the object from an xml formatted string
|
||||
* @param xml_str The xml-formatted string
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int get_iid() const
|
||||
{
|
||||
return oid;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the uid of the owner of the Image
|
||||
* @return uid
|
||||
**/
|
||||
int get_uid()
|
||||
{
|
||||
return uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Image's name
|
||||
* @return name Image's name
|
||||
*/
|
||||
const string& get_name() const
|
||||
{
|
||||
return name;
|
||||
};
|
||||
int from_xml(const string &xml_str);
|
||||
|
||||
/**
|
||||
* Returns true if the image is public
|
||||
@ -356,34 +330,29 @@ private:
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Owner if the image
|
||||
* Image owner's name
|
||||
*/
|
||||
int uid;
|
||||
|
||||
/**
|
||||
* The name of the Image
|
||||
*/
|
||||
string name;
|
||||
string user_name;
|
||||
|
||||
/**
|
||||
* Type of the Image
|
||||
*/
|
||||
ImageType type;
|
||||
ImageType type;
|
||||
|
||||
/**
|
||||
* Public scope of the Image
|
||||
*/
|
||||
int public_img;
|
||||
int public_img;
|
||||
|
||||
/**
|
||||
* Persistency of the Image
|
||||
*/
|
||||
int persistent_img;
|
||||
int persistent_img;
|
||||
|
||||
/**
|
||||
* Registration time
|
||||
*/
|
||||
time_t regtime;
|
||||
time_t regtime;
|
||||
|
||||
/**
|
||||
* Path to the image
|
||||
@ -422,15 +391,6 @@ private:
|
||||
*/
|
||||
int insert_replace(SqlDB *db, bool replace);
|
||||
|
||||
/**
|
||||
* Callback function to unmarshall a Image object (Image::select)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param values the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int select_cb(void *nil, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the Image
|
||||
*/
|
||||
@ -455,7 +415,9 @@ protected:
|
||||
// Constructor
|
||||
// *************************************************************************
|
||||
|
||||
Image(int uid=-1, ImageTemplate *img_template = 0);
|
||||
Image(int uid,
|
||||
const string& user_name,
|
||||
ImageTemplate* img_template);
|
||||
|
||||
virtual ~Image();
|
||||
|
||||
@ -463,37 +425,12 @@ protected:
|
||||
// DataBase implementation
|
||||
// *************************************************************************
|
||||
|
||||
enum ColNames
|
||||
{
|
||||
OID = 0, /* Image identifier (IID) */
|
||||
UID = 1, /* Image owner id */
|
||||
NAME = 2, /* Image name */
|
||||
TYPE = 3, /* 0) OS 1) CDROM 2) DATABLOCK */
|
||||
PUBLIC = 4, /* Public scope (YES OR NO) */
|
||||
PERSISTENT = 5, /* Peristency (YES OR NO) */
|
||||
REGTIME = 6, /* Time of registration */
|
||||
SOURCE = 7, /* Path to the image */
|
||||
STATE = 8, /* 0) INIT 1) ALLOCATED */
|
||||
RUNNING_VMS = 9, /* Number of VMs using the img */
|
||||
TEMPLATE = 10, /* Image template xml data */
|
||||
LIMIT = 11
|
||||
};
|
||||
|
||||
static const char * extended_db_names;
|
||||
|
||||
static const char * db_names;
|
||||
|
||||
static const char * db_bootstrap;
|
||||
|
||||
static const char * table;
|
||||
|
||||
/**
|
||||
* Reads the Image (identified with its OID=IID) from the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int select(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Writes the Image in the database.
|
||||
* @param db pointer to the db
|
||||
@ -507,23 +444,6 @@ protected:
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int update(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Drops Image and associated template from the database
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int drop(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Function to output an Image object in to an stream in XML format
|
||||
* @param oss the output stream
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int dump(ostringstream& oss, int num, char **values, char **names);
|
||||
};
|
||||
|
||||
#endif /*IMAGE_H_*/
|
||||
|
@ -38,10 +38,10 @@ class ImagePool : public PoolSQL
|
||||
{
|
||||
public:
|
||||
|
||||
ImagePool(SqlDB * db,
|
||||
const string& _source_prefix,
|
||||
const string& _default_type,
|
||||
const string& _default_dev_prefix);
|
||||
ImagePool(SqlDB * db,
|
||||
const string& _source_prefix,
|
||||
const string& _default_type,
|
||||
const string& _default_dev_prefix);
|
||||
|
||||
~ImagePool(){};
|
||||
|
||||
@ -56,20 +56,19 @@ public:
|
||||
*/
|
||||
int allocate (
|
||||
int uid,
|
||||
string user_name,
|
||||
ImageTemplate * img_template,
|
||||
int * oid,
|
||||
string& error_str);
|
||||
|
||||
/**
|
||||
* Function to get a Image from the pool, if the object is not in memory
|
||||
** Function to get a Image from the pool, if the object is not in memory
|
||||
* it is loaded from the DB
|
||||
* @param oid Image unique id
|
||||
* @param lock locks the Image mutex
|
||||
* @return a pointer to the Image, 0 if the Image could not be loaded
|
||||
*/
|
||||
Image * get(
|
||||
int oid,
|
||||
bool lock)
|
||||
Image * get(int oid, bool lock)
|
||||
{
|
||||
return static_cast<Image *>(PoolSQL::get(oid,lock));
|
||||
};
|
||||
@ -78,25 +77,15 @@ public:
|
||||
* Function to get an Image from the pool using the image name
|
||||
* @param name of the image
|
||||
* @param lock locks the User mutex
|
||||
* @return a pointer to the Image, 0 if the User could not be loaded
|
||||
* @return a pointer to the Image, 0 if the image could not be loaded
|
||||
*/
|
||||
Image * get(
|
||||
const string& name,
|
||||
bool lock)
|
||||
Image * get(const string& name, int uid, bool lock)
|
||||
{
|
||||
map<string, int>::iterator index;
|
||||
|
||||
index = image_names.find(name);
|
||||
|
||||
if ( index != image_names.end() )
|
||||
{
|
||||
return get((int)index->second,lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return static_cast<Image *>(PoolSQL::get(name,uid,lock));
|
||||
}
|
||||
|
||||
/** Update a particular Image
|
||||
/**
|
||||
* Update a particular Image
|
||||
* @param image pointer to Image
|
||||
* @return 0 on success
|
||||
*/
|
||||
@ -111,14 +100,7 @@ public:
|
||||
*/
|
||||
int drop(Image * image)
|
||||
{
|
||||
int rc = PoolSQL::drop(image);
|
||||
|
||||
if ( rc == 0)
|
||||
{
|
||||
image_names.erase(image->get_name());
|
||||
}
|
||||
|
||||
return rc;
|
||||
return PoolSQL::drop(image);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -136,7 +118,10 @@ public:
|
||||
* @param where filter for the objects, defaults to all
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump(ostringstream& oss, const string& where);
|
||||
int dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
return PoolSQL::dump(oss, "IMAGE_POOL", Image::table, where);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a DISK attribute for VM templates using the Image metadata
|
||||
@ -145,18 +130,21 @@ public:
|
||||
* @param index number of datablock images used by the same VM. Will be
|
||||
* automatically increased.
|
||||
* @param img_type will be set to the used image's type
|
||||
* @param uid of VM owner (to look for the image id within its images)
|
||||
* @return 0 on success, -1 error, -2 not using the pool
|
||||
*/
|
||||
int disk_attribute(VectorAttribute * disk,
|
||||
int disk_id,
|
||||
int * index,
|
||||
Image::ImageType * img_type);
|
||||
Image::ImageType * img_type,
|
||||
int uid);
|
||||
/**
|
||||
* Generates an Authorization token for the DISK attribute
|
||||
* @param disk the disk to be authorized
|
||||
* @param uid of owner (to look for the image id within her images)
|
||||
* @param ar the AuthRequest
|
||||
*/
|
||||
void authorize_disk(VectorAttribute * disk, AuthRequest * ar);
|
||||
void authorize_disk(VectorAttribute * disk, int uid, AuthRequest * ar);
|
||||
|
||||
static const string& source_prefix()
|
||||
{
|
||||
@ -180,54 +168,29 @@ private:
|
||||
/**
|
||||
* Path to the image repository
|
||||
**/
|
||||
static string _source_prefix;
|
||||
static string _source_prefix;
|
||||
|
||||
/**
|
||||
* Default image type
|
||||
**/
|
||||
static string _default_type;
|
||||
static string _default_type;
|
||||
|
||||
/**
|
||||
* Default device prefix
|
||||
**/
|
||||
static string _default_dev_prefix;
|
||||
static string _default_dev_prefix;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Pool Attributes
|
||||
// -------------------------------------------------------------------------
|
||||
/**
|
||||
* This map stores the association between IIDs and Image names
|
||||
*/
|
||||
map<string, int> image_names;
|
||||
|
||||
/**
|
||||
* Factory method to produce Image objects
|
||||
* @return a pointer to the new Image
|
||||
*/
|
||||
PoolObjectSQL * create()
|
||||
{
|
||||
return new Image;
|
||||
return new Image(-1,"",0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback function to get output the image pool in XML format
|
||||
* (Image::dump)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_cb(void * _oss, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Callback function to build the image_names map
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int init_cb(void *nil, int num, char **values, char **names);
|
||||
|
||||
};
|
||||
|
||||
#endif /*IMAGE_POOL_H_*/
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define LEASES_H_
|
||||
|
||||
#include "ObjectSQL.h"
|
||||
#include "ObjectXML.h"
|
||||
#include "Attribute.h"
|
||||
|
||||
#include <map>
|
||||
@ -40,7 +41,8 @@ public:
|
||||
* @param _size the max number of leases
|
||||
*/
|
||||
Leases(SqlDB * _db, int _oid, unsigned long _size):
|
||||
oid(_oid), size(_size), db(_db){};
|
||||
ObjectSQL(),
|
||||
oid(_oid), size(_size), n_used(0), db(_db){};
|
||||
|
||||
virtual ~Leases()
|
||||
{
|
||||
@ -108,7 +110,7 @@ protected:
|
||||
* The Lease class, it represents a pair of IP and MAC assigned to
|
||||
* a Virtual Machine
|
||||
*/
|
||||
class Lease
|
||||
class Lease : public ObjectXML
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@ -129,13 +131,19 @@ protected:
|
||||
* @param _used, the lease is in use
|
||||
*/
|
||||
Lease(unsigned int _ip, unsigned int _mac[], int _vid, bool _used=true)
|
||||
:ip(_ip), vid(_vid), used(_used)
|
||||
:ObjectXML(),ip(_ip), vid(_vid), used(_used)
|
||||
{
|
||||
// TODO check size
|
||||
mac[PREFIX]=_mac[PREFIX];
|
||||
mac[SUFFIX]=_mac[SUFFIX];
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new empty lease. Method from_xml should be called right
|
||||
* after this constructor.
|
||||
*/
|
||||
Lease():ObjectXML(){};
|
||||
|
||||
~Lease(){};
|
||||
|
||||
/**
|
||||
@ -172,14 +180,6 @@ protected:
|
||||
*/
|
||||
friend ostream& operator<<(ostream& os, Lease& _lease);
|
||||
|
||||
/**
|
||||
* Function to print the Lease object into a string in
|
||||
* plain text
|
||||
* @param str the resulting string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_str(string& str) const;
|
||||
|
||||
/**
|
||||
* Function to print the Lease object into a string in
|
||||
* XML format
|
||||
@ -188,6 +188,23 @@ protected:
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
/**
|
||||
* Function to print the Lease object into a string in
|
||||
* XML format. The output contains all the internal attributes,
|
||||
* to be saved in the DB as a blob
|
||||
* @param xml the resulting XML string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_xml_db(string& xml) const;
|
||||
|
||||
/**
|
||||
* Rebuilds the object from an xml formatted string
|
||||
* @param xml_str The xml-formatted string
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int from_xml(const string &xml_str);
|
||||
|
||||
/**
|
||||
* Constants to access the array storing the MAC address
|
||||
*/
|
||||
@ -227,6 +244,11 @@ protected:
|
||||
*/
|
||||
map<unsigned int, Lease *> leases;
|
||||
|
||||
/**
|
||||
* Number of used leases
|
||||
*/
|
||||
int n_used;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// DataBase implementation variables
|
||||
// -------------------------------------------------------------------------
|
||||
@ -235,17 +257,6 @@ protected:
|
||||
*/
|
||||
SqlDB * db;
|
||||
|
||||
enum ColNames
|
||||
{
|
||||
OID = 0,
|
||||
IP = 1,
|
||||
MAC_PREFIX = 2,
|
||||
MAC_SUFFIX = 3,
|
||||
VID = 4,
|
||||
USED = 5,
|
||||
LIMIT = 6
|
||||
};
|
||||
|
||||
static const char * table;
|
||||
|
||||
static const char * db_names;
|
||||
@ -274,14 +285,6 @@ protected:
|
||||
|
||||
friend ostream& operator<<(ostream& os, Lease& _lease);
|
||||
|
||||
/**
|
||||
* Function to print the Leases object into a string in
|
||||
* plain text
|
||||
* @param str the resulting string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_str(string& str) const;
|
||||
|
||||
/**
|
||||
* Function to print the Leases object into a string in
|
||||
* XML format
|
||||
|
@ -75,6 +75,11 @@ public:
|
||||
return ipool;
|
||||
};
|
||||
|
||||
ClusterPool * get_cpool()
|
||||
{
|
||||
return cpool;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Manager Accessors
|
||||
// --------------------------------------------------------------
|
||||
@ -224,7 +229,7 @@ private:
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
Nebula():nebula_configuration(0),db(0),vmpool(0),hpool(0),vnpool(0),upool(0),
|
||||
ipool(0),lcm(0),vmm(0),im(0),tm(0),dm(0),rm(0),hm(0),authm(0)
|
||||
ipool(0),cpool(0),lcm(0),vmm(0),im(0),tm(0),dm(0),rm(0),hm(0),authm(0)
|
||||
{
|
||||
const char * nl = getenv("ONE_LOCATION");
|
||||
|
||||
@ -284,6 +289,11 @@ private:
|
||||
delete ipool;
|
||||
}
|
||||
|
||||
if ( cpool != 0)
|
||||
{
|
||||
delete cpool;
|
||||
}
|
||||
|
||||
if ( vmm != 0)
|
||||
{
|
||||
delete vmm;
|
||||
@ -370,6 +380,7 @@ private:
|
||||
VirtualNetworkPool * vnpool;
|
||||
UserPool * upool;
|
||||
ImagePool * ipool;
|
||||
ClusterPool * cpool;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Nebula Managers
|
||||
|
@ -60,6 +60,61 @@ public:
|
||||
*/
|
||||
vector<string> operator[] (const char * xpath_expr);
|
||||
|
||||
/**
|
||||
* Gets and sets a xpath attribute, if the attribute is not found a default
|
||||
* is used
|
||||
* @param value to set
|
||||
* @param xpath_expr of the xml element
|
||||
* @param def default value if the element is not found
|
||||
*
|
||||
* @return -1 if default was set
|
||||
*/
|
||||
int xpath(string& value, const char * xpath_expr, const char * def);
|
||||
|
||||
/**
|
||||
* Gets and sets a xpath attribute, if the attribute is not found a default
|
||||
* is used
|
||||
* @param value to set
|
||||
* @param xpath_expr of the xml element
|
||||
* @param def default value if the element is not found
|
||||
*
|
||||
* @return -1 if default was set
|
||||
*/
|
||||
int xpath(int& value, const char * xpath_expr, const int& def);
|
||||
|
||||
/**
|
||||
* Gets and sets a xpath attribute, if the attribute is not found a default
|
||||
* is used
|
||||
* @param value to set
|
||||
* @param xpath_expr of the xml element
|
||||
* @param def default value if the element is not found
|
||||
*
|
||||
* @return -1 if default was set
|
||||
*/
|
||||
int xpath(unsigned int& value, const char * xpath_expr,
|
||||
const unsigned int& def);
|
||||
|
||||
/**
|
||||
* Gets and sets a xpath attribute, if the attribute is not found a default
|
||||
* is used
|
||||
* @param value to set
|
||||
* @param xpath_expr of the xml element
|
||||
* @param def default value if the element is not found
|
||||
*
|
||||
* @return -1 if default was set
|
||||
*/
|
||||
int xpath(time_t& value, const char * xpath_expr, const time_t& def);
|
||||
|
||||
/**
|
||||
* Gets the value of an element from an xml string
|
||||
* @param value the value of the element
|
||||
* @param xml the xml string
|
||||
* @param xpath the xpath of the target element
|
||||
*
|
||||
* @return -1 if the element was not found
|
||||
*/
|
||||
static int xpath_value(string& value, const char *xml, const char *xpath);
|
||||
|
||||
/**
|
||||
* Get xml nodes by Xpath
|
||||
* @param xpath_expr the Xpath for the elements
|
||||
@ -67,14 +122,21 @@ public:
|
||||
* returned as pointers to the object nodes.
|
||||
* @return the number of nodes found
|
||||
*/
|
||||
int get_nodes (const char * xpath_expr, vector<xmlNodePtr>& content);
|
||||
int get_nodes(const char * xpath_expr, vector<xmlNodePtr>& content);
|
||||
|
||||
/**
|
||||
* Updates the object representation with a new XML document. Previous
|
||||
* XML resources are freed
|
||||
* @param xml_doc the new xml document
|
||||
*/
|
||||
int update(const string &xml_doc);
|
||||
int update_from_str(const string &xml_doc);
|
||||
|
||||
/**
|
||||
* Updates the object representation with a new XML document. Previous
|
||||
* XML resources are freed
|
||||
* @param xml_doc the new xml document
|
||||
*/
|
||||
int update_from_node(const xmlNodePtr node);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Lex & bison parser for requirements and rank expressions
|
@ -18,7 +18,9 @@
|
||||
#define POOL_OBJECT_SQL_H_
|
||||
|
||||
#include "ObjectSQL.h"
|
||||
#include "ObjectXML.h"
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -31,11 +33,13 @@ using namespace std;
|
||||
* is called.
|
||||
*/
|
||||
|
||||
class PoolObjectSQL : public ObjectSQL
|
||||
class PoolObjectSQL : public ObjectSQL, public ObjectXML
|
||||
{
|
||||
public:
|
||||
|
||||
PoolObjectSQL(int id=-1):oid(id),valid(true)
|
||||
PoolObjectSQL(int id, const string& _name, int _uid,const char *_table)
|
||||
:ObjectSQL(),ObjectXML(),oid(id),name(_name),uid(_uid),
|
||||
valid(true),table(_table)
|
||||
{
|
||||
pthread_mutex_init(&mutex,0);
|
||||
};
|
||||
@ -47,11 +51,25 @@ public:
|
||||
pthread_mutex_destroy(&mutex);
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
int get_oid() const
|
||||
{
|
||||
return oid;
|
||||
};
|
||||
|
||||
const string& get_name() const
|
||||
{
|
||||
return name;
|
||||
};
|
||||
|
||||
int get_uid()
|
||||
{
|
||||
return uid;
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Check if the object is valid
|
||||
* @return true if object is valid
|
||||
@ -68,7 +86,7 @@ public:
|
||||
void set_valid(const bool _valid)
|
||||
{
|
||||
valid = _valid;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to lock the object
|
||||
@ -86,17 +104,99 @@ public:
|
||||
pthread_mutex_unlock(&mutex);
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to print the object into a string in XML format
|
||||
* @param xml the resulting XML string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
virtual string& to_xml(string& xml) const = 0;
|
||||
|
||||
/**
|
||||
* Rebuilds the object from an xml formatted string
|
||||
* @param xml_str The xml-formatted string
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
virtual int from_xml(const string &xml_str) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* The object unique ID
|
||||
* Callback function to unmarshall a PoolObjectSQL
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int oid;
|
||||
int select_cb(void *nil, int num, char **values, char **names)
|
||||
{
|
||||
if ( (!values[0]) || (num != 1) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return from_xml(values[0]);
|
||||
};
|
||||
|
||||
/**
|
||||
* The contents ob this object are valid
|
||||
* Reads the PoolObjectSQL (identified by its OID) from the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
bool valid;
|
||||
virtual int select(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Reads the PoolObjectSQL (identified by its OID) from the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int select(SqlDB *db, const string& _name, int _uid);
|
||||
|
||||
/**
|
||||
* Drops object from the database
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int drop(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Function to output a pool object into a stream in XML format
|
||||
* @param oss the output stream
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int dump(ostringstream& oss, int num, char **values, char **names)
|
||||
{
|
||||
if ( (!values[0]) || (num != 1) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
oss << values[0];
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* The object's unique ID
|
||||
*/
|
||||
int oid;
|
||||
|
||||
/**
|
||||
* The object's name
|
||||
*/
|
||||
string name;
|
||||
|
||||
/**
|
||||
* Object's owner, set it to -1 if owner is not used
|
||||
*/
|
||||
int uid;
|
||||
|
||||
/**
|
||||
* The contents of this object are valid
|
||||
*/
|
||||
bool valid;
|
||||
|
||||
private:
|
||||
|
||||
@ -110,6 +210,11 @@ private:
|
||||
* IS LOCKED when the class destructor is called.
|
||||
*/
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
/**
|
||||
* Pointer to the SQL table for the PoolObjectSQL
|
||||
*/
|
||||
const char * table;
|
||||
};
|
||||
|
||||
#endif /*POOL_OBJECT_SQL_H_*/
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
* @param _db a pointer to the database
|
||||
* @param table the name of the table supporting the pool (to set the oid
|
||||
* counter). If null the OID counter is not updated.
|
||||
* @param with_uid the Pool objects have an owner id (uid)
|
||||
*/
|
||||
PoolSQL(SqlDB * _db, const char * table);
|
||||
|
||||
@ -68,9 +69,18 @@ public:
|
||||
*
|
||||
* @return a pointer to the object, 0 in case of failure
|
||||
*/
|
||||
virtual PoolObjectSQL * get(
|
||||
int oid,
|
||||
bool lock);
|
||||
PoolObjectSQL * get(int oid, bool lock);
|
||||
|
||||
/**
|
||||
* Gets an object from the pool (if needed the object is loaded from the
|
||||
* database).
|
||||
* @param name of the object
|
||||
* @param uid id of owner
|
||||
* @param lock locks the object if true
|
||||
*
|
||||
* @return a pointer to the object, 0 in case of failure
|
||||
*/
|
||||
PoolObjectSQL * get(const string& name, int uid, bool lock);
|
||||
|
||||
/**
|
||||
* Finds a set objects that satisfies a given condition
|
||||
@ -141,6 +151,27 @@ protected:
|
||||
*/
|
||||
SqlDB * db;
|
||||
|
||||
/**
|
||||
* Dumps the pool in XML format. A filter can be also added to the
|
||||
* query
|
||||
* @param oss the output stream to dump the pool contents
|
||||
* @param elem_name Name of the root xml pool name
|
||||
* @param table Pool table name
|
||||
* @param where filter for the objects, defaults to all
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump(ostringstream& oss, const string& elem_name,
|
||||
const char * table, const string& where);
|
||||
|
||||
/**
|
||||
* Returns the value of the last identifier assigned by the pool
|
||||
*/
|
||||
int get_lastOID()
|
||||
{
|
||||
return lastOID;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
@ -156,7 +187,7 @@ private:
|
||||
* Last object ID assigned to an object. It must be initialized by the
|
||||
* target pool.
|
||||
*/
|
||||
int lastOID;
|
||||
int lastOID;
|
||||
|
||||
/**
|
||||
* The pool is implemented with a Map of SQL object pointers, using the
|
||||
@ -164,6 +195,12 @@ private:
|
||||
*/
|
||||
map<int,PoolObjectSQL *> pool;
|
||||
|
||||
/**
|
||||
* This is a name index for the pool map. The key is the name of the object
|
||||
* , that may be combained with the owner id.
|
||||
*/
|
||||
map<string,PoolObjectSQL *> name_pool;
|
||||
|
||||
/**
|
||||
* Factory method, must return an ObjectSQL pointer to an allocated pool
|
||||
* specific object.
|
||||
@ -200,6 +237,25 @@ private:
|
||||
*/
|
||||
void replace();
|
||||
|
||||
/**
|
||||
* Generate an index key for the object
|
||||
* @param name of the object
|
||||
* @param uid owner of the object, only used if needed
|
||||
*
|
||||
* @return the key, a string
|
||||
*/
|
||||
string key(const string& name, int uid)
|
||||
{
|
||||
ostringstream key;
|
||||
|
||||
key << name << ':' << uid;
|
||||
|
||||
return key.str();
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Callback to set the lastOID (PoolSQL::PoolSQL)
|
||||
*/
|
||||
@ -209,6 +265,15 @@ private:
|
||||
* Callback to store the IDs of pool objects (PoolSQL::search)
|
||||
*/
|
||||
int search_cb(void *_oids, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Callback function to get output in XML format
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_cb(void * _oss, int num, char **values, char **names);
|
||||
};
|
||||
|
||||
#endif /*POOL_SQL_H_*/
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "UserPool.h"
|
||||
#include "VirtualNetworkPool.h"
|
||||
#include "ImagePool.h"
|
||||
#include "ClusterPool.h"
|
||||
|
||||
#include <xmlrpc-c/base.hpp>
|
||||
#include <xmlrpc-c/registry.hpp>
|
||||
@ -44,10 +45,12 @@ public:
|
||||
VirtualNetworkPool * _vnpool,
|
||||
UserPool * _upool,
|
||||
ImagePool * _ipool,
|
||||
ClusterPool * _cpool,
|
||||
int _port,
|
||||
string _xml_log_file)
|
||||
:vmpool(_vmpool),hpool(_hpool),vnpool(_vnpool),upool(_upool),
|
||||
ipool(_ipool),port(_port),socket_fd(-1),xml_log_file(_xml_log_file)
|
||||
ipool(_ipool),cpool(_cpool),port(_port),socket_fd(-1),
|
||||
xml_log_file(_xml_log_file)
|
||||
{
|
||||
am.addListener(this);
|
||||
};
|
||||
@ -126,6 +129,11 @@ private:
|
||||
*/
|
||||
ImagePool * ipool;
|
||||
|
||||
/**
|
||||
* Pointer to the Image Pool, to access images
|
||||
*/
|
||||
ClusterPool * cpool;
|
||||
|
||||
/**
|
||||
* Port number where the connection will be open
|
||||
*/
|
||||
@ -478,7 +486,7 @@ private:
|
||||
vmpool(_vmpool),
|
||||
upool(_upool)
|
||||
{
|
||||
_signature="A:sibi";
|
||||
_signature="A:sii";
|
||||
_help="Returns the virtual machine pool";
|
||||
};
|
||||
|
||||
@ -632,10 +640,10 @@ private:
|
||||
{
|
||||
public:
|
||||
ClusterAllocate(
|
||||
HostPool * _hpool,
|
||||
UserPool * _upool):
|
||||
hpool(_hpool),
|
||||
upool(_upool)
|
||||
UserPool * _upool,
|
||||
ClusterPool * _cpool):
|
||||
upool(_upool),
|
||||
cpool(_cpool)
|
||||
{
|
||||
_signature="A:ss";
|
||||
_help="Allocates a cluster in the pool";
|
||||
@ -648,8 +656,8 @@ private:
|
||||
xmlrpc_c::value * const retvalP);
|
||||
|
||||
private:
|
||||
HostPool * hpool;
|
||||
UserPool * upool;
|
||||
UserPool * upool;
|
||||
ClusterPool * cpool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -658,10 +666,10 @@ private:
|
||||
{
|
||||
public:
|
||||
ClusterInfo(
|
||||
HostPool * _hpool,
|
||||
UserPool * _upool):
|
||||
hpool(_hpool),
|
||||
upool(_upool)
|
||||
UserPool * _upool,
|
||||
ClusterPool * _cpool):
|
||||
upool(_upool),
|
||||
cpool(_cpool)
|
||||
{
|
||||
_signature="A:si";
|
||||
_help="Returns cluster information";
|
||||
@ -674,8 +682,8 @@ private:
|
||||
xmlrpc_c::value * const retvalP);
|
||||
|
||||
private:
|
||||
HostPool * hpool;
|
||||
UserPool * upool;
|
||||
UserPool * upool;
|
||||
ClusterPool * cpool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -684,10 +692,10 @@ private:
|
||||
{
|
||||
public:
|
||||
ClusterDelete(
|
||||
HostPool * _hpool,
|
||||
UserPool * _upool):
|
||||
hpool(_hpool),
|
||||
upool(_upool)
|
||||
UserPool * _upool,
|
||||
ClusterPool * _cpool):
|
||||
upool(_upool),
|
||||
cpool(_cpool)
|
||||
{
|
||||
_signature="A:si";
|
||||
_help="Deletes a cluster from the pool";
|
||||
@ -700,8 +708,8 @@ private:
|
||||
xmlrpc_c::value * const retvalP);
|
||||
|
||||
private:
|
||||
HostPool * hpool;
|
||||
UserPool * upool;
|
||||
UserPool * upool;
|
||||
ClusterPool * cpool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -710,10 +718,12 @@ private:
|
||||
{
|
||||
public:
|
||||
ClusterAdd(
|
||||
HostPool * _hpool,
|
||||
UserPool * _upool):
|
||||
HostPool * _hpool,
|
||||
UserPool * _upool,
|
||||
ClusterPool * _cpool):
|
||||
hpool(_hpool),
|
||||
upool(_upool)
|
||||
upool(_upool),
|
||||
cpool(_cpool)
|
||||
{
|
||||
_signature="A:sii";
|
||||
_help="Adds a host to a cluster";
|
||||
@ -726,8 +736,9 @@ private:
|
||||
xmlrpc_c::value * const retvalP);
|
||||
|
||||
private:
|
||||
HostPool * hpool;
|
||||
UserPool * upool;
|
||||
HostPool * hpool;
|
||||
UserPool * upool;
|
||||
ClusterPool * cpool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -736,10 +747,12 @@ private:
|
||||
{
|
||||
public:
|
||||
ClusterRemove(
|
||||
HostPool * _hpool,
|
||||
UserPool * _upool):
|
||||
HostPool * _hpool,
|
||||
UserPool * _upool,
|
||||
ClusterPool * _cpool):
|
||||
hpool(_hpool),
|
||||
upool(_upool)
|
||||
upool(_upool),
|
||||
cpool(_cpool)
|
||||
{
|
||||
_signature="A:si";
|
||||
_help="Removes a host from its cluster";
|
||||
@ -752,8 +765,9 @@ private:
|
||||
xmlrpc_c::value * const retvalP);
|
||||
|
||||
private:
|
||||
HostPool * hpool;
|
||||
UserPool * upool;
|
||||
HostPool * hpool;
|
||||
UserPool * upool;
|
||||
ClusterPool * cpool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -762,10 +776,10 @@ private:
|
||||
{
|
||||
public:
|
||||
ClusterPoolInfo(
|
||||
HostPool * _hpool,
|
||||
UserPool * _upool):
|
||||
hpool(_hpool),
|
||||
upool(_upool)
|
||||
UserPool * _upool,
|
||||
ClusterPool * _cpool):
|
||||
upool(_upool),
|
||||
cpool(_cpool)
|
||||
{
|
||||
_signature="A:s";
|
||||
_help="Returns the cluster pool information";
|
||||
@ -778,8 +792,8 @@ private:
|
||||
xmlrpc_c::value * const retvalP);
|
||||
|
||||
private:
|
||||
HostPool * hpool;
|
||||
UserPool * upool;
|
||||
UserPool * upool;
|
||||
ClusterPool * cpool;
|
||||
};
|
||||
|
||||
|
||||
@ -1034,6 +1048,27 @@ private:
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
class UserAuthenticate: public xmlrpc_c::method
|
||||
{
|
||||
public:
|
||||
UserAuthenticate(UserPool * _upool):upool(_upool)
|
||||
{
|
||||
_signature="A:s";
|
||||
_help="Authenticates the user.";
|
||||
};
|
||||
|
||||
~UserAuthenticate(){};
|
||||
|
||||
void execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retvalP);
|
||||
|
||||
private:
|
||||
UserPool * upool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
class UserInfo: public xmlrpc_c::method
|
||||
{
|
||||
public:
|
||||
|
@ -176,6 +176,14 @@ public:
|
||||
*/
|
||||
int from_xml(const string &xml_str);
|
||||
|
||||
/**
|
||||
* Rebuilds the object from an xml node
|
||||
* @param node The xml node pointer
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int from_xml_node(const xmlNodePtr node);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* The template attributes
|
||||
@ -215,6 +223,12 @@ private:
|
||||
* Name of the Root element for the XML document
|
||||
*/
|
||||
string xml_root;
|
||||
|
||||
/**
|
||||
* Builds the template attribute from the node
|
||||
* @param root_element The xml element to build the template from.
|
||||
*/
|
||||
void rebuild_attributes(const xmlNode * root_element);
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -36,13 +36,6 @@ public:
|
||||
*/
|
||||
friend ostream& operator<<(ostream& os, User& u);
|
||||
|
||||
/**
|
||||
* Function to print the User object into a string in plain text
|
||||
* @param str the resulting string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_str(string& str) const;
|
||||
|
||||
/**
|
||||
* Function to print the User object into a string in XML format
|
||||
* @param xml the resulting XML string
|
||||
@ -50,15 +43,6 @@ public:
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
/**
|
||||
* Get the User unique identifier UID, that matches the OID of the object
|
||||
* @return UID User identifier
|
||||
*/
|
||||
int get_uid() const
|
||||
{
|
||||
return oid;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the user is enabled
|
||||
* @return true if the user is enabled
|
||||
@ -68,15 +52,6 @@ public:
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns user username
|
||||
* @return username User's hostname
|
||||
*/
|
||||
const string& get_username() const
|
||||
{
|
||||
return username;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns user password
|
||||
* @return username User's hostname
|
||||
@ -102,14 +77,6 @@ public:
|
||||
enabled = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets user username
|
||||
*/
|
||||
void set_username(string _username)
|
||||
{
|
||||
username = _username;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets user password
|
||||
*/
|
||||
@ -145,11 +112,6 @@ private:
|
||||
// User Attributes
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* User's username
|
||||
*/
|
||||
string username;
|
||||
|
||||
/**
|
||||
* User's password
|
||||
*/
|
||||
@ -191,16 +153,24 @@ private:
|
||||
db->exec(oss_user);
|
||||
};
|
||||
|
||||
/**
|
||||
* Rebuilds the object from an xml formatted string
|
||||
* @param xml_str The xml-formatted string
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int from_xml(const string &xml_str);
|
||||
|
||||
protected:
|
||||
|
||||
// *************************************************************************
|
||||
// Constructor
|
||||
// *************************************************************************
|
||||
|
||||
User(int id=-1,
|
||||
string _username="",
|
||||
string _password="",
|
||||
bool _enabled=true);
|
||||
User(int id,
|
||||
string _username,
|
||||
string _password,
|
||||
bool _enabled);
|
||||
|
||||
virtual ~User();
|
||||
|
||||
@ -208,58 +178,28 @@ protected:
|
||||
// DataBase implementation
|
||||
// *************************************************************************
|
||||
|
||||
enum ColNames
|
||||
{
|
||||
OID = 0,
|
||||
USERNAME = 1,
|
||||
PASSWORD = 2,
|
||||
ENABLED = 3, // 0 = false, 1 = true
|
||||
LIMIT = 4
|
||||
};
|
||||
|
||||
static const char * db_names;
|
||||
|
||||
static const char * db_bootstrap;
|
||||
|
||||
static const char * table;
|
||||
|
||||
/**
|
||||
* Reads the User (identified with its OID=UID) from the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int select(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Writes the User in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int insert(SqlDB *db, string& error_str);
|
||||
int insert(SqlDB *db, string& error_str);
|
||||
|
||||
/**
|
||||
* Writes/updates the User data fields in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int update(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Drops USer from the database
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int drop(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Function to output a User object in to an stream in XML format
|
||||
* @param oss the output stream
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int dump(ostringstream& oss, int num, char **values, char **names);
|
||||
int update(SqlDB *db)
|
||||
{
|
||||
return insert_replace(db, true);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*USER_H_*/
|
||||
|
@ -59,17 +59,12 @@ public:
|
||||
* it is loaded from the DB
|
||||
* @param oid User unique id
|
||||
* @param lock locks the User mutex
|
||||
* @return a pointer to the Host, 0 if the User could not be loaded
|
||||
* @return a pointer to the User, 0 if the User could not be loaded
|
||||
*/
|
||||
User * get(
|
||||
int oid,
|
||||
bool lock)
|
||||
User * get(int oid, bool lock)
|
||||
{
|
||||
User * user = static_cast<User *>(PoolSQL::get(oid,lock));
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
return static_cast<User *>(PoolSQL::get(oid,lock));
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to get a User from the pool, if the object is not in memory
|
||||
@ -78,21 +73,10 @@ public:
|
||||
* @param lock locks the User mutex
|
||||
* @return a pointer to the User, 0 if the User could not be loaded
|
||||
*/
|
||||
User * get(
|
||||
string username,
|
||||
bool lock)
|
||||
User * get(string name, bool lock)
|
||||
{
|
||||
map<string, int>::iterator index;
|
||||
|
||||
index = known_users.find(username);
|
||||
|
||||
if ( index != known_users.end() )
|
||||
{
|
||||
return get((int)index->second,lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
return static_cast<User *>(PoolSQL::get(name,-1,lock));
|
||||
};
|
||||
|
||||
/** Update a particular User
|
||||
* @param user pointer to User
|
||||
@ -103,20 +87,12 @@ public:
|
||||
return user->update(db);
|
||||
};
|
||||
|
||||
|
||||
/** Drops a user from the DB, the user mutex MUST BE locked
|
||||
* @param user pointer to User
|
||||
*/
|
||||
int drop(User * user)
|
||||
{
|
||||
int rc = PoolSQL::drop(user);
|
||||
|
||||
if ( rc == 0)
|
||||
{
|
||||
known_users.erase(user->get_username());
|
||||
}
|
||||
|
||||
return rc;
|
||||
return PoolSQL::drop(user);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -149,7 +125,10 @@ public:
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump(ostringstream& oss, const string& where);
|
||||
int dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
return PoolSQL::dump(oss, "USER_POOL", User::table, where);
|
||||
};
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -158,33 +137,8 @@ private:
|
||||
*/
|
||||
PoolObjectSQL * create()
|
||||
{
|
||||
return new User;
|
||||
return new User(-1,"","",true);
|
||||
};
|
||||
|
||||
/**
|
||||
* This map stores the association between UIDs and Usernames
|
||||
*/
|
||||
map<string, int> known_users;
|
||||
|
||||
/**
|
||||
* Callback function to get output the user pool in XML format
|
||||
* (User::dump)
|
||||
* @param _oss pointer to the output stream
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_cb(void * _oss, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Callback function to build the knwon_user map (User::User)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int init_cb(void *nil, int num, char **values, char **names);
|
||||
};
|
||||
|
||||
#endif /*USER_POOL_H_*/
|
||||
|
@ -119,14 +119,6 @@ public:
|
||||
*/
|
||||
friend ostream& operator<<(ostream& os, const VirtualMachine& vm);
|
||||
|
||||
/**
|
||||
* Function to print the VirtualMachine object into a string in
|
||||
* plain text
|
||||
* @param str the resulting string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_str(string& str) const;
|
||||
|
||||
/**
|
||||
* Function to print the VirtualMachine object into a string in
|
||||
* XML format
|
||||
@ -135,6 +127,14 @@ public:
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
/**
|
||||
* Rebuilds the object from an xml formatted string
|
||||
* @param xml_str The xml-formatted string
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int from_xml(const string &xml_str);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Dynamic Info
|
||||
// ------------------------------------------------------------------------
|
||||
@ -183,16 +183,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the VM
|
||||
* @return the VM name
|
||||
*/
|
||||
const string& get_name() const
|
||||
{
|
||||
return name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the deployment ID
|
||||
* @return the VMM driver specific ID
|
||||
@ -218,11 +208,11 @@ public:
|
||||
* Adds a new history record an writes it in the database.
|
||||
*/
|
||||
void add_history(
|
||||
int hid,
|
||||
string& hostname,
|
||||
string& vm_dir,
|
||||
string& vmm_mad,
|
||||
string& tm_mad);
|
||||
int hid,
|
||||
const string& hostname,
|
||||
const string& vm_dir,
|
||||
const string& vmm_mad,
|
||||
const string& tm_mad);
|
||||
|
||||
/**
|
||||
* Duplicates the last history record. Only the host related fields are
|
||||
@ -678,16 +668,6 @@ public:
|
||||
lcm_state = s;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the user id of the owner of this VM
|
||||
* @return the VM uid
|
||||
*/
|
||||
int get_uid() const
|
||||
{
|
||||
return uid;
|
||||
};
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Timers
|
||||
// ------------------------------------------------------------------------
|
||||
@ -733,6 +713,7 @@ public:
|
||||
|
||||
/**
|
||||
* Get all disk images for this Virtual Machine
|
||||
* @param error_str Returns the error reason, if any
|
||||
* @return 0 if success
|
||||
*/
|
||||
int get_disk_images(string &error_str);
|
||||
@ -753,7 +734,6 @@ public:
|
||||
*/
|
||||
int generate_context(string &files);
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Image repository related functions
|
||||
// ------------------------------------------------------------------------
|
||||
@ -779,11 +759,10 @@ private:
|
||||
// -------------------------------------------------------------------------
|
||||
// Identification variables
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* User (owner) id
|
||||
* Owner's name
|
||||
*/
|
||||
int uid;
|
||||
string user_name;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// VM Scheduling & Managing Information
|
||||
@ -797,11 +776,6 @@ private:
|
||||
// Virtual Machine Description
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Name of the VM
|
||||
*/
|
||||
string name;
|
||||
|
||||
/**
|
||||
* The Virtual Machine template, holds the VM attributes.
|
||||
*/
|
||||
@ -854,11 +828,6 @@ private:
|
||||
*/
|
||||
int net_rx;
|
||||
|
||||
/**
|
||||
* Sequence number of the last history item.
|
||||
*/
|
||||
int last_seq;
|
||||
|
||||
/**
|
||||
* History record, for the current host
|
||||
*/
|
||||
@ -958,16 +927,18 @@ private:
|
||||
/**
|
||||
* Parse the "CONTEXT" attribute of the template by substituting
|
||||
* $VARIABLE, $VARIABLE[ATTR] and $VARIABLE[ATTR, ATTR = VALUE]
|
||||
* @param error_str Returns the error reason, if any
|
||||
* @return 0 on success
|
||||
*/
|
||||
int parse_context();
|
||||
int parse_context(string& error_str);
|
||||
|
||||
/**
|
||||
* Parse the "REQUIREMENTS" attribute of the template by substituting
|
||||
* $VARIABLE, $VARIABLE[ATTR] and $VARIABLE[ATTR, ATTR = VALUE]
|
||||
* @param error_str Returns the error reason, if any
|
||||
* @return 0 on success
|
||||
*/
|
||||
int parse_requirements();
|
||||
int parse_requirements(string& error_str);
|
||||
|
||||
/**
|
||||
* Parse the "GRAPHICS" attribute and generates a default PORT if not
|
||||
@ -981,7 +952,8 @@ protected:
|
||||
// Constructor
|
||||
//**************************************************************************
|
||||
|
||||
VirtualMachine(int id=-1, VirtualMachineTemplate * _vm_template = 0);
|
||||
VirtualMachine(int id, int uid, string _user_name,
|
||||
VirtualMachineTemplate * _vm_template);
|
||||
|
||||
virtual ~VirtualMachine();
|
||||
|
||||
@ -989,32 +961,10 @@ protected:
|
||||
// DataBase implementation
|
||||
// *************************************************************************
|
||||
|
||||
enum ColNames
|
||||
{
|
||||
OID = 0,
|
||||
UID = 1,
|
||||
NAME = 2,
|
||||
LAST_POLL = 3,
|
||||
STATE = 4,
|
||||
LCM_STATE = 5,
|
||||
STIME = 6,
|
||||
ETIME = 7,
|
||||
DEPLOY_ID = 8,
|
||||
MEMORY = 9,
|
||||
CPU = 10,
|
||||
NET_TX = 11,
|
||||
NET_RX = 12,
|
||||
LAST_SEQ = 13,
|
||||
TEMPLATE = 14,
|
||||
LIMIT = 15
|
||||
};
|
||||
|
||||
static const char * table;
|
||||
|
||||
static const char * db_names;
|
||||
|
||||
static const char * extended_db_names;
|
||||
|
||||
static const char * db_bootstrap;
|
||||
|
||||
/**
|
||||
@ -1029,48 +979,28 @@ protected:
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int insert(SqlDB * db, string& error_str);
|
||||
int insert(SqlDB * db, string& error_str);
|
||||
|
||||
/**
|
||||
* Writes/updates the Virtual Machine data fields in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int update(SqlDB * db);
|
||||
int update(SqlDB * db)
|
||||
{
|
||||
return insert_replace(db, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a VM from the database and all its associated information
|
||||
* @param db pointer to the db
|
||||
* @return -1
|
||||
*/
|
||||
virtual int drop(SqlDB * db)
|
||||
int drop(SqlDB * db)
|
||||
{
|
||||
NebulaLog::log("ONE",Log::ERROR, "VM Drop not implemented!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the contect of a set of VirtualMachine objects in the given stream
|
||||
* using XML format
|
||||
* @param oss the output stream
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int dump(ostringstream& oss, int num, char ** values, char ** names);
|
||||
|
||||
/**
|
||||
* Dumps the contect of a set of VirtualMachine objects in the given stream
|
||||
* using XML format
|
||||
* @param oss the output stream
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int dump_extended( ostringstream& oss,
|
||||
int num, char ** values, char ** names);
|
||||
};
|
||||
|
||||
#endif /*VIRTUAL_MACHINE_H_*/
|
||||
|
@ -48,11 +48,12 @@ public:
|
||||
* the template
|
||||
*/
|
||||
int allocate (
|
||||
int uid,
|
||||
VirtualMachineTemplate *vm_template,
|
||||
int * oid,
|
||||
string& error_str,
|
||||
bool on_hold = false);
|
||||
int uid,
|
||||
string user_name,
|
||||
VirtualMachineTemplate * vm_template,
|
||||
int * oid,
|
||||
string& error_str,
|
||||
bool on_hold = false);
|
||||
|
||||
/**
|
||||
* Function to get a VM from the pool, if the object is not in memory
|
||||
@ -134,7 +135,7 @@ public:
|
||||
*/
|
||||
int dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
return dump(oss, true, -1, where);
|
||||
return dump(oss, -1, where);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,7 +150,7 @@ public:
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump(ostringstream& oss, bool extended, int state, const string& where);
|
||||
int dump(ostringstream& oss, int state, const string& where);
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -158,29 +159,8 @@ private:
|
||||
*/
|
||||
PoolObjectSQL * create()
|
||||
{
|
||||
return new VirtualMachine;
|
||||
return new VirtualMachine(-1,-1,"", 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback function to get output the vm pool in XML format
|
||||
* (VirtualMachinePool::dump)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_cb(void * _oss, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Callback function to get output the vm pool in XML format
|
||||
* (VirtualMachinePool::dump)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_extended_cb(void * _oss, int num, char **values, char **names);
|
||||
|
||||
};
|
||||
|
||||
#endif /*VIRTUAL_MACHINE_POOL_H_*/
|
||||
|
@ -58,24 +58,6 @@ public:
|
||||
// Virtual Network Public Methods
|
||||
// *************************************************************************
|
||||
|
||||
/**
|
||||
* Get the Vnet unique identifier VNID, that matches the OID of the object
|
||||
* @return VNID Image identifier
|
||||
*/
|
||||
int get_vnid() const
|
||||
{
|
||||
return oid;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the uid of the owner of the Virtual Network
|
||||
* @return uid
|
||||
**/
|
||||
int get_uid()
|
||||
{
|
||||
return uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the Virtual Network is public
|
||||
* @return true if the Virtual Network is public
|
||||
@ -175,14 +157,6 @@ public:
|
||||
*/
|
||||
friend ostream& operator<<(ostream& os, VirtualNetwork& vn);
|
||||
|
||||
/**
|
||||
* Function to print the VirtualNetwork object into a string in
|
||||
* plain text
|
||||
* @param str the resulting string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_str(string& str) const;
|
||||
|
||||
/**
|
||||
* Function to print the VirtualNetwork object into a string in
|
||||
* XML format
|
||||
@ -274,14 +248,9 @@ private:
|
||||
// Identification variables
|
||||
// -------------------------------------------------------------------------
|
||||
/**
|
||||
* Name of the Virtual Network
|
||||
* Owner's name
|
||||
*/
|
||||
string name;
|
||||
|
||||
/**
|
||||
* Owner of the Virtual Network
|
||||
*/
|
||||
int uid;
|
||||
string user_name;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Binded physical attributes
|
||||
@ -341,28 +310,29 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback function to unmarshall a VNW object (VirtualNetwork::select)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
* Function to print the VirtualNetwork object into a string in
|
||||
* XML format
|
||||
* @param xml the resulting XML string
|
||||
* @param extended If true, leases are included
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
int select_cb(void * nil, int num, char **values, char **names);
|
||||
string& to_xml_extended(string& xml, bool extended) const;
|
||||
|
||||
/**
|
||||
* Function to drop VN entry in vn_pool
|
||||
* @return 0 on success
|
||||
* Rebuilds the object from an xml formatted string
|
||||
* @param xml_str The xml-formatted string
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int vn_drop(SqlDB * db);
|
||||
|
||||
|
||||
protected:
|
||||
int from_xml(const string &xml_str);
|
||||
|
||||
//**************************************************************************
|
||||
// Constructor
|
||||
//**************************************************************************
|
||||
|
||||
VirtualNetwork(VirtualNetworkTemplate * _vn_template = 0);
|
||||
VirtualNetwork(int uid,
|
||||
string _user_name,
|
||||
VirtualNetworkTemplate * _vn_template = 0);
|
||||
|
||||
~VirtualNetwork();
|
||||
|
||||
@ -370,24 +340,10 @@ protected:
|
||||
// DataBase implementation
|
||||
// *************************************************************************
|
||||
|
||||
enum ColNames
|
||||
{
|
||||
OID = 0,
|
||||
UID = 1,
|
||||
NAME = 2,
|
||||
TYPE = 3,
|
||||
BRIDGE = 4,
|
||||
PUBLIC = 5,
|
||||
TEMPLATE = 6,
|
||||
LIMIT = 7
|
||||
};
|
||||
|
||||
static const char * table;
|
||||
|
||||
static const char * db_names;
|
||||
|
||||
static const char * extended_db_names;
|
||||
|
||||
static const char * db_bootstrap;
|
||||
|
||||
/**
|
||||
@ -397,6 +353,23 @@ protected:
|
||||
*/
|
||||
int select(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Reads the Virtual Network (identified with its OID) from the database.
|
||||
* @param db pointer to the db
|
||||
* @param name of the network
|
||||
* @param uid of the owner
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int select(SqlDB * db, const string& name, int uid);
|
||||
|
||||
/**
|
||||
* Reads the Virtual Network leases from the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int select_leases(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Writes the Virtual Network and its associated template and leases in the database.
|
||||
* @param db pointer to the db
|
||||
@ -409,7 +382,10 @@ protected:
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update(SqlDB * db);
|
||||
int update(SqlDB * db)
|
||||
{
|
||||
return insert_replace(db, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a VNW from the database and all its associated information:
|
||||
@ -418,27 +394,7 @@ protected:
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int drop(SqlDB * db)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = leases->drop(db);
|
||||
|
||||
rc += vn_drop(db);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the contect of a VirtualNetwork object in the given stream using
|
||||
* XML format
|
||||
* @param oss the output stream
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int dump(ostringstream& oss, int num, char **values, char **names);
|
||||
int drop(SqlDB * db);
|
||||
};
|
||||
|
||||
#endif /*VIRTUAL_NETWORK_H_*/
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
*/
|
||||
int allocate (
|
||||
int uid,
|
||||
string user_name,
|
||||
VirtualNetworkTemplate * vn_template,
|
||||
int * oid,
|
||||
string& error_str);
|
||||
@ -59,9 +60,7 @@ public:
|
||||
* @param lock locks the VN mutex
|
||||
* @return a pointer to the VN, 0 if the VN could not be loaded
|
||||
*/
|
||||
VirtualNetwork * get(
|
||||
int oid,
|
||||
bool lock)
|
||||
VirtualNetwork * get(int oid, bool lock)
|
||||
{
|
||||
return static_cast<VirtualNetwork *>(PoolSQL::get(oid,lock));
|
||||
};
|
||||
@ -70,12 +69,14 @@ public:
|
||||
* Function to get a VN from the pool using the network name
|
||||
* If the object is not in memory it is loaded from the DB
|
||||
* @param name VN unique name
|
||||
* @param uid of the VN owner
|
||||
* @param lock locks the VN mutex
|
||||
* @return a pointer to the VN, 0 if the VN could not be loaded
|
||||
*/
|
||||
VirtualNetwork * get(
|
||||
const string& name,
|
||||
bool lock);
|
||||
VirtualNetwork * get(const string& name, int uid, bool lock)
|
||||
{
|
||||
return static_cast<VirtualNetwork *>(PoolSQL::get(name,uid,lock));
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Virtual Network DB access functions
|
||||
@ -88,14 +89,14 @@ public:
|
||||
* @param vid of the VM requesting the lease
|
||||
* @return 0 on success, -1 error, -2 not using the pool
|
||||
*/
|
||||
int nic_attribute(VectorAttribute * nic, int vid);
|
||||
int nic_attribute(VectorAttribute * nic, int uid, int vid);
|
||||
|
||||
/**
|
||||
* Generates an Authorization token for a NIC attribute
|
||||
* @param nic the nic to be authorized
|
||||
* @param ar the AuthRequest
|
||||
*/
|
||||
void authorize_nic(VectorAttribute * nic, AuthRequest * ar);
|
||||
void authorize_nic(VectorAttribute * nic, int uid, AuthRequest * ar);
|
||||
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the VirtualNetwork pool
|
||||
@ -113,7 +114,10 @@ public:
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump(ostringstream& oss, const string& where);
|
||||
int dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
return PoolSQL::dump(oss, "VNET_POOL", VirtualNetwork::table,where);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mac prefix
|
||||
@ -150,28 +154,8 @@ private:
|
||||
*/
|
||||
PoolObjectSQL * create()
|
||||
{
|
||||
return new VirtualNetwork();
|
||||
return new VirtualNetwork(0,"",0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback function to get output the virtual network pool in XML format
|
||||
* (VirtualNetworkPool::dump)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_cb(void * _oss, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Callback function to get the ID of a given virtual network
|
||||
* (VirtualNetworkPool::get)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int get_cb(void * _oss, int num, char **values, char **names);
|
||||
};
|
||||
|
||||
#endif /*VIRTUAL_NETWORK_POOL_H_*/
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "VirtualNetworkPool.h"
|
||||
#include "HostPool.h"
|
||||
#include "UserPool.h"
|
||||
#include "ClusterPool.h"
|
||||
|
||||
#include "VirtualMachineManager.h"
|
||||
#include "LifeCycleManager.h"
|
||||
@ -41,7 +42,7 @@ protected:
|
||||
|
||||
NebulaTest():mysql(false), need_host_pool(false), need_vm_pool(false),
|
||||
need_vnet_pool(false), need_image_pool(false),
|
||||
need_user_pool(false), need_vmm(false),
|
||||
need_user_pool(false), need_cluster_pool(false),need_vmm(false),
|
||||
need_im(false), need_tm(false),
|
||||
need_lcm(false), need_dm(false),
|
||||
need_rm(false), need_hm(false),
|
||||
@ -60,6 +61,7 @@ public:
|
||||
bool need_vnet_pool;
|
||||
bool need_image_pool;
|
||||
bool need_user_pool;
|
||||
bool need_cluster_pool;
|
||||
|
||||
bool need_vmm;
|
||||
bool need_im;
|
||||
@ -94,6 +96,8 @@ public:
|
||||
string default_image_type,
|
||||
string default_device_prefix);
|
||||
|
||||
virtual ClusterPool* create_cpool(SqlDB* db);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Managers
|
||||
// ------------------------------------------------------------------------
|
||||
@ -122,6 +126,7 @@ public:
|
||||
VirtualNetworkPool * vnpool,
|
||||
UserPool * upool,
|
||||
ImagePool * ipool,
|
||||
ClusterPool * cpool,
|
||||
string log_file);
|
||||
|
||||
virtual HookManager* create_hm(VirtualMachinePool * vmpool);
|
||||
|
@ -166,14 +166,14 @@ public:
|
||||
{
|
||||
// The pool is empty
|
||||
// Non existing oid
|
||||
obj = pool->get(13, true);
|
||||
obj = pool->get(13, false);
|
||||
CPPUNIT_ASSERT( obj == 0 );
|
||||
|
||||
// Allocate an object
|
||||
allocate(0);
|
||||
|
||||
// Ask again for a non-existing oid
|
||||
obj = pool->get(213, true);
|
||||
obj = pool->get(213, false);
|
||||
CPPUNIT_ASSERT( obj == 0 );
|
||||
}
|
||||
|
||||
|
@ -363,7 +363,7 @@ VM_HOOK = [
|
||||
# on = "ERROR",
|
||||
# command = "host_error.rb",
|
||||
# arguments = "$HID -r n",
|
||||
# remote = no ]
|
||||
# remote = "no" ]
|
||||
#-------------------------------------------------------------------------------
|
||||
# This two hooks can be used to automatically delete or resubmit VMs that reach
|
||||
# the "failed" state. This way, the administrator doesn't have to interact
|
||||
@ -374,14 +374,14 @@ VM_HOOK = [
|
||||
#
|
||||
#VM_HOOK = [
|
||||
# name = "on_failure_delete",
|
||||
# on = "FAILURE",
|
||||
# command = "onevm delete",
|
||||
# on = "FAILED",
|
||||
# command = "/usr/bin/env onevm delete",
|
||||
# arguments = "$VMID" ]
|
||||
#
|
||||
#VM_HOOK = [
|
||||
# name = "on_failure_resubmit",
|
||||
# on = "FAILURE",
|
||||
# command = "onevm resubmit",
|
||||
# on = "FAILED",
|
||||
# command = "/usr/bin/env onevm resubmit",
|
||||
# arguments = "$VMID" ]
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
@ -6,10 +6,11 @@ TWD_DIR="../../src"
|
||||
BASE_DIR=$PWD
|
||||
|
||||
TESTS="$TWD_DIR/vnm/test \
|
||||
$TWD_DIR/scheduler/src/xml/test \
|
||||
$TWD_DIR/xml/test \
|
||||
$TWD_DIR/scheduler/src/pool/test \
|
||||
$TWD_DIR/common/test \
|
||||
$TWD_DIR/host/test \
|
||||
$TWD_DIR/cluster/test \
|
||||
$TWD_DIR/template/test \
|
||||
$TWD_DIR/image/test \
|
||||
$TWD_DIR/authm/test \
|
||||
|
184
src/cluster/Cluster.cc
Normal file
184
src/cluster/Cluster.cc
Normal file
@ -0,0 +1,184 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
||||
/* not use this file except in compliance with the License. You may obtain */
|
||||
/* a copy of the License at */
|
||||
/* */
|
||||
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* */
|
||||
/* Unless required by applicable law or agreed to in writing, software */
|
||||
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
||||
/* See the License for the specific language governing permissions and */
|
||||
/* limitations under the License. */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "Cluster.h"
|
||||
|
||||
|
||||
const char * Cluster::table = "cluster_pool";
|
||||
|
||||
const char * Cluster::db_names = "oid, name, body";
|
||||
|
||||
const char * Cluster::db_bootstrap = "CREATE TABLE IF NOT EXISTS cluster_pool ("
|
||||
"oid INTEGER PRIMARY KEY, name VARCHAR(256), body TEXT, UNIQUE(name))";
|
||||
|
||||
|
||||
/* ************************************************************************ */
|
||||
/* Cluster :: Constructor/Destructor */
|
||||
/* ************************************************************************ */
|
||||
|
||||
Cluster::Cluster(int id, const string& name):PoolObjectSQL(id,name,-1,table){};
|
||||
|
||||
Cluster::~Cluster(){};
|
||||
|
||||
/* ************************************************************************ */
|
||||
/* Cluster :: Database Access Functions */
|
||||
/* ************************************************************************ */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Cluster::insert(SqlDB *db, string& error_str)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = insert_replace(db, false);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
error_str = "Error inserting Cluster in DB.";
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Cluster::update(SqlDB *db)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = insert_replace(db, true);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Cluster::insert_replace(SqlDB *db, bool replace)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
int rc;
|
||||
string xml_body;
|
||||
|
||||
char * sql_name;
|
||||
char * sql_xml;
|
||||
|
||||
// Update the Cluster
|
||||
|
||||
sql_name = db->escape_str(name.c_str());
|
||||
|
||||
if ( sql_name == 0 )
|
||||
{
|
||||
goto error_name;
|
||||
}
|
||||
|
||||
sql_xml = db->escape_str(to_xml(xml_body).c_str());
|
||||
|
||||
if ( sql_xml == 0 )
|
||||
{
|
||||
goto error_body;
|
||||
}
|
||||
|
||||
if(replace)
|
||||
{
|
||||
oss << "REPLACE";
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << "INSERT";
|
||||
}
|
||||
|
||||
// Construct the SQL statement to Insert or Replace
|
||||
|
||||
oss <<" INTO "<<table <<" ("<< db_names <<") VALUES ("
|
||||
<< oid << ","
|
||||
<< "'" << sql_name << "',"
|
||||
<< "'" << sql_xml << "')";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
db->free_str(sql_name);
|
||||
db->free_str(sql_xml);
|
||||
|
||||
return rc;
|
||||
|
||||
error_body:
|
||||
db->free_str(sql_name);
|
||||
error_name:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ************************************************************************ */
|
||||
/* Cluster :: Misc */
|
||||
/* ************************************************************************ */
|
||||
|
||||
ostream& operator<<(ostream& os, Cluster& cluster)
|
||||
{
|
||||
string cluster_str;
|
||||
|
||||
os << cluster.to_xml(cluster_str);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
string& Cluster::to_xml(string& xml) const
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss <<
|
||||
"<CLUSTER>" <<
|
||||
"<ID>" << oid << "</ID>" <<
|
||||
"<NAME>" << name << "</NAME>" <<
|
||||
"</CLUSTER>";
|
||||
|
||||
xml = oss.str();
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Cluster::from_xml(const string& xml)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
// Initialize the internal XML object
|
||||
update_from_str(xml);
|
||||
|
||||
// Get class base attributes
|
||||
rc += xpath(oid, "/CLUSTER/ID", -1);
|
||||
rc += xpath(name,"/CLUSTER/NAME", "not_found");
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
150
src/cluster/ClusterPool.cc
Normal file
150
src/cluster/ClusterPool.cc
Normal file
@ -0,0 +1,150 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
||||
/* not use this file except in compliance with the License. You may obtain */
|
||||
/* a copy of the License at */
|
||||
/* */
|
||||
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* */
|
||||
/* Unless required by applicable law or agreed to in writing, software */
|
||||
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
||||
/* See the License for the specific language governing permissions and */
|
||||
/* limitations under the License. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "ClusterPool.h"
|
||||
#include "Nebula.h"
|
||||
#include "NebulaLog.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
const string ClusterPool::DEFAULT_CLUSTER_NAME = "default";
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
ClusterPool::ClusterPool(SqlDB * db):PoolSQL(db, Cluster::table)
|
||||
{
|
||||
// lastOID is set in PoolSQL::init_cb
|
||||
if (get_lastOID() == -1)
|
||||
{
|
||||
int rc;
|
||||
Cluster * cluster;
|
||||
string error_str;
|
||||
|
||||
// Build a new Cluster object
|
||||
cluster = new Cluster(0, ClusterPool::DEFAULT_CLUSTER_NAME);
|
||||
|
||||
// Insert the Object in the pool
|
||||
rc = PoolSQL::allocate(cluster, error_str);
|
||||
|
||||
if(rc != 0)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "Error trying to create default cluster: " << error_str;
|
||||
NebulaLog::log("CLUSTER",Log::ERROR,oss);
|
||||
|
||||
throw runtime_error(oss.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ClusterPool::allocate(int * oid, string name, string& error_str)
|
||||
{
|
||||
Cluster * cluster;
|
||||
ostringstream oss;
|
||||
|
||||
if ( name.empty() )
|
||||
{
|
||||
goto error_name;
|
||||
}
|
||||
|
||||
// Check for duplicates
|
||||
cluster = get(name, false);
|
||||
|
||||
if( cluster != 0 )
|
||||
{
|
||||
goto error_duplicated;
|
||||
}
|
||||
|
||||
// Build a new Cluster object
|
||||
cluster = new Cluster(-1, name);
|
||||
|
||||
// Insert the Object in the pool
|
||||
*oid = PoolSQL::allocate(cluster, error_str);
|
||||
|
||||
return *oid;
|
||||
|
||||
|
||||
error_name:
|
||||
oss << "NAME cannot be empty.";
|
||||
goto error_common;
|
||||
|
||||
error_duplicated:
|
||||
oss << "NAME is already taken by CLUSTER " << cluster->get_oid() << ".";
|
||||
|
||||
error_common:
|
||||
*oid = -1;
|
||||
error_str = oss.str();
|
||||
|
||||
return *oid;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ClusterPool::drop(Cluster * cluster)
|
||||
{
|
||||
int rc;
|
||||
|
||||
Host* host;
|
||||
vector<int> hids;
|
||||
vector<int>::iterator hid_it;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
HostPool * hpool = nd.get_hpool();
|
||||
|
||||
string cluster_name = cluster->get_name();
|
||||
string where = "cluster = '" + cluster_name + "'";
|
||||
|
||||
// Return error if cluster is 'default'
|
||||
if( cluster->get_oid() == 0 )
|
||||
{
|
||||
NebulaLog::log("CLUSTER",Log::WARNING,
|
||||
"Default cluster cannot be deleted.");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = cluster->drop(db);
|
||||
|
||||
// Move the hosts assigned to the deleted cluster to the default one
|
||||
if( rc == 0 )
|
||||
{
|
||||
hpool->search(hids, where);
|
||||
|
||||
for ( hid_it=hids.begin() ; hid_it < hids.end(); hid_it++ )
|
||||
{
|
||||
host = hpool->get(*hid_it, true);
|
||||
|
||||
if ( host == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
set_default_cluster(host);
|
||||
|
||||
hpool->update(host);
|
||||
|
||||
host->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
30
src/cluster/SConstruct
Normal file
30
src/cluster/SConstruct
Normal file
@ -0,0 +1,30 @@
|
||||
# SConstruct for src/cluster
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2010, 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
Import('env')
|
||||
|
||||
lib_name='nebula_cluster'
|
||||
|
||||
# Sources to generate the library
|
||||
source_files=[
|
||||
'ClusterPool.cc',
|
||||
'Cluster.cc'
|
||||
]
|
||||
|
||||
# Build library
|
||||
env.StaticLibrary(lib_name, source_files)
|
415
src/cluster/test/ClusterPoolTest.cc
Normal file
415
src/cluster/test/ClusterPoolTest.cc
Normal file
@ -0,0 +1,415 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
||||
/* not use this file except in compliance with the License. You may obtain */
|
||||
/* a copy of the License at */
|
||||
/* */
|
||||
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* */
|
||||
/* Unless required by applicable law or agreed to in writing, software */
|
||||
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
||||
/* See the License for the specific language governing permissions and */
|
||||
/* limitations under the License. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ClusterPool.h"
|
||||
#include "PoolTest.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
const string names[] = {"cluster_a", "Second cluster"};
|
||||
|
||||
const string xmls[] =
|
||||
{
|
||||
"<CLUSTER><ID>1</ID><NAME>cluster_a</NAME></CLUSTER>",
|
||||
"<CLUSTER><ID>2</ID><NAME>Second cluster</NAME></CLUSTER>"
|
||||
};
|
||||
|
||||
const string cluster_default =
|
||||
"<CLUSTER><ID>0</ID><NAME>default</NAME></CLUSTER>";
|
||||
|
||||
const string cluster_xml_dump =
|
||||
"<CLUSTER_POOL><CLUSTER><ID>0</ID><NAME>default</NAME></CLUSTER><CLUSTER><ID>1</ID><NAME>cluster_a</NAME></CLUSTER><CLUSTER><ID>3</ID><NAME>cluster_c</NAME></CLUSTER><CLUSTER><ID>4</ID><NAME>cluster_d</NAME></CLUSTER></CLUSTER_POOL>";
|
||||
|
||||
const string host_0_cluster =
|
||||
"<HOST><ID>0</ID><NAME>Host one</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>cluster_a</CLUSTER><HOST_SHARE><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST>";
|
||||
|
||||
const string host_0_default =
|
||||
"<HOST><ID>0</ID><NAME>Host one</NAME><STATE>0</STATE>"
|
||||
"<IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD>"
|
||||
"<LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><HOST_SHARE>"
|
||||
"<DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE>"
|
||||
"<MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU>"
|
||||
"<FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU>"
|
||||
"<USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU>"
|
||||
"<RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST>";
|
||||
|
||||
/* ************************************************************************* */
|
||||
/* ************************************************************************* */
|
||||
|
||||
|
||||
#include "NebulaTest.h"
|
||||
|
||||
class NebulaTestCluster: public NebulaTest
|
||||
{
|
||||
public:
|
||||
NebulaTestCluster():NebulaTest()
|
||||
{
|
||||
NebulaTest::the_tester = this;
|
||||
|
||||
need_host_pool = true;
|
||||
need_cluster_pool= true;
|
||||
}
|
||||
};
|
||||
|
||||
class ClusterPoolTest : public PoolTest
|
||||
{
|
||||
CPPUNIT_TEST_SUITE (ClusterPoolTest);
|
||||
|
||||
// Not all tests from PoolTest can be used. Because
|
||||
// of the initial default cluster added to the DB, the
|
||||
// oid_assignment would fail.
|
||||
CPPUNIT_TEST (get_from_cache);
|
||||
CPPUNIT_TEST (get_from_db);
|
||||
CPPUNIT_TEST (wrong_get);
|
||||
CPPUNIT_TEST (drop_and_get);
|
||||
|
||||
CPPUNIT_TEST (name_pool);
|
||||
|
||||
CPPUNIT_TEST (duplicates);
|
||||
CPPUNIT_TEST (set_cluster);
|
||||
CPPUNIT_TEST (remove_cluster);
|
||||
CPPUNIT_TEST (delete_cluster);
|
||||
CPPUNIT_TEST (dump);
|
||||
|
||||
CPPUNIT_TEST_SUITE_END ();
|
||||
|
||||
protected:
|
||||
|
||||
NebulaTestCluster * tester;
|
||||
HostPool * hpool;
|
||||
ClusterPool * cpool;
|
||||
|
||||
|
||||
|
||||
void bootstrap(SqlDB* db)
|
||||
{
|
||||
// setUp overwritten
|
||||
};
|
||||
|
||||
PoolSQL* create_pool(SqlDB* db)
|
||||
{
|
||||
// setUp overwritten
|
||||
return cpool;
|
||||
};
|
||||
|
||||
int allocate(int index)
|
||||
{
|
||||
int oid;
|
||||
string err;
|
||||
|
||||
return cpool->allocate(&oid, names[index], err);
|
||||
};
|
||||
|
||||
void check(int index, PoolObjectSQL* obj)
|
||||
{
|
||||
Cluster * cluster = static_cast<Cluster *>(obj);
|
||||
|
||||
CPPUNIT_ASSERT( obj != 0 );
|
||||
|
||||
string xml_str = "";
|
||||
string name = cluster->get_name();
|
||||
|
||||
CPPUNIT_ASSERT( name == names[index] );
|
||||
|
||||
// Get the xml
|
||||
cluster->to_xml(xml_str);
|
||||
|
||||
// A little help for debugging
|
||||
/*
|
||||
if( xml_str != xmls[index] )
|
||||
{
|
||||
cout << endl << xml_str << endl << "========"
|
||||
<< endl << xmls[index];
|
||||
}
|
||||
//*/
|
||||
CPPUNIT_ASSERT( xml_str == xmls[index]);
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Allocates a Host.
|
||||
*/
|
||||
void init_hp()
|
||||
{
|
||||
int oid;
|
||||
string err;
|
||||
|
||||
// Allocate a host
|
||||
oid = hpool->allocate(&oid, "Host one","im_mad","vmm_mad", "tm_mad", err);
|
||||
CPPUNIT_ASSERT(oid == 0);
|
||||
|
||||
hpool->clean();
|
||||
};
|
||||
|
||||
public:
|
||||
ClusterPoolTest()
|
||||
{
|
||||
xmlInitParser();
|
||||
};
|
||||
|
||||
~ClusterPoolTest()
|
||||
{
|
||||
xmlCleanupParser();
|
||||
};
|
||||
|
||||
void setUp()
|
||||
{
|
||||
create_db();
|
||||
|
||||
tester = new NebulaTestCluster();
|
||||
|
||||
Nebula& neb = Nebula::instance();
|
||||
neb.start();
|
||||
|
||||
hpool = neb.get_hpool();
|
||||
cpool = neb.get_cpool();
|
||||
|
||||
pool = cpool;
|
||||
};
|
||||
|
||||
void tearDown()
|
||||
{
|
||||
delete_db();
|
||||
|
||||
delete tester;
|
||||
};
|
||||
|
||||
/* ********************************************************************* */
|
||||
/* ********************************************************************* */
|
||||
|
||||
// Test intended to check the PoolSQL name index functionallity
|
||||
void name_pool()
|
||||
{
|
||||
Cluster * cluster;
|
||||
int oid;
|
||||
string err;
|
||||
|
||||
|
||||
// Allocate some clusters
|
||||
cpool->allocate(&oid, "name_1", err);
|
||||
CPPUNIT_ASSERT( oid == 1 );
|
||||
|
||||
cpool->allocate(&oid, "name_2", err);
|
||||
CPPUNIT_ASSERT( oid == 2 );
|
||||
|
||||
cpool->allocate(&oid, "name_3", err);
|
||||
CPPUNIT_ASSERT( oid == 3 );
|
||||
|
||||
// Clean the cache
|
||||
cpool->clean();
|
||||
|
||||
cpool->allocate(&oid, "name_4", err);
|
||||
CPPUNIT_ASSERT( oid == 4 );
|
||||
|
||||
cpool->allocate(&oid, "name_5", err);
|
||||
CPPUNIT_ASSERT( oid == 5 );
|
||||
|
||||
// Cluster names 0-3 should be unknown, and 4-5 cached
|
||||
// Ask for a cached object
|
||||
cluster = cpool->get("name_5", false);
|
||||
CPPUNIT_ASSERT( cluster != 0 );
|
||||
CPPUNIT_ASSERT( cluster->get_oid() == 5 );
|
||||
CPPUNIT_ASSERT( cluster->get_name() == "name_5" );
|
||||
|
||||
// Ask for non-cached object
|
||||
cluster = cpool->get("name_2", false);
|
||||
CPPUNIT_ASSERT( cluster != 0 );
|
||||
CPPUNIT_ASSERT( cluster->get_oid() == 2 );
|
||||
CPPUNIT_ASSERT( cluster->get_name() == "name_2" );
|
||||
|
||||
// Ask for non-existing object
|
||||
cluster = cpool->get("name_X", false);
|
||||
CPPUNIT_ASSERT( cluster == 0 );
|
||||
};
|
||||
|
||||
/* ********************************************************************* */
|
||||
|
||||
void duplicates()
|
||||
{
|
||||
int rc, oid;
|
||||
string err;
|
||||
|
||||
// Allocate a cluster.
|
||||
rc = cpool->allocate(&oid, names[1], err);
|
||||
CPPUNIT_ASSERT( oid == 1 );
|
||||
CPPUNIT_ASSERT( oid == rc );
|
||||
|
||||
// Try to allocate twice the same cluster, should fail
|
||||
rc = cpool->allocate(&oid, names[1], err);
|
||||
CPPUNIT_ASSERT( rc == -1 );
|
||||
CPPUNIT_ASSERT( oid == rc );
|
||||
}
|
||||
|
||||
/* ********************************************************************* */
|
||||
|
||||
void set_cluster()
|
||||
{
|
||||
Host* host;
|
||||
int rc;
|
||||
string xml_str, err;
|
||||
|
||||
init_hp();
|
||||
|
||||
host = hpool->get(0, false);
|
||||
CPPUNIT_ASSERT(host != 0);
|
||||
|
||||
rc = host->set_cluster("cluster_a");
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
hpool->update(host);
|
||||
|
||||
host->to_xml(xml_str);
|
||||
CPPUNIT_ASSERT( xml_str == host_0_cluster);
|
||||
}
|
||||
|
||||
/* ********************************************************************* */
|
||||
|
||||
void remove_cluster()
|
||||
{
|
||||
Host* host;
|
||||
|
||||
int rc;
|
||||
string xml_str;
|
||||
|
||||
init_hp();
|
||||
|
||||
host = hpool->get(0, false);
|
||||
CPPUNIT_ASSERT(host != 0);
|
||||
|
||||
// Set cluster
|
||||
rc = host->set_cluster("cluster_a");
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
hpool->update(host);
|
||||
|
||||
host->to_xml(xml_str);
|
||||
CPPUNIT_ASSERT( xml_str == host_0_cluster);
|
||||
|
||||
// Remove from the cluster
|
||||
rc = cpool->set_default_cluster(host);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
hpool->update(host);
|
||||
|
||||
// The host should have been moved to the default cluster
|
||||
|
||||
host = hpool->get(0, false);
|
||||
CPPUNIT_ASSERT(host != 0);
|
||||
|
||||
host->to_xml(xml_str);
|
||||
CPPUNIT_ASSERT( xml_str == host_0_default);
|
||||
}
|
||||
|
||||
/* ********************************************************************* */
|
||||
|
||||
void delete_cluster()
|
||||
{
|
||||
Host * host;
|
||||
Cluster * cluster;
|
||||
|
||||
int rc, oid;
|
||||
string xml_str;
|
||||
|
||||
init_hp();
|
||||
host = hpool->get(0, false);
|
||||
CPPUNIT_ASSERT(host != 0);
|
||||
|
||||
// Allocate a cluster
|
||||
oid = allocate(0);
|
||||
CPPUNIT_ASSERT(oid == 1);
|
||||
|
||||
cluster = cpool->get(1, false);
|
||||
|
||||
// Set cluster
|
||||
rc = host->set_cluster(cluster->get_name());
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
hpool->update(host);
|
||||
|
||||
host->to_xml(xml_str);
|
||||
CPPUNIT_ASSERT( xml_str == host_0_cluster);
|
||||
|
||||
// Delete the cluster
|
||||
rc = cpool->drop(cluster);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
// The host should have been moved to the default cluster
|
||||
host = hpool->get(0, false);
|
||||
host->to_xml(xml_str);
|
||||
/*
|
||||
if( xml_str != host_0_default )
|
||||
{
|
||||
cout << endl << xml_str << endl << "========"
|
||||
<< endl << host_0_default;
|
||||
}
|
||||
//*/
|
||||
CPPUNIT_ASSERT( xml_str == host_0_default);
|
||||
}
|
||||
|
||||
/* ********************************************************************* */
|
||||
|
||||
void dump()
|
||||
{
|
||||
Cluster * cluster;
|
||||
int oid, rc;
|
||||
ostringstream oss;
|
||||
string err;
|
||||
|
||||
// Allocate some clusters
|
||||
rc = cpool->allocate(&oid, "cluster_a", err);
|
||||
CPPUNIT_ASSERT( rc == 1 );
|
||||
|
||||
rc = cpool->allocate(&oid, "cluster_b", err);
|
||||
CPPUNIT_ASSERT( rc == 2 );
|
||||
|
||||
rc = cpool->allocate(&oid, "cluster_c", err);
|
||||
CPPUNIT_ASSERT( rc == 3 );
|
||||
|
||||
rc = cpool->allocate(&oid, "cluster_d", err);
|
||||
CPPUNIT_ASSERT( rc == 4 );
|
||||
|
||||
// Drop one of them
|
||||
cluster = cpool->get(2, false);
|
||||
CPPUNIT_ASSERT( cluster != 0 );
|
||||
|
||||
rc = cpool->drop(cluster);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
// dump the pool
|
||||
rc = cpool->dump(oss,"");
|
||||
/*
|
||||
if( oss.str() != cluster_xml_dump )
|
||||
{
|
||||
cout << endl << oss.str() << endl << "========"
|
||||
<< endl << cluster_xml_dump;
|
||||
}
|
||||
//*/
|
||||
CPPUNIT_ASSERT( oss.str() == cluster_xml_dump );
|
||||
}
|
||||
};
|
||||
|
||||
/* ************************************************************************* */
|
||||
/* ************************************************************************* */
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
return PoolTest::main(argc, argv, ClusterPoolTest::suite());
|
||||
}
|
56
src/cluster/test/SConstruct
Normal file
56
src/cluster/test/SConstruct
Normal file
@ -0,0 +1,56 @@
|
||||
# --------------------------------------------------------------------------
|
||||
# Copyright 2002-2010, 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.
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
Import('env')
|
||||
|
||||
env.Prepend(LIBS=[
|
||||
'nebula_cluster',
|
||||
'nebula_host',
|
||||
'nebula_pool',
|
||||
'nebula_template',
|
||||
'nebula_xml',
|
||||
'nebula_log',
|
||||
'nebula_common',
|
||||
'nebula_sql',
|
||||
|
||||
|
||||
### TODO: delete not needed
|
||||
'nebula_core_test',
|
||||
'nebula_host',
|
||||
'nebula_cluster',
|
||||
'nebula_xml',
|
||||
'nebula_vmm',
|
||||
'nebula_im',
|
||||
'nebula_rm',
|
||||
'nebula_tm',
|
||||
'nebula_um',
|
||||
'nebula_mad',
|
||||
'nebula_template',
|
||||
'nebula_vm',
|
||||
'nebula_vnm',
|
||||
'nebula_image',
|
||||
'nebula_pool',
|
||||
'nebula_hm',
|
||||
'nebula_authm',
|
||||
'nebula_common',
|
||||
'nebula_lcm',
|
||||
'nebula_dm',
|
||||
'nebula_sql',
|
||||
'nebula_log',
|
||||
'crypto'
|
||||
])
|
||||
|
||||
env.Program('test','ClusterPoolTest.cc')
|
@ -1,185 +0,0 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
||||
/* not use this file except in compliance with the License. You may obtain */
|
||||
/* a copy of the License at */
|
||||
/* */
|
||||
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* */
|
||||
/* Unless required by applicable law or agreed to in writing, software */
|
||||
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
||||
/* See the License for the specific language governing permissions and */
|
||||
/* limitations under the License. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "ClusterPool.h"
|
||||
#include "NebulaLog.h"
|
||||
|
||||
const char * ClusterPool::table = "cluster_pool";
|
||||
|
||||
const char * ClusterPool::db_names = "oid, cluster_name";
|
||||
|
||||
const char * ClusterPool::db_bootstrap =
|
||||
"CREATE TABLE IF NOT EXISTS cluster_pool ("
|
||||
"oid INTEGER PRIMARY KEY, cluster_name VARCHAR(128), "
|
||||
"UNIQUE(cluster_name) )";
|
||||
|
||||
const string ClusterPool::DEFAULT_CLUSTER_NAME = "default";
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ClusterPool::allocate(int * clid, string name, SqlDB *db, string& error_str)
|
||||
{
|
||||
int rc;
|
||||
map<int, string>::iterator it;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
// Return error if name already exists
|
||||
for(it=cluster_names.begin();it!=cluster_names.end();it++)
|
||||
{
|
||||
if(it->second == name)
|
||||
{
|
||||
goto error_existing_name;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the highest key, and add 1
|
||||
*clid = cluster_names.rbegin()->first + 1;
|
||||
|
||||
rc = insert(*clid, name, db);
|
||||
|
||||
if(rc != 0)
|
||||
{
|
||||
goto error_db;
|
||||
}
|
||||
|
||||
return *clid;
|
||||
|
||||
|
||||
error_existing_name:
|
||||
oss << "Could not allocate new cluster: "
|
||||
<< name << ", already exists.";
|
||||
|
||||
goto error_common;
|
||||
error_db:
|
||||
oss << "Could not allocate new cluster " << name << ".";
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
error_str = oss.str();
|
||||
NebulaLog::log("CLUSTER", Log::ERROR, oss);
|
||||
|
||||
*clid = -1;
|
||||
return *clid;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
string ClusterPool::info(int clid)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
map<int, string>::iterator it;
|
||||
|
||||
it = cluster_names.find(clid);
|
||||
|
||||
if(it != cluster_names.end())
|
||||
{
|
||||
dump_cluster(oss, it->first, it->second);
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ClusterPool::drop(int clid, SqlDB *db)
|
||||
{
|
||||
int rc;
|
||||
ostringstream oss;
|
||||
|
||||
// Return error if cluster is 'default' or if it doesn't exist
|
||||
if( clid == 0 || cluster_names.count(clid) == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
oss << "DELETE FROM " << table << " WHERE oid=" << clid;
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
if(rc == 0)
|
||||
{
|
||||
cluster_names.erase(clid);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ClusterPool::dump(ostringstream& oss)
|
||||
{
|
||||
map<int, string>::iterator it;
|
||||
|
||||
|
||||
oss << "<CLUSTER_POOL>";
|
||||
|
||||
for(it=cluster_names.begin();it!=cluster_names.end();it++)
|
||||
{
|
||||
dump_cluster(oss, it->first, it->second);
|
||||
}
|
||||
|
||||
oss << "</CLUSTER_POOL>";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ClusterPool::insert(int oid, string name, SqlDB *db)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
int rc;
|
||||
|
||||
char * sql_name;
|
||||
|
||||
sql_name = db->escape_str(name.c_str());
|
||||
|
||||
if ( sql_name == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
oss << "INSERT INTO "<< table <<" ("<< db_names <<") VALUES ("
|
||||
<< oid << ","
|
||||
<< "'" << sql_name << "')";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
db->free_str(sql_name);
|
||||
|
||||
if( rc == 0 )
|
||||
{
|
||||
cluster_names.insert( make_pair(oid, name) );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void ClusterPool::dump_cluster(ostringstream& oss, int id, string name)
|
||||
{
|
||||
oss <<
|
||||
"<CLUSTER>" <<
|
||||
"<ID>" << id << "</ID>" <<
|
||||
"<NAME>" << name << "</NAME>" <<
|
||||
"</CLUSTER>";
|
||||
}
|
323
src/host/Host.cc
323
src/host/Host.cc
@ -29,18 +29,18 @@
|
||||
|
||||
Host::Host(
|
||||
int id,
|
||||
string _hostname,
|
||||
string _im_mad_name,
|
||||
string _vmm_mad_name,
|
||||
string _tm_mad_name):
|
||||
PoolObjectSQL(id),
|
||||
hostname(_hostname),
|
||||
const string& _hostname,
|
||||
const string& _im_mad_name,
|
||||
const string& _vmm_mad_name,
|
||||
const string& _tm_mad_name,
|
||||
const string& _cluster):
|
||||
PoolObjectSQL(id,_hostname,-1,table),
|
||||
state(INIT),
|
||||
im_mad_name(_im_mad_name),
|
||||
vmm_mad_name(_vmm_mad_name),
|
||||
tm_mad_name(_tm_mad_name),
|
||||
last_monitored(0),
|
||||
cluster(ClusterPool::DEFAULT_CLUSTER_NAME),
|
||||
cluster(_cluster),
|
||||
host_template()
|
||||
{}
|
||||
|
||||
@ -52,92 +52,11 @@ Host::~Host(){}
|
||||
|
||||
const char * Host::table = "host_pool";
|
||||
|
||||
const char * Host::db_names = "oid,host_name,state,im_mad,vm_mad,"
|
||||
"tm_mad,last_mon_time, cluster, template";
|
||||
const char * Host::db_names = "oid, name, body, state, last_mon_time, cluster";
|
||||
|
||||
const char * Host::db_bootstrap = "CREATE TABLE IF NOT EXISTS host_pool ("
|
||||
"oid INTEGER PRIMARY KEY,host_name VARCHAR(256), state INTEGER,"
|
||||
"im_mad VARCHAR(128),vm_mad VARCHAR(128),tm_mad VARCHAR(128),"
|
||||
"last_mon_time INTEGER, cluster VARCHAR(128), template TEXT, "
|
||||
"UNIQUE(host_name))";
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Host::select_cb(void * nil, int num, char **values, char ** names)
|
||||
{
|
||||
if ((!values[OID]) ||
|
||||
(!values[HOST_NAME]) ||
|
||||
(!values[STATE]) ||
|
||||
(!values[IM_MAD]) ||
|
||||
(!values[VM_MAD]) ||
|
||||
(!values[TM_MAD]) ||
|
||||
(!values[LAST_MON_TIME]) ||
|
||||
(!values[CLUSTER]) ||
|
||||
(!values[TEMPLATE]) ||
|
||||
(num != LIMIT ))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
oid = atoi(values[OID]);
|
||||
hostname = values[HOST_NAME];
|
||||
state = static_cast<HostState>(atoi(values[STATE]));
|
||||
|
||||
im_mad_name = values[IM_MAD];
|
||||
vmm_mad_name = values[VM_MAD];
|
||||
tm_mad_name = values[TM_MAD];
|
||||
|
||||
last_monitored = static_cast<time_t>(atoi(values[LAST_MON_TIME]));
|
||||
|
||||
cluster = values[CLUSTER];
|
||||
|
||||
host_template.from_xml(values[TEMPLATE]);
|
||||
|
||||
host_share.hsid = oid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Host::select(SqlDB *db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
int boid;
|
||||
|
||||
set_callback(static_cast<Callbackable::Callback>(&Host::select_cb));
|
||||
|
||||
oss << "SELECT " << db_names << " FROM " << table << " WHERE oid = " << oid;
|
||||
|
||||
boid = oid;
|
||||
oid = -1;
|
||||
|
||||
rc = db->exec(oss, this);
|
||||
|
||||
unset_callback();
|
||||
|
||||
if ((rc != 0) || (oid != boid ))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Select the host shares from the DB
|
||||
rc = host_share.select(db);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
"oid INTEGER PRIMARY KEY, name VARCHAR(256), body TEXT, state INTEGER, "
|
||||
"last_mon_time INTEGER, cluster VARCHAR(128), UNIQUE(name))";
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@ -145,34 +64,15 @@ int Host::select(SqlDB *db)
|
||||
int Host::insert(SqlDB *db, string& error_str)
|
||||
{
|
||||
int rc;
|
||||
map<int,HostShare *>::iterator iter;
|
||||
|
||||
// Set up the share ID, to insert it
|
||||
if ( host_share.hsid == -1 )
|
||||
{
|
||||
host_share.hsid = oid;
|
||||
}
|
||||
|
||||
// Update the HostShare
|
||||
rc = host_share.insert(db, error_str);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
//Insert the Host
|
||||
rc = insert_replace(db, false);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
error_str = "Error inserting Host in DB.";
|
||||
host_share.drop(db);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@ -182,24 +82,9 @@ int Host::update(SqlDB *db)
|
||||
{
|
||||
int rc;
|
||||
|
||||
// Update the HostShare
|
||||
rc = host_share.update(db);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = insert_replace(db, true);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@ -210,45 +95,21 @@ int Host::insert_replace(SqlDB *db, bool replace)
|
||||
ostringstream oss;
|
||||
|
||||
int rc;
|
||||
string xml_template;
|
||||
string xml_body;
|
||||
|
||||
char * sql_hostname;
|
||||
char * sql_im_mad_name;
|
||||
char * sql_tm_mad_name;
|
||||
char * sql_vmm_mad_name;
|
||||
char * sql_cluster;
|
||||
char * sql_template;
|
||||
char * sql_xml;
|
||||
|
||||
// Update the Host
|
||||
|
||||
sql_hostname = db->escape_str(hostname.c_str());
|
||||
sql_hostname = db->escape_str(name.c_str());
|
||||
|
||||
if ( sql_hostname == 0 )
|
||||
{
|
||||
goto error_hostname;
|
||||
}
|
||||
|
||||
sql_im_mad_name = db->escape_str(im_mad_name.c_str());
|
||||
|
||||
if ( sql_im_mad_name == 0 )
|
||||
{
|
||||
goto error_im;
|
||||
}
|
||||
|
||||
sql_tm_mad_name = db->escape_str(tm_mad_name.c_str());
|
||||
|
||||
if ( sql_tm_mad_name == 0 )
|
||||
{
|
||||
goto error_tm;
|
||||
}
|
||||
|
||||
sql_vmm_mad_name = db->escape_str(vmm_mad_name.c_str());
|
||||
|
||||
if ( sql_vmm_mad_name == 0 )
|
||||
{
|
||||
goto error_vmm;
|
||||
}
|
||||
|
||||
sql_cluster = db->escape_str(cluster.c_str());
|
||||
|
||||
if ( sql_cluster == 0 )
|
||||
@ -256,12 +117,11 @@ int Host::insert_replace(SqlDB *db, bool replace)
|
||||
goto error_cluster;
|
||||
}
|
||||
|
||||
host_template.to_xml(xml_template);
|
||||
sql_template = db->escape_str(xml_template.c_str());
|
||||
sql_xml = db->escape_str(to_xml(xml_body).c_str());
|
||||
|
||||
if ( sql_template == 0 )
|
||||
if ( sql_xml == 0 )
|
||||
{
|
||||
goto error_template;
|
||||
goto error_body;
|
||||
}
|
||||
|
||||
if(replace)
|
||||
@ -275,37 +135,25 @@ int Host::insert_replace(SqlDB *db, bool replace)
|
||||
|
||||
// Construct the SQL statement to Insert or Replace
|
||||
|
||||
oss <<" INTO "<< table <<" ("<< db_names <<") VALUES ("
|
||||
oss <<" INTO "<<table <<" ("<< db_names <<") VALUES ("
|
||||
<< oid << ","
|
||||
<< "'" << sql_hostname << "',"
|
||||
<< "'" << sql_xml << "',"
|
||||
<< state << ","
|
||||
<< "'" << sql_im_mad_name << "',"
|
||||
<< "'" << sql_vmm_mad_name << "',"
|
||||
<< "'" << sql_tm_mad_name << "',"
|
||||
<< last_monitored << ","
|
||||
<< "'" << sql_cluster << "',"
|
||||
<< "'" << sql_template << "')";
|
||||
<< "'" << sql_cluster << "')";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
db->free_str(sql_hostname);
|
||||
db->free_str(sql_im_mad_name);
|
||||
db->free_str(sql_tm_mad_name);
|
||||
db->free_str(sql_vmm_mad_name);
|
||||
db->free_str(sql_cluster);
|
||||
db->free_str(sql_template);
|
||||
db->free_str(sql_xml);
|
||||
|
||||
return rc;
|
||||
|
||||
error_template:
|
||||
error_body:
|
||||
db->free_str(sql_cluster);
|
||||
error_cluster:
|
||||
db->free_str(sql_vmm_mad_name);
|
||||
error_vmm:
|
||||
db->free_str(sql_tm_mad_name);
|
||||
error_tm:
|
||||
db->free_str(sql_im_mad_name);
|
||||
error_im:
|
||||
db->free_str(sql_hostname);
|
||||
error_hostname:
|
||||
return -1;
|
||||
@ -314,66 +162,6 @@ error_hostname:
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Host::dump(ostringstream& oss, int num, char **values, char **names)
|
||||
{
|
||||
if ((!values[OID]) ||
|
||||
(!values[HOST_NAME]) ||
|
||||
(!values[STATE]) ||
|
||||
(!values[IM_MAD]) ||
|
||||
(!values[VM_MAD]) ||
|
||||
(!values[TM_MAD]) ||
|
||||
(!values[LAST_MON_TIME]) ||
|
||||
(!values[CLUSTER]) ||
|
||||
(!values[TEMPLATE]) ||
|
||||
(num != LIMIT + HostShare::LIMIT ))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
oss <<
|
||||
"<HOST>" <<
|
||||
"<ID>" << values[OID] <<"</ID>" <<
|
||||
"<NAME>" << values[HOST_NAME] <<"</NAME>" <<
|
||||
"<STATE>" << values[STATE] <<"</STATE>" <<
|
||||
"<IM_MAD>" << values[IM_MAD] <<"</IM_MAD>" <<
|
||||
"<VM_MAD>" << values[VM_MAD] <<"</VM_MAD>" <<
|
||||
"<TM_MAD>" << values[TM_MAD] <<"</TM_MAD>" <<
|
||||
"<LAST_MON_TIME>"<< values[LAST_MON_TIME]<<"</LAST_MON_TIME>"<<
|
||||
"<CLUSTER>" << values[CLUSTER] <<"</CLUSTER>" <<
|
||||
values[TEMPLATE];
|
||||
|
||||
HostShare::dump(oss,num - LIMIT, values + LIMIT, names + LIMIT);
|
||||
|
||||
oss << "</HOST>";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Host::drop(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
host_share.drop(db);
|
||||
|
||||
oss << "DELETE FROM " << table << " WHERE oid=" << oid;
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
set_valid(false);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Host::update_info(string &parse_str)
|
||||
{
|
||||
char * error_msg;
|
||||
@ -426,7 +214,7 @@ string& Host::to_xml(string& xml) const
|
||||
oss <<
|
||||
"<HOST>"
|
||||
"<ID>" << oid << "</ID>" <<
|
||||
"<NAME>" << hostname << "</NAME>" <<
|
||||
"<NAME>" << name << "</NAME>" <<
|
||||
"<STATE>" << state << "</STATE>" <<
|
||||
"<IM_MAD>" << im_mad_name << "</IM_MAD>" <<
|
||||
"<VM_MAD>" << vmm_mad_name << "</VM_MAD>" <<
|
||||
@ -445,26 +233,55 @@ string& Host::to_xml(string& xml) const
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
string& Host::to_str(string& str) const
|
||||
int Host::from_xml(const string& xml)
|
||||
{
|
||||
string template_str;
|
||||
string share_str;
|
||||
vector<xmlNodePtr> content;
|
||||
|
||||
int int_state;
|
||||
int rc = 0;
|
||||
|
||||
ostringstream os;
|
||||
// Initialize the internal XML object
|
||||
update_from_str(xml);
|
||||
|
||||
os <<
|
||||
"ID = " << oid << endl <<
|
||||
"NAME = " << hostname << endl <<
|
||||
"STATE = " << state << endl <<
|
||||
"IM MAD = " << im_mad_name << endl <<
|
||||
"VMM MAD = " << vmm_mad_name << endl <<
|
||||
"TM MAD = " << tm_mad_name << endl <<
|
||||
"LAST_MON = " << last_monitored << endl <<
|
||||
"CLUSTER = " << cluster << endl <<
|
||||
"ATTRIBUTES" << endl << host_template.to_str(template_str) << endl <<
|
||||
"HOST SHARES" << endl << host_share.to_str(share_str) <<endl;
|
||||
// Get class base attributes
|
||||
rc += xpath(oid, "/HOST/ID", -1);
|
||||
rc += xpath(name, "/HOST/NAME", "not_found");
|
||||
rc += xpath(int_state, "/HOST/STATE", 0);
|
||||
|
||||
str = os.str();
|
||||
rc += xpath(im_mad_name, "/HOST/IM_MAD", "not_found");
|
||||
rc += xpath(vmm_mad_name, "/HOST/VM_MAD", "not_found");
|
||||
rc += xpath(tm_mad_name, "/HOST/TM_MAD", "not_found");
|
||||
|
||||
return str;
|
||||
rc += xpath(last_monitored, "/HOST/LAST_MON_TIME", 0);
|
||||
rc += xpath(cluster, "/HOST/CLUSTER", "not_found");
|
||||
|
||||
state = static_cast<HostState>( int_state );
|
||||
|
||||
// Get associated classes
|
||||
ObjectXML::get_nodes("/HOST/HOST_SHARE", content);
|
||||
|
||||
if( content.size() < 1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc += host_share.from_xml_node( content[0] );
|
||||
|
||||
content.clear();
|
||||
|
||||
ObjectXML::get_nodes("/HOST/TEMPLATE", content);
|
||||
|
||||
if( content.size() < 1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc += host_template.from_xml_node( content[0] );
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ void HostAllocateHook::do_hook(void *arg)
|
||||
{
|
||||
hmd->execute(host->get_oid(),
|
||||
name,
|
||||
host->get_hostname(),
|
||||
host->get_name(),
|
||||
cmd,
|
||||
parsed_args);
|
||||
}
|
||||
@ -179,7 +179,7 @@ void HostStateHook::do_hook(void *arg)
|
||||
{
|
||||
hmd->execute(host->get_oid(),
|
||||
name,
|
||||
host->get_hostname(),
|
||||
host->get_name(),
|
||||
cmd,
|
||||
parsed_args);
|
||||
}
|
||||
|
@ -22,54 +22,17 @@
|
||||
|
||||
#include "HostPool.h"
|
||||
#include "HostHook.h"
|
||||
#include "ClusterPool.h"
|
||||
#include "NebulaLog.h"
|
||||
#include "ClusterPool.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int HostPool::init_cb(void *nil, int num, char **values, char **names)
|
||||
{
|
||||
if ( num != 2 || values == 0 || values[0] == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
cluster_pool.cluster_names.insert( make_pair(atoi(values[0]), values[1]) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
HostPool::HostPool(SqlDB* db,
|
||||
vector<const Attribute *> hook_mads,
|
||||
const string& hook_location)
|
||||
: PoolSQL(db,Host::table)
|
||||
{
|
||||
// ------------------ Initialize Cluster Array ----------------------
|
||||
|
||||
ostringstream sql;
|
||||
|
||||
set_callback(static_cast<Callbackable::Callback>(&HostPool::init_cb));
|
||||
|
||||
sql << "SELECT " << ClusterPool::db_names << " FROM "
|
||||
<< ClusterPool::table;
|
||||
|
||||
db->exec(sql, this);
|
||||
|
||||
unset_callback();
|
||||
|
||||
if (cluster_pool.cluster_names.empty())
|
||||
{
|
||||
int rc = cluster_pool.insert(0, ClusterPool::DEFAULT_CLUSTER_NAME, db);
|
||||
|
||||
if(rc != 0)
|
||||
{
|
||||
throw runtime_error("Could not create default cluster HostPool");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------ Initialize Hooks fot the pool ----------------------
|
||||
|
||||
const VectorAttribute * vattr;
|
||||
@ -180,6 +143,34 @@ int HostPool::allocate (
|
||||
string& error_str)
|
||||
{
|
||||
Host * host;
|
||||
ostringstream oss;
|
||||
|
||||
if ( hostname.empty() )
|
||||
{
|
||||
goto error_name;
|
||||
}
|
||||
|
||||
if ( im_mad_name.empty() )
|
||||
{
|
||||
goto error_im;
|
||||
}
|
||||
|
||||
if ( vmm_mad_name.empty() )
|
||||
{
|
||||
goto error_vmm;
|
||||
}
|
||||
|
||||
if ( tm_mad_name.empty() )
|
||||
{
|
||||
goto error_tm;
|
||||
}
|
||||
|
||||
host = get(hostname,false);
|
||||
|
||||
if ( host !=0)
|
||||
{
|
||||
goto error_duplicated;
|
||||
}
|
||||
|
||||
// Build a new Host object
|
||||
|
||||
@ -187,13 +178,40 @@ int HostPool::allocate (
|
||||
hostname,
|
||||
im_mad_name,
|
||||
vmm_mad_name,
|
||||
tm_mad_name);
|
||||
tm_mad_name,
|
||||
ClusterPool::DEFAULT_CLUSTER_NAME);
|
||||
|
||||
// Insert the Object in the pool
|
||||
|
||||
*oid = PoolSQL::allocate(host, error_str);
|
||||
|
||||
return *oid;
|
||||
|
||||
|
||||
error_name:
|
||||
oss << "NAME cannot be empty.";
|
||||
goto error_common;
|
||||
|
||||
error_im:
|
||||
oss << "IM_MAD_NAME cannot be empty.";
|
||||
goto error_common;
|
||||
|
||||
error_vmm:
|
||||
oss << "VMM_MAD_NAME cannot be empty.";
|
||||
goto error_common;
|
||||
|
||||
error_tm:
|
||||
oss << "TM_MAD_NAME cannot be empty.";
|
||||
goto error_common;
|
||||
|
||||
error_duplicated:
|
||||
oss << "NAME is already taken by HOST " << host->get_oid() << ".";
|
||||
|
||||
error_common:
|
||||
*oid = -1;
|
||||
error_str = oss.str();
|
||||
|
||||
return *oid;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -202,18 +220,24 @@ int HostPool::allocate (
|
||||
int HostPool::discover_cb(void * _map, int num, char **values, char **names)
|
||||
{
|
||||
map<int, string> * discovered_hosts;
|
||||
string im_mad(values[1]);
|
||||
string im_mad;
|
||||
int hid;
|
||||
int rc;
|
||||
|
||||
discovered_hosts = static_cast<map<int, string> *>(_map);
|
||||
|
||||
if ( (num<=0) || (values[0] == 0) )
|
||||
if ( (num<2) || (values[0] == 0) || (values[1] == 0) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
hid = atoi(values[0]);
|
||||
im_mad = values[1];
|
||||
hid = atoi(values[0]);
|
||||
rc = ObjectXML::xpath_value(im_mad,values[1],"/HOST/IM_MAD");
|
||||
|
||||
if( rc != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
discovered_hosts->insert(make_pair(hid,im_mad));
|
||||
|
||||
@ -230,7 +254,7 @@ int HostPool::discover(map<int, string> * discovered_hosts, int host_limit)
|
||||
set_callback(static_cast<Callbackable::Callback>(&HostPool::discover_cb),
|
||||
static_cast<void *>(discovered_hosts));
|
||||
|
||||
sql << "SELECT oid, im_mad FROM "
|
||||
sql << "SELECT oid, body FROM "
|
||||
<< Host::table << " WHERE state != "
|
||||
<< Host::DISABLED << " ORDER BY last_mon_time ASC LIMIT " << host_limit;
|
||||
|
||||
@ -240,97 +264,3 @@ int HostPool::discover(map<int, string> * discovered_hosts, int host_limit)
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int HostPool::dump_cb(void * _oss, int num, char **values, char **names)
|
||||
{
|
||||
ostringstream * oss;
|
||||
|
||||
oss = static_cast<ostringstream *>(_oss);
|
||||
|
||||
return Host::dump(*oss, num, values, names);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int HostPool::dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
int rc;
|
||||
ostringstream cmd;
|
||||
|
||||
oss << "<HOST_POOL>";
|
||||
|
||||
set_callback(static_cast<Callbackable::Callback>(&HostPool::dump_cb),
|
||||
static_cast<void *>(&oss));
|
||||
|
||||
cmd << "SELECT " << Host::db_names << " , " << HostShare::db_names
|
||||
<< " FROM " << Host::table << " JOIN " << HostShare::table
|
||||
<< " ON " << Host::table << ".oid = " << HostShare::table << ".hid";
|
||||
|
||||
if ( !where.empty() )
|
||||
{
|
||||
cmd << " WHERE " << where;
|
||||
}
|
||||
|
||||
rc = db->exec(cmd, this);
|
||||
|
||||
oss << "</HOST_POOL>";
|
||||
|
||||
unset_callback();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int HostPool::drop_cluster(int clid)
|
||||
{
|
||||
int rc;
|
||||
map<int, string>::iterator it;
|
||||
string cluster_name;
|
||||
|
||||
it = cluster_pool.cluster_names.find(clid);
|
||||
|
||||
if ( it == cluster_pool.cluster_names.end() )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
cluster_name = it->second;
|
||||
|
||||
// try to drop the cluster from the pool and DB
|
||||
rc = cluster_pool.drop(clid, db);
|
||||
|
||||
// Move the hosts assigned to the deleted cluster to the default one
|
||||
if( rc == 0 )
|
||||
{
|
||||
Host* host;
|
||||
vector<int> hids;
|
||||
vector<int>::iterator hid_it;
|
||||
|
||||
string where = "cluster = '" + cluster_name + "'";
|
||||
|
||||
search(hids, Host::table, where);
|
||||
|
||||
for ( hid_it=hids.begin() ; hid_it < hids.end(); hid_it++ )
|
||||
{
|
||||
host = get(*hid_it, true);
|
||||
|
||||
if ( host == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
set_default_cluster(host);
|
||||
|
||||
update(host);
|
||||
|
||||
host->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -28,12 +28,10 @@
|
||||
/* ************************************************************************ */
|
||||
|
||||
HostShare::HostShare(
|
||||
int _hsid,
|
||||
int _max_disk,
|
||||
int _max_mem,
|
||||
int _max_cpu):
|
||||
ObjectSQL(),
|
||||
hsid(_hsid),
|
||||
ObjectXML(),
|
||||
disk_usage(0),
|
||||
mem_usage(0),
|
||||
cpu_usage(0),
|
||||
@ -46,228 +44,7 @@ HostShare::HostShare(
|
||||
used_disk(0),
|
||||
used_mem(0),
|
||||
used_cpu(0),
|
||||
running_vms(0)
|
||||
{
|
||||
}
|
||||
|
||||
/* ************************************************************************ */
|
||||
/* HostShare :: Database Access Functions */
|
||||
/* ************************************************************************ */
|
||||
|
||||
const char * HostShare::table = "host_shares";
|
||||
|
||||
const char * HostShare::db_names = "hid,"
|
||||
"disk_usage, mem_usage, cpu_usage,"
|
||||
"max_disk, max_mem, max_cpu,"
|
||||
"free_disk, free_mem, free_cpu,"
|
||||
"used_disk, used_mem, used_cpu,"
|
||||
"running_vms";
|
||||
|
||||
const char * HostShare::db_bootstrap = "CREATE TABLE IF NOT EXISTS host_shares("
|
||||
"hid INTEGER PRIMARY KEY,"
|
||||
"disk_usage INTEGER, mem_usage INTEGER, cpu_usage INTEGER,"
|
||||
"max_disk INTEGER, max_mem INTEGER, max_cpu INTEGER,"
|
||||
"free_disk INTEGER, free_mem INTEGER, free_cpu INTEGER,"
|
||||
"used_disk INTEGER, used_mem INTEGER, used_cpu INTEGER,"
|
||||
"running_vms INTEGER)";
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int HostShare::select_cb(void * nil, int num, char **values, char **names)
|
||||
{
|
||||
if ((!values[HID]) ||
|
||||
(!values[DISK_USAGE]) ||
|
||||
(!values[MEM_USAGE]) ||
|
||||
(!values[CPU_USAGE]) ||
|
||||
(!values[MAX_DISK]) ||
|
||||
(!values[MAX_MEMORY]) ||
|
||||
(!values[MAX_CPU]) ||
|
||||
(!values[FREE_DISK]) ||
|
||||
(!values[FREE_MEMORY]) ||
|
||||
(!values[FREE_CPU]) ||
|
||||
(!values[USED_DISK]) ||
|
||||
(!values[USED_MEMORY]) ||
|
||||
(!values[USED_CPU]) ||
|
||||
(!values[RUNNING_VMS]) ||
|
||||
(num != LIMIT ))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
hsid = atoi(values[HID]);
|
||||
|
||||
disk_usage = atoi(values[DISK_USAGE]);
|
||||
mem_usage = atoi(values[MEM_USAGE]);
|
||||
cpu_usage = atoi(values[CPU_USAGE]);
|
||||
|
||||
max_disk = atoi(values[MAX_DISK]);
|
||||
max_mem = atoi(values[MAX_MEMORY]);
|
||||
max_cpu = atoi(values[MAX_CPU]);
|
||||
|
||||
free_disk = atoi(values[FREE_DISK]);
|
||||
free_mem = atoi(values[FREE_MEMORY]);
|
||||
free_cpu = atoi(values[FREE_CPU]);
|
||||
|
||||
used_disk = atoi(values[USED_DISK]);
|
||||
used_mem = atoi(values[USED_MEMORY]);
|
||||
used_cpu = atoi(values[USED_CPU]);
|
||||
|
||||
running_vms = atoi(values[RUNNING_VMS]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int HostShare::dump(ostringstream& oss,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names)
|
||||
{
|
||||
if ((!values[HID]) ||
|
||||
(!values[DISK_USAGE]) ||
|
||||
(!values[MEM_USAGE]) ||
|
||||
(!values[CPU_USAGE]) ||
|
||||
(!values[MAX_DISK]) ||
|
||||
(!values[MAX_MEMORY]) ||
|
||||
(!values[MAX_CPU]) ||
|
||||
(!values[FREE_DISK]) ||
|
||||
(!values[FREE_MEMORY]) ||
|
||||
(!values[FREE_CPU]) ||
|
||||
(!values[USED_DISK]) ||
|
||||
(!values[USED_MEMORY]) ||
|
||||
(!values[USED_CPU]) ||
|
||||
(!values[RUNNING_VMS]) ||
|
||||
(num != LIMIT))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
oss <<
|
||||
"<HOST_SHARE>" <<
|
||||
"<HID>" << values[HID] << "</HID>" <<
|
||||
"<DISK_USAGE>"<< values[DISK_USAGE] << "</DISK_USAGE>"<<
|
||||
"<MEM_USAGE>" << values[MEM_USAGE] << "</MEM_USAGE>" <<
|
||||
"<CPU_USAGE>" << values[CPU_USAGE] << "</CPU_USAGE>" <<
|
||||
"<MAX_DISK>" << values[MAX_DISK] << "</MAX_DISK>" <<
|
||||
"<MAX_MEM>" << values[MAX_MEMORY] << "</MAX_MEM>" <<
|
||||
"<MAX_CPU>" << values[MAX_CPU] << "</MAX_CPU>" <<
|
||||
"<FREE_DISK>" << values[FREE_DISK] << "</FREE_DISK>" <<
|
||||
"<FREE_MEM>" << values[FREE_MEMORY] << "</FREE_MEM>" <<
|
||||
"<FREE_CPU>" << values[FREE_CPU] << "</FREE_CPU>" <<
|
||||
"<USED_DISK>" << values[USED_DISK] << "</USED_DISK>" <<
|
||||
"<USED_MEM>" << values[USED_MEMORY] << "</USED_MEM>" <<
|
||||
"<USED_CPU>" << values[USED_CPU] << "</USED_CPU>" <<
|
||||
"<RUNNING_VMS>"<<values[RUNNING_VMS] << "</RUNNING_VMS>"<<
|
||||
"</HOST_SHARE>";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int HostShare::select(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
int bhsid;
|
||||
|
||||
set_callback(static_cast<Callbackable::Callback>(&HostShare::select_cb));
|
||||
|
||||
oss << "SELECT "<< db_names << " FROM " << table << " WHERE hid = " << hsid;
|
||||
|
||||
bhsid = hsid;
|
||||
hsid = -1;
|
||||
|
||||
rc = db->exec(oss,this);
|
||||
|
||||
unset_callback();
|
||||
|
||||
if (hsid != bhsid )
|
||||
{
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int HostShare::insert(SqlDB * db, string& error_str)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = insert_replace(db, false);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
error_str = "Error inserting Host Share in DB.";
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int HostShare::update(SqlDB * db)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = insert_replace(db, true);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int HostShare::insert_replace(SqlDB *db, bool replace)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
if(replace)
|
||||
{
|
||||
oss << "REPLACE";
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << "INSERT";
|
||||
}
|
||||
|
||||
oss << " INTO " << table << " ("<< db_names <<") VALUES ("
|
||||
<< hsid << ","
|
||||
<< disk_usage <<","<< mem_usage <<","<< cpu_usage<< ","
|
||||
<< max_disk <<","<< max_mem <<","<< max_cpu << ","
|
||||
<< free_disk <<","<< free_mem <<","<< free_cpu << ","
|
||||
<< used_disk <<","<< used_mem <<","<< used_cpu << ","
|
||||
<< running_vms<< ")";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int HostShare::drop(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "DELETE FROM " << table << " WHERE hid=" << hsid;
|
||||
|
||||
return db->exec(oss);
|
||||
}
|
||||
|
||||
/* ************************************************************************ */
|
||||
/* HostShare :: Misc */
|
||||
/* ************************************************************************ */
|
||||
running_vms(0){};
|
||||
|
||||
ostream& operator<<(ostream& os, HostShare& hs)
|
||||
{
|
||||
@ -287,7 +64,6 @@ string& HostShare::to_xml(string& xml) const
|
||||
ostringstream oss;
|
||||
|
||||
oss << "<HOST_SHARE>"
|
||||
<< "<HID>" << hsid << "</HID>"
|
||||
<< "<DISK_USAGE>" << disk_usage << "</DISK_USAGE>"
|
||||
<< "<MEM_USAGE>" << mem_usage << "</MEM_USAGE>"
|
||||
<< "<CPU_USAGE>" << cpu_usage << "</CPU_USAGE>"
|
||||
@ -311,30 +87,35 @@ string& HostShare::to_xml(string& xml) const
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
string& HostShare::to_str(string& str) const
|
||||
int HostShare::from_xml_node(const xmlNodePtr node)
|
||||
{
|
||||
string template_xml;
|
||||
ostringstream oss;
|
||||
int rc = 0;
|
||||
|
||||
oss<< "\tHID = " << hsid
|
||||
<< "\tCPU_USAGE = " << cpu_usage << endl
|
||||
<< "\tMEMORY_USAGE = " << mem_usage << endl
|
||||
<< "\tDISK_USAGE = " << disk_usage<< endl
|
||||
<< "\tMAX_CPU = " << max_cpu << endl
|
||||
<< "\tMAX_MEMORY = " << max_mem << endl
|
||||
<< "\tMAX_DISK = " << max_disk<< endl
|
||||
<< "\tFREE_CPU = " << free_cpu << endl
|
||||
<< "\tFREE_MEMORY = " << free_mem << endl
|
||||
<< "\tFREE_DISK = " << free_disk<< endl
|
||||
<< "\tUSED_CPU = " << used_cpu << endl
|
||||
<< "\tUSED_MEMORY = " << used_mem << endl
|
||||
<< "\tUSED_DISK = " << used_disk<< endl
|
||||
<< "\tRUNNING_VMS = " << running_vms<< endl;
|
||||
// Initialize the internal XML object
|
||||
ObjectXML::update_from_node(node);
|
||||
|
||||
str = oss.str();
|
||||
rc += xpath(disk_usage, "/HOST_SHARE/DISK_USAGE", -1);
|
||||
rc += xpath(mem_usage, "/HOST_SHARE/MEM_USAGE", -1);
|
||||
rc += xpath(cpu_usage, "/HOST_SHARE/CPU_USAGE", -1);
|
||||
|
||||
return str;
|
||||
rc += xpath(max_disk, "/HOST_SHARE/MAX_DISK", -1);
|
||||
rc += xpath(max_mem , "/HOST_SHARE/MAX_MEM", -1);
|
||||
rc += xpath(max_cpu , "/HOST_SHARE/MAX_CPU", -1);
|
||||
|
||||
rc += xpath(free_disk, "/HOST_SHARE/FREE_DISK", -1);
|
||||
rc += xpath(free_mem , "/HOST_SHARE/FREE_MEM", -1);
|
||||
rc += xpath(free_cpu , "/HOST_SHARE/FREE_CPU", -1);
|
||||
|
||||
rc += xpath(used_disk, "/HOST_SHARE/USED_DISK", -1);
|
||||
rc += xpath(used_mem , "/HOST_SHARE/USED_MEM", -1);
|
||||
rc += xpath(used_cpu , "/HOST_SHARE/USED_CPU", -1);
|
||||
|
||||
rc += xpath(running_vms,"/HOST_SHARE/RUNNING_VMS",-1);
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
@ -25,7 +25,6 @@ source_files=[
|
||||
'Host.cc',
|
||||
'HostShare.cc',
|
||||
'HostPool.cc',
|
||||
'ClusterPool.cc',
|
||||
'HostHook.cc'
|
||||
]
|
||||
|
||||
|
@ -33,7 +33,7 @@ const string xmls[] =
|
||||
{
|
||||
"<HOST><ID>0</ID><NAME>Host one</NAME><STATE>0</STATE>"
|
||||
"<IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD>"
|
||||
"<LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><HOST_SHARE><HID>0</HID>"
|
||||
"<LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><HOST_SHARE>"
|
||||
"<DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE>"
|
||||
"<MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU>"
|
||||
"<FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU>"
|
||||
@ -42,7 +42,7 @@ const string xmls[] =
|
||||
|
||||
"<HOST><ID>1</ID><NAME>Second host</NAME><STATE>0</STATE>"
|
||||
"<IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD>"
|
||||
"<LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><HOST_SHARE><HID>1</HID>"
|
||||
"<LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><HOST_SHARE>"
|
||||
"<DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE>"
|
||||
"<MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU>"
|
||||
"<FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU>"
|
||||
@ -54,72 +54,72 @@ const string xmls[] =
|
||||
const string xml_dump =
|
||||
"<HOST_POOL><HOST><ID>0</ID><NAME>a</NAME><STATE>0</STATE><IM_MAD>im_mad</I"
|
||||
"M_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0"
|
||||
"</LAST_MON_TIME><CLUSTER>default</CLUSTER><TEMPLATE></TEMPLATE><HOST_SHARE><HID>0</HID><DISK_USAGE>0</DISK_USAGE><MEM"
|
||||
"</LAST_MON_TIME><CLUSTER>default</CLUSTER><HOST_SHARE><DISK_USAGE>0</DISK_USAGE><MEM"
|
||||
"_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM"
|
||||
">0</MAX_MEM><MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_"
|
||||
"MEM><FREE_CPU>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><U"
|
||||
"SED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE></HOST><HOST>"
|
||||
"SED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST><HOST>"
|
||||
"<ID>1</ID><NAME>a name</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MA"
|
||||
"D>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_M"
|
||||
"ON_TIME><CLUSTER>default</CLUSTER><TEMPLATE></TEMPLATE><HOST_SHARE><HID>1</HID><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</ME"
|
||||
"ON_TIME><CLUSTER>default</CLUSTER><HOST_SHARE><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</ME"
|
||||
"M_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM>"
|
||||
"<MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CP"
|
||||
"U>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</U"
|
||||
"SED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE></HOST><HOST><ID>2</ID><N"
|
||||
"SED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST><HOST><ID>2</ID><N"
|
||||
"AME>a_name</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</V"
|
||||
"M_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><TEMPLATE></TEMPLATE><HOS"
|
||||
"T_SHARE><HID>2</HID><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU"
|
||||
"M_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><HOS"
|
||||
"T_SHARE><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU"
|
||||
"_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</"
|
||||
"MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CP"
|
||||
"U><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUN"
|
||||
"NING_VMS>0</RUNNING_VMS></HOST_SHARE></HOST><HOST><ID>3</ID><NAME>another "
|
||||
"NING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST><HOST><ID>3</ID><NAME>another "
|
||||
"name</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD>"
|
||||
"<TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><TEMPLATE></TEMPLATE><HOST_SHAR"
|
||||
"E><HID>3</HID><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE"
|
||||
"<TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><HOST_SHAR"
|
||||
"E><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE"
|
||||
">0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CP"
|
||||
"U><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU><USE"
|
||||
"D_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUNNING_V"
|
||||
"MS>0</RUNNING_VMS></HOST_SHARE></HOST><HOST><ID>4</ID><NAME>host</NAME><ST"
|
||||
"MS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST><HOST><ID>4</ID><NAME>host</NAME><ST"
|
||||
"ATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad"
|
||||
"</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><TEMPLATE></TEMPLATE><HOST_SHARE><HID>4</HID>"
|
||||
"</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><HOST_SHARE>"
|
||||
"<DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE>"
|
||||
"<MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU><FREE_DISK>0"
|
||||
"</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU><USED_DISK>0</USED"
|
||||
"_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_"
|
||||
"VMS></HOST_SHARE></HOST></HOST_POOL>";
|
||||
"VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST></HOST_POOL>";
|
||||
|
||||
const string xml_dump_like_a =
|
||||
"<HOST_POOL><HOST><ID>0</ID><NAME>a</NAME><STATE>0</STATE><IM_MAD>im_mad</I"
|
||||
"M_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0"
|
||||
"</LAST_MON_TIME><CLUSTER>default</CLUSTER><TEMPLATE></TEMPLATE><HOST_SHARE><HID>0</HID><DISK_USAGE>0</DISK_USAGE><MEM"
|
||||
"</LAST_MON_TIME><CLUSTER>default</CLUSTER><HOST_SHARE><DISK_USAGE>0</DISK_USAGE><MEM"
|
||||
"_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM"
|
||||
">0</MAX_MEM><MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_"
|
||||
"MEM><FREE_CPU>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><U"
|
||||
"SED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE></HOST><HOST>"
|
||||
"SED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST><HOST>"
|
||||
"<ID>1</ID><NAME>a name</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MA"
|
||||
"D>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_M"
|
||||
"ON_TIME><CLUSTER>default</CLUSTER><TEMPLATE></TEMPLATE><HOST_SHARE><HID>1</HID><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</ME"
|
||||
"ON_TIME><CLUSTER>default</CLUSTER><HOST_SHARE><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</ME"
|
||||
"M_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM>"
|
||||
"<MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CP"
|
||||
"U>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</U"
|
||||
"SED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE></HOST><HOST><ID>2</ID><N"
|
||||
"SED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST><HOST><ID>2</ID><N"
|
||||
"AME>a_name</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</V"
|
||||
"M_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><TEMPLATE></TEMPLATE><HOS"
|
||||
"T_SHARE><HID>2</HID><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU"
|
||||
"M_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><HOS"
|
||||
"T_SHARE><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU"
|
||||
"_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</"
|
||||
"MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CP"
|
||||
"U><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUN"
|
||||
"NING_VMS>0</RUNNING_VMS></HOST_SHARE></HOST><HOST><ID>3</ID><NAME>another "
|
||||
"NING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST><HOST><ID>3</ID><NAME>another "
|
||||
"name</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD>"
|
||||
"<TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><TEMPLATE></TEMPLATE><HOST_SHAR"
|
||||
"E><HID>3</HID><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE"
|
||||
"<TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><HOST_SHAR"
|
||||
"E><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE"
|
||||
">0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CP"
|
||||
"U><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU><USE"
|
||||
"D_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUNNING_V"
|
||||
"MS>0</RUNNING_VMS></HOST_SHARE></HOST></HOST_POOL>";
|
||||
"MS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST></HOST_POOL>";
|
||||
|
||||
const string host0_updated =
|
||||
"<HOST><ID>0</ID><NAME>Host one</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><HOST_SHARE><HID>0</HID><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE><ATT_A><![CDATA[VALUE_A]]></ATT_A><ATT_B><![CDATA[VALUE_B]]></ATT_B></TEMPLATE></HOST>";
|
||||
"<HOST><ID>0</ID><NAME>Host one</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>default</CLUSTER><HOST_SHARE><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE><ATT_A><![CDATA[VALUE_A]]></ATT_A><ATT_B><![CDATA[VALUE_B]]></ATT_B></TEMPLATE></HOST>";
|
||||
|
||||
const string cluster_default =
|
||||
"<CLUSTER><ID>0</ID><NAME>default</NAME></CLUSTER>";
|
||||
@ -128,7 +128,7 @@ const string cluster_xml_dump =
|
||||
"<CLUSTER_POOL><CLUSTER><ID>0</ID><NAME>default</NAME></CLUSTER><CLUSTER><ID>1</ID><NAME>cluster_a</NAME></CLUSTER><CLUSTER><ID>3</ID><NAME>cluster_c</NAME></CLUSTER><CLUSTER><ID>4</ID><NAME>cluster_d</NAME></CLUSTER></CLUSTER_POOL>";
|
||||
|
||||
const string host_0_cluster =
|
||||
"<HOST><ID>0</ID><NAME>Host one</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>cluster_a</CLUSTER><HOST_SHARE><HID>0</HID><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST>";
|
||||
"<HOST><ID>0</ID><NAME>Host one</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>cluster_a</CLUSTER><HOST_SHARE><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST>";
|
||||
/* ************************************************************************* */
|
||||
/* ************************************************************************* */
|
||||
|
||||
@ -143,16 +143,10 @@ class HostPoolTest : public PoolTest
|
||||
CPPUNIT_TEST (dump_where);
|
||||
CPPUNIT_TEST (discover);
|
||||
CPPUNIT_TEST (duplicates);
|
||||
|
||||
CPPUNIT_TEST (cluster_init);
|
||||
CPPUNIT_TEST (cluster_allocate);
|
||||
CPPUNIT_TEST (cluster_drop);
|
||||
CPPUNIT_TEST (cluster_id);
|
||||
CPPUNIT_TEST (cluster_dump);
|
||||
CPPUNIT_TEST (set_cluster);
|
||||
CPPUNIT_TEST (remove_cluster);
|
||||
CPPUNIT_TEST (update_info);
|
||||
|
||||
// CPPUNIT_TEST (scale_test);
|
||||
|
||||
CPPUNIT_TEST_SUITE_END ();
|
||||
|
||||
protected:
|
||||
@ -184,12 +178,21 @@ protected:
|
||||
CPPUNIT_ASSERT( obj != 0 );
|
||||
|
||||
string xml_str = "";
|
||||
string name = host->get_hostname();
|
||||
string name = host->get_name();
|
||||
|
||||
CPPUNIT_ASSERT( name == names[index] );
|
||||
|
||||
// Get the xml
|
||||
host->to_xml(xml_str);
|
||||
|
||||
// A little help for debugging
|
||||
/*
|
||||
if( xml_str != xmls[index] )
|
||||
{
|
||||
cout << endl << xml_str << endl << "========"
|
||||
<< endl << xmls[index];
|
||||
}
|
||||
//*/
|
||||
CPPUNIT_ASSERT( xml_str == xmls[index]);
|
||||
};
|
||||
|
||||
@ -285,6 +288,15 @@ public:
|
||||
|
||||
string result = oss.str();
|
||||
|
||||
// A little help for debugging
|
||||
/*
|
||||
if( result != xml_dump )
|
||||
{
|
||||
cout << endl << result << endl << "========"
|
||||
<< endl << xml_dump;
|
||||
}
|
||||
//*/
|
||||
|
||||
CPPUNIT_ASSERT( result == xml_dump );
|
||||
}
|
||||
|
||||
@ -304,12 +316,21 @@ public:
|
||||
|
||||
|
||||
ostringstream oss;
|
||||
rc = ((HostPool*)pool)->dump(oss, "host_name LIKE 'a%'");
|
||||
rc = ((HostPool*)pool)->dump(oss, "name LIKE 'a%' ORDER BY oid");
|
||||
CPPUNIT_ASSERT(rc == 0);
|
||||
|
||||
|
||||
string result = oss.str();
|
||||
|
||||
// A little help for debugging
|
||||
/*
|
||||
if( result != xml_dump_like_a )
|
||||
{
|
||||
cout << endl << result << endl << "========"
|
||||
<< endl << xml_dump_like_a;
|
||||
}
|
||||
//*/
|
||||
|
||||
CPPUNIT_ASSERT( result == xml_dump_like_a );
|
||||
}
|
||||
|
||||
@ -360,201 +381,87 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/* ********************************************************************* */
|
||||
/* ********************************************************************* */
|
||||
|
||||
void cluster_init()
|
||||
void scale_test()
|
||||
{
|
||||
time_t the_time, the_time2;
|
||||
int oid,i,j,rc;
|
||||
|
||||
ostringstream oss,ossdump;
|
||||
string err;
|
||||
Host * host;
|
||||
|
||||
string monitor = "ARCH=x86_64 MODELNAME=\"Intel(R) Core(TM)2 Duo CPU P9300 @ 2.26GHz\" HYPERVISOR=kvm TOTALCPU=200 CPUSPEED=800 TOTALMEMORY=4005416 USEDMEMORY=2351928 FREEMEMORY=2826904 FREECPU=188.4 USEDCPU=11.599999999999994 NETRX=0 NETTX=0 HOSTNAME=pc-ruben";
|
||||
|
||||
cout << endl << "Allocate Test" << endl;
|
||||
|
||||
tearDown();
|
||||
|
||||
for (i=1000; i<30000 ; i = i + 5000)
|
||||
{
|
||||
setUp();
|
||||
|
||||
HostPool * hp = static_cast<HostPool *>(pool);
|
||||
|
||||
the_time = time(0);
|
||||
|
||||
for (j=0,oss.str(""); j<i ; j=j+1,oss.str(""))
|
||||
{
|
||||
oss << "host" << j;
|
||||
|
||||
hp->allocate(&oid, oss.str().c_str(),im_mad,vmm_mad,tm_mad,err);
|
||||
}
|
||||
|
||||
the_time2 = time(0) - the_time;
|
||||
|
||||
hp->clean();
|
||||
|
||||
the_time = time(0);
|
||||
|
||||
rc = hp->dump(ossdump, "");
|
||||
|
||||
cout <<"\t"<<i<<"\t"<<the_time2<<"\t"<<time(0)-the_time<< endl;
|
||||
|
||||
tearDown();
|
||||
}
|
||||
|
||||
cout << endl << "Read Test" << endl;
|
||||
|
||||
setUp();
|
||||
|
||||
|
||||
// Allocate a HostPool
|
||||
setUp();
|
||||
|
||||
HostPool * hp = static_cast<HostPool *>(pool);
|
||||
|
||||
CPPUNIT_ASSERT( hp->info_cluster(0) == cluster_default );
|
||||
}
|
||||
for (i=10000,oss.str(""); i<30000 ; i++,oss.str(""))
|
||||
{
|
||||
oss << "host" << i;
|
||||
hp->allocate(&oid,oss.str().c_str(),im_mad,vmm_mad,tm_mad,err);
|
||||
|
||||
/* ********************************************************************* */
|
||||
host = hp->get(oid, false);
|
||||
|
||||
void cluster_allocate()
|
||||
{
|
||||
HostPool * hp = static_cast<HostPool *>(pool);
|
||||
int clid, rc;
|
||||
string err;
|
||||
host->update_info(monitor);
|
||||
hp->update(host);
|
||||
}
|
||||
|
||||
//Load test
|
||||
for (i=0; i<25000; i=i+5000)
|
||||
{
|
||||
hp->clean();
|
||||
|
||||
rc = hp->allocate_cluster(&clid, "new_cluster", err);
|
||||
CPPUNIT_ASSERT( rc == clid );
|
||||
CPPUNIT_ASSERT( clid == 1 );
|
||||
the_time = time(0);
|
||||
|
||||
CPPUNIT_ASSERT( hp->info_cluster(clid) ==
|
||||
"<CLUSTER><ID>1</ID><NAME>new_cluster</NAME></CLUSTER>");
|
||||
for (j=0; j<i ; j++)
|
||||
{
|
||||
host = hp->get(j,true);
|
||||
host->unlock();
|
||||
}
|
||||
|
||||
// Try to allocate using the same name
|
||||
rc = hp->allocate_cluster(&clid, "new_cluster", err);
|
||||
CPPUNIT_ASSERT( rc == clid );
|
||||
CPPUNIT_ASSERT( clid == -1 );
|
||||
}
|
||||
|
||||
/* ********************************************************************* */
|
||||
|
||||
void cluster_drop()
|
||||
{
|
||||
HostPool * hp = static_cast<HostPool *>(pool);
|
||||
int clid, rc;
|
||||
string err;
|
||||
|
||||
// Drop a non-existing cluster
|
||||
rc = hp->drop_cluster(20);
|
||||
CPPUNIT_ASSERT( rc == -1 );
|
||||
|
||||
// Allocate a cluster and drop it
|
||||
rc = hp->allocate_cluster(&clid, "new_cluster", err);
|
||||
CPPUNIT_ASSERT( clid == 1);
|
||||
|
||||
rc = hp->drop_cluster(clid);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
// Try to drop the default cluster, should fail
|
||||
rc = hp->drop_cluster(0);
|
||||
CPPUNIT_ASSERT( rc == -1 );
|
||||
}
|
||||
|
||||
/* ********************************************************************* */
|
||||
|
||||
void cluster_id()
|
||||
{
|
||||
HostPool * hp = static_cast<HostPool *>(pool);
|
||||
int clid, rc;
|
||||
ostringstream oss;
|
||||
string err;
|
||||
|
||||
// Allocate some clusters
|
||||
rc = hp->allocate_cluster(&clid, "cluster_a", err);
|
||||
CPPUNIT_ASSERT( rc == 1 );
|
||||
|
||||
rc = hp->allocate_cluster(&clid, "cluster_b", err);
|
||||
CPPUNIT_ASSERT( rc == 2 );
|
||||
|
||||
rc = hp->allocate_cluster(&clid, "cluster_c", err);
|
||||
CPPUNIT_ASSERT( rc == 3 );
|
||||
|
||||
rc = hp->allocate_cluster(&clid, "cluster_d", err);
|
||||
CPPUNIT_ASSERT( rc == 4 );
|
||||
|
||||
// Drop id 2
|
||||
rc = hp->drop_cluster(2);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
// Next one should use id 5, because the biggest id is 4
|
||||
rc = hp->allocate_cluster(&clid, "cluster_e", err);
|
||||
CPPUNIT_ASSERT( rc == 5 );
|
||||
|
||||
// Drop id 5
|
||||
rc = hp->drop_cluster(5);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
// Next one should use id 5, because the biggest id is 4 again
|
||||
rc = hp->allocate_cluster(&clid, "cluster_f", err);
|
||||
CPPUNIT_ASSERT( rc == 5 );
|
||||
|
||||
}
|
||||
|
||||
/* ********************************************************************* */
|
||||
|
||||
void cluster_dump()
|
||||
{
|
||||
HostPool * hp = static_cast<HostPool *>(pool);
|
||||
int clid, rc;
|
||||
ostringstream oss;
|
||||
string err;
|
||||
|
||||
// Allocate some clusters
|
||||
rc = hp->allocate_cluster(&clid, "cluster_a", err);
|
||||
CPPUNIT_ASSERT( rc == 1 );
|
||||
|
||||
rc = hp->allocate_cluster(&clid, "cluster_b", err);
|
||||
CPPUNIT_ASSERT( rc == 2 );
|
||||
|
||||
rc = hp->allocate_cluster(&clid, "cluster_c", err);
|
||||
CPPUNIT_ASSERT( rc == 3 );
|
||||
|
||||
rc = hp->allocate_cluster(&clid, "cluster_d", err);
|
||||
CPPUNIT_ASSERT( rc == 4 );
|
||||
|
||||
|
||||
// Drop one of them
|
||||
rc = hp->drop_cluster(2);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
// dump the pool
|
||||
rc = hp->dump_cluster(oss);
|
||||
CPPUNIT_ASSERT( oss.str() == cluster_xml_dump );
|
||||
}
|
||||
|
||||
/* ********************************************************************* */
|
||||
|
||||
void set_cluster()
|
||||
{
|
||||
HostPool * hp = static_cast<HostPool *>(pool);
|
||||
Host* host;
|
||||
int clid, rc, oid;
|
||||
string xml_str, err;
|
||||
|
||||
// Allocate a host
|
||||
oid = allocate(0);
|
||||
CPPUNIT_ASSERT(oid >= 0);
|
||||
|
||||
host = hp->get(0, false);
|
||||
CPPUNIT_ASSERT(host != 0);
|
||||
|
||||
rc = hp->allocate_cluster(&clid, "cluster_a", err);
|
||||
CPPUNIT_ASSERT( rc == 1 );
|
||||
|
||||
rc = hp->set_cluster(host, clid);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
host->to_xml(xml_str);
|
||||
CPPUNIT_ASSERT( xml_str == host_0_cluster);
|
||||
|
||||
|
||||
// Try to set a non-existing cluster
|
||||
rc = hp->set_cluster(host, 20);
|
||||
CPPUNIT_ASSERT( rc == -1 );
|
||||
|
||||
CPPUNIT_ASSERT( xml_str == host_0_cluster);
|
||||
|
||||
}
|
||||
|
||||
/* ********************************************************************* */
|
||||
|
||||
void remove_cluster()
|
||||
{
|
||||
HostPool * hp = static_cast<HostPool *>(pool);
|
||||
Host* host;
|
||||
int clid, rc, oid;
|
||||
string xml_str, err;
|
||||
|
||||
// Allocate a host
|
||||
oid = allocate(0);
|
||||
CPPUNIT_ASSERT(oid >= 0);
|
||||
|
||||
host = hp->get(0, false);
|
||||
CPPUNIT_ASSERT(host != 0);
|
||||
|
||||
rc = hp->allocate_cluster(&clid, "cluster_a", err);
|
||||
CPPUNIT_ASSERT( rc == 1 );
|
||||
|
||||
// Set host 0 to cluster 1
|
||||
rc = hp->set_cluster(host, clid);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
// Check
|
||||
host->to_xml(xml_str);
|
||||
CPPUNIT_ASSERT( xml_str == host_0_cluster);
|
||||
|
||||
// Remove the cluster
|
||||
rc = hp->set_default_cluster(host);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
// The host should have been moved to the default cluster
|
||||
host->to_xml(xml_str);
|
||||
check(0, host);
|
||||
cout << "\t" << i << "\t" << time(0) - the_time << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/* ********************************************************************* */
|
||||
|
@ -21,6 +21,8 @@ Import('env')
|
||||
env.Prepend(LIBS=[
|
||||
'nebula_core_test',
|
||||
'nebula_host',
|
||||
'nebula_cluster',
|
||||
'nebula_xml',
|
||||
'nebula_vmm',
|
||||
'nebula_im',
|
||||
'nebula_rm',
|
||||
|
@ -201,7 +201,7 @@ void InformationManager::timer_action()
|
||||
(thetime - host->get_last_monitored() >= monitor_period))
|
||||
{
|
||||
oss.str("");
|
||||
oss << "Monitoring host " << host->get_hostname()
|
||||
oss << "Monitoring host " << host->get_name()
|
||||
<< " (" << it->first << ")";
|
||||
NebulaLog::log("InM",Log::INFO,oss);
|
||||
|
||||
@ -225,7 +225,7 @@ void InformationManager::timer_action()
|
||||
update_remotes = true;
|
||||
}
|
||||
|
||||
imd->monitor(it->first,host->get_hostname(),update_remotes);
|
||||
imd->monitor(it->first,host->get_name(),update_remotes);
|
||||
|
||||
host->set_state(Host::MONITORING);
|
||||
}
|
||||
|
@ -28,14 +28,17 @@
|
||||
#include "AuthManager.h"
|
||||
#include "UserPool.h"
|
||||
|
||||
#define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper)
|
||||
|
||||
/* ************************************************************************ */
|
||||
/* Image :: Constructor/Destructor */
|
||||
/* Image :: Constructor/Destructor */
|
||||
/* ************************************************************************ */
|
||||
|
||||
Image::Image(int _uid, ImageTemplate * _image_template):
|
||||
PoolObjectSQL(-1),
|
||||
uid(_uid),
|
||||
name(""),
|
||||
Image::Image(int _uid,
|
||||
const string& _user_name,
|
||||
ImageTemplate * _image_template):
|
||||
PoolObjectSQL(-1,"",_uid,table),
|
||||
user_name(_user_name),
|
||||
type(OS),
|
||||
regtime(time(0)),
|
||||
source(""),
|
||||
@ -61,92 +64,16 @@ Image::~Image()
|
||||
}
|
||||
|
||||
/* ************************************************************************ */
|
||||
/* Image :: Database Access Functions */
|
||||
/* Image :: Database Access Functions */
|
||||
/* ************************************************************************ */
|
||||
|
||||
const char * Image::table = "image_pool";
|
||||
|
||||
const char * Image::db_names = "oid, uid, name, type, public, persistent, regtime, "
|
||||
"source, state, running_vms, template";
|
||||
|
||||
const char * Image::extended_db_names = "image_pool.oid, image_pool.uid, "
|
||||
"image_pool.name, image_pool.type, image_pool.public, "
|
||||
"image_pool.persistent, image_pool.regtime, image_pool.source, "
|
||||
"image_pool.state, image_pool.running_vms, image_pool.template";
|
||||
const char * Image::db_names = "oid, name, body, uid, public";
|
||||
|
||||
const char * Image::db_bootstrap = "CREATE TABLE IF NOT EXISTS image_pool ("
|
||||
"oid INTEGER PRIMARY KEY, uid INTEGER, name VARCHAR(128), "
|
||||
"type INTEGER, public INTEGER, persistent INTEGER, regtime INTEGER, source TEXT, state INTEGER, "
|
||||
"running_vms INTEGER, template TEXT, UNIQUE(name) )";
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Image::select_cb(void * nil, int num, char **values, char ** names)
|
||||
{
|
||||
if ((!values[OID]) ||
|
||||
(!values[UID]) ||
|
||||
(!values[NAME]) ||
|
||||
(!values[TYPE]) ||
|
||||
(!values[PUBLIC]) ||
|
||||
(!values[PERSISTENT]) ||
|
||||
(!values[REGTIME]) ||
|
||||
(!values[SOURCE]) ||
|
||||
(!values[STATE]) ||
|
||||
(!values[RUNNING_VMS]) ||
|
||||
(!values[TEMPLATE]) ||
|
||||
(num != LIMIT ))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
oid = atoi(values[OID]);
|
||||
uid = atoi(values[UID]);
|
||||
|
||||
name = values[NAME];
|
||||
|
||||
type = static_cast<ImageType>(atoi(values[TYPE]));
|
||||
public_img = atoi(values[PUBLIC]);
|
||||
persistent_img = atoi(values[PERSISTENT]);
|
||||
regtime = static_cast<time_t>(atoi(values[REGTIME]));
|
||||
|
||||
source = values[SOURCE];
|
||||
|
||||
state = static_cast<ImageState>(atoi(values[STATE]));
|
||||
|
||||
running_vms = atoi(values[RUNNING_VMS]);
|
||||
|
||||
image_template->from_xml(values[TEMPLATE]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Image::select(SqlDB *db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
int boid;
|
||||
|
||||
set_callback(static_cast<Callbackable::Callback>(&Image::select_cb));
|
||||
|
||||
oss << "SELECT " << db_names << " FROM " << table << " WHERE oid = " << oid;
|
||||
|
||||
boid = oid;
|
||||
oid = -1;
|
||||
|
||||
rc = db->exec(oss, this);
|
||||
|
||||
if ((rc != 0) || (oid != boid ))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
"oid INTEGER PRIMARY KEY, name VARCHAR(256), body TEXT, uid INTEGER, "
|
||||
"public INTEGER, UNIQUE(name,uid) )";
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@ -155,11 +82,11 @@ int Image::insert(SqlDB *db, string& error_str)
|
||||
{
|
||||
int rc;
|
||||
|
||||
string source_att;
|
||||
string type_att;
|
||||
string public_attr;
|
||||
string persistent_attr;
|
||||
string dev_prefix;
|
||||
string path_attr;
|
||||
string type_att;
|
||||
string public_attr;
|
||||
string persistent_attr;
|
||||
string dev_prefix;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Check default image attributes
|
||||
@ -169,17 +96,11 @@ int Image::insert(SqlDB *db, string& error_str)
|
||||
|
||||
get_template_attribute("NAME", name);
|
||||
|
||||
if ( name.empty() == true )
|
||||
{
|
||||
goto error_name;
|
||||
}
|
||||
|
||||
// ------------ TYPE --------------------
|
||||
|
||||
get_template_attribute("TYPE", type_att);
|
||||
|
||||
transform (type_att.begin(), type_att.end(), type_att.begin(),
|
||||
(int(*)(int))toupper);
|
||||
TO_UPPER(type_att);
|
||||
|
||||
if ( type_att.empty() == true )
|
||||
{
|
||||
@ -194,20 +115,20 @@ int Image::insert(SqlDB *db, string& error_str)
|
||||
// ------------ PUBLIC --------------------
|
||||
|
||||
get_template_attribute("PUBLIC", public_attr);
|
||||
|
||||
image_template->erase("PUBLIC");
|
||||
|
||||
transform (public_attr.begin(), public_attr.end(), public_attr.begin(),
|
||||
(int(*)(int))toupper);
|
||||
TO_UPPER(public_attr);
|
||||
|
||||
public_img = (public_attr == "YES");
|
||||
|
||||
// ------------ PERSISTENT --------------------
|
||||
|
||||
get_template_attribute("PERSISTENT", persistent_attr);
|
||||
|
||||
image_template->erase("PERSISTENT");
|
||||
|
||||
transform (persistent_attr.begin(), persistent_attr.end(), persistent_attr.begin(),
|
||||
(int(*)(int))toupper);
|
||||
TO_UPPER(persistent_attr);
|
||||
|
||||
persistent_img = (persistent_attr == "YES");
|
||||
|
||||
@ -230,10 +151,32 @@ int Image::insert(SqlDB *db, string& error_str)
|
||||
image_template->set(dev_att);
|
||||
}
|
||||
|
||||
// ------------ SOURCE (path to store the image)--------------------
|
||||
// ------------ PATH --------------------
|
||||
get_template_attribute("PATH", path_attr);
|
||||
|
||||
// ------------ SOURCE (path to store the image) --------------------
|
||||
get_template_attribute("SOURCE", source);
|
||||
|
||||
// The template should contain PATH or SOURCE
|
||||
if ( source.empty() && path_attr.empty() )
|
||||
{
|
||||
string size_attr;
|
||||
string fstype_attr;
|
||||
|
||||
get_template_attribute("SIZE", size_attr);
|
||||
get_template_attribute("FSTYPE", fstype_attr);
|
||||
|
||||
// It could be an empty DATABLOCK image, if it declares SIZE and FSTYPE
|
||||
if ( type_att != "DATABLOCK" || size_attr.empty() || fstype_attr.empty() )
|
||||
{
|
||||
goto error_no_path;
|
||||
}
|
||||
}
|
||||
else if ( !source.empty() && !path_attr.empty() )
|
||||
{
|
||||
goto error_path_and_source;
|
||||
}
|
||||
|
||||
if (source.empty())
|
||||
{
|
||||
ostringstream tmp_hashstream;
|
||||
@ -262,18 +205,30 @@ int Image::insert(SqlDB *db, string& error_str)
|
||||
|
||||
return rc;
|
||||
|
||||
error_name:
|
||||
error_str = "NAME not present in image template.";
|
||||
goto error_common;
|
||||
|
||||
error_type:
|
||||
error_str = "Incorrect TYPE in image template.";
|
||||
error_str = "Incorrect TYPE in template.";
|
||||
goto error_common;
|
||||
|
||||
error_public_and_persistent:
|
||||
error_str = "Image cannot be public and persistent.";
|
||||
goto error_common;
|
||||
|
||||
error_no_path:
|
||||
if ( type_att == "DATABLOCK" )
|
||||
{
|
||||
error_str = "A DATABLOCK type IMAGE has to declare a PATH, or both "
|
||||
"SIZE and FSTYPE.";
|
||||
}
|
||||
else
|
||||
{
|
||||
error_str = "No PATH in template.";
|
||||
}
|
||||
goto error_common;
|
||||
|
||||
error_path_and_source:
|
||||
error_str = "Template malformed, PATH and SOURCE are mutuallly exclusive.";
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
NebulaLog::log("IMG", Log::ERROR, error_str);
|
||||
return -1;
|
||||
@ -296,11 +251,10 @@ int Image::insert_replace(SqlDB *db, bool replace)
|
||||
|
||||
int rc;
|
||||
|
||||
string xml_template;
|
||||
string xml_body;
|
||||
|
||||
char * sql_name;
|
||||
char * sql_source;
|
||||
char * sql_template;
|
||||
char * sql_xml;
|
||||
|
||||
// Update the Image
|
||||
|
||||
@ -311,19 +265,11 @@ int Image::insert_replace(SqlDB *db, bool replace)
|
||||
goto error_name;
|
||||
}
|
||||
|
||||
sql_source = db->escape_str(source.c_str());
|
||||
sql_xml = db->escape_str(to_xml(xml_body).c_str());
|
||||
|
||||
if ( sql_source == 0 )
|
||||
if ( sql_xml == 0 )
|
||||
{
|
||||
goto error_source;
|
||||
}
|
||||
|
||||
image_template->to_xml(xml_template);
|
||||
sql_template = db->escape_str(xml_template.c_str());
|
||||
|
||||
if ( sql_template == 0 )
|
||||
{
|
||||
goto error_template;
|
||||
goto error_body;
|
||||
}
|
||||
|
||||
if(replace)
|
||||
@ -339,100 +285,24 @@ int Image::insert_replace(SqlDB *db, bool replace)
|
||||
|
||||
oss <<" INTO "<< table <<" ("<< db_names <<") VALUES ("
|
||||
<< oid << ","
|
||||
<< uid << ","
|
||||
<< "'" << sql_name << "',"
|
||||
<< type << ","
|
||||
<< public_img << ","
|
||||
<< persistent_img << ","
|
||||
<< regtime << ","
|
||||
<< "'" << sql_source << "',"
|
||||
<< state << ","
|
||||
<< running_vms << ","
|
||||
<< "'" << sql_template << "')";
|
||||
<< "'" << sql_xml << "',"
|
||||
<< uid << ","
|
||||
<< public_img << ")";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
db->free_str(sql_name);
|
||||
db->free_str(sql_source);
|
||||
db->free_str(sql_template);
|
||||
db->free_str(sql_xml);
|
||||
|
||||
return rc;
|
||||
|
||||
error_template:
|
||||
db->free_str(sql_source);
|
||||
error_source:
|
||||
error_body:
|
||||
db->free_str(sql_name);
|
||||
error_name:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Image::dump(ostringstream& oss, int num, char **values, char **names)
|
||||
{
|
||||
if ((!values[OID]) ||
|
||||
(!values[UID]) ||
|
||||
(!values[NAME]) ||
|
||||
(!values[TYPE]) ||
|
||||
(!values[PUBLIC]) ||
|
||||
(!values[PERSISTENT]) ||
|
||||
(!values[REGTIME]) ||
|
||||
(!values[SOURCE]) ||
|
||||
(!values[STATE]) ||
|
||||
(!values[RUNNING_VMS]) ||
|
||||
(!values[TEMPLATE]) ||
|
||||
(num != LIMIT + 1))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
oss <<
|
||||
"<IMAGE>" <<
|
||||
"<ID>" << values[OID] << "</ID>" <<
|
||||
"<UID>" << values[UID] << "</UID>" <<
|
||||
"<USERNAME>" << values[LIMIT] << "</USERNAME>" <<
|
||||
"<NAME>" << values[NAME] << "</NAME>" <<
|
||||
"<TYPE>" << values[TYPE] << "</TYPE>" <<
|
||||
"<PUBLIC>" << values[PUBLIC] << "</PUBLIC>" <<
|
||||
"<PERSISTENT>" << values[PERSISTENT] << "</PERSISTENT>" <<
|
||||
"<REGTIME>" << values[REGTIME] << "</REGTIME>" <<
|
||||
"<SOURCE>" << values[SOURCE] << "</SOURCE>" <<
|
||||
"<STATE>" << values[STATE] << "</STATE>" <<
|
||||
"<RUNNING_VMS>" << values[RUNNING_VMS] << "</RUNNING_VMS>" <<
|
||||
values[TEMPLATE] <<
|
||||
"</IMAGE>";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Image::drop(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
// Only delete the VM
|
||||
if (running_vms != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
oss << "DELETE FROM " << table << " WHERE oid=" << oid;
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
set_valid(false);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* ************************************************************************ */
|
||||
/* Image :: Misc */
|
||||
/* ************************************************************************ */
|
||||
@ -458,6 +328,7 @@ string& Image::to_xml(string& xml) const
|
||||
"<IMAGE>" <<
|
||||
"<ID>" << oid << "</ID>" <<
|
||||
"<UID>" << uid << "</UID>" <<
|
||||
"<USERNAME>" << user_name << "</USERNAME>" <<
|
||||
"<NAME>" << name << "</NAME>" <<
|
||||
"<TYPE>" << type << "</TYPE>" <<
|
||||
"<PUBLIC>" << public_img << "</PUBLIC>" <<
|
||||
@ -477,30 +348,50 @@ string& Image::to_xml(string& xml) const
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
string& Image::to_str(string& str) const
|
||||
int Image::from_xml(const string& xml)
|
||||
{
|
||||
string template_str;
|
||||
vector<xmlNodePtr> content;
|
||||
int int_state;
|
||||
int int_type;
|
||||
|
||||
ostringstream os;
|
||||
int rc = 0;
|
||||
|
||||
os <<
|
||||
"ID = " << oid << endl <<
|
||||
"UID = " << uid << endl <<
|
||||
"NAME = " << name << endl <<
|
||||
"TYPE = " << type << endl <<
|
||||
"PUBLIC = " << public_img << endl <<
|
||||
"PERSISTENT = " << persistent_img << endl <<
|
||||
"REGTIME = " << regtime << endl <<
|
||||
"SOURCE = " << source << endl <<
|
||||
"STATE = " << state << endl <<
|
||||
"RUNNING_VMS = " << running_vms << endl <<
|
||||
"TEMPLATE" << endl
|
||||
<< image_template->to_str(template_str)
|
||||
<< endl;
|
||||
// Initialize the internal XML object
|
||||
update_from_str(xml);
|
||||
|
||||
str = os.str();
|
||||
// Get class base attributes
|
||||
rc += xpath(oid, "/IMAGE/ID", -1);
|
||||
rc += xpath(uid, "/IMAGE/UID", -1);
|
||||
rc += xpath(user_name, "/IMAGE/USERNAME", "not_found");
|
||||
rc += xpath(name, "/IMAGE/NAME", "not_found");
|
||||
|
||||
return str;
|
||||
rc += xpath(int_type, "/IMAGE/TYPE", 0);
|
||||
rc += xpath(public_img, "/IMAGE/PUBLIC", 0);
|
||||
rc += xpath(persistent_img, "/IMAGE/PERSISTENT", 0);
|
||||
rc += xpath(regtime, "/IMAGE/REGTIME", 0);
|
||||
|
||||
rc += xpath(source, "/IMAGE/SOURCE", "not_found");
|
||||
rc += xpath(int_state, "/IMAGE/STATE", 0);
|
||||
rc += xpath(running_vms, "/IMAGE/RUNNING_VMS", -1);
|
||||
|
||||
type = static_cast<ImageType>(int_type);
|
||||
state = static_cast<ImageState>(int_state);
|
||||
|
||||
// Get associated classes
|
||||
ObjectXML::get_nodes("/IMAGE/TEMPLATE", content);
|
||||
if( content.size() < 1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc += image_template->from_xml_node(content[0]);
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
@ -27,61 +27,30 @@ string ImagePool::_source_prefix;
|
||||
string ImagePool::_default_type;
|
||||
string ImagePool::_default_dev_prefix;
|
||||
|
||||
int ImagePool::init_cb(void *nil, int num, char **values, char **names)
|
||||
{
|
||||
if ( num == 0 || values == 0 || values[0] == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
image_names.insert(make_pair(values[1],atoi(values[0])));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
ImagePool::ImagePool( SqlDB * db,
|
||||
const string& __source_prefix,
|
||||
const string& __default_type,
|
||||
const string& __default_dev_prefix):
|
||||
|
||||
ImagePool::ImagePool(SqlDB * db,
|
||||
const string& __source_prefix,
|
||||
const string& __default_type,
|
||||
const string& __default_dev_prefix):
|
||||
PoolSQL(db,Image::table)
|
||||
{
|
||||
ostringstream sql;
|
||||
int rc;
|
||||
ostringstream sql;
|
||||
|
||||
// Init static defaults
|
||||
_source_prefix = __source_prefix;
|
||||
_default_type = __default_type;
|
||||
_default_dev_prefix = __default_dev_prefix;
|
||||
_source_prefix = __source_prefix;
|
||||
_default_type = __default_type;
|
||||
_default_dev_prefix = __default_dev_prefix;
|
||||
|
||||
// Set default type
|
||||
if (_default_type != "OS" &&
|
||||
_default_type != "CDROM" &&
|
||||
_default_type != "DATABLOCK" )
|
||||
{
|
||||
NebulaLog::log("IMG", Log::ERROR,
|
||||
"Bad default for image type, setting OS");
|
||||
NebulaLog::log("IMG", Log::ERROR, "Bad default for type, setting OS");
|
||||
_default_type = "OS";
|
||||
}
|
||||
|
||||
// Read from the DB the existing images, and build the ID:Name map
|
||||
set_callback(static_cast<Callbackable::Callback>(&ImagePool::init_cb));
|
||||
|
||||
sql << "SELECT oid, name FROM " << Image::table;
|
||||
|
||||
rc = db->exec(sql, this);
|
||||
|
||||
unset_callback();
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
NebulaLog::log("IMG", Log::ERROR,
|
||||
"Could not load the existing images from the DB.");
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -89,32 +58,57 @@ ImagePool::ImagePool( SqlDB * db,
|
||||
|
||||
int ImagePool::allocate (
|
||||
int uid,
|
||||
string user_name,
|
||||
ImageTemplate* img_template,
|
||||
int * oid,
|
||||
string& error_str)
|
||||
{
|
||||
Image * img;
|
||||
string name;
|
||||
Image * img;
|
||||
Image * img_aux;
|
||||
string name;
|
||||
ostringstream oss;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Build a new Image object
|
||||
// ---------------------------------------------------------------------
|
||||
img = new Image(uid,img_template);
|
||||
img = new Image(uid, user_name, img_template);
|
||||
|
||||
// Check name
|
||||
img->get_template_attribute("NAME", name);
|
||||
|
||||
if ( name.empty() )
|
||||
{
|
||||
goto error_name;
|
||||
}
|
||||
|
||||
// Check for duplicates
|
||||
img_aux = get(name,uid,false);
|
||||
|
||||
if( img_aux != 0 )
|
||||
{
|
||||
goto error_duplicated;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Insert the Object in the pool
|
||||
// ---------------------------------------------------------------------
|
||||
*oid = PoolSQL::allocate(img, error_str);
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Add the image name to the map of image_names
|
||||
// ---------------------------------------------------------------------
|
||||
if ( *oid != -1 )
|
||||
{
|
||||
image_names.insert(make_pair(name, *oid));
|
||||
}
|
||||
return *oid;
|
||||
|
||||
|
||||
error_name:
|
||||
oss << "NAME cannot be empty.";
|
||||
goto error_common;
|
||||
|
||||
error_duplicated:
|
||||
oss << "NAME is already taken by IMAGE " << img_aux->get_oid() << ".";
|
||||
|
||||
error_common:
|
||||
delete img;
|
||||
|
||||
*oid = -1;
|
||||
error_str = oss.str();
|
||||
|
||||
return *oid;
|
||||
}
|
||||
@ -122,54 +116,11 @@ int ImagePool::allocate (
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ImagePool::dump_cb(void * _oss, int num, char **values, char **names)
|
||||
{
|
||||
ostringstream * oss;
|
||||
|
||||
oss = static_cast<ostringstream *>(_oss);
|
||||
|
||||
return Image::dump(*oss, num, values, names);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ImagePool::dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
int rc;
|
||||
ostringstream cmd;
|
||||
|
||||
oss << "<IMAGE_POOL>";
|
||||
|
||||
set_callback(static_cast<Callbackable::Callback>(&ImagePool::dump_cb),
|
||||
static_cast<void *>(&oss));
|
||||
|
||||
cmd << "SELECT "<< Image::extended_db_names << ", user_pool.user_name FROM "
|
||||
<< Image::table
|
||||
<< " LEFT OUTER JOIN (SELECT oid, user_name FROM user_pool) "
|
||||
<< "AS user_pool ON " << Image::table << ".uid = user_pool.oid";
|
||||
|
||||
if ( !where.empty() )
|
||||
{
|
||||
cmd << " WHERE " << where;
|
||||
}
|
||||
|
||||
rc = db->exec(cmd, this);
|
||||
|
||||
oss << "</IMAGE_POOL>";
|
||||
|
||||
unset_callback();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ImagePool::disk_attribute(VectorAttribute * disk,
|
||||
int disk_id,
|
||||
int * index,
|
||||
Image::ImageType * img_type)
|
||||
Image::ImageType * img_type,
|
||||
int uid)
|
||||
{
|
||||
string source;
|
||||
Image * img = 0;
|
||||
@ -204,7 +155,7 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
|
||||
}
|
||||
else
|
||||
{
|
||||
img = get(source,true);
|
||||
img = get(source,uid,true);
|
||||
|
||||
if (img == 0)
|
||||
{
|
||||
@ -255,7 +206,7 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void ImagePool::authorize_disk(VectorAttribute * disk, AuthRequest * ar)
|
||||
void ImagePool::authorize_disk(VectorAttribute * disk,int uid, AuthRequest * ar)
|
||||
{
|
||||
string source;
|
||||
Image * img = 0;
|
||||
@ -284,7 +235,7 @@ void ImagePool::authorize_disk(VectorAttribute * disk, AuthRequest * ar)
|
||||
}
|
||||
else
|
||||
{
|
||||
img = get(source,true);
|
||||
img = get(source,uid,true);
|
||||
}
|
||||
|
||||
if (img == 0)
|
||||
@ -293,7 +244,7 @@ void ImagePool::authorize_disk(VectorAttribute * disk, AuthRequest * ar)
|
||||
}
|
||||
|
||||
ar->add_auth(AuthRequest::IMAGE,
|
||||
img->get_iid(),
|
||||
img->get_oid(),
|
||||
AuthRequest::USE,
|
||||
img->get_uid(),
|
||||
img->isPublic());
|
||||
|
@ -24,6 +24,7 @@
|
||||
using namespace std;
|
||||
|
||||
const int uids[] = {0,1,2};
|
||||
const string user_names[] = {"A user","B user","C user"};
|
||||
|
||||
const string names[] = {"Image one", "Second Image", "The third image"};
|
||||
|
||||
@ -49,19 +50,19 @@ const string templates[] =
|
||||
|
||||
const string xmls[] =
|
||||
{
|
||||
"<IMAGE><ID>0</ID><UID>0</UID><NAME>Image one</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>1</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a very long description of an image, and to achieve the longness I will copy this over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over.This is a very long description of an image, and to achieve the longness I will copy this over.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Image one]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE>",
|
||||
"<IMAGE><ID>0</ID><UID>0</UID><USERNAME>A user</USERNAME><NAME>Image one</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>1</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a very long description of an image, and to achieve the longness I will copy this over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over.This is a very long description of an image, and to achieve the longness I will copy this over.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Image one]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE>",
|
||||
|
||||
"<IMAGE><ID>1</ID><UID>1</UID><NAME>Second Image</NAME><TYPE>0</TYPE><PUBLIC>1</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f3</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a rather short description.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Second Image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_second_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE>",
|
||||
"<IMAGE><ID>1</ID><UID>1</UID><USERNAME>B user</USERNAME><NAME>Second Image</NAME><TYPE>0</TYPE><PUBLIC>1</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f3</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a rather short description.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Second Image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_second_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE>",
|
||||
|
||||
"<IMAGE><ID>0</ID><UID>2</UID><NAME>The third image</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/e50b0c738be9d431475bf5859629e5580301a7d6</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><BUS><![CDATA[SCSI]]></BUS><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[The third image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH><PROFILE><![CDATA[STUDENT]]></PROFILE></TEMPLATE></IMAGE>"
|
||||
"<IMAGE><ID>0</ID><UID>2</UID><USERNAME>C user</USERNAME><NAME>The third image</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/e50b0c738be9d431475bf5859629e5580301a7d6</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><BUS><![CDATA[SCSI]]></BUS><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[The third image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH><PROFILE><![CDATA[STUDENT]]></PROFILE></TEMPLATE></IMAGE>"
|
||||
};
|
||||
|
||||
|
||||
// This xml dump result has the STIMEs modified to 0000000000
|
||||
const string xml_dump =
|
||||
"<IMAGE_POOL><IMAGE><ID>0</ID><UID>0</UID><USERNAME>one_user_test</USERNAME><NAME>Image one</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>1</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a very long description of an image, and to achieve the longness I will copy this over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over.This is a very long description of an image, and to achieve the longness I will copy this over.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Image one]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE><IMAGE><ID>1</ID><UID>1</UID><USERNAME>A user</USERNAME><NAME>Second Image</NAME><TYPE>0</TYPE><PUBLIC>1</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f3</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a rather short description.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Second Image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_second_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE><IMAGE><ID>2</ID><UID>2</UID><USERNAME>B user</USERNAME><NAME>The third image</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/e50b0c738be9d431475bf5859629e5580301a7d6</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><BUS><![CDATA[SCSI]]></BUS><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[The third image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH><PROFILE><![CDATA[STUDENT]]></PROFILE></TEMPLATE></IMAGE></IMAGE_POOL>";
|
||||
"<IMAGE_POOL><IMAGE><ID>0</ID><UID>0</UID><USERNAME>A user</USERNAME><NAME>Image one</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>1</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a very long description of an image, and to achieve the longness I will copy this over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over.This is a very long description of an image, and to achieve the longness I will copy this over.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Image one]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE><IMAGE><ID>1</ID><UID>1</UID><USERNAME>B user</USERNAME><NAME>Second Image</NAME><TYPE>0</TYPE><PUBLIC>1</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f3</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a rather short description.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Second Image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_second_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE><IMAGE><ID>2</ID><UID>2</UID><USERNAME>C user</USERNAME><NAME>The third image</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/e50b0c738be9d431475bf5859629e5580301a7d6</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><BUS><![CDATA[SCSI]]></BUS><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[The third image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH><PROFILE><![CDATA[STUDENT]]></PROFILE></TEMPLATE></IMAGE></IMAGE_POOL>";
|
||||
const string xml_dump_where =
|
||||
"<IMAGE_POOL><IMAGE><ID>0</ID><UID>0</UID><USERNAME>one_user_test</USERNAME><NAME>Image one</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>1</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a very long description of an image, and to achieve the longness I will copy this over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over.This is a very long description of an image, and to achieve the longness I will copy this over.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Image one]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE><IMAGE><ID>1</ID><UID>1</UID><USERNAME>A user</USERNAME><NAME>Second Image</NAME><TYPE>0</TYPE><PUBLIC>1</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f3</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a rather short description.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Second Image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_second_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE></IMAGE_POOL>";
|
||||
"<IMAGE_POOL><IMAGE><ID>0</ID><UID>0</UID><USERNAME>A user</USERNAME><NAME>Image one</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>1</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a very long description of an image, and to achieve the longness I will copy this over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over.This is a very long description of an image, and to achieve the longness I will copy this over.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Image one]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE><IMAGE><ID>1</ID><UID>1</UID><USERNAME>B user</USERNAME><NAME>Second Image</NAME><TYPE>0</TYPE><PUBLIC>1</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f3</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a rather short description.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Second Image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_second_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE></IMAGE_POOL>";
|
||||
|
||||
const string replacement = "0000000000";
|
||||
|
||||
@ -91,7 +92,7 @@ public:
|
||||
|
||||
if( rc == 0 )
|
||||
{
|
||||
return ImagePool::allocate(uid, img_template, oid, err);
|
||||
return ImagePool::allocate(uid, user_names[uid], img_template, oid, err);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -167,33 +168,17 @@ protected:
|
||||
((Image*)obj)->to_xml(xml_str);
|
||||
xml_str.replace( xml_str.find("<REGTIME>")+9, 10, replacement);
|
||||
|
||||
//cout << endl << xml_str << endl << xmls[index] << endl;
|
||||
/*
|
||||
if( xml_str != xmls[index] )
|
||||
{
|
||||
cout << endl << xml_str << endl << xmls[index] << endl;
|
||||
}
|
||||
//*/
|
||||
|
||||
CPPUNIT_ASSERT( ((Image*)obj)->get_name() == names[index] );
|
||||
CPPUNIT_ASSERT( xml_str == xmls[index]);
|
||||
};
|
||||
|
||||
void set_up_user_pool()
|
||||
{
|
||||
string err;
|
||||
|
||||
UserPool::bootstrap(db);
|
||||
UserPool * user_pool = new UserPool(db);
|
||||
int uid_1, uid_2;
|
||||
|
||||
string username_1 = "A user";
|
||||
string username_2 = "B user";
|
||||
|
||||
string pass_1 = "A pass";
|
||||
string pass_2 = "B pass";
|
||||
|
||||
user_pool->allocate(&uid_1, username_1, pass_1, true, err);
|
||||
user_pool->allocate(&uid_2, username_2, pass_2, true, err);
|
||||
|
||||
delete user_pool;
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
ImagePoolTest(){xmlInitParser();};
|
||||
|
||||
@ -207,7 +192,7 @@ public:
|
||||
ImagePool * imp;
|
||||
Image * img;
|
||||
|
||||
// Allocate 2 users, so they are written to the DB.
|
||||
// Allocate 2 images, so they are written to the DB.
|
||||
allocate(0);
|
||||
allocate(2);
|
||||
|
||||
@ -215,13 +200,13 @@ public:
|
||||
// allocated images.
|
||||
imp = new ImagePool(db, "source_prefix", "OS", "hd");
|
||||
|
||||
img = imp->get(names[0], false);
|
||||
img = imp->get(names[0], uids[0], false);
|
||||
CPPUNIT_ASSERT( img != 0 );
|
||||
|
||||
img = imp->get(names[1], false);
|
||||
img = imp->get(names[1], uids[1], false);
|
||||
CPPUNIT_ASSERT( img == 0 );
|
||||
|
||||
img = imp->get(names[2], false);
|
||||
img = imp->get(names[2], uids[2], false);
|
||||
CPPUNIT_ASSERT( img != 0 );
|
||||
|
||||
|
||||
@ -312,7 +297,7 @@ public:
|
||||
check(0, obj);
|
||||
|
||||
// Get using its name
|
||||
obj = imp->get(names[1], true);
|
||||
obj = imp->get(names[1], uids[1], true);
|
||||
CPPUNIT_ASSERT( obj != 0 );
|
||||
obj->unlock();
|
||||
|
||||
@ -324,7 +309,7 @@ public:
|
||||
pool->clean();
|
||||
|
||||
// Get first object and check its integrity
|
||||
obj = imp->get(names[0], false);
|
||||
obj = imp->get(names[0], uids[0], false);
|
||||
check(0, obj);
|
||||
|
||||
// Get using its name
|
||||
@ -341,14 +326,14 @@ public:
|
||||
|
||||
// The pool is empty
|
||||
// Non existing name
|
||||
obj = imp->get("Wrong name", true);
|
||||
obj = imp->get("Wrong name", 0, true);
|
||||
CPPUNIT_ASSERT( obj == 0 );
|
||||
|
||||
// Allocate an object
|
||||
allocate(0);
|
||||
|
||||
// Ask again for a non-existing name
|
||||
obj = imp->get("Non existing name", true);
|
||||
obj = imp->get("Non existing name",uids[0], true);
|
||||
CPPUNIT_ASSERT( obj == 0 );
|
||||
}
|
||||
|
||||
@ -370,9 +355,9 @@ public:
|
||||
CPPUNIT_ASSERT( rc == -1 );
|
||||
CPPUNIT_ASSERT( oid == rc );
|
||||
|
||||
// Try again, with different uid
|
||||
// Try again, this time with different uid. Should be allowed
|
||||
rc = imp->allocate(uids[1], templates[0], &oid);
|
||||
CPPUNIT_ASSERT( rc == -1 );
|
||||
CPPUNIT_ASSERT( rc >= 0 );
|
||||
CPPUNIT_ASSERT( oid == rc );
|
||||
}
|
||||
|
||||
@ -487,6 +472,7 @@ public:
|
||||
CPPUNIT_ASSERT(oid >= 0);
|
||||
|
||||
img = imp->get(oid, false);
|
||||
CPPUNIT_ASSERT( img != 0 );
|
||||
|
||||
img->enable(true);
|
||||
img->disk_attribute(disk, &index, &img_type);
|
||||
@ -508,6 +494,7 @@ public:
|
||||
CPPUNIT_ASSERT(oid >= 0);
|
||||
|
||||
img = imp->get(oid, false);
|
||||
CPPUNIT_ASSERT( img != 0 );
|
||||
|
||||
img->enable(true);
|
||||
img->disk_attribute(disk, &index, &img_type);
|
||||
@ -529,6 +516,7 @@ public:
|
||||
CPPUNIT_ASSERT(oid >= 0);
|
||||
|
||||
img = imp->get(oid, false);
|
||||
CPPUNIT_ASSERT( img != 0 );
|
||||
|
||||
img->enable(true);
|
||||
img->disk_attribute(disk, &index, &img_type);
|
||||
@ -557,6 +545,7 @@ public:
|
||||
// Allocate an OS type image
|
||||
oid = allocate(0);
|
||||
img = imp->get(oid, false);
|
||||
CPPUNIT_ASSERT( img != 0 );
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// A disk without a BUS attribute should not have it added.
|
||||
@ -643,7 +632,7 @@ public:
|
||||
disk = new VectorAttribute("DISK");
|
||||
disk->replace("IMAGE", "Image 0");
|
||||
|
||||
((ImagePool*)imp)->disk_attribute(disk, 0, &index, &img_type);
|
||||
((ImagePool*)imp)->disk_attribute(disk, 0, &index, &img_type,0);
|
||||
|
||||
value = "";
|
||||
value = disk->vector_value("TARGET");
|
||||
@ -660,7 +649,7 @@ public:
|
||||
disk = new VectorAttribute("DISK");
|
||||
disk->replace("IMAGE_ID", "1");
|
||||
|
||||
((ImagePool*)imp)->disk_attribute(disk, 0, &index, &img_type);
|
||||
((ImagePool*)imp)->disk_attribute(disk, 0, &index, &img_type,0);
|
||||
|
||||
value = "";
|
||||
value = disk->vector_value("TARGET");
|
||||
@ -865,8 +854,6 @@ public:
|
||||
int rc;
|
||||
string nan;
|
||||
|
||||
set_up_user_pool();
|
||||
|
||||
allocate(0);
|
||||
allocate(1);
|
||||
allocate(2);
|
||||
@ -876,9 +863,16 @@ public:
|
||||
|
||||
string result = oss.str();
|
||||
|
||||
result.replace(164, 10, replacement);
|
||||
result.replace(1154, 10, replacement);
|
||||
result.replace(1684, 10, replacement);
|
||||
result.replace(157, 10, replacement);
|
||||
result.replace(1147, 10, replacement);
|
||||
result.replace(1677, 10, replacement);
|
||||
|
||||
/*
|
||||
if( result != xml_dump )
|
||||
{
|
||||
cout << endl << result << endl << xml_dump << endl;
|
||||
}
|
||||
//*/
|
||||
|
||||
CPPUNIT_ASSERT( result == xml_dump );
|
||||
}
|
||||
@ -894,8 +888,6 @@ public:
|
||||
ostringstream oss;
|
||||
ostringstream where;
|
||||
|
||||
set_up_user_pool();
|
||||
|
||||
allocate(0);
|
||||
allocate(1);
|
||||
allocate(2);
|
||||
@ -906,8 +898,15 @@ public:
|
||||
CPPUNIT_ASSERT(rc == 0);
|
||||
|
||||
string result = oss.str();
|
||||
result.replace(164, 10, replacement);
|
||||
result.replace(1154, 10, replacement);
|
||||
result.replace(157, 10, replacement);
|
||||
result.replace(1147, 10, replacement);
|
||||
|
||||
/*
|
||||
if( result != xml_dump_where )
|
||||
{
|
||||
cout << endl << result << endl << xml_dump_where << endl;
|
||||
}
|
||||
//*/
|
||||
|
||||
CPPUNIT_ASSERT( result == xml_dump_where );
|
||||
}
|
||||
@ -921,7 +920,5 @@ public:
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
OneUnitTest::set_one_auth();
|
||||
|
||||
return PoolTest::main(argc, argv, ImagePoolTest::suite());
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ env.Prepend(LIBS=[
|
||||
'nebula_core',
|
||||
'nebula_sql',
|
||||
'nebula_log',
|
||||
'nebula_xml',
|
||||
'crypto'
|
||||
])
|
||||
|
||||
|
@ -185,7 +185,7 @@ private:
|
||||
|
||||
if( rc == 0 )
|
||||
{
|
||||
return vmpool->allocate(uids[index], vm_template, &oid,
|
||||
return vmpool->allocate(uids[index], "username", vm_template, &oid,
|
||||
err, false);
|
||||
}
|
||||
else
|
||||
|
@ -21,6 +21,7 @@ Import('env')
|
||||
env.Prepend(LIBS=[
|
||||
'nebula_core_test',
|
||||
'nebula_host',
|
||||
'nebula_cluster',
|
||||
'nebula_vmm',
|
||||
'nebula_im',
|
||||
'nebula_rm',
|
||||
@ -32,6 +33,7 @@ env.Prepend(LIBS=[
|
||||
'nebula_vnm',
|
||||
'nebula_image',
|
||||
'nebula_pool',
|
||||
'nebula_xml',
|
||||
'nebula_hm',
|
||||
'nebula_authm',
|
||||
'nebula_common',
|
||||
|
@ -234,6 +234,7 @@ void Nebula::start()
|
||||
VirtualNetworkPool::bootstrap(db);
|
||||
UserPool::bootstrap(db);
|
||||
ImagePool::bootstrap(db);
|
||||
ClusterPool::bootstrap(db);
|
||||
}
|
||||
catch (exception&)
|
||||
{
|
||||
@ -273,6 +274,8 @@ void Nebula::start()
|
||||
repository_path,
|
||||
default_image_type,
|
||||
default_device_prefix);
|
||||
|
||||
cpool = new ClusterPool(db);
|
||||
}
|
||||
catch (exception&)
|
||||
{
|
||||
@ -438,6 +441,7 @@ void Nebula::start()
|
||||
vnpool,
|
||||
upool,
|
||||
ipool,
|
||||
cpool,
|
||||
rm_port,
|
||||
log_location + "one_xmlrpc.log");
|
||||
}
|
||||
|
@ -46,12 +46,14 @@ env.Prepend(LIBS=[
|
||||
'nebula_template',
|
||||
'nebula_image',
|
||||
'nebula_pool',
|
||||
'nebula_cluster',
|
||||
'nebula_host',
|
||||
'nebula_vnm',
|
||||
'nebula_vm',
|
||||
'nebula_common',
|
||||
'nebula_sql',
|
||||
'nebula_log',
|
||||
'nebula_xml',
|
||||
'crypto'
|
||||
])
|
||||
|
||||
|
110
src/pool/PoolObjectSQL.cc
Normal file
110
src/pool/PoolObjectSQL.cc
Normal file
@ -0,0 +1,110 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
||||
/* not use this file except in compliance with the License. You may obtain */
|
||||
/* a copy of the License at */
|
||||
/* */
|
||||
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* */
|
||||
/* Unless required by applicable law or agreed to in writing, software */
|
||||
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
||||
/* See the License for the specific language governing permissions and */
|
||||
/* limitations under the License. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "PoolObjectSQL.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int PoolObjectSQL::select(SqlDB *db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
int boid;
|
||||
|
||||
set_callback(
|
||||
static_cast<Callbackable::Callback>(&PoolObjectSQL::select_cb));
|
||||
|
||||
oss << "SELECT body FROM " << table << " WHERE oid = " << oid;
|
||||
|
||||
boid = oid;
|
||||
oid = -1;
|
||||
|
||||
rc = db->exec(oss, this);
|
||||
|
||||
unset_callback();
|
||||
|
||||
if ((rc != 0) || (oid != boid ))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int PoolObjectSQL::select(SqlDB *db, const string& _name, int _uid)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
int rc;
|
||||
char * sql_name;
|
||||
|
||||
sql_name = db->escape_str(_name.c_str());
|
||||
|
||||
if ( sql_name == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
set_callback(
|
||||
static_cast<Callbackable::Callback>(&PoolObjectSQL::select_cb));
|
||||
|
||||
oss << "SELECT body FROM " << table << " WHERE name = '" <<_name << "'";
|
||||
|
||||
if ( _uid != -1 )
|
||||
{
|
||||
oss << " AND uid = " << _uid;
|
||||
}
|
||||
|
||||
name = "";
|
||||
uid = -1;
|
||||
|
||||
rc = db->exec(oss, this);
|
||||
|
||||
unset_callback();
|
||||
|
||||
db->free_str(sql_name);
|
||||
|
||||
if ((rc != 0) || (_name != name) || (_uid != uid))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int PoolObjectSQL::drop(SqlDB *db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
oss << "DELETE FROM " << table << " WHERE oid=" << oid;
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
set_valid(false);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
@ -86,6 +86,7 @@ PoolSQL::~PoolSQL()
|
||||
pthread_mutex_destroy(&mutex);
|
||||
}
|
||||
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* PoolSQL public interface */
|
||||
/* ************************************************************************** */
|
||||
@ -185,7 +186,82 @@ PoolObjectSQL * PoolSQL::get(
|
||||
return 0;
|
||||
}
|
||||
|
||||
string okey = key(objectsql->name,objectsql->uid);
|
||||
|
||||
pool.insert(make_pair(objectsql->oid,objectsql));
|
||||
name_pool.insert(make_pair(okey, objectsql));
|
||||
|
||||
if ( olock == true )
|
||||
{
|
||||
objectsql->lock();
|
||||
}
|
||||
|
||||
oid_queue.push(objectsql->oid);
|
||||
|
||||
if ( pool.size() > MAX_POOL_SIZE )
|
||||
{
|
||||
replace();
|
||||
}
|
||||
|
||||
unlock();
|
||||
|
||||
return objectsql;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
PoolObjectSQL * PoolSQL::get(const string& name, int ouid, bool olock)
|
||||
{
|
||||
map<string,PoolObjectSQL *>::iterator index;
|
||||
|
||||
PoolObjectSQL * objectsql;
|
||||
int rc;
|
||||
|
||||
lock();
|
||||
|
||||
index = name_pool.find(key(name,ouid));
|
||||
|
||||
if ( index != name_pool.end() )
|
||||
{
|
||||
if ( index->second->isValid() == false )
|
||||
{
|
||||
objectsql = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
objectsql = index->second;
|
||||
|
||||
if ( olock == true )
|
||||
{
|
||||
objectsql->lock();
|
||||
}
|
||||
}
|
||||
|
||||
unlock();
|
||||
|
||||
return objectsql;
|
||||
}
|
||||
else
|
||||
{
|
||||
objectsql = create();
|
||||
|
||||
rc = objectsql->select(db,name,ouid);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
delete objectsql;
|
||||
|
||||
unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
string okey = key(objectsql->name,objectsql->uid);
|
||||
|
||||
pool.insert(make_pair(objectsql->oid, objectsql));
|
||||
name_pool.insert(make_pair(okey, objectsql));
|
||||
|
||||
if ( olock == true )
|
||||
{
|
||||
@ -236,10 +312,11 @@ void PoolSQL::replace()
|
||||
}
|
||||
else
|
||||
{
|
||||
PoolObjectSQL * tmp_ptr;
|
||||
PoolObjectSQL * tmp_ptr = index->second;
|
||||
string okey = key(tmp_ptr->name,tmp_ptr->uid);
|
||||
|
||||
tmp_ptr = index->second;
|
||||
pool.erase(index);
|
||||
name_pool.erase(okey);
|
||||
|
||||
delete tmp_ptr;
|
||||
|
||||
@ -266,12 +343,63 @@ void PoolSQL::clean()
|
||||
}
|
||||
|
||||
pool.clear();
|
||||
name_pool.clear();
|
||||
|
||||
unlock();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int PoolSQL::dump_cb(void * _oss, int num, char **values, char **names)
|
||||
{
|
||||
ostringstream * oss;
|
||||
|
||||
oss = static_cast<ostringstream *>(_oss);
|
||||
|
||||
if ( (!values[0]) || (num != 1) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
*oss << values[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int PoolSQL::dump(ostringstream& oss,
|
||||
const string& elem_name,
|
||||
const char * table,
|
||||
const string& where)
|
||||
{
|
||||
int rc;
|
||||
ostringstream cmd;
|
||||
|
||||
oss << "<" << elem_name << ">";
|
||||
|
||||
set_callback(static_cast<Callbackable::Callback>(&PoolSQL::dump_cb),
|
||||
static_cast<void *>(&oss));
|
||||
|
||||
cmd << "SELECT body FROM " << table;
|
||||
|
||||
if ( !where.empty() )
|
||||
{
|
||||
cmd << " WHERE " << where;
|
||||
}
|
||||
|
||||
rc = db->exec(cmd, this);
|
||||
|
||||
oss << "</" << elem_name << ">";
|
||||
|
||||
unset_callback();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int PoolSQL:: search_cb(void * _oids, int num, char **values, char **names)
|
||||
{
|
||||
vector<int> * oids;
|
||||
@ -309,3 +437,4 @@ int PoolSQL::search(
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,8 @@ lib_name='nebula_pool'
|
||||
|
||||
# Sources to generate the library
|
||||
source_files=[
|
||||
'PoolSQL.cc'
|
||||
'PoolSQL.cc',
|
||||
'PoolObjectSQL.cc'
|
||||
]
|
||||
|
||||
# Build library
|
||||
|
@ -23,6 +23,7 @@ env.Append(LIBPATH=[
|
||||
|
||||
env.Prepend(LIBS=[
|
||||
'nebula_pool',
|
||||
'nebula_xml',
|
||||
'nebula_common',
|
||||
'nebula_log',
|
||||
'nebula_core',
|
||||
|
@ -32,10 +32,10 @@
|
||||
|
||||
const char * TestObjectSQL::table = "test_pool";
|
||||
|
||||
const char * TestObjectSQL::db_names = "(oid,number,text)";
|
||||
const char * TestObjectSQL::db_names = "(oid,number,name)";
|
||||
|
||||
const char * TestObjectSQL::db_bootstrap = "CREATE TABLE test_pool ("
|
||||
"oid INTEGER, number INTEGER, text TEXT, PRIMARY KEY(oid))";
|
||||
"oid INTEGER, number INTEGER, name TEXT, PRIMARY KEY(oid))";
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
@ -30,7 +30,7 @@ class TestObjectSQL : public PoolObjectSQL
|
||||
{
|
||||
public:
|
||||
//OBJECT ATTRIBUTES
|
||||
TestObjectSQL(int n=-1, string t="default"):number(n),text(t){};
|
||||
TestObjectSQL(int n=-1, string t="default"):PoolObjectSQL(-1,"",0,0),number(n),text(t){};
|
||||
|
||||
~TestObjectSQL(){};
|
||||
|
||||
@ -71,6 +71,16 @@ public:
|
||||
|
||||
db->exec(oss,0);
|
||||
};
|
||||
|
||||
string& to_xml(string& xml) const
|
||||
{
|
||||
return xml;
|
||||
};
|
||||
|
||||
int from_xml(const string &xml_str)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
};
|
||||
|
||||
// THE POOL
|
||||
|
@ -141,7 +141,7 @@ public:
|
||||
|
||||
vector<int> results;
|
||||
const char * table = "test_pool";
|
||||
string where = "text = '" + stB + "'";
|
||||
string where = "name = '" + stB + "'";
|
||||
int ret;
|
||||
|
||||
ret = pool->search(results, table, where);
|
||||
@ -205,4 +205,4 @@ public:
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
return OneUnitTest::main(argc, argv, PoolTest::suite());
|
||||
}
|
||||
}
|
||||
|
@ -250,22 +250,22 @@ void RequestManager::register_xml_methods()
|
||||
RequestManager::HostEnable(hpool,upool));
|
||||
|
||||
xmlrpc_c::methodPtr cluster_allocate(new
|
||||
RequestManager::ClusterAllocate(hpool,upool));
|
||||
RequestManager::ClusterAllocate(upool,cpool));
|
||||
|
||||
xmlrpc_c::methodPtr cluster_info(new
|
||||
RequestManager::ClusterInfo(hpool,upool));
|
||||
RequestManager::ClusterInfo(upool,cpool));
|
||||
|
||||
xmlrpc_c::methodPtr cluster_delete(new
|
||||
RequestManager::ClusterDelete(hpool,upool));
|
||||
RequestManager::ClusterDelete(upool,cpool));
|
||||
|
||||
xmlrpc_c::methodPtr cluster_add(new
|
||||
RequestManager::ClusterAdd(hpool,upool));
|
||||
RequestManager::ClusterAdd(hpool,upool,cpool));
|
||||
|
||||
xmlrpc_c::methodPtr cluster_remove(new
|
||||
RequestManager::ClusterRemove(hpool,upool));
|
||||
RequestManager::ClusterRemove(hpool,upool,cpool));
|
||||
|
||||
xmlrpc_c::methodPtr clusterpool_info(new
|
||||
RequestManager::ClusterPoolInfo(hpool,upool));
|
||||
RequestManager::ClusterPoolInfo(upool,cpool));
|
||||
|
||||
xmlrpc_c::methodPtr vn_allocate(new
|
||||
RequestManager::VirtualNetworkAllocate(vnpool,upool));
|
||||
@ -300,6 +300,9 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::methodPtr user_change_password(new
|
||||
RequestManager::UserChangePassword(upool));
|
||||
|
||||
xmlrpc_c::methodPtr user_authenticate(new
|
||||
RequestManager::UserAuthenticate(upool));
|
||||
|
||||
xmlrpc_c::methodPtr userpool_info(new
|
||||
RequestManager::UserPoolInfo(upool));
|
||||
|
||||
@ -378,6 +381,7 @@ void RequestManager::register_xml_methods()
|
||||
RequestManagerRegistry.addMethod("one.user.delete", user_delete);
|
||||
RequestManagerRegistry.addMethod("one.user.info", user_info);
|
||||
RequestManagerRegistry.addMethod("one.user.passwd", user_change_password);
|
||||
RequestManagerRegistry.addMethod("one.user.authenticate",user_authenticate);
|
||||
|
||||
RequestManagerRegistry.addMethod("one.userpool.info", userpool_info);
|
||||
|
||||
|
@ -29,6 +29,7 @@ void RequestManager::VirtualMachineAllocate::execute(
|
||||
string session;
|
||||
string str_template;
|
||||
string error_str;
|
||||
string user_name;
|
||||
|
||||
const string method_name = "VirtualMachineAllocate";
|
||||
|
||||
@ -41,6 +42,7 @@ void RequestManager::VirtualMachineAllocate::execute(
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
VirtualMachineTemplate * vm_template;
|
||||
User * user;
|
||||
char * error_msg = 0;
|
||||
|
||||
int num;
|
||||
@ -92,7 +94,7 @@ void RequestManager::VirtualMachineAllocate::execute(
|
||||
continue;
|
||||
}
|
||||
|
||||
VirtualMachineAllocate::ipool->authorize_disk(vector,&ar);
|
||||
VirtualMachineAllocate::ipool->authorize_disk(vector,uid,&ar);
|
||||
}
|
||||
|
||||
vectors.clear();
|
||||
@ -108,7 +110,7 @@ void RequestManager::VirtualMachineAllocate::execute(
|
||||
continue;
|
||||
}
|
||||
|
||||
VirtualMachineAllocate::vnpool->authorize_nic(vector,&ar);
|
||||
VirtualMachineAllocate::vnpool->authorize_nic(vector,uid,&ar);
|
||||
}
|
||||
|
||||
ar.add_auth(AuthRequest::VM,
|
||||
@ -123,10 +125,26 @@ void RequestManager::VirtualMachineAllocate::execute(
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Get the User Name
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
user = VirtualMachineAllocate::upool->get(uid,true);
|
||||
|
||||
if ( user == 0 )
|
||||
{
|
||||
goto error_user_get;
|
||||
}
|
||||
|
||||
user_name = user->get_name();
|
||||
|
||||
user->unlock();
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Allocate the VirtualMAchine
|
||||
//--------------------------------------------------------------------------
|
||||
rc = VirtualMachineAllocate::vmpool->allocate(uid,
|
||||
user_name,
|
||||
vm_template,
|
||||
&vid,
|
||||
error_str,
|
||||
@ -147,6 +165,13 @@ void RequestManager::VirtualMachineAllocate::execute(
|
||||
|
||||
return;
|
||||
|
||||
|
||||
error_user_get:
|
||||
oss.str(get_error(method_name, "USER", uid));
|
||||
|
||||
delete vm_template;
|
||||
goto error_common;
|
||||
|
||||
error_authenticate:
|
||||
oss.str(authenticate_error(method_name));
|
||||
goto error_common;
|
||||
|
@ -34,7 +34,8 @@ void RequestManager::ClusterAdd::execute(
|
||||
|
||||
const string method_name = "ClusterAdd";
|
||||
|
||||
Host * host;
|
||||
Host * host;
|
||||
Cluster * cluster;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
@ -71,6 +72,14 @@ void RequestManager::ClusterAdd::execute(
|
||||
}
|
||||
}
|
||||
|
||||
// Check if cluster exists
|
||||
cluster = ClusterAdd::cpool->get(clid,true);
|
||||
|
||||
if ( cluster == 0 )
|
||||
{
|
||||
goto error_cluster_get;
|
||||
}
|
||||
|
||||
// Check if host exists
|
||||
host = ClusterAdd::hpool->get(hid,true);
|
||||
|
||||
@ -80,7 +89,7 @@ void RequestManager::ClusterAdd::execute(
|
||||
}
|
||||
|
||||
// Set cluster
|
||||
rc = ClusterAdd::hpool->set_cluster(host, clid);
|
||||
rc = host->set_cluster(cluster->get_name());
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
@ -92,6 +101,8 @@ void RequestManager::ClusterAdd::execute(
|
||||
|
||||
host->unlock();
|
||||
|
||||
cluster->unlock();
|
||||
|
||||
// All nice, return success to the client
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS
|
||||
|
||||
@ -112,11 +123,17 @@ error_authorize:
|
||||
goto error_common;
|
||||
|
||||
error_host_get:
|
||||
cluster->unlock();
|
||||
oss.str(get_error(method_name, "HOST", hid));
|
||||
goto error_common;
|
||||
|
||||
error_cluster_get:
|
||||
oss.str(get_error(method_name, "CLUSTER", clid));
|
||||
goto error_common;
|
||||
|
||||
error_cluster_add:
|
||||
host->unlock();
|
||||
cluster->unlock();
|
||||
oss.str(action_error(method_name, "USE", "CLUSTER", clid, rc));
|
||||
goto error_common;
|
||||
|
||||
|
@ -69,7 +69,7 @@ void RequestManager::ClusterAllocate::execute(
|
||||
}
|
||||
|
||||
// Perform the allocation in the hostpool
|
||||
rc = ClusterAllocate::hpool->allocate_cluster(&id, clustername, error_str);
|
||||
rc = ClusterAllocate::cpool->allocate(&id, clustername, error_str);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
|
@ -26,14 +26,14 @@ void RequestManager::ClusterDelete::execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
string session;
|
||||
|
||||
// <clid> of the cluster to delete from the HostPool
|
||||
int clid;
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
int clid;
|
||||
Cluster * cluster;
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
const string method_name = "ClusterDelete";
|
||||
const string method_name = "ClusterDelete";
|
||||
|
||||
/* -- RPC specific vars -- */
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
@ -66,7 +66,17 @@ void RequestManager::ClusterDelete::execute(
|
||||
}
|
||||
}
|
||||
|
||||
rc = ClusterDelete::hpool->drop_cluster(clid);
|
||||
// Perform the deletion from the pool
|
||||
cluster = ClusterDelete::cpool->get(clid,true);
|
||||
|
||||
if ( cluster == 0 )
|
||||
{
|
||||
goto error_cluster_get;
|
||||
}
|
||||
|
||||
rc = ClusterDelete::cpool->drop(cluster);
|
||||
|
||||
cluster->unlock();
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
@ -92,6 +102,10 @@ error_authorize:
|
||||
oss.str(authorization_error(method_name, "DELETE", "CLUSTER", rc, clid));
|
||||
goto error_common;
|
||||
|
||||
error_cluster_get:
|
||||
oss.str(get_error(method_name, "CLUSTER", clid));
|
||||
goto error_common;
|
||||
|
||||
error_cluster_delete:
|
||||
oss.str(action_error(method_name, "DELETE", "CLUSTER", clid, rc));
|
||||
goto error_common;
|
||||
|
@ -29,12 +29,14 @@ void RequestManager::ClusterInfo::execute(
|
||||
string session;
|
||||
string info;
|
||||
|
||||
int clid;
|
||||
int rc;
|
||||
|
||||
Cluster * cluster;
|
||||
ostringstream oss;
|
||||
|
||||
int clid;
|
||||
int rc;
|
||||
|
||||
const string method_name = "ClusterInfo";
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
/* -- RPC specific vars -- */
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
@ -54,14 +56,18 @@ void RequestManager::ClusterInfo::execute(
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
info = ClusterInfo::hpool->info_cluster(clid);
|
||||
// Get the cluster
|
||||
cluster = ClusterInfo::cpool->get(clid,true);
|
||||
|
||||
// Cluster does not exists
|
||||
if ( info.empty() )
|
||||
if ( cluster == 0 )
|
||||
{
|
||||
goto error_cluster;
|
||||
goto error_cluster_get;
|
||||
}
|
||||
|
||||
oss << *cluster;
|
||||
|
||||
cluster->unlock();
|
||||
|
||||
// All nice, return the cluster info to the client
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS
|
||||
arrayData.push_back(xmlrpc_c::value_string(info));
|
||||
@ -78,7 +84,7 @@ error_authenticate:
|
||||
oss.str(authenticate_error(method_name));
|
||||
goto error_common;
|
||||
|
||||
error_cluster:
|
||||
error_cluster_get:
|
||||
oss.str(get_error(method_name, "CLUSTER", clid));
|
||||
goto error_common;
|
||||
|
||||
|
6
src/rm/RequestManagerClusterPoolInfo.cc
Executable file → Normal file
6
src/rm/RequestManagerClusterPoolInfo.cc
Executable file → Normal file
@ -29,7 +29,7 @@ void RequestManager::ClusterPoolInfo::execute(
|
||||
string session;
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
|
||||
const string method_name = "ClusterPoolInfo";
|
||||
|
||||
/* -- RPC specific vars -- */
|
||||
@ -49,8 +49,8 @@ void RequestManager::ClusterPoolInfo::execute(
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
// Perform the allocation in the vmpool
|
||||
rc = ClusterPoolInfo::hpool->dump_cluster(oss);
|
||||
// Dump the pool
|
||||
rc = ClusterPoolInfo::cpool->dump(oss, "");
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
|
@ -27,10 +27,10 @@ void RequestManager::ClusterRemove::execute(
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
|
||||
|
||||
int hid;
|
||||
int rc;
|
||||
|
||||
|
||||
const string method_name = "ClusterRemove";
|
||||
|
||||
Host * host;
|
||||
@ -77,7 +77,7 @@ void RequestManager::ClusterRemove::execute(
|
||||
}
|
||||
|
||||
// Remove host from cluster
|
||||
rc = ClusterRemove::hpool->set_default_cluster(host);
|
||||
rc = ClusterRemove::cpool->set_default_cluster(host);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
|
@ -107,7 +107,7 @@ void RequestManager::VirtualMachineDeploy::execute(
|
||||
goto error_host_get;
|
||||
}
|
||||
|
||||
hostname = host->get_hostname();
|
||||
hostname = host->get_name();
|
||||
vmm_mad = host->get_vmm_mad();
|
||||
tm_mad = host->get_tm_mad();
|
||||
|
||||
|
@ -67,7 +67,7 @@ void RequestManager::HostDelete::execute(
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the allocation in the hostpool
|
||||
// Perform the deletion from the hostpool
|
||||
host = HostDelete::hpool->get(hid,true);
|
||||
|
||||
if ( host == 0 )
|
||||
|
0
src/rm/RequestManagerHostPoolInfo.cc
Executable file → Normal file
0
src/rm/RequestManagerHostPoolInfo.cc
Executable file → Normal file
@ -31,8 +31,10 @@ void RequestManager::ImageAllocate::execute(
|
||||
string session;
|
||||
string str_template;
|
||||
string error_str;
|
||||
string user_name;
|
||||
|
||||
ImageTemplate * img_template;
|
||||
ImageTemplate * img_template = 0;
|
||||
User * user;
|
||||
|
||||
int iid;
|
||||
int uid;
|
||||
@ -96,10 +98,28 @@ void RequestManager::ImageAllocate::execute(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Get the User Name
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
user = ImageAllocate::upool->get(uid,true);
|
||||
|
||||
if ( user == 0 )
|
||||
{
|
||||
goto error_user_get;
|
||||
}
|
||||
|
||||
user_name = user->get_name();
|
||||
|
||||
user->unlock();
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Allocate the Image
|
||||
//--------------------------------------------------------------------------
|
||||
rc = ImageAllocate::ipool->allocate(uid,img_template,&iid, error_str);
|
||||
|
||||
rc = ImageAllocate::ipool->allocate(uid,user_name,
|
||||
img_template,&iid, error_str);
|
||||
|
||||
if ( rc < 0 )
|
||||
{
|
||||
@ -118,6 +138,12 @@ void RequestManager::ImageAllocate::execute(
|
||||
|
||||
return;
|
||||
|
||||
|
||||
error_user_get:
|
||||
oss.str(get_error(method_name, "USER", uid));
|
||||
delete img_template;
|
||||
goto error_common;
|
||||
|
||||
error_authenticate:
|
||||
oss.str(authenticate_error(method_name));
|
||||
goto error_common;
|
||||
|
0
src/rm/RequestManagerImagePoolInfo.cc
Executable file → Normal file
0
src/rm/RequestManagerImagePoolInfo.cc
Executable file → Normal file
@ -67,7 +67,7 @@ void RequestManager::VirtualMachineMigrate::execute(
|
||||
goto error_host_get;
|
||||
}
|
||||
|
||||
hostname = host->get_hostname();
|
||||
hostname = host->get_name();
|
||||
vmm_mad = host->get_vmm_mad();
|
||||
tm_mad = host->get_tm_mad();
|
||||
|
||||
|
@ -32,8 +32,6 @@ void RequestManager::VirtualMachinePoolInfo::execute(
|
||||
int rc;
|
||||
int state;
|
||||
|
||||
bool extended;
|
||||
|
||||
ostringstream oss;
|
||||
ostringstream where_string;
|
||||
|
||||
@ -45,18 +43,17 @@ void RequestManager::VirtualMachinePoolInfo::execute(
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"VirtualMachinePoolInfo method invoked");
|
||||
|
||||
// For backwards compatibility, 2 or 3 arguments can be present.
|
||||
switch (paramList.size())
|
||||
{
|
||||
case 2:
|
||||
extended = true;
|
||||
state = -1;
|
||||
break;
|
||||
case 4:
|
||||
extended = xmlrpc_c::value_boolean(paramList.getBoolean(2));
|
||||
case 3:
|
||||
state = xmlrpc_c::value_int (paramList.getInt(3));
|
||||
break;
|
||||
default:
|
||||
paramList.verifyEnd(4);
|
||||
paramList.verifyEnd(3);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -86,7 +83,7 @@ void RequestManager::VirtualMachinePoolInfo::execute(
|
||||
where_string << "UID=" << filter_flag;
|
||||
}
|
||||
|
||||
rc = VirtualMachinePoolInfo::vmpool->dump(oss, extended, state, where_string.str());
|
||||
rc = VirtualMachinePoolInfo::vmpool->dump(oss, state, where_string.str());
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
|
79
src/rm/RequestManagerUserAuthenticate.cc
Normal file
79
src/rm/RequestManagerUserAuthenticate.cc
Normal file
@ -0,0 +1,79 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
||||
/* not use this file except in compliance with the License. You may obtain */
|
||||
/* a copy of the License at */
|
||||
/* */
|
||||
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* */
|
||||
/* Unless required by applicable law or agreed to in writing, software */
|
||||
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
||||
/* See the License for the specific language governing permissions and */
|
||||
/* limitations under the License. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "RequestManager.h"
|
||||
#include "NebulaLog.h"
|
||||
|
||||
#include "AuthManager.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManager::UserAuthenticate::execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
int uid;
|
||||
|
||||
ostringstream oss;
|
||||
const string method_name = "UserAuthenticate";
|
||||
|
||||
|
||||
/* -- RPC specific vars -- */
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"UserAuthenticate method invoked");
|
||||
|
||||
// Get the parameters
|
||||
session = xmlrpc_c::value_string(paramList.getString(0));
|
||||
|
||||
// Try to authenticate the user
|
||||
uid = UserAuthenticate::upool->authenticate(session);
|
||||
|
||||
if( uid == -1 )
|
||||
{
|
||||
goto error_common;
|
||||
}
|
||||
|
||||
//Result
|
||||
arrayData.push_back(xmlrpc_c::value_boolean( true ));
|
||||
arrayData.push_back(xmlrpc_c::value_int(uid));
|
||||
arrayresult = new xmlrpc_c::value_array(arrayData);
|
||||
|
||||
*retval = *arrayresult;
|
||||
|
||||
delete arrayresult;
|
||||
|
||||
return;
|
||||
|
||||
error_common:
|
||||
oss.str(authenticate_error(method_name));
|
||||
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
|
||||
arrayData.push_back(xmlrpc_c::value_string(authenticate_error(method_name)));
|
||||
|
||||
NebulaLog::log("ReM",Log::ERROR,oss);
|
||||
|
||||
xmlrpc_c::value_array arrayresult_error(arrayData);
|
||||
|
||||
*retval = arrayresult_error;
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
@ -28,10 +28,12 @@ void RequestManager::VirtualNetworkAllocate::execute(
|
||||
{
|
||||
string session;
|
||||
string name;
|
||||
string user_name;
|
||||
string str_template;
|
||||
string error_str;
|
||||
|
||||
VirtualNetworkTemplate * vn_template;
|
||||
User * user;
|
||||
|
||||
int nid;
|
||||
int uid;
|
||||
@ -96,10 +98,25 @@ void RequestManager::VirtualNetworkAllocate::execute(
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Get the User Name
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
user = VirtualNetworkAllocate::upool->get(uid,true);
|
||||
|
||||
if ( user == 0 )
|
||||
{
|
||||
goto error_user_get;
|
||||
}
|
||||
|
||||
user_name = user->get_name();
|
||||
|
||||
user->unlock();
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Allocate the Virtual Network
|
||||
//--------------------------------------------------------------------------
|
||||
rc = vnpool->allocate(uid,vn_template,&nid,error_str);
|
||||
rc = vnpool->allocate(uid,user_name,vn_template,&nid,error_str);
|
||||
|
||||
if ( rc < 0 )
|
||||
{
|
||||
@ -118,6 +135,12 @@ void RequestManager::VirtualNetworkAllocate::execute(
|
||||
return;
|
||||
|
||||
|
||||
error_user_get:
|
||||
oss.str(get_error(method_name, "USER", uid));
|
||||
|
||||
delete vn_template;
|
||||
goto error_common;
|
||||
|
||||
error_authenticate:
|
||||
oss.str(authenticate_error(method_name));
|
||||
goto error_common;
|
||||
|
0
src/rm/RequestManagerVirtualNetworkPoolInfo.cc
Executable file → Normal file
0
src/rm/RequestManagerVirtualNetworkPoolInfo.cc
Executable file → Normal file
@ -60,6 +60,7 @@ source_files=[
|
||||
'RequestManagerUserAllocate.cc',
|
||||
'RequestManagerUserDelete.cc',
|
||||
'RequestManagerUserChangePassword.cc',
|
||||
'RequestManagerUserAuthenticate.cc',
|
||||
'RequestManagerUserInfo.cc',
|
||||
'RequestManagerUserPoolInfo.cc'
|
||||
]
|
||||
|
@ -28,7 +28,7 @@ env.Append(CPPPATH=[
|
||||
# Library dirs
|
||||
|
||||
env.Append(LIBPATH=[
|
||||
cwd+'/src/xml',
|
||||
cwd+'/src/client',
|
||||
cwd+'/src/pool',
|
||||
cwd+'/src/sched'
|
||||
])
|
||||
@ -38,7 +38,7 @@ env.Append(LIBPATH=[
|
||||
################################################################################
|
||||
|
||||
build_scripts=[
|
||||
'src/xml/SConstruct',
|
||||
'src/client/SConstruct',
|
||||
'src/pool/SConstruct',
|
||||
'src/sched/SConstruct'
|
||||
]
|
||||
@ -46,7 +46,6 @@ build_scripts=[
|
||||
if env['testing']=='yes':
|
||||
build_scripts.extend([
|
||||
'src/pool/test/SConstruct',
|
||||
'src/xml/test/SConstruct',
|
||||
])
|
||||
|
||||
for script in build_scripts:
|
||||
|
@ -84,7 +84,7 @@ public:
|
||||
return -1;
|
||||
}
|
||||
|
||||
update(message);
|
||||
update_from_str(message);
|
||||
|
||||
vector<xmlNodePtr> nodes;
|
||||
int num_objs;
|
||||
|
26
src/scheduler/src/client/SConstruct
Normal file
26
src/scheduler/src/client/SConstruct
Normal file
@ -0,0 +1,26 @@
|
||||
# SConstruct for src/pool
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2010, 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
Import('sched_env')
|
||||
|
||||
lib_name='scheduler_client'
|
||||
|
||||
source_files=['Client.cc']
|
||||
|
||||
# Build library
|
||||
sched_env.StaticLibrary(lib_name, source_files)
|
@ -18,7 +18,7 @@ Import('sched_env')
|
||||
|
||||
# Libraries
|
||||
sched_env.Prepend(LIBS=[
|
||||
'scheduler_xml',
|
||||
'nebula_xml',
|
||||
'scheduler_pool',
|
||||
'nebula_log',
|
||||
'nebula_common',
|
||||
|
@ -31,7 +31,8 @@ sched_env.Prepend(LIBS=[
|
||||
'scheduler_sched',
|
||||
'scheduler_pool',
|
||||
'nebula_log',
|
||||
'scheduler_xml',
|
||||
'scheduler_client',
|
||||
'nebula_xml',
|
||||
'nebula_common',
|
||||
'crypto',
|
||||
])
|
||||
|
@ -46,15 +46,16 @@ module OpenNebulaJSON
|
||||
when "deploy" then self.deploy(action_hash['params'])
|
||||
when "finalize" then self.finalize
|
||||
when "hold" then self.hold
|
||||
when "livemigrate" then self.live_migrate(action_hash['params'])
|
||||
when "livemigrate" then self.live_migrate(action_hash['params'])
|
||||
when "migrate" then self.migrate(action_hash['params'])
|
||||
when "resume" then self.resume
|
||||
when "release" then self.release
|
||||
when "stop" then self.stop
|
||||
when "suspend" then self.suspend
|
||||
when "restart" then self.restart
|
||||
when "saveas" then self.save_as(action_hash['params'])
|
||||
when "saveas" then self.save_as(action_hash['params'])
|
||||
when "shutdown" then self.shutdown
|
||||
when "resubmit" then self.resubmit
|
||||
else
|
||||
error_msg = "#{action_hash['perform']} action not " <<
|
||||
" available for this resource"
|
||||
|
@ -407,7 +407,7 @@ tr.even:hover{
|
||||
.top_button {
|
||||
font-size: 0.8em;
|
||||
height: 25px;
|
||||
margin: 3px 0;
|
||||
margin: 3px 2px;
|
||||
vertical-align: middle;
|
||||
/*width: 89px;*/
|
||||
}
|
||||
@ -417,6 +417,13 @@ tr.even:hover{
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.image_button {
|
||||
font-size: 0.8em;
|
||||
margin: 3px 2px;
|
||||
vertical-align: middle;
|
||||
border:0;
|
||||
}
|
||||
|
||||
/*
|
||||
.multi_action_slct{
|
||||
font-size: 0.7em;
|
||||
|
@ -57,7 +57,7 @@ function showTab(tabname){
|
||||
$(document).ready(function () {
|
||||
$(".tab").hide();
|
||||
|
||||
$(".outer-west ul li a").click(function(){
|
||||
$(".outer-west ul li a").live("click",function(){
|
||||
var tab = $(this).attr('href');
|
||||
showTab(tab);
|
||||
return false;
|
||||
@ -97,6 +97,5 @@ $(document).ready(function () {
|
||||
, spacing_closed: 12 // ALL panes
|
||||
});
|
||||
|
||||
showTab("#dashboard");
|
||||
});
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -182,8 +182,8 @@ var OpenNebula = {
|
||||
var password = params.data.password;
|
||||
var remember = params.remember;
|
||||
|
||||
var resource = this.resource;
|
||||
var request = OpenNebula.Helper.request(this.resource,"login");
|
||||
var resource = OpenNebula.Auth.resource;
|
||||
var request = OpenNebula.Helper.request(resource,"login");
|
||||
|
||||
$.ajax({
|
||||
url: "/login",
|
||||
@ -216,8 +216,8 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
|
||||
var resource = this.resource;
|
||||
var request = OpenNebula.Helper.request(this.resource,"logout");
|
||||
var resource = OpenNebula.Auth.resource;
|
||||
var request = OpenNebula.Helper.request(resource,"logout");
|
||||
|
||||
$.ajax({
|
||||
url: "/logout",
|
||||
@ -248,8 +248,8 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
|
||||
var resource = this.resource;
|
||||
var request = OpenNebula.Helper.request(this.resource,"list");
|
||||
var resource = OpenNebula.Config.resource;
|
||||
var request = OpenNebula.Helper.request(resource,"list");
|
||||
|
||||
$.ajax({
|
||||
url: "/config",
|
||||
@ -281,8 +281,9 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var data = params.data;
|
||||
var resource = OpenNebula.Host.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"create", data);
|
||||
var request = OpenNebula.Helper.request(resource,"create", data);
|
||||
|
||||
$.ajax({
|
||||
url: "/host",
|
||||
@ -311,9 +312,10 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.Host.resource;
|
||||
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"delete", id);
|
||||
var request = OpenNebula.Helper.request(resource,"delete", id);
|
||||
|
||||
$.ajax({
|
||||
url: "/host/" + id,
|
||||
@ -341,8 +343,8 @@ var OpenNebula = {
|
||||
var callback_error = params.error;
|
||||
var timeout = params.timeout || false;
|
||||
|
||||
var resource = this.resource;
|
||||
var request = OpenNebula.Helper.request(this.resource,"list");
|
||||
var resource = OpenNebula.Host.resource;
|
||||
var request = OpenNebula.Helper.request(resource,"list");
|
||||
|
||||
$.ajax({
|
||||
url: "/host",
|
||||
@ -374,8 +376,8 @@ var OpenNebula = {
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
|
||||
var resource = this.resource;
|
||||
var request = OpenNebula.Helper.request(this.resource,"show", id);
|
||||
var resource = OpenNebula.Host.resource;
|
||||
var request = OpenNebula.Helper.request(resource,"show", id);
|
||||
|
||||
$.ajax({
|
||||
url: "/host/" + id,
|
||||
@ -403,10 +405,11 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.Host.resource;
|
||||
|
||||
var method = "enable";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/host/" + id + "/action",
|
||||
@ -434,10 +437,11 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.Host.resource;
|
||||
|
||||
var method = "disable";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/host/" + id + "/action",
|
||||
@ -469,8 +473,9 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var data = params.data;
|
||||
var resource = OpenNebula.Network.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"create",data);
|
||||
var request = OpenNebula.Helper.request(resource,"create",data);
|
||||
|
||||
$.ajax({
|
||||
url: "/vnet",
|
||||
@ -499,8 +504,9 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.Network.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"delete", id);
|
||||
var request = OpenNebula.Helper.request(resource,"delete", id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vnet/" + id,
|
||||
@ -527,9 +533,9 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var timeout = params.timeout || false;
|
||||
|
||||
var resource = this.resource;
|
||||
var request = OpenNebula.Helper.request(this.resource,"list");
|
||||
var resource = OpenNebula.Network.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(resource,"list");
|
||||
|
||||
$.ajax({
|
||||
url: "/vnet",
|
||||
@ -559,8 +565,9 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.Network.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"show", id);
|
||||
var request = OpenNebula.Helper.request(resource,"show", id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vnet/" + id,
|
||||
@ -588,10 +595,11 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.Network.resource;
|
||||
|
||||
var method = "publish";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vnet/" + id + "/action",
|
||||
@ -619,10 +627,11 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.Network.resource;
|
||||
|
||||
var method = "unpublish";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vnet/" + id + "/action",
|
||||
@ -654,8 +663,9 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var data = params.data;
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"create",data);
|
||||
var request = OpenNebula.Helper.request(resource,"create",data);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm",
|
||||
@ -684,8 +694,9 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.Network.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"delete", id);
|
||||
var request = OpenNebula.Helper.request(resource,"delete", id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id,
|
||||
@ -713,8 +724,8 @@ var OpenNebula = {
|
||||
var callback_error = params.error;
|
||||
var timeout = params.timeout || false;
|
||||
|
||||
var resource = this.resource;
|
||||
var request = OpenNebula.Helper.request(this.resource,"list");
|
||||
var resource = OpenNebula.VM.resource;
|
||||
var request = OpenNebula.Helper.request(resource,"list");
|
||||
|
||||
$.ajax({
|
||||
url: "/vm",
|
||||
@ -744,8 +755,9 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"log", id);
|
||||
var request = OpenNebula.Helper.request(resource,"log", id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id + "/log",
|
||||
@ -772,8 +784,9 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"show", id);
|
||||
var request = OpenNebula.Helper.request(resource,"show", id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id,
|
||||
@ -801,11 +814,12 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var host = params.data.host_id;
|
||||
var host = params.data.extra_param;
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var method = "deploy";
|
||||
var action = OpenNebula.Helper.action(method, {"host_id": host});
|
||||
var request = OpenNebula.Helper.request(this.resource,method, [id, host]);
|
||||
var request = OpenNebula.Helper.request(resource,method, [id, host]);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id + "/action",
|
||||
@ -833,10 +847,11 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var method = "shutdown";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id + "/action",
|
||||
@ -864,11 +879,12 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var host = params.data.host_id;
|
||||
var host = params.data.extra_param;
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var method = "livemigrate";
|
||||
var action = OpenNebula.Helper.action(method,{"host_id": host});
|
||||
var request = OpenNebula.Helper.request(this.resource,method, [id, host]);
|
||||
var request = OpenNebula.Helper.request(resource,method, [id, host]);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id + "/action",
|
||||
@ -896,11 +912,12 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var host = params.data.host_id;
|
||||
var host = params.data.extra_param;
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var method = "migrate";
|
||||
var action = OpenNebula.Helper.action(method,{"host_id": host});
|
||||
var request = OpenNebula.Helper.request(this.resource,method, [id, host]);
|
||||
var request = OpenNebula.Helper.request(resource,method, [id, host]);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id + "/action",
|
||||
@ -928,10 +945,11 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var method = "hold";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id + "/action",
|
||||
@ -959,10 +977,11 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var method = "release";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id + "/action",
|
||||
@ -990,10 +1009,11 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var method = "stop";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id + "/action",
|
||||
@ -1021,10 +1041,11 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var method = "cancel";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id + "/action",
|
||||
@ -1052,10 +1073,11 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var method = "suspend";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id + "/action",
|
||||
@ -1083,10 +1105,11 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var method = "resume";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id + "/action",
|
||||
@ -1113,20 +1136,21 @@ var OpenNebula = {
|
||||
{
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var vm_id = params.data.vm_id;
|
||||
var id = params.data.vm_id;
|
||||
var disk_id = params.data.disk_id;
|
||||
var image_name = params.data.image_name;
|
||||
var type = params.data.type;
|
||||
|
||||
var method = "saveas";
|
||||
var saveas_params = {
|
||||
"vm_id" : vm_id,
|
||||
"disk_id" : disk_id,
|
||||
"image_name": image_name,
|
||||
"type" : type
|
||||
}
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var action = OpenNebula.Helper.action(method,saveas_params)
|
||||
var request = OpenNebula.Helper.request(this.resource,method, [vm_id, disk_id, image_name, type]);
|
||||
var request = OpenNebula.Helper.request(resource,method, [id,disk_id, image_name, type]);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id + "/action",
|
||||
@ -1154,10 +1178,43 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var method = "restart";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id + "/action",
|
||||
type: "POST",
|
||||
data: JSON.stringify(action),
|
||||
success: function()
|
||||
{
|
||||
if (callback)
|
||||
{
|
||||
callback(request);
|
||||
}
|
||||
},
|
||||
error: function(response)
|
||||
{
|
||||
if (callback_error)
|
||||
{
|
||||
callback_error(request, OpenNebula.Error(response));
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
"resubmit": function(params)
|
||||
{
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.VM.resource;
|
||||
|
||||
var method = "resubmit";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/vm/" + id + "/action",
|
||||
@ -1189,8 +1246,9 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var data = params.data;
|
||||
var resource = OpenNebula.Cluster.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"create", name);
|
||||
var request = OpenNebula.Helper.request(resource,"create", name);
|
||||
|
||||
$.ajax({
|
||||
url: "/cluster",
|
||||
@ -1219,8 +1277,9 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.Cluster.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"delete", id);
|
||||
var request = OpenNebula.Helper.request(resource,"delete", id);
|
||||
|
||||
$.ajax({
|
||||
url: "/cluster/" + id,
|
||||
@ -1248,8 +1307,8 @@ var OpenNebula = {
|
||||
var callback_error = params.error;
|
||||
var timeout = params.timeout || false;
|
||||
|
||||
var resource = this.resource;
|
||||
var request = OpenNebula.Helper.request(this.resource,"list");
|
||||
var resource = OpenNebula.Cluster.resource;
|
||||
var request = OpenNebula.Helper.request(resource,"list");
|
||||
|
||||
$.ajax({
|
||||
url: "/cluster",
|
||||
@ -1279,13 +1338,14 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var host_id = params.data.id;
|
||||
var cluster_id = params.data.cluster_id;
|
||||
var cluster_id = params.data.extra_param;
|
||||
var resource = OpenNebula.Cluster.resource;
|
||||
|
||||
var method = "add_host";
|
||||
var action = OpenNebula.Helper.action(method, {
|
||||
"host_id" : host_id
|
||||
});
|
||||
var request = OpenNebula.Helper.request(this.resource,method, [host_id, cluster_id]);
|
||||
var request = OpenNebula.Helper.request(resource,method, [host_id, cluster_id]);
|
||||
|
||||
$.ajax({
|
||||
url: "/cluster/" + cluster_id + "/action",
|
||||
@ -1313,13 +1373,15 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var host_id = params.data.id;
|
||||
var cluster_id = params.data.cluster_id;
|
||||
var cluster_id = params.data.extra_param;
|
||||
|
||||
var method = "remove_host";
|
||||
var action = OpenNebula.Helper.action(method, {
|
||||
"host_id" : host_id
|
||||
});
|
||||
var request = OpenNebula.Helper.request(this.resource,method, [host_id, cluster_id]);
|
||||
var resource = OpenNebula.Cluster.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(resource,method, [host_id, cluster_id]);
|
||||
|
||||
$.ajax({
|
||||
url: "/cluster/" + cluster_id + "/action",
|
||||
@ -1351,8 +1413,9 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var data = params.data;
|
||||
var resource = OpenNebula.User.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"create",data);
|
||||
var request = OpenNebula.Helper.request(resource,"create",data);
|
||||
|
||||
$.ajax({
|
||||
url: "/user",
|
||||
@ -1381,8 +1444,9 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.User.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"delete", id);
|
||||
var request = OpenNebula.Helper.request(resource,"delete", id);
|
||||
|
||||
$.ajax({
|
||||
url: "/user/" + id,
|
||||
@ -1410,8 +1474,8 @@ var OpenNebula = {
|
||||
var callback_error = params.error;
|
||||
var timeout = params.timeout || false;
|
||||
|
||||
var resource = this.resource;
|
||||
var request = OpenNebula.Helper.request(this.resource,"list");
|
||||
var resource = OpenNebula.User.resource;
|
||||
var request = OpenNebula.Helper.request(resource,"list");
|
||||
|
||||
$.ajax({
|
||||
url: "/user",
|
||||
@ -1447,7 +1511,9 @@ var OpenNebula = {
|
||||
var action = OpenNebula.Helper.action(method, {
|
||||
"password" : passwd
|
||||
});
|
||||
var request = OpenNebula.Helper.request(this.resource,method, passwd);
|
||||
|
||||
var resource = OpenNebula.User.resource;
|
||||
var request = OpenNebula.Helper.request(resource,method, passwd);
|
||||
|
||||
$.ajax({
|
||||
url: "/user/" + id + "/action",
|
||||
@ -1479,8 +1545,9 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var data = params.data;
|
||||
var resource = OpenNebula.Image.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"register",data);
|
||||
var request = OpenNebula.Helper.request(resource,"register",data);
|
||||
|
||||
$.ajax({
|
||||
url: "/image",
|
||||
@ -1509,8 +1576,9 @@ var OpenNebula = {
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
var resource = OpenNebula.Image.resource;
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"delete", id);
|
||||
var request = OpenNebula.Helper.request(resource,"delete", id);
|
||||
|
||||
$.ajax({
|
||||
url: "/image/" + id,
|
||||
@ -1538,8 +1606,8 @@ var OpenNebula = {
|
||||
var callback_error = params.error;
|
||||
var timeout = params.timeout || false;
|
||||
|
||||
var resource = this.resource;
|
||||
var request = OpenNebula.Helper.request(this.resource,"list");
|
||||
var resource = OpenNebula.Image.resource;
|
||||
var request = OpenNebula.Helper.request(resource,"list");
|
||||
|
||||
$.ajax({
|
||||
url: "/image",
|
||||
@ -1570,7 +1638,8 @@ var OpenNebula = {
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
|
||||
var request = OpenNebula.Helper.request(this.resource,"show", id);
|
||||
var resource = OpenNebula.Image.resource;
|
||||
var request = OpenNebula.Helper.request(resource,"show", id);
|
||||
|
||||
$.ajax({
|
||||
url: "/image/" + id,
|
||||
@ -1606,7 +1675,9 @@ var OpenNebula = {
|
||||
"name" : name,
|
||||
"value" : value
|
||||
});
|
||||
var request = OpenNebula.Helper.request(this.resource,method, [id, name, value]);
|
||||
|
||||
var resource = OpenNebula.Image.resource;
|
||||
var request = OpenNebula.Helper.request(resource,method, [id, name, value]);
|
||||
|
||||
$.ajax({
|
||||
url: "/image/" + id + "/action",
|
||||
@ -1641,7 +1712,9 @@ var OpenNebula = {
|
||||
var action = OpenNebula.Helper.action(method, {
|
||||
"name" : name
|
||||
});
|
||||
var request = OpenNebula.Helper.request(this.resource,method, [id, name]);
|
||||
|
||||
var resource = OpenNebula.Image.resource;
|
||||
var request = OpenNebula.Helper.request(resource,method, [id, name]);
|
||||
|
||||
$.ajax({
|
||||
url: "/image/" + id + "/action",
|
||||
@ -1672,7 +1745,9 @@ var OpenNebula = {
|
||||
|
||||
var method = "enable";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
|
||||
var resource = OpenNebula.Image.resource;
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/image/" + id + "/action",
|
||||
@ -1703,7 +1778,8 @@ var OpenNebula = {
|
||||
|
||||
var method = "disable";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
var resource = OpenNebula.Image.resource;
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/image/" + id + "/action",
|
||||
@ -1734,7 +1810,8 @@ var OpenNebula = {
|
||||
|
||||
var method = "publish";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
var resource = OpenNebula.Image.resource;
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/image/" + id + "/action",
|
||||
@ -1765,7 +1842,8 @@ var OpenNebula = {
|
||||
|
||||
var method = "unpublish";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
var resource = OpenNebula.Image.resource;
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/image/" + id + "/action",
|
||||
@ -1796,7 +1874,9 @@ var OpenNebula = {
|
||||
|
||||
var method = "persistent";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
|
||||
var resource = OpenNebula.Image.resource;
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/image/" + id + "/action",
|
||||
@ -1827,7 +1907,9 @@ var OpenNebula = {
|
||||
|
||||
var method = "nonpersistent";
|
||||
var action = OpenNebula.Helper.action(method);
|
||||
var request = OpenNebula.Helper.request(this.resource,method, id);
|
||||
|
||||
var resource = OpenNebula.Image.resource;
|
||||
var request = OpenNebula.Helper.request(resource,method, id);
|
||||
|
||||
$.ajax({
|
||||
url: "/image/" + id + "/action",
|
||||
|
241
src/sunstone/public/js/plugins/dashboard-tab.js
Normal file
241
src/sunstone/public/js/plugins/dashboard-tab.js
Normal file
@ -0,0 +1,241 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
var dashboard_tab_content =
|
||||
'<table id="dashboard_table">\
|
||||
<tr>\
|
||||
<td>\
|
||||
<div class="panel">\
|
||||
<h3><a href="#hosts_tab">Hosts</a>\
|
||||
<div class="new-resource">\
|
||||
<a class="action_button" href="#hosts_tab" value="Host.create_dialog">+</a>\
|
||||
</div>\
|
||||
</h3>\
|
||||
<div class="panel_info">\
|
||||
<table class="info_table">\
|
||||
<tr>\
|
||||
<td class="key_td">Total</td>\
|
||||
<td class="value_td"><span id="total_hosts"></span></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td key_td_green">Active</td>\
|
||||
<td class="value_td"><span id="active_hosts"></span></td>\
|
||||
</tr>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
</td>\
|
||||
<td>\
|
||||
<div class="panel">\
|
||||
<h3><a href="#hosts_tab">Clusters</a>\
|
||||
<div class="new-resource">\
|
||||
<a class="action_button" href="#hosts_tab" value="Cluster.create_dialog">+</a>\
|
||||
</div>\
|
||||
</h3>\
|
||||
<div class="panel_info">\
|
||||
<table class="info_table">\
|
||||
<tr>\
|
||||
<td class="key_td">Total</td>\
|
||||
<td class="value_td"><span id="total_clusters"></span></td>\
|
||||
</tr>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td>\
|
||||
<div class="panel">\
|
||||
<h3><a href="#vms_tab">Virtual Machines</a>\
|
||||
<div class="new-resource">\
|
||||
<a class="action_button" href="#vms_tab" value="VM.create_dialog">+</a>\
|
||||
</div>\
|
||||
</h3>\
|
||||
<div class="panel_info">\
|
||||
<table class="info_table">\
|
||||
<tr>\
|
||||
<td class="key_td">Total</td>\
|
||||
<td class="value_td"><span id="total_vms"></span></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td key_td_green">Running</td>\
|
||||
<td class="value_td"><span id="running_vms"></span></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td key_td_red">Failed</td>\
|
||||
<td class="value_td"><span id="failed_vms"></span></td>\
|
||||
</tr>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
</td>\
|
||||
<td>\
|
||||
<div class="panel">\
|
||||
<h3><a href="#vnets_tab">Virtual Networks</a>\
|
||||
<div class="new-resource">\
|
||||
<a class="action_button" href="#vnets_tab" value="Network.create_dialog">+</a>\
|
||||
</div>\
|
||||
</h3>\
|
||||
<div class="panel_info">\
|
||||
<table class="info_table">\
|
||||
<tr>\
|
||||
<td class="key_td">Total</td>\
|
||||
<td class="value_td"><span id="total_vnets"></span></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Public</td>\
|
||||
<td class="value_td"><span id="public_vnets"></span></td>\
|
||||
</tr>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td>\
|
||||
<div class="panel">\
|
||||
<h3>\
|
||||
<a href="#images_tab">Images</a>\
|
||||
<div class="new-resource">\
|
||||
<a class="action_button" href="#images_tab" value="Image.create_dialog">+</a>\
|
||||
</div>\
|
||||
</h3>\
|
||||
<div class="panel_info">\
|
||||
<table class="info_table">\
|
||||
<tr>\
|
||||
<td class="key_td">Total</td>\
|
||||
<td class="value_td"><span id="total_images"></span></td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Public</td>\
|
||||
<td class="value_td"><span id="public_images"></span></td>\
|
||||
</tr>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
</td>\
|
||||
<td class="oneadmin">\
|
||||
<div class="panel">\
|
||||
<h3><a href="#users_tab">Users</a>\
|
||||
<div class="new-resource">\
|
||||
<a class="action_button" href="#users_tab" value="User.create_dialog">+</a>\
|
||||
</div>\
|
||||
</h3>\
|
||||
<div class="panel_info">\
|
||||
<table class="info_table">\
|
||||
<tr>\
|
||||
<td class="key_td">Total</td>\
|
||||
<td class="value_td"><span id="total_users"></span></td>\
|
||||
</tr>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
</td>\
|
||||
</tr>\
|
||||
</table>';
|
||||
|
||||
|
||||
var dashboard_tab = {
|
||||
title: 'Dashboard',
|
||||
content: dashboard_tab_content,
|
||||
condition : True
|
||||
}
|
||||
|
||||
Sunstone.addMainTab('dashboard_tab',dashboard_tab);
|
||||
|
||||
$(document).ready(function(){
|
||||
//Dashboard link listener
|
||||
$("#dashboard_table h3 a").live("click", function (){
|
||||
var tab = $(this).attr('href');
|
||||
showTab(tab);
|
||||
return false;
|
||||
});
|
||||
|
||||
emptyDashboard();
|
||||
if (uid!=0) {
|
||||
$("td.oneadmin").hide();
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
//puts the dashboard values into "retrieving"
|
||||
function emptyDashboard(){
|
||||
$("#dashboard_tab .value_td span").html(spinner);
|
||||
}
|
||||
|
||||
|
||||
function updateDashboard(what,json_info){
|
||||
db = $('#dashboard_tab');
|
||||
switch (what){
|
||||
case "hosts":
|
||||
total_hosts=json_info.length;
|
||||
active_hosts=0;
|
||||
$.each(json_info,function(){
|
||||
if (parseInt(this.HOST.STATE) < 3){
|
||||
active_hosts++;}
|
||||
});
|
||||
$('#total_hosts',db).html(total_hosts);
|
||||
$('#active_hosts',db).html(active_hosts);
|
||||
break;
|
||||
case "clusters":
|
||||
total_clusters=json_info.length;
|
||||
$('#total_clusters',db).html(total_clusters);
|
||||
break;
|
||||
case "vms":
|
||||
total_vms=json_info.length;
|
||||
running_vms=0;
|
||||
failed_vms=0;
|
||||
$.each(json_info,function(){
|
||||
vm_state = parseInt(this.VM.STATE);
|
||||
if (vm_state == 3){
|
||||
running_vms++;
|
||||
}
|
||||
else if (vm_state == 7) {
|
||||
failed_vms++;
|
||||
}
|
||||
});
|
||||
$('#total_vms',db).html(total_vms);
|
||||
$('#running_vms',db).html(running_vms);
|
||||
$('#failed_vms',db).html(failed_vms);
|
||||
break;
|
||||
case "vnets":
|
||||
public_vnets=0;
|
||||
total_vnets=json_info.length;
|
||||
$.each(json_info,function(){
|
||||
if (parseInt(this.VNET.PUBLIC)){
|
||||
public_vnets++;}
|
||||
});
|
||||
$('#total_vnets',db).html(total_vnets);
|
||||
$('#public_vnets',db).html(public_vnets);
|
||||
break;
|
||||
case "users":
|
||||
total_users=json_info.length;
|
||||
$('#total_users',db).html(total_users);
|
||||
break;
|
||||
case "images":
|
||||
total_images=json_info.length;
|
||||
public_images=0;
|
||||
$.each(json_info,function(){
|
||||
if (parseInt(this.IMAGE.PUBLIC)){
|
||||
public_images++;}
|
||||
});
|
||||
$('#total_images',db).html(total_images);
|
||||
$('#public_images',db).html(public_images);
|
||||
break;
|
||||
}
|
||||
}
|
686
src/sunstone/public/js/plugins/hosts-tab.js
Normal file
686
src/sunstone/public/js/plugins/hosts-tab.js
Normal file
@ -0,0 +1,686 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/*Host tab plugin*/
|
||||
|
||||
var hosts_tab_content =
|
||||
'<form id="form_hosts" action="javascript:alert(\'js errors?!\')">\
|
||||
<div class="action_blocks">\
|
||||
</div>\
|
||||
<table id="datatable_hosts" class="display">\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th class="check"><input type="checkbox" class="check_all" value="">All</input></th>\
|
||||
<th>ID</th>\
|
||||
<th>Name</th>\
|
||||
<th>Cluster</th>\
|
||||
<th>Running VMs</th>\
|
||||
<th>CPU Use</th>\
|
||||
<th>Memory use</th>\
|
||||
<th>Status</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody id="tbodyhosts">\
|
||||
</tbody>\
|
||||
</table>\
|
||||
</form>';
|
||||
|
||||
var create_host_tmpl =
|
||||
'<div class="create_form"><form id="create_host_form" action="">\
|
||||
<fieldset>\
|
||||
<legend style="display:none;">Host parameters</legend>\
|
||||
<label for="name">Name: </label><input type="text" name="name" id="name" />\
|
||||
</fieldset>\
|
||||
<h3>Drivers</h3>\
|
||||
<fieldset>\
|
||||
<div class="manager clear" id="vmm_mads">\
|
||||
<label>Virtualization Manager:</label>\
|
||||
<select id="vmm_mad" name="vmm">\
|
||||
<option value="vmm_kvm">KVM</option>\
|
||||
<option value="vmm_xen">XEN</option>\
|
||||
<option value="vmm_ec2">EC2</option>\
|
||||
<option value="vmm_dummy">Dummy</option>\
|
||||
</select>\
|
||||
</div>\
|
||||
<div class="manager clear" id="im_mads">\
|
||||
<label>Information Manager:</label>\
|
||||
<select id="im_mad" name="im">\
|
||||
<option value="im_kvm">KVM</option>\
|
||||
<option value="im_xen">XEN</option>\
|
||||
<option value="im_ec2">EC2</option>\
|
||||
<option value="im_dummy">Dummy</option>\
|
||||
</select>\
|
||||
</div>\
|
||||
<div class="manager clear" id="tm_mads">\
|
||||
<label>Transfer Manager:</label>\
|
||||
<select id="tm_mad" name="tm">\
|
||||
<option value="tm_nfs">NFS</option>\
|
||||
<option value="tm_ssh">SSH</option>\
|
||||
<option value="tm_dummy">Dummy</option>\
|
||||
</select>\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
<div class="form_buttons">\
|
||||
<div><button class="button" id="create_host_submit" value="OpenNebula.Host.create">Create</button>\
|
||||
<button class="button" type="reset" value="reset">Reset</button></div>\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
</form></div>';
|
||||
|
||||
var create_cluster_tmpl =
|
||||
'<form id="create_cluster_form" action="">\
|
||||
<fieldset style="border:none;">\
|
||||
<div>\
|
||||
<label for="name">Cluster name:</label>\
|
||||
<input type="text" name="name" id="name" /><br />\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
<div class="form_buttons">\
|
||||
<button class="button" id="create_cluster_submit" value="cluster/create">Create</button>\
|
||||
<button class="button" type="reset" value="reset">Reset</button>\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
</form>';
|
||||
|
||||
var hosts_select="";
|
||||
var clusters_select="";
|
||||
var host_list_json = {};
|
||||
var cluster_list_json = {};
|
||||
var dataTable_hosts;
|
||||
|
||||
//Setup actions
|
||||
var host_actions = {
|
||||
|
||||
"Host.create" : {
|
||||
type: "create",
|
||||
call : OpenNebula.Host.create,
|
||||
callback : addHostElement,
|
||||
error : onError,
|
||||
notify: true
|
||||
},
|
||||
|
||||
"Host.create_dialog" : {
|
||||
type: "custom",
|
||||
call: popUpCreateHostDialog
|
||||
},
|
||||
|
||||
//Custom below
|
||||
//~ "Host.list" : {
|
||||
//~ type: "list",
|
||||
//~ call: OpenNebula.Host.list,
|
||||
//~ callback: updateHostsView,
|
||||
//~ error: onError,
|
||||
//~ notify:False
|
||||
//~ },
|
||||
|
||||
"Host.show" : {
|
||||
type: "single",
|
||||
call: OpenNebula.Host.show,
|
||||
callback: updateHostElement,
|
||||
error: onError
|
||||
},
|
||||
|
||||
"Host.showinfo" : {
|
||||
type: "single",
|
||||
call: OpenNebula.Host.show,
|
||||
callback: updateHostInfo,
|
||||
error: onError
|
||||
},
|
||||
|
||||
"Host.refresh" : {
|
||||
type: "custom",
|
||||
call: function(){
|
||||
waitingNodes(dataTable_hosts);
|
||||
Sunstone.runAction("Host.list");
|
||||
},
|
||||
callback: function(){},
|
||||
error: onError,
|
||||
notify:false
|
||||
},
|
||||
|
||||
"Host.autorefresh" : {
|
||||
type: "custom",
|
||||
call : function() {
|
||||
OpenNebula.Host.list({timeout: true, success: updateHostsView,error: onError});
|
||||
}
|
||||
},
|
||||
|
||||
"Host.enable" : {
|
||||
type: "multiple",
|
||||
call : OpenNebula.Host.enable,
|
||||
callback : function (req) {
|
||||
Sunstone.runAction("Host.show",req.request.data[0]);
|
||||
},
|
||||
elements: function() { return getSelectedNodes(dataTable_hosts); },
|
||||
error : onError,
|
||||
notify: true
|
||||
},
|
||||
|
||||
"Host.disable" : {
|
||||
type: "multiple",
|
||||
call : OpenNebula.Host.disable,
|
||||
callback : function (req) {
|
||||
Sunstone.runAction("Host.show",req.request.data[0]);
|
||||
},
|
||||
elements: function() { return getSelectedNodes(dataTable_hosts); },
|
||||
error : onError,
|
||||
notify:true
|
||||
},
|
||||
|
||||
"Host.delete" : {
|
||||
type: "multiple",
|
||||
call : OpenNebula.Host.delete,
|
||||
callback : deleteHostElement,
|
||||
elements: function() { return getSelectedNodes(dataTable_hosts); },
|
||||
error : onError,
|
||||
notify:true
|
||||
},
|
||||
|
||||
"Host.list" : {
|
||||
type: "custom",
|
||||
call : function() {
|
||||
OpenNebula.Host.list({success: updateHostsView, error: onError});
|
||||
OpenNebula.Cluster.list({success: updateClustersView, error: onError});
|
||||
}
|
||||
},
|
||||
|
||||
"Cluster.create" : {
|
||||
type: "create",
|
||||
call : OpenNebula.Cluster.create,
|
||||
callback : function(){
|
||||
Sunstone.runAction("Cluster.list");
|
||||
},
|
||||
error : onError,
|
||||
notify: true
|
||||
},
|
||||
|
||||
"Cluster.create_dialog" : {
|
||||
type: "custom",
|
||||
call: popUpCreateClusterDialog
|
||||
},
|
||||
|
||||
"Cluster.list" : {
|
||||
type: "list",
|
||||
call: OpenNebula.Cluster.list,
|
||||
callback: updateClustersView,
|
||||
error: onError,
|
||||
},
|
||||
|
||||
"Cluster.autorefresh" : {
|
||||
type: "custom",
|
||||
call: function () {
|
||||
OpenNebula.Cluster.list({timeout: true, success: updateClustersView,error: onError});
|
||||
}
|
||||
},
|
||||
|
||||
"Cluster.delete" : {
|
||||
type: "single",
|
||||
call : OpenNebula.Cluster.delete,
|
||||
callback : function(){
|
||||
//OpenNebula.Cluster.list({success: updateClustersView, error: onError});
|
||||
Sunstone.runAction("Cluster.list");
|
||||
},
|
||||
error : onError,
|
||||
notify:true
|
||||
},
|
||||
|
||||
"Cluster.addhost" : {
|
||||
type: "multiple",
|
||||
call : OpenNebula.Cluster.addhost,
|
||||
callback : function(req){
|
||||
Sunstone.runAction("Host.show",req.request.data);
|
||||
},
|
||||
elements: function() { return getSelectedNodes(dataTable_hosts); },
|
||||
error : onError,
|
||||
notify:true
|
||||
},
|
||||
|
||||
"Cluster.removehost" : {
|
||||
type: "multiple",
|
||||
call : OpenNebula.Cluster.removehost,
|
||||
callback : deleteHostElement,
|
||||
elements: function() { return getSelectedNodes(dataTable_hosts); },
|
||||
error : onError,
|
||||
notify:true
|
||||
}
|
||||
};
|
||||
|
||||
var host_buttons = {
|
||||
"Host.refresh" : {
|
||||
type: "image",
|
||||
text: "Refresh list",
|
||||
img: "/images/Refresh-icon.png",
|
||||
condition: True
|
||||
},
|
||||
"Host.create_dialog" : {
|
||||
type: "create_dialog",
|
||||
text: "+ New",
|
||||
condition :True
|
||||
},
|
||||
"Host.enable" : {
|
||||
type: "action",
|
||||
text: "Enable",
|
||||
condition : True
|
||||
},
|
||||
"Host.disable" : {
|
||||
type: "action",
|
||||
text: "Disable",
|
||||
condition : True
|
||||
},
|
||||
"Cluster.create_dialog" : {
|
||||
type: "create_dialog",
|
||||
text: "+ New Cluster",
|
||||
condition : True
|
||||
},
|
||||
"Cluster.delete" : {
|
||||
type: "confirm_with_select",
|
||||
text: "Delete cluster",
|
||||
select: function(){return clusters_select},
|
||||
tip: "Select the cluster you want to remove",
|
||||
condition : True
|
||||
},
|
||||
|
||||
"action_list" : { //Special button
|
||||
type: "select",
|
||||
actions: { "Cluster.addhost": {
|
||||
type: "confirm_with_select",
|
||||
text: "Add host to cluster",
|
||||
select: function(){return clusters_select;},
|
||||
tip: "Select the cluster in which you would like to place the hosts",
|
||||
condition: True
|
||||
},
|
||||
"Cluster.removehost" : {
|
||||
type: "action",
|
||||
text: "Remove host from cluster",
|
||||
condition: True
|
||||
}},
|
||||
condition : True
|
||||
},
|
||||
"Host.delete" : {
|
||||
type: "action",
|
||||
text: "Delete host",
|
||||
condition : True
|
||||
}
|
||||
};
|
||||
|
||||
var host_info_panel = {
|
||||
"host_info_tab" : {
|
||||
title: "Host information",
|
||||
content:""
|
||||
},
|
||||
|
||||
"host_template_tab" : {
|
||||
title: "Host template",
|
||||
content: ""
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var hosts_tab = {
|
||||
title: 'Hosts & Clusters',
|
||||
content: hosts_tab_content,
|
||||
buttons: host_buttons,
|
||||
condition: True
|
||||
}
|
||||
|
||||
Sunstone.addActions(host_actions);
|
||||
Sunstone.addMainTab('hosts_tab',hosts_tab);
|
||||
Sunstone.addInfoPanel("host_info_panel",host_info_panel);
|
||||
|
||||
|
||||
|
||||
//Creates an array to be added to the dataTable from the JSON of a host.
|
||||
function hostElementArray(host_json){
|
||||
|
||||
var host = host_json.HOST;
|
||||
|
||||
//Calculate some values
|
||||
var acpu = parseInt(host.HOST_SHARE.MAX_CPU);
|
||||
if (!acpu) {acpu=100};
|
||||
acpu = acpu - parseInt(host.HOST_SHARE.CPU_USAGE);
|
||||
|
||||
var total_mem = parseInt(host.HOST_SHARE.MAX_MEM);
|
||||
var free_mem = parseInt(host.HOST_SHARE.FREE_MEM);
|
||||
|
||||
var ratio_mem = 0;
|
||||
if (total_mem) {
|
||||
ratio_mem = Math.round(((total_mem - free_mem) / total_mem) * 100);
|
||||
}
|
||||
|
||||
|
||||
var total_cpu = parseInt(host.HOST_SHARE.MAX_CPU);
|
||||
var used_cpu = Math.max(total_cpu - parseInt(host.HOST_SHARE.USED_CPU),acpu);
|
||||
|
||||
var ratio_cpu = 0;
|
||||
if (total_cpu){
|
||||
ratio_cpu = Math.round(((total_cpu - used_cpu) / total_cpu) * 100);
|
||||
}
|
||||
|
||||
|
||||
//progressbars html code - hardcoded jquery html result
|
||||
var pb_mem =
|
||||
'<div style="height:10px" class="ratiobar ui-progressbar ui-widget ui-widget-content ui-corner-all" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="'+ratio_mem+'">\
|
||||
<div class="ui-progressbar-value ui-widget-header ui-corner-left ui-corner-right" style="width: '+ratio_mem+'%;"/>\
|
||||
<span style="position:relative;left:45px;top:-4px;font-size:0.6em">'+ratio_mem+'%</span>\
|
||||
</div>\
|
||||
</div>';
|
||||
|
||||
var pb_cpu =
|
||||
'<div style="height:10px" class="ratiobar ui-progressbar ui-widget ui-widget-content ui-corner-all" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="'+ratio_cpu+'">\
|
||||
<div class="ui-progressbar-value ui-widget-header ui-corner-left ui-corner-right" style="width: '+ratio_cpu+'%;"/>\
|
||||
<span style="position:relative;left:45px;top:-4px;font-size:0.6em">'+ratio_cpu+'%</span>\
|
||||
</div>\
|
||||
</div>';
|
||||
|
||||
|
||||
return [ '<input type="checkbox" id="host_'+host.ID+'" name="selected_items" value="'+host.ID+'"/>',
|
||||
host.ID,
|
||||
host.NAME,
|
||||
host.CLUSTER,
|
||||
host.HOST_SHARE.RUNNING_VMS, //rvm
|
||||
pb_cpu,
|
||||
pb_mem,
|
||||
OpenNebula.Helper.resource_state("host",host.STATE) ];
|
||||
|
||||
}
|
||||
|
||||
//Listen to clicks on the tds of the tables and shows the info dialogs.
|
||||
function hostInfoListener(){
|
||||
$('#tbodyhosts tr').live("click",function(e){
|
||||
|
||||
//do nothing if we are clicking a checkbox!
|
||||
if ($(e.target).is('input')) {return true;}
|
||||
popDialogLoading();
|
||||
var aData = dataTable_hosts.fnGetData(this);
|
||||
var id = $(aData[0]).val();
|
||||
Sunstone.runAction("Host.showinfo",id);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
//updates the host select by refreshing the options in it
|
||||
function updateHostSelect(){
|
||||
|
||||
hosts_select = makeSelectOptions(dataTable_hosts,1,2,7,"DISABLED");
|
||||
|
||||
}
|
||||
|
||||
//updates the cluster select by refreshing the options in it
|
||||
function updateClusterSelect(cluster_list){
|
||||
|
||||
//manual, as there is not dataTable for it
|
||||
clusters_select="<option value=\"\">Select a cluster</option>";
|
||||
$.each(cluster_list, function(){
|
||||
clusters_select += "<option value=\""+this.CLUSTER.ID+"\">"+this.CLUSTER.NAME+"</option>";
|
||||
});
|
||||
}
|
||||
|
||||
//callback for an action affecting a host element
|
||||
function updateHostElement(request, host_json){
|
||||
var id = host_json.HOST.ID;
|
||||
var element = hostElementArray(host_json);
|
||||
updateSingleElement(element,dataTable_hosts,'#host_'+id);
|
||||
updateHostSelect();
|
||||
}
|
||||
|
||||
//callback for actions deleting a host element
|
||||
function deleteHostElement(req){
|
||||
deleteElement(dataTable_hosts,'#host_'+req.request.data);
|
||||
updateHostSelect();
|
||||
}
|
||||
|
||||
//call back for actions creating a host element
|
||||
function addHostElement(request,host_json){
|
||||
var id = host_json.HOST.ID;
|
||||
var element = hostElementArray(host_json);
|
||||
addElement(element,dataTable_hosts);
|
||||
updateHostSelect();
|
||||
}
|
||||
|
||||
//callback to update the list of hosts.
|
||||
function updateHostsView (request,host_list){
|
||||
host_list_json = host_list;
|
||||
var host_list_array = []
|
||||
|
||||
$.each(host_list,function(){
|
||||
//Grab table data from the host_list
|
||||
host_list_array.push(hostElementArray(this));
|
||||
});
|
||||
|
||||
updateView(host_list_array,dataTable_hosts);
|
||||
updateHostSelect();
|
||||
//dependency with the dashboard plugin
|
||||
updateDashboard("hosts",host_list_json);
|
||||
}
|
||||
|
||||
//updates the list of clusters
|
||||
function updateClustersView(request, cluster_list){
|
||||
cluster_list_json = cluster_list;
|
||||
updateClusterSelect(cluster_list);
|
||||
updateDashboard("clusters",cluster_list);
|
||||
}
|
||||
|
||||
//Updates the host info panel tab's content and pops it up
|
||||
function updateHostInfo(request,host){
|
||||
var host_info = host.HOST;
|
||||
|
||||
//Information tab
|
||||
var info_tab = {
|
||||
title : "Host information",
|
||||
content :
|
||||
'<table id="info_host_table" class="info_table">\
|
||||
<thead>\
|
||||
<tr><th colspan="2">Host information - '+host_info.NAME+'</th></tr>\
|
||||
</thead>\
|
||||
<tr>\
|
||||
<td class="key_td">ID</td>\
|
||||
<td class="value_td">'+host_info.ID+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">State</td>\
|
||||
<td class="value_td">'+OpenNebula.Helper.resource_state("host",host_info.STATE)+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Cluster</td>\
|
||||
<td class="value_td">'+host_info.CLUSTER+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">IM MAD</td>\
|
||||
<td class="value_td">'+host_info.IM_MAD+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">VM MAD</td>\
|
||||
<td class="value_td">'+host_info.VM_MAD+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">TM MAD</td>\
|
||||
<td class="value_td">'+host_info.TM_MAD+'</td>\
|
||||
</tr>\
|
||||
</table>\
|
||||
<table id="host_shares_table" class="info_table">\
|
||||
<thead>\
|
||||
<tr><th colspan="2">Host shares</th></tr>\
|
||||
</thead>\
|
||||
<tr>\
|
||||
<td class="key_td">Max Mem</td>\
|
||||
<td class="value_td">'+humanize_size(host_info.HOST_SHARE.MAX_MEM)+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Used Mem (real)</td>\
|
||||
<td class="value_td">'+humanize_size(host_info.HOST_SHARE.USED_MEM)+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Used Mem (allocated)</td>\
|
||||
<td class="value_td">'+humanize_size(host_info.HOST_SHARE.MAX_USAGE)+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Used CPU (real)</td>\
|
||||
<td class="value_td">'+host_info.HOST_SHARE.USED_CPU+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Used CPU(allocated)</td>\
|
||||
<td class="value_td">'+host_info.HOST_SHARE.CPU_USAGE+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Running VMs</td>\
|
||||
<td class="value_td">'+host_info.HOST_SHARE.RUNNING_VMS+'</td>\
|
||||
</tr>\
|
||||
</table>'
|
||||
}
|
||||
|
||||
//Template tab
|
||||
var template_tab = {
|
||||
title : "Host template",
|
||||
content :
|
||||
'<table id="host_template_table" class="info_table">\
|
||||
<thead><tr><th colspan="2">Host template</th></tr></thead>'+
|
||||
prettyPrintJSON(host_info.TEMPLATE)+
|
||||
'</table>'
|
||||
}
|
||||
|
||||
//Sunstone.updateInfoPanelTab(info_panel_name,tab_name, new tab object);
|
||||
Sunstone.updateInfoPanelTab("host_info_panel","host_info_tab",info_tab);
|
||||
Sunstone.updateInfoPanelTab("host_info_panel","host_template_tab",template_tab);
|
||||
Sunstone.popUpInfoPanel("host_info_panel");
|
||||
|
||||
}
|
||||
|
||||
//Prepares the host creation dialog
|
||||
function setupCreateHostDialog(){
|
||||
$('div#dialogs').append('<div title="Create host" id="create_host_dialog"></div>');
|
||||
$('div#create_host_dialog').html(create_host_tmpl);
|
||||
$('#create_host_dialog').dialog({
|
||||
autoOpen: false,
|
||||
modal: true,
|
||||
width: 500
|
||||
});
|
||||
|
||||
$('#create_host_dialog button').button();
|
||||
|
||||
//Handle the form submission
|
||||
$('#create_host_form').submit(function(){
|
||||
if (!($('#name',this).val().length)){
|
||||
notifyError("Host name missing!");
|
||||
return false;
|
||||
}
|
||||
var host_json = { "host": { "name": $('#name',this).val(),
|
||||
"tm_mad": $('#tm_mad :selected',this).val(),
|
||||
"vm_mad": $('#vmm_mad :selected',this).val(),
|
||||
"im_mad": $('#im_mad :selected',this).val()}}
|
||||
|
||||
//Create the OpenNebula.Host.
|
||||
//If it's successfull we refresh the list.
|
||||
Sunstone.runAction("Host.create",host_json);
|
||||
//OpenNebula.Host.create({data: host_json, success: addHostElement, error: onError});
|
||||
$('#create_host_dialog').dialog('close');
|
||||
return false;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
//Prepares the dialog to create a cluster
|
||||
function setupCreateClusterDialog(){
|
||||
$('div#dialogs').append('<div title="Create cluster" id="create_cluster_dialog"></div>');
|
||||
$('#create_cluster_dialog').html(create_cluster_tmpl);
|
||||
|
||||
$('#create_cluster_dialog').dialog({
|
||||
autoOpen: false,
|
||||
modal: true,
|
||||
width: 400
|
||||
});
|
||||
|
||||
$('#create_cluster_dialog button').button();
|
||||
|
||||
$('#create_cluster_form').submit(function(){
|
||||
var name=$('#name',this).val();
|
||||
var cluster_json = { "cluster" : { "name" : name }};
|
||||
Sunstone.runAction("Cluster.create",cluster_json);
|
||||
$('#create_cluster_dialog').dialog('close');
|
||||
return false;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Open creation dialogs
|
||||
function popUpCreateHostDialog(){
|
||||
$('#create_host_dialog').dialog('open');
|
||||
return false;
|
||||
}
|
||||
|
||||
function popUpCreateClusterDialog(){
|
||||
$('#create_cluster_dialog').dialog('open');
|
||||
return false;
|
||||
}
|
||||
|
||||
//Prepares the autorefresh for hosts
|
||||
function setHostAutorefresh() {
|
||||
setInterval(function(){
|
||||
var checked = $('input:checked',dataTable_hosts.fnGetNodes());
|
||||
var filter = $("#datatable_hosts_filter input").attr("value");
|
||||
if (!checked.length && !filter.length){
|
||||
Sunstone.runAction("Host.autorefresh");
|
||||
}
|
||||
},INTERVAL+someTime());
|
||||
}
|
||||
|
||||
//Prepares the autorefresh for clusters
|
||||
function setClusterAutorefresh(){
|
||||
setInterval(function(){
|
||||
Sunstone.runAction("Cluster.autorefresh");
|
||||
},INTERVAL+someTime());
|
||||
}
|
||||
|
||||
//This is executed after the sunstone.js ready() is run.
|
||||
//Here we can basicly init the host datatable, preload it
|
||||
//and add specific listeners
|
||||
$(document).ready(function(){
|
||||
|
||||
//prepare host datatable
|
||||
dataTable_hosts = $("#datatable_hosts").dataTable({
|
||||
"bJQueryUI": true,
|
||||
"bSortClasses": false,
|
||||
"bAutoWidth":false,
|
||||
"sPaginationType": "full_numbers",
|
||||
"aoColumnDefs": [
|
||||
{ "bSortable": false, "aTargets": ["check"] },
|
||||
{ "sWidth": "60px", "aTargets": [0,4] },
|
||||
{ "sWidth": "35px", "aTargets": [1] },
|
||||
{ "sWidth": "120px", "aTargets": [5,6] }
|
||||
]
|
||||
});
|
||||
|
||||
//preload it
|
||||
dataTable_hosts.fnClearTable();
|
||||
addElement([
|
||||
spinner,
|
||||
'','','','','','',''],dataTable_hosts);
|
||||
Sunstone.runAction("Host.list");
|
||||
Sunstone.runAction("Cluster.list");
|
||||
|
||||
setupCreateHostDialog();
|
||||
setupCreateClusterDialog();
|
||||
|
||||
setHostAutorefresh();
|
||||
setClusterAutorefresh();
|
||||
|
||||
initCheckAllBoxes(dataTable_hosts);
|
||||
tableCheckboxesListener(dataTable_hosts);
|
||||
hostInfoListener();
|
||||
|
||||
});
|
851
src/sunstone/public/js/plugins/images-tab.js
Normal file
851
src/sunstone/public/js/plugins/images-tab.js
Normal file
@ -0,0 +1,851 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/*Images tab plugin*/
|
||||
|
||||
var images_tab_content =
|
||||
'<form id="image_form" action="" action="javascript:alert(\'js error!\');">\
|
||||
<div class="action_blocks">\
|
||||
</div>\
|
||||
<table id="datatable_images" class="display">\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th class="check"><input type="checkbox" class="check_all" value="">All</input></th>\
|
||||
<th>ID</th>\
|
||||
<th>User</th>\
|
||||
<th>Name</th>\
|
||||
<th>Type</th>\
|
||||
<th>Registration time</th>\
|
||||
<th>Public</th>\
|
||||
<th>Persistent</th>\
|
||||
<th>State</th>\
|
||||
<th>#VMS</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody id="tbodyimages">\
|
||||
</tbody>\
|
||||
</table>\
|
||||
</form>';
|
||||
|
||||
var create_image_tmpl =
|
||||
'<div id="img_tabs">\
|
||||
<ul><li><a href="#img_easy">Wizard</a></li>\
|
||||
<li><a href="#img_manual">Advanced mode</a></li>\
|
||||
</ul>\
|
||||
<div id="img_easy">\
|
||||
<form id="create_image_form_easy" action="">\
|
||||
<p style="font-size:0.8em;text-align:right;"><i>Fields marked with <span style="display:inline-block;" class="ui-icon ui-icon-alert" /> are mandatory</i><br />\
|
||||
<fieldset>\
|
||||
<div class="img_param img_man">\
|
||||
<label for="img_name">Name:</label>\
|
||||
<input type="text" name="img_name" id="img_name" />\
|
||||
<div class="tip">Name that the Image will get. Every image must have a unique name.</div>\
|
||||
</div>\
|
||||
<div class="img_param">\
|
||||
<label for="img_desc">Description:</label>\
|
||||
<input type="text" name="img_desc" id="img_desc" />\
|
||||
<div class="tip">Human readable description of the image for other users.</div>\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
<div class="img_param">\
|
||||
<label for="img_type">Type:</label>\
|
||||
<select name="img_type" id="img_type">\
|
||||
<option value="OS">OS</option>\
|
||||
<option value="CDROM">CD-ROM</option>\
|
||||
<option value="DATABLOCK">Datablock</option>\
|
||||
</select>\
|
||||
<div class="tip">Type of the image, explained in detail in the following section. If omitted, the default value is the one defined in oned.conf (install default is OS).</div>\
|
||||
</div>\
|
||||
<div class="img_param">\
|
||||
<label for="img_public">Public:</label>\
|
||||
<input type="checkbox" id="img_public" name="img_public" value="YES" />\
|
||||
<div class="tip">Public scope of the image</div>\
|
||||
</div>\
|
||||
<div class="img_param">\
|
||||
<label for="img_persistent">Persistent:</label>\
|
||||
<input type="checkbox" id="img_persistent" name="img_persistent" value="YES" />\
|
||||
<div class="tip">Persistence of the image</div>\
|
||||
</div>\
|
||||
<div class="img_param">\
|
||||
<label for="img_dev_prefix">Device prefix:</label>\
|
||||
<input type="text" name="img_dev_prefix" id="img_dev_prefix" />\
|
||||
<div class="tip">Prefix for the emulated device this image will be mounted at. For instance, “hd”, “sd”. If omitted, the default value is the one defined in oned.conf (installation default is “hd”).</div>\
|
||||
</div>\
|
||||
<div class="img_param">\
|
||||
<label for="img_bus">Bus:</label>\
|
||||
<select name="img_bus" id="img_bus">\
|
||||
<option value="IDE">IDE</option>\
|
||||
<option value="SCSI">SCSI</option>\
|
||||
<option value="virtio">Virtio (KVM)</option>\
|
||||
</select>\
|
||||
<div class="tip">Type of disk device to emulate.</div>\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
<div class="" id="src_path_select">\
|
||||
<label style="height:3em;">Path vs. source:</label>\
|
||||
<input type="radio" name="src_path" id="path_img" value="path" />\
|
||||
<label style="float:none">Provide a path</label><br />\
|
||||
<input type="radio" name="src_path" id="source_img" value="source" />\
|
||||
<label style="float:none">Provide a source</label><br />\
|
||||
<input type="radio" name="src_path" id="datablock_img" value="datablock" />\
|
||||
<label style="float:none;vertical-align:top">Create an empty datablock</label>\
|
||||
<div class="tip">Please choose path if you have a file-based image. Choose source otherwise or create an empty datablock disk.</div><br />\
|
||||
</div>\
|
||||
<div class="img_param">\
|
||||
<label for="img_path">Path:</label>\
|
||||
<input type="text" name="img_path" id="img_path" />\
|
||||
<div class="tip">Path to the original file that will be copied to the image repository. If not specified for a DATABLOCK type image, an empty image will be created.</div>\
|
||||
</div>\
|
||||
<div class="img_param">\
|
||||
<label for="img_source">Source:</label>\
|
||||
<input type="text" name="img_source" id="img_source" />\
|
||||
<div class="tip">Source to be used in the DISK attribute. Useful for not file-based images.</div>\
|
||||
</div>\
|
||||
<div class="img_size">\
|
||||
<label for="img_size">Size:</label>\
|
||||
<input type="text" name="img_size" id="img_size" />\
|
||||
<div class="tip">Size of the datablock in MB.</div>\
|
||||
</div>\
|
||||
<div class="img_param">\
|
||||
<label for="img_fstype">FS type:</label>\
|
||||
<input type="text" name="img_fstype" id="img_fstype" />\
|
||||
<div class="tip">Type of file system to be built. This can be any value understood by mkfs unix command.</div>\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
<div class="form_buttons">\
|
||||
<button class="button" id="create_image_submit" value="user/create">Create</button>\
|
||||
<button class="button" type="reset" value="reset">Reset</button>\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
</form>\
|
||||
</div>\
|
||||
<div id="img_manual">\
|
||||
<form id="create_image_form_manual" action="">\
|
||||
<fieldset style="border-top:none;">\
|
||||
<h3 style="margin-bottom:10px;">Write the image template here</h3>\
|
||||
<textarea id="template" rows="15" style="width:100%;">\
|
||||
</textarea>\
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
<div class="form_buttons">\
|
||||
<button class="button" id="create_vn_submit_manual" value="vn/create">\
|
||||
Create\
|
||||
</button>\
|
||||
<button class="button" type="reset" value="reset">Reset</button>\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
</form>\
|
||||
</div>\
|
||||
</div>';
|
||||
|
||||
var images_select = "";
|
||||
var image_list_json = {};
|
||||
var dataTable_images;
|
||||
|
||||
var image_actions = {
|
||||
|
||||
"Image.register" : {
|
||||
type: "create",
|
||||
call: OpenNebula.Image.register,
|
||||
callback: addImageElement,
|
||||
error: onError,
|
||||
notify:true
|
||||
},
|
||||
|
||||
"Image.create_dialog" : {
|
||||
type: "custom",
|
||||
call: popUpCreateImageDialog
|
||||
},
|
||||
|
||||
"Image.list" : {
|
||||
type: "list",
|
||||
call: OpenNebula.Image.list,
|
||||
callback: updateImagesView,
|
||||
error: onError
|
||||
},
|
||||
|
||||
"Image.show" : {
|
||||
type : "single",
|
||||
call: OpenNebula.Image.show,
|
||||
callback: updateImageElement,
|
||||
error: onError
|
||||
},
|
||||
|
||||
"Image.showinfo" : {
|
||||
type: "single",
|
||||
call: OpenNebula.Image.show,
|
||||
callback: updateImageInfo,
|
||||
error: onError
|
||||
},
|
||||
|
||||
"Image.refresh" : {
|
||||
type: "custom",
|
||||
call: function () {
|
||||
waitingNodes(dataTable_images);
|
||||
Sunstone.runAction("Image.list");
|
||||
},
|
||||
},
|
||||
|
||||
"Image.autorefresh" : {
|
||||
type: "custom",
|
||||
call: function() {
|
||||
OpenNebula.Image.list({timeout: true, success: updateImagesView, error: onError});
|
||||
}
|
||||
},
|
||||
|
||||
"Image.addattr" : {
|
||||
type: "multiple",
|
||||
call: function(obj){
|
||||
var id_attr = obj.data.id;
|
||||
var name = $('#img_attr_name').val();
|
||||
var value = $('#img_attr_value').val();
|
||||
OpenNebula.Image.addattr(
|
||||
{data: {
|
||||
id: id_attr,
|
||||
name: name,
|
||||
value: value
|
||||
},
|
||||
success: obj.success,
|
||||
error: obj.error
|
||||
});
|
||||
},
|
||||
callback : function (req) {
|
||||
Sunstone.runAction("Image.show",req.request.data[0]);
|
||||
},
|
||||
elements: function() { return getSelectedNodes(dataTable_images); },
|
||||
error: onError,
|
||||
notify: true
|
||||
},
|
||||
|
||||
"Image.addattr_dialog" : {
|
||||
type: "custom",
|
||||
call: popUpImageAddattrDialog
|
||||
},
|
||||
|
||||
"Image.updateattr_dialog" : {
|
||||
type: "custom",
|
||||
call: popUpImageAddattrDialog
|
||||
},
|
||||
|
||||
"Image.rmattr" : {
|
||||
type: "multiple",
|
||||
call: function(obj){
|
||||
var id_attr = obj.data.id;
|
||||
var name = $('#img_attr_name').val();
|
||||
OpenNebula.Image.rmattr(
|
||||
{data: {
|
||||
id: id_attr,
|
||||
name: name
|
||||
},
|
||||
success: obj.success,
|
||||
error: obj.error
|
||||
});
|
||||
},
|
||||
callback: function (req) {
|
||||
Sunstone.runAction("Image.show",req.request.data[0]);
|
||||
},
|
||||
elements: function() { return getSelectedNodes(dataTable_images); },
|
||||
error: onError,
|
||||
notify: true
|
||||
},
|
||||
|
||||
"Image.rmattr_dialog" : {
|
||||
type: "custom",
|
||||
call: popUpImageRmattrDialog,
|
||||
},
|
||||
|
||||
"Image.enable" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.Image.enable,
|
||||
callback: function (req) {
|
||||
Sunstone.runAction("Image.show",req.request.data[0]);
|
||||
},
|
||||
elements: function() { return getSelectedNodes(dataTable_images); },
|
||||
error: onError,
|
||||
notify: true
|
||||
},
|
||||
|
||||
"Image.disable" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.Image.disable,
|
||||
callback: function (req) {
|
||||
Sunstone.runAction("Image.show",req.request.data[0]);
|
||||
},
|
||||
elements: function() { return getSelectedNodes(dataTable_images); },
|
||||
error: onError,
|
||||
notify: true
|
||||
},
|
||||
|
||||
"Image.persistent" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.Image.persistent,
|
||||
callback: function (req) {
|
||||
Sunstone.runAction("Image.show",req.request.data[0]);
|
||||
},
|
||||
elements: function() { return getSelectedNodes(dataTable_images); },
|
||||
error: onError,
|
||||
notify: true
|
||||
},
|
||||
|
||||
"Image.nonpersistent" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.Image.nonpersistent,
|
||||
callback: function (req) {
|
||||
Sunstone.runAction("Image.show",req.request.data[0]);
|
||||
},
|
||||
elements: function() { return getSelectedNodes(dataTable_images); },
|
||||
error: onError,
|
||||
notify: true
|
||||
},
|
||||
|
||||
"Image.publish" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.Image.publish,
|
||||
callback: function (req) {
|
||||
Sunstone.runAction("Image.show",req.request.data[0]);
|
||||
},
|
||||
elements: function() { return getSelectedNodes(dataTable_images); },
|
||||
error: onError,
|
||||
notify: true
|
||||
},
|
||||
|
||||
"Image.unpublish" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.Image.unpublish,
|
||||
callback: function (req) {
|
||||
Sunstone.runAction("Image.show",req.request.data[0]);
|
||||
},
|
||||
elements: function() { return getSelectedNodes(dataTable_images); },
|
||||
error: onError,
|
||||
notify: true
|
||||
},
|
||||
|
||||
"Image.delete" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.Image.delete,
|
||||
callback: function (req) {
|
||||
Sunstone.runAction("Image.show",req.request.data[0]);
|
||||
},
|
||||
elements: function() { return getSelectedNodes(dataTable_images); },
|
||||
error: onError,
|
||||
notify: true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var image_buttons = {
|
||||
"Image.refresh" : {
|
||||
type: "image",
|
||||
text: "Refresh list",
|
||||
img: "/images/Refresh-icon.png",
|
||||
condition: True
|
||||
},
|
||||
"Image.create_dialog" : {
|
||||
type: "create_dialog",
|
||||
text: "+ New",
|
||||
condition: True
|
||||
},
|
||||
"Image.addattr_dialog" : {
|
||||
type: "action",
|
||||
text: "Add attribute",
|
||||
condition: True
|
||||
},
|
||||
"Image.updateattr_dialog" : {
|
||||
type: "action",
|
||||
text: "Update attribute",
|
||||
condition: True
|
||||
},
|
||||
"Image.rmattr_dialog" : {
|
||||
type: "action",
|
||||
text: "Remove attribute",
|
||||
condition: True
|
||||
},
|
||||
"action_list" : {
|
||||
type: "select",
|
||||
condition: True,
|
||||
actions: {
|
||||
"Image.enable" : {
|
||||
type: "action",
|
||||
text: "Enable",
|
||||
condition: True
|
||||
},
|
||||
"Image.disable" : {
|
||||
type: "action",
|
||||
text: "Disable",
|
||||
condition: True
|
||||
},
|
||||
"Image.publish" : {
|
||||
type: "action",
|
||||
text: "Publish",
|
||||
condition: True
|
||||
},
|
||||
"Image.unpublish" : {
|
||||
type: "action",
|
||||
text: "Unpublish",
|
||||
condition: True
|
||||
},
|
||||
"Image.persistent" : {
|
||||
type: "action",
|
||||
text: "Make persistent",
|
||||
condition: True
|
||||
},
|
||||
"Image.nonpersistent" : {
|
||||
type: "action",
|
||||
text: "Make non persistent",
|
||||
condition: True
|
||||
}
|
||||
}
|
||||
},
|
||||
"Image.delete" : {
|
||||
type: "action",
|
||||
text: "Delete",
|
||||
condition: True
|
||||
}
|
||||
}
|
||||
|
||||
var image_info_panel = {
|
||||
"image_info_tab" : {
|
||||
title: "Image information",
|
||||
content: ""
|
||||
},
|
||||
|
||||
"image_template_tab" : {
|
||||
title: "Image template",
|
||||
content: ""
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var images_tab = {
|
||||
title: "Images",
|
||||
content: images_tab_content,
|
||||
buttons: image_buttons,
|
||||
condition: True
|
||||
}
|
||||
|
||||
Sunstone.addActions(image_actions);
|
||||
Sunstone.addMainTab('images_tab',images_tab);
|
||||
Sunstone.addInfoPanel('image_info_panel',image_info_panel);
|
||||
|
||||
// Returns an array containing the values of the image_json and ready
|
||||
// to be inserted in the dataTable
|
||||
function imageElementArray(image_json){
|
||||
var image = image_json.IMAGE;
|
||||
return [
|
||||
'<input type="checkbox" id="image_'+image.ID+'" name="selected_items" value="'+image.ID+'"/>',
|
||||
image.ID,
|
||||
image.USERNAME ? image.USERNAME : getUserName(image.UID),
|
||||
image.NAME,
|
||||
OpenNebula.Helper.image_type(image.TYPE),
|
||||
pretty_time(image.REGTIME),
|
||||
parseInt(image.PUBLIC) ? "yes" : "no",
|
||||
parseInt(image.PERSISTENT) ? "yes" : "no",
|
||||
OpenNebula.Helper.resource_state("image",image.STATE),
|
||||
image.RUNNING_VMS
|
||||
];
|
||||
}
|
||||
|
||||
// Set up the listener on the table TDs to show the info panel
|
||||
function imageInfoListener(){
|
||||
|
||||
$('#tbodyimages tr').live("click",function(e){
|
||||
if ($(e.target).is('input')) {return true;}
|
||||
popDialogLoading();
|
||||
var aData = dataTable_images.fnGetData(this);
|
||||
var id = $(aData[0]).val();
|
||||
Sunstone.runAction("Image.showinfo",id);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
//Updates the select input field with an option for each image
|
||||
function updateImageSelect(){
|
||||
images_select = makeSelectOptions(dataTable_images,1,3,8,"DISABLED");
|
||||
|
||||
//update static selectors:
|
||||
//in the VM section
|
||||
$('div.vm_section#disks select#IMAGE_ID').html(images_select);
|
||||
}
|
||||
|
||||
// Callback to update an element in the dataTable
|
||||
function updateImageElement(request, image_json){
|
||||
var id = image_json.IMAGE.ID;
|
||||
var element = imageElementArray(image_json);
|
||||
updateSingleElement(element,dataTable_images,'#image_'+id);
|
||||
updateImageSelect();
|
||||
}
|
||||
|
||||
// Callback to remove an element from the dataTable
|
||||
function deleteImageElement(req){
|
||||
deleteElement(dataTable_images,'#image_'+req.request.data);
|
||||
updateImageSelect();
|
||||
}
|
||||
|
||||
// Callback to add an image element
|
||||
function addImageElement(request, image_json){
|
||||
var element = imageElementArray(image_json);
|
||||
addElement(element,dataTable_images);
|
||||
//NOTE that the select is not updated because newly added images
|
||||
//are disabled by default
|
||||
}
|
||||
|
||||
// Callback to refresh the list of images
|
||||
function updateImagesView(request, images_list){
|
||||
image_list_json = images_list;
|
||||
var image_list_array = [];
|
||||
$.each(image_list_json,function(){
|
||||
image_list_array.push(imageElementArray(this));
|
||||
});
|
||||
|
||||
updateView(image_list_array,dataTable_images);
|
||||
updateImageSelect();
|
||||
updateDashboard("images",image_list_json);
|
||||
|
||||
}
|
||||
|
||||
// Prepare the dialog to add/remove/update image attributes
|
||||
function setupImageAttributesDialogs(){
|
||||
|
||||
//Append to DOM
|
||||
$('div#dialogs').append('<div id="image_attributes_dialog" title="Image attributes"></div>');
|
||||
|
||||
//Put HTML in place
|
||||
$('#image_attributes_dialog').html(
|
||||
'<form action="javascript:alert(\'js error!\');">\
|
||||
<fieldset>\
|
||||
<div id="img_attr_action_desc">\
|
||||
</div>\
|
||||
<div>\
|
||||
<label for="img_attr_name">Name:</label>\
|
||||
<input type="text" id="img_attr_name" name="img_attr_name" value="" />\
|
||||
</div>\
|
||||
<div>\
|
||||
<label for="img_attr_value">Value:</label>\
|
||||
<input type="text" id="img_attr_value" name="img_attr_value" value="" />\
|
||||
</div>\
|
||||
<div class="form_buttons">\
|
||||
<button class="action_button" id="img_attr_proceed" value="">OK</button>\
|
||||
<button id="img_attr_cancel" value="">Cancel</button>\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
</form>');
|
||||
|
||||
$('#image_attributes_dialog').dialog({
|
||||
autoOpen:false,
|
||||
width:400,
|
||||
modal:true,
|
||||
height:220,
|
||||
resizable:false,
|
||||
});
|
||||
|
||||
$('#image_attributes_dialog button').button();
|
||||
|
||||
//Upcase variable names
|
||||
$('#img_attr_name').keyup(function(){
|
||||
$(this).val($(this).val().toUpperCase());
|
||||
});
|
||||
|
||||
$('#image_attributes_dialog #img_attr_proceed').click(function(){
|
||||
$('#image_attributes_dialog').dialog('close');
|
||||
});
|
||||
|
||||
$('#image_attributes_dialog #img_attr_cancel').click(function(){
|
||||
$('#image_attributes_dialog').dialog('close');
|
||||
return false;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Popup a dialog to add/update an attribute
|
||||
function popUpImageAddattrDialog(){
|
||||
|
||||
//Show value field and label
|
||||
$('#img_attr_value').show();
|
||||
$('#img_attr_value').prev().show();
|
||||
var desc = "Please write the name and value of the attribute. It will be added or updated in all selected images:";
|
||||
$('#img_attr_proceed').val("Image.addattr");
|
||||
$('#img_attr_action_desc').html(desc);
|
||||
$('#image_attributes_dialog').dialog('open');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Popup a dialog to remove an attribute
|
||||
function popUpImageRmattrDialog(){
|
||||
|
||||
//Hide value field and label
|
||||
$('#img_attr_value').hide();
|
||||
$('#img_attr_value').prev().hide();
|
||||
var desc = "Please type the attribute you want to remove:";
|
||||
$('#img_attr_proceed').val("Image.rmattr");
|
||||
$('#img_attr_action_desc').html(desc);
|
||||
$('#image_attributes_dialog').dialog('open');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Callback to update the information panel tabs and pop it up
|
||||
function updateImageInfo(request,img){
|
||||
var img_info = img.IMAGE;
|
||||
var info_tab = {
|
||||
title: "Image information",
|
||||
content:
|
||||
'<table id="info_img_table" class="info_table">\
|
||||
<thead>\
|
||||
<tr><th colspan="2">Image "'+img_info.NAME+'" information</th></tr>\
|
||||
</thead>\
|
||||
<tr>\
|
||||
<td class="key_td">ID</td>\
|
||||
<td class="value_td">'+img_info.ID+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Name</td>\
|
||||
<td class="value_td">'+img_info.NAME+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Type</td>\
|
||||
<td class="value_td">'+OpenNebula.Helper.image_type(img_info.TYPE)+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Register time</td>\
|
||||
<td class="value_td">'+pretty_time(img_info.REGTIME)+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Public</td>\
|
||||
<td class="value_td">'+(parseInt(img_info.PUBLIC) ? "yes" : "no")+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Persistent</td>\
|
||||
<td class="value_td">'+(parseInt(img_info.PERSISTENT) ? "yes" : "no")+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Source</td>\
|
||||
<td class="value_td">'+img_info.SOURCE+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">State</td>\
|
||||
<td class="value_td">'+OpenNebula.Helper.resource_state("image",img_info.STATE)+'</td>\
|
||||
</tr>\
|
||||
</table>'
|
||||
}
|
||||
|
||||
var template_tab = {
|
||||
title: "Image template",
|
||||
content: '<table id="img_template_table" class="info_table">\
|
||||
<thead><tr><th colspan="2">Image template</th></tr></thead>'+
|
||||
prettyPrintJSON(img_info.TEMPLATE)+
|
||||
'</table>'
|
||||
}
|
||||
|
||||
Sunstone.updateInfoPanelTab("image_info_panel","image_info_tab",info_tab);
|
||||
Sunstone.updateInfoPanelTab("image_info_panel","image_template_tab",template_tab);
|
||||
|
||||
Sunstone.popUpInfoPanel("image_info_panel");
|
||||
|
||||
}
|
||||
|
||||
// Prepare the image creation dialog
|
||||
function setupCreateImageDialog(){
|
||||
$('div#dialogs').append('<div title="Create Image" id="create_image_dialog"></div>');
|
||||
|
||||
//Insert HTML in place
|
||||
$('#create_image_dialog').html(create_image_tmpl);
|
||||
|
||||
//Prepare jquery dialog
|
||||
$('#create_image_dialog').dialog({
|
||||
autoOpen: false,
|
||||
modal:true,
|
||||
width: 520
|
||||
});
|
||||
|
||||
$('#img_tabs').tabs();
|
||||
$('#create_image_dialog button').button();
|
||||
$('#img_type option').first().attr("selected","selected");
|
||||
$('#datablock_img').attr("disabled","disabled");
|
||||
|
||||
//Chrome workaround
|
||||
$('select#img_type').change(function(){
|
||||
$(this).trigger("click");
|
||||
});
|
||||
|
||||
$('select#img_type').click(function(){
|
||||
var value = $(this).val();
|
||||
switch (value){
|
||||
case "DATABLOCK":
|
||||
$('#datablock_img').removeAttr("disabled");
|
||||
break;
|
||||
default:
|
||||
$('#datablock_img').attr("disabled","disabled");
|
||||
$('#path_img').attr("checked","checked");
|
||||
$('#img_source,#img_fstype,#img_size').parent().hide();
|
||||
$('#img_path').parent().show();
|
||||
}
|
||||
});
|
||||
|
||||
$('#img_source,#img_fstype,#img_size').parent().hide();
|
||||
$('#path_img').attr("checked","checked");
|
||||
$('#img_path').parent().addClass("img_man");
|
||||
|
||||
$('#img_public').click(function(){
|
||||
$('#img_persistent').removeAttr("checked");
|
||||
});
|
||||
|
||||
$('#img_persistent').click(function(){
|
||||
$('#img_public').removeAttr("checked");
|
||||
});
|
||||
|
||||
|
||||
|
||||
$('#src_path_select input').click(function(){
|
||||
var value = $(this).val();
|
||||
switch (value){
|
||||
case "path":
|
||||
$('#img_source,#img_fstype,#img_size').parent().hide();
|
||||
$('#img_source,#img_fstype,#img_size').parent().removeClass("img_man");
|
||||
$('#img_path').parent().show();
|
||||
$('#img_path').parent().addClass("img_man");
|
||||
break;
|
||||
case "source":
|
||||
$('#img_path,#img_fstype,#img_size').parent().hide();
|
||||
$('#img_path,#img_fstype,#img_size').parent().removeClass("img_man");
|
||||
$('#img_source').parent().show();
|
||||
$('#img_source').parent().addClass("img_man");
|
||||
break;
|
||||
case "datablock":
|
||||
$('#img_source,#img_path').parent().hide();
|
||||
$('#img_source,#img_path').parent().removeClass("img_man");
|
||||
$('#img_fstype,#img_size').parent().show();
|
||||
$('#img_fstype,#img_size').parent().addClass("img_man");
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$('#create_image_form_easy').submit(function(){
|
||||
var exit = false;
|
||||
$('.img_man',this).each(function(){
|
||||
if (!$('input',this).val().length){
|
||||
notifyError("There are mandatory parameters missing");
|
||||
exit = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (exit) { return false; }
|
||||
var img_json = {};
|
||||
|
||||
var name = $('#img_name').val();
|
||||
img_json["NAME"] = name;
|
||||
|
||||
var desc = $('#img_desc').val();
|
||||
if (desc.length){
|
||||
img_json["DESCRIPTION"] = desc;
|
||||
}
|
||||
|
||||
var type = $('#img_type').val();
|
||||
img_json["TYPE"]= type;
|
||||
|
||||
img_json["PUBLIC"] = $('#img_public:checked').length ? "YES" : "NO";
|
||||
|
||||
img_json["PERSISTENT"] = $('#img_persistent:checked').length ? "YES" : "NO";
|
||||
|
||||
var dev_prefix = $('#img_dev_prefix').val();
|
||||
if (dev_prefix.length){
|
||||
img_json["DEV_PREFIX"] = dev_prefix;
|
||||
}
|
||||
|
||||
var bus = $('#img_bus').val();
|
||||
img_json["BUS"] = bus;
|
||||
|
||||
switch ($('#src_path_select input:checked').val()){
|
||||
case "path":
|
||||
path = $('#img_path').val();
|
||||
img_json["PATH"] = path;
|
||||
break;
|
||||
case "source":
|
||||
source = $('#img_source').val();
|
||||
img_json["SOURCE"] = source;
|
||||
break;
|
||||
case "datablock":
|
||||
size = $('#img_size').val();
|
||||
fstype = $('#img_fstype').val();
|
||||
img_json["SIZE"] = size;
|
||||
img_json["FSTYPE"] = fstype;
|
||||
break;
|
||||
}
|
||||
var obj = { "image" : img_json };
|
||||
Sunstone.runAction("Image.register", obj);
|
||||
|
||||
$('#create_image_dialog').dialog('close');
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#create_image_form_manual').submit(function(){
|
||||
var template=$('#template',this).val();
|
||||
Sunstone.runAction("Image.register",template);
|
||||
$('#create_image_dialog').dialog('close');
|
||||
return false;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function popUpCreateImageDialog(){
|
||||
$('#create_image_dialog').dialog('open');
|
||||
}
|
||||
|
||||
// Set the autorefresh interval for the datatable
|
||||
function setImageAutorefresh() {
|
||||
setInterval(function(){
|
||||
var checked = $('input:checked',dataTable_images.fnGetNodes());
|
||||
var filter = $("#datatable_images_filter input").attr("value");
|
||||
if (!checked.length && !filter.length){
|
||||
Sunstone.runAction("Image.autorefresh");
|
||||
}
|
||||
},INTERVAL+someTime());
|
||||
}
|
||||
|
||||
//The DOM is ready at this point
|
||||
$(document).ready(function(){
|
||||
|
||||
dataTable_images = $("#datatable_images").dataTable({
|
||||
"bJQueryUI": true,
|
||||
"bSortClasses": false,
|
||||
"bAutoWidth":false,
|
||||
"sPaginationType": "full_numbers",
|
||||
"aoColumnDefs": [
|
||||
{ "bSortable": false, "aTargets": ["check"] },
|
||||
{ "sWidth": "60px", "aTargets": [0,3] },
|
||||
{ "sWidth": "35px", "aTargets": [1] },
|
||||
{ "sWidth": "100px", "aTargets": [2,3] }
|
||||
]
|
||||
});
|
||||
|
||||
dataTable_images.fnClearTable();
|
||||
addElement([
|
||||
spinner,
|
||||
'','','','','','','','',''],dataTable_images);
|
||||
Sunstone.runAction("Image.list");
|
||||
|
||||
setupCreateImageDialog();
|
||||
setupImageAttributesDialogs();
|
||||
setupTips($('#create_image_dialog'));
|
||||
setImageAutorefresh();
|
||||
|
||||
initCheckAllBoxes(dataTable_images);
|
||||
tableCheckboxesListener(dataTable_images);
|
||||
imageInfoListener();
|
||||
|
||||
})
|
257
src/sunstone/public/js/plugins/users-tab.js
Normal file
257
src/sunstone/public/js/plugins/users-tab.js
Normal file
@ -0,0 +1,257 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/*Users tab plugin*/
|
||||
|
||||
var users_tab_content =
|
||||
'<form id="user_form" action="" action="javascript:alert(\'js error!\');">\
|
||||
<div class="action_blocks">\
|
||||
</div>\
|
||||
<table id="datatable_users" class="display">\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th class="check"><input type="checkbox" class="check_all" value="">All</input></th>\
|
||||
<th>ID</th>\
|
||||
<th>Name</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody id="tbodyusers">\
|
||||
</tbody>\
|
||||
</table>\
|
||||
</form>';
|
||||
|
||||
var create_user_tmpl =
|
||||
'<form id="create_user_form" action="">\
|
||||
<fieldset>\
|
||||
<div>\
|
||||
<label for="username">Username:</label>\
|
||||
<input type="text" name="username" id="username" /><br />\
|
||||
<label for="pass">Password:</label>\
|
||||
<input type="password" name="pass" id="pass" />\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
<div class="form_buttons">\
|
||||
<button class="button" id="create_user_submit" value="user/create">Create</button>\
|
||||
<button class="button" type="reset" value="reset">Reset</button>\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
</form>';
|
||||
|
||||
var user_list_json = {};
|
||||
var dataTable_users;
|
||||
|
||||
var user_actions = {
|
||||
"User.create" : {
|
||||
type: "create",
|
||||
call: OpenNebula.User.create,
|
||||
callback: addUserElement,
|
||||
error: onError,
|
||||
notify: true
|
||||
},
|
||||
|
||||
"User.create_dialog" : {
|
||||
type: "custom",
|
||||
call: popUpCreateUserDialog
|
||||
},
|
||||
|
||||
"User.list" : {
|
||||
type: "list",
|
||||
call: OpenNebula.User.list,
|
||||
callback: updateUsersView,
|
||||
error: onError
|
||||
},
|
||||
|
||||
"User.refresh" : {
|
||||
type: "custom",
|
||||
call: function () {
|
||||
waitingNodes(dataTable_users);
|
||||
Sunstone.runAction("User.list");
|
||||
},
|
||||
},
|
||||
|
||||
"User.autorefresh" : {
|
||||
type: "custom",
|
||||
call: function(){
|
||||
OpenNebula.User.list({timeout: true, success: updateUsersView, error: onError});
|
||||
},
|
||||
condition: function(){ uid == 0 },
|
||||
notify: false
|
||||
},
|
||||
|
||||
"User.delete" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.User.delete,
|
||||
callback: deleteUserElement,
|
||||
elements: function() { return getSelectedNodes(dataTable_users); },
|
||||
error: onError,
|
||||
notify: true
|
||||
},
|
||||
}
|
||||
|
||||
var user_buttons = {
|
||||
"User.refresh" : {
|
||||
type: "image",
|
||||
text: "Refresh list",
|
||||
img: "/images/Refresh-icon.png",
|
||||
condition: True
|
||||
},
|
||||
"User.create_dialog" : {
|
||||
type: "create_dialog",
|
||||
text: "+ New",
|
||||
condition: True
|
||||
},
|
||||
"User.delete" : {
|
||||
type: "action",
|
||||
text: "Delete",
|
||||
condition: True
|
||||
}
|
||||
}
|
||||
|
||||
var users_tab = {
|
||||
title: "Users",
|
||||
content: users_tab_content,
|
||||
buttons: user_buttons,
|
||||
condition: function(){ return uid == 0; }
|
||||
}
|
||||
|
||||
Sunstone.addActions(user_actions);
|
||||
Sunstone.addMainTab('users_tab',users_tab);
|
||||
|
||||
// Returns an array with the values from the user_json ready to be
|
||||
// added to the dataTable
|
||||
function userElementArray(user_json){
|
||||
var user = user_json.USER;
|
||||
if (!user.NAME || user.NAME == {}){
|
||||
name = "";
|
||||
} else {
|
||||
name = user.NAME;
|
||||
}
|
||||
|
||||
return [
|
||||
'<input type="checkbox" id="user_'+user.ID+'" name="selected_items" value="'+user.ID+'"/>',
|
||||
user.ID,
|
||||
name
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
// Callback to refresh a single element from the dataTable
|
||||
function updateUserElement(request, user_json){
|
||||
var id = user_json.USER.ID;
|
||||
var element = userElementArray(user_json);
|
||||
updateSingleElement(element,dataTable_users,'#user_'+id);
|
||||
}
|
||||
|
||||
// Callback to delete a single element from the dataTable
|
||||
function deleteUserElement(req){
|
||||
deleteElement(dataTable_users,'#user_'+req.request.data);
|
||||
}
|
||||
|
||||
// Callback to add a single user element
|
||||
function addUserElement(request,user_json){
|
||||
var element = userElementArray(user_json);
|
||||
addElement(element,dataTable_users);
|
||||
}
|
||||
|
||||
// Callback to update the list of users
|
||||
function updateUsersView(request,users_list){
|
||||
user_list_json = users_list;
|
||||
var user_list_array = [];
|
||||
|
||||
$.each(user_list_json,function(){
|
||||
user_list_array.push(userElementArray(this));
|
||||
});
|
||||
updateView(user_list_array,dataTable_users);
|
||||
updateDashboard("users",user_list_json);
|
||||
}
|
||||
|
||||
// Prepare the user creation dialog
|
||||
function setupCreateUserDialog(){
|
||||
$('div#dialogs').append('<div title="Create user" id="create_user_dialog"></div>');
|
||||
$('#create_user_dialog').html(create_user_tmpl);
|
||||
|
||||
//Prepare jquery dialog
|
||||
$('#create_user_dialog').dialog({
|
||||
autoOpen: false,
|
||||
modal:true,
|
||||
width: 400
|
||||
});
|
||||
|
||||
$('#create_user_dialog button').button();
|
||||
|
||||
$('#create_user_form').submit(function(){
|
||||
var user_name=$('#username',this).val();
|
||||
var user_password=$('#pass',this).val();
|
||||
if (!user_name.length && !user_password.length){
|
||||
notifyError("User name and password must be filled in");
|
||||
return false;
|
||||
}
|
||||
|
||||
var user_json = { "user" :
|
||||
{ "name" : user_name,
|
||||
"password" : user_password }
|
||||
};
|
||||
Sunstone.runAction("User.create",user_json);
|
||||
$('#create_user_dialog').dialog('close');
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
function popUpCreateUserDialog(){
|
||||
$('#create_user_dialog').dialog('open');
|
||||
}
|
||||
|
||||
// Prepare the autorefresh of the list
|
||||
function setUserAutorefresh(){
|
||||
setInterval(function(){
|
||||
var checked = $('input:checked',dataTable_users.fnGetNodes());
|
||||
var filter = $("#datatable_users_filter input").attr("value");
|
||||
if (!checked.length && !filter.length){
|
||||
Sunstone.runAction("User.autorefresh");
|
||||
}
|
||||
},INTERVAL+someTime());
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//if we are not oneadmin, our tab will not even be in the DOM.
|
||||
if (uid==0) {
|
||||
dataTable_users = $("#datatable_users").dataTable({
|
||||
"bJQueryUI": true,
|
||||
"bSortClasses": false,
|
||||
"sPaginationType": "full_numbers",
|
||||
"bAutoWidth":false,
|
||||
"aoColumnDefs": [
|
||||
{ "bSortable": false, "aTargets": ["check"] },
|
||||
{ "sWidth": "60px", "aTargets": [0] },
|
||||
{ "sWidth": "35px", "aTargets": [1] }
|
||||
]
|
||||
});
|
||||
dataTable_users.fnClearTable();
|
||||
addElement([
|
||||
spinner,
|
||||
'',''],dataTable_users);
|
||||
|
||||
Sunstone.runAction("User.list");
|
||||
|
||||
setupCreateUserDialog();
|
||||
setUserAutorefresh();
|
||||
|
||||
initCheckAllBoxes(dataTable_users);
|
||||
tableCheckboxesListener(dataTable_users);
|
||||
}
|
||||
})
|
1969
src/sunstone/public/js/plugins/vms-tab.js
Normal file
1969
src/sunstone/public/js/plugins/vms-tab.js
Normal file
File diff suppressed because it is too large
Load Diff
587
src/sunstone/public/js/plugins/vnets-tab.js
Normal file
587
src/sunstone/public/js/plugins/vnets-tab.js
Normal file
@ -0,0 +1,587 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/*Virtual networks tab plugin*/
|
||||
|
||||
var vnets_tab_content =
|
||||
'<form id="virtualNetworks_form" action="javascript:alert(\'js error!\');">\
|
||||
<div class="action_blocks">\
|
||||
</div>\
|
||||
<table id="datatable_vnetworks" class="display">\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th class="check"><input type="checkbox" class="check_all" value="">All</input></th>\
|
||||
<th>ID</th>\
|
||||
<th>User</th>\
|
||||
<th>Name</th>\
|
||||
<th>Type</th>\
|
||||
<th>Bridge</th>\
|
||||
<th>Public?</th>\
|
||||
<th>Total Leases</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody id="tbodyvnetworks">\
|
||||
</tbody>\
|
||||
</table>\
|
||||
</form>';
|
||||
|
||||
var create_vn_tmpl =
|
||||
'<div id="vn_tabs">\
|
||||
<ul>\
|
||||
<li><a href="#easy">Wizard</a></li>\
|
||||
<li><a href="#manual">Advanced mode</a></li>\
|
||||
</ul>\
|
||||
<div id="easy">\
|
||||
<form id="create_vn_form_easy" action="">\
|
||||
<fieldset>\
|
||||
<label for="name">Name:</label>\
|
||||
<input type="text" name="name" id="name" /><br />\
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
<label for="bridge">Bridge:</label>\
|
||||
<input type="text" name="bridge" id="bridge" /><br />\
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
<label style="height:2em;">Network type:</label>\
|
||||
<input type="radio" name="fixed_ranged" id="fixed_check" value="fixed" checked="checked">Fixed network</input><br />\
|
||||
<input type="radio" name="fixed_ranged" id="ranged_check" value="ranged">Ranged network</input><br />\
|
||||
</fieldset>\
|
||||
<div class="clear"></div>\
|
||||
<div id="easy_tabs">\
|
||||
<div id="fixed">\
|
||||
<fieldset>\
|
||||
<label for="leaseip">Lease IP:</label>\
|
||||
<input type="text" name="leaseip" id="leaseip" /><br />\
|
||||
<label for="leasemac">Lease MAC (opt):</label>\
|
||||
<input type="text" name="leasemac" id="leasemac" />\
|
||||
<div class="clear"></div>\
|
||||
<button class="add_remove_button add_button" id="add_lease" value="add/lease">\
|
||||
Add\
|
||||
</button>\
|
||||
<button class="add_remove_button" id="remove_lease" value="remove/lease">\
|
||||
Remove selected\
|
||||
</button>\
|
||||
<label for="leases">Current leases:</label>\
|
||||
<select id="leases" name="leases" size="10" style="width:150px" multiple>\
|
||||
<!-- insert leases -->\
|
||||
</select><br />\
|
||||
</fieldset>\
|
||||
</div>\
|
||||
<div id="ranged">\
|
||||
<fieldset>\
|
||||
<label for="net_address">Network Address:</label>\
|
||||
<input type="text" name="net_address" id="net_address" /><br />\
|
||||
<label for="net_size">Network size:</label>\
|
||||
<input type="text" name="net_size" id="net_size" />\
|
||||
</fieldset>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="clear"></div>\
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
<div class="form_buttons">\
|
||||
<button class="button" id="create_vn_submit_easy" value="vn/create">\
|
||||
Create\
|
||||
</button>\
|
||||
<button class="button" type="reset" value="reset">Reset</button>\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
</form>\
|
||||
</div>\
|
||||
<div id="manual">\
|
||||
<form id="create_vn_form_manual" action="">\
|
||||
<h3 style="margin-bottom:10px;">Write the Virtual Network template here</h3>\
|
||||
<fieldset style="border-top:none;">\
|
||||
<textarea id="template" rows="15" style="width:100%;"></textarea>\
|
||||
<div class="clear"></div>\
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
<div class="form_buttons">\
|
||||
<button class="button" id="create_vn_submit_manual" value="vn/create">\
|
||||
Create\
|
||||
</button>\
|
||||
<button class="button" type="reset" value="reset">Reset</button>\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
</form>\
|
||||
</div>\
|
||||
</div>';
|
||||
|
||||
var vnetworks_select="";
|
||||
var network_list_json = {};
|
||||
var dataTable_vNetworks;
|
||||
|
||||
//Setup actions
|
||||
|
||||
var vnet_actions = {
|
||||
"Network.create" : {
|
||||
type: "create",
|
||||
call: OpenNebula.Network.create,
|
||||
callback: addVNetworkElement,
|
||||
error: onError,
|
||||
notify: true
|
||||
},
|
||||
|
||||
"Network.create_dialog" : {
|
||||
type: "custom",
|
||||
call: popUpCreateVnetDialog
|
||||
},
|
||||
|
||||
"Network.list" : {
|
||||
type: "list",
|
||||
call: OpenNebula.Network.list,
|
||||
callback: updateVNetworksView,
|
||||
error: onError
|
||||
},
|
||||
|
||||
"Network.show" : {
|
||||
type: "single",
|
||||
call: OpenNebula.Network.show,
|
||||
callback: updateVNetworkElement,
|
||||
error: onError
|
||||
},
|
||||
|
||||
"Network.showinfo" : {
|
||||
type: "single",
|
||||
call: OpenNebula.Network.show,
|
||||
callback: updateVNetworkInfo,
|
||||
error: onError
|
||||
|
||||
},
|
||||
|
||||
"Network.refresh" : {
|
||||
type: "custom",
|
||||
call: function(){
|
||||
waitingNodes(dataTable_vNetworks);
|
||||
Sunstone.runAction("Network.list");
|
||||
}
|
||||
},
|
||||
|
||||
"Network.autorefresh" : {
|
||||
type: "custom",
|
||||
call: function() {
|
||||
OpenNebula.Network.list({timeout: true, success: updateVNetworksView, error: onError});
|
||||
}
|
||||
},
|
||||
|
||||
"Network.publish" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.Network.publish,
|
||||
callback: function (req) {
|
||||
Sunstone.runAction("Network.show",req.request.data[0]);
|
||||
},
|
||||
elements: function() { return getSelectedNodes(dataTable_vNetworks); },
|
||||
error: onError,
|
||||
notify: true
|
||||
},
|
||||
|
||||
"Network.unpublish" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.Network.unpublish,
|
||||
callback: function (req) {
|
||||
Sunstone.runAction("Network.show",req.request.data[0]);
|
||||
},
|
||||
elements: function() { return getSelectedNodes(dataTable_vNetworks); },
|
||||
error: onError,
|
||||
notify: true
|
||||
},
|
||||
|
||||
"Network.delete" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.Network.delete,
|
||||
callback: deleteVNetworkElement,
|
||||
elements: function() { return getSelectedNodes(dataTable_vNetworks); },
|
||||
error: onError,
|
||||
notify: true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
var vnet_buttons = {
|
||||
"Network.refresh" : {
|
||||
type: "image",
|
||||
text: "Refresh list",
|
||||
img: "/images/Refresh-icon.png",
|
||||
condition: True
|
||||
},
|
||||
|
||||
"Network.create_dialog" : {
|
||||
type: "create_dialog",
|
||||
text: "+ New",
|
||||
condition: True
|
||||
},
|
||||
|
||||
"Network.publish" : {
|
||||
type: "action",
|
||||
text: "Publish",
|
||||
condition: True
|
||||
},
|
||||
|
||||
"Network.unpublish" : {
|
||||
type: "action",
|
||||
text: "Unpublish",
|
||||
condition: True
|
||||
},
|
||||
|
||||
"Network.delete" : {
|
||||
type: "action",
|
||||
text: "Delete",
|
||||
condition: True
|
||||
}
|
||||
}
|
||||
|
||||
var vnet_info_panel = {
|
||||
"vnet_info_tab" : {
|
||||
title: "Virtual network information",
|
||||
content: ""
|
||||
},
|
||||
"vnet_template_tab" : {
|
||||
title: "Virtual network template",
|
||||
content: ""
|
||||
}
|
||||
}
|
||||
|
||||
var vnets_tab = {
|
||||
title: "Virtual Networks",
|
||||
content: vnets_tab_content,
|
||||
buttons: vnet_buttons,
|
||||
condition: True
|
||||
}
|
||||
|
||||
Sunstone.addActions(vnet_actions);
|
||||
Sunstone.addMainTab('vnets_tab',vnets_tab);
|
||||
Sunstone.addInfoPanel('vnet_info_panel',vnet_info_panel);
|
||||
|
||||
//returns an array with the VNET information fetched from the JSON object
|
||||
function vNetworkElementArray(vn_json){
|
||||
var network = vn_json.VNET;
|
||||
var total_leases = "0";
|
||||
|
||||
if (network.TOTAL_LEASES){
|
||||
total_leases = network.TOTAL_LEASES;
|
||||
} else if (network.LEASES && network.LEASES.LEASE){
|
||||
total_leases = network.LEASES.LEASE.length ? network.LEASES.LEASE.length : "1";
|
||||
}
|
||||
|
||||
//Does the JSON bring a username field? Otherwise try
|
||||
//to get it from the users dataTable
|
||||
var username = network.USERNAME? network.USERNAME : getUserName(network.UID)
|
||||
|
||||
|
||||
return ['<input type="checkbox" id="vnetwork_'+network.ID+'" name="selected_items" value="'+network.ID+'"/>',
|
||||
network.ID,
|
||||
username,
|
||||
network.NAME,
|
||||
parseInt(network.TYPE) ? "FIXED" : "RANGED",
|
||||
network.BRIDGE,
|
||||
parseInt(network.PUBLIC) ? "yes" : "no",
|
||||
total_leases ];
|
||||
}
|
||||
|
||||
|
||||
//Adds a listener to show the extended info when clicking on a row
|
||||
function vNetworkInfoListener(){
|
||||
|
||||
$('#tbodyvnetworks tr').live("click", function(e){
|
||||
if ($(e.target).is('input')) {return true;}
|
||||
popDialogLoading();
|
||||
var aData = dataTable_vNetworks.fnGetData(this);
|
||||
var id = $(aData[0]).val();
|
||||
Sunstone.runAction("Network.showinfo",id);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
//updates the vnet select different options
|
||||
function updateNetworkSelect(){
|
||||
vnetworks_select= makeSelectOptions(dataTable_vNetworks,1,3,6,"no")
|
||||
|
||||
//update static selectors:
|
||||
//in the VM creation dialog
|
||||
$('div.vm_section#networks select#NETWORK_ID').html(vnetworks_select);
|
||||
}
|
||||
|
||||
//Callback to update a vnet element after an action on it
|
||||
function updateVNetworkElement(request, vn_json){
|
||||
id = vn_json.VNET.ID;
|
||||
element = vNetworkElementArray(vn_json);
|
||||
updateSingleElement(element,dataTable_vNetworks,'#vnetwork_'+id);
|
||||
updateNetworkSelect();
|
||||
}
|
||||
|
||||
//Callback to delete a vnet element from the table
|
||||
function deleteVNetworkElement(req){
|
||||
deleteElement(dataTable_vNetworks,'#vnetwork_'+req.request.data);
|
||||
updateNetworkSelect();
|
||||
}
|
||||
|
||||
//Callback to add a new element
|
||||
function addVNetworkElement(request,vn_json){
|
||||
var element = vNetworkElementArray(vn_json);
|
||||
addElement(element,dataTable_vNetworks);
|
||||
updateNetworkSelect();
|
||||
}
|
||||
|
||||
//updates the list of virtual networks
|
||||
function updateVNetworksView(request, network_list){
|
||||
network_list_json = network_list;
|
||||
var network_list_array = [];
|
||||
|
||||
$.each(network_list,function(){
|
||||
network_list_array.push(vNetworkElementArray(this));
|
||||
});
|
||||
|
||||
updateView(network_list_array,dataTable_vNetworks);
|
||||
updateNetworkSelect();
|
||||
//dependency with dashboard
|
||||
updateDashboard("vnets",network_list_json);
|
||||
|
||||
}
|
||||
|
||||
//updates the information panel tabs and pops the panel up
|
||||
function updateVNetworkInfo(request,vn){
|
||||
var vn_info = vn.VNET;
|
||||
var info_tab_content =
|
||||
'<table id="info_vn_table" class="info_table">\
|
||||
<thead>\
|
||||
<tr><th colspan="2">Virtual Network '+vn_info.ID+' information</th></tr>\
|
||||
</thead>\
|
||||
<tr>\
|
||||
<td class="key_td">ID</td>\
|
||||
<td class="value_td">'+vn_info.ID+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">UID</td>\
|
||||
<td class="value_td">'+vn_info.UID+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Public</td>\
|
||||
<td class="value_td">'+(parseInt(vn_info.PUBLIC) ? "yes" : "no" )+'</td>\
|
||||
</tr>\
|
||||
</table>';
|
||||
|
||||
//if it is a fixed VNET we can add leases information
|
||||
if (vn_info.TEMPLATE.TYPE == "FIXED"){
|
||||
info_tab_content += '<table id="vn_leases_info_table" class="info_table">\
|
||||
<thead>\
|
||||
<tr><th colspan="2">Leases information</th></tr>\
|
||||
</thead>'+
|
||||
prettyPrintJSON(vn_info.LEASES)+
|
||||
'</table>';
|
||||
}
|
||||
|
||||
|
||||
var info_tab = {
|
||||
title: "Virtual Network information",
|
||||
content: info_tab_content
|
||||
}
|
||||
|
||||
var template_tab = {
|
||||
title: "Virtual Network template",
|
||||
content: '<table id="vn_template_table" class="info_table">\
|
||||
<thead><tr><th colspan="2">Virtual Network template</th></tr></thead>'+
|
||||
prettyPrintJSON(vn_info.TEMPLATE)+
|
||||
'</table>'
|
||||
}
|
||||
|
||||
Sunstone.updateInfoPanelTab("vnet_info_panel","vnet_info_tab",info_tab);
|
||||
Sunstone.updateInfoPanelTab("vnet_info_panel","vnet_template_tab",template_tab);
|
||||
|
||||
Sunstone.popUpInfoPanel("vnet_info_panel");
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Prepares the vnet creation dialog
|
||||
function setupCreateVNetDialog() {
|
||||
|
||||
$('div#dialogs').append('<div title="Create Virtual Network" id="create_vn_dialog"></div>');
|
||||
$('#create_vn_dialog').html(create_vn_tmpl);
|
||||
|
||||
|
||||
//Prepare the jquery-ui dialog. Set style options here.
|
||||
$('#create_vn_dialog').dialog({
|
||||
autoOpen: false,
|
||||
modal: true,
|
||||
width: 475,
|
||||
height: 500
|
||||
});
|
||||
|
||||
//Make the tabs look nice for the creation mode
|
||||
$('#vn_tabs').tabs();
|
||||
$('div#ranged').hide();
|
||||
$('#fixed_check').click(function(){
|
||||
$('div#fixed').show();
|
||||
$('div#ranged').hide();
|
||||
});
|
||||
$('#ranged_check').click(function(){
|
||||
$('div#fixed').hide();
|
||||
$('div#ranged').show();
|
||||
});
|
||||
$('#create_vn_dialog button').button();
|
||||
|
||||
|
||||
//When we hit the add lease button...
|
||||
$('#add_lease').click(function(){
|
||||
var create_form = $('#create_vn_form_easy'); //this is our scope
|
||||
|
||||
//Fetch the interesting values
|
||||
var lease_ip = $('#leaseip',create_form).val();
|
||||
var lease_mac = $('#leasemac',create_form).val();
|
||||
|
||||
//We don't add anything to the list if there is nothing to add
|
||||
if (lease_ip == null) {
|
||||
notifyError("Please provide a lease IP");
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
var lease = ""; //contains the HTML to be included in the select box
|
||||
if (lease_mac == "") {
|
||||
lease='<option value="' + lease_ip + '">' + lease_ip + '</option>';
|
||||
} else {
|
||||
lease='<option value="' +
|
||||
lease_ip + ',' +
|
||||
lease_mac + '">' +
|
||||
lease_ip + ',' + lease_mac +
|
||||
'</option>';
|
||||
};
|
||||
|
||||
//We append the HTML into the select box.
|
||||
$('select#leases').append(lease);
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#remove_lease').click(function(){
|
||||
$('select#leases :selected').remove();
|
||||
return false;
|
||||
});
|
||||
|
||||
//Handle submission of the easy mode
|
||||
$('#create_vn_form_easy').submit(function(){
|
||||
//Fetch values
|
||||
var name = $('#name',this).val();
|
||||
if (!name.length){
|
||||
notifyError("Virtual Network name missing!");
|
||||
return false;
|
||||
}
|
||||
var bridge = $('#bridge',this).val();
|
||||
var type = $('input:checked',this).val();
|
||||
|
||||
//TODO: Name and bridge provided?!
|
||||
|
||||
var network_json = null;
|
||||
if (type == "fixed") {
|
||||
var leases = $('#leases option', this);
|
||||
var leases_obj=[];
|
||||
|
||||
//for each specified lease we prepare the JSON object
|
||||
$.each(leases,function(){
|
||||
leases_obj.push({"ip": $(this).val() });
|
||||
});
|
||||
|
||||
//and construct the final data for the request
|
||||
network_json = {
|
||||
"vnet" : {
|
||||
"type" : "FIXED",
|
||||
"leases" : leases_obj,
|
||||
"bridge" : bridge,
|
||||
"name" : name }};
|
||||
}
|
||||
else { //type ranged
|
||||
|
||||
var network_addr = $('#net_address',this).val();
|
||||
var network_size = $('#net_size',this).val();
|
||||
if (!network_addr.length){
|
||||
notifyError("Please provide a network address");
|
||||
return false;
|
||||
};
|
||||
|
||||
//we form the object for the request
|
||||
network_json = {
|
||||
"vnet" : {
|
||||
"type" : "RANGED",
|
||||
"bridge" : bridge,
|
||||
"network_size" : network_size,
|
||||
"network_address" : network_addr,
|
||||
"name" : name }
|
||||
};
|
||||
};
|
||||
|
||||
//Create the VNetwork.
|
||||
|
||||
Sunstone.runAction("Network.create",network_json);
|
||||
$('#create_vn_dialog').dialog('close');
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#create_vn_form_manual').submit(function(){
|
||||
var template=$('#template',this).val();
|
||||
var vnet_json = {vnet: {vnet_raw: template}};
|
||||
Sunstone.runAction("Network.create",vnet_json);
|
||||
$('#create_vn_dialog').dialog('close');
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
function popUpCreateVnetDialog() {
|
||||
$('#create_vn_dialog').dialog('open');
|
||||
}
|
||||
|
||||
function setVNetAutorefresh() {
|
||||
setInterval(function(){
|
||||
var checked = $('input:checked',dataTable_vNetworks.fnGetNodes());
|
||||
var filter = $("#datatable_vnetworks_filter input").attr("value");
|
||||
if (!checked.length && !filter.length){
|
||||
Sunstone.runAction("Network.autorefresh");
|
||||
}
|
||||
},INTERVAL+someTime());
|
||||
}
|
||||
|
||||
//The DOM is ready and the ready() from sunstone.js
|
||||
//has been executed at this point.
|
||||
$(document).ready(function(){
|
||||
|
||||
dataTable_vNetworks = $("#datatable_vnetworks").dataTable({
|
||||
"bJQueryUI": true,
|
||||
"bSortClasses": false,
|
||||
"bAutoWidth":false,
|
||||
"sPaginationType": "full_numbers",
|
||||
"aoColumnDefs": [
|
||||
{ "bSortable": false, "aTargets": ["check"] },
|
||||
{ "sWidth": "60px", "aTargets": [0,4,5,6,7] },
|
||||
{ "sWidth": "35px", "aTargets": [1] },
|
||||
{ "sWidth": "100px", "aTargets": [2] }
|
||||
]
|
||||
});
|
||||
|
||||
dataTable_vNetworks.fnClearTable();
|
||||
addElement([
|
||||
spinner,
|
||||
'','','','','','',''],dataTable_vNetworks);
|
||||
Sunstone.runAction("Network.list");
|
||||
|
||||
|
||||
setupCreateVNetDialog();
|
||||
setVNetAutorefresh();
|
||||
|
||||
initCheckAllBoxes(dataTable_vNetworks);
|
||||
tableCheckboxesListener(dataTable_vNetworks);
|
||||
vNetworkInfoListener();
|
||||
|
||||
|
||||
});
|
404
src/sunstone/public/js/sunstone-util.js
Normal file
404
src/sunstone/public/js/sunstone-util.js
Normal file
@ -0,0 +1,404 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* Some useful functions for Sunstone default plugins */
|
||||
var INTERVAL=60000;
|
||||
|
||||
function someTime(){
|
||||
return Math.floor(Math.random()*30000);
|
||||
}
|
||||
|
||||
//introduces 0s before a number until in reaches 'length'.
|
||||
function pad(number,length) {
|
||||
var str = '' + number;
|
||||
while (str.length < length)
|
||||
str = '0' + str;
|
||||
return str;
|
||||
}
|
||||
|
||||
//turns a Unix-formatted time into a human readable string
|
||||
function pretty_time(time_seconds)
|
||||
{
|
||||
var d = new Date();
|
||||
d.setTime(time_seconds*1000);
|
||||
|
||||
var secs = pad(d.getSeconds(),2);
|
||||
var hour = pad(d.getHours(),2);
|
||||
var mins = pad(d.getMinutes(),2);
|
||||
var day = pad(d.getDate(),2);
|
||||
var month = pad(d.getMonth(),2);
|
||||
var year = d.getFullYear();
|
||||
|
||||
return hour + ":" + mins +":" + secs + " " + month + "/" + day + "/" + year;
|
||||
}
|
||||
|
||||
//returns a human readable size in Kilo, Mega, Giga or Tera bytes
|
||||
function humanize_size(value) {
|
||||
if (typeof(value) === "undefined") {
|
||||
value = 0;
|
||||
}
|
||||
var binarySufix = ["K", "M", "G", "T" ];
|
||||
var i=0;
|
||||
while (value > 1024 && i < 3){
|
||||
value = value / 1024;
|
||||
i++;
|
||||
}
|
||||
value = Math.round(value * 10) / 10;
|
||||
|
||||
if (value - Math.round(value) == 0) {
|
||||
value = Math.round(value);
|
||||
}
|
||||
|
||||
var st = value + binarySufix[i];
|
||||
return st;
|
||||
}
|
||||
|
||||
//Wrapper to add an element to a dataTable
|
||||
function addElement(element,data_table){
|
||||
data_table.fnAddData(element);
|
||||
}
|
||||
|
||||
//deletes an element with id 'tag' from a dataTable
|
||||
function deleteElement(data_table,tag){
|
||||
var tr = $(tag).parents('tr')[0];
|
||||
data_table.fnDeleteRow(tr);
|
||||
$('input',data_table).trigger("change");
|
||||
}
|
||||
|
||||
//Listens to the checkboxes of the datatable. This function is used
|
||||
//by standard sunstone plugins to enable/disable certain action buttons
|
||||
//according to the number of elements checked in the dataTables.
|
||||
//It also checks the "check-all" box when all elements are checked
|
||||
function tableCheckboxesListener(dataTable){
|
||||
|
||||
//Initialization - disable all buttons
|
||||
var context = dataTable.parents('form');
|
||||
var last_action_b = $('.last_action_button',context);
|
||||
$('.top_button, .list_button',context).button("disable");
|
||||
if (last_action_b.length && last_action_b.val().length){
|
||||
last_action_b.button("disable");
|
||||
};
|
||||
$('.create_dialog_button',context).button("enable");
|
||||
|
||||
//listen to changes in the visible inputs
|
||||
$('tbody input',dataTable).live("change",function(){
|
||||
var table = $(this).parents('tbody');
|
||||
var context = table.parents('form');
|
||||
var nodes = $('tr',table);
|
||||
var total_length = nodes.length;
|
||||
var checked_length = $('input:checked',nodes).length;
|
||||
|
||||
var last_action_b = $('.last_action_button',context);
|
||||
|
||||
|
||||
//if all elements are checked we check the check-all box
|
||||
if (total_length == checked_length && total_length != 0){
|
||||
$('.check_all',dataTable).attr("checked","checked");
|
||||
} else {
|
||||
$('.check_all',dataTable).removeAttr("checked");
|
||||
}
|
||||
|
||||
//if some element is checked, we enable buttons, otherwise
|
||||
//we disable them.
|
||||
if (checked_length){
|
||||
$('.top_button, .list_button',context).button("enable");
|
||||
//check if the last_action_button should be enabled
|
||||
if (last_action_b.length && last_action_b.val().length){
|
||||
last_action_b.button("enable");
|
||||
};
|
||||
} else {
|
||||
$('.top_button, .list_button',context).button("disable");
|
||||
last_action_b.button("disable");
|
||||
}
|
||||
|
||||
//any case the create dialog buttons should always be enabled.
|
||||
$('.create_dialog_button',context).button("enable");
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Updates a data_table, with a 2D array containing the new values
|
||||
// Does a partial redraw, so the filter and pagination are kept
|
||||
function updateView(item_list,data_table){
|
||||
if (data_table!=null) {
|
||||
data_table.fnClearTable();
|
||||
data_table.fnAddData(item_list);
|
||||
data_table.fnDraw(false);
|
||||
};
|
||||
}
|
||||
|
||||
//replaces an element with id 'tag' in a dataTable with a new one
|
||||
function updateSingleElement(element,data_table,tag){
|
||||
var nodes = data_table.fnGetNodes();
|
||||
var tr = $(tag,nodes).parents('tr')[0];
|
||||
var position = data_table.fnGetPosition(tr);
|
||||
data_table.fnUpdate(element,position,0,false);
|
||||
$('input',data_table).trigger("change");
|
||||
|
||||
}
|
||||
|
||||
// Returns an string in the form key=value key=value ...
|
||||
// Does not explore objects in depth.
|
||||
function stringJSON(json){
|
||||
var str = ""
|
||||
for (field in json) {
|
||||
str+= field + '=' + json[field] + ' ';
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
//Notifications
|
||||
//Notification of submission of action
|
||||
function notifySubmit(action, args, extra_param){
|
||||
var action_text = action.replace(/OpenNebula\./,'').replace(/\./,' ');
|
||||
|
||||
var msg = "<h1>Submitted</h1>";
|
||||
if (!args || (typeof args == 'object' && args.constructor != Array)){
|
||||
msg += action_text;
|
||||
} else {
|
||||
msg += action_text + ": " + args;
|
||||
}
|
||||
if (extra_param != null)
|
||||
msg += " >> " + extra_param;
|
||||
|
||||
$.jGrowl(msg, {theme: "jGrowl-notify-submit"});
|
||||
}
|
||||
|
||||
//Notification on error
|
||||
function notifyError(msg){
|
||||
msg = "<h1>Error</h1>" + msg;
|
||||
|
||||
$.jGrowl(msg, {theme: "jGrowl-notify-error", sticky: true });
|
||||
}
|
||||
|
||||
// Returns an HTML string with the json keys and values in the form
|
||||
// key: value<br />
|
||||
// It recursively explores objects, and flattens their contents in
|
||||
// the result.
|
||||
function prettyPrintJSON(template_json){
|
||||
var str = ""
|
||||
for (field in template_json) {
|
||||
if (typeof template_json[field] == 'object'){
|
||||
str += prettyPrintJSON(template_json[field]) + '<tr><td></td><td></td></tr>';
|
||||
} else {
|
||||
str += '<tr><td class="key_td">'+field+'</td><td class="value_td">'+template_json[field]+'</td></tr>';
|
||||
};
|
||||
};
|
||||
return str;
|
||||
}
|
||||
|
||||
//Add a listener to the check-all box of a datatable, enabling it to
|
||||
//check and uncheck all the checkboxes of its elements.
|
||||
function initCheckAllBoxes(datatable){
|
||||
//not showing nice in that position
|
||||
//$('.check_all').button({ icons: {primary : "ui-icon-check" },
|
||||
// text : true});
|
||||
|
||||
//small css hack
|
||||
$('.check_all',datatable).css({"border":"2px"});
|
||||
$('.check_all',datatable).click(function(){
|
||||
if ($(this).attr("checked")) {
|
||||
$('tbody input:checkbox',
|
||||
$(this).parents("table")).each(function(){
|
||||
$(this).attr("checked","checked");
|
||||
});
|
||||
|
||||
} else {
|
||||
$('tbody input:checkbox',
|
||||
$(this).parents("table")).each(function(){
|
||||
$(this).removeAttr("checked");
|
||||
});
|
||||
}
|
||||
$('tbody input:checkbox',$(this).parents("table")).trigger("change");
|
||||
});
|
||||
}
|
||||
|
||||
//standard handling for the server errors on ajax requests.
|
||||
//Pops up a message with the information.
|
||||
function onError(request,error_json) {
|
||||
var method;
|
||||
var action;
|
||||
var object;
|
||||
var id;
|
||||
var reason;
|
||||
var m;
|
||||
var message = error_json.error.message;
|
||||
|
||||
//redirect to login if unauthenticated
|
||||
if (error_json.error.http_status=="401") {
|
||||
window.location.href = "/login";
|
||||
};
|
||||
|
||||
if (!message){
|
||||
notifyError("Cannot contact server: is Sunstone server running and reachable?");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Parse known errors:
|
||||
var action_error = /^\[(\w+)\] Error trying to (\w+) (\w+) \[(\w+)\].*Reason: (.*)\.$/;
|
||||
var action_error_noid = /^\[(\w+)\] Error trying to (\w+) (\w+) (.*)\.$/;
|
||||
var get_error = /^\[(\w+)\] Error getting (\w+) \[(\w+)\]\.$/;
|
||||
var auth_error = /^\[(\w+)\] User \[.\] not authorized to perform (\w+) on (\w+) \[?(\w+)\]?\.?$/;
|
||||
|
||||
if (m = message.match(action_error)) {
|
||||
method = m[1];
|
||||
action = m[2];
|
||||
object = m[3];
|
||||
id = m[4];
|
||||
reason = m[5];
|
||||
} else if (m = message.match(action_error_noid)) {
|
||||
method = m[1];
|
||||
action = m[2];
|
||||
object = m[3];
|
||||
reason = m[4];
|
||||
} else if (m = message.match(get_error)) {
|
||||
method = m[1];
|
||||
action = "SHOW";
|
||||
object = m[2];
|
||||
id = m[3];
|
||||
} else if (m = message.match(auth_error)) {
|
||||
method = m[1];
|
||||
action = m[2];
|
||||
object = m[3];
|
||||
id = m[4];
|
||||
}
|
||||
|
||||
if (m) {
|
||||
var rows;
|
||||
var i;
|
||||
var value;
|
||||
rows = ["method","action","object","id","reason"];
|
||||
message = "";
|
||||
for (i in rows){
|
||||
key = rows[i];
|
||||
value = eval(key);
|
||||
if (value)
|
||||
message += "<tr><td class=\"key_error\">"+key+"</td><td>"+value+"</td></tr>";
|
||||
}
|
||||
message = "<table>" + message + "</table>";
|
||||
}
|
||||
|
||||
notifyError(message);
|
||||
return true;
|
||||
}
|
||||
|
||||
//Replaces the checkboxes of a datatable with a ajax-loading spinner.
|
||||
//Used when refreshing elements of a datatable.
|
||||
function waitingNodes(dataTable){
|
||||
var nodes = dataTable.fnGetData();
|
||||
for (var i=0;i<nodes.length;i++){
|
||||
dataTable.fnUpdate(spinner,i,0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//given a user ID, returns an string with the user name.
|
||||
//To do this it finds the user name in the user dataTable. If it is
|
||||
//not defined then it returns "uid UID".
|
||||
//TODO not very nice to hardcode a dataTable here...
|
||||
function getUserName(uid){
|
||||
var user = "uid "+uid;
|
||||
if (typeof(dataTable_users) == "undefined") {
|
||||
return user;
|
||||
}
|
||||
var nodes = dataTable_users.fnGetData();
|
||||
|
||||
$.each(nodes,function(){
|
||||
if (uid == this[1]) {
|
||||
user = this[2];
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return user;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Replaces all class"tip" divs with an information icon that
|
||||
//displays the tip information on mouseover.
|
||||
function setupTips(context){
|
||||
|
||||
//For each tip in this context
|
||||
$('div.tip',context).each(function(){
|
||||
//store the text
|
||||
var tip = $(this).html();
|
||||
//replace the text with an icon and spans
|
||||
$(this).html('<span class="ui-icon ui-icon-info info_icon"></span>');
|
||||
$(this).append('<span class="tipspan"></span>');
|
||||
|
||||
$(this).append('<span class="ui-icon ui-icon-alert man_icon" />');
|
||||
|
||||
//add the text to .tipspan
|
||||
$('span.tipspan',this).html(tip);
|
||||
//make sure it is not floating in the wrong place
|
||||
$(this).parent().append('<div class="clear"></div>');
|
||||
//hide the text
|
||||
$('span.tipspan',this).hide();
|
||||
|
||||
//When the mouse is hovering on the icon we fadein/out
|
||||
//the tip text
|
||||
$('span.info_icon',this).hover(function(e){
|
||||
var top, left;
|
||||
top = e.pageY - 15;// - $(this).parents('#create_vm_dialog').offset().top - 15;
|
||||
left = e.pageX + 15;// - $(this).parents('#create_vm_dialog').offset().left;
|
||||
$(this).next().css(
|
||||
{"top":top+"px",
|
||||
"left":left+"px"});
|
||||
$(this).next().fadeIn();
|
||||
},function(){
|
||||
$(this).next().fadeOut();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//returns an array of ids of selected elements in a dataTable
|
||||
function getSelectedNodes(dataTable){
|
||||
var selected_nodes = [];
|
||||
if (dataTable != null){
|
||||
//Which rows of the datatable are checked?
|
||||
var nodes = $('input:checked',$('tbody',dataTable));
|
||||
$.each(nodes,function(){
|
||||
selected_nodes.push($(this).val());
|
||||
});
|
||||
}
|
||||
return selected_nodes;
|
||||
}
|
||||
|
||||
//returns a HTML string with a select input code generated from
|
||||
//a dataTable
|
||||
function makeSelectOptions(dataTable,id_col,name_col,status_col,status_bad){
|
||||
var nodes = dataTable.fnGetData();
|
||||
var select = "<option value=\"\">Please select</option>";
|
||||
var array;
|
||||
$.each(nodes,function(){
|
||||
var id = this[id_col];
|
||||
var name = this[name_col];
|
||||
var status = this[status_col];
|
||||
if (status != status_bad){
|
||||
select +='<option value="'+id+'">'+name+'</option>';
|
||||
}
|
||||
});
|
||||
return select;
|
||||
}
|
||||
|
||||
//functions that used as true and false conditions for testing mainly
|
||||
function True(){
|
||||
return true;
|
||||
}
|
||||
function False(){
|
||||
return false;
|
||||
}
|
654
src/sunstone/public/js/sunstone.js
Normal file
654
src/sunstone/public/js/sunstone.js
Normal file
@ -0,0 +1,654 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
var cookie = {};
|
||||
var username = '';
|
||||
var uid = '';
|
||||
var spinner = '<img src="/images/ajax-loader.gif" alt="retrieving" class="loading_img"/>';
|
||||
|
||||
|
||||
//Sunstone configuration is formed by predifined "actions", main tabs
|
||||
//and "info_panels". Each tab has "content" and "buttons". Each
|
||||
//"info_panel" has "tabs" with "content".
|
||||
var SunstoneCfg = {
|
||||
"actions" : {},
|
||||
"tabs" : {},
|
||||
"info_panels" : {}
|
||||
};
|
||||
|
||||
/* Public plugin interface */
|
||||
|
||||
var Sunstone = {
|
||||
|
||||
//Adds a predifined action
|
||||
"addAction" : function (action_name,action_obj) {
|
||||
SunstoneCfg["actions"][action_name] = action_obj;
|
||||
},
|
||||
|
||||
//Replaces a predefined action
|
||||
"updateAction" : function(action_name,action_obj) {
|
||||
SunstoneCfg["actions"][action_name] = action_obj;
|
||||
},
|
||||
|
||||
//Deletes a predefined action.
|
||||
"removeAction" : function(action_name) {
|
||||
delete SunstoneCfg["actions"][action_name];
|
||||
},
|
||||
|
||||
//Adds several actions encapsulated in an js object.
|
||||
"addActions" : function(actions) {
|
||||
for (action in actions){
|
||||
Sunstone.addAction(action,actions[action]);
|
||||
}
|
||||
},
|
||||
|
||||
//Adds a new main tab. Refreshes the dom if wanted.
|
||||
"addMainTab" : function(tab_id,tab_obj,refresh) {
|
||||
SunstoneCfg["tabs"][tab_id] = tab_obj;
|
||||
if (refresh){
|
||||
insertTab(tab_id);
|
||||
}
|
||||
},
|
||||
|
||||
//Updates the content of an info tab and refreshes the DOM if wanted.
|
||||
"updateMainTabContent" : function(tab_id,content_arg,refresh){
|
||||
SunstoneCfg["tabs"][tab_id]["content"]=content_arg;
|
||||
if (refresh){ //if not present it won't be updated
|
||||
$('div#'+tab_id).html(content_arg);
|
||||
}
|
||||
},
|
||||
|
||||
//Replaces the buttons of an info tab and regenerates them if wanted.
|
||||
"updateMainTabButtons" : function(tab_id,buttons_arg,refresh){
|
||||
SunstoneCfg["tabs"][tab_id]["buttons"]=buttons_arg;
|
||||
if (refresh){
|
||||
$('div#'+tab_id+' .action_blocks').empty();
|
||||
insertButtonsInTab(tab_id);
|
||||
}
|
||||
},
|
||||
|
||||
//Removes a tab and refreshes the DOM
|
||||
"removeMainTab" : function(tab_id,refresh) {
|
||||
delete SunstoneCfg["tabs"][tab_id];
|
||||
if (refresh) {
|
||||
$('div#'+tab_id).remove();
|
||||
$('ul#navigation li#li_'+tab_id).remove();
|
||||
}
|
||||
},
|
||||
|
||||
//Adds a new info panel
|
||||
"addInfoPanel" : function(panel_name, panel_obj){
|
||||
SunstoneCfg["info_panels"][panel_name]=panel_obj;
|
||||
},
|
||||
|
||||
//Replaces an existing info panel
|
||||
"updateInfoPanel" : function(panel_name,panel_obj){
|
||||
SunstoneCfg["info_panels"][panel_name]=panel_obj;
|
||||
},
|
||||
|
||||
//Removes an info panel
|
||||
"removeInfoPanel" : function(panel_name){
|
||||
delete SunstoneCfg["info_panels"][panel_name];
|
||||
},
|
||||
|
||||
//Makes an info panel content pop up in the screen.
|
||||
"popUpInfoPanel" : function(panel_name, selected_tab){
|
||||
popDialog(Sunstone.getInfoPanelHTML(panel_name, selected_tab));
|
||||
},
|
||||
|
||||
//Generates and returns the HTML div element for an info panel, with
|
||||
//Jquery tabs.
|
||||
"getInfoPanelHTML" : function(panel_name,selected_tab){
|
||||
var info_panel = $('<div id="'+panel_name+'"><ul></ul></div>');
|
||||
var tabs = SunstoneCfg["info_panels"][panel_name];
|
||||
var tab=null;
|
||||
for (tab_name in tabs){
|
||||
tab=tabs[tab_name];
|
||||
$('ul',info_panel).append('<li><a href="#'+tab_name+'">'+tab.title+'</a></li>');
|
||||
info_panel.append('<div id="'+tab_name+'">'+tab.content+'</div>');
|
||||
}
|
||||
if (selected_tab){
|
||||
return info_panel.tabs({selected: selected_tab});
|
||||
}
|
||||
return info_panel.tabs({selected: 0});
|
||||
|
||||
},
|
||||
|
||||
//adds a tab to an info panel.
|
||||
"addInfoPanelTab" : function(panel_name, panel_tab_id, panel_tab_obj){
|
||||
SunstoneCfg["info_panels"][panel_name][panel_tab_id] = panel_tab_obj;
|
||||
},
|
||||
|
||||
//Replaces a tab from an info panel. Refreshes the DOM if wanted.
|
||||
"updateInfoPanelTab" : function(panel_name, panel_tab_id,
|
||||
panel_tab_obj, refresh){
|
||||
SunstoneCfg["info_panels"][panel_name][panel_tab_id] = panel_tab_obj;
|
||||
if (refresh){
|
||||
var tab_content = panel_tab_obj.content;
|
||||
$('div#'+panel_name+' div#'+panel_tab_id).html(tab_content);
|
||||
}
|
||||
},
|
||||
|
||||
//Removes a tab from an info panel configuration.
|
||||
"removeInfoPanelTab" : function(panel_name,panel_tab_id){
|
||||
delete SunstoneCfg["info_panels"][panel_name][panel_tab_id];
|
||||
},
|
||||
|
||||
//Runs a predefined action. Wraps the calls to opennebula.js and
|
||||
//can be use to run action depending on conditions and notify them
|
||||
//if desired.
|
||||
"runAction" : function(action, data_arg, extra_param){
|
||||
|
||||
var actions = SunstoneCfg["actions"];
|
||||
if (!actions[action]){
|
||||
notifyError("Action "+action+" not defined");
|
||||
return;
|
||||
}
|
||||
|
||||
var action_cfg = actions[action];
|
||||
var notify = action_cfg.notify;
|
||||
|
||||
var condition = action_cfg["condition"];
|
||||
|
||||
//Is the condition to run the action met?
|
||||
//Should we inform if it is not met?
|
||||
if (condition && !condition()){
|
||||
if (notify) {
|
||||
notifyError("This action cannot be run");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var call = action_cfg["call"];
|
||||
var callback = action_cfg["callback"];
|
||||
var err = action_cfg["error"];
|
||||
|
||||
|
||||
//Time to close any confirmation dialogs, as the execution may have
|
||||
//come from them.
|
||||
$('div#confirm_with_select_dialog').dialog("close");
|
||||
$('div#confirm_dialog').dialog("close");
|
||||
|
||||
|
||||
//We ease the use of:
|
||||
// * "create" calls to opennebula.js
|
||||
// * "single" element calls to opennebula.js
|
||||
// * "list" (get the pool of elements) calls to opennebula.js
|
||||
// * "multiple" - actions to be run on a given list of elements
|
||||
// (with maybe an extra parameter).
|
||||
// * The default actions. Simple call the the pre-defined "call"
|
||||
// function with an extraparam if defined.
|
||||
switch (action_cfg.type){
|
||||
|
||||
case "create":
|
||||
case "register":
|
||||
call({data:data_arg, success: callback, error:err});
|
||||
break;
|
||||
case "single":
|
||||
call({data:{id:data_arg}, success: callback,error:err});
|
||||
break;
|
||||
case "list":
|
||||
call({success: callback, error:err});
|
||||
break;
|
||||
case "multiple":
|
||||
//run on the list of nodes that come on the data
|
||||
$.each(data_arg,function(){
|
||||
if (extra_param){
|
||||
call({data:{id:this,extra_param:extra_param}, success: callback, error: err});
|
||||
} else {
|
||||
call({data:{id:this}, success: callback, error:err});
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
//This action is complemente handled by the "call" function.
|
||||
//we pass any data if present.
|
||||
if (data_arg && extra_param) {call(data_arg,extra_param);}
|
||||
else if (data_arg) {call(data_arg);}
|
||||
else {call();}
|
||||
}
|
||||
//notify submission
|
||||
if (notify) {
|
||||
notifySubmit(action,data_arg,extra_param);
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
|
||||
//Runs a predefined action on the selected nodes of a datatable.
|
||||
//Optionally they are run with an extra_parameter.
|
||||
//If no datatable is provided, it simply runs the action.
|
||||
//~ "runActionOnDatatableNodes": function(action,dataTable,extra_param){
|
||||
//~ if (dataTable != null){
|
||||
//~
|
||||
//~ //Which rows of the datatable are checked?
|
||||
//~ var nodes = $('input:checked',dataTable.fnGetNodes());
|
||||
//~ var data = [];
|
||||
//~ $.each(nodes,function(){
|
||||
//~ data.push($(this).val());
|
||||
//~ });
|
||||
//~ Sunstone.runAction(action,data,extra_param);
|
||||
//~
|
||||
//~ } else {
|
||||
//~ Sunstone.runAction(action,extra_param);
|
||||
//~ };
|
||||
//~ },
|
||||
//~
|
||||
//returns a button object from the desired tab
|
||||
"getButton" : function(tab_id,button_name){
|
||||
var button = null;
|
||||
var buttons = SunstoneCfg["tabs"][tab_id]["buttons"];
|
||||
button = buttons[button_name];
|
||||
//not found, is it in the list then?
|
||||
if (!button && buttons["action_list"])
|
||||
{
|
||||
button = buttons["action_list"]["actions"][button_name];
|
||||
}
|
||||
return button;
|
||||
} //end sunstone methods
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Plugins have done their pre-ready jobs when we execute this. That means
|
||||
//all startup configuration is in place regarding tabs, info panels etc.
|
||||
$(document).ready(function(){
|
||||
readCookie();
|
||||
setLogin();
|
||||
|
||||
//Insert the tabs in the DOM and their buttons.
|
||||
insertTabs();
|
||||
insertButtons();
|
||||
|
||||
//Enhace the look of select buttons
|
||||
initListButtons();
|
||||
|
||||
//Prepare the standard confirmation dialogs
|
||||
setupConfirmDialogs();
|
||||
|
||||
//Listen for .action_buttons
|
||||
//An action buttons runs a predefined action. If it has type
|
||||
//"multiple" it runs that action on the elements of a datatable.
|
||||
$('.action_button').live("click",function(){
|
||||
|
||||
var table = null;
|
||||
var value = $(this).attr("value");
|
||||
var action = SunstoneCfg["actions"][value];
|
||||
if (!action) { notifyError("Action "+value+" not defined."); return false;};
|
||||
switch (action.type){
|
||||
case "multiple": //find the datatable
|
||||
var nodes = action.elements();
|
||||
Sunstone.runAction(value,nodes);
|
||||
break;
|
||||
default:
|
||||
Sunstone.runAction(value);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
//Listen .confirm_buttons. These buttons show a confirmation dialog
|
||||
//before running the action.
|
||||
$('.confirm_button').live("click",function(){
|
||||
popUpConfirmDialog(this);
|
||||
return false;
|
||||
});
|
||||
|
||||
//Listen .confirm_buttons. These buttons show a confirmation dialog
|
||||
//with a select box before running the action.
|
||||
$('.confirm_with_select_button').live("click",function(){
|
||||
popUpConfirmWithSelectDialog(this);
|
||||
return false;
|
||||
});
|
||||
|
||||
//Jquery-enhace the buttons in the DOM
|
||||
$('button').button();
|
||||
|
||||
//Close overlay dialogs when clicking outside of them.
|
||||
$(".ui-widget-overlay").live("click", function (){
|
||||
$("div:ui-dialog:visible").dialog("close");
|
||||
});
|
||||
|
||||
//Close select lists when clicking somewhere else.
|
||||
$('*:not(.action_list,.list_button)').click(function(){
|
||||
$('.action_list:visible').hide();
|
||||
});
|
||||
|
||||
//Start with the dashboard (supposing we have one).
|
||||
showTab('#dashboard_tab');
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
//reads the cookie and places its info in the 'cookie' var
|
||||
function readCookie(){
|
||||
$.each(document.cookie.split("; "), function(i,e){
|
||||
var e_split = e.split("=");
|
||||
var key = e_split[0];
|
||||
var value = e_split[1];
|
||||
cookie[key] = value;
|
||||
});
|
||||
}
|
||||
|
||||
//sets the user info in the top bar and creates a listner in the
|
||||
//signout button
|
||||
function setLogin(){
|
||||
//This two variables can be used anywhere
|
||||
username = cookie["one-user"];
|
||||
uid = cookie["one-user_id"];
|
||||
|
||||
$("#user").html(username);
|
||||
$("#logout").click(function(){
|
||||
OpenNebula.Auth.logout({success:function(){
|
||||
window.location.href = "/login";
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
//Inserts all main tabs in the DOM
|
||||
function insertTabs(){
|
||||
var tab_info;
|
||||
for (tab in SunstoneCfg["tabs"]){
|
||||
insertTab(tab);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Inserts a main tab in the DOM. This is done by
|
||||
//adding the content to the proper div and by adding a list item
|
||||
//link to the navigation menu
|
||||
function insertTab(tab_name){
|
||||
var tab_info = SunstoneCfg["tabs"][tab_name];
|
||||
var condition = tab_info["condition"];
|
||||
//skip this tab if we do not meet the condition
|
||||
if (condition && !condition()) {return;}
|
||||
$("div.inner-center").append('<div id="'+tab_name+'" class="tab"></div>');
|
||||
$('div#'+tab_name).html(tab_info.content);
|
||||
|
||||
$('ul#navigation').append('<li id="li_'+tab_name+'"><a href="#'+tab_name+'">'+tab_info.title+'</a></li>');
|
||||
}
|
||||
|
||||
|
||||
//Inserts the buttons of all tabs.
|
||||
function insertButtons(){
|
||||
for (tab in SunstoneCfg["tabs"]){
|
||||
insertButtonsInTab(tab)
|
||||
}
|
||||
}
|
||||
|
||||
//If we have defined a block of action buttons in a tab,
|
||||
//this function takes care of inserting them in the DOM.
|
||||
function insertButtonsInTab(tab_name){
|
||||
var buttons = SunstoneCfg["tabs"][tab_name]["buttons"];
|
||||
var button_code="";
|
||||
var sel_obj=null;
|
||||
var condition=null;
|
||||
|
||||
//Check if we have included an appropiate space our tab to
|
||||
//insert them (an .action_blocks div)
|
||||
if ($('div#'+tab_name+' div.action_blocks').length){
|
||||
|
||||
//for every button defined for this tab...
|
||||
for (button_name in buttons){
|
||||
button_code = "";
|
||||
button = buttons[button_name];
|
||||
condition = button.condition;
|
||||
//if we meet the condition we proceed. Otherwise we skip it.
|
||||
if (condition && !condition()) { continue; }
|
||||
|
||||
//depending on the type of button we generate different
|
||||
//code. There are 4 possible types:
|
||||
/*
|
||||
* select: We need to create a select element with actions inside.
|
||||
* image: a button consisting of a link with an image inside.
|
||||
* create: we make sure they have the "action_button" class.
|
||||
* default: generally buttons have the "<type>_button" class.
|
||||
*/
|
||||
switch (button.type) {
|
||||
case "select":
|
||||
button_code = '<select class="multi_action_slct">';
|
||||
//for each subbutton in the list we add an option to the select.
|
||||
for (sel_name in button.actions){
|
||||
sel_obj = button["actions"][sel_name];
|
||||
condition = sel_obj.condition;
|
||||
//only add if we meet the condition
|
||||
if (condition && !condition()){ continue; };
|
||||
button_code += '<option class="'+sel_obj.type+'_button" value="'+sel_name+'">'+sel_obj.text+'</option>';
|
||||
};
|
||||
button_code += '</select>';
|
||||
break;
|
||||
case "image":
|
||||
button_code = '<a href="#" class="action_button" value="'+button_name+'"><img class="image_button" src="'+button.img+'" alt="'+button.text+'" /></a>';
|
||||
break;
|
||||
case "create_dialog":
|
||||
button_code = '<button class="'+button.type+'_button action_button top_button" value="'+button_name+'">'+button.text+'</button>';
|
||||
break;
|
||||
default:
|
||||
button_code = '<button class="'+button.type+'_button top_button" value="'+button_name+'">'+button.text+'</button>';
|
||||
|
||||
}
|
||||
|
||||
$('div#'+tab_name+' .action_blocks').append(button_code);
|
||||
|
||||
}//for each button in tab
|
||||
$('.top_button').button();
|
||||
}//if tab exists
|
||||
}
|
||||
|
||||
//Converts selects into buttons which show a list of actions when
|
||||
//clicked. This lists have two parts, one for the last action run, and
|
||||
//another containing a list of actions that can be folded/unfolded.
|
||||
function initListButtons(){
|
||||
|
||||
//for each multi_action select
|
||||
$('.multi_action_slct').each(function(){
|
||||
//prepare replacement buttons
|
||||
var buttonset = $('<div style="display:inline-block;" class="top_button"></div');
|
||||
var button1 = $('<button class="last_action_button action_button confirm_button confirm_with_select_button" value="">Previous action</button>').button();
|
||||
button1.attr("disabled","disabled");
|
||||
var button2 = $('<button class="list_button" value="">See more</button>').button({
|
||||
text:false,
|
||||
icons: { primary: "ui-icon-triangle-1-s" }
|
||||
});
|
||||
buttonset.append(button1);
|
||||
buttonset.append(button2);
|
||||
buttonset.buttonset();
|
||||
|
||||
//prepare list
|
||||
var options = $('option', $(this));
|
||||
var list = $('<ul class="action_list"></ul>');
|
||||
$.each(options,function(){
|
||||
var classes = $(this).attr("class");
|
||||
var item = $('<li></li>');
|
||||
var a = $('<a href="#" class="'+classes+'" value="'+$(this).val()+'">'+$(this).text()+'</a>');
|
||||
a.val($(this).val());
|
||||
item.html(a);
|
||||
list.append(item);
|
||||
});
|
||||
list.css({
|
||||
"display":"none"
|
||||
});
|
||||
|
||||
|
||||
//replace the select and insert the buttons
|
||||
$(this).before(buttonset);
|
||||
$(this).parents('.action_blocks').append(list);
|
||||
$(this).remove();
|
||||
//$(this).replaceWith(list);
|
||||
|
||||
});
|
||||
|
||||
|
||||
//below the listeners for events on these buttons and list
|
||||
|
||||
//enable run the last action button
|
||||
$('.action_list li a').click(function(){
|
||||
//enable run last action button
|
||||
var prev_action_button = $('.last_action_button',$(this).parents('.action_blocks'));
|
||||
prev_action_button.val($(this).val());
|
||||
prev_action_button.removeClass("confirm_with_select_button");
|
||||
prev_action_button.removeClass("confirm_button");
|
||||
prev_action_button.removeClass("action_button");
|
||||
prev_action_button.addClass($(this).attr("class"));
|
||||
prev_action_button.button("option","label",$(this).text());
|
||||
prev_action_button.button("enable");
|
||||
$(this).parents('ul').hide("blind",100);
|
||||
//return false;
|
||||
});
|
||||
|
||||
|
||||
//Show the list of actions in place
|
||||
$('.list_button').click(function(){
|
||||
$('.action_list',$(this).parents('.action_blocks')).css({
|
||||
"left": $(this).prev().position().left,
|
||||
"top": $(this).prev().position().top+13,
|
||||
"width": $(this).parent().outerWidth()-11
|
||||
});
|
||||
$('.action_list',$(this).parents('.action_blocks')).toggle("blind",100);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
//Prepares the standard confirm dialogs
|
||||
function setupConfirmDialogs(){
|
||||
|
||||
//add div to the main body if it isn't present.
|
||||
if (!($('div#confirm_dialog').length)){
|
||||
$('div#dialogs').append('<div id="confirm_dialog" title="Confirmation of action"></div>');
|
||||
};
|
||||
|
||||
//add the HTML with the standard question and buttons.
|
||||
$('div#confirm_dialog').html(
|
||||
'<form action="javascript:alert(\'js error!\');">\
|
||||
<div id="confirm_tip">You have to confirm this action.</div>\
|
||||
<br />\
|
||||
<div id="question">Do you want to proceed?</div>\
|
||||
<br />\
|
||||
<div class="form_buttons">\
|
||||
<button id="confirm_proceed" class="action_button" value="">OK</button>\
|
||||
<button class="confirm_cancel" value="">Cancel</button>\
|
||||
</div>\
|
||||
</form>');
|
||||
|
||||
//prepare the jquery dialog
|
||||
$('div#confirm_dialog').dialog({
|
||||
resizable:false,
|
||||
modal:true,
|
||||
width:300,
|
||||
heigth:200,
|
||||
autoOpen:false
|
||||
});
|
||||
|
||||
//enhace the button look
|
||||
$('div#confirm_dialog button').button();
|
||||
|
||||
//same for the confirm with select dialog.
|
||||
if (!($('div#confirm_with_select_dialog').length)){
|
||||
$('div#dialogs').append('<div id="confirm_with_select_dialog" title="Confirmation of action"></div>');
|
||||
};
|
||||
|
||||
$('div#confirm_with_select_dialog').html(
|
||||
'<form action="javascript:alert(\'js error!\');">\
|
||||
<div id="confirm_with_select_tip">You need to select something.</div>\
|
||||
<select style="margin: 10px 0;" id="confirm_select">\
|
||||
</select>\
|
||||
<div class="form_buttons">\
|
||||
<button id="confirm_with_select_proceed" class="" value="">OK</button>\
|
||||
<button class="confirm_cancel" value="">Cancel</button>\
|
||||
</div>\
|
||||
</form>');
|
||||
|
||||
|
||||
//prepare the jquery dialog
|
||||
$('div#confirm_with_select_dialog').dialog({
|
||||
resizable:false,
|
||||
modal:true,
|
||||
width:300,
|
||||
heigth:300,
|
||||
autoOpen:false
|
||||
});
|
||||
|
||||
$('div#confirm_with_select_dialog button').button();
|
||||
|
||||
//if a cancel button is pressed, we close the dialog.
|
||||
$('button.confirm_cancel').click(function(){
|
||||
$('div#confirm_with_select_dialog').dialog("close");
|
||||
$('div#confirm_dialog').dialog("close");
|
||||
return false;
|
||||
});
|
||||
|
||||
//when we proceed with a "confirm with select" we need to
|
||||
//find out if we are running an action with a parametre on a datatable
|
||||
//items or if its just an action
|
||||
$('button#confirm_with_select_proceed').click(function(){
|
||||
var value = $(this).val();
|
||||
var action = SunstoneCfg["actions"][value];
|
||||
var param = $('select#confirm_select').val();
|
||||
if (!action) { notifyError("Action "+value+" not defined."); return false;};
|
||||
switch (action.type){
|
||||
case "multiple": //find the datatable
|
||||
var nodes = action.elements();
|
||||
Sunstone.runAction(value,nodes,param);
|
||||
break;
|
||||
default:
|
||||
Sunstone.runAction(value,param);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
//Popup a confirmation dialog.
|
||||
//In order to find out the dialog action and
|
||||
//tip for the user we need to access the clicked button
|
||||
//configuration. We do this by discovering the name of the parent tab
|
||||
//and with the value of the clicked element.
|
||||
function popUpConfirmDialog(target_elem){
|
||||
var value = $(target_elem).val();
|
||||
var tab_id = $(target_elem).parents('.tab').attr('id');
|
||||
var button = Sunstone.getButton(tab_id,value);
|
||||
var tip = button.tip;
|
||||
$('button#confirm_proceed').val(value);
|
||||
$('div#confirm_tip').text(tip);
|
||||
$('div#confirm_dialog').dialog("open");
|
||||
}
|
||||
|
||||
//Same as previous. This time we need as well to access the updated
|
||||
//select list, which is done through the pointer of found in the
|
||||
//config of the button (a function returning the select options).
|
||||
function popUpConfirmWithSelectDialog(target_elem){
|
||||
var value = $(target_elem).val();
|
||||
var tab_id = $(target_elem).parents('.tab').attr('id');
|
||||
var button = Sunstone.getButton(tab_id,value);
|
||||
var tip = button.tip;
|
||||
var select_var = button.select();
|
||||
$('select#confirm_select').html(select_var);
|
||||
$('div#confirm_with_select_tip').text(tip);
|
||||
|
||||
$('button#confirm_with_select_proceed').val(value);
|
||||
$('div#confirm_with_select_dialog').dialog("open");
|
||||
}
|
||||
|
||||
|
@ -20,31 +20,28 @@
|
||||
<link rel="stylesheet" type="text/css" href="/css/application.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/layout.css" />
|
||||
<script type="text/javascript" src="/js/opennebula.js"></script>
|
||||
<script type="text/javascript" src="/js/one-ui_views.templates.js"></script>
|
||||
<script type="text/javascript" src="/js/one-ui_views.js"></script>
|
||||
<script type="text/javascript" src="/js/layout.js"></script>
|
||||
<script type="text/javascript" src="/js/sunstone.js"></script>
|
||||
<script type="text/javascript" src="/js/sunstone-util.js"></script>
|
||||
<script type="text/javascript" src="/js/plugins/dashboard-tab.js"></script>
|
||||
<script type="text/javascript" src="/js/plugins/hosts-tab.js"></script>
|
||||
<script type="text/javascript" src="/js/plugins/vms-tab.js"></script>
|
||||
<script type="text/javascript" src="/js/plugins/vnets-tab.js"></script>
|
||||
<script type="text/javascript" src="/js/plugins/images-tab.js"></script>
|
||||
<script type="text/javascript" src="/js/plugins/users-tab.js"></script>
|
||||
|
||||
<!--<script type="text/javascript" src="/js/plugins/dummy-plugin.js"></script>-->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="outer-center">
|
||||
<div class="inner-center">
|
||||
<div id="dashboard" class="tab"></div>
|
||||
<div id="hosts" class="tab"></div>
|
||||
<div id="virtualMachines" class="tab"></div>
|
||||
<div id="virtualNetworks" class="tab"></div>
|
||||
<div id="images" class="tab"></div>
|
||||
<div id="users" class="tab"></div>
|
||||
</div>
|
||||
<div id="dialog" class="inner-south"></div>
|
||||
</div>
|
||||
|
||||
<div id="menu" class="outer-west">
|
||||
<ul id="navigation">
|
||||
<li><a href="#dashboard">Dashboard</a></li>
|
||||
<li><a href="#hosts">Hosts & Clusters</a></li>
|
||||
<li><a href="#virtualMachines">Virtual Machines</a></li>
|
||||
<li><a href="#virtualNetworks">Virtual Networks</a></li>
|
||||
<li><a href="#images">Images</a></li>
|
||||
<li class="oneadmin"><a href="#users">Users</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -67,32 +64,8 @@
|
||||
|
||||
|
||||
<div id="dialogs">
|
||||
<div id="create_host_dialog" title="Create a new host">
|
||||
</div>
|
||||
|
||||
<div id="create_cluster_dialog" title="Create a new cluster">
|
||||
</div>
|
||||
|
||||
<div id="create_vn_dialog" title="Create a new Virtual Network">
|
||||
</div>
|
||||
|
||||
<div id="create_vm_dialog" title="Create a new Virtual Machine">
|
||||
</div>
|
||||
|
||||
<div id="create_user_dialog" title="Create a new user">
|
||||
</div>
|
||||
|
||||
<div id="create_image_dialog" title="Create a new image">
|
||||
</div>
|
||||
|
||||
<div id="host_info_dialog" title="Host Information">
|
||||
</div>
|
||||
|
||||
<div id="vm_info_dialog" title="Virtual Machine Information">
|
||||
</div>
|
||||
|
||||
<div id="vn_info_dialog" title="Virtual Network Information">
|
||||
</div>
|
||||
</div>
|
||||
<div id="info_panels"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -445,12 +445,7 @@ Attribute * Template::vector_xml_att(const xmlNode * node)
|
||||
int Template::from_xml(const string &xml_str)
|
||||
{
|
||||
xmlDocPtr xml_doc = 0;
|
||||
|
||||
xmlNode * root_element;
|
||||
xmlNode * cur_node = 0;
|
||||
|
||||
Attribute * attr;
|
||||
|
||||
|
||||
// Parse xml string as libxml document
|
||||
xml_doc = xmlParseMemory (xml_str.c_str(),xml_str.length());
|
||||
@ -460,6 +455,44 @@ int Template::from_xml(const string &xml_str)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get the <TEMPLATE> element
|
||||
root_element = xmlDocGetRootElement(xml_doc);
|
||||
if( root_element == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
rebuild_attributes(root_element);
|
||||
|
||||
xmlFreeDoc(xml_doc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Template::from_xml_node(const xmlNodePtr node)
|
||||
{
|
||||
if (node == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
rebuild_attributes(node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void Template::rebuild_attributes(const xmlNode * root_element)
|
||||
{
|
||||
xmlNode * cur_node = 0;
|
||||
|
||||
Attribute * attr;
|
||||
|
||||
//Clear the template if not empty
|
||||
if (!attributes.empty())
|
||||
{
|
||||
@ -473,9 +506,6 @@ int Template::from_xml(const string &xml_str)
|
||||
attributes.clear();
|
||||
}
|
||||
|
||||
// Get the <TEMPLATE> element
|
||||
root_element = xmlDocGetRootElement(xml_doc);
|
||||
|
||||
// Get the root's children and try to build attributes.
|
||||
for (cur_node = root_element->children;
|
||||
cur_node != 0;
|
||||
@ -497,10 +527,6 @@ int Template::from_xml(const string &xml_str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xmlFreeDoc(xml_doc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -641,7 +641,7 @@ static int input (void );
|
||||
/* This used to be an fputs(), but since the string might contain NUL's,
|
||||
* we now use fwrite().
|
||||
*/
|
||||
#define ECHO fwrite( template_text, template_leng, 1, template_out )
|
||||
#define ECHO do { if (fwrite( template_text, template_leng, 1, template_out )) {} } while (0)
|
||||
#endif
|
||||
|
||||
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
|
||||
@ -652,7 +652,7 @@ static int input (void );
|
||||
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
|
||||
{ \
|
||||
int c = '*'; \
|
||||
int n; \
|
||||
unsigned n; \
|
||||
for ( n = 0; n < max_size && \
|
||||
(c = getc( template_in )) != EOF && c != '\n'; ++n ) \
|
||||
buf[n] = (char) c; \
|
||||
|
@ -17,6 +17,7 @@
|
||||
Import('env')
|
||||
|
||||
env.Append(LIBS=[
|
||||
'nebula_xml',
|
||||
'nebula_template',
|
||||
'nebula_common',
|
||||
'nebula_core',
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user