xcat-core/xCAT-UI/js/nodes/nodes.js
2010-11-04 19:30:39 +00:00

1613 lines
38 KiB
JavaScript

/**
* Global variables
*/
var nodesTabs; // Node tabs
var nodesDataTable; // Datatable containing all nodes within a group
/**
* Set the nodes tab
*
* @param obj
* Tab object
* @return Nothing
*/
function setNodesTab(obj) {
nodesTabs = obj;
}
/**
* Get the nodes tab
*
* @param Nothing
* @return Tab object
*/
function getNodesTab() {
return nodesTabs;
}
/**
* Get the nodes datatable
*
* @param Nothing
* @return Data table object
*/
function getNodesDataTable() {
return nodesDataTable;
}
/**
* Set the nodes datatable
*
* @param table
* Data table object
* @return Nothing
*/
function setNodesDataTable(table) {
nodesDataTable = table;
}
/**
* Load nodes page
*
* @return Nothing
*/
function loadNodesPage() {
// If groups are not already loaded
if (!$('#groups').length) {
var layoutSelectorDiv = $('<div id="layoutselector"></div>');
var logicalLayoutDiv = $('<div id="logicalLayout"></div>');
var physicalLayoutDiv = $('<div id="physicalLayout"></div>');
physicalLayoutDiv.hide();
$('#content').append(layoutSelectorDiv);
$('#content').append(logicalLayoutDiv);
$('#content').append(physicalLayoutDiv);
// Create layout selector
var groupRadio = $('<input type="radio" name="layoutselector" checked="checked">Group</input>');
groupRadio.bind('click',function(){
$('#physicalLayout').hide();
$('#logicalLayout').show();
});
var physicalRadio = $('<input type="radio" name="layoutselector">Graphical</input>');
physicalRadio.bind('click', function(){
$('#logicalLayout').hide();
$('#physicalLayout').show();
});
layoutSelectorDiv.append('<label>Layout:</label>');
layoutSelectorDiv.append(groupRadio);
layoutSelectorDiv.append(physicalRadio);
// Create a groups division
groupDIV = $('<div id="groups"></div>');
nodesDIV = $('<div id="nodes"></div>');
logicalLayoutDiv.append(groupDIV);
logicalLayoutDiv.append(nodesDIV);
// Create loader
var loader = createLoader();
groupDIV.append(loader);
// Create info bar
var info = createInfoBar('Select a group to view its nodes');
$('#nodes').append(info);
// Get groups
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'extnoderange',
tgt : '/.*',
args : 'subgroups',
msg : ''
},
success : loadGroups
});
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'nodels',
tgt : 'all',
args : 'nodetype.nodetype;ppc.parent;vpd.mtm;nodelist.status',
msg : ''
},
success : function(data){
createPhysicalLayout(data, $('#physicalLayout'));
}
});
}
}
/**
* Load groups
*
* @param data
* Data returned from HTTP request
* @return
*/
function loadGroups(data) {
// Remove loader
$('#groups').find('img').remove();
var groups = data.rsp;
setGroupsCookies(data);
// Create a list of groups
var ul = $('<ul></ul>');
var item = $('<li id="root"><h3>Groups</h3></li>');
ul.append(item);
var subUL = $('<ul></ul>');
item.append(subUL);
// Create a link for each group
for ( var i = groups.length; i--;) {
var subItem = $('<li></li>');
var link = $('<a id="' + groups[i] + '">' + groups[i] + '</a>');
// Open node table onclick
link.bind('click', function(event) {
var thisGroup = $(this).attr('id');
if (thisGroup) {
// Clear nodes division
$('#nodes').children().remove();
// 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);
// Get nodes within selected group
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'lsdef',
tgt : '',
args : thisGroup,
msg : thisGroup
},
success : loadNodes
});
} // End of if (thisGroup)
});
subItem.append(link);
subUL.append(subItem);
}
// Turn groups list into a tree
$('#groups').append(ul);
$('#groups').jstree( {
core : { "initially_open" : [ "root" ] },
themes : {
"theme" : "default",
"dots" : false, // No dots
"icons" : false // No icons
}
});
// Create link to add nodes
var addNodeLink = $('<a title="Add a node or a node range to xCAT">Add node</a>');
addNodeLink.bind('click', function(event) {
var info = createInfoBar('Select the hardware management for the new node range');
var addNodeForm = $('<div class="form"></div>');
addNodeForm.append(info);
addNodeForm.append('<div><label for="mgt">Hardware management:</label>'
+ '<select id="mgt" name="mgt">'
+ '<option>ipmi</option>'
+ '<option>blade</option>'
+ '<option>hmc</option>'
+ '<option>ivm</option>'
+ '<option>fsp</option>'
+ '<option>zvm</option>'
+ '</select>'
+ '</div>' );
// Open dialog to add node
addNodeForm.dialog({
modal: true,
width: 400,
buttons: {
"Ok": function(){
// Get hardware management
var mgt = $(this).find('select[name=mgt]').val();
var plugin;
switch(mgt) {
case "blade":
plugin = new bladePlugin();
break;
case "fsp":
plugin = new fspPlugin();
break;
case "hmc":
plugin = new hmcPlugin();
break;
case "ipmi":
plugin = new ipmiPlugin();
break;
case "ivm":
plugin = new ivmPlugin();
break;
case "zvm":
plugin = new zvmPlugin();
break;
}
plugin.addNode();
$(this).dialog( "close" );
},
"Cancel": function(){
$(this).dialog( "close" );
}
}
});
});
// Generate tooltips
addNodeLink.tooltip({
position: "center right", // Place tooltip on the right edge
offset: [-2, 10], // A little tweaking of the position
effect: "fade", // Use the built-in fadeIn/fadeOut effect
opacity: 0.7 // Custom opacity setting
});
$('#groups').append(addNodeLink);
}
/**
* Load nodes belonging to a given group
*
* @param data
* Data returned from HTTP request
* @return Nothing
*/
function loadNodes(data) {
// Data returned
var rsp = data.rsp;
// Group name
var group = data.msg;
// Node attributes hash
var attrs = new Object();
// Node attributes
var headers = new Object();
var node;
var 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('=');
var key = jQuery.trim(args[0]);
var val = jQuery.trim(args[1]);
// Create a hash table
attrs[node][key] = val;
headers[key] = 1;
}
// Sort headers
var sorted = new Array();
for ( var key in headers) {
sorted.push(key);
}
sorted.sort();
// Add column for check box, node, ping, and power
sorted.unshift('<input type="checkbox" onclick="selectAllCheckbox(event, $(this))">', 'node',
'<a>ping</a><img src="images/loader.gif"></img>',
'<a>power</a><img src="images/loader.gif"></img>');
// Create a datatable
var dTable = new DataTable('nodesDataTable');
dTable.init(sorted);
// Go through each node
for ( var node in attrs) {
// Create a row
var row = new Array();
// Create a check box
var checkBx = '<input type="checkbox" name="' + node + '"/>';
// Open node onclick
var nodeLink = $('<a class="node" id="' + node + '">' + node + '</a>').bind('click', loadNode);
row.push(checkBx, nodeLink, '', '');
// Go through each header
for ( var i = 4; i < sorted.length; i++) {
// Add the node attributes to the row
var key = sorted[i];
var val = attrs[node][key];
if (val) {
row.push(val);
} else {
row.push('');
}
}
// Add the row to the table
dTable.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, clone, delete, unlock, and advanced
*/
/*
* Power
*/
var powerLnk = $('<a>Power</a>');
/*
* Power on
*/
var powerOnLnk = $('<a>Power on</a>');
powerOnLnk.bind('click', function(event) {
var tgtNodes = getNodesChecked('nodesDataTable');
if (tgtNodes) {
powerNode(tgtNodes, 'on');
}
});
/*
* Power off
*/
var powerOffLnk = $('<a>Power off</a>');
powerOffLnk.bind('click', function(event) {
var tgtNodes = getNodesChecked('nodesDataTable');
if (tgtNodes) {
powerNode(tgtNodes, 'off');
}
});
/*
* Clone
*/
var cloneLnk = $('<a>Clone</a>');
cloneLnk.bind('click', function(event) {
var tgtNodes = getNodesChecked('nodesDataTable').split(',');
for ( var i = 0; i < tgtNodes.length; i++) {
var mgt = getNodeAttr(tgtNodes[i], 'mgt');
// Create an instance of the plugin
var plugin;
switch(mgt) {
case "blade":
plugin = new bladePlugin();
break;
case "fsp":
plugin = new fspPlugin();
break;
case "hmc":
plugin = new hmcPlugin();
break;
case "ipmi":
plugin = new ipmiPlugin();
break;
case "ivm":
plugin = new ivmPlugin();
break;
case "zvm":
plugin = new zvmPlugin();
break;
}
plugin.loadClonePage(tgtNodes[i]);
}
});
/*
* Delete
*/
var deleteLnk = $('<a>Delete</a>');
deleteLnk.bind('click', function(event) {
var tgtNodes = getNodesChecked('nodesDataTable');
if (tgtNodes) {
deleteNode(tgtNodes);
}
});
/*
* Unlock
*/
var unlockLnk = $('<a>Unlock</a>');
unlockLnk.bind('click', function(event) {
var tgtNodes = getNodesChecked('nodesDataTable');
if (tgtNodes) {
loadUnlockPage(tgtNodes);
}
});
/*
* Run script
*/
var scriptLnk = $('<a>Run script</a>');
scriptLnk.bind('click', function(event) {
var tgtNodes = getNodesChecked('nodesDataTable');
if (tgtNodes) {
loadScriptPage(tgtNodes);
}
});
/*
* Update node
*/
var updateLnk = $('<a>Update</a>');
updateLnk.bind('click', function(event) {
var tgtNodes = getNodesChecked('nodesDataTable');
if (tgtNodes) {
loadUpdatenodePage(tgtNodes);
}
});
/*
* Set boot state
*/
var setBootStateLnk = $('<a>Set boot state</a>');
setBootStateLnk.bind('click', function(event) {
var tgtNodes = getNodesChecked('nodesDataTable');
if (tgtNodes) {
loadNodesetPage(tgtNodes);
}
});
/*
* Boot to network
*/
var boot2NetworkLnk = $('<a>Boot to network</a>');
boot2NetworkLnk.bind('click', function(event) {
var tgtNodes = getNodesChecked('nodesDataTable');
if (tgtNodes) {
loadNetbootPage(tgtNodes);
}
});
/*
* Open the Rcons page
*/
var rcons = $('<a>Open Rcons</a>');
rcons.bind('click', function(event){
var tgtNodes = getNodesChecked('nodesDataTable');
if (tgtNodes) {
loadRconsPage(tgtNodes);
}
});
/*
* Advanced
*/
var advancedLnk = $('<a>Advanced</a>');
// Power actions
var powerActions = [ powerOnLnk, powerOffLnk ];
var powerActionMenu = createMenu(powerActions);
// Advanced actions
var advancedActions;
if ('compute' == group) {
advancedActions = [ boot2NetworkLnk, scriptLnk, setBootStateLnk, updateLnk, rcons ];
} else {
advancedActions = [ boot2NetworkLnk, scriptLnk, setBootStateLnk, updateLnk ];
}
var advancedActionMenu = createMenu(advancedActions);
/**
* Create an action menu
*/
var actionsDIV = $('<div></div>');
var actions = [ [ powerLnk, powerActionMenu ], cloneLnk, deleteLnk, unlockLnk, [ advancedLnk, advancedActionMenu ] ];
var actionMenu = createMenu(actions);
actionMenu.superfish();
actionsDIV.append(actionMenu);
actionBar.append(actionsDIV);
$('#nodesTab').append(actionBar);
// Insert table
$('#nodesTab').append(dTable.object());
// Turn table into a datatable
var myDataTable = $('#nodesDataTable').dataTable();
setNodesDataTable(myDataTable);
// Do not sort ping and power column
var pingCol = $('#nodesDataTable thead tr th').eq(2);
var powerCol = $('#nodesDataTable thead tr th').eq(3);
pingCol.unbind('click');
powerCol.unbind('click');
// Create enough space for loader to be displayed
$('#nodesDataTable tbody tr td:nth-child(3)').css('min-width', '60px');
$('#nodesDataTable tbody tr td:nth-child(4)').css('min-width', '60px');
// Instead refresh the ping status and power status
pingCol.bind('click', function(event) {
refreshPingStatus(group);
});
powerCol.bind('click', function(event) {
refreshPowerStatus(group);
});
/**
* Get power and ping status for each node
*/
// Get the power status
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'rpower',
tgt : group,
args : 'stat',
msg : ''
},
success : loadPowerStatus
});
// Get the ping status
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'webrun',
tgt : '',
args : 'pping ' + group,
msg : ''
},
success : loadPingStatus
});
/**
* Additional ajax requests need to be made for zVM
*/
// Get the index of the HCP column
var i = $.inArray('hcp', sorted);
if (i) {
// Get hardware control point
var rows = dTable.object().find('tbody tr');
var hcps = new Object();
for ( var j = 0; j < rows.length; j++) {
var val = rows.eq(j).find('td').eq(i).html();
hcps[val] = 1;
}
var args;
for ( var h in hcps) {
// Get node without domain name
args = h.split('.');
// 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 (HCP) specific info
// Get disk pools and network names
success : loadHcpInfo
});
} // End of for
} // End of if
}
/**
* Load power status for each node
*
* @param data
* Data returned from HTTP request
* @return Nothing
*/
function loadPowerStatus(data) {
// Get datatable
var dTable = getNodesDataTable();
var power = data.rsp;
var rowNum, 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
rowNum = getRowNum(node);
// Update the power status column
dTable.fnUpdate(status, rowNum, 3);
}
// Hide power loader
var powerCol = $('#nodesDataTable thead tr th').eq(3);
powerCol.find('img').hide();
}
/**
* Refresh power status for each node
*
* @param group
* Group name
* @return Nothing
*/
function refreshPowerStatus(group) {
// Show power loader
var powerCol = $('#nodesDataTable thead tr th').eq(3);
powerCol.find('img').show();
// Get the power status
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'rpower',
tgt : group,
args : 'stat',
msg : ''
},
success : loadPowerStatus
});
}
/**
* Load ping status for each node
*
* @param data
* Data returned from HTTP request
* @return Nothing
*/
function loadPingStatus(data) {
// Get data table
var dTable = getNodesDataTable();
var ping = data.rsp;
var rowPos, node, status;
// Get all nodes within the datatable
var rows = dTable.fnGetNodes();
for ( var i in ping) {
// ping[0] = nodeName and ping[1] = state
node = jQuery.trim(ping[i][0]);
status = jQuery.trim(ping[i][1]);
// Get the row containing the node
rowPos = getRowNum(node);
// Update the ping status column
dTable.fnUpdate(status, rowPos, 2);
}
// Hide ping loader
var pingCol = $('#nodesDataTable thead tr th').eq(2);
pingCol.find('img').hide();
}
/**
* Refresh ping status for each node
*
* @param group
* Group name
* @return Nothing
*/
function refreshPingStatus(group) {
// Show ping loader
var pingCol = $('#nodesDataTable thead tr th').eq(2);
pingCol.find('img').show();
// Get the ping status
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'webrun',
tgt : '',
args : 'pping ' + group,
msg : ''
},
success : loadPingStatus
});
}
/**
* Load inventory for given node
*
* @param e
* Windows event
* @return Nothing
*/
function loadNode(e) {
if (!e) {
e = window.event;
}
// Get node that was clicked
var node = (e.target) ? e.target.id : e.srcElement.id;
var mgt = getNodeAttr(node, 'mgt');
// Create an instance of the plugin
var plugin;
switch(mgt) {
case "blade":
plugin = new bladePlugin();
break;
case "fsp":
plugin = new fspPlugin();
break;
case "hmc":
plugin = new hmcPlugin();
break;
case "ipmi":
plugin = new ipmiPlugin();
break;
case "ivm":
plugin = new ivmPlugin();
break;
case "zvm":
plugin = new zvmPlugin();
break;
}
// Get tab area where a new tab will be inserted
// The node name may contain special characters (e.g. '.','#'), so we can not use the node name as an ID.
var myTab = getNodesTab();
var inst = 0;
var newTabId = 'nodeTab' + inst;
while ($('#' + newTabId).length) {
// If one already exists, generate another one
inst = inst + 1;
newTabId = 'nodeTab' + inst;
}
// Reset node process
$.cookie(node + 'Processes', 0);
// Add new tab, only if one does not exist
var loader = createLoader(newTabId + 'TabLoader');
loader = $('<center></center>').append(loader);
myTab.add(newTabId, node, loader, true);
// Get node inventory
var msg = 'out=' + newTabId + ',node=' + node;
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'rinv',
tgt : node,
args : 'all',
msg : msg
},
success : plugin.loadInventory
});
// Select new tab
// Tab ID may contains special char, so we had to use the index
myTab.select(newTabId);
}
/**
* Unlock a node by setting the SSH keys
*
* @param tgtNodes
* Nodes to unlock
* @return Nothing
*/
function loadUnlockPage(tgtNodes) {
// Get nodes tab
var tab = getNodesTab();
// Generate new tab ID
var instance = 0;
var newTabId = 'UnlockTab' + instance;
while ($('#' + newTabId).length) {
// If one already exists, generate another one
instance = instance + 1;
newTabId = 'UnlockTab' + instance;
}
var unlockForm = $('<div class="form"></div>');
// Create status bar, hide on load
var statBarId = 'UnlockStatusBar' + instance;
var statusBar = createStatusBar(statBarId).hide();
unlockForm.append(statusBar);
// Create loader
var loader = createLoader('');
statusBar.append(loader);
// Create info bar
var infoBar = createInfoBar('Give the root password for this node range to setup its SSH keys');
unlockForm.append(infoBar);
unlockForm.append('<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>');
// Generate tooltips
unlockForm.find('div input[title]').tooltip({
position: "center right", // Place tooltip on the right edge
offset: [-2, 10], // A little tweaking of the position
effect: "fade", // Use the built-in fadeIn/fadeOut effect
opacity: 0.7 // Custom opacity setting
});
/**
* Ok
*/
var okBtn = createButton('Ok');
okBtn.bind('click', function(event) {
// Remove any warning messages
$(this).parent().parent().find('.ui-state-error').remove();
// If form is complete
var ready = formComplete(newTabId);
if (ready) {
var password = $('#' + newTabId + ' input[name=password]').val();
// Setup SSH keys
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'webrun',
tgt : '',
args : 'unlock;' + tgtNodes + ';' + password,
msg : 'out=' + statBarId + ';cmd=unlock;tgt=' + tgtNodes
},
success : updateStatusBar
});
// Show status bar
statusBar.show();
// Disable Ok button
$(this).attr('disabled', 'true');
} else {
// Show warning message
var warn = createWarnBar('You are missing some values');
warn.prependTo($(this).parent().parent());
}
});
unlockForm.append(okBtn);
tab.add(newTabId, 'Unlock', unlockForm, true);
tab.select(newTabId);
}
/**
* Load script page
*
* @param tgtNodes
* Targets to run script against
* @return Nothing
*/
function loadScriptPage(tgtNodes) {
// Get nodes tab
var tab = getNodesTab();
// Generate new tab ID
var inst = 0;
var newTabId = 'scriptTab' + inst;
while ($('#' + newTabId).length) {
// If one already exists, generate another one
inst = inst + 1;
newTabId = 'scriptTab' + inst;
}
// Open new tab
// Create remote script form
var scriptForm = $('<div class="form"></div>');
// Create status bar
var barId = 'scriptStatusBar' + inst;
var statBar = createStatusBar(barId);
statBar.hide();
scriptForm.append(statBar);
// Create loader
var loader = createLoader('scriptLoader' + inst);
statBar.append(loader);
// Create info bar
var infoBar = createInfoBar('Run a script against this node range');
scriptForm.append(infoBar);
// Target node or group
var tgt = $('<div><label for="target">Target node range:</label><input type="text" name="target" value="' + tgtNodes + '" title="The node or node range to run a given script against"/></div>');
scriptForm.append(tgt);
// Upload file
var upload = $('<form action="lib/upload.php" method="post" enctype="multipart/form-data"></form>');
var label = $('<label for="file">Remote file:</label>');
var file = $('<input type="file" name="file" id="file"/>');
var subBtn = createButton('Load');
upload.append(label);
upload.append(file);
upload.append(subBtn);
scriptForm.append(upload);
// Generate tooltips
scriptForm.find('div input[title]').tooltip({
position: "center right", // Place tooltip on the right edge
offset: [-2, 10], // A little tweaking of the position
effect: "fade", // Use the built-in fadeIn/fadeOut effect
opacity: 0.7 // Custom opacity setting
});
// Script
var script = $('<div><label>Script:</label><textarea/>');
scriptForm.append(script);
// Ajax form options
var options = {
// Output to text area
target : '#' + newTabId + ' textarea'
};
upload.ajaxForm(options);
/**
* Run
*/
var runBtn = createButton('Run');
runBtn.bind('click', function(event) {
// Remove any warning messages
$(this).parent().parent().find('.ui-state-error').remove();
var ready = true;
// Check script
var textarea = $('#' + newTabId + ' textarea');
for ( var i = 0; i < textarea.length; i++) {
if (!textarea.eq(i).val()) {
textarea.eq(i).css('border', 'solid #FF0000 1px');
ready = false;
} else {
textarea.eq(i).css('border', 'solid #424242 1px');
}
}
// If no inputs are empty
if (ready) {
// Run script
runScript(inst);
} else {
// Show warning message
var warn = createWarnBar('You are missing some values');
warn.prependTo($(this).parent().parent());
}
});
scriptForm.append(runBtn);
// Append to discover tab
tab.add(newTabId, 'Script', scriptForm, true);
// Select new tab
tab.select(newTabId);
}
/**
* Sort a list
*
* @return Sorted list
*/
jQuery.fn.sort = function() {
return this.pushStack( [].sort.apply(this, arguments), []);
};
function sortAlpha(a, b) {
return a.innerHTML > b.innerHTML ? 1 : -1;
};
/**
* 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) {
node = node.replace('Power', '');
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'rpower',
tgt : node,
args : power2,
msg : node
},
success : updatePowerStatus
});
}
/**
* Delete a given node
*
* @param tgtNodes
* Nodes to delete
* @return Nothing
*/
function deleteNode(tgtNodes) {
// Get datatable
var myTab = getNodesTab();
// Generate new tab ID
var inst = 0;
newTabId = 'DeleteTab' + inst;
while ($('#' + newTabId).length) {
// If one already exists, generate another one
inst = inst + 1;
newTabId = 'DeleteTab' + inst;
}
// Create status bar, hide on load
var statBarId = 'DeleteStatusBar' + inst;
var statBar = $('<div class="statusBar" id="' + statBarId + '"></div>').hide();
// Create loader
var loader = createLoader('');
statBar.append(loader);
statBar.hide();
// Create target nodes string
var tgtNodesStr = '';
var nodes = tgtNodes.split(',');
// Loop through each node
for ( var i in nodes) {
// If it is the 1st and only node
if (i == 0 && i == nodes.length - 1) {
tgtNodesStr += nodes[i];
}
// If it is the 1st node of many nodes
else if (i == 0 && i != nodes.length - 1) {
// Append a comma to the string
tgtNodesStr += nodes[i] + ', ';
} else {
// If it is the last node
if (i == nodes.length - 1) {
// Append nothing to the string
tgtNodesStr += nodes[i];
} else {
// Append a comma to the string
tgtNodesStr += nodes[i] + ', ';
}
}
}
var deleteForm = $('<div class="form"></div>');
deleteForm.append(statBar);
deleteForm.append(statBar);
// Word wrap
var instr = $('<p>Do you want to delete ' + tgtNodesStr + '?</p>').css('word-wrap', 'break-word');
deleteForm.append(instr);
/**
* Delete
*/
var deleteBtn = createButton('Delete');
deleteBtn.bind('click', function(event) {
// Delete the virtual server
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'rmvm',
tgt : tgtNodes,
args : '',
msg : 'out=' + statBarId + ';cmd=rmvm;tgt=' + tgtNodes
},
success : updateStatusBar
});
// Show status bar loader
statBar.show();
// Disable delete button
$(this).attr('disabled', 'true');
});
var cancelBtn = createButton('Cancel');
cancelBtn.bind('click', function(){
myTab.remove($(this).parent().parent().attr('id'));
});
deleteForm.append(deleteBtn);
deleteForm.append(cancelBtn);
myTab.add(newTabId, 'Delete', deleteForm, true);
myTab.select(newTabId);
}
/**
* Update status bar of a given tab
*
* @param data
* Data returned from HTTP request
* @return Nothing
*/
function updateStatusBar(data) {
// Get ajax response
var rsp = data.rsp;
var args = data.msg.split(';');
var statBarId = args[0].replace('out=', '');
var cmd = args[1].replace('cmd=', '');
var tgts = args[2].replace('tgt=', '').split(',');
if (cmd == 'unlock' || cmd == 'updatenode') {
// Hide loader
$('#' + statBarId).find('img').hide();
// Write ajax response to status bar
var prg = writeRsp(rsp, '');
$('#' + statBarId).append(prg);
} else if (cmd == 'rmvm') {
// Get data table
var dTable = getNodesDataTable();
var failed = false;
// Hide loader
$('#' + statBarId).find('img').hide();
// Write ajax response to status bar
var prg = writeRsp(rsp, '');
$('#' + statBarId).append(prg);
// If there was an error, do not continue
if (prg.html().indexOf('Error') > -1) {
failed = true;
}
// Update data table
var rows = dTable.fnGetNodes();
for ( var i = 0; i < tgts.length; i++) {
if (!failed) {
// Get the row containing the node link and delete it
var row = getNodeRow(tgts[i], rows);
var rowPos = dTable.fnGetPosition(row);
dTable.fnDeleteRow(rowPos);
}
}
} else if (cmd == 'xdsh') {
// Hide loader
$('#' + statBarId).find('img').hide();
// Write ajax response to status bar
var prg = $('<p></p>');
for (var i in rsp) {
for (var j in tgts) {
rsp[i] = rsp[i].replace(new RegExp(tgts[j] + ':', 'g'), '<br>');
}
prg.append(rsp[i]);
prg.append('<br>');
}
$('#' + statBarId).append(prg);
// Enable fields
$('#' + statBarId).parent().find('input').removeAttr('disabled');
$('#' + statBarId).parent().find('textarea').removeAttr('disabled');
// Enable buttons
$('#' + statBarId).parent().find('button').removeAttr('disabled');
} else {
// Hide loader
$('#' + statBarId).find('img').hide();
// Write ajax response to status bar
var prg = writeRsp(rsp, '[A-Za-z0-9._-]+:');
$('#' + statBarId).append(prg);
}
}
/**
* Check if the form is complete
*
* @param tabId
* Tab ID containing form
* @return True: If the form is complete, False: Otherwise
*/
function formComplete(tabId) {
var ready = true;
// Check all inputs within the form
var inputs = $('#' + tabId + ' input');
for ( var i = 0; i < inputs.length; i++) {
// If there is no value given in the input
if (!inputs.eq(i).val()) {
inputs.eq(i).css('border', 'solid #FF0000 1px');
// It is not complete
ready = false;
} else {
inputs.eq(i).css('border', 'solid #BDBDBD 1px');
}
}
return ready;
}
/**
* Update power status of a node in the datatable
*
* @param data
* Data from HTTP request
* @return Nothing
*/
function updatePowerStatus(data) {
// Get datatable
var dTable = getNodesDataTable();
// Get all nodes within the datatable
var rows = dTable.fnGetNodes();
// Get xCAT response
var rsp = data.rsp;
// Loop through each line
for ( var i = 0; i < rsp.length; i++) {
// Get the node
var node = rsp[i].split(":")[0];
// If there is no error
var status;
if (rsp[i].indexOf("Error") < 0 || rsp[i].indexOf("Failed") < 0) {
// Get the row containing the node link
var row = getNodeRow(node, rows);
var rowPos = dTable.fnGetPosition(row);
// If it was power on, then the data return would contain "Starting"
var strPos = rsp[i].indexOf("Starting");
if (strPos > -1) {
status = 'on';
} else {
status = 'off';
}
// Update the power status column
dTable.fnUpdate(status, rowPos, 3);
} else {
// Power on/off failed
alert(rsp[i]);
}
}
}
/**
* Run a script
*
* @param inst
* Remote script tab instance
* @return Nothing
*/
function runScript(inst) {
var tabId = 'scriptTab' + inst;
// Get node name
var tgts = $('#' + tabId + ' input[name=target]').val();
// Get script
var script = $('#' + tabId + ' textarea').val();
var statBarId = 'scriptStatusBar' + inst;
$('#' + statBarId).show(); // Show status bar
$('#' + statBarId + ' img').show(); // Show loader
$('#' + statBarId + ' p').remove(); // Clear status bar
// Disable all fields
$('#' + tabId + ' input').attr('disabled', 'true');
$('#' + tabId + ' textarea').attr('disabled', 'true');
// Disable buttons
$('#' + tabId + ' button').attr('disabled', 'true');
// Run script
$.ajax( {
url : 'lib/zCmd.php',
dataType : 'json',
data : {
cmd : 'xdsh',
tgt : tgts,
args : '-e',
att : script,
msg : 'out=scriptStatusBar' + inst + ';cmd=xdsh;tgt=' + tgts
},
success : updateStatusBar
});
}
/**
* Get an attribute of a given node
*
* @param node
* The node
* @param attrName
* The attribute
* @return The attribute of the node
*/
function getNodeAttr(node, attrName) {
// Get the row
var row = $('[id=' + node + ']').parent().parent();
// Search for the column containing the attribute
var attrCol;
var cols = row.parent().parent().find('th:contains("' + attrName + '")');
// Loop through each column
for (var i in cols) {
// Find column that matches the attribute
if (cols.eq(i).html() == attrName) {
attrCol = cols.eq(i);
break;
}
}
// If the column containing the attribute is found
if (attrCol) {
// Get the attribute column index
var attrIndex = attrCol.index();
// Get the attribute for the given node
var attr = row.find('td:eq(' + attrIndex + ')');
return attr.text();
} else {
return '';
}
}
/**
* Set a cookie for the OS images
*
* @param data
* Data from HTTP request
* @return Nothing
*/
function setOSImageCookies(data) {
var rsp = data.rsp;
var imageNames = new Array;
var profilesHash = new Object();
var osVersHash = new Object();
var osArchsHash = new Object();
for ( var i = 1; i < rsp.length; i++) {
// osimage table columns: imagename, profile, imagetype, provmethod,
// osname, osvers, osdistro, osarch, synclists, comments, disable
// e.g. sles11.1-s390x-statelite-compute, compute, linux, statelite,
// Linux, sles11.1, , s390x, , s,
// Get the image name
var cols = rsp[i].split(',');
var osImage = cols[0].replace(new RegExp('"', 'g'), '');
var profile = cols[1].replace(new RegExp('"', 'g'), '');
var osVer = cols[5].replace(new RegExp('"', 'g'), '');
var osArch = cols[7].replace(new RegExp('"', 'g'), '');
imageNames.push(osImage);
profilesHash[profile] = 1;
osVersHash[osVer] = 1;
osArchsHash[osArch] = 1;
}
// Save image names in a cookie
$.cookie('ImageNames', imageNames);
// Save profiles in a cookie
var tmp = new Array;
for ( var key in profilesHash) {
tmp.push(key);
}
$.cookie('Profiles', tmp);
// Save OS versions in a cookie
tmp = [];
for ( var key in osVersHash) {
tmp.push(key);
}
$.cookie('OSVers', tmp);
// Save OS architectures in a cookie
tmp = [];
for ( var key in osArchsHash) {
tmp.push(key);
}
$.cookie('OSArchs', tmp);
}
/**
* Set a cookie for the groups
*
* @param data
* Data from HTTP request
* @return Nothing
*/
function setGroupsCookies(data) {
var rsp = data.rsp;
$.cookie('Groups', rsp);
}
/**
* Get row element that contains given node
*
* @param tgtNode
* Node to find
* @param rows
* Rows within the datatable
* @return Row element
*/
function getNodeRow(tgtNode, rows) {
// Find the row
for ( var i in rows) {
// Get all columns within the row
var cols = rows[i].children;
// Get the 1st column (node name)
var cont = cols[1].children;
var node = cont[0].innerHTML;
// If the node matches the target node
if (node == tgtNode) {
// Return the row
return rows[i];
}
}
return;
}
/**
* Get nodes that are checked in a given datatable
*
* @param datatableId
* The datatable ID
* @return Nodes that were checked
*/
function getNodesChecked(datatableId) {
var tgts = '';
// Get nodes that were checked
var nodes = $('#' + datatableId + ' input[type=checkbox]:checked');
for ( var i = 0; i < nodes.length; i++) {
var tgtNode = nodes.eq(i).attr('name');
if (tgtNode){
tgts += tgtNode;
// Add a comma at the end
if (i < nodes.length - 1) {
tgts += ',';
}
}
}
return tgts;
}
/**
* Get the column index for a given column name
*
* @param colName
* The column name to search
* @return The index containing the column name
*/
function getColNum(colName){
var colNum;
var columns = $('table thead tr').children();
for(colNum = 1; colNum < columns.length; colNum++){
if (colName == columns[colNum].innerHTML){
return colNum;
}
}
return -1;
}
/**
* Get the row index for a given node name
*
* @param nodeName
* Node name
* @return The row index containing the node name
*/
function getRowNum(nodeName){
// Get datatable
var dTable = getNodesDataTable();
// Get all data from datatable
var data = dTable.fnGetData();
var row;
var nodeItem;
for(row = 0; row < data.length; row++){
nodeItem = data[row][1];
if(nodeItem.indexOf('>' + nodeName + '<') > -1){
return row;
}
}
return -1;
}
/**
* Select all checkboxes in a given datatable
*
* @param event
* Event on element
* @param obj
* Object triggering event
* @return Nothing
*/
function selectAllCheckbox(event, obj) {
// Get datatable ID
// This will ascend from <input> <td> <tr> <thead> <table>
var datatableId = obj.parent().parent().parent().parent().attr('id');
var status = obj.attr('checked');
$('#' + datatableId + ' :checkbox').attr('checked', status);
event.stopPropagation();
}
/**
* Load rcons page
*
* @param tgtNodes
* Targets to run rcons against
* @return Nothing
*/
function loadRconsPage(tgtNodes){
var hostName = window.location.host;
var urlPath = window.location.pathname;
var redirectUrl = 'https://';
var pos = 0;
//we only support one node
if (-1 != tgtNodes.indexOf(',')){
alert("Sorry, the Rcons Page only support one node.");
return;
}
redirectUrl += hostName;
pos = urlPath.lastIndexOf('/');
redirectUrl += urlPath.substring(0, pos + 1);
redirectUrl += 'rconsShow.php';
//open the rcons page
window.open(redirectUrl + "?rconsnd=" + tgtNodes, '', "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=670,height=436");
}