var bpaList;
var fspList;
var lparList;
var bladeList;
var rackList;
var unknownList;
var graphicalNodeList;
var selectNode;
/**
* Get all nodes useful attributes from remote server
*
* @param dataTypeIndex The index in the array which contains attributes we need.
* @param attrNullNode The target node list for this attribute
*/
function initGraphicalData() {
$('#graphTab').append(createLoader());
$.ajax({
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'webrun',
tgt : '',
args : 'graph',
msg : ''
},
success : function(data) {
if (!data.rsp[0]) {
return;
}
extractGraphicalData(data.rsp[0]);
getNodesAndDraw();
}
});
}
/**
* Extract all nodes userful data into a hash, which will be used for creating graphical
*
* @param data The response from xCAT command 'nodels all nodetype.nodetype ppc.parent ...'
* @return nodes list for next time query
*/
function extractGraphicalData(data) {
var nodes = data.split(';');
var attrs;
var nodeName;
// Extract useful info into tempList
for (var i = 0; i < nodes.length; i++) {
attrs = nodes[i].split(':');
nodeName = attrs[0];
if (undefined == graphicalNodeList[nodeName]) {
graphicalNodeList[nodeName] = new Object();
}
graphicalNodeList[nodeName]['type'] = attrs[1].toLowerCase();
switch (attrs[1].toLowerCase()) {
case 'cec':
case 'frame':
case 'lpar':
case 'lpar,osi':
case 'osi,lpar':
graphicalNodeList[nodeName]['parent'] = attrs[2];
graphicalNodeList[nodeName]['mtm'] = attrs[3];
graphicalNodeList[nodeName]['status'] = attrs[4];
break;
case 'blade':
graphicalNodeList[nodeName]['mpa'] = attrs[2];
graphicalNodeList[nodeName]['unit'] = attrs[3];
graphicalNodeList[nodeName]['status'] = attrs[4];
break;
case 'systemx':
graphicalNodeList[nodeName]['rack'] = attrs[2];
graphicalNodeList[nodeName]['unit'] = attrs[3];
graphicalNodeList[nodeName]['mtm'] = attrs[4];
graphicalNodeList[nodeName]['status'] = attrs[5];
break;
default:
break;
}
}
}
function createPhysicalLayout(nodeList) {
var flag = false;
// When the graphical layout is shown, do not need to redraw
if (1 < $('#graphTab').children().length) {
return;
}
// Save the new selected nodes
if (graphicalNodeList) {
for (var i in graphicalNodeList) {
flag = true;
break;
}
}
bpaList = new Object();
fspList = new Object();
lparList = new Object();
bladeList = new Object();
selectNode = new Object();
rackList = new Object();
unknownList = new Array();
// There is no graphical data, get the info now
if (!flag) {
graphicalNodeList = new Object();
initGraphicalData();
} else {
getNodesAndDraw();
}
}
function getNodesAndDraw() {
var groupName = $.cookie('selectgrouponnodes');
$.ajax({
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'nodels',
tgt : groupName,
args : '',
msg : ''
},
success : function(data) {
for (var temp in data.rsp) {
var nodeName = data.rsp[temp][0];
if ('' == nodeName) {
continue;
}
fillList(nodeName);
}
$('#graphTab').empty();
createGraphical();
}
});
}
function fillList(nodeName, defaultnodetype) {
var parentName = '';
var mtm = '';
var status = '';
var nodeType = '';
var mpa = '';
var unit = '';
var rack = '';
if (!graphicalNodeList[nodeName]) {
parentName = '';
mtm = '';
status = '';
nodeType = defaultnodetype;
} else {
status = graphicalNodeList[nodeName]['status'];
nodeType = graphicalNodeList[nodeName]['type'];
switch (nodeType) {
case 'frame':
case 'lpar,osi':
case 'lpar':
case 'osi':
case 'cec':
parentName = graphicalNodeList[nodeName]['parent'];
mtm = graphicalNodeList[nodeName]['mtm'];
break;
case 'blade':
mpa = graphicalNodeList[nodeName]['mpa'];
unit = graphicalNodeList[nodeName]['unit'];
break;
case 'systemx':
rack = graphicalNodeList[nodeName]['rack'];
unit = graphicalNodeList[nodeName]['unit'];
break;
default:
break;
}
}
if ('' == status) {
status = 'unknown';
}
switch (nodeType) {
case 'frame':
if (undefined == bpaList[nodeName]) {
bpaList[nodeName] = new Array();
}
break;
case 'lpar,osi':
case 'lpar':
case 'osi':
if ('' == parentName) {
break;
}
if (undefined == fspList[parentName]) {
fillList(parentName, 'cec');
}
fspList[parentName]['children'].push(nodeName);
lparList[nodeName] = status;
break;
case 'cec':
if (undefined != fspList[nodeName]) {
break;
}
fspList[nodeName] = new Object();
fspList[nodeName]['children'] = new Array();
fspList[nodeName]['mtm'] = mtm;
if ('' == parentName) {
break;
}
if (undefined == bpaList[parentName]) {
fillList(parentName, 'frame');
}
bpaList[parentName].push(nodeName);
break;
case 'blade':
if (undefined == bladeList[mpa]) {
bladeList[mpa] = new Array();
}
bladeList[mpa].push(nodeName + ',' + unit);
break;
case 'systemx':
if (!rack) {
rack = '_notsupply_';
}
if (undefined == rackList[rack]) {
rackList[rack] = new Array();
}
rackList[rack].push(nodeName + ',' + unit);
break;
default:
unknownList.push(nodeName);
break;
}
}
function createGraphical() {
var tabArea = $('#graphTab');
var selectNodeDiv = $('
');
var temp = 0;
for (var i in selectNode) {
temp++;
break;
}
// There is no selected LPAR, show the info bar
if (temp == 0) {
tabArea.append(createInfoBar('Hover over a CEC and select the LPARs to do operations against.'));
} else {
// Show selected LPARs
updateSelectNodeDiv();
}
// Add buttons
tabArea.append(createActionMenu());
tabArea.append(selectNodeDiv);
createSystempGraphical(bpaList, fspList, tabArea);
createBladeGraphical(bladeList, tabArea);
createSystemxGraphical(rackList, tabArea);
addUnknownGraphical(unknownList, tabArea);
}
/**
* Create the physical/graphical layout for System p machines
*
* @param bpa All BPA and their related FSPs
* @param fsp All FSP and their related LPARs
* @param area The element to append graphical layout
*/
function createSystempGraphical(bpa, fsp, area) {
var usedFsp = new Object();
var graphTable = $('
');
var elementNum = 0;
var row = null;
var showFlag = false;
// There is a node in the BPA list, so show add the title and show all frames
for (var bpaName in bpa) {
showFlag = true;
$('#graphTab').append('system p');
$('#graphTab').append(graphTable);
break;
}
for (var bpaName in bpa) {
if (0 == elementNum % 3) {
row = $('
');
graphTable.append(row);
}
elementNum++;
var td = $('
');
var frameDiv = $('');
frameDiv.append('');
// For P7-IH, all the CECs are insert into the frame from bottom to up,
// so we have to show the CECs same as the physical layout
var tempBlankDiv = $('');
var tempHeight = 0;
for (var fspIndex in bpa[bpaName]) {
var fspName = bpa[bpaName][fspIndex];
usedFsp[fspName] = 1;
// This is the P7-IH, we should add the blank at the top
if ((0 == fspIndex) && ('9125-F2C' == fsp[fspName]['mtm'])) {
frameDiv.append(tempBlankDiv);
}
frameDiv.append(createFspDiv(fspName, fsp[fspName]['mtm'], fsp));
frameDiv.append(createFspTip(fspName, fsp[fspName]['mtm'], fsp));
tempHeight += calculateBlank(fsp[fspName]['mtm']);
}
// tempHeight is the total height for all CECs, so we should minus BPA div
// height and CEC div heights
tempHeight = 428 - tempHeight;
tempBlankDiv.css('height', tempHeight);
td.append(frameDiv);
row.append(td);
}
// Find the single FSP and sort descend by units
var singleFsp = new Array();
for (var fspName in fsp) {
if (usedFsp[fspName]) {
continue;
}
singleFsp.push([ fspName, fsp[fspName]['mtm'] ]);
}
// If there is no frame, we should check if there is single CEC and show
// the title and add node area
if (!showFlag) {
for (var fspIndex in singleFsp) {
$('#graphTab').append('system p');
$('#graphTab').append(graphTable);
break;
}
}
singleFsp.sort(function(a, b) {
var unitNumA = 4;
var unitNumB = 4;
if (hardwareInfo[a[1]]) {
unitNumA = hardwareInfo[a[1]][1];
}
if (hardwareInfo[b[1]]) {
unitNumB = hardwareInfo[b[1]][1];
}
return (unitNumB - unitNumA);
});
elementNum = 0;
for (var fspIndex in singleFsp) {
var fspName = singleFsp[fspIndex][0];
if (0 == elementNum % 3) {
row = $('
');
graphTable.append(row);
}
elementNum++;
var td = $('
');
td.append(createFspDiv(fspName, fsp[fspName]['mtm'], fsp));
td.append(createFspTip(fspName, fsp[fspName]['mtm'], fsp));
row.append(td);
}
$('.tooltip input[type = checkbox]').bind('click', function() {
var lparName = $(this).attr('name');
if ('' == lparName) {
return;
}
if (true == $(this).attr('checked')) {
changeNode(lparName, 'select');
} else {
changeNode(lparName, 'unselect');
}
updateSelectNodeDiv();
});
$('.fspDiv2, .fspDiv4, .fspDiv42').tooltip({
position : "center right",
relative : true,
offset : [ 10, -40 ],
effect : "fade",
opacity : 0.9
});
$('.tooltip a').bind('click', function() {
var lparName = $(this).html();
$('#nodesDatatable #' + lparName).trigger('click');
});
$('.fspDiv2, .fspDiv4, .fspDiv42').bind('click', function() {
var fspName = $(this).attr('value');
var selectCount = 0;
for (var lparIndex in fspList[fspName]['children']) {
var lparName = fspList[fspName]['children'][lparIndex];
if (selectNode[lparName]) {
selectCount++;
}
}
// All LPARs are selected, so unselect nodes
if (selectCount == fspList[fspName]['children'].length) {
for (var lparIndex in fspList[fspName]['children']) {
var lparName = fspList[fspName]['children'][lparIndex];
changeNode(lparName, 'unselect');
}
}
// No selected LPARs on the cec, so add all LPARs into selectNode hash
else {
for (var lparIndex in fspList[fspName]['children']) {
var lparName = fspList[fspName]['children'][lparIndex];
changeNode(lparName, 'select');
}
}
updateSelectNodeDiv();
});
$('.fspCheckbox').bind('click', function() {
var itemName = $(this).attr('name');
name = itemName.substr(6);
if ($(this).attr('checked')) {
selectNode[name] = 1;
} else {
delete selectNode[name];
}
updateSelectNodeDiv();
});
}
/**
* Create the physical/graphical layout for blades
*
* @param blades The blade list in global
* @param area The element to append the graphical layout
*/
function createBladeGraphical(blades, area) {
var graphTable = $('
');
var mpa = '';
var bladeName = '';
var index = 0;
var mpaNumber = 0;
var row;
var showFlag = false;
// Only show the title and nodes when there are blade in the blade list
for (mpa in blades) {
showFlag = true;
break;
}
if (showFlag) {
$('#graphTab').append('Blade');
$('#graphTab').append(graphTable);
}
// If there is no blade node, return directly
else {
return;
}
for (mpa in blades) {
var tempArray = new Array(14);
var bladeInfo = new Array();
var unit = 0;
if (0 == mpaNumber % 3) {
row = $('
');
graphTable.append(row);
}
mpaNumber++;
var td = $('
');
var chasisDiv = $('');
// Fill the array with blade information, to create the empty slot
for (index in blades[mpa]) {
bladeInfo = blades[mpa][index].split(',');
unit = parseInt(bladeInfo[1]);
tempArray[unit - 1] = bladeInfo[0];
}
// Draw the blades and empty slot in chasis
for (index = 0; index < 14; index++) {
if (tempArray[index]) {
bladeName = tempArray[index];
chasisDiv.append('');
} else {
chasisDiv.append('');
}
}
td.append(chasisDiv);
row.append(td);
}
}
/**
* Create the physical/graphical layout for System x machines
*
* @param xnodes The system x node list in global
* @param area The element to append graphical layout
*/
function createSystemxGraphical(xnodes, area) {
var graphTable = $('
');
var xnodename = '';
var index = 0;
var rack = '';
var row;
var xNodeCount = 0;
var showflag = false;
// Only the title and System x node when there are x nodes in the list
for (rack in rackList) {
showflag = true;
break;
}
if (showflag) {
$('#graphTab').append('system x');
$('#graphTab').append(graphTable);
}
// There is nothing to show, return directly
else {
return;
}
for (rack in rackList) {
for (index in rackList[rack]) {
var xNodeName = rackList[rack][index];
if (0 == xNodeCount % 3) {
row = $('
');
graphTable.append(row);
}
xNodeCount++;
var td = $('
');
var xNodeDiv = '';
td.append(xNodeDiv);
row.append(td);
}
}
}
function addUnknownGraphical(unknownNodes, tab) {
// Do not continue if no nodes were found
if (unknownNodes.length < 1)
return;
var list = "";
tab.append('');
for (var index in unknownNodes) {
list += unknownNodes[index] + ', ';
}
// Delete last comma
list = list.substr(0, list.length - 2);
tab.append(list);
}
/**
* Update the LPARs background in CEC, LPAR area and selectNode
*/
function updateSelectNodeDiv() {
var temp = 0;
$('#selectNodeDiv').empty();
// Add buttons
if (selectNode.length) {
$('#selectNodeDiv').append('Nodes: ');
for (var lparName in selectNode) {
$('#selectNodeDiv').append(lparName + ' ');
temp++;
if (temp > 6) {
$('#selectNodeDiv').append('...');
break;
}
}
}
}
/**
* Create the action menu
*/
function createActionMenu() {
// Create action bar
var actionBar = $('').css("width", "400px");
// Power on
var powerOnLnk = $('Power on');
powerOnLnk.click(function() {
var tgtNodes = getSelectNodes();
$.ajax({
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'rpower',
tgt : tgtNodes,
args : 'on',
msg : ''
}
});
});
// Power off
var powerOffLnk = $('Power off');
powerOffLnk.click(function() {
var tgtNodes = getSelectNodes();
$.ajax({
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'rpower',
tgt : tgtNodes,
args : 'off',
msg : ''
}
});
});
// Delete
var deleteLnk = $('Delete');
deleteLnk.click(function() {
var tgtNodes = getSelectNodes();
if (tgtNodes) {
loadDeletePage(tgtNodes);
}
});
// Unlock
var unlockLnk = $('Unlock');
unlockLnk.click(function() {
var tgtNodes = getSelectNodes();
if (tgtNodes) {
loadUnlockPage(tgtNodes);
}
});
// Run script
var scriptLnk = $('Run script');
scriptLnk.click(function() {
var tgtNodes = getSelectNodes();
if (tgtNodes) {
loadScriptPage(tgtNodes);
}
});
// Update
var updateLnk = $('Update');
updateLnk.click(function() {
var tgtNodes = getSelectNodes();
if (tgtNodes) {
loadUpdatenodePage(tgtNodes);
}
});
// Set boot state
var setBootStateLnk = $('Set boot state');
setBootStateLnk.click(function() {
var tgtNodes = getSelectNodes();
if (tgtNodes) {
loadNodesetPage(tgtNodes);
}
});
// Boot to network
var boot2NetworkLnk = $('Boot to network');
boot2NetworkLnk.click(function() {
var tgtNodes = getSelectNodes();
if (tgtNodes) {
loadNetbootPage(tgtNodes);
}
});
// Remote console
var rconLnk = $('Open console');
rconLnk.bind('click', function(event) {
var tgtNodes = getSelectNodes();
if (tgtNodes) {
loadRconsPage(tgtNodes);
}
});
// Edit properties
var editProps = $('Edit properties');
editProps.bind('click', function(event) {
for (var node in selectNode) {
loadEditPropsPage(node);
}
});
// Actions
var actionsLnk = 'Actions';
var actsMenu = createMenu([ deleteLnk, powerOnLnk, powerOffLnk, scriptLnk ]);
// Configurations
var configLnk = 'Configuration';
var configMenu = createMenu([ unlockLnk, updateLnk, editProps ]);
// Provision
var provLnk = 'Provision';
var provMenu = createMenu([ boot2NetworkLnk, setBootStateLnk, rconLnk ]);
// Create an action menu
var actionsMenu = createMenu([ [ actionsLnk, actsMenu ],
[ configLnk, configMenu ], [ provLnk, provMenu ] ]);
actionsMenu.superfish();
actionsMenu.css('display', 'inline-block');
actionBar.append(actionsMenu);
actionBar.css('margin-top', '10px');
// Set correct theme for action menu
actionsMenu.find('li').hover(function() {
setMenu2Theme($(this));
}, function() {
setMenu2Normal($(this));
});
return actionBar;
}
/**
* Create the physical/graphical layout
*/
function createFspDiv(fspName, mtm, fsp) {
// Create FSP title
var lparStatusRow = '';
var temp = '';
for (var lparIndex in fsp[fspName]['children']) {
// Show 8 lpars on one cec at most.
if (lparIndex >= 8) {
break;
}
var lparName = fsp[fspName]['children'][lparIndex];
var color = statusMap(lparList[lparName]);
lparStatusRow += '
';
}
// Select the backgroud
var divClass = '';
if ('' == mtm) {
temp = '8231-E2B';
} else {
temp = mtm;
}
if (!hardwareInfo[temp]){
hardwareInfo[temp] = ['unkown', 2];
}
if (hardwareInfo[temp][1]) {
divClass += 'fspDiv' + hardwareInfo[temp][1];
} else {
divClass += 'fspDiv4';
}
// Create return value
var retHtml = '';
retHtml += '
';
retHtml += '
' + lparStatusRow
+ '
';
return retHtml;
}
/**
* Create the physical/graphical FSP tooltip which is used to select the LPAR
*/
function createFspTip(fspName, mtm, fsp) {
var tip = $('');
var tempTable = $('
');
var temp = '';
if ('' == mtm) {
temp = 'unkown';
} else {
temp = mtm;
}
if (hardwareInfo[temp]) {
tip.append('
' + fspName + '(' + hardwareInfo[temp][0] + ')
');
} else {
tip.append('
' + fspName + '
');
}
for (var lparIndex in fsp[fspName]['children']) {
var lparName = fsp[fspName]['children'][lparIndex];
var color = statusMap(lparList[lparName]);
var row = '
';
tempTable.append(row);
}
tip.append(tempTable);
return tip;
}
/**
* Map the LPAR status into a color
*
* @param status LPAR status in nodelist table
* @return Corresponding color name
*/
function statusMap(status) {
var color = 'gainsboro';
switch (status) {
case 'alive':
case 'ready':
case 'pbs':
case 'sshd':
case 'booting':
case 'booted':
case 'ping':
color = 'green';
break;
case 'noping':
case 'unreachable':
color = 'red';
break;
default:
color = 'grey';
break;
}
return color;
}
/**
* Select all LPAR checkboxes
*/
function selectAllLpars(checkbox) {
var temp = checkbox.attr('checked');
$('#selectNodeTable input[type = checkbox]').attr('checked', temp);
}
/**
* Export all LPAR names from selectNode
*
* @return lpars' string
*/
function getSelectNodes() {
var ret = '';
for (var lparName in selectNode) {
ret += lparName + ',';
}
return ret.substring(0, ret.length - 1);
}
/**
* When the node is selected or unselected, update the area on CEC, update
* the global list, and update the tooltip table
*/
function changeNode(lparName, status) {
var imgUrl = '';
var checkFlag = true;
if ('select' == status) {
selectNode[lparName] = 1;
imgUrl = 'url(images/nodes/s-' + statusMap(lparList[lparName])
+ '.gif)';
checkFlag = true;
} else {
delete selectNode[lparName];
imgUrl = 'url(images/nodes/' + statusMap(lparList[lparName]) + '.gif)';
checkFlag = false;
}
$('#' + lparName + 'status').css('background-image', imgUrl);
$('.tooltip input[name="' + lparName + '"]').attr('checked', checkFlag);
}
/**
* The P7-IH's CECs are insert from bottom to up, so we had to calculate the blank height
*
* @return Height for the CEC
*/
function calculateBlank(mtm) {
if ('' == mtm) {
return 24;
}
if (!hardwareInfo[mtm]) {
return 24;
}
switch (hardwareInfo[mtm][1]) {
case 1:
return 13;
break;
case 2:
return 24;
break;
case 4:
return 47;
break;
default:
return 0;
break;
}
}