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(){ +