/** * Global variables */ // Node tabs var nodesTab; // Original node attributes var origAttrs = new Object(); // Node attributes var nodeAttrs; // Node list var nodesList; // Nodes datatable ID var nodesTableId = 'nodesDatatable'; // provision clock for provision progress stop var provisionClock; /** * Set node tab * * @param tab * Tab object * @return Nothing */ function setNodesTab(tab) { nodesTab = tab; } /** * Get node tab * * @return Tab object */ function getNodesTab() { return nodesTab; } /** * Get node list * * @return Node list */ function getNodesList() { return nodesList; } /** * Get nodes table ID * * @return Nodes table ID */ function getNodesTableId() { return nodesTableId; } /** * Load nodes page * * @return Nothing */ function loadNodesPage() { // If groups are not already loaded if (!$('#groups').length) { // Create a groups division var groups = $('
'); var nodes = $('
'); $('#content').append(groups); $('#content').append(nodes); // Create loader var loader = createLoader(); groups.append(loader); // Create info bar var info = createInfoBar('Select a group to view its nodes.'); $('#nodes').append(info); // Get groups $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'extnoderange', tgt : '/.*', args : 'subgroups', msg : '' }, success : function(data){ loadGroups(data); // draw cluster's summary by group names loadPieSummary(); } }); } } /** * show cluster's summary in pie chats * * @return Nothing */ function loadPieSummary(){ $('#nodes').append('

Cluster Summary


