diff --git a/src/sunstone/public/js/monitoring.js b/src/sunstone/public/js/monitoring.js
index 5b31bc1fd6..e2efa88563 100644
--- a/src/sunstone/public/js/monitoring.js
+++ b/src/sunstone/public/js/monitoring.js
@@ -15,26 +15,82 @@
/* -------------------------------------------------------------------------- */
+/* This files act as helper to manage gathering and plotting of data
+ in dashboards. */
+
+// Monitoring configuration is composed of diferent configurations that can
+// be added anytime. According to its values, data is gathered and processed
+// for resources. Example:
+/*
+SunstoneMonitoringConfig['HOST'] = {
+ plot: function(monitoring){
+ // receives monitoring data object, with monitoring series
+ // information for this resource. monitoring object contains one key per monitoring value below. Normally you can call SunstoneMonitoring.plot() directly
+ // with each of the series
+ },
+ monitor : {
+ //This object defines what data is collected and how. i.e.
+ "statePie" : {
+ // must be an element of resource object. If its a second level
+ // key, then write as ['TEMPLATE','MAX_CPU']
+ partitionPath: "STATE", //Will create a partition looking at...
+
+ // A function that receives the list of elements and returns
+ // a set of series with the relevant information ready
+ // ready to be plotted
+ operation: SunstoneMonitoring.ops.partition //processing function
+
+ // "pie" or "bars", according to this the series will be
+ // formatted in different ways.
+ dataType: "pie", //In what format data is collected (for what plot)
+ colorize: function(state){ //how to color the series.
+ // ie. pie sectors depending on host state
+ }
+ },
+ plotOptions : {
+ //jquery flot plot options. See host plugin directly. This options
+ //are passed to flot on SunstoneMonitoring.plot().
+ }
+ },
+ "cpuPerCluster" : {
+ path: ["HOST_SHARE","CPU_USAGE"], //second level data
+ partitionPath: "CLUSTER_ID", //partition data according to...
+ operation: SunstoneMonitoring.ops.partition, //processing
+ dataType: "bars",
+ plotOptions: {
+ }
+ }
+ ...
+
+See sunstone plugins for more info and examples
+*/
+
+
var SunstoneMonitoringConfig = {}
var SunstoneMonitoring = {
monitor : function(resource, list){
-
+ // Runs the monitoring operation for each monitor object option
+ // on the list of resources that comes as parameter.
+ // Forms the monitoring object with the results and calls
+ // the plotting function (defined in config).
if (!SunstoneMonitoringConfig[resource])
return false
var monConfigs = SunstoneMonitoringConfig[resource].monitor
var monitoring = {}
- for (conf in monConfigs){
+ for (conf in monConfigs){ //for each of the things we want to monitor
var conf_obj = monConfigs[conf]
var plotID = conf
var series = conf_obj.operation(resource, list, conf_obj)
monitoring[plotID]=series
}
- //Call back after monitorization is done
SunstoneMonitoringConfig[resource].plot(monitoring)
},
plot : function(resource,plotID,container,series){
+ // Calls the jQuery flot library plot()
+ // with the plotOptions from the configuration for the resource.
+ // If series (monitoring info) is empty, put message instead.
var config = SunstoneMonitoringConfig[resource].monitor[plotID]
var options = config.plotOptions
@@ -47,31 +103,56 @@ var SunstoneMonitoring = {
}
},
ops : {
+ // Functions to process data contained in a list of resources in a
+ // specific way. The result is a series array containing the
+ // information, in the format jQuery flot expects it to plot.
partition : function(resource,list,config){
+ // Partitions data according to partitionPath.
+ // That is, it groups resources according to the value of
+ // partitionPath (for example, by CLUSTER), and counts
+ // how many of them are in each group (so it can be plotted).
+ // If path is provided (for example MEMORY),
+ // then it sums the value of path, instead
+ // of counting.
+
+ // We use this for state pies, memory/cpu by cluster graphs,
+ // users per group graphs...
+
var path = config.path
var partitionPath = config.partitionPath
- var dataType = config.dataType
+ var dataType = config.dataType //which way the series should look like for flot
+
var partitions = {}
+
+ // for each element (for example HOST) in the list
for (var i=0; i< list.length; i++){
var elem = list[i][resource]
var value = path ? parseInt(explore_path(elem,path),10) : 1
var partition = explore_path(elem, partitionPath)
- //Things on cluster none
+ // Things on cluster none hack
if ((partitionPath == "CLUSTER" && !partition.length) ||
(partitionPath == "CLUSTER_ID" && partition == "-1"))
partition = "none"
+ // If the partition group is not there, we create it
if (!partitions[partition])
partitions[partition] = value
+ // Otherwise we sum the value to it.
else
partitions[partition] += value
}
+ // Now we have to format the data in the partitions according
+ // to what flot expects.
+ // Note that for bars the values of our x axis are fixed to
+ // [0, 1, 2...] this values are later not shown or alternatively
+ // the ticks are renamed with the axis_labels names.
+
var series = []
var axis_labels = []
var i = 0;
- for (partition in partitions) {
+ for (partition in partitions) { //for each partition
var value = partitions[partition]
var data;
switch (dataType){
@@ -84,15 +165,21 @@ var SunstoneMonitoring = {
default:
data = value;
}
+ // prepare labels for the axis ticks
+ // for example CLUSTER names
axis_labels.push([i,partition])
+
+ // set color of this bar/pie sector
var color = config.colorize ? config.colorize(partition) : null
+
+ // push the data in the series
series.push({ label: partition,
data: data,
color: color
})
i++
}
-
+ // Modify configuration with custom labels.
if (config.plotOptions.xaxis &&
config.plotOptions.xaxis.customLabels == true){
config.plotOptions.xaxis.ticks = axis_labels
@@ -102,6 +189,8 @@ var SunstoneMonitoring = {
return series
},
hostCpuUsagePartition : function(resource,list,config){
+ // Work as function above, except that partition is pre-defined
+ // and hosts are divided into them according to cpu usage.
var partitions = {
"Idle" : 0,
"Ok" : 0,
@@ -139,25 +228,38 @@ var SunstoneMonitoring = {
return series
},
totalize : function(resource,list,config){
+ // just count how many items are in the list
return list.length
},
singleBar : function(resource,list,config){
- var paths = config.paths
+ // Paint data series on a single horizontal bar
+ // For example used_memory together with memory_usage and max_memory
+ // or net_tx vs. net_rx
+ // For each data object in the series, a total sum is calculated
+ var paths = config.paths // array of paths
+ // each path can be an array too if it is >= 2nd level path
+
+ // initialize sums
var totals = new Array(paths.length)
for (var i=0; i< totals.length; i++) totals[i] = 0
var series = []
+ // for each item (i.e. HOST), add the value of each of the paths
+ // to the respective totals
for (var i=0; i< list.length; i++){
var elem = list[i][resource]
for (var j=0; j< paths.length; j++)
totals[j] += parseInt(explore_path(elem,paths[j]),10)
}
+ // The totals have the sum of all items (for example of max_memory)
+ // Now for each total we push it to the series object.
for (var i=0; i< totals.length; i++){
series.push({
- data: [[totals[i],0]],
+ data: [[totals[i],0]], //we paint on 0 value of y axis
+ // y axis labels will be hidden
label: paths[i],
color: config.colorize? config.colorize(paths[i]) : null,
})
@@ -167,6 +269,10 @@ var SunstoneMonitoring = {
}
}
+
+// This function explores a path in an element and returns the value.
+// For example, if path = 'STATE' it will return elem.STATE. But if
+// path = ['TEMPLATE','MAX_CPU'] it will return elem.TEMPLATE.MAX_CPU
function explore_path(elem,path){
if (!$.isArray(path)) //base case - non array
return elem[path]
diff --git a/src/sunstone/public/js/plugins/acls-tab.js b/src/sunstone/public/js/plugins/acls-tab.js
index 9fdebd324c..2189989d69 100644
--- a/src/sunstone/public/js/plugins/acls-tab.js
+++ b/src/sunstone/public/js/plugins/acls-tab.js
@@ -183,7 +183,7 @@ var acls_tab = {
parentTab: 'system_tab'
}
-
+//Monitoring for ACLs - just count how many
SunstoneMonitoringConfig['ACL'] = {
plot: function(monitoring){
//$('#totalAcls', $dashboard).text(monitoring['totalAcls'])
@@ -358,12 +358,14 @@ function setupCreateAclDialog(){
height: height
});
+ //Default selected options
$('#res_subgroup_all',dialog).attr('checked','checked');
$('#res_id',dialog).attr('disabled','disabled');
$('#belonging_to',dialog).attr('disabled','disabled');
$('button',dialog).button();
+ //Resource subset radio buttons
$('.res_subgroup',dialog).click(function(){
var value = $(this).val();
var context = $(this).parent();
@@ -383,6 +385,7 @@ function setupCreateAclDialog(){
};
});
+ //trigger ACL string preview on keyup
$('input#res_id',dialog).keyup(function(){
$(this).trigger("change");
});
@@ -480,12 +483,12 @@ function setupCreateAclDialog(){
// required: we have to put the right options in the
// selects.
function popUpCreateAclDialog(){
- var users = $('');
+ var users = $('');
$('.empty_value',users).remove();
$('option',users).addClass("user");
users.prepend('');
- var groups = $('');
+ var groups = $('');
$('.empty_value',groups).remove();
$('option',groups).addClass("group");
groups.prepend('');
diff --git a/src/sunstone/public/js/plugins/clusters-tab.js b/src/sunstone/public/js/plugins/clusters-tab.js
index a8c2087cde..3b365ea362 100644
--- a/src/sunstone/public/js/plugins/clusters-tab.js
+++ b/src/sunstone/public/js/plugins/clusters-tab.js
@@ -219,8 +219,14 @@ var clusters_tab = {
parentTab: "infra_tab",
};
+
+// Cluster monitoring configuration. This config controls the monitoring
+// which is plotted in the cluster dashboards.
+// It operations are run for every cluster and are related to hosts in that
+// cluster
SunstoneMonitoringConfig['CLUSTER_HOST'] = {
plot: function(monitoring){
+ //plot the series calculated for the hosts in a specific cluster
var cluster_id = SunstoneMonitoringConfig.CLUSTER_HOST.cluster_id
if (cluster_id == '-1') cluster_id = '-';
@@ -232,6 +238,9 @@ SunstoneMonitoringConfig['CLUSTER_HOST'] = {
monitoring[plotID]);
};
},
+ // Monitor configuration are the same those in the HOST
+ // configuration (except for cluster partitions)
+ // the difference is that these are plotted somewhere else.
monitor : {
"statePie" : {
partitionPath: "STATE",
@@ -325,7 +334,7 @@ Sunstone.addActions(cluster_actions);
Sunstone.addMainTab('clusters_tab',clusters_tab);
//Sunstone.addInfoPanel("host_info_panel",host_info_panel);
-
+//return lists of selected elements in cluster list
function clusterElements(){
return getSelectedNodes(dataTable_clusters);
}
@@ -341,25 +350,8 @@ function clusterElementArray(element_json){
];
}
-/*
-//Listen to clicks on the tds of the tables and shows the info dialogs.
-function hostInfoListener(){
- $('#tbodyhosts tr',dataTable_hosts).live("click",function(e){
- //do nothing if we are clicking a checkbox!
- if ($(e.target).is('input')) {return true;}
- var aData = dataTable_hosts.fnGetData(this);
- var id = $(aData[0]).val();
- if (!id) return true;
-
- popDialogLoading();
- Sunstone.runAction("Host.showinfo",id);
- return false;
- });
-}
-*/
-
-//updates the host select by refreshing the options in it
+//updates the cluster select by refreshing the options in it
function updateClusterSelect(){
clusters_select = '';
clusters_select += makeSelectOptions(dataTable_clusters,
@@ -371,7 +363,7 @@ function updateClusterSelect(){
);
}
-//callback for an action affecting a host element
+//callback for an action affecting a cluster element
function updateClusterElement(request, element_json){
var id = element_json.CLUSTER.ID;
var element = clusterElementArray(element_json);
@@ -379,14 +371,14 @@ function updateClusterElement(request, element_json){
updateClusterSelect();
}
-//callback for actions deleting a host element
+//callback for actions deleting a cluster element
function deleteClusterElement(req){
deleteElement(dataTable_clusters,'#cluster_'+req.request.data);
$('div#cluster_tab_'+req.request.data,main_tabs_context).remove();
updateClusterSelect();
}
-//call back for actions creating a host element
+//call back for actions creating a cluster element
function addClusterElement(request,element_json){
var id = element_json.CLUSTER.ID;
var element = clusterElementArray(element_json);
@@ -394,31 +386,34 @@ function addClusterElement(request,element_json){
updateClusterSelect();
}
-//callback to update the list of hosts.
+//callback to update the list of clusters.
function updateClustersView (request,list){
var list_array = [];
$.each(list,function(){
- //Grab table data from the host_list
+ //Grab table data from the list
list_array.push(clusterElementArray(this));
});
+ //Remove the menus as we recreate them again.
removeClusterMenus();
+ newClusterMenu(list);
updateView(list_array,dataTable_clusters);
updateClusterSelect();
- //dependency with the dashboard plugin
+ //dependency with the infraestructure dashboard plugin
updateInfraDashboard("clusters",list);
- newClusterMenu(list);
};
-
+//generates the HTML for the dashboard of a specific cluster
function clusterTabContent(cluster_json) {
var cluster = cluster_json.CLUSTER;
var hosts_n = 0;
var dss_n = 0;
var vnets_n = 0;
+
+ // Count resources in cluster
if (cluster.DATASTORES.ID &&
cluster.DATASTORES.ID.constructor == Array){
dss_n = cluster.DATASTORES.ID.length;
@@ -496,8 +491,8 @@ function clusterTabContent(cluster_json) {
' + tr("Hosts CPU Usage") + '
\
\
\
-
\
-
\
+
'+tr("No monitoring information available")+'
\
+
'+tr("No monitoring information available")+'
\
\
\
\
@@ -506,7 +501,7 @@ function clusterTabContent(cluster_json) {
\
\
\
- \
+
'+tr("No monitoring information available")+'
\
\
\
\
@@ -516,7 +511,7 @@ function clusterTabContent(cluster_json) {
\
\
\
- \
+
'+tr("No monitoring information available")+'
\
\
\
\
@@ -613,7 +608,7 @@ function clusterTabContent(cluster_json) {
\
\
\
- \
+
'+tr("No monitoring information available")+'
\
\
\
\
@@ -623,7 +618,7 @@ function clusterTabContent(cluster_json) {
\
\
\
- \
+
'+tr("No monitoring information available")+'
\
\
\
\
@@ -690,6 +685,7 @@ function clusterTabContent(cluster_json) {
return html_code;
};
+//Removes the clusters from the submenu
function removeClusterMenus(){
var data = dataTable_clusters.fnGetData();
@@ -707,7 +703,8 @@ function removeClusterMenus(){
};
};
-
+// Creates new cluster submenus
+// insert cluster none manually
function newClusterMenu(list){
var cluster_none = {
'CLUSTER' : {
@@ -728,11 +725,15 @@ function newClusterMenu(list){
$('div#menu li#li_clusters_tab span').addClass('ui-icon-circle-plus');
};
+// Create new cluster menu
function newClusterMenuElement(element){
var cluster = element.CLUSTER;
+
+ //trim long cluster names
var menu_name = cluster.NAME.length > 10 ?
cluster.NAME.substring(0,9)+'...' : cluster.NAME;
+ // Menu object
var menu_cluster = {
title: menu_name + ' (id ' + cluster.ID + ')',
content: clusterTabContent(element),
@@ -762,6 +763,7 @@ function newClusterMenuElement(element){
parentTab: "cluster_tab_" + cluster.ID
};
*/
+ // Add to sunstone
Sunstone.addMainTab('cluster_tab_'+cluster.ID,menu_cluster,true);
// Sunstone.addMainTab('cluster_hosts_tab_'+cluster.ID,submenu_hosts,true);
@@ -769,6 +771,8 @@ function newClusterMenuElement(element){
// Sunstone.addMainTab('cluster_vnets_tab_'+cluster.ID,submenu_vnets,true);
};
+// Basicly, we show the hosts/datastore/vnets tab, but before we set
+// a filter on the cluster column, so it only shows the cluster we want.
function clusterResourceViewListeners(){
//hack the menu selection
$('.show_tab_button').live('click',function(){
@@ -860,6 +864,11 @@ function popUpCreateClusterDialog(){
return false;
}
+
+// Receives the list of hosts, divides them into clusters.
+// For each cluster, it calls the monitoring action for the hosts
+// on that cluster. The monitoring is then plotted in the cluster dashboard.
+// This is called from hosts plugin.
function monitorClusters(list){
var clustered_hosts = { "-" : []}
@@ -933,7 +942,7 @@ $(document).ready(function(){
addElement([
spinner,
'','',''],dataTable_clusters);
- Sunstone.runAction("Cluster.list");
+// Sunstone.runAction("Cluster.list");
setupCreateClusterDialog();
diff --git a/src/sunstone/public/js/plugins/config-tab.js b/src/sunstone/public/js/plugins/config-tab.js
index 7907a523c6..32b14d16f8 100644
--- a/src/sunstone/public/js/plugins/config-tab.js
+++ b/src/sunstone/public/js/plugins/config-tab.js
@@ -79,7 +79,7 @@ var config_tab = {
Sunstone.addActions(config_actions);
Sunstone.addMainTab('config_tab',config_tab);
-
+// Callback when configuration list is received
function updateConfig(request,response){
var config = response['user_config'];
@@ -89,6 +89,13 @@ function updateConfig(request,response){
};
};
+// Update secure websockets configuration
+// First we perform a User.show(). In the callback we update the user template
+// to include this parameter.
+// Then we post to the server configuration so that it is saved for the session
+// Note: the session is originally initialized to the user VNC_WSS if present
+// otherwise it is set according to sunstone configuration
+// TO DO improve this, server side should take care
function updateWss(){
var user_info_req = {
data : {
@@ -125,7 +132,7 @@ $(document).ready(function(){
if (lang)
$('table#config_table #lang_sel option[value="'+lang+'"]').attr('selected','selected');
- //Listener to change language
+ //Listener to change language. setLang in locale.js
$('table#config_table #lang_sel').change(function(){
setLang($(this).val());
});
diff --git a/src/sunstone/public/js/plugins/dashboard-tab.js b/src/sunstone/public/js/plugins/dashboard-tab.js
index a9f0a1f65b..0c83095251 100644
--- a/src/sunstone/public/js/plugins/dashboard-tab.js
+++ b/src/sunstone/public/js/plugins/dashboard-tab.js
@@ -188,6 +188,8 @@ Sunstone.addMainTab('dashboard_tab',dashboard_tab);
var $dashboard;
+// All monitoring calls and config are called from the Sunstone plugins.
+
$(document).ready(function(){
$dashboard = $('#dashboard_tab', main_tabs_context);
});
\ No newline at end of file
diff --git a/src/sunstone/public/js/plugins/dashboard-users-tab.js b/src/sunstone/public/js/plugins/dashboard-users-tab.js
index 1a51f7047a..d3ad15a86f 100644
--- a/src/sunstone/public/js/plugins/dashboard-users-tab.js
+++ b/src/sunstone/public/js/plugins/dashboard-users-tab.js
@@ -128,6 +128,8 @@ Sunstone.addMainTab('dashboard_tab',dashboard_tab);
var $dashboard;
+// Monitoring calls and config in Sunstone plugins
+
$(document).ready(function(){
$dashboard = $('#dashboard_tab', main_tabs_context);
});
\ No newline at end of file
diff --git a/src/sunstone/public/js/plugins/datastores-tab.js b/src/sunstone/public/js/plugins/datastores-tab.js
index 364e2aeb30..554c6c1ab2 100644
--- a/src/sunstone/public/js/plugins/datastores-tab.js
+++ b/src/sunstone/public/js/plugins/datastores-tab.js
@@ -508,8 +508,7 @@ function updateDatastoreInfo(request,ds){
Sunstone.popUpInfoPanel("datastore_info_panel");
}
-// Sets up the create-template dialog and all the processing associated to it,
-// which is a lot.
+// Set up the create datastore dialog
function setupCreateDatastoreDialog(){
dialogs_context.append('');
@@ -624,6 +623,9 @@ function setupDatastoreTemplateUpdateDialog(){
});
};
+// Standard template edition dialog
+// If one element is selected auto fecth template
+// otherwise let user select
function popUpDatastoreTemplateUpdateDialog(){
var select = makeSelectOptions(dataTable_datastores,
1,//id_col
@@ -711,6 +713,8 @@ $(document).ready(function(){
tableCheckboxesListener(dataTable_datastores);
infoListener(dataTable_datastores,'Datastore.showinfo');
+ // Reset filter in case the view was filtered because it was accessed
+ // from a single cluster.
$('div#menu li#li_datastores_tab').live('click',function(){
dataTable_datastores.fnFilter('',5);
});
diff --git a/src/sunstone/public/js/plugins/groups-tab.js b/src/sunstone/public/js/plugins/groups-tab.js
index 4968358b6d..ea4319232d 100644
--- a/src/sunstone/public/js/plugins/groups-tab.js
+++ b/src/sunstone/public/js/plugins/groups-tab.js
@@ -388,6 +388,7 @@ function popUpCreateGroupDialog(){
return false;
}
+// Add groups quotas dialog and calls common setup() in sunstone utils.
function setupGroupQuotasDialog(){
dialogs_context.append('');
$group_quotas_dialog = $('#group_quotas_dialog',dialogs_context);
diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js
index 0fdcc0fe44..f6ff4b2625 100644
--- a/src/sunstone/public/js/plugins/hosts-tab.js
+++ b/src/sunstone/public/js/plugins/hosts-tab.js
@@ -17,6 +17,7 @@
/*Host tab plugin*/
/* HOST_HISTORY_LENGTH is ignored by server */
var HOST_HISTORY_LENGTH = 40;
+// Configuration object for historical graphs of individual hosts
var host_graphs = [
{
title : tr("CPU Monitoring information"),
@@ -363,29 +364,34 @@ var hosts_tab = {
showOnTopMenu: false,
};
+
+// Configuration object for plots related to hosts in the dashboard
SunstoneMonitoringConfig['HOST'] = {
plot: function(monitoring){
+ // Write the total hosts and discard this value
$('#totalHosts', $dashboard).text(monitoring['totalHosts'])
delete monitoring['totalHosts']
//if (!$dashboard.is(':visible')) return;
+ //Plot each of the monitored series
for (plotID in monitoring){
var container = $('div#'+plotID,$dashboard);
if (!container.length) continue;
SunstoneMonitoring.plot("HOST",
plotID,
container,
- monitoring[plotID]);
+ monitoring[plotID]); //serie
};
},
monitor : {
+ // Config to extract data to make state pie
"statePie" : {
- partitionPath: "STATE",
+ partitionPath: "STATE", //we partition hosts acc. to STATE
operation: SunstoneMonitoring.ops.partition,
- dataType: "pie",
+ dataType: "pie", //we want to paint a pie
colorize: function(state){
- switch (state) {
+ switch (state) { //This is how we color each pie sector
case '0': return "rgb(239,201,86)" //yellow
case '1': return "rgb(175,216,248)" //blue
case '2': return "rgb(108,183,108)" //green
@@ -394,7 +400,7 @@ SunstoneMonitoringConfig['HOST'] = {
case '5': return "rgb(160,160,160)" //light gray
}
},
- plotOptions : {
+ plotOptions : { //jquery.flot plotting options
series: { pie: { show: true } },
legend : {
labelFormatter: function(label, series){
@@ -405,13 +411,16 @@ SunstoneMonitoringConfig['HOST'] = {
}
}
},
- "cpuPerCluster" : {
- path: ["HOST_SHARE","CPU_USAGE"],
- partitionPath: "CLUSTER_ID",
+ "cpuPerCluster" : { //cpu used in each cluster
+ path: ["HOST_SHARE","CPU_USAGE"], //totalize cpu
+ partitionPath: "CLUSTER_ID", //in each cluster
operation: SunstoneMonitoring.ops.partition,
- dataType: "bars",
+ dataType: "bars", //we want to paint vertical bars
plotOptions: {
series: { bars: {show: true, barWidth: 0.5, align: 'center' }},
+ //customLabels is a custom option, means a ticks array will
+ //be added to this configuration with the labels (cluster
+ //names) when it is ready.
xaxis: { show: true, customLabels: true },
yaxis: { min: 0 },
legend : {
@@ -424,7 +433,7 @@ SunstoneMonitoringConfig['HOST'] = {
}
}
},
- "memoryPerCluster" : {
+ "memoryPerCluster" : { //memory used in each cluster. same as above.
path: ["HOST_SHARE","MEM_USAGE"],
partitionPath: "CLUSTER_ID",
operation: SunstoneMonitoring.ops.partition,
@@ -448,7 +457,7 @@ SunstoneMonitoringConfig['HOST'] = {
}
}
},
- "globalCpuUsage" : {
+ "globalCpuUsage" : { //pie according to cpu usage.
partitionPath: ["HOST_SHARE", "USED_CPU"],
dataType: "pie",
operation: SunstoneMonitoring.ops.hostCpuUsagePartition,
@@ -456,10 +465,11 @@ SunstoneMonitoringConfig['HOST'] = {
series: { pie: { show: true } },
}
},
- "totalHosts" : {
+ "totalHosts" : { //count number of hosts
operation: SunstoneMonitoring.ops.totalize
},
- "cpuUsageBar" : {
+ "cpuUsageBar" : { //horizontal bar with cpu usage
+ // we want the following values to be totalized in the same bar
paths: [
["HOST_SHARE","MAX_CPU"],
["HOST_SHARE","USED_CPU"],
@@ -482,7 +492,7 @@ SunstoneMonitoringConfig['HOST'] = {
}
}
},
- "memoryUsageBar" : {
+ "memoryUsageBar" : { //same as above
paths: [
["HOST_SHARE","MAX_MEM"],
["HOST_SHARE","USED_MEM"],
@@ -518,7 +528,7 @@ Sunstone.addActions(host_actions);
Sunstone.addMainTab('hosts_tab',hosts_tab);
Sunstone.addInfoPanel("host_info_panel",host_info_panel);
-
+// return selected elements from hosts datatable
function hostElements(){
return getSelectedNodes(dataTable_hosts);
}
@@ -624,7 +634,11 @@ function updateHostsView (request,host_list){
});
SunstoneMonitoring.monitor('HOST', host_list)
- if (typeof(monitorClusters) != 'undefined') monitorClusters(host_list)
+
+ //if clusters_sel is there, it means the clusters have arrived.
+ //Otherwise do not attempt to monitor them.
+ if (typeof(monitorClusters) != 'undefined' && clusters_sel())
+ monitorClusters(host_list)
updateView(host_list_array,dataTable_hosts);
updateHostSelect();
//dependency with the dashboard plugin
@@ -755,6 +769,8 @@ function setupCreateHostDialog(){
$('button',dialog).button();
+
+ // Show custom driver input only when custom is selected in selects
$('input[name="custom_vmm_mad"],'+
'input[name="custom_im_mad"],'+
'input[name="custom_vnm_mad"]',dialog).parent().hide();
@@ -834,6 +850,7 @@ function setHostAutorefresh() {
},INTERVAL+someTime());
}
+// Call back when individual host history monitoring fails
function hostMonitorError(req,error_json){
var message = error_json.error.message;
var info = req.request.data[0].monitor;
@@ -853,7 +870,7 @@ $(document).ready(function(){
"bJQueryUI": true,
"bSortClasses": false,
"sDom" : '<"H"lfrC>t<"F"ip>',
- "oColVis": {
+ "oColVis": { //exclude checkbox column
"aiExclude": [ 0 ]
},
"bAutoWidth":false,
@@ -887,9 +904,14 @@ $(document).ready(function(){
tableCheckboxesListener(dataTable_hosts);
infoListener(dataTable_hosts, "Host.showinfo");
+ // This listener removes any filter on hosts table when its menu item is
+ // selected. The cluster plugins will filter hosts when the hosts
+ // in a cluster are shown. So we have to make sure no filter has been
+ // left in place when we want to see all hosts.
$('div#menu li#li_hosts_tab').live('click',function(){
dataTable_hosts.fnFilter('',3);
});
+ // Hide help
$('div#hosts_tab div.legend_div',main_tabs_context).hide();
});
diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js
index 1fea3e7433..f81cbdb151 100644
--- a/src/sunstone/public/js/plugins/images-tab.js
+++ b/src/sunstone/public/js/plugins/images-tab.js
@@ -557,6 +557,7 @@ function imageElementArray(image_json){
var value = OpenNebula.Helper.image_type(image.TYPE);
$('option[value="'+value+'"]',type).replaceWith('');
+ //add also persistent/non-persistent selects, type select.
return [
'',
image.ID,
@@ -813,6 +814,7 @@ function setupCreateImageDialog(){
var img_obj;
+ // Upload is handled by FileUploader vendor plugin
var uploader = new qq.FileUploaderBasic({
button: $('#file-uploader',$create_image_dialog)[0],
action: 'upload',
@@ -823,10 +825,14 @@ function setupCreateImageDialog(){
//notifyMessage(message);
},
onSubmit: function(id, fileName){
+ //set url params
+ //since the body is the upload, we need the pass
+ //the image info here
uploader.setParams({
img : JSON.stringify(img_obj),
file: fileName
});
+ //we pop up an upload progress dialog
var pos_top = $(window).height() - 120;
var pos_left = 190;
var pb_dialog = $('
1){
for (var i=0; i< sel_elems.length; i++)
+ //If we are cloning several images we
+ //use the name as prefix
Sunstone.runAction('Image.clone',
sel_elems[i],
name+getImageName(sel_elems[i]));
diff --git a/src/sunstone/public/js/plugins/marketplace-tab.js b/src/sunstone/public/js/plugins/marketplace-tab.js
index 30ff3b6aff..5223e9837b 100644
--- a/src/sunstone/public/js/plugins/marketplace-tab.js
+++ b/src/sunstone/public/js/plugins/marketplace-tab.js
@@ -245,6 +245,7 @@ $(document).ready(function(){
"aoColumns": [
{ "bSortable": false,
"fnRender": function ( o, val ) {
+ //we render 1st column as a checkbox directly
return '
');
@@ -2160,6 +2158,7 @@ function setupTemplateCloneDialog(){
notifyError('A name or prefix is needed!');
if (sel_elems.length > 1){
for (var i=0; i< sel_elems.length; i++)
+ //use name as prefix if several items selected
Sunstone.runAction('Template.clone',
sel_elems[i],
name+getTemplateName(sel_elems[i]));
diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js
index 93e634e809..0fe79025c2 100644
--- a/src/sunstone/public/js/plugins/users-tab.js
+++ b/src/sunstone/public/js/plugins/users-tab.js
@@ -325,6 +325,9 @@ var user_actions = {
type: "single",
call: OpenNebula.User.show,
callback: function (request,response) {
+ // when we receive quotas we parse them and create an
+ // quota objects with html code (
) that can be inserted
+ // in the dialog
var parsed = parseQuotas(response.USER);
$('ul#quotas_ul_vm',$user_quotas_dialog).html(parsed.VM)
$('ul#quotas_ul_datastore',$user_quotas_dialog).html(parsed.DATASTORE)
@@ -391,6 +394,7 @@ var user_buttons = {
"User.chauth" : {
type: "confirm_with_select",
text: tr("Change authentication"),
+ //We insert our custom select there.
select: function() {
return '\
\
@@ -447,10 +451,12 @@ var users_tab = {
SunstoneMonitoringConfig['USER'] = {
plot: function(monitoring){
+ //plot the number of total users
$('#totalUsers', $dashboard).text(monitoring['totalUsers'])
//if (!$dashboard.is(':visible')) return;
+ //plot users per group
var container = $('div#usersPerGroup',$dashboard);
SunstoneMonitoring.plot('USER',
'usersPerGroup',
@@ -459,6 +465,7 @@ SunstoneMonitoringConfig['USER'] = {
},
monitor: {
"usersPerGroup" : {
+ //we want to monitor users divided by GNAME to paint bars.
partitionPath: "GNAME",
operation: SunstoneMonitoring.ops.partition,
dataType: "bars",
@@ -636,6 +643,7 @@ function setupCreateUserDialog(){
$('input[name="custom_auth"]',dialog).parent().hide();
});
+
$('#create_user_form',dialog).submit(function(){
var user_name=$('#username',this).val();
var user_password=$('#pass',this).val();
@@ -689,6 +697,8 @@ function setupUpdatePasswordDialog(){
});
};
+
+//add a setup quota dialog and call the sunstone-util.js initialization
function setupUserQuotasDialog(){
dialogs_context.append('');
$user_quotas_dialog = $('#user_quotas_dialog',dialogs_context);
diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js
index 5854d780bf..bc61c3236d 100644
--- a/src/sunstone/public/js/plugins/vnets-tab.js
+++ b/src/sunstone/public/js/plugins/vnets-tab.js
@@ -488,7 +488,7 @@ Sunstone.addActions(vnet_actions);
Sunstone.addMainTab('vnets_tab',vnets_tab);
Sunstone.addInfoPanel('vnet_info_panel',vnet_info_panel);
-
+// return list of selected elements in list
function vnElements(){
return getSelectedNodes(dataTable_vNetworks);
}
@@ -634,6 +634,9 @@ function updateVNetworkInfo(request,vn){
}
+// Prints the lis of leases depending on the Vnet TYPE
+// It adds the "add lease", "hold lease" fields, and each lease comes with
+// hold, release buttons etc. Listeners in setupLeasesOps()
function printLeases(vn_info){
var html ='