xcat-core/xCAT-UI/js/service/service.js
2011-09-28 22:31:18 +00:00

2413 lines
60 KiB
JavaScript

/**
* Global variables
*/
var serviceTabs;
var nodeName;
var nodePath;
var nodeStatus;
var gangliaTimer;
/**
* Initialize service page
*/
function initServicePage() {
// Load theme
var theme = $.cookie('xcat_theme');
if (theme) {
switch (theme) {
case 'cupertino':
includeCss("css/themes/jquery-ui-cupertino.css");
break;
case 'dark_hive':
includeCss("css/themes/jquery-ui-dark_hive.css");
break;
case 'redmond':
includeCss("css/themes/jquery-ui-redmond.css");
break;
case 'start':
includeCss("css/themes/jquery-ui-start.css");
break;
case 'sunny':
includeCss("css/themes/jquery-ui-sunny.css");
break;
case 'ui_dark':
includeCss("css/themes/jquery-ui-ui_darkness.css");
break;
default:
includeCss("css/themes/jquery-ui-start.css");
}
} else {
includeCss("css/themes/jquery-ui-start.css");
}
// Load jQuery stylesheets
includeCss("css/jquery.dataTables.css");
includeCss("css/superfish.css");
includeCss("css/jstree.css");
includeCss("css/jquery.jqplot.css");
// Load custom stylesheet
includeCss("css/style.css");
// Reuqired JQuery plugins
includeJs("js/jquery/jquery.dataTables.min.js");
includeJs("js/jquery/jquery.cookie.min.js");
includeJs("js/jquery/tooltip.min.js");
includeJs("js/jquery/superfish.min.js");
includeJs("js/jquery/jquery.jqplot.min.js");
includeJs("js/jquery/jqplot.dateAxisRenderer.min.js");
// Enable settings link
$('#xcat_settings').click(function() {
openSettings();
});
// Show service page
$("#content").children().remove();
includeJs("js/service/utils.js");
loadServicePage();
}
/**
* Load service page
*/
function loadServicePage() {
// If the page is loaded
if ($('#content').children().length) {
// Do not load again
return;
}
// Create manage and provision tabs
serviceTabs = new Tab();
serviceTabs.init();
$('#content').append(serviceTabs.object());
var manageTabId = 'manageTab';
serviceTabs.add(manageTabId, 'Manage', '', false);
loadManagePage(manageTabId);
var provTabId = 'provisionTab';
serviceTabs.add(provTabId, 'Provision', '', false);
loadzProvisionPage(provTabId);
serviceTabs.select(manageTabId);
// Get zVM host names
if (!$.cookie('srv_zvm')){
$.ajax( {
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'webportal',
tgt : '',
args : 'lszvm',
msg : ''
},
success : function(data) {
setzVMCookies(data);
loadzVMs();
}
});
} else {
loadzVMs();
}
// Get OS image names
if (!$.cookie('srv_imagenames')){
$.ajax( {
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'tabdump',
tgt : '',
args : 'osimage',
msg : ''
},
success : function(data) {
setOSImageCookies(data);
loadOSImages();
}
});
} else {
loadOSImages();
}
// Get contents of hosts table
if (!$.cookie('srv_groups')) {
$.ajax( {
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'tabdump',
tgt : '',
args : 'hosts',
msg : ''
},
success : function(data) {
setGroupCookies(data);
loadGroups();
}
});
} else {
loadGroups();
}
// Get nodes owned by user
$.ajax( {
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'tabdump',
tgt : '',
args : 'nodetype',
msg : ''
},
success : function(data) {
setUserNodes(data);
getUserNodesDef();
getNodesCurrentLoad();
}
});
}
/**
* Load manage page
*
* @param tabId
* Tab ID where page will reside
* @return Nothing
*/
function loadManagePage(tabId) {
// Create manage form
var loader = createLoader('');
var manageForm = $('<div></div>').append(loader);
// Append to manage tab
$('#' + tabId).append(manageForm);
}
/**
* Get the user nodes definitions
*/
function getUserNodesDef() {
var userName = $.cookie('srv_usrname');
var userNodes = $.cookie(userName + '_usrnodes');
if (userNodes) {
// Get nodes definitions
$.ajax( {
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'lsdef',
tgt : '',
args : userNodes,
msg : ''
},
success : loadNodesTable
});
} else {
prompt('Warning', $('<p>Your session has expired! Please log out and back in.</p>'));
}
}
/**
* Load user nodes definitions into a table
*
* @param data
* Data from HTTP request
* @return Nothing
*/
function loadNodesTable(data) {
// Clear the tab before inserting the table
$('#manageTab').children().remove();
// Nodes datatable ID
var nodesDTId = 'userNodesDT';
// Hash of node attributes
var attrs = new Object();
// Node attributes
var headers = new Object();
var node, args;
// Create hash of node attributes
for (var i in data.rsp) {
// Get node name
if (data.rsp[i].indexOf('Object name:') > -1) {
var temp = data.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 = data.rsp[i].split('=', 2);
var key = jQuery.trim(args[0]);
var val = jQuery.trim(data.rsp[i].substring(data.rsp[i].indexOf('=') + 1, data.rsp[i].length));
// Create a hash table
attrs[node][key] = val;
headers[key] = 1;
}
// Sort headers
var sorted = new Array();
var attrs2hide = new Array('status', 'statustime', 'appstatus', 'appstatustime', 'usercomment');
var attrs2show = new Array('arch', 'groups', 'hcp', 'hostnames', 'ip', 'os', 'userid');
for (var key in headers) {
// Show node attributes
if (jQuery.inArray(key, attrs2show) > -1) {
sorted.push(key);
}
}
sorted.sort();
// Add column for check box, node, ping, power, monitor, and comments
sorted.unshift('<input type="checkbox" onclick="selectAll(event, $(this))">',
'node',
'<span><a>status</a></span><img src="images/loader.gif" style="display: none;"></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
var nodesDT = new DataTable(nodesDTId);
nodesDT.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, 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 = $('<img id="' + tipID + '" src="' + iconSrc + '"></img>').css({
'width': '18px',
'height': '18px'
});
// Create tooltip
var tip = createCommentsToolTip(comments);
var col = $('<span></span>').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($('<span>' + val + '</span>'));
} else {
row.push('');
}
}
}
// Add the row to the table
nodesDT.add(row);
}
// Create info bar
var infoBar = createInfoBar('Manage and monitor your virtual machines.');
$('#manageTab').append(infoBar);
// Insert action bar and nodes datatable
$('#manageTab').append(nodesDT.object());
// Turn table into a datatable
$('#' + nodesDTId).dataTable({
'iDisplayLength': 50,
'bLengthChange': false,
"sScrollX": "100%",
"sScrollXInner": "110%"
});
// Set datatable header class to add color
// $('.datatable thead').attr('class', 'ui-widget-header');
// Do not sort ping, power, and comment column
var cols = $('#' + nodesDTId + ' thead tr th').click(function() {
getNodeAttrs(group);
});
var checkboxCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(0)');
var pingCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(2)');
var powerCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(3)');
var monitorCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(4)');
var commentCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(5)');
checkboxCol.unbind('click');
pingCol.unbind('click');
powerCol.unbind('click');
monitorCol.unbind('click');
commentCol.unbind('click');
// Refresh the node ping, power, and monitor status on-click
var nodes = getNodesShown(nodesDTId);
pingCol.find('span a').click(function() {
refreshNodeStatus(nodes);
});
powerCol.find('span a').click(function() {
refreshPowerStatus(nodes);
});
monitorCol.find('span a').click(function() {
refreshGangliaStatus(nodes);
});
// Create actions menu
// Power on
var powerOnLnk = $('<a>Power on</a>');
powerOnLnk.click(function() {
var tgtNodes = getNodesChecked(nodesDTId);
if (tgtNodes) {
powerNode(tgtNodes, 'on');
}
});
// Power off
var powerOffLnk = $('<a>Power off</a>');
powerOffLnk.click(function() {
var tgtNodes = getNodesChecked(nodesDTId);
if (tgtNodes) {
powerNode(tgtNodes, 'off');
}
});
// Turn monitoring on
var monitorOnLnk = $('<a>Monitor on</a>');
monitorOnLnk.click(function() {
var tgtNodes = getNodesChecked(nodesDTId);
if (tgtNodes) {
monitorNode(tgtNodes, 'on');
}
});
// Turn monitoring off
var monitorOffLnk = $('<a>Monitor off</a>');
monitorOffLnk.click(function() {
var tgtNodes = getNodesChecked(nodesDTId);
if (tgtNodes) {
monitorNode(tgtNodes, 'off');
}
});
// Delete
var deleteLnk = $('<a>Delete</a>');
deleteLnk.click(function() {
var tgtNodes = getNodesChecked(nodesDTId);
if (tgtNodes) {
deleteNode(tgtNodes);
}
});
// Unlock
var unlockLnk = $('<a>Unlock</a>');
unlockLnk.click(function() {
var tgtNodes = getNodesChecked(nodesDTId);
if (tgtNodes) {
unlockNode(tgtNodes);
}
});
// Create action bar
var actionBar = $('<div class="actionBar"></div>');
// Prepend menu to datatable
var actionsLnk = '<a>Actions</a>';
var actionMenu = createMenu([deleteLnk, powerOnLnk, powerOffLnk, monitorOnLnk, monitorOffLnk, unlockLnk]);
var menu = createMenu([[actionsLnk, actionMenu]]);
menu.superfish();
actionBar.append(menu);
// Set correct theme for action menu
actionMenu.find('li').hover(function() {
setMenu2Theme($(this));
}, function() {
setMenu2Normal($(this));
});
// Create a division to hold actions menu
var menuDiv = $('<div id="' + nodesDTId + '_menuDiv" class="menuDiv"></div>');
$('#' + nodesDTId + '_wrapper').prepend(menuDiv);
menuDiv.append(actionBar);
$('#' + nodesDTId + '_filter').appendTo(menuDiv);
// Get power and monitor status
var nodes = getNodesShown(nodesDTId);
refreshPowerStatus(nodes);
refreshGangliaStatus(nodes);
}
/**
* Refresh ping status for each node
*
* @param nodes
* Nodes to get ping status
* @return Nothing
*/
function refreshNodeStatus(nodes) {
// Show ping loader
var nodesDTId = 'userNodesDT';
var pingCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(2)');
pingCol.find('img').show();
// Get the node ping status
$.ajax( {
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'nodestat',
tgt : nodes,
args : '-u',
msg : ''
},
success : loadNodePing
});
}
/**
* Load node ping status for each node
*
* @param data
* Data returned from HTTP request
* @return Nothing
*/
function loadNodePing(data) {
var nodesDTId = 'userNodesDT';
var datatable = $('#' + nodesDTId).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, '#' + nodesDTId, 1);
// Update ping status column
datatable.fnUpdate(status, rowPos, 2, false);
}
// Hide status loader
var pingCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(2)');
pingCol.find('img').hide();
adjustColumnSize(nodesDTId);
}
/**
* Refresh power status for each node
*
* @param nodes
* Nodes to get power status
* @return Nothing
*/
function refreshPowerStatus(nodes) {
// Show power loader
var nodesDTId = 'userNodesDT';
var powerCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(3)');
powerCol.find('img').show();
// Get power status
$.ajax( {
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'rpower',
tgt : nodes,
args : 'stat',
msg : ''
},
success : loadPowerStatus
});
}
/**
* Load power status for each node
*
* @param data
* Data returned from HTTP request
* @return Nothing
*/
function loadPowerStatus(data) {
var nodesDTId = 'userNodesDT';
var datatable = $('#' + nodesDTId).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, '#' + nodesDTId, 1);
// Update the power status column
datatable.fnUpdate(status, rowPos, 3, false);
}
// Hide power loader
var powerCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(3)');
powerCol.find('img').hide();
adjustColumnSize(nodesDTId);
}
/**
* Refresh the status of Ganglia for each node
*
* @param nodes
* Nodes to get Ganglia status
* @return Nothing
*/
function refreshGangliaStatus(nodes) {
// Show ganglia loader
var nodesDTId = 'userNodesDT';
var gangliaCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(4)');
gangliaCol.find('img').show();
// Get the status of Ganglia
$.ajax( {
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'webrun',
tgt : '',
args : 'gangliastatus;' + nodes,
msg : ''
},
success : loadGangliaStatus
});
}
/**
* Load the status of Ganglia for a given group
*
* @param data
* Data returned from HTTP request
* @return Nothing
*/
function loadGangliaStatus(data) {
// Get datatable
var nodesDTId = 'userNodesDT';
var datatable = $('#' + nodesDTId).dataTable();
var ganglia = data.rsp;
var rowNum, node, status;
for ( var i in ganglia) {
// ganglia[0] = nodeName and ganglia[1] = state
node = jQuery.trim(ganglia[i][0]);
status = jQuery.trim(ganglia[i][1]);
if (node) {
// Get the row containing the node
rowNum = findRow(node, '#' + nodesDTId, 1);
// Update the power status column
datatable.fnUpdate(status, rowNum, 4);
}
}
// Hide Ganglia loader
var gangliaCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(4)');
gangliaCol.find('img').hide();
adjustColumnSize(nodesDTId);
}
/**
* 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;
// Create a new tab to show inventory
var tabId = node + '_inventory';
if(!$('#' + tabId).length) {
// Add new tab, only if one does not exist
var loader = createLoader(node + 'Loader');
loader = $('<center></center>').append(loader);
serviceTabs.add(tabId, node, loader, true);
// Get node inventory
var msg = 'out=' + tabId + ',node=' + node;
$.ajax( {
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'rinv',
tgt : node,
args : 'all',
msg : msg
},
success : showInventory
});
}
// Select new tab
serviceTabs.select(tabId);
}
/**
* Show node inventory
*
* @param data
* Data from HTTP request
* @return Nothing
*/
function showInventory(data) {
var args = data.msg.split(',');
// Get tab ID
var tabId = args[0].replace('out=', '');
// Get node
var node = args[1].replace('node=', '');
// Get node inventory
var inv = data.rsp[0].split(node + ':');
// Remove loader
$('#' + tabId).find('img').remove();
// Create array of property keys
var keys = new Array('userId', 'host', 'os', 'arch', 'hcp', 'priv', 'memory', 'proc', 'disk', 'nic');
// Create hash table for property names
var attrNames = new Object();
attrNames['userId'] = 'z/VM UserID:';
attrNames['host'] = 'z/VM Host:';
attrNames['os'] = 'Operating System:';
attrNames['arch'] = 'Architecture:';
attrNames['hcp'] = 'HCP:';
attrNames['priv'] = 'Privileges:';
attrNames['memory'] = 'Total Memory:';
attrNames['proc'] = 'Processors:';
attrNames['disk'] = 'Disks:';
attrNames['nic'] = 'NICs:';
// Create hash table for node attributes
var attrs = getAttrs(keys, attrNames, inv);
// Create division to hold inventory
var invDivId = node + 'Inventory';
var invDiv = $('<div class="inventory" id="' + invDivId + '"></div>');
var infoBar = createInfoBar('Below is the inventory for the virtual machine you selected.');
invDiv.append(infoBar);
/**
* General info section
*/
var fieldSet = $('<fieldset></fieldset>');
var legend = $('<legend>General</legend>');
fieldSet.append(legend);
var oList = $('<ol></ol>');
var item, label, args;
// Loop through each property
for ( var k = 0; k < 5; k++) {
// Create a list item for each property
item = $('<li></li>');
// Create a label - Property name
label = $('<label>' + attrNames[keys[k]] + '</label>');
item.append(label);
for ( var l = 0; l < attrs[keys[k]].length; l++) {
// Create a input - Property value(s)
// Handle each property uniquely
item.append(attrs[keys[k]][l]);
}
oList.append(item);
}
// Append to inventory form
fieldSet.append(oList);
invDiv.append(fieldSet);
/**
* Monitoring section
*/
fieldSet = $('<fieldset id="' + node + '_monitor"></fieldset>');
legend = $('<legend>Monitoring</legend>');
fieldSet.append(legend);
getMonitorMetrics(node);
// Append to inventory form
invDiv.append(fieldSet);
/**
* Hardware info section
*/
var hwList, hwItem;
fieldSet = $('<fieldset></fieldset>');
legend = $('<legend>Hardware</legent>');
fieldSet.append(legend);
oList = $('<ol></ol>');
// Loop through each property
var label;
for (k = 5; k < keys.length; k++) {
// Create a list item
item = $('<li></li>');
// Create a list to hold the property value(s)
hwList = $('<ul></ul>');
hwItem = $('<li></li>');
/**
* Privilege section
*/
if (keys[k] == 'priv') {
// Create a label - Property name
label = $('<label>' + attrNames[keys[k]].replace(':', '') + '</label>');
item.append(label);
// Loop through each line
for (l = 0; l < attrs[keys[k]].length; l++) {
// Create a new list item for each line
hwItem = $('<li></li>');
// Determine privilege
args = attrs[keys[k]][l].split(' ');
if (args[0] == 'Directory:') {
label = $('<label>' + args[0] + '</label>');
hwItem.append(label);
hwItem.append(args[1]);
} else if (args[0] == 'Currently:') {
label = $('<label>' + args[0] + '</label>');
hwItem.append(label);
hwItem.append(args[1]);
}
hwList.append(hwItem);
}
item.append(hwList);
}
/**
* Memory section
*/
else if (keys[k] == 'memory') {
// Create a label - Property name
label = $('<label>' + attrNames[keys[k]].replace(':', '') + '</label>');
item.append(label);
// Loop through each value line
for (l = 0; l < attrs[keys[k]].length; l++) {
// Create a new list item for each line
hwItem = $('<li></li>');
hwItem.append(attrs[keys[k]][l]);
hwList.append(hwItem);
}
item.append(hwList);
}
/**
* Processor section
*/
else if (keys[k] == 'proc') {
// Create a label - Property name
label = $('<label><b>' + attrNames[keys[k]].replace(':', '') + '</b></label>');
item.append(label);
// Create a table to hold processor data
var procTable = $('<table></table>');
var procBody = $('<tbody></tbody>');
// Table columns - Type, Address, ID, Base, Dedicated, and Affinity
var procTabRow = $('<thead class="ui-widget-header"> <th>Type</th> <th>Address</th> <th>ID</th> <th>Base</th> <th>Dedicated</th> <th>Affinity</th> </thead>');
procTable.append(procTabRow);
var procType, procAddr, procId, procAff;
// Loop through each processor
var n, temp;
for (l = 0; l < attrs[keys[k]].length; l++) {
if (attrs[keys[k]][l]) {
args = attrs[keys[k]][l].split(' ');
// Get processor type, address, ID, and affinity
n = 3;
temp = args[args.length - n];
while (!jQuery.trim(temp)) {
n = n + 1;
temp = args[args.length - n];
}
procType = $('<td>' + temp + '</td>');
procAddr = $('<td>' + args[1] + '</td>');
procId = $('<td>' + args[5] + '</td>');
procAff = $('<td>' + args[args.length - 1] + '</td>');
// Base processor
if (args[6] == '(BASE)') {
baseProc = $('<td>' + true + '</td>');
} else {
baseProc = $('<td>' + false + '</td>');
}
// Dedicated processor
if (args[args.length - 3] == 'DEDICATED') {
dedicatedProc = $('<td>' + true + '</td>');
} else {
dedicatedProc = $('<td>' + false + '</td>');
}
// Create a new row for each processor
procTabRow = $('<tr></tr>');
procTabRow.append(procType);
procTabRow.append(procAddr);
procTabRow.append(procId);
procTabRow.append(baseProc);
procTabRow.append(dedicatedProc);
procTabRow.append(procAff);
procBody.append(procTabRow);
}
}
procTable.append(procBody);
item.append(procTable);
}
/**
* Disk section
*/
else if (keys[k] == 'disk') {
// Create a label - Property name
label = $('<label><b>' + attrNames[keys[k]].replace(':', '') + '</b></label>');
item.append(label);
// Create a table to hold disk (DASD) data
var dasdTable = $('<table></table>');
var dasdBody = $('<tbody></tbody>');
// Table columns - Virtual Device, Type, VolID, Type of Access, and Size
var dasdTabRow = $('<thead class="ui-widget-header"> <th>Virtual Device #</th> <th>Type</th> <th>VolID</th> <th>Type of Access</th> <th>Size</th> </thead>');
dasdTable.append(dasdTabRow);
var dasdVDev, dasdType, dasdVolId, dasdAccess, dasdSize;
// Loop through each DASD
for (l = 0; l < attrs[keys[k]].length; l++) {
if (attrs[keys[k]][l]) {
args = attrs[keys[k]][l].split(' ');
// Get DASD virtual device, type, volume ID, access, and size
dasdVDev = $('<td>' + args[1] + '</td>');
dasdType = $('<td>' + args[2] + '</td>');
dasdVolId = $('<td>' + args[3] + '</td>');
dasdAccess = $('<td>' + args[4] + '</td>');
dasdSize = $('<td>' + args[args.length - 9] + ' ' + args[args.length - 8] + '</td>');
// Create a new row for each DASD
dasdTabRow = $('<tr></tr>');
dasdTabRow.append(dasdVDev);
dasdTabRow.append(dasdType);
dasdTabRow.append(dasdVolId);
dasdTabRow.append(dasdAccess);
dasdTabRow.append(dasdSize);
dasdBody.append(dasdTabRow);
}
}
dasdTable.append(dasdBody);
item.append(dasdTable);
}
/**
* NIC section
*/
else if (keys[k] == 'nic') {
// Create a label - Property name
label = $('<label><b>' + attrNames[keys[k]].replace(':', '') + '</b></label>');
item.append(label);
// Create a table to hold NIC data
var nicTable = $('<table></table>');
var nicBody = $('<tbody></tbody>');
// Table columns - Virtual device, Adapter Type, Port Name, # of Devices, MAC Address, and LAN Name
var nicTabRow = $('<thead class="ui-widget-header"><th>Virtual Device #</th> <th>Adapter Type</th> <th>Port Name</th> <th># of Devices</th> <th>LAN Name</th></thead>');
nicTable.append(nicTabRow);
var nicVDev, nicType, nicPortName, nicNumOfDevs, nicLanName;
// Loop through each NIC (Data contained in 2 lines)
for (l = 0; l < attrs[keys[k]].length; l = l + 2) {
if (attrs[keys[k]][l]) {
args = attrs[keys[k]][l].split(' ');
// Get NIC virtual device, type, port name, and number of devices
nicVDev = $('<td>' + args[1] + '</td>');
nicType = $('<td>' + args[3] + '</td>');
nicPortName = $('<td>' + args[10] + '</td>');
nicNumOfDevs = $('<td>' + args[args.length - 1] + '</td>');
args = attrs[keys[k]][l + 1].split(' ');
nicLanName = $('<td>' + args[args.length - 2] + ' ' + args[args.length - 1] + '</td>');
// Create a new row for each DASD
nicTabRow = $('<tr></tr>');
nicTabRow.append(nicVDev);
nicTabRow.append(nicType);
nicTabRow.append(nicPortName);
nicTabRow.append(nicNumOfDevs);
nicTabRow.append(nicLanName);
nicBody.append(nicTabRow);
}
}
nicTable.append(nicBody);
item.append(nicTable);
}
oList.append(item);
}
// Append inventory to division
fieldSet.append(oList);
invDiv.append(fieldSet);
invDiv.find('th').css({
'padding': '5px 10px',
'font-weight': 'bold'
});
// Append to tab
$('#' + tabId).append(invDiv);
}
/**
* Load provision page (z)
*
* @param tabId
* Tab ID where page will reside
* @return Nothing
*/
function loadzProvisionPage(tabId) {
// Create provision form
var provForm = $('<div></div>');
// Create info bar
var infoBar = createInfoBar('Provision a Linux virtual machine on System z by selecting the appropriate choices below. Once you are ready, click on Provision to provision the virtual machine.');
provForm.append(infoBar);
// Append to provision tab
$('#' + tabId).append(provForm);
// Create provision table
var provTable = $('<table id="select-table" style="margin: 10px;"></table');
var provHeader = $('<thead class="ui-widget-header"> <th>zVM</th> <th>Group</th> <th>Image</th></thead>');
var provBody = $('<tbody></tbody>');
var provFooter = $('<tfoot></tfoot>');
provTable.append(provHeader, provBody, provFooter);
provForm.append(provTable);
provHeader.children('th').css({
'font': 'bold 12px verdana, arial, helvetica, sans-serif'
});
// Create row to contain selections
var provRow = $('<tr></tr>');
provBody.append(provRow);
// Create columns for zVM, group, and image
var zvmCol = $('<td style="vertical-align: top;"></td>');
provRow.append(zvmCol);
var groupCol = $('<td style="vertical-align: top;"></td>');
provRow.append(groupCol);
var imageCol = $('<td style="vertical-align: top;"></td>');
provRow.append(imageCol);
provRow.children('td').css({
'min-width': '250px'
});
/**
* Provision VM
*/
var provisionBtn = createButton('Provision');
provisionBtn.bind('click', function(event) {
var hcp = $('#select-table tbody tr:eq(0) td:eq(0) input[name="hcp"]:checked').val();
var group = $('#select-table tbody tr:eq(0) td:eq(1) input[name="group"]:checked').val();
var img = $('#select-table tbody tr:eq(0) td:eq(2) input[name="image"]:checked').val();
var owner = $.cookie('srv_usrname');;
// Begin by creating VM
createVM(tabId, group, hcp, img, owner);
});
provForm.append(provisionBtn);
}
/**
* Create virtual machine
*
* @param tabId
* Tab ID
* @param group
* Group
* @param hcp
* Hardware control point
* @param img
* OS image
* @return Nothing
*/
function createVM(tabId, group, hcp, img, owner) {
var statBar = createStatusBar('provsionStatBar');
var loader = createLoader('provisionLoader');
statBar.find('div').append(loader);
statBar.prependTo($('#provisionTab'));
// Submit request to create VM
// webportal provzlinux [group] [hcp] [image] [owner]
$.ajax({
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'webportal',
tgt : '',
args : 'provzlinux;' + group + ';' + hcp + ';' + img + ';' + owner,
msg : ''
},
success:function(data){
$('#provisionLoader').remove();
for(var i in data.rsp){
$('#provsionStatBar').find('div').append('<pre>' + data.rsp[i] + '</pre>');
}
// Refresh nodes table
$.ajax( {
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'tabdump',
tgt : '',
args : 'nodetype',
msg : ''
},
success : function(data) {
setUserNodes(data);
}
});
}
});
}
/**
* Load zVMs into column
*/
function loadzVMs() {
var zvmCol = $('#select-table tbody tr:eq(0) td:eq(0)');
// Get group names and description and append to group column
var groupNames = $.cookie('srv_zvms').split(',');
var radio, zvmBlock, args, zvm, hcp;
for (var i in groupNames) {
args = groupNames[i].split(':');
zvm = args[0];
hcp = args[1];
// Create block for each group
zvmBlock = $('<div class="ui-state-default"></div>').css({
'border': '1px solid',
'max-width': '200px',
'margin': '5px auto',
'padding': '5px',
'display': 'block',
'vertical-align': 'middle',
'cursor': 'pointer',
'white-space': 'normal'
}).click(function(){
$(this).children('input:radio').attr('checked', 'checked');
$(this).parents('td').find('div').attr('class', 'ui-state-default');
$(this).attr('class', 'ui-state-active');
});
radio = $('<input type="radio" name="hcp" value="' + hcp + '"/>').css('display', 'none');
zvmBlock.append(radio, $('<span><b>Name: </b>' + zvm + '</span>'), $('<span><b>zHCP: </b>' + hcp + '</span>'));
zvmBlock.children('span').css({
'display': 'block',
'margin': '5px',
'text-align': 'left'
});
zvmCol.append(zvmBlock);
}
}
/**
* Load groups into column
*/
function loadGroups() {
var groupCol = $('#select-table tbody tr:eq(0) td:eq(1)');
// Get group names and description and append to group column
var groupNames = $.cookie('srv_groups').split(',');
var groupBlock, radio, args, name, ip, hostname, desc;
for (var i in groupNames) {
args = groupNames[i].split(':');
name = args[0];
ip = args[1];
hostname = args[2];
desc = args[3];
// Create block for each group
groupBlock = $('<div class="ui-state-default"></div>').css({
'border': '1px solid',
'max-width': '200px',
'margin': '5px auto',
'padding': '5px',
'display': 'block',
'vertical-align': 'middle',
'cursor': 'pointer',
'white-space': 'normal'
}).click(function(){
$(this).children('input:radio').attr('checked', 'checked');
$(this).parents('td').find('div').attr('class', 'ui-state-default');
$(this).attr('class', 'ui-state-active');
});
radio = $('<input type="radio" name="group" value="' + name + '"/>').css('display', 'none');
groupBlock.append(radio, $('<span><b>Name: </b>' + name + '</span>'), $('<span><b>Description: </b>' + desc + '</span>'));
groupBlock.children('span').css({
'display': 'block',
'margin': '5px',
'text-align': 'left'
});
groupCol.append(groupBlock);
}
}
/**
* Load OS images into column
*/
function loadOSImages() {
var imgCol = $('#select-table tbody tr:eq(0) td:eq(2)');
// Get group names and description and append to group column
var imgNames = $.cookie('srv_imagenames').split(',');
var imgBlock, radio, args, name, desc;
for (var i in imgNames) {
args = imgNames[i].split(':');
name = args[0];
desc = args[1];
// Create block for each image
imgBlock = $('<div class="ui-state-default"></div>').css({
'border': '1px solid',
'max-width': '200px',
'margin': '5px auto',
'padding': '5px',
'display': 'block',
'vertical-align': 'middle',
'cursor': 'pointer',
'white-space': 'normal'
}).click(function(){
$(this).children('input:radio').attr('checked', 'checked');
$(this).parents('td').find('div').attr('class', 'ui-state-default');
$(this).attr('class', 'ui-state-active');
});
radio = $('<input type="radio" name="image" value="' + name + '"/>').css('display', 'none');
imgBlock.append(radio, $('<span><b>Name: </b>' + name + '</span>'), $('<span><b>Description: </b>' + desc + '</span>'));
imgBlock.children('span').css({
'display': 'block',
'margin': '5px',
'text-align': 'left'
});
imgCol.append(imgBlock);
}
}
/**
* Set a cookie for zVM host names
*
* @param data
* Data from HTTP request
* @return Nothing
*/
function setzVMCookies(data) {
if (data.rsp) {
var zvms = new Array();
for ( var i = 0; i < data.rsp.length; i++) {
zvms.push(data.rsp[i]);
}
// Set cookie to expire in 60 minutes
var exDate = new Date();
exDate.setTime(exDate.getTime() + (240 * 60 * 1000));
$.cookie('srv_zvms', zvms, { expires: exDate });
}
}
/**
* Set a cookie for disk pool names
*
* @param data
* Data from HTTP request
* @return Nothing
*/
function setGroupCookies(data) {
if (data.rsp) {
var groups = new Array();
// Index 0 is the table header
var cols, name, ip, hostname, desc;
for ( var i = 1; i < data.rsp.length; i++) {
// Split into columns:
// node, ip, hostnames, otherinterfaces, comments, disable
cols = data.rsp[i].split(',');
name = cols[0].replace(new RegExp('"', 'g'), '');
ip = cols[1].replace(new RegExp('"', 'g'), '');
hostname = cols[2].replace(new RegExp('"', 'g'), '');
desc = cols[4].replace(new RegExp('"', 'g'), '');
groups.push(name + ':' + ip + ':' + hostname + ':' + desc);
}
// Set cookie to expire in 60 minutes
var exDate = new Date();
exDate.setTime(exDate.getTime() + (240 * 60 * 1000));
$.cookie('srv_groups', groups, { expires: exDate });
}
}
/**
* Set a cookie for the OS images
*
* @param data
* Data from HTTP request
* @return Nothing
*/
function setOSImageCookies(data) {
// Get response
var rsp = data.rsp;
var imageNames = new Array;
var profilesHash = new Object();
var osVersHash = new Object();
var osArchsHash = new Object();
var imagePos = 0;
var profilePos = 0;
var osversPos = 0;
var osarchPos = 0;
var provMethodPos = 0;
var comments = 0;
// Get the column value
var colNameArray = rsp[0].substr(1).split(',');
for (var i in colNameArray){
switch (colNameArray[i]){
case 'imagename': {
imagePos = i;
}
break;
case 'profile':{
profilePos = i;
}
break;
case 'osvers':{
osversPos = i;
}
break;
case 'osarch':{
osarchPos = i;
}
break;
case 'comments':{
comments = i;
}
break;
case 'provmethod':{
provMethodPos = i;
}
break;
default :
break;
}
}
// Go through each index
for (var i = 1; i < rsp.length; i++) {
// Get image name
var cols = rsp[i].split(',');
var osImage = cols[imagePos].replace(new RegExp('"', 'g'), '');
var profile = cols[profilePos].replace(new RegExp('"', 'g'), '');
var provMethod = cols[provMethodPos].replace(new RegExp('"', 'g'), '');
var osVer = cols[osversPos].replace(new RegExp('"', 'g'), '');
var osArch = cols[osarchPos].replace(new RegExp('"', 'g'), '');
var osComments = cols[comments].replace(new RegExp('"', 'g'), '');
// Only save compute profile and install boot
if (profile.indexOf('compute') > -1 && provMethod.indexOf('install') > -1) {
if (!osComments)
osComments = 'No descritption';
imageNames.push(osImage + ':' + osComments);
profilesHash[profile] = 1;
osVersHash[osVer] = 1;
osArchsHash[osArch] = 1;
}
}
// Save image names in a cookie
$.cookie('srv_imagenames', imageNames);
// Save profiles in a cookie
var tmp = new Array;
for (var key in profilesHash) {
tmp.push(key);
}
$.cookie('srv_profiles', tmp);
// Save OS versions in a cookie
tmp = new Array;
for (var key in osVersHash) {
tmp.push(key);
}
$.cookie('srv_osvers', tmp);
// Save OS architectures in a cookie
tmp = new Array;
for (var key in osArchsHash) {
tmp.push(key);
}
$.cookie('srv_osarchs', tmp);
}
/**
* Set a cookie for disk pool names of a given node
*
* @param data
* Data from HTTP request
* @return Nothing
*/
function setDiskPoolCookies(data) {
if (data.rsp) {
var node = data.msg;
var pools = data.rsp[0].split(node + ': ');
for (var i in pools) {
pools[i] = jQuery.trim(pools[i]);
}
// Set cookie to expire in 60 minutes
var exDate = new Date();
exDate.setTime(exDate.getTime() + (240 * 60 * 1000));
$.cookie(node + 'diskpools', pools, { expires: exDate });
}
}
/**
* Set a cookie for user nodes
*
* @param data
* Data from HTTP request
* @return Nothing
*/
function setUserNodes(data) {
if (data.rsp) {
// Get user name that is logged in
var userName = $.cookie('srv_usrname');
var usrNodes = new Array();
// Ignore first columns because it is the header
for ( var i = 1; i < data.rsp.length; i++) {
// Go through each column
// where column names are: node, os, arch, profile, provmethod, supportedarchs, nodetype, comments, disable
var cols = data.rsp[i].split(',');
var node = cols[0].replace(new RegExp('"', 'g'), '');
var owner = cols[7].replace(new RegExp('"', 'g'), '');
owner = owner.replace('owner:', '');
if (owner == userName) {
usrNodes.push(node);
}
} // End of for
// Set cookie to expire in 240 minutes
var exDate = new Date();
exDate.setTime(exDate.getTime() + (240 * 60 * 1000));
$.cookie(userName + '_usrnodes', usrNodes, { expires: exDate });
} // End of if
}
/**
* Power on a given node
*
* @param node
* Node to power on or off
* @param power2
* Power node to given state
* @return Nothing
*/
function powerNode(node, power2) {
$.ajax({
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'rpower',
tgt : node,
args : power2,
msg : node
},
success : updatePowerStatus
});
}
/**
* Update power status of a node in the datatable
*
* @param data
* Data from HTTP request
* @return Nothing
*/
function updatePowerStatus(data) {
// Get datatable
var nodesDTId = 'userNodesDT';
var dTable = $('#' + nodesDTId).dataTable();
// Get xCAT response
var rsp = data.rsp;
// Loop through each line
var node, status, rowPos, strPos;
for (var i in rsp) {
// Get node name
node = rsp[i].split(":")[0];
// If there is no error
if (rsp[i].indexOf("Error") < 0 || rsp[i].indexOf("Failed") < 0) {
// Get the row containing the node link
rowPos = findRow(node, '#' + nodesDTId, 1);
// If it was power on, then the data return would contain "Starting"
strPos = rsp[i].indexOf("Starting");
if (strPos > -1) {
status = 'on';
} else {
status = 'off';
}
// Update the power status column
dTable.fnUpdate(status, rowPos, 3, false);
} else {
// Power on/off failed
alert(rsp[i]);
}
}
}
/**
* 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/srv_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/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'webrun',
tgt : '',
args : 'gangliastart;' + data.msg,
msg : data.msg
},
success : function(data) {
// Remove any warnings
$('#nodesTab').find('.ui-state-error').remove();
refreshGangliaStatus(data.msg);
}
});
} // End of if (warn)
} // End of function(data)
});
}
} else {
var args;
if (node) {
args = 'gangliastop;' + node;
$.ajax( {
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'webrun',
tgt : '',
args : args,
msg : node
},
success : function(data) {
refreshGangliaStatus(data.msg);
}
});
}
}
}
/**
* Open a dialog to delete node
*
* @param tgtNodes
* Nodes to delete
* @return Nothing
*/
function deleteNode(tgtNodes) {
var nodes = tgtNodes.split(',');
// Loop through each node and create target nodes string
var tgtNodesStr = '';
for (var i in nodes) {
if (i == 0 && i == nodes.length - 1) {
// If it is the 1st and only node
tgtNodesStr += nodes[i];
} else if (i == 0 && i != nodes.length - 1) {
// If it is the 1st node of many nodes, append a comma to the string
tgtNodesStr += nodes[i] + ', ';
} else {
if (i == nodes.length - 1) {
// If it is the last node, append nothing to the string
tgtNodesStr += nodes[i];
} else {
// Append a comma to the string
tgtNodesStr += nodes[i] + ', ';
}
}
}
// Confirm delete
var confirmMsg = $('<p>Are you sure you want to delete ' + tgtNodesStr + '?</p>').css({
'display': 'inline',
'margin': '5px',
'vertical-align': 'middle',
'word-wrap': 'break-word'
});
var style = {
'display': 'inline-block',
'margin': '5px',
'vertical-align': 'middle'
};
var dialog = $('<div></div>');
var icon = $('<span class="ui-icon ui-icon-alert"></span>').css(style);
dialog.append(icon);
dialog.append(confirmMsg);
// Open dialog
dialog.dialog({
title: "Confirm",
modal: true,
width: 400,
buttons: {
"Yes": function(){
// Create status bar and append to tab
var instance = 0;
var statBarId = 'deleteStat' + instance;
while ($('#' + statBarId).length) {
// If one already exists, generate another one
instance = instance + 1;
statBarId = 'deleteStat' + instance;
}
var statBar = createStatusBar(statBarId);
var loader = createLoader('');
statBar.find('div').append(loader);
statBar.prependTo($('#manageTab'));
// Delete the virtual server
$.ajax( {
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'rmvm',
tgt : tgtNodes,
args : '',
msg : 'out=' + statBarId + ';cmd=rmvm;tgt=' + tgtNodes
},
success : function(data) {
var args = data.msg.split(';');
var statBarId = args[0].replace('out=', '');
var tgts = args[2].replace('tgt=', '').split(',');
// Get data table
var nodesDTId = 'userNodesDT';
var dTable = $('#' + nodesDTId).dataTable();
var failed = false;
// Create an info box to show output
var output = writeRsp(data.rsp, '');
output.css('margin', '0px');
// Remove loader and append output
$('#' + statBarId + ' img').remove();
$('#' + statBarId + ' div').append(output);
// If there was an error, do not continue
if (output.html().indexOf('Error') > -1) {
failed = true;
}
// Update data table
var rowPos;
for (var i in tgts) {
if (!failed) {
// Get row containing the node link and delete it
rowPos = findRow(tgts[i], '#' + nodesDTId, 1);
dTable.fnDeleteRow(rowPos);
}
}
// Refresh nodes owned by user
$.ajax( {
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'tabdump',
tgt : '',
args : 'nodetype',
msg : ''
},
success : function(data) {
setUserNodes(data);
}
});
}
});
$(this).dialog("close");
},
"No": function() {
$(this).dialog("close");
}
}
});
}
/**
* Unlock a node by setting the ssh keys
*
* @param tgtNodes
* Nodes to unlock
* @return Nothing
*/
function unlockNode(tgtNodes) {
var nodes = tgtNodes.split(',');
// Loop through each node and create target nodes string
var tgtNodesStr = '';
for (var i in nodes) {
if (i == 0 && i == nodes.length - 1) {
// If it is the 1st and only node
tgtNodesStr += nodes[i];
} else if (i == 0 && i != nodes.length - 1) {
// If it is the 1st node of many nodes, append a comma to the string
tgtNodesStr += nodes[i] + ', ';
} else {
if (i == nodes.length - 1) {
// If it is the last node, append nothing to the string
tgtNodesStr += nodes[i];
} else {
// Append a comma to the string
tgtNodesStr += nodes[i] + ', ';
}
}
}
var dialog = $('<div></div>');
var infoBar = createInfoBar('Give the root password for this node range to setup its SSH keys.');
dialog.append(infoBar);
var unlockForm = $('<div class="form"></div>').css('margin', '5px');
unlockForm.append('<div><label>Target node range:</label><input type="text" id="node" name="node" readonly="readonly" value="' + tgtNodes + '" title="The node or node range to unlock"/></div>');
unlockForm.append('<div><label>Password:</label><input type="password" id="password" name="password" title="The root password to unlock this node"/></div>');
dialog.append(unlockForm);
dialog.find('div input').css('margin', '5px');
// 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"
}
});
// Open dialog
dialog.dialog({
title: "Confirm",
modal: true,
width: 450,
buttons: {
"Ok": function(){
// Create status bar and append to tab
var instance = 0;
var statBarId = 'unlockStat' + instance;
while ($('#' + statBarId).length) {
// If one already exists, generate another one
instance = instance + 1;
statBarId = 'unlockStat' + instance;
}
var statBar = createStatusBar(statBarId);
var loader = createLoader('');
statBar.find('div').append(loader);
statBar.prependTo($('#manageTab'));
// If a password is given
var password = unlockForm.find('input[name=password]:eq(0)');
if (password.val()) {
// Setup SSH keys
$.ajax( {
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'webrun',
tgt : '',
args : 'unlock;' + tgtNodes + ';' + password.val(),
msg : 'out=' + statBarId + ';cmd=unlock;tgt=' + tgtNodes
},
success : function(data) {
// Create an info box to show output
var output = writeRsp(data.rsp, '');
output.css('margin', '0px');
// Remove loader and append output
$('#' + statBarId + ' img').remove();
$('#' + statBarId + ' div').append(output);
}
});
$(this).dialog("close");
}
},
"Cancel": function() {
$(this).dialog("close");
}
}
});
}
/**
* Get nodes current load information
*/
function getNodesCurrentLoad(){
var userName = $.cookie('srv_usrname');
var nodes = $.cookie(userName + '_usrnodes');
// Get nodes current status
$.ajax({
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'webrun',
tgt : '',
args : 'gangliacurrent;node;' + nodes,
msg : ''
},
success: saveNodeLoad
});
}
/**
* Save node load data
*
* @param status
* Data returned from HTTP request
*/
function saveNodeLoad(status){
// Save node path and status for future use
nodePath = new Object();
nodeStatus = new Object();
// Get nodes status
var nodes = status.rsp[0].split(';');
var i = 0, pos = 0;
var node = '', tmpStr = '';
var tmpArry;
for (i = 0; i < nodes.length; i++){
tmpStr = nodes[i];
pos = tmpStr.indexOf(':');
node = tmpStr.substring(0, pos);
tmpArry = tmpStr.substring(pos + 1).split(',');
switch(tmpArry[0]){
case 'UNKNOWN':{
nodeStatus[node] = -2;
}
break;
case 'ERROR':{
nodeStatus[node] = -1;
}
break;
case 'WARNING':{
nodeStatus[node] = 0;
nodePath[node] = tmpArry[1];
}
break;
case 'NORMAL':{
nodeStatus[node] = 1;
nodePath[node] = tmpArry[1];
}
break;
}
}
}
/**
* Get monitoring metrics and load into inventory fieldset
*
* @param node
* Node to collect metrics
* @return Nothing
*/
function getMonitorMetrics(node) {
$('#' + node + '_monitor').children().remove();
// Get monitoring metrics
$.ajax({
url : 'lib/srv_cmd.php',
dataType : 'json',
data : {
cmd : 'webrun',
tgt : '',
args : 'gangliashow;' + nodePath[node] + ';hour;_summary_',
msg : node
},
success: drawMonitoringCharts
});
}
/**
* Draw monitoring charts based on node metrics
*
* @param data
* Data returned from HTTP request
* @return Nothing
*/
function drawMonitoringCharts(data){
var nodeMetrics = new Object();
var metricData = data.rsp[0].split(';');
var node = data.msg;
var metricName = '';
var metricVal = '';
var pos = 0;
// Go through the metrics returned
for (var m = 0; m < metricData.length; m++){
pos = metricData[m].indexOf(':');
// Get metric name
metricName = metricData[m].substr(0, pos);
nodeMetrics[metricName] = new Array();
// Get metric values
metricVal = metricData[m].substr(pos + 1).split(',');
// Save node metrics
for (var i = 0; i < metricVal.length; i++){
nodeMetrics[metricName].push(Number(metricVal[i]));
}
}
drawLoadFlot(node, nodeMetrics['load_one'], nodeMetrics['cpu_num']);
drawCpuFlot(node, nodeMetrics['cpu_idle']);
drawMemFlot(node, nodeMetrics['mem_free'], nodeMetrics['mem_total']);
drawDiskFlot(node, nodeMetrics['disk_free'], nodeMetrics['disk_total']);
drawNetworkFlot(node, nodeMetrics['bytes_in'], nodeMetrics['bytes_out']);
}
/**
* Draw load metrics flot
*
* @param node
* Node name
* @param loadpair
* Load timestamp and value pair
* @param cpupair
* CPU number and value pair
* @return Nothing
*/
function drawLoadFlot(node, loadPair, cpuPair){
var load = new Array();
var cpu = new Array();
var i = 0;
var yAxisMax = 0;
var interval = 1;
// Append flot to node monitoring fieldset
var loadFlot = $('<div id="' + node + '_load"></div>').css({
'float': 'left',
'height': '150px',
'margin': '0 0 10px',
'width': '300px'
});
$('#' + node + '_monitor').append(loadFlot);
$('#' + node + '_load').empty();
// Parse load pair where:
// timestamp must be mutiplied by 1000 and Javascript timestamp is in ms
for (i = 0; i < loadPair.length; i += 2){
load.push([loadPair[i] * 1000, loadPair[i + 1]]);
if (loadPair[i + 1] > yAxisMax){
yAxisMax = loadPair[i + 1];
}
}
// Parse CPU pair
for (i = 0; i < cpuPair.length; i += 2){
cpu.push([cpuPair[i] * 1000, cpuPair[i + 1]]);
if (cpuPair[i + 1] > yAxisMax){
yAxisMax = cpuPair[i + 1];
}
}
interval = parseInt(yAxisMax / 3);
if (interval < 1){
interval = 1;
}
$.jqplot(node + '_load', [load, cpu],{
title: ' Loads/Procs Last Hour',
axes:{
xaxis:{
renderer : $.jqplot.DateAxisRenderer,
numberTicks: 4,
tickOptions : {
formatString : '%R',
show : true
}
},
yaxis: {
min : 0,
tickInterval : interval
}
},
legend : {
show: true,
location: 'nw'
},
series:[{label:'Load'}, {label: 'CPU Number'}],
seriesDefaults : {showMarker: false}
});
}
/**
* Draw CPU usage flot
*
* @param node
* Node name
* @param cpuPair
* CPU timestamp and value pair
* @return Nothing
*/
function drawCpuFlot(node, cpuPair){
var cpu = new Array();
// Append flot to node monitoring fieldset
var cpuFlot = $('<div id="' + node + '_cpu"></div>').css({
'float': 'left',
'height': '150px',
'margin': '0 0 10px',
'width': '300px'
});
$('#' + node + '_monitor').append(cpuFlot);
$('#' + node + '_cpu').empty();
// Time stamp should by mutiplied by 1000
// CPU idle comes from server, subtract 1 from idle
for(var i = 0; i < cpuPair.length; i +=2){
cpu.push([(cpuPair[i] * 1000), (100 - cpuPair[i + 1])]);
}
$.jqplot(node + '_cpu', [cpu],{
title: 'CPU Use Last Hour',
axes:{
xaxis:{
renderer : $.jqplot.DateAxisRenderer,
numberTicks: 4,
tickOptions : {
formatString : '%R',
show : true
}
},
yaxis: {
min : 0,
max : 100,
tickOptions:{formatString : '%d\%'}
}
},
seriesDefaults : {showMarker: false}
});
}
/**
* Draw memory usage flot
*
* @param node
* Node name
* @param freePair
* Free memory timestamp and value pair
* @param totalPair
* Total memory timestamp and value pair
* @return Nothing
*/
function drawMemFlot(node, freePair, totalPair){
var used = new Array();
var total = new Array();
var size = 0;
// Append flot to node monitoring fieldset
var memoryFlot = $('<div id="' + node + '_memory"></div>').css({
'float': 'left',
'height': '150px',
'margin': '0 0 10px',
'width': '300px'
});
$('#' + node + '_monitor').append(memoryFlot);
$('#' + node + '_memory').empty();
if(freePair.length < totalPair.length){
size = freePair.length;
} else {
size = freePair.length;
}
var tmpTotal, tmpUsed;
for(var i = 0; i < size; i+=2){
tmpTotal = totalPair[i+1];
tmpUsed = tmpTotal-freePair[i+1];
tmpTotal = tmpTotal/1000000;
tmpUsed = tmpUsed/1000000;
total.push([totalPair[i]*1000, tmpTotal]);
used.push([freePair[i]*1000, tmpUsed]);
}
$.jqplot(node + '_memory', [used, total],{
title: 'Memory Use Last Hour',
axes:{
xaxis:{
renderer : $.jqplot.DateAxisRenderer,
numberTicks: 4,
tickOptions : {
formatString : '%R',
show : true
}
},
yaxis: {
min : 0,
tickOptions:{formatString : '%.2fG'}
}
},
legend : {
show: true,
location: 'nw'
},
series:[{label:'Used'}, {label: 'Total'}],
seriesDefaults : {showMarker: false}
});
}
/**
* Draw disk usage flot
*
* @param node
* Node name
* @param freePair
* Free disk space (Ganglia only logs free data)
* @param totalPair
* Total disk space
* @return Nothing
*/
function drawDiskFlot(node, freePair, totalPair) {
var used = new Array();
var total = new Array();
var size = 0;
// Append flot to node monitoring fieldset
var diskFlot = $('<div id="' + node + '_disk"></div>').css({
'float' : 'left',
'height' : '150px',
'margin' : '0 0 10px',
'width' : '300px'
});
$('#' + node + '_monitor').append(diskFlot);
$('#' + node + '_disk').empty();
if (freePair.length < totalPair.length) {
size = freePair.length;
} else {
size = freePair.length;
}
var tmpTotal, tmpUsed;
for ( var i = 0; i < size; i += 2) {
tmpTotal = totalPair[i + 1];
tmpUsed = tmpTotal - freePair[i + 1];
total.push([ totalPair[i] * 1000, tmpTotal ]);
used.push([ freePair[i] * 1000, tmpUsed ]);
}
$.jqplot(node + '_disk', [ used, total ], {
title : 'Disk Use Last Hour',
axes : {
xaxis : {
renderer : $.jqplot.DateAxisRenderer,
numberTicks : 4,
tickOptions : {
formatString : '%R',
show : true
}
},
yaxis : {
min : 0,
tickOptions : {
formatString : '%.2fG'
}
}
},
legend : {
show : true,
location : 'nw'
},
series : [ {
label : 'Used'
}, {
label : 'Total'
} ],
seriesDefaults : {
showMarker : false
}
});
}
/**
* Draw network usage flot
*
* @param node
* Node name
* @param freePair
* Free memory timestamp and value pair
* @param totalPair
* Total memory timestamp and value pair
* @return Nothing
*/
function drawNetworkFlot(node, inPair, outPair) {
var inArray = new Array();
var outArray = new Array();
var maxVal = 0;
var unitName = 'B';
var divisor = 1;
// Append flot to node monitoring fieldset
var diskFlot = $('<div id="' + node + '_network"></div>').css({
'float' : 'left',
'height' : '150px',
'margin' : '0 0 10px',
'width' : '300px'
});
$('#' + node + '_monitor').append(diskFlot);
$('#' + node + '_network').empty();
for (var i = 0; i < inPair.length; i += 2) {
if (inPair[i + 1] > maxVal) {
maxVal = inPair[i + 1];
}
}
for (var i = 0; i < outPair.length; i += 2) {
if (outPair[i + 1] > maxVal) {
maxVal = outPair[i + 1];
}
}
if (maxVal > 3000000) {
divisor = 1000000;
unitName = 'GB';
} else if (maxVal >= 3000) {
divisor = 1000;
unitName = 'MB';
} else {
// Do nothing
}
for (i = 0; i < inPair.length; i += 2) {
inArray.push([ (inPair[i] * 1000), (inPair[i + 1] / divisor) ]);
}
for (i = 0; i < outPair.length; i += 2) {
outArray.push([ (outPair[i] * 1000), (outPair[i + 1] / divisor) ]);
}
$.jqplot(node + '_network', [ inArray, outArray ], {
title : 'Network Last Hour',
axes : {
xaxis : {
renderer : $.jqplot.DateAxisRenderer,
numberTicks : 4,
tickOptions : {
formatString : '%R',
show : true
}
},
yaxis : {
min : 0,
tickOptions : {
formatString : '%d' + unitName
}
}
},
legend : {
show : true,
location : 'nw'
},
series : [ {
label : 'In'
}, {
label : 'Out'
} ],
seriesDefaults : {
showMarker : false
}
});
}