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 += ''; - //switch name - showString += ''; - showString += ''; - //switch start ip - showString += ''; - //Number of Ports Per Switch - showString += ''; - showString += ''; - //ports' name prefix - showString += ''; - //hmc title - showString += ''; - //hmc name - showString += ''; - showString += ''; - //hmc start ip - showString += ''; - //Number of Frames per HMC - showString += ''; - //BPA title - showString += ''; - //BPA Name - showString += ''; - showString += ''; - //BPA start ip - showString += ''; - //Number of Drawers per Frame - showString += ''; - //FSP title - showString += ''; - //FSP name - showString += ''; - showString += ''; - //FSP start ip - showString += ''; + //Frame title + showString += ''; + //Frame Name + showString += ''; + //use the super node configure file to calculate the cec's number + showString += ''; + + //CEC title + showString += ''; + //CEC name + showString += ''; //Number of LPARs per Drawer: - showString += ''; - showString += '
Service LAN Switches
Hostname Range:Starting IP Address:
Number of Ports Per Switch:Switch Port Prefix:
HMCs
Hostname Range:Starting IP Address:
Number of Frames per HMC:
Frames (BPAs)
Hostname Range:Starting IP Address:
Number of Drawers per Frame:
Drawers (FSPs/CECs)
Hostname Range:Starting IP Address:

Frames:

Name Range:

Drawers:

Name Range:
Number of LPARs per Drawer:
'; + 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('

' + errMessage + '

'); + return false; + } + + setDiscoverEnv('cecNum', cecNum); + setDiscoverEnv('frameNum', frameNum); + setDiscoverEnv('lparNum', lparNum); + setDiscoverEnv('hmcNum', hmcNum); + return true; } /** - * Step 3: define switch ports + * Step 3: allowed the users to edit the super node condigure file * * @param * * @return */ -function initSwitch(){ +function initSupernode(){ $('#discoverContentDiv').empty(); - var showString = '

' + steps[currentStep] + '

'; - showString += ''; - //Discovery Information title - showString += ''; - //Dynamic IP Range for DHCP - showString += ''; - showString += ''; - //IP Address to Broadcast - showString += ''; + $('.tooltip').remove(); + $('#discoverContentDiv').append('

' + steps[currentStep] + '

'); + 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 = '
Switch Port Assignments
Dynamic IP Range for DHCP:IP Address to Broadcast From:
'; + for (var i in frameArray){ + showStr += ''; + } + showStr += '
' + frameArray[i] + ':
'; + $('#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 = $('

' + steps[currentStep] + '(Site info)

