diff --git a/xCAT-UI/js/configure/discover.js b/xCAT-UI/js/configure/discover.js
index 8c55d67db..c208103c8 100644
--- a/xCAT-UI/js/configure/discover.js
+++ b/xCAT-UI/js/configure/discover.js
@@ -1,28 +1,39 @@
/*associate the step name with step number*/
var steps = ['Discover Hardware',
'Cluster Patterns',
- 'Switch Ports',
+ 'Supernode Numbers',
'More Cluster Patterns',
- 'Prepare Management Node',
'Power On Hardware',
- 'Discover HW Control Points',
+ 'Discover Frames',
+ 'Prepare Management Node',
'Update Definitions',
- 'Configure HW Control Points',
- 'Create Nodes',
+ 'Create Lpars',
'Complete'];
/*associate the function with step number*/
var initFunctions = [initSelectPlatform,
initBasicPattern,
- initSwitch,
- initAdvancedPattern];
+ initSupernode,
+ initSiteTable,
+ initPoweronHardware,
+ initDiscoverFrames,
+ initConfig,
+ initUpdateDefinition,
+ initCreateLpar,
+ complete];
/*associate the function witch should be called before the page changed(when click next or back)
* if there is no need to call functions, use undefined.*/
-var nextFunctions = [undefined,
+var nextFunctions = [getPlatform,
+ checkBasicPattern,
+ checkSupernode,
+ checkSiteTable,
+ undefined,
+ checkFrameMtms,
+ undefined,
+ undefined,
collectInputValue,
- collectInputValue,
- collectInputValue];
+ undefined];
/*save current step number*/
var currentStep = 0;
@@ -81,7 +92,7 @@ function createDiscoverButtons(){
cancelButton.bind('click', function(){
$('#discoverTab').empty();
for (var name in discoverEnv){
- delete discoverEnv[name];
+ removeDiscoverEnv(name);
}
loadDiscoverPage();
});
@@ -106,6 +117,7 @@ function createDiscoverButtons(){
* @return
*/
function createNextButton(){
+ var tempFlag = true;
if ((steps.length - 1) == currentStep){
return undefined;
}
@@ -113,11 +125,15 @@ function createNextButton(){
var nextButton = createButton('Next');
nextButton.bind('click', function(){
if (nextFunctions[currentStep]){
- nextFunctions[currentStep]();
+ tempFlag = nextFunctions[currentStep]('next');
+ }
+
+ if (!tempFlag){
+ return;
}
currentStep ++;
updateDiscoverStep();
- initFunctions[currentStep]();
+ initFunctions[currentStep]('next');
});
return nextButton;
@@ -131,6 +147,7 @@ function createNextButton(){
* @return
*/
function createBackButton(){
+ var tempFlag = true;
if (0 == currentStep){
return undefined;
}
@@ -138,11 +155,16 @@ function createBackButton(){
var backButton = createButton('Back');
backButton.bind('click', function(){
if (nextFunctions[currentStep]){
- nextFunctions[currentStep]();
+ tempFlag = nextFunctions[currentStep]('back');
}
+
+ if (!tempFlag){
+ return;
+ }
+
currentStep--;
updateDiscoverStep();
- initFunctions[currentStep]();
+ initFunctions[currentStep]('back');
});
return backButton;
@@ -166,6 +188,35 @@ function getDiscoverEnv(envName){
return '';
}
}
+
+/**
+ * set the input value on discover page
+ *
+ * @param
+ * envName : value's name(discoverEnv's key)
+ * envValue: value
+ * @return null.
+ */
+function setDiscoverEnv(envName, envValue){
+ if (envName){
+ discoverEnv[envName] = envValue;
+ }
+}
+
+/**
+ * delete the input value on discover page
+ *
+ * @param
+ * envName : value's name(discoverEnv's key)
+ *
+ * @return null.
+ */
+function removeDiscoverEnv(envName){
+ if (discoverEnv[envName]){
+ delete discoverEnv[envName];
+ }
+}
+
/**
* Expand the noderange into node names.
*
@@ -239,6 +290,29 @@ function expandNR(nodeRange){
return retArray;
}
+/**
+ * collect all inputs' value from the page
+ *
+ * @param
+ *
+ * @return true: this step is correct, can go to the next page
+ * false: this step contains error.
+ */
+function collectInputValue(){
+ $('#discoverContentDiv input[type=text]').each(function(){
+ var name = $(this).attr('name');
+ var value = $(this).attr('value');
+ if('' != value){
+ setDiscoverEnv(name, value);
+ }
+ else{
+ removeDiscoverEnv(name);
+ }
+ });
+
+ return true;
+}
+
/**
* Step 1: show the wizard's function
* platform selector(system P or system X)
@@ -249,20 +323,44 @@ function expandNR(nodeRange){
*/
function initSelectPlatform(){
var temp = '';
+ var type = '';
$('#discoverContentDiv').empty();
- temp += '
' + steps[currentStep] + '
';
+ $('.tooltip').remove();
+ temp += '
' + steps[currentStep] + '
';
temp += '
This wizard will guide you through the process of defining the naming conventions within' +
'your cluster, discovering the hardware on your network, and automatically defining it in the xCAT' +
'database. Choose which type of hardware you want to discover, and then click Next.
';
temp += ' System x hardware (not implemented yet) ';
- temp += ' System p hardware (only partially implemented) ';
- temp += '
';
+ temp += ' System p hardware (P7 IH) ';
+ temp += ' System p hardware (Non P7 IH) ';
+ temp += '
';
$('#discoverContentDiv').append(temp);
+ if (getDiscoverEnv('machineType')){
+ type = getDiscoverEnv('machineType');
+ }
+ else{
+ type = 'ih';
+ }
+
+ $('#discoverContentDiv #' + type).attr('checked', 'checked');
createDiscoverButtons();
}
+/**
+ * Step 1: Get the platform type
+ *
+ * @param
+ *
+ * @return
+ */
+function getPlatform(){
+ var radioValue = $('#discoverContentDiv :checked').attr('id');
+ setDiscoverEnv('machineType', radioValue);
+
+ return true;
+}
/**
* Step 2: Cluster basic patterns
* users can input the switches' name range, the number of port, start ip and port prefix
@@ -276,117 +374,1159 @@ function initSelectPlatform(){
*/
function initBasicPattern(){
$('#discoverContentDiv').empty();
- var showString = '
' + steps[currentStep] + '
';
+ $('.tooltip').remove();
+ var showString = '
' + steps[currentStep] + '
';
showString += '
';
- //switch title
- showString += '
Service LAN Switches
';
- //switch name
- showString += '
Hostname Range:
';
- showString += '
';
- //switch start ip
- showString += '
Starting IP Address:
';
- //Number of Ports Per Switch
- showString += '
Number of Ports Per Switch:
';
- showString += '
';
- //ports' name prefix
- showString += '
Switch Port Prefix:
';
- //hmc title
- showString += '
HMCs
';
- //hmc name
- showString += '
Hostname Range:
';
- showString += '
';
- //hmc start ip
- showString += '
Starting IP Address:
';
- //Number of Frames per HMC
- showString += '
Number of Frames per HMC:
';
- //BPA title
- showString += '
Frames (BPAs)
';
- //BPA Name
- showString += '
Hostname Range:
';
- showString += '
';
- //BPA start ip
- showString += '
Starting IP Address:
';
- //Number of Drawers per Frame
- showString += '
Number of Drawers per Frame:
';
- //FSP title
- showString += '
Drawers (FSPs/CECs)
';
- //FSP name
- showString += '
Hostname Range:
';
- showString += '
';
- //FSP start ip
- showString += '
Starting IP Address:
';
+ //Frame title
+ showString += '
Frames:
';
+ //Frame Name
+ showString += '
Name Range:
';
+ //use the super node configure file to calculate the cec's number
+ showString += '
';
+
+ //CEC title
+ showString += '
Drawers:
';
+ //CEC name
+ showString += '
Name Range:
';
//Number of LPARs per Drawer:
- showString += '
Number of LPARs per Drawer:
';
- showString += '
';
+ showString += '
Number of LPARs per Drawer:
';
+
+ //Lpar title
+ showString += '
Lpars:
';
+ //lpar name
+ showString += '
Name Range:
';
+
+ //hmc title
+ showString += '
HMCs:
';
+ //hmc name
+ showString += '
Name Range:
';
+ //Number of Frames per HMC
+ showString += '
Number of Frames per HMC:
';
+ showString += '
Hardware Managment:
HMC ';
+ showString += 'DFM
';
+ showString += '
';
+
$('#discoverContentDiv').append(showString);
- $('#discoverContentDiv input[type=text][title]').tooltip({
+
+ $('#discoverContentDiv [title]').tooltip({
position: "center right",
offset: [-2, 10],
effect: "fade",
opacity: 1
});
+
+ //change the radio inputs' checked status
+ if (getDiscoverEnv('hmcFlag')){
+ $('#discoverContentDiv :radio[value=hmc]').attr('checked', 'checked');
+ }
+ else{
+ $('#discoverContentDiv :radio[value=dfm]').attr('checked', 'checked');
+ }
+
createDiscoverButtons();
}
/**
- * Step 2: Cluster basic patterns
- * save all of users' input into the global object discoverEnv
- *
+ * Step 2: check basic patterns
+ * when user input the basic patterns, we should check if the input is correct.
* @param
*
* @return
*/
-function collectInputValue(){
- $('#discoverContentDiv input[type=text]').each(function(){
- var name = $(this).attr('name');
- var value = $(this).attr('value');
- if('' != value){
- discoverEnv[name] = value;
- }
- else{
- if(discoverEnv[name]){
- delete discoverEnv[name];
- }
- }
- });
+function checkBasicPattern(operType){
+ collectInputValue();
+
+ //click back button, do not need check, only collect input value is ok.
+ if ('back' == operType){
+ return true;
+ }
- return;
+ $('#patternDiv .ui-state-error').remove();
+
+ var errMessage = '';
+ var tempName = '';
+ var frameNum = 0;
+ var cecNum = 0;
+ var lparNum = 0;
+ var hmcNum = 0;
+ var cecNumPerFrame = getDiscoverEnv('cecNumPerFrame');
+ var frameNumPerHmc = getDiscoverEnv('frameNumPerHmc');
+ var lparNumPerCec = getDiscoverEnv('lparNumPerCec');
+
+ //check the frame name
+ tempName = getDiscoverEnv('frameName');
+ if (!tempName){
+ errMessage += 'Input the Frame Name Range. ';
+ }
+ else{
+ frameNum = expandNR(tempName).length;
+ }
+
+ //check the cec name
+ tempName = getDiscoverEnv('cecName');
+ if (!tempName){
+ errMessage += 'Input the CEC Name Range. ';
+ }
+ else{
+ cecNum = expandNR(tempName).length;
+ }
+
+ //lpar number per cec
+ if (!lparNumPerCec){
+ errMessage += 'Input the Lpar Number Per Drawer. ';
+ }
+
+ //check the lpar name
+ tempName = getDiscoverEnv('lparName');
+ if (!tempName){
+ errMessage += 'Input the Lpar Name Range. ';
+ }
+ else{
+ lparNum = expandNR(tempName).length;
+ }
+
+ //check the hmc name
+ tempName = getDiscoverEnv('hmcName');
+ if (!tempName){
+ errMessage += 'Input the HMC Name Range. ';
+ }
+ else{
+ hmcNum = expandNR(tempName).length;
+ }
+
+ //frame number per hmc
+ if (!frameNumPerHmc){
+ errMessage += 'Input the Frame Number Per HMC. ';
+ }
+
+ //the hardware management type is hmc.
+ if ('hmc' == $('#discoverContentDiv :checked').attr('value')){
+ setDiscoverEnv('hmcFlag', true);
+ }
+ else{
+ removeDiscoverEnv('hmcFlag');
+ }
+
+ //the input value check is finished.
+ if ('' != errMessage){
+ $('#patternDiv').prepend('
' + errMessage + '
');
+ return false;
+ }
+
+ //check the connections between all numbers.
+ if (getDiscoverEnv('hmcFlag')){
+ if ((Number(frameNumPerHmc) * hmcNum) < frameNum){
+ errMessage += 'The frame number should less than ' + Number(cecNumPerFrame) * frameNum +
+ ' ("the number of hmc" * "the number of frame managed by per hmc")';
+ }
+ }
+
+ if ((Number(lparNumPerCec) * cecNum) != lparNum){
+ errMessage += 'The number of Lpars calculate by Name Range should be ' + Number(lparNumPerCec) * cecNum +
+ '("the number of Drawers" * "the number of lpar per drawer")';
+ }
+
+ if ('' != errMessage){
+ $('#patternDiv').prepend('
');
+ createDiscoverButtons();
+
+ //add the introduction about the page
+ var infoStr = '
The supernode-list file lists what supernode numbers should be ';
+ infoStr += 'given to each CEC in each frame. Here is a sample file: ';
+ infoStr += 'frame1: 0, 1, 16 frame2: 17, 32 frame3: 33, 48, 49 ';
+ infoStr += 'frame4: 64 , 65, 80 frame5: 81, 96 frame6: 97(1), 112(1), 113(1), 37(1), 55, 71 ';
+ infoStr += 'The name before the colon is the node name of the frame BPC. The numbers after the colon ' +
+ 'are the supernode numbers to assign to the groups of CECs in that frame from bottom to top. ' +
+ 'Each supernode contains 4 CECs, unless it is immediately followed by "(#)", in which case the ' +
+ 'number in parenthesis indicates how many CECs are in this supernode.
';
+ var InfoBar = createInfoBar(infoStr);
+ $('#discoverContentDiv #supernodeDiv').append(InfoBar);
+
+ var frameArray = expandNR(getDiscoverEnv('frameName'));
+ var showStr = '
';
+ for (var i in frameArray){
+ showStr += '
' + frameArray[i] + ':
';
+ }
+ showStr += '
';
+ $('#discoverContentDiv #supernodeDiv').append(showStr);
+}
+
+/**
+ * Step 3: check the super node configure file
+ *
+ * @param
+ *
+ * @return
+ */
+function checkSupernode(operType){
+ collectInputValue();
+
+ if ('back' == operType){
+ return true;
+ }
+
+ $('#supernodeDiv .ui-state-error').remove();
+
+ var errString = '';
+ var eceNum = 0;
+ var args = '';
+ var frameArray = expandNR(getDiscoverEnv('frameName'));
+ for (var i in frameArray){
+ var sp_config = getDiscoverEnv('sp_' + frameArray[i]);
+ if (sp_config){
+ eceNum += calcCec(sp_config);
+ if (0 == i){
+ args += frameArray[i] + ': ' + sp_config;
+ }
+ else{
+ args += '\n' + frameArray[i] + ': ' + sp_config;
+ }
+ }
+ else{
+ errString += 'Input the super node configure for ' + frameArray[i] + ' ';
+ }
+ }
+
+ if (errString){
+ $('#supernodeDiv').prepend('
' + errString + '
');
+ return false;
+ }
+
+ var cecArray = expandNR(getDiscoverEnv('cecName'));
+ if (eceNum != cecArray.length){
+ errString += 'The number of CEC calculated from supernode configure is ' + eceNum + ', but the number ' +
+ 'calculated from CECs\' Name Range is ' + cecArray.length + '. Reconfigure the supernode please.';
+ $('#supernodeDiv').prepend('
' + errString + '
');
+ return false;
+ }
+
+ $.ajax({
+ url : 'lib/systemcmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'echo -e "' + args + '" > /tmp/websupernode.txt'
+ }
+ });
+ return true;
+}
+
+function calcCec(spConfigStr){
+ var tempArray = spConfigStr.split(',');
+ var num = 0;
+ var reg = /\(([1-4])\)/;
+ for (var i in tempArray){
+ var regRes = reg.exec(tempArray[i]);
+ if (regRes && regRes[1]){
+ num += Number(regRes[1]);
+ }
+ else{
+ num += 4;
+ }
+ }
+
+ return num;
+}
+
+/**
+ * Step 4: show the field which need to be configured in site table
+ *
+ * @param
+ *
+ * @return
+ */
+function initSiteTable(operType){
+ $('#discoverContentDiv').empty();
+ $('.tooltip').remove();
+ var showDiv = $('
');
+
+ if (getDiscoverEnv('framemtmsmap')){
+ $('#framedisc').html('Mapping the frame name and mtms which discovered by lsslp. ' +
+ 'Select the frame name, then select the mtms.');
+ var mapArray = getDiscoverEnv('framemtmsmap').split(':');
+ for(var i in mapArray){
+ var tempArray = mapArray[i].split(',');
+ showMap(tempArray[0], tempArray[1] + '-' + tempArray[2]);
+ }
+
+ createDiscoverButtons();
+ return;
+ }
+
+ statBar.append('Discovering all Frames by lsslp.').append(createLoader());
+ //use lsslp to find all bpas in cluster
+ $.ajax({
+ url : 'lib/cmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'webrun',
+ tgt : '',
+ args : 'discover;frame',
+ msg : ''
+ },
+
+ success : function(data){
+ var tempInfo = data.rsp[0];
+ if (-1 != tempInfo.indexOf('Error')){
+ $('#framedisc').html(tempInfo);
+ createDiscoverButtons();
+ return;
+ }
+
+ var mtmsArray = tempInfo.split(';');
+ var frameArray = expandNR(getDiscoverEnv('frameName'));
+ //chech the defined number and discovered number
+ if (mtmsArray.length != frameArray.length){
+ $('#framedisc').html('Error: Definded Number is ' + frameArray.length +
+ ', but lsslp discovered Number is ' + mtmsArray.length + ', please check your configure!');
+ createDiscoverButtons();
+ return;
+ }
+
+ $('#framedisc').html('Mapping the frame name and mtms which discovered by lsslp. ' +
+ 'Select the frame name, then select the mtms.');
+
+ for (var i in frameArray){
+ $('#frameTd').append('
' +
+ frameArray[i] + '
');
+
+ }
+ for (var i in mtmsArray){
+ $('#mtmsTd').append('
');
+ switch (getDiscoverEnv('machineType')){
+ case 'ih':{
+ ihCreateLpar(showDiv);
+ }
+ break;
+ case 'nonih':{
+ nonihCreateLpar(showDiv);
+ }
+ break;
+ default:
+ break;
+ }
+ $('#discoverContentDiv').append(showDiv);
+ createDiscoverButtons();
+}
+
+function ihCreateLpar(parentDiv){
+ var showStr = 'Partition Rule: ' +
+ 'If all the octants configuration value are same in one CEC, it will be " -r 0-7:value". ' +
+ 'If the octants use the different configuration value in one cec, it will be "-r 0:value1,1:value2,...7:value7", or "-r 0:value1,1-7:value2". ' +
+ 'The octants configuration value for one Octant could be 1, 2, 3, 4, 5 . The meanings of the octants configuration value are as following: ' +
+ '1 - 1 partition with all cpus and memory of the octant ' +
+ '2 - 2 partitions with a 50/50 split of cpus and memory ' +
+ '3 - 3 partitions with a 25/25/50 split of cpus and memory ' +
+ '4 - 4 partitions with a 25/25/25/25 split of cpus and memory ' +
+ '5 - 2 partitions with a 25/75 split of cpus and memory ' +
+ 'Define the configuration rule for one CEC, and create all Lpars on all CECs by this rule. Or ignore this step.';
+
+ parentDiv.append(createInfoBar(showStr));
+ parentDiv.append('
Partition Configuration:
' +
+ '
');
+
+ var lparButton = createButton('Create Lpars');
+ parentDiv.find('td').eq(2).append(lparButton);
+
+ lparButton.bind('click', function(){
+ var reg = /(([0-7]|[0-7]-[0-7]):[1-5],)*(([0-7]|[0-7]-[0-7]):[1-5])$/g;
+ var lparCount = 0;
+ $('#discoverContentDiv .ui-state-error').remove();
+ collectInputValue();
+ var inputStr = getDiscoverEnv('partconf');
+ var testArray = reg.exec(inputStr);
+ if (!testArray || inputStr != testArray[0]){
+ $('#discoverContentDiv').prepend('
' +
+ '
Input the correct configuration rule.
');
+ return;
+ }
+
+ var ruleArray = inputStr.split(',');
+ for(var i in ruleArray){
+ var octantCount = 0;
+ var octantArray = ruleArray[i].split(':');
+ var octantRule = Number(octantArray[1]);
+ var pos = octantArray[0].indexOf('-');
+ if (5 == octantRule){
+ octantRule = 2;
+ }
+
+ if (-1 == pos){
+ octantCount = 1;
+ }
+ else{
+ var startIndex = Number(octantArray[0].substring(0, pos));
+ var endIndex = Number(octantArray[0].substring(pos + 1));
+ octantCount = endIndex - startIndex + 1;
+ }
+
+ lparCount += octantCount * octantRule;
+ }
+
+ if(getDiscoverEnv('lparNumPerCec') != lparCount){
+ $('#discoverContentDiv').prepend('
' +
+ '
The Lpar number per CEC is ' + getDiscoverEnv('lparNumPerCec') + ', but the configuration ' +
+ 'rule calculation is ' + lparCount + '.