mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-30 22:50:10 +03:00
Merge branch 'master' into remove-xen
This commit is contained in:
commit
0766d6a872
356
include/BitMap.h
Normal file
356
include/BitMap.h
Normal file
@ -0,0 +1,356 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */
|
||||
/* */
|
||||
/* 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 BITMAP_H_
|
||||
#define BITMAP_H_
|
||||
|
||||
#include <bitset>
|
||||
|
||||
#include "Attribute.h"
|
||||
#include "Callbackable.h"
|
||||
|
||||
class SqlDB;
|
||||
|
||||
/**
|
||||
* This class represents a generic BitMap
|
||||
*
|
||||
*/
|
||||
template <unsigned int N>
|
||||
class BitMap : public Callbackable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Creates a new bitmap, it stores a pointer to the DB parameters
|
||||
* that MUST exists during the object lifetime.
|
||||
*/
|
||||
BitMap(const VectorAttribute& bs_conf, int _id, const char * _db_table)
|
||||
: id(_id), start_bit(0), bs(0), db_table(_db_table)
|
||||
{
|
||||
std::string reserved;
|
||||
|
||||
bs_conf.vector_value("START", start_bit);
|
||||
bs_conf.vector_value("RESERVED", reserved);
|
||||
|
||||
if (!reserved.empty())
|
||||
{
|
||||
one_util::split_unique(reserved, ',', reserved_bit);
|
||||
}
|
||||
};
|
||||
|
||||
virtual ~BitMap()
|
||||
{
|
||||
delete bs;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Database interface */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/**
|
||||
* Returns a string stream with the SQL bootstrap command for the
|
||||
* bitmap table
|
||||
*/
|
||||
static std::ostringstream& bootstrap(const char * t, std::ostringstream& o)
|
||||
{
|
||||
o << "CREATE TABLE IF NOT EXISTS " << t
|
||||
<< " (id INTEGER, map LONGTEXT, PRIMARY KEY(id))";
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a new bitmap into the bitmap table. The bitmap marks the
|
||||
* associated reserved bits as initialized by the bitmap conf. This
|
||||
* function is called once to bootstrap the bitmap contents.
|
||||
* @param id of the set, this will update the id of the bitmap
|
||||
* @return 0 on success
|
||||
*/
|
||||
int insert(int _id, SqlDB * db)
|
||||
{
|
||||
id = _id;
|
||||
|
||||
init("");
|
||||
|
||||
return insert_replace(db, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a bitmap and marks (again) the reserved bits. This function
|
||||
* is called once to load the bitmap from the DB. The reserved bits are
|
||||
* updated.
|
||||
* @param id of the set, this will update the id of the bitmap
|
||||
* @return 0 on success
|
||||
*/
|
||||
int select(int _id, SqlDB * db)
|
||||
{
|
||||
std::string * uzbs;
|
||||
|
||||
id = _id;
|
||||
|
||||
if ( select(db, &uzbs) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
init(*uzbs);
|
||||
|
||||
delete uzbs;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int update(SqlDB * db)
|
||||
{
|
||||
return insert_replace(db, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a bitmap from the DB.
|
||||
* @return 0 on success
|
||||
*/
|
||||
int drop(SqlDB * db)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "DELETE FROM " << db_table << " WHERE id = " << id ;
|
||||
|
||||
return db->exec(oss);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* BitMap interface */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/*+
|
||||
* Gets the first 0 bit in the map and set it.
|
||||
* @param hint try this bit first, 0 does not use any hint
|
||||
* @param bit the bit number reserved
|
||||
* @return -1 in case of error
|
||||
*/
|
||||
int get(unsigned int hint, unsigned int& bit)
|
||||
{
|
||||
if ( hint != 0 )
|
||||
{
|
||||
if ( bs->test(hint) == false )
|
||||
{
|
||||
bs->set(hint);
|
||||
|
||||
bit = hint;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (bit = start_bit; ; ++bit)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( bs->test(bit) == false )
|
||||
{
|
||||
bs->set(bit);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
catch (const std::out_of_range& oor)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears a bit in the map and updates DB.
|
||||
* @param bit to reset
|
||||
*/
|
||||
void reset(int bit)
|
||||
{
|
||||
try
|
||||
{
|
||||
bs->reset(bit);
|
||||
}
|
||||
catch(const std::out_of_range& oor){};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a bit in the map and updates DB.
|
||||
* @param bit to set
|
||||
* @return 0 on success, -1 if bit was set
|
||||
*/
|
||||
int set(int bit)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
try
|
||||
{
|
||||
if (bs->test(bit) == false)
|
||||
{
|
||||
bs->set(bit);
|
||||
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
catch(const std::out_of_range& oor){};
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the start_bit of the bitmap
|
||||
*/
|
||||
unsigned int get_start_bit()
|
||||
{
|
||||
return start_bit;
|
||||
}
|
||||
|
||||
private:
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Bitmap configuration attributes */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
int id;
|
||||
|
||||
unsigned int start_bit;
|
||||
|
||||
std::set<int> reserved_bit;
|
||||
|
||||
std::bitset<N> * bs;
|
||||
|
||||
/**
|
||||
* Initialized a bitmap by creating a new object and setting the reserved
|
||||
* bits.
|
||||
* @param bm_s the bitmap in string form
|
||||
*/
|
||||
void init(const std::string& bm_s)
|
||||
{
|
||||
std::set<int>::iterator it;
|
||||
|
||||
bs = new std::bitset<N>(bm_s);
|
||||
|
||||
for (it = reserved_bit.begin(); it != reserved_bit.end(); ++it)
|
||||
{
|
||||
try
|
||||
{
|
||||
bs->set(*it);
|
||||
}
|
||||
catch (const std::out_of_range& oor) {};
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Database implementation */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
const char * db_table;
|
||||
|
||||
/**
|
||||
* Select callback from DB engine
|
||||
*/
|
||||
int select_cb(void * _bs, int num, char **values, char **names)
|
||||
{
|
||||
if ( num == 0 || values == 0 || values[0] == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
*static_cast<std::string*>(_bs) = (const char *) values[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a the contents of a bitmap from DB
|
||||
* @param **uzbs, pointer to a string pointer to store the bitmap, must
|
||||
* be freed by caller.
|
||||
* @return 0 on success
|
||||
*/
|
||||
int select(SqlDB * db, std::string ** uzbs)
|
||||
{
|
||||
int rc;
|
||||
|
||||
std::ostringstream oss;
|
||||
|
||||
std::string zbs;
|
||||
|
||||
*uzbs = 0;
|
||||
|
||||
set_callback(static_cast<Callbackable::Callback>(&BitMap::select_cb),
|
||||
static_cast<void *>(&zbs));
|
||||
|
||||
oss << "SELECT map FROM " << db_table << " WHERE id = " << id ;
|
||||
|
||||
rc = db->exec(oss, this);
|
||||
|
||||
unset_callback();
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
else if (zbs.empty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
*uzbs = one_util::zlib_decompress(zbs, true);
|
||||
|
||||
if ( *uzbs == 0 )
|
||||
{
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Insert a Bitmap in the DB, the bitmap is stored in a compressed (zlib)
|
||||
* string form.
|
||||
* @param replace true to replace false to insert
|
||||
* @return 0 on success
|
||||
*/
|
||||
int insert_replace(SqlDB * db, bool replace)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
||||
if (replace)
|
||||
{
|
||||
oss << "REPLACE ";
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << "INSERT ";
|
||||
}
|
||||
|
||||
std::string * zipped = one_util::zlib_compress(bs->to_string(), true);
|
||||
|
||||
if (zipped == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
char * ezipped64 = db->escape_str(zipped->c_str());
|
||||
|
||||
oss << "INTO " << db_table << " (id, map) VALUES ("
|
||||
<< id << ",'" << ezipped64 << "')";
|
||||
|
||||
int rc = db->exec(oss);
|
||||
|
||||
delete zipped;
|
||||
|
||||
db->free_str(ezipped64);
|
||||
|
||||
return rc;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*BITMAP_H_*/
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "ObjectCollection.h"
|
||||
#include "DatastorePool.h"
|
||||
#include "ClusterTemplate.h"
|
||||
#include "BitMap.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -173,6 +174,36 @@ public:
|
||||
get_template_attribute("RESERVED_MEM", mem);
|
||||
}
|
||||
|
||||
// *************************************************************************
|
||||
// VNC Port management function
|
||||
// *************************************************************************
|
||||
|
||||
/**
|
||||
* Returns a free VNC port, it will try first to allocate base_port + vmid.
|
||||
* If this port is not free the first lower port from the VNC_PORT/START
|
||||
* port is returned.
|
||||
* @param vmid of the VM
|
||||
* @param port reserved
|
||||
* @return 0 on success
|
||||
*/
|
||||
int get_vnc_port(int vmid, unsigned int& port)
|
||||
{
|
||||
unsigned int base_port = vnc_bitmap.get_start_bit();
|
||||
unsigned int hint_port = base_port + (vmid % (65535 - base_port));
|
||||
|
||||
return vnc_bitmap.get(hint_port,port);
|
||||
}
|
||||
|
||||
void release_vnc_port(int port)
|
||||
{
|
||||
vnc_bitmap.reset(port);
|
||||
}
|
||||
|
||||
int set_vnc_port(int port)
|
||||
{
|
||||
return vnc_bitmap.set(port);
|
||||
}
|
||||
|
||||
// *************************************************************************
|
||||
// DataBase implementation (Public)
|
||||
// *************************************************************************
|
||||
@ -203,9 +234,8 @@ private:
|
||||
// *************************************************************************
|
||||
// Constructor
|
||||
// *************************************************************************
|
||||
Cluster(int id,
|
||||
const string& name,
|
||||
ClusterTemplate* cl_template);
|
||||
Cluster(int id, const string& name, ClusterTemplate* cl_template,
|
||||
const VectorAttribute& vnc_conf);
|
||||
|
||||
virtual ~Cluster(){};
|
||||
|
||||
@ -216,6 +246,8 @@ private:
|
||||
ObjectCollection datastores;
|
||||
ObjectCollection vnets;
|
||||
|
||||
BitMap<65536> vnc_bitmap;
|
||||
|
||||
// *************************************************************************
|
||||
// DataBase implementation (Private)
|
||||
// *************************************************************************
|
||||
@ -231,6 +263,7 @@ private:
|
||||
static const char * network_db_names;
|
||||
static const char * network_db_bootstrap;
|
||||
|
||||
static const char * bitmap_table;
|
||||
/**
|
||||
* Execute an INSERT or REPLACE Sql query.
|
||||
* @param db The SQL DB
|
||||
@ -268,7 +301,16 @@ private:
|
||||
*/
|
||||
int insert(SqlDB *db, string& error_str)
|
||||
{
|
||||
return insert_replace(db, false, error_str);
|
||||
int rc;
|
||||
|
||||
rc = insert_replace(db, false, error_str);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
return vnc_bitmap.insert(oid, db);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -279,9 +321,48 @@ private:
|
||||
int update(SqlDB *db)
|
||||
{
|
||||
string error_str;
|
||||
return insert_replace(db, true, error_str);
|
||||
|
||||
int rc = insert_replace(db, true, error_str);
|
||||
|
||||
rc += vnc_bitmap.update(db);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the PoolObjectSQL (identified by its OID) from the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int select(SqlDB *db)
|
||||
{
|
||||
int rc = PoolObjectSQL::select(db);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
return vnc_bitmap.select(oid, db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the PoolObjectSQL (identified by its OID) from the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int select(SqlDB *db, const string& _name, int _uid)
|
||||
{
|
||||
int rc = PoolObjectSQL::select(db, _name, _uid);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
return vnc_bitmap.select(oid, db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if all the collections are empty, and therefore this cluster
|
||||
* can be dropped.
|
||||
|
@ -26,7 +26,7 @@ using namespace std;
|
||||
class ClusterPool : public PoolSQL
|
||||
{
|
||||
public:
|
||||
ClusterPool(SqlDB * db);
|
||||
ClusterPool(SqlDB * db, const VectorAttribute * vnc_conf);
|
||||
|
||||
~ClusterPool(){};
|
||||
|
||||
@ -54,6 +54,77 @@ public:
|
||||
*/
|
||||
static const int DEFAULT_CLUSTER_ID;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Cluster Resources */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/**
|
||||
* Get a free VNC port in the cluster. It will try first base_port + id
|
||||
* @param oid of the cluster
|
||||
* @param vm_id of the ID requesting the port
|
||||
* @param port to free
|
||||
*/
|
||||
int get_vnc_port(int oid, int vm_id, unsigned int& port)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
Cluster * cluster = get(oid, true);
|
||||
|
||||
if ( cluster != 0 )
|
||||
{
|
||||
rc = cluster->get_vnc_port(vm_id, port);
|
||||
|
||||
update(cluster);
|
||||
|
||||
cluster->unlock();
|
||||
}
|
||||
|
||||
return rc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Release a previously allocated VNC port in the cluster
|
||||
* @param oid of the cluster
|
||||
* @param port to free
|
||||
*/
|
||||
void release_vnc_port(int oid, unsigned int port)
|
||||
{
|
||||
Cluster * cluster = get(oid, true);
|
||||
|
||||
if ( cluster != 0 )
|
||||
{
|
||||
cluster->release_vnc_port(port);
|
||||
|
||||
update(cluster);
|
||||
|
||||
cluster->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a VNC port as in-use in the cluster.
|
||||
* @param oid of the cluster
|
||||
* @param port to set
|
||||
*
|
||||
* @return 0 on success, -1 if the port was in-use.
|
||||
*/
|
||||
int set_vnc_port(int oid, unsigned int port)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
Cluster * cluster = get(oid, true);
|
||||
|
||||
if ( cluster != 0 )
|
||||
{
|
||||
rc = cluster->set_vnc_port(port);
|
||||
|
||||
update(cluster);
|
||||
|
||||
cluster->unlock();
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Methods for DB management */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -67,9 +138,7 @@ public:
|
||||
*
|
||||
* @return the oid assigned to the object, -1 in case of failure
|
||||
*/
|
||||
int allocate(string name,
|
||||
int * oid,
|
||||
string& error_str);
|
||||
int allocate(string name, int * oid, string& error_str);
|
||||
|
||||
/**
|
||||
* Function to get a cluster from the pool, if the object is not in memory
|
||||
@ -128,7 +197,13 @@ public:
|
||||
*/
|
||||
static int bootstrap(SqlDB * _db)
|
||||
{
|
||||
return Cluster::bootstrap(_db);
|
||||
ostringstream oss_bitmap;
|
||||
int rc;
|
||||
|
||||
rc = Cluster::bootstrap(_db);
|
||||
rc += _db->exec(BitMap<0>::bootstrap(Cluster::bitmap_table, oss_bitmap));
|
||||
|
||||
return rc;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -156,13 +231,18 @@ public:
|
||||
static void cluster_acl_filter(ostringstream& filter,
|
||||
PoolObjectSQL::ObjectType auth_object, const vector<int>& cids);
|
||||
private:
|
||||
/**
|
||||
* VNC configuration for clusters
|
||||
*/
|
||||
const VectorAttribute vnc_conf;
|
||||
|
||||
/**
|
||||
* Factory method to produce objects
|
||||
* @return a pointer to the new object
|
||||
*/
|
||||
PoolObjectSQL * create()
|
||||
{
|
||||
return new Cluster(-1,"",0);
|
||||
return new Cluster(-1,"",0, &vnc_conf);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "HostPool.h"
|
||||
#include "ImagePool.h"
|
||||
#include "SecurityGroupPool.h"
|
||||
#include "ClusterPool.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -42,7 +43,8 @@ class LifeCycleManager : public ActionListener
|
||||
public:
|
||||
|
||||
LifeCycleManager():
|
||||
vmpool(0), hpool(0), ipool(0), sgpool(0), tm(0), vmm(0), dm(0), imagem(0)
|
||||
vmpool(0), hpool(0), ipool(0), sgpool(0), clpool(0), tm(0), vmm(0),
|
||||
dm(0), imagem(0)
|
||||
{
|
||||
am.addListener(this);
|
||||
};
|
||||
@ -178,6 +180,11 @@ private:
|
||||
*/
|
||||
SecurityGroupPool * sgpool;
|
||||
|
||||
/**
|
||||
* Pointer to the Cluster Pool
|
||||
*/
|
||||
ClusterPool * clpool;
|
||||
|
||||
/**
|
||||
* Pointer to TransferManager
|
||||
*/
|
||||
|
@ -238,6 +238,24 @@ namespace one_util
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input string unsing zlib
|
||||
* @param in input string
|
||||
* @param bool64 true to base64 encode output
|
||||
* @return pointer to the compressed sting (must be freed) or 0 in case
|
||||
* of error
|
||||
*/
|
||||
std::string * zlib_compress(const std::string& in, bool base64);
|
||||
|
||||
/**
|
||||
* Decompress the input string unsing zlib
|
||||
* @param in input string
|
||||
* @param base64 true if the input is base64 encoded
|
||||
* @return pointer to the decompressed sting (must be freed) or 0 in case
|
||||
* of error
|
||||
*/
|
||||
std::string * zlib_decompress(const std::string& in, bool base64);
|
||||
};
|
||||
|
||||
#endif /* _NEBULA_UTIL_H_ */
|
||||
|
@ -1439,22 +1439,6 @@ public:
|
||||
*/
|
||||
static void disk_extended_info(int uid,
|
||||
VirtualMachineTemplate *tmpl);
|
||||
/**
|
||||
* Adds extra info to the volatile disks of the given template, ds inherited
|
||||
* attributes and TYPE
|
||||
* @param tmpl the virtual machine template
|
||||
* @return true if there at least one volatile disk was found
|
||||
*/
|
||||
bool volatile_disk_extended_info(Template *tmpl);
|
||||
|
||||
/**
|
||||
* Adds extra info to the volatile disks of the given VM
|
||||
*/
|
||||
bool volatile_disk_extended_info()
|
||||
{
|
||||
return volatile_disk_extended_info(obj_template);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Hotplug related functions
|
||||
// -------------------------------------------------------------------------
|
||||
@ -1465,14 +1449,6 @@ public:
|
||||
*/
|
||||
void get_disk_info(int& max_disk_id, set<string>& used_targets);
|
||||
|
||||
/**
|
||||
* Get the IMAGE_ID of the image that's being saved as hot
|
||||
* @param disk_id of the DISK
|
||||
* @param image_id id of the image being saved
|
||||
* @return IMAGE_ID on success, -1 otherwise
|
||||
*/
|
||||
//int get_disk_hot_info(int& image_id, int& disk_id, string& source);
|
||||
|
||||
/**
|
||||
* Generate a DISK attribute to be attached to the VM.
|
||||
* @param tmpl Template containing a single DISK vector attribute.
|
||||
|
@ -24,7 +24,6 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
/**
|
||||
* The Virtual Machine Pool class. ...
|
||||
*/
|
||||
@ -393,19 +392,19 @@ private:
|
||||
/**
|
||||
* Size, in seconds, of the historical monitoring information
|
||||
*/
|
||||
static time_t _monitor_expiration;
|
||||
time_t _monitor_expiration;
|
||||
|
||||
/**
|
||||
* True or false whether to submit new VM on HOLD or not
|
||||
*/
|
||||
static bool _submit_on_hold;
|
||||
bool _submit_on_hold;
|
||||
|
||||
/**
|
||||
* Default values for cpu and memory cost
|
||||
*/
|
||||
static float _default_cpu_cost;
|
||||
static float _default_mem_cost;
|
||||
static float _default_disk_cost;
|
||||
float _default_cpu_cost;
|
||||
float _default_mem_cost;
|
||||
float _default_disk_cost;
|
||||
|
||||
/**
|
||||
* Callback used to get an int in the DB it is used by VM Pool in:
|
||||
|
@ -34,8 +34,9 @@
|
||||
# passwd : (mysql) the password for user
|
||||
# db_name : (mysql) the database name
|
||||
#
|
||||
# VNC_BASE_PORT: VNC ports for VMs can be automatically set to VNC_BASE_PORT +
|
||||
# VMID
|
||||
# VNC_PORTS: VNC port pool fot automatic VNC port assigment
|
||||
# start : first port to assgin
|
||||
# reserved: comma separated list of ports
|
||||
#
|
||||
# LOG: Configuration for the logging system
|
||||
# system: defines the logging system:
|
||||
@ -77,7 +78,10 @@ DB = [ backend = "sqlite" ]
|
||||
# passwd = "oneadmin",
|
||||
# db_name = "opennebula" ]
|
||||
|
||||
VNC_BASE_PORT = 5900
|
||||
VNC_PORTS = [
|
||||
start = 5900
|
||||
# reserved = "6800, 6801, 9869"
|
||||
]
|
||||
|
||||
#VM_SUBMIT_ON_HOLD = "NO"
|
||||
|
||||
@ -88,19 +92,19 @@ VNC_BASE_PORT = 5900
|
||||
# requires a special DB configuration.
|
||||
#
|
||||
# FEDERATION: Federation attributes
|
||||
# MODE: Operation mode of this oned.
|
||||
# mode: Operation mode of this oned.
|
||||
# STANDALONE no federated.This is the default operational mode
|
||||
# MASTER this oned is the master zone of the federation
|
||||
# SLAVE this oned is a slave zone
|
||||
# ZONE_ID: The zone ID as returned by onezone command
|
||||
# MASTER_ONED: The xml-rpc endpoint of the master oned, e.g.
|
||||
# zone_id: The zone ID as returned by onezone command
|
||||
# master_oned: The xml-rpc endpoint of the master oned, e.g.
|
||||
# http://master.one.org:2633/RPC2
|
||||
#*******************************************************************************
|
||||
|
||||
FEDERATION = [
|
||||
MODE = "STANDALONE",
|
||||
ZONE_ID = 0,
|
||||
MASTER_ONED = ""
|
||||
mode = "STANDALONE",
|
||||
zone_id = 0,
|
||||
master_oned = ""
|
||||
]
|
||||
|
||||
#*******************************************************************************
|
||||
|
@ -39,8 +39,10 @@
|
||||
# passwd : (mysql) the password for user
|
||||
# db_name : (mysql) the database name
|
||||
#
|
||||
# VNC_BASE_PORT: VNC ports for VMs can be automatically set to VNC_BASE_PORT +
|
||||
# VMID
|
||||
# VNC_PORTS: VNC port pool fot automatic VNC port assigment, if possible the
|
||||
# port will be set to ``START`` + ``VMID``
|
||||
# start : first port to assgin
|
||||
# reserved: comma separated list of ports
|
||||
#
|
||||
# LOG: Configuration for the logging system
|
||||
# system: defines the logging system:
|
||||
@ -86,7 +88,10 @@ DB = [ backend = "sqlite" ]
|
||||
# passwd = "oneadmin",
|
||||
# db_name = "opennebula" ]
|
||||
|
||||
VNC_BASE_PORT = 5900
|
||||
VNC_PORTS = [
|
||||
start = 5900
|
||||
# reserved = "6800, 6801, 9869"
|
||||
]
|
||||
|
||||
#VM_SUBMIT_ON_HOLD = "NO"
|
||||
|
||||
@ -107,9 +112,9 @@ VNC_BASE_PORT = 5900
|
||||
#*******************************************************************************
|
||||
|
||||
FEDERATION = [
|
||||
MODE = "STANDALONE",
|
||||
ZONE_ID = 0,
|
||||
MASTER_ONED = ""
|
||||
mode = "STANDALONE",
|
||||
zone_id = 0,
|
||||
master_oned = ""
|
||||
]
|
||||
|
||||
#*******************************************************************************
|
||||
@ -959,7 +964,8 @@ TM_MAD_CONF = [
|
||||
DS_MAD_CONF = [
|
||||
NAME = "ceph",
|
||||
REQUIRED_ATTRS = "DISK_TYPE,BRIDGE_LIST,CEPH_HOST,CEPH_USER,CEPH_SECRET",
|
||||
PERSISTENT_ONLY = "NO"
|
||||
PERSISTENT_ONLY = "NO",
|
||||
MARKETPLACE_ACTIONS = "export"
|
||||
]
|
||||
|
||||
DS_MAD_CONF = [
|
||||
@ -976,7 +982,8 @@ DS_MAD_CONF = [
|
||||
]
|
||||
|
||||
DS_MAD_CONF = [
|
||||
NAME = "fs", REQUIRED_ATTRS = "", PERSISTENT_ONLY = "NO"
|
||||
NAME = "fs", REQUIRED_ATTRS = "", PERSISTENT_ONLY = "NO",
|
||||
MARKETPLACE_ACTIONS = "export"
|
||||
]
|
||||
|
||||
DS_MAD_CONF = [
|
||||
@ -997,7 +1004,8 @@ DS_MAD_CONF = [
|
||||
]
|
||||
|
||||
DS_MAD_CONF = [
|
||||
NAME = "vcenter", REQUIRED_ATTRS = "VCENTER_CLUSTER", PERSISTENT_ONLY = "YES"
|
||||
NAME = "vcenter", REQUIRED_ATTRS = "VCENTER_CLUSTER", PERSISTENT_ONLY = "YES",
|
||||
MARKETPLACE_ACTIONS = "export"
|
||||
]
|
||||
|
||||
#*******************************************************************************
|
||||
|
@ -258,7 +258,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
|
||||
answer = STDIN.gets.strip
|
||||
|
||||
t[:one] += "VCENTER_DATASTORE=#{answer}"
|
||||
t[:one] += "VCENTER_DATASTORE=\"#{answer}\"\n"
|
||||
end
|
||||
|
||||
# Resource Pools
|
||||
@ -267,7 +267,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
|
||||
if rp_split.size > 3
|
||||
STDOUT.print "\n This template is currently set to "\
|
||||
"launch VMs in the default resource pool."
|
||||
"launch VMs in the default resource pool."\
|
||||
"\n Press y to keep this behaviour, n to select"\
|
||||
" a new resource pool or d to delegate the choice"\
|
||||
" to the user [y/n/d]? "
|
||||
@ -324,7 +324,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
|
||||
answer = STDIN.gets.strip
|
||||
|
||||
t[:one] += "RESOURCE_POOL=#{answer}"
|
||||
t[:one] += "RESOURCE_POOL=\"#{answer}\"\n"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -46,6 +46,8 @@ const char * Cluster::network_db_bootstrap =
|
||||
"CREATE TABLE IF NOT EXISTS cluster_network_relation ("
|
||||
"cid INTEGER, oid INTEGER, PRIMARY KEY(cid, oid))";
|
||||
|
||||
const char * Cluster::bitmap_table = "vm_bitmap";
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Cluster :: Constructor/Destructor */
|
||||
/* ************************************************************************** */
|
||||
@ -53,11 +55,13 @@ const char * Cluster::network_db_bootstrap =
|
||||
Cluster::Cluster(
|
||||
int id,
|
||||
const string& name,
|
||||
ClusterTemplate* cl_template):
|
||||
ClusterTemplate* cl_template,
|
||||
const VectorAttribute& vnc_conf):
|
||||
PoolObjectSQL(id,CLUSTER,name,-1,-1,"","",table),
|
||||
hosts("HOSTS"),
|
||||
datastores("DATASTORES"),
|
||||
vnets("VNETS")
|
||||
vnets("VNETS"),
|
||||
vnc_bitmap(vnc_conf, id, bitmap_table)
|
||||
{
|
||||
if (cl_template != 0)
|
||||
{
|
||||
@ -68,11 +72,8 @@ Cluster::Cluster(
|
||||
obj_template = new ClusterTemplate;
|
||||
}
|
||||
|
||||
string default_cpu; //TODO - Get these two from oned.conf
|
||||
string default_mem;
|
||||
|
||||
add_template_attribute("RESERVED_CPU", default_cpu);
|
||||
add_template_attribute("RESERVED_MEM", default_cpu);
|
||||
add_template_attribute("RESERVED_CPU", "");
|
||||
add_template_attribute("RESERVED_MEM", "");
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -225,7 +226,6 @@ int Cluster::insert_replace(SqlDB *db, bool replace, string& error_str)
|
||||
}
|
||||
|
||||
// Construct the SQL statement to Insert or Replace
|
||||
|
||||
oss <<" INTO "<<table <<" ("<< db_names <<") VALUES ("
|
||||
<< oid << ","
|
||||
<< "'" << sql_name << "',"
|
||||
@ -302,9 +302,9 @@ int Cluster::insert_replace(SqlDB *db, bool replace, string& error_str)
|
||||
{
|
||||
oss.str("");
|
||||
|
||||
oss << "BEGIN; "
|
||||
<< "DELETE FROM " << network_table << " WHERE cid = " << oid << "; "
|
||||
<< "DELETE FROM " << datastore_table<< " WHERE cid = " << oid << "; ";
|
||||
oss <<"BEGIN; "
|
||||
<<"DELETE FROM "<< network_table <<" WHERE cid = "<< oid<< "; "
|
||||
<<"DELETE FROM "<< datastore_table<<" WHERE cid = "<< oid<< "; ";
|
||||
|
||||
set<int>::iterator i;
|
||||
|
||||
|
@ -35,7 +35,8 @@ const int ClusterPool::DEFAULT_CLUSTER_ID = 0;
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
ClusterPool::ClusterPool(SqlDB * db):PoolSQL(db, Cluster::table, true, true)
|
||||
ClusterPool::ClusterPool(SqlDB * db, const VectorAttribute * _vnc_conf):
|
||||
PoolSQL(db, Cluster::table, true, true), vnc_conf(_vnc_conf)
|
||||
{
|
||||
ostringstream oss;
|
||||
string error_str;
|
||||
@ -109,7 +110,7 @@ int ClusterPool::allocate(string name, int * oid, string& error_str)
|
||||
}
|
||||
|
||||
// Build a new Cluster object
|
||||
cluster = new Cluster(-1, name, 0);
|
||||
cluster = new Cluster(-1, name, 0, vnc_conf);
|
||||
|
||||
// Insert the Object in the pool
|
||||
*oid = PoolSQL::allocate(cluster, error_str);
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/aes.h>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
@ -333,3 +335,148 @@ std::string one_util::gsub(const std::string& st, const std::string& sfind,
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Buffer length for zlib inflate/deflate
|
||||
*/
|
||||
#define ZBUFFER 16384
|
||||
|
||||
std::string * one_util::zlib_compress(const std::string& in, bool base64)
|
||||
{
|
||||
z_stream zs;
|
||||
|
||||
std::ostringstream oss;
|
||||
unsigned char out[ZBUFFER];
|
||||
|
||||
std::string * zstr;
|
||||
|
||||
if ( in.empty() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
zs.zalloc = Z_NULL;
|
||||
zs.zfree = Z_NULL;
|
||||
zs.opaque = Z_NULL;
|
||||
|
||||
if ( deflateInit(&zs, Z_DEFAULT_COMPRESSION) != Z_OK )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
zs.avail_in = in.size();
|
||||
zs.next_in = (unsigned char *) const_cast<char *>(in.c_str());
|
||||
|
||||
do
|
||||
{
|
||||
zs.avail_out = ZBUFFER;
|
||||
zs.next_out = out;
|
||||
|
||||
if ( deflate(&zs, Z_FINISH) == Z_STREAM_ERROR )
|
||||
{
|
||||
deflateEnd(&zs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
oss.write((const char *)out, ZBUFFER - zs.avail_out);
|
||||
} while (zs.avail_out == 0);
|
||||
|
||||
deflateEnd(&zs);
|
||||
|
||||
if ( base64 )
|
||||
{
|
||||
zstr = one_util::base64_encode(oss.str());
|
||||
}
|
||||
else
|
||||
{
|
||||
zstr = new std::string(oss.str());
|
||||
}
|
||||
|
||||
return zstr;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
std::string * one_util::zlib_decompress(const std::string& in, bool base64)
|
||||
{
|
||||
int rc;
|
||||
|
||||
z_stream zs;
|
||||
|
||||
std::ostringstream oss;
|
||||
unsigned char out[ZBUFFER];
|
||||
|
||||
std::string * in64;
|
||||
|
||||
if ( in.empty() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
zs.zalloc = Z_NULL;
|
||||
zs.zfree = Z_NULL;
|
||||
zs.opaque = Z_NULL;
|
||||
|
||||
zs.avail_in = 0;
|
||||
zs.next_in = Z_NULL;
|
||||
|
||||
if ( inflateInit(&zs) != Z_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( base64 )
|
||||
{
|
||||
in64 = one_util::base64_decode(in);
|
||||
|
||||
if (in64 == 0)
|
||||
{
|
||||
inflateEnd(&zs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
zs.avail_in = in64->size();
|
||||
zs.next_in = (unsigned char *) const_cast<char *>(in64->c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
zs.avail_in = in.size();
|
||||
zs.next_in = (unsigned char *) const_cast<char *>(in.c_str());
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
zs.avail_out = ZBUFFER;
|
||||
zs.next_out = out;
|
||||
|
||||
if ( (rc = inflate(&zs, Z_FINISH)) == Z_STREAM_ERROR )
|
||||
{
|
||||
inflateEnd(&zs);
|
||||
|
||||
if ( base64 )
|
||||
{
|
||||
delete in64;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
oss.write((const char *)out, ZBUFFER - zs.avail_out);
|
||||
} while (rc != Z_STREAM_END);
|
||||
|
||||
inflateEnd(&zs);
|
||||
|
||||
if ( base64 )
|
||||
{
|
||||
delete in64;
|
||||
}
|
||||
|
||||
return new std::string(oss.str());
|
||||
}
|
||||
|
||||
|
||||
|
@ -835,6 +835,8 @@ void LifeCycleManager::clean_action(int vid)
|
||||
void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, int& image_id)
|
||||
{
|
||||
int cpu, mem, disk;
|
||||
unsigned int port;
|
||||
|
||||
vector<VectorAttribute *> pci;
|
||||
time_t the_time = time(0);
|
||||
|
||||
@ -865,8 +867,16 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, int& imag
|
||||
vm->set_reason(History::USER);
|
||||
|
||||
vm->get_requirements(cpu, mem, disk, pci);
|
||||
|
||||
hpool->del_capacity(vm->get_hid(), vm->get_oid(), cpu, mem, disk, pci);
|
||||
|
||||
const VectorAttribute * graphics = vm->get_template_attribute("GRAPHICS");
|
||||
|
||||
if ( graphics != 0 && (graphics->vector_value("PORT", port) == 0))
|
||||
{
|
||||
clpool->release_vnc_port(vm->get_cid(), port);
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case VirtualMachine::PROLOG:
|
||||
|
@ -74,6 +74,7 @@ void LifeCycleManager::init_managers()
|
||||
hpool = nd.get_hpool();
|
||||
ipool = nd.get_ipool();
|
||||
sgpool = nd.get_secgrouppool();
|
||||
clpool = nd.get_clpool();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -811,6 +811,7 @@ void LifeCycleManager::epilog_success_action(int vid)
|
||||
|
||||
time_t the_time = time(0);
|
||||
int cpu,mem,disk;
|
||||
unsigned int port;
|
||||
|
||||
VirtualMachine::LcmState state;
|
||||
DispatchManager::Actions action;
|
||||
@ -883,6 +884,13 @@ void LifeCycleManager::epilog_success_action(int vid)
|
||||
|
||||
hpool->del_capacity(vm->get_hid(), vm->get_oid(), cpu, mem, disk, pci);
|
||||
|
||||
const VectorAttribute * graphics = vm->get_template_attribute("GRAPHICS");
|
||||
|
||||
if ( graphics != 0 && (graphics->vector_value("PORT", port) == 0))
|
||||
{
|
||||
clpool->release_vnc_port(vm->get_cid(), port);
|
||||
}
|
||||
|
||||
//----------------------------------------------------
|
||||
|
||||
dm->trigger(action,vid);
|
||||
|
@ -436,170 +436,160 @@ void Nebula::start(bool bootstrap_only)
|
||||
throw runtime_error("Could not start the ACL Manager");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// -------------------------------------------------------------------------
|
||||
// Pools
|
||||
// -----------------------------------------------------------
|
||||
// -------------------------------------------------------------------------
|
||||
try
|
||||
{
|
||||
int size;
|
||||
/* -------------------------- Cluster Pool -------------------------- */
|
||||
const VectorAttribute * vnc_conf;
|
||||
|
||||
string mac_prefix;
|
||||
string default_image_type;
|
||||
string default_device_prefix;
|
||||
string default_cdrom_device_prefix;
|
||||
vnc_conf = nebula_configuration->get("VNC_PORTS");
|
||||
|
||||
time_t expiration_time;
|
||||
time_t vm_expiration;
|
||||
time_t host_expiration;
|
||||
|
||||
bool vm_submit_on_hold;
|
||||
float cpu_cost;
|
||||
float mem_cost;
|
||||
float disk_cost;
|
||||
clpool = new ClusterPool(db, vnc_conf);
|
||||
|
||||
/* --------------------- VirtualMachine Pool ------------------------ */
|
||||
vector<const VectorAttribute *> vm_hooks;
|
||||
vector<const VectorAttribute *> host_hooks;
|
||||
vector<const VectorAttribute *> vrouter_hooks;
|
||||
vector<const VectorAttribute *> vnet_hooks;
|
||||
vector<const VectorAttribute *> user_hooks;
|
||||
vector<const VectorAttribute *> group_hooks;
|
||||
vector<const VectorAttribute *> image_hooks;
|
||||
|
||||
vector<const SingleAttribute *> vm_restricted_attrs;
|
||||
vector<const SingleAttribute *> img_restricted_attrs;
|
||||
vector<const SingleAttribute *> vnet_restricted_attrs;
|
||||
|
||||
vector<const SingleAttribute *> inherit_image_attrs;
|
||||
vector<const SingleAttribute *> inherit_datastore_attrs;
|
||||
vector<const SingleAttribute *> inherit_vnet_attrs;
|
||||
time_t vm_expiration;
|
||||
bool vm_submit_on_hold;
|
||||
|
||||
vector<const VectorAttribute *> default_cost;
|
||||
float cpu_cost;
|
||||
float mem_cost;
|
||||
float disk_cost;
|
||||
|
||||
clpool = new ClusterPool(db);
|
||||
docpool = new DocumentPool(db);
|
||||
zonepool= new ZonePool(db, is_federation_slave());
|
||||
vdcpool = new VdcPool(db, is_federation_slave());
|
||||
const VectorAttribute * default_cost;
|
||||
|
||||
nebula_configuration->get("VM_HOOK", vm_hooks);
|
||||
nebula_configuration->get("HOST_HOOK", host_hooks);
|
||||
nebula_configuration->get("VROUTER_HOOK", vrouter_hooks);
|
||||
nebula_configuration->get("VNET_HOOK", vnet_hooks);
|
||||
nebula_configuration->get("USER_HOOK", user_hooks);
|
||||
nebula_configuration->get("GROUP_HOOK", group_hooks);
|
||||
nebula_configuration->get("IMAGE_HOOK", image_hooks);
|
||||
nebula_configuration->get("VM_HOOK", vm_hooks);
|
||||
|
||||
nebula_configuration->get("VM_RESTRICTED_ATTR", vm_restricted_attrs);
|
||||
nebula_configuration->get("IMAGE_RESTRICTED_ATTR", img_restricted_attrs);
|
||||
nebula_configuration->get("VNET_RESTRICTED_ATTR", vnet_restricted_attrs);
|
||||
|
||||
nebula_configuration->get("INHERIT_IMAGE_ATTR", inherit_image_attrs);
|
||||
nebula_configuration->get("INHERIT_DATASTORE_ATTR", inherit_datastore_attrs);
|
||||
nebula_configuration->get("INHERIT_VNET_ATTR", inherit_vnet_attrs);
|
||||
|
||||
nebula_configuration->get("VM_MONITORING_EXPIRATION_TIME",vm_expiration);
|
||||
nebula_configuration->get("HOST_MONITORING_EXPIRATION_TIME",host_expiration);
|
||||
|
||||
nebula_configuration->get("VM_SUBMIT_ON_HOLD",vm_submit_on_hold);
|
||||
|
||||
rc = nebula_configuration->get("DEFAULT_COST", default_cost);
|
||||
default_cost = nebula_configuration->get("DEFAULT_COST");
|
||||
|
||||
cpu_cost = 0;
|
||||
mem_cost = 0;
|
||||
disk_cost= 0;
|
||||
|
||||
if (rc != 0)
|
||||
if (default_cost->vector_value("CPU_COST", cpu_cost) != 0)
|
||||
{
|
||||
const VectorAttribute * vatt = static_cast<const VectorAttribute *>
|
||||
(default_cost[0]);
|
||||
|
||||
rc = vatt->vector_value("CPU_COST", cpu_cost);
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
cpu_cost = 0;
|
||||
}
|
||||
|
||||
rc = vatt->vector_value("MEMORY_COST", mem_cost);
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
mem_cost = 0;
|
||||
}
|
||||
|
||||
|
||||
rc = vatt->vector_value("DISK_COST", disk_cost);
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
disk_cost = 0;
|
||||
}
|
||||
cpu_cost = 0;
|
||||
}
|
||||
|
||||
vmpool = new VirtualMachinePool(db,
|
||||
vm_hooks,
|
||||
hook_location,
|
||||
remotes_location,
|
||||
vm_restricted_attrs,
|
||||
vm_expiration,
|
||||
vm_submit_on_hold,
|
||||
cpu_cost,
|
||||
mem_cost,
|
||||
disk_cost);
|
||||
if (default_cost->vector_value("MEMORY_COST", mem_cost) != 0)
|
||||
{
|
||||
mem_cost = 0;
|
||||
}
|
||||
|
||||
hpool = new HostPool(db,
|
||||
host_hooks,
|
||||
hook_location,
|
||||
remotes_location,
|
||||
host_expiration);
|
||||
if (default_cost->vector_value("DISK_COST", disk_cost) != 0)
|
||||
{
|
||||
disk_cost = 0;
|
||||
}
|
||||
|
||||
vrouterpool = new VirtualRouterPool(db,
|
||||
vrouter_hooks,
|
||||
remotes_location);
|
||||
vmpool = new VirtualMachinePool(db, vm_hooks, hook_location,
|
||||
remotes_location, vm_restricted_attrs, vm_expiration,
|
||||
vm_submit_on_hold, cpu_cost, mem_cost, disk_cost);
|
||||
|
||||
/* ---------------------------- Host Pool --------------------------- */
|
||||
vector<const VectorAttribute *> host_hooks;
|
||||
|
||||
time_t host_expiration;
|
||||
|
||||
nebula_configuration->get("HOST_HOOK", host_hooks);
|
||||
|
||||
nebula_configuration->get("HOST_MONITORING_EXPIRATION_TIME", host_expiration);
|
||||
|
||||
hpool = new HostPool(db, host_hooks, hook_location, remotes_location,
|
||||
host_expiration);
|
||||
|
||||
/* --------------------- VirtualRouter Pool ------------------------- */
|
||||
vector<const VectorAttribute *> vrouter_hooks;
|
||||
|
||||
nebula_configuration->get("VROUTER_HOOK", vrouter_hooks);
|
||||
|
||||
vrouterpool = new VirtualRouterPool(db, vrouter_hooks, remotes_location);
|
||||
|
||||
/* -------------------- VirtualNetwork Pool ------------------------- */
|
||||
int size;
|
||||
string mac_prefix;
|
||||
|
||||
vector<const SingleAttribute *> inherit_vnet_attrs;
|
||||
vector<const SingleAttribute *> vnet_restricted_attrs;
|
||||
vector<const VectorAttribute *> vnet_hooks;
|
||||
|
||||
nebula_configuration->get("MAC_PREFIX", mac_prefix);
|
||||
|
||||
nebula_configuration->get("NETWORK_SIZE", size);
|
||||
|
||||
vnpool = new VirtualNetworkPool(db,
|
||||
mac_prefix,
|
||||
size,
|
||||
vnet_restricted_attrs,
|
||||
vnet_hooks,
|
||||
remotes_location,
|
||||
inherit_vnet_attrs);
|
||||
nebula_configuration->get("VNET_RESTRICTED_ATTR", vnet_restricted_attrs);
|
||||
|
||||
gpool = new GroupPool(db, group_hooks,
|
||||
remotes_location, is_federation_slave());
|
||||
nebula_configuration->get("VNET_HOOK", vnet_hooks);
|
||||
|
||||
nebula_configuration->get("INHERIT_VNET_ATTR", inherit_vnet_attrs);
|
||||
|
||||
vnpool = new VirtualNetworkPool(db, mac_prefix, size, vnet_restricted_attrs,
|
||||
vnet_hooks, remotes_location, inherit_vnet_attrs);
|
||||
|
||||
/* ----------------------- Group/User Pool -------------------------- */
|
||||
vector<const VectorAttribute *> user_hooks;
|
||||
vector<const VectorAttribute *> group_hooks;
|
||||
|
||||
time_t expiration_time;
|
||||
|
||||
nebula_configuration->get("GROUP_HOOK", group_hooks);
|
||||
|
||||
gpool = new GroupPool(db, group_hooks, remotes_location,
|
||||
is_federation_slave());
|
||||
|
||||
nebula_configuration->get("SESSION_EXPIRATION_TIME", expiration_time);
|
||||
|
||||
upool = new UserPool(db, expiration_time, user_hooks,
|
||||
remotes_location, is_federation_slave());
|
||||
nebula_configuration->get("USER_HOOK", user_hooks);
|
||||
|
||||
nebula_configuration->get("DEFAULT_IMAGE_TYPE", default_image_type);
|
||||
nebula_configuration->get("DEFAULT_DEVICE_PREFIX",
|
||||
default_device_prefix);
|
||||
nebula_configuration->get("DEFAULT_CDROM_DEVICE_PREFIX",
|
||||
default_cdrom_device_prefix);
|
||||
ipool = new ImagePool(db,
|
||||
default_image_type,
|
||||
default_device_prefix,
|
||||
default_cdrom_device_prefix,
|
||||
img_restricted_attrs,
|
||||
image_hooks,
|
||||
remotes_location,
|
||||
inherit_image_attrs);
|
||||
upool = new UserPool(db, expiration_time, user_hooks, remotes_location,
|
||||
is_federation_slave());
|
||||
|
||||
tpool = new VMTemplatePool(db);
|
||||
/* -------------------- Image/Datastore Pool ------------------------ */
|
||||
string image_type;
|
||||
string device_prefix;
|
||||
string cd_dev_prefix;
|
||||
|
||||
dspool = new DatastorePool(db, inherit_datastore_attrs);
|
||||
vector<const VectorAttribute *> image_hooks;
|
||||
vector<const SingleAttribute *> img_restricted_attrs;
|
||||
vector<const SingleAttribute *> inherit_image_attrs;
|
||||
vector<const SingleAttribute *> inherit_ds_attrs;
|
||||
|
||||
default_user_quota.select();
|
||||
default_group_quota.select();
|
||||
nebula_configuration->get("DEFAULT_IMAGE_TYPE", image_type);
|
||||
nebula_configuration->get("DEFAULT_DEVICE_PREFIX", device_prefix);
|
||||
nebula_configuration->get("DEFAULT_CDROM_DEVICE_PREFIX", cd_dev_prefix);
|
||||
|
||||
nebula_configuration->get("IMAGE_HOOK", image_hooks);
|
||||
|
||||
nebula_configuration->get("IMAGE_RESTRICTED_ATTR", img_restricted_attrs);
|
||||
|
||||
nebula_configuration->get("INHERIT_IMAGE_ATTR", inherit_image_attrs);
|
||||
|
||||
ipool = new ImagePool(db, image_type, device_prefix, cd_dev_prefix,
|
||||
img_restricted_attrs, image_hooks, remotes_location,
|
||||
inherit_image_attrs);
|
||||
|
||||
nebula_configuration->get("INHERIT_DATASTORE_ATTR", inherit_ds_attrs);
|
||||
|
||||
dspool = new DatastorePool(db, inherit_ds_attrs);
|
||||
|
||||
/* ----- Document, Zone, VDC, VMTemplate, SG and Makerket Pools ----- */
|
||||
docpool = new DocumentPool(db);
|
||||
zonepool = new ZonePool(db, is_federation_slave());
|
||||
vdcpool = new VdcPool(db, is_federation_slave());
|
||||
|
||||
tpool = new VMTemplatePool(db);
|
||||
|
||||
secgrouppool = new SecurityGroupPool(db);
|
||||
|
||||
marketpool = new MarketPlacePool(db, is_federation_slave());
|
||||
apppool = new MarketPlaceAppPool(db, is_federation_slave());
|
||||
marketpool = new MarketPlacePool(db, is_federation_slave());
|
||||
apppool = new MarketPlaceAppPool(db, is_federation_slave());
|
||||
|
||||
default_user_quota.select();
|
||||
default_group_quota.select();
|
||||
}
|
||||
catch (exception&)
|
||||
{
|
||||
|
@ -310,9 +310,9 @@ void OpenNebulaTemplate::set_conf_default()
|
||||
# LISTEN_ADDRESS
|
||||
# PORT
|
||||
# DB
|
||||
# VNC_BASE_PORT
|
||||
# SCRIPTS_REMOTE_DIR
|
||||
# VM_SUBMIT_ON_HOLD
|
||||
# VNC_PORTS
|
||||
#*******************************************************************************
|
||||
*/
|
||||
set_conf_single("MANAGER_TIMER", "15");
|
||||
@ -325,7 +325,6 @@ void OpenNebulaTemplate::set_conf_default()
|
||||
set_conf_single("VM_MONITORING_EXPIRATION_TIME", "14400");
|
||||
set_conf_single("PORT", "2633");
|
||||
set_conf_single("LISTEN_ADDRESS", "0.0.0.0");
|
||||
set_conf_single("VNC_BASE_PORT", "5900");
|
||||
set_conf_single("SCRIPTS_REMOTE_DIR", "/var/tmp/one");
|
||||
set_conf_single("VM_SUBMIT_ON_HOLD", "NO");
|
||||
|
||||
@ -342,6 +341,15 @@ void OpenNebulaTemplate::set_conf_default()
|
||||
|
||||
vattribute = new VectorAttribute("LOG",vvalue);
|
||||
conf_default.insert(make_pair(vattribute->name(),vattribute));
|
||||
|
||||
// LOG CONFIGURATION
|
||||
vvalue.clear();
|
||||
vvalue.insert(make_pair("RESERVED",""));
|
||||
vvalue.insert(make_pair("START","5900"));
|
||||
|
||||
vattribute = new VectorAttribute("VNC_PORTS",vvalue);
|
||||
conf_default.insert(make_pair(vattribute->name(),vattribute));
|
||||
|
||||
/*
|
||||
#*******************************************************************************
|
||||
# Federation configuration attributes
|
||||
|
@ -446,15 +446,13 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
string vmdir;
|
||||
int rc;
|
||||
|
||||
VirtualMachinePool * vmpool = static_cast<VirtualMachinePool *>(pool);
|
||||
|
||||
vm->add_history(hid, cid, hostname, vmm_mad, vnm_mad, tm_mad, ds_location, ds_id);
|
||||
vm->add_history(hid, cid, hostname, vmm_mad, vnm_mad, tm_mad, ds_location,
|
||||
ds_id);
|
||||
|
||||
rc = vmpool->update_history(vm);
|
||||
|
||||
if ( rc != 0 )
|
||||
if ( vmpool->update_history(vm) != 0 )
|
||||
{
|
||||
att.resp_msg = "Cannot update virtual machine history";
|
||||
failure_response(INTERNAL, att);
|
||||
@ -462,7 +460,13 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm,
|
||||
return -1;
|
||||
}
|
||||
|
||||
vmpool->update(vm);
|
||||
if ( vmpool->update(vm) != 0 )
|
||||
{
|
||||
att.resp_msg = "Cannot update virtual machine";
|
||||
failure_response(INTERNAL, att);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -650,6 +654,127 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Adds extra info to the volatile disks of the given template, ds inherited
|
||||
* attributes and TYPE
|
||||
* @param ds_id datastore id
|
||||
* @param vd vector of DISKS
|
||||
* @return true if there at least one volatile disk was found
|
||||
*/
|
||||
static bool set_volatile_disk_info(int ds_id, vector<VectorAttribute *>& vd)
|
||||
{
|
||||
DatastorePool * ds_pool = Nebula::instance().get_dspool();
|
||||
|
||||
bool found = false;
|
||||
|
||||
for(vector<VectorAttribute *>::iterator it = vd.begin(); it!=vd.end(); ++it)
|
||||
{
|
||||
if ( !VirtualMachine::is_volatile(*it) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ds_pool->disk_attribute(ds_id, *it);
|
||||
|
||||
found = true;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static bool set_volatile_disk_info(VirtualMachine *vm)
|
||||
{
|
||||
if ( !vm->hasHistory() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
vector<VectorAttribute *> disks;
|
||||
|
||||
int ds_id = vm->get_ds_id();
|
||||
|
||||
vm->get_template_attribute("DISK", disks);
|
||||
|
||||
bool found = set_volatile_disk_info(ds_id, disks);
|
||||
|
||||
if ( found )
|
||||
{
|
||||
Nebula::instance().get_vmpool()->update(vm);
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
static bool set_volatile_disk_info(VirtualMachine *vm, Template& tmpl)
|
||||
{
|
||||
if ( !vm->hasHistory() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
vector<VectorAttribute *> disks;
|
||||
|
||||
int ds_id = vm->get_ds_id();
|
||||
|
||||
tmpl.get("DISK", disks);
|
||||
|
||||
bool found = set_volatile_disk_info(ds_id, disks);
|
||||
|
||||
if ( found )
|
||||
{
|
||||
Nebula::instance().get_vmpool()->update(vm);
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int set_vnc_port(VirtualMachine *vm, RequestAttributes& att)
|
||||
{
|
||||
ClusterPool * cpool = Nebula::instance().get_clpool();
|
||||
|
||||
VectorAttribute * graphics = vm->get_template_attribute("GRAPHICS");
|
||||
|
||||
unsigned int port;
|
||||
int rc;
|
||||
|
||||
if (graphics == 0 || !vm->hasHistory())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (graphics->vector_value("PORT", port) == 0)
|
||||
{
|
||||
rc = cpool->set_vnc_port(vm->get_cid(), port);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
att.resp_msg = "Requested VNC port already assgined to a VM";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = cpool->get_vnc_port(vm->get_cid(), vm->get_oid(), port);
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
graphics->replace("PORT", port);
|
||||
|
||||
Nebula::instance().get_vmpool()->update(vm);
|
||||
}
|
||||
else
|
||||
{
|
||||
att.resp_msg = "No free VNC ports available in the cluster";
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
@ -743,7 +868,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
set<int> ds_cluster_ids;
|
||||
bool ds_migr;
|
||||
|
||||
if (get_ds_information(ds_id, ds_cluster_ids, tm_mad, att, ds_migr) != 0)
|
||||
if (get_ds_information(ds_id,ds_cluster_ids,tm_mad,att,ds_migr) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -752,10 +877,11 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << object_name(PoolObjectSQL::DATASTORE) << " [" << ds_id << "] and "
|
||||
<< object_name(PoolObjectSQL::HOST) << " [" << hid
|
||||
<< "] are not in the same "
|
||||
<< object_name(PoolObjectSQL::CLUSTER) << " [" << cluster_id << "].";
|
||||
oss << object_name(PoolObjectSQL::DATASTORE) << " [" << ds_id
|
||||
<< "] and " << object_name(PoolObjectSQL::HOST) << " ["
|
||||
<< hid << "] are not in the same "
|
||||
<< object_name(PoolObjectSQL::CLUSTER) << " [" << cluster_id
|
||||
<< "].";
|
||||
|
||||
att.resp_msg = oss.str();
|
||||
|
||||
@ -806,7 +932,6 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
// - VM States are right
|
||||
// - Host capacity if required
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if ((vm = get_vm(id, att)) == 0)
|
||||
{
|
||||
return;
|
||||
@ -817,7 +942,9 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
vm->get_state() != VirtualMachine::STOPPED &&
|
||||
vm->get_state() != VirtualMachine::UNDEPLOYED)
|
||||
{
|
||||
att.resp_msg = "Deploy action is not available for state " + vm->state_str();
|
||||
att.resp_msg = "Deploy action is not available for state " +
|
||||
vm->state_str();
|
||||
|
||||
failure_response(ACTION, att);
|
||||
|
||||
vm->unlock();
|
||||
@ -833,9 +960,8 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Add a new history record and update volatile DISK info
|
||||
// Add a new history record
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (add_history(vm,
|
||||
hid,
|
||||
cluster_id,
|
||||
@ -851,7 +977,19 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
return;
|
||||
}
|
||||
|
||||
vm->volatile_disk_extended_info();
|
||||
// ------------------------------------------------------------------------
|
||||
// Add deployment dependent attributes to VM
|
||||
// - volatile disk (selected system DS driver)
|
||||
// - vnc port (free in the selected cluster)
|
||||
// ------------------------------------------------------------------------
|
||||
set_volatile_disk_info(vm);
|
||||
|
||||
if (set_vnc_port(vm, att) != 0)
|
||||
{
|
||||
failure_response(ACTION, att);
|
||||
vm->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// deploy the VM
|
||||
@ -1178,7 +1316,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
|
||||
return;
|
||||
}
|
||||
|
||||
vm->volatile_disk_extended_info();
|
||||
set_volatile_disk_info(vm);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Migrate the VM
|
||||
@ -1570,9 +1708,10 @@ void VirtualMachineAttach::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
|
||||
vm->get_permissions(vm_perms);
|
||||
|
||||
volatile_disk = vm->volatile_disk_extended_info(&tmpl);
|
||||
volatile_disk = set_volatile_disk_info(vm, tmpl);
|
||||
|
||||
if (vm->is_vrouter() && !VirtualRouter::is_action_supported(History::DISK_ATTACH_ACTION))
|
||||
if (vm->is_vrouter() &&
|
||||
!VirtualRouter::is_action_supported(History::DISK_ATTACH_ACTION))
|
||||
{
|
||||
att.resp_msg = "Action is not supported for virtual router VMs";
|
||||
failure_response(ACTION, att);
|
||||
|
@ -33,6 +33,10 @@ enabled_tabs:
|
||||
autorefresh: true
|
||||
features:
|
||||
showback: true
|
||||
|
||||
# Allows to change the security groups for each network interface
|
||||
# on the VM creation dialog
|
||||
secgroups: true
|
||||
tabs:
|
||||
dashboard-tab:
|
||||
panel_tabs:
|
||||
|
@ -33,6 +33,10 @@ enabled_tabs:
|
||||
autorefresh: true
|
||||
features:
|
||||
showback: true
|
||||
|
||||
# Allows to change the security groups for each network interface
|
||||
# on the VM creation dialog
|
||||
secgroups: false
|
||||
tabs:
|
||||
dashboard-tab:
|
||||
panel_tabs:
|
||||
|
@ -5,6 +5,10 @@ enabled_tabs:
|
||||
- settings-tab
|
||||
features:
|
||||
showback: true
|
||||
|
||||
# Allows to change the security groups for each network interface
|
||||
# on the VM creation dialog
|
||||
secgroups: true
|
||||
tabs:
|
||||
provision-tab:
|
||||
panel_tabs:
|
||||
@ -85,10 +89,18 @@ tabs:
|
||||
- 0 # Checkbox
|
||||
- 1 # ID
|
||||
- 2 # Owner
|
||||
- 3 # Group
|
||||
#- 3 # Group
|
||||
- 4 # Name
|
||||
- 5 # Reservation
|
||||
- 6 # Cluster
|
||||
#- 5 # Reservation
|
||||
#- 6 # Cluster
|
||||
#- 7 # Bridge
|
||||
- 8 # Leases
|
||||
#- 8 # Leases
|
||||
#- 9 # VLAN ID
|
||||
secgroups-tab:
|
||||
table_columns:
|
||||
- 0 # Checkbox
|
||||
- 1 # ID
|
||||
- 2 # Owner
|
||||
#- 3 # Group
|
||||
- 4 # Name
|
||||
#- 5 # Labels
|
@ -5,6 +5,10 @@ enabled_tabs:
|
||||
- settings-tab
|
||||
features:
|
||||
showback: true
|
||||
|
||||
# Allows to change the security groups for each network interface
|
||||
# on the VM creation dialog
|
||||
secgroups: false
|
||||
tabs:
|
||||
provision-tab:
|
||||
panel_tabs:
|
||||
@ -92,3 +96,11 @@ tabs:
|
||||
#- 7 # Bridge
|
||||
- 8 # Leases
|
||||
#- 9 # VLAN ID
|
||||
secgroups-tab:
|
||||
table_columns:
|
||||
- 0 # Checkbox
|
||||
- 1 # ID
|
||||
- 2 # Owner
|
||||
#- 3 # Group
|
||||
- 4 # Name
|
||||
#- 5 # Labels
|
@ -33,6 +33,10 @@ enabled_tabs:
|
||||
autorefresh: true
|
||||
features:
|
||||
showback: true
|
||||
|
||||
# Allows to change the security groups for each network interface
|
||||
# on the VM creation dialog
|
||||
secgroups: true
|
||||
tabs:
|
||||
dashboard-tab:
|
||||
panel_tabs:
|
||||
|
@ -33,6 +33,10 @@ enabled_tabs:
|
||||
autorefresh: true
|
||||
features:
|
||||
showback: true
|
||||
|
||||
# Allows to change the security groups for each network interface
|
||||
# on the VM creation dialog
|
||||
secgroups: false
|
||||
tabs:
|
||||
dashboard-tab:
|
||||
panel_tabs:
|
||||
|
@ -33,6 +33,10 @@ enabled_tabs:
|
||||
autorefresh: true
|
||||
features:
|
||||
showback: true
|
||||
|
||||
# Allows to change the security groups for each network interface
|
||||
# on the VM creation dialog
|
||||
secgroups: true
|
||||
tabs:
|
||||
dashboard-tab:
|
||||
panel_tabs:
|
||||
|
@ -70,9 +70,6 @@ define(function(require) {
|
||||
Sunstone.showTab(DASHBOARD_TAB_ID);
|
||||
$('#loading').hide();
|
||||
}
|
||||
|
||||
// init the zone list, needed for market & apps zone columns
|
||||
Sunstone.runAction("Zone.list");
|
||||
});
|
||||
|
||||
function _setupCloseDropdownsOnClick() {
|
||||
|
@ -17,6 +17,8 @@
|
||||
define(function(require) {
|
||||
var OpenNebulaAction = require('./action');
|
||||
var Locale = require('utils/locale');
|
||||
var Config = require('sunstone-config');
|
||||
var OpenNebulaHelper = require('./helper');
|
||||
|
||||
var RESOURCE = "DATASTORE";
|
||||
var STATES_STR = [
|
||||
@ -40,6 +42,8 @@ define(function(require) {
|
||||
FILE_DS : 2
|
||||
};
|
||||
|
||||
var dsMadIndex = {};
|
||||
|
||||
var Datastore = {
|
||||
"resource": RESOURCE,
|
||||
"stateStr": function(stateId) {
|
||||
@ -57,7 +61,17 @@ define(function(require) {
|
||||
OpenNebulaAction.del(params, RESOURCE);
|
||||
},
|
||||
"list" : function(params) {
|
||||
OpenNebulaAction.list(params, RESOURCE);
|
||||
OpenNebulaAction.list(params, RESOURCE, null, function(response) {
|
||||
var list = OpenNebulaHelper.pool(RESOURCE, response);
|
||||
|
||||
dsMadIndex = {};
|
||||
|
||||
$.each(list, function(){
|
||||
dsMadIndex[ this[RESOURCE].ID ] = this[RESOURCE].DS_MAD;
|
||||
});
|
||||
|
||||
return list;
|
||||
});
|
||||
},
|
||||
"list_in_zone" : function(params) {
|
||||
OpenNebulaAction.list_in_zone(params, RESOURCE);
|
||||
@ -95,6 +109,33 @@ define(function(require) {
|
||||
},
|
||||
"getName": function(id){
|
||||
return OpenNebulaAction.getName(id, RESOURCE);
|
||||
},
|
||||
"isMarketExportSupported": function(id){
|
||||
var name = dsMadIndex[id];
|
||||
|
||||
if(name == undefined){
|
||||
// When in doubt, allow the action and let oned return failure
|
||||
return true;
|
||||
}
|
||||
|
||||
var support = false;
|
||||
|
||||
$.each(Config.onedConf.DS_MAD_CONF, function(){
|
||||
if (this.NAME == name){
|
||||
support = (this.MARKETPLACE_ACTIONS != undefined &&
|
||||
this.MARKETPLACE_ACTIONS.split(',').includes("export"));
|
||||
return false; //break
|
||||
}
|
||||
});
|
||||
|
||||
return support;
|
||||
},
|
||||
"initMarketExportSupported": function(){
|
||||
this.list({
|
||||
timeout: true,
|
||||
success: function (request, obj_list) {},
|
||||
//error: Notifier.onError
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ define(function(require) {
|
||||
},
|
||||
"isNetworkChangeEnabled": function(template) {
|
||||
if (template.VMTEMPLATE.TEMPLATE.SUNSTONE &&
|
||||
template.VMTEMPLATE.TEMPLATE.SUNSTONE.NETWORK_SELECT !== 'NO') {
|
||||
template.VMTEMPLATE.TEMPLATE.SUNSTONE.NETWORK_SELECT == 'NO') {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
|
@ -58,6 +58,11 @@ define(function(require) {
|
||||
_addPanelsHooks(_tabId, panelsHooks);
|
||||
}
|
||||
|
||||
var initHooks = tabObj.initHooks;
|
||||
if (initHooks) {
|
||||
_addInitHooks(_tabId, initHooks);
|
||||
}
|
||||
|
||||
var dialogs = tabObj.dialogs;
|
||||
if (dialogs) {
|
||||
_addDialogs(dialogs)
|
||||
@ -89,6 +94,11 @@ define(function(require) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var _addInitHooks = function(tabId, hooks) {
|
||||
SunstoneCfg["tabs"][tabId]['initHooks'] = hooks;
|
||||
return false;
|
||||
}
|
||||
|
||||
var _addPanels = function(tabId, panels) {
|
||||
var indexedPanels = {}
|
||||
$.each(panels, function(index, panel) {
|
||||
@ -115,6 +125,14 @@ define(function(require) {
|
||||
_insertButtonsInTab(tabName);
|
||||
_setupDataTable(tabName);
|
||||
|
||||
var hooks = SunstoneCfg['tabs'][tabName].initHooks;
|
||||
|
||||
if (hooks) {
|
||||
$.each(hooks, function(i, hook){
|
||||
hook.init();
|
||||
});
|
||||
}
|
||||
|
||||
// TODO Add openenbula actions
|
||||
/*if (config['view']['autorefresh']) {
|
||||
var tabContext = $("#" + tabName);
|
||||
|
@ -19,6 +19,7 @@ define(function(require) {
|
||||
var Notifier = require('utils/notifier');
|
||||
var Locale = require('utils/locale');
|
||||
var OpenNebulaResource = require('opennebula/image');
|
||||
var OpenNebula = require('opennebula');
|
||||
var OpenNebulaAction = require('opennebula/action');
|
||||
var CommonActions = require('utils/common-actions');
|
||||
|
||||
@ -30,7 +31,7 @@ define(function(require) {
|
||||
var CLONE_DIALOG_ID = require('./dialogs/clone/dialogId');
|
||||
var CREATE_APP_DIALOG_ID = require('tabs/marketplaceapps-tab/form-panels/create/formPanelId');
|
||||
var IMPORT_DIALOG_ID = require('./form-panels/import/formPanelId');
|
||||
|
||||
var CONFIRM_DIALOG_ID = require('utils/dialogs/generic-confirm/dialogId');
|
||||
|
||||
var _commonActions = new CommonActions(OpenNebulaResource, RESOURCE, TAB_ID, XML_ROOT);
|
||||
|
||||
@ -63,19 +64,52 @@ define(function(require) {
|
||||
"Image.snapshot_delete": _commonActions.singleAction("snapshot_delete"),
|
||||
"Image.export_dialog" : {
|
||||
type: "custom",
|
||||
call: function() {
|
||||
Sunstone.showTab(MARKETPLACEAPPS_TAB_ID);
|
||||
Sunstone.showFormPanel(MARKETPLACEAPPS_TAB_ID, CREATE_APP_DIALOG_ID, "export",
|
||||
function(formPanelInstance, context) {
|
||||
var selectedNodes = Sunstone.getDataTable(TAB_ID).elements();
|
||||
if (selectedNodes.length !== 1) {
|
||||
Notifier.notifyMessage(Locale.tr("Please select one (and just one) Image to export."));
|
||||
return false;
|
||||
}
|
||||
call: function(params) {
|
||||
var selectedNodes = Sunstone.getDataTable(TAB_ID).elements();
|
||||
|
||||
var resourceId = '' + selectedNodes[0];
|
||||
formPanelInstance.setImageId(resourceId);
|
||||
});
|
||||
if (selectedNodes.length !== 1) {
|
||||
Notifier.notifyMessage(Locale.tr("Please select one (and just one) Image to export."));
|
||||
return false;
|
||||
}
|
||||
|
||||
var resourceId = '' + selectedNodes[0];
|
||||
|
||||
OpenNebulaResource.show({
|
||||
data : {
|
||||
id: resourceId
|
||||
},
|
||||
success: function(request, img_json){
|
||||
var img = img_json[XML_ROOT];
|
||||
|
||||
if (OpenNebula.Datastore.isMarketExportSupported(img.DATASTORE_ID)){
|
||||
Sunstone.showTab(MARKETPLACEAPPS_TAB_ID);
|
||||
Sunstone.showFormPanel(MARKETPLACEAPPS_TAB_ID, CREATE_APP_DIALOG_ID, "export",
|
||||
function(formPanelInstance, context) {
|
||||
formPanelInstance.setImageId(resourceId);
|
||||
});
|
||||
} else {
|
||||
Sunstone.getDialog(CONFIRM_DIALOG_ID).setParams({
|
||||
header : Locale.tr("Error"),
|
||||
body : Locale.tr("This Image resides in Datastore ") +
|
||||
img.DATASTORE_ID + " (" + img.DATASTORE + ")" +
|
||||
Locale.tr(". The export action is not supported for that Datastore DS_MAD driver."),
|
||||
question : "",
|
||||
buttons : [
|
||||
Locale.tr("Ok"),
|
||||
],
|
||||
submit : [
|
||||
function(){
|
||||
return false;
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
Sunstone.getDialog(CONFIRM_DIALOG_ID).reset();
|
||||
Sunstone.getDialog(CONFIRM_DIALOG_ID).show();
|
||||
}
|
||||
},
|
||||
error: Notifier.onError
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -35,6 +35,10 @@ define(function(require) {
|
||||
require('../utils/hooks/header')
|
||||
];
|
||||
|
||||
var _initHooks = [
|
||||
require('./marketplaceapps-tab/hooks/init')
|
||||
];
|
||||
|
||||
var _formPanels = [
|
||||
require('./marketplaceapps-tab/form-panels/create'),
|
||||
require('./marketplaceapps-tab/form-panels/export')
|
||||
@ -55,6 +59,7 @@ define(function(require) {
|
||||
dataTable: new Table(DATATABLE_ID, {actions: true, info: true, oneSelection: true}),
|
||||
panels: _panels,
|
||||
panelsHooks: _panelsHooks,
|
||||
initHooks: _initHooks,
|
||||
formPanels: _formPanels,
|
||||
dialogs: _dialogs
|
||||
};
|
||||
|
@ -28,6 +28,7 @@ define(function(require) {
|
||||
var MarketPlacesTable = require('tabs/marketplaces-tab/datatable');
|
||||
var Config = require('sunstone-config');
|
||||
var WizardFields = require('utils/wizard-fields');
|
||||
var OpenNebula = require('opennebula');
|
||||
|
||||
/*
|
||||
TEMPLATES
|
||||
@ -65,7 +66,13 @@ define(function(require) {
|
||||
|
||||
this.imagesTable = new ImagesTable(
|
||||
FORM_PANEL_ID + 'imagesTable',
|
||||
{'select': true});
|
||||
{ 'select': true,
|
||||
'selectOptions': {
|
||||
'filter_fn': function(image) {
|
||||
return OpenNebula.Datastore.isMarketExportSupported(image.DATASTORE_ID);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.marketPlacesTable = new MarketPlacesTable(
|
||||
FORM_PANEL_ID + 'marketPlacesTable',
|
||||
|
@ -0,0 +1,41 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */
|
||||
/* */
|
||||
/* 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
define(function(require) {
|
||||
|
||||
var Sunstone = require('sunstone');
|
||||
var OpenNebula = require('opennebula');
|
||||
var Config = require('sunstone-config');
|
||||
|
||||
var ZONE_TAB_ID = require('tabs/zones-tab/tabId');
|
||||
|
||||
/*
|
||||
FUNCTION DEFINITIONS
|
||||
*/
|
||||
|
||||
function _init() {
|
||||
// init the zone list, needed for market & apps zone columns
|
||||
if (Config.isTabActionEnabled(ZONE_TAB_ID, "Zone.list")) {
|
||||
Sunstone.runAction("Zone.list");
|
||||
}
|
||||
|
||||
OpenNebula.Datastore.initMarketExportSupported();
|
||||
}
|
||||
|
||||
return {
|
||||
'init': _init
|
||||
};
|
||||
});
|
@ -35,6 +35,10 @@ define(function(require) {
|
||||
require('../utils/hooks/header')
|
||||
];
|
||||
|
||||
var _initHooks = [
|
||||
require('./marketplaceapps-tab/hooks/init')
|
||||
];
|
||||
|
||||
var _formPanels = [
|
||||
require('./marketplaces-tab/form-panels/create')
|
||||
];
|
||||
@ -54,6 +58,7 @@ define(function(require) {
|
||||
dataTable: new Table(DATATABLE_ID, {actions: true, info: true, oneSelection: true}),
|
||||
panels: _panels,
|
||||
panelsHooks: _panelsHooks,
|
||||
initHooks: _initHooks,
|
||||
formPanels: _formPanels,
|
||||
dialogs: _dialogs
|
||||
};
|
||||
|
39
src/sunstone/public/app/tabs/marketplaces-tab/hooks/init.js
Normal file
39
src/sunstone/public/app/tabs/marketplaces-tab/hooks/init.js
Normal file
@ -0,0 +1,39 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */
|
||||
/* */
|
||||
/* 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
define(function(require) {
|
||||
|
||||
var Sunstone = require('sunstone');
|
||||
var OpenNebula = require('opennebula');
|
||||
var Config = require('sunstone-config');
|
||||
|
||||
var ZONE_TAB_ID = require('tabs/zones-tab/tabId');
|
||||
|
||||
/*
|
||||
FUNCTION DEFINITIONS
|
||||
*/
|
||||
|
||||
function _init() {
|
||||
// init the zone list, needed for market & apps zone columns
|
||||
if (Config.isTabActionEnabled(ZONE_TAB_ID, "Zone.list")) {
|
||||
Sunstone.runAction("Zone.list");
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
'init': _init
|
||||
};
|
||||
});
|
@ -917,7 +917,8 @@ define(function(require) {
|
||||
}
|
||||
|
||||
if (Config.provision.create_vm.isEnabled("network_select")) {
|
||||
NicsSection.insert(template_json, create_vm_context);
|
||||
NicsSection.insert(template_json, create_vm_context,
|
||||
{'securityGroups': Config.isFeatureEnabled("secgroups")});
|
||||
} else {
|
||||
$(".provision_network_selector", create_vm_context).html("");
|
||||
}
|
||||
@ -1108,42 +1109,9 @@ define(function(require) {
|
||||
var context = $("#provision_create_flow");
|
||||
|
||||
if (body.custom_attrs) {
|
||||
var network_attrs = [];
|
||||
var text_attrs = [];
|
||||
|
||||
$.each(body.custom_attrs, function(key, value){
|
||||
var parts = value.split("|");
|
||||
// 0 mandatory; 1 type; 2 desc;
|
||||
var attrs = {
|
||||
"name": key,
|
||||
"mandatory": parts[0],
|
||||
"type": parts[1],
|
||||
"description": parts[2],
|
||||
}
|
||||
|
||||
switch (parts[1]) {
|
||||
case "vnet_id":
|
||||
network_attrs.push(attrs)
|
||||
break;
|
||||
case "text":
|
||||
case "text64":
|
||||
case "password":
|
||||
text_attrs.push(attrs)
|
||||
break;
|
||||
}
|
||||
})
|
||||
|
||||
if (network_attrs.length > 0) {
|
||||
NicsSection.generate_provision_network_accordion(
|
||||
$(".provision_network_selector", context), {hide_add_button:true});
|
||||
|
||||
$.each(network_attrs, function(index, vnet_attr){
|
||||
NicsSection.generate_provision_network_table(
|
||||
$(".provision_nic_accordion", context),
|
||||
{vnet_attr: vnet_attr});
|
||||
});
|
||||
}
|
||||
|
||||
UserInputs.serviceTemplateInsert(
|
||||
$(".provision_network_selector", context),
|
||||
data);
|
||||
} else {
|
||||
$(".provision_network_selector", context).html("")
|
||||
$(".provision_custom_attributes_selector", context).html("")
|
||||
@ -1225,24 +1193,7 @@ define(function(require) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var custom_attrs = {}
|
||||
var missing_network = false;
|
||||
if ($(".provision_nic_accordion", context)) {
|
||||
$(".selected_network", $(".provision_nic_accordion", context)).each(function(){
|
||||
if (!$(this).attr("opennebula_id")) {
|
||||
$(this).css("color", "red");
|
||||
missing_network = true;
|
||||
} else {
|
||||
$(this).css("color", "#777");
|
||||
custom_attrs[$(this).attr("attr_name")] = $(this).attr("opennebula_id");
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (missing_network) {
|
||||
$(".alert-box-error", context).fadeIn().html(Locale.tr("You have not specified all the Networks for this Service"));
|
||||
return false;
|
||||
}
|
||||
var custom_attrs = WizardFields.retrieve($(".provision_network_selector", context));
|
||||
|
||||
var roles = [];
|
||||
|
||||
|
@ -95,7 +95,7 @@
|
||||
<div class="large-6 columns">
|
||||
<div class="provision_disk_selector"></div>
|
||||
</div>
|
||||
<div class="large-6 columns">
|
||||
<div class="small-12 columns">
|
||||
<div class="provision_network_selector"></div>
|
||||
</div>
|
||||
<div class="large-6 columns">
|
||||
|
@ -181,7 +181,10 @@ define(function(require) {
|
||||
}) );
|
||||
|
||||
DisksResize.insert(template_json, $(".disksContext" + template_json.VMTEMPLATE.ID, context));
|
||||
NicsSection.insert(template_json, $(".nicsContext" + template_json.VMTEMPLATE.ID, context));
|
||||
|
||||
NicsSection.insert(template_json,
|
||||
$(".nicsContext" + template_json.VMTEMPLATE.ID, context),
|
||||
{'securityGroups': Config.isFeatureEnabled("secgroups")});
|
||||
|
||||
var inputs_div = $(".template_user_inputs" + template_json.VMTEMPLATE.ID, context);
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
</div>
|
||||
<div class="large-6 small-12 columns disksContext{{element.ID}}"></div>
|
||||
<div class="large-6 small-12 columns template_user_inputs{{element.ID}}"></div>
|
||||
<div class="large-6 small-12 columns nicsContext{{element.ID}}">
|
||||
<div class="small-12 columns nicsContext{{element.ID}}">
|
||||
<div class="provision_network_selector">
|
||||
</div>
|
||||
</div>
|
||||
|
@ -54,16 +54,14 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="medium-6 columns">
|
||||
<div class="row text-center">
|
||||
<div class="row">
|
||||
<div class="large-12 columns">
|
||||
<h3 class="subheader">
|
||||
<small>{{tr "REAL CPU"}}</small>
|
||||
</h3>
|
||||
<span>{{tr "REAL CPU"}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="large-12 columns">
|
||||
<div class="large-12 columns centered graph vm_cpu_graph text-center" style="height: 100px;">
|
||||
<div class="large-12 columns centered graph vm_cpu_graph" style="height: 100px;">
|
||||
<span id="provision_dashboard_total" style="font-size:80px">
|
||||
<i class="fa fa-spinner fa-spin"></i>
|
||||
</span>
|
||||
@ -72,13 +70,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="medium-6 columns">
|
||||
<div class="row text-center">
|
||||
<h3 class="subheader">
|
||||
<small>{{tr "REAL MEMORY"}}</small>
|
||||
</h3>
|
||||
<div class="row">
|
||||
<div class="large-12 columns">
|
||||
<span>{{tr "REAL MEMORY"}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="large-12 columns centered graph vm_memory_graph text-center" style="height: 100px;">
|
||||
<div class="large-12 columns centered graph vm_memory_graph" style="height: 100px;">
|
||||
<span id="provision_dashboard_total" style="font-size:80px">
|
||||
<i class="fa fa-spinner fa-spin"></i>
|
||||
</span>
|
||||
|
@ -137,11 +137,11 @@ define(function(require) {
|
||||
html += '\
|
||||
<div class="row">\
|
||||
<div class="medium-6 columns">\
|
||||
<div class="row text-center">\
|
||||
<h3 class="subheader"><small>' + Locale.tr("NET RX") + '</small></h3>\
|
||||
<div class="row">\
|
||||
<span>' + Locale.tr("NET RX") + '</span3>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns centered graph text-center" id="vm_net_rx_graph" style="height: 100px;">\
|
||||
<div class="large-12 columns centered graph" id="vm_net_rx_graph" style="height: 100px;">\
|
||||
<span id="provision_dashboard_total" style="font-size:80px">\
|
||||
<i class="fa fa-spinner fa-spin"></i>\
|
||||
</span>\
|
||||
@ -153,11 +153,11 @@ define(function(require) {
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="medium-6 columns">\
|
||||
<div class="row text-center">\
|
||||
<h3 class="subheader"><small>' + Locale.tr("NET TX") + '</small></h3>\
|
||||
<div class="row">\
|
||||
<span>' + Locale.tr("NET TX") + '</span3>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns centered graph text-center" id="vm_net_tx_graph" style="height: 100px;">\
|
||||
<div class="large-12 columns centered graph" id="vm_net_tx_graph" style="height: 100px;">\
|
||||
<span id="provision_dashboard_total" style="font-size:80px">\
|
||||
<i class="fa fa-spinner fa-spin"></i>\
|
||||
</span>\
|
||||
@ -169,11 +169,11 @@ define(function(require) {
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="medium-6 columns">\
|
||||
<div class="row text-center">\
|
||||
<h3 class="subheader"><small>' + Locale.tr("NET DOWNLOAD SPEED") + '</small></h3>\
|
||||
<div class="row">\
|
||||
<span>' + Locale.tr("NET DOWNLOAD SPEED") + '</span3>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns centered graph text-center" id="vm_net_rx_speed_graph" style="height: 100px;">\
|
||||
<div class="large-12 columns centered graph" id="vm_net_rx_speed_graph" style="height: 100px;">\
|
||||
<span id="provision_dashboard_total" style="font-size:80px">\
|
||||
<i class="fa fa-spinner fa-spin"></i>\
|
||||
</span>\
|
||||
@ -185,11 +185,11 @@ define(function(require) {
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="medium-6 columns">\
|
||||
<div class="row text-center">\
|
||||
<h3 class="subheader"><small>' + Locale.tr("NET UPLOAD SPEED") + '</small></h3>\
|
||||
<div class="row">\
|
||||
<span>' + Locale.tr("NET UPLOAD SPEED") + '</span3>\
|
||||
</div>\
|
||||
<div class="row">\
|
||||
<div class="large-12 columns centered graph text-center" id="vm_net_tx_speed_graph" style="height: 100px;">\
|
||||
<div class="large-12 columns centered graph" id="vm_net_tx_speed_graph" style="height: 100px;">\
|
||||
<span id="provision_dashboard_total" style="font-size:80px">\
|
||||
<i class="fa fa-spinner fa-spin"></i>\
|
||||
</span>\
|
||||
|
@ -15,7 +15,7 @@
|
||||
{{! -------------------------------------------------------------------------- }}
|
||||
|
||||
<form id="ar_list_form">
|
||||
<div class="row collapse">
|
||||
<div class="row">
|
||||
<div class="large-12 columns">
|
||||
{{#isTabActionEnabled "vnets-tab" "Network.add_ar"}}
|
||||
<button class="button success small radius" id="add_ar_button">
|
||||
@ -36,7 +36,7 @@
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row collapse">
|
||||
<div class="row">
|
||||
<div class="large-12 columns" style="overflow:auto">
|
||||
<table id="ar_list_datatable" class="datatable twelve">
|
||||
<thead>
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
<form id="leases_form">
|
||||
{{#isTabActionEnabled "vnets-tab" "Network.hold_lease"}}
|
||||
<div class="row collapse">
|
||||
<div class="row">
|
||||
<div class="large-4 columns">
|
||||
<input type="text" id="panel_hold_lease"/>
|
||||
</div>
|
||||
@ -27,7 +27,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{{/isTabActionEnabled}}
|
||||
<div class="row collapse">
|
||||
<div class="row">
|
||||
<div class="large-12 columns" style="overflow:auto">
|
||||
<table id="leases_datatable" class="datatable twelve">
|
||||
<thead>
|
||||
|
@ -25,6 +25,7 @@ define(function(require) {
|
||||
var Notifier = require('utils/notifier');
|
||||
var NicsSection = require('utils/nics-section');
|
||||
var WizardFields = require('utils/wizard-fields');
|
||||
var Config = require('sunstone-config');
|
||||
|
||||
/*
|
||||
CONSTANTS
|
||||
@ -68,7 +69,10 @@ define(function(require) {
|
||||
|
||||
NicsSection.insert({},
|
||||
$(".nicsContext", context),
|
||||
{floatingIP: true, forceIPv4:true, management: true,
|
||||
{ floatingIP: true,
|
||||
forceIPv4:true,
|
||||
management: true,
|
||||
securityGroups: Config.isFeatureEnabled("secgroups"),
|
||||
hide_add_button:true,
|
||||
click_add_button:true
|
||||
});
|
||||
|
@ -33,6 +33,7 @@ define(function(require) {
|
||||
var OpenNebulaTemplate = require('opennebula/template');
|
||||
var OpenNebulaAction = require('opennebula/action');
|
||||
var Notifier = require('utils/notifier');
|
||||
var Config = require('sunstone-config');
|
||||
|
||||
/*
|
||||
TEMPLATES
|
||||
@ -108,7 +109,10 @@ define(function(require) {
|
||||
|
||||
NicsSection.insert({},
|
||||
$(".nicsContext", context),
|
||||
{floatingIP: true, forceIPv4:true, management: true});
|
||||
{ floatingIP: true,
|
||||
forceIPv4:true,
|
||||
management: true,
|
||||
securityGroups: Config.isFeatureEnabled("secgroups")});
|
||||
|
||||
this.templatesTable.initialize();
|
||||
|
||||
|
@ -20,15 +20,16 @@ define(function(require) {
|
||||
var Notifier = require('utils/notifier');
|
||||
var OpenNebula = require('opennebula');
|
||||
var OpenNebulaTemplate = require('opennebula/template');
|
||||
var TemplateSection = require('hbs!./nics-section/html');
|
||||
var TemplateDD = require('hbs!./nics-section/dd');
|
||||
var SecurityGroupsTable = require('tabs/secgroups-tab/datatable');
|
||||
var VNetsTable = require('tabs/vnets-tab/datatable');
|
||||
|
||||
var provision_nic_accordion_id = 0;
|
||||
var provision_nic_accordion_dd_id = 0;
|
||||
|
||||
return {
|
||||
'insert': _insert,
|
||||
'retrieve': _retrieve,
|
||||
'generate_provision_network_accordion': _generate_provision_network_accordion,
|
||||
'generate_provision_network_table': _generate_provision_network_table
|
||||
'retrieve': _retrieve
|
||||
}
|
||||
|
||||
/**
|
||||
@ -44,6 +45,7 @@ define(function(require) {
|
||||
* input to select the IPv4
|
||||
* - management {bool}: true to show the
|
||||
* management checkbox
|
||||
* - securityGroups {bool}: true to select SGs
|
||||
*/
|
||||
function _insert(template_json, context, options) {
|
||||
if (options == undefined){
|
||||
@ -80,34 +82,61 @@ define(function(require) {
|
||||
function _retrieve(context) {
|
||||
var nics = [];
|
||||
var nic;
|
||||
$(".selected_network", context).each(function() {
|
||||
if ($(this).attr("template_nic")) {
|
||||
nic = JSON.parse($(this).attr("template_nic"))
|
||||
} else if ($(this).attr("opennebula_id")) {
|
||||
nic = {
|
||||
'network_id': $(this).attr("opennebula_id")
|
||||
}
|
||||
$(".nic-section-entry", context).each(function() {
|
||||
// template_nic is the original NIC definition in an instantiate action.
|
||||
// We try to use it replacing only the settings offered in this
|
||||
// module, to preserve any other potential settings (such as IP6_GLOBAL)
|
||||
|
||||
if ($(this).data("template_nic") != undefined) {
|
||||
nic = $(this).data("template_nic");
|
||||
} else {
|
||||
nic = undefined;
|
||||
nic = {};
|
||||
}
|
||||
|
||||
if (nic) {
|
||||
if ($("input.floating_ip", $(this)).prop("checked")){
|
||||
nic["FLOATING_IP"] = "YES";
|
||||
}
|
||||
var val = $(this).data("vnetsTable").retrieveResourceTableSelect();
|
||||
|
||||
var ip4 = $("input.manual_ip4", $(this)).val();
|
||||
|
||||
if (ip4 != undefined && ip4 != ""){
|
||||
nic["IP"] = ip4;
|
||||
}
|
||||
|
||||
if ($("input.management", $(this)).prop("checked")){
|
||||
nic["VROUTER_MANAGEMENT"] = "YES";
|
||||
}
|
||||
|
||||
nics.push(nic);
|
||||
if (val == undefined || val == ""){
|
||||
if (nic["NETWORK"] == undefined && nic["NETWORK_ID"] == undefined )
|
||||
// No network name or id in original NIC, and no selection done
|
||||
return true; //continue
|
||||
}
|
||||
|
||||
delete nic["NETWORK"];
|
||||
delete nic["NETWORK_ID"];
|
||||
delete nic["NETWORK_UNAME"];
|
||||
|
||||
nic["NETWORK_ID"] = val;
|
||||
|
||||
delete nic["FLOATING_IP"];
|
||||
if ($("input.floating_ip", $(this)).prop("checked")){
|
||||
nic["FLOATING_IP"] = "YES";
|
||||
}
|
||||
|
||||
delete nic["IP"];
|
||||
var ip4 = $("input.manual_ip4", $(this)).val();
|
||||
|
||||
if (ip4 != undefined && ip4 != ""){
|
||||
nic["IP"] = ip4;
|
||||
}
|
||||
|
||||
delete nic["VROUTER_MANAGEMENT"];
|
||||
|
||||
if ($("input.management", $(this)).prop("checked")){
|
||||
nic["VROUTER_MANAGEMENT"] = "YES";
|
||||
}
|
||||
|
||||
var sgTable = $(this).data("sgTable");
|
||||
|
||||
if (sgTable){
|
||||
delete nic["SECURITY_GROUPS"];
|
||||
|
||||
var secgroups = sgTable.retrieveResourceTableSelect();
|
||||
if (secgroups != undefined && secgroups.length != 0) {
|
||||
nic["SECURITY_GROUPS"] = secgroups.join(",");
|
||||
}
|
||||
}
|
||||
|
||||
nics.push(nic);
|
||||
});
|
||||
|
||||
return nics
|
||||
@ -117,13 +146,13 @@ define(function(require) {
|
||||
* @param {object} context JQuery selector
|
||||
* @param {object} options Options
|
||||
* - nic {object}
|
||||
* - vnet_attr {object}
|
||||
* - floatingIP {bool}: true to show the
|
||||
* floating IP checkbox
|
||||
* - forceIPv4 {bool}: true to show the
|
||||
* input to select the IPv4
|
||||
* - management {bool}: true to show the
|
||||
* management checkbox
|
||||
* - securityGroups {bool}: true to select SGs
|
||||
*/
|
||||
function _generate_provision_network_table(context, options) {
|
||||
context.off();
|
||||
@ -133,212 +162,86 @@ define(function(require) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
if (options.nic) {
|
||||
nic_span = '<span class="selected_network" template_nic=\'' + JSON.stringify(options.nic) + '\'>' +
|
||||
'<span>' + Locale.tr("INTERFACE") + " </span>" +
|
||||
'<span>' + (options.nic.NETWORK || options.nic.NETWORK_ID) + "</span>" +
|
||||
'</span>' +
|
||||
'<span class="button right hollow tiny alert provision_remove_nic">' +
|
||||
'<i class="fa fa-times"/>' +
|
||||
'</span>' +
|
||||
'<span class="button right hollow tiny">' +
|
||||
'<i class="fa fa-pencil"/>' +
|
||||
'</span>';
|
||||
} else if (options.vnet_attr) {
|
||||
nic_span = '<span>' + options.vnet_attr.description + "</span><br>" +
|
||||
'<span class="selected_network only-not-active" attr_name=\'' + options.vnet_attr.name + '\'>' +
|
||||
'<span>' + Locale.tr("INTERFACE") + " </span>" +
|
||||
'<span class="label secondary">' + Locale.tr("Select a Network") + "</span>" +
|
||||
'</span>' +
|
||||
'<span class="only-active">' +
|
||||
Locale.tr("Select a Network for this interface") +
|
||||
'</span>' +
|
||||
'<span class="button right hollow tiny only-not-active">' +
|
||||
'<i class="fa fa-pencil"/>' +
|
||||
'</span>';
|
||||
} else {
|
||||
nic_span =
|
||||
'<span class="selected_network only-not-active">' +
|
||||
'<span>' + Locale.tr("INTERFACE") + " </span>" +
|
||||
'<span class="label secondary">' + Locale.tr("Select a Network") + "</span>" +
|
||||
'</span>' +
|
||||
'<span class="only-active">' +
|
||||
Locale.tr("Select a Network for this interface") +
|
||||
'</span>' +
|
||||
'<span class="button right hollow tiny alert provision_remove_nic">' +
|
||||
'<i class="fa fa-times"/>' +
|
||||
'</span>' +
|
||||
'<span class="button right hollow tiny only-not-active">' +
|
||||
'<i class="fa fa-pencil"/>' +
|
||||
'</span>';
|
||||
var vnetsTable = new VNetsTable(
|
||||
'vnet_nics_section_'+provision_nic_accordion_dd_id,
|
||||
{ 'select': true });
|
||||
|
||||
var sgTable;
|
||||
var sgHtml = "";
|
||||
|
||||
if (options.securityGroups == true){
|
||||
sgTable = new SecurityGroupsTable(
|
||||
'sg_nics_section_'+provision_nic_accordion_dd_id,
|
||||
{ 'select': true,
|
||||
'selectOptions': { 'multiple_choice': true }
|
||||
});
|
||||
|
||||
sgHtml = sgTable.dataTableHTML;
|
||||
}
|
||||
|
||||
var dd_context = $('<dd class="accordion-item" data-accordion-item>' +
|
||||
'<a href="#provision_accordion_dd_' + provision_nic_accordion_dd_id + '" class="accordion-title">' +
|
||||
nic_span +
|
||||
'</a>' +
|
||||
'<div id="provision_accordion_dd_' + provision_nic_accordion_dd_id + '" class="accordion-content" data-tab-content>' +
|
||||
'<div class="row">' +
|
||||
'<div class="large-12 large-centered columns">' +
|
||||
'<h3 class="subheader">' +
|
||||
'<input type="search" class="provision-search-input" placeholder="Search"/>' +
|
||||
'</h3>' +
|
||||
'<br>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="row">' +
|
||||
'<div class="large-12 large-centered columns">' +
|
||||
'<table class="provision_networks_table">' +
|
||||
'<thead hidden>' +
|
||||
'<tr>' +
|
||||
'<th>' + Locale.tr("ID") + '</th>' +
|
||||
'<th>' + Locale.tr("Name") + '</th>' +
|
||||
'</tr>' +
|
||||
'</thead>' +
|
||||
'<tbody hidden>' +
|
||||
'</tbody>' +
|
||||
'</table>' +
|
||||
'<br>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</dd>').appendTo(context);
|
||||
var dd_context = $(TemplateDD({
|
||||
vnetsTableHTML: vnetsTable.dataTableHTML,
|
||||
securityGroupsTableHTML: sgHtml,
|
||||
provision_nic_accordion_dd_id: provision_nic_accordion_dd_id,
|
||||
options: options
|
||||
})).appendTo(context);
|
||||
|
||||
$(".nic-section-entry", dd_context).data("template_nic", options.nic);
|
||||
$(".nic-section-entry", dd_context).data("vnetsTable", vnetsTable);
|
||||
$(".nic-section-entry", dd_context).data("sgTable", sgTable);
|
||||
|
||||
Tips.setup(dd_context);
|
||||
Foundation.reInit(context);
|
||||
|
||||
provision_nic_accordion_dd_id += 1;
|
||||
|
||||
var provision_networks_datatable = $('.provision_networks_table', dd_context).dataTable({
|
||||
"iDisplayLength": 6,
|
||||
"sDom" : '<"H">t<"F"lp>',
|
||||
"aLengthMenu": [[6, 12, 36, 72], [6, 12, 36, 72]],
|
||||
"aoColumnDefs": [
|
||||
{"bVisible": false, "aTargets": ["all"]}
|
||||
],
|
||||
"aoColumns": [
|
||||
{"mDataProp": "VNET.ID"},
|
||||
{"mDataProp": "VNET.NAME"}
|
||||
],
|
||||
"fnPreDrawCallback": function (oSettings) {
|
||||
// create a thumbs container if it doesn't exist. put it in the dataTables_scrollbody div
|
||||
if (this.$('tr', {"filter": "applied"}).length == 0) {
|
||||
this.html('<div class="text-center">' +
|
||||
'<span class="fa-stack fa-5x">' +
|
||||
'<i class="fa fa-cloud fa-stack-2x"></i>' +
|
||||
'<i class="fa fa-info-circle fa-stack-1x fa-inverse"></i>' +
|
||||
'</span>' +
|
||||
'<br>' +
|
||||
'<br>' +
|
||||
'<span>' +
|
||||
Locale.tr("There are no networks available. Please contact your cloud administrator") +
|
||||
'</span>' +
|
||||
'</div>');
|
||||
} else {
|
||||
$(".provision_networks_table", dd_context).html(
|
||||
'<div class="provision_networks_ul large-up-3 medium-up-3 small-up-1 text-center">' +
|
||||
'</div>');
|
||||
}
|
||||
vnetsTable.initialize();
|
||||
vnetsTable.refreshResourceTableSelect();
|
||||
|
||||
return true;
|
||||
},
|
||||
"fnRowCallback": function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
|
||||
var data = aData.VNET;
|
||||
$(".provision_networks_ul", dd_context).append(
|
||||
'<div class="column">' +
|
||||
'<ul class="provision-pricing-table hoverable more-than-one menu vertical" opennebula_id="' + data.ID + '" opennebula_name="' + data.NAME + '">' +
|
||||
'<li class="provision-title" title="' + data.NAME + '">' +
|
||||
data.NAME +
|
||||
'</li>' +
|
||||
'<li class="provision-bullet-item">' +
|
||||
'<i class="fa fa-fw fa-globe"/>' +
|
||||
'</li>' +
|
||||
'<li class="provision-description">' +
|
||||
(data.TEMPLATE.DESCRIPTION || '...') +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'</div>');
|
||||
if (options.securityGroups == true){
|
||||
sgTable.initialize();
|
||||
sgTable.refreshResourceTableSelect();
|
||||
}
|
||||
|
||||
return nRow;
|
||||
if (options.nic != undefined){
|
||||
var selectedResources;
|
||||
|
||||
if (options.nic.NETWORK_ID != undefined) {
|
||||
selectedResources = {
|
||||
ids : templateJSON.NETWORK_ID
|
||||
}
|
||||
} else if (options.nic.NETWORK != undefined && options.nic.NETWORK_UNAME != undefined) {
|
||||
selectedResources = {
|
||||
names : {
|
||||
name: options.nic.NETWORK,
|
||||
uname: options.nic.NETWORK_UNAME
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedResources != undefined){
|
||||
vnetsTable.selectResourceTableSelect(selectedResources);
|
||||
|
||||
vnetsTable.idInput().data("prev", vnetsTable.idInput().val());
|
||||
}
|
||||
|
||||
if (options.securityGroups == true && options.nic.SECURITY_GROUPS != undefined){
|
||||
sgTable.selectResourceTableSelect({ids: options.nic.SECURITY_GROUPS.split(',')});
|
||||
}
|
||||
}
|
||||
|
||||
vnetsTable.idInput().on("change", function(){
|
||||
$(".selected_network", dd_context).text(OpenNebula.Network.getName($(this).val()));
|
||||
});
|
||||
|
||||
$('.provision-search-input', dd_context).on('input', function() {
|
||||
provision_networks_datatable.fnFilter($(this).val());
|
||||
})
|
||||
|
||||
dd_context.on("click", ".provision-pricing-table.more-than-one" , function() {
|
||||
var html =
|
||||
'<span>' + Locale.tr("INTERFACE") + " </span>" +
|
||||
'<span>' + $(this).attr("opennebula_name") + "</span>";
|
||||
|
||||
if (options.floatingIP){
|
||||
html +=
|
||||
'<div class="row noclick">' +
|
||||
'<div class="small-12 columns">' +
|
||||
'<label class="inline">' +
|
||||
'<input type="checkbox" class="floating_ip" />' +
|
||||
Locale.tr("Floating IP") + " " +
|
||||
'<span class="tip">' +
|
||||
Locale.tr("If checked, each Virtual Machine will have a floating IP added to its network interface.") +
|
||||
'</span>' +
|
||||
'</label>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
if (options.forceIPv4){
|
||||
html +=
|
||||
'<div class="row noclick">' +
|
||||
'<div class="small-5 columns">' +
|
||||
'<label class="right inline">' +
|
||||
Locale.tr("Force IPv4:") + " " +
|
||||
'<span class="tip">' +
|
||||
Locale.tr("Optionally, you can force the IP assigned to the network interface.") +
|
||||
'</span>' +
|
||||
'</label>' +
|
||||
'</div>' +
|
||||
'<div class="small-7 columns">' +
|
||||
'<input type="text" class="manual_ip4" />' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
if (options.management){
|
||||
html +=
|
||||
'<div class="noclick">' +
|
||||
'<label>' +
|
||||
'<input type="checkbox" class="management" />' +
|
||||
Locale.tr("Management Interface") + " " +
|
||||
'<span class="tip">' +
|
||||
Locale.tr("If checked, this network interface will be a Virtual Router management interface. Traffic will not be forwarded.") +
|
||||
'</span>' +
|
||||
'</label>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
$(".selected_network", dd_context).html(html);
|
||||
$(".selected_network", dd_context).attr("opennebula_id", $(this).attr("opennebula_id"))
|
||||
$(".selected_network", dd_context).removeAttr("template_nic")
|
||||
|
||||
Tips.setup($(".selected_network", dd_context));
|
||||
|
||||
$('a', dd_context).first().trigger("click");
|
||||
})
|
||||
|
||||
dd_context.on("click", ".provision_remove_nic" , function() {
|
||||
dd_context.remove();
|
||||
return false;
|
||||
});
|
||||
|
||||
dd_context.on("click", ".noclick" , function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
if (!options.nic && !options.vnet_attr) {
|
||||
if (!options.nic) {
|
||||
$('a', dd_context).trigger("click");
|
||||
}
|
||||
|
||||
update_provision_networks_datatable(provision_networks_datatable);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -352,28 +255,18 @@ define(function(require) {
|
||||
* input to select the IPv4
|
||||
* - management {bool}: true to show the
|
||||
* management checkbox
|
||||
* - securityGroups {bool}: true to select SGs
|
||||
*/
|
||||
function _generate_provision_network_accordion(context, options) {
|
||||
context.off();
|
||||
context.html(
|
||||
'<fieldset>' +
|
||||
'<legend>' +
|
||||
'<i class="fa fa-globe"></i> ' +
|
||||
Locale.tr("Network") +
|
||||
'</legend>' +
|
||||
'<div>' +
|
||||
'<dl class="accordion provision_nic_accordion" data-accordion data-allow-all-closed="true">' +
|
||||
'</dl>' +
|
||||
'<a class="button small provision_add_network_interface"' + (options.hide_add_button ? 'hidden' : '') + '>' +
|
||||
Locale.tr("Add another Network Interface") +
|
||||
'</a>' +
|
||||
'</div>' +
|
||||
'</fieldset>')
|
||||
context.html(TemplateSection());
|
||||
|
||||
if (options.hide_add_button == true){
|
||||
$(".provision_add_network_interface", context).hide();
|
||||
}
|
||||
|
||||
Foundation.reflow(context, 'accordion');
|
||||
|
||||
provision_nic_accordion_id += 1;
|
||||
|
||||
$(".provision_add_network_interface", context).on("click", function() {
|
||||
_generate_provision_network_table($(".accordion", context), options);
|
||||
});
|
||||
@ -381,8 +274,6 @@ define(function(require) {
|
||||
if (options.click_add_button == true){
|
||||
$(".provision_add_network_interface", context).click();
|
||||
}
|
||||
|
||||
//TODO $(document).foundation();
|
||||
}
|
||||
|
||||
function update_provision_networks_datatable(datatable) {
|
||||
|
76
src/sunstone/public/app/utils/nics-section/dd.hbs
Normal file
76
src/sunstone/public/app/utils/nics-section/dd.hbs
Normal file
@ -0,0 +1,76 @@
|
||||
<dd class="accordion-item" data-accordion-item>
|
||||
<a href="#provision_accordion_dd_{{provision_nic_accordion_dd_id}}" class="accordion-title">
|
||||
<i class="only-not-active fa fa-angle-double-down"/>
|
||||
<i class="only-active fa fa-angle-double-up"/>
|
||||
{{tr "Interface"}}
|
||||
<span class="selected_network">
|
||||
{{#if options.nic}}
|
||||
{{#if options.nic.NETWORK}}
|
||||
{{options.nic.NETWORK}}
|
||||
{{else}}
|
||||
{{options.nic.NETWORK_ID}}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<span class="label secondary">{{tr "Select a Network"}} </span>
|
||||
{{/if}}
|
||||
</span>
|
||||
<i class="right fa fa-times-circle remove-tab provision_remove_nic"></i>
|
||||
</a>
|
||||
<div id="provision_accordion_dd_{{provision_nic_accordion_dd_id}}" class="accordion-content nic-section-entry" data-tab-content>
|
||||
<div class="row collapse">
|
||||
{{{vnetsTableHTML}}}
|
||||
</div>
|
||||
{{#if options.forceIPv4}}
|
||||
<div class="row">
|
||||
<div class="small-5 columns">
|
||||
<label class="right inline">
|
||||
{{tr "Force IPv4:"}}
|
||||
<span class="tip">
|
||||
{{tr "Optionally, you can force the IP assigned to the network interface."}}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="small-7 columns">
|
||||
<input type="text" class="manual_ip4" />
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if options.floatingIP}}
|
||||
<div class="row">
|
||||
<div class="small-12 columns">
|
||||
<label class="inline">
|
||||
<input type="checkbox" class="floating_ip" />
|
||||
{{tr "Floating IP"}}
|
||||
<span class="tip">
|
||||
{{tr "If checked, each Virtual Machine will have a floating IP added to its network interface."}}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if options.management}}
|
||||
<div class="row">
|
||||
<div class="small-12 columns">
|
||||
<label>
|
||||
<input type="checkbox" class="management" />
|
||||
{{tr "Management Interface"}}
|
||||
<span class="tip">
|
||||
{{tr "If checked, this network interface will be a Virtual Router management interface. Traffic will not be forwarded."}}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if options.securityGroups}}
|
||||
<div class="row collapse">
|
||||
<h6>
|
||||
{{tr "Security Groups"}}
|
||||
<span class="tip">
|
||||
{{tr "You can add Security Groups to this network interface. These IDs do not overwrite the ones defined in the Virtual Network. All the Security Group IDs are combined, and applied to the Virtual Machine instance."}}
|
||||
</span>
|
||||
</h6>
|
||||
{{{securityGroupsTableHTML}}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</dd>
|
12
src/sunstone/public/app/utils/nics-section/html.hbs
Normal file
12
src/sunstone/public/app/utils/nics-section/html.hbs
Normal file
@ -0,0 +1,12 @@
|
||||
<fieldset>
|
||||
<legend>
|
||||
<i class="fa fa-globe"></i> {{tr "Network"}}
|
||||
</legend>
|
||||
<div>
|
||||
<dl class="accordion provision_nic_accordion" data-accordion data-allow-all-closed="true">
|
||||
</dl>
|
||||
<a class="button small provision_add_network_interface">
|
||||
{{tr "Add another Network Interface"}}
|
||||
</a>
|
||||
</div>
|
||||
</fieldset>
|
@ -43,7 +43,7 @@ define(function(require) {
|
||||
fromJSONtoHTMLTable(templateJSON, resourceType) +
|
||||
'<tr>\
|
||||
<td class="key_td"><input type="text" name="new_key" id="new_key" /></td>\
|
||||
<td class="value_td"><textarea rows="1" type="text" name="new_value" id="new_value"></textarea></td>\
|
||||
<td class="value_td"><textarea type="text" name="new_value" id="new_value"></textarea></td>\
|
||||
<td class="text-right"><button type="button" id="button_add_value" class="button small secondary">' + Locale.tr("Add") + '</button>\</td>\
|
||||
</tr>' +
|
||||
'</table>'
|
||||
|
@ -501,7 +501,7 @@ define(function(require) {
|
||||
});
|
||||
}
|
||||
|
||||
if (that.labelsColumn) {
|
||||
if (that.labelsColumn && !SunstoneConfig.isTabEnabled("provision-tab")) {
|
||||
LabelsUtils.insertLabelsMenu({'tabName': that.tabId});
|
||||
LabelsUtils.insertLabelsDropdown(that.tabId);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
.right-content {
|
||||
.tab:not(#provision-tab) {
|
||||
margin-top: -2rem;
|
||||
}
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
.logo-header {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.provision-logo {
|
||||
|
@ -1,8 +1,20 @@
|
||||
table {
|
||||
input {
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
textarea {
|
||||
margin-bottom: 0px !important;
|
||||
}
|
||||
|
||||
textarea {
|
||||
height: $input-font-size + ($form-spacing * 1.5) - rem-calc(1);
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
select {
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
thead {
|
||||
border: 0;
|
||||
|
||||
|
@ -62,4 +62,10 @@
|
||||
& > .tabs-panel {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.wizard_tabs {
|
||||
a {
|
||||
padding: 0.5rem 1.5rem;
|
||||
}
|
||||
}
|
@ -1133,58 +1133,30 @@ int VirtualMachine::parse_pci(string& error_str)
|
||||
|
||||
int VirtualMachine::parse_graphics(string& error_str)
|
||||
{
|
||||
vector<Attribute *> array_graphics;
|
||||
VectorAttribute * graphics;
|
||||
VectorAttribute * user_graphics = user_obj_template->get("GRAPHICS");
|
||||
|
||||
vector<Attribute *>::iterator it;
|
||||
|
||||
int num = user_obj_template->remove("GRAPHICS", array_graphics);
|
||||
|
||||
for (it=array_graphics.begin(); it != array_graphics.end(); it++)
|
||||
{
|
||||
obj_template->set(*it);
|
||||
}
|
||||
|
||||
if ( num == 0 )
|
||||
if ( user_graphics == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
graphics = dynamic_cast<VectorAttribute * >(array_graphics[0]);
|
||||
VectorAttribute * graphics = new VectorAttribute(user_graphics);
|
||||
|
||||
if ( graphics == 0 )
|
||||
user_obj_template->erase("GRAPHICS");
|
||||
|
||||
obj_template->set(graphics);
|
||||
|
||||
if ( !graphics->vector_value("PORT").empty() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
unsigned int port;
|
||||
|
||||
string port = graphics->vector_value("PORT");
|
||||
int port_i;
|
||||
int rc = graphics->vector_value("PORT", port);
|
||||
|
||||
int rc = graphics->vector_value("PORT", port_i);
|
||||
|
||||
if ( port.empty() )
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
|
||||
ostringstream oss;
|
||||
istringstream iss;
|
||||
|
||||
int base_port;
|
||||
string base_port_s;
|
||||
|
||||
int limit = 65535;
|
||||
|
||||
nd.get_configuration_attribute("VNC_BASE_PORT",base_port_s);
|
||||
iss.str(base_port_s);
|
||||
iss >> base_port;
|
||||
|
||||
oss << ( base_port + ( oid % (limit - base_port) ));
|
||||
graphics->replace("PORT", oss.str());
|
||||
}
|
||||
else if ( rc == -1 || port_i < 0 )
|
||||
{
|
||||
error_str = "Wrong PORT number in GRAPHICS attribute";
|
||||
return -1;
|
||||
if (rc == -1 || port > 65535 )
|
||||
{
|
||||
error_str = "Wrong PORT number in GRAPHICS attribute";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
string random_passwd = graphics->vector_value("RANDOM_PASSWD");
|
||||
@ -3588,36 +3560,6 @@ void VirtualMachine::disk_extended_info(int uid,
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
bool VirtualMachine::volatile_disk_extended_info(Template *tmpl)
|
||||
{
|
||||
int num;
|
||||
vector<VectorAttribute * > disks;
|
||||
DatastorePool * ds_pool = Nebula::instance().get_dspool();
|
||||
|
||||
bool found = false;
|
||||
|
||||
num = tmpl->get("DISK", disks);
|
||||
|
||||
for(int i=0; i<num; i++)
|
||||
{
|
||||
if ( !is_volatile(disks[i]) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
found = true;
|
||||
|
||||
if (hasHistory())
|
||||
{
|
||||
ds_pool->disk_attribute(get_ds_id(), disks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -25,13 +25,6 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
time_t VirtualMachinePool::_monitor_expiration;
|
||||
bool VirtualMachinePool::_submit_on_hold;
|
||||
float VirtualMachinePool::_default_cpu_cost;
|
||||
float VirtualMachinePool::_default_mem_cost;
|
||||
float VirtualMachinePool::_default_disk_cost;
|
||||
|
||||
|
||||
const char * VirtualMachinePool::import_table = "vm_import";
|
||||
|
||||
const char * VirtualMachinePool::import_db_names = "deploy_id, vmid";
|
||||
@ -40,7 +33,6 @@ const char * VirtualMachinePool::import_db_bootstrap =
|
||||
"CREATE TABLE IF NOT EXISTS vm_import "
|
||||
"(deploy_id VARCHAR(128), vmid INTEGER, PRIMARY KEY(deploy_id))";
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@ -55,7 +47,10 @@ VirtualMachinePool::VirtualMachinePool(
|
||||
float default_cpu_cost,
|
||||
float default_mem_cost,
|
||||
float default_disk_cost)
|
||||
: PoolSQL(db, VirtualMachine::table, true, false)
|
||||
: PoolSQL(db, VirtualMachine::table, true, false),
|
||||
_monitor_expiration(expire_time), _submit_on_hold(on_hold),
|
||||
_default_cpu_cost(default_cpu_cost), _default_mem_cost(default_mem_cost),
|
||||
_default_disk_cost(default_disk_cost)
|
||||
{
|
||||
|
||||
string name;
|
||||
@ -64,12 +59,6 @@ VirtualMachinePool::VirtualMachinePool(
|
||||
string arg;
|
||||
bool remote;
|
||||
|
||||
_monitor_expiration = expire_time;
|
||||
_submit_on_hold = on_hold;
|
||||
_default_cpu_cost = default_cpu_cost;
|
||||
_default_mem_cost = default_mem_cost;
|
||||
_default_disk_cost= default_disk_cost;
|
||||
|
||||
if ( _monitor_expiration == 0 )
|
||||
{
|
||||
clean_all_monitoring();
|
||||
|
@ -36,6 +36,7 @@ ENV['LANG'] = 'C'
|
||||
$: << LIB_LOCATION+'/ruby/vendors/rbvmomi/lib'
|
||||
$: << LIB_LOCATION+'/ruby'
|
||||
|
||||
require 'ostruct'
|
||||
require 'rbvmomi'
|
||||
require 'yaml'
|
||||
require 'opennebula'
|
||||
@ -135,6 +136,22 @@ class VIClient
|
||||
return entities
|
||||
end
|
||||
|
||||
# Only retrieve properties with faster search
|
||||
def get_entities_to_import(folder, type)
|
||||
res = folder.inventory_flat(type => :all)
|
||||
objects = []
|
||||
|
||||
res.each {|k,v|
|
||||
if k.to_s.split('(').first == type
|
||||
obj = {}
|
||||
v.propSet.each{ |dynprop|
|
||||
obj[dynprop.name] = dynprop.val
|
||||
}
|
||||
objects << OpenStruct.new(obj)
|
||||
end
|
||||
}
|
||||
return objects
|
||||
end
|
||||
|
||||
############################################################################
|
||||
# Initializr the VIClient, and creates an OpenNebula client. The parameters
|
||||
@ -368,11 +385,13 @@ class VIClient
|
||||
datacenters = get_entities(@root, 'Datacenter')
|
||||
|
||||
datacenters.each { |dc|
|
||||
vms = get_entities(dc.vmFolder, 'VirtualMachine')
|
||||
vms = get_entities_to_import(dc.vmFolder, 'VirtualMachine')
|
||||
|
||||
tmp = vms.select { |v| v.config && (v.config.template == true) }
|
||||
|
||||
one_tmp = []
|
||||
one_tmp = []
|
||||
host_cache = {}
|
||||
ds_cache = {}
|
||||
|
||||
tmp.each { |t|
|
||||
vi_tmp = VCenterVm.new(self, t)
|
||||
@ -380,15 +399,28 @@ class VIClient
|
||||
if !tpool["VMTEMPLATE/TEMPLATE/PUBLIC_CLOUD[\
|
||||
TYPE=\"vcenter\" \
|
||||
and VM_TEMPLATE=\"#{vi_tmp.vm.config.uuid}\"]"]
|
||||
hostname = vi_tmp.vm.runtime.host.parent.name
|
||||
# Check cached objects
|
||||
if !host_cache[vi_tmp.vm.runtime.host.to_s]
|
||||
host_cache[vi_tmp.vm.runtime.host.to_s] =
|
||||
VCenterCachedHost.new vi_tmp.vm.runtime.host
|
||||
end
|
||||
|
||||
if !ds_cache[t.datastore[0].to_s]
|
||||
ds_cache[t.datastore[0].to_s] =
|
||||
VCenterCachedDatastore.new t.datastore[0]
|
||||
end
|
||||
|
||||
host = host_cache[vi_tmp.vm.runtime.host.to_s]
|
||||
ds = ds_cache[t.datastore[0].to_s]
|
||||
|
||||
one_tmp << {
|
||||
:name => "#{vi_tmp.vm.name} - #{hostname}",
|
||||
:name => "#{vi_tmp.vm.name} - #{host.cluster_name}",
|
||||
:uuid => vi_tmp.vm.config.uuid,
|
||||
:host => hostname,
|
||||
:one => vi_tmp.to_one,
|
||||
:ds => vi_tmp.to_one_ds,
|
||||
:default_ds => t.datastore[0].name,
|
||||
:rp => vi_tmp.to_one_rp
|
||||
:host => host.cluster_name,
|
||||
:one => vi_tmp.to_one(host),
|
||||
:ds => vi_tmp.to_one_ds(host, ds.name),
|
||||
:default_ds => ds.name,
|
||||
:rp => vi_tmp.to_one_rp(host)
|
||||
}
|
||||
end
|
||||
}
|
||||
@ -889,6 +921,95 @@ class VIClient
|
||||
end
|
||||
end
|
||||
|
||||
###########
|
||||
# Cached Classes to speed up import and monitorization
|
||||
############
|
||||
class VCenterCachedHost
|
||||
|
||||
def initialize(rbVmomiHost)
|
||||
@host = rbVmomiHost
|
||||
@attributes = Hash.new
|
||||
end
|
||||
|
||||
def name
|
||||
if !@attributes['name']
|
||||
@attributes['name']=@host.parent.name
|
||||
end
|
||||
@attributes['name']
|
||||
end
|
||||
|
||||
def cluster_name
|
||||
if !@attributes['cluster_name']
|
||||
@attributes['cluster_name']=@host.parent.name
|
||||
end
|
||||
@attributes['cluster_name']
|
||||
end
|
||||
|
||||
def ds_list
|
||||
if !@attributes['ds_list']
|
||||
@attributes['ds_list']=""
|
||||
@host.parent.parent.parent.datastoreFolder.childEntity.each { |ds|
|
||||
@attributes['ds_list'] += ds.name + ","
|
||||
}
|
||||
@attributes['ds_list']=@attributes['ds_list'][0..-2]
|
||||
end
|
||||
@attributes['ds_list']
|
||||
end
|
||||
|
||||
def rp_list
|
||||
if !@attributes['rp_list']
|
||||
@attributes['rp_list']=""
|
||||
@host.parent.resourcePool.resourcePool.each{|rp|
|
||||
@attributes['rp_list'] += get_child_rp_names(rp, "")
|
||||
}
|
||||
@attributes['rp_list']=@attributes['rp_list'][0..-2]
|
||||
end
|
||||
@attributes['rp_list']
|
||||
end
|
||||
|
||||
def get_child_rp_names(rp, parent_prefix)
|
||||
rp_str = ""
|
||||
|
||||
current_rp = (parent_prefix.empty? ? "" : parent_prefix + "/")
|
||||
current_rp += rp.name
|
||||
|
||||
if rp.resourcePool.size != 0
|
||||
rp.resourcePool.each{|child_rp|
|
||||
rp_str += get_child_rp_names(child_rp, current_rp)
|
||||
}
|
||||
end
|
||||
|
||||
rp_str += current_rp + ","
|
||||
|
||||
return rp_str
|
||||
end
|
||||
|
||||
def cpumhz
|
||||
if !@attributes['cpumhz']
|
||||
@attributes['cpumhz']=@host.summary.hardware.cpuMhz.to_f
|
||||
end
|
||||
@attributes['cpumhz']
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class VCenterCachedDatastore
|
||||
|
||||
def initialize(rbVmomiDatastore)
|
||||
@ds = rbVmomiDatastore
|
||||
@attributes = Hash.new
|
||||
end
|
||||
|
||||
def name
|
||||
if !@attributes['name']
|
||||
@attributes['name']=@ds.name
|
||||
end
|
||||
@attributes['name']
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
################################################################################
|
||||
# This class is an OpenNebula hosts that abstracts a vCenter cluster. It
|
||||
# includes the functionality needed to monitor the cluster and report the ESX
|
||||
@ -1115,8 +1236,18 @@ class VCenterHost < ::OpenNebula::Host
|
||||
}
|
||||
end
|
||||
|
||||
host_cache = {}
|
||||
|
||||
rp.vm.each { |v|
|
||||
begin
|
||||
# Check cached objects
|
||||
if !host_cache[v.runtime.host.to_s]
|
||||
host_cache[v.runtime.host.to_s] =
|
||||
VCenterCachedHost.new v.runtime.host
|
||||
end
|
||||
|
||||
host = host_cache[v.runtime.host.to_s]
|
||||
|
||||
name = v.name
|
||||
number = -1
|
||||
# Extract vmid if possible
|
||||
@ -1128,16 +1259,16 @@ class VCenterHost < ::OpenNebula::Host
|
||||
number = extraconfig_vmid[0][:value]
|
||||
end
|
||||
vm = VCenterVm.new(@client, v)
|
||||
vm.monitor
|
||||
vm.monitor(host)
|
||||
next if !vm.vm.config
|
||||
str_info << "\nVM = ["
|
||||
str_info << "ID=#{number},"
|
||||
str_info << "DEPLOY_ID=\"#{vm.vm.config.uuid}\","
|
||||
str_info << "VM_NAME=\"#{name} - "\
|
||||
"#{v.runtime.host.parent.name}\","
|
||||
"#{host.cluster_name}\","
|
||||
if number == -1
|
||||
vm_template_to_one =
|
||||
Base64.encode64(vm.vm_to_one).gsub("\n","")
|
||||
Base64.encode64(vm.vm_to_one(host)).gsub("\n","")
|
||||
str_info << "IMPORT_TEMPLATE=\"#{vm_template_to_one}\","
|
||||
end
|
||||
str_info << "POLL=\"#{vm.info}\"]"
|
||||
@ -1353,7 +1484,6 @@ class VCenterVm
|
||||
else
|
||||
detach_attached_disks(vm, disks, hostname)
|
||||
end
|
||||
exit -1
|
||||
vm.Destroy_Task.wait_for_completion
|
||||
when "SHUTDOWN_POWEROFF", "SHUTDOWN_UNDEPLOY"
|
||||
begin
|
||||
@ -1533,7 +1663,7 @@ class VCenterVm
|
||||
########################################################################
|
||||
# Initialize the vm monitor information
|
||||
########################################################################
|
||||
def monitor
|
||||
def monitor(host)
|
||||
@summary = @vm.summary
|
||||
@state = state_to_c(@summary.runtime.powerState)
|
||||
|
||||
@ -1548,9 +1678,7 @@ class VCenterVm
|
||||
end
|
||||
|
||||
@used_memory = @summary.quickStats.hostMemoryUsage * 1024
|
||||
|
||||
host = @vm.runtime.host
|
||||
cpuMhz = host.summary.hardware.cpuMhz.to_f
|
||||
cpuMhz = host.cpumhz
|
||||
|
||||
@used_cpu =
|
||||
((@summary.quickStats.overallCpuUsage.to_f / cpuMhz) * 100).to_s
|
||||
@ -1560,7 +1688,7 @@ class VCenterVm
|
||||
@used_memory = 0 if @used_memory.to_i < 0
|
||||
@used_cpu = 0 if @used_cpu.to_i < 0
|
||||
|
||||
@esx_host = @vm.summary.runtime.host.name
|
||||
@esx_host = host.name
|
||||
@guest_ip = @vm.guest.ipAddress
|
||||
@guest_state = @vm.guest.guestState
|
||||
@vmware_tools = @vm.guest.toolsRunningStatus
|
||||
@ -1607,8 +1735,8 @@ class VCenterVm
|
||||
########################################################################
|
||||
# Generates an OpenNebula Template for this VCenterVm
|
||||
########################################################################
|
||||
def to_one
|
||||
cluster_name = @vm.runtime.host.parent.name
|
||||
def to_one(host)
|
||||
cluster_name = host.cluster_name
|
||||
|
||||
str = "NAME = \"#{@vm.name} - #{cluster_name}\"\n"\
|
||||
"CPU = \"#{@vm.config.hardware.numCPU}\"\n"\
|
||||
@ -1656,17 +1784,13 @@ class VCenterVm
|
||||
########################################################################
|
||||
# Generates a Datastore user input
|
||||
########################################################################
|
||||
def to_one_ds
|
||||
def to_one_ds(host, default_ds)
|
||||
# Datastores User Input
|
||||
ds_str = ""
|
||||
@vm.runtime.host.parent.parent.parent.datastoreFolder.childEntity.each { |ds|
|
||||
ds_str += ds.name + ","
|
||||
}
|
||||
ds_str = ds_str[0..-2]
|
||||
str = ""
|
||||
|
||||
if ds_str != ""
|
||||
if host.ds_list != ""
|
||||
str = "M|list|Which datastore you want this VM to run on?|"\
|
||||
<< "#{ds_str}|#{ds_str.split(",")[0]}"
|
||||
<< "#{host.ds_list}|#{default_ds}"
|
||||
end
|
||||
|
||||
return str
|
||||
@ -1675,34 +1799,16 @@ class VCenterVm
|
||||
########################################################################
|
||||
# Generates a Resource Pool user input
|
||||
########################################################################
|
||||
def to_one_rp
|
||||
rp_str = ""
|
||||
def to_one_rp(host)
|
||||
# Resource Pool User Input
|
||||
str = ""
|
||||
|
||||
@vm.runtime.host.parent.resourcePool.resourcePool.each{|rp|
|
||||
rp_str += get_child_rp_names(rp, "")
|
||||
}
|
||||
|
||||
rp_str = rp_str[0..-2]
|
||||
|
||||
return "M|list|Which resource pool you want this VM to run"\
|
||||
" in?|#{rp_str}|#{rp_str.split(",")[0]}"
|
||||
end
|
||||
|
||||
def get_child_rp_names(rp, parent_prefix)
|
||||
rp_str = ""
|
||||
|
||||
current_rp = (parent_prefix.empty? ? "" : parent_prefix + "/")
|
||||
current_rp += rp.name
|
||||
|
||||
if rp.resourcePool.size != 0
|
||||
rp.resourcePool.each{|child_rp|
|
||||
rp_str += get_child_rp_names(child_rp, current_rp)
|
||||
}
|
||||
if host.rp_list != ""
|
||||
str = "M|list|Which resource pool you want this VM to run"\
|
||||
" in?|#{host.rp_list}|#{host.rp_list.split(",")[0]}"
|
||||
end
|
||||
|
||||
rp_str += current_rp + ","
|
||||
|
||||
return rp_str
|
||||
return str
|
||||
end
|
||||
|
||||
########################################################################
|
||||
@ -1710,8 +1816,8 @@ class VCenterVm
|
||||
#
|
||||
#
|
||||
########################################################################
|
||||
def vm_to_one
|
||||
host_name = @vm.runtime.host.parent.name
|
||||
def vm_to_one(host)
|
||||
cluster_name = host.cluster_name
|
||||
|
||||
state = case state_to_c(@summary.runtime.powerState)
|
||||
when 'a'
|
||||
@ -1720,7 +1826,7 @@ class VCenterVm
|
||||
"POWEROFF"
|
||||
end
|
||||
|
||||
str = "NAME = \"#{@vm.name} - #{host_name}\"\n"\
|
||||
str = "NAME = \"#{@vm.name} - #{cluster_name}\"\n"\
|
||||
"CPU = \"#{@vm.config.hardware.numCPU}\"\n"\
|
||||
"vCPU = \"#{@vm.config.hardware.numCPU}\"\n"\
|
||||
"MEMORY = \"#{@vm.config.hardware.memoryMB}\"\n"\
|
||||
@ -1728,11 +1834,11 @@ class VCenterVm
|
||||
"PUBLIC_CLOUD = [\n"\
|
||||
" TYPE =\"vcenter\",\n"\
|
||||
" VM_TEMPLATE =\"#{@vm.config.uuid}\",\n"\
|
||||
" HOST =\"#{host_name}\"\n"\
|
||||
" HOST =\"#{cluster_name}\"\n"\
|
||||
"]\n"\
|
||||
"IMPORT_VM_ID = \"#{@vm.config.uuid}\"\n"\
|
||||
"IMPORT_STATE = \"#{state}\"\n"\
|
||||
"SCHED_REQUIREMENTS=\"NAME=\\\"#{host_name}\\\"\"\n"
|
||||
"SCHED_REQUIREMENTS=\"NAME=\\\"#{cluster_name}\\\"\"\n"
|
||||
|
||||
vp = @vm.config.extraConfig.select{|v|
|
||||
v[:key].downcase=="remotedisplay.vnc.port"}
|
||||
@ -1750,7 +1856,7 @@ class VCenterVm
|
||||
|
||||
if @vm.config.annotation.nil? || @vm.config.annotation.empty?
|
||||
str << "DESCRIPTION = \"vCenter Virtual Machine imported by"\
|
||||
" OpenNebula from Cluster #{@vm.runtime.host.parent.name}\"\n"
|
||||
" OpenNebula from Cluster #{cluster_name}\"\n"
|
||||
else
|
||||
notes = @vm.config.annotation.gsub("\\", "\\\\").gsub("\"", "\\\"")
|
||||
str << "DESCRIPTION = \"#{notes}\"\n"
|
||||
|
Loading…
x
Reference in New Issue
Block a user