'); + var statBar = createStatusBar('siteTableStat'); + statBar.append(createLoader()); + showDiv.append(statBar); + $('#discoverContentDiv').append(showDiv); + + if (getDiscoverEnv('domainname')){ + showSiteArea(); + return; + } + + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'tabdump', + tgt : '', + args : 'site', + msg : '' + }, + + success : function(data){ + setDiscoverEnv('domainname', ''); + setDiscoverEnv('nameserver',''); + for (var i in data.rsp){ + var tempArray = data.rsp[i].split(','); + var tempValue = tempArray[1]; + switch (tempArray[0]){ + case '"domain"':{ + setDiscoverEnv('domainname', tempValue.substr(1, tempValue.length - 2)); + } + break; + case '"nameservers"':{ + setDiscoverEnv('nameserver', tempValue.substr(1, tempValue.length - 2)); + } + break; + } + } + + showSiteArea(); + } + }); +} + +/** + * Step 4: when the values are ready, create the table + * + * @param + * + * @return + */ +function showSiteArea(){ + var showString = ''; + //domain name: + showString += ''; + + //Name server + showString += ''; + + //ntp server + showString += ''; showString += '
Domain Name:
Name server:
DHCP Dynamic Range:-
'; - $('#discoverContentDiv').append(showString); + + $('#discoverContentDiv div').eq(0).append(showString); + + $('#discoverContentDiv [title]').tooltip({ + position: "center right", + offset: [-2, 10], + effect: "fade", + opacity: 1 + }); + + $('#discoverContentDiv input[name=ipStart]').bind('change', function(){ + var reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-4])$/; + if (reg.test($(this).attr('value'))){ + var tempNum = Number(getDiscoverEnv('frameNum')) * 4 + Number(getDiscoverEnv('cecNum')) * 4 + + Number(getDiscoverEnv('lparNum')) + Number(getDiscoverEnv('hmcNum')); + var ipEnd = calcEndIp($(this).attr('value'), tempNum); + if (!reg.test(ipEnd)){ + ipEnd = ''; + } + $('#discoverContentDiv input[name=ipEnd]').attr('value', ipEnd); + } + else{ + $('#discoverContentDiv input[name=ipEnd]').attr('value', ''); + } + }); + + //show the current network interface configure + $.ajax({ + url : 'lib/systemcmd.php', + dataType : 'json', + data : { + cmd : 'ifconfig | grep -E "encap|Mask"' + }, + + success : function(data){ + $('#discoverContentDiv #siteTableStat').html('Current network interface configuration:
' + 
+						data.rsp + '
'); + } + }); createDiscoverButtons(); } -function initAdvancedPattern(){ +function calcEndIp(ipStart, num){ + var sum = 0; + var tempNum = Number(num); + var temp = /(\d+)\.(\d+)\.(\d+)\.(\d+)/; + var ipArray = temp.exec(ipStart); + + ipArray.shift(); + sum = Number(ipArray[3]) + tempNum; + if (sum <= 254){ + ipArray[3] = sum; + return (ipArray.join('.')); + } + + ipArray[3] = sum % 254; + + sum = Number(ipArray[2]) + parseInt(sum / 254); + if (sum <= 255){ + ipArray[2] = sum; + return (ipArray.join('.')); + } + + ipArray[2] = sum % 255; + + sum = Number(ipArray[1]) + parseInt(sum / 255); + if (sum <= 255){ + ipArray[1] = sum; + return (ipArray.join('.')); + } + + ipArray[1] = sum % 255; + ipArray[0] = ipArray[0] + parseInt(sum / 255); + return (ipArray.join('.')); +} +/** + * Step 4: check the input are all filled + * + * @param + * + * @return + */ +function checkSiteTable(operType){ + $('#discoverContentDiv input[name=ipStart]').trigger('change'); + collectInputValue(); + + if ('back' == operType){ + return true; + } + + $('#discoverContentDiv .ui-state-error').remove(); + var errMessage = ''; + if (!getDiscoverEnv('domainname')){ + errMessage += 'Input the domain name.
'; + } + + if (!getDiscoverEnv('nameserver')){ + errMessage += 'Input the name server.
'; + } + + if (!getDiscoverEnv('ipEnd')){ + errMessage += 'Input the DHCP Dynamic Range.
'; + } + + if ('' == errMessage){ + return true; + } + + $('#discoverContentDiv #siteDiv').prepend('

' + errMessage + '

'); + return false; +} + +/** + * Step 5: told users to power on machines + * + * @param + * + * @return + */ +function initPoweronHardware(){ $('#discoverContentDiv').empty(); - var showString = '

' + steps[currentStep] + '

'; - showString += ''; - showString += ''; - //Starting Subnet IP for Cluster Mgmt LAN: - showString += ''; - showString += ''; - //Compute Node Hostname Range - showString += ''; - showString += '
Building Blocks
Starting Subnet IP for Cluster Mgmt LAN:Compute Node Hostname Range:
'; - $('#discoverContentDiv').append(showString); + $('.tooltip').remove(); + var showStr = '

' + steps[currentStep] + + '

Do the following manual steps now:

