1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-21 14:50:08 +03:00

Sunstone: comment code, very small code fixes and improvements

(cherry picked from commit dfd2a227c09a04e44b3b740b646ad9e401a05fa5)
This commit is contained in:
Hector Sanjuan 2012-07-02 12:18:51 +02:00 committed by Ruben S. Montero
parent ed45af12da
commit d091f426b5
15 changed files with 287 additions and 77 deletions

View File

@ -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]

View File

@ -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 = $('<select>'+users_select+'</select>');
var users = $('<select>'+users_sel()+'</select>');
$('.empty_value',users).remove();
$('option',users).addClass("user");
users.prepend('<option value="">---'+tr("Users")+'---</option>');
var groups = $('<select>'+groups_select+'</select>');
var groups = $('<select>'+groups_sel()+'</select>');
$('.empty_value',groups).remove();
$('option',groups).addClass("group");
groups.prepend('<option value="">---'+tr("Groups")+'---</option>');

View File

@ -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 = '<option value="-1">Default (none)</option>';
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) {
<td class="key_td">' + tr("Hosts CPU Usage") + '</td>\
</tr>\
<tr>\
<td colspan="2"><div id="statePie'+cluster.ID+'" style="float:left;width:50%;height:100px;"></div>\
<div id="globalCpuUsage'+cluster.ID+'" style="float:right;width:50%;height:100px;"></div></td>\
<td colspan="2"><div id="statePie'+cluster.ID+'" style="float:left;width:50%;height:100px;">'+tr("No monitoring information available")+'</div>\
<div id="globalCpuUsage'+cluster.ID+'" style="float:right;width:50%;height:100px;">'+tr("No monitoring information available")+'</div></td>\
</tr>\
\
<tr>\
@ -506,7 +501,7 @@ function clusterTabContent(cluster_json) {
</tr>\
<tr>\
<td colspan="2">\
<div id="cpuUsageBar'+cluster.ID+'" style="width:95%;height:50px"></div>\
<div id="cpuUsageBar'+cluster.ID+'" style="width:95%;height:50px">'+tr("No monitoring information available")+'</div>\
</td>\
</tr>\
\
@ -516,7 +511,7 @@ function clusterTabContent(cluster_json) {
</tr>\
<tr>\
<td colspan="2">\
<div id="memoryUsageBar'+cluster.ID+'" style="width:95%;height:50px"></div>\
<div id="memoryUsageBar'+cluster.ID+'" style="width:95%;height:50px">'+tr("No monitoring information available")+'</div>\
</td>\
</tr>\
</table>\
@ -613,7 +608,7 @@ function clusterTabContent(cluster_json) {
</tr>\
<tr>\
<td colspan="2">\
<div id="cpuUsageBar'+cluster.ID+'" style="width:95%;height:50px"></div>\
<div id="cpuUsageBar'+cluster.ID+'" style="width:95%;height:50px">'+tr("No monitoring information available")+'</div>\
</td>\
</tr>\
\
@ -623,7 +618,7 @@ function clusterTabContent(cluster_json) {
</tr>\
<tr>\
<td colspan="2">\
<div id="memoryUsageBar'+cluster.ID+'" style="width:95%;height:50px"></div>\
<div id="memoryUsageBar'+cluster.ID+'" style="width:95%;height:50px">'+tr("No monitoring information available")+'</div>\
</td>\
</tr>\
</table>\
@ -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();

View File

@ -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());
});

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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('<div title=\"'+tr("Create Datastore")+'\" id="create_datastore_dialog"></div>');
@ -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);
});

View File

@ -388,6 +388,7 @@ function popUpCreateGroupDialog(){
return false;
}
// Add groups quotas dialog and calls common setup() in sunstone utils.
function setupGroupQuotasDialog(){
dialogs_context.append('<div title="'+tr("Group quotas")+'" id="group_quotas_dialog"></div>');
$group_quotas_dialog = $('#group_quotas_dialog',dialogs_context);

View File

@ -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();
});

View File

@ -557,6 +557,7 @@ function imageElementArray(image_json){
var value = OpenNebula.Helper.image_type(image.TYPE);
$('option[value="'+value+'"]',type).replaceWith('<option value="'+value+'" selected="selected">'+tr(value)+'</option>');
//add also persistent/non-persistent selects, type select.
return [
'<input class="check_item" type="checkbox" id="image_'+image.ID+'" name="selected_items" value="'+image.ID+'"/>',
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 = $('<div id="pb_dialog" title="'+
@ -845,9 +851,11 @@ function setupCreateImageDialog(){
$('#upload-progress',pb_dialog).progressbar({value:0});
},
onProgress: function(id, fileName, loaded, total){
//update upload dialog with current progress
$('div#pb_dialog #upload-progress').progressbar("option","value",Math.floor(loaded*100/total));
},
onComplete: function(id, fileName, responseJSON){
//Inform complete upload, destroy upload dialog, refresh img list
notifyMessage("Image uploaded correctly");
$('div#pb_dialog').dialog('destroy');
Sunstone.runAction("Image.list");
@ -938,6 +946,9 @@ function setupCreateImageDialog(){
img_obj = { "image" : img_json,
"ds_id" : ds_id};
//we this is an image upload we trigger FileUploader
//to start the upload
if (upload){
uploader._onInputChange(file_input);
} else {
@ -1178,6 +1189,8 @@ function setupImageCloneDialog(){
notifyError('A name or prefix is needed!');
if (sel_elems.length > 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]));

View File

@ -245,6 +245,7 @@ $(document).ready(function(){
"aoColumns": [
{ "bSortable": false,
"fnRender": function ( o, val ) {
//we render 1st column as a checkbox directly
return '<input class="check_item" type="checkbox" id="marketplace_'+
o.aData['_id']['$oid']+
'" name="selected_items" value="'+

View File

@ -1682,11 +1682,7 @@ function setupCreateTemplateDialog(){
return false;
});
//Chrome workaround
$('select#TYPE',section_graphics).change(function(){
$(this).trigger("click");
});
$('select#TYPE',section_graphics).click(function(){
g_type = $(this).val();
switch (g_type) {
case "vnc":
@ -2120,6 +2116,8 @@ function popUpTemplateTemplateUpdateDialog(){
};
// Template clone dialog
function setupTemplateCloneDialog(){
//Append to DOM
dialogs_context.append('<div id="template_clone_dialog" title="'+tr("Clone a template")+'"></div>');
@ -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]));

View File

@ -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 (<li>) 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 '<option value="core" selected="selected">'+tr("Core")+'</option>\
<option value="ssh">'+tr("SSH")+'</option>\
@ -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('<div title="'+tr("User quotas")+'" id="user_quotas_dialog"></div>');
$user_quotas_dialog = $('#user_quotas_dialog',dialogs_context);

View File

@ -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 ='<form style="display:inline-block;width:80%" id="leases_form" vnid="'+vn_info.ID+'"><table id="vn_leases_info_table" class="info_table" style="width:100%;">\
<thead>\
@ -881,6 +884,8 @@ function setupCreateVNetDialog() {
var vlan = $('#vlan',this).val();
var vlan_id = $('#vlan_id',this).val();
//Depending on network mode we include certain params in the
//template
switch (network_mode) {
case "default":
if (!bridge && !phydev){
@ -1066,6 +1071,9 @@ function setupVNetTemplateUpdateDialog(){
});
};
// When 1 elem in the list is selected then fetch template automaticly
// Otherwise include selected elements in the select and let user choose
function popUpVNetTemplateUpdateDialog(){
var select = makeSelectOptions(dataTable_vNetworks,
1,//id_col
@ -1103,6 +1111,8 @@ function popUpVNetTemplateUpdateDialog(){
}
// Listeners to the add, hold, release, delete leases operations in the
// extended information panel.
function setupLeasesOps(){
$('button#panel_add_lease_button').live("click",function(){
var lease = $(this).prev().val();
@ -1115,6 +1125,7 @@ function setupLeasesOps(){
return false;
});
//ranged networks hold lease
$('button#panel_hold_lease_button').live("click",function(){
var lease = $(this).prev().val();
//var mac = $(this).previous().val();
@ -1136,6 +1147,7 @@ function setupLeasesOps(){
return false;
});
//fixed networks hold lease
$('a.hold_lease').live("click",function(){
var lease = $(this).parents('tr').attr('ip');
var id = $(this).parents('form').attr('vnid');
@ -1209,6 +1221,8 @@ $(document).ready(function(){
tableCheckboxesListener(dataTable_vNetworks);
infoListener(dataTable_vNetworks,'Network.showinfo');
// Reset list filter in case it was set because we were lookin
// at a single cluster view
$('div#menu li#li_vnets_tab').live('click',function(){
dataTable_vNetworks.fnFilter('',5);
});

View File

@ -18,7 +18,7 @@
/* Some useful functions for Sunstone default plugins */
var INTERVAL=60000; //milisecs
function someTime(){
function someTime(){ //some time under 30secs
return Math.floor(Math.random()*30000);
}
@ -46,6 +46,7 @@ function pretty_time(time_seconds)
return hour + ":" + mins +":" + secs + "&nbsp;" + month + "/" + day + "/" + year;
}
// Format time for plot axis
function pretty_time_axis(time){
var d = new Date();
d.setTime(time*1000);
@ -412,6 +413,10 @@ function waitingNodes(dataTable){
$('tr input.check_item:visible',dataTable).replaceWith(spinner);
}
//The following functions extract the value of a specific column
//in a dataTable. If the order of datatable columns is changed this
//should be the only place to adjust.
function getUserName(uid){
if (typeof(dataTable_users) != "undefined"){
return getName(uid,dataTable_users,2);
@ -468,6 +473,8 @@ function getTemplateName(id){
return id;
};
// Returns the value of the column with the resource of specified
// id in the dataTable.
function getName(id,dataTable,name_col){
var name = id;
if (typeof(dataTable) == "undefined") {
@ -484,8 +491,9 @@ function getName(id,dataTable,name_col){
return name;
};
//Search a datatable record matching the filter_str in the filter_col. Returns
//the value of that record in the desired value column.
// A more general version of the above.
// Search a datatable record matching the filter_str in the filter_col. Returns
// the value of that record in the desired value column.
function getValue(filter_str,filter_col,value_col,dataTable){
var value="";
if (typeof(dataTable) == "undefined") return value;
@ -806,6 +814,8 @@ function infoListener(dataTable, info_action){
var count = $('tbody .check_item:checked', dataTable).length;
//If ctrl is hold down or there is already some item selected
//then just select.
if (info_action){
if (e.ctrlKey || count >= 1)
$('.check_item',this).trigger('click');
@ -845,7 +855,7 @@ function datastores_sel() {
return datastores_select;
}
/* Below functions to easier permission management */
function ownerUse(resource){
return parseInt(resource.PERMISSIONS.OWNER_U);
@ -923,6 +933,7 @@ function setPermissionsTable(resource,context){
$('.other_a',context).attr('checked','checked');
};
//Returns an octet given a permission table with checkboxes
function buildOctet(permTable){
var owner=0;
var group=0;
@ -952,6 +963,9 @@ function buildOctet(permTable){
return ""+owner+group+other;
};
// Sets up a dialog to edit and update user and group quotas
// Called from user/group plugins
function setupQuotasDialog(dialog){
var height = Math.floor($(window).height()*0.8); //set height to a percentage of the window
@ -1035,6 +1049,8 @@ function popUpQuotasDialog(dialog, resource, sel_elems){
dialog.dialog('open');
}
//Action to be performed when an edit quota icon is clicked.
function setupQuotaIcons(){
$('.quota_edit_icon').live('click',function(){
var dialog = $(this).parents('form');
@ -1066,6 +1082,7 @@ function setupQuotaIcons(){
});
}
// Returns an object with quota information in form of list items
function parseQuotas(elem){
var quotas = [];
var results = {