mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 03:12:30 +00:00 
			
		
		
		
	Added Ganglia summary page. Moved monitoring command, i.e. turn on/off monitoring + install monitoring, to nodes page.
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@9468 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		| @@ -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; | ||||
|   | ||||
| @@ -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 = $('<a href="#">click here</a>'); | ||||
| 			var gangliaLnk = $('<a href="#">Click here</a>'); | ||||
| 			gangliaLnk.css( { | ||||
| 				'color' : 'blue', | ||||
| 				'text-decoration' : 'none' | ||||
| @@ -203,7 +203,7 @@ function loadGroups4Ganglia(data) { | ||||
| 			var info = $('<div class="ui-state-highlight ui-corner-all"></div>'); | ||||
| 			info.append('<span class="ui-icon ui-icon-info" style="display: inline-block; margin: 10px 5px;"></span>'); | ||||
| 			var msg = $('<p style="display: inline-block; width: 95%;"></p>'); | ||||
| 			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 = $('<center></center>').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('<input type="checkbox" onclick="selectAllCheckbox(event, $(this))">',  | ||||
| 		'node',  | ||||
| 		'<span><a>status</a></span><img src="images/loader.gif"></img>', | ||||
| 		'<span><a>power</a></span><img src="images/loader.gif" style="display: none;"></img>',  | ||||
| 		'<span><a>ganglia</a></span><img src="images/loader.gif" style="display: none;"></img>'); | ||||
|  | ||||
| 	// 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 = '<input type="checkbox" name="' + node + '"/>'; | ||||
| 		var nodeLink = $('<a class="node" id="' + node + '">' + node + '</a>').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 = $('<div class="actionBar"></div>'); | ||||
|  | ||||
| 	/** | ||||
| 	 * The following actions are available to perform against a given node: | ||||
| 	 * power and monitor | ||||
| 	 */ | ||||
|  | ||||
| 	/* | ||||
| 	 * Power | ||||
| 	 */ | ||||
| 	var powerLnk = $('<a>Power</a>'); | ||||
|  | ||||
| 	// Power on | ||||
| 	var powerOnLnk = $('<a>Power on</a>'); | ||||
| 	powerOnLnk.click(function() { | ||||
| 		var tgtNodes = getNodesChecked(gangliaTableId); | ||||
| 		if (tgtNodes) { | ||||
| 			powerNode(tgtNodes, 'on'); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| 	// Power off | ||||
| 	var powerOffLnk = $('<a>Power off</a>'); | ||||
| 	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 = $('<a>Monitor</a>'); | ||||
|  | ||||
| 	// Turn monitoring on | ||||
| 	var monitorOnLnk = $('<a>Monitor on</a>'); | ||||
| 	monitorOnLnk.click(function() { | ||||
| 		var tgtNodes = getNodesChecked(gangliaTableId); | ||||
| 		if (tgtNodes) { | ||||
| 			monitorNode(tgtNodes, 'on'); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| 	// Turn monitoring off | ||||
| 	var monitorOffLnk = $('<a>Monitor off</a>'); | ||||
| 	monitorOffLnk.click(function() { | ||||
| 		var tgtNodes = getNodesChecked(gangliaTableId); | ||||
| 		if (tgtNodes) { | ||||
| 			monitorNode(tgtNodes, 'off'); | ||||
| 		} | ||||
| 	}); | ||||
| 	 | ||||
| 	// Install Ganglia | ||||
| 	var installLnk = $('<a>Install</a>'); | ||||
| 	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 = $('<div></div>'); | ||||
| 	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 += '<br>' + 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 = $('<div id="ganglia_sum"></div>'); | ||||
| 	$('#nodes').append(summary); | ||||
| 	 | ||||
| 			success : addNodes2GangliaTable | ||||
| 		}); | ||||
| 	// Create pie details | ||||
| 	var details = $('<div id="ganglia_details"></div>'); | ||||
| 	$('#nodes').append(details); | ||||
| 		 | ||||
| 		// Create dialog to indicate table is updating | ||||
| 		var update = $('<div id="updatingDialog" class="ui-state-highlight ui-corner-all">'  | ||||
| 				+ '<p><span class="ui-icon ui-icon-info"></span> Updating table <img src="images/loader.gif"/></p>' | ||||
| 			+'</div>'); | ||||
| 		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 = $('<div class="tooltip">Click here to refresh the Ganglia status</div>').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($('<p>' + data[1] + ' node(s) ' + data[0] + '</p>')); | ||||
| 		$('#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 | ||||
| } | ||||
| @@ -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('<input type="checkbox" onclick="selectAllCheckbox(event, $(this))">',  | ||||
| 		'node',  | ||||
| 		'<span><a>status</a></span><img src="images/loader.gif"></img>',  | ||||
| 		'<span><a>power</a></span><img src="images/loader.gif" style="display: none;"></img>', | ||||
| 		'<span><a>monitor</a></span><img src="images/loader.gif" style="display: none;"></img>', | ||||
| 		'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 = $('<a>Monitor</a>'); | ||||
|  | ||||
| 	// Turn monitoring on | ||||
| 	var monitorOnLnk = $('<a>Monitor on</a>'); | ||||
| 	monitorOnLnk.click(function() { | ||||
| 		var tgtNodes = getNodesChecked(nodesTableId); | ||||
| 		if (tgtNodes) { | ||||
| 			monitorNode(tgtNodes, 'on'); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| 	// Turn monitoring off | ||||
| 	var monitorOffLnk = $('<a>Monitor off</a>'); | ||||
| 	monitorOffLnk.click(function() { | ||||
| 		var tgtNodes = getNodesChecked(nodesTableId); | ||||
| 		if (tgtNodes) { | ||||
| 			monitorNode(tgtNodes, 'off'); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| 	// Clone | ||||
| 	var cloneLnk = $('<a>Clone</a>'); | ||||
| @@ -684,23 +705,36 @@ function loadNodes(data) { | ||||
| 		} | ||||
| 	}); | ||||
| 	 | ||||
| 	// Install Ganglia | ||||
| 	var installMonLnk = $('<a>Install monitoring</a>'); | ||||
| 	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 = $('<a>Advanced</a>'); | ||||
| 	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 = $('<div></div>'); | ||||
| 	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 = $('<div class="tooltip">Click here to refresh the monitoring status</div>').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 += '<br>' + 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'); | ||||
| } | ||||
| @@ -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"); | ||||
|   | ||||
| @@ -16,6 +16,7 @@ function loadPage(){ | ||||
| 			<link href="css/jquery.dataTables.css" rel=stylesheet type="text/css"> | ||||
| 			<link href="css/superfish.css" rel=stylesheet type="text/css"> | ||||
| 			<link href="css/jstree.css" rel=stylesheet type="text/css"> | ||||
| 			<link href="css/jquery.jqplot.css" rel=stylesheet type="text/css"> | ||||
| 			<link href="css/style.css" rel=stylesheet type="text/css"> | ||||
| 			<script type="text/javascript" src="js/jquery/jquery-1.4.4.min.js"></script> | ||||
| 			<script type="text/javascript" src="js/jquery/jquery-ui-1.8.7.custom.min.js"></script> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user