/**
* Global variables
*/
var origAttrs = new Object(); // Original image attributes
var defAttrs; // Definable image attributes
var imgTableId = 'imagesDatatable'; // Images datatable ID
var softwareList = {
"rsct" : ["rsct.core.utils", "rsct.core", "src"],
"pe" : ["IBMJava2-142-ppc64-JRE", "ibm_lapi_ip_rh6p", "ibm_lapi_us_rh6p", "IBM_pe_license", "ibm_pe_rh6p", "ppe_pdb_ppc64_rh600", "sci_ppc_32bit_rh600", "sci_ppc_64bit_rh600", "vac.cmp",
"vac.lib", "vac.lic", "vacpp.cmp", "vacpp.help.pdf", "vacpp.lib", "vacpp.man", "vacpp.rte", "vacpp.rte.lnk", "vacpp.samples", "xlf.cmp", "xlf.help.pdf", "xlf.lib", "xlf.lic", "xlf.man",
"xlf.msg.rte", "xlf.rte", "xlf.rte.lnk", "xlf.samples", "xlmass.lib", "xlsmp.lib", "xlsmp.msg.rte", "xlsmp.rte"],
"gpfs" : ["gpfs.base", "gpfs.gpl", "gpfs.gplbin", "gpfs.msg.en_US"],
"essl" : ["essl.3232.rte", "essl.3264.rte", "essl.6464.rte", "essl.common", "essl.license", "essl.man", "essl.msg", "essl.rte", "ibm-java2", "pessl.common", "pessl.license", "pessl.man",
"pessl.msg", "pessl.rte.ppe"],
"loadl" : ["IBMJava2", "LoadL-full-license-RH6", "LoadL-resmgr-full-RH6", "LoadL-scheduler-full-RH6"],
"ganglia" : ["rrdtool", "ganglia", "ganglia-gmetad", "ganglia-gmond"],
"base" : ["createrepo"]
};
/**
* Load images page
*/
function loadImagesPage() {
// Set padding for images page
$('#imagesTab').css('padding', '20px 60px');
// Get images within the database
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'lsdef',
tgt : '',
args : '-t;osimage;-l',
msg : ''
},
success : loadImages
});
}
/**
* Load images within the database
*
* @param data Data returned from HTTP request
*/
function loadImages(data) {
// Data returned
var rsp = data.rsp;
// Image attributes hash
var attrs = new Object();
// Image attributes
var headers = new Object();
// Clear hash table containing image attributes
origAttrs = '';
var image;
var args;
for (var i in rsp) {
// Get the image
var pos = rsp[i].indexOf('Object name:');
if (pos > -1) {
var temp = rsp[i].split(': ');
image = jQuery.trim(temp[1]);
// Create a hash for the image attributes
attrs[image] = 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[image][key] = val;
headers[key] = 1;
}
// Save attributes in hash table
origAttrs = attrs;
// Sort headers
var sorted = new Array();
for (var key in headers) {
sorted.push(key);
}
sorted.sort();
// Add column for check box and image name
sorted.unshift('', 'imagename');
// Create a datatable
var dTable = new DataTable(imgTableId);
dTable.init(sorted);
// Go through each image
for (var img in attrs) {
// Create a row
var row = new Array();
// Create a check box
var checkBx = '';
// Push in checkbox and image name
row.push(checkBx, img);
// Go through each header
for (var i = 2; i < sorted.length; i++) {
// Add the node attributes to the row
var key = sorted[i];
var val = attrs[img][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
$('#imagesTab').children().remove();
// Create info bar for images tab
var info = createInfoBar('Double click on a cell to edit. Click outside the table to save changes. Hit the Escape key to ignore changes.');
$('#imagesTab').append(info);
/**
* The following actions are available for images:
* copy Linux distribution and edit image properties
*/
// Copy CD into install directory
var copyCDLnk = $('Copy CD');
copyCDLnk.click(function() {
openCopyCdDialog();
});
// Generate stateless or statelite image
var generateLnk = $('Generate image');
generateLnk.click(function() {
loadCreateImage();
});
// Edit image attributes
var editLnk = $('Edit');
editLnk.click(function() {
var tgtImages = getNodesChecked(imgTableId).split(',');
if (tgtImages) {
for (var i in tgtImages) {
openEditImagePage(tgtImages[i]);
}
}
});
// Add a row
var addLnk = $('Add');
addLnk.click(function() {
openAddImageDialog();
});
// Remove a row
var removeLnk = $('Remove');
removeLnk.click(function() {
var images = getNodesChecked(imgTableId);
if (images) {
confirmImageDeleteDialog(images);
}
});
// Refresh image table
var refreshLnk = $('Refresh');
refreshLnk.click(function() {
// Get images within the database
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'lsdef',
tgt : '',
args : '-t;osimage;-l',
msg : ''
},
success : loadImages
});
});
// Insert table
$('#imagesTab').append(dTable.object());
// Turn table into a datatable
var myDataTable = $('#' + imgTableId).dataTable({
'iDisplayLength': 50,
'bLengthChange': false,
"sScrollX": "100%",
"bAutoWidth": true,
"fnInitComplete": function() {
adjustColumnSize(imgTableId);
}
});
// Set datatable width
$('#' + imgTableId + '_wrapper').css({
'width': '880px'
});
// Actions
var actionBar = $('
');
var advancedLnk = 'Advanced';
var advancedMenu = createMenu([copyCDLnk, generateLnk]);
// Create an action menu
var actionsMenu = createMenu([refreshLnk, addLnk, editLnk, removeLnk, [advancedLnk, advancedMenu]]);
actionsMenu.superfish();
actionsMenu.css('display', 'inline-block');
actionBar.append(actionsMenu);
// Set correct theme for action menu
actionsMenu.find('li').hover(function() {
setMenu2Theme($(this));
}, function() {
setMenu2Normal($(this));
});
// Create a division to hold actions menu
var menuDiv = $('');
$('#' + imgTableId + '_wrapper').prepend(menuDiv);
menuDiv.append(actionBar);
$('#' + imgTableId + '_filter').appendTo(menuDiv);
/**
* Enable editable columns
*/
// Do not make 1st column editable
$('#' + imgTableId + ' td:not(td:nth-child(1))').editable(
function(value, settings) {
// Get column index
var colPos = this.cellIndex;
// Get row index
var dTable = $('#' + imgTableId).dataTable();
var rowPos = dTable.fnGetPosition(this.parentNode);
// Update datatable
dTable.fnUpdate(value, rowPos, colPos);
// Get image name
var image = $(this).parent().find('td:eq(1)').text();
// Get table headers
var headers = $('#' + imgTableId).parents('.dataTables_scroll').find('.dataTables_scrollHead thead tr:eq(0) th');
// Get attribute name
var attrName = jQuery.trim(headers.eq(colPos).text());
// Get column value
var value = $(this).text();
// Build argument
var args = attrName + '=' + value;
// Send command to change image attributes
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'chdef',
tgt : '',
args : '-t;osimage;-o;' + image + ';' + args,
msg : 'out=imagesTab;tgt=' + image
},
success: showChdefOutput
});
return value;
}, {
onblur : 'submit', // Clicking outside editable area submits changes
type : 'textarea', // Input type to use
placeholder: ' ',
event : "dblclick", // Double click and edit
height : '30px' // The height of the text area
});
// Get definable node attributes
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'lsdef',
tgt : '',
args : '-t;osimage;-h',
msg : ''
},
success : setImageDefAttrs
});
}
/**
* Open dialog to confirm deleting image
*
* @param images Comma delimited image names
*/
function confirmImageDeleteDialog(images) {
// Make images list more readable
var dialogId = 'confirmImageRemove';
var tmp = images.replace(new RegExp(',', 'g'), ', ');
var confirmDialog = $('
'
+ '
Are you sure you want to remove ' + tmp + '?
'
+ '
');
// Open dialog to confirm delete
confirmDialog.dialog({
modal: true,
close: function(){
$(this).remove();
},
title: 'Confirm',
width: 500,
buttons: {
"Ok": function(){
// Change dialog buttons
$(this).dialog('option', 'buttons', {
'Close': function() {$(this).dialog("close");}
});
// Add image to xCAT
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'rmdef',
tgt : '',
args : '-t;osimage;-o;' + images,
msg : dialogId
},
success : updateImageDialog
});
},
"Cancel": function(){
$(this).dialog("close");
}
}
});
}
/**
* Open a dialog to add an image
*/
function openAddImageDialog() {
// Create dialog to add image
var dialogId = 'addImage';
var addImageForm = $('');
// Create info bar
var info = createInfoBar('Provide the following attributes for the image. The image name will be generated based on the attributes you will give.');
addImageForm.append(info);
// Create inputs for image attributes
var imageName = $('');
var imageType = $('');
var architecture = $('');
var osName = $('');
var osVersion = $('');
var profile = $('');
var provisionMethod = $('');
var provisionSelect = $('');
provisionMethod.append(provisionSelect);
// Create inputs for optional attributes
var exList = $('');
var exListInput = $('');
exList.append(exListInput);
exListInput.serverBrowser({
onSelect : function(path) {
$('#addImage input[name="exlist"]').val(path);
},
onLoad : function() {
return $('#addImage input[name="exlist"]').val();
},
knownPaths : [{
text : 'Install',
image : 'desktop.png',
path : '/install'
}],
imageUrl : 'images/serverbrowser/',
systemImageUrl : 'images/serverbrowser/',
handlerUrl : 'lib/getpath.php',
title : 'Browse',
requestMethod : 'POST',
width : '500',
height : '300',
basePath : '/install' // Limit user to only install directory
});
var otherpkgDirectory = $('');
var otherpkgDirectoryInput = $('');
otherpkgDirectory.append(otherpkgDirectoryInput);
otherpkgDirectoryInput.serverBrowser({
onSelect : function(path) {
$('#addImage input[name="otherpkgdir"]').val(path);
},
onLoad : function() {
return $('#addImage input[name="otherpkgdir"]').val();
},
knownPaths : [{
text : 'Install',
image : 'desktop.png',
path : '/install'
}],
imageUrl : 'images/serverbrowser/',
systemImageUrl : 'images/serverbrowser/',
handlerUrl : 'lib/getpath.php',
title : 'Browse',
requestMethod : 'POST',
width : '500',
height : '300',
basePath : '/install' // Limit user to only install directory
});
var packageDirectory = $('');
var packageDirectoryInput = $('');
packageDirectory.append(packageDirectoryInput);
packageDirectoryInput.serverBrowser({
onSelect : function(path) {
$('#addImage input[name="pkgdir"]').val(path);
},
onLoad : function() {
return $('#addImage input[name="pkgdir"]').val();
},
knownPaths : [{
text : 'Install',
image : 'desktop.png',
path : '/install'
}],
imageUrl : 'images/serverbrowser/',
systemImageUrl : 'images/serverbrowser/',
handlerUrl : 'lib/getpath.php',
title : 'Browse',
requestMethod : 'POST',
width : '500',
height : '300',
basePath : '/install' // Limit user to only install directory
});
var packageList = $('');
var packageListInput = $('');
packageList.append(packageListInput);
packageListInput.serverBrowser({
onSelect : function(path) {
$('#addImage input[name="pkglist"]').val(path);
},
onLoad : function() {
return $('#addImage input[name="pkglist"]').val();
},
knownPaths : [{
text : 'Install',
image : 'desktop.png',
path : '/install'
}],
imageUrl : 'images/serverbrowser/',
systemImageUrl : 'images/serverbrowser/',
handlerUrl : 'lib/getpath.php',
title : 'Browse',
requestMethod : 'POST',
width : '500',
height : '300',
basePath : '/install' // Limit user to only install directory
});
var postInstall = $('');
var postInstallInput = $('');
postInstall.append(postInstallInput);
postInstallInput.serverBrowser({
onSelect : function(path) {
$('#addImage input[name="postinstall"]').val(path);
},
onLoad : function() {
return $('#addImage input[name="postinstall"]').val();
},
knownPaths : [{
text : 'Install',
image : 'desktop.png',
path : '/install'
}],
imageUrl : 'images/serverbrowser/',
systemImageUrl : 'images/serverbrowser/',
handlerUrl : 'lib/getpath.php',
title : 'Browse',
requestMethod : 'POST',
width : '500',
height : '300',
basePath : '/install' // Limit user to only install directory
});
var template = $('');
var templateInput = $('');
template.append(templateInput);
templateInput.serverBrowser({
onSelect : function(path) {
$('#addImage input[name="template"]').val(path);
},
onLoad : function() {
return $('#addImage input[name="template"]').val();
},
knownPaths : [{
text : 'Install',
image : 'desktop.png',
path : '/install'
}],
imageUrl : 'images/serverbrowser/',
systemImageUrl : 'images/serverbrowser/',
handlerUrl : 'lib/getpath.php',
title : 'Browse',
requestMethod : 'POST',
width : '500',
height : '300',
basePath : '/install' // Limit user to only install directory
});
addImageForm.append(imageName, imageType, architecture, osName, osVersion, profile, provisionMethod,
exList, otherpkgDirectory, packageDirectory, packageList, postInstall, template);
// Open dialog to add image
addImageForm.dialog({
title:'Add image',
modal: true,
close: function(){
$(this).remove();
},
width: 400,
buttons: {
"Ok": function(){
// Remove any warning messages
$(this).find('.ui-state-error').remove();
// Get image attributes
var imageType = $(this).find('input[name="imagetype"]');
var architecture = $(this).find('input[name="osarch"]');
var osName = $(this).find('input[name="osname"]');
var osVersion = $(this).find('input[name="osvers"]');
var profile = $(this).find('input[name="profile"]');
var provisionMethod = $(this).find('select[name="provmethod"]');
// Get optional image attributes
var exList = $(this).find('input[name="exlist"]');
var otherpkgDirectory = $(this).find('input[name="otherpkgdir"]');
var pkgDirectory = $(this).find('input[name="pkgdir"]');
var pkgList = $(this).find('input[name="pkglist"]');
var postInstall = $(this).find('input[name="postinstall"]');
var template = $(this).find('input[name="template"]');
// Check that image attributes are provided before continuing
var ready = 1;
var inputs = new Array(imageType, architecture, osName, osVersion, profile, provisionMethod);
for (var i in inputs) {
if (!inputs[i].val()) {
inputs[i].css('border-color', 'red');
ready = 0;
} else
inputs[i].css('border-color', '');
}
// If inputs are not complete, show warning message
if (!ready) {
var warn = createWarnBar('Please provide a value for each missing field.');
warn.prependTo($(this));
} else {
// Override image name
$(this).find('input[name="imagename"]').val(osVersion.val() + '-' + architecture.val() + '-' + provisionMethod.val() + '-' + profile.val());
var imageName = $(this).find('input[name="imagename"]');
// Change dialog buttons
$(this).dialog('option', 'buttons', {
'Close': function() {$(this).dialog("close");}
});
// Create arguments to send via AJAX
var args = '-t;osimage;-o;' + imageName.val() + ';' +
'imagetype=' + imageType.val() + ';' +
'osarch=' + architecture.val() + ';' +
'osname=' + osName.val() + ';' +
'osvers=' + osVersion.val() + ';' +
'profile=' + profile.val() + ';' +
'provmethod=' + provisionMethod.val();
// Get optional attributes
if (exList.val())
args += ';exlist=' + exList.val();
if (otherpkgDirectory.val())
args += ';otherpkgdir=' + otherpkgDirectory.val();
if (pkgDirectory.val())
args += ';pkgdir=' + pkgDirectory.val();
if (pkgList.val())
args += ';pkglist=' + pkgList.val();
if (postInstall.val())
args += ';postinstall=' + postInstall.val();
if (template.val())
args += ';template=' + template.val();
// Add image to xCAT
$.ajax( {
url : 'lib/cmd.php',
dataType : 'json',
data : {
cmd : 'chdef',
tgt : '',
args : args,
msg : dialogId
},
success : updateImageDialog
});
}
},
"Cancel": function() {
$(this).dialog( "close" );
}
}
});
}
/**
* Update image dialog
*
* @param data HTTP request data
*/
function updateImageDialog(data) {
var dialogId = data.msg;
var infoMsg;
// Delete loader if one does exist
$('.ui-dialog #' + dialogId + ' img[src="images/loader.gif"]').remove();
// Create info message
if (jQuery.isArray(data.rsp)) {
infoMsg = '';
// If the data returned is more than 10 lines, get only the last line
var i, start;
if (data.rsp.length > 10)
start = data.rsp.length - 1;
else
start = 0;
for (i = start; i < data.rsp.length; i++)
infoMsg += data.rsp[i] + '';
} else {
infoMsg = data.rsp;
}
// Create info bar with close button
var infoBar = $('').css('margin', '5px 0px');
var icon = $('').css({
'display': 'inline-block',
'margin': '10px 5px'
});
// Create close button to close info bar
var close = $('').css({
'display': 'inline-block',
'float': 'right'
}).click(function() {
$(this).parent().remove();
});
var msg = $('
' + infoMsg + '
').css({
'display': 'inline-block',
'width': '90%'
});
infoBar.append(icon, msg, close);
infoBar.prependTo($('.ui-dialog #' + dialogId));
}
/**
* Set definable image attributes
*
* @param data Data returned from HTTP request
*/
function setImageDefAttrs(data) {
// Clear hash table containing definable image attributes
defAttrs = new Array();
// Get definable attributes
var attrs = data.rsp[2].split(/\n/);
// Go through each line
var attr, key, descr;
for (var i in attrs) {
attr = attrs[i];
// If the line is not empty
if (attr) {
// If the line has the attribute name
if (attr.indexOf(':') && attr.indexOf(' ')) {
// Get attribute name and description
key = jQuery.trim(attr.substring(0, attr.indexOf(':')));
descr = jQuery.trim(attr.substring(attr.indexOf(':') + 1));
descr = descr.replace(new RegExp('<', 'g'), '[').replace(new RegExp('>', 'g'), ']');
// Set hash table where key = attribute name and value = description
defAttrs[key] = descr;
} else {
// Append description to hash table
defAttrs[key] = defAttrs[key] + '\n' + attr.replace(new RegExp('<', 'g'), '[').replace(new RegExp('>', 'g'), ']');
}
} // End of if
} // End of for
}
/**
* Load create image page
*/
function loadCreateImage() {
// Get nodes tab
var tab = getProvisionTab();
var tabId = 'createImageTab';
// Generate new tab ID
if ($('#' + tabId).size()) {
tab.select(tabId);
return;
}
var imageOsVers = $.cookie("osvers").split(",");
var imageArch = $.cookie("osarchs").split(",");
var profiles = $.cookie("profiles").split(",");
var createImgForm = $('');
var createImgFS = $('').append('');
createImgForm.append(createImgFS);
// Show info bar
var infoBar = createInfoBar('Specify the parameters for the image (stateless or statelite) you want to create, then click Create.');
createImgFS.append(infoBar);
// Drop down for OS versions
var osVerSelect = $('');
for (var i in imageOsVers)
osVerSelect.append('');
createImgFS.append($('').append(osVerSelect));
// Drop down for OS architectures
var imgSelect = $('');
for (var i in imageArch)
imgSelect.append('');
createImgFS.append($('').append(imgSelect));
// Netboot interface input
createImgFS.append($(''));
// Profile selector
var profileSelect = $('