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

Merge branch 'master' into feature-4217

This commit is contained in:
Ruben S. Montero 2016-02-02 14:50:46 +01:00
commit 49575e163a
204 changed files with 4157 additions and 1361 deletions

View File

@ -223,6 +223,12 @@ public:
return shared;
};
/**
* Returns true if the DS_MAD_CONF has PERSISTENT_ONLY = "YES" flag
* @return true if persistent only
*/
bool is_persistent_only();
/**
* Enable or disable the DS. Only for System DS.
* @param enable true to enable
@ -373,6 +379,17 @@ private:
return new DatastoreTemplate;
}
/**
* Verify the proper definition of the DS_MAD by checking the attributes
* related to the DS defined in DS_MAD_CONF specified in the Datastore
* template
*/
int set_ds_mad(string &ds_mad, string &error_str);
/**
* Verify the proper definition of the TM_MAD by checking the attributes
* related to the TM defined in TM_MAD_CONF
*/
int set_tm_mad(string &tm_mad, string &error_str);
/**

View File

@ -76,16 +76,17 @@ public:
*/
enum DiskType
{
FILE = 0, /** < File-based disk */
CD_ROM = 1, /** < An ISO9660 disk */
BLOCK = 2, /** < Block-device disk */
RBD = 3, /** < CEPH RBD disk */
RBD_CDROM = 4, /** < CEPH RBD CDROM disk */
GLUSTER = 5, /** < Gluster Block Device */
GLUSTER_CDROM = 6, /** < Gluster CDROM Device Device */
SHEEPDOG = 7, /** < Sheepdog Block Device */
FILE = 0, /** < File-based disk */
CD_ROM = 1, /** < An ISO9660 disk */
BLOCK = 2, /** < Block-device disk */
RBD = 3, /** < CEPH RBD disk */
RBD_CDROM = 4, /** < CEPH RBD CDROM disk */
GLUSTER = 5, /** < Gluster Block Device */
GLUSTER_CDROM = 6, /** < Gluster CDROM Device Device */
SHEEPDOG = 7, /** < Sheepdog Block Device */
SHEEPDOG_CDROM = 8, /** < Sheepdog CDROM Device Device */
NONE = 255 /** < No disk type, error situation */
ISCSI = 9, /** < iSCSI Volume (Devices Datastore) */
NONE = 255 /** < No disk type, error situation */
};
/**
@ -106,6 +107,7 @@ public:
case GLUSTER_CDROM: return "GLUSTER_CDROM" ; break;
case SHEEPDOG: return "SHEEPDOG" ; break;
case SHEEPDOG_CDROM: return "SHEEPDOG_CDROM" ; break;
case ISCSI: return "ISCSI" ; break;
default: return "";
}
};

View File

@ -48,6 +48,8 @@ private:
static const int GLUSTER_DEFAULT_PORT;
static const int ISCSI_DEFAULT_PORT;
int deployment_description(
const VirtualMachine * vm,
const string& file_name) const

View File

@ -217,57 +217,13 @@ public:
* Returns the value of LOG->DEBUG_LEVEL in oned.conf file
* @return the debug level, to instantiate Log'ers
*/
Log::MessageType get_debug_level() const
{
Log::MessageType clevel = Log::ERROR;
vector<const Attribute *> logs;
int rc;
int log_level_int;
rc = nebula_configuration->get("LOG", logs);
if ( rc != 0 )
{
string value;
const VectorAttribute * log = static_cast<const VectorAttribute *>
(logs[0]);
value = log->vector_value("DEBUG_LEVEL");
log_level_int = atoi(value.c_str());
if ( Log::ERROR <= log_level_int && log_level_int <= Log::DDDEBUG )
{
clevel = static_cast<Log::MessageType>(log_level_int);
}
}
return clevel;
}
Log::MessageType get_debug_level() const;
/**
* Returns the value of LOG->SYSTEM in oned.conf file
* @return the logging system CERR, FILE_TS or SYSLOG
*/
NebulaLog::LogType get_log_system() const
{
vector<const Attribute *> logs;
int rc;
NebulaLog::LogType log_system = NebulaLog::UNDEFINED;
rc = nebula_configuration->get("LOG", logs);
if ( rc != 0 )
{
string value;
const VectorAttribute * log = static_cast<const VectorAttribute *>
(logs[0]);
value = log->vector_value("SYSTEM");
log_system = NebulaLog::str_to_type(value);
}
return log_system;
};
NebulaLog::LogType get_log_system() const;
/**
* Returns the value of ONE_LOCATION env variable. When this variable is
@ -325,28 +281,7 @@ public:
*
*
*/
int get_ds_location(int cluster_id, string& dsloc)
{
if ( cluster_id != -1 )
{
Cluster * cluster = clpool->get(cluster_id, true);
if ( cluster == 0 )
{
return -1;
}
cluster->get_ds_location(dsloc);
cluster->unlock();
}
else
{
get_configuration_attribute("DATASTORE_LOCATION", dsloc);
}
return 0;
}
int get_ds_location(int cluster_id, string& dsloc);
/**
* Returns the default vms location. When ONE_LOCATION is defined this path
@ -368,21 +303,7 @@ public:
* /var/log/one/$VM_ID.log
* @return the log location for the VM.
*/
string get_vm_log_filename(int oid)
{
ostringstream oss;
if (nebula_location == "/")
{
oss << log_location << oid << ".log";
}
else
{
oss << vms_location << oid << "/vm.log";
}
return oss.str();
};
string get_vm_log_filename(int oid);
/**
* Returns the name of the host running oned
@ -437,7 +358,10 @@ public:
/**
* Initialize the database
*/
void bootstrap_db();
void bootstrap_db()
{
start(true);
}
// --------------------------------------------------------------
// Federation
@ -521,36 +445,19 @@ public:
nebula_configuration->Template::get(_name, value);
};
/**
* Gets a DS configuration attribute
*/
int get_ds_conf_attribute(
const std::string& ds_name,
const VectorAttribute* &value) const;
/**
* Gets a TM configuration attribute
*/
int get_tm_conf_attribute(
const string& tm_name,
const VectorAttribute* &value) const
{
vector<const Attribute*>::const_iterator it;
vector<const Attribute*> values;
nebula_configuration->Template::get("TM_MAD_CONF", values);
for (it = values.begin(); it != values.end(); it ++)
{
value = dynamic_cast<const VectorAttribute*>(*it);
if (value == 0)
{
continue;
}
if (value->vector_value("NAME") == tm_name)
{
return 0;
}
}
value = 0;
return -1;
};
const VectorAttribute* &value) const;
/**
* Gets an XML document with all of the configuration attributes

View File

@ -133,12 +133,17 @@ protected:
/**
* Defaults for the configuration file
*/
map<string, Attribute*> conf_default;
multimap<string, Attribute*> conf_default;
/**
* Sets the defaults value for the template
*/
virtual void set_conf_default() = 0;
/**
* Sets the defaults value for multiple attributes
*/
virtual void set_multiple_conf_default() = 0;
};
// -----------------------------------------------------------------------------
@ -176,6 +181,39 @@ private:
* Sets the defaults value for the template
*/
void set_conf_default();
/**
* Sets the defaults value for multiple attributes
*/
void set_multiple_conf_default();
/**
* register the multiple configuration attributes and clean the
* conf_default hash
*/
void register_multiple_conf_default(const std::string& conf_section);
/**
* Sets a default single attribute value
*/
void set_conf_single(const std::string& attr, const std::string& value);
/**
* Sets a the defaults for a DS
*/
void set_conf_ds(const std::string& name,
const std::string& required_attrs,
const std::string& persistent_only);
/**
* Sets a the defaults for a TM
*/
void set_conf_tm(const std::string& name,
const std::string& ln_target,
const std::string& clone_target,
const std::string& shared,
const std::string& ds_migrate);
};

View File

