'Discover Hardware', 'patterns' => 'Cluster Patterns', 'patterns1b' => 'Switch Ports', 'patterns2' => 'More Cluster Patterns', 'preparemn' => 'Prepare Management Node', 'prediscover' => 'Power On Hardware', 'discover' => 'Discover HW Control Points', 'updatedefs' => 'Update Definitions', 'configurehcps' => 'Configure HW Control Points', 'createnodes' => 'Create Nodes', /* 'testhcps' => 'Test HW Control', */ 'done' => 'Complete', ); if (isset($_REQUEST['page'])) { displayWizard($pages); } else { // initial display of the wizard, show the whole page insertHeader('Discover New Nodes', array('discover.css',"$TOPDIR/lib/wizard.css"), array("$TOPDIR/lib/wizard.js"), array('machines','discover')); echo "
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."; echo " Choose which type of hardware you want to discover, and then click Next.
\n"; // The least hacky way to get this list left justified, but have the block in the center, is to use a table. CSS snobs, just deal with it. echo "\n"; } //----------------------------------------------------------------------------- function patterns($action, $step) { echo "\n"; //todo: get HCP userids/pws from the user } //----------------------------------------------------------------------------- function patterns1b($action, $step) { //todo: do validation of all pages that have input savePostVars(); // Figure out how many switches there need to be //todo: do not want to count the fsps if they are on the bpa hubs $hmcs = expandNR($_SESSION['hmcHostname']); $bpas = expandNR($_SESSION['bpaHostname']); $fsps = expandNR($_SESSION['fspHostname']); //echo "", implode(',',$hmcs), "
\n"; $total = count($hmcs) + count($bpas) + count($fsps); if (!$_SESSION['portsPerSwitch']) { $numswitches = 1; } else { $numswitches = (integer) ((($total-1) / $_SESSION['portsPerSwitch']) + 1); } //echo "$numswitches
\n"; echo "\n"; } //----------------------------------------------------------------------------- function patterns2($action, $step) { savePostVars(); echo "\n"; // do we need to get any info about the resources that should be in each lpar, or do we just divide them evenly? } //----------------------------------------------------------------------------- function preparemn($action, $step) { global $TOPDIR; if ($step == 0) { savePostVars(); insertProgressTable(array('Wrote xCAT switch table.', 'Wrote xCAT hosts table.', 'Defined networks.', 'Configured DHCP.', )); if ($action != 'back') { nextStep(1,FALSE); } } elseif ($step == 1) { writeSwitchTable($step); } elseif ($step == 2) { writeHostsTable($step); } elseif ($step == 3) { setDynRange(@$_SESSION["dynamicIP"], $step); } elseif ($step == 4) { makedhcp($step); } } //----------------------------------------------------------------------------- // Using the hcp and switch ranges, write out the switch table //todo: maybe should not use tabrestore in case we are just discovery additional hw function writeSwitchTable($step) { $hmcs = expandNR($_SESSION['hmcHostname']); $bpas = expandNR($_SESSION['bpaHostname']); $fsps = expandNR($_SESSION['fspHostname']); $switches = expandNR($_SESSION['switchHostname']); $numports = $_SESSION['portsPerSwitch']; $data = array(array('#node,switch,port,vlan,interface,comments,disable')); //echo "\n";
foreach ($switches as $k => $sw) {
$num = $k + 1;
$sequence = $_SESSION["switchSequence$num"];
$seq = preg_split('/[\s,]+/', $sequence);
$port = 1;
foreach ($seq as $s) { // each $s is something like: FSP:5
list($type, $num) = explode(':', $s);
$andFsps = NULL;
if (preg_match('/^hmc$/i',$type)) $ar=&$hmcs;
elseif (preg_match('/^bpa\/fsp$/i',$type)) { $ar=&$bpas; $andFsps=&$fsps; }
elseif (preg_match('/^bpa$/i',$type)) $ar=&$bpas;
elseif (preg_match('/^fsp$/i',$type)) $ar=&$fsps;
elseif (preg_match('/^space$/i',$type)) {if ($num=='*') {break;} $port+=$num; if ($port>$numports) break; else continue;}
else { msg('E', "Invalid HW component type: $s"); nextStep(++$step,TRUE); return; }
if ($num == '*') { $num = count($ar); }
for ($i=1; $i<=$num; $i++) {
$node = array_shift($ar);
if (!$node) { $port++; continue; }
$data[] = array($node,$sw,@$_SESSION['portPrefix'].$port);
for ($j=1; $j<=$_SESSION['numFspsPerFrame']; $j++) {
$f = array_shift($andFsps);
if (!$f) { break; }
$data[] = array($f,$sw,@$_SESSION['portPrefix'].$port);
}
/* $xml = docmd('nodeadd',NULL,array($node,'groups=all',"switch.node=$node","switch.switch=$sw","switch.port=$port"));
if (getXmlErrors($xml,$errors)) { msg('E',"nodeadd failed: " . implode(' ',$errors)); return; }
else { echo "Wrote: $node,$sw,$port
\n"; }*/
if (++$port > $numports) break 2;
}
}
}
//echo "
\n"; foreach ($machines as $ip => $ar) { // this loop goes thru each type of hw foreach ($ar as $hostname) { // this loop goes thru each of the hostnames for that type of hw $data[] = array($hostname,$ip); //echo "
Wrote: $hostname,$ip
\n"; myflush(); //sleep(1); // remove incrementIP($ip); } } //echo "\n"; myflush(); $xml = doTabrestore('hosts', $data); if (getXmlErrors($xml,$errors)) { msg('E',"tabrestore hosts failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } nextStep(++$step,FALSE); } //----------------------------------------------------------------------------- function incrementIP(& $ip) { //todo: hard coded for the percs demo cluster - remove //if ($ip == '192.168.200.233') { $ip='192.168.200.237'; return; } //if ($ip == '192.168.200.237') { $ip='192.168.200.239'; return; } $parts = explode('.', $ip); $parts[3]++; if ($parts[3] >= 255) { $parts[2]++; $parts[3] = 1; if ($parts[3] >= 255) { $parts[1]++; $parts[2] = 1; } // assume parts[1] is not 255, because we never increment the 1st field } $ip = implode('.', $parts); } //----------------------------------------------------------------------------- //todo: we need a better way to change the networks table than tabdump/tabrestore. We can not use chtab because its not client/svr. We can not use chdef because there is no netname defined by makenetworks. function setDynRange($range, $step) { if (isset($range) && !empty($range)) { // only set the dyn range if they entered it, otherwise another machine may be providing dynamic ranges // Get the whole table via tabdump $xml = docmd('tabdump','',array('networks')); if (getXmlErrors($xml,$errors)) { msg('E',"tabdump networks failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } $data = array(); foreach ($xml->children() as $response) foreach ($response->children() as $line) { $line = (string) $line; if(ereg("^#", $line)) { // handle the header specially $data[] = array($line); continue; } $values = splitTableFields($line); //todo: only give the dynamic range to the network that has same ip as the dyn range $values[8] = '"' . $range . '"'; // dynamicrange is the 9th field $data[] = $values; } // Now restore that data back into the networks table $xml = doTabrestore('networks', $data); if (getXmlErrors($xml,$errors)) { msg('E',"tabrestore networks failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } } nextStep(++$step,FALSE); } //----------------------------------------------------------------------------- function makedhcp($step) { //todo: remove this check because we should always be running makedhcp, but it is starting dhcpd, which we do not want on the demo system //todo: also can not do makedhcp on aix yet, but for now just do not set the dynamic ip if (isset($_SESSION["dynamicIP"]) && !empty($_SESSION["dynamicIP"])) { $xml = docmd('makedhcp',NULL,array('-n')); if (getXmlErrors($xml,$errors)) { msg('E',"makedhcp failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } } //todo: also need to restart makedhcp so the omapi config takes hold nextStep(++$step,TRUE); } //----------------------------------------------------------------------------- function prediscover($action, $step) { echo "\n";
echo " Do the following manual steps now: \n"; echo "
|
Discovered and defined ", $_SESSION['hmcHostname'], ".
\n"; myflush(); //$xml = docmd('nodeadd',NULL,array($_SESSION['bpaHostname'],'groups=frame,all','nodetype.nodetype=bpa','nodehm.mgt=hmc','nodehm.power=hmc','ppc.comments=bpa','vpd.mtm=9A00-100' /* ,'vpd.serial=|(\D+)(\d+)|($2)|' */ )); $xml = docmd('nodeadd',NULL,array($_SESSION['bpaHostname'],'groups=frame,all','nodetype.nodetype=bpa','ppc.hcp=|^(.+)$|($1)|','ppc.comments=bpa')); if (getXmlErrors($xml,$errors)) { msg('E',"nodeadd bpa failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } echo "Defined ", $_SESSION['bpaHostname'], ".
\n"; myflush(); echo "Discovering BPAs...
\n"; myflush(); //$xml = docmd('lsslp','',array('-s','BPA','-w','-H','-i',$discoverIP,'-c','1000,2000,2000,3000,4000')); $xml = docmd('lsslp','',array('-s','BPA','-w','-H','-i',$discoverIP,'-t','9')); if (getXmlErrors($xml,$errors)) { msg('E',"lsslp BPA failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } $numfound = 0; foreach ($xml->children() as $response) foreach ($response->children() as $line) { $line = (string) $line; //echo "$line
\n"; myflush(); $parts = array(); if (!preg_match('/^\s+(\S+)\s+=>/', $line, $parts)) { continue; } echo "found $parts[1]
\n"; myflush(); $numfound++; } echo "Found $numfound BPAs.
\n"; myflush(); //$parts = array(); //preg_match('/^(\D+)/', $_SESSION['bpaHostname'], $parts); //$bpaprefix = $parts[1]; //todo: we are hardcoding the cage # offset for now //todo: now that we use the real lsslp, it is not setting nodepos attrs //$xml = docmd('nodeadd',NULL,array($_SESSION['fspHostname'],'groups=cec,all','nodetype.nodetype=fsp','nodehm.mgt=hmc','nodehm.power=hmc','ppc.id=|\D+(\d+)|((((($1-1)%5)+1)*2)-1)|','ppc.parent=|\D+(\d+)|'.$bpaprefix.'((($1-1)/5)+1)|','nodepos.u=|\D+(\d+)|((((($1-1)%5)+1)*2)-1)|','nodepos.rack=|\D+(\d+)|((($1-1)/5)+1)|','vpd.mtm=9125-F2A' /* ,'vpd.serial=|(\D+)(\d+)|($2)|' */ )); $xml = docmd('nodeadd',NULL,array($_SESSION['fspHostname'],'groups=cec,all','nodetype.nodetype=fsp','ppc.hcp=|^(.+)$|($1)|','ppc.id=|\D+(\d+)|((($1-1)%'.$_SESSION['numFspsPerFrame'].')+5)|')); if (getXmlErrors($xml,$errors)) { msg('E',"nodeadd fsp failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } //todo: because of the irregularity in the cage numbers in frame 4 and 8, we have to do something special $fsps = expandNR($_SESSION['fspHostname']); $xml = docmd('nodech',"$fsps[36]-$fsps[41],$fsps[84]-$fsps[89]",array('ppc.id=|\D+(\d+)|((($1-1)%'.$_SESSION['numFspsPerFrame'].')+1)|')); if (getXmlErrors($xml,$errors)) { msg('E',"nodech frame failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } $xml = docmd('nodech',"$fsps[42]-$fsps[47],$fsps[90]-$fsps[95]",array('ppc.id=|\D+(\d+)|((($1-1)%'.$_SESSION['numFspsPerFrame'].')+3)|')); if (getXmlErrors($xml,$errors)) { msg('E',"nodech frame failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } echo "
Defined ", $_SESSION['fspHostname'], ".
Discovering FSPs...
\n"; myflush(); //$xml = docmd('lsslp','',array('-s','FSP','-w','-H','-i',$discoverIP,'-t','2','-c','3000,3000,3000,3000,3000')); $xml = docmd('lsslp','',array('-s','FSP','-w','-H','-i',$discoverIP,'-t','9')); if (getXmlErrors($xml,$errors)) { msg('E',"lsslp FSP failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } $numfound = 0; foreach ($xml->children() as $response) foreach ($response->children() as $line) { $line = (string) $line; $parts = array(); if (!preg_match('/^\s+(\S+)\s+=>/', $line, $parts)) { continue; } echo "found $parts[1]
\n"; myflush(); $numfound++; } echo "Found $numfound FSPs.
\n"; myflush(); /* $xml = docmd('chdef',NULL,array('-t','group','bpa','serial=|(\D+)(\d+)|($2)|','mtm=|(\D+)(\d+)|($1)|')); if (getXmlErrors($xml,$errors)) { msg('E',"chdef bpa failed: " . implode(' ',$errors)); return; } $xml = docmd('chdef',NULL,array('-t','group','fsp','serial=|(\D+)(\d+)|($2)|','mtm=|(\D+)(\d+)|($1)|')); if (getXmlErrors($xml,$errors)) { msg('E',"chdef fsp failed: " . implode(' ',$errors)); return; } */ nextStep(++$step,TRUE); } //----------------------------------------------------------------------------- function updatedefs($action, $step) { global $TOPDIR; if ($step == 0) { insertProgressTable(array('Assigned frame numbers.', 'Determined which CECs/Frames each HMC should manage.', 'Created HW control point node groups.', /* 'Assigned supernode numbers and building block numbers.', 'Assigned building block subnets.', */ 'Updated name resolution.', )); if ($action != 'back') { nextStep(1,FALSE); } } elseif ($step == 1) { assignframenums($step); } elseif ($step == 2) { assigncecs($step); } elseif ($step == 3) { createhcpgroups($step); } elseif ($step == 4) { nameres($step); } } //----------------------------------------------------------------------------- // Give frame numbers to each bpa function assignframenums($step) { //todo: this just uses the number from the nodename of the frame. Should instead count from the beginning. $xml = docmd('nodech','frame',array('ppc.id=|\D+(\d+)|($1)|')); if (getXmlErrors($xml,$errors)) { msg('E',"nodech frame failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } nextStep(++$step,FALSE); } //----------------------------------------------------------------------------- function assigncecs($step) { $numFrames = $_SESSION['numFramesPerHMC']; $hmcs = expandNR($_SESSION['hmcHostname']); $bpas = expandNR($_SESSION['bpaHostname']); $fsps = expandNR($_SESSION['fspHostname']); // 1st query ppc.parent of all fsps and save in a hash, so we can assign the bpa and its fsps to the // same hmc. $fspparent = getNodes($_SESSION['fspHostname'], array('ppc.parent')); $bpacecs = array(); foreach ($fspparent as $fsp => $parent) { $bpacecs[$parent][] = $fsp; } $h = 0; // start with the 1st hmc $b = 0; // Go thru the bpas taking groups of numFrames and assigning them to the next hmc while (TRUE) { // Get the next group of fsps $length = min($numFrames, count($bpas)-$b); $bslice = array_slice($bpas, $b, $length); // Assign the bpa to the hmc //trace("b=$b, numFrames=$numFrames, length=$length."); //echo "bpas:"; print_r($bpas); "
\n"; //trace("nodech ".implode(',',$bslice)); //$xml = docmd('nodech',implode(',',$bslice),array('nodehm.mgt=hmc',"ppc.hcp=$hmcs[$h]","ppc.parent=$hmcs[$h]")); $xml = docmd('nodech',implode(',',$bslice),array('nodehm.mgt=hmc',"ppc.hcp=$hmcs[$h]")); if (getXmlErrors($xml,$errors)) { msg('E',"nodech bpa failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } // Collect the list of the fsps in these bpas $fsprange = array(); foreach ($bslice as $b2) { $fsprange = array_merge($fsprange, $bpacecs[$b2]); } //trace("nodech ".implode(',',$fsprange)); $xml = docmd('nodech',implode(',',$fsprange),array('nodehm.mgt=hmc',"ppc.hcp=$hmcs[$h]")); if (getXmlErrors($xml,$errors)) { msg('E',"nodech fsp failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } // Decide if we are all out of bpas $h++; $b += $length; if ($h>=count($hmcs) || $b>=count($bpas)) break; } nextStep(++$step,FALSE); } //----------------------------------------------------------------------------- function createhcpgroups($step) { //todo: may need to do this once we are using the real lsslp nextStep(++$step,FALSE); } //----------------------------------------------------------------------------- // Run makehosts and makedns function nameres($step) { $xml = docmd('makehosts',NULL,NULL); if (getXmlErrors($xml,$errors)) { msg('E',"makehosts failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } //todo: enable this on non-aix //$xml = docmd('makedns',NULL,NULL); //if (getXmlErrors($xml,$errors)) { msg('E',"makedns failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } nextStep(++$step,TRUE); } //----------------------------------------------------------------------------- function configurehcps($action, $step) { global $TOPDIR; if ($step == 0) { insertProgressTable(array(array('Assigned CECs to their HMC.','disabled'), array('Set frame numbers in BPAs.','disabled'), array('Powered on CECs to Standby.','disabled'), )); if ($action != 'back') { nextStep(1,FALSE); } } elseif ($step == 1) { cecs2hmcs($step); } elseif ($step == 2) { setframenum($step); } elseif ($step == 3) { cecs2standby($step); } //todo: set HCP userids/pws } function cecs2hmcs($step) {nextStep(++$step,FALSE);} function setframenum($step) {nextStep(++$step,FALSE);} function cecs2standby($step) {nextStep(++$step,TRUE);} //----------------------------------------------------------------------------- function createnodes($action, $step) { global $TOPDIR; if ($step == 0) { insertProgressTable(array(array('Created LPARs in each CEC and save node definitions in xCAT database.','output'))); if ($action != 'back') { nextStep(1,FALSE); } } elseif ($step == 1) { createlpars($step); } //todo: set up rcons for the lpars (makeconserver.cf) } //----------------------------------------------------------------------------- function createlpars($step) { $numlpars = $_SESSION['numLPARs']; $fsps = expandNR($_SESSION['fspHostname']); $nodes = expandNR($_SESSION['computeNodename']); $n = 0; // index into the nodes array //$parts = array(); //preg_match('/^(\D+)/', $_SESSION['fspHostname'], $parts); //$fspprefix = $parts[1]; $fspattrs = getNodes($_SESSION['fspHostname'], array('ppc.hcp','ppc.parent')); // Go thru each fsp and create/define the nodes that should be in that fsp foreach ($fsps as $f) { $length = min($numlpars, count($nodes)-$n); $hcp = $fspattrs[$f]['ppc.hcp']; $bpa = $fspattrs[$f]['ppc.parent']; //todo: currently can not create the 1st lpar in the cec $xml = docmd('nodeadd',NULL,array($nodes[$n],"groups=lpars-$f,lpars-$bpa,lpars-$hcp,lpar,compute,all",'nodetype.nodetype=lpar,osi', 'nodehm.mgt=hmc','nodehm.power=hmc','nodehm.cons=hmc', 'nodetype.arch=ppc64','ppc.id=1', "ppc.parent=$f","ppc.hcp=$hcp","ppc.pprofile=$nodes[$n]")); if (getXmlErrors($xml,$errors)) { msg('E',"nodeadd nodes failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } echo "Created and defined $nodes[$n] in $f.
\n"; myflush(); $length--; $n++; if ($length == 0) continue; // the case of only 1 lpar per cec $nmax = $length + $n; $numnodes = 5; // how many lpars to create before displaying some output $n2 = $n; // Go thru $length nodes, $numnodes at a time, creating the lpars and defining the nodes in the db while (TRUE) { $length2 = min($numnodes, $nmax-$n2); $nslice = array_slice($nodes, $n2, $length2); $nstr = implode(',',$nslice); //todo: this assumes the lpar id starts at 3 for a cec $xml = docmd('nodeadd',NULL,array($nstr,"groups=lpars-$f,lpars-$bpa,lpars-$hcp,lpar,all",'nodetype.nodetype=lpar,osi', 'nodehm.mgt=hmc','nodehm.power=hmc','nodehm.cons=hmc','noderes.netboot=yaboot', 'nodetype.arch=ppc64','ppc.id=|\D+(\d+)|((($1-1)%'.$numlpars.')+3)|', "ppc.parent=$f","ppc.hcp=$hcp",'ppc.pprofile=diskless2')); if (getXmlErrors($xml,$errors)) { msg('E',"nodeadd nodes failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } // Actually make the lpar profiles. Todo: this is not actually creating the lpar, just a new profile for the existing lpars. if ($_SERVER["SERVER_ADDR"] != '192.168.153.128') { //todo: remove this check $xml = docmd('chvm',$nstr,array('-p','diskless2')); if (getXmlErrors($xml,$errors)) { msg('E',"chvm failed for $nstr: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } } echo "Created and defined $nstr in $f.
\n"; myflush(); $n2 += $length2; if ($n2 >= $nmax) break; } // Decide if we are all out of nodes $n += $length; if ($n >= count($nodes)) break; } // Also, the following assumes the node range starts with 1 and the fsp node range is simple. // Really need to do individual nodeadd for each node. /* $xml = docmd('nodeadd',NULL,array($_SESSION['computeNodename'],'groups=lpar,all','nodetype.nodetype=lpar,osi', 'nodehm.mgt=hmc','nodehm.power=hmc','nodehm.cons=hmc','noderes.netboot=yaboot', 'nodetype.arch=ppc64','ppc.id=|\D+(\d+)|((($1-1)%'.$numlpars.')+1)|', 'ppc.parent=|(\D+)(\d+)|'.$fspprefix.'((($2-1)/'.$numlpars.')+1)|')); if (getXmlErrors($xml,$errors)) { msg('E',"nodeadd nodes failed: " . implode(' ',$errors)); nextStep(++$step,TRUE); return; } */ nextStep(++$step,TRUE); } //----------------------------------------------------------------------------- // Flush the output buffers function myflush() { if ($_SERVER["SERVER_SOFTWARE"] != 'IBM_HTTP_Server') { ob_flush(); } // for some reason ob_flush() does not work on aix flush(); } //----------------------------------------------------------------------------- // Currently not used. function testhcps($action, $step) { global $TOPDIR; echo "Cluster set up successfully completed!
\n"; echo "You can now view your node definitions and start to deploy nodes.
\n"; echo "