'; + showStr += '
'; + + $('#discoverContentDiv').append(showStr); + createDiscoverButtons(); +} + +/** + * Step 6: discover all frames from the cluster and map all mtms with frame name + * + * @param + * + * @return + */ +function initDiscoverFrames(){ + $('#discoverContentDiv').empty(); + $('.tooltip').remove(); + var showDiv = $('

' + steps[currentStep] + '

'); + var statBar = createStatusBar('framedisc'); + showDiv.append(statBar); + $('#discoverContentDiv').append(showDiv); + $('#discoverShow').append('
' + + '
'); + + 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('

' + + mtmsArray[i] + '

'); + } + + createDiscoverButtons(); + } + }); +} + +function createMap(obj){ + var fname = ''; + var mname = ''; + + if ($('#discoverShow :checked').size() < 2){ + return; + } + + if('frameradio' == $(obj).attr('name')){ + fname = $(obj).next().html(); + mname = $('#discoverShow input[name=mtmsradio]:checked').next().html(); + } + else{ + fname = $('#discoverShow input[name=frameradio]:checked').next().html(); + mname = $(obj).next().html(); + } + + $('#discoverShow :checked').parent().remove(); + showMap(fname, mname); +} + +function showMap(fname, mname){ + var rowClass = ''; + + if ($('#discoverShow fieldset').size() < 1){ + $('#discoverShow').append('
Frame and MTMS map
'); + } + + if (0 == $('#discoverShow fieldset tr').size() % 2){ + rowClass = 'odd'; + } + else{ + rowClass = 'even'; + } + + $('#discoverShow fieldset table').append('' + fname + + '<---->' + mname + + ''); +} + +function deleteMap(obj){ + var mname = $(obj).parent().prev().html(); + var fname = $(obj).parent().prev().prev().prev().html(); + + $(obj).parent().parent().remove(); + + $('#frameTd').append('

' + fname + '

'); + $('#mtmsTd').append('

' + mname + '

'); +} + +/** + * Step 6: write the frame and mtms map file + * + * @param + * + * @return + */ +function checkFrameMtms(operType){ + //check the number of radio button + var vpdFileCon = ''; + $('#discoverShow .ui-state-error').remove(); + if (0 < $('#discoverShow :radio').size()){ + $('#discoverContentDiv #discoverShow').prepend('

' + + 'Map all of the frame with mtms.

'); + return false; + } + + //find out all maps + var maps = ''; + $('#discoverShow fieldset tr').each(function(){ + var fname = $(this).children().eq(0).html(); + var mtms = $(this).children().eq(2).html(); + var pos = mtms.lastIndexOf('-'); + + maps += (fname + ',' + mtms.substring(0, pos) + ',' + mtms.substring(pos + 1) + ':'); + vpdFileCon += fname + ':\n'; + vpdFileCon += ' objtype=node\n serial=' + mtms.substring(pos + 1) + '\n'; + vpdFileCon += ' mtm=' + mtms.substring(0, pos) + '\n side=A\n'; + }); + + maps = maps.substr(0, maps.length - 1); + setDiscoverEnv('framemtmsmap', maps); + + if ('back' == operType){ + return true; + } + + //write the maps into vpd table + $.ajax({ + url : 'lib/systemcmd.php', + dataType : 'json', + data : { + cmd : 'echo -e "' + vpdFileCon + '" > /tmp/webvpd.stanza' + } + }); + + return true; +} + +/** + * Step 7: create the xcatsetup configure file and run xcatsetup to define all objects + * in xcat database. + * + * @param + * + * @return + */ +function initConfig(operType){ + $('#discoverContentDiv').empty(); + $('.tooltip').remove(); + var showStr = '

' + steps[currentStep] + '

'; + var iconClass = ''; + if ('back' == operType){ + iconClass = 'ui-icon-check'; + } + else{ + iconClass = 'ui-icon-wrench'; + } + showStr += '
    '; + showStr += '
  • Create configure file for xcatsetup.
  • '; + showStr += '
  • Wrote Objects into xCAT database by xcatsetup.
  • '; + showStr += '
  • Configured DHCP.
  • '; + showStr += '
