23b37343b2
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@15061 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
2661 lines
103 KiB
JavaScript
2661 lines
103 KiB
JavaScript
/**
|
|
* Execute when the DOM is fully loaded
|
|
*/
|
|
$(document).ready(function() {
|
|
// Load utility scripts
|
|
includeJs("js/custom/zvmUtils.js");
|
|
});
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
var zvmPlugin = function() {
|
|
|
|
};
|
|
|
|
/**
|
|
* Configure self-service configure page
|
|
*/
|
|
zvmPlugin.prototype.loadConfigPage = function(tabId) {
|
|
var configAccordion = $('<div id="zvmConfigAccordion"></div>');
|
|
|
|
// Create accordion panel for profiles
|
|
var profileSection = $('<div id="zvmConfigProfile"></div>');
|
|
var profileLnk = $('<h3><a href="#">Profiles</a></h3>').click(function () {
|
|
// Do not load panel again if it is already loaded
|
|
if ($('#zvmConfigProfile').find('.dataTables_wrapper').length)
|
|
return;
|
|
else
|
|
$('#zvmConfigProfile').append(createLoader(''));
|
|
|
|
queryProfiles('zvmConfigProfile');
|
|
});
|
|
|
|
// Create accordion panel for images
|
|
var imgSection = $('<div id="zvmConfigImages"></div>');
|
|
var imgLnk = $('<h3><a href="#">Images</a></h3>').click(function () {
|
|
// Do not load panel again if it is already loaded
|
|
if ($('#zvmConfigImages').find('.dataTables_wrapper').length)
|
|
return;
|
|
else
|
|
$('#zvmConfigImages').append(createLoader(''));
|
|
|
|
queryImages('zvmConfigImages');
|
|
});
|
|
|
|
// Create accordion panel for groups
|
|
var groupsSection = $('<div id="zvmConfigGroups"></div>');
|
|
var groupsLnk = $('<h3><a href="#">Groups</a></h3>').click(function () {
|
|
// Do not load panel again if it is already loaded
|
|
if ($('#zvmConfigGroups').find('.dataTables_wrapper').length)
|
|
return;
|
|
else
|
|
$('#zvmConfigGroups').append(createLoader(''));
|
|
|
|
queryGroups('zvmConfigGroups');
|
|
});
|
|
|
|
configAccordion.append(profileLnk, profileSection, imgLnk, imgSection, groupsLnk, groupsSection);
|
|
$('#' + tabId).append(configAccordion);
|
|
configAccordion.accordion();
|
|
|
|
profileLnk.trigger('click');
|
|
};
|
|
|
|
/**
|
|
* Clone node (service page)
|
|
*
|
|
* @param node Node to clone
|
|
*/
|
|
zvmPlugin.prototype.serviceClone = function(node) {
|
|
var owner = $.cookie('xcat_username');
|
|
var group = getUserNodeAttr(node, 'groups');
|
|
|
|
// Submit request to clone VM
|
|
// webportal clonezlinux [src node] [group] [owner]
|
|
var iframe = createIFrame('lib/srv_cmd.php?cmd=webportal&tgt=&args=clonezlinux;' + node + ';' + group + ';' + owner + '&msg=&opts=flush');
|
|
iframe.prependTo($('#manageTab'));
|
|
};
|
|
|
|
/**
|
|
* Load provision page (service page)
|
|
*
|
|
* @param tabId Tab ID where page will reside
|
|
*/
|
|
zvmPlugin.prototype.loadServiceProvisionPage = function(tabId) {
|
|
// Create provision form
|
|
var provForm = $('<div></div>');
|
|
|
|
// Create info bar
|
|
var infoBar = createInfoBar('Provision a Linux virtual machine on System z by selecting the appropriate choices below. Once you are ready, click on Provision to provision the virtual machine.');
|
|
provForm.append(infoBar);
|
|
|
|
// Append to provision tab
|
|
$('#' + tabId).append(provForm);
|
|
|
|
// Create provision table
|
|
var provTable = $('<table id="select-table" style="margin: 10px;"></table');
|
|
var provHeader = $('<thead class="ui-widget-header"> <th>zVM</th> <th>Group</th> <th>Image</th></thead>');
|
|
var provBody = $('<tbody></tbody>');
|
|
var provFooter = $('<tfoot></tfoot>');
|
|
provTable.append(provHeader, provBody, provFooter);
|
|
provForm.append(provTable);
|
|
|
|
provHeader.children('th').css({
|
|
'font': 'bold 12px verdana, arial, helvetica, sans-serif'
|
|
});
|
|
|
|
// Create row to contain selections
|
|
var provRow = $('<tr></tr>');
|
|
provBody.append(provRow);
|
|
// Create columns for zVM, group, and image
|
|
var zvmCol = $('<td style="vertical-align: top;"></td>');
|
|
provRow.append(zvmCol);
|
|
var groupCol = $('<td style="vertical-align: top;"></td>');
|
|
provRow.append(groupCol);
|
|
var imageCol = $('<td style="vertical-align: top;"></td>');
|
|
provRow.append(imageCol);
|
|
|
|
provRow.children('td').css({
|
|
'min-width': '250px'
|
|
});
|
|
|
|
/**
|
|
* Provision VM
|
|
*/
|
|
var provisionBtn = createButton('Provision');
|
|
provisionBtn.bind('click', function(event) {
|
|
// Remove any warning messages
|
|
$(this).parent().find('.ui-state-error').remove();
|
|
|
|
var hcp = $('#select-table tbody tr:eq(0) td:eq(0) input[name="hcp"]:checked').val();
|
|
var group = $('#select-table tbody tr:eq(0) td:eq(1) input[name="group"]:checked').val();
|
|
var img = $('#select-table tbody tr:eq(0) td:eq(2) input[name="image"]:checked').val();
|
|
var owner = $.cookie('xcat_username');
|
|
|
|
if (!hcp || !group || !img) {
|
|
// Show warning message
|
|
var warn = createWarnBar('You need to select an option for each column');
|
|
warn.prependTo($(this).parent());
|
|
} else {
|
|
// Begin by creating VM
|
|
createzVM(tabId, group, hcp, img, owner);
|
|
}
|
|
});
|
|
provForm.append(provisionBtn);
|
|
|
|
// Load zVMs, groups, and images into their respective columns
|
|
loadSrvGroups(groupCol);
|
|
loadOSImages(imageCol);
|
|
|
|
// Get zVM host names
|
|
if (!$.cookie('zvm')){
|
|
$.ajax( {
|
|
url : 'lib/srv_cmd.php',
|
|
dataType : 'json',
|
|
data : {
|
|
cmd : 'webportal',
|
|
tgt : '',
|
|
args : 'lszvm',
|
|
msg : ''
|
|
},
|
|
|
|
success : function(data) {
|
|
setzVMCookies(data);
|
|
loadzVMs(zvmCol);
|
|
}
|
|
});
|
|
} else {
|
|
loadzVMs(zvmCol);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Show node inventory (service page)
|
|
*
|
|
* @param data Data from HTTP request
|
|
*/
|
|
zvmPlugin.prototype.loadServiceInventory = function(data) {
|
|
var args = data.msg.split(',');
|
|
|
|
// Get tab ID
|
|
var tabId = args[0].replace('out=', '');
|
|
// Get node
|
|
var node = args[1].replace('node=', '');
|
|
|
|
// Remove loader
|
|
$('#' + tabId).find('img').remove();
|
|
|
|
// Do not continue if error is found
|
|
if (data.rsp[0].indexOf('Error') > -1) {
|
|
var warn = createWarnBar(data.rsp[0]);
|
|
$('#' + tabId).append(warn);
|
|
return;
|
|
}
|
|
|
|
// Get node inventory
|
|
var inv = data.rsp[0].split(node + ':');
|
|
|
|
// Create array of property keys (VM)
|
|
var keys = new Array('userId', 'host', 'os', 'arch', 'uptime', 'cpuusedtime', 'hcp', 'priv', 'memory', 'maxmemory', 'proc', 'disk', 'zfcp', 'nic');
|
|
|
|
// Create hash table for property names (VM)
|
|
var attrNames = new Object();
|
|
attrNames['userId'] = 'z/VM UserID:';
|
|
attrNames['host'] = 'z/VM Host:';
|
|
attrNames['os'] = 'Operating System:';
|
|
attrNames['arch'] = 'Architecture:';
|
|
attrNames['uptime'] = 'Uptime:';
|
|
attrNames['cpuusedtime'] = 'CPU Used Time:';
|
|
attrNames['hcp'] = 'HCP:';
|
|
attrNames['priv'] = 'Privileges:';
|
|
attrNames['memory'] = 'Total Memory:';
|
|
attrNames['maxmemory'] = 'Max Memory:';
|
|
attrNames['proc'] = 'Processors:';
|
|
attrNames['disk'] = 'Disks:';
|
|
attrNames['zfcp'] = 'zFCP:';
|
|
attrNames['nic'] = 'NICs:';
|
|
|
|
// Create hash table for node attributes
|
|
var attrs = getAttrs(keys, attrNames, inv);
|
|
|
|
// Create division to hold inventory
|
|
var invDivId = node + 'Inventory';
|
|
var invDiv = $('<div class="inventory" id="' + invDivId + '"></div>');
|
|
|
|
var infoBar = createInfoBar('Below is the inventory for the virtual machine you selected.');
|
|
invDiv.append(infoBar);
|
|
|
|
/**
|
|
* General info section
|
|
*/
|
|
var fieldSet = $('<fieldset></fieldset>');
|
|
var legend = $('<legend>General</legend>');
|
|
fieldSet.append(legend);
|
|
var oList = $('<ol></ol>');
|
|
var item, label, args;
|
|
|
|
// Loop through each property
|
|
for ( var k = 0; k < 5; k++) {
|
|
// Create a list item for each property
|
|
item = $('<li></li>');
|
|
|
|
// Create a label - Property name
|
|
label = $('<label>' + attrNames[keys[k]] + '</label>');
|
|
item.append(label);
|
|
|
|
for ( var l = 0; l < attrs[keys[k]].length; l++) {
|
|
// Create a input - Property value(s)
|
|
// Handle each property uniquely
|
|
item.append(attrs[keys[k]][l]);
|
|
}
|
|
|
|
oList.append(item);
|
|
}
|
|
// Append to inventory form
|
|
fieldSet.append(oList);
|
|
invDiv.append(fieldSet);
|
|
|
|
/**
|
|
* Monitoring section
|
|
*/
|
|
fieldSet = $('<fieldset id="' + node + '_monitor"></fieldset>');
|
|
legend = $('<legend>Monitoring [<a style="font-weight: normal; color: blue; text-decoration: none;">Refresh</a>]</legend>');
|
|
fieldSet.append(legend);
|
|
// var info = createInfoBar('No data available');
|
|
// fieldSet.append(info.css('width', '300px'));
|
|
|
|
getMonitorMetrics(node);
|
|
|
|
// Refresh monitoring charts on-click
|
|
legend.find('a').click(function() {
|
|
getMonitorMetrics(node);
|
|
});
|
|
|
|
// Append to inventory form
|
|
invDiv.append(fieldSet);
|
|
|
|
/**
|
|
* Hardware info section
|
|
*/
|
|
var hwList, hwItem;
|
|
fieldSet = $('<fieldset></fieldset>');
|
|
legend = $('<legend>Hardware</legent>');
|
|
fieldSet.append(legend);
|
|
oList = $('<ol></ol>');
|
|
|
|
// Loop through each property
|
|
var label;
|
|
for (k = 5; k < keys.length; k++) {
|
|
// Create a list item
|
|
item = $('<li></li>');
|
|
|
|
// Create a list to hold the property value(s)
|
|
hwList = $('<ul></ul>');
|
|
hwItem = $('<li></li>');
|
|
|
|
/**
|
|
* Privilege section
|
|
*/
|
|
if (keys[k] == 'priv') {
|
|
// Create a label - Property name
|
|
label = $('<label><b>' + attrNames[keys[k]].replace(':', '') + '</b></label>');
|
|
item.append(label);
|
|
|
|
// Loop through each line
|
|
for (l = 0; l < attrs[keys[k]].length; l++) {
|
|
// Create a new list item for each line
|
|
hwItem = $('<li></li>');
|
|
|
|
// Determine privilege
|
|
args = attrs[keys[k]][l].split(' ');
|
|
if (args[0] == 'Directory:') {
|
|
label = $('<label>' + args[0] + '</label>');
|
|
hwItem.append(label);
|
|
hwItem.append(args[1]);
|
|
} else if (args[0] == 'Currently:') {
|
|
label = $('<label>' + args[0] + '</label>');
|
|
hwItem.append(label);
|
|
hwItem.append(args[1]);
|
|
}
|
|
|
|
hwList.append(hwItem);
|
|
}
|
|
|
|
item.append(hwList);
|
|
}
|
|
|
|
/**
|
|
* Memory section
|
|
*/
|
|
else if (keys[k] == 'memory') {
|
|
// Create a label - Property name
|
|
label = $('<label><b>' + attrNames[keys[k]].replace(':', '') + '</b></label>');
|
|
item.append(label);
|
|
|
|
// Loop through each value line
|
|
for (l = 0; l < attrs[keys[k]].length; l++) {
|
|
// Create a new list item for each line
|
|
hwItem = $('<li></li>');
|
|
hwItem.append(attrs[keys[k]][l]);
|
|
hwList.append(hwItem);
|
|
}
|
|
|
|
item.append(hwList);
|
|
}
|
|
|
|
/**
|
|
* Processor section
|
|
*/
|
|
else if (keys[k] == 'proc') {
|
|
// Create a label - Property name
|
|
label = $('<label><b>' + attrNames[keys[k]].replace(':', '') + '</b></label>');
|
|
item.append(label);
|
|
|
|
// Create a table to hold processor data
|
|
var procTable = $('<table></table>');
|
|
var procBody = $('<tbody></tbody>');
|
|
|
|
// Table columns - Type, Address, ID, Base, Dedicated, and Affinity
|
|
var procTabRow = $('<thead class="ui-widget-header"> <th>Type</th> <th>Address</th> <th>ID</th> <th>Base</th> <th>Dedicated</th> <th>Affinity</th> </thead>');
|
|
procTable.append(procTabRow);
|
|
var procType, procAddr, procId, procAff;
|
|
|
|
// Loop through each processor
|
|
var n, temp;
|
|
for (l = 0; l < attrs[keys[k]].length; l++) {
|
|
if (attrs[keys[k]][l]) {
|
|
args = attrs[keys[k]][l].split(' ');
|
|
|
|
// Get processor type, address, ID, and affinity
|
|
n = 3;
|
|
temp = args[args.length - n];
|
|
while (!jQuery.trim(temp)) {
|
|
n = n + 1;
|
|
temp = args[args.length - n];
|
|
}
|
|
procType = $('<td>' + temp + '</td>');
|
|
procAddr = $('<td>' + args[1] + '</td>');
|
|
procId = $('<td>' + args[5] + '</td>');
|
|
procAff = $('<td>' + args[args.length - 1] + '</td>');
|
|
|
|
// Base processor
|
|
if (args[6] == '(BASE)') {
|
|
baseProc = $('<td>' + true + '</td>');
|
|
} else {
|
|
baseProc = $('<td>' + false + '</td>');
|
|
}
|
|
|
|
// Dedicated processor
|
|
if (args[args.length - 3] == 'DEDICATED') {
|
|
dedicatedProc = $('<td>' + true + '</td>');
|
|
} else {
|
|
dedicatedProc = $('<td>' + false + '</td>');
|
|
}
|
|
|
|
// Create a new row for each processor
|
|
procTabRow = $('<tr></tr>');
|
|
procTabRow.append(procType);
|
|
procTabRow.append(procAddr);
|
|
procTabRow.append(procId);
|
|
procTabRow.append(baseProc);
|
|
procTabRow.append(dedicatedProc);
|
|
procTabRow.append(procAff);
|
|
procBody.append(procTabRow);
|
|
}
|
|
}
|
|
|
|
procTable.append(procBody);
|
|
item.append(procTable);
|
|
}
|
|
|
|
/**
|
|
* Disk section
|
|
*/
|
|
else if (keys[k] == 'disk') {
|
|
// Create a label - Property name
|
|
label = $('<label><b>' + attrNames[keys[k]].replace(':', '') + '</b></label>');
|
|
item.append(label);
|
|
|
|
// Create a table to hold disk (DASD) data
|
|
var dasdTable = $('<table></table>');
|
|
var dasdBody = $('<tbody></tbody>');
|
|
|
|
// Table columns - Virtual Device, Type, VolID, Type of Access, and Size
|
|
var dasdTabRow = $('<thead class="ui-widget-header"> <th>Virtual Device #</th> <th>Type</th> <th>VolID</th> <th>Type of Access</th> <th>Size</th> </thead>');
|
|
dasdTable.append(dasdTabRow);
|
|
var dasdVDev, dasdType, dasdVolId, dasdAccess, dasdSize;
|
|
|
|
// Loop through each DASD
|
|
for (l = 0; l < attrs[keys[k]].length; l++) {
|
|
if (attrs[keys[k]][l]) {
|
|
args = attrs[keys[k]][l].split(' ');
|
|
|
|
// Get DASD virtual device, type, volume ID, access, and size
|
|
dasdVDev = $('<td>' + args[1] + '</td>');
|
|
dasdType = $('<td>' + args[2] + '</td>');
|
|
dasdVolId = $('<td>' + args[3] + '</td>');
|
|
dasdAccess = $('<td>' + args[4] + '</td>');
|
|
dasdSize = $('<td>' + args[args.length - 9] + ' ' + args[args.length - 8] + '</td>');
|
|
|
|
// Create a new row for each DASD
|
|
dasdTabRow = $('<tr></tr>');
|
|
dasdTabRow.append(dasdVDev);
|
|
dasdTabRow.append(dasdType);
|
|
dasdTabRow.append(dasdVolId);
|
|
dasdTabRow.append(dasdAccess);
|
|
dasdTabRow.append(dasdSize);
|
|
dasdBody.append(dasdTabRow);
|
|
}
|
|
}
|
|
|
|
dasdTable.append(dasdBody);
|
|
item.append(dasdTable);
|
|
}
|
|
|
|
/**
|
|
* zFCP section
|
|
*/
|
|
else if (keys[k] == 'zfcp') {
|
|
// Create a label - Property name
|
|
label = $('<label><b>' + attrNames[keys[k]].replace(':', '') + '</b></label>');
|
|
item.append(label);
|
|
|
|
// Create a table to hold NIC data
|
|
var zfcpTable = $('<table></table>');
|
|
var zfcpBody = $('<tbody></tbody>');
|
|
|
|
// Table columns - Virtual device, Adapter Type, Port Name, # of Devices, MAC Address, and LAN Name
|
|
var zfcpTabRow = $('<thead class="ui-widget-header"> <th>Virtual Device #</th> <th>Port Name</th> <th>Unit Number</th> <th>Size</th></thead>');
|
|
zfcpTable.append(zfcpTabRow);
|
|
var zfcpVDev, zfcpPortName, zfcpLun, zfcpSize;
|
|
|
|
// Loop through each zFCP device
|
|
if (attrs[keys[k]]) {
|
|
for (l = 0; l < attrs[keys[k]].length; l++) {
|
|
if (attrs[keys[k]][l]) {
|
|
args = attrs[keys[k]][l].split(' ');
|
|
|
|
// Get zFCP virtual device, port name (WWPN), unit number (LUN), and size
|
|
zfcpVDev = $('<td>' + args[1].replace('0.0.', '') + '</td>');
|
|
zfcpPortName = $('<td>' + args[4] + '</td>');
|
|
zfcpLun = $('<td>' + args[7] + '</td>');
|
|
zfcpSize = $('<td>' + args[args.length - 2] + ' ' + args[args.length - 1] + '</td>');
|
|
|
|
// Create a new row for each zFCP device
|
|
zfcpTabRow = $('<tr></tr>');
|
|
zfcpTabRow.append(zfcpVDev);
|
|
zfcpTabRow.append(zfcpPortName);
|
|
zfcpTabRow.append(zfcpLun);
|
|
zfcpTabRow.append(zfcpSize);
|
|
|
|
zfcpBody.append(zfcpTabRow);
|
|
}
|
|
}
|
|
}
|
|
|
|
zfcpTable.append(zfcpBody);
|
|
item.append(zfcpTable);
|
|
}
|
|
|
|
/**
|
|
* NIC section
|
|
*/
|
|
else if (keys[k] == 'nic') {
|
|
// Create a label - Property name
|
|
label = $('<label><b>' + attrNames[keys[k]].replace(':', '') + '</b></label>');
|
|
item.append(label);
|
|
|
|
// Create a table to hold NIC data
|
|
var nicTable = $('<table></table>');
|
|
var nicBody = $('<tbody></tbody>');
|
|
|
|
// Table columns - Virtual device, Adapter Type, Port Name, # of Devices, MAC Address, and LAN Name
|
|
var nicTabRow = $('<thead class="ui-widget-header"><th>Virtual Device #</th> <th>Adapter Type</th> <th>Port Name</th> <th># of Devices</th> <th>LAN Name</th></thead>');
|
|
nicTable.append(nicTabRow);
|
|
var nicVDev, nicType, nicPortName, nicNumOfDevs, nicLanName;
|
|
|
|
// Loop through each NIC (Data contained in 2 lines)
|
|
for (l = 0; l < attrs[keys[k]].length; l = l + 2) {
|
|
if (attrs[keys[k]][l]) {
|
|
args = attrs[keys[k]][l].split(' ');
|
|
|
|
// Get NIC virtual device, type, port name, and number of devices
|
|
nicVDev = $('<td>' + args[1] + '</td>');
|
|
nicType = $('<td>' + args[3] + '</td>');
|
|
nicPortName = $('<td>' + args[10] + '</td>');
|
|
nicNumOfDevs = $('<td>' + args[args.length - 1] + '</td>');
|
|
|
|
args = attrs[keys[k]][l + 1].split(' ');
|
|
nicLanName = $('<td>' + args[args.length - 2] + ' ' + args[args.length - 1] + '</td>');
|
|
|
|
// Create a new row for each DASD
|
|
nicTabRow = $('<tr></tr>');
|
|
nicTabRow.append(nicVDev);
|
|
nicTabRow.append(nicType);
|
|
nicTabRow.append(nicPortName);
|
|
nicTabRow.append(nicNumOfDevs);
|
|
nicTabRow.append(nicLanName);
|
|
|
|
nicBody.append(nicTabRow);
|
|
}
|
|
}
|
|
|
|
nicTable.append(nicBody);
|
|
item.append(nicTable);
|
|
}
|
|
|
|
// Ignore any fields not in key
|
|
else {
|
|
continue;
|
|
}
|
|
|
|
oList.append(item);
|
|
}
|
|
|
|
// Append inventory to division
|
|
fieldSet.append(oList);
|
|
invDiv.append(fieldSet);
|
|
invDiv.find('th').css({
|
|
'padding': '5px 10px',
|
|
'font-weight': 'bold'
|
|
});
|
|
|
|
// Append to tab
|
|
$('#' + tabId).append(invDiv);
|
|
};
|
|
|
|
/**
|
|
* Load clone page
|
|
*
|
|
* @param node Source node to clone
|
|
*/
|
|
zvmPlugin.prototype.loadClonePage = function(node) {
|
|
// Get nodes tab
|
|
var tab = getNodesTab();
|
|
var newTabId = node + 'CloneTab';
|
|
|
|
// If there is no existing clone tab
|
|
if (!$('#' + newTabId).length) {
|
|
// Get table headers
|
|
var tableId = $('#' + node).parents('table').attr('id');
|
|
var headers = $('#' + tableId).parents('.dataTables_scroll').find('.dataTables_scrollHead thead tr:eq(0) th');
|
|
var cols = new Array();
|
|
for ( var i = 0; i < headers.length; i++) {
|
|
var col = headers.eq(i).text();
|
|
cols.push(col);
|
|
}
|
|
|
|
// Get hardware control point column
|
|
var hcpCol = $.inArray('hcp', cols);
|
|
|
|
// Get hardware control point
|
|
var nodeRow = $('#' + node).parent().parent();
|
|
var datatable = $('#' + getNodesTableId()).dataTable();
|
|
var rowPos = datatable.fnGetPosition(nodeRow.get(0));
|
|
var aData = datatable.fnGetData(rowPos);
|
|
var hcp = aData[hcpCol];
|
|
|
|
// Create status bar and hide it
|
|
var statBarId = node + 'CloneStatusBar';
|
|
var statBar = createStatusBar(statBarId).hide();
|
|
|
|
// Create info bar
|
|
var infoBar = createInfoBar('Clone a zVM node.');
|
|
|
|
// Create clone form
|
|
var cloneForm = $('<div class="form"></div>');
|
|
cloneForm.append(statBar);
|
|
cloneForm.append(infoBar);
|
|
|
|
// Create VM fieldset
|
|
var vmFS = $('<fieldset></fieldset>');
|
|
var vmLegend = $('<legend>Virtual Machine</legend>');
|
|
vmFS.append(vmLegend);
|
|
cloneForm.append(vmFS);
|
|
|
|
var vmAttr = $('<div style="display: inline-table; vertical-align: middle;"></div>');
|
|
vmFS.append($('<div style="display: inline-table; vertical-align: middle;"><img src="images/provision/computer.png"></img></div>'));
|
|
vmFS.append(vmAttr);
|
|
|
|
// Create hardware fieldset
|
|
var storageFS = $('<fieldset></fieldset>');
|
|
var storageLegend = $('<legend>Storage</legend>');
|
|
storageFS.append(storageLegend);
|
|
cloneForm.append(storageFS);
|
|
|
|
var storageAttr = $('<div style="display: inline-table; vertical-align: middle;"></div>');
|
|
storageFS.append($('<div style="display: inline-table; vertical-align: middle;"><img src="images/provision/hdd.png"></img></div>'));
|
|
storageFS.append(storageAttr);
|
|
|
|
vmAttr.append('<div><label>Target node range:</label><input type="text" id="tgtNode" name="tgtNode" title="You must give a node or a node range. A node range must be given as: node1-node9 or node[1-9]."/></div>');
|
|
vmAttr.append('<div><label>Target user ID range:</label><input type="text" id="tgtUserId" name="tgtUserId" title="You must give a user ID or a user ID range. A user ID range must be given as: user1-user9 or user[1-9]."/></div>');
|
|
vmAttr.append('<div><label>Clone source:</label><input type="text" id="srcNode" name="srcNode" readonly="readonly" value="' + node + '" title="The source node to be cloned"/></div>');
|
|
vmAttr.append('<div><label>Hardware control point:</label><input type="text" id="newHcp" name="newHcp" readonly="readonly" value="' + hcp + '" title="The System z hardware control point (zHCP) responsible for managing the node(s). It must be the same as the source node."/></div>');
|
|
|
|
// Create group input
|
|
var group = $('<div></div>');
|
|
var groupLabel = $('<label>Group:</label>');
|
|
var groupInput = $('<input type="text" id="newGroup" name="newGroup" title="You must give the group where the new node(s) will be placed under."/>');
|
|
groupInput.one('focus', function(){
|
|
var groupNames = $.cookie('groups');
|
|
if (groupNames) {
|
|
// Turn on auto complete
|
|
$(this).autocomplete({
|
|
source: groupNames.split(',')
|
|
});
|
|
}
|
|
});
|
|
group.append(groupLabel);
|
|
group.append(groupInput);
|
|
vmAttr.append(group);
|
|
|
|
// Create an advanced link to set IP address and hostname
|
|
var advancedLnk = $('<div><label><a style="color: blue; cursor: pointer;">Advanced</a></label></div>');
|
|
vmAttr.append(advancedLnk);
|
|
var advanced = $('<div style="margin-left: 20px;"></div>').hide();
|
|
vmAttr.append(advanced);
|
|
|
|
var ip = $('<div><label>IP address range:</label><input type="text" name="ip" ' +
|
|
'title="Optional. Specify the IP address range that will be assigned to these nodes. An IP address range must be given in the following format: 192.168.0.1-192.168.9."/></div>');
|
|
advanced.append(ip);
|
|
var hostname = $('<div><label>Hostname range:</label><input type="text" name="hostname" ' +
|
|
'title="Optional. Specify the hostname range that will be assigned to these node. A hostname range must be given in the following format: ihost1.sourceforge.net-ihost9.sourceforge.net."/></div>');
|
|
advanced.append(hostname);
|
|
|
|
// Show IP address and hostname inputs on-click
|
|
advancedLnk.click(function() {
|
|
advanced.toggle();
|
|
});
|
|
|
|
// Get list of disk pools
|
|
var temp = hcp.split('.');
|
|
var diskPools = $.cookie(temp[0] + 'diskpools');
|
|
|
|
// Create disk pool input
|
|
var poolDiv = $('<div></div>');
|
|
var poolLabel = $('<label>Disk pool:</label>');
|
|
var poolInput = $('<input type="text" id="diskPool" name="diskPool" title="You must give a disk pool. xCAT relies on DirMaint to allocate minidisks out of a pool of DASD volumes. These DASD volume pools are defined in the EXTENT CONTROL file."/>').autocomplete({
|
|
source: diskPools.split(',')
|
|
});
|
|
poolDiv.append(poolLabel);
|
|
poolDiv.append(poolInput);
|
|
storageAttr.append(poolDiv);
|
|
|
|
storageAttr.append('<div><label>Disk password:</label><input type="password" id="diskPw" name="diskPw" title="The password that will be used for accessing the disk. This input is optional."/></div>');
|
|
|
|
// Generate tooltips
|
|
cloneForm.find('div input[title]').tooltip({
|
|
position : "center right",
|
|
offset : [ -2, 10 ],
|
|
effect : "fade",
|
|
opacity : 0.7,
|
|
predelay: 800,
|
|
events : {
|
|
def : "mouseover,mouseout",
|
|
input : "mouseover,mouseout",
|
|
widget : "focus mouseover,blur mouseout",
|
|
tooltip : "mouseover,mouseout"
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Clone node
|
|
*/
|
|
var cloneBtn = createButton('Clone');
|
|
cloneBtn.bind('click', function(event) {
|
|
// Remove any warning messages
|
|
$(this).parents('.ui-tabs-panel').find('.ui-state-error').remove();
|
|
|
|
var ready = true;
|
|
var errMsg = '';
|
|
|
|
// Check node name, userId, hardware control point, group, and password
|
|
var inputs = $('#' + newTabId + ' input');
|
|
for ( var i = 0; i < inputs.length; i++) {
|
|
if (!inputs.eq(i).val()
|
|
&& inputs.eq(i).attr('name') != 'diskPw'
|
|
&& inputs.eq(i).attr('name') != 'diskPool'
|
|
&& inputs.eq(i).attr('name') != 'ip'
|
|
&& inputs.eq(i).attr('name') != 'hostname') {
|
|
inputs.eq(i).css('border', 'solid #FF0000 1px');
|
|
ready = false;
|
|
} else {
|
|
inputs.eq(i).css('border', 'solid #BDBDBD 1px');
|
|
}
|
|
}
|
|
|
|
// Write error message
|
|
if (!ready) {
|
|
errMsg = errMsg + 'Please provide a value for each missing field.<br>';
|
|
}
|
|
|
|
// Get target node
|
|
var nodeRange = $('#' + newTabId + ' input[name=tgtNode]').val();
|
|
// Get target user ID
|
|
var userIdRange = $('#' + newTabId + ' input[name=tgtUserId]').val();
|
|
// Get IP address range
|
|
var ipRange = $('#' + newTabId + ' input[name=ip]').val();
|
|
// Get hostname range
|
|
var hostnameRange = $('#' + newTabId + ' input[name=hostname]').val();
|
|
|
|
// Check node range and user ID range
|
|
if (nodeRange.indexOf('-') > -1 || userIdRange.indexOf('-') > -1 || ipRange.indexOf('-') > -1 || hostnameRange.indexOf('-') > -1) {
|
|
if (nodeRange.indexOf('-') < 0 || userIdRange.indexOf('-') < 0) {
|
|
errMsg = errMsg + 'A user ID range and node range needs to be given.<br>';
|
|
ready = false;
|
|
} else {
|
|
var tmp = nodeRange.split('-');
|
|
|
|
// Get node base name
|
|
var nodeBase = tmp[0].match(/[a-zA-Z]+/);
|
|
// Get starting index
|
|
var nodeStart = parseInt(tmp[0].match(/\d+/));
|
|
// Get ending index
|
|
var nodeEnd = parseInt(tmp[1].match(/\d+/));
|
|
|
|
tmp = userIdRange.split('-');
|
|
|
|
// Get user ID base name
|
|
var userIdBase = tmp[0].match(/[a-zA-Z]+/);
|
|
// Get starting index
|
|
var userIdStart = parseInt(tmp[0].match(/\d+/));
|
|
// Get ending index
|
|
var userIdEnd = parseInt(tmp[1].match(/\d+/));
|
|
|
|
var ipStart = "", ipEnd = "";
|
|
if (ipRange) {
|
|
tmp = ipRange.split('-');
|
|
|
|
// Get starting IP address
|
|
ipStart = tmp[0].substring(tmp[0].lastIndexOf(".") + 1);
|
|
// Get ending IP address
|
|
ipEnd = tmp[1].substring(tmp[1].lastIndexOf(".") + 1);
|
|
}
|
|
|
|
var hostnameStart = "", hostnameEnd = "";
|
|
if (hostnameRange) {
|
|
tmp = hostnameRange.split('-');
|
|
|
|
// Get starting hostname
|
|
hostnameStart = parseInt(tmp[0].substring(0, tmp[0].indexOf(".")).match(/\d+/));
|
|
// Get ending hostname
|
|
hostnameEnd = parseInt(tmp[1].substring(0, tmp[1].indexOf(".")).match(/\d+/));
|
|
}
|
|
|
|
// If starting and ending index do not match
|
|
if (!(nodeStart == userIdStart) || !(nodeEnd == userIdEnd)) {
|
|
// Not ready to provision
|
|
errMsg = errMsg + 'The node range and user ID range does not match.<br>';
|
|
ready = false;
|
|
}
|
|
|
|
// If an IP address range is given and the starting and ending index do not match
|
|
if (ipRange && (!(nodeStart == ipStart) || !(nodeEnd == ipEnd))) {
|
|
errMsg = errMsg + 'The node range and IP address range does not match. ';
|
|
ready = false;
|
|
}
|
|
|
|
// If a hostname range is given and the starting and ending index do not match
|
|
if (hostnameRange && (!(nodeStart == hostnameStart) || !(nodeEnd == hostnameEnd))) {
|
|
errMsg = errMsg + 'The node range and hostname range does not match. ';
|
|
ready = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get source node, hardware control point, group, disk pool, and disk password
|
|
var srcNode = $('#' + newTabId + ' input[name=srcNode]').val();
|
|
var hcp = $('#' + newTabId + ' input[name=newHcp]').val();
|
|
var group = $('#' + newTabId + ' input[name=newGroup]').val();
|
|
var diskPool = $('#' + newTabId + ' input[name=diskPool]').val();
|
|
var diskPw = $('#' + newTabId + ' input[name=diskPw]').val();
|
|
|
|
// If a value is given for every input
|
|
if (ready) {
|
|
// Disable all inputs
|
|
var inputs = $('#' + newTabId + ' input');
|
|
inputs.attr('disabled', 'disabled');
|
|
|
|
// If a node range is given
|
|
if (nodeRange.indexOf('-') > -1) {
|
|
var tmp = nodeRange.split('-');
|
|
|
|
// Get node base name
|
|
var nodeBase = tmp[0].match(/[a-zA-Z]+/);
|
|
// Get starting index
|
|
var nodeStart = parseInt(tmp[0].match(/\d+/));
|
|
// Get ending index
|
|
var nodeEnd = parseInt(tmp[1].match(/\d+/));
|
|
|
|
tmp = userIdRange.split('-');
|
|
|
|
// Get user ID base name
|
|
var userIdBase = tmp[0].match(/[a-zA-Z]+/);
|
|
|
|
var ipBase = "";
|
|
if (ipRange) {
|
|
tmp = ipRange.split('-');
|
|
|
|
// Get network base
|
|
ipBase = tmp[0].substring(0, tmp[0].lastIndexOf(".") + 1);
|
|
}
|
|
|
|
var domain = "";
|
|
if (hostnameRange) {
|
|
tmp = hostnameRange.split('-');
|
|
|
|
// Get domain name
|
|
domain = tmp[0].substring(tmp[0].indexOf("."));
|
|
}
|
|
|
|
// Loop through each node in the node range
|
|
for ( var i = nodeStart; i <= nodeEnd; i++) {
|
|
var node = nodeBase + i.toString();
|
|
var userId = userIdBase + i.toString();
|
|
var inst = i + '/' + nodeEnd;
|
|
|
|
var args = node
|
|
+ ';zvm.hcp=' + hcp
|
|
+ ';zvm.userid=' + userId
|
|
+ ';nodehm.mgt=zvm'
|
|
+ ';groups=' + group;
|
|
|
|
if (ipRange) {
|
|
var ip = ipBase + i.toString();
|
|
args += ';hosts.ip=' + ip;
|
|
}
|
|
|
|
if (hostnameRange) {
|
|
var hostname = node + domain;
|
|
args += ';hosts.hostnames=' + hostname;
|
|
}
|
|
|
|
/**
|
|
* (1) Define node
|
|
*/
|
|
$.ajax( {
|
|
url : 'lib/cmd.php',
|
|
dataType : 'json',
|
|
data : {
|
|
cmd : 'nodeadd',
|
|
tgt : '',
|
|
args : args,
|
|
msg : 'cmd=nodeadd;inst=' + inst
|
|
+ ';out=' + statBarId
|
|
+ ';node=' + node
|
|
},
|
|
|
|
success : updateZCloneStatus
|
|
});
|
|
}
|
|
} else {
|
|
var args = nodeRange
|
|
+ ';zvm.hcp=' + hcp
|
|
+ ';zvm.userid=' + userIdRange
|
|
+ ';nodehm.mgt=zvm'
|
|
+ ';groups=' + group;
|
|
|
|
if (ipRange)
|
|
args += ';hosts.ip=' + ipRange;
|
|
|
|
if (hostnameRange)
|
|
args += ';hosts.hostnames=' + hostnameRange;
|
|
|
|
/**
|
|
* (1) Define node
|
|
*/
|
|
$.ajax( {
|
|
url : 'lib/cmd.php',
|
|
dataType : 'json',
|
|
data : {
|
|
cmd : 'nodeadd',
|
|
tgt : '',
|
|
args : args,
|
|
msg : 'cmd=nodeadd;inst=1/1;out=' + statBarId
|
|
+ ';node=' + nodeRange
|
|
},
|
|
|
|
success : updateZCloneStatus
|
|
});
|
|
}
|
|
|
|
// Create loader
|
|
$('#' + statBarId).find('div').append(createLoader());
|
|
$('#' + statBarId).show();
|
|
|
|
// Disable clone button
|
|
$(this).attr('disabled', 'true');
|
|
} else {
|
|
// Show warning message
|
|
var warn = createWarnBar(errMsg);
|
|
warn.prependTo($(this).parent().parent());
|
|
}
|
|
});
|
|
cloneForm.append(cloneBtn);
|
|
|
|
// Add clone tab
|
|
tab.add(newTabId, 'Clone', cloneForm, true);
|
|
}
|
|
|
|
tab.select(newTabId);
|
|
};
|
|
|
|
/**
|
|
* Load node inventory
|
|
*
|
|
* @param data Data from HTTP request
|
|
*/
|
|
zvmPlugin.prototype.loadInventory = function(data) {
|
|
var args = data.msg.split(',');
|
|
|
|
// Get tab ID
|
|
var tabId = args[0].replace('out=', '');
|
|
// Get node
|
|
var node = args[1].replace('node=', '');
|
|
|
|
// Remove loader
|
|
$('#' + tabId).find('img').remove();
|
|
|
|
// Check for error
|
|
var error = false;
|
|
if (data.rsp.length && data.rsp[0].indexOf('Error') > -1) {
|
|
error = true;
|
|
|
|
var warn = createWarnBar(data.rsp[0]);
|
|
$('#' + tabId).append(warn);
|
|
}
|
|
|
|
// Determine the node type
|
|
if (data.rsp.length && data.rsp[0].indexOf('Hypervisor OS:') > -1) {
|
|
loadHypervisorInventory(data);
|
|
return;
|
|
}
|
|
|
|
// Create status bar
|
|
var statBarId = node + 'StatusBar';
|
|
var statBar = createStatusBar(statBarId);
|
|
|
|
// Add loader to status bar and hide it
|
|
var loader = createLoader(node + 'StatusBarLoader').hide();
|
|
statBar.find('div').append(loader);
|
|
statBar.hide();
|
|
|
|
// Create division to hold user entry
|
|
var ueDivId = node + 'UserEntry';
|
|
var ueDiv = $('<div class="userEntry" id="' + ueDivId + '"></div>');
|
|
|
|
// Create division to hold inventory
|
|
var invDivId = node + 'Inventory';
|
|
var invDiv = $('<div class="inventory" id="' + invDivId + '"></div>');
|
|
|
|
/**
|
|
* Show user entry
|
|
*/
|
|
var toggleLinkId = node + 'ToggleLink';
|
|
var toggleLink = $('<a style="color: blue;" id="' + toggleLinkId + '">Show directory entry</a>');
|
|
toggleLink.one('click', function(event) {
|
|
// Toggle inventory division
|
|
$('#' + invDivId).toggle();
|
|
|
|
// Create loader
|
|
var loader = createLoader(node + 'TabLoader');
|
|
loader = $('<center></center>').append(loader);
|
|
ueDiv.append(loader);
|
|
|
|
// Get user entry
|
|
var msg = 'out=' + ueDivId + ';node=' + node;
|
|
$.ajax( {
|
|
url : 'lib/cmd.php',
|
|
dataType : 'json',
|
|
data : {
|
|
cmd : 'lsvm',
|
|
tgt : node,
|
|
args : '',
|
|
msg : msg
|
|
},
|
|
|
|
success : loadUserEntry
|
|
});
|
|
|
|
// Change text
|
|
$(this).text('Show inventory');
|
|
|
|
// Disable toggle link
|
|
$(this).unbind(event);
|
|
});
|
|
|
|
// Align toggle link to the right
|
|
var toggleLnkDiv = $('<div class="toggle"></div>').css({
|
|
'text-align' : 'right'
|
|
});
|
|
toggleLnkDiv.append(toggleLink);
|
|
|
|
// Append to tab
|
|
$('#' + tabId).append(statBar);
|
|
$('#' + tabId).append(toggleLnkDiv);
|
|
$('#' + tabId).append(ueDiv);
|
|
$('#' + tabId).append(invDiv);
|
|
|
|
// Do not load inventory if no inventory is returned
|
|
if (data.rsp.length && data.rsp[0].indexOf('z/VM UserID:') > -1) {
|
|
// Do nothing
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
// Create array of property keys (VM)
|
|
var keys = new Array('userId', 'host', 'os', 'arch', 'uptime', 'cpuusedtime', 'hcp', 'priv', 'memory', 'maxmemory', 'proc', 'disk', 'zfcp', 'nic');
|
|
|
|
// Create hash table for property names (VM)
|
|
var attrNames = new Object();
|
|
attrNames['userId'] = 'z/VM UserID:';
|
|
attrNames['host'] = 'z/VM Host:';
|
|
attrNames['os'] = 'Operating System:';
|
|
attrNames['arch'] = 'Architecture:';
|
|
attrNames['uptime'] = 'Uptime:';
|
|
attrNames['cpuusedtime'] = 'CPU Used Time:';
|
|
attrNames['hcp'] = 'HCP:';
|
|
attrNames['priv'] = 'Privileges:';
|
|
attrNames['memory'] = 'Total Memory:';
|
|
attrNames['maxmemory'] = 'Max Memory:';
|
|
attrNames['proc'] = 'Processors:';
|
|
attrNames['disk'] = 'Disks:';
|
|
attrNames['zfcp'] = 'zFCP:';
|
|
attrNames['nic'] = 'NICs:';
|
|
|
|
// Create hash table for node attributes
|
|
var inv = data.rsp[0].split(node + ':');
|
|
var attrs;
|
|
if (!error) {
|
|
attrs = getAttrs(keys, attrNames, inv);
|
|
}
|
|
|
|
// Do not continue if error
|
|
if (error) {
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* General info section
|
|
*/
|
|
var fieldSet = $('<fieldset></fieldset>');
|
|
var legend = $('<legend>General</legend>');
|
|
fieldSet.append(legend);
|
|
var oList = $('<ol></ol>');
|
|
var item, label, args;
|
|
|
|
// Loop through each property
|
|
for (var k = 0; k < 6; k++) {
|
|
// Create a list item for each property
|
|
item = $('<li></li>');
|
|
|
|
// Create a label - Property name
|
|
label = $('<label>' + attrNames[keys[k]] + '</label>');
|
|
item.append(label);
|
|
|
|
for (var l = 0; l < attrs[keys[k]].length; l++) {
|
|
// Create a input - Property value(s)
|
|
// Handle each property uniquely
|
|
item.append(attrs[keys[k]][l]);
|
|
}
|
|
|
|
oList.append(item);
|
|
}
|
|
// Append to inventory form
|
|
fieldSet.append(oList);
|
|
invDiv.append(fieldSet);
|
|
|
|
/**
|
|
* Hardware info section
|
|
*/
|
|
var hwList, hwItem;
|
|
fieldSet = $('<fieldset></fieldset>');
|
|
legend = $('<legend>Hardware</legent>');
|
|
fieldSet.append(legend);
|
|
oList = $('<ol></ol>');
|
|
|
|
// Loop through each property
|
|
var label;
|
|
for (k = 6; k < keys.length; k++) {
|
|
// Create a list item
|
|
item = $('<li></li>');
|
|
|
|
// Create a list to hold the property value(s)
|
|
hwList = $('<ul></ul>');
|
|
hwItem = $('<li></li>');
|
|
|
|
/**
|
|
* Privilege section
|
|
*/
|
|
if (keys[k] == 'priv') {
|
|
// Create a label - Property name
|
|
label = $('<label><b>' + attrNames[keys[k]].replace(':', '') + '</b></label>');
|
|
item.append(label);
|
|
|
|
// Loop through each line
|
|
for (l = 0; l < attrs[keys[k]].length; l++) {
|
|
// Create a new list item for each line
|
|
hwItem = $('<li></li>');
|
|
|
|
// Determine privilege
|
|
args = attrs[keys[k]][l].split(' ');
|
|
if (args[0] == 'Directory:') {
|
|
label = $('<label>' + args[0] + '</label>');
|
|
hwItem.append(label);
|
|
hwItem.append(args[1]);
|
|
} else if (args[0] == 'Currently:') {
|
|
label = $('<label>' + args[0] + '</label>');
|
|
hwItem.append(label);
|
|
hwItem.append(args[1]);
|
|
}
|
|
|
|
hwList.append(hwItem);
|
|
}
|
|
|
|
item.append(hwList);
|
|
}
|
|
|
|
/**
|
|
* Memory section
|
|
*/
|
|
else if (keys[k] == 'memory') {
|
|
// Create a label - Property name
|
|
label = $('<label><b>' + attrNames[keys[k]].replace(':', '') + '</b></label>');
|
|
item.append(label);
|
|
|
|
// Loop through each value line
|
|
for (l = 0; l < attrs[keys[k]].length; l++) {
|
|
// Create a new list item for each line
|
|
hwItem = $('<li></li>');
|
|
hwItem.append(attrs[keys[k]][l]);
|
|
hwList.append(hwItem);
|
|
}
|
|
|
|
item.append(hwList);
|
|
}
|
|
|
|
/**
|
|
* Processor section
|
|
*/
|
|
else if (keys[k] == 'proc') {
|
|
// Create a label - Property name
|
|
label = $('<label><b>' + attrNames[keys[k]].replace(':', '') + '</b></label>');
|
|
item.append(label);
|
|
|
|
// Create a table to hold processor data
|
|
var procTable = $('<table></table>');
|
|
var procBody = $('<tbody></tbody>');
|
|
var procFooter = $('<tfoot></tfoot>');
|
|
|
|
// Table columns - Type, Address, ID, Base, Dedicated, and Affinity
|
|
var procTabRow = $('<thead class="ui-widget-header"> <th>Type</th> <th>Address</th> <th>ID</th> <th>Base</th> <th>Dedicated</th> <th>Affinity</th> </thead>');
|
|
procTable.append(procTabRow);
|
|
var procId, procAff;
|
|
|
|
/**
|
|
* Remove processor
|
|
*/
|
|
var contextMenu = [{
|
|
'Remove' : function(menuItem, menu) {
|
|
var addr = $(this).text();
|
|
|
|
// Open dialog to confirm
|
|
var confirmDialog = $('<div><p>Are you sure you want to remove this processor?</p></div>');
|
|
confirmDialog.dialog({
|
|
title: "Confirm",
|
|
modal: true,
|
|
width: 300,
|
|
buttons: {
|
|
"Ok": function(){
|
|
removeProcessor(node, addr);
|
|
$(this).dialog("close");
|
|
},
|
|
"Cancel": function() {
|
|
$(this).dialog("close");
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}];
|
|
|
|
// Loop through each processor
|
|
var n, temp;
|
|
var procType, procAddr, procLink;
|
|
for (l = 0; l < attrs[keys[k]].length; l++) {
|
|
if (attrs[keys[k]][l]) {
|
|
args = attrs[keys[k]][l].split(' ');
|
|
|
|
// Get processor type, address, ID, and affinity
|
|
n = 3;
|
|
temp = args[args.length - n];
|
|
while (!jQuery.trim(temp)) {
|
|
n = n + 1;
|
|
temp = args[args.length - n];
|
|
}
|
|
procType = $('<td>' + temp + '</td>');
|
|
procAddr = $('<td></td>');
|
|
procLink = $('<a>' + args[1] + '</a>');
|
|
|
|
// Append context menu to link
|
|
procLink.contextMenu(contextMenu, {
|
|
theme : 'vista'
|
|
});
|
|
|
|
procAddr.append(procLink);
|
|
procId = $('<td>' + args[5] + '</td>');
|
|
procAff = $('<td>' + args[args.length - 1] + '</td>');
|
|
|
|
// Base processor
|
|
if (args[6] == '(BASE)') {
|
|
baseProc = $('<td>' + true + '</td>');
|
|
} else {
|
|
baseProc = $('<td>' + false + '</td>');
|
|
}
|
|
|
|
// Dedicated processor
|
|
if (args[args.length - 3] == 'DEDICATED') {
|
|
dedicatedProc = $('<td>' + true + '</td>');
|
|
} else {
|
|
dedicatedProc = $('<td>' + false + '</td>');
|
|
}
|
|
|
|
// Create a new row for each processor
|
|
procTabRow = $('<tr></tr>');
|
|
procTabRow.append(procType);
|
|
procTabRow.append(procAddr);
|
|
procTabRow.append(procId);
|
|
procTabRow.append(baseProc);
|
|
procTabRow.append(dedicatedProc);
|
|
procTabRow.append(procAff);
|
|
procBody.append(procTabRow);
|
|
}
|
|
}
|
|
|
|
procTable.append(procBody);
|
|
|
|
/**
|
|
* Add processor
|
|
*/
|
|
var addProcLink = $('<a>+ Add temporary processor</a>');
|
|
addProcLink.bind('click', function(event) {
|
|
openAddProcDialog(node);
|
|
});
|
|
|
|
procFooter.append(addProcLink);
|
|
procTable.append(procFooter);
|
|
item.append(procTable);
|
|
}
|
|
|
|
/**
|
|
* Disk section
|
|
*/
|
|
else if (keys[k] == 'disk') {
|
|
// Create a label - Property name
|
|
label = $('<label><b>' + attrNames[keys[k]].replace(':', '') + '</b></label>');
|
|
item.append(label);
|
|
|
|
// Create a table to hold disk (DASD) data
|
|
var dasdTable = $('<table></table>');
|
|
var dasdBody = $('<tbody></tbody>');
|
|
var dasdFooter = $('<tfoot></tfoot>');
|
|
|
|
/**
|
|
* Remove disk
|
|
*/
|
|
contextMenu = [{
|
|
'Remove' : function(menuItem, menu) {
|
|
var addr = $(this).text();
|
|
|
|
// Open dialog to confirm
|
|
var confirmDialog = $('<div><p>Are you sure you want to remove this disk?</p></div>');
|
|
confirmDialog.dialog({
|
|
title: "Confirm",
|
|
modal: true,
|
|
width: 300,
|
|
buttons: {
|
|
"Ok": function(){
|
|
removeDisk(node, addr);
|
|
$(this).dialog("close");
|
|
},
|
|
"Cancel": function() {
|
|
$(this).dialog("close");
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}];
|
|
|
|
// Table columns - Virtual Device, Type, VolID, Type of Access, and Size
|
|
var dasdTabRow = $('<thead class="ui-widget-header"> <th>Virtual Device #</th> <th>Type</th> <th>VolID</th> <th>Type of Access</th> <th>Size</th> </thead>');
|
|
dasdTable.append(dasdTabRow);
|
|
var dasdVDev, dasdType, dasdVolId, dasdAccess, dasdSize;
|
|
|
|
// Loop through each DASD
|
|
for (l = 0; l < attrs[keys[k]].length; l++) {
|
|
if (attrs[keys[k]][l]) {
|
|
args = attrs[keys[k]][l].split(' ');
|
|
|
|
// Get DASD virtual device, type, volume ID, access, and size
|
|
dasdVDev = $('<td></td>');
|
|
dasdLink = $('<a>' + args[1] + '</a>');
|
|
|
|
// Append context menu to link
|
|
dasdLink.contextMenu(contextMenu, {
|
|
theme : 'vista'
|
|
});
|
|
dasdVDev.append(dasdLink);
|
|
|
|
dasdType = $('<td>' + args[2] + '</td>');
|
|
dasdVolId = $('<td>' + args[3] + '</td>');
|
|
dasdAccess = $('<td>' + args[4] + '</td>');
|
|
dasdSize = $('<td>' + args[args.length - 9] + ' ' + args[args.length - 8] + '</td>');
|
|
|
|
// Create a new row for each DASD
|
|
dasdTabRow = $('<tr></tr>');
|
|
dasdTabRow.append(dasdVDev);
|
|
dasdTabRow.append(dasdType);
|
|
dasdTabRow.append(dasdVolId);
|
|
dasdTabRow.append(dasdAccess);
|
|
dasdTabRow.append(dasdSize);
|
|
dasdBody.append(dasdTabRow);
|
|
}
|
|
}
|
|
|
|
dasdTable.append(dasdBody);
|
|
|
|
/**
|
|
* Add disk
|
|
*/
|
|
var addDasdLink = $('<a>+ Add disk</a>');
|
|
addDasdLink.bind('click', function(event) {
|
|
var hcp = attrs['hcp'][0].split('.');
|
|
openAddDiskDialog(node, hcp[0]);
|
|
});
|
|
dasdFooter.append(addDasdLink);
|
|
dasdTable.append(dasdFooter);
|
|
|
|
item.append(dasdTable);
|
|
}
|
|
|
|
/**
|
|
* zFCP section
|
|
*/
|
|
else if (keys[k] == 'zfcp') {
|
|
// Create a label - Property name
|
|
label = $('<label><b>' + attrNames[keys[k]].replace(':', '') + '</b></label>');
|
|
item.append(label);
|
|
|
|
// Create a table to hold NIC data
|
|
var zfcpTable = $('<table></table>');
|
|
var zfcpBody = $('<tbody></tbody>');
|
|
var zfcpFooter = $('<tfoot></tfoot>');
|
|
|
|
/**
|
|
* Remove zFCP
|
|
*/
|
|
contextMenu = [ {
|
|
'Remove' : function(menuItem, menu) {
|
|
var addr = $(this).text();
|
|
var portName = $(this).parents('tr').find('td:eq(1)').text();
|
|
var unitNo = $(this).parents('tr').find('td:eq(2)').text();
|
|
|
|
// Open dialog to confirm
|
|
var confirmDialog = $('<div><p>Are you sure you want to remove this zFCP device?</p></div>');
|
|
confirmDialog.dialog({
|
|
title: "Confirm",
|
|
modal: true,
|
|
width: 300,
|
|
buttons: {
|
|
"Ok": function(){
|
|
removeZfcp(node, addr, portName, unitNo);
|
|
$(this).dialog("close");
|
|
},
|
|
"Cancel": function() {
|
|
$(this).dialog("close");
|
|
}
|
|
}
|
|
});
|
|
}
|
|
} ];
|
|
|
|
// Table columns - Virtual device, Adapter Type, Port Name, # of Devices, MAC Address, and LAN Name
|
|
var zfcpTabRow = $('<thead class="ui-widget-header"> <th>Virtual Device #</th> <th>Port Name</th> <th>Unit Number</th> <th>Size</th></thead>');
|
|
zfcpTable.append(zfcpTabRow);
|
|
var zfcpVDev, zfcpPortName, zfcpLun, zfcpSize;
|
|
|
|
// Loop through each zFCP device
|
|
if (attrs[keys[k]]) {
|
|
for (l = 0; l < attrs[keys[k]].length; l++) {
|
|
if (attrs[keys[k]][l]) {
|
|
args = attrs[keys[k]][l].split(' ');
|
|
|
|
// Get zFCP virtual device, port name (WWPN), unit number (LUN), and size
|
|
zfcpVDev = $('<td></td>');
|
|
zfcpLink = $('<a>' + args[1].replace('0.0.', '') + '</a>');
|
|
|
|
// Append context menu to link
|
|
zfcpLink.contextMenu(contextMenu, {
|
|
theme : 'vista'
|
|
});
|
|
zfcpVDev.append(zfcpLink);
|
|
|
|
zfcpPortName = $('<td>' + args[4] + '</td>');
|
|
zfcpLun = $('<td>' + args[7] + '</td>');
|
|
zfcpSize = $('<td>' + args[args.length - 2] + ' ' + args[args.length - 1] + '</td>');
|
|
|
|
// Create a new row for each zFCP device
|
|
zfcpTabRow = $('<tr></tr>');
|
|
zfcpTabRow.append(zfcpVDev);
|
|
zfcpTabRow.append(zfcpPortName);
|
|
zfcpTabRow.append(zfcpLun);
|
|
zfcpTabRow.append(zfcpSize);
|
|
|
|
zfcpBody.append(zfcpTabRow);
|
|
}
|
|
}
|
|
}
|
|
|
|
zfcpTable.append(zfcpBody);
|
|
|
|
/**
|
|
* Add dedicated device
|
|
*/
|
|
var dedicateDeviceLink = $('<a>+ Add dedicated device</a>').css('display', 'block');
|
|
dedicateDeviceLink.bind('click', function(event) {
|
|
var hcp = attrs['hcp'][0].split('.');
|
|
openDedicateDeviceDialog(node, hcp[0]);
|
|
});
|
|
|
|
/**
|
|
* Add zFCP device
|
|
*/
|
|
var addZfcpLink = $('<a>+ Add zFCP</a>').css('display', 'block');
|
|
addZfcpLink.bind('click', function(event) {
|
|
var hcp = attrs['hcp'][0].split('.');
|
|
var zvm = attrs['host'][0].toLowerCase();
|
|
openAddZfcpDialog(node, hcp[0], zvm);
|
|
});
|
|
|
|
zfcpFooter.append(dedicateDeviceLink, addZfcpLink);
|
|
zfcpTable.append(zfcpFooter);
|
|
|
|
item.append(zfcpTable);
|
|
}
|
|
|
|
/**
|
|
* NIC section
|
|
*/
|
|
else if (keys[k] == 'nic') {
|
|
// Create a label - Property name
|
|
label = $('<label><b>' + attrNames[keys[k]].replace(':', '') + '</b></label>');
|
|
item.append(label);
|
|
|
|
// Create a table to hold NIC data
|
|
var nicTable = $('<table></table>');
|
|
var nicBody = $('<tbody></tbody>');
|
|
var nicFooter = $('<tfoot></tfoot>');
|
|
|
|
/**
|
|
* Remove NIC
|
|
*/
|
|
contextMenu = [ {
|
|
'Remove' : function(menuItem, menu) {
|
|
var addr = $(this).text();
|
|
|
|
// Open dialog to confirm
|
|
var confirmDialog = $('<div><p>Are you sure you want to remove this NIC?</p></div>');
|
|
confirmDialog.dialog({
|
|
title: "Confirm",
|
|
modal: true,
|
|
width: 300,
|
|
buttons: {
|
|
"Ok": function(){
|
|
removeNic(node, addr);
|
|
$(this).dialog("close");
|
|
},
|
|
"Cancel": function() {
|
|
$(this).dialog("close");
|
|
}
|
|
}
|
|
});
|
|
}
|
|
} ];
|
|
|
|
// Table columns - Virtual device, Adapter Type, Port Name, # of Devices, MAC Address, and LAN Name
|
|
var nicTabRow = $('<thead class="ui-widget-header"> <th>Virtual Device #</th> <th>Adapter Type</th> <th>Port Name</th> <th># of Devices</th> <th>LAN Name</th></thead>');
|
|
nicTable.append(nicTabRow);
|
|
var nicVDev, nicType, nicPortName, nicNumOfDevs, nicLanName;
|
|
|
|
// Loop through each NIC (Data contained in 2 lines)
|
|
for (l = 0; l < attrs[keys[k]].length; l = l + 2) {
|
|
if (attrs[keys[k]][l]) {
|
|
args = attrs[keys[k]][l].split(' ');
|
|
|
|
// Get NIC virtual device, type, port name, and number of devices
|
|
nicVDev = $('<td></td>');
|
|
nicLink = $('<a>' + args[1] + '</a>');
|
|
|
|
// Append context menu to link
|
|
nicLink.contextMenu(contextMenu, {
|
|
theme : 'vista'
|
|
});
|
|
nicVDev.append(nicLink);
|
|
|
|
nicType = $('<td>' + args[3] + '</td>');
|
|
nicPortName = $('<td>' + args[10] + '</td>');
|
|
nicNumOfDevs = $('<td>' + args[args.length - 1] + '</td>');
|
|
|
|
args = attrs[keys[k]][l + 1].split(' ');
|
|
nicLanName = $('<td>' + args[args.length - 2] + ' ' + args[args.length - 1] + '</td>');
|
|
|
|
// Create a new row for each NIC
|
|
nicTabRow = $('<tr></tr>');
|
|
nicTabRow.append(nicVDev);
|
|
nicTabRow.append(nicType);
|
|
nicTabRow.append(nicPortName);
|
|
nicTabRow.append(nicNumOfDevs);
|
|
nicTabRow.append(nicLanName);
|
|
|
|
nicBody.append(nicTabRow);
|
|
}
|
|
}
|
|
|
|
nicTable.append(nicBody);
|
|
|
|
/**
|
|
* Add NIC
|
|
*/
|
|
var addNicLink = $('<a>+ Add NIC</a>');
|
|
addNicLink.bind('click', function(event) {
|
|
var hcp = attrs['hcp'][0].split('.');
|
|
openAddNicDialog(node, hcp[0]);
|
|
});
|
|
nicFooter.append(addNicLink);
|
|
nicTable.append(nicFooter);
|
|
|
|
item.append(nicTable);
|
|
}
|
|
|
|
// Ignore any fields not in key
|
|
else {
|
|
continue;
|
|
}
|
|
|
|
oList.append(item);
|
|
}
|
|
|
|
// Append inventory to division
|
|
fieldSet.append(oList);
|
|
invDiv.append(fieldSet);
|
|
};
|
|
|
|
/**
|
|
* Load hypervisor inventory
|
|
*
|
|
* @param data Data from HTTP request
|
|
*/
|
|
function loadHypervisorInventory(data) {
|
|
var args = data.msg.split(',');
|
|
|
|
// Get tab ID
|
|
var tabId = args[0].replace('out=', '');
|
|
// Get node
|
|
var node = args[1].replace('node=', '');
|
|
|
|
// Remove loader
|
|
$('#' + tabId).find('img').remove();
|
|
|
|
// Check for error
|
|
var error = false;
|
|
if (data.rsp.length && data.rsp[0].indexOf('Error') > -1) {
|
|
error = true;
|
|
|
|
var warn = createWarnBar(data.rsp[0]);
|
|
$('#' + tabId).append(warn);
|
|
}
|
|
|
|
// Get node inventory
|
|
var inv = data.rsp[0].split(node + ':');
|
|
|
|
// Create status bar
|
|
var statBarId = node + 'StatusBar';
|
|
var statBar = createStatusBar(statBarId);
|
|
|
|
// Add loader to status bar and hide it
|
|
var loader = createLoader(node + 'StatusBarLoader').hide();
|
|
statBar.find('div').append(loader);
|
|
statBar.hide();
|
|
|
|
// Create array of property keys (z/VM hypervisor)
|
|
var keys = new Array('host', 'hcp', 'arch', 'cecvendor', 'cecmodel', 'hypos', 'hypname', 'lparcputotal', 'lparcpuused', 'lparmemorytotal', 'lparmemoryused', 'lparmemoryoffline');
|
|
|
|
// Create hash table for property names (z/VM hypervisor)
|
|
var attrNames = new Object();
|
|
attrNames['host'] = 'z/VM Host:';
|
|
attrNames['hcp'] = 'zHCP:';
|
|
attrNames['arch'] = 'Architecture:';
|
|
attrNames['cecvendor'] = 'CEC Vendor:';
|
|
attrNames['cecmodel'] = 'CEC Model:';
|
|
attrNames['hypos'] = 'Hypervisor OS:';
|
|
attrNames['hypname'] = 'Hypervisor Name:';
|
|
attrNames['lparcputotal'] = 'LPAR CPU Total:';
|
|
attrNames['lparcpuused'] = 'LPAR CPU Used:';
|
|
attrNames['lparmemorytotal'] = 'LPAR Memory Total:';
|
|
attrNames['lparmemoryused'] = 'LPAR Memory Used:';
|
|
attrNames['lparmemoryoffline'] = 'LPAR Memory Offline:';
|
|
|
|
// Remove loader
|
|
$('#' + tabId).find('img').remove();
|
|
|
|
// Create hash table for node attributes
|
|
var attrs;
|
|
if (!error) {
|
|
attrs = getAttrs(keys, attrNames, inv);
|
|
}
|
|
|
|
// Create division to hold inventory
|
|
var invDivId = node + 'Inventory';
|
|
var invDiv = $('<div class="inventory" id="' + invDivId + '"></div>');
|
|
|
|
// Append to tab
|
|
$('#' + tabId).append(statBar);
|
|
$('#' + tabId).append(invDiv);
|
|
|
|
// Do not continue if error
|
|
if (error) {
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* General info section
|
|
*/
|
|
var fieldSet = $('<fieldset></fieldset>');
|
|
var legend = $('<legend>General</legend>');
|
|
fieldSet.append(legend);
|
|
var oList = $('<ol></ol>');
|
|
var item, label, args;
|
|
|
|
// Loop through each property
|
|
for (var k = 0; k < 7; k++) {
|
|
// Create a list item for each property
|
|
item = $('<li></li>');
|
|
|
|
// Create a label - Property name
|
|
label = $('<label>' + attrNames[keys[k]] + '</label>');
|
|
item.append(label);
|
|
|
|
for (var l = 0; l < attrs[keys[k]].length; l++) {
|
|
// Create a input - Property value(s)
|
|
// Handle each property uniquely
|
|
item.append(attrs[keys[k]][l]);
|
|
}
|
|
|
|
oList.append(item);
|
|
}
|
|
// Append to inventory form
|
|
fieldSet.append(oList);
|
|
invDiv.append(fieldSet);
|
|
|
|
/**
|
|
* Hardware info section
|
|
*/
|
|
var hwList, hwItem;
|
|
fieldSet = $('<fieldset></fieldset>');
|
|
legend = $('<legend>Hardware</legent>');
|
|
fieldSet.append(legend);
|
|
oList = $('<ol></ol>');
|
|
|
|
// Loop through each property
|
|
var label;
|
|
for (k = 7; k < keys.length; k++) {
|
|
// Create a list item for each property
|
|
item = $('<li></li>');
|
|
|
|
// Create a label - Property name
|
|
label = $('<label>' + attrNames[keys[k]] + '</label>');
|
|
item.append(label);
|
|
|
|
for (var l = 0; l < attrs[keys[k]].length; l++) {
|
|
// Create a input - Property value(s)
|
|
// Handle each property uniquely
|
|
item.append(attrs[keys[k]][l]);
|
|
}
|
|
|
|
oList.append(item);
|
|
}
|
|
// Append to inventory form
|
|
fieldSet.append(oList);
|
|
invDiv.append(fieldSet);
|
|
|
|
// Append to inventory form
|
|
$('#' + tabId).append(invDiv);
|
|
};
|
|
|
|
/**
|
|
* Load provision page
|
|
*
|
|
* @param tabId The provision tab ID
|
|
*/
|
|
zvmPlugin.prototype.loadProvisionPage = function(tabId) {
|
|
// Get OS image names
|
|
$.ajax( {
|
|
url : 'lib/cmd.php',
|
|
dataType : 'json',
|
|
data : {
|
|
cmd : 'tabdump',
|
|
tgt : '',
|
|
args : 'osimage',
|
|
msg : ''
|
|
},
|
|
|
|
success : setOSImageCookies
|
|
});
|
|
|
|
// Get groups
|
|
$.ajax( {
|
|
url : 'lib/cmd.php',
|
|
dataType : 'json',
|
|
data : {
|
|
cmd : 'extnoderange',
|
|
tgt : '/.*',
|
|
args : 'subgroups',
|
|
msg : ''
|
|
},
|
|
|
|
success : setGroupsCookies
|
|
});
|
|
|
|
// Get provision tab instance
|
|
var inst = tabId.replace('zvmProvisionTab', '');
|
|
|
|
// Create provision form
|
|
var provForm = $('<div class="form"></div>');
|
|
|
|
// Create status bar
|
|
var statBarId = 'zProvisionStatBar' + inst;
|
|
var statBar = createStatusBar(statBarId).hide();
|
|
provForm.append(statBar);
|
|
|
|
// Create loader
|
|
var loader = createLoader('zProvisionLoader' + inst).hide();
|
|
statBar.find('div').append(loader);
|
|
|
|
// Create info bar
|
|
var infoBar = createInfoBar('Provision a node on System z.');
|
|
provForm.append(infoBar);
|
|
|
|
// Append to provision tab
|
|
$('#' + tabId).append(provForm);
|
|
|
|
var typeFS = $('<fieldset></fieldset>');
|
|
var typeLegend = $('<legend>Type</legend>');
|
|
typeFS.append(typeLegend);
|
|
provForm.append(typeFS);
|
|
|
|
// Create provision type drop down
|
|
var provType = $('<div></div>');
|
|
var typeLabel = $('<label>Type:</label>');
|
|
var typeSelect = $('<select></select>');
|
|
var provNewNode = $('<option value="new">New node</option>');
|
|
var provExistNode = $('<option value="existing">Existing node</option>');
|
|
typeSelect.append(provNewNode);
|
|
typeSelect.append(provExistNode);
|
|
provType.append(typeLabel);
|
|
provType.append(typeSelect);
|
|
typeFS.append(provType);
|
|
|
|
/**
|
|
* Create provision new node division
|
|
*/
|
|
var provNew = createZProvisionNew(inst);
|
|
provForm.append(provNew);
|
|
|
|
/**
|
|
* Create provision existing node division
|
|
*/
|
|
var provExisting = createZProvisionExisting(inst);
|
|
provForm.append(provExisting);
|
|
|
|
// Toggle provision new/existing on select
|
|
typeSelect.change(function(){
|
|
var selected = $(this).val();
|
|
if (selected == 'new') {
|
|
provNew.toggle();
|
|
provExisting.toggle();
|
|
} else {
|
|
provNew.toggle();
|
|
provExisting.toggle();
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Load the resources
|
|
*/
|
|
zvmPlugin.prototype.loadResources = function() {
|
|
// Reset resource table
|
|
setDiskDataTable('');
|
|
setNetworkDataTable('');
|
|
|
|
// Get hardware control points
|
|
$.ajax( {
|
|
url : 'lib/cmd.php',
|
|
dataType : 'json',
|
|
data : {
|
|
cmd : 'nodels',
|
|
tgt : 'mgt==zvm',
|
|
args : 'zvm.hcp',
|
|
msg : ''
|
|
},
|
|
success : getZResources
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Add node range
|
|
*/
|
|
zvmPlugin.prototype.addNode = function() {
|
|
// Create form to add node range
|
|
var addNodeForm = $('<div id="addZvm" class="form"></div>');
|
|
var info = createInfoBar('Add a z/VM node range');
|
|
addNodeForm.append(info);
|
|
|
|
// Create provision type drop down
|
|
var type = $('<div></div>');
|
|
var typeLabel = $('<label>Type:</label>');
|
|
var typeSelect = $('<select type="text" name="type"></select>');
|
|
typeSelect.append('<option value="vm" selected="selected">VM</option>');
|
|
typeSelect.append('<option value="host">Host</option>');
|
|
type.append(typeLabel);
|
|
type.append(typeSelect);
|
|
addNodeForm.append(type);
|
|
|
|
addNodeForm.append('<div><label>Node range *:</label><input type="text" name="node"/></div>');
|
|
addNodeForm.append('<div><label>User ID range *:</label><input type="text" name="userId"/></div>');
|
|
addNodeForm.append('<div><label>zHCP *:</label><input type="text" name="hcp"/></div>');
|
|
addNodeForm.append('<div><label>Groups *:</label><input type="text" name="groups"/></div>');
|
|
addNodeForm.append('<div><label>Operating system *:</label><input type="text" name="os"/></div>');
|
|
addNodeForm.append('<div><label>IP address range:</label><input name="ip" type="text"></div>');
|
|
addNodeForm.append('<div><label>Hostname range:</label><input name="hostname" type="text"></div>');
|
|
addNodeForm.append('<div><label>* required</label></div>');
|
|
|
|
// OS field only required for hosts
|
|
addNodeForm.find('input[name=os]').parent().hide();
|
|
|
|
// Toggle user Id on select
|
|
typeSelect.change(function(){
|
|
var selected = $(this).val();
|
|
if (selected == 'host') {
|
|
addNodeForm.find('input[name=userId]').parent().toggle();
|
|
addNodeForm.find('input[name=os]').parent().toggle();
|
|
} else {
|
|
addNodeForm.find('input[name=userId]').parent().toggle();
|
|
addNodeForm.find('input[name=os]').parent().toggle();
|
|
}
|
|
});
|
|
|
|
// Open form as a dialog
|
|
addNodeForm.dialog({
|
|
title: 'Add node',
|
|
modal: true,
|
|
width: 400,
|
|
buttons: {
|
|
"Ok": function(){
|
|
// Remove any warning messages
|
|
$(this).find('.ui-state-error').remove();
|
|
|
|
// Get inputs
|
|
var type = $(this).find('select[name=type]').val();
|
|
var nodeRange = $(this).find('input[name=node]').val();
|
|
var ipRange = $(this).find('input[name=ip]').val();
|
|
var hostnameRange = $(this).find('input[name=hostname]').val();
|
|
var userIdRange = $(this).find('input[name=userId]').val();
|
|
var os = $(this).find('input[name=os]').val();
|
|
var group = $(this).find('input[name=groups]').val();
|
|
var hcp = $(this).find('input[name=hcp]').val();
|
|
|
|
// Check required fields
|
|
if (type == 'host') {
|
|
if (!nodeRange || !os || !group || !hcp) {
|
|
var warn = createWarnBar('Please provide a value for each missing field!');
|
|
warn.prependTo($(this));
|
|
return;
|
|
}
|
|
} else {
|
|
if (!nodeRange || !userIdRange || !group || !hcp) {
|
|
var warn = createWarnBar('Please provide a value for each missing field!');
|
|
warn.prependTo($(this));
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Check node range and user ID range
|
|
// Range can be given as gpok10-gpok20, gpok[10-20], or gpok10+10
|
|
var errMsg = '';
|
|
var ready = true;
|
|
if (nodeRange.indexOf('-') > -1 || userIdRange.indexOf('-') > -1) {
|
|
if (nodeRange.indexOf('-') < 0 || userIdRange.indexOf('-') < 0) {
|
|
errMsg = errMsg + 'A user ID range and node range needs to be given. ';
|
|
ready = false;
|
|
} else {
|
|
var tmp = nodeRange.split('-');
|
|
|
|
// Get starting index
|
|
var nodeStart = parseInt(tmp[0].match(/\d+/));
|
|
// Get ending index
|
|
var nodeEnd = parseInt(tmp[1].match(/\d+/));
|
|
|
|
tmp = userIdRange.split('-');
|
|
|
|
// Get starting index
|
|
var userIdStart = parseInt(tmp[0].match(/\d+/));
|
|
// Get ending index
|
|
var userIdEnd = parseInt(tmp[1].match(/\d+/));
|
|
|
|
var ipStart = "", ipEnd = "";
|
|
if (ipRange != "" && ipRange != null) {
|
|
tmp = ipRange.split('-');
|
|
|
|
// Get starting IP address
|
|
ipStart = tmp[0].substring(tmp[0].lastIndexOf(".") + 1);
|
|
// Get ending IP address
|
|
ipEnd = tmp[1].substring(tmp[1].lastIndexOf(".") + 1);
|
|
}
|
|
|
|
var hostnameStart = "", hostnameEnd = "";
|
|
if (hostnameRange != "" && hostnameRange != null) {
|
|
tmp = hostnameRange.split('-');
|
|
|
|
// Get starting hostname
|
|
hostnameStart = parseInt(tmp[0].substring(0, tmp[0].indexOf(".")).match(/\d+/));
|
|
// Get ending hostname
|
|
hostnameEnd = parseInt(tmp[1].substring(0, tmp[1].indexOf(".")).match(/\d+/));
|
|
}
|
|
|
|
// If starting and ending index do not match
|
|
if (!(nodeStart == userIdStart) || !(nodeEnd == userIdEnd)) {
|
|
errMsg = errMsg + 'The node range and user ID range does not match. ';
|
|
ready = false;
|
|
}
|
|
|
|
// If an IP address range is given and the starting and ending index do not match
|
|
if (ipRange != "" && ipRange != null && (!(nodeStart == ipStart) || !(nodeEnd == ipEnd))) {
|
|
errMsg = errMsg + 'The node range and IP address range does not match. ';
|
|
ready = false;
|
|
}
|
|
|
|
// If a hostname range is given and the starting and ending index do not match
|
|
if (hostnameRange != "" && hostnameRange != null && (!(nodeStart == hostnameStart) || !(nodeEnd == hostnameEnd))) {
|
|
errMsg = errMsg + 'The node range and hostname range does not match. ';
|
|
ready = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If there are no errors
|
|
if (ready) {
|
|
$('#addZvm').append(createLoader());
|
|
|
|
// Change dialog buttons
|
|
$('#addZvm').dialog('option', 'buttons', {
|
|
'Close':function(){
|
|
$('#addZvm').dialog('close');
|
|
}
|
|
});
|
|
|
|
// If a node range is given
|
|
if (nodeRange.indexOf('-') > -1 && userIdRange.indexOf('-') > -1) {
|
|
var tmp = nodeRange.split('-');
|
|
|
|
// Get node base name
|
|
var nodeBase = tmp[0].match(/[a-zA-Z]+/);
|
|
// Get starting index
|
|
var nodeStart = parseInt(tmp[0].match(/\d+/));
|
|
// Get ending index
|
|
var nodeEnd = parseInt(tmp[1].match(/\d+/));
|
|
|
|
tmp = userIdRange.split('-');
|
|
|
|
// Get user ID base name
|
|
var userIdBase = tmp[0].match(/[a-zA-Z]+/);
|
|
|
|
var ipBase = "";
|
|
if (ipRange != "" && ipRange != null) {
|
|
tmp = ipRange.split('-');
|
|
|
|
// Get network base
|
|
ipBase = tmp[0].substring(0, tmp[0].lastIndexOf(".") + 1);
|
|
}
|
|
|
|
var domain = "";
|
|
if (hostnameRange != "" && hostnameRange != null) {
|
|
tmp = hostnameRange.split('-');
|
|
|
|
// Get domain name
|
|
domain = tmp[0].substring(tmp[0].indexOf("."));
|
|
}
|
|
|
|
// Loop through each node in the node range
|
|
for ( var i = nodeStart; i <= nodeEnd; i++) {
|
|
var node = nodeBase + i.toString();
|
|
var userId = userIdBase + i.toString();
|
|
var inst = i + '/' + nodeEnd;
|
|
|
|
var args = "";
|
|
if (type == 'host') {
|
|
args = node + ';zvm.hcp=' + hcp
|
|
+ ';nodehm.mgt=zvm;hypervisor.type=zvm;groups=' + group
|
|
+ ';nodetype.os=' + os;
|
|
} else {
|
|
args = node + ';zvm.hcp=' + hcp
|
|
+ ';zvm.userid=' + userId
|
|
+ ';nodehm.mgt=zvm' + ';groups=' + group;
|
|
}
|
|
|
|
if (ipRange != "" && ipRange != null) {
|
|
var ip = ipBase + i.toString();
|
|
args += ';hosts.ip=' + ip;
|
|
}
|
|
|
|
if (hostnameRange != "" && hostnameRange != null) {
|
|
var hostname = node + domain;
|
|
args += ';hosts.hostnames=' + hostname;
|
|
}
|
|
|
|
/**
|
|
* (1) Define node
|
|
*/
|
|
$.ajax( {
|
|
url : 'lib/cmd.php',
|
|
dataType : 'json',
|
|
data : {
|
|
cmd : 'nodeadd',
|
|
tgt : '',
|
|
args : args,
|
|
msg : 'cmd=addnewnode;inst=' + inst + ';noderange=' + nodeRange
|
|
},
|
|
|
|
/**
|
|
* Return function on successful AJAX call
|
|
*
|
|
* @param data
|
|
* Data returned from HTTP request
|
|
* @return Nothing
|
|
*/
|
|
success : function (data) {
|
|
// Get ajax response
|
|
var rsp = data.rsp;
|
|
var args = data.msg.split(';');
|
|
|
|
// Get instance returned and node range
|
|
var inst = args[1].replace('inst=', '');
|
|
var nodeRange = args[2].replace('noderange=', '');
|
|
|
|
// If the last node was added
|
|
var tmp = inst.split('/');
|
|
if (tmp[0] == tmp[1]) {
|
|
// Update /etc/hosts
|
|
$.ajax({
|
|
url : 'lib/cmd.php',
|
|
dataType : 'json',
|
|
data : {
|
|
cmd : 'makehosts',
|
|
tgt : '',
|
|
args : '',
|
|
msg : ''
|
|
}
|
|
});
|
|
|
|
// Remove loader
|
|
$('#addZvm img').remove();
|
|
|
|
// If there was an error, do not continue
|
|
if (rsp.length) {
|
|
$('#addZvm').prepend(createWarnBar('Failed to create node definitions'));
|
|
} else {
|
|
$('#addZvm').prepend(createInfoBar('Node definitions created for ' + nodeRange));
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
} else {
|
|
var args = "";
|
|
if (type == 'host') {
|
|
args = nodeRange + ';zvm.hcp=' + hcp
|
|
+ ';nodehm.mgt=zvm;hypervisor.type=zvm;groups=' + group
|
|
+ ';nodetype.os=' + os;
|
|
} else {
|
|
args = nodeRange + ';zvm.hcp=' + hcp
|
|
+ ';zvm.userid=' + userIdRange
|
|
+ ';nodehm.mgt=zvm' + ';groups=' + group;
|
|
}
|
|
|
|
if (ipRange)
|
|
args += ';hosts.ip=' + ipRange;
|
|
|
|
if (hostnameRange)
|
|
args += ';hosts.hostnames=' + hostnameRange;
|
|
|
|
// Only one node to add
|
|
$.ajax( {
|
|
url : 'lib/cmd.php',
|
|
dataType : 'json',
|
|
data : {
|
|
cmd : 'nodeadd',
|
|
tgt : '',
|
|
args : args,
|
|
msg : 'cmd=addnewnode;node=' + nodeRange
|
|
},
|
|
|
|
/**
|
|
* Return function on successful AJAX call
|
|
*
|
|
* @param data
|
|
* Data returned from HTTP request
|
|
* @return Nothing
|
|
*/
|
|
success : function (data) {
|
|
// Get ajax response
|
|
var rsp = data.rsp;
|
|
var args = data.msg.split(';');
|
|
var node = args[1].replace('node=', '');
|
|
|
|
// Update /etc/hosts
|
|
$.ajax({
|
|
url : 'lib/cmd.php',
|
|
dataType : 'json',
|
|
data : {
|
|
cmd : 'makehosts',
|
|
tgt : '',
|
|
args : '',
|
|
msg : ''
|
|
}
|
|
});
|
|
|
|
// Remove loader
|
|
$('#addZvm img').remove();
|
|
|
|
// If there was an error, do not continue
|
|
if (rsp.length) {
|
|
$('#addZvm').prepend(createWarnBar('Failed to create node definitions'));
|
|
} else {
|
|
$('#addZvm').prepend(createInfoBar('Node definitions created for ' + node));
|
|
}
|
|
}
|
|
});
|
|
}
|
|
} else {
|
|
// Show warning message
|
|
var warn = createWarnBar(errMsg);
|
|
warn.prependTo($(this));
|
|
}
|
|
},
|
|
"Cancel": function(){
|
|
$(this).dialog( "close" );
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Migrate page
|
|
*
|
|
* @param tgtNode Targets to migrate
|
|
*/
|
|
zvmPlugin.prototype.loadMigratePage = function(tgtNode) {
|
|
var hosts = $.cookie('zvms').split(',');
|
|
var radio, zvmBlock, args;
|
|
var zvms = new Array();
|
|
var hcp = new Object();
|
|
|
|
// Create a drop-down for z/VM destinations
|
|
var destSelect = $('<select name="dest"></select>')
|
|
destSelect.append($('<option></option>'));
|
|
for (var i in hosts) {
|
|
args = hosts[i].split(':');
|
|
hcp[args[0]] = args[1];
|
|
zvms.push(args[0]);
|
|
|
|
destSelect.append($('<option>' + args[0] + '</option>'));
|
|
}
|
|
|
|
// Get nodes tab
|
|
var tab = getNodesTab();
|
|
|
|
// Generate new tab ID
|
|
var inst = 0;
|
|
var newTabId = 'migrateTab' + inst;
|
|
while ($('#' + newTabId).length) {
|
|
// If one already exists, generate another one
|
|
inst = inst + 1;
|
|
newTabId = 'migrateTab' + inst;
|
|
}
|
|
|
|
// Open new tab
|
|
// Create remote script form
|
|
var migrateForm = $('<div class="form"></div>');
|
|
|
|
// Create status bar
|
|
var barId = 'migrateStatusBar' + inst;
|
|
var statBar = createStatusBar(barId);
|
|
statBar.hide();
|
|
migrateForm.append(statBar);
|
|
|
|
// Create loader
|
|
var loader = createLoader('migrateLoader' + inst);
|
|
statBar.find('div').append(loader);
|
|
|
|
// Create info bar
|
|
var infoBar = createInfoBar('Migrate, test relocation eligibility, or cancel the relocation of the specified virtual machine, while it continues to run, to the specified system within the z/VM SSI cluster.');
|
|
migrateForm.append(infoBar);
|
|
|
|
// Virtual machine label
|
|
var vmFS = $('<fieldset><legend>Virtual Machine</legend></fieldset>');
|
|
migrateForm.append(vmFS);
|
|
|
|
var vmAttr = $('<div style="display: inline-table; vertical-align: middle;"></div>');
|
|
vmFS.append($('<div style="display: inline-table; vertical-align: middle;"><img src="images/provision/computer.png"></img></div>'));
|
|
vmFS.append(vmAttr);
|
|
|
|
// Target node or group
|
|
var tgt = $('<div><label>Target node range:</label><input type="text" name="target" value="' + tgtNode + '" title="The node or node range to migrate, test, or cancel relocation"/></div>');
|
|
vmAttr.append(tgt);
|
|
|
|
// Destination
|
|
var dest = $('<div><label>Destination:</label></div>');
|
|
var destInput = $('<input type="text" name="dest" title="The z/VM SSI cluster name of the destination system to which the specified virtual machine will be relocated"/>');
|
|
destInput.autocomplete({
|
|
source: zvms
|
|
});
|
|
|
|
// Create a drop-down if there are known z/VMs
|
|
if (zvms.length) {
|
|
dest.append(destSelect);
|
|
} else {
|
|
dest.append(destInput);
|
|
}
|
|
vmAttr.append(dest);
|
|
|
|
// Action Parameter
|
|
var actionparam = $('<div><label>Action:</label><select name="action"><option value=""></option><option value="MOVE">Move</option><option value="TEST">Test</option><option value="CANCEL">Cancel</option></select></div>');
|
|
vmAttr.append(actionparam);
|
|
|
|
// Parameters label
|
|
var optionalFS = $('<fieldset><legend>Optional</legend></fieldset>').css('margin-top', '20px');
|
|
migrateForm.append(optionalFS);
|
|
|
|
var optAttr = $('<div style="display: inline-table; vertical-align: middle;"></div>');
|
|
optionalFS.append($('<div style="display: inline-table; vertical-align: middle; width: 70px;"><img src="images/provision/setting.png" style="width: 90%;"></img></div>'));
|
|
optionalFS.append(optAttr);
|
|
|
|
// Immediate Parameter
|
|
var immediateparam = $('<div><label>Immediate:</label><select name="immediate"><option value="NO">No (default)</option><option value="YES">Yes</option></select></div>');
|
|
optAttr.append(immediateparam);
|
|
immediateparam.change(function() {
|
|
if ($('#' + newTabId + ' select[name=immediate]').val() == 'yes') {
|
|
$('#' + newTabId + ' input[name=maxQuiesce]').val('0');
|
|
} else {
|
|
$('#' + newTabId + ' input[name=maxQuiesce]').val('10');
|
|
}
|
|
});
|
|
|
|
// Max total
|
|
var maxTotalParam = $('<div><label>Max total time:</label><input type="text" name="maxTotal" value="0" title="The maximum total time in seconds that the command issuer is willing to wait for the entire relocation (0 indicates no limit)"/></div>');
|
|
optAttr.append(maxTotalParam);
|
|
|
|
// Max quiesce
|
|
var maxQuiesceParam = $('<div><label>Max quiesce time:</label><input type="text" name="maxQuiesce" value="10" title="The maximum quiesce time (in seconds) a virtual machine may be stopped during a relocation attempt (0 indicates no limit)"/></div>');
|
|
optAttr.append(maxQuiesceParam);
|
|
|
|
// Force parameter
|
|
var forceParam = $('<div style="width: 500px;"><label>Force:</label><input type="checkbox" name="force" value="ARCHITECTURE" style="margin-left:10px">Architecture</input><input type="checkbox" name="force" value="DOMAIN" style="margin-left:10px">Domain</input><input type="checkbox" name="force" value="STORAGE" style="margin-left:10px">Storage</input></div>');
|
|
optAttr.append(forceParam);
|
|
|
|
// Generate tooltips
|
|
migrateForm.find('div input[title]').tooltip({
|
|
position: "center right",
|
|
offset: [-2, 10],
|
|
effect: "fade",
|
|
opacity: 0.7,
|
|
predelay: 800,
|
|
events : {
|
|
def : "mouseover,mouseout",
|
|
input : "mouseover,mouseout",
|
|
widget : "focus mouseover,blur mouseout",
|
|
tooltip : "mouseover,mouseout"
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Run
|
|
*/
|
|
var runBtn = createButton('Run');
|
|
runBtn.click(function() {
|
|
// Remove any warning messages
|
|
$(this).parent().parent().find('.ui-state-error').remove();
|
|
|
|
var tgt = $('#' + newTabId + ' input[name=target]');
|
|
|
|
// Drop-down box exists if z/VM systems are known
|
|
// Otherwise, only input box exists
|
|
var dest = $('#' + newTabId + ' select[name=dest]');
|
|
if (!dest.length) {
|
|
dest = $('#' + newTabId + ' input[name=dest]');
|
|
}
|
|
|
|
var action = $('#' + newTabId + ' select[name=action]');
|
|
var immediate = $('#' + newTabId + ' select[name=immediate]');
|
|
var maxTotal = $('#' + newTabId + ' input[name=maxTotal]');
|
|
var maxQuiesce = $('#' + newTabId + ' input[name=maxQuiesce]');
|
|
var tgts = $('#' + newTabId + ' input[name=target]');
|
|
|
|
// Change borders color back to normal
|
|
var inputs = $('#' + newTabId + ' input').css('border', 'solid #BDBDBD 1px');
|
|
var inputs = $('#' + newTabId + ' select').css('border', 'solid #BDBDBD 1px');
|
|
|
|
// Check if required arguments are given
|
|
var message = "";
|
|
if (!isInteger(maxTotal.val())) {
|
|
message += "Max total time must be an integer. ";
|
|
maxTotal.css('border', 'solid #FF0000 1px');
|
|
} if (!isInteger(maxQuiesce.val())) {
|
|
message += "Max quiesce time must be an integer. ";
|
|
maxQuiesce.css('border', 'solid #FF0000 1px');
|
|
} if (!tgt.val()) {
|
|
message += "Target must be specified. ";
|
|
tgt.css('border', 'solid #FF0000 1px');
|
|
} if (!dest.val()) {
|
|
message += "Destination must be specified. ";
|
|
dest.css('border', 'solid #FF0000 1px');
|
|
} if (!action.val()) {
|
|
message += "Action must be specified. ";
|
|
action.css('border', 'solid #FF0000 1px');
|
|
}
|
|
|
|
// Show warning message
|
|
if (message) {
|
|
var warn = createWarnBar(message);
|
|
warn.prependTo($(this).parent().parent());
|
|
return;
|
|
}
|
|
|
|
var args = "destination=" + dest.val() + ";action=" + action.val() + ";immediate=" + immediate.val() + ";";
|
|
|
|
// Append max total argument. Specified <= 0 to accomodate negative values.
|
|
if (maxTotal.val() <= 0) {
|
|
args = args + "max_total=NOLIMIT;";
|
|
} else {
|
|
args = args + "max_total=" + maxTotal.val() + ";";
|
|
}
|
|
|
|
// Append max quiesce argument. Specified <= 0 to accomodate negative values.
|
|
if (maxQuiesce.val() <= 0) {
|
|
args = args + "max_quiesce=NOLIMIT;";
|
|
} else {
|
|
args = args + "'max_quiesce=" + maxQuiesce.val() + "';";
|
|
}
|
|
|
|
// Append force argument
|
|
if ($("input[name=force]:checked").length > 0) {
|
|
args = args + "'force="
|
|
$("input[name=force]:checked").each(function() {
|
|
args = args + $(this).val() + ' ';
|
|
});
|
|
args = args + "';";
|
|
} else {
|
|
args = args + ";";
|
|
}
|
|
|
|
var statBarId = 'migrateStatusBar' + inst;
|
|
$('#' + statBarId).show();
|
|
|
|
// Disable all fields
|
|
$('#' + newTabId + ' input').attr('disabled', 'true');
|
|
$('#' + newTabId + ' select').attr('disabled', 'true');
|
|
|
|
// Disable buttons
|
|
$('#' + newTabId + ' button').attr('disabled', 'true');
|
|
|
|
// Run migrate
|
|
$.ajax( {
|
|
url : 'lib/cmd.php',
|
|
dataType : 'json',
|
|
data : {
|
|
cmd : 'rmigrate',
|
|
tgt : tgts.val(),
|
|
args : args,
|
|
msg : 'out=migrateStatusBar' + inst + ';cmd=rmigrate;tgt=' + tgts.val()
|
|
},
|
|
|
|
success : updateStatusBar
|
|
});
|
|
});
|
|
migrateForm.append(runBtn);
|
|
|
|
// Append to discover tab
|
|
tab.add(newTabId, 'Migrate', migrateForm, true);
|
|
|
|
// Select new tab
|
|
tab.select(newTabId);
|
|
};
|
|
|
|
/**
|
|
* Load event log configuration page
|
|
*
|
|
* @param node Source node to clone
|
|
*/
|
|
zvmPlugin.prototype.loadLogPage = function(node) {
|
|
// Get nodes tab
|
|
var tab = getNodesTab();
|
|
var newTabId = node + 'LogsTab';
|
|
|
|
// If there is no existing clone tab
|
|
if (!$('#' + newTabId).length) {
|
|
// Get table headers
|
|
var tableId = $('#' + node).parents('table').attr('id');
|
|
var headers = $('#' + tableId).parents('.dataTables_scroll').find('.dataTables_scrollHead thead tr:eq(0) th');
|
|
var cols = new Array();
|
|
for ( var i = 0; i < headers.length; i++) {
|
|
var col = headers.eq(i).text();
|
|
cols.push(col);
|
|
}
|
|
|
|
// Get hardware control point column
|
|
var hcpCol = $.inArray('hcp', cols);
|
|
|
|
// Get hardware control point
|
|
var nodeRow = $('#' + node).parent().parent();
|
|
var datatable = $('#' + getNodesTableId()).dataTable();
|
|
var rowPos = datatable.fnGetPosition(nodeRow.get(0));
|
|
var aData = datatable.fnGetData(rowPos);
|
|
var hcp = aData[hcpCol];
|
|
|
|
// Create status bar and hide it
|
|
var statBarId = node + 'CloneStatusBar';
|
|
var statBar = createStatusBar(statBarId).hide();
|
|
|
|
// Create info bar
|
|
var infoBar = createInfoBar('Retrieve, clear, or set options for event logs.');
|
|
|
|
// Create clone form
|
|
var logForm = $('<div class="form"></div>');
|
|
logForm.append(statBar);
|
|
logForm.append(infoBar);
|
|
|
|
// Create VM fieldset
|
|
var vmFS = $('<fieldset></fieldset>');
|
|
var vmLegend = $('<legend>Virtual Machine</legend>');
|
|
vmFS.append(vmLegend);
|
|
logForm.append(vmFS);
|
|
|
|
var vmAttr = $('<div style="display: inline-table; vertical-align: middle;"></div>');
|
|
vmFS.append($('<div style="display: inline-table; vertical-align: middle;"><img src="images/provision/computer.png"></img></div>'));
|
|
vmFS.append(vmAttr);
|
|
|
|
// Create logs fieldset
|
|
var logFS = $('<fieldset></fieldset>');
|
|
var logLegend = $('<legend>Logs</legend>');
|
|
logFS.append(logLegend);
|
|
logForm.append(logFS);
|
|
|
|
var logAttr = $('<div style="display: inline-table; vertical-align: middle;"></div>');
|
|
logFS.append($('<div style="display: inline-table; vertical-align: middle;"><img src="images/nodes/log.png"></img></div>'));
|
|
logFS.append(logAttr);
|
|
|
|
vmAttr.append('<div><label>Target node range:</label><input type="text" id="tgtNode" name="tgtNode" value="' + node + '" title="You must give a node or a node range. A node range must be given as: node1-node9 or node[1-9]."/></div>');
|
|
logAttr.append('<div><label>Source log:</label><input type="text" name="srcLog" title="The log file to retrieve, clear, or set."/></div>');
|
|
|
|
var optsLabel = $('<label>Options:</label>');
|
|
var optsList = $('<ul></ul>');
|
|
logAttr.append(optsLabel);
|
|
logAttr.append(optsList);
|
|
|
|
// Create retrieve log checkbox
|
|
var retrieveChkBox = $('<li><input type="checkbox" name="s"/></li>');
|
|
optsList.append(retrieveChkBox);
|
|
retrieveChkBox.append('Retrieve log');
|
|
|
|
// Create log destination input
|
|
var tgtLog = $('<li><label>Log destination:</label><input type="text" name="tgtLog"/></li>');
|
|
tgtLog.hide();
|
|
optsList.append(tgtLog);
|
|
|
|
// Create set log checkbox
|
|
var setChkBox = $('<li><input type="checkbox" name="o"/></li>');
|
|
optsList.append(setChkBox);
|
|
setChkBox.append('Set options');
|
|
|
|
// Create log options input
|
|
var logOpt = $('<li><label>Log options:</label><input type="text" name="logOpt"/></li>');
|
|
logOpt.hide();
|
|
optsList.append(logOpt);
|
|
|
|
// Create clear log checkbox
|
|
var clearChkBox = $('<li><input type="checkbox" name="c"/></li>');
|
|
optsList.append(clearChkBox);
|
|
clearChkBox.append('Clear log');
|
|
|
|
retrieveChkBox.bind('click', function(event) {
|
|
tgtLog.toggle();
|
|
});
|
|
|
|
setChkBox.bind('click', function(event) {
|
|
logOpt.toggle();
|
|
});
|
|
|
|
// Generate tooltips
|
|
logForm.find('div input[title]').tooltip({
|
|
position : "center right",
|
|
offset : [ -2, 10 ],
|
|
effect : "fade",
|
|
opacity : 0.7,
|
|
predelay: 800,
|
|
events : {
|
|
def : "mouseover,mouseout",
|
|
input : "mouseover,mouseout",
|
|
widget : "focus mouseover,blur mouseout",
|
|
tooltip : "mouseover,mouseout"
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Run node
|
|
*/
|
|
var runBtn = createButton('Run');
|
|
runBtn.bind('click', function(event) {
|
|
// Remove any warning messages
|
|
$(this).parent().parent().find('.ui-state-error').remove();
|
|
|
|
var ready = true;
|
|
var errMsg = '';
|
|
|
|
// Verify required inputs are provided
|
|
var inputs = $('#' + newTabId + ' input');
|
|
for ( var i = 0; i < inputs.length; i++) {
|
|
if (!inputs.eq(i).val()
|
|
&& inputs.eq(i).attr('name') != 'tgtLog'
|
|
&& inputs.eq(i).attr('name') != 'logOpt') {
|
|
inputs.eq(i).css('border', 'solid #FF0000 1px');
|
|
ready = false;
|
|
} else {
|
|
inputs.eq(i).css('border', 'solid #BDBDBD 1px');
|
|
}
|
|
}
|
|
|
|
// Write error message
|
|
if (!ready) {
|
|
errMsg = errMsg + 'Please provide a value for each missing field.<br>';
|
|
}
|
|
|
|
var tgts = $('#' + newTabId + ' input[name=tgtNode]').val();
|
|
var srcLog = $('#' + newTabId + ' input[name=srcLog]').val();
|
|
|
|
var chkBoxes = $("#" + newTabId + " input[type='checkbox']:checked");
|
|
var optStr = '-s;' + srcLog + ';';
|
|
var opt;
|
|
for ( var i = 0; i < chkBoxes.length; i++) {
|
|
opt = chkBoxes.eq(i).attr('name');
|
|
optStr += '-' + opt;
|
|
|
|
// If it is the retrieve log
|
|
if (opt == 's') {
|
|
// Append log destination
|
|
optStr += ';' + $('#' + newTabId + ' input[name=tgtLog]').val();
|
|
}
|
|
|
|
// If it is set options
|
|
if (opt == 'o') {
|
|
// Append options
|
|
optStr += ';' + $('#' + newTabId + ' input[name=logOpt]').val();
|
|
}
|
|
|
|
// Append ; to end of string
|
|
if (i < (chkBoxes.length - 1)) {
|
|
optStr += ';';
|
|
}
|
|
}
|
|
|
|
// If a value is given for every input
|
|
if (ready) {
|
|
// Disable all inputs
|
|
var inputs = $('#' + newTabId + ' input');
|
|
inputs.attr('disabled', 'disabled');
|
|
|
|
/**
|
|
* (1) Retrieve, clear, or set options for event logs
|
|
*/
|
|
$.ajax( {
|
|
url : 'lib/cmd.php',
|
|
dataType : 'json',
|
|
data : {
|
|
cmd : 'reventlog',
|
|
tgt : tgts,
|
|
args : optStr,
|
|
msg : 'out=' + statBarId + ';cmd=reventlog;tgt=' + tgts
|
|
},
|
|
|
|
success : updateStatusBar
|
|
});
|
|
|
|
// Create loader
|
|
$('#' + statBarId).find('div').append(createLoader());
|
|
$('#' + statBarId).show();
|
|
|
|
// Disable run button
|
|
$(this).attr('disabled', 'true');
|
|
} else {
|
|
// Show warning message
|
|
var warn = createWarnBar(errMsg);
|
|
warn.prependTo($(this).parent().parent());
|
|
}
|
|
});
|
|
logForm.append(runBtn);
|
|
|
|
// Add clone tab
|
|
tab.add(newTabId, 'Logs', logForm, true);
|
|
}
|
|
|
|
tab.select(newTabId);
|
|
}; |