/** * 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; }