'; + + $('#discoverContentDiv').append(showStr); + + if ('back' == operType){ + createDiscoverButtons(); + return; + } + + createSetupFile(); +} +/** + * Step 7: create the xcat configure file + * + * @param + * + * @return + */ +function createSetupFile(){ + var fileContent = ''; + + $('#fileLine').append(createLoader()); + //site info + fileContent += 'xcat-site:\n'; + fileContent += ' domain = ' + getDiscoverEnv('domainname') + '\n'; + if (getDiscoverEnv('hmcFlag')){ + //do nothing + } + else{ + fileContent += ' use-direct-fsp-control = 1\n'; + } + + //dhcp ip range + fileContent += 'xcat-service-lan:\n'; + fileContent += ' dhcp-dynamic-range = ' + getDiscoverEnv('ipStart') + '-' + getDiscoverEnv('ipEnd') + '\n'; + + //hmc + if (getDiscoverEnv('hmcName')){ + fileContent += 'xcat-hmcs:\n'; + fileContent += ' hostname-range = ' + getDiscoverEnv('hmcName') + '\n'; + } + + //frame + fileContent += 'xcat-frames:\n'; + fileContent += ' hostname-range = ' + getDiscoverEnv('frameName') + '\n'; + fileContent += ' num-frames-per-hmc = ' + getDiscoverEnv('frameNumPerHmc') + '\n'; + fileContent += ' vpd-file = /tmp/webvpd.stanza\n'; + + //cec + fileContent += 'xcat-cecs:\n'; + fileContent += ' hostname-range = ' + getDiscoverEnv('cecName') + '\n'; + fileContent += ' delete-unused-cecs = 1\n'; + fileContent += ' supernode-list = /tmp/websupernode.txt\n'; + + //lpar + fileContent += 'xcat-lpars:\n'; + fileContent += ' num-lpars-per-cec = ' + getDiscoverEnv('lparNumPerCec') + '\n'; + fileContent += ' hostname-range = ' + getDiscoverEnv('lparName') + '\n'; + + $.ajax({ + url : 'lib/systemcmd.php', + dataType : 'json', + data : { + cmd : 'echo -e "' + fileContent + '" > /tmp/webxcat.conf' + }, + + success : function(){ + $('#fileLine img').remove(); + var tempSpan = $('#fileLine').find('span'); + tempSpan.removeClass('ui-icon-wrench'); + tempSpan.addClass('ui-icon-check'); + runSetup(); + } + }); +} + +/** + * Step 7: run the xcatsetup command + * + * @param + * + * @return + */ +function runSetup(){ + $('#setupLine').append(createLoader()); + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'xcatsetup', + tgt : '', + args : '/tmp/webxcat.conf', + msg : '' + }, + + success : function(){ + $('#setupLine img').remove(); + var tempSpan = $('#setupLine').find('span'); + tempSpan.removeClass('ui-icon-wrench'); + tempSpan.addClass('ui-icon-check'); + configDHCP(); + } + }); +} +/** + * Step 7: create the dhcp configure file + * + * @param + * + * @return + */ +function configDHCP(){ + $('#dhcpLine').append(createLoader()); + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'makedhcp', + tgt : '', + args : '-n', + msg : '' + }, + + success : function(){ + $('#dhcpLine img').remove(); + var tempSpan = $('#dhcpLine').find('span'); + tempSpan.removeClass('ui-icon-wrench'); + tempSpan.addClass('ui-icon-check'); + createDiscoverButtons(); + } + }); +} + +/** + * Step 8: discover all hmc,cec in cluster and update into xcat database + * + * @param + * + * @return + */ +function initUpdateDefinition(operType){ + $('#discoverContentDiv').empty(); + $('.tooltip').remove(); + var showStr = '

' + steps[currentStep] + '

