1831 lines
41 KiB
JavaScript
1831 lines
41 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) {
|
||
|
// Create a groups division
|
||
|
groupDIV = $('<div id="groups"></div>');
|
||
|
nodesDIV = $('<div id="nodes"></div>');
|
||
|
$('#nodes_page').append(groupDIV);
|
||
|
$('#nodes_page').append(nodesDIV);
|
||
|
|
||
|
// 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
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load groups
|
||
|
*
|
||
|
* @param data
|
||
|
* Data returned from HTTP request
|
||
|
* @return
|
||
|
*/
|
||
|
function loadGroups(data) {
|
||
|
var groups = data.rsp;
|
||
|
setGroupsCookies(data);
|
||
|
|
||
|
// Create a list of groups
|
||
|
var ul = $('<ul></ul>');
|
||
|
var item = $('<li><ins></ins><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 href="#"><ins></ins>' + groups[i] + '</a>');
|
||
|
|
||
|
subItem.append(link);
|
||
|
subUL.append(subItem);
|
||
|
}
|
||
|
|
||
|
// Turn groups list into a tree
|
||
|
$('#groups').append(ul);
|
||
|
$('#groups').tree( {
|
||
|
callback : {
|
||
|
// Open the group onclick
|
||
|
onselect : function(node, tree) {
|
||
|
var thisGroup = tree.get_text(node);
|
||
|
if (thisGroup) {
|
||
|
// Clear the nodes DIV
|
||
|
$('#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);
|
||
|
|
||
|
// 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)
|
||
|
} // End of onselect
|
||
|
}
|
||
|
// End of callback
|
||
|
} );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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('', 'node', 'ping', 'power');
|
||
|
|
||
|
// 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 + '" href="#">' + 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 buttons
|
||
|
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 href="#">Power</a>');
|
||
|
|
||
|
/*
|
||
|
* Power on
|
||
|
*/
|
||
|
var powerOnLnk = $('<a href="#">Power on</a>');
|
||
|
powerOnLnk.bind('click', function(event) {
|
||
|
var tgtNodes = '';
|
||
|
|
||
|
// Get node that was checked
|
||
|
var nodes = $('#nodesDataTable input[type=checkbox]:checked');
|
||
|
for ( var i = 0; i < nodes.length; i++) {
|
||
|
tgtNodes += nodes.eq(i).attr('name');
|
||
|
|
||
|
// Add a comma in front of each node
|
||
|
if (i < nodes.length - 1) {
|
||
|
tgtNodes += ',';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (tgtNodes) {
|
||
|
powerNode(tgtNodes, 'on');
|
||
|
}
|
||
|
} );
|
||
|
|
||
|
/*
|
||
|
* Power off
|
||
|
*/
|
||
|
var powerOffLnk = $('<a href="#">Power off</a>');
|
||
|
powerOffLnk.bind('click', function(event) {
|
||
|
var tgtNodes = '';
|
||
|
|
||
|
// Get node that was checked
|
||
|
var nodes = $('#nodesDataTable input[type=checkbox]:checked');
|
||
|
for ( var i = 0; i < nodes.length; i++) {
|
||
|
tgtNodes += nodes.eq(i).attr('name');
|
||
|
|
||
|
// Add a comma in front of each node
|
||
|
if (i < nodes.length - 1) {
|
||
|
tgtNodes += ',';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (tgtNodes) {
|
||
|
powerNode(tgtNodes, 'off');
|
||
|
}
|
||
|
} );
|
||
|
|
||
|
/*
|
||
|
* Clone
|
||
|
*/
|
||
|
var cloneLnk = $('<a href="#">Clone</a>');
|
||
|
cloneLnk.bind('click', function(event) {
|
||
|
// Get node that was checked
|
||
|
var nodes = $('#nodesDataTable input[type=checkbox]:checked');
|
||
|
for ( var i = 0; i < nodes.length; i++) {
|
||
|
var node = nodes.eq(i).attr('name');
|
||
|
|
||
|
// Load clone page
|
||
|
if (node) {
|
||
|
var mgt = getNodeMgt(node);
|
||
|
if (mgt == 'zvm') {
|
||
|
loadZClonePage(node);
|
||
|
} else {
|
||
|
// TODO: Add clone for other platforms
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} );
|
||
|
|
||
|
/*
|
||
|
* Delete
|
||
|
*/
|
||
|
var deleteLnk = $('<a href="#">Delete</a>');
|
||
|
deleteLnk.bind('click', function(event) {
|
||
|
var tgtNodes = '';
|
||
|
|
||
|
// Get node that was checked
|
||
|
var nodes = $('#nodesDataTable input[type=checkbox]:checked');
|
||
|
for ( var i = 0; i < nodes.length; i++) {
|
||
|
tgtNodes += nodes.eq(i).attr('name');
|
||
|
|
||
|
// Add a comma in front of each node
|
||
|
if (i < nodes.length - 1) {
|
||
|
tgtNodes += ',';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Load delete page
|
||
|
if (tgtNodes) {
|
||
|
deleteNode(tgtNodes);
|
||
|
}
|
||
|
} );
|
||
|
|
||
|
/*
|
||
|
* Unlock
|
||
|
*/
|
||
|
var unlockLnk = $('<a href="#">Unlock</a>');
|
||
|
unlockLnk.bind('click', function(event) {
|
||
|
var tgtNodes = '';
|
||
|
|
||
|
// Get node that was checked
|
||
|
var nodes = $('#nodesDataTable input[type=checkbox]:checked');
|
||
|
for ( var i = 0; i < nodes.length; i++) {
|
||
|
tgtNodes += nodes.eq(i).attr('name');
|
||
|
|
||
|
// Add a comma in front of each node
|
||
|
if (i < nodes.length - 1) {
|
||
|
tgtNodes += ',';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Load unlock page
|
||
|
if (tgtNodes) {
|
||
|
loadUnlockPage(tgtNodes);
|
||
|
}
|
||
|
} );
|
||
|
|
||
|
/*
|
||
|
* Run script
|
||
|
*/
|
||
|
var scriptLnk = $('<a href="#">Run script</a>');
|
||
|
scriptLnk.bind('click', function(event) {
|
||
|
// Get node that was checked
|
||
|
var tgtNodes = '';
|
||
|
var nodes = $('#nodesDataTable input[type=checkbox]:checked');
|
||
|
for ( var i = 0; i < nodes.length; i++) {
|
||
|
tgtNodes += nodes.eq(i).attr('name');
|
||
|
|
||
|
// Add a comma in front of each node
|
||
|
if (i < nodes.length - 1) {
|
||
|
tgtNodes += ',';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Load script page
|
||
|
if (tgtNodes) {
|
||
|
loadScriptPage(tgtNodes);
|
||
|
}
|
||
|
} );
|
||
|
|
||
|
/*
|
||
|
* Update node
|
||
|
*/
|
||
|
var updateLnk = $('<a href="#">Update</a>');
|
||
|
updateLnk.bind('click', function(event) {
|
||
|
// Get node that was checked
|
||
|
var tgtNodes = '';
|
||
|
var nodes = $('#nodesDataTable input[type=checkbox]:checked');
|
||
|
for ( var i = 0; i < nodes.length; i++) {
|
||
|
tgtNodes += nodes.eq(i).attr('name');
|
||
|
|
||
|
// Add a comma in front of each node
|
||
|
if (i < nodes.length - 1) {
|
||
|
tgtNodes += ',';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// TODO: Load update page
|
||
|
if (tgtNodes) {
|
||
|
|
||
|
}
|
||
|
} );
|
||
|
|
||
|
/*
|
||
|
* Set boot state
|
||
|
*/
|
||
|
var setBootStateLnk = $('<a href="#">Set boot state</a>');
|
||
|
setBootStateLnk.bind('click', function(event) {
|
||
|
// Get node that was checked
|
||
|
var nodes = $('#nodesDataTable input[type=checkbox]:checked');
|
||
|
for ( var i = 0; i < nodes.length; i++) {
|
||
|
// Get node that was checked
|
||
|
var tgtNodes = '';
|
||
|
var nodes = $('#nodesDataTable input[type=checkbox]:checked');
|
||
|
for ( var i = 0; i < nodes.length; i++) {
|
||
|
tgtNodes += nodes.eq(i).attr('name');
|
||
|
|
||
|
// Add a comma in front of each node
|
||
|
if (i < nodes.length - 1) {
|
||
|
tgtNodes += ',';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Load nodeset page
|
||
|
if (tgtNodes) {
|
||
|
loadNodesetPage(tgtNodes);
|
||
|
}
|
||
|
}
|
||
|
} );
|
||
|
|
||
|
/*
|
||
|
* Boot to network
|
||
|
*/
|
||
|
var boot2NetworkLnk = $('<a href="#">Boot to network</a>');
|
||
|
boot2NetworkLnk.bind('click', function(event) {
|
||
|
// Get node that was checked
|
||
|
var nodes = $('#nodesDataTable input[type=checkbox]:checked');
|
||
|
for ( var i = 0; i < nodes.length; i++) {
|
||
|
// Get node that was checked
|
||
|
var mgt;
|
||
|
var tgtNodes = '';
|
||
|
var nodes = $('#nodesDataTable input[type=checkbox]:checked');
|
||
|
for ( var i = 0; i < nodes.length; i++) {
|
||
|
tgtNodes += nodes.eq(i).attr('name');
|
||
|
|
||
|
// Add a comma in front of each node
|
||
|
if (i < nodes.length - 1) {
|
||
|
tgtNodes += ',';
|
||
|
}
|
||
|
|
||
|
var node = nodes.eq(i).attr('name');
|
||
|
mgt = getNodeMgt(node);
|
||
|
}
|
||
|
|
||
|
// Load nodeset page
|
||
|
if (tgtNodes) {
|
||
|
if (mgt == 'zvm') {
|
||
|
loadZNetbootPage(tgtNodes);
|
||
|
} else {
|
||
|
// TODO: Add boot to network for other platforms
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} );
|
||
|
|
||
|
/*
|
||
|
* Advanced
|
||
|
*/
|
||
|
var advancedLnk = $('<a href="#">Advanced</a>');
|
||
|
|
||
|
// Power actions
|
||
|
var powerActions = [ powerOnLnk, powerOffLnk ];
|
||
|
var powerActionMenu = createMenu(powerActions);
|
||
|
|
||
|
// Advanced actions
|
||
|
var 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);
|
||
|
|
||
|
/*
|
||
|
* Select all or none
|
||
|
*/
|
||
|
var selectDIV = $('<div></div>');
|
||
|
actionBar.append(selectDIV);
|
||
|
|
||
|
var selectLabel = $('<span>Select: </span>');
|
||
|
var selectAllLnk = $('<span><a href="#">All</a></span>');
|
||
|
selectAllLnk.bind('click', function(event) {
|
||
|
// Check all nodes
|
||
|
var nodes = $('#nodesDataTable input[type=checkbox]');
|
||
|
nodes.attr('checked', true);
|
||
|
});
|
||
|
|
||
|
var selectNoneLnk = $('<span><a href="#">None</a></span>');
|
||
|
selectNoneLnk.bind('click', function(event) {
|
||
|
// Check no nodes
|
||
|
var nodes = $('#nodesDataTable input[type=checkbox]');
|
||
|
nodes.attr('checked', false);
|
||
|
});
|
||
|
|
||
|
selectDIV.append(selectLabel);
|
||
|
selectDIV.append(selectAllLnk);
|
||
|
selectDIV.append(selectNoneLnk);
|
||
|
|
||
|
$('#nodesTab').append(actionBar);
|
||
|
|
||
|
// Insert table
|
||
|
$('#nodesTab').append(dTable.object());
|
||
|
|
||
|
// Turn table into a datatable
|
||
|
var myDataTable = $('#nodesDataTable').dataTable();
|
||
|
setNodesDataTable(myDataTable);
|
||
|
|
||
|
/**
|
||
|
* 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
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* Only for zVM
|
||
|
*/
|
||
|
|
||
|
// Get the index of the HCP column
|
||
|
var i = $.inArray('hcp', sorted);
|
||
|
if (i) {
|
||
|
var rows = dTable.object().find('tbody tr');
|
||
|
|
||
|
// Get HCP
|
||
|
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('.');
|
||
|
|
||
|
// Get disk pools
|
||
|
$.ajax( {
|
||
|
url : 'lib/cmd.php',
|
||
|
dataType : 'json',
|
||
|
data : {
|
||
|
cmd : 'lsvm',
|
||
|
tgt : args[0],
|
||
|
args : '--diskpoolnames',
|
||
|
msg : args[0]
|
||
|
},
|
||
|
|
||
|
success : setDiskPoolCookies
|
||
|
});
|
||
|
|
||
|
// Get network names
|
||
|
$.ajax( {
|
||
|
url : 'lib/cmd.php',
|
||
|
dataType : 'json',
|
||
|
data : {
|
||
|
cmd : 'lsvm',
|
||
|
tgt : args[0],
|
||
|
args : '--getnetworknames',
|
||
|
msg : args[0]
|
||
|
},
|
||
|
|
||
|
success : setNetworkCookies
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load the power status for each node
|
||
|
*
|
||
|
* @param data
|
||
|
* Data returned from HTTP request
|
||
|
* @return Nothing
|
||
|
*/
|
||
|
function loadPowerStatus(data) {
|
||
|
// Get datatable
|
||
|
var dTable = getNodesDataTable();
|
||
|
|
||
|
// Power state of each node
|
||
|
// where power[0] = nodeName and power[1] = state
|
||
|
var power = data.rsp;
|
||
|
|
||
|
var row, rowPos;
|
||
|
var node, nodeLink;
|
||
|
var status, statusLink;
|
||
|
var args;
|
||
|
|
||
|
// Get all nodes within the datatable
|
||
|
var rows = dTable.fnGetNodes();
|
||
|
|
||
|
for ( var i in power) {
|
||
|
args = power[i].split(':');
|
||
|
|
||
|
// Update the power status column
|
||
|
node = jQuery.trim(args[0]);
|
||
|
status = jQuery.trim(args[1]);
|
||
|
|
||
|
// Get the row containing the node
|
||
|
row = getNodeRow(node, rows);
|
||
|
rowPos = dTable.fnGetPosition(row);
|
||
|
dTable.fnUpdate(status, rowPos, 3);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load the ping status for each node
|
||
|
*
|
||
|
* @param data
|
||
|
* Data returned from HTTP request
|
||
|
* @return Nothing
|
||
|
*/
|
||
|
function loadPingStatus(data) {
|
||
|
// Get data table
|
||
|
var dTable = getNodesDataTable();
|
||
|
|
||
|
// Power state of each node
|
||
|
// where ping[0] = nodeName ping[1] = state
|
||
|
var ping = data.rsp;
|
||
|
|
||
|
var row, rowPos;
|
||
|
var node, nodeLink;
|
||
|
var status, statusLink;
|
||
|
var args;
|
||
|
|
||
|
// Get all nodes within the datatable
|
||
|
var rows = dTable.fnGetNodes();
|
||
|
for ( var i in ping) {
|
||
|
args = ping[i][0];
|
||
|
|
||
|
// Update the power status column
|
||
|
node = jQuery.trim(ping[i][0]);
|
||
|
status = jQuery.trim(ping[i][1]);
|
||
|
|
||
|
// Get the row containing the node
|
||
|
row = getNodeRow(node, rows);
|
||
|
rowPos = dTable.fnGetPosition(row);
|
||
|
|
||
|
// Update the power status column
|
||
|
status = jQuery.trim(ping[i][1]);
|
||
|
dTable.fnUpdate(status, rowPos, 2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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 = getNodeMgt(node);
|
||
|
|
||
|
// Get tab area where a new tab will be inserted
|
||
|
var myTab = getNodesTab();
|
||
|
var newTabId = node + 'Tab';
|
||
|
|
||
|
/**
|
||
|
* Only for zVM
|
||
|
*/
|
||
|
if (mgt == 'zvm') {
|
||
|
// Reset node process
|
||
|
$.cookie(node + 'Processes', 0);
|
||
|
|
||
|
// Add new tab, only if one does not exist
|
||
|
if (!$('#' + newTabId).length) {
|
||
|
var loader = createLoader(node + 'TabLoader');
|
||
|
loader = $('<center></center>').append(loader);
|
||
|
myTab.add(newTabId, node, loader);
|
||
|
|
||
|
// 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 : loadZInventory
|
||
|
});
|
||
|
}
|
||
|
} else {
|
||
|
// Add new tab, only if one does not exist
|
||
|
if (!$('#' + newTabId).length) {
|
||
|
var p = $('<p>No supported</p>');
|
||
|
myTab.add(newTabId, node, p);
|
||
|
|
||
|
// TODO: Add inventory for other platforms
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Select new tab
|
||
|
myTab.select(newTabId);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Unlock a node by exchanging the SSH keys between the xCAT MN and the target
|
||
|
* node
|
||
|
*
|
||
|
* @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 exchange its SSH keys');
|
||
|
unlockForm.append(infoBar);
|
||
|
|
||
|
unlockForm
|
||
|
.append('<div><label>Node range:</label><input type="text" id="node" name="node" readonly="readonly" value="' + tgtNodes + '"/></div>');
|
||
|
unlockForm
|
||
|
.append('<div><label>Password:</label><input type="password" id="password" name="password"/></div>');
|
||
|
|
||
|
/**
|
||
|
* Ok
|
||
|
*/
|
||
|
var okBtn = createButton('Ok');
|
||
|
okBtn.bind('click', function(event) {
|
||
|
// If the form is complete
|
||
|
var ready = formComplete(newTabId);
|
||
|
if (ready) {
|
||
|
var password = $('#' + newTabId + ' input[name=password]').val();
|
||
|
|
||
|
// Exchange 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();
|
||
|
|
||
|
// Stop this function from executing again
|
||
|
// Unbind event
|
||
|
$(this).unbind(event);
|
||
|
$(this).css( {
|
||
|
'background-color' : '#F2F2F2',
|
||
|
'color' : '#BDBDBD'
|
||
|
});
|
||
|
}
|
||
|
} );
|
||
|
|
||
|
unlockForm.append(okBtn);
|
||
|
tab.add(newTabId, 'Unlock', unlockForm);
|
||
|
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');
|
||
|
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 or group:</label><input type="text" name="target" value="' + tgtNodes + '"/></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);
|
||
|
|
||
|
// 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) {
|
||
|
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);
|
||
|
|
||
|
// Stop this function from executing again
|
||
|
// Unbind event
|
||
|
$(this).unbind(event);
|
||
|
$(this).css( {
|
||
|
'background-color' : '#F2F2F2',
|
||
|
'color' : '#424242'
|
||
|
});
|
||
|
|
||
|
// Show status bar
|
||
|
statBar.show();
|
||
|
} else {
|
||
|
alert('You are missing some values');
|
||
|
}
|
||
|
});
|
||
|
scriptForm.append(runBtn);
|
||
|
|
||
|
// Append to discover tab
|
||
|
tab.add(newTabId, 'Script', scriptForm);
|
||
|
|
||
|
// Select new tab
|
||
|
tab.select(newTabId);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load nodeset page
|
||
|
*
|
||
|
* @param trgtNodes
|
||
|
* Targets to run nodeset against
|
||
|
* @return Nothing
|
||
|
*/
|
||
|
function loadNodesetPage(trgtNodes) {
|
||
|
// Get the OS images
|
||
|
$.ajax( {
|
||
|
url : 'lib/cmd.php',
|
||
|
dataType : 'json',
|
||
|
data : {
|
||
|
cmd : 'tabdump',
|
||
|
tgt : '',
|
||
|
args : 'osimage',
|
||
|
msg : ''
|
||
|
},
|
||
|
|
||
|
success : setOSImageCookies
|
||
|
});
|
||
|
|
||
|
// Get nodes tab
|
||
|
var tab = getNodesTab();
|
||
|
|
||
|
// Generate new tab ID
|
||
|
var inst = 0;
|
||
|
var tabId = 'nodesetTab' + inst;
|
||
|
while ($('#' + tabId).length) {
|
||
|
// If one already exists, generate another one
|
||
|
inst = inst + 1;
|
||
|
tabId = 'nodesetTab' + inst;
|
||
|
}
|
||
|
|
||
|
// Open new tab
|
||
|
// Create nodeset form
|
||
|
var nodesetForm = $('<div class="form"></div>');
|
||
|
|
||
|
// Create status bar
|
||
|
var barId = 'nodesetStatusBar' + inst;
|
||
|
var statusBar = createStatusBar(barId);
|
||
|
statusBar.hide();
|
||
|
nodesetForm.append(statusBar);
|
||
|
|
||
|
// Create loader
|
||
|
var loader = createLoader('nodesetLoader');
|
||
|
statusBar.append(loader);
|
||
|
|
||
|
// Create info bar
|
||
|
var infoBar = createInfoBar('Set the boot state for a node range');
|
||
|
nodesetForm.append(infoBar);
|
||
|
|
||
|
// Target node or group
|
||
|
var tgt = $('<div><label for="target">Target node or group:</label><input type="text" name="target" value="' + trgtNodes + '"/></div>');
|
||
|
nodesetForm.append(tgt);
|
||
|
|
||
|
// Boot method (boot, install, stat, iscsiboot, netboot, statelite)
|
||
|
var method = $('<div></div>');
|
||
|
var methodLabel = $('<label for="method">Boot method:</label>');
|
||
|
var methodSelect = $('<select id="bootMethod" name="bootMethod"></select>');
|
||
|
methodSelect.append('<option value="boot">boot</option>');
|
||
|
methodSelect.append('<option value="install">install</option>');
|
||
|
methodSelect.append('<option value="iscsiboot">iscsiboot</option>');
|
||
|
methodSelect.append('<option value="netboot">netboot</option>');
|
||
|
methodSelect.append('<option value="statelite">statelite</option>');
|
||
|
method.append(methodLabel);
|
||
|
method.append(methodSelect);
|
||
|
nodesetForm.append(method);
|
||
|
|
||
|
// Boot type (zvm, pxe, yaboot)
|
||
|
var type = $('<div></div>');
|
||
|
var typeLabel = $('<label for="type">Boot type:</label>');
|
||
|
var typeSelect = $('<select id="bootType" name="bootType"></select>');
|
||
|
typeSelect.append('<option value="zvm">zvm</option>');
|
||
|
typeSelect.append('<option value="install">pxe</option>');
|
||
|
typeSelect.append('<option value="iscsiboot">yaboot</option>');
|
||
|
type.append(typeLabel);
|
||
|
type.append(typeSelect);
|
||
|
nodesetForm.append(type);
|
||
|
|
||
|
// Operating system
|
||
|
var os = $('<div></div>');
|
||
|
var osLabel = $('<label for="os">Operating system:</label>');
|
||
|
var osInput = $('<input type="text" name="os"/>');
|
||
|
|
||
|
// Get the OS versions on-focus
|
||
|
var tmp;
|
||
|
osInput.focus(function() {
|
||
|
tmp = $.cookie('OSVers');
|
||
|
|
||
|
// If there are any, turn on auto-complete
|
||
|
if (tmp) {
|
||
|
$(this).autocomplete(tmp.split(','));
|
||
|
}
|
||
|
});
|
||
|
os.append(osLabel);
|
||
|
os.append(osInput);
|
||
|
nodesetForm.append(os);
|
||
|
|
||
|
// Architecture
|
||
|
var arch = $('<div></div>');
|
||
|
var archLabel = $('<label for="arch">Architecture:</label>');
|
||
|
var archInput = $('<input type="text" name="arch"/>');
|
||
|
|
||
|
// Get the OS architectures on-focus
|
||
|
archInput.focus(function() {
|
||
|
tmp = $.cookie('OSArchs');
|
||
|
|
||
|
// If there are any, turn on auto-complete
|
||
|
if (tmp) {
|
||
|
$(this).autocomplete(tmp.split(','));
|
||
|
}
|
||
|
});
|
||
|
arch.append(archLabel);
|
||
|
arch.append(archInput);
|
||
|
nodesetForm.append(arch);
|
||
|
|
||
|
// Profiles
|
||
|
var profile = $('<div></div>');
|
||
|
var profileLabel = $('<label for="profile">Profile:</label>');
|
||
|
var profileInput = $('<input type="text" name="profile"/>');
|
||
|
|
||
|
// Get the profiles on-focus
|
||
|
profileInput.focus(function() {
|
||
|
tmp = $.cookie('Profiles');
|
||
|
|
||
|
// If there are any, turn on auto-complete
|
||
|
if (tmp) {
|
||
|
$(this).autocomplete(tmp.split(','));
|
||
|
}
|
||
|
});
|
||
|
profile.append(profileLabel);
|
||
|
profile.append(profileInput);
|
||
|
nodesetForm.append(profile);
|
||
|
|
||
|
/**
|
||
|
* Ok
|
||
|
*/
|
||
|
var okBtn = createButton('Ok');
|
||
|
okBtn.bind('click', function(event) {
|
||
|
var ready = true;
|
||
|
|
||
|
// Check state, OS, arch, and profile
|
||
|
var inputs = $('#' + tabId + ' input');
|
||
|
for ( var i = 0; i < inputs.length; i++) {
|
||
|
if (!inputs.eq(i).val() && inputs.eq(i).attr('name') != 'diskPw') {
|
||
|
inputs.eq(i).css('border', 'solid #FF0000 1px');
|
||
|
ready = false;
|
||
|
} else {
|
||
|
inputs.eq(i).css('border', 'solid #BDBDBD 1px');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// If no inputs are empty
|
||
|
if (ready) {
|
||
|
// Get nodes
|
||
|
var tgts = $('#' + tabId + ' input[name=target]').val();
|
||
|
|
||
|
// Get boot method
|
||
|
var method = $('#' + tabId + ' select[id=bootMethod]').val();
|
||
|
|
||
|
// Get boot type
|
||
|
var type = $('#' + tabId + ' select[id=bootType]').val();
|
||
|
|
||
|
// Get OS, arch, and profile
|
||
|
var os = $('#' + tabId + ' input[name=os]').val();
|
||
|
var arch = $('#' + tabId + ' input[name=arch]').val();
|
||
|
var profile = $('#' + tabId + ' input[name=profile]').val();
|
||
|
|
||
|
// Stop this function from executing again
|
||
|
// Unbind event
|
||
|
$(this).unbind(event);
|
||
|
$(this).css( {
|
||
|
'background-color' : '#F2F2F2',
|
||
|
'color' : '#424242'
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* 1. Set the OS, arch, and profile
|
||
|
*/
|
||
|
$.ajax( {
|
||
|
url : 'lib/cmd.php',
|
||
|
dataType : 'json',
|
||
|
data : {
|
||
|
cmd : 'nodeadd',
|
||
|
tgt : '',
|
||
|
args : tgts + ';noderes.netboot=' + type + ';nodetype.os='
|
||
|
+ os + ';nodetype.arch=' + arch + ';nodetype.profile='
|
||
|
+ profile,
|
||
|
msg : 'cmd=nodeadd;inst=' + inst
|
||
|
},
|
||
|
|
||
|
success : updateNodesetStatus
|
||
|
});
|
||
|
|
||
|
// Show status bar
|
||
|
statusBar.show();
|
||
|
} else {
|
||
|
alert('You are missing some values');
|
||
|
}
|
||
|
});
|
||
|
nodesetForm.append(okBtn);
|
||
|
|
||
|
// Append to discover tab
|
||
|
tab.add(tabId, 'Nodeset', nodesetForm);
|
||
|
|
||
|
// Select new tab
|
||
|
tab.select(tabId);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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', '');
|
||
|
|
||
|
// Power on/off node
|
||
|
$.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 {
|
||
|
// For every 10 nodes, append a break
|
||
|
if ((i % 10) > 0) {
|
||
|
tgtNodesStr += nodes[i] + ', ';
|
||
|
} else {
|
||
|
tgtNodesStr += nodes[i] + ', <br>';
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var deleteForm = $('<div class="form"></div>');
|
||
|
deleteForm.append(statBar);
|
||
|
deleteForm.append('<p>Do you want to delete ' + tgtNodesStr + '?</p>');
|
||
|
|
||
|
/**
|
||
|
* 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();
|
||
|
|
||
|
// Stop this function from executing again
|
||
|
// Unbind event
|
||
|
$(this).unbind(event);
|
||
|
$(this).css( {
|
||
|
'background-color' : '#F2F2F2',
|
||
|
'color' : '#BDBDBD'
|
||
|
});
|
||
|
});
|
||
|
|
||
|
deleteForm.append(deleteBtn);
|
||
|
myTab.add(newTabId, 'Delete', deleteForm);
|
||
|
|
||
|
myTab.select(newTabId);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Update nodeset status
|
||
|
*
|
||
|
* @param data
|
||
|
* Data returned from HTTP request
|
||
|
* @return Nothing
|
||
|
*/
|
||
|
function updateNodesetStatus(data) {
|
||
|
var rsp = data.rsp;
|
||
|
var args = data.msg.split(';');
|
||
|
var cmd = args[0].replace('cmd=', '');
|
||
|
|
||
|
// Get nodeset instance
|
||
|
var inst = args[1].replace('inst=', '');
|
||
|
var statBarId = 'nodesetStatusBar' + inst;
|
||
|
var tabId = 'nodesetTab' + inst;
|
||
|
|
||
|
// Get nodes
|
||
|
var tgts = $('#' + tabId + ' input[name=target]').val();
|
||
|
|
||
|
// Get boot method
|
||
|
var method = $('#' + tabId + ' select[id=bootMethod]').val();
|
||
|
|
||
|
/**
|
||
|
* 2. Update /etc/hosts
|
||
|
*/
|
||
|
if (cmd == 'nodeadd') {
|
||
|
// If no output, no errors occurred
|
||
|
if (rsp.length) {
|
||
|
$('#' + statBarId).append(
|
||
|
'<p>(Error) Failed to create node definition</p>');
|
||
|
} else {
|
||
|
// Create target nodes string
|
||
|
var tgtNodesStr = '';
|
||
|
var nodes = tgts.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 {
|
||
|
// For every 10 nodes, append a break
|
||
|
if ((i % 10) > 0) {
|
||
|
tgtNodesStr += nodes[i] + ', ';
|
||
|
} else {
|
||
|
tgtNodesStr += nodes[i] + ', <br>';
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$('#' + statBarId).append(
|
||
|
'<p>Node definition created for ' + tgtNodesStr + '</p>');
|
||
|
}
|
||
|
|
||
|
// Update /etc/hosts
|
||
|
$.ajax( {
|
||
|
url : 'lib/cmd.php',
|
||
|
dataType : 'json',
|
||
|
data : {
|
||
|
cmd : 'makehosts',
|
||
|
tgt : '',
|
||
|
args : '',
|
||
|
msg : 'cmd=makehosts;inst=' + inst
|
||
|
},
|
||
|
|
||
|
success : updateNodesetStatus
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 4. Update DNS
|
||
|
*/
|
||
|
else if (cmd == 'makehosts') {
|
||
|
// If no output, no errors occurred
|
||
|
if (rsp.length) {
|
||
|
$('#' + statBarId).append(
|
||
|
'<p>(Error) Failed to update /etc/hosts</p>');
|
||
|
} else {
|
||
|
$('#' + statBarId).append('<p>/etc/hosts updated</p>');
|
||
|
}
|
||
|
|
||
|
// Update DNS
|
||
|
$.ajax( {
|
||
|
url : 'lib/cmd.php',
|
||
|
dataType : 'json',
|
||
|
data : {
|
||
|
cmd : 'makedns',
|
||
|
tgt : '',
|
||
|
args : '',
|
||
|
msg : 'cmd=makedns;inst=' + inst
|
||
|
},
|
||
|
|
||
|
success : updateNodesetStatus
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 5. Update DHCP
|
||
|
*/
|
||
|
else if (cmd == 'makedns') {
|
||
|
// Separate output into lines
|
||
|
var p = $('<p></p>');
|
||
|
for ( var i = 0; i < rsp.length; i++) {
|
||
|
if (rsp[i]) {
|
||
|
p.append(rsp[i]);
|
||
|
p.append('<br>');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$('#' + statBarId).append(p);
|
||
|
|
||
|
// Update DHCP
|
||
|
$.ajax( {
|
||
|
url : 'lib/cmd.php',
|
||
|
dataType : 'json',
|
||
|
data : {
|
||
|
cmd : 'makedhcp',
|
||
|
tgt : '',
|
||
|
args : '-a',
|
||
|
msg : 'cmd=makedhcp;inst=' + inst
|
||
|
},
|
||
|
|
||
|
success : updateNodesetStatus
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 6. Prepare node for boot
|
||
|
*/
|
||
|
else if (cmd == 'makedhcp') {
|
||
|
var failed = false;
|
||
|
|
||
|
// Separate output into lines
|
||
|
var p = $('<p></p>');
|
||
|
for ( var i = 0; i < rsp.length; i++) {
|
||
|
if (rsp[i]) {
|
||
|
// Find the node name and insert a break before it
|
||
|
rsp[i] = rsp[i].replace(new RegExp(node + ': ', 'g'), '<br>');
|
||
|
|
||
|
p.append(rsp[i]);
|
||
|
p.append('<br>');
|
||
|
|
||
|
// If the call failed
|
||
|
if (rsp[i].indexOf('Failed') > -1
|
||
|
|| rsp[i].indexOf('Error') > -1) {
|
||
|
failed = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$('#' + statBarId).append(p);
|
||
|
|
||
|
// Prepare node for boot
|
||
|
$.ajax( {
|
||
|
url : 'lib/cmd.php',
|
||
|
dataType : 'json',
|
||
|
data : {
|
||
|
cmd : 'nodeset',
|
||
|
tgt : tgts,
|
||
|
args : method,
|
||
|
msg : 'cmd=nodeset;inst=' + inst
|
||
|
},
|
||
|
|
||
|
success : updateNodesetStatus
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 7. Boot node from network
|
||
|
*/
|
||
|
else if (cmd == 'nodeset') {
|
||
|
var tgtsArray = tgts.split(',');
|
||
|
|
||
|
// Separate output into lines
|
||
|
var p = $('<p></p>');
|
||
|
for ( var i = 0; i < rsp.length; i++) {
|
||
|
if (rsp[i]) {
|
||
|
// Find the node name and insert a break before it
|
||
|
for ( var j = 0; j < tgtsArray.length; j++) {
|
||
|
rsp[i] = rsp[i].replace(new RegExp(tgtsArray[j], 'g'),
|
||
|
'<br>' + tgtsArray[j]);
|
||
|
}
|
||
|
|
||
|
p.append(rsp[i]);
|
||
|
p.append('<br>');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$('#' + statBarId).append(p);
|
||
|
|
||
|
// Hide loader
|
||
|
$('#' + statBarId).find('img').hide();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Update the status bar
|
||
|
*
|
||
|
* @param data
|
||
|
* Data returned from HTTP request
|
||
|
* @return Nothing
|
||
|
*/
|
||
|
function updateStatusBar(data) {
|
||
|
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') {
|
||
|
// Hide loader
|
||
|
$('#' + statBarId).find('img').hide();
|
||
|
|
||
|
// Separate output into lines
|
||
|
var p = $('<p></p>');
|
||
|
for ( var i = 0; i < rsp.length; i++) {
|
||
|
if (rsp[i]) {
|
||
|
p.append(rsp[i]);
|
||
|
p.append('<br>');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$('#' + statBarId).append(p);
|
||
|
} else if (cmd == 'rmvm') {
|
||
|
// Get data table
|
||
|
var dTable = getNodesDataTable();
|
||
|
var failed = false;
|
||
|
|
||
|
// Hide loader
|
||
|
$('#' + statBarId).find('img').hide();
|
||
|
|
||
|
// Separate output into lines
|
||
|
var p = $('<p></p>');
|
||
|
for ( var i = 0; i < rsp.length; i++) {
|
||
|
if (rsp[i]) {
|
||
|
// Determine if the command failed
|
||
|
if (rsp[i].indexOf("Error") > -1
|
||
|
|| rsp[i].indexOf("Failed") > -1) {
|
||
|
failed = true;
|
||
|
}
|
||
|
|
||
|
// Find the node name and insert a break before it
|
||
|
for ( var j = 0; j < tgts.length; j++) {
|
||
|
rsp[i] = rsp[i].replace(new RegExp(tgts[j] + ': ', 'g'),
|
||
|
'<br>');
|
||
|
}
|
||
|
|
||
|
p.append(rsp[i]);
|
||
|
p.append('<br>');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$('#' + statBarId).append(p);
|
||
|
|
||
|
// Update data table
|
||
|
for ( var i = 0; i < tgts.length; i++) {
|
||
|
if (!failed) {
|
||
|
// Get the row containing the node link and delete it
|
||
|
var row = $('#' + tgts[i]).parent().parent();
|
||
|
var rowPos = dTable.fnGetPosition(row.get(0));
|
||
|
dTable.fnDeleteRow(rowPos);
|
||
|
}
|
||
|
}
|
||
|
} else if (cmd == 'xdsh') {
|
||
|
// Hide loader
|
||
|
$('#' + statBarId).find('img').hide();
|
||
|
|
||
|
// Separate output into lines
|
||
|
var p = $('<p></p>');
|
||
|
for ( var i = 0; i < rsp.length; i++) {
|
||
|
if (rsp[i]) {
|
||
|
// Find the node name and insert a break before it
|
||
|
for ( var j = 0; j < tgts.length; j++) {
|
||
|
rsp[i] = rsp[i].replace(new RegExp(tgts[j], 'g'),
|
||
|
'<br>' + tgts[j]);
|
||
|
}
|
||
|
|
||
|
p.append(rsp[i]);
|
||
|
p.append('<br>');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$('#' + statBarId).append(p);
|
||
|
} else {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check the completeness of the form
|
||
|
*
|
||
|
* @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 the power status of the node
|
||
|
*
|
||
|
* @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();
|
||
|
|
||
|
// Disable all fields
|
||
|
$('#' + tabId + ' input').attr('readonly', 'readonly');
|
||
|
$('#' + tabId + ' input').css( {
|
||
|
'background-color' : '#F2F2F2'
|
||
|
});
|
||
|
|
||
|
$('#' + tabId + ' textarea').attr('readonly', 'readonly');
|
||
|
$('#' + tabId + ' textarea').css( {
|
||
|
'background-color' : '#F2F2F2'
|
||
|
});
|
||
|
|
||
|
// 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 the hardware management of a given node
|
||
|
*
|
||
|
* @param node
|
||
|
* The node
|
||
|
* @return The hardware management of the node
|
||
|
*/
|
||
|
function getNodeMgt(node) {
|
||
|
// Get the row
|
||
|
var row = $('#' + node).parent().parent();
|
||
|
|
||
|
// Search for the mgt column
|
||
|
var mgtCol = row.parent().parent().find('th:contains("mgt")');
|
||
|
// Get the mgt column index
|
||
|
var mgtIndex = mgtCol.index();
|
||
|
|
||
|
// Get the mgt for the given node
|
||
|
var mgt = row.find('td:eq(' + mgtIndex + ')');
|
||
|
|
||
|
return mgt.text();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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;
|
||
|
|
||
|
// Save image names in a cookie
|
||
|
$.cookie('Groups', rsp);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the row element that contains the given node
|
||
|
*
|
||
|
* @param tgtNode
|
||
|
* Node to find
|
||
|
* @param rows
|
||
|
* Rows within the datatable
|
||
|
* @return Row element
|
||
|
*/
|
||
|
function getNodeRow(tgtNode, rows) {
|
||
|
// Get nodes datatable
|
||
|
var dTable = getNodesDataTable();
|
||
|
|
||
|
// 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;
|
||
|
}
|