@ -20,14 +20,13 @@
#include <string>
#include <vector>
#include <sstream>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
using namespace std;
/**
* This class represents a generic Object supported by a xml document.
* The class provides basic methods to query attributes, and get xml nodes
@ -43,7 +42,7 @@ public:
/**
* Constructs an object using a XML document
*/
ObjectXML(const string &xml_doc);
ObjectXML(const std::string &xml_doc);
/**
* Constructs an object using a XML Node. The node is copied to the new
@ -54,11 +53,25 @@ public:
virtual ~ObjectXML();
/**
* Access Object elements using Xpath
* Gets elements using Xpath expression.
* @param xpath_expr the Xpath of the element
* @return a vector with the elements
*/
vector<string> operator[] (const char * xpath_expr);
void xpaths(std::vector<std::string>& values, const char * xpath_expr);
/* ---------------------------------------------------------------------- */
/* Gets elements, type wrappers. See __xpaths definition for full */
/* description of these methods. */
/* ---------------------------------------------------------------------- */
inline void xpaths(std::vector<int>& values, const char * xpath_expr)
{
__xpaths<int>(values, xpath_expr);
};
inline void xpaths(std::vector<float>& values, const char * xpath_expr)
{
__xpaths<float>(values, xpath_expr);
};
/**
* Gets and sets a xpath attribute, if the attribute is not found a default
@ -69,76 +82,41 @@ public:
*
* @return -1 if default was set
*/
int xpath(string& value, const char * xpath_expr, const char * def);
int xpath(std::string& value, const char * xpath_expr, const char * def);
/**
* Gets and sets a xpath attribute, if the attribute is not found a default
* is used
* @param value to set
* @param xpath_expr of the xml element
* @param def default value if the element is not found
*
* @return -1 if default was set
*/
int xpath(int& value, const char * xpath_expr, const int& def);
/* ---------------------------------------------------------------------- */
/* Gets xpath attribute, type wrappers. See __xpath definition for full */
/* description of these methods. */
/* ---------------------------------------------------------------------- */
inline int xpath(int& v, const char * x, const int& d)
{
return __xpath<int>(v, x, d);
}
/**
* Gets and sets a xpath attribute, if the attribute is not found a default
* is used
* @param value to set
* @param xpath_expr of the xml element
* @param def default value if the element is not found
*
* @return -1 if default was set
*/
int xpath(float& value, const char * xpath_expr, const float& def);
inline int xpath(float& v, const char * x, const float& d)
{
return __xpath<float>(v, x, d);
}
/**
* Gets and sets a xpath attribute, if the attribute is not found a default
* is used
* @param value to set
* @param xpath_expr of the xml element
* @param def default value if the element is not found
*
* @return -1 if default was set
*/
int xpath(unsigned int& value, const char * xpath_expr,
const unsigned int& def);
inline int xpath(unsigned int& v, const char * x, const unsigned int& d)
{
return __xpath<unsigned int>(v, x, d);
}
/**
* Gets and sets a xpath attribute, if the attribute is not found a default
* is used
* @param value to set
* @param xpath_expr of the xml element
* @param def default value if the element is not found
*
* @return -1 if default was set
*/
int xpath(long long& value, const char * xpath_expr,
const long long& def);
inline int xpath(long long& v, const char * x, const long long& d)
{
return __xpath<long long>(v, x, d);
}
/**
* Gets and sets a xpath attribute, if the attribute is not found a default
* is used
* @param value to set
* @param xpath_expr of the xml element
* @param def default value if the element is not found
*
* @return -1 if default was set
*/
int xpath(unsigned long long& value, const char * xpath_expr,
const unsigned long long& def);
inline int xpath(unsigned long long& v, const char * x, const unsigned long long& d)
{
return __xpath<unsigned long long>(v, x, d);
}
/**
* Gets and sets a xpath attribute, if the attribute is not found a default
* is used
* @param value to set
* @param xpath_expr of the xml element
* @param def default value if the element is not found
*
* @return -1 if default was set
*/
int xpath(time_t& value, const char * xpath_expr, const time_t& def);
inline int xpath(time_t& v, const char * x, const time_t& d)
{
return __xpath<time_t>(v, x, d);
}
/**
* Gets the value of an element from an xml string
@ -148,7 +126,7 @@ public:
*
* @return -1 if the element was not found
*/
static int xpath_value(string& value, const char *xml, const char *xpath);
static int xpath_value(std::string& value, const char *xml, const char *xpath);
/**
* Search the Object for a given attribute in a set of object specific
@ -158,7 +136,7 @@ public:
*
* @return -1 if the element was not found
*/
virtual int search(const char *name, string& value);
virtual int search(const char *name, std::string& value);
/**
* Search the Object for a given attribute in a set of object specific
@ -179,7 +157,7 @@ public:
* returned as pointers to the object nodes.
* @return the number of nodes found
*/
int get_nodes(const char * xpath_expr, vector<xmlNodePtr>& content);
int get_nodes(const char * xpath_expr, std::vector<xmlNodePtr>& content);
/**
* Adds a copy of the node as a child of the node in the xpath expression.
@ -197,9 +175,9 @@ public:
* Frees a vector of XMLNodes, as returned by the get_nodes function
* @param content the vector of xmlNodePtr
*/
void free_nodes(vector<xmlNodePtr>& content)
void free_nodes(std::vector<xmlNodePtr>& content)
{
vector<xmlNodePtr>::iterator it;
std::vector<xmlNodePtr>::iterator it;
for (it = content.begin(); it < content.end(); it++)
{
@ -212,7 +190,7 @@ public:
* XML resources are freed
* @param xml_doc the new xml document
*/
int update_from_str(const string &xml_doc);
int update_from_str(const std::string &xml_doc);
/**
* Updates the object representation with a new XML document. Previous
@ -227,7 +205,7 @@ public:
* @param xml_doc string to parse
* @return 0 if the xml validates
*/
static int validate_xml(const string &xml_doc);
static int validate_xml(const std::string &xml_doc);
/**
* Renames the nodes given in the xpath expression
@ -250,7 +228,7 @@ public:
* calling function
* @return 0 on success
*/
int eval_bool(const string& expr, bool& result, char **errmsg);
int eval_bool(const std::string& expr, bool& result, char **errmsg);
/**
* Evaluates a rank expression on the given host.
@ -260,19 +238,19 @@ public:
* calling function
* @return 0 on success
*/
int eval_arith(const string& expr, int& result, char **errmsg);
int eval_arith(const std::string& expr, int& result, char **errmsg);
/**
* Function to write the Object in an output stream
*/
friend ostream& operator<<(ostream& os, ObjectXML& oxml)
friend std::ostream& operator<<(std::ostream& os, ObjectXML& oxml)
{
xmlChar * mem;
int size;
xmlDocDumpMemory(oxml.xml,&mem,&size);
string str(reinterpret_cast<char *>(mem));
std::string str(reinterpret_cast<char *>(mem));
os << str;
xmlFree(mem);
@ -305,7 +283,7 @@ private:
/**
* Parse a XML documents and initializes XPath contexts
*/
void xml_parse(const string &xml_doc);
void xml_parse(const std::string &xml_doc);
/**
* Search the Object for a given attribute in a set of object specific
@ -313,7 +291,105 @@ private:
* @param name of the attribute
* @results vector of attributes that matches the query
*/
void search(const char* name, vector<string>& results);
void search(const char* name, std::vector<std::string>& results);
/**
* Gets a xpath attribute, if the attribute is not found a default is used.
* This function only returns the first element
* @param value of the element
* @param xpath_expr of the xml element
* @param def default value if the element is not found
*
* @return -1 if default was set
*/
template<typename T>
int __xpath(T& value, const char * xpath_expr, const T& def)
{
std::vector<std::string> values;
xpaths(values, xpath_expr);
if (values.empty() == true)
{
value = def;
return -1;
}
std::istringstream iss(values[0]);
iss >> std::dec >> value;
if (iss.fail() == true)
{
value = def;
return -1;
}
return 0;
}
/**
* Gets elements by xpath.
* @param values vector with the element values.
* @param expr of the xml element
*/
template<typename T>
void __xpaths(std::vector<T>& values, const char * expr)
{
xmlXPathObjectPtr obj;
xmlNodePtr cur;
xmlChar * str_ptr;
obj=xmlXPathEvalExpression(reinterpret_cast<const xmlChar *>(expr),ctx);
if (obj == 0)
{
return;
}
switch (obj->type)
{
case XPATH_NUMBER:
values.push_back(static_cast<T>(obj->floatval));
break;
case XPATH_NODESET:
for(int i = 0; i < obj->nodesetval->nodeNr ; ++i)
{
cur = obj->nodesetval->nodeTab[i];
if ( cur == 0 || cur->type != XML_ELEMENT_NODE )
{
continue;
}
str_ptr = xmlNodeGetContent(cur);
if (str_ptr != 0)
{
std::istringstream iss(reinterpret_cast<char *>(str_ptr));
T val;
iss >> std::dec >> val;
if (!iss.fail())
{
values.push_back(val);
}
xmlFree(str_ptr);
}
}
break;
default:
break;
}
xmlXPathFreeObject(obj);
};
};
#endif /*OBJECT_XML_H_*/

View File

@ -127,7 +127,9 @@ public:
RequestAttributes& att)
{
DocumentPool * docpool = static_cast<DocumentPool *>(pool);
Document * doc = docpool->get(source_id, true);
Document * doc = docpool->get(source_id, true);
doc->unlock();
return docpool->allocate(att.uid, att.gid, att.uname, att.gname,
att.umask, doc->get_document_type(), tmpl, &id, att.resp_msg);

View File

@ -285,6 +285,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \
$VAR_LOCATION/remotes/tm/lvm \
$VAR_LOCATION/remotes/tm/ceph \
$VAR_LOCATION/remotes/tm/dev \
$VAR_LOCATION/remotes/tm/iscsi \
$VAR_LOCATION/remotes/hooks \
$VAR_LOCATION/remotes/hooks/ft \
$VAR_LOCATION/remotes/datastore \
@ -297,6 +298,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \
$VAR_LOCATION/remotes/market \
$VAR_LOCATION/remotes/market/http \
$VAR_LOCATION/remotes/market/one \
$VAR_LOCATION/remotes/datastore/iscsi \
$VAR_LOCATION/remotes/auth \
$VAR_LOCATION/remotes/auth/plain \
$VAR_LOCATION/remotes/auth/ssh \
@ -418,6 +420,7 @@ INSTALL_FILES=(
TM_LVM_FILES:$VAR_LOCATION/remotes/tm/lvm
TM_CEPH_FILES:$VAR_LOCATION/remotes/tm/ceph
TM_DEV_FILES:$VAR_LOCATION/remotes/tm/dev
TM_ISCSI_FILES:$VAR_LOCATION/remotes/tm/iscsi
TM_DUMMY_FILES:$VAR_LOCATION/remotes/tm/dummy
DATASTORE_DRIVER_COMMON_SCRIPTS:$VAR_LOCATION/remotes/datastore/
DATASTORE_DRIVER_DUMMY_SCRIPTS:$VAR_LOCATION/remotes/datastore/dummy
@ -426,6 +429,7 @@ INSTALL_FILES=(
DATASTORE_DRIVER_LVM_SCRIPTS:$VAR_LOCATION/remotes/datastore/lvm
DATASTORE_DRIVER_CEPH_SCRIPTS:$VAR_LOCATION/remotes/datastore/ceph
DATASTORE_DRIVER_DEV_SCRIPTS:$VAR_LOCATION/remotes/datastore/dev
DATASTORE_DRIVER_ISCSI_SCRIPTS:$VAR_LOCATION/remotes/datastore/iscsi
MARKETPLACE_DRIVER_HTTP_SCRIPTS:$VAR_LOCATION/remotes/market/http
MARKETPLACE_DRIVER_ONE_SCRIPTS:$VAR_LOCATION/remotes/market/one
MARKETPLACE_DRIVER_S3_SCRIPTS:$VAR_LOCATION/remotes/market/s3
@ -980,6 +984,7 @@ NETWORK_VMWARE_FILES="src/vnm_mad/remotes/vmware/clean \
# - LVM TM, $VAR_LOCATION/tm/lvm
# - CEPH TM, $VAR_LOCATION/tm/ceph
# - DEV TM, $VAR_LOCATION/tm/dev
# - ISCSI TM, $VAR_LOCATION/tm/iscsi
#-------------------------------------------------------------------------------
TM_FILES="src/tm_mad/tm_common.sh"
@ -1131,6 +1136,20 @@ TM_DEV_FILES="src/tm_mad/dev/clone \
src/tm_mad/dev/failmigrate \
src/tm_mad/dev/delete"
TM_ISCSI_FILES="src/tm_mad/iscsi/clone \
src/tm_mad/iscsi/ln \
src/tm_mad/iscsi/mv \
src/tm_mad/iscsi/mvds \
src/tm_mad/iscsi/cpds \
src/tm_mad/iscsi/premigrate \
src/tm_mad/iscsi/postmigrate \
src/tm_mad/iscsi/snap_create \
src/tm_mad/iscsi/snap_create_live \
src/tm_mad/iscsi/snap_delete \
src/tm_mad/iscsi/snap_revert \
src/tm_mad/iscsi/failmigrate \
src/tm_mad/iscsi/delete"
#-------------------------------------------------------------------------------
# Datastore drivers, to be installed under $REMOTES_LOCATION/datastore
# - Dummy Image Repository, $REMOTES_LOCATION/datastore/dummy
@ -1209,6 +1228,16 @@ DATASTORE_DRIVER_DEV_SCRIPTS="src/datastore_mad/remotes/dev/cp \
src/datastore_mad/remotes/dev/snap_flatten \
src/datastore_mad/remotes/dev/clone"
DATASTORE_DRIVER_ISCSI_SCRIPTS="src/datastore_mad/remotes/iscsi/cp \
src/datastore_mad/remotes/iscsi/mkfs \
src/datastore_mad/remotes/iscsi/stat \
src/datastore_mad/remotes/iscsi/rm \
src/datastore_mad/remotes/iscsi/monitor \
src/datastore_mad/remotes/iscsi/snap_delete \
src/datastore_mad/remotes/iscsi/snap_revert \
src/datastore_mad/remotes/iscsi/snap_flatten \
src/datastore_mad/remotes/iscsi/clone"
#-------------------------------------------------------------------------------
# Marketplace drivers, to be installed under $REMOTES_LOCATION/market
# - HTTP based marketplace, $REMOTES_LOCATION/market/http
@ -1236,7 +1265,8 @@ MARKETPLACE_DRIVER_S3_SCRIPTS="src/market_mad/remotes/s3/import \
ONEDB_FILES="src/onedb/fsck.rb \
src/onedb/import_slave.rb \
src/onedb/onedb.rb \
src/onedb/onedb_backend.rb"
src/onedb/onedb_backend.rb \
src/onedb/sqlite2mysql.rb"
ONEDB_SHARED_MIGRATOR_FILES="src/onedb/shared/2.0_to_2.9.80.rb \
src/onedb/shared/2.9.80_to_2.9.85.rb \

View File

@ -57,7 +57,7 @@ LOG = [
debug_level = 3
]
#MANAGER_TIMER = 30
#MANAGER_TIMER = 15
MONITORING_INTERVAL = 60
MONITORING_THREADS = 50
@ -547,8 +547,8 @@ VM_MAD = [
# default = "vmm_exec/vmm_exec_vcenter.conf",
# type = "xml",
# imported_vms_actions = "shutdown, shutdown-hard, hold, release, suspend,
# resume, delete, reboot, reboot-hard, resched, unresched, poweroff,
# poweroff-hard, disk-attach, disk-detach, nic-attach, nic-detach,
# resume, delete, reboot, reboot-hard, resched, unresched, poweroff,
# poweroff-hard, disk-attach, disk-detach, nic-attach, nic-detach,
# snap-create, snap-delete"
#]
#-------------------------------------------------------------------------------
@ -563,7 +563,7 @@ VM_MAD = [
# executable = "one_vmm_sh",
# arguments = "-t 15 -r 0 ec2",
# type = "xml",
# imported_vms_actions = "shutdown, shutdown-hard, hold, release, suspend,
# imported_vms_actions = "shutdown, shutdown-hard, hold, release, suspend,
# resume, delete, reboot, reboot-hard, resched, unresched, poweroff,
# poweroff-hard, disk-attach, disk-detach, nic-attach, nic-detach,
# snap-create, snap-delete"
@ -580,7 +580,7 @@ VM_MAD = [
# executable = "one_vmm_sh",
# arguments = "-t 15 -r 0 sl",
# type = "xml",
# imported_vms_actions = "shutdown, shutdown-hard, hold, release, suspend,
# imported_vms_actions = "shutdown, shutdown-hard, hold, release, suspend,
# resume, delete, reboot, reboot-hard, resched, unresched, poweroff,
# poweroff-hard, disk-attach, disk-detach, nic-attach, nic-detach,
# snap-create, snap-delete"
@ -597,7 +597,7 @@ VM_MAD = [
# executable = "one_vmm_sh",
# arguments = "-t 15 -r 0 az",
# type = "xml",
# imported_vms_actions = "shutdown, shutdown-hard, hold, release, suspend,
# imported_vms_actions = "shutdown, shutdown-hard, hold, release, suspend,
# resume, delete, reboot, reboot-hard, resched, unresched, poweroff,
# poweroff-hard, disk-attach, disk-detach, nic-attach, nic-detach,
# snap-create, snap-delete"
@ -628,7 +628,7 @@ VM_MAD = [
TM_MAD = [
executable = "one_tm",
arguments = "-t 15 -d dummy,lvm,shared,fs_lvm,qcow2,ssh,vmfs,ceph,dev"
arguments = "-t 15 -d dummy,lvm,shared,fs_lvm,qcow2,ssh,vmfs,ceph,dev,iscsi"
]
#*******************************************************************************
@ -647,7 +647,7 @@ TM_MAD = [
DATASTORE_MAD = [
executable = "one_datastore",
arguments = "-t 15 -d dummy,fs,vmfs,lvm,ceph,dev -s shared,ssh,ceph"
arguments = "-t 15 -d dummy,fs,vmfs,lvm,ceph,dev,iscsi -s shared,ssh,ceph"
]
#*******************************************************************************
@ -928,6 +928,15 @@ INHERIT_DATASTORE_ATTR = "CEPH_USER"
INHERIT_DATASTORE_ATTR = "CEPH_CONF"
INHERIT_DATASTORE_ATTR = "POOL_NAME"
INHERIT_DATASTORE_ATTR = "ISCSI_USER"
INHERIT_DATASTORE_ATTR = "ISCSI_USAGE"
INHERIT_DATASTORE_ATTR = "ISCSI_HOST"
INHERIT_IMAGE_ATTR = "ISCSI_USER"
INHERIT_IMAGE_ATTR = "ISCSI_USAGE"
INHERIT_IMAGE_ATTR = "ISCSI_HOST"
INHERIT_IMAGE_ATTR = "ISCSI_IQN"
INHERIT_DATASTORE_ATTR = "GLUSTER_HOST"
INHERIT_DATASTORE_ATTR = "GLUSTER_VOLUME"
@ -957,47 +966,105 @@ INHERIT_VNET_ATTR = "MTU"
# SYSTEM: The image will be cloned in the System datastore
# shared : determines if the storage holding the system datastore is shared
# among the different hosts or not. Valid values: "yes" or "no"
# ds_migrate : The driver allows migrations across datastores. Valid values:
# ds_migrate : The driver allows migrations across datastores. Valid values:
# "yes" or "no". Note: THIS ONLY APPLIES TO SYSTEM DS.
#*******************************************************************************
TM_MAD_CONF = [
name = "dummy", ln_target = "NONE", clone_target = "SYSTEM", shared = "yes",
ds_migrate = "yes"
NAME = "dummy", LN_TARGET = "NONE", CLONE_TARGET = "SYSTEM", SHARED = "YES",
DS_MIGRATE = "YES"
]
TM_MAD_CONF = [
name = "lvm", ln_target = "NONE", clone_target = "SELF", shared = "yes"
NAME = "lvm", LN_TARGET = "NONE", CLONE_TARGET = "SELF", SHARED = "YES"
]
TM_MAD_CONF = [
name = "shared", ln_target = "NONE", clone_target = "SYSTEM", shared = "yes",
ds_migrate = "yes"
NAME = "shared", LN_TARGET = "NONE", CLONE_TARGET = "SYSTEM", SHARED = "YES",
DS_MIGRATE = "YES"
]
TM_MAD_CONF = [
name = "fs_lvm", ln_target = "SYSTEM", clone_target = "SYSTEM", shared="yes"
NAME = "fs_lvm", LN_TARGET = "SYSTEM", CLONE_TARGET = "SYSTEM", SHARED="YES"
]
TM_MAD_CONF = [
name = "qcow2", ln_target = "NONE", clone_target = "SYSTEM", shared = "yes"
NAME = "qcow2", LN_TARGET = "NONE", CLONE_TARGET = "SYSTEM", SHARED = "YES"
]
TM_MAD_CONF = [
name = "ssh", ln_target = "SYSTEM", clone_target = "SYSTEM", shared = "no",
ds_migrate = "yes"
NAME = "ssh", LN_TARGET = "SYSTEM", CLONE_TARGET = "SYSTEM", SHARED = "NO",
DS_MIGRATE = "YES"
]
TM_MAD_CONF = [
name = "vmfs", ln_target = "NONE", clone_target= "SYSTEM", shared = "yes"
NAME = "vmfs", LN_TARGET = "NONE", CLONE_TARGET= "SYSTEM", SHARED = "YES"
]
TM_MAD_CONF = [
name = "ceph", ln_target = "NONE", clone_target = "SELF", shared = "yes",
ds_migrate = "no"
NAME = "ceph", LN_TARGET = "NONE", CLONE_TARGET = "SELF", SHARED = "YES",
DS_MIGRATE = "NO"
]
TM_MAD_CONF = [
name = "dev", ln_target = "NONE", clone_target = "NONE", shared = "yes"
NAME = "iscsi", LN_TARGET = "NONE", CLONE_TARGET = "SELF", SHARED = "YES",
DS_MIGRATE = "NO"
]
TM_MAD_CONF = [
NAME = "dev", LN_TARGET = "NONE", CLONE_TARGET = "NONE", SHARED = "YES"
]
#*******************************************************************************
# Datastore Manager Driver Behavior Configuration
#*******************************************************************************
# The configuration for each driver is defined in DS_MAD_CONF. These
# values are used when creating a new datastore and should not be modified
# since they define the datastore behavior.
# name : name of the transfer driver, listed in the -d option of the
# DS_MAD section
# required_attrs : comma separated list of required attributes in the DS
# template
# persistent_only: specifies whether the datastore can only manage persistent
# images
#*******************************************************************************
DS_MAD_CONF = [
NAME = "ceph",
REQUIRED_ATTRS = "DISK_TYPE,BRIDGE_LIST,CEPH_HOST,CEPH_USER,CEPH_SECRET",
PERSISTENT_ONLY = "NO"
]
DS_MAD_CONF = [
NAME = "dev", REQUIRED_ATTRS = "DISK_TYPE", PERSISTENT_ONLY = "YES"
]
DS_MAD_CONF = [
NAME = "iscsi", REQUIRED_ATTRS = "DISK_TYPE,ISCSI_HOST",
PERSISTENT_ONLY = "YES"
]
DS_MAD_CONF = [
NAME = "dummy", REQUIRED_ATTRS = "", PERSISTENT_ONLY = "NO"
]
DS_MAD_CONF = [
NAME = "fs", REQUIRED_ATTRS = "", PERSISTENT_ONLY = "NO"
]
DS_MAD_CONF = [
NAME = "lvm", REQUIRED_ATTRS = "DISK_TYPE,BRIDGE_LIST",
PERSISTENT_ONLY = "NO"
]
DS_MAD_CONF = [
NAME = "shared", REQUIRED_ATTRS = "", PERSISTENT_ONLY = "NO"
]
DS_MAD_CONF = [
NAME = "ssh", REQUIRED_ATTRS = "", PERSISTENT_ONLY = "NO"
]
DS_MAD_CONF = [
NAME = "vmfs", REQUIRED_ATTRS = "BRIDGE_LIST", PERSISTENT_ONLY = "NO"
]

View File

@ -665,12 +665,12 @@ EOT
end
end
private
def retrieve_resource(id)
factory(id)
end
private
def pool_to_array(pool)
if !pool.instance_of?(Hash)
phash = pool.to_hash

View File

@ -194,6 +194,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do
str = OpenNebulaHelper.update_template(args[0], obj, args[1])
end
helper.set_client(options)
obj = helper.retrieve_resource(obj.id)
obj.update(str, options[:append])
end
end

View File

@ -171,6 +171,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do
str = OpenNebulaHelper.update_template(args[0], obj, args[1])
end
helper.set_client(options)
obj = helper.retrieve_resource(obj.id)
obj.update(str, options[:append])
end
end

View File

@ -130,6 +130,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do
str = OpenNebulaHelper.update_template(args[0], obj, args[1])
end
helper.set_client(options)
obj = helper.retrieve_resource(obj.id)
obj.update(str, options[:append])
end
end

View File

@ -174,6 +174,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do
str = OpenNebulaHelper.update_template(args[0], obj, args[1])
end
helper.set_client(options)
obj = helper.retrieve_resource(obj.id)
obj.update(str, options[:append])
end
end

View File

@ -223,6 +223,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do
str = OpenNebulaHelper.update_template(args[0], obj, args[1])
end
helper.set_client(options)
obj = helper.retrieve_resource(obj.id)
obj.update(str, options[:append])
end
end

View File

@ -166,6 +166,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do
str = OpenNebulaHelper.update_template(args[0], obj, args[1])
end
helper.set_client(options)
obj = helper.retrieve_resource(obj.id)
obj.update(str, options[:append])
end
end

View File

@ -284,6 +284,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do
str = OpenNebulaHelper.update_template(args[0], obj, args[1])
end
helper.set_client(options)
obj = helper.retrieve_resource(obj.id)
obj.update(str, options[:append])
end
end

View File

@ -40,7 +40,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
helper = OneUserHelper.new
before_proc do
helper.set_client(options) if @comm_name != :login
helper.set_client(options) if ![:login, :key].include?(@comm_name)
end
########################################################################
@ -210,6 +210,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do
str = OpenNebulaHelper.update_template(args[0], obj, args[1])
end
helper.set_client(options)
obj = helper.retrieve_resource(obj.id)
obj.update(str, options[:append])
end
end
@ -348,8 +351,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
key_desc = <<-EOT.unindent
DEPRECATED, use login to generate auth files.
Shows a public key from a private SSH key. Use it as password
for the SSH authentication mechanism.
EOT

View File

@ -148,6 +148,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do
str = OpenNebulaHelper.update_template(args[0], obj, args[1])
end
helper.set_client(options)
obj = helper.retrieve_resource(obj.id)
obj.update(str, options[:append])
end
end

View File

@ -255,6 +255,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do
str = OpenNebulaHelper.update_template(args[0], obj, args[1], 'USER_TEMPLATE')
end
helper.set_client(options)
obj = helper.retrieve_resource(obj.id)
obj.update(str, options[:append])
end
end

View File

@ -329,6 +329,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do
str = OpenNebulaHelper.update_template(args[0], obj, args[1])
end
helper.set_client(options)
obj = helper.retrieve_resource(obj.id)
obj.update(str, options[:append])
end
end
@ -365,6 +368,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do
str = OpenNebulaHelper.update_template_helper(false, args[0], obj,
args[2], "AR_POOL", false)
helper.set_client(options)
obj = helper.retrieve_resource(obj.id)
obj.update_ar(str)
end
end

View File

@ -105,6 +105,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do
str = OpenNebulaHelper.update_template(args[0], obj, args[1])
end
helper.set_client(options)
obj = helper.retrieve_resource(obj.id)
obj.update(str, options[:append])
end
end

View File

@ -109,6 +109,7 @@ void Datastore::disk_attribute(
ostringstream oss;
string st;
string inherit_val;
string current_val;
vector<string>::const_iterator it;
@ -142,9 +143,10 @@ void Datastore::disk_attribute(
for (it = inherit_attrs.begin(); it != inherit_attrs.end(); it++)
{
current_val = disk->vector_value((*it).c_str());
get_template_attribute((*it).c_str(), inherit_val);
if (!inherit_val.empty())
if ( current_val.empty() && !inherit_val.empty() )
{
disk->replace(*it, inherit_val);
}
@ -209,24 +211,81 @@ static int check_tm_target_type(string& tm_tt)
/* -------------------------------------------------------------------------- */
int Datastore::set_ds_mad(std::string &mad, std::string &error_str)
{
const VectorAttribute* vatt;
std::vector <std::string> vrequired_attrs;
int rc;
std::string required_attrs, required_attr, value;
std::ostringstream oss;
if ( type == SYSTEM_DS ) //No ds_mad for SYSTEM_DS
{
return 0;
}
rc = Nebula::instance().get_ds_conf_attribute(mad, vatt);
if ( rc != 0 )
{
goto error_conf;
}
rc = vatt->vector_value("REQUIRED_ATTRS", required_attrs);
if ( rc == -1 ) //No required attributes
{
return 0;
}
vrequired_attrs = one_util::split(required_attrs, ',');
for ( std::vector<std::string>::const_iterator it = vrequired_attrs.begin();
it != vrequired_attrs.end(); it++ )
{
required_attr = *it;
required_attr = one_util::trim(required_attr);
one_util::toupper(required_attr);
get_template_attribute(required_attr.c_str(), value);
if ( value.empty() )
{
goto error_required;
}
}
return 0;
error_conf:
oss << "DS_MAD named \"" << mad << "\" is not defined in oned.conf";
goto error_common;
error_required:
oss << "Datastore template is missing the \"" << required_attr
<< "\" attribute or it's empty.";
error_common:
error_str = oss.str();
return -1;
}
/* -------------------------------------------------------------------------- */
int Datastore::set_tm_mad(string &tm_mad, string &error_str)
{
const VectorAttribute* vatt;
int rc;
string st;
ostringstream oss;
rc = Nebula::instance().get_tm_conf_attribute(tm_mad, vatt);
if (rc != 0)
if ( Nebula::instance().get_tm_conf_attribute(tm_mad, vatt) != 0 )
{
oss << "TM_MAD named \"" << tm_mad << "\" is not defined in oned.conf";
error_str = oss.str();
return -1;
goto error_conf;
}
if (type == SYSTEM_DS)
@ -290,12 +349,16 @@ int Datastore::set_tm_mad(string &tm_mad, string &error_str)
return 0;
error_conf:
oss << "TM_MAD named \"" << tm_mad << "\" is not defined in oned.conf";
goto error_common;
error:
oss << "Attribute shared, ln_target or clone_target in TM_MAD_CONF for "
<< tm_mad << " is missing or has wrong value in oned.conf";
error_common:
error_str = oss.str();
return -1;
}
@ -321,6 +384,7 @@ int Datastore::set_ds_disk_type(string& s_dt, string& error)
//Valid disk types for Image DS
case Image::FILE:
case Image::BLOCK:
case Image::ISCSI:
case Image::RBD:
case Image::GLUSTER:
case Image::SHEEPDOG:
@ -350,6 +414,7 @@ int Datastore::set_ds_disk_type(string& s_dt, string& error)
case Image::GLUSTER:
case Image::SHEEPDOG:
case Image::BLOCK:
case Image::ISCSI:
case Image::CD_ROM:
case Image::RBD_CDROM:
case Image::SHEEPDOG_CDROM:
@ -416,6 +481,11 @@ int Datastore::insert(SqlDB *db, string& error_str)
goto error_ds;
}
if (set_ds_mad(ds_mad, error_str) != 0)
{
goto error_common;
}
get_template_attribute("TM_MAD", tm_mad);
if ( tm_mad.empty() == true )
@ -701,13 +771,13 @@ int Datastore::post_update_template(string& error_str)
DatastoreType old_ds_type = type;
Image::DiskType old_disk_type = disk_type;
string old_tm_mad = tm_mad;
string old_ds_mad = ds_mad;
/* ---------------------------------------------------------------------- */
/* Set the TYPE of the Datastore (class & template) */
/* ---------------------------------------------------------------------- */
old_ds_type = type;
get_template_attribute("TYPE", s_ds_type);
if (!s_ds_type.empty())
@ -808,6 +878,20 @@ int Datastore::post_update_template(string& error_str)
}
}
/* ---------------------------------------------------------------------- */
/* Verify that the template has the required attributees */
/* ---------------------------------------------------------------------- */
if ( set_ds_mad(ds_mad, error_str) != 0 )
{
type = old_ds_type;
disk_type = old_disk_type;
tm_mad = old_tm_mad;
ds_mad = old_ds_mad;
return -1;
}
/* ---------------------------------------------------------------------- */
/* Set the BASE_PATH of the Datastore (class & template) */
/* ---------------------------------------------------------------------- */
@ -868,3 +952,27 @@ bool Datastore::get_avail_mb(long long &avail)
return check;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
bool Datastore::is_persistent_only()
{
int rc;
bool persistent_only = false;
const VectorAttribute* vatt;
rc = Nebula::instance().get_ds_conf_attribute(ds_mad, vatt);
if ( rc != 0 )
{
// No DS_MAD_CONF is available for this DS_MAD.
// Assuming this DS is not PERSISTENT_ONLY
return false;
}
vatt->vector_value("PERSISTENT_ONLY", persistent_only);
return persistent_only;
};

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -0,0 +1 @@
../dev/cp

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -0,0 +1 @@
../dev/monitor

View File

@ -0,0 +1 @@
../dev/rm

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -0,0 +1 @@
../dev/stat

View File

@ -245,6 +245,8 @@ post '/service/:id/action' do
OpenNebula::Error.new("Action #{action['perform']}: " <<
"You have to specify an OCTET")
end
when 'rename'
service.rename(opts['name'])
else
OpenNebula::Error.new("Action #{action['perform']} not supported")
end
@ -472,24 +474,24 @@ post '/service_template/:id/action' do
args << opts['owner_id'].to_i
args << (opts['group_id'].to_i || -1)
service_template.chown(*args)
status 204
service_template.chown(*args)
else
OpenNebula::Error.new("Action #{action['perform']}: " <<
"You have to specify a UID")
end
when 'chgrp'
if opts && opts['group_id']
service_template.chown(-1, opts['group_id'].to_i)
status 204
service_template.chown(-1, opts['group_id'].to_i)
else
OpenNebula::Error.new("Action #{action['perform']}: " <<
"You have to specify a GID")
end
when 'chmod'
if opts && opts['octet']
service_template.chmod_octet(opts['octet'])
status 204
service_template.chmod_octet(opts['octet'])
else
OpenNebula::Error.new("Action #{action['perform']}: " <<
"You have to specify an OCTET")
@ -506,6 +508,13 @@ post '/service_template/:id/action' do
OpenNebula::Error.new("Action #{action['perform']}: " <<
"You have to provide a template")
end
when 'rename'
status 204
service_template.rename(opts['name'])
when 'clone'
status 204
service_template.clone(opts['name'])
# TODO return id of the new template
else
OpenNebula::Error.new("Action #{action['perform']} not supported")
end

View File

@ -811,6 +811,10 @@ Image::DiskType Image::str_to_disk_type(string& s_disk_type)
{
type = Image::BLOCK;
}
else if (s_disk_type == "ISCSI")
{
type = Image::ISCSI;
}
else if (s_disk_type == "CDROM")
{
type = Image::CD_ROM;

View File

@ -454,7 +454,7 @@ fi
EOF`
SSH_EXEC_RC=$?
if [ $? -ne 0 ]; then
if [ $SSH_EXEC_RC -ne 0 ]; then
error_message "Error creating directory $2 at $1: $SSH_EXEC_ERR"
exit $SSH_EXEC_RC
@ -594,3 +594,36 @@ function iqn_get_host {
VG_NAME=$(iqn_get_vg_name "$IQN")
echo ${TARGET%%.$VG_NAME.$LV_NAME}
}
# ------------------------------------------------------------------------------
# VMM helpers
# ------------------------------------------------------------------------------
# This function builds the XML necessary for attach-disk operations
# that require declaration of host sources
# @param $1 - Space separated list of hosts
# @return The XML via STDOUT
function get_source_xml {
for host in $1 ; do
BCK_IFS=$IFS
IFS=':'
unset k HOST_PARTS SOURCE_HOST
for part in $host ; do
HOST_PARTS[k++]="$part"
done
SOURCE_HOST="$SOURCE_HOST<host name='${HOST_PARTS[0]}'"
if [ -n "${HOST_PARTS[1]}" ]; then
SOURCE_HOST="$SOURCE_HOST port='${HOST_PARTS[1]}'"
fi
SOURCE_HOST="$SOURCE_HOST/>"
IFS=$BCK_IFS
done
echo "$SOURCE_HOST"
}

View File

@ -36,14 +36,6 @@ using namespace std;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Nebula::bootstrap_db()
{
start(true);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Nebula::start(bool bootstrap_only)
{
int rc;
@ -1009,3 +1001,178 @@ error_mad:
throw runtime_error("Could not load an OpenNebula driver");
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
Log::MessageType Nebula::get_debug_level() const
{
Log::MessageType clevel = Log::ERROR;
vector<const Attribute *> logs;
int rc;
int log_level_int;
rc = nebula_configuration->get("LOG", logs);
if ( rc != 0 )
{
string value;
const VectorAttribute * log = static_cast<const VectorAttribute *>
(logs[0]);
value = log->vector_value("DEBUG_LEVEL");
log_level_int = atoi(value.c_str());
if ( Log::ERROR <= log_level_int && log_level_int <= Log::DDDEBUG )
{
clevel = static_cast<Log::MessageType>(log_level_int);
}
}
return clevel;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
NebulaLog::LogType Nebula::get_log_system() const
{
vector<const Attribute *> logs;
int rc;
NebulaLog::LogType log_system = NebulaLog::UNDEFINED;
rc = nebula_configuration->get("LOG", logs);
if ( rc != 0 )
{
string value;
const VectorAttribute * log = static_cast<const VectorAttribute *>
(logs[0]);
value = log->vector_value("SYSTEM");
log_system = NebulaLog::str_to_type(value);
}
return log_system;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Nebula::get_ds_location(int cluster_id, string& dsloc)
{
if ( cluster_id != -1 )
{
Cluster * cluster = clpool->get(cluster_id, true);
if ( cluster == 0 )
{
return -1;
}
cluster->get_ds_location(dsloc);
cluster->unlock();
}
else
{
get_configuration_attribute("DATASTORE_LOCATION", dsloc);
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string Nebula::get_vm_log_filename(int oid)
{
ostringstream oss;
if (nebula_location == "/")
{
oss << log_location << oid << ".log";
}
else
{
oss << vms_location << oid << "/vm.log";
}
return oss.str();
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Nebula::get_ds_conf_attribute(
const std::string& ds_name,
const VectorAttribute* &value) const
{
std::vector<const Attribute*>::const_iterator it;
std::vector<const Attribute*> values;
std::string template_ds_name;
std::string ds_name_upper;
nebula_configuration->Template::get("DS_MAD_CONF", values);
for (it = values.begin(); it != values.end(); it ++)
{
value = dynamic_cast<const VectorAttribute*>(*it);
if (value == 0)
{
continue;
}
template_ds_name = value->vector_value("NAME");
ds_name_upper = ds_name;
one_util::toupper(ds_name_upper);
one_util::toupper(template_ds_name);
if ( template_ds_name == ds_name_upper)
{
return 0;
}
}
value = 0;
return -1;
};
int Nebula::get_tm_conf_attribute(
const string& tm_name,
const VectorAttribute* &value) const
{
vector<const Attribute*>::const_iterator it;
vector<const Attribute*> values;
std::string template_tm_name;
std::string tm_name_upper;
nebula_configuration->Template::get("TM_MAD_CONF", values);
for (it = values.begin(); it != values.end(); it ++)
{
value = dynamic_cast<const VectorAttribute*>(*it);
if (value == 0)
{
continue;
}
template_tm_name = value->vector_value("NAME");
tm_name_upper = tm_name;
one_util::toupper(tm_name_upper);
one_util::toupper(template_tm_name);
if ( tm_name_upper == template_tm_name)
{
return 0;
}
}
value = 0;
return -1;
};

View File

@ -72,8 +72,11 @@ int NebulaTemplate::load_configuration()
}
}
set_multiple_conf_default();
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -82,22 +85,210 @@ const char * OpenNebulaTemplate::conf_name="oned.conf";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void OpenNebulaTemplate::set_conf_default()
void OpenNebulaTemplate::set_multiple_conf_default()
{
/*
#*******************************************************************************
# Transfer Manager Configuration
#*******************************************************************************
# dummy
# lvm
# shared
# fs_lvm
# qcow2
# ssh
# vmfs
# ceph
# dev
#*******************************************************************************
*/
set_conf_tm("dummy", "NONE", "SYSTEM", "YES", "YES");
set_conf_tm("lvm", "NONE", "SELF", "YES", "NO");
set_conf_tm("shared", "NONE", "SYSTEM", "YES", "YES");
set_conf_tm("fs_lvm", "SYSTEM", "SYSTEM", "YES", "NO");
set_conf_tm("qcow2", "NONE", "SYSTEM", "YES", "NO");
set_conf_tm("ssh", "SYSTEM", "SYSTEM", "NO", "YES");
set_conf_tm("vmfs", "NONE", "SYSTEM", "YES", "NO");
set_conf_tm("ceph", "NONE", "SELF", "YES", "NO");
set_conf_tm("dev", "NONE", "NONE", "YES", "NO");
register_multiple_conf_default("TM_MAD_CONF");
/*
#*******************************************************************************
# Datastore Manager Configuration
#*******************************************************************************
# ceph
# dev
# dummy
# fs
# lvm
# shared
# ssh
# vmfs
#******
*/
set_conf_ds("dev", "DISK_TYPE", "YES");
set_conf_ds("iscsi", "DISK_TYPE,ISCSI_HOST", "YES");
set_conf_ds("dummy", "", "NO");
set_conf_ds("fs", "", "NO");
set_conf_ds("lvm", "DISK_TYPE", "NO");
set_conf_ds("shared", "", "NO");
set_conf_ds("ssh", "", "NO");
set_conf_ds("vmfs", "BRIDGE_LIST", "NO");
set_conf_ds("ceph",
"DISK_TYPE,BRIDGE_LIST,CEPH_HOST,CEPH_USER,CEPH_SECRET",
"NO");
register_multiple_conf_default("DS_MAD_CONF");
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void OpenNebulaTemplate::register_multiple_conf_default(
const std::string& conf_section)
{
std::string defaults_name, attributes_name;
Attribute * defaults_value;
bool found;
const VectorAttribute* defaults_attr;
const VectorAttribute* attributes_attr;
std::map<std::string, Attribute *>::iterator iter_defaults, prev;
std::vector<const Attribute*>::const_iterator iter_attributes;
std::vector<const Attribute*> attributes_values;
get(conf_section.c_str(), attributes_values);
for( iter_defaults = conf_default.begin();
iter_defaults != conf_default.end(); )
{
if ( iter_defaults->first == conf_section )
{
found = false;
defaults_value = iter_defaults->second;
defaults_attr = dynamic_cast<const VectorAttribute*>
(defaults_value);
defaults_name = defaults_attr->vector_value("NAME");
for (iter_attributes = attributes_values.begin();
iter_attributes != attributes_values.end(); iter_attributes++)
{
attributes_attr = dynamic_cast<const VectorAttribute*>
(*iter_attributes);
if (attributes_attr == 0)
{
continue;
}
attributes_name = attributes_attr->vector_value("NAME");
if ( attributes_name == defaults_name )
{
found = true;
break;
}
}
if ( !found )
{
// insert into attributes
attributes.insert(make_pair(conf_section, defaults_value));
iter_defaults++;
}
else
{
// remove from conf_defaults
delete iter_defaults->second;
prev = iter_defaults++;
conf_default.erase(prev);
}
}
else
{
iter_defaults++;
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void OpenNebulaTemplate::set_conf_single(const std::string& attr,
const std::string& value)
{
SingleAttribute * attribute;
attribute = new SingleAttribute(attr, value);
conf_default.insert(make_pair(attribute->name(),attribute));
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void OpenNebulaTemplate::set_conf_ds(const std::string& name,
const std::string& required_attrs,
const std::string& persistent_only)
{
VectorAttribute * vattribute;
std::map<std::string,std::string> vvalue;
vvalue.insert(make_pair("NAME", name));
vvalue.insert(make_pair("REQUIRED_ATTRS", required_attrs));
vvalue.insert(make_pair("PERSISTENT_ONLY", persistent_only));
vattribute = new VectorAttribute("DS_MAD_CONF", vvalue);
conf_default.insert(make_pair(vattribute->name(), vattribute));
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void OpenNebulaTemplate::set_conf_tm(const std::string& name,
const std::string& ln_target,
const std::string& clone_target,
const std::string& shared,
const std::string& ds_migrate)
{
VectorAttribute * vattribute;
std::map<std::string,std::string> vvalue;
vvalue.insert(make_pair("NAME", name));
vvalue.insert(make_pair("LN_TARGET", ln_target));
vvalue.insert(make_pair("CLONE_TARGET", clone_target));
vvalue.insert(make_pair("SHARED", shared));
vvalue.insert(make_pair("DS_MIGRATE", ds_migrate));
vattribute = new VectorAttribute("TM_MAD_CONF", vvalue);
conf_default.insert(make_pair(vattribute->name(), vattribute));
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void OpenNebulaTemplate::set_conf_default()
{
VectorAttribute * vattribute;
string value;
map<string,string> vvalue;
// MANAGER_TIMER
value = "15";
attribute = new SingleAttribute("MANAGER_TIMER",value);
conf_default.insert(make_pair(attribute->name(),attribute));
/*
#*******************************************************************************
# Daemon configuration attributes
#-------------------------------------------------------------------------------
# MANAGER_TIMER
# MONITORING_INTERVAL
# MONITORING_THREADS
# HOST_PER_INTERVAL
@ -113,59 +304,19 @@ void OpenNebulaTemplate::set_conf_default()
# VM_SUBMIT_ON_HOLD
#*******************************************************************************
*/
// MONITORING_INTERVAL
value = "60";
attribute = new SingleAttribute("MONITORING_INTERVAL",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// MONITORING_THREADS
value = "50";
attribute = new SingleAttribute("MONITORING_THREADS",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// HOST_PER_INTERVAL
value = "15";
attribute = new SingleAttribute("HOST_PER_INTERVAL",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// HOST_MONITORING_EXPIRATION_TIME
value = "43200";
attribute = new SingleAttribute("HOST_MONITORING_EXPIRATION_TIME",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// VM_INDIVIDUAL_MONITORING
value = "no";
attribute = new SingleAttribute("VM_INDIVIDUAL_MONITORING",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// VM_PER_INTERVAL
value = "5";
attribute = new SingleAttribute("VM_PER_INTERVAL",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// VM_MONITORING_EXPIRATION_TIME
value = "14400";
attribute = new SingleAttribute("VM_MONITORING_EXPIRATION_TIME",value);
conf_default.insert(make_pair(attribute->name(),attribute));
//XML-RPC Server PORT
value = "2633";
attribute = new SingleAttribute("PORT",value);
conf_default.insert(make_pair(attribute->name(),attribute));
//XML-RPC Server listen address
value = "0.0.0.0";
attribute = new SingleAttribute("LISTEN_ADDRESS",value);
conf_default.insert(make_pair(attribute->name(),attribute));
set_conf_single("MANAGER_TIMER", "15");
set_conf_single("MONITORING_INTERVAL", "60");
set_conf_single("MONITORING_THREADS", "50");
set_conf_single("HOST_PER_INTERVAL", "15");
set_conf_single("HOST_MONITORING_EXPIRATION_TIME", "43200");
set_conf_single("VM_INDIVIDUAL_MONITORING", "no");
set_conf_single("VM_PER_INTERVAL", "5");
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");
//DB CONFIGURATION
vvalue.insert(make_pair("BACKEND","sqlite"));
@ -173,24 +324,6 @@ void OpenNebulaTemplate::set_conf_default()
vattribute = new VectorAttribute("DB",vvalue);
conf_default.insert(make_pair(vattribute->name(),vattribute));
//VNC_BASE_PORT
value = "5900";
attribute = new SingleAttribute("VNC_BASE_PORT",value);
conf_default.insert(make_pair(attribute->name(),attribute));
//SCRIPTS_REMOTE_DIR
value = "/var/tmp/one";
attribute = new SingleAttribute("SCRIPTS_REMOTE_DIR",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// VM_SUBMIT_ON_HOLD
value = "NO";
attribute = new SingleAttribute("VM_SUBMIT_ON_HOLD",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// LOG CONFIGURATION
vvalue.clear();
vvalue.insert(make_pair("SYSTEM","file"));
@ -244,53 +377,15 @@ void OpenNebulaTemplate::set_conf_default()
# LOG_CALL_FORMAT
#*******************************************************************************
*/
// MAX_CONN
value = "15";
set_conf_single("MAX_CONN", "15");
set_conf_single("MAX_CONN_BACKLOG", "15");
set_conf_single("KEEPALIVE_TIMEOUT", "15");
set_conf_single("KEEPALIVE_MAX_CONN", "30");
set_conf_single("TIMEOUT", "15");
set_conf_single("RPC_LOG", "NO");
set_conf_single("MESSAGE_SIZE", "1073741824");
set_conf_single("LOG_CALL_FORMAT", "Req:%i UID:%u %m invoked %l");
attribute = new SingleAttribute("MAX_CONN",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// MAX_CONN_BACKLOG
value = "15";
attribute = new SingleAttribute("MAX_CONN_BACKLOG",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// KEEPALIVE_TIMEOUT
value = "15";
attribute = new SingleAttribute("KEEPALIVE_TIMEOUT",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// KEEPALIVE_MAX_CONN
value = "30";
attribute = new SingleAttribute("KEEPALIVE_MAX_CONN",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// TIMEOUT
value = "15";
attribute = new SingleAttribute("TIMEOUT",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// RPC_LOG
value = "NO";
attribute = new SingleAttribute("RPC_LOG",value);
conf_default.insert(make_pair(attribute->name(),attribute));
//MESSAGE_SIZE
value = "1073741824";
attribute = new SingleAttribute("MESSAGE_SIZE",value);
conf_default.insert(make_pair(attribute->name(),attribute));
//LOG_CALL_FORMAT
value = "Req:%i UID:%u %m invoked %l";
attribute = new SingleAttribute("LOG_CALL_FORMAT",value);
conf_default.insert(make_pair(attribute->name(),attribute));
/*
#*******************************************************************************
# Physical Networks configuration
@ -299,17 +394,9 @@ void OpenNebulaTemplate::set_conf_default()
# MAC_PREFIX
#*******************************************************************************
*/
//MAC_PREFIX
value = "02:00";
attribute = new SingleAttribute("MAC_PREFIX",value);
conf_default.insert(make_pair(attribute->name(),attribute));
//NETWORK_SIZE
value = "254";
attribute = new SingleAttribute("NETWORK_SIZE",value);
conf_default.insert(make_pair(attribute->name(),attribute));
set_conf_single("MAC_PREFIX", "02:00");
set_conf_single("NETWORK_SIZE", "254");
/*
#*******************************************************************************
@ -323,37 +410,13 @@ void OpenNebulaTemplate::set_conf_default()
# DEFAULT_CDROM_DEVICE_PREFIX
#*******************************************************************************
*/
//DATASTORE_LOCATION
attribute = new SingleAttribute("DATASTORE_LOCATION",
var_location + "/datastores");
conf_default.insert(make_pair(attribute->name(),attribute));
set_conf_single("DATASTORE_LOCATION", var_location + "/datastores");
set_conf_single("DATASTORE_BASE_PATH", var_location + "/datastores");
set_conf_single("DATASTORE_CAPACITY_CHECK", "YES");
set_conf_single("DEFAULT_IMAGE_TYPE", "OS");
set_conf_single("DEFAULT_DEVICE_PREFIX", "hd");
set_conf_single("DEFAULT_CDROM_DEVICE_PREFIX", "hd");
//DATASTORE_BASE_PATH
attribute = new SingleAttribute("DATASTORE_BASE_PATH",
var_location + "/datastores");
conf_default.insert(make_pair(attribute->name(),attribute));
//DATASTORE_CAPACITY_CHECK
value = "YES";
attribute = new SingleAttribute("DATASTORE_CAPACITY_CHECK",value);
conf_default.insert(make_pair(attribute->name(),attribute));
//DEFAULT_IMAGE_TYPE
value = "OS";
attribute = new SingleAttribute("DEFAULT_IMAGE_TYPE",value);
conf_default.insert(make_pair(attribute->name(),attribute));
//DEFAULT_DEVICE_PREFIX
value = "hd";
attribute = new SingleAttribute("DEFAULT_DEVICE_PREFIX",value);
conf_default.insert(make_pair(attribute->name(),attribute));
//DEFAULT_CDROM_DEVICE_PREFIX
attribute = new SingleAttribute("DEFAULT_CDROM_DEVICE_PREFIX",value);
conf_default.insert(make_pair(attribute->name(),attribute));
/*
#*******************************************************************************
# Auth Manager Configuration
@ -364,29 +427,10 @@ void OpenNebulaTemplate::set_conf_default()
# DEFAULT_UMASK
#*******************************************************************************
*/
// DEFAULT_AUTH
value = "default";
attribute = new SingleAttribute("DEFAULT_AUTH",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// SESSION_EXPIRATION_TIME
value = "0";
attribute = new SingleAttribute("SESSION_EXPIRATION_TIME",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// ENABLE_OTHER_PERMISSIONS
value = "YES";
attribute = new SingleAttribute("ENABLE_OTHER_PERMISSIONS",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// DEFAULT_UMASK
value = "177";
attribute = new SingleAttribute("DEFAULT_UMASK",value);
conf_default.insert(make_pair(attribute->name(),attribute));
set_conf_single("DEFAULT_AUTH", "default");
set_conf_single("SESSION_EXPIRATION_TIME", "0");
set_conf_single("ENABLE_OTHER_PERMISSIONS", "YES");
set_conf_single("DEFAULT_UMASK", "177");
}
/* -------------------------------------------------------------------------- */

View File

@ -139,31 +139,38 @@ module OpenNebula
return OpenNebula::Error.new(error_msg)
end
str = ""
sunstone_attrs = []
# Add Sunstone views for the group
if group_hash[:views]
str += "SUNSTONE_VIEWS=\"#{group_hash[:views].join(",")}\"\n"
sunstone_attrs << "VIEWS=\"#{group_hash[:views].join(",")}\""
end
if group_hash[:default_view]
str += "DEFAULT_VIEW=\"#{group_hash[:default_view]}\"\n"
sunstone_attrs << "DEFAULT_VIEW=\"#{group_hash[:default_view]}\""
end
# And the admin views
if group_hash[:admin_views]
str += "GROUP_ADMIN_VIEWS=\"#{group_hash[:admin_views].join(",")}\"\n"
sunstone_attrs << "GROUP_ADMIN_VIEWS=\"#{group_hash[:admin_views].join(",")}\""
else
str += "GROUP_ADMIN_VIEWS=#{GROUP_ADMIN_SUNSTONE_VIEWS}\n"
sunstone_attrs << "GROUP_ADMIN_VIEWS=#{GROUP_ADMIN_SUNSTONE_VIEWS}"
end
if group_hash[:default_admin_view]
str += "GROUP_ADMIN_DEFAULT_VIEW=\"#{group_hash[:default_admin_view]}\"\n"
sunstone_attrs << "GROUP_ADMIN_DEFAULT_VIEW=\"#{group_hash[:default_admin_view]}\""
else
str += "GROUP_ADMIN_DEFAULT_VIEW=#{GROUP_ADMIN_SUNSTONE_VIEWS}"
sunstone_attrs << "GROUP_ADMIN_DEFAULT_VIEW=#{GROUP_ADMIN_SUNSTONE_VIEWS}"
end
self.update(str, true)
if sunstone_attrs.length > 0
rc = self.update("SUNSTONE=[#{sunstone_attrs.join(",\n")}]", true)
if OpenNebula.is_error?(rc)
self.delete
error_msg = "Error updating group template: #{rc.message}"
return OpenNebula::Error.new(error_msg)
end
end
return 0
end

View File

@ -356,4 +356,24 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
###########################################################################
# Migrate SQLite to MySQL
###########################################################################
sqlite2mysql_desc = <<-EOT.unindent
Migrates a SQLite OpenNebula Database to MySQL
EOT
command :sqlite2mysql , sqlite2mysql_desc, :options=>[BACKUP] do
begin
options[:backend] = :sqlite
sqlite = OneDB.new(options)
options[:backend] = :mysql
mysql = OneDB.new(options)
mysql.sqlite2mysql(options, sqlite)
rescue Exception => e
[-1, e.message]
end
end
end

View File

@ -20,6 +20,8 @@ require 'onedb_backend'
LOG_TIME = false
class OneDB
attr_accessor :backend
def initialize(ops)
if ops[:backend] == :sqlite
begin
@ -519,6 +521,38 @@ is preserved.
end
end
def sqlite2mysql(options, sqlite)
one_not_running()
sqlite_v = sqlite.backend.read_db_version
mysql_v = @backend.read_db_version
match = true
match = false if sqlite_v[:version] != mysql_v[:version]
match = false if sqlite_v[:local_version] != mysql_v[:local_version]
if !match
err_msg = "SQLite version: #{sqlite_v[:version]}\n"
err_msg << "SQLite local version: #{sqlite_v[:local_version]}\n"
err_msg << "MySQL version: #{mysql_v[:version]}\n"
err_msg << "MySQL local version: #{mysql_v[:local_version]}\n"
err_msg << "The MySQL and SQLite versions do not match. Please run "
err_msg << "'onedb -i' in order to bootstrap a blank OpenNebula DB."
raise err_msg
end
backup(options[:backup], options)
file = "#{RUBY_LIB_LOCATION}/onedb/sqlite2mysql.rb"
load(file)
@backend.extend Sqlite2MySQL
@backend.convert(sqlite.backend.db)
return 0
end
private
def one_not_running()

View File

@ -286,7 +286,11 @@ class BackEndSQLite < OneDBBacKEnd
require 'fileutils'
def initialize(file)
@sqlite_file = file
if !file.nil?
@sqlite_file = file
else
raise "SQLite database path not supplied."
end
end
def bck_file

34
src/onedb/sqlite2mysql.rb Normal file
View File

@ -0,0 +1,34 @@
module Sqlite2MySQL
PROGRESS = 1000
def convert(sqlite_db)
puts "Starting migration from SQLite to MySQL\n"
sqlite_db.tables.each do |table|
@db[table].delete
records = sqlite_db[table].count
puts "> #{table} (#{records} records)"
@db.transaction do
i=0
sqlite_db[table].each do |row|
@db[table].insert(row)
i+=1
if i % PROGRESS == 0
if i < PROGRESS+1
print " #{i}"
else
print "...#{i}"
end
end
end
puts if i > PROGRESS-1
end
end
puts "\nMigration successful."
end
end

View File

@ -77,4 +77,42 @@
:show: true
:change_cardinality: true
# Attrs that cannot be modified when updating a VM template
:restricted_attrs:
- SCHED_REQUIREMENTS
- SERVICE_ID
- ROLE_NAME
# Actions that cannot be performed on a VM
:restricted_actions:
#- deploy
#- delete
#- hold
#- livemigrate
#- migrate
#- resume
#- release
#- stop
#- suspend
#- saveas
#- snapshot_create
#- snapshot_revert
#- snapshot_delete
#- shutdown
#- reboot
#- poweroff
#- resubmit
#- chown
#- chmod
#- resize
#- attachdisk
#- detachdisk
#- attachnic
#- detachnic
#- rename
#- undeploy
#- resched
#- unresched
#- recover

View File

@ -52,6 +52,22 @@ require 'opennebula/oneflow_client'
USER_AGENT = 'GATE'
# Attrs that cannot be modified when updating a VM template
# If this parameter is not defined in onegate-server.conf
# this constant will be used
RESTRICTED_ATTRS = [
'SCHED_REQUIREMENTS',
'SERVICE_ID',
'ROLE_NAME'
]
# Actions that cannot be triggered on a VM
# If this parameter is not defined in onegate-server.conf
# this constant will be used
RESTRICTED_ACTIONS = [
'reboot'
]
include OpenNebula
begin
@ -98,7 +114,13 @@ helpers do
logger.info { "Unauthorized login attempt" }
halt 401, "Not authorized"
else
return $cloud_auth.client(result)
client = $cloud_auth.client(result)
if client.nil?
logger.info { "Unauthorized login attempt" }
halt 401, "Not authorized"
end
return client
end
end
@ -124,6 +146,75 @@ helpers do
vm
end
# Retrieve the VM id from the header of the request and return
# an OpenNebula VirtualMachine object
def get_source_vm(request_env, client)
vm_id = request_env['HTTP_X_ONEGATE_VMID'].to_i
get_vm(vm_id, client)
end
def get_requested_vm(requested_vm_id, request_env, client)
source_vm = get_source_vm(request_env, client)
if source_vm['ID'] != requested_vm_id
service_id = source_vm['USER_TEMPLATE/SERVICE_ID']
check_vm_in_service(requested_vm_id, service_id, client)
requested_vm = get_vm(requested_vm_id, client)
else
requested_vm = source_vm
end
end
# Perform the action provided in the body of the request on the
# given VM. If error trigger a halt
def perform_action(vm, body)
action_hash = parse_json(body, 'action')
if OpenNebula.is_error?(action_hash)
halt 400, rc.message
end
check_restricted_actions(action_hash['perform'])
rc = case action_hash['perform']
when "deploy" then vm.deploy(action_hash['params'])
when "delete" then vm.finalize
when "hold" then vm.hold
when "livemigrate" then vm.migrate(action_hash['params'], true)
when "migrate" then vm.migrate(action_hash['params'], false)
when "resume" then vm.resume
when "release" then vm.release
when "stop" then vm.stop
when "suspend" then vm.suspend
when "saveas" then vm.save_as(action_hash['params'])
when "snapshot_create" then vm.snapshot_create(action_hash['params'])
when "snapshot_revert" then vm.snapshot_revert(action_hash['params'])
when "snapshot_delete" then vm.snapshot_delete(action_hash['params'])
when "shutdown" then vm.shutdown(action_hash['params'])
when "reboot" then vm.reboot(action_hash['params'])
when "poweroff" then vm.poweroff(action_hash['params'])
when "resubmit" then vm.resubmit
when "chown" then vm.chown(action_hash['params'])
when "chmod" then vm.chmod_octet(action_hash['params'])
when "resize" then vm.resize(action_hash['params'])
when "attachdisk" then vm.disk_attach(action_hash['params'])
when "detachdisk" then vm.disk_detach(action_hash['params'])
when "attachnic" then vm.nic_attach(action_hash['params'])
when "detachnic" then vm.nic_detach(action_hash['params'])
when "rename" then vm.rename(action_hash['params'])
when "undeploy" then vm.undeploy(action_hash['params'])
when "resched" then vm.resched
when "unresched" then vm.unresched
when "recover" then vm.recover(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
end
if OpenNebula.is_error?(rc)
halt 500, rc.message
end
end
def get_service(service_id, client)
if service_id.nil? || !service_id.match(/^\d+$/)
error_msg = "Empty or invalid SERVICE_ID"
@ -156,6 +247,38 @@ helpers do
end
end
# Attrs that cannot be modified when updating a VM template
def check_restricted_attrs(request)
body = request.body.read
body.split("\n").each{ |key_value|
parts = key_value.split('=')
if parts[0] && get_restricted_attrs.include?(parts[0].upcase)
error_msg = "Attribute (#{parts[0]}) cannot be modified"
logger.error {error_msg}
halt 403, error_msg
end
}
request.body.rewind
end
def get_restricted_attrs
$conf[':restricted_attrs'] || RESTRICTED_ATTRS
end
# Actions that cannot be performed on a VM
def check_restricted_actions(action)
if action && get_restricted_actions.include?(action.downcase)
error_msg = "Action (#{action}) is not allowed on this resource"
logger.error {error_msg}
halt 403, error_msg
end
end
def get_restricted_actions
$conf[':restricted_actions'] || RESTRICTED_ACTIONS
end
def check_permissions(resource, action)
permissions = settings.config[:permissions]
unless permissions && permissions[resource] && permissions[resource][action]
@ -164,6 +287,38 @@ helpers do
halt 403, error_msg
end
end
# Check if the source VM is part of a service and if the requested
# VM is part of the same Service as the source VM.
#
# If true the service hash is returned
# If false a halt is triggered
#
def check_vm_in_service(requested_vm_id, service_id, client)
service = get_service(service_id, client)
service_hash = JSON.parse(service)
response = build_service_hash(service_hash) rescue nil
if response.nil?
error_msg = "Service #{service_id} is empty."
logger.error {error_msg}
halt 400, error_msg
end
# Check that the user has not spoofed the Service_ID
service_vm_ids = response["SERVICE"]["roles"].collect do |r|
r["nodes"].collect{|n| n["deploy_id"]}
end.flatten rescue []
if service_vm_ids.empty? || !service_vm_ids.include?(requested_vm_id.to_i)
error_msg = "Service #{service_id} does not contain VM #{requested_vm_id}."
logger.error {error_msg}
halt 400, error_msg
end
return response
end
end
NIC_VALID_KEYS = %w(IP IP6_LINK IP6_SITE IP6_GLOBAL NETWORK MAC)
@ -248,7 +403,6 @@ end
get '/' do
client = authenticate(request.env, params)
halt 401, "Not authorized" if client.nil?
if $conf[:ssl_server]
base_uri = $conf[:ssl_server]
@ -268,19 +422,14 @@ end
put '/vm' do
check_permissions(:vm, :update)
client = authenticate(request.env, params)
halt 401, "Not authorized" if client.nil?
vm_id = request.env['HTTP_X_ONEGATE_VMID'].to_i
vm = get_vm(vm_id, client)
rc = vm.update(request.body.read, true)
source_vm = get_source_vm(request.env, client)
check_restricted_attrs(request)
rc = source_vm.update(request.body.read, true)
if OpenNebula.is_error?(rc)
logger.error {"VMID:#{vm_id} vm.update error: #{rc.message}"}
logger.error {"VMID:#{source_vm['ID']} vm.update error: #{rc.message}"}
halt 500, rc.message
end
@ -289,222 +438,52 @@ end
get '/vm' do
check_permissions(:vm, :show)
client = authenticate(request.env, params)
halt 401, "Not authorized" if client.nil?
vm_id = request.env['HTTP_X_ONEGATE_VMID'].to_i
vm = get_vm(vm_id, client)
response = build_vm_hash(vm.to_hash["VM"])
source_vm = get_source_vm(request.env, client)
response = build_vm_hash(source_vm.to_hash["VM"])
[200, response.to_json]
end
get '/service' do
check_permissions(:service, :show)
client = authenticate(request.env, params)
halt 401, "Not authorized" if client.nil?
vm_id = request.env['HTTP_X_ONEGATE_VMID'].to_i
vm = get_vm(vm_id, client)
service_id = vm['USER_TEMPLATE/SERVICE_ID']
service = get_service(service_id, client)
service_hash = JSON.parse(service)
response = build_service_hash(service_hash) rescue nil
if response.nil?
error_msg = "VMID:#{vm_id} Service #{service_id} is empty."
logger.error {error_msg}
halt 400, error_msg
end
# Check that the user has not spoofed the Service_ID
service_vm_ids = response["SERVICE"]["roles"].collect do |r|
r["nodes"].collect{|n| n["deploy_id"]}
end.flatten rescue []
if service_vm_ids.empty? || !service_vm_ids.include?(vm_id)
error_msg = "VMID:#{vm_id} Service #{service_id} does not contain VM."
logger.error {error_msg}
halt 400, error_msg
end
source_vm = get_source_vm(request.env, client)
service_id = source_vm['USER_TEMPLATE/SERVICE_ID']
response = check_vm_in_service(source_vm['ID'], service_id, client)
[200, response.to_json]
end
get '/vms/:id' do
check_permissions(:vm, :show_by_id)
client = authenticate(request.env, params)
halt 401, "Not authorized" if client.nil?
requested_vm = get_requested_vm(params[:id].to_i, request.env, client)
source_vm_id = request.env['HTTP_X_ONEGATE_VMID'].to_i
requested_vm_id = params[:id].to_i
vm = get_vm(source_vm_id, client)
service_id = vm['USER_TEMPLATE/SERVICE_ID']
service = get_service(service_id, client)
service_hash = JSON.parse(service)
response = build_service_hash(service_hash) rescue nil
if response.nil?
error_msg = "VMID:#{source_vm_id} Service #{service_id} is empty."
logger.error {error_msg}
halt 400, error_msg
end
# Check that the user has not spoofed the Service_ID
service_vm_ids = response["SERVICE"]["roles"].collect do |r|
r["nodes"].collect{|n| n["deploy_id"]}
end.flatten rescue []
if service_vm_ids.empty? || !service_vm_ids.include?(requested_vm_id)
error_msg = "VMID:#{requested_vm_id} Service #{service_id} does not contain VM."
logger.error {error_msg}
halt 400, error_msg
end
vm = get_vm(requested_vm_id, client)
response = build_vm_hash(vm.to_hash["VM"])
[200, response.to_json]
[200, build_vm_hash(requested_vm.to_hash["VM"]).to_json]
end
post '/vms/:id/action' do
check_permissions(:vm, :action_by_id)
client = authenticate(request.env, params)
halt 401, "Not authorized" if client.nil?
requested_vm = get_requested_vm(params[:id].to_i, request.env, client)
source_vm_id = request.env['HTTP_X_ONEGATE_VMID'].to_i
requested_vm_id = params[:id].to_i
vm = get_vm(source_vm_id, client)
service_id = vm['USER_TEMPLATE/SERVICE_ID']
service = get_service(service_id, client)
service_hash = JSON.parse(service)
response = build_service_hash(service_hash) rescue nil
if response.nil?
error_msg = "VMID:#{source_vm_id} Service #{service_id} is empty."
logger.error {error_msg}
halt 400, error_msg
end
# Check that the user has not spoofed the Service_ID
service_vm_ids = response["SERVICE"]["roles"].collect do |r|
r["nodes"].collect{|n| n["deploy_id"]}
end.flatten rescue []
if service_vm_ids.empty? || !service_vm_ids.include?(requested_vm_id)
error_msg = "VMID:#{requested_vm_id} Service #{service_id} does not contain VM."
logger.error {error_msg}
halt 400, error_msg
end
vm = get_vm(requested_vm_id, client)
action_hash = parse_json(request.body.read, 'action')
if OpenNebula.is_error?(action_hash)
halt 400, rc.message
end
rc = case action_hash['perform']
when "deploy" then vm.deploy(action_hash['params'])
when "delete" then vm.finalize
when "hold" then vm.hold
when "livemigrate" then vm.migrate(action_hash['params'], true)
when "migrate" then vm.migrate(action_hash['params'], false)
when "resume" then vm.resume
when "release" then vm.release
when "stop" then vm.stop
when "suspend" then vm.suspend
when "saveas" then vm.save_as(action_hash['params'])
when "snapshot_create" then vm.snapshot_create(action_hash['params'])
when "snapshot_revert" then vm.snapshot_revert(action_hash['params'])
when "snapshot_delete" then vm.snapshot_delete(action_hash['params'])
when "shutdown" then vm.shutdown(action_hash['params'])
when "reboot" then vm.reboot(action_hash['params'])
when "poweroff" then vm.poweroff(action_hash['params'])
when "resubmit" then vm.resubmit
when "chown" then vm.chown(action_hash['params'])
when "chmod" then vm.chmod_octet(action_hash['params'])
when "resize" then vm.resize(action_hash['params'])
when "attachdisk" then vm.disk_attach(action_hash['params'])
when "detachdisk" then vm.disk_detach(action_hash['params'])
when "attachnic" then vm.nic_attach(action_hash['params'])
when "detachnic" then vm.nic_detach(action_hash['params'])
when "update" then vm.update(action_hash['params'])
when "rename" then vm.rename(action_hash['params'])
when "undeploy" then vm.undeploy(action_hash['params'])
when "resched" then vm.resched
when "unresched" then vm.unresched
when "recover" then vm.recover(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
end
if OpenNebula.is_error?(rc)
halt 500, rc.message
else
[204, vm.to_json]
end
perform_action(requested_vm, request.body.read)
[204, requested_vm.to_json]
end
put '/service/role/:role' do
check_permissions(:service, :change_cardinality)
client = authenticate(request.env, params)
halt 401, "Not authorized" if client.nil?
source_vm = get_source_vm(request.env, client)
service_id = source_vm['USER_TEMPLATE/SERVICE_ID']
vm_id = request.env['HTTP_X_ONEGATE_VMID'].to_i
vm = get_vm(vm_id, client)
service_id = vm['USER_TEMPLATE/SERVICE_ID']
service = get_service(service_id, client)
service_hash = JSON.parse(service)
response = build_service_hash(service_hash) rescue nil
if response.nil?
error_msg = "VMID:#{vm_id} Service #{service_id} is empty."
logger.error {error_msg}
halt 400, error_msg
end
# Check that the user has not spoofed the Service_ID
service_vm_ids = response["SERVICE"]["roles"].collect do |r|
r["nodes"].collect{|n| n["deploy_id"]}
end.flatten rescue []
if service_vm_ids.empty? || !service_vm_ids.include?(vm_id)
error_msg = "VMID:#{vm_id} Service #{service_id} does not contain VM."
logger.error {error_msg}
halt 400, error_msg
end
check_vm_in_service(source_vm['ID'], service_id, client)
action_response = flow_client(client).put(
"/service/" + service_id + "/role/" + params[:role],
@ -522,21 +501,12 @@ end
put '/vms/:id' do
check_permissions(:vm, :update_by_id)
client = authenticate(request.env, params)
halt 401, "Not authorized" if client.nil?
vm = VirtualMachine.new_with_id(params[:id], client)
rc = vm.info
if OpenNebula.is_error?(rc)
logger.error {"VMID:#{params[:id]} vm.info error: #{rc.message}"}
halt 404, rc.message
end
rc = vm.update(request.body.read, true)
requested_vm = get_requested_vm(params[:id].to_i, request.env, client)
check_restricted_attrs(request)
rc = requested_vm.update(request.body.read, true)
if OpenNebula.is_error?(rc)
logger.error {"VMID:#{params[:id]} vm.update error: #{rc.message}"}
halt 500, rc.message

View File

@ -27,11 +27,13 @@ int ObjectCollection::from_xml_node(const xmlNodePtr node)
ostringstream oss;
vector<string>::iterator it;
vector<string> ids;
ObjectXML oxml(node);
oss << "/" << collection_name << "/ID";
vector<string> ids = oxml[oss.str().c_str()];
oxml.xpaths(ids, oss.str().c_str());
for (it = ids.begin(); it != ids.end(); it++)
{

View File

@ -293,6 +293,8 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
string ds_name;
string ds_data;
bool ds_persistent_only;
Datastore::DatastoreType ds_type;
int rc, id;
@ -325,6 +327,7 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
long long avail;
bool ds_check;
bool persistent_attr;
string extra_data = "";
@ -369,9 +372,10 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
ds->get_permissions(ds_perms);
ds_name = ds->get_name();
ds_disk_type = ds->get_disk_type();
ds_check = ds->get_avail_mb(avail);
ds_name = ds->get_name();
ds_disk_type = ds->get_disk_type();
ds_check = ds->get_avail_mb(avail);
ds_persistent_only = ds->is_persistent_only();
ds->to_xml(ds_data);
@ -505,6 +509,21 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
}
}
// ------------------------- Check persistent only -------------------------
tmpl->get("PERSISTENT", persistent_attr);
if ( ds_persistent_only && persistent_attr == false )
{
att.resp_msg = "This Datastore only accepts persistent images.";
failure_response(ALLOCATE, att);
delete tmpl;
return;
}
// ------------------------- Allocate --------------------------------------
rc = ipool->allocate(att.uid,
att.gid,
att.uname,

View File

@ -66,6 +66,13 @@ void ImagePersistent::request_execute(xmlrpc_c::paramList const& paramList,
bool persistent_flag = xmlrpc_c::value_boolean(paramList.getBoolean(2));
int rc;
int ds_id;
int ds_persistent_only;
Nebula& nd = Nebula::instance();
DatastorePool * dspool = nd.get_dspool();
Datastore * ds;
Image * image;
if ( basic_authorization(id, att) == false )
@ -83,6 +90,34 @@ void ImagePersistent::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
ds_id = image->get_ds_id();
image->unlock();
ds = dspool->get(ds_id, true);
if ( ds == 0 )
{
att.resp_msg = "Datastore no longer exists.";
failure_response(INTERNAL, att);
return;
}
ds_persistent_only = ds->is_persistent_only();
ds->unlock();
image = static_cast<Image *>(pool->get(id,true));
if ( image == 0 )
{
att.resp_id = id;
failure_response(NO_EXISTS, att);
return;
}
switch (image->get_type())
{
case Image::OS:
@ -99,6 +134,16 @@ void ImagePersistent::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
/* Check if datastore allows the operation */
if ( ds_persistent_only && persistent_flag == false )
{
att.resp_msg = "This Datastore only accepts persistent images.";
failure_response(INTERNAL, att);
image->unlock();
return;
}
rc = image->persistent(persistent_flag, att.resp_msg);
if ( rc != 0 )

View File

@ -19,6 +19,7 @@
#include "Log.h"
#include "HostPoolXML.h"
#include "UserPoolXML.h"
#include "ClusterPoolXML.h"
#include "DatastorePoolXML.h"
#include "VirtualMachinePoolXML.h"
@ -54,6 +55,7 @@ protected:
vmapool(0),
dspool(0),
img_dspool(0),
upool(0),
acls(0),
timer(0),
url(""),
@ -76,6 +78,8 @@ protected:
delete dspool;
delete img_dspool;
delete upool;
delete acls;
delete client;
@ -92,6 +96,7 @@ protected:
VirtualMachineActionsPoolXML* vmapool;
SystemDatastorePoolXML * dspool;
ImageDatastorePoolXML * img_dspool;
UserPoolXML * upool;
AclXML * acls;

View File

@ -44,6 +44,11 @@ private:
* Sets the defaults value for the template
*/
void set_conf_default();
/**
* Sets the defaults value for multiple attributes
*/
void set_multiple_conf_default(){};
};
#endif /*SCHEDULER_TEMPLATE_H_*/

View File

@ -0,0 +1,57 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2015, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#ifndef USER_POOL_XML_H_
#define USER_POOL_XML_H_
#include <vector>
#include "PoolXML.h"
#include "UserXML.h"
class UserPoolXML : public PoolXML
{
public:
UserPoolXML(Client* client):PoolXML(client){};
~UserPoolXML(){};
/**
* Gets an object from the pool
* @param oid the object unique identifier
*
* @return a pointer to the object, 0 in case of failure
*/
UserXML * get(int oid) const
{
return static_cast<UserXML *>(PoolXML::get(oid));
};
protected:
int get_suitable_nodes(std::vector<xmlNodePtr>& content)
{
return get_nodes("/USER_POOL/USER", content);
};
void add_object(xmlNodePtr node);
int load_info(xmlrpc_c::value &result);
};
#endif /* USER_POOL_XML_H_ */

View File

@ -0,0 +1,57 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2015, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#ifndef USER_XML_H_
#define USER_XML_H_
#include "ObjectXML.h"
class UserXML : public ObjectXML
{
public:
UserXML(const string &xml_doc):ObjectXML(xml_doc)
{
init_attributes();
};
UserXML(const xmlNodePtr node):ObjectXML(node)
{
init_attributes();
};
int get_oid() const
{
return oid;
};
const std::vector<int>& get_gids() const
{
return gids;
};
private:
int oid;
std::vector<int> gids;
void init_attributes()
{
xpath(oid, "/USER/ID", -1);
xpaths(gids,"/USER/GROUPS/ID");
};
};
#endif /* USER_XML_H_ */

View File

@ -53,8 +53,11 @@ void HostXML::init_attributes()
public_cloud = (one_util::toupper(public_cloud_st) == "YES");
//-------------------- HostShare Datastores ------------------------------
vector<string> ds_ids = (*this)["/HOST/HOST_SHARE/DATASTORES/DS/ID"];
vector<string> ds_free = (*this)["/HOST/HOST_SHARE/DATASTORES/DS/FREE_MB"];
vector<string> ds_ids;
vector<string> ds_free;
xpaths(ds_ids, "/HOST/HOST_SHARE/DATASTORES/DS/ID");
xpaths(ds_free,"/HOST/HOST_SHARE/DATASTORES/DS/FREE_MB");
int id;
long long disk;
@ -99,7 +102,9 @@ int HostXML::search(const char *name, int& value)
istringstream iss;
int id;
vector<string> results = (*this)["/HOST/VMS/ID"];
vector<string> results;
xpaths(results, "/HOST/VMS/ID");
for (it=results.begin(); it!=results.end(); it++)
{

View File

@ -27,6 +27,7 @@ source_files=[
'VirtualMachinePoolXML.cc',
'VirtualMachineXML.cc',
'ClusterPoolXML.cc',
'UserPoolXML.cc',
'DatastorePoolXML.cc',
'DatastoreXML.cc']

View File

@ -0,0 +1,62 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2015, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "UserPoolXML.h"
void UserPoolXML::add_object(xmlNodePtr node)
{
if ( node == 0 || node->children == 0 )
{
NebulaLog::log("USER",Log::ERROR,
"XML Node does not represent a valid user");
return;
}
UserXML* user = new UserXML( node );
objects.insert( pair<int,ObjectXML*>(user->get_oid(), user) );
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int UserPoolXML::load_info(xmlrpc_c::value &result)
{
try
{
client->call(client->get_endpoint(), // serverUrl
"one.userpool.info", // methodName
"s", // arguments format
&result, // resultP
client->get_oneauth().c_str() // argument
);
return 0;
}
catch (exception const& e)
{
ostringstream oss;
oss << "Exception raised: " << e.what();
NebulaLog::log("USER", Log::ERROR, oss);
return -1;
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -321,6 +321,7 @@ void Scheduler::start()
// -------------------------------------------------------------------------
hpool = new HostPoolXML(client);
upool = new UserPoolXML(client);
clpool = new ClusterPoolXML(client);
vmpool = new VirtualMachinePoolXML(client,machines_limit,(live_rescheds==1));
@ -430,8 +431,6 @@ int Scheduler::set_up_pools()
//Cleans the cache and get the datastores
//--------------------------------------------------------------------------
// TODO: Avoid two ds pool info calls to oned
rc = dspool->set_up();
if ( rc != 0 )
@ -450,6 +449,17 @@ int Scheduler::set_up_pools()
//Cleans the cache and get the hosts ids
//--------------------------------------------------------------------------
rc = upool->set_up();
if ( rc != 0 )
{
return rc;
}
//--------------------------------------------------------------------------
//Cleans the cache and get the hosts ids
//--------------------------------------------------------------------------
rc = hpool->set_up();
if ( rc != 0 )
@ -499,6 +509,8 @@ int Scheduler::set_up_pools()
* 2. Meets user/policy requirements
* 3. Have enough capacity to host the VM
*
* @param acl pool
* @param users the user pool
* @param vm the virtual machine
* @param vm_memory vm requirement
* @param vm_cpu vm requirement
@ -511,9 +523,9 @@ int Scheduler::set_up_pools()
* @param error, string describing why the host is not valid
* @return true for a positive match
*/
static bool match_host(AclXML * acls, VirtualMachineXML* vm, int vmem, int vcpu,
vector<Attribute *>& vpci, HostXML * host, int &n_auth, int& n_error,
int &n_fits, int &n_matched, string &error)
static bool match_host(AclXML * acls, UserPoolXML * upool, VirtualMachineXML* vm,
int vmem, int vcpu, vector<Attribute *>& vpci, HostXML * host, int &n_auth,
int& n_error, int &n_fits, int &n_matched, string &error)
{
// -------------------------------------------------------------------------
// Filter current Hosts for resched VMs
@ -544,10 +556,17 @@ static bool match_host(AclXML * acls, VirtualMachineXML* vm, int vmem, int vcpu,
hperms.cid = host->get_cid();
hperms.obj_type = PoolObjectSQL::HOST;
// Only include the VM group ID
UserXML * user = upool->get(vm->get_uid());
set<int> gids;
gids.insert(vm->get_gid());
if (user == 0)
{
error = "User does not exists.";
return false;
}
const vector<int> vgids = user->get_gids();
set<int> gids(vgids.begin(), vgids.end());
if ( !acls->authorize(vm->get_uid(), gids, hperms, AuthRequest::MANAGE))
{
@ -614,6 +633,8 @@ static bool match_host(AclXML * acls, VirtualMachineXML* vm, int vmem, int vcpu,
* 1. Meet user/policy requirements
* 2. Have enough capacity to host the VM
*
* @param acl pool
* @param users the user pool
* @param vm the virtual machine
* @param vdisk vm requirement
* @param ds to evaluate vm assgiment
@ -624,9 +645,9 @@ static bool match_host(AclXML * acls, VirtualMachineXML* vm, int vmem, int vcpu,
* @param error, string describing why the host is not valid
* @return true for a positive match
*/
static bool match_system_ds(AclXML * acls, VirtualMachineXML* vm, long long vdisk,
DatastoreXML * ds, int& n_auth, int& n_error, int& n_fits, int &n_matched,
string &error)
static bool match_system_ds(AclXML * acls, UserPoolXML * upool,
VirtualMachineXML* vm, long long vdisk, DatastoreXML * ds, int& n_auth,
int& n_error, int& n_fits, int &n_matched, string &error)
{
// -------------------------------------------------------------------------
// Check if user is authorized
@ -637,10 +658,17 @@ static bool match_system_ds(AclXML * acls, VirtualMachineXML* vm, long long vdis
ds->get_permissions(dsperms);
// Only include the VM group ID
UserXML * user = upool->get(vm->get_uid());
set<int> gids;
gids.insert(vm->get_gid());
if (user == 0)
{
error = "User does not exists.";
return false;
}
const vector<int> vgids = user->get_gids();
set<int> gids(vgids.begin(), vgids.end());
if ( !acls->authorize(vm->get_uid(), gids, dsperms, AuthRequest::USE))
{
@ -740,6 +768,7 @@ void Scheduler::match_schedule()
const map<int, ObjectXML*> pending_vms = vmpool->get_objects();
const map<int, ObjectXML*> hosts = hpool->get_objects();
const map<int, ObjectXML*> datastores = dspool->get_objects();
const map<int, ObjectXML*> users = upool->get_objects();
double total_match_time = 0;
double total_rank_time = 0;
@ -790,8 +819,8 @@ void Scheduler::match_schedule()
{
host = static_cast<HostXML *>(h_it->second);
if (match_host(acls, vm, vm_memory, vm_cpu, vm_pci, host, n_auth,
n_error, n_fits, n_matched, m_error))
if (match_host(acls, upool, vm, vm_memory, vm_cpu, vm_pci, host,
n_auth, n_error, n_fits, n_matched, m_error))
{
vm->add_match_host(host->get_hid());
@ -894,8 +923,8 @@ void Scheduler::match_schedule()
{
ds = static_cast<DatastoreXML *>(h_it->second);
if (match_system_ds(acls, vm, vm_disk, ds, n_auth, n_error, n_fits,
n_matched, m_error))
if (match_system_ds(acls, upool, vm, vm_disk, ds, n_auth, n_error,
n_fits, n_matched, m_error))
{
vm->add_match_datastore(ds->get_oid());

View File

@ -52,6 +52,7 @@ tabs:
panel_tabs:
user_info_tab: true
user_quotas_tab: true
user_groups_tab: true
user_accounting_tab: true
user_showback_tab: true
table_columns:
@ -65,11 +66,13 @@ tabs:
- 7 # CPU
#- 8 # Group ID
#- 9 # Hidden User Data
#- 10 # Labels
actions:
User.refresh: true
User.create_dialog: true
User.update_password: true
User.quotas_dialog: true
User.groups_dialog: true
User.chgrp: true
User.addgroup: true
User.delgroup: true
@ -90,6 +93,7 @@ tabs:
- 4 # VMs
- 5 # Memory
- 6 # CPU
#- 7 # Labels
actions:
Group.refresh: true
Group.create_dialog: true
@ -110,6 +114,7 @@ tabs:
- 5 # Hosts
- 6 # VNets
- 7 # Datastores
#- 8 # Labels
actions:
Vdc.refresh: true
Vdc.create_dialog: true
@ -160,6 +165,7 @@ tabs:
#- 10 # Start Time
- 11 # VNC
#- 12 # Hidden Template
#- 13 # Labels
actions:
VM.refresh: true
VM.create_dialog: true
@ -211,6 +217,7 @@ tabs:
- 3 # Group
- 4 # Name
- 5 # Registration time
#- 6 # Labels
actions:
Template.refresh: true
Template.create_dialog: true
@ -253,6 +260,7 @@ tabs:
- 10 # Status
- 11 # #VMs
#- 12 # Target
#- 13 # Labels
actions:
Image.refresh: true
Image.create_dialog: true
@ -286,6 +294,7 @@ tabs:
- 10 # Status
#- 11 # #VMs
#- 12 # Target
#- 13 # Labels
actions:
File.refresh: true
File.create_dialog: true
@ -312,6 +321,7 @@ tabs:
- 3 # Hosts
- 4 # VNets
- 5 # Datastores
#- 6 # Labels
actions:
Cluster.refresh: true
Cluster.create_dialog: true
@ -340,6 +350,7 @@ tabs:
#- 10 # IM MAD
#- 11 # VM MAD
#- 12 # Last monitored on
#- 13 # Labels
actions:
Host.refresh: true
Host.create_dialog: true
@ -365,6 +376,7 @@ tabs:
#- 9 # DS
- 10 # Type
- 11 # Status
#- 12 # Labels
actions:
Datastore.refresh: true
Datastore.create_dialog: true
@ -399,6 +411,7 @@ tabs:
#- 7 # Bridge
- 8 # Leases
#- 9 # VLAN ID
#- 10 # Labels
actions:
Network.refresh: true
Network.create_dialog: true
@ -424,6 +437,7 @@ tabs:
- 2 # Owner
- 3 # Group
- 4 # Name
#- 5 # Labels
actions:
SecurityGroup.refresh: true
SecurityGroup.create_dialog: true
@ -524,6 +538,7 @@ tabs:
Service.chown: true
Service.chgrp: true
Service.chmod: true
Service.rename: true
Service.shutdown: true
Service.recover: true
Service.delete: true
@ -544,6 +559,8 @@ tabs:
ServiceTemplate.chown: true
ServiceTemplate.chgrp: true
ServiceTemplate.chmod: true
ServiceTemplate.rename: true
ServiceTemplate.clone: true
ServiceTemplate.delete: true
zones-tab:
panel_tabs:
@ -553,6 +570,7 @@ tabs:
- 1 # ID
- 2 # Name
- 3 # Endpoint
#- 4 # Labels
actions:
Zone.refresh: true
Zone.create_dialog: true

View File

@ -51,6 +51,7 @@ tabs:
panel_tabs:
user_info_tab: true
user_quotas_tab: true
user_groups_tab: true
user_accounting_tab: true
user_showback_tab: true
table_columns:
@ -64,11 +65,13 @@ tabs:
- 7 # CPU
#- 8 # Group ID
#- 9 # Hidden User Data
#- 10 # Labels
actions:
User.refresh: true
User.create_dialog: true
User.update_password: true
User.quotas_dialog: true
User.groups_dialog: true
User.chgrp: true
User.addgroup: true
User.delgroup: true
@ -89,6 +92,7 @@ tabs:
- 4 # VMs
- 5 # Memory
- 6 # CPU
#- 7 # Labels
actions:
Group.refresh: true
Group.create_dialog: true
@ -109,6 +113,7 @@ tabs:
- 5 # Hosts
- 6 # VNets
- 7 # Datastores
#- 8 # Labels
actions:
Vdc.refresh: true
Vdc.create_dialog: true
@ -159,6 +164,7 @@ tabs:
#- 10 # Start Time
- 11 # VNC
#- 12 # Hidden Template
#- 13 # Labels
actions:
VM.refresh: true
VM.create_dialog: true
@ -210,6 +216,7 @@ tabs:
- 3 # Group
- 4 # Name
- 5 # Registration time
#- 6 # Labels
actions:
Template.refresh: true
Template.create_dialog: true
@ -252,6 +259,7 @@ tabs:
- 10 # Status
- 11 # #VMs
#- 12 # Target
#- 13 # Labels
actions:
Image.refresh: true
Image.create_dialog: true
@ -285,6 +293,7 @@ tabs:
- 10 # Status
#- 11 # #VMs
#- 12 # Target
#- 13 # Labels
actions:
File.refresh: true
File.create_dialog: true
@ -311,6 +320,7 @@ tabs:
- 3 # Hosts
- 4 # VNets
- 5 # Datastores
#- 6 # Labels
actions:
Cluster.refresh: true
Cluster.create_dialog: true
@ -339,6 +349,7 @@ tabs:
#- 10 # IM MAD
#- 11 # VM MAD
#- 12 # Last monitored on
#- 13 # Labels
actions:
Host.refresh: true
Host.create_dialog: true
@ -364,6 +375,7 @@ tabs:
#- 9 # DS
- 10 # Type
- 11 # Status
#- 12 # Labels
actions:
Datastore.refresh: true
Datastore.create_dialog: true
@ -393,6 +405,7 @@ tabs:
#- 7 # Bridge
- 8 # Leases
#- 9 # VLAN ID
#- 10 # Labels
actions:
Network.refresh: true
Network.create_dialog: true
@ -418,6 +431,7 @@ tabs:
- 2 # Owner
- 3 # Group
- 4 # Name
#- 5 # Labels
actions:
SecurityGroup.refresh: true
SecurityGroup.create_dialog: true
@ -518,6 +532,7 @@ tabs:
Service.chown: true
Service.chgrp: true
Service.chmod: true
Service.rename: true
Service.shutdown: true
Service.recover: true
Service.delete: true
@ -538,6 +553,8 @@ tabs:
ServiceTemplate.chown: true
ServiceTemplate.chgrp: true
ServiceTemplate.chmod: true
ServiceTemplate.rename: true
ServiceTemplate.clone: true
ServiceTemplate.delete: true
zones-tab:
panel_tabs:
@ -547,6 +564,7 @@ tabs:
- 1 # ID
- 2 # Name
- 3 # Endpoint
#- 4 # Labels
actions:
Zone.refresh: true
Zone.create_dialog: true

View File

@ -52,6 +52,7 @@ tabs:
panel_tabs:
user_info_tab: true
user_quotas_tab: true
user_groups_tab: true
user_accounting_tab: true
user_showback_tab: true
table_columns:
@ -65,11 +66,13 @@ tabs:
- 7 # CPU
#- 8 # Group ID
#- 9 # Hidden User Data
#- 10 # Labels
actions:
User.refresh: true
User.create_dialog: true
User.update_password: true
User.quotas_dialog: true
User.groups_dialog: true
User.chgrp: true
User.addgroup: true
User.delgroup: true
@ -90,6 +93,7 @@ tabs:
- 4 # VMs
- 5 # Memory
- 6 # CPU
#- 7 # Labels
actions:
Group.refresh: true
Group.create_dialog: true
@ -110,6 +114,7 @@ tabs:
- 5 # Hosts
- 6 # VNets
- 7 # Datastores
#- 8 # Labels
actions:
Vdc.refresh: true
Vdc.create_dialog: true
@ -160,6 +165,7 @@ tabs:
#- 10 # Start Time
- 11 # VNC
#- 12 # Hidden Template
#- 13 # Labels
actions:
VM.refresh: true
VM.create_dialog: true
@ -211,6 +217,7 @@ tabs:
- 3 # Group
- 4 # Name
- 5 # Registration time
#- 6 # Labels
actions:
Template.refresh: true
Template.create_dialog: true
@ -253,6 +260,7 @@ tabs:
- 10 # Status
- 11 # #VMs
#- 12 # Target
#- 13 # Labels
actions:
Image.refresh: true
Image.create_dialog: true
@ -286,6 +294,7 @@ tabs:
- 10 # Status
#- 11 # #VMs
#- 12 # Target
#- 13 # Labels
actions:
File.refresh: true
File.create_dialog: true
@ -312,6 +321,7 @@ tabs:
- 3 # Hosts
- 4 # VNets
- 5 # Datastores
#- 6 # Labels
actions:
Cluster.refresh: true
Cluster.create_dialog: true
@ -340,6 +350,7 @@ tabs:
#- 10 # IM MAD
#- 11 # VM MAD
#- 12 # Last monitored on
#- 13 # Labels
actions:
Host.refresh: true
Host.create_dialog: true
@ -365,6 +376,7 @@ tabs:
#- 9 # DS
#- 10 # Type
#- 11 # Status
#- 12 # Labels
actions:
Datastore.refresh: true
Datastore.create_dialog: false
@ -394,6 +406,7 @@ tabs:
#- 7 # Bridge
- 8 # Leases
#- 9 # VLAN ID
#- 10 # Labels
actions:
Network.refresh: true
Network.create_dialog: false
@ -419,6 +432,7 @@ tabs:
- 2 # Owner
- 3 # Group
- 4 # Name
#- 5 # Labels
actions:
SecurityGroup.refresh: true
SecurityGroup.create_dialog: true
@ -519,6 +533,7 @@ tabs:
Service.chown: false
Service.chgrp: false
Service.chmod: true
Service.rename: true
Service.shutdown: true
Service.recover: true
Service.delete: true
@ -539,6 +554,8 @@ tabs:
ServiceTemplate.chown: false
ServiceTemplate.chgrp: false
ServiceTemplate.chmod: true
ServiceTemplate.rename: true
ServiceTemplate.clone: true
ServiceTemplate.delete: true
zones-tab:
panel_tabs:
@ -548,6 +565,7 @@ tabs:
- 1 # ID
- 2 # Name
- 3 # Endpoint
#- 4 # Labels
actions:
Zone.refresh: true
Zone.create_dialog: true

View File

@ -77,7 +77,11 @@ module OpenNebulaJSON
end
def update(params=Hash.new)
super(params['template_raw'])
if !params['append'].nil?
super(params['template_raw'], params['append'])
else
super(params['template_raw'])
end
end
def rename(params=Hash.new)

View File

@ -61,7 +61,11 @@ module OpenNebulaJSON
end
def update(params=Hash.new)
super(params['template_raw'])
if !params['append'].nil?
super(params['template_raw'], params['append'])
else
super(params['template_raw'])
end
end
def chown(params=Hash.new)

View File

@ -53,7 +53,11 @@ module OpenNebulaJSON
end
def update_json(params=Hash.new)
update(params['template_raw'])
if !params['append'].nil?
update(params['template_raw'], params['append'])
else
update(params['template_raw'])
end
end
def set_quota(params=Hash.new)

View File

@ -60,7 +60,11 @@ module OpenNebulaJSON
end
def update(params=Hash.new)
super(params['template_raw'])
if !params['append'].nil?
super(params['template_raw'], params['append'])
else
super(params['template_raw'])
end
end
def rename(params=Hash.new)

View File

@ -71,7 +71,11 @@ module OpenNebulaJSON
end
def update(params=Hash.new)
super(params['template_raw'])
if !params['append'].nil?
super(params['template_raw'], params['append'])
else
super(params['template_raw'])
end
end
def remove_attr(params=Hash.new)

View File

@ -57,7 +57,11 @@ module OpenNebulaJSON
end
def update(params=Hash.new)
super(params['template_raw'])
if !params['append'].nil?
super(params['template_raw'], params['append'])
else
super(params['template_raw'])
end
end
def chown(params=Hash.new)

View File

@ -70,14 +70,11 @@ module OpenNebulaJSON
end
def update(params=Hash.new)
template_hash = parse_json(params, 'vmtemplate')
if template_hash['template_raw']
template = template_hash['template_raw']
if !params['append'].nil?
super(params['template_raw'], params['append'])
else
template = template_to_str(template_hash)
super(params['template_raw'])
end
super(template)
end
def chown(params=Hash.new)

View File

@ -104,7 +104,11 @@ module OpenNebulaJSON
end
def update(params=Hash.new)
super(params['template_raw'])
if !params['append'].nil?
super(params['template_raw'], params['append'])
else
super(params['template_raw'])
end
end
def rename(params=Hash.new)

View File

@ -173,7 +173,11 @@ module OpenNebulaJSON
end
def update(params=Hash.new)
super(params['template_raw'])
if !params['append'].nil?
super(params['template_raw'], params['append'])
else
super(params['template_raw'])
end
end
def rename(params=Hash.new)

View File

@ -62,7 +62,11 @@ module OpenNebulaJSON
end
def update(params=Hash.new)
super(params['template_raw'])
if !params['append'].nil?
super(params['template_raw'], params['append'])
else
super(params['template_raw'])
end
end
def chown(params=Hash.new)

View File

@ -49,7 +49,11 @@ module OpenNebulaJSON
end
def update(params=Hash.new)
super(params['template_raw'])
if !params['append'].nil?
super(params['template_raw'], params['append'])
else
super(params['template_raw'])
end
end
def rename(params=Hash.new)

View File

@ -80,15 +80,15 @@ class SunstoneViews
return available.uniq
end
if group["TEMPLATE/SUNSTONE_VIEWS"]
views_array = group["TEMPLATE/SUNSTONE_VIEWS"].split(",")
if group["TEMPLATE/SUNSTONE/VIEWS"]
views_array = group["TEMPLATE/SUNSTONE/VIEWS"].split(",")
available << views_array.each{|v| v.strip!}
elsif @views_config['groups']
available << @views_config['groups'][group.name]
end
gadmins = group.admin_ids
gadmins_views = group["TEMPLATE/GROUP_ADMIN_VIEWS"]
gadmins_views = group["TEMPLATE/SUNSTONE/GROUP_ADMIN_VIEWS"]
if gadmins && gadmins.include?(user.id) && gadmins_views
views_array = gadmins_views.split(",")

View File

@ -20,17 +20,26 @@ Sunstone dependencies
Building minified JS and CSS files
==================================
4. Run the following command to generate the app.css file in the css folder:
The dependencies defined in the previous section must be instaled before running these commands:
Option A - Grunt
----------------
* Run the following command to generate the app.css file in the css folder:
```
grunt sass
```
5. Run the following command to generate the minified js files in the dist foler
* Run the following command to generate the minified js files in the dist foler
and the app.min.css in the css folder:
```
grunt requirejs
```
These are the files generate by the grunt requirejs command:
```
css
app.min.css
@ -40,10 +49,11 @@ These are the files generate by the grunt requirejs command:
spice.js spice.js.map vnc.js vnc.js.map
```
Scons
=====
Option B - Scons
----------------
Scons includes an option to build the minified JS and CSS files.
Scons includes an option to build the minified JS and CSS files. Steps 1, 2 and 3 have to be performed before running this command
```
scons sunstone=yes
```
@ -52,3 +62,58 @@ Install.sh
==========
By default the install.sh script will install all the files, including the non-minified ones. Providing the -p option, only the minified files will be installed.
Documentation
=============
[JSDoc](http://usejsdoc.org/) is used for the JS documentation.
Examples
--------
* Parameters with properties
```
/**
* Assign the project to an employee.
* @param {Object} employee - The employee who is responsible for the project.
* @param {string} employee.name - The name of the employee.
* @param {string} employee.department - The employee's department.
*/
Project.prototype.assign = function(employee) {
// ...
};
```
* Optional parameter
```
/**
* @param {string} [somebody] - Somebody's name.
*/
function sayHello(somebody) {
if (!somebody) {
somebody = 'John Doe';
}
alert('Hello ' + somebody);
}
```
* Returns
```
/**
* Returns the sum of a and b
* @param {Number} a
* @param {Number} b
* @param {Boolean} retArr If set to true, the function will return an array
* @returns {Number|Array} Sum of a and b or an array that contains a, b and the sum of a and b.
*/
function sum(a, b, retArr) {
if (retArr) {
return [a, b, a + b];
}
return a + b;
}
```

View File

@ -53,7 +53,7 @@ define(function(require) {
_setupCloseDropdownsOnClick();
_insertUserAndZoneSelector();
Config.initDefaultCost();
Config.initOnedConf();
if (Config.isTabEnabled(PROVISION_TAB_ID)) {
Sunstone.showTab(PROVISION_TAB_ID);

View File

@ -64,6 +64,10 @@ define(function(require) {
var action_obj = {"template_raw" : params.data.extra_param};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"append": function(params) {
var action_obj = {"template_raw" : params.data.extra_param, append : true};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"rename" : function(params) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "rename", action_obj);

View File

@ -79,6 +79,10 @@ define(function(require) {
var action_obj = {"template_raw" : params.data.extra_param};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"append": function(params) {
var action_obj = {"template_raw" : params.data.extra_param, append : true};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"rename" : function(params) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "rename", action_obj);

View File

@ -60,6 +60,10 @@ define(function(require) {
var action_obj = {"template_raw" : params.data.extra_param};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"append": function(params) {
var action_obj = {"template_raw" : params.data.extra_param, append : true};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"set_quota" : function(params) {
var action_obj = {quotas : params.data.extra_param};
OpenNebulaAction.simple_action(params, RESOURCE, "set_quota", action_obj);

View File

@ -99,6 +99,11 @@ define(function(require) {
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
_clearCache();
},
"append": function(params) {
var action_obj = {"template_raw" : params.data.extra_param, append : true};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
_clearCache();
},
"enable": function(params) {
OpenNebulaAction.simple_action(params, RESOURCE, "enable");
_clearCache();

View File

@ -93,6 +93,10 @@ define(function(require) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "chmod", action_obj);
},
"append": function(params) {
var action_obj = {"template_raw" : params.data.extra_param, append : true};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"update": function(params) {
var action_obj = {"template_raw" : params.data.extra_param};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);

View File

@ -80,6 +80,10 @@ define(function(require) {
var action_obj = {"template_raw" : params.data.extra_param};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"append": function(params) {
var action_obj = {"template_raw" : params.data.extra_param, append : true};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"rename" : function(params) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "rename", action_obj);

View File

@ -48,6 +48,10 @@ define(function(require) {
var action_obj = {"template_raw" : params.data.extra_param};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"append": function(params) {
var action_obj = {"template_raw" : params.data.extra_param, append : true};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"clone" : function(params) {
var name = params.data.extra_param ? params.data.extra_param : "";
var action_obj = {"name" : name};

View File

@ -85,6 +85,10 @@ define(function(require) {
params.cache_name = CACHE_NAME;
OpenNebulaAction.simple_action(params, RESOURCE, "recover", null, PATH);
},
"rename" : function(params) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "rename", action_obj, PATH);
},
"stateStr" : function(stateId) {
return STATES_STR[stateId];
},

View File

@ -63,6 +63,15 @@ define(function(require) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "chmod", action_obj, PATH);
},
"rename" : function(params) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "rename", action_obj, PATH);
},
"clone" : function(params) {
var name = params.data.extra_param ? params.data.extra_param : "";
var action_obj = {"name" : name};
OpenNebulaAction.simple_action(params, RESOURCE, "clone", action_obj, PATH);
},
"getName": function(id){
return OpenNebulaAction.getName(id, CACHE_NAME);
}

View File

@ -50,8 +50,12 @@ define(function(require) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "chmod_from_provision", action_obj);
},
"append": function(params) {
var action_obj = {"template_raw" : params.data.extra_param, append : true};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"update" : function(params) {
var action_obj = params.data.extra_param;
var action_obj = {"template_raw" : params.data.extra_param};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"publish" : function(params) {

View File

@ -37,6 +37,10 @@ define(function(require) {
var action_obj = {"template_raw" : params.data.extra_param};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"append": function(params) {
var action_obj = {"template_raw" : params.data.extra_param, append : true};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"rename" : function(params) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "rename", action_obj);

View File

@ -459,6 +459,10 @@ define(function(require) {
}
});
},
"append": function(params) {
var action_obj = {"template_raw" : params.data.extra_param, append : true};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"update": function(params) {
var action_obj = {"template_raw" : params.data.extra_param};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);

View File

@ -37,6 +37,10 @@ define(function(require) {
var action_obj = {"template_raw" : params.data.extra_param};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"append": function(params) {
var action_obj = {"template_raw" : params.data.extra_param, append : true};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"rename" : function(params) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "rename", action_obj);

View File

@ -27,6 +27,11 @@ define(function(require) {
diskCost : 0
};
var _dsMadConf = {};
var _imMadConf = {};
var _vmMadConf = {};
var _authMadConf = {};
var Config = {
'isTabEnabled': function(tabName) {
var enabled = _config['view']['enabled_tabs'].indexOf(tabName) != -1;
@ -62,7 +67,7 @@ define(function(require) {
if (_config['view']['tabs'][tabName]['provision_tabs']) {
return _config['view']['tabs'][tabName]['provision_tabs'][panelTabName];
} else {
// if provision_tabs is not defined use panel_tabs.
// if provision_tabs is not defined use panel_tabs.
// This attribute was used in before 4.14, provision_tabs was include in 4.14.2
return _config['view']['tabs'][tabName]['panel_tabs'][panelTabName];
}
@ -152,7 +157,11 @@ define(function(require) {
'vmLogos': (_config['vm_logos']),
'enabledTabs': _config['view']['enabled_tabs'],
"defaultCost" : _defaultCost,
"initDefaultCost" : function() {
'dsMadConf' : _dsMadConf,
'imMadConf' : _imMadConf,
'vmMadConf' : _vmMadConf,
'authMadConf' : _authMadConf,
"initOnedConf" : function() {
OpenNebulaSystem.onedconf({
data : {},
timeout: true,
@ -168,6 +177,22 @@ define(function(require) {
_defaultCost.diskCost = parseInt(onedconf.DEFAULT_COST.DISK_COST);
}
}
if (onedconf.DS_MAD_CONF != undefined){
$.extend(true, _dsMadConf, onedconf.DS_MAD_CONF);
}
if (onedconf.IM_MAD != undefined){
$.extend(true, _imMadConf, onedconf.IM_MAD);
}
if (onedconf.VM_MAD != undefined){
$.extend(true, _vmMadConf, onedconf.VM_MAD);
}
if (onedconf.AUTH_MAD != undefined){
$.extend(true, _authMadConf, onedconf.AUTH_MAD);
}
},
error: function(request, error_json){
console.error("There was an error requesting oned.conf: "+

View File

@ -131,8 +131,15 @@ define(function(require) {
}
var _setupDataTable = function(tabName) {
if (SunstoneCfg['tabs'][tabName].dataTable) {
SunstoneCfg['tabs'][tabName].dataTable.initialize();
var dataTable = SunstoneCfg['tabs'][tabName].dataTable;
if (dataTable) {
dataTable.initialize();
if (dataTable.labelsColumn) {
$('#' + tabName + 'labels_buttons').html(
'<button href="#" data-dropdown="' + tabName + 'LabelsDropdown" class="only-right-info only-right-list top_button small secondary button dropdown radius">' +
'<i class="fa fa-tags"/></button>' +
'<ul id="' + tabName + 'LabelsDropdown" class="only-right-info only-right-list labels-dropdown f-dropdown" data-dropdown-content></ul>');
}
}
}
@ -454,13 +461,13 @@ define(function(require) {
var _setupTabs = function() {
var topTabs = $(".left-content ul li.topTab");
var subTabs = $(".left-content ul li.subTab");
var subTabs = $(".left-content ul li.subTab > a");
subTabs.on("click", function() {
if ($(this).hasClass('topTab')) {
if ($(this).closest('li').hasClass('topTab')) {
return false;
} else {
var tabName = $(this).attr('id').substring(3);
var tabName = $(this).closest('li').attr('id').substring(3);
_showTab(tabName);
return false;
}
@ -527,6 +534,7 @@ define(function(require) {
//clean selected menu
$("#navigation li").removeClass("navigation-active-li");
$("#navigation li#li_" + tabName).addClass("navigation-active-li");
$('.tree', '#navigation').remove();
var tab = $('#' + tabName);
//show tab
@ -534,6 +542,9 @@ define(function(require) {
var dataTable = SunstoneCfg['tabs'][tabName]['dataTable'];
if (dataTable) {
if (dataTable.clearLabelsFilter) {
dataTable.clearLabelsFilter();
}
dataTable.recountCheckboxes();
}
@ -971,6 +982,12 @@ define(function(require) {
}
}
var _getResource = function(tabName) {
if (SunstoneCfg['tabs'][tabName]) {
return SunstoneCfg['tabs'][tabName].resource;
}
}
var _getDialogInstance = function(dialogId) {
var dialogInstance = SunstoneCfg['dialogInstances'][dialogId];
if (dialogInstance == undefined) {
@ -1011,6 +1028,7 @@ define(function(require) {
"getAction": _getAction,
"getButton": _getButton,
"getDataTable": _getDataTable,
"getResource": _getResource,
"getDialog": _getDialogInstance,
"insertButtonsInTab": _insertButtonsInTab,

View File

@ -29,6 +29,7 @@
</span>
<span class="right" style="margin-left: 20px">
<span id='{{customId}}labels_buttons' class='only-right-info only-right-list'></span>
<button href='#' data-dropdown='{{customId}}user_buttons' class='only-right-info only-right-list top_button small secondary button dropdown radius'>
<i class='fa fa-user'/></button>
<ul id='{{customId}}user_buttons' class='only-right-info only-right-list f-dropdown' data-dropdown-content></ul>

View File

@ -273,18 +273,35 @@ define(function(require) {
}
function _onShow(context) {
ResourceSelect.insert('div#applies_to_user', context, "User", null, true);
ResourceSelect.insert('div#applies_to_group', context, "Group", null, true);
ResourceSelect.insert({
context: $('#applies_to_user', context),
resourceName: 'User',
emptyValue: true
});
ResourceSelect.insert('div#belonging_to', context, "Group", null, true);
ResourceSelect.insert('#in_cluster',context, "Cluster", null, true);
ResourceSelect.insert({
context: $('#applies_to_group', context),
resourceName: 'Group',
emptyValue: true
});
// TODO BUG: doesn't work if the cluster.list callback is not finished yet
// Delete cluster -1 option
$('#in_cluster select option[value="-1"]',context).remove();
ResourceSelect.insert({
context: $('#belonging_to', context),
resourceName: 'Group',
emptyValue: true
});
ResourceSelect.insert('div#zones_applies', context, "Zone", "*", false,
'<option value="*">'+Locale.tr("All")+'</option>');
ResourceSelect.insert({
context: $('#in_cluster', context),
resourceName: 'Cluster',
emptyValue: true
});
ResourceSelect.insert({
context: $('#zones_applies', context),
resourceName: 'Zone',
initValue: '*',
extraOptions: '<option value="*">' + Locale.tr("All") + '</option>'
});
}
});

View File

@ -37,6 +37,7 @@ define(function(require) {
"Cluster.refresh" : _commonActions.refresh(),
"Cluster.delete" : _commonActions.del(),
"Cluster.update_template" : _commonActions.updateTemplate(),
"Cluster.append_template" : _commonActions.appendTemplate(),
"Cluster.update_dialog" : _commonActions.checkAndShowUpdate(),
"Cluster.show_to_update" : _commonActions.showUpdate(CREATE_DIALOG_ID),
"Cluster.rename": _commonActions.singleAction('rename'),

View File

@ -22,6 +22,7 @@ define(function(require) {
var TabDataTable = require('utils/tab-datatable');
var SunstoneConfig = require('sunstone-config');
var Locale = require('utils/locale');
var LabelsUtils = require('utils/labels/utils');
/*
CONSTANTS
@ -30,6 +31,8 @@ define(function(require) {
var RESOURCE = "Cluster";
var XML_ROOT = "CLUSTER";
var TAB_NAME = require('./tabId');
var LABELS_COLUMN = 6;
var TEMPLATE_ATTR = 'TEMPLATE';
/*
CONSTRUCTOR
@ -41,6 +44,7 @@ define(function(require) {
this.dataTableId = dataTableId;
this.resource = RESOURCE;
this.xmlRoot = XML_ROOT;
this.labelsColumn = LABELS_COLUMN;
this.dataTableOptions = {
"bAutoWidth": false,
@ -59,7 +63,8 @@ define(function(require) {
Locale.tr("Name"),
Locale.tr("Hosts"),
Locale.tr("VNets"),
Locale.tr("Datastores")
Locale.tr("Datastores"),
Locale.tr("Labels")
];
this.selectOptions = {
@ -95,7 +100,8 @@ define(function(require) {
element.NAME,
_lengthOf(element.HOSTS.ID),
_lengthOf(element.VNETS.ID),
_lengthOf(element.DATASTORES.ID)
_lengthOf(element.DATASTORES.ID),
(LabelsUtils.labelsStr(element[TEMPLATE_ATTR])||'')
];
}

View File

@ -42,6 +42,7 @@ define(function(require) {
"Datastore.chmod": _commonActions.singleAction('chmod'),
"Datastore.update" : _commonActions.updateTemplate(),
"Datastore.update_template" : _commonActions.updateTemplate(),
"Datastore.append_template" : _commonActions.appendTemplate(),
"Datastore.rename": _commonActions.singleAction('rename'),
"Datastore.enable": _commonActions.multipleAction('enable'),
"Datastore.disable": _commonActions.multipleAction('disable'),

View File

@ -24,6 +24,7 @@ define(function(require) {
var Locale = require('utils/locale');
var OpenNebulaDatastore = require('opennebula/datastore');
var DatastoreCapacityBar = require('./utils/datastore-capacity-bar');
var LabelsUtils = require('utils/labels/utils');
/*
CONSTANTS
@ -32,6 +33,8 @@ define(function(require) {
var RESOURCE = "Datastore";
var XML_ROOT = "DATASTORE";
var TAB_NAME = require('./tabId');
var LABELS_COLUMN = 12;
var TEMPLATE_ATTR = 'TEMPLATE';
/*
CONSTRUCTOR
@ -57,6 +60,7 @@ define(function(require) {
this.dataTableId = dataTableId;
this.resource = RESOURCE;
this.xmlRoot = XML_ROOT;
this.labelsColumn = LABELS_COLUMN;
this.dataTableOptions = {
"bAutoWidth": false,
@ -83,6 +87,7 @@ define(function(require) {
Locale.tr("DS MAD"),
Locale.tr("Type"),
Locale.tr("Status"),
Locale.tr("Labels")
]
this.selectOptions = {
@ -125,7 +130,8 @@ define(function(require) {
element.TM_MAD,
element.DS_MAD,
OpenNebulaDatastore.typeStr(element.TYPE),
OpenNebulaDatastore.stateStr(element.STATE)
OpenNebulaDatastore.stateStr(element.STATE),
(LabelsUtils.labelsStr(element[TEMPLATE_ATTR])||'')
];
}
});

View File

@ -26,6 +26,7 @@ define(function(require) {
var Notifier = require('utils/notifier');
var Tips = require('utils/tips');
var ResourceSelect = require('utils/resource-select');
var Config = require('sunstone-config');
/*
TEMPLATES
@ -94,8 +95,19 @@ define(function(require) {
var cluster_id_raw = $("div#datastore_cluster_raw .resource_list_select", dialog).val();
if (!cluster_id_raw) cluster_id_raw = "-1";
ResourceSelect.insert('div#cluster_id', dialog, "Cluster", cluster_id, false);
ResourceSelect.insert('div#datastore_cluster_raw', dialog, "Cluster", cluster_id_raw, false);
ResourceSelect.insert({
context: $('#cluster_id', dialog),
resourceName: 'Cluster',
initValue: cluster_id,
includeDefaultCluster: true
});
ResourceSelect.insert({
context: $('#datastore_cluster_raw', dialog),
resourceName: 'Cluster',
initValue: cluster_id_raw,
includeDefaultCluster: true
});
return false;
}
@ -109,10 +121,12 @@ define(function(require) {
'input[name="ds_tab_custom_tm_mad"]', dialog).parent().hide();
$('select#ds_mad', dialog).change(function() {
if ($(this).val() == "custom")
if ($(this).val() == "custom") {
$('input[name="ds_tab_custom_ds_mad"]', dialog).parent().show();
else
$('input[name="ds_tab_custom_ds_mad"]', dialog).parent().hide();
} else {
_setRequiredFields(dialog, $(this).val());
$('input[name="ds_tab_custom_ds_mad"]', dialog).parent().hide();
}
});
$('select#tm_mad', dialog).change(function() {
@ -125,6 +139,7 @@ define(function(require) {
$('#presets', dialog).change(function() {
_hideAll(dialog);
var choice_str = $(this).val();
switch (choice_str)
{
case 'fs':
@ -148,12 +163,17 @@ define(function(require) {
case 'dev':
_selectDevices(dialog);
break;
case 'iscsi':
_selectISCSI(dialog);
break;
case 'custom':
_selectCustom(dialog);
break;
}
});
$('#presets', dialog).change();
// Hide disk_type
$('select#disk_type', dialog).parent().hide();
@ -192,6 +212,9 @@ define(function(require) {
var rbd_format = $('#rbd_format', dialog).val();
var staging_dir = $('#staging_dir', dialog).val();
var ceph_conf = $('#ceph_conf', dialog).val();
var iscsi_host = $('#iscsi_host', dialog).val();
var iscsi_user = $('#iscsi_user', dialog).val();
var iscsi_usage = $('#iscsi_usage', dialog).val();
var ds_obj = {
"datastore" : {
@ -265,6 +288,15 @@ define(function(require) {
if (ceph_conf)
ds_obj.datastore.ceph_conf = ceph_conf;
if (iscsi_host)
ds_obj.datastore.iscsi_host = iscsi_host;
if (iscsi_user)
ds_obj.datastore.iscsi_user = iscsi_user;
if (iscsi_usage)
ds_obj.datastore.iscsi_usage = iscsi_usage;
Sunstone.runAction("Datastore.create", ds_obj);
return false;
}
@ -308,6 +340,9 @@ define(function(require) {
$('label[for="rbd_format"],input#rbd_format', dialog).parent().hide();
$('label[for="staging_dir"],input#staging_dir', dialog).parent().hide();
$('label[for="ceph_conf"],input#ceph_conf', dialog).parent().hide();
$('label[for="iscsi_host"],input#iscsi_host', dialog).parent().hide();
$('label[for="iscsi_user"],input#iscsi_user', dialog).parent().hide();
$('label[for="iscsi_usage"],input#iscsi_usage', dialog).parent().hide();
$('label[for="limit_transfer_bw"],input#limit_transfer_bw', dialog).parent().hide();
$('label[for="no_decompress"],input#no_decompress', dialog).parent().hide();
$('select#ds_mad', dialog).removeAttr('disabled');
@ -325,7 +360,7 @@ define(function(require) {
}
function _selectFilesystem(dialog) {
$('select#ds_mad', dialog).val('fs');
$('select#ds_mad', dialog).val('fs').change();
$('select#tm_mad', dialog).val('shared');
$('select#ds_mad', dialog).attr('disabled', 'disabled');
$('select#tm_mad', dialog).children('option').each(function() {
@ -354,7 +389,7 @@ define(function(require) {
function _selectVmwareVmfs(dialog) {
$('label[for="bridge_list"],input#bridge_list', dialog).parent().fadeIn();
$('label[for="ds_tmp_dir"],input#ds_tmp_dir', dialog).parent().fadeIn();
$('select#ds_mad', dialog).val('vmfs');
$('select#ds_mad', dialog).val('vmfs').change();
$('select#ds_mad', dialog).attr('disabled', 'disabled');
$('select#tm_mad', dialog).val('vmfs');
$('select#tm_mad', dialog).attr('disabled', 'disabled');
@ -372,7 +407,7 @@ define(function(require) {
function _selectCeph(dialog) {
$('input#image_ds_type', dialog).click();
$('input#file_ds_type', dialog).attr('disabled', 'disabled');
$('select#ds_mad', dialog).val('ceph');
$('select#ds_mad', dialog).val('ceph').change();
$('select#ds_mad', dialog).attr('disabled', 'disabled');
$('select#tm_mad', dialog).val('ceph');
$('select#tm_mad', dialog).attr('disabled', 'disabled');
@ -396,7 +431,7 @@ define(function(require) {
}
function _selectBlockLvm(dialog) {
$('select#ds_mad', dialog).val('lvm');
$('select#ds_mad', dialog).val('lvm').change();
$('select#ds_mad', dialog).attr('disabled', 'disabled');
$('select#tm_mad', dialog).val('lvm');
$('select#tm_mad', dialog).attr('disabled', 'disabled');
@ -416,7 +451,7 @@ define(function(require) {
}
function _selectFsLvm(dialog) {
$('select#ds_mad', dialog).val('fs');
$('select#ds_mad', dialog).val('fs').change();
$('select#ds_mad', dialog).attr('disabled', 'disabled');
$('select#tm_mad', dialog).val('fs_lvm');
$('select#tm_mad', dialog).attr('disabled', 'disabled');
@ -434,7 +469,7 @@ define(function(require) {
}
function _selectGluster(dialog) {
$('select#ds_mad', dialog).val('fs');
$('select#ds_mad', dialog).val('fs').change();
$('select#ds_mad', dialog).attr('disabled', 'disabled');
$('select#tm_mad', dialog).val('shared');
$('select#tm_mad', dialog).children('option').each(function() {
@ -461,7 +496,7 @@ define(function(require) {
}
function _selectDevices(dialog) {
$('select#ds_mad', dialog).val('dev');
$('select#ds_mad', dialog).val('dev').change();
$('select#ds_mad', dialog).attr('disabled', 'disabled');
$('select#tm_mad', dialog).val('dev');
$('select#tm_mad', dialog).attr('disabled', 'disabled');
@ -478,9 +513,30 @@ define(function(require) {
$('input#restricted_dirs', dialog).attr('disabled', 'disabled');
}
function _selectISCSI(dialog) {
$('select#ds_mad', dialog).val('iscsi').change();
$('select#ds_mad', dialog).attr('disabled', 'disabled');
$('select#tm_mad', dialog).val('iscsi');
$('select#tm_mad', dialog).attr('disabled', 'disabled');
$('input#image_ds_type', dialog).click();
$('input[name=ds_type]', dialog).attr('disabled', 'disabled');
$('label[for="iscsi_host"],input#iscsi_host', dialog).parent().fadeIn();
$('label[for="iscsi_user"],input#iscsi_user', dialog).parent().fadeIn();
$('label[for="iscsi_usage"],input#iscsi_usage', dialog).parent().fadeIn();
$('select#disk_type', dialog).val('iscsi');
$('select#disk_type', dialog).attr('disabled', 'disabled');
$('label[for="limit_transfer_bw"],input#limit_transfer_bw', dialog).parent().hide();
$('label[for="no_decompress"],input#no_decompress', dialog).parent().hide();
$('label[for="datastore_capacity_check"],input#datastore_capacity_check', dialog).parent().hide();
$('input#safe_dirs', dialog).attr('disabled', 'disabled');
$('input#base_path', dialog).attr('disabled', 'disabled');
$('input#limit_mb', dialog).attr('disabled', 'disabled');
$('input#restricted_dirs', dialog).attr('disabled', 'disabled');
}
function _selectCustom(dialog) {
_hideAll(dialog);
$('select#ds_mad', dialog).val('fs');
$('select#ds_mad', dialog).val('fs').change();
$('select#tm_mad', dialog).val('shared');
$('input#safe_dirs', dialog).removeAttr('disabled');
$('select#disk_type', dialog).removeAttr('disabled');
@ -491,4 +547,24 @@ define(function(require) {
$('label[for="no_decompress"],input#no_decompress', dialog).parent().fadeIn();
$('label[for="datastore_capacity_check"],input#datastore_capacity_check', dialog).parent().fadeIn();
}
function _setRequiredFields(dialog, mad) {
// Disable all required attributes except for those that come in the
// template.
$('[required_active]', dialog).removeAttr('required')
.removeAttr('required_active');
$.each(Config.dsMadConf, function(i, e){
if (e["NAME"] == mad) {
if (!$.isEmptyObject(e["REQUIRED_ATTRS"])) {
$.each(e["REQUIRED_ATTRS"].split(","), function(i, e){
$('#' + e.toLowerCase(), dialog).attr('required', true).attr('required_active', '');
});
}
return false;
}
}
);
}
});

View File

@ -32,6 +32,7 @@
<option value="ceph">{{tr "Ceph"}}</option>
<option value="gluster">{{tr "Gluster"}}</option>
<option value="dev">{{tr "Devices"}}</option>
<option value="iscsi">{{tr "iSCSI"}}</option>
<option value="custom">{{tr "Custom"}}</option>
</select>
</div>
@ -68,6 +69,7 @@
<option value="vmfs">{{tr "VMFS"}}</option>
<option value="ceph">{{tr "Ceph"}}</option>
<option value="dev">{{tr "Devices"}}</option>
<option value="iscsi">{{tr "iSCSI"}}</option>
<option value="custom">{{tr "Custom"}}</option>
</select>
<div>
@ -86,6 +88,7 @@
<option value="vmfs">{{tr "VMFS"}}</option>
<option value="ceph">{{tr "Ceph"}}</option>
<option value="dev">{{tr "Devices"}}</option>
<option value="iscsi">{{tr "iSCSI"}}</option>
<option value="custom">{{tr "Custom"}}</option>
</select>
<div>
@ -104,6 +107,7 @@
<option value="block">{{tr "Block"}}</option>
<option value="RBD">{{tr "RBD"}}</option>
<option value="gluster">{{tr "Gluster"}}</option>
<option value="iscsi">{{tr "iSCSI"}}</option>
</select>
</div>
</div>
@ -267,5 +271,32 @@
</label>
<input type="text" name="ceph_conf" id="ceph_conf" />
</div>
<div class="medium-6 columns">
<label for="iscsi_host">
{{tr "iSCSI Host"}}
<span class="tip">
{{tr "The iSCSI Host. Example: 'host' or 'host:port' (if no port is specified, the default one is chosen)."}}
</span>
</label>
<input type="text" name="iscsi_host" id="iscsi_host" />
</div>
<div class="medium-6 columns">
<label for="iscsi_user">
{{tr "iSCSI User"}}
<span class="tip">
{{tr "The iSCSI User."}}
</span>
</label>
<input type="text" name="iscsi_user" id="iscsi_user" />
</div>
<div class="medium-6 columns">
<label for="iscsi_usage">
{{tr "iSCSI Usage"}}
<span class="tip">
{{tr "'Usage' of the registered secret that contains the CHAP Authentication string."}}
</span>
</label>
<input type="text" name="iscsi_usage" id="iscsi_usage" />
</div>
</div>
</form>

View File

@ -36,6 +36,7 @@ define(function(require) {
"File.refresh" : _commonActions.refresh(),
"File.delete" : _commonActions.del(),
"File.update_template" : _commonActions.updateTemplate(),
"File.append_template" : _commonActions.appendTemplate(),
"File.chown": _commonActions.multipleAction('chown'),
"File.chgrp": _commonActions.multipleAction('chgrp'),
"File.chmod": _commonActions.singleAction('chmod'),

View File

@ -25,6 +25,7 @@ define(function(require) {
var Humanize = require('utils/humanize');
var Notifier = require('utils/notifier');
var OpenNebulaImage = require('opennebula/image');
var LabelsUtils = require('utils/labels/utils');
/*
CONSTANTS
@ -33,6 +34,8 @@ define(function(require) {
var RESOURCE = "File";
var XML_ROOT = "IMAGE";
var TAB_NAME = require('./tabId');
var LABELS_COLUMN = 13;
var TEMPLATE_ATTR = 'TEMPLATE';
/*
CONSTRUCTOR
@ -44,6 +47,7 @@ define(function(require) {
this.dataTableId = dataTableId;
this.resource = RESOURCE;
this.xmlRoot = XML_ROOT;
this.labelsColumn = LABELS_COLUMN;
this.dataTableOptions = {
"bAutoWidth": false,
@ -70,13 +74,14 @@ define(function(require) {
Locale.tr("Status"),
Locale.tr("#VMS"),
Locale.tr("Target"),
Locale.tr("Labels")
];
this.selectOptions = {
"id_index": 1,
"name_index": 4,
"uname_index": 2,
"select_resource": Locale.tr("Please select an file from the list"),
"select_resource": Locale.tr("Please select a file from the list"),
"you_selected": Locale.tr("You selected the following file:"),
"select_resource_multiple": Locale.tr("Please select one or more files from the list"),
"you_selected_multiple": Locale.tr("You selected the following files:")
@ -119,7 +124,8 @@ define(function(require) {
parseInt(element.PERSISTENT) ? "yes" : "no",
OpenNebulaImage.stateStr(element.STATE),
element.RUNNING_VMS,
element.TEMPLATE.TARGET ? element.TEMPLATE.TARGET : '--'
element.TEMPLATE.TARGET ? element.TEMPLATE.TARGET : '--',
(LabelsUtils.labelsStr(element[TEMPLATE_ATTR])||'')
];
}
});

View File

@ -28,6 +28,7 @@ define(function(require) {
var Tips = require('utils/tips');
var ResourceSelect = require('utils/resource-select');
var BrowserInfo = require('utils/browser-info');
var OpenNebulaDatastore = require('opennebula/datastore');
var TemplateWizardHTML = require('hbs!./create/wizard');
var TemplateAdvancedHTML = require('hbs!./create/advanced');
@ -92,15 +93,21 @@ define(function(require) {
var ds_id = $('#file_datastore .resource_list_select', context).val();
var ds_id_raw = $('#file_datastore_raw .resource_list_select', context).val();
// Filter out DS with type image (0) or system (1)
var filter_att = ["TYPE", "TYPE"];
var filter_val = ["0", "1"];
ResourceSelect.insert({
context: $('#file_datastore', context),
resourceName: 'Datastore',
initValue: ds_id,
filterKey: 'TYPE',
filterValue: '' + OpenNebulaDatastore.TYPES.FILE_DS
});
ResourceSelect.insert('div#file_datastore', context, "Datastore",
ds_id, false, null, filter_att, filter_val);
ResourceSelect.insert('div#file_datastore_raw', context, "Datastore",
ds_id_raw, false, null, filter_att, filter_val);
ResourceSelect.insert({
context: $('#file_datastore_raw', context),
resourceName: 'Datastore',
initValue: ds_id_raw,
filterKey: 'TYPE',
filterValue: '' + OpenNebulaDatastore.TYPES.FILE_DS
});
return false;
}

View File

@ -40,6 +40,7 @@ define(function(require) {
"Group.delete" : _commonActions.del(),
"Group.update" : _commonActions.update(),
"Group.update_template" : _commonActions.updateTemplate(),
"Group.append_template" : _commonActions.appendTemplate(),
"Group.update_dialog" : _commonActions.checkAndShowUpdate(),
"Group.show_to_update" : _commonActions.showUpdate(CREATE_DIALOG_ID),

View File

@ -24,6 +24,7 @@ define(function(require) {
var Locale = require('utils/locale');
var QuotaDefaults = require('utils/quotas/quota-defaults');
var QuotaWidgets = require('utils/quotas/quota-widgets');
var LabelsUtils = require('utils/labels/utils');
/*
CONSTANTS
@ -32,6 +33,8 @@ define(function(require) {
var RESOURCE = "Group";
var XML_ROOT = "GROUP";
var TAB_NAME = require('./tabId');
var LABELS_COLUMN = 7;
var TEMPLATE_ATTR = 'TEMPLATE';
/*
CONSTRUCTOR
@ -43,6 +46,7 @@ define(function(require) {
this.dataTableId = dataTableId;
this.resource = RESOURCE;
this.xmlRoot = XML_ROOT;
this.labelsColumn = LABELS_COLUMN;
this.dataTableOptions = {
"bAutoWidth": false,
@ -63,7 +67,8 @@ define(function(require) {
Locale.tr("Users"),
Locale.tr("VMs"),
Locale.tr("Memory"),
Locale.tr("CPU")
Locale.tr("CPU"),
Locale.tr("Labels")
];
this.selectOptions = {
@ -141,7 +146,8 @@ define(function(require) {
users_str,
vms,
memory,
cpu
cpu,
(LabelsUtils.labelsStr(element[TEMPLATE_ATTR])||'')
];
}

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