'; + showStr += '
    '; + showStr += '
  • Update Frames into xCAT database.
  • '; + showStr += '
  • Discover HMCs.
  • '; + showStr += '
  • Update HMCs into xCAT database.
  • '; + showStr += '
  • Discover CECs and update into xCAT database.
  • '; + showStr += '
'; + + $('#discoverContentDiv').append(showStr); + + if ('back' == operType){ + createDiscoverButtons(); + return; + } + + lsslpWriteFrame(); +} + +/** + * Step 8: write all the lsslp -s FRAME info into database + * + * @param + * + * @return + */ +function lsslpWriteFrame(){ + $('#frameLine').append(createLoader()); + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'lsslp', + tgt : '', + args : '-s;BPA;-w', + msg : '' + }, + + success : function(){ + $('#frameLine img').remove(); + var tempSpan = $('#frameLine').find('span'); + tempSpan.removeClass('ui-icon-wrench'); + tempSpan.addClass('ui-icon-check'); + lsslpWriteHMC(); + } + }); +} + +/** + * Step 8: write all the lsslp -s HMC info into database + * + * @param + * + * @return + */ +function lsslpWriteHMC(){ + $('#hmcLine1').append(createLoader()); + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'webrun', + tgt : '', + args : 'discover;hmc', + msg : '' + }, + + success : function(data){ + //modify the page elements + $('#hmcLine1 img').remove(); + var tempSpan = $('#hmcLine1').find('span'); + tempSpan.removeClass('ui-icon-wrench'); + tempSpan.addClass('ui-icon-check'); + $('#hmcLine2').append(createLoader()); + + var hmcArray = expandNR(getDiscoverEnv('hmcName')); + var mtmsArray = data.rsp[0].split(';'); + var tempPar = ''; + + if(hmcArray.length != mtmsArray.length){ + //error info + $('#hmcLine2 img').remove(); + $('#discoverContentDiv div').append('

' + + 'Error: Defined ' + hmcArray.length + ' hmcs, but discovered ' + mtmsArray.length + + ' hmcs. Check the configuration please.

'); + createDiscoverButtons(); + return; + } + + //create the hmc and mtms pair string + for (var i in hmcArray){ + var tPos = mtmsArray[i].lastIndexOf('-'); + if ('' == tempPar){ + tempPar += hmcArray[i] + ',' + mtmsArray[i].substring(0, tPos) + ',' +mtmsArray[i].substring(tPos + 1); + } + else{ + tempPar += ':' + hmcArray[i] + ',' + mtmsArray[i].substring(0, tPos) + ',' +mtmsArray[i].substring(tPos + 1); + } + } + + //write the mtms and hmcname pair into vpd table + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'webrun', + tgt : '', + args : 'updatevpd;' + tempPar, + msg : '' + }, + success: function(){ + //run lsslp and write all infomation into datatable + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'lsslp', + tgt : '', + args : '-s;HMC;-w', + msg : '' + }, + success: function(){ + $('#hmcLine2 img').remove(); + var tempSpan = $('#hmcLine2').find('span'); + tempSpan.removeClass('ui-icon-wrench'); + tempSpan.addClass('ui-icon-check'); + lsslpWriteCec(); + } + }); + } + }); + } + }); +} + +/** + * Step 8: write all the lsslp -s cec info into database + * + * @param + * + * @return + */ +function lsslpWriteCec(){ + $('#cecLine').append(createLoader()); + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'lsslp', + tgt : '', + args : '-s;FSP;-w', + msg : '' + }, + success: function(){ + $('#cecLine img').remove(); + var tempSpan = $('#cecLine').find('span'); + tempSpan.removeClass('ui-icon-wrench'); + tempSpan.addClass('ui-icon-check'); + createDiscoverButtons(); + } + }); +} + +/** + * Step 9: create lpars + * + * @param + * + * @return + */ +function initCreateLpar(){ + $('#discoverContentDiv').empty(); + $('.tooltip').remove(); + var showDiv = $('