'); var summaryTable = '' + '' + '' + '' + '' + '' + '' + '' + '
'; $('#nodes').append(summaryTable); $('#nodes .summarypie').append(createLoader()); $.ajax({ url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'webrun', tgt : '', args : 'summary', msg : '' }, success:function(data){ for(var i in data.rsp){ drawPieSummary(i, data.rsp[i]); } } }); } /** * use nodels to get nodes' information and call jqplot to draw on the page * * @return Nothing */ function drawPieSummary(index, valuepair){ var position = 0; var key = ''; var val = ''; var chattitle = ''; var dataArray = []; var tempArray = []; var container = $('#nodes .summarypie').eq(index); position = valuepair.indexOf('='); chattitle = valuepair.substr(0, position); tempArray = valuepair.substr(position + 1).split(';'); for (var i in tempArray){ position = tempArray[i].indexOf(':'); key = tempArray[i].substr(0, position); val = Number(tempArray[i].substr(position + 1)); dataArray.push([key,val]); } container.empty(); var plot=$.jqplot(container.attr('id'), [dataArray], { title: chattitle, seriesDefaults: { renderer: $.jqplot.PieRenderer, rendererOptions: { padding: 5, fill:true, shadow:true, shadowOffset: 2, shadowDepth: 5, shadowAlpha: 0.07, dataLabels : 'value', showDataLabels: true } }, legend: { show:true, location: 'e' } }); container.bind('jqplotDataClick',loadSummaryDetail); container.bind('jqplotDataHighlight',function(){this.style.cursor='pointer';}); container.bind('jqplotDataUnhighlight',function(){this.style.cursor='';}); } function loadSummaryDetail(ev, seriesIndex, pointIndex, data){ var temp = $(this).attr('id'); temp = temp.replace('pie', ''); var table = ''; switch(temp){ case 'os': case 'arch': case 'provmethod': case 'nodetype':{ table = 'nodetype'; } break; case 'status': { table = 'nodelist'; } break; } var args = table + '.' + temp + '=='; if(data[0] != 'unknown'){ args += data[0]; } drawNodesArea('', args, ''); } /** * Load groups * * @param data * Data returned from HTTP request * @return */ function loadGroups(data) { // Remove loader $('#groups').find('img').remove(); // Save group in cookie var groups = data.rsp; setGroupsCookies(data); // Create a list of groups $('#groups').append('
Groups
'); var grouplist= $('
'); // Create a link for each group for (var i = groups.length; i--;) { grouplist.append('
' + groups[i] + '
'); } $('#groups').append(grouplist); //bind the click event $('#groups .groupdiv div').bind('click', function(){ var thisgroup=$(this).text(); $('#groups .groupdiv div').removeClass('selectgroup'); $(this).addClass('selectgroup'); drawNodesArea(thisgroup,'',thisgroup); }); // Make a link to add nodes $('#groups').append('
'); $('#groups #adddiv').append(mkAddNodeLink()); } /** * empty the nodes area, and add two tabs for add loading nodes result * * @param targetgroup: the name range for nodels command * arguments: filter arguments for nodels command * message: the useful information for the http request * * @return */ function drawNodesArea(targetgroup, cmdargs, message){ // Clear nodes division $('#nodes').empty(); // Create loader var loader = $('
').append(createLoader()); // Create a tab for this group var tab = new Tab('nodesPageTabs'); setNodesTab(tab); tab.init(); $('#nodes').append(tab.object()); tab.add('nodesTab', 'Table', loader, false); tab.add('graphTab', 'Graphic', '', false); $('#nodesPageTabs').bind('tabsselect', function(event, ui){ // for the graphical tab, we should check the graphical data // first if (1 == ui.index){ createPhysicalLayout(nodesList); } }); // To improve performance, get all nodes within selected group // Get node definitions only for first 50 nodes $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'nodels', tgt : targetgroup, args : cmdargs, msg : message }, /** * Get node definitions for first 50 nodes * * @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, msg : targetgroup }, success : loadNodes }); } }); } /** * Make a link to add nodes * * @returns Link to add nodes */ function mkAddNodeLink() { // Create link to add nodes var addNodeLink = $('+ Add Node'); addNodeLink.click(function() { // Create info bar var info = createInfoBar('Select the hardware management for the new node range'); // Create form to add node var addNodeForm = $('
'); addNodeForm.append(info); addNodeForm.append('
' + '' + '
'); // Create advanced link to set advanced node properties var advanced = $('
'); var advancedLnk = $('Advanced').css({ 'cursor': 'pointer', 'color': '#0000FF' }); advancedLnk.click(function() { // Get node attributes $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'lsdef', tgt : '', args : '-t;node;-h', msg : '' }, /** * Set node attributes and open dialog * * @param data * Data returned from HTTP request * @return Nothing */ success : function(data) { // Save node attributes setNodeAttrs(data); // Open a dialog to set node attributes openSetAttrsDialog(); } }); // Close dialog addNodeForm.dialog('close'); }); advanced.append(advancedLnk); addNodeForm.append(advanced); // Open dialog to add node addNodeForm.dialog({ modal: true, width: 400, title:'Add Node', close: function(){$(this).remove();}, buttons: { 'Ok': function(){ // Get hardware management var mgt = $(this).find('select[name=mgt]').val(); var plugin; switch(mgt) { case "blade": plugin = new bladePlugin(); break; case "hmc": plugin = new hmcPlugin(); break; case "ipmi": plugin = new ipmiPlugin(); break; case "zvm": plugin = new zvmPlugin(); break; } plugin.addNode(); $(this).dialog('close'); }, 'Cancel': function(){ $(this).dialog('close'); } } }); }); // Generate tooltips addNodeLink.tooltip({ position: 'center right', offset: [-2, 10], effect: 'fade', opacity: 0.7, predelay: 800 }); return addNodeLink; } /** * Load subgroups * * @param data * Data returned from HTTP request * @return Nothing */ function loadSubgroups(data) { var rsp = data.rsp; // Data returned var group = data.msg; // Group name // Go through each subgroup for (var i in rsp) { // Do not put the same group in the subgroup if (rsp[i] != group && $('#' + group).length) { // Add subgroup inside group $('#groups').jstree('create', $('#' + group), 'inside', { 'attr': {'id': rsp[i] + 'Subgroup'}, 'data': rsp[i]}, '', true); } } } /** * Load nodes belonging to a given group * * @param data * Data returned from HTTP request * @return Nothing */ function loadNodes(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 = new Object(); // Variable to send command and request node status var getNodeStatus = true; // Clear cookie containing list of nodes where their attributes need to be updated $.cookie('nodes2update', ''); // Clear hash table containing node attributes origAttrs = ''; 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 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)); // Create a hash table attrs[node][key] = val; headers[key] = 1; // If node status is available if (key == 'status') { // Do not request node status getNodeStatus = false; } } // 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 attributes in hash table origAttrs = attrs; // Sort headers var sorted = new Array(); for (var key in headers) { // Do not put comments and status in twice if (key != 'usercomment' && key != 'status' && key.indexOf('statustime') < 0) { sorted.push(key); } } sorted.sort(); // Add column for check box, node, ping, power, monitor, and comments sorted.unshift('', 'node', 'status', 'power', 'monitor', 'comments'); // Create a datatable var nodesTable = new DataTable(nodesTableId); nodesTable.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, monitor, and power row.push(checkBx, nodeLink, status, '', ''); // If the node attributes are known (i.e the group is known) if (attrs[node]['groups']) { // Put in comments var comments = attrs[node]['usercomment']; // If no comments exists, show 'No comments' and set icon image source var iconSrc; if (!comments) { comments = 'No comments'; iconSrc = 'images/nodes/ui-icon-no-comment.png'; } else { iconSrc = 'images/nodes/ui-icon-comment.png'; } // Create comments icon var tipID = node + 'Tip'; var icon = $('').css({ 'width': '18px', 'height': '18px' }); // Create tooltip var tip = createCommentsToolTip(comments); var col = $('').append(icon); col.append(tip); row.push(col); // Generate tooltips icon.tooltip({ position: "center right", offset: [-2, 10], effect: "fade", opacity: 0.8, relative: true, delay: 500 }); } else { // Do not put in comments if attributes are not known row.push(''); } // Go through each header for (var i = 6; i < sorted.length; i++) { // Add the node attributes to the row var key = sorted[i]; // Do not put comments and status in twice 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 nodesTable.add(row); } // Clear the tab before inserting the table $('#nodesTab').children().remove(); // Create info bar for nodes tab var info = createInfoBar('Click on a cell to edit. Click outside the table to write to the cell. Hit the Escape key to ignore changes. Once you are satisfied with how the table looks, click on Save.'); $('#nodesTab').append(info); // Create action bar var actionBar = $('
'); /** * Create menu for actions to perform against a given node: * power, clone, delete, unlock, and advanced */ // Power on var powerOnLnk = $('Power on'); powerOnLnk.click(function() { var tgtNodes = getNodesChecked(nodesTableId); if (tgtNodes) { powerNode(tgtNodes, 'on'); } }); // Power off var powerOffLnk = $('Power off'); powerOffLnk.click(function() { var tgtNodes = getNodesChecked(nodesTableId); if (tgtNodes) { 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'); cloneLnk.click(function() { var tgtNodes = getNodesChecked(nodesTableId).split(','); for (var i in tgtNodes) { var mgt = getNodeAttr(tgtNodes[i], 'mgt'); // Create an instance of the plugin var plugin; switch(mgt) { case "blade": plugin = new bladePlugin(); break; case "fsp": plugin = new fspPlugin(); break; case "hmc": plugin = new hmcPlugin(); break; case "ipmi": plugin = new ipmiPlugin(); break; case "ivm": plugin = new ivmPlugin(); break; case "zvm": plugin = new zvmPlugin(); break; } plugin.loadClonePage(tgtNodes[i]); } }); // Delete var deleteLnk = $('Delete'); deleteLnk.click(function() { var tgtNodes = getNodesChecked(nodesTableId); if (tgtNodes) { loadDeletePage(tgtNodes); } }); // Unlock var unlockLnk = $('Unlock'); unlockLnk.click(function() { var tgtNodes = getNodesChecked(nodesTableId); if (tgtNodes) { loadUnlockPage(tgtNodes); } }); // Run script var scriptLnk = $('Run script'); scriptLnk.click(function() { var tgtNodes = getNodesChecked(nodesTableId); if (tgtNodes) { loadScriptPage(tgtNodes); } }); // Update var updateLnk = $('Update'); updateLnk.click(function() { var tgtNodes = getNodesChecked(nodesTableId); if (tgtNodes) { loadUpdatenodePage(tgtNodes); } }); // Set boot state var setBootStateLnk = $('Set boot state'); setBootStateLnk.click(function() { var tgtNodes = getNodesChecked(nodesTableId); if (tgtNodes) { loadNodesetPage(tgtNodes); } }); // Boot to network var boot2NetworkLnk = $('Boot to network'); boot2NetworkLnk.click(function() { var tgtNodes = getNodesChecked(nodesTableId); if (tgtNodes) { loadNetbootPage(tgtNodes); } }); var provisionLnk = $('Provision'); provisionLnk.click(function(){ var tgtNodes = getNodesChecked(nodesTableId); if (tgtNodes){ openQuickProvisionDia(tgtNodes); } }); // Remote console var rcons = $('Open console'); rcons.bind('click', function(event){ var tgtNodes = getNodesChecked(nodesTableId); if (tgtNodes) { loadRconsPage(tgtNodes); } }); // Edit properties var editProps = $('Edit properties'); editProps.bind('click', function(event){ var tgtNodes = getNodesChecked(nodesTableId).split(','); for (var i in tgtNodes) { loadEditPropsPage(tgtNodes[i]); } }); // Install Ganglia var installMonLnk = $('Install monitoring'); installMonLnk.click(function() { var tgtNodes = getNodesChecked(nodesTableId); if (tgtNodes) { installGanglia(tgtNodes); } }); // actions (power monitor) var powerLnk = 'Actions'; var powerActionMenu = createMenu([cloneLnk, deleteLnk, monitorOnLnk, monitorOffLnk, powerOnLnk, powerOffLnk, scriptLnk]); // configurations var configLnk = 'Configuration'; var configMenu = createMenu([unlockLnk, updateLnk, editProps, installMonLnk]); // Advanced actions var advancedLnk = 'Provision'; var advancedActionMenu = createMenu([ boot2NetworkLnk, setBootStateLnk, rcons, provisionLnk]); // Create an action menu var actionsMenu = createMenu([ [ powerLnk, powerActionMenu ], [ configLnk, configMenu ], [ advancedLnk, advancedActionMenu ] ]); actionsMenu.superfish(); actionsMenu.css('display', 'inline-block'); actionBar.append(actionsMenu); // Insert action bar and nodes datatable //$('#nodesTab').append(actionBar); $('#nodesTab').append(nodesTable.object()); /** * Create menu to save and undo table changes */ /* // Save changes var saveLnk = $('Save'); saveLnk.bind('click', function(event){ updateNodeAttrs(group); }); // Undo changes var undoLnk = $('Undo'); undoLnk.bind('click', function(event){ restoreNodeAttrs(); // Hide table menu actions tableActionsMenu.hide(); }); // It will be hidden until a change is made var tableActionsMenu = createMenu([saveLnk, undoLnk]); tableActionsMenu.css('display', 'inline-block'); tableActionsMenu.attr('id', 'tableActionMenu'); actionsDiv.append(tableActionsMenu.hide()); */ // Turn table into a datatable var nodesDatatable = $('#' + nodesTableId).dataTable({ 'iDisplayLength': 50, 'bLengthChange': false }); // Filter table when enter key is pressed $('#' + nodesTableId + '_filter input').unbind(); $('#' + nodesTableId + '_filter input').bind('keyup', function(e){ if (e.keyCode == 13) { var table = $('#' + nodesTableId).dataTable(); table.fnFilter($(this).val()); // If there are nodes found, get the node attributes if (!$('#' + nodesTableId + ' .dataTables_empty').length) { getNodeAttrs(group); } } }); // Load node definitions when next or previous buttons are clicked $('#' + nodesTableId + '_next, #' + nodesTableId + '_previous').click(function() { getNodeAttrs(group); }); /** * Change how datatable behaves */ // Do not sort ping, power, and comment column var cols = $('#' + nodesTableId + ' thead tr th').click(function() { getNodeAttrs(group); }); var pingCol = $('#' + nodesTableId + ' thead tr th').eq(2); var powerCol = $('#' + nodesTableId + ' thead tr th').eq(3); 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 // Center align power, ping, and comments $('#' + nodesTableId + ' td:nth-child(3),td:nth-child(4),td:nth-child(5)').css({ 'min-width': '65px', 'text-align': 'center' }); // 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); }); var menuDiv=$('
'); $('#' + nodesTableId + '_wrapper').prepend(menuDiv); menuDiv.append(actionBar); $('#'+nodesTableId+'_filter').appendTo(menuDiv); // 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 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, 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'); // Get column index var colPos = this.cellIndex; // Get row index var dTable = $('#' + nodesTableId).dataTable(); var rowPos = dTable.fnGetPosition(this.parentNode); // Update datatable dTable.fnUpdate(value, rowPos, colPos, false); // Get node name var node = $(this).parent().find('td a.node').text(); // Flag node to update flagNode2Update(node); // Show table menu actions tableActionsMenu.show(); return (value); }, { onblur : 'submit', // Clicking outside editable area submits changes type : 'textarea', placeholder: ' ', height : '30px' // The height of the text area }); /* /** * Get the node status and definable node attributes */ // If request to get node status is made if (getNodeStatus) { var tgt = getNodesShown(nodesTableId); // Get node status $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'nodestat', tgt : tgt, args : '-u', msg : '' }, success : loadNodeStatus }); } else { // Hide status loader var statCol = $('#' + nodesTableId + ' thead tr th').eq(2); statCol.find('img').hide(); } // Get definable node attributes $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'lsdef', tgt : '', args : '-t;node;-h', msg : '' }, success : setNodeAttrs }); /** * Additional ajax requests need to be made for zVM * load advanced information based on hardware architecture */ advancedLoad(group); } /** * Get nodes currently shown in datatable * * @param tableId * Datatable ID * @return String of nodes shown */ function getNodesShown(tableId) { // String of nodes shown var shownNodes = ''; // Get rows of shown nodes var nodes = $('#' + tableId + ' tbody tr'); // Go through each row var cols; for (var i = 0; i < nodes.length; i++) { // Get second column containing node name cols = nodes.eq(i).find('td'); shownNodes += cols.eq(1).text() + ','; } // Remove last comma shownNodes = shownNodes.substring(0, shownNodes.length-1); return shownNodes; } /** * Get attributes for nodes not yet initialized * * @param group * Group name * @return Nothing */ function getNodeAttrs(group) { // Get datatable headers and rows var headers = $('#' + nodesTableId + ' thead tr th'); var nodes = $('#' + nodesTableId + ' 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 + ','; } } // 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 }, success : addNodes2Table }); // 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 addNodes2Table(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 = $('#' + nodesTableId + ' thead tr th'); // Variable to send command and request node status var getNodeStatus = true; // Clear cookie containing list of nodes where their attributes need to be updated $.cookie('nodes2update', ''); // 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; // Save attributes in original hash table origAttrs[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['comments'] = 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 = $('#' + nodesTableId).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); // Insert node comments // This is done after datatable is updated because // you cannot insert an object using fnUpdate() var comments = attrs[node]['usercomment']; // If no comments exists, show 'No comments' and // set icon image source var iconSrc; if (!comments) { comments = 'No comments'; iconSrc = 'images/nodes/ui-icon-no-comment.png'; } else { iconSrc = 'images/nodes/ui-icon-comment.png'; } // Create icon for node comments var tipID = node + 'Tip'; var commentsCol = $('#' + node).parent().parent().find('td').eq(4); // Create tooltip var icon = $('').css({ 'width': '18px', 'height': '18px' }); var tip = createCommentsToolTip(comments); var span = $('').append(icon); span.append(tip); commentsCol.append(span); // Generate tooltips icon.tooltip({ position: "center right", offset: [-2, 10], effect: "fade", opacity: 0.8, relative: true, delay: 500 }); } // Enable node link $('.node').bind('click', loadNode); // Close dialog for updating table $('.ui-dialog-content').dialog('close'); /** * 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( function(value, settings) { // Change text color to red $(this).css('color', 'red'); // Get column index var colPos = this.cellIndex; // Get row index var dTable = $('#' + nodesTableId).dataTable(); var rowPos = dTable.fnGetPosition(this.parentNode); // Update datatable dTable.fnUpdate(value, rowPos, colPos, false); // Get node name var node = $(this).parent().find('td a.node').text(); // Flag node to update flagNode2Update(node); // Show table menu actions $('#tableActionMenu').show(); return (value); }, { onblur : 'submit', // Clicking outside editable area submits changes type : 'textarea', placeholder: ' ', height : '30px' // The height of the text area }); */ // If request to get node status is made if (getNodeStatus) { // Get node status $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'nodestat', tgt : group, args : '-u', msg : '' }, success : loadNodeStatus }); } else { // Hide status loader var statCol = $('#' + nodesTableId + ' thead tr th').eq(2); statCol.find('img').hide(); } /** * Additional ajax requests need to be made for zVM */ advancedLoad(group); } /** * 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 * * @param data * Data returned from HTTP request * @return Nothing */ function loadPowerStatus(data) { var dTable = $('#' + nodesTableId).dataTable(); var power = data.rsp; var rowPos, node, status, args; for (var i in power) { // power[0] = nodeName and power[1] = state args = power[i].split(':'); node = jQuery.trim(args[0]); status = jQuery.trim(args[1]); // Get the row containing the node rowPos = findRow(node, '#' + nodesTableId, 1); // Update the power status column dTable.fnUpdate(status, rowPos, 3, false); } // Hide power loader var powerCol = $('#' + nodesTableId + ' thead tr th').eq(3); powerCol.find('img').hide(); } /** * Refresh power status for each node * * @param group * Group name * @param tableId * Table to update node status * @return Nothing */ function refreshPowerStatus(group, tableId) { // Show power loader var powerCol = $('#' + tableId + ' thead tr th').eq(3); powerCol.find('img').show(); // Get power status for nodes shown var nodes = getNodesShown(tableId); // Get power status $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'rpower', tgt : nodes, args : 'stat', msg : '' }, success : loadPowerStatus }); } /** * Load node status for each node * * @param data * Data returned from HTTP request * @return Nothing */ function loadNodeStatus(data) { var dTable = $('#' + nodesTableId).dataTable(); var rsp = data.rsp; var args, rowPos, node, status; // Get all nodes within datatable for (var i in rsp) { args = rsp[i].split(':'); // args[0] = node and args[1] = status node = jQuery.trim(args[0]); status = jQuery.trim(args[1]).replace('sshd', 'ping'); // Get row containing node rowPos = findRow(node, '#' + nodesTableId, 1); // Update ping status column dTable.fnUpdate(status, rowPos, 2, false); } // Hide status loader var statCol = $('#' + nodesTableId + ' thead tr th').eq(2); statCol.find('img').hide(); } /** * Refresh ping status for each node * * @param group * Group name * @param tableId * Table to update node status * @return Nothing */ function refreshNodeStatus(group, tableId) { // Show ping loader var pingCol = $('#' + tableId + ' thead tr th').eq(2); pingCol.find('img').show(); // Get power status for nodes shown var nodes = getNodesShown(tableId); // Get the node status $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'nodestat', tgt : nodes, args : '-u', msg : '' }, success : loadNodeStatus }); } /** * Load inventory for given node * * @param e * Windows event * @return Nothing */ function loadNode(e) { if (!e) { e = window.event; } // Get node that was clicked var node = (e.target) ? e.target.id : e.srcElement.id; var mgt = getNodeAttr(node, 'mgt'); // Create an instance of the plugin var plugin; switch(mgt) { case "blade": plugin = new bladePlugin(); break; case "fsp": plugin = new fspPlugin(); break; case "hmc": plugin = new hmcPlugin(); break; case "ipmi": plugin = new ipmiPlugin(); break; case "ivm": plugin = new ivmPlugin(); break; case "zvm": plugin = new zvmPlugin(); break; } // Get tab area where a new tab will be inserted var myTab = getNodesTab(); var inst = 0; var newTabId = 'nodeTab' + inst; while ($('#' + newTabId).length) { // If one already exists, generate another one inst = inst + 1; newTabId = 'nodeTab' + inst; } // Reset node process $.cookie(node + 'Processes', 0); // Add new tab, only if one does not exist var loader = createLoader(newTabId + 'TabLoader'); loader = $('
').append(loader); myTab.add(newTabId, node, loader, true); // Get node inventory var msg = 'out=' + newTabId + ',node=' + node; $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'rinv', tgt : node, args : 'all', msg : msg }, success : plugin.loadInventory }); // Select new tab myTab.select(newTabId); } /** * Unlock a node by setting the ssh keys * * @param tgtNodes * Nodes to unlock * @return Nothing */ function loadUnlockPage(tgtNodes) { // Get nodes tab var tab = getNodesTab(); // Generate new tab ID var instance = 0; var newTabId = 'unlockTab' + instance; while ($('#' + newTabId).length) { // If one already exists, generate another one instance = instance + 1; newTabId = 'unlockTab' + instance; } var unlockForm = $('
'); // Create status bar, hide on load var statBarId = 'unlockStatusBar' + instance; var statusBar = createStatusBar(statBarId).hide(); unlockForm.append(statusBar); // Create loader var loader = createLoader(''); statusBar.find('div').append(loader); // Create info bar var infoBar = createInfoBar('Give the root password for this node range to setup its SSH keys.'); unlockForm.append(infoBar); unlockForm.append('
'); unlockForm.append('
'); // Generate tooltips unlockForm.find('div input[title]').tooltip({ position: "center right", offset: [-2, 10], effect: "fade", opacity: 0.7, predelay: 800, events : { def : "mouseover,mouseout", input : "mouseover,mouseout", widget : "focus mouseover,blur mouseout", tooltip : "mouseover,mouseout" } }); /** * Ok */ var okBtn = createButton('Ok'); okBtn.click(function() { // Remove any warning messages $(this).parent().parent().find('.ui-state-error').remove(); // If a password is given var password = $('#' + newTabId + ' input[name=password]').css('border', 'solid #BDBDBD 1px'); if (password.val()) { // Setup SSH keys $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'webrun', tgt : '', args : 'unlock;' + tgtNodes + ';' + password.val(), msg : 'out=' + statBarId + ';cmd=unlock;tgt=' + tgtNodes }, success : updateStatusBar }); // Show status bar statusBar.show(); // Disable all inputs and Ok button $('#' + newTabId + ' input').attr('disabled', 'disabled'); $(this).attr('disabled', 'true'); } else { // Show warning message var warn = createWarnBar('You are missing some values!'); warn.prependTo($(this).parent().parent()); password.css('border', 'solid #FF0000 1px'); } }); unlockForm.append(okBtn); tab.add(newTabId, 'Unlock', unlockForm, true); tab.select(newTabId); } /** * Load script page * * @param tgtNodes * Targets to run script against * @return Nothing */ function loadScriptPage(tgtNodes) { // Get nodes tab var tab = getNodesTab(); // Generate new tab ID var inst = 0; var newTabId = 'scriptTab' + inst; while ($('#' + newTabId).length) { // If one already exists, generate another one inst = inst + 1; newTabId = 'scriptTab' + inst; } // Open new tab // Create remote script form var scriptForm = $('
'); // Create status bar var barId = 'scriptStatusBar' + inst; var statBar = createStatusBar(barId); statBar.hide(); scriptForm.append(statBar); // Create loader var loader = createLoader('scriptLoader' + inst); statBar.find('div').append(loader); // Create info bar var infoBar = createInfoBar('Load a script to run against this node range.'); scriptForm.append(infoBar); // Target node or group var tgt = $('
'); scriptForm.append(tgt); // Upload file var upload = $('
'); var label = $(''); var file = $(''); var subBtn = createButton('Load'); upload.append(label); upload.append(file); upload.append(subBtn); scriptForm.append(upload); // Generate tooltips scriptForm.find('div input[title]').tooltip({ position: "center right", offset: [-2, 10], effect: "fade", opacity: 0.7, predelay: 800, events : { def : "mouseover,mouseout", input : "mouseover,mouseout", widget : "focus mouseover,blur mouseout", tooltip : "mouseover,mouseout" } }); // Script var script = $('
').css({ 'font-size': '10px', 'height': '50px', 'width': '200px', 'background-color': '#000', 'color': '#fff', 'border': '0px', 'display': 'block' }); // Create links to save and cancel changes var lnkStyle = { 'color': '#58ACFA', 'font-size': '10px', 'display': 'inline-block', 'padding': '5px', 'float': 'right' }; var saveLnk = $('Save').css(lnkStyle).hide(); var cancelLnk = $('Cancel').css(lnkStyle).hide(); var infoSpan = $('Click to edit').css(lnkStyle); // Save changes onclick saveLnk.bind('click', function(){ // Get node and comment var node = $(this).parent().parent().find('img').attr('id').replace('Tip', ''); var comments = $(this).parent().find('textarea').val(); // Save comment $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'chdef', tgt : '', args : '-t;node;-o;' + node + ';usercomment=' + comments, msg : 'out=nodesTab;tgt=' + node }, success: showChdefOutput }); // Hide cancel and save links $(this).hide(); cancelLnk.hide(); }); // Cancel changes onclick cancelLnk.bind('click', function(){ // Get original comment and put it back var orignComments = $(this).parent().find('textarea').text(); $(this).parent().find('textarea').val(orignComments); // Hide cancel and save links $(this).hide(); saveLnk.hide(); infoSpan.show(); }); // Show save link when comment is edited txtArea.bind('click', function(){ saveLnk.show(); cancelLnk.show(); infoSpan.hide(); }); toolTip.append(txtArea); toolTip.append(cancelLnk); toolTip.append(saveLnk); toolTip.append(infoSpan); return toolTip; } /** * Create a tool tip for node status * * @return Tool tip */ function createStatusToolTip() { // Create tooltip container var toolTip = $('
').css({ 'width': '150px' }); // Create info text var info = $('

'); info.append('Click here to refresh the node status. To configure the xCAT monitor, '); // Create link to turn on xCAT monitoring var monitorLnk = $('click here').css({ 'color': '#58ACFA', 'font-size': '10px' }); // Open dialog to configure xCAT monitor monitorLnk.bind('click', function(){ // Check if xCAT monitor is enabled $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'monls', tgt : '', args : 'xcatmon', msg : '' }, success : openConfXcatMon }); }); info.append(monitorLnk); toolTip.append(info); return toolTip; } /** * Create a tool tip for power status * * @return Tool tip */ function createPowerToolTip() { // Create tooltip container var toolTip = $('
Click here to refresh the power status
').css({ 'width': '150px' }); 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 * * @param data * Data returned from HTTP request * @return Nothing */ function openConfXcatMon(data) { // Create info bar var info = createInfoBar('Configure the xCAT monitor. Select to enable or disable the monitor below.'); var dialog = $('
'); dialog.append(info); // Create status area var statusArea = $('
').css('padding-top', '10px'); var label = $(''); statusArea.append(label); // Get xCAT monitor status var status = data.rsp[0]; var buttons; // If xCAT monitor is disabled if (status.indexOf('not-monitored') > -1) { status = $('Disabled').css('padding', '0px 5px'); statusArea.append(status); // Create enable and cancel buttons buttons = { "Enable": function(){ // Enable xCAT monitor $.ajax({ url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'monstart', tgt : '', args : 'xcatmon', msg : '' }, success : function(data){ openDialog('info', data.rsp[0]); } }); $(this).dialog("close"); }, "Cancel": function(){ $(this).dialog("close"); } }; } else { status = $('Enabled').css('padding', '0px 5px'); statusArea.append(status); // Create disable and cancel buttons buttons = { "Disable": function(){ // Disable xCAT monitor $.ajax({ url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'monstop', tgt : '', args : 'xcatmon', msg : '' }, success : function(data){ openDialog('info', data.rsp[0]); } }); $(this).dialog("close"); }, "Cancel": function(){ $(this).dialog("close"); } }; } dialog.append(statusArea); // Open dialog dialog.dialog({ modal: true, width: 500, buttons: buttons }); } /** * Show chdef output * * @param data * Data returned from HTTP request * @return Nothing */ function showChdefOutput(data) { // Get output var out = data.rsp; var args = data.msg.split(';'); var tabID = args[0].replace('out=', ''); var tgt = args[1].replace('tgt=', ''); // Find info bar on nodes tab, if any var info = $('#' + tabID).find('.ui-state-highlight'); if (!info.length) { // Create info bar if one does not exist info = createInfoBar(''); $('#' + tabID).append(info); } // Go through output and append to paragraph var prg = $('

'); for (var i in out) { prg.append(tgt + ': ' + out[i] + '
'); } info.append(prg); } /** * Set node attributes * * @param data * Data returned from HTTP request * @return Nothing */ function setNodeAttrs(data) { // Clear hash table containing definable node attributes nodeAttrs = new Array(); // Get definable attributes var attrs = data.rsp[2].split(/\n/); // Go through each line var attr, key, descr; for (var i in attrs) { attr = attrs[i]; // If the line is not empty if (attr) { // If the line has the attribute name if (attr.indexOf(':') && attr.indexOf(' ')) { // Get attribute name and description key = jQuery.trim(attr.substring(0, attr.indexOf(':'))); descr = jQuery.trim(attr.substring(attr.indexOf(':') + 1)); // Remove arrow brackets descr = descr.replace(new RegExp('<|>', 'g'), ''); // Set hash table where key = attribute name and value = // description nodeAttrs[key] = descr; } else { // Remove arrow brackets attr = attr.replace(new RegExp('<|>', 'g'), ''); // Append description to hash table nodeAttrs[key] = nodeAttrs[key] + '\n' + attr; } } // End of if } // End of for } /** * Load set node properties page * * @param tgtNode * Target node to set properties * @return Nothing */ function loadEditPropsPage(tgtNode) { // Get nodes tab var tab = getNodesTab(); // Generate new tab ID var inst = 0; var newTabId = 'editPropsTab' + inst; while ($('#' + newTabId).length) { // If one already exists, generate another one inst = inst + 1; newTabId = 'editPropsTab' + inst; } // Open new tab // Create set properties form var editPropsForm = $('
'); // Create info bar var infoBar = createInfoBar('Choose the properties you wish to change on the node. When you are finished, click Save.'); editPropsForm.append(infoBar); // Create an input for each definable attribute var div, label, input, descr, value; // Set node attribute origAttrs[tgtNode]['node'] = tgtNode; for (var key in nodeAttrs) { // If an attribute value exists if (origAttrs[tgtNode][key]) { // Set the value value = origAttrs[tgtNode][key]; } else { value = ''; } // Create label and input for attribute div = $('
').css('display', 'inline'); label = $('').css('vertical-align', 'middle'); input = $('').css('margin-top', '5px'); // Change border to blue onchange input.bind('change', function(event) { $(this).css('border-color', 'blue'); }); div.append(label); div.append(input); editPropsForm.append(div); } // Change style for last division div.css({ 'display': 'block', 'margin': '0px 0px 10px 0px' }); // Generate tooltips editPropsForm.find('div input[title]').tooltip({ position: "center right", offset: [-2, 10], effect: "fade", opacity: 0.8, delay: 0, predelay: 800, events: { def: "mouseover,mouseout", input: "mouseover,mouseout", widget: "focus mouseover,blur mouseout", tooltip: "mouseover,mouseout" } }); /** * Save */ var saveBtn = createButton('Save'); saveBtn.click(function() { // Get all inputs var inputs = $('#' + newTabId + ' input'); // Go through each input var args = ''; var attrName, attrVal; inputs.each(function(){ // If the border color is blue if ($(this).css('border-left-color') == 'rgb(0, 0, 255)') { // Change border color back to normal $(this).css('border-color', ''); // Get attribute name and value attrName = $(this).parent().find('label').text().replace(':', ''); attrVal = $(this).val(); // Build argument string if (args) { // Handle subsequent arguments args += ';' + attrName + '=' + attrVal; } else { // Handle the 1st argument args += attrName + '=' + attrVal; } } }); // Send command to change node attributes $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'chdef', tgt : '', args : '-t;node;-o;' + tgtNode + ';' + args, msg : 'out=' + newTabId + ';tgt=' + tgtNode }, success: showChdefOutput }); }); editPropsForm.append(saveBtn); /** * Cancel */ var cancelBtn = createButton('Cancel'); cancelBtn.click(function() { // Close the tab tab.remove($(this).parent().parent().attr('id')); }); editPropsForm.append(cancelBtn); // Append to discover tab tab.add(newTabId, 'Edit', editPropsForm, true); // Select new tab tab.select(newTabId); } /** * Open set node attributes dialog * * @return Nothing */ function openSetAttrsDialog() { // Open new tab // Create set properties form var setPropsForm = $('
'); // Create info bar var infoBar = createInfoBar('Choose the properties you wish to change on the node. When you are finished, click Save.'); setPropsForm.append(infoBar); // Create an input for each definable attribute var div, label, input, descr, value; for (var key in nodeAttrs) { value = ''; // Create label and input for attribute div = $('
').css('display', 'inline'); label = $('').css('vertical-align', 'middle'); input = $('').css('margin-top', '5px'); // Change border to blue onchange input.bind('change', function(event) { $(this).css('border-color', 'blue'); }); div.append(label); div.append(input); setPropsForm.append(div); } // Change style for last division div.css({ 'display': 'block', 'margin': '0px 0px 10px 0px' }); // Generate tooltips setPropsForm.find('div input[title]').tooltip({ position: "center right", offset: [-2, 10], effect: "fade", opacity: 0.8, delay: 0, predelay: 800, events: { def: "mouseover,mouseout", input: "mouseover,mouseout", widget: "focus mouseover,blur mouseout", tooltip: "mouseover,mouseout" }, // Change z index to show tooltip in front onBeforeShow: function() { this.getTip().css('z-index', $.topZIndex()); } }); // Enable vertical scroll setPropsForm.css('overflow', 'auto'); // Open form as a dialog setPropsForm.dialog({ modal: true, height: 400, width: 700, buttons: { "Save": function() { // Remove any warning messages $(this).find('.ui-state-error').remove(); // Get all inputs var inputs = $(this).find('input'); // Go through each input var args = ''; var tgtNode, attrName, attrVal; inputs.each(function(){ // If the border color is blue if ($(this).css('border-left-color') == 'rgb(0, 0, 255)') { // Change border color back to normal $(this).css('border-color', ''); // Get attribute name and value attrName = $(this).parent().find('label').text().replace(':', ''); attrVal = $(this).val(); // Get node name if (attrName == 'node') { tgtNode = attrVal; } else { // Build argument string if (args) { // Handle subsequent arguments args += ';' + attrName + '=' + attrVal; } else { // Handle the 1st argument args += attrName + '=' + attrVal; } } } }); // Send command to change node attributes $.ajax( { url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'chdef', tgt : '', args : '-t;node;-o;' + tgtNode + ';' + args, msg : 'node=' + tgtNode }, /** * Show results * * @param data * Data returned from HTTP request * @return Nothing */ success: function(data) { // Get output var out = data.rsp; var node = data.msg.replace('node=', ''); // Go through output and append to paragraph var msg = ''; for (var i in out) { if (!msg) { msg = node + ': ' + out[i]; } else { msg += '
' + node + ': ' + out[i]; } } openDialog('info', msg); } }); // Close dialog $(this).dialog( "close" ); }, "Cancel": function(){ $(this).dialog( "close" ); } } }); } /** * 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'); } /** * when nodes are loaded, based on different hardware architecture, should load different informations * * @return Nothing */ function advancedLoad(group){ var tempIndex = 0; var tableHeaders = $('#' + nodesTableId + ' th'); var colNameHash = new Object(); var colName = ''; var archCol = 0, hcpCol = 0; //find out the column name and their index for (tempIndex = 0; tempIndex < tableHeaders.size(); tempIndex++){ var header = tableHeaders.eq(tempIndex); //if link header(status, power, monitor) can dump to next one if (header.find('a').size() > 0){ continue; } colName = header.text(); if (colName){ colNameHash[colName] = tempIndex; } } //there is not arch column, can not distinguish hardware type return directly if (!colNameHash['arch']){ return; } if (!colNameHash['hcp']){ return; } archCol = colNameHash['arch']; hcpCol = colNameHash['hcp']; // Get hardware control point var rows = $('#' + nodesTableId + ' 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(hcpCol).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 } /** * when click the provison button, show this dislog for provision * this is the quick way to deploy on the nodes page. * * @return Nothing */ function openQuickProvisionDia(tgtnodes){ var nodeArray = tgtnodes.split(','); var nodeName = ''; var index = 0; var archtype = ''; var errormessage = ''; var diaDiv = $('
'); //check the first node's arch type for (index in nodeArray){ nodeName = nodeArray[index]; //does not have arch if (!origAttrs[nodeName]['arch']){ errormessage = 'All nodes should define arch first!'; break; } if (0 == index){ archtype = origAttrs[nodeName]['arch']; } //all nodes should have same archtype if (archtype != origAttrs[nodeName]['arch']){ errormessage = 'All nodes should belong to same arch!
'; break; } } //check the mac address for (index in nodeArray){ if (!origAttrs[nodeName]['mac'] || !origAttrs[nodeName]['ip']){ errormessage += 'All nodes should define ip and mac!
'; break; } } if (-1 != archtype.indexOf('390')){ errormessage += 'System Z should use provision page.'; } //error message should show in a dialog if ('' != errormessage){ diaDiv.append(createWarnBar(errormessage)); diaDiv.dialog({ modal: true, width: 400, buttons: { 'Close': function(){ $(this).dialog('destroy'); } } }); return; } //organize the provison dialog var showstr = ''; showstr += ''; showstr += ''; showstr += ''; showstr += ''; showstr += ''; showstr += ''; showstr += ''; showstr += ''; showstr += '
Target node:
Arch:
Image:
Install Nic:
Primary Nic:
xCAT Master:
TFTP Server:
NFS Server:
'; showstr += '
'; diaDiv.append(showstr); diaDiv.dialog({ modal: true, width: 400, height: 480, close: function(){$(this).remove();}, buttons: { 'Close': function(){$(this).remove();} } }); $('#deployDiv select').parent().append(createLoader()); $.ajax({ url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'lsdef', tgt : '', args : '-t;osimage', msg : '' }, success : function(data){ var index = 0; var imagename = 0; var position = 0; $('#deployDiv img').remove(); if (data.rsp.lenght < 1){ $('#deployDiv').append(createWarnBar('Please copycds and genimage in provision page first!')); return; } for (index in data.rsp){ imagename = data.rsp[index]; position = imagename.indexOf(' '); imagename = imagename.substr(0, position); $('#deployDiv select').append(''); } $('#deployDiv').dialog( "option", "buttons", {'Ok': function(){quickProvision();}, 'Cancel': function(){$(this).remove();}} ); } }); } /** * get all needed field for provsion and send the command to server * * @return Nothing */ function quickProvision(){ var errormessage = ''; var argsArray = new Array(); var nodesName = ''; var provisionArg = ''; var provisionFrame; var imageName = ''; var url = ''; $('#deployDiv .ui-state-error').remove(); $('#deployDiv input').each(function(){ if ('' == $(this).val()){ errormessage = 'You are missing input!'; return false; } }); if ('' != errormessage){ $('#deployDiv').prepend('

' + errormessage + '

'); return; } $('#deployDiv input').each(function(){ argsArray.push($(this).val()); }); nodesName = argsArray.shift(); imageName = $('#deployDiv select').val(); provisionArg = argsArray.join(','); url = 'lib/cmd.php?cmd=webrun&tgt=&args=provision;' + nodesName + ';' + imageName + ';' + provisionArg + '&msg=&opts=flush'; //show the result $('#deployDiv').empty().append(createLoader()).append('
'); $('#deployDiv').dialog( "option", "buttons", {'Close': function(){$(this).remove();clearTimeout(provisionClock);}}); $('#deployDiv').dialog( "option", "width", 600); provisionFrame = $(''); $('#deployDiv').append(provisionFrame); provisionFrame.attr('src', url); provisionStopCheck(); } function provisionStopCheck(){ var content = $('#provisionFrame').contents().find('body').text(); if (-1 != content.indexOf('provision stop')){ $('#deployDiv img').remove(); clearTimeout(provisionClock); } else{ provisionClock = setTimeout('provisionStopCheck()', 5000); } }