2007-10-26 22:44:33 +00:00
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
2008-04-03 13:27:16 +00:00
package xCAT_plugin::anaconda ;
2008-09-12 22:40:15 +00:00
BEGIN
{
$ ::XCATROOT = $ ENV { 'XCATROOT' } ? $ ENV { 'XCATROOT' } : '/opt/xcat' ;
}
use lib "$::XCATROOT/lib/perl" ;
2007-10-26 22:44:33 +00:00
use Storable qw( dclone ) ;
use Sys::Syslog ;
2008-04-21 18:31:27 +00:00
use Thread qw( yield ) ;
use POSIX qw( WNOHANG nice ) ;
2007-10-26 22:44:33 +00:00
use xCAT::Table ;
2008-04-03 13:27:16 +00:00
use xCAT::Utils ;
use xCAT::MsgUtils ;
2009-09-19 17:03:14 +00:00
use xCAT::SvrUtils ;
2009-09-18 19:53:48 +00:00
#use Data::Dumper;
2007-10-26 22:44:33 +00:00
use Getopt::Long ;
Getopt::Long:: Configure ( "bundling" ) ;
Getopt::Long:: Configure ( "pass_through" ) ;
use File::Path ;
use File::Copy ;
2009-09-23 01:34:03 +00:00
#use strict;
2008-06-02 23:58:15 +00:00
my @ cpiopid ;
2007-10-26 22:44:33 +00:00
my % distnames = (
2008-05-05 19:34:58 +00:00
"1176234647.982657" = > "centos5" ,
"1156364963.862322" = > "centos4.4" ,
"1178480581.024704" = > "centos4.5" ,
"1195929648.203590" = > "centos5.1" ,
"1195929637.060433" = > "centos5.1" ,
2008-06-26 19:12:56 +00:00
"1213888991.267240" = > "centos5.2" ,
"1214240246.285059" = > "centos5.2" ,
2009-04-01 15:02:33 +00:00
"1237641529.260981" = > "centos5.3" ,
2008-05-05 19:34:58 +00:00
"1195488871.805863" = > "centos4.6" ,
"1195487524.127458" = > "centos4.6" ,
"1170973598.629055" = > "rhelc5" ,
"1170978545.752040" = > "rhels5" ,
"1192660014.052098" = > "rhels5.1" ,
"1192663619.181374" = > "rhels5.1" ,
2008-05-22 19:23:24 +00:00
"1209608466.515430" = > "rhels5.2" ,
"1209603563.756628" = > "rhels5.2" ,
"1209597827.293308" = > "rhels5.2" ,
2009-08-07 07:24:58 +00:00
"1231287803.932941" = > "rhels5.3" ,
"1231285121.960246" = > "rhels5.3" ,
2009-09-10 14:34:08 +00:00
"1250668122.507797" = > "rhels5.4" , #x86-64
"1250663123.136977" = > "rhels5.4" , #x86
"1250666120.105861" = > "rhels5.4" , #ppc
2008-05-05 19:34:58 +00:00
"1194015916.783841" = > "fedora8" ,
2008-05-15 17:30:13 +00:00
"1194015385.299901" = > "fedora8" ,
"1210112435.291709" = > "fedora9" ,
"1210111941.792844" = > "fedora9" ,
2009-02-09 17:17:55 +00:00
"1227147467.285093" = > "fedora10" ,
"1227142402.812888" = > "fedora10" ,
2009-12-17 21:40:14 +00:00
"1243981097.897160" = > "fedora11" , #x86_64 DVD ISO
"1257725234.740991" = > "fedora12" , #x86_64 DVD ISO
2008-05-05 19:34:58 +00:00
"1194512200.047708" = > "rhas4.6" ,
"1194512327.501046" = > "rhas4.6" ,
) ;
2007-10-26 22:44:33 +00:00
my % numdiscs = (
2008-05-05 19:34:58 +00:00
"1156364963.862322" = > 4 ,
"1178480581.024704" = > 3
) ;
sub handled_commands
{
return {
copycd = > "anaconda" ,
mknetboot = > "nodetype:os=(centos.*)|(rh.*)|(fedora.*)" ,
2009-06-16 14:15:00 +00:00
mkinstall = > "nodetype:os=(esx[34].*)|(centos.*)|(rh.*)|(fedora.*)" ,
2009-12-04 00:59:24 +00:00
mkstatelite = > "nodetype:os=(esx[34].*)|(centos.*)|(rh.*)|(fedora.*)" ,
2008-05-05 19:34:58 +00:00
} ;
2007-10-26 22:44:33 +00:00
}
2008-05-05 19:34:58 +00:00
2008-04-03 13:27:16 +00:00
sub preprocess_request
{
2008-05-05 19:34:58 +00:00
my $ req = shift ;
my $ callback = shift ;
2009-04-22 23:05:47 +00:00
return [ $ req ] ; #calls are only made from pre-farmed out scenarios
2008-05-05 19:34:58 +00:00
if ( $ req - > { command } - > [ 0 ] eq 'copycd' )
{ #don't farm out copycd
return [ $ req ] ;
}
2008-05-06 14:39:57 +00:00
my $ stab = xCAT::Table - > new ( 'site' ) ;
my $ sent ;
( $ sent ) = $ stab - > getAttribs ( { key = > 'sharedtftp' } , 'value' ) ;
unless ( $ sent
and defined ( $ sent - > { value } )
and ( $ sent - > { value } =~ /no/i or $ sent - > { value } =~ /0/ ) )
{
#unless requesting no sharedtftp, don't make hierarchical call
return [ $ req ] ;
}
2008-05-05 19:34:58 +00:00
my % localnodehash ;
2008-05-06 14:39:57 +00:00
my % dispatchhash ;
my $ nrtab = xCAT::Table - > new ( 'noderes' ) ;
2008-07-11 19:02:39 +00:00
my $ nrents = $ nrtab - > getNodesAttribs ( $ req - > { node } , [ qw( tftpserver servicenode ) ] ) ;
2008-05-05 19:34:58 +00:00
foreach my $ node ( @ { $ req - > { node } } )
{
2008-05-06 14:39:57 +00:00
my $ nodeserver ;
2008-07-11 19:02:39 +00:00
my $ tent = $ nrents - > { $ node } - > [ 0 ] ; #$nrtab->getNodeAttribs($node, ['tftpserver']);
2008-05-06 14:39:57 +00:00
if ( $ tent ) { $ nodeserver = $ tent - > { tftpserver } }
unless ( $ tent and $ tent - > { tftpserver } )
{
2008-07-11 19:02:39 +00:00
$ tent = $ nrents - > { $ node } - > [ 0 ] ; #$nrtab->getNodeAttribs($node, ['servicenode']);
2008-05-06 14:39:57 +00:00
if ( $ tent ) { $ nodeserver = $ tent - > { servicenode } }
}
if ( $ nodeserver )
{
$ dispatchhash { $ nodeserver } - > { $ node } = 1 ;
}
else
{
$ localnodehash { $ node } = 1 ;
}
2008-05-05 19:34:58 +00:00
}
my @ requests ;
my $ reqc = { %$ req } ;
$ reqc - > { node } = [ keys % localnodehash ] ;
if ( scalar ( @ { $ reqc - > { node } } ) ) { push @ requests , $ reqc }
2008-05-06 14:39:57 +00:00
foreach my $ dtarg ( keys % dispatchhash )
{ #iterate dispatch targets
my $ reqcopy = { %$ req } ; #deep copy
$ reqcopy - > { '_xcatdest' } = $ dtarg ;
$ reqcopy - > { node } = [ keys % { $ dispatchhash { $ dtarg } } ] ;
push @ requests , $ reqcopy ;
}
2008-05-05 19:34:58 +00:00
return \ @ requests ;
2008-04-03 13:27:16 +00:00
}
2008-05-05 19:34:58 +00:00
sub process_request
{
my $ request = shift ;
my $ callback = shift ;
my $ doreq = shift ;
my $ distname = undef ;
my $ arch = undef ;
my $ path = undef ;
if ( $ request - > { command } - > [ 0 ] eq 'copycd' )
{
return copycd ( $ request , $ callback , $ doreq ) ;
}
elsif ( $ request - > { command } - > [ 0 ] eq 'mkinstall' )
{
return mkinstall ( $ request , $ callback , $ doreq ) ;
}
2009-12-04 00:59:24 +00:00
elsif ( $ request - > { command } - > [ 0 ] eq 'mknetboot' or
$ request - > { command } - > [ 0 ] eq 'mkstatelite' )
2008-05-05 19:34:58 +00:00
{
return mknetboot ( $ request , $ callback , $ doreq ) ;
}
2007-10-26 22:44:33 +00:00
}
2008-05-05 19:34:58 +00:00
sub mknetboot
{
2009-02-21 14:25:29 +00:00
my $ xenstyle = 0 ;
2008-05-05 19:34:58 +00:00
my $ req = shift ;
2007-11-05 22:12:39 +00:00
my $ callback = shift ;
2008-05-05 19:34:58 +00:00
my $ doreq = shift ;
2009-12-04 00:59:24 +00:00
my $ statelite = 0 ;
if ( $ req - > { command } - > [ 0 ] =~ 'mkstatelite' ) {
$ statelite = "true" ;
}
2008-05-05 19:34:58 +00:00
my $ tftpdir = "/tftpboot" ;
2009-09-23 01:34:03 +00:00
my $ nodes = @ { $ req - > { node } } ;
2008-05-05 19:34:58 +00:00
my @ args = @ { $ req - > { arg } } ;
my @ nodes = @ { $ req - > { node } } ;
my $ ostab = xCAT::Table - > new ( 'nodetype' ) ;
my $ sitetab = xCAT::Table - > new ( 'site' ) ;
2009-09-23 01:34:03 +00:00
my $ linuximagetab ;
my $ osimagetab ;
my % img_hash = ( ) ;
2008-04-03 13:27:16 +00:00
my $ installroot ;
$ installroot = "/install" ;
2009-12-15 20:37:40 +00:00
my $ xcatdport = "3001" ;
2008-04-14 13:32:45 +00:00
2008-05-05 19:34:58 +00:00
if ( $ sitetab )
{
2009-09-23 01:34:03 +00:00
( my $ ref ) = $ sitetab - > getAttribs ( { key = > 'installdir' } , 'value' ) ;
2008-05-05 19:34:58 +00:00
if ( $ ref and $ ref - > { value } )
{
2007-11-05 22:12:39 +00:00
$ installroot = $ ref - > { value } ;
}
2009-12-15 20:37:40 +00:00
( $ ref ) = $ sitetab - > getAttribs ( { key = > 'xcatdport' } , 'value' ) ;
if ( $ ref and $ ref - > { value } )
{
$ xcatdport = $ ref - > { value } ;
}
2007-11-05 22:12:39 +00:00
}
2008-05-13 23:40:05 +00:00
my % donetftp = ( ) ;
2009-09-23 01:34:03 +00:00
my % oents = % { $ ostab - > getNodesAttribs ( \ @ nodes , [ qw( os arch profile provmethod ) ] ) } ;
2008-07-11 19:02:39 +00:00
my $ restab = xCAT::Table - > new ( 'noderes' ) ;
my $ bptab = xCAT::Table - > new ( 'bootparams' , - create = > 1 ) ;
my $ hmtab = xCAT::Table - > new ( 'nodehm' ) ;
2009-12-15 20:37:40 +00:00
my $ reshash = $ restab - > getNodesAttribs ( \ @ nodes , [ 'primarynic' , 'tftpserver' , 'xcatmaster' , 'nfsserver' , 'nfsdir' ] ) ;
2008-07-11 19:02:39 +00:00
my $ hmhash =
$ hmtab - > getNodesAttribs ( \ @ nodes ,
[ 'serialport' , 'serialspeed' , 'serialflow' ] ) ;
2009-12-15 20:37:40 +00:00
my $ statetab ;
my $ stateHash ;
if ( $ statelite ) {
$ statetab = xCAT::Table - > new ( 'statelite' , - create = > 1 ) ;
$ stateHash = $ statetab - > getNodeAttribs ( \ @ nodes , [ 'statemnt' ] ) ;
}
2009-06-29 18:41:00 +00:00
#my $addkcmdhash =
# $bptab->getNodesAttribs(\@nodes, ['addkcmdline']);
2009-09-23 01:34:03 +00:00
foreach my $ node ( @ nodes )
2008-05-05 19:34:58 +00:00
{
2009-09-23 01:34:03 +00:00
my $ osver ;
my $ arch ;
my $ profile ;
my $ platform ;
my $ rootimgdir ;
2008-07-11 14:12:05 +00:00
my $ ent = $ oents { $ node } - > [ 0 ] ; #ostab->getNodeAttribs($node, ['os', 'arch', 'profile']);
2009-12-04 00:59:24 +00:00
if ( $ ent and $ ent - > { provmethod } and ( $ ent - > { provmethod } ne 'install' ) and ( $ ent - > { provmethod } ne 'netboot' ) and ( $ ent - > { provmethod } ne 'statelite' ) ) {
2009-09-23 01:34:03 +00:00
my $ imagename = $ ent - > { provmethod } ;
#print "imagename=$imagename\n";
if ( ! exists ( $ img_hash { $ imagename } ) ) {
if ( ! $ osimagetab ) {
$ osimagetab = xCAT::Table - > new ( 'osimage' , - create = > 1 ) ;
}
( my $ ref ) = $ osimagetab - > getAttribs ( { imagename = > $ imagename } , 'osvers' , 'osarch' , 'profile' , 'provmethod' ) ;
if ( $ ref ) {
$ img_hash { $ imagename } - > { osver } = $ ref - > { 'osvers' } ;
$ img_hash { $ imagename } - > { osarch } = $ ref - > { 'osarch' } ;
$ img_hash { $ imagename } - > { profile } = $ ref - > { 'profile' } ;
$ img_hash { $ imagename } - > { provmethod } = $ ref - > { 'provmethod' } ;
if ( ! $ linuximagetab ) {
$ linuximagetab = xCAT::Table - > new ( 'linuximage' , - create = > 1 ) ;
}
( my $ ref1 ) = $ linuximagetab - > getAttribs ( { imagename = > $ imagename } , 'rootimgdir' ) ;
if ( ( $ ref1 ) && ( $ ref1 - > { 'rootimgdir' } ) ) {
$ img_hash { $ imagename } - > { rootimgdir } = $ ref1 - > { 'rootimgdir' } ;
}
} else {
$ callback - > (
{ error = > [ "The os image $imagename does not exists on the osimage table for $node" ] ,
errorcode = > [ 1 ] } ) ;
next ;
}
}
my $ ph = $ img_hash { $ imagename } ;
$ osver = $ ph - > { osver } ;
$ arch = $ ph - > { osarch } ;
$ profile = $ ph - > { profile } ;
$ rootimgdir = $ ph - > { rootimgdir } ;
if ( ! $ rootimgdir ) {
$ rootimgdir = "$installroot/netboot/$osver/$arch/$profile" ;
}
}
else {
$ osver = $ ent - > { os } ;
$ arch = $ ent - > { arch } ;
$ profile = $ ent - > { profile } ;
$ rootimgdir = "$installroot/netboot/$osver/$arch/$profile" ;
}
#print"osvr=$osver, arch=$arch, profile=$profile, imgdir=$rootimgdir\n";
unless ( $ osver and $ arch and $ profile )
2008-05-05 19:34:58 +00:00
{
$ callback - > (
{
2009-09-23 01:34:03 +00:00
error = > [ "Insufficient nodetype entry or osimage entry for $node" ] ,
2008-05-05 19:34:58 +00:00
errorcode = > [ 1 ]
}
) ;
2007-11-06 21:28:02 +00:00
next ;
}
2008-04-14 13:32:45 +00:00
2009-09-23 01:34:03 +00:00
$ platform = xCAT_plugin::anaconda:: getplatform ( $ osver ) ;
2008-05-05 19:34:58 +00:00
my $ suffix = 'gz' ;
2009-09-23 01:34:03 +00:00
if ( - r "$rootimgdir/rootimg.sfs" )
2008-05-05 19:34:58 +00:00
{
$ suffix = 'sfs' ;
2007-11-06 21:28:02 +00:00
}
2009-09-23 01:34:03 +00:00
if ( - r "$rootimgdir/rootimg.nfs" )
2008-05-05 19:34:58 +00:00
{
$ suffix = 'nfs' ;
2008-04-24 17:32:18 +00:00
}
2009-12-04 00:59:24 +00:00
#statelite images are not packed.
2008-05-05 19:34:58 +00:00
unless (
(
2009-09-23 01:34:03 +00:00
- r "$rootimgdir/rootimg.gz"
or - r "$rootimgdir/rootimg.sfs"
or - r "$rootimgdir/rootimg.nfs"
2009-12-04 00:59:24 +00:00
or $ statelite
2008-05-05 19:34:58 +00:00
)
2009-09-23 01:34:03 +00:00
and - r "$rootimgdir/kernel"
and - r "$rootimgdir/initrd.gz"
2008-05-05 19:34:58 +00:00
)
{
2009-12-15 20:37:40 +00:00
if ( $ statelite ) {
$ callback - > ( { error = > [ "$node: statelite image $osver-$arch-$profile does not exist" ] , errorcode = > [ 1 ] } ) ;
} else {
$ callback - > (
{
error = > [
"No packed image for platform $osver, architecture $arch, and profile $profile, please run packimage (i.e. packimage -o $osver -p $profile -a $arch"
] ,
errorcode = > [ 1 ]
}
) ;
}
next ;
2007-11-06 21:28:02 +00:00
}
2008-04-14 13:32:45 +00:00
2008-05-05 19:34:58 +00:00
# create the node-specific post scripts
#mkpath "/install/postscripts/";
#xCAT::Postage->writescript($node,"/install/postscripts/".$node, "netboot", $callback);
2008-04-14 13:32:45 +00:00
2008-02-11 20:35:22 +00:00
mkpath ( "/$tftpdir/xcat/netboot/$osver/$arch/$profile/" ) ;
2008-05-05 19:34:58 +00:00
2009-12-04 00:59:24 +00:00
#TODO: only copy if newer...
2008-05-13 23:40:05 +00:00
unless ( $ donetftp { $ osver , $ arch , $ profile } ) {
2009-12-04 00:59:24 +00:00
if ( - f "$rootimgdir/hypervisor" ) {
copy ( "$rootimgdir/hypervisor" ,
"/$tftpdir/xcat/netboot/$osver/$arch/$profile/" ) ;
$ xenstyle = 1 ;
}
copy ( "$rootimgdir/kernel" ,
"/$tftpdir/xcat/netboot/$osver/$arch/$profile/" ) ;
copy ( "$rootimgdir/initrd.gz" ,
"/$tftpdir/xcat/netboot/$osver/$arch/$profile/" ) ;
$ donetftp { $ osver , $ arch , $ profile } = 1 ;
2008-05-13 23:40:05 +00:00
}
2008-05-05 19:34:58 +00:00
unless ( - r "/$tftpdir/xcat/netboot/$osver/$arch/$profile/kernel"
and - r "/$tftpdir/xcat/netboot/$osver/$arch/$profile/initrd.gz" )
{
$ callback - > (
{
error = > [
"Copying to /$tftpdir/xcat/netboot/$osver/$arch/$profile failed"
] ,
errorcode = > [ 1 ]
}
) ;
next ;
2007-11-06 21:28:02 +00:00
}
2008-07-11 19:02:39 +00:00
my $ ent = $ reshash - > { $ node } - > [ 0 ] ; #$restab->getNodeAttribs($node, ['primarynic']);
my $ sent = $ hmhash - > { $ node } - > [ 0 ] ;
# $hmtab->getNodeAttribs($node,
# ['serialport', 'serialspeed', 'serialflow']);
2008-05-05 19:34:58 +00:00
# determine image server, if tftpserver use it, else use xcatmaster
2009-03-12 16:34:54 +00:00
# last resort use self
2008-05-05 19:34:58 +00:00
my $ imgsrv ;
my $ ient ;
2008-07-11 19:02:39 +00:00
$ ient = $ reshash - > { $ node } - > [ 0 ] ; #$restab->getNodeAttribs($node, ['tftpserver']);
2008-05-05 19:34:58 +00:00
if ( $ ient and $ ient - > { tftpserver } )
{
$ imgsrv = $ ient - > { tftpserver } ;
}
else
{
2009-09-01 17:50:13 +00:00
$ ient = $ reshash - > { $ node } - > [ 0 ] ; #$restab->getNodeAttribs($node, ['xcatmaster']);
2008-05-05 19:34:58 +00:00
if ( $ ient and $ ient - > { xcatmaster } )
{
$ imgsrv = $ ient - > { xcatmaster } ;
}
else
{
2009-03-12 16:34:54 +00:00
# master not correct for service node pools
#$ient = $sitetab->getAttribs({key => master}, value);
#if ($ient and $ient->{value})
#{
# $imgsrv = $ient->{value};
#}
#else
#{
2009-03-18 14:11:30 +00:00
$ imgsrv = '!myipfn!' ;
2009-03-12 16:34:54 +00:00
#}
2008-05-05 19:34:58 +00:00
}
}
unless ( $ imgsrv )
{
$ callback - > (
{
error = > [
"Unable to determine or reasonably guess the image server for $node"
] ,
errorcode = > [ 1 ]
}
) ;
next ;
2008-02-11 20:35:22 +00:00
}
2008-04-24 17:32:18 +00:00
my $ kcmdline ;
2008-05-05 19:34:58 +00:00
if ( $ suffix eq "nfs" )
{
$ kcmdline =
"imgurl=nfs://$imgsrv/install/netboot/$osver/$arch/$profile/rootimg " ;
2008-04-24 17:32:18 +00:00
}
2009-12-04 00:59:24 +00:00
elsif ( $ statelite ) {
2009-12-15 20:37:40 +00:00
# get entry for nfs root if it exists:
# have to get nfssvr and nfsdir from noderes table
my $ nfssrv = $ imgsrv ;
my $ nfsdir = $ rootimgdir ;
if ( $ ient - > { nfsserver } ) {
$ nfssrv = $ ient - > { nfsserver } ;
}
if ( $ ient - > { nfsdir } ne '' ) {
$ nfsdir = $ ient - > { nfsdir } . "/netboot/$osver/$arch/$profile" ;
}
2009-12-04 00:59:24 +00:00
$ kcmdline =
2009-12-15 20:37:40 +00:00
"NFSROOT=$nfssrv:$nfsdir STATEMNT=" ;
if ( $ stateHash - > { statemnt } ) {
$ kcmdline . = $ stateHash - > { statemnt } . " " ;
} else {
$ kcmdline . = " " ;
}
$ kcmdline . =
"XCAT=$imgsrv:$xcatdport " ;
2009-12-04 00:59:24 +00:00
}
2008-05-05 19:34:58 +00:00
else
{
$ kcmdline =
"imgurl=http://$imgsrv/install/netboot/$osver/$arch/$profile/rootimg.$suffix " ;
2008-04-24 17:32:18 +00:00
}
2008-05-05 19:34:58 +00:00
if ( defined $ sent - > { serialport } )
{
#my $sent = $hmtab->getNodeAttribs($node,['serialspeed','serialflow']);
unless ( $ sent - > { serialspeed } )
{
$ callback - > (
{
error = > [
"serialport defined, but no serialspeed for $node in nodehm table"
] ,
errorcode = > [ 1 ]
}
) ;
next ;
}
$ kcmdline . =
2009-09-15 17:59:11 +00:00
"console=tty0 console=ttyS" . $ sent - > { serialport } . "," . $ sent - > { serialspeed } ;
2008-05-05 19:34:58 +00:00
if ( $ sent - > { serialflow } =~ /(hard|tcs|ctsrts)/ )
{
$ kcmdline . = "n8r" ;
}
}
2008-10-14 19:27:40 +00:00
# add the addkcmdline attribute to the end
# of the command, if it exists
2009-06-29 18:41:00 +00:00
#my $addkcmd = $addkcmdhash->{$node}->[0];
2008-10-14 19:27:40 +00:00
# add the extra addkcmd command info, if in the table
2009-06-29 18:41:00 +00:00
#if ($addkcmd->{'addkcmdline'}) {
# $kcmdline .= " ";
# $kcmdline .= $addkcmd->{'addkcmdline'};
2008-10-14 19:27:40 +00:00
2009-06-29 18:41:00 +00:00
#}
2008-10-14 19:27:40 +00:00
2009-02-21 14:25:29 +00:00
my $ kernstr = "xcat/netboot/$osver/$arch/$profile/kernel" ;
if ( $ xenstyle ) {
$ kernstr . = "!xcat/netboot/$osver/$arch/$profile/hypervisor" ;
}
2008-05-05 19:34:58 +00:00
$ bptab - > setNodeAttribs (
$ node ,
{
2009-02-21 14:25:29 +00:00
kernel = > "$kernstr" ,
2008-05-05 19:34:58 +00:00
initrd = > "xcat/netboot/$osver/$arch/$profile/initrd.gz" ,
kcmdline = > $ kcmdline
}
) ;
2007-11-06 21:28:02 +00:00
}
2008-05-05 19:34:58 +00:00
#my $rc = xCAT::Utils->create_postscripts_tar();
#if ( $rc != 0 ) {
# xCAT::MsgUtils->message( "S", "Error creating postscripts tar file." );
#}
2007-11-06 21:28:02 +00:00
}
2007-11-05 22:12:39 +00:00
2008-05-05 19:34:58 +00:00
sub mkinstall
{
my $ request = shift ;
my $ callback = shift ;
my $ doreq = shift ;
my @ nodes = @ { $ request - > { node } } ;
2009-09-23 01:34:03 +00:00
my $ sitetab = xCAT::Table - > new ( 'site' ) ;
my $ linuximagetab ;
my $ osimagetab ;
my % img_hash = ( ) ;
2008-05-05 19:34:58 +00:00
my $ installroot ;
$ installroot = "/install" ;
2009-09-23 01:34:03 +00:00
if ( $ sitetab )
{
( my $ ref ) = $ sitetab - > getAttribs ( { key = > 'installdir' } , 'value' ) ;
if ( $ ref and $ ref - > { value } )
{
$ installroot = $ ref - > { value } ;
}
}
2008-05-05 19:34:58 +00:00
my $ node ;
my $ ostab = xCAT::Table - > new ( 'nodetype' ) ;
my % doneimgs ;
2008-07-11 14:12:05 +00:00
my $ restab = xCAT::Table - > new ( 'noderes' ) ;
my $ bptab = xCAT::Table - > new ( 'bootparams' , - create = > 1 ) ;
my $ hmtab = xCAT::Table - > new ( 'nodehm' ) ;
2009-09-23 01:34:03 +00:00
my % osents = % { $ ostab - > getNodesAttribs ( \ @ nodes , [ 'profile' , 'os' , 'arch' , 'provmethod' ] ) } ;
2008-07-11 14:12:05 +00:00
my % rents =
% { $ restab - > getNodesAttribs ( \ @ nodes ,
[ 'nfsserver' , 'primarynic' , 'installnic' ] ) } ;
my % hents =
% { $ hmtab - > getNodesAttribs ( \ @ nodes ,
[ 'serialport' , 'serialspeed' , 'serialflow' ] ) } ;
2009-06-29 18:41:00 +00:00
#my $addkcmdhash =
# $bptab->getNodesAttribs(\@nodes, ['addkcmdline']);
2009-03-14 16:14:29 +00:00
require xCAT::Template ;
2008-05-05 19:34:58 +00:00
foreach $ node ( @ nodes )
{
2009-09-23 01:34:03 +00:00
my $ os ;
my $ arch ;
my $ profile ;
my $ tmplfile ;
my $ pkgdir ;
my $ imagename ;
my $ platform ;
2008-05-05 19:34:58 +00:00
my $ osinst ;
2008-07-11 14:12:05 +00:00
my $ ent = $ osents { $ node } - > [ 0 ] ; #$ostab->getNodeAttribs($node, ['profile', 'os', 'arch']);
2009-09-23 01:34:03 +00:00
if ( $ ent and $ ent - > { provmethod } and ( $ ent - > { provmethod } ne 'install' ) and ( $ ent - > { provmethod } ne 'netboot' ) ) {
$ imagename = $ ent - > { provmethod } ;
#print "imagename=$imagename\n";
if ( ! exists ( $ img_hash { $ imagename } ) ) {
if ( ! $ osimagetab ) {
$ osimagetab = xCAT::Table - > new ( 'osimage' , - create = > 1 ) ;
}
( my $ ref ) = $ osimagetab - > getAttribs ( { imagename = > $ imagename } , 'osvers' , 'osarch' , 'profile' , 'provmethod' ) ;
if ( $ ref ) {
$ img_hash { $ imagename } - > { osver } = $ ref - > { 'osvers' } ;
$ img_hash { $ imagename } - > { osarch } = $ ref - > { 'osarch' } ;
$ img_hash { $ imagename } - > { profile } = $ ref - > { 'profile' } ;
$ img_hash { $ imagename } - > { provmethod } = $ ref - > { 'provmethod' } ;
if ( ! $ linuximagetab ) {
$ linuximagetab = xCAT::Table - > new ( 'linuximage' , - create = > 1 ) ;
}
( my $ ref1 ) = $ linuximagetab - > getAttribs ( { imagename = > $ imagename } , 'template' , 'pkgdir' ) ;
if ( $ ref1 ) {
if ( $ ref1 - > { 'template' } ) {
$ img_hash { $ imagename } - > { template } = $ ref1 - > { 'template' } ;
}
if ( $ ref1 - > { 'pkgdir' } ) {
$ img_hash { $ imagename } - > { pkgdir } = $ ref1 - > { 'pkgdir' } ;
}
}
} else {
$ callback - > (
{ error = > [ "The os image $imagename does not exists on the osimage table for $node" ] ,
errorcode = > [ 1 ] } ) ;
next ;
}
}
my $ ph = $ img_hash { $ imagename } ;
$ os = $ ph - > { osver } ;
$ arch = $ ph - > { osarch } ;
$ profile = $ ph - > { profile } ;
$ platform = xCAT_plugin::anaconda:: getplatform ( $ os ) ;
$ tmplfile = $ ph - > { template } ;
$ pkgdir = $ ph - > { pkgdir } ;
if ( ! $ pkgdir ) {
$ pkgdir = "$installroot/$os/$arch" ;
}
}
else {
$ os = $ ent - > { os } ;
$ arch = $ ent - > { arch } ;
$ profile = $ ent - > { profile } ;
$ platform = xCAT_plugin::anaconda:: getplatform ( $ os ) ;
my $ genos = $ os ;
$ genos =~ s/\..*// ;
if ( $ genos =~ /rh.*s(\d*)/ )
{
unless ( - r "$installroot/custom/install/$platform/$profile.$genos.$arch.tmpl"
or - r "/install/custom/install/$platform/$profile.$genos.tmpl"
or - r "$::XCATROOT/share/xcat/install/$platform/$profile.$genos.$arch.tmpl"
or - r "$::XCATROOT/share/xcat/install/$platform/$profile.$genos.tmpl" )
{
$ genos = "rhel$1" ;
}
}
$ tmplfile = xCAT::SvrUtils:: get_tmpl_file_name ( "$installroot/custom/install/$platform" , $ profile , $ os , $ arch , $ genos ) ;
if ( ! $ tmplfile ) { $ tmplfile = xCAT::SvrUtils:: get_tmpl_file_name ( "$::XCATROOT/share/xcat/install/$platform" , $ profile , $ os , $ arch , $ genos ) ; }
$ pkgdir = "$installroot/$os/$arch" ;
}
2008-05-22 14:12:05 +00:00
my @ missingparms ;
2009-09-23 01:34:03 +00:00
unless ( $ os ) {
if ( $ imagename ) { push @ missingparms , "osimage.osvers" ; }
else { push @ missingparms , "nodetype.os" ; }
2008-05-22 14:12:05 +00:00
}
2009-09-23 01:34:03 +00:00
unless ( $ arch ) {
if ( $ imagename ) { push @ missingparms , "osimage.osarch" ; }
else { push @ missingparms , "nodetype.arch" ; }
2008-05-22 14:12:05 +00:00
}
2009-09-23 01:34:03 +00:00
unless ( $ profile ) {
if ( $ imagename ) { push @ missingparms , "osimage.profile" ; }
else { push @ missingparms , "nodetype.profile" ; }
2008-05-22 14:12:05 +00:00
}
2009-09-23 01:34:03 +00:00
unless ( $ os and $ arch and $ profile )
2008-05-05 19:34:58 +00:00
{
$ callback - > (
{
2008-05-22 14:12:05 +00:00
error = > [ "Missing " . join ( ',' , @ missingparms ) . " for $node" ] ,
2008-05-05 19:34:58 +00:00
errorcode = > [ 1 ]
}
) ;
next ; #No profile
}
2009-09-23 01:34:03 +00:00
2008-09-12 22:40:15 +00:00
unless ( - r "$tmplfile" )
2008-05-05 19:34:58 +00:00
{
$ callback - > (
{
error = > [
"No $platform kickstart template exists for "
2009-09-23 01:34:03 +00:00
. $ profile
2008-05-05 19:34:58 +00:00
] ,
errorcode = > [ 1 ]
}
) ;
next ;
}
#Call the Template class to do substitution to produce a kickstart file in the autoinst dir
2009-09-23 01:34:03 +00:00
my $ tmperr ;
if ( $ imagename ) {
$ tmperr = "Unable to find template file: $tmplfile" ;
} else {
$ tmperr = "Unable to find template in /install/custom/install/$platform or $::XCATROOT/share/xcat/install/$platform (for $profile/$os/$arch combination)" ;
}
2008-09-12 22:40:15 +00:00
if ( - r "$tmplfile" )
2008-05-05 19:34:58 +00:00
{
$ tmperr =
xCAT::Template - > subvars (
2008-09-12 22:40:15 +00:00
$ tmplfile ,
2008-05-05 19:34:58 +00:00
"/$installroot/autoinst/" . $ node ,
$ node
) ;
}
2008-09-12 22:40:15 +00:00
2008-05-05 19:34:58 +00:00
if ( $ tmperr )
{
$ callback - > (
{
node = >
[ { name = > [ $ node ] , error = > [ $ tmperr ] , errorcode = > [ 1 ] } ]
}
) ;
next ;
}
2009-09-23 01:34:03 +00:00
#my $installdir="/install"; #TODO: not hardcode installdir
2009-06-16 18:57:12 +00:00
my $ tftpdir = "/tftpboot" ;
2008-05-05 19:34:58 +00:00
# create the node-specific post scripts
#mkpath "/install/postscripts/";
#xCAT::Postage->writescript($node,"/install/postscripts/".$node, "install", $callback);
2009-06-16 18:57:12 +00:00
my $ kernpath ;
my $ initrdpath ;
my $ maxmem ;
2008-05-05 19:34:58 +00:00
if (
(
2009-06-16 18:57:12 +00:00
$ arch =~ /x86/ and
(
2009-09-23 01:34:03 +00:00
- r "$pkgdir/images/pxeboot/vmlinuz"
and $ kernpath = "$pkgdir/images/pxeboot/vmlinuz"
2009-09-24 20:13:33 +00:00
and - r "$pkgdir/images/pxeboot/initrd.img"
2009-09-23 01:34:03 +00:00
and $ initrdpath = "$pkgdir/images/pxeboot/initrd.img"
2009-06-16 18:57:12 +00:00
) or ( #Handle the case seen in VMWare 4.0 ESX media
#In VMWare 4.0 they dropped the pxe-optimized initrd
#leaving us no recourse but the rather large optical disk
#initrd, but perhaps we can mitigate with gPXE
2009-09-23 01:34:03 +00:00
- d "$pkgdir/VMware"
and - r "$pkgdir/isolinux/vmlinuz"
and $ kernpath = "$pkgdir/isolinux/vmlinuz"
and - r "$pkgdir/isolinux/initrd.img"
and $ initrdpath = "$pkgdir/isolinux/initrd.img"
2009-06-16 18:57:12 +00:00
and $ maxmem = "512M" #Have to give up linux room to make room for vmware hypervisor evidently
)
) or ( $ arch =~ /ppc/
2009-09-23 01:34:03 +00:00
and - r "$pkgdir/ppc/ppc64/vmlinuz"
and $ kernpath = "$pkgdir/ppc/ppc64/vmlinuz"
and - r "$pkgdir/ppc/ppc64/ramdisk.image.gz"
and $ initrdpath = "$pkgdir/ppc/ppc64/ramdisk.image.gz" )
2008-05-05 19:34:58 +00:00
)
{
#TODO: driver slipstream, targetted for network.
unless ( $ doneimgs { "$os|$arch" } )
{
mkpath ( "/tftpboot/xcat/$os/$arch" ) ;
2009-12-04 00:59:24 +00:00
copy ( $ kernpath , "$tftpdir/xcat/$os/$arch" ) ;
copy ( $ initrdpath , "$tftpdir/xcat/$os/$arch/initrd.img" ) ;
2008-05-05 19:34:58 +00:00
$ doneimgs { "$os|$arch" } = 1 ;
}
#We have a shot...
2008-07-11 14:12:05 +00:00
my $ ent = $ rents { $ node } - > [ 0 ] ;
# $restab->getNodeAttribs($node,
# ['nfsserver', 'primarynic', 'installnic']);
my $ sent = $ hents { $ node } - > [ 0 ] ;
# $hmtab->getNodeAttribs(
# $node,
# [
# 'serialport', 'serialspeed', 'serialflow'
# ]
# );
2008-05-05 19:34:58 +00:00
unless ( $ ent and $ ent - > { nfsserver } )
{
$ callback - > (
{
error = > [ "No noderes.nfsserver defined for " . $ node ] ,
errorcode = > [ 1 ]
}
) ;
next ;
}
my $ kcmdline =
"nofb utf8 ks=http://"
. $ ent - > { nfsserver }
. "/install/autoinst/"
. $ node ;
2009-06-16 18:57:12 +00:00
if ( $ maxmem ) {
$ kcmdline . = " mem=$maxmem" ;
}
2008-05-05 19:34:58 +00:00
if ( $ ent - > { installnic } )
{
$ kcmdline . = " ksdevice=" . $ ent - > { installnic } ;
}
elsif ( $ ent - > { primarynic } )
{
$ kcmdline . = " ksdevice=" . $ ent - > { primarynic } ;
}
else
{
$ kcmdline . = " ksdevice=eth0" ;
}
#TODO: dd=<url> for driver disks
if ( defined ( $ sent - > { serialport } ) )
{
unless ( $ sent - > { serialspeed } )
{
$ callback - > (
{
error = > [
"serialport defined, but no serialspeed for $node in nodehm table"
] ,
errorcode = > [ 1 ]
}
) ;
next ;
}
$ kcmdline . =
2009-09-15 17:59:11 +00:00
" console=tty0 console=ttyS"
2008-05-05 19:34:58 +00:00
. $ sent - > { serialport } . ","
. $ sent - > { serialspeed } ;
if ( $ sent - > { serialflow } =~ /(hard|cts|ctsrts)/ )
{
$ kcmdline . = "n8r" ;
}
}
$ kcmdline . = " noipv6" ;
2009-05-07 14:13:36 +00:00
# add the addkcmdline attribute to the end
# of the command, if it exists
2009-06-29 18:41:00 +00:00
#my $addkcmd = $addkcmdhash->{$node}->[0];
2009-05-07 14:13:36 +00:00
# add the extra addkcmd command info, if in the table
2009-06-29 18:41:00 +00:00
#if ($addkcmd->{'addkcmdline'}) {
# $kcmdline .= " ";
# $kcmdline .= $addkcmd->{'addkcmdline'};
#}
2008-05-05 19:34:58 +00:00
$ bptab - > setNodeAttribs (
$ node ,
{
kernel = > "xcat/$os/$arch/vmlinuz" ,
initrd = > "xcat/$os/$arch/initrd.img" ,
kcmdline = > $ kcmdline
}
) ;
}
else
{
$ callback - > (
{
error = > [ "Install image not found in /install/$os/$arch" ] ,
errorcode = > [ 1 ]
}
) ;
}
2007-10-26 22:44:33 +00:00
}
2008-05-07 20:33:35 +00:00
#my $rc = xCAT::Utils->create_postscripts_tar();
#if ($rc != 0)
#{
# xCAT::MsgUtils->message("S", "Error creating postscripts tar file.");
#}
2008-05-05 19:34:58 +00:00
}
sub copycd
{
my $ request = shift ;
my $ callback = shift ;
my $ doreq = shift ;
my $ installroot ;
my $ sitetab = xCAT::Table - > new ( 'site' ) ;
if ( $ sitetab )
{
2009-09-23 01:34:03 +00:00
( my $ ref ) = $ sitetab - > getAttribs ( { key = > 'installdir' } , 'value' ) ;
2009-09-18 19:53:48 +00:00
#print Dumper($ref);
2008-05-05 19:34:58 +00:00
if ( $ ref and $ ref - > { value } )
{
$ installroot = $ ref - > { value } ;
}
2008-04-29 17:39:28 +00:00
}
2009-09-23 01:34:03 +00:00
my $ distname ;
my $ arch ;
my $ path ;
2008-05-05 19:34:58 +00:00
@ ARGV = @ { $ request - > { arg } } ;
GetOptions (
'n=s' = > \ $ distname ,
'a=s' = > \ $ arch ,
'p=s' = > \ $ path
) ;
unless ( $ path )
{
2008-04-29 17:39:28 +00:00
2008-05-05 19:34:58 +00:00
#this plugin needs $path...
return ;
2007-10-26 22:44:33 +00:00
}
2008-05-05 19:34:58 +00:00
if ( $ distname
and $ distname !~ /^centos/
and $ distname !~ /^fedora/
and $ distname !~ /^rh/ )
{
#If they say to call it something unidentifiable, give up?
return ;
2008-04-03 13:27:16 +00:00
}
2008-05-05 19:34:58 +00:00
unless ( - r $ path . "/.discinfo" )
{
return ;
2008-03-10 14:20:47 +00:00
}
2008-05-05 19:34:58 +00:00
my $ dinfo ;
open ( $ dinfo , $ path . "/.discinfo" ) ;
my $ did = <$dinfo> ;
chomp ( $ did ) ;
my $ desc = <$dinfo> ;
chomp ( $ desc ) ;
my $ darch = <$dinfo> ;
chomp ( $ darch ) ;
2008-04-14 13:32:45 +00:00
2008-05-05 19:34:58 +00:00
if ( $ darch and $ darch =~ /i.86/ )
{
$ darch = "x86" ;
}
close ( $ dinfo ) ;
if ( $ distnames { $ did } )
{
unless ( $ distname )
{
$ distname = $ distnames { $ did } ;
}
}
elsif ( $ desc =~ /^Final$/ )
{
unless ( $ distname )
{
$ distname = "centos5" ;
}
}
elsif ( $ desc =~ /^Fedora 8$/ )
{
unless ( $ distname )
{
$ distname = "fedora8" ;
}
}
elsif ( $ desc =~ /^CentOS-4 .*/ )
{
unless ( $ distname )
{
$ distname = "centos4" ;
}
}
elsif ( $ desc =~ /^Red Hat Enterprise Linux Client 5$/ )
{
unless ( $ distname )
{
$ distname = "rhelc5" ;
}
}
elsif ( $ desc =~ /^Red Hat Enterprise Linux Server 5$/ )
{
unless ( $ distname )
{
$ distname = "rhels5" ;
}
2007-10-26 22:44:33 +00:00
}
2008-05-05 19:34:58 +00:00
unless ( $ distname )
{
return ; #Do nothing, not ours..
2007-10-26 22:44:33 +00:00
}
2008-05-05 19:34:58 +00:00
if ( $ darch )
{
unless ( $ arch )
{
$ arch = $ darch ;
}
if ( $ arch and $ arch ne $ darch )
{
$ callback - > (
{
error = >
"Requested distribution architecture $arch, but media is $darch"
}
) ;
return ;
}
if ( $ arch =~ /ppc/ ) { $ arch = "ppc64" }
2007-10-26 22:44:33 +00:00
}
2008-05-05 19:34:58 +00:00
% { $ request } = ( ) ; #clear request we've got it.
$ callback - > ( { data = > "Copying media to $installroot/$distname/$arch/" } ) ;
my $ omask = umask 0022 ;
mkpath ( "$installroot/$distname/$arch" ) ;
umask $ omask ;
my $ rc ;
my $ reaped = 0 ;
$ SIG { INT } = $ SIG { TERM } = sub {
2008-06-02 23:58:15 +00:00
foreach ( @ cpiopid ) {
kill 2 , $ _ ;
}
2008-05-15 15:48:34 +00:00
if ( $ ::CDMOUNTPATH ) {
2008-08-11 18:36:10 +00:00
chdir ( "/" ) ;
2008-05-15 15:48:34 +00:00
system ( "umount $::CDMOUNTPATH" ) ;
}
2008-05-05 19:34:58 +00:00
} ;
my $ KID ;
chdir $ path ;
2008-06-02 20:27:02 +00:00
my $ numFiles = `find . -print | wc -l` ;
2008-05-05 19:34:58 +00:00
my $ child = open ( $ KID , "|-" ) ;
unless ( defined $ child )
{
$ callback - > ( { error = > "Media copy operation fork failure" } ) ;
return ;
2007-10-26 22:44:33 +00:00
}
2008-05-05 19:34:58 +00:00
if ( $ child )
{
2008-06-02 23:58:15 +00:00
push @ cpiopid , $ child ;
2008-05-05 19:34:58 +00:00
my @ finddata = `find .` ;
for ( @ finddata )
{
print $ KID $ _ ;
}
close ( $ KID ) ;
$ rc = $? ;
2007-10-26 22:44:33 +00:00
}
2008-05-05 19:34:58 +00:00
else
{
nice 10 ;
2008-06-02 20:27:02 +00:00
my $ c = "nice -n 20 cpio -vdump $installroot/$distname/$arch" ;
2008-06-02 23:58:15 +00:00
my $ k2 = open ( PIPE , "$c 2>&1 |" ) ||
2008-06-02 20:27:02 +00:00
$ callback - > ( { error = > "Media copy operation fork failure" } ) ;
2008-06-02 23:58:15 +00:00
push @ cpiopid , $ k2 ;
2008-06-02 20:27:02 +00:00
my $ copied = 0 ;
my ( $ percent , $ fout ) ;
while ( <PIPE> ) {
next if /^cpio:/ ;
$ percent = $ copied / $ numFiles ;
$ fout = sprintf "%0.2f%%" , $ percent * 100 ;
$ callback - > ( { sinfo = > "$fout" } ) ;
+ + $ copied ;
}
exit ;
2008-05-05 19:34:58 +00:00
}
#my $rc = system("cd $path; find . | nice -n 20 cpio -dump $installroot/$distname/$arch");
#my $rc = system("cd $path;rsync -a . $installroot/$distname/$arch/");
chmod 0755 , "$installroot/$distname/$arch" ;
2009-03-14 16:00:35 +00:00
require xCAT::Yum ;
2008-05-05 19:34:58 +00:00
xCAT::Yum - > localize_yumrepo ( $ installroot , $ distname , $ arch ) ;
if ( $ rc != 0 )
{
$ callback - > ( { error = > "Media copy operation failed, status $rc" } ) ;
2007-10-26 22:44:33 +00:00
}
2008-05-05 19:34:58 +00:00
else
{
$ callback - > ( { data = > "Media copy operation successful" } ) ;
2009-09-19 17:03:14 +00:00
my @ ret = xCAT::SvrUtils - > update_tables_with_templates ( $ distname , $ arch ) ;
if ( $ ret [ 0 ] != 0 ) {
$ callback - > ( { data = > "Error when updating the osimage tables: " . $ ret [ 1 ] } ) ;
}
2007-10-26 22:44:33 +00:00
}
}
2008-09-12 22:40:15 +00:00
2009-09-23 01:34:03 +00:00
sub getplatform {
my $ os = shift ;
my $ platform ;
if ( $ os =~ /rh.*/ )
{
$ platform = "rh" ;
}
elsif ( $ os =~ /centos.*/ )
{
$ platform = "centos" ;
}
elsif ( $ os =~ /fedora.*/ )
{
$ platform = "fedora" ;
}
elsif ( $ os =~ /esx.*/ )
{
$ platform = "esx" ;
}
return $ platform ;
}
2008-09-12 22:40:15 +00:00
2007-10-26 22:44:33 +00:00
1 ;