diff --git a/xCAT-UI/css/style.css b/xCAT-UI/css/style.css
index b4200690b..8a5dab26f 100644
--- a/xCAT-UI/css/style.css
+++ b/xCAT-UI/css/style.css
@@ -693,11 +693,13 @@ table a:hover {
-webkit-border-radius: .5em;
border-radius: .5em;
}
+
.discovercurrentstep{
background-color: yellow;
font: normal bold 12px/ 35px verdana, arial, helvetica, sans-serif;
padding: 5px;
}
+
.discovercontent {
width: 960px;
display: inline-table;
diff --git a/xCAT-UI/js/monitor/gangliamon.js b/xCAT-UI/js/monitor/gangliamon.js
index ec280f3e2..fc9bc77eb 100644
--- a/xCAT-UI/js/monitor/gangliamon.js
+++ b/xCAT-UI/js/monitor/gangliamon.js
@@ -2,7 +2,7 @@
* Global variables
*/
var gangliaTableId = 'nodesDatatable';
-var gangliaNodesList;
+var gangliaData;
/**
* Load Ganglia monitoring tool
@@ -189,7 +189,7 @@ function loadGroups4Ganglia(data) {
$('#nodes').children().remove();
// Create link to Ganglia
- var gangliaLnk = $('click here');
+ var gangliaLnk = $('Click here');
gangliaLnk.css( {
'color' : 'blue',
'text-decoration' : 'none'
@@ -203,7 +203,7 @@ function loadGroups4Ganglia(data) {
var info = $('
');
info.append('');
var msg = $('');
- msg.append('Review the nodes that are monitored by Ganglia. Install Ganglia onto a node you want to monitor by selecting it and clicking on Install. Turn on Ganglia monitoring for a node by selecting it and clicking on Monitor. If you are satisfied with the nodes you want to monitor, ');
+ msg.append('Below is a summary of nodes within the selected group. ');
msg.append(gangliaLnk);
msg.append(' to open the Ganglia page.');
info.append(msg);
@@ -212,13 +212,7 @@ function loadGroups4Ganglia(data) {
// Create loader
var loader = $('
').append(createLoader());
-
- // Create a tab for this group
- var tab = new Tab();
- setNodesTab(tab);
- tab.init();
- $('#nodes').append(tab.object());
- tab.add('nodesTab', 'Nodes', loader, false);
+ $('#nodes').append(loader);
// To improve performance, get all nodes within selected group
// Get node definitions only for first 50 nodes
@@ -233,52 +227,27 @@ function loadGroups4Ganglia(data) {
},
/**
- * Get node definitions for first 50 nodes
+ * Get node definitions
*
* @param data
* Data returned from HTTP request
* @return Nothing
*/
success : function(data) {
- var rsp = data.rsp;
var group = data.msg;
-
- // Save nodes in a list so it can be accessed later
- nodesList = new Array();
- for (var i in rsp) {
- if (rsp[i][0]) {
- nodesList.push(rsp[i][0]);
- }
- }
- // Sort nodes list
- nodesList.sort();
-
- // Get first 50 nodes
- var nodes = '';
- for (var i = 0; i < nodesList.length; i++) {
- if (i > 49) {
- break;
- }
-
- nodes += nodesList[i] + ',';
- }
-
- // Remove last comma
- nodes = nodes.substring(0, nodes.length-1);
-
// Get nodes definitions
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
- cmd : 'lsdef',
- tgt : '',
- args : nodes,
+ cmd : 'nodestat',
+ tgt : group,
+ args : '',
msg : group
},
- success : loadNodes4Ganglia
+ success : loadGangliaSummary
});
}
});
@@ -304,371 +273,49 @@ function loadGroups4Ganglia(data) {
}
/**
- * Load nodes belonging to a given group
+ * Load Ganglia summary page
*
* @param data
* Data returned from HTTP request
* @return Nothing
*/
-function loadNodes4Ganglia(data) {
+function loadGangliaSummary(data) {
// Data returned
var rsp = data.rsp;
// Group name
var group = data.msg;
// Node attributes hash
var attrs = new Object();
- // Node attributes
- var headers = new Object();
-
- // Variable to send command and request node status
- var getNodeStatus = true;
- var node, args;
+ var node, status, args;
for ( var i in rsp) {
- // Get the node
- var pos = rsp[i].indexOf('Object name:');
- if (pos > -1) {
- var temp = rsp[i].split(': ');
- node = jQuery.trim(temp[1]);
-
- // Create a hash for the node attributes
- attrs[node] = new Object();
- i++;
- }
-
// Get key and value
- args = rsp[i].split('=', 2);
- var key = jQuery.trim(args[0]);
- var val = jQuery.trim(rsp[i].substring(rsp[i].indexOf('=') + 1, rsp[i].length));
+ args = rsp[i].split(':', 2);
+ node = jQuery.trim(args[0]);
+ status = jQuery.trim(args[1]);
// Create a hash table
- attrs[node][key] = val;
- headers[key] = 1;
-
- // If the node status is available
- if (key == 'status') {
- // Do not send command to request node status
- getNodeStatus = false;
- }
+ attrs[node] = new Object();
+ attrs[node]['status'] = status;
}
- // Add nodes that are not in data returned
- for (var i in nodesList) {
- if (!attrs[nodesList[i]]) {
- // Create attributes list and save node name
- attrs[nodesList[i]] = new Object();
- attrs[nodesList[i]]['node'] = nodesList[i];
- }
- }
+ // Save node attributes hash
+ gangliaData = attrs;
- // Sort headers
- var sorted = new Array();
- for ( var key in headers) {
- // Do not put comments and status in
- if (key != 'usercomment' && key != 'status' && key.indexOf('statustime') < 0) {
- sorted.push(key);
- }
- }
- sorted.sort();
-
- // Add column for check box, node, ping, and power
- sorted.unshift('',
- 'node',
- 'status',
- 'power',
- 'ganglia');
-
- // Create a datatable
- var gangliaTable = new DataTable(gangliaTableId);
- gangliaTable.init(sorted);
-
- // Go through each node
- for ( var node in attrs) {
- // Create a row
- var row = new Array();
-
- // Create a check box, node link, and get node status
- var checkBx = '';
- var nodeLink = $('' + node + '').bind('click', loadNode);
-
- // If there is no status attribute for the node, do not try to access hash table
- // Else the code will break
- var status = '';
- if (attrs[node]['status']) {
- status = attrs[node]['status'].replace('sshd', 'ping');
- }
-
- // Push in checkbox, node, status, and power
- row.push(checkBx, nodeLink, status, '', '');
-
- // Go through each header
- for ( var i = 5; i < sorted.length; i++) {
- // Add the node attributes to the row
- var key = sorted[i];
-
- // Do not put comments and status in
- if (key != 'usercomment' && key != 'status' && key.indexOf('statustime') < 0) {
- var val = attrs[node][key];
- if (val) {
- row.push(val);
- } else {
- row.push('');
- }
- }
- }
-
- // Add the row to the table
- gangliaTable.add(row);
- }
-
- // Clear the tab before inserting the table
- $('#nodesTab').children().remove();
-
- // Create action bar
- var actionBar = $('');
-
- /**
- * The following actions are available to perform against a given node:
- * power and monitor
- */
-
- /*
- * Power
- */
- var powerLnk = $('Power');
-
- // Power on
- var powerOnLnk = $('Power on');
- powerOnLnk.click(function() {
- var tgtNodes = getNodesChecked(gangliaTableId);
- if (tgtNodes) {
- powerNode(tgtNodes, 'on');
- }
- });
-
- // Power off
- var powerOffLnk = $('Power off');
- powerOffLnk.click(function() {
- var tgtNodes = getNodesChecked(gangliaTableId);
- if (tgtNodes) {
- powerNode(tgtNodes, 'off');
- }
- });
-
- // Power actions
- var powerActions = [ powerOnLnk, powerOffLnk ];
- var powerActionMenu = createMenu(powerActions);
-
- /*
- * Monitor
- */
- var monitorLnk = $('Monitor');
-
- // Turn monitoring on
- var monitorOnLnk = $('Monitor on');
- monitorOnLnk.click(function() {
- var tgtNodes = getNodesChecked(gangliaTableId);
- if (tgtNodes) {
- monitorNode(tgtNodes, 'on');
- }
- });
-
- // Turn monitoring off
- var monitorOffLnk = $('Monitor off');
- monitorOffLnk.click(function() {
- var tgtNodes = getNodesChecked(gangliaTableId);
- if (tgtNodes) {
- monitorNode(tgtNodes, 'off');
- }
- });
-
- // Install Ganglia
- var installLnk = $('Install');
- installLnk.click(function() {
- var tgtNodes = getNodesChecked(gangliaTableId);
- if (tgtNodes) {
- installGanglia(tgtNodes);
- }
- });
-
- // Power actions
- var monitorActions = [ monitorOnLnk, monitorOffLnk ];
- var monitorActionMenu = createMenu(monitorActions);
-
- // Create an action menu
- var actionsDIV = $('');
- var actions = [ [ powerLnk, powerActionMenu ], [ monitorLnk, monitorActionMenu ], installLnk ];
- var actionMenu = createMenu(actions);
- actionMenu.superfish();
- actionsDIV.append(actionMenu);
- actionBar.append(actionsDIV);
- $('#nodesTab').append(actionBar);
-
- // Insert table
- $('#nodesTab').append(gangliaTable.object());
-
- // Turn table into a datatable
- var gangliaDataTable = $('#' + gangliaTableId).dataTable({
- 'iDisplayLength': 50
- });
-
- // Filter table when enter key is pressed
- $('#' + gangliaTableId + '_filter input').unbind();
- $('#' + gangliaTableId + '_filter input').bind('keyup', function(e){
- if (e.keyCode == 13) {
- var table = $('#' + gangliaTableId).dataTable();
- table.fnFilter($(this).val());
-
- // If there are nodes found, get the node attributes
- if (!$('#' + gangliaTableId + ' .dataTables_empty').length) {
- getNodeAttrs4Ganglia(group);
- }
- }
- });
-
- // Load node definitions when next or previous buttons are clicked
- $('#' + gangliaTableId + '_next, #' + gangliaTableId + '_previous').click(function() {
- getNodeAttrs4Ganglia(group);
- });
-
- // Do not sort ping, power, and comment column
- var cols = $('#' + gangliaTableId + ' thead tr th').click(function() {
- getNodeAttrs4Ganglia(group);
- });
- var pingCol = $('#' + gangliaTableId + ' thead tr th').eq(2);
- var powerCol = $('#' + gangliaTableId + ' thead tr th').eq(3);
- var gangliaCol = $('#' + gangliaTableId + ' thead tr th').eq(4);
- pingCol.unbind('click');
- powerCol.unbind('click');
- gangliaCol.unbind('click');
-
- // Create enough space for loader to be displayed
- var style = {'min-width': '60px', 'text-align': 'center'};
- $('#' + gangliaTableId + ' tbody tr td:nth-child(3)').css(style);
- $('#' + gangliaTableId + ' tbody tr td:nth-child(4)').css(style);
- $('#' + gangliaTableId + ' tbody tr td:nth-child(5)').css(style);
-
- // Instead refresh the ping status and power status
- pingCol.find('span a').bind('click', function(event) {
- refreshNodeStatus(group, gangliaTableId);
- });
- powerCol.find('span a').bind('click', function(event) {
- refreshPowerStatus(group, gangliaTableId);
- });
- gangliaCol.find('span a').bind('click', function(event) {
- refreshGangliaStatus(group);
- });
-
- // Create tooltip for status
- var tooltipConf = {
- position: "center right",
- offset: [-2, 10],
- effect: "fade",
- opacity: 0.8,
- relative: true,
- predelay: 800
- };
-
- var pingTip = createStatusToolTip();
- pingCol.find('span').append(pingTip);
- pingCol.find('span a').tooltip(tooltipConf);
-
- // Create tooltip for power
- var powerTip = createPowerToolTip();
- powerCol.find('span').append(powerTip);
- powerCol.find('span a').tooltip(tooltipConf);
-
- // Create tooltip for ganglia
- var gangliaTip = createGangliaToolTip();
- gangliaCol.find('span').append(gangliaTip);
- gangliaCol.find('span a').tooltip(tooltipConf);
-
- /**
- * Get node and ganglia status
- */
-
- // If request to get node status is made
- if (getNodeStatus) {
- // Get the node status
- $.ajax( {
- url : 'lib/cmd.php',
- dataType : 'json',
- data : {
- cmd : 'nodestat',
- tgt : group,
- args : '',
- msg : ''
- },
-
- success : loadNodeStatus
- });
- } else {
- // Hide status loader
- var statCol = $('#' + gangliaTableId + ' thead tr th').eq(2);
- statCol.find('img').hide();
- }
-
// Get the status of Ganglia
- var nodes = getNodesShown(gangliaTableId);
+ // Then create pie chart for node and Ganglia status
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'webrun',
tgt : '',
- args : 'gangliastatus;' + nodes,
+ args : 'gangliastatus;' + group,
msg : ''
},
success : loadGangliaStatus
});
-
- /**
- * Additional ajax requests need to be made for zVM
- */
-
- // Get index of hcp column
- var i = $.inArray('hcp', sorted);
- var archCol = $.inArray('arch', sorted);
- if (i) {
- // Get hardware control point
- var rows = gangliaTable.object().find('tbody tr');
- var hcps = new Object();
- var rowsNum = rows.size();
- for (var j = 0; j < rowsNum; j++) {
- var val = rows.eq(j).find('td').eq(i).html();
- var archval = rows.eq(j).find('td').eq(archCol).html();
- if (-1 == archval.indexOf('390')){
- continue;
- }
- hcps[val] = 1;
- }
-
- var args;
- for (var h in hcps) {
- // Get node without domain name
- args = h.split('.');
-
- // If there are no disk pools or network names cookie for this hcp
- if (!$.cookie(args[0] + 'diskpools') || !$.cookie(args[0] + 'networks')) {
- // Check if SMAPI is online
- $.ajax( {
- url : 'lib/cmd.php',
- dataType : 'json',
- data : {
- cmd : 'lsvm',
- tgt : args[0],
- args : '',
- msg : 'group=' + group + ';hcp=' + args[0]
- },
-
- // Load hardware control point specific info
- // Get disk pools and network names
- success : loadHcpInfo
- });
- }
- } // End of for
- } // End of if
}
/**
@@ -679,412 +326,85 @@ function loadNodes4Ganglia(data) {
* @return Nothing
*/
function loadGangliaStatus(data) {
+ // Remove loader
+ $('#nodes').find('img').remove();
+
// Get datatable
- var datatable = $('#' + gangliaTableId).dataTable();
var ganglia = data.rsp;
- var rowNum, node, status, args;
+ var node, ping, monitored;
+ // Count nodes that are pingable and not pingable
+ // and nodes that are pingable and monitored by Ganglia
+ var pingWGanglia = 0;
+ var pingWOGanglia = 0;
+ var noping = 0;
for ( var i in ganglia) {
// ganglia[0] = nodeName and ganglia[1] = state
node = jQuery.trim(ganglia[i][0]);
- status = jQuery.trim(ganglia[i][1]);
-
- // Get the row containing the node
- rowNum = findRow(node, '#' + gangliaTableId, 1);
-
- // Update the power status column
- datatable.fnUpdate(status, rowNum, 4);
- }
-
- // Hide Ganglia loader
- var gangliaCol = $('#' + gangliaTableId + ' thead tr th').eq(4);
- gangliaCol.find('img').hide();
-}
-
-/**
- * Refresh the status of Ganglia for each node
- *
- * @param group
- * Group name
- * @return Nothing
- */
-function refreshGangliaStatus(group) {
- // Show ganglia loader
- var gangliaCol = $('#' + gangliaTableId + ' thead tr th').eq(4);
- gangliaCol.find('img').show();
-
- // Get power status for nodes shown
- var nodes = getNodesShown(gangliaTableId);
-
- // Get the status of Ganglia
- $.ajax( {
- url : 'lib/cmd.php',
- dataType : 'json',
- data : {
- cmd : 'webrun',
- tgt : '',
- args : 'gangliastatus;' + nodes,
- msg : ''
- },
-
- success : loadGangliaStatus
- });
-}
-
-/**
- * Turn on monitoring for a given node
- *
- * @param node
- * Node to monitor on or off
- * @param monitor
- * Monitor state, on or off
- * @return Nothing
- */
-function monitorNode(node, monitor) {
- if (monitor == 'on') {
- // Append loader to warning bar
- var gangliaLoader = createLoader('');
- var warningBar = $('#gangliamon').find('.ui-state-error p');
- if (warningBar.length) {
- warningBar.append(gangliaLoader);
- }
-
- if (node) {
- // Check if ganglia RPMs are installed
- $.ajax( {
- url : 'lib/cmd.php',
- dataType : 'json',
- data : {
- cmd : 'webrun',
- tgt : '',
- args : 'gangliacheck;' + node,
- msg : node // Node range will be passed along in data.msg
- },
-
- /**
- * Start ganglia on a given node range
- *
- * @param data
- * Data returned from HTTP request
- * @return Nothing
- */
- success : function(data) {
- // Get response
- var out = data.rsp[0].split(/\n/);
-
- // Go through each line
- var warn = false;
- var warningMsg = '';
- for (var i in out) {
- // If an RPM is not installed
- if (out[i].indexOf('not installed') > -1) {
- warn = true;
-
- if (warningMsg) {
- warningMsg += ' ' + out[i];
- } else {
- warningMsg = out[i];
- }
- }
- }
-
- // If there are warnings
- if (warn) {
- // Create warning bar
- var warningBar = createWarnBar(warningMsg);
- warningBar.css('margin-bottom', '10px');
- warningBar.prependTo($('#nodes'));
- } else {
- $.ajax( {
- url : 'lib/cmd.php',
- dataType : 'json',
- data : {
- cmd : 'webrun',
- tgt : '',
- args : 'gangliastart;' + data.msg,
- msg : ''
- },
-
- success : function(data) {
- // Remove any warnings
- $('#nodes').find('.ui-state-error').remove();
- $('#gangliamon').find('.ui-state-error').remove();
- }
- });
- } // End of if (warn)
- } // End of function(data)
- });
+ monitored = jQuery.trim(ganglia[i][1]);
+ ping = gangliaData[node]['status'];
+
+ // If the node is monitored, increment count
+ if (ping == 'sshd' && monitored == 'on') {
+ pingWGanglia++;
+ } else if (ping == 'sshd' && monitored == 'off') {
+ pingWOGanglia++;
} else {
- $.ajax( {
- url : 'lib/cmd.php',
- dataType : 'json',
- data : {
- cmd : 'webrun',
- tgt : '',
- args : 'gangliastart',
- msg : ''
- },
-
- success : function(data) {
- // Remove any warnings
- $('#gangliamon').find('.ui-state-error').remove();
- }
- });
- } // End of if (node)
- } else {
- var args;
- if (node) {
- args = 'gangliastop;' + node;
- } else {
- args = 'gangliastop';
- }
-
- $.ajax( {
- url : 'lib/cmd.php',
- dataType : 'json',
- data : {
- cmd : 'webrun',
- tgt : '',
- args : args,
- msg : ''
- },
-
- success : function(data) {
- // Do nothing
- }
- });
- }
-}
-
-/**
- * Get attributes for nodes not yet initialized
- *
- * @param group
- * Group name
- * @return Nothing
- */
-function getNodeAttrs4Ganglia(group) {
- // Get datatable headers and rows
- var headers = $('#' + gangliaTableId + ' thead tr th');
- var nodes = $('#' + gangliaTableId + ' tbody tr');
-
- // Find group column
- var head, groupsCol;
- for (var i = 0; i < headers.length; i++) {
- head = headers.eq(i).html();
- if (head == 'groups') {
- groupsCol = i;
- break;
- }
- }
-
- // Check if groups definition is set
- var node, cols;
- var tgtNodes = '';
- for (var i = 0; i < nodes.length; i++) {
- cols = nodes.eq(i).find('td');
- if (!cols.eq(groupsCol).html()) {
- node = cols.eq(1).text();
- tgtNodes += node + ',';
+ noping++;
}
}
- // If there are node definitions to load
- if (tgtNodes) {
- // Remove last comma
- tgtNodes = tgtNodes.substring(0, tgtNodes.length-1);
-
- // Get node definitions
- $.ajax( {
- url : 'lib/cmd.php',
- dataType : 'json',
- data : {
- cmd : 'lsdef',
- tgt : '',
- args : tgtNodes,
- msg : group
- },
+ // Create pie chart
+ var summary = $('');
+ $('#nodes').append(summary);
- success : addNodes2GangliaTable
- });
+ // Create pie details
+ var details = $('');
+ $('#nodes').append(details);
- // Create dialog to indicate table is updating
- var update = $('
'
- + '
Updating table
'
- +'
');
- update.dialog({
- modal: true,
- width: 300,
- position: 'center'
- });
- }
-}
-
-/**
- * Add nodes to datatable
- *
- * @param data
- * Data returned from HTTP request
- * @return Nothing
- */
-function addNodes2GangliaTable(data) {
- // Data returned
- var rsp = data.rsp;
- // Group name
- var group = data.msg;
- // Hash of node attributes
- var attrs = new Object();
- // Node attributes
- var headers = $('#' + gangliaTableId + ' thead tr th');
-
- // Variable to send command and request node status
- var getNodeStatus = true;
-
- // Go through each attribute
- var node, args;
- for (var i in rsp) {
- // Get node name
- if (rsp[i].indexOf('Object name:') > -1) {
- var temp = rsp[i].split(': ');
- node = jQuery.trim(temp[1]);
-
- // Create a hash for node attributes
- attrs[node] = new Object();
- i++;
- }
-
- // Get key and value
- args = rsp[i].split('=', 2);
- var key = jQuery.trim(args[0]);
- var val = jQuery.trim(rsp[i].substring(rsp[i].indexOf('=') + 1, rsp[i].length));
-
- // Create a hash table
- attrs[node][key] = val;
-
- // If node status is available
- if (key == 'status') {
- // Do not request node status
- getNodeStatus = false;
- }
- }
-
- // Set the first four headers
- var headersCol = new Object();
- headersCol['node'] = 1;
- headersCol['status'] = 2;
- headersCol['power'] = 3;
- headersCol['ganglia'] = 4;
-
- // Go through each header
- for (var i = 5; i < headers.length; i++) {
- // Get the column index
- headersCol[headers.eq(i).html()] = i;
- }
-
- // Go through each node
- var datatable = $('#' + gangliaTableId).dataTable();
- var rows = datatable.fnGetData();
- for (var node in attrs) {
- // Get row containing node
- var nodeRowPos;
- for (var i in rows) {
- // If column contains node
- if (rows[i][1].indexOf('>' + node + '<') > -1) {
- nodeRowPos = i;
- break;
- }
- }
-
- // Get node status
- var status = '';
- if (attrs[node]['status']){
- status = attrs[node]['status'].replace('sshd', 'ping');
- }
-
- rows[nodeRowPos][headersCol['status']] = status;
-
- // Go through each header
- for (var key in headersCol) {
- // Do not put comments and status in twice
- if (key != 'usercomment' && key != 'status' && key.indexOf('statustime') < 0) {
- var val = attrs[node][key];
- if (val) {
- rows[nodeRowPos][headersCol[key]] = val;
- }
- }
- }
-
- // Update row
- datatable.fnUpdate(rows[nodeRowPos], nodeRowPos, 0, false);
- }
-
- // Enable node link
- $('.node').bind('click', loadNode);
-
- // Close dialog for updating table
- $('.ui-dialog-content').dialog('close');
-
- // If request to get node status is made
- if (getNodeStatus) {
- // Get the node status
- $.ajax( {
- url : 'lib/cmd.php',
- dataType : 'json',
- data : {
- cmd : 'nodestat',
- tgt : group,
- args : '',
- msg : ''
- },
-
- success : loadNodeStatus
- });
- } else {
- // Hide status loader
- var statCol = $('#' + gangliaTableId + ' thead tr th').eq(2);
- statCol.find('img').hide();
- }
-
- // Get the status of Ganglia
- var nodes = getNodesShown(gangliaTableId);
- $.ajax( {
- url : 'lib/cmd.php',
- dataType : 'json',
- data : {
- cmd : 'webrun',
- tgt : '',
- args : 'gangliastatus;' + nodes,
- msg : ''
+ var pie = [['Ping & monitored', pingWGanglia], ['Ping & not monitored', pingWOGanglia], ['Noping', noping]];
+ var chart = $.jqplot('ganglia_sum', [ pie ], {
+ seriesDefaults : {
+ renderer : $.jqplot.PieRenderer
},
-
- success : loadGangliaStatus
+ seriesColors : [
+ '#3CB548', '#FE9A2E', '#848484' // Green, orange, grey
+ ],
+ legend : {
+ show : true
+ },
+ grid : {
+ background : 'transparent',
+ borderColor : 'white',
+ borderWidth : '0px',
+ shadow : false
+ },
+ show : true
});
-}
-
-/**
- * Create a tool tip for ganglia status
- *
- * @return Tool tip
- */
-function createGangliaToolTip() {
- // Create tooltip container
- var toolTip = $('
Click here to refresh the Ganglia status
').css({
- 'width': '150px'
- });
- return toolTip;
-}
-
-/**
- * Install Ganglia on a given node
- *
- * @param node
- * Node to install Ganglia on
- * @return Nothing
- */
-function installGanglia(node) {
- var iframe = createIFrame('lib/cmd.php?cmd=webrun&tgt=&args=installganglia;' + node + '&msg=' + node + '&opts=flush');
- iframe.prependTo($('#gangliamon #nodes'));
- // Turn on Ganglia for node
- monitorNode(node, 'on');
+ // Change CSS styling for legend
+ summary.find('table').css({
+ 'border-style': 'none'
+ }).find('td').css({
+ 'border-style': 'none'
+ });
+
+ // Show details on mouse-over
+ $('#ganglia_sum').bind('jqplotDataMouseOver', function(env, srIndex, ptIndex, data) {
+ // Show for 8 seconds before sliding up
+ $('#ganglia_details').children().remove();
+ $('#ganglia_details').show();
+ $('#ganglia_details').append($('
' + data[1] + ' node(s) ' + data[0] + '
'));
+ $('#ganglia_details').delay(8000).slideUp();
+ });
+
+ // Open nodes page on-click
+ $('#ganglia_sum').bind('jqplotDataClick', function(env, srIndex, ptIndex, data) {
+ window.open('../xcat/index.php');
+ });
+
+ // Special note
+ // To redraw pie chart:
+ // - Use chart.series[0].data[i] to reference existing data
+ // - Use chart.redraw() to redraw chart
}
\ No newline at end of file
diff --git a/xCAT-UI/js/nodes/nodes.js b/xCAT-UI/js/nodes/nodes.js
index 1ca02dc5d..73d0aaa6e 100644
--- a/xCAT-UI/js/nodes/nodes.js
+++ b/xCAT-UI/js/nodes/nodes.js
@@ -452,11 +452,12 @@ function loadNodes(data) {
}
sorted.sort();
- // Add column for check box, node, ping, power, and comments
+ // Add column for check box, node, ping, power, monitor, and comments
sorted.unshift('',
'node',
'status',
'power',
+ 'monitor',
'comments');
// Create a datatable
@@ -479,8 +480,8 @@ function loadNodes(data) {
status = attrs[node]['status'].replace('sshd', 'ping');
}
- // Push in checkbox, node, status, and power
- row.push(checkBx, nodeLink, status, '');
+ // Push in checkbox, node, status, monitor, and power
+ row.push(checkBx, nodeLink, status, '', '');
// If the node attributes are known (i.e the group is known)
if (attrs[node]['groups']) {
@@ -523,7 +524,7 @@ function loadNodes(data) {
}
// Go through each header
- for (var i = 5; i < sorted.length; i++) {
+ for (var i = 6; i < sorted.length; i++) {
// Add the node attributes to the row
var key = sorted[i];
@@ -576,6 +577,26 @@ function loadNodes(data) {
powerNode(tgtNodes, 'off');
}
});
+
+ var monitorLnk = $('Monitor');
+
+ // Turn monitoring on
+ var monitorOnLnk = $('Monitor on');
+ monitorOnLnk.click(function() {
+ var tgtNodes = getNodesChecked(nodesTableId);
+ if (tgtNodes) {
+ monitorNode(tgtNodes, 'on');
+ }
+ });
+
+ // Turn monitoring off
+ var monitorOffLnk = $('Monitor off');
+ monitorOffLnk.click(function() {
+ var tgtNodes = getNodesChecked(nodesTableId);
+ if (tgtNodes) {
+ monitorNode(tgtNodes, 'off');
+ }
+ });
// Clone
var cloneLnk = $('Clone');
@@ -684,23 +705,36 @@ function loadNodes(data) {
}
});
+ // Install Ganglia
+ var installMonLnk = $('Install monitoring');
+ installMonLnk.click(function() {
+ var tgtNodes = getNodesChecked(nodesTableId);
+ if (tgtNodes) {
+ installGanglia(tgtNodes);
+ }
+ });
+
// Power actions
var powerActions = [ powerOnLnk, powerOffLnk ];
var powerActionMenu = createMenu(powerActions);
+
+ // Monitor actions
+ var monitorActions = [ monitorOnLnk, monitorOffLnk ];
+ var monitorActionMenu = createMenu(monitorActions);
// Advanced actions
var advancedLnk = $('Advanced');
var advancedActions;
if ('compute' == group) {
- advancedActions = [ boot2NetworkLnk, scriptLnk, setBootStateLnk, updateLnk, rcons, editProps ];
+ advancedActions = [ boot2NetworkLnk, scriptLnk, setBootStateLnk, updateLnk, rcons, editProps, installMonLnk ];
} else {
- advancedActions = [ boot2NetworkLnk, scriptLnk, setBootStateLnk, updateLnk, editProps ];
+ advancedActions = [ boot2NetworkLnk, scriptLnk, setBootStateLnk, updateLnk, editProps, installMonLnk ];
}
var advancedActionMenu = createMenu(advancedActions);
// Create an action menu
var actionsDiv = $('');
- var actions = [ [ powerLnk, powerActionMenu ], cloneLnk, deleteLnk, unlockLnk, [ advancedLnk, advancedActionMenu ] ];
+ var actions = [ [ powerLnk, powerActionMenu ], [ monitorLnk, monitorActionMenu ], cloneLnk, deleteLnk, unlockLnk, [ advancedLnk, advancedActionMenu ] ];
var actionsMenu = createMenu(actions);
actionsMenu.superfish();
actionsDiv.append(actionsMenu);
@@ -766,58 +800,64 @@ function loadNodes(data) {
});
var pingCol = $('#' + nodesTableId + ' thead tr th').eq(2);
var powerCol = $('#' + nodesTableId + ' thead tr th').eq(3);
- var commentCol = $('#' + nodesTableId + ' thead tr th').eq(4);
+ var monitorCol = $('#' + nodesTableId + ' thead tr th').eq(4);
+ var commentCol = $('#' + nodesTableId + ' thead tr th').eq(5);
pingCol.unbind('click');
powerCol.unbind('click');
+ monitorCol.unbind('click');
commentCol.unbind('click');
// Create enough space for loader to be displayed
- $('#' + nodesTableId + ' tbody tr td:nth-child(3)').css('min-width', '60px');
- $('#' + nodesTableId + ' tbody tr td:nth-child(4)').css('min-width', '60px');
-
// Center align power, ping, and comments
- $('#' + nodesTableId + ' tbody tr td:nth-child(3)').css('text-align', 'center');
- $('#' + nodesTableId + ' tbody tr td:nth-child(4)').css('text-align', 'center');
- $('#' + nodesTableId + ' tbody tr td:nth-child(5)').css('text-align', 'center');
+ $('#' + nodesTableId + ' td:nth-child(3),td:nth-child(4),td:nth-child(5)').css({
+ 'min-width': '65px',
+ 'text-align': 'center'
+ });
- // Instead refresh the node status and power status
+ // No minimum width for comments column
+ $('#' + nodesTableId + ' tbody tr td:nth-child(6)').css('text-align', 'center');
+
+ // Instead refresh the node, power, and monitor status
pingCol.find('span a').click(function() {
refreshNodeStatus(group, nodesTableId);
});
powerCol.find('span a').click(function() {
refreshPowerStatus(group, nodesTableId);
});
+ monitorCol.find('span a').click(function() {
+ refreshGangliaStatus(group, nodesTableId);
+ });
- // Create tooltip for status
+ // Create tooltip for status
+ var tooltipConf = {
+ position: "center right",
+ offset: [-2, 10],
+ effect: "fade",
+ opacity: 0.8,
+ relative: true,
+ predelay: 800
+ };
+
var pingTip = createStatusToolTip();
pingCol.find('span').append(pingTip);
- pingCol.find('span a').tooltip({
- position: "center right",
- offset: [-2, 10],
- effect: "fade",
- opacity: 0.8,
- relative: true,
- predelay: 800
- });
+ pingCol.find('span a').tooltip(tooltipConf);
// Create tooltip for power
var powerTip = createPowerToolTip();
powerCol.find('span').append(powerTip);
- powerCol.find('span a').tooltip({
- position: "center right",
- offset: [-2, 10],
- effect: "fade",
- opacity: 0.8,
- relative: true,
- predelay: 800
- });
+ powerCol.find('span a').tooltip(tooltipConf);
+
+ // Create tooltip for monitor
+ var monitorTip = createMonitorToolTip();
+ monitorCol.find('span').append(monitorTip);
+ monitorCol.find('span a').tooltip(tooltipConf);
/**
* Enable editable columns
*/
- // Do not make 1st, 2nd, 3rd, 4th, or 5th column editable
- $('#' + nodesTableId + ' td:not(td:nth-child(1),td:nth-child(2),td:nth-child(3),td:nth-child(4),td:nth-child(5))').editable(
+ // Do not make 1st, 2nd, 3rd, 4th, 5th, or 6th column editable
+ $('#' + nodesTableId + ' td:not(td:nth-child(1),td:nth-child(2),td:nth-child(3),td:nth-child(4),td:nth-child(5),td:nth-child(6))').editable(
function(value, settings) {
// Change text color to red
$(this).css('color', 'red');
@@ -1276,6 +1316,66 @@ function addNodes2Table(data) {
} // End of if
}
+/**
+ * Load the status of Ganglia for a given group
+ *
+ * @param data
+ * Data returned from HTTP request
+ * @return Nothing
+ */
+function loadGangliaStatus(data) {
+ // Get datatable
+ var datatable = $('#' + nodesTableId).dataTable();
+ var ganglia = data.rsp;
+ var rowNum, node, status, args;
+
+ for ( var i in ganglia) {
+ // ganglia[0] = nodeName and ganglia[1] = state
+ node = jQuery.trim(ganglia[i][0]);
+ status = jQuery.trim(ganglia[i][1]);
+
+ // Get the row containing the node
+ rowNum = findRow(node, '#' + nodesTableId, 1);
+
+ // Update the power status column
+ datatable.fnUpdate(status, rowNum, 4);
+ }
+
+ // Hide Ganglia loader
+ var gangliaCol = $('#' + nodesTableId + ' thead tr th').eq(4);
+ gangliaCol.find('img').hide();
+}
+
+/**
+ * Refresh the status of Ganglia for each node
+ *
+ * @param group
+ * Group name
+ * @return Nothing
+ */
+function refreshGangliaStatus(group) {
+ // Show ganglia loader
+ var gangliaCol = $('#' + nodesTableId + ' thead tr th').eq(4);
+ gangliaCol.find('img').show();
+
+ // Get power status for nodes shown
+ var nodes = getNodesShown(nodesTableId);
+
+ // Get the status of Ganglia
+ $.ajax( {
+ url : 'lib/cmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'webrun',
+ tgt : '',
+ args : 'gangliastatus;' + nodes,
+ msg : ''
+ },
+
+ success : loadGangliaStatus
+ });
+}
+
/**
* Load power status for each node
*
@@ -2510,6 +2610,19 @@ function createPowerToolTip() {
return toolTip;
}
+/**
+ * Create a tool tip for monitoring status
+ *
+ * @return Tool tip
+ */
+function createMonitorToolTip() {
+ // Create tooltip container
+ var toolTip = $('
Click here to refresh the monitoring status
').css({
+ 'width': '150px'
+ });
+ return toolTip;
+}
+
/**
* Open dialog to configure xCAT monitor
*
@@ -2969,4 +3082,143 @@ function openSetAttrsDialog() {
}
}
});
+}
+
+/**
+ * Turn on monitoring for a given node
+ *
+ * @param node
+ * Node to monitor on or off
+ * @param monitor
+ * Monitor state, on or off
+ * @return Nothing
+ */
+function monitorNode(node, monitor) {
+ if (monitor == 'on') {
+ // Append loader to warning bar
+ var gangliaLoader = createLoader('');
+ var warningBar = $('#nodesTab').find('.ui-state-error p');
+ if (warningBar.length) {
+ warningBar.append(gangliaLoader);
+ }
+
+ if (node) {
+ // Check if ganglia RPMs are installed
+ $.ajax( {
+ url : 'lib/cmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'webrun',
+ tgt : '',
+ args : 'gangliacheck;' + node,
+ msg : node // Node range will be passed along in data.msg
+ },
+
+ /**
+ * Start ganglia on a given node range
+ *
+ * @param data
+ * Data returned from HTTP request
+ * @return Nothing
+ */
+ success : function(data) {
+ // Get response
+ var out = data.rsp[0].split(/\n/);
+
+ // Go through each line
+ var warn = false;
+ var warningMsg = '';
+ for (var i in out) {
+ // If an RPM is not installed
+ if (out[i].indexOf('not installed') > -1) {
+ warn = true;
+
+ if (warningMsg) {
+ warningMsg += ' ' + out[i];
+ } else {
+ warningMsg = out[i];
+ }
+ }
+ }
+
+ // If there are warnings
+ if (warn) {
+ // Create warning bar
+ var warningBar = createWarnBar(warningMsg);
+ warningBar.css('margin-bottom', '10px');
+ warningBar.prependTo($('#nodesTab'));
+ } else {
+ $.ajax( {
+ url : 'lib/cmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'webrun',
+ tgt : '',
+ args : 'gangliastart;' + data.msg,
+ msg : ''
+ },
+
+ success : function(data) {
+ // Remove any warnings
+ $('#nodesTab').find('.ui-state-error').remove();
+ }
+ });
+ } // End of if (warn)
+ } // End of function(data)
+ });
+ } else {
+ $.ajax( {
+ url : 'lib/cmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'webrun',
+ tgt : '',
+ args : 'gangliastart',
+ msg : ''
+ },
+
+ success : function(data) {
+ // Remove any warnings
+ $('#nodesTab').find('.ui-state-error').remove();
+ }
+ });
+ } // End of if (node)
+ } else {
+ var args;
+ if (node) {
+ args = 'gangliastop;' + node;
+ } else {
+ args = 'gangliastop';
+ }
+
+ $.ajax( {
+ url : 'lib/cmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'webrun',
+ tgt : '',
+ args : args,
+ msg : ''
+ },
+
+ success : function(data) {
+ // Do nothing
+ }
+ });
+ }
+}
+
+/**
+ * Install Ganglia on a given node
+ *
+ * @param node
+ * Node to install Ganglia on
+ * @return Nothing
+ */
+function installGanglia(node) {
+ var iframe = createIFrame('lib/cmd.php?cmd=webrun&tgt=&args=installganglia;' + node + '&msg=' + node + '&opts=flush');
+ iframe.prependTo($('#nodesTab'));
+
+ // Turn on Ganglia for node
+ monitorNode(node, 'on');
}
\ No newline at end of file
diff --git a/xCAT-UI/js/ui.js b/xCAT-UI/js/ui.js
index 7cac4b0d7..a8ec477bf 100644
--- a/xCAT-UI/js/ui.js
+++ b/xCAT-UI/js/ui.js
@@ -506,6 +506,8 @@ function initPage() {
headers.eq(2).css('background-color', '#A9D0F5');
loadProvisionPage();
} else if (page == 'monitor.php') {
+ includeJs("js/jquery/jquery.jqplot.min.js");
+ includeJs("js/jquery/jqplot.pieRenderer.min.js");
includeJs("js/monitor/xcatmon.js");
includeJs("js/monitor/rmcmon.js");
includeJs("js/monitor/gangliamon.js");
@@ -515,8 +517,7 @@ function initPage() {
includeJs("js/manual/manual.js");
headers.eq(4).css('background-color', '#A9D0F5');
loadManualPage();
- }
- else {
+ } else {
includeJs("js/jquery/jquery.topzindex.min.js");
includeJs("js/nodes/nodeset.js");
includeJs("js/nodes/rnetboot.js");
diff --git a/xCAT-UI/lib/ui.php b/xCAT-UI/lib/ui.php
index bc7ec98b8..d903fd7d6 100644
--- a/xCAT-UI/lib/ui.php
+++ b/xCAT-UI/lib/ui.php
@@ -16,6 +16,7 @@ function loadPage(){
+