' + steps[currentStep] + '

'); + 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 + '.

'); + return; + } + + var diaDiv = $('
'); + diaDiv.append('
    '); + diaDiv.append(createLoader()); + diaDiv.dialog({ + modal: true, + width: 600, + title: 'Creating Lpars...' + }); + + $('.ui-dialog-titlebar-close').hide(); + + var cecArray = expandNR(getDiscoverEnv('cecName')); + for (var i in cecArray){ + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'mkvm', + tgt : cecArray[i] + 'nodes', + args : '-i;1;-m;non-interleaved;-r;' + inputStr, + msg : cecArray[i] + ';' + cecArray.length + }, + + success : function(data) { + //update the dialogure + var tempArray = data.msg.split(';'); + updateCreateLparDia(tempArray[0], Number(tempArray[1])); + } + }); + } + }); +} + +function updateCreateLparDia(cecname, cecNum){ + $('#createLparDiv ul').append('
  • Creating lpars on ' + cecname + ' competed.
  • '); + + if (cecNum != $('#createLparDiv li').size()){ + return; + } + + $('#createLparDiv').empty(); + $('#createLparDiv').append('

    All lpars are created. You must:
    1. reboot the all CECS.
    '+ + '2.use chvm to assign the I/O slots to the new LPAR.

    '); + + var chvmButton = createButton('OK'); + $('#createLparDiv').append(chvmButton); + chvmButton.bind('click', function(){ + $('#createLparDiv').dialog('destroy'); + $('#createLparDiv').remove(); + }); +} +function nonihCreateLpar(parentDiv){ + var showStr = 'The machine type is not P7 IH, so you had to create lpars by command line manually.'; + parentDiv.append(createInfoBar(showStr)); + return; +} +/** + * Step 10: compelte + * + * @param + * + * @return + */ +function complete(){ + $('#discoverContentDiv').empty(); + $('.tooltip').remove(); + var showStr = '

    ' + steps[currentStep] + '

    '; + showStr += 'You can go to the nodes page to check nodes which were defined just now.'; + $('#discoverContentDiv').append(showStr); + + createDiscoverButtons(); + } \ No newline at end of file diff --git a/xCAT-server/lib/xcat/plugins/web.pm b/xCAT-server/lib/xcat/plugins/web.pm index be12cbb28..127391948 100644 --- a/xCAT-server/lib/xcat/plugins/web.pm +++ b/xCAT-server/lib/xcat/plugins/web.pm @@ -1094,7 +1094,7 @@ sub web_createimage{ close($CONFILE); #write exlist for stateless - open($CONFILE, ">/install/custom/netboot/$ostype/$profile.exlist"); + open($CONFILE, ">$installdir/custom/netboot/$ostype/$profile.exlist"); print $CONFILE "#INCLUDE:/opt/xcat/share/xcat/IBMhpc/IBMhpc.$ostype.$osarch.exlist#\n"; close($CONFILE); @@ -1106,7 +1106,10 @@ sub web_createimage{ for my $soft (@softArray){ $soft = lc($soft); if ('gpfs' eq $soft){ - web_gpfsConfigure($ostype, $profile, $installdir); + web_gpfsConfigure($ostype, $profile, $osarch, $installdir); + } + elsif ('rsct' eq $soft){ + web_rsctConfigure($ostype, $profile, $osarch, $installdir); } } @@ -1132,6 +1135,7 @@ sub web_createimage{ my $retInfo = xCAT::Utils->runcmd( "${cmdPath}/genimage -i $bootif -n $netdriver -o $ostype -p $profile", -1, 1 ); $ret = join ("\n", @$retInfo); if ($::RUNCMD_RC){ + web_restoreChange($request->{arg}->[6], $archFlag, $imagetype, $ostype, $installdir); $callback->({data=>$ret}); return; } @@ -1177,7 +1181,9 @@ sub web_createimage{ for my $soft (@softArray){ $soft = lc($soft); - system ("grep '^[^#]' /opt/xcat/share/xcat/IBMhpc/$soft/litefile.csv >> /tmp/litefile.csv"); + if (-e /opt/xcat/share/xcat/IBMhpc/$soft/litefile.csv){ + system ("grep '^[^#]' /opt/xcat/share/xcat/IBMhpc/$soft/litefile.csv >> /tmp/litefile.csv"); + } } system("tabrestore /tmp/litefile.csv"); @@ -1186,47 +1192,121 @@ sub web_createimage{ my $retInfo = xCAT::Utils->runcmd( "${cmdPath}/genimage -i $bootif -n $netdriver -o $ostype -p $profile", -1, 1 ); $ret = join ("\n", @$retInfo); if ($::RUNCMD_RC){ + web_restoreChange($request->{arg}->[6], $archFlag, $imagetype, $ostype, $installdir); $callback->({data=>$ret}); return; } $ret .= "\n"; my $retInfo = xCAT::Utils->runcmd( "liteimg -o $ostype -p $profile -a $osarch", -1, 1 ); $ret .= join ("\n", @$retInfo); - - #restore the litefile table - system("rm -r /tmp/litefile.csv ; mv /tmp/litefilearchive.csv /tmp/litefile.csv ; tabrestore /tmp/litefile.csv"); } - #recover all file in the $installdir/custom/netboot/$ostype/ - if ($request->{arg}->[6]){ - system("rm -f $installdir/custom/netboot/$ostype/*.*"); - } - - if ($archFlag){ - system("mv /tmp/webImageArch/*.* $installdir/custom/netboot/$ostype/"); - } + web_restoreChange($request->{arg}->[6], $archFlag, $imagetype, $ostype, $installdir); $callback->({data=>$ret}); return; } sub web_gpfsConfigure{ - my ($ostype, $profile, $installdir) = @_; + my ($ostype, $profile, $osarch, $installdir) = @_; my $CONFILE; + + #createrepo + system('createrepo $installdir/post/otherpkgs/$ostype/$osarch/gpfs'); + #other pakgs open($CONFILE, ">>$installdir/custom/netboot/$ostype/$profile.otherpkgs.pkglist"); print $CONFILE "#INCLUDE:/opt/xcat/share/xcat/IBMhpc/gpfs/gpfs.otherpkgs.pkglist#\n"; close($CONFILE); #exlist - open ($CONFILE, ">>/install/custom/netboot/$ostype/$profile.exlist"); + open ($CONFILE, ">>$installdir/custom/netboot/$ostype/$profile.exlist"); print $CONFILE "#INCLUDE:/opt/xcat/share/xcat/IBMhpc/gpfs/gpfs.exlist#\n"; close ($CONFILE); #postinstall - system ('cp /opt/xcat/share/xcat/IBMhpc/gpfs/gpfs_mmsdrfs /install/postscripts/gpfs_mmsdrfs'); + system ('cp /opt/xcat/share/xcat/IBMhpc/gpfs/gpfs_mmsdrfs $installdir/postscripts/gpfs_mmsdrfs'); open($CONFILE, ">>$installdir/custom/netboot/$ostype/$profile.postinstall"); - print $CONFILE "NODESETSTATE=genimage installroot=\$1 /opt/xcat/share/xcat/IBMhpc/gpfs/gpfs_updates \n"; - print $CONFILE "installroot=$1 /install/postscripts/gpfs_mmsdrfs\n"; + print $CONFILE "NODESETSTATE=genimage installroot=\$1 /opt/xcat/share/xcat/IBMhpc/gpfs/gpfs_updates\n"; + print $CONFILE "installroot=\$1 $installdir/postscripts/gpfs_mmsdrfs\n"; close($CONFILE); } + +sub web_rsctConfigure{ + my ($ostype, $profile, $osarch, $installdir) = @_; + my $CONFILE; + + #createrepo + system('createrepo $installdir/post/otherpkgs/$ostype/$osarch/rsct'); + + #packagelist for sles11 + if ($ostype =~ /sles/i){ + open($CONFILE, ">>$installdir/custom/netboot/$ostype/$profile.pkglist"); + print $CONFILE "#INCLUDE:/opt/xcat/share/xcat/IBMhpc/rsct/rsct.pkglist# \n"; + close($CONFILE); + } + + #exlist + open ($CONFILE, ">>$installdir/custom/netboot/$ostype/$profile.exlist"); + print $CONFILE "#INCLUDE:/opt/xcat/share/xcat/IBMhpc/rsct/rsct.exlist#\n"; + close ($CONFILE); + + #postinstall + open($CONFILE, ">>$installdir/custom/netboot/$ostype/$profile.postinstall"); + print $CONFILE "installroot=\$1 rsctdir=/install/post/otherpkgs/rhels6/ppc64/rsct NODESETSTATE=genimage /opt/xcat/share/xcat/IBMhpc/rsct/rsct_install\n"; + close ($CONFILE); +} + +sub web_peConfigure{ + my ($ostype, $profile, $osarch, $installdir) = @_; + my $CONFILE; + + #createrepo + system('createrepo $installdir/post/otherpkgs/$ostype/$osarch/pe'); + system('createrepo $installdir/post/otherpkgs/$ostype/$osarch/compilers'); + + #pkglist + open($CONFILE, ">>$installdir/custom/netboot/$ostype/$profile.pkglist"); + if ($ostype =~ /rh/i){ + print $CONFILE "#INCLUDE:/opt/xcat/share/xcat/IBMhpc/pe/pe.$ostype.pkglist#\n"; + } + else{ + print $CONFILE "#INCLUDE:/opt/xcat/share/xcat/IBMhpc/compilers/compilers.pkglist#\n"; + print $CONFILE "#INCLUDE:/opt/xcat/share/xcat/IBMhpc/pe/pe.pkglist#\n"; + } + close($CONFILE); + + #otherpaglist + open($CONFILE, ">>$installdir/custom/netboot/$ostype/$profile.otherpkgs.pkglist"); + print $CONFILE "#INCLUDE:/opt/xcat/share/xcat/IBMhpc/pe/pe.otherpkgs.pkglist#\n"; + close($CONFILE); + + #exlist + open ($CONFILE, ">>$installdir/custom/netboot/$ostype/$profile.exlist"); + print $CONFILE "#INCLUDE:/opt/xcat/share/xcat/IBMhpc/compilers/compilers.exlist#\n"; + print $CONFILE "#INCLUDE:/opt/xcat/share/xcat/IBMhpc/pe/pe.exlist#\n"; + close ($CONFILE); + + #postinstall + open($CONFILE, ">>$installdir/custom/netboot/$ostype/$profile.postinstall"); + print $CONFILE "installroot=\$1 NODESETSTATE=genimage /opt/xcat/share/xcat/IBMhpc/compilers/compilers_license"; + print $CONFILE "installroot=\$1 pedir=/install/post/otherpkgs/rhels6/ppc64/pe NODESETSTATE=genimage /opt/xcat/share/xcat/IBMhpc/pe/pe_install"; + close ($CONFILE); +} + +sub web_restoreChange{ + my ($software, $archFlag, $imagetype, $ostype, $installdir) = @_; + #recover all file in the $installdir/custom/netboot/$ostype/ + if ($software){ + system("rm -f $installdir/custom/netboot/$ostype/*.*"); + } + + if ($archFlag){ + system("mv /tmp/webImageArch/*.* $installdir/custom/netboot/$ostype/"); + } + + #recover the litefile table for statelite image + if ('statelite' == $imagetype){ + system("rm -r /tmp/litefile.csv ; mv /tmp/litefilearchive.csv /tmp/litefile.csv ; tabrestore /tmp/litefile.csv"); + } +} 1; \ No newline at end of file