diff --git a/xCAT-server/lib/perl/xCAT/Postage.pm b/xCAT-server/lib/perl/xCAT/Postage.pm index 6bd9f908e..9564ccad4 100644 --- a/xCAT-server/lib/perl/xCAT/Postage.pm +++ b/xCAT-server/lib/perl/xCAT/Postage.pm @@ -470,6 +470,8 @@ sub makescript elsif ($os =~ /fedora.*/) { $platform = "fedora"; } elsif ($os =~ /SL.*/) { $platform = "SL"; } elsif ($os =~ /sles.*/) { $platform = "sles"; } + elsif ($os =~ /ubuntu.*/) { $platform = "ubuntu"; } + elsif ($os =~ /debian.*/) { $platform = "debian"; } elsif ($os =~ /aix.*/) { $platform = "aix"; } } if (($nodesetstate) && ($nodesetstate eq "netboot")) diff --git a/xCAT-server/lib/perl/xCAT/SvrUtils.pm b/xCAT-server/lib/perl/xCAT/SvrUtils.pm index a9e0d7026..f8d78a43e 100644 --- a/xCAT-server/lib/perl/xCAT/SvrUtils.pm +++ b/xCAT-server/lib/perl/xCAT/SvrUtils.pm @@ -320,6 +320,8 @@ sub getsynclistfile() elsif ($os =~ /fedora.*/) { $platform = "fedora"; } elsif ($os =~ /sles.*/) { $platform = "sles"; } elsif ($os =~ /SL.*/) { $platform = "SL"; } + elsif ($os =~ /ubuntu.*/) { $platform = "ubuntu"; } + elsif ($os =~ /debian.*/) { $platform = "debian"; } elsif ($os =~ /AIX.*/) { $platform = "AIX"; } } @@ -345,6 +347,8 @@ sub getsynclistfile() elsif ($os =~ /fedora.*/) { $platform = "fedora"; } elsif ($os =~ /sles.*/) { $platform = "sles"; } elsif ($os =~ /SL.*/) { $platform = "SL"; } + elsif ($os =~ /ubuntu.*/) { $platform = "ubuntu"; } + elsif ($os =~ /debian.*/) { $platform = "debian"; } elsif ($os =~ /AIX.*/) { $platform = "AIX"; } elsif ($os =~ /win/) {$platform = "windows"; } } diff --git a/xCAT-server/lib/xcat/plugins/debian.pm b/xCAT-server/lib/xcat/plugins/debian.pm new file mode 100644 index 000000000..4fab63761 --- /dev/null +++ b/xCAT-server/lib/xcat/plugins/debian.pm @@ -0,0 +1,1356 @@ +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html +package xCAT_plugin::debian; +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; +use Storable qw(dclone); +use Sys::Syslog; +use File::Temp qw/tempdir/; +use xCAT::Table; +use xCAT::Utils; +use xCAT::SvrUtils; +use xCAT::MsgUtils; +use Data::Dumper; +use Getopt::Long; +Getopt::Long::Configure("bundling"); +Getopt::Long::Configure("pass_through"); +use File::Path; +use File::Copy; + +use Socket; + +#use strict; +my @cpiopid; + +############################################################################## +# +# Author: +# +# Arif Ali (OCF plc) +# +# Notes: +# +# This will not work with Ubuntu Desktop Edition, as all the packages are in +# a compressed image, and not readily available for creating images. So will +# only support Server ISOs. +# +# +# +# ChangeLog: +# +# 13 Aug 2010 - Initial release +# - Implementation of only copycd +# - Tested with 9.10 desktop and server ISOs +# 06 Oct 2010 - Added copycd support for Ubuntu 10.04 Server (LTS releases) +# - Added support for mkinstall, install successfull for 10.04 +# -> used function from anaconda.pm +# -> Need to cleanup so that it has no references to rhel +# 07 Oct 2010 - Added preprocess_request (direct copy from anaconda.pm) +# +############################################################################## + +sub handled_commands +{ + return { + copycd => "debian", + mknetboot => "nodetype:os=(ubuntu.*)|(debian.*)", + mkinstall => "nodetype:os=(ubuntu.*)|(debian.*)", + }; +} + +sub preprocess_request +{ + my $req = shift; + my $callback = shift; + return [$req]; #calls are only made from pre-farmed out scenarios + if ($req->{command}->[0] eq 'copycd') + { #don't farm out copycd + return [$req]; + } + + 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]; + } + + my %localnodehash; + my %dispatchhash; + my $nrtab = xCAT::Table->new('noderes'); + my $nrents = $nrtab->getNodesAttribs($req->{node},[qw(tftpserver servicenode)]); + foreach my $node (@{$req->{node}}) + { + my $nodeserver; + my $tent = $nrents->{$node}->[0]; #$nrtab->getNodeAttribs($node, ['tftpserver']); + if ($tent) { $nodeserver = $tent->{tftpserver} } + unless ($tent and $tent->{tftpserver}) + { + $tent = $nrents->{$node}->[0]; #$nrtab->getNodeAttribs($node, ['servicenode']); + if ($tent) { $nodeserver = $tent->{servicenode} } + } + if ($nodeserver) + { + $dispatchhash{$nodeserver}->{$node} = 1; + } + else + { + $localnodehash{$node} = 1; + } + } + my @requests; + my $reqc = {%$req}; + $reqc->{node} = [keys %localnodehash]; + if (scalar(@{$reqc->{node}})) { push @requests, $reqc } + + foreach my $dtarg (keys %dispatchhash) + { #iterate dispatch targets + my $reqcopy = {%$req}; #deep copy + $reqcopy->{'_xcatdest'} = $dtarg; + $reqcopy->{node} = [keys %{$dispatchhash{$dtarg}}]; + push @requests, $reqcopy; + } + return \@requests; +} + +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); + } + elsif ($request->{command}->[0] eq 'mknetboot') + { + return mknetboot($request, $callback, $doreq); + } +} + +sub copycd +{ + xCAT::MsgUtils->message("S","Doing debian copycds"); + my $request = shift; + my $callback = shift; + my $doreq = shift; + my $distname = ""; + my $detdistname = ""; + my $installroot; + my $arch; + my $path; + $installroot = "/install"; + my $sitetab = xCAT::Table->new('site'); + if ($sitetab) + { + (my $ref) = $sitetab->getAttribs({key => 'installdir'}, 'value'); + print Dumper($ref); + if ($ref and $ref->{value}) + { + $installroot = $ref->{value}; + } + } + + @ARGV = @{$request->{arg}}; + GetOptions( + 'n=s' => \$distname, + 'a=s' => \$arch, + 'p=s' => \$path, + ); + unless ($path) + { + + #this plugin needs $path... + return; + } + + unless (-r $path . "/.disk/info") + { + xCAT::MsgUtils->message("S","The CD doesn't look like a Debian CD, exiting..."); + return; + } + my $dinfo; + open($dinfo, $path . "/.disk/info"); + my $darch; + my $line = <$dinfo>; + chomp($line); + my @line2 = split(/ /,$line); + $darch = $line2[6]; + close($dinfo); + + + # Ubuntu 10.04 doesn't put into the correct place + # This in essence will pick up the LTS releases + $darch = $line2[7] if ($darch eq "Release"); + + # For debian lenny to work + $darch = $line2[8] if ($darch eq "Official"); + + # Check to see if $darch is defined + unless ($darch) + { + return; + } + + # The product should be the first word + my $prod = $line2[0]; + + # The version should be the second word + my $ver = $line2[1]; + + # For debian lenny to work + $ver = $line2[2] if ($ver eq "GNU/Linux"); + + if ($prod eq "Ubuntu" or $prod eq "Ubuntu-Server" ) + { + $distname="ubuntu".$ver; + $detdistname="ubuntu".$ver; + } + elsif ($prod eq "Debian") + { + $distname="debian".$ver; + $detdistname="debian".$ver; + } + else { + return; + } + + # So that I can use amd64 below + my $debarch=$darch; + + if ($darch and $darch =~ /i.86/) + { + $darch = "x86"; + } + elsif ($darch and $darch =~ /ppc/) + { + $darch = "ppc64"; + } + elsif ($darch and $darch =~ /amd64/) + { + $darch = "x86_64"; + } + + if ($darch) + { + unless ($arch) + { + $arch = $darch; + } + if ($arch and $arch ne $darch) + { + $callback->( + { + error => + ["Requested Debian architecture $arch, but media is $darch"], + errorcode => [1] + } + ); + return; + } + } + %{$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; + $SIG{INT} = $SIG{TERM} = sub { + foreach(@cpiopid){ + kill 2, $_; + } + if ($::CDMOUNTPATH) { + chdir("/"); + system("umount $::CDMOUNTPATH"); + } + }; + my $kid; + chdir $path; + my $numFiles = `find . -print | wc -l`; + my $child = open($kid,"|-"); + unless (defined $child) { + $callback->({error=>"Media copy operation fork failure"}); + return; + } + if ($child) { + push @cpiopid,$child; + my @finddata = `find .`; + for (@finddata) { + print $kid $_; + } + close($kid); + $rc = $?; + } else { + my $c = "nice -n 20 cpio -vdump $installroot/$distname/$arch"; + my $k2 = open(PIPE, "$c 2>&1 |") || + $callback->({error => "Media copy operation fork failure"}); + push @cpiopid, $k2; + my $copied = 0; + my ($percent, $fout); + while(){ + next if /^cpio:/; + $percent = $copied / $numFiles; + $fout = sprintf "%0.2f%%", $percent * 100; + $callback->({sinfo => "$fout"}); + ++$copied; + } + exit; + } + # system( + # "cd $path; find . | nice -n 20 cpio -dump $installroot/$distname/$arch/" + # ); + chmod 0755, "$installroot/$distname/$arch"; + + # Need to do this otherwise there will be warning about corrupt Packages file + # when installing a system + + # Grabs the distribution codename + my @line=split(" ",`ls -lh $installroot/$distname/$arch/dists/ | grep dr`); + my $dist = $line[@line-1]; + + # touches the Packages file so that deb packaging works + system("touch $installroot/$distname/$arch/dists/$dist/restricted/binary-$debarch/Packages"); + + # removes the links unstable and testing, otherwise the repository does not work for debian + system("rm -f $installroot/$distname/$arch/dists/unstable"); + system("rm -f $installroot/$distname/$arch/dists/testing"); + + if ($rc != 0) + { + $callback->({error => "Media copy operation failed, status $rc"}); + } + else + { + $callback->({data => "Media copy operation successful"}); + my @ret=xCAT::SvrUtils->update_tables_with_templates($distname, $arch); + if ($ret[0] != 0) { + $callback->({data => "Error when updating the osimage tables: " . $ret[1]}); + } + + } +} + +sub mkinstall +{ + xCAT::MsgUtils->message("S","Doing debian mkinstall"); + my $request = shift; + my $callback = shift; + my $doreq = shift; + my @nodes = @{$request->{node}}; + my $sitetab = xCAT::Table->new('site'); + my $linuximagetab; + my $osimagetab; + my %img_hash=(); + + my $installroot; + $installroot = "/install"; + if ($sitetab) + { + (my $ref) = $sitetab->getAttribs({key => 'installdir'}, 'value'); + if ($ref and $ref->{value}) + { + $installroot = $ref->{value}; + } + } + + my $node; + my $ostab = xCAT::Table->new('nodetype'); + my %doneimgs; + my $restab = xCAT::Table->new('noderes'); + my $bptab = xCAT::Table->new('bootparams',-create=>1); + my $hmtab = xCAT::Table->new('nodehm'); + my %osents = %{$ostab->getNodesAttribs(\@nodes, ['profile', 'os', 'arch', 'provmethod'])}; + my %rents = + %{$restab->getNodesAttribs(\@nodes, + ['nfsserver', 'primarynic', 'installnic'])}; + my %hents = + %{$hmtab->getNodesAttribs(\@nodes, + ['serialport', 'serialspeed', 'serialflow'])}; + #my $addkcmdhash = + # $bptab->getNodesAttribs(\@nodes, ['addkcmdline']); + require xCAT::Template; + foreach $node (@nodes) + { + my $os; + my $arch; + my $darch; + my $profile; + my $tmplfile; + my $pkgdir; + my $imagename; + my $platform; + + my $osinst; + my $ent = $osents{$node}->[0]; #$ostab->getNodeAttribs($node, ['profile', 'os', 'arch']); + if ($ent and $ent->{provmethod} and ($ent->{provmethod} ne 'install') and ($ent->{provmethod} ne 'netboot') and ($ent->{provmethod} ne 'statelite')) { + $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'}; + } + } + # if the install template wasn't found, then lets look for it in the default locations. + unless($img_hash{$imagename}->{template}){ + my $pltfrm=xCAT_plugin::debian::getplatform($ref->{'osvers'}); + my $tmplfile=xCAT::SvrUtils::get_tmpl_file_name("$installroot/custom/install/$pltfrm", + $ref->{'profile'}, $ref->{'osvers'}, $ref->{'osarch'}, $ref->{'osvers'}); + if (! $tmplfile) { $tmplfile=xCAT::SvrUtils::get_tmpl_file_name("$::XCATROOT/share/xcat/install/$pltfrm", + $ref->{'profile'}, $ref->{'osvers'}, $ref->{'osarch'}, $ref->{'osvers'}); + } + # if we managed to find it, put it in the hash: + if($tmplfile){ + $img_hash{$imagename}->{template}=$tmplfile; + } + } + } 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::debian::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::debian::getplatform($os); + my $genos = $os; + $genos =~ s/\..*//; + + $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"; + } + + if ($arch == "x86_64") { + $darch = "amd64"; + } elsif ($arch == "x86") { + $darch = "i386"; + } else { + xCAT::MsgUtils->message("S","debian.pm: Unknown arch ($arch)"); + $darch = $arch; + } + + my @missingparms; + unless ($os) { + if ($imagename) { push @missingparms,"osimage.osvers"; } + else { push @missingparms,"nodetype.os";} + } + unless ($arch) { + if ($imagename) { push @missingparms,"osimage.osarch"; } + else { push @missingparms,"nodetype.arch";} + } + unless ($profile) { + if ($imagename) { push @missingparms,"osimage.profile"; } + else { push @missingparms,"nodetype.profile";} + } + unless ($os and $arch and $profile) + { + $callback->( + { + error => ["Missing ".join(',',@missingparms)." for $node"], + errorcode => [1] + } + ); + next; #No profile + } + + unless ( -r "$tmplfile") + { + $callback->( + { + error => [ + "No $platform preseed template exists for " + . $profile + ], + errorcode => [1] + } + ); + next; + } + + #Call the Template class to do substitution to produce a preseed file in the autoinst dir + my $tmperr; + my $preerr; + my $posterr; + if ($imagename) { + $tmperr="Unable to find template file: $tmplfile"; + } else { + $tmperr="Unable to find template in $installroot/custom/install/$platform or $::XCATROOT/share/xcat/install/$platform (for $profile/$os/$arch combination)"; + } + if (-r "$tmplfile") + { + $tmperr = + xCAT::Template->subvars( + $tmplfile, + "$installroot/autoinst/" . $node, + $node + ); + } + + my $prescript = "$::XCATROOT/share/xcat/install/scripts/pre.$platform"; + my $postscript = "$::XCATROOT/share/xcat/install/scripts/post.$platform"; + + if (-r "$prescript") + { + $preerr = + xCAT::Template->subvars( + $prescript, + "$installroot/autoinst/" . $node . ".pre", + $node + ); + + } + if (-r "$postscript") + { + $posterr = + xCAT::Template->subvars( + $postscript, + "$installroot/autoinst/" . $node . ".post", + $node + ); + } + + my $errtmp; + + if ($errtmp=$tmperr or $errtmp=$preerr or $errtmp=$posterr) + { + $callback->( + { + node => + [{name => [$node], error => [$errtmp], errorcode => [1]}] + } + ); + next; + } + my $tftpdir = "/tftpboot"; + + # create the node-specific post scripts + #mkpath "$installroot/postscripts/"; + #xCAT::Postage->writescript($node,"$installroot/postscripts/".$node, "install", $callback); + my $kernpath; + my $initrdpath; + my $maxmem; + + if ( + ( + $arch =~ /x86/ and + ( + ( + -r "$pkgdir/install/netboot/ubuntu-installer/$darch/linux" + and $kernpath = "$pkgdir/install/netboot/ubuntu-installer/$darch/linux" + and -r "$pkgdir/install/netboot/ubuntu-installer/$darch/initrd.gz" + and $initrdpath = "$pkgdir/install/netboot/ubuntu-installer/$darch/initrd.gz" + ) or + ( + -r "$::XCATROOT/share/xcat/install/$platform/".$os."Images/linux" + and $kernpath = "$::XCATROOT/share/xcat/install/$platform/".$os."Images/linux" + and -r "$::XCATROOT/share/xcat/install/$platform/".$os."Images/initrd.gz" + and $initrdpath = "$::XCATROOT/share/xcat/install/$platform/".$os."Images/initrd.gz" + + ) + ) + + ) + ) + { + + #TODO: driver slipstream, targetted for network. + unless ($doneimgs{"$os|$arch"}) + { + mkpath("/tftpboot/xcat/$os/$arch"); + copy($kernpath,"$tftpdir/xcat/$os/$arch/vmlinuz"); + copy($initrdpath,"$tftpdir/xcat/$os/$arch/initrd.img"); + $doneimgs{"$os|$arch"} = 1; + } + + #We have a shot... + my $ent = $rents{$node}->[0]; +# $restab->getNodeAttribs($node, +# ['nfsserver', 'primarynic', 'installnic']); + my $sent = $hents{$node}->[0]; +# $hmtab->getNodeAttribs( +# $node, +# [ +# 'serialport', 'serialspeed', 'serialflow' +# ] +# ); + unless ($ent and $ent->{nfsserver}) + { + $callback->( + { + error => ["No noderes.nfsserver defined for " . $node], + errorcode => [1] + } + ); + next; + } + #if ($platform eq "ubuntu") + #{ + # my $kcmdline = + # "nofb utf8 auto url=http://" + # . $ent->{nfsserver} + # . "$installroot/autoinst/" + # . $node; + #} else + #{ + my $kcmdline = + "nofb utf8 auto url=http://" + . $ent->{nfsserver} + . "$installroot/autoinst/" + . $node; + #} + + if ($maxmem) { + $kcmdline.=" mem=$maxmem"; + } + my $ksdev = ""; + if ($ent->{installnic}) + { + if ($ent->{installnic} eq "mac") + { + my $mactab = xCAT::Table->new("mac"); + my $macref = $mactab->getNodeAttribs($node, ['mac']); + $ksdev = $macref->{mac}; + } + else + { + $ksdev = $ent->{installnic}; + } + } + elsif ($ent->{primarynic}) + { + if ($ent->{primarynic} eq "mac") + { + my $mactab = xCAT::Table->new("mac"); + my $macref = $mactab->getNodeAttribs($node, ['mac']); + $ksdev = $macref->{mac}; + } + else + { + $ksdev = $ent->{primarynic}; + } + } + else + { + $ksdev = "eth0"; + } + if ($ksdev eq "") + { + $callback->( + { + error => ["No MAC address defined for " . $node], + errorcode => [1] + } + ); + } + $kcmdline .= " netcfg/choose_interface=" . $ksdev; + + #TODO: dd= 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 .= + " console=tty0 console=ttyS" + . $sent->{serialport} . "," + . $sent->{serialspeed}; + if ($sent->{serialflow} =~ /(hard|cts|ctsrts)/) + { + $kcmdline .= "n8r"; + } + } + $kcmdline .= " noipv6"; + # add the addkcmdline attribute to the end + # of the command, if it exists + #my $addkcmd = $addkcmdhash->{$node}->[0]; + # add the extra addkcmd command info, if in the table + #if ($addkcmd->{'addkcmdline'}) { + # $kcmdline .= " "; + # $kcmdline .= $addkcmd->{'addkcmdline'}; + #} + + # need to add these in, otherwise aptitude will ask questions + $kcmdline .= " locale=en_US console-setup/layoutcode=us"; + #$kcmdline .= " netcfg/wireless_wep= netcfg/get_hostname= netcfg/get_domain="; + + # default answers as much as possible, we don't want any interactiveness :) + $kcmdline .= " priority=critical"; + + # Automatically detect all HDD + #$kcmdline .= " all-generic-ide irqpoll"; + + # by default do text based install + #$kcmdline .= " DEBIAN_FRONTEND=text"; + + # Maybe useful for debugging purposes + # + #$kcmdline .= " BOOT_DEBUG=3"; + #$kcmdline .= " DEBCONF_DEBUG=5"; + + # I don't need the timeout for ubuntu, but for debian there is a problem with getting dhcp in a timely manner + $kcmdline .= " netcfg/dhcp_timeout=120"; + + $bptab->setNodeAttribs( + $node, + { + kernel => "xcat/$os/$arch/vmlinuz", + initrd => "xcat/$os/$arch/initrd.img", + kcmdline => $kcmdline + } + ); + } + else + { + $callback->( + { + error => ["Install image not found in $installroot/$os/$arch"], + errorcode => [1] + } + ); + } + } + #my $rc = xCAT::Utils->create_postscripts_tar(); + #if ($rc != 0) + #{ + # xCAT::MsgUtils->message("S", "Error creating postscripts tar file."); + #} +} + +sub mknetboot +{ + my $xenstyle=0; + my $req = shift; + my $callback = shift; + my $doreq = shift; + my $statelite = 0; + if($req->{command}->[0] =~ 'mkstatelite'){ + $statelite = "true"; + } + my $tftpdir = "/tftpboot"; + my $nodes = @{$req->{node}}; + my @args = @{$req->{arg}}; + my @nodes = @{$req->{node}}; + my $ostab = xCAT::Table->new('nodetype'); + my $sitetab = xCAT::Table->new('site'); + my $linuximagetab; + my $osimagetab; + my %img_hash=(); + my $installroot; + $installroot = "/install"; + my $xcatdport = "3001"; + + if ($sitetab) + { + (my $ref) = $sitetab->getAttribs({key => 'installdir'}, 'value'); + if ($ref and $ref->{value}) + { + $installroot = $ref->{value}; + } + ($ref) = $sitetab->getAttribs({key => 'xcatdport'}, 'value'); + if ($ref and $ref->{value}) + { + $xcatdport = $ref->{value}; + } + } + my %donetftp=(); + my %oents = %{$ostab->getNodesAttribs(\@nodes,[qw(os arch profile provmethod)])}; + my $restab = xCAT::Table->new('noderes'); + my $bptab = xCAT::Table->new('bootparams',-create=>1); + my $hmtab = xCAT::Table->new('nodehm'); + my $reshash = $restab->getNodesAttribs(\@nodes, ['primarynic','tftpserver','xcatmaster','nfsserver','nfsdir']); + my $hmhash = + $hmtab->getNodesAttribs(\@nodes, + ['serialport', 'serialspeed', 'serialflow']); + my $statetab; + my $stateHash; + if($statelite){ + $statetab = xCAT::Table->new('statelite',-create=>1); + $stateHash = $statetab->getNodesAttribs(\@nodes, ['statemnt']); + } + #my $addkcmdhash = + # $bptab->getNodesAttribs(\@nodes, ['addkcmdline']); + foreach my $node (@nodes) + { + my $osver; + my $arch; + my $profile; + my $platform; + my $rootimgdir; + + my $ent = $oents{$node}->[0]; #ostab->getNodeAttribs($node, ['os', 'arch', 'profile']); + if ($ent and $ent->{provmethod} and ($ent->{provmethod} ne 'install') and ($ent->{provmethod} ne 'netboot') and ($ent->{provmethod} ne 'statelite')) { + 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) + { + $callback->( + { + error => ["Insufficient nodetype entry or osimage entry for $node"], + errorcode => [1] + } + ); + next; + } + + $platform=xCAT_plugin::debian::getplatform($osver); + my $suffix = 'gz'; + if (-r "$rootimgdir/rootimg.sfs") + { + $suffix = 'sfs'; + } + if (-r "$rootimgdir/rootimg.nfs") + { + $suffix = 'nfs'; + } + #statelite images are not packed. + unless ( + ( + -r "$rootimgdir/rootimg.gz" + or -r "$rootimgdir/rootimg.sfs" + or -r "$rootimgdir/rootimg.nfs" + or $statelite + ) + and -r "$rootimgdir/kernel" + and -r "$rootimgdir/initrd.gz" + ) + { + if($statelite){ + $callback->({error=> ["$node: statelite image $osver-$arch-statelite-$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; + } + + # create the node-specific post scripts + #mkpath "/install/postscripts/"; + #xCAT::Postage->writescript($node,"/install/postscripts/".$node, "netboot", $callback); + + mkpath("/$tftpdir/xcat/netboot/$osver/$arch/$profile/"); + + #TODO: only copy if newer... + unless ($donetftp{$osver,$arch,$profile}) { + 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; + } + 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; + } + my $ent = $reshash->{$node}->[0];#$restab->getNodeAttribs($node, ['primarynic']); + my $sent = $hmhash->{$node}->[0]; +# $hmtab->getNodeAttribs($node, +# ['serialport', 'serialspeed', 'serialflow']); + + # determine image server, if tftpserver use it, else use xcatmaster + # last resort use self + my $imgsrv; + my $ient; + my $xcatmaster; + + $ient = $reshash->{$node}->[0]; #$restab->getNodeAttribs($node, ['tftpserver']); + + if ($ient and $ient->{xcatmaster}) + { + $xcatmaster = $ient->{xcatmaster}; + } else { + $xcatmaster = '!myipfn!'; #allow service nodes to dynamically nominate themselves as a good contact point, this is of limited use in the event that xcat is not the dhcp/tftp server + } + + if ($ient and $ient->{tftpserver}) + { + $imgsrv = $ient->{tftpserver}; + } + else + { + $ient = $reshash->{$node}->[0]; #$restab->getNodeAttribs($node, ['xcatmaster']); + #if ($ient and $ient->{xcatmaster}) + #{ + # $imgsrv = $ient->{xcatmaster}; + #} + #else + #{ + # master not correct for service node pools + #$ient = $sitetab->getAttribs({key => master}, value); + #if ($ient and $ient->{value}) + #{ + # $imgsrv = $ient->{value}; + #} + #else + #{ + # $imgsrv = '!myipfn!'; + #} + #} + $imgsrv = $xcatmaster; + } + unless ($imgsrv) + { + $callback->( + { + error => [ + "Unable to determine or reasonably guess the image server for $node" + ], + errorcode => [1] + } + ); + next; + } + my $kcmdline; + if ($suffix eq "nfs") + { + $kcmdline = + "imgurl=nfs://$imgsrv/install/netboot/$osver/$arch/$profile/rootimg "; + } + elsif($statelite){ + # 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"; + #this code sez, "if nfsdir starts with //, then + #use a absolute path, i.e. do not append xCATisms" + #this is required for some statelite envs. + #still open for debate. + + if($ient->{nfsdir} =~ m!^//!) { + $nfsdir = $ient->{nfsdir}; + $nfsdir =~ s!^/!!; + } + } + + $kcmdline = + "NFSROOT=$nfssrv:$nfsdir STATEMNT="; + + # add support for subVars in the value of "statemnt" + my $statemnt = ""; + if (exists($stateHash->{$node})) { + $statemnt = $stateHash->{$node}->[0]->{statemnt}; + if (grep /\$/, $statemnt) { + my ($server, $dir) = split(/:/, $statemnt); + + #if server is blank, then its the directory + unless($dir) { + $dir = $server; + $server = ''; + } + if(grep /\$|#CMD/, $dir) { + $dir = subVars($dir, $node, 'dir', $callback); + $dir = ~ s/\/\//\//g; + } + if($server) { + $server = subVars($server, $node, 'server', $callback); + } + $statemnt = $server . ":" . $dir; + } + } + $kcmdline .= $statemnt ." "; + $kcmdline .= + "XCAT=$xcatmaster:$xcatdport "; + # BEGIN service node + my $isSV = xCAT::Utils->isServiceNode(); + my $res = xCAT::Utils->runcmd("hostname", 0); + my $sip = inet_ntoa(inet_aton($res)); # this is the IP of service node + if($isSV and (($xcatmaster eq $sip) or ($xcatmaster eq $res))) { + # if the NFS directory in litetree is on the service node, + # and it is not exported, then it will be mounted automatically + setupNFSTree($node, $sip, $callback); + # then, export the statemnt directory if it is on the service node + if($statemnt) { + setupStatemnt($sip, $statemnt, $callback); + } + } + # END service node + } + else + { + $kcmdline = + "imgurl=http://$imgsrv/install/netboot/$osver/$arch/$profile/rootimg.$suffix "; + } + 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 .= + "console=tty0 console=ttyS" . $sent->{serialport} . "," . $sent->{serialspeed}; + if ($sent->{serialflow} =~ /(hard|tcs|ctsrts)/) + { + $kcmdline .= "n8r"; + } + } + # add the addkcmdline attribute to the end + # of the command, if it exists + #my $addkcmd = $addkcmdhash->{$node}->[0]; + # add the extra addkcmd command info, if in the table + #if ($addkcmd->{'addkcmdline'}) { + # $kcmdline .= " "; + # $kcmdline .= $addkcmd->{'addkcmdline'}; + + #} + + my $kernstr="xcat/netboot/$osver/$arch/$profile/kernel"; + if ($xenstyle) { + $kernstr.= "!xcat/netboot/$osver/$arch/$profile/hypervisor"; + } + $bptab->setNodeAttribs( + $node, + { + kernel => "$kernstr", + initrd => "xcat/netboot/$osver/$arch/$profile/initrd.gz", + kcmdline => $kcmdline + } + ); + } + + #my $rc = xCAT::Utils->create_postscripts_tar(); + #if ( $rc != 0 ) { + # xCAT::MsgUtils->message( "S", "Error creating postscripts tar file." ); + #} +} + +sub getplatform { + my $os=shift; + my $platform; + if ($os =~ /debian.*/) + { + $platform = "debian"; + } + elsif ($os =~ /ubuntu.*/) + { + $platform = "ubuntu"; + } + return $platform; +} + +# sub subVars +# copied from litetreee.pm +# TODO: need to move the function to xCAT::Utils? + +# some directories will have xCAT database values, like: +# $nodetype.os. If that is the case we need to open up +# the database and look at them. We need to make sure +# we do this sparingly... We don't like tons of hits +# to the database. + +sub subVars() +{ + my $dir = shift; + my $node = shift; + my $type = shift; + my $callback = shift; + + # parse all the dollar signs... + # if its a directory then it has a / in it, so you have to parse it. + # if its a server, it won't have one so don't worry about it. + my @arr = split("/", $dir); + my $fdir = ""; + foreach my $p (@arr){ + # have to make this geric so $ can be in the midle of the name: asdf$foobar.sitadsf + if($p =~ /\$/){ + my $pre; + my $suf; + my @fParts; + if($p =~ /([^\$]*)([^# ]*)(.*)/){ + $pre= $1; + $p = $2; + $suf = $3; + } + # have to sub here: + # get rid of the $ sign. + foreach my $part (split('\$',$p)){ + if($part eq ''){ next; } + #$callback->({error=>["part is $part"],errorcode=>[1]}); + # check if p is just the node name: + if($part eq 'node'){ + # it is so, just return the node. + #$fdir .= "/$pre$node$suf"; + push @fParts, $node; + }else{ + # ask the xCAT DB what the attribute is. + my ($table, $col) = split('\.', $part); + unless($col){ $col = 'UNDEFINED' }; + my $tab = xCAT::Table->new($table); + unless($tab){ + $callback->({error=>["$table does not exist"],errorcode=>[1]}); + return; + } + my $ent; + my $val; + if($table eq 'site'){ + $val = $tab->getAttribs( { key => "$col" }, 'value' ); + $val = $val->{'value'}; + }else{ + $ent = $tab->getNodeAttribs($node,[$col]); + $val = $ent->{$col}; + } + unless($val){ + # couldn't find the value!! + $val = "UNDEFINED" + } + push @fParts, $val; + } + } + my $val = join('.', @fParts); + if($type eq 'dir'){ + $fdir .= "/$pre$val$suf"; + }else{ + $fdir .= $pre . $val . $suf; + } + }else{ + # no substitution here + $fdir .= "/$p"; + } + } + # now that we've processed variables, process commands + # this isn't quite rock solid. You can't name directories with #'s in them. + if($fdir =~ /#CMD=/){ + my $dir; + foreach my $p (split(/#/,$fdir)){ + if($p =~ /CMD=/){ + $p =~ s/CMD=//; + my $cmd = $p; + #$callback->({info=>[$p]}); + $p = `$p 2>&1`; + chomp($p); + #$callback->({info=>[$p]}); + unless($p){ + $p = "#CMD=$p did not return output#"; + } + } + $dir .= $p; + } + $fdir = $dir; + } + + return $fdir; +} + +sub setupNFSTree { + my $node = shift; + my $sip = shift; + my $callback = shift; + + my $cmd = "litetree $node"; + my @uris = xCAT::Utils->runcmd($cmd, 0); + + foreach my $uri (@uris) { + # parse the result + # the result looks like "nodename: nfsserver:directory"; + $uri =~ m/\Q$node\E:\s+(.+):(.+)$/; + my $nfsserver = $1; + my $nfsdirectory = $2; + + if($nfsserver eq $sip) { # on the service node + unless (-d $nfsdirectory) { + if (-e $nfsdirectory) { + unlink $nfsdirectory; + } + mkpath $nfsdirectory; + } + + + $cmd = "showmount -e $nfsserver"; + my @entries = xCAT::Utils->runcmd($cmd, 0); + shift @entries; + if(grep /\Q$nfsdirectory\E/, @entries) { + $callback->({data=>["$nfsdirectory has been exported already!"]}); + } else { + $cmd = "/usr/sbin/exportfs :$nfsdirectory"; + xCAT::Utils->runcmd($cmd, 0); + # exportfs can export this directory immediately + $callback->({data=>["now $nfsdirectory is exported!"]}); + $cmd = "cat /etc/exports"; + @entries = xCAT::Utils->runcmd($cmd, 0); + unless (my $entry = grep /\Q$nfsdirectory\E/, @entries) { + # if no entry in /etc/exports, one entry with default options will be added + $cmd = qq{echo "$nfsdirectory *(rw,no_root_squash,sync,no_subtree_check)" >> /etc/exports}; + xCAT::Utils->runcmd($cmd, 0); + $callback->({data=>["$nfsdirectory is added to /etc/exports with default option"]}); + } + } + } + } +} + +sub setupStatemnt { + my $sip = shift; + my $statemnt = shift; + my $callback = shift; + + $statemnt =~ m/^(.+):(.+)$/; + my $nfsserver = $1; + my $nfsdirectory = $2; + + if($sip eq inet_ntoa(inet_aton($nfsserver))) { + unless (-d $nfsdirectory) { + if (-e $nfsdirectory) { + unlink $nfsdirectory; + } + mkpath $nfsdirectory; + } + + my $cmd = "showmount -e $nfsserver"; + my @entries = xCAT::Utils->runcmd($cmd, 0); + shift @entries; + if(grep /\Q$nfsdirectory\E/, @entries) { + $callback->({data=>["$nfsdirectory has been exported already!"]}); + } else { + $cmd = "/usr/sbin/exportfs :$nfsdirectory -o rw,no_root_squash,sync,no_subtree_check"; + xCAT::Utils->runcmd($cmd, 0); + $callback->({data=>["now $nfsdirectory is exported!"]}); + # add the directory into /etc/exports if not exist + $cmd = "cat /etc/exports"; + @entries = xCAT::Utils->runcmd($cmd, 0); + if(my $entry = grep /\Q$nfsdirectory\E/, @entries) { + unless ($entry =~ m/rw/) { + $callback->({data => ["The $nfsdirectory should be with rw option in /etc/exports"]}); + } + } else { + xCAT::Utils->runcmd(qq{echo "$nfsdirectory *(rw,no_root_squash,sync,no_subtree_check)" >> /etc/exports}, 0); + $callback->({data => ["$nfsdirectory is added into /etc/exports with default options"]}); + } + } + } +} + + +1; diff --git a/xCAT-server/share/xcat/install/debian/compute.tmpl b/xCAT-server/share/xcat/install/debian/compute.tmpl new file mode 100644 index 000000000..1528a5e80 --- /dev/null +++ b/xCAT-server/share/xcat/install/debian/compute.tmpl @@ -0,0 +1,129 @@ + +### Localization +d-i debian-installer/locale string en_GB + +# Keyboard Selection +d-i console-setup/ask_detect boolean false +d-i console-setup/layoutcode string uk + +### Network Configuration +d-i netcfg/choose_interface select #TABLE:noderes:$NODE:primarynic# +d-i netcfg/dhcp_options select Configure network manually + +d-i netcfg/dhcp_timeout string 60 +d-i netcfg/get_hostname string #TABLE:nodelist:THISNODE:node# +d-i netcfg/get_domain string #TABLE:site:key=domain:value# +d-i netcfg/wireless_wep string +d-i netcfg/disable-dhcp boolean false +d-i netcfg/confirm_static boolean false + +### Mirror settings +# If you select ftp, the mirror/country string does not need to be set. + +d-i mirror/country string manual +d-i mirror/protocol string http +d-i mirror/http/hostname string #TABLE:noderes:$NODE:nfsserver# +d-i mirror/http/directory string /install/#TABLE:nodetype:$NODE:os#/#TABLE:nodetype:$NODE:arch#/ +d-i mirror/http/proxy string + +# Suite to install. +#d-i mirror/suite select stable +#d-i mirror/codename string +# Suite to use for loading installer components (optional). +#d-i mirror/udeb/suite string testing +#d-i mirror/suite string feisty + + +### Partitioning +# This creates a small /boot partition, suitable +# swap, and uses the rest of the space for the root partition: + +d-i partman-auto/method string regular +d-i partman-lvm/device_remove_lvm boolean true +d-i partman-md/device_remove_md boolean true + +d-i partman-auto/expert_recipe string \ + boot-root :: \ + 40 50 100 ext3 \ + $primary{ } $bootable{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext3 } \ + mountpoint{ /boot } \ + . \ + 500 10000 1000000000 ext3 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext3 } \ + mountpoint{ / } \ + . \ + 64 512 300% linux-swap \ + method{ swap } format{ } \ + . + +# This makes partman automatically partition without confirmation, provided +# that you told it what to do using one of the methods above. + +d-i partman/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true + + +### Account setup + +d-i passwd/root-login boolean true +d-i passwd/make-user boolean false + +d-i passwd/root-password-crypted password #CRYPT:passwd:key=system,username=root:password# + +### Clock and time zone setup + +d-i clock-setup/ntp boolean true +d-i clock-setup/ntp-server string #TABLE:site:key=master:value# +d-i clock-setup/utc boolean true +d-i time/zone string #TABLE:site:key=timezone:value# + +### Apt setup + +#d-i apt-setup/multiverse boolean true +#d-i apt-setup/universe boolean true + + +### Boot loader installation + +d-i grub-installer/only_debian boolean true + +### Package selection + +tasksel tasksel/first multiselect standard + +# gawk required for the xCAT scripts to work +# Otherwise it installs mawk, which doesn't work + +d-i pkgsel/include string openssh-server ntp gawk + +d-i debian-installer/allow_unauthenticated string true +d-i pkgsel/update-policy select none +d-i pkgsel/updatedb boolean false + +### Finishing up the installation +d-i finish-install/reboot_in_progress note + +### X configuration +xserver-xorg xserver-xorg/autodetect_monitor boolean true + +xserver-xorg xserver-xorg/config/monitor/selection-method \ + select medium + +xserver-xorg xserver-xorg/config/monitor/mode-list \ + select 1024x768 @ 60 Hz + + +d-i preseed/early_command string wget http://#TABLE:noderes:$NODE:nfsserver#/install/autoinst/#TABLE:nodelist:THISNODE:node#.pre; \ + chmod u+x #TABLE:nodelist:THISNODE:node#.pre; \ + ./#TABLE:nodelist:THISNODE:node#.pre + +d-i preseed/late_command string wget http://#TABLE:noderes:$NODE:nfsserver#/install/autoinst/#TABLE:nodelist:THISNODE:node#.post; \ + chmod u+x #TABLE:nodelist:THISNODE:node#.post; \ + cp ./#TABLE:nodelist:THISNODE:node#.post /target/root/post.script; \ + chroot /target /root/post.script + diff --git a/xCAT-server/share/xcat/install/debian/debian5.0.6Images/initrd.gz b/xCAT-server/share/xcat/install/debian/debian5.0.6Images/initrd.gz new file mode 100644 index 000000000..692fc4fc6 Binary files /dev/null and b/xCAT-server/share/xcat/install/debian/debian5.0.6Images/initrd.gz differ diff --git a/xCAT-server/share/xcat/install/debian/debian5.0.6Images/initrd.gz.backport b/xCAT-server/share/xcat/install/debian/debian5.0.6Images/initrd.gz.backport new file mode 100644 index 000000000..4d3e4cb96 Binary files /dev/null and b/xCAT-server/share/xcat/install/debian/debian5.0.6Images/initrd.gz.backport differ diff --git a/xCAT-server/share/xcat/install/debian/debian5.0.6Images/linux b/xCAT-server/share/xcat/install/debian/debian5.0.6Images/linux new file mode 100644 index 000000000..4d3e4cb96 Binary files /dev/null and b/xCAT-server/share/xcat/install/debian/debian5.0.6Images/linux differ diff --git a/xCAT-server/share/xcat/install/debian/debian5.0.6Images/linux.backport b/xCAT-server/share/xcat/install/debian/debian5.0.6Images/linux.backport new file mode 100644 index 000000000..9feeb4a11 Binary files /dev/null and b/xCAT-server/share/xcat/install/debian/debian5.0.6Images/linux.backport differ diff --git a/xCAT-server/share/xcat/install/scripts/post.debian b/xCAT-server/share/xcat/install/scripts/post.debian new file mode 100644 index 000000000..2bb38be0d --- /dev/null +++ b/xCAT-server/share/xcat/install/scripts/post.debian @@ -0,0 +1,141 @@ +#!/bin/bash +# +# Setup hostname +# +echo "post scripts" >/root/post.log +export PRINIC=#TABLE:noderes:THISNODE:primarynic# +if [ "$PRINIC" == "mac" ] +then + export PRINIC='#TABLE:mac:THISNODE:mac#' +fi +if [ -z "$PRINIC" ] +then + export PRINIC=eth0 +elif [[ `echo "$PRINIC" | grep -sqE ^[A-Fa-f0-9]+:[A-Fa-f0-9]+:[A-Fa-f0-9]+:[A-Fa-f0-9]+:[A-Fa-f0-9]+:[A-Fa-f0-9]+$ ;echo $?` == "0" ]]; then + export PRINIC=`ifconfig -a | grep -i "HWaddr $PRINIC" | awk '{print $1}'` +fi +IP=$(ifconfig $PRINIC | grep inet | awk '{print $2}' | awk -F: '{print $2}') +if [ -z $IP ] +then + dhclient eth0 + IP=$(ifconfig $PRINIC | grep inet | awk '{print $2}' | awk -F: '{print $2}') +fi +echo "search #TABLE:site:key=domain:value#" >/etc/resolv.conf +for i in $(echo #TABLE:site:key=nameservers:value# | tr ',' ' ') +do + echo "nameserver $i" +done >>/etc/resolv.conf +export HOSTNAME=$(host $IP 2>/dev/null | awk '{print $5}' | awk -F. '{print $1}') +hostname $HOSTNAME +# +# Run xCAT post install +# +export MASTER_IP="#XCATVAR:XCATMASTER#" +export MASTER_IPS="#XCATVAR:XCATMASTER#" +export MASTER="#XCATVAR:XCATMASTER#" +cd /tmp +RAND=$(perl -e 'print int(rand(50)). "\n"') +sleep $RAND +for i in $(seq 1 20) +do + GOTIT=0 + for i in $MASTER_IPS + do + wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 0 -T 60 ftp://$i/postscripts + #wget --wait=10 --random-wait --waitretry=10 --retry-connrefused -t 0 -T 60 http://$i/install/autoinst/xcatpost.tar.gz + if [ "$?" = "0" ] + then + if [ ! -x /usr/bin/openssl ]; then #Stop if no openssl to help the next bit + exit 1 + fi + USEOPENSSLFORXCAT=1 #Though this is the only method going forward, flag to allow backward compatibility with 2.2 generated netboot images + export USEOPENSSLFORXCAT + XCATSERVER=$i:3001 + export XCATSERVER + mv $i/postscripts /xcatpost + rm -rf $i + chmod +x /xcatpost/* + /xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript + MYCONT=`grep MASTER /tmp/mypostscript` + MAX_RETRIES=10 + RETRY=0 + while [ -z "$MYCONT" ]; do + RETRY=$(($RETRY+1)) + if [ $RETRY -eq $MAX_RETRIES ] + then + break + fi + + let SLI=$RANDOM%10+10 + sleep $SLI + /xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript + MYCONT=`grep MASTER /tmp/mypostscript` + done + + + chmod +x /tmp/mypostscript + GOTIT=1 + break + fi + done + if [ "$GOTIT" = "1" ] + then + #save the master to /opt/xcat/xcatinfo file + if [ ! -f /opt/xcat/xcatinfo ]; then + mkdir -p /opt/xcat + touch /opt/xcat/xcatinfo + fi + echo "XCATSERVER=$i" > /opt/xcat/xcatinfo + break + fi + RAND=$(perl -e 'print int(rand(5)). "\n"') + sleep $RAND +done +cd /xcatpost +#gunzip xcatpost.tar.gz +#tar -xvf xcatpost.tar +#/xcatpost/#TABLE:nodelist:THISNODE:node# +export PATH=/xcatpost:$PATH + +#save the postboot scripts to /tmp/mypostscript.post +TMP=`sed "/postscripts-start-here/,/postscripts-end-here/ d" /tmp/mypostscript` +echo "$TMP" > /tmp/mypostscript.post +chmod 755 /tmp/mypostscript.post + +#create the post init +cat >/etc/init.d/xcatpostinit1 << 'EOF' +#INCLUDE:#TABLE:site:key=installdir:value#/postscripts/xcatpostinit1# +EOF +chmod 755 /etc/init.d/xcatpostinit1 +ln -s /etc/init.d/xcatpostinit1 /etc/rc2.d/S84xcatpostinit1 +mkdir -p /opt/xcat +cat >/opt/xcat/xcatinstallpost << 'EOF' +#INCLUDE:#TABLE:site:key=installdir:value#/postscripts/xcatinstallpost# +rm /etc/rc2.d/S84xcatpostinit1 +EOF +chmod 755 /opt/xcat/xcatinstallpost + +#only run the prebooot scripts here +TMP=`sed "/postbootscripts-start-here/,/postbootscripts-end-here/ d" /tmp/mypostscript` +echo "$TMP" > /tmp/mypostscript + +/tmp/mypostscript +export NODE=#TABLE:nodelist:THISNODE:node# +export OSVER=#TABLE:nodetype:THISNODE:os# +export ARCH=#TABLE:nodetype:THISNODE:arch# +#addsiteyum +if [[ -r /boot/grub/menu.lst ]]; then +sed -i 's/^serial/#serial/' /boot/grub/menu.lst +sed -i 's/^terminal/#terminal/' /boot/grub/menu.lst +elif [[ -r /boot/grub/grub.cfg ]] ; then +sed -i 's/\(GRUB_CMDLINE_LINUX=\).*/\1\"console=tty0\ console=ttyS#TABLE:nodehm:THISNODE:serialport#,#TABLE:nodehm:THISNODE:serialspeed#\"/' /etc/default/grub +sed -i 's/\(GRUB_CMDLINE_LINUX_DEFAULT=\).*/\1""/g' /etc/default/grub +update-grub +fi +sed -i 's/\(deb.*security.*\)/#\1/' /etc/apt/sources.list +updateflag.awk $MASTER 3002 +cd / +#rm -Rf /xcatpost +#rm -f /tmp/mypostscript +exit 0 + diff --git a/xCAT-server/share/xcat/install/scripts/post.ubuntu b/xCAT-server/share/xcat/install/scripts/post.ubuntu new file mode 100644 index 000000000..2bb38be0d --- /dev/null +++ b/xCAT-server/share/xcat/install/scripts/post.ubuntu @@ -0,0 +1,141 @@ +#!/bin/bash +# +# Setup hostname +# +echo "post scripts" >/root/post.log +export PRINIC=#TABLE:noderes:THISNODE:primarynic# +if [ "$PRINIC" == "mac" ] +then + export PRINIC='#TABLE:mac:THISNODE:mac#' +fi +if [ -z "$PRINIC" ] +then + export PRINIC=eth0 +elif [[ `echo "$PRINIC" | grep -sqE ^[A-Fa-f0-9]+:[A-Fa-f0-9]+:[A-Fa-f0-9]+:[A-Fa-f0-9]+:[A-Fa-f0-9]+:[A-Fa-f0-9]+$ ;echo $?` == "0" ]]; then + export PRINIC=`ifconfig -a | grep -i "HWaddr $PRINIC" | awk '{print $1}'` +fi +IP=$(ifconfig $PRINIC | grep inet | awk '{print $2}' | awk -F: '{print $2}') +if [ -z $IP ] +then + dhclient eth0 + IP=$(ifconfig $PRINIC | grep inet | awk '{print $2}' | awk -F: '{print $2}') +fi +echo "search #TABLE:site:key=domain:value#" >/etc/resolv.conf +for i in $(echo #TABLE:site:key=nameservers:value# | tr ',' ' ') +do + echo "nameserver $i" +done >>/etc/resolv.conf +export HOSTNAME=$(host $IP 2>/dev/null | awk '{print $5}' | awk -F. '{print $1}') +hostname $HOSTNAME +# +# Run xCAT post install +# +export MASTER_IP="#XCATVAR:XCATMASTER#" +export MASTER_IPS="#XCATVAR:XCATMASTER#" +export MASTER="#XCATVAR:XCATMASTER#" +cd /tmp +RAND=$(perl -e 'print int(rand(50)). "\n"') +sleep $RAND +for i in $(seq 1 20) +do + GOTIT=0 + for i in $MASTER_IPS + do + wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 0 -T 60 ftp://$i/postscripts + #wget --wait=10 --random-wait --waitretry=10 --retry-connrefused -t 0 -T 60 http://$i/install/autoinst/xcatpost.tar.gz + if [ "$?" = "0" ] + then + if [ ! -x /usr/bin/openssl ]; then #Stop if no openssl to help the next bit + exit 1 + fi + USEOPENSSLFORXCAT=1 #Though this is the only method going forward, flag to allow backward compatibility with 2.2 generated netboot images + export USEOPENSSLFORXCAT + XCATSERVER=$i:3001 + export XCATSERVER + mv $i/postscripts /xcatpost + rm -rf $i + chmod +x /xcatpost/* + /xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript + MYCONT=`grep MASTER /tmp/mypostscript` + MAX_RETRIES=10 + RETRY=0 + while [ -z "$MYCONT" ]; do + RETRY=$(($RETRY+1)) + if [ $RETRY -eq $MAX_RETRIES ] + then + break + fi + + let SLI=$RANDOM%10+10 + sleep $SLI + /xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript + MYCONT=`grep MASTER /tmp/mypostscript` + done + + + chmod +x /tmp/mypostscript + GOTIT=1 + break + fi + done + if [ "$GOTIT" = "1" ] + then + #save the master to /opt/xcat/xcatinfo file + if [ ! -f /opt/xcat/xcatinfo ]; then + mkdir -p /opt/xcat + touch /opt/xcat/xcatinfo + fi + echo "XCATSERVER=$i" > /opt/xcat/xcatinfo + break + fi + RAND=$(perl -e 'print int(rand(5)). "\n"') + sleep $RAND +done +cd /xcatpost +#gunzip xcatpost.tar.gz +#tar -xvf xcatpost.tar +#/xcatpost/#TABLE:nodelist:THISNODE:node# +export PATH=/xcatpost:$PATH + +#save the postboot scripts to /tmp/mypostscript.post +TMP=`sed "/postscripts-start-here/,/postscripts-end-here/ d" /tmp/mypostscript` +echo "$TMP" > /tmp/mypostscript.post +chmod 755 /tmp/mypostscript.post + +#create the post init +cat >/etc/init.d/xcatpostinit1 << 'EOF' +#INCLUDE:#TABLE:site:key=installdir:value#/postscripts/xcatpostinit1# +EOF +chmod 755 /etc/init.d/xcatpostinit1 +ln -s /etc/init.d/xcatpostinit1 /etc/rc2.d/S84xcatpostinit1 +mkdir -p /opt/xcat +cat >/opt/xcat/xcatinstallpost << 'EOF' +#INCLUDE:#TABLE:site:key=installdir:value#/postscripts/xcatinstallpost# +rm /etc/rc2.d/S84xcatpostinit1 +EOF +chmod 755 /opt/xcat/xcatinstallpost + +#only run the prebooot scripts here +TMP=`sed "/postbootscripts-start-here/,/postbootscripts-end-here/ d" /tmp/mypostscript` +echo "$TMP" > /tmp/mypostscript + +/tmp/mypostscript +export NODE=#TABLE:nodelist:THISNODE:node# +export OSVER=#TABLE:nodetype:THISNODE:os# +export ARCH=#TABLE:nodetype:THISNODE:arch# +#addsiteyum +if [[ -r /boot/grub/menu.lst ]]; then +sed -i 's/^serial/#serial/' /boot/grub/menu.lst +sed -i 's/^terminal/#terminal/' /boot/grub/menu.lst +elif [[ -r /boot/grub/grub.cfg ]] ; then +sed -i 's/\(GRUB_CMDLINE_LINUX=\).*/\1\"console=tty0\ console=ttyS#TABLE:nodehm:THISNODE:serialport#,#TABLE:nodehm:THISNODE:serialspeed#\"/' /etc/default/grub +sed -i 's/\(GRUB_CMDLINE_LINUX_DEFAULT=\).*/\1""/g' /etc/default/grub +update-grub +fi +sed -i 's/\(deb.*security.*\)/#\1/' /etc/apt/sources.list +updateflag.awk $MASTER 3002 +cd / +#rm -Rf /xcatpost +#rm -f /tmp/mypostscript +exit 0 + diff --git a/xCAT-server/share/xcat/install/scripts/pre.debian b/xCAT-server/share/xcat/install/scripts/pre.debian new file mode 100644 index 000000000..cabbe9c68 --- /dev/null +++ b/xCAT-server/share/xcat/install/scripts/pre.debian @@ -0,0 +1,90 @@ +#!/bin/sh + +AWK=`find / -name awk | tail -1` +#old awk /mounts/instsys/bin/awk -f + +cat >/tmp/bar.awk </tmp/foo.awk < 0) +# print \$0 |& ns +# print "EOO" |& ns +# close(output) +# } + + if(\$1 == "screendump") { + output = "chvt " \$2 ";cat /dev/vcs" + while((output | getline) > 0) + print \$0 |& ns + close(output) + } + + if(\$1 == "stat") { + while((getline < "/target/var/log/installer/syslog") > 0) { + line = \$0 + } + close("/target/var/log/installer/syslog") + + if(line ~ /Unpacking/) { + sub(/\.[^\.]+\.deb .*$/,"",line) + sub(/^.* /,"",line) + } + if( (line ~ /Installing/) (line ~ /Selecting/) or (line ~ /Setting\ up/)) { + sub(/\.[^\.]+\.deb .*$/,"",line) + sub(/^.* /,"",line) + } + else { + line = "prep" + } + + print ("installing " line) |& ns + } + + close(ns) + } +} +EOF + +chmod 755 /tmp/foo.awk +chmod 755 /tmp/bar.awk + +/tmp/bar.awk & +/tmp/foo.awk >/tmp/foo.log 2>&1 & diff --git a/xCAT-server/share/xcat/install/scripts/pre.ubuntu b/xCAT-server/share/xcat/install/scripts/pre.ubuntu new file mode 100644 index 000000000..cabbe9c68 --- /dev/null +++ b/xCAT-server/share/xcat/install/scripts/pre.ubuntu @@ -0,0 +1,90 @@ +#!/bin/sh + +AWK=`find / -name awk | tail -1` +#old awk /mounts/instsys/bin/awk -f + +cat >/tmp/bar.awk </tmp/foo.awk < 0) +# print \$0 |& ns +# print "EOO" |& ns +# close(output) +# } + + if(\$1 == "screendump") { + output = "chvt " \$2 ";cat /dev/vcs" + while((output | getline) > 0) + print \$0 |& ns + close(output) + } + + if(\$1 == "stat") { + while((getline < "/target/var/log/installer/syslog") > 0) { + line = \$0 + } + close("/target/var/log/installer/syslog") + + if(line ~ /Unpacking/) { + sub(/\.[^\.]+\.deb .*$/,"",line) + sub(/^.* /,"",line) + } + if( (line ~ /Installing/) (line ~ /Selecting/) or (line ~ /Setting\ up/)) { + sub(/\.[^\.]+\.deb .*$/,"",line) + sub(/^.* /,"",line) + } + else { + line = "prep" + } + + print ("installing " line) |& ns + } + + close(ns) + } +} +EOF + +chmod 755 /tmp/foo.awk +chmod 755 /tmp/bar.awk + +/tmp/bar.awk & +/tmp/foo.awk >/tmp/foo.log 2>&1 & diff --git a/xCAT-server/share/xcat/install/ubuntu/compute.tmpl b/xCAT-server/share/xcat/install/ubuntu/compute.tmpl new file mode 100644 index 000000000..c65d453ae --- /dev/null +++ b/xCAT-server/share/xcat/install/ubuntu/compute.tmpl @@ -0,0 +1,127 @@ + +### Localization +d-i debian-installer/locale string en_GB + +# Keyboard Selection +d-i console-setup/ask_detect boolean false +d-i console-setup/layoutcode string uk + +### Network Configuration +d-i netcfg/choose_interface select #TABLE:noderes:$NODE:primarynic# + +d-i netcfg/get_hostname string unassigned-hostname +d-i netcfg/get_domain string unassigned-domain +d-i netcfg/wireless_wep string + +### Mirror settings +# If you select ftp, the mirror/country string does not need to be set. + +d-i mirror/country string manual +d-i mirror/protocol string http +d-i mirror/http/hostname string #TABLE:noderes:$NODE:nfsserver# +d-i mirror/http/directory string /install/#TABLE:nodetype:$NODE:os#/#TABLE:nodetype:$NODE:arch# +d-i mirror/http/proxy string + +# Suite to install. +#d-i mirror/suite string testing +# Suite to use for loading installer components (optional). +#d-i mirror/udeb/suite string testing +#d-i mirror/suite string feisty + + +### Partitioning +# This creates a small /boot partition, suitable +# swap, and uses the rest of the space for the root partition: + +d-i partman-auto/method strng regular +d-i partman-lvm/device_remove_lvm boolean true +d-i partman-md/device_remove_md boolean true + +# 100M /boot +# 4G swap +# / rest +d-i partman-auto/expert_recipe string \ + boot-root :: \ + 100 50 100 ext3 \ + $primary{ } $bootable{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext3 } \ + mountpoint{ /boot } \ + . \ + 500 10000 1000000000 ext3 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext3 } \ + mountpoint{ / } \ + . \ + 4096 512 300% linux-swap \ + method{ swap } format{ } \ + . + +# This makes partman automatically partition without confirmation, provided +# that you told it what to do using one of the methods above. + +d-i partman/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true + + +### Account setup + +d-i passwd/root-login boolean true +d-i passwd/make-user boolean false + +d-i passwd/root-password-crypted password #CRYPT:passwd:key=system,username=root:password# + +### Clock and time zone setup + +d-i clock-setup/ntp boolean true +d-i clock-setup/ntp-server string #TABLE:site:key=master:value# +d-i clock-setup/utc boolean true +d-i time/zone string #TABLE:site:key=timezone:value# + +### Apt setup + +d-i apt-setup/multiverse boolean false +d-i apt-setup/universe boolean false + + +### Boot loader installation + +d-i grub-installer/only_debian boolean true + +### Package selection + +tasksel tasksel/first multiselect standard + +# gawk required for the xCAT scripts to work +# Otherwise it installs mawk, which doesn't work + +d-i pkgsel/include string openssh-server ntp gawk + +d-i debian-installer/allow_unauthenticated string true +d-i pkgsel/update-policy select none +d-i pkgsel/updatedb boolean false + +### Finishing up the installation +d-i finish-install/reboot_in_progress note + +### X configuration +xserver-xorg xserver-xorg/autodetect_monitor boolean true + +xserver-xorg xserver-xorg/config/monitor/selection-method \ + select medium + +xserver-xorg xserver-xorg/config/monitor/mode-list \ + select 1024x768 @ 60 Hz + + +d-i preseed/early_command string wget http://#TABLE:noderes:$NODE:nfsserver#/install/autoinst/#TABLE:nodelist:THISNODE:node#.pre; \ + chmod u+x #TABLE:nodelist:THISNODE:node#.pre; \ + ./#TABLE:nodelist:THISNODE:node#.pre + +d-i preseed/late_command string wget http://#TABLE:noderes:$NODE:nfsserver#/install/autoinst/#TABLE:nodelist:THISNODE:node#.post; \ + chmod u+x #TABLE:nodelist:THISNODE:node#.post; \ + cp ./#TABLE:nodelist:THISNODE:node#.post /target/root/post.script; \ + chroot /target /root/post.script + diff --git a/xCAT-server/share/xcat/netboot/debian/compute.exlist b/xCAT-server/share/xcat/netboot/debian/compute.exlist new file mode 100644 index 000000000..fb4fb072b --- /dev/null +++ b/xCAT-server/share/xcat/netboot/debian/compute.exlist @@ -0,0 +1,13 @@ +./usr/share/man* +./usr/share/locale* +./usr/share/i18n* +./var/cache/yum* +./usr/share/doc* +./usr/share/gnome* +./usr/share/zoneinfo* +./usr/share/cracklib* +./usr/share/info* +./usr/share/omf* +./usr/lib/locale* +./usr/lib/perl5* +./boot* diff --git a/xCAT-server/share/xcat/netboot/debian/compute.pkglist b/xCAT-server/share/xcat/netboot/debian/compute.pkglist new file mode 100644 index 000000000..74b91240d --- /dev/null +++ b/xCAT-server/share/xcat/netboot/debian/compute.pkglist @@ -0,0 +1,12 @@ +bash +nfs-common +openssl +dhcp3-client +linux-image +openssh-server +openssh-client +wget +vim +ntp +rsyslog +rsync diff --git a/xCAT-server/share/xcat/netboot/debian/genimage b/xCAT-server/share/xcat/netboot/debian/genimage new file mode 100755 index 000000000..198b17514 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/debian/genimage @@ -0,0 +1,1265 @@ +#!/usr/bin/env perl +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; + +use File::Basename; +use File::Path; +use File::Copy; +use File::Find; +use Getopt::Long; +use Cwd qw(realpath); +#use strict; +Getopt::Long::Configure("bundling"); +Getopt::Long::Configure("pass_through"); + +my $prinic; #TODO be flexible on node primary nic +my $othernics; #TODO be flexible on node primary nic +my $netdriver; +my @yumdirs; +my $arch; +my %libhash; +my @filestoadd; +my $profile; +my $osver; +my $pathtofiles=dirname($0); +my $fullpath=realpath($pathtofiles); +my $name = basename($0); +my $onlyinitrd=0; +if ($name =~ /geninitrd/) { + $onlyinitrd=1; +} +my $rootlimit; +my $tmplimit; +my $installroot = "/install"; +my $kernelver = ""; #`uname -r`; +my $basekernelver; # = $kernelver; +my $customdir=$fullpath; +$customdir =~ s/.*share\/xcat/$installroot\/custom/; +my $imagename; +my $pkglist; +my $srcdir; +my $destdir; +my $srcdir_otherpkgs; +my $otherpkglist; +my $postinstall_filename; +my $rootimg_dir; +my $rwfiles; # these files are used by statelite for tmpfs rw +my $mode; +my $permission; # the permission works only for statelite mode currently + + +sub xdie { + system("rm -rf /tmp/xcatinitrd.$$"); + die @_; +} + +$SIG{INT} = $SIG{TERM} = sub { xdie "Interrupted" }; +GetOptions( + 'a=s' => \$arch, + 'p=s' => \$profile, + 'o=s' => \$osver, + 'n=s' => \$netdriver, + 'i=s' => \$prinic, + 'r=s' => \$othernics, + 'l=s' => \$rootlimit, + 't=s' => \$tmplimit, + 'k=s' => \$kernelver, + 'm=s' => \$mode, + 'permission=s' => \$permission +); +if (@ARGV > 0) { + $imagename=$ARGV[0]; + if ($arch or $osver or $profile) { + print "-o, -p and -a options are not allowed when a image name is specified.\n"; + exit 1; + } + #load the module in memory + eval {require("$::XCATROOT/lib/perl/xCAT/Table.pm")}; + if ($@) { + print $@; + exit 1; + } + + #get the info from the osimage and linux + my $osimagetab=xCAT::Table->new('osimage', -create=>1); + if (!$osimagetab) { + print "The osimage table cannot be opened.\n"; + exit 1; + } + my $linuximagetab=xCAT::Table->new('linuximage', -create=>1); + if (!$linuximagetab) { + print "The linuximage table cannot be opened.\n"; + exit 1; + } + (my $ref) = $osimagetab->getAttribs({imagename => $imagename}, 'osvers', 'osarch', 'profile', 'provmethod'); + if (!$ref) { + print "Cannot find image \'$imagename\' from the osimage table.\n"; + exit 1; + } + (my $ref1) = $linuximagetab->getAttribs({imagename => $imagename}, 'pkglist', 'pkgdir', 'otherpkglist', 'otherpkgdir', 'postinstall', 'rootimgdir'); + if (!$ref1) { + print "Cannot find $imagename from the linuximage table\n"; + exit 1; + } + + $osver=$ref->{'osvers'}; + $arch=$ref->{'osarch'}; + $profile=$ref->{'profile'}; + my $provmethod=$ref->{'provmethod'}; + + unless ($osver and $arch and $profile and $provmethod) { + print"osimage.osvers, osimage.osarch, osimage.profile and osimage.provmethod must be specified for the image $imagename in the database.\n"; + exit 1; + } + + if ($provmethod ne 'netboot') { + print "\'$imagename\' cannot be used to build diskless image. Make sure osimage.provmethod is 'netboot'."; + exit 1; + } + + if (! $ref1->{'pkglist'}) { + print"A .pkglist file must be specified for image \'$imagename\' in the linuximage table.\n"; + exit 0; + } + $pkglist =$ref1->{'pkglist'}; + + $srcdir=$ref1->{'pkgdir'}; + $srcdir_otherpkgs=$ref1->{'otherpkgdir'}; + $otherpkglist=$ref1->{'otherpkglist'}; + $postinstall_filename=$ref1->{'postinstall'}; + $destdir=$ref1->{'rootimgdir'}; +} + +if ($mode eq "statelite") { + if (!$permission) { + $permission = "755"; + } +} + +if (!$arch) { + $arch = `uname -m`; + chomp($arch); + if ($arch =~ /i.86$/) { + $arch = "x86"; + } +} + +if (!$srcdir) { + $srcdir="$installroot/$osver/$arch"; +} + +if (!$srcdir_otherpkgs) { + $srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch"; +} + +if (!$destdir) +{ + $destdir="$installroot/netboot/$osver/$arch/$profile"; +} +$rootimg_dir="$destdir/rootimg"; + + +unless ($osver and $profile and $netdriver and $prinic) { + print 'Usage: genimage -i -n [-r ] -o -p -k [-m [--permission ]]'."\n"; + print ' genimage -i -n [-r ] -k '."\n"; + print " --permission only works when '-m statelite' is set\n"; + print "Examples:\n"; + print " genimage -i eth0 -n tg3 -o centos5.1 -p compute\n"; + print " genimage -i eth0 -r eth1,eth2 -n tg3,bnx2 -o centos5.1 -p compute\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot -m statelite\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot -m statelite --permission 777\n"; + print " genimage -i eth0 -n tg3 myimage\n"; + exit 1; +} + +my @ndrivers; +foreach (split /,/,$netdriver) { + unless (/\.ko$/) { + s/$/.ko/; + } + if (/^$/) { + next; + } + push @ndrivers,$_; +} +if($mode eq "statelite"){ + push @ndrivers,"fscache.ko"; + push @ndrivers,"sunrpc.ko"; + push @ndrivers,"lockd.ko"; + push @ndrivers,"nfs_acl.ko"; + push @ndrivers,"nfs.ko"; + +} + +my $uarch=$arch; + +if ( $arch eq x86_64 ) +{ + $uarch="amd64"; +} + + +unless ($onlyinitrd) { + @aptdirs=(); + find(\&isaptdir, <$installroot/$osver/$arch/>); + unless (scalar(@aptdirs)) { + #unless ( -d $srcdir."/dists/stable/main/binary-$uarch/Packages.gz" ) { + print "Need $installroot/$osver/$arch/ available from a system that has ran copycds on $osver $arch\n"; + exit 1; + } + + my $aptconfig; + open($aptconfig,">","/tmp/genimage.$$.apt.list"); + my $repnum=0; + foreach $srcdir (@aptdirs) { + print $aptconfig "deb file://$srcdir main stable\n\n"; + $repnum += 1; + } + $repnum-=1; + close($aptconfig); + mkpath "$rootimg_dir/etc"; + + + my $fd; + open($fd,">>","$rootimg_dir/etc/fstab"); + print $fd "#Dummy fstab for rpm postscripts to see\n"; + close($fd); + + my @line=split(" ",`ls -lh $installroot/$osver/$arch/dists/ | grep dr`); + #print "$line\n"; + #print "$index\n"; + my $dist = $line[@line-1]; + + my $aptcmd1 = "debootstrap"; + my $aptcmd2 = "--arch $uarch $dist $rootimg_dir file://$installroot/$osver/$arch/"; + #foreach (0..$repnum) { + # $yumcmd .= "--enablerepo=$osver-$arch-$_ "; + #} + + #yumcmd .= "install "; + #mkpath("$rootimg_dir/var/lib/yum"); + + if (!$imagename) { + $pkglist= get_profile_def_filename($customdir,"pkglist"); + if (!$pkglist) { + $pkglist= get_profile_def_filename($pathtofiles, "pkglist"); + } + } + + if (!$pkglist) { + print "Unable to find package list for $profile!\n"; + exit 1; + } + + my %pkg_hash=get_package_names($pkglist); + my $index=1; + my $pass; + foreach $pass (sort (keys(%pkg_hash))) { + my $pkgnames = ""; + foreach (keys(%{$pkg_hash{$pass}})) { + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE")) { next;} + my $pa=$pkg_hash{$pass}{$_}; + $pkgnames .= "" . join(',', @$pa); + } + + print "$aptcmd1 --include=$pkgnames $aptcmd2\n"; + my $rc = system("$aptcmd1 --include=$pkgnames $aptcmd2"); + if ($rc) { + print "apt invocation failed\n"; + exit 1; + } + } + + #Now let's handle extra packages + if (!$imagename) { + $otherpkglist=get_profile_def_filename($customdir, "otherpkgs.pkglist"); + if (!$otherpkglist) { $otherpkglist=get_profile_def_filename($pathtofiles, "otherpkgs.pkglist"); } + } + my %extra_hash=(); + if ($otherpkglist) { + %extra_hash=get_package_names($otherpkglist); + } + my %extrapkgnames; + + if (keys(%extra_hash) > 0) { + open($yumconfig,">>","/tmp/genimage.$$.yum.conf"); + my $index=1; + foreach $pass (sort (keys(%extra_hash))) { + foreach (keys(%{$extra_hash{$pass}})) { + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE")) { next;} + print $yumconfig "[otherpkgs$index]\nname=otherpkgs$index\nbaseurl=file://$srcdir_otherpkgs/$_\ngpgpcheck=0\n\n"; + $index++; + my $pa=$extra_hash{$pass}{$_}; + $extrapkgnames{$pass} .= " " . join(' ', @$pa); + } + } + close($yumconfig); + $index--; + $yumcmd = "yum -y -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + foreach (0..$repnum) { + $yumcmd .= "--enablerepo=$osver-$arch-$_ "; + } + for (1..$index) { + $yumcmd .= "--enablerepo=otherpkgs$_ "; + } + + foreach $pass (sort (keys(%extra_hash))) { + #remove the packages that are specified in the otherpkgs.list files with leading '-' + my $yumcmd_remove= "$yumcmd erase "; + if (exists ($extra_hash{$pass}{'PRE_REMOVE'})) { + my $pa=$extra_hash{$pass}{'PRE_REMOVE'}; + my $rm_packges= join(' ', @$pa); + if ($rm_packges) { + print "$yumcmd_remove $rm_packges\n"; + $rc = system("$yumcmd_remove $rm_packges"); + } + } + + + #install extra packages + my $yumcmd_base = $yumcmd; + $yumcmd .= "install "; + #append extra pkg names to yum command + if ($extrapkgnames{$pass}) { + $yumcmd .= " $extrapkgnames{$pass} "; + } + $yumcmd =~ s/ $/\n/; + + #debug + print "yumcmd=$yumcmd\n"; + #my $repo=`cat /tmp/genimage.$$.yum.conf`; + #print "repo=$repo"; + + my $rc = system($yumcmd); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + + #remove the packages that are specified in the otherpkgs.list files with leading '--' + if (exists ($extra_hash{$pass}{'POST_REMOVE'})) { + my $pa=$extra_hash{$pass}{'POST_REMOVE'}; + my $rm_packges= join(' ', @$pa); + if ($rm_packges) { + print "$yumcmd_remove $rm_packges\n"; + $rc = system("$yumcmd_remove $rm_packges"); + } + } + } + } + + # run yum update to update any installed rpms + # needed when running genimage again after updating software in repositories + my $yumcmd_update = $yumcmd_base . " update "; + $rc = system("$yumcmd_update"); + # ignore any return code + + + postscripts(); #run 'postscripts' +} +#Default to the first kernel found in the install image if nothing specified explicitly. +#A more accurate guess than whatever the image build server happens to be running +#If specified, that takes precedence. +#if image has one, that is used +#if all else fails, resort to uname -r like this script did before +my @KVERS= <$rootimg_dir/boot/vmlinuz-*>; +foreach (@KVERS) { + s/vmlinuz-//; +} +unless (scalar(@KVERS)) { + @KVERS= <$rootimg_dir/lib/modules/*>; +} +if (scalar(@KVERS)) { + $basekernelver = basename(pop @KVERS); +} +unless ($basekernelver) { + $basekernelver = `uname -r`; +} +unless ($kernelver) { + $kernelver=$basekernelver; +} +chomp($kernelver); +open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); +my @moddeps = <$moddeps>; +my @checkdeps = @ndrivers; +while (scalar @checkdeps) { + my $driver = pop @checkdeps; + my @lines = grep /\/$driver:/,@moddeps; + foreach (@lines) { + chomp; + s/.*://; + s/^\s*//; + my @deps = split /\s+/,$_; + my $dep; + foreach $dep (@deps) { + $dep =~ s/.*\///; + unless (grep { $_ eq $dep } @ndrivers) { #only add if not added + unshift (@checkdeps,$dep); #recursively check dependencies + unshift (@ndrivers,$dep); + print "Added $dep as an autodetected depedency\n"; + } + } + } +} +close($moddeps); +unlink "/tmp/genimage.$$.yum.conf"; + +#-- run postinstall script +if (!$imagename) { + $postinstall_filename= get_profile_def_filename($customdir, "postinstall"); + if (!$postinstall_filename) { + $postinstall_filename= get_profile_def_filename($pathtofiles, "postinstall"); + } +} + +if (($postinstall_filename) && (-x $postinstall_filename)) { + my $rc = system($postinstall_filename, $rootimg_dir,$osver,$arch,$profile); + if($rc) { + print "postinstall script failed\n"; + exit 1; + } +} + + +# statelite .statelite directory added here. +# this is where tmpfs will be created. +if($mode eq "statelite"){ + mkpath "$rootimg_dir/.statelite"; # create place for NFS mounts. + # this script will get the directories. + unless(-f "../add-on/statelite/rc.statelite"){ + print "Can't find ../add-on/statelite/rc.statelite!\n"; + exit; + } + system("cp ../add-on/statelite/rc.statelite $rootimg_dir/etc/init.d/statelite"); + # also need to add this file: + # may have already been made into a symbolic link, if so ignore it + + unless(-l "$rootimg_dir/var/lib/dhclient" ){ + mkpath "$rootimg_dir/var/lib/dhclient/"; + system("touch $rootimg_dir/var/lib/dhclient/dhclient-$prinic.leases"); + } + + unless(-l "$rootimg_dir/var/lib/dhcp" ){ + mkpath "$rootimg_dir/var/lib/dhcp/"; + system("touch $rootimg_dir/var/lib/dhcp/dhclient-$prinic.leases"); + } +} + + + +mkinitrd(); + +sub getlibs { + my $file = shift; + my $liblist = `chroot $rootimg_dir ldd $file`; + my @libs = split/\n/,$liblist; + my @return; + foreach (@libs) { + unless (/=>/) { + (my $wjnk, my $lib,my $jnk) = split /\s+/,$_,3; + $lib =~ s/^\///; + $libhash{$lib}=1; + next; + } + (my $temp1,my $temp2) = split />/,$_,2; + (my $whitespace,$temp1,$temp2) = split /\s+/,$temp2,4; + unless ($temp1 =~ /\//) { + next; + } + $temp1 =~ s/^\///; + $libhash{$temp1}=1; + } +} + +sub mkinitrd { + mkpath("/tmp/xcatinitrd.$$/bin"); + if($basekernelver eq $kernelver) { + copy(<$rootimg_dir/boot/vmlinuz*>,"$destdir/kernel"); + } + else { + if(-r "$rootimg_dir/boot/vmlinuz-$kernelver") { + copy("$rootimg_dir/boot/vmlinuz-$kernelver","$destdir/kernel"); + } elsif(-r "/boot/vmlinuz-$kernelver") { + copy("/boot/vmlinuz-$kernelver","$destdir/kernel"); + } + else { + xdie("Cannot read /boot/vmlinuz-$kernelver"); + } + } + symlink("bin","/tmp/xcatinitrd.$$/sbin"); + mkpath("/tmp/xcatinitrd.$$/usr/bin"); + mkpath("/tmp/xcatinitrd.$$/usr/sbin"); + mkpath("/tmp/xcatinitrd.$$/usr/lib"); + mkpath("/tmp/xcatinitrd.$$/usr/lib64"); + mkpath("/tmp/xcatinitrd.$$/lib/firmware"); + mkpath("/tmp/xcatinitrd.$$/lib64/firmware"); + mkpath("/tmp/xcatinitrd.$$/proc"); + mkpath("/tmp/xcatinitrd.$$/sys"); + mkpath("/tmp/xcatinitrd.$$/dev/mapper"); + mkpath("/tmp/xcatinitrd.$$/sysroot"); + mkpath("/tmp/xcatinitrd.$$/etc/ld.so.conf.d"); + mkpath("/tmp/xcatinitrd.$$/var/lib/dhclient"); + my $inifile; + +# start writing to the init script. + open($inifile,">","/tmp/xcatinitrd.$$/init"); + print $inifile "#!/sbin/busybox.anaconda sh\n"; + +# add some functions + print $inifile < <\\ \\____/ | \\ | + /__/\\_ \\\\______ /\\____|__ /____| + \\/ \\/ \\/ +' + echo -e "\$RESET" +} + +EOS1 + + + print $inifile "mount -t proc /proc /proc\n"; + #print $inifile "busybox.anaconda --install\n"; + print $inifile "mount -t sysfs /sys /sys\n"; + print $inifile "mount -o mode=0755 -t tmpfs /dev /dev\n"; + print $inifile "mkdir /dev/pts\n"; + print $inifile "mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts\n"; + print $inifile "mkdir /dev/shm\n"; + print $inifile "mkdir /dev/mapper\n"; + print $inifile "mknod /dev/null c 1 3\n"; + print $inifile "mknod /dev/zero c 1 5\n"; + print $inifile "mknod /dev/systty c 4 0\n"; + print $inifile "mknod /dev/tty c 5 0\n"; + print $inifile "mknod /dev/console c 5 1\n"; + print $inifile "mknod /dev/ptmx c 5 2\n"; + print $inifile "mknod /dev/rtc c 10 135\n"; + print $inifile "mknod /dev/tty0 c 4 0\n"; + print $inifile "mknod /dev/tty1 c 4 1\n"; + print $inifile "mknod /dev/tty2 c 4 2\n"; + print $inifile "mknod /dev/tty3 c 4 3\n"; + print $inifile "mknod /dev/tty4 c 4 4\n"; + print $inifile "mknod /dev/tty5 c 4 5\n"; + print $inifile "mknod /dev/tty6 c 4 6\n"; + print $inifile "mknod /dev/tty7 c 4 7\n"; + print $inifile "mknod /dev/tty8 c 4 8\n"; + print $inifile "mknod /dev/tty9 c 4 9\n"; + print $inifile "mknod /dev/tty10 c 4 10\n"; + print $inifile "mknod /dev/tty11 c 4 11\n"; + print $inifile "mknod /dev/tty12 c 4 12\n"; + print $inifile "mknod /dev/ttyS0 c 4 64\n"; + print $inifile "mknod /dev/ttyS1 c 4 65\n"; + print $inifile "mknod /dev/ttyS2 c 4 66\n"; + print $inifile "mknod /dev/ttyS3 c 4 67\n"; + foreach (@ndrivers) { + print $inifile "insmod /lib/$_\n"; + } + print $inifile < /dev/null && export DEBUG=1 +netstart +while ! ifconfig | grep inet; do + echo -e "\${RED}Failed to acquire address, retrying \${RESET}" + sleep 1 + netstart +done +ifconfig lo 127.0.0.1 +ifconfig lo up +cd / +for i in `cat /proc/cmdline`; do + KEY=`echo \$i |awk -F= '{print \$1}'` + if [ "\$KEY" == 'imgurl' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + if [ "http" == "`echo \$VALUE|awk -F: '{print \$1}'`" ]; then + #NOTE needs FT retry code to scale + #NOTE: should prob have max count + FILENAME=`echo \$VALUE|awk -F/ '{print \$NF}'` + while [ ! -r "\$FILENAME" ]; do + echo Getting \$VALUE... + if ! wget \$VALUE; then + ST=`expr \$RANDOM % 5` + sleep \$ST + rm -f \$FILENAME + fi + done + NFS=0 + fi + if [ "nfs" == "`echo \$VALUE|awk -F: '{print \$1}'`" ]; then + NFS=1 + SERVER=`echo \$VALUE|awk -F/ '{print \$3}'` + ROOTDIR=`echo \$VALUE|awk -F/ '{for(i=4;i<=NF;i++) printf "/%s",\$i}'` + fi + # for NFS root + elif [ "\$KEY" == 'NFSROOT' ]; then + NFSROOT=1 + VALUE=`echo \$i |awk -F= '{print \$2}'` + SERVER=`echo \$VALUE|awk -F: '{print \$1}'` + ROOTDIR=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'` + elif [ "\$KEY" == 'STATEMNT' ]; then + NFSROOT=1 + VALUE=`echo \$i |awk -F= '{print \$2}'` + SNAPSHOTSERVER=`echo \$VALUE|awk -F: '{print \$1}'` + SNAPSHOTROOT=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'` + # may be that there is not server and just a directory. + if [ -z \$SNAPSHOTROOT ] + then + SNAPSHOTROOT=\$SNAPSHOTSERVER + SNAPSHOTSERVER= + fi + fi +done + +# show xCAT logo +fancydisplay + + +echo 0 > /proc/sys/vm/zone_reclaim_mode #Avoid kernel bug + +# NFSROOT code here: +if [ "\$NFSROOT" = "1" ]; then + echo Setting up Statelite + # for loop back mounting capability! + mknod /dev/loop0 b 7 0 + mkdir -p \$NEWROOT + MAXTRIES=5 + ITER=0 + ME=`hostname` + while ! mount.nfs \${SERVER}:\${ROOTDIR}/rootimg \$NEWROOT -r -n -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14 + do + ITER=\$(expr \$ITER + 1) + if [ "\$ITER" == "\$MAXTRIES" ] + then + echo "You're dead. rpower \$ME boot to play again." + echo "Possible problems: +1. This initrd wasn't created for statelite node? rerun genimage with the -m statelite flag, then rerun 'nodeset \$ME statelite' +2. Is DNS set up? Maybe that's why I can't mount \${SERVER}. +3. The nfs modules aren't set right in this initfs?" + + shell + exit + fi + echo -e "\${RED}Could not mount \$SERVER:\$ROOTDIR on \$NEWROOT \$RESET" + RS=`expr \$RANDOM % 30` + echo -e "Trying again in \$RS seconds" + sleep \$RS + done + +# now we need to mount the rest of the system. This is the read/write portions +#echo "Mounting Snapshot directories" + + if [ ! -e "\$NEWROOT/\$RWDIR" ] + then + echo "" + echo -e "\${RED}Hmmm... this NFS root directory doesn't have a /\$RWDIR directory for me to mount a rw filesystem. You'd better create it... \${NORMAL}" + echo "." + shell + fi + + while [ ! -e "\$NEWROOT/etc/init.d/statelite" ] + do + echo "" + echo -e "\${RED}Hmmm... \$NEWROOT/etc/init.d/statelite doesn't exist. Perhaps you didn't create this image with the -m statelite mode" + echo "" + shell + done + grep '\\(shell\\)' /proc/cmdline >/dev/null && shell + mount -t tmpfs rw -o mode=$permission \$NEWROOT/\$RWDIR + mkdir -p \$NEWROOT/\$RWDIR/tmpfs + + + # mount the SNAPSHOT directory here for persistent use. + if [ ! -z \$SNAPSHOTSERVER ] + then + mkdir -p \$NEWROOT/\$RWDIR/persistent + MAXTRIES=5 + ITER=0 + while ! mount \$SNAPSHOTSERVER:\$SNAPSHOTROOT \$NEWROOT/\$RWDIR/persistent -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14 + do + ITER=\$(expr \$ITER + 1) + if [ "\$ITER" == "\$MAXTRIES" ] + then + echo "You're dead. rpower \$ME boot to play again." + echo "Possible problems: +1. \$SNAPSHOTSERVER is not exporting \$SNAPSHOTROOT ? +2. Is DNS set up? Maybe that's why I can't mount \$SNAPSHOTSERVER." + shell + exit + fi + echo -e "\${RED}Hmmm... Can't mount \$SNAPSHOTSERVER:\$SNAPSHOTROOT. \${NORMAL}" + RS=`expr \$RANDOM % 20` + echo -e "Trying again in \$RS seconds" + sleep \$RS + done + fi + + grep '\\(shell\\)' /proc/cmdline >/dev/null && shell + + # have to preserve the initial DHCP request. So we link it. + + if [ ! -d \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhclient ] + then + mkdir -p \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhclient + fi + if [ ! -d \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhcp ] + then + mkdir -p \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhcp + fi + + cp -fp /var/lib/dhclient/dhclient.leases \${NEWROOT}/\${RWDIR}/tmpfs/var/lib/dhclient/dhclient-$prinic.leases + cp -fp /var/lib/dhclient/dhclient.leases \${NEWROOT}/\${RWDIR}/tmpfs/var/lib/dhcp/dhclient-$prinic.leases + + # dhclient + #while ! mount -n --bind \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhclient/dhclient-$prinic.leases \$NEWROOT/var/lib/dhclient/dhclient-$prinic.leases + #do + # echo "Can't mount /tmpfs/var/lib/dhclient/dhclient-$prinic.leases to /var/lib/dhclient/dhclient-$prinic.leases" + # shell + #done + + # dhcp + #while ! mount -n --bind \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhcp/dhclient-$prinic.leases \$NEWROOT/var/lib/dhcp/dhclient-$prinic.leases + #do + # echo "Can't mount /tmpfs/var/lib/dhcp/dhclient-$prinic.leases to /var/lib/dhcp/dhclient-$prinic.leases" + # shell + #done + + + + [ -e /etc/ntp.conf ] && mkdir -p \$NEWROOT/\$RWDIR/tmpfs/etc && cp /etc/ntp.conf \$NEWROOT/\$RWDIR/tmpfs/etc/ + + + [ -e /etc/ntp/step-kickers ] && mkdir -p \$NEWROOT/\$RWDIR/tmpfs/etc/ntp && cp /etc/ntp/step-kickers \$NEWROOT/\$RWDIR/tmpfs/etc/ntp + + + [ -e /etc/resolv.conf ] && mkdir -p \$NEWROOT/\$RWDIR/tmpfs/etc && cp /etc/resolv.conf \$NEWROOT/\$RWDIR/tmpfs/etc/ + + # now that everything is mounted, lets do this + # hmmm, apparently I'm checking this twice... so I'd better + # be really sure the file is there. + while [ -z \$NEWROOT/etc/init.d/statelite ] + do + echo "\$NEWROOT/etc/init.d/statelite does not exist in image!" + shell + done + + # do all the mounts: + \$NEWROOT/etc/init.d/statelite + + # give the debug shell just before we go if specified! + grep '\(shell\)' /proc/cmdline > /dev/null && shell + + echo 0x100 > /proc/sys/kernel/real-root-dev + export keep_old_ip=yes + export fastboot=yes + export READONLY=yes + grep '\\(shell\\)' /proc/cmdline >/dev/null && shell + mount -n --bind /dev /sysroot/dev + umount /sys + umount /proc + + if ! exec /sbin/switch_root -c /dev/console \$NEWROOT /sbin/init + then + echo "" + echo -e "\${RED}Couldn't switch_root. Something must be wrong with NFS root image.\${RESET}" + # mount -t proc proc /proc + shell + fi + exit +fi +# END NFSROOT/Statelite code + +# RAM root Hybrid with NFS root +if [ "\$NFS" = "1" ]; then + echo Setting up nfs with ram overlay. + mknod /dev/loop0 b 7 0 + mkdir -p /ro + mkdir -p /rw + #NOTE: should prob have max count + while [ ! -d /ro/bin ]; do + echo mounting \$SERVER:\$ROOTDIR on /ro + mount.nfs \$SERVER:\$ROOTDIR /ro -r -n -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14 + ST=`expr \$RANDOM % 5` + sleep \$ST + done + mount -t tmpfs rw /rw + mkdir -p /rw/etc + mkdir -p /rw/var/lib/dhclient + cp /etc/resolv.conf /rw/etc/ + cp /var/lib/dhclient/dhclient.leases /rw/var/lib/dhclient/dhclient-$prinic.leases + mount -t aufs -o dirs=/rw:/ro mergedroot /sysroot + mkdir -p /sysroot/ro + mkdir -p /sysroot/rw + mount --move /ro /sysroot/ro + mount --move /rw /sysroot/rw + cp /etc/resolv.conf /sysroot/etc/ + echo xcatfs / aufs rw,_netdev 0 0 >> /sysroot/etc/fstab +elif [ -r /rootimg.sfs ]; then + echo Setting up squashfs with ram overlay. + mknod /dev/loop0 b 7 0 + mkdir -p /ro + mkdir -p /rw + mount -t squashfs /rootimg.sfs /ro + mount -t tmpfs rw /rw + mount -t aufs -o dirs=/rw:/ro mergedroot /sysroot + mkdir -p /sysroot/ro + mkdir -p /sysroot/rw + mount --move /ro /sysroot/ro + mount --move /rw /sysroot/rw +EOMS + print $inifile "elif [ -r /rootimg.gz ]; then\n"; + print $inifile "echo Setting up RAM-root tmpfs.\n"; + if ($rootlimit) { + print $inifile " mount -o size=$rootlimit -t tmpfs rootfs /sysroot\n"; + } else { + print $inifile " mount -t tmpfs rootfs /sysroot\n"; + } + print $inifile " cd /sysroot\n"; + print $inifile " echo -n \"Extracting root filesystem:\"\n"; + print $inifile " if [ -x /bin/cpio ]; then\n"; + print $inifile " zcat /rootimg.gz |/bin/cpio -idum\n"; + print $inifile " else\n"; + print $inifile " zcat /rootimg.gz |cpio -idum\n"; + print $inifile " fi\n"; + print $inifile " echo Done\n"; + print $inifile "else\n"; + print $inifile " echo -n Failed to download image, panicing in 5...\n"; + print $inifile " for i in 4 3 2 1 0; do\n"; + print $inifile " /bin/sleep 1\n"; + print $inifile " echo -n \$i...\n"; + print $inifile " done\n"; + print $inifile " echo\n"; + print $inifile <"."/tmp/xcatinitrd.$$/bin/netstart"); + print $inifile "#!/sbin/nash\n"; + print $inifile "network --device $prinic --bootproto dhcp\n"; + close($inifile); + chmod(0755,"/tmp/xcatinitrd.$$/init"); + chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart"); + @filestoadd=(); + foreach (@ndrivers) { + if (-f "$customdir/$_") { + push @filestoadd,[$_,"lib/$_"]; + } elsif (-f "$pathtofiles/$_") { + push @filestoadd,[$_,"lib/$_"]; + } + } + # add rsync for statelite + foreach ("bin/cpio","sbin/nash","sbin/busybox.anaconda","bin/bash", "usr/sbin/chroot", "sbin/rmmod","sbin/mount.nfs","/usr/bin/rsync") { + getlibs($_); + push @filestoadd,$_; + } + if ($arch =~ /x86_64/) { + push @filestoadd,"lib64/libnss_dns.so.2"; + push @filestoadd,"lib64/libresolv.so.2"; + } + else { + push @filestoadd,"lib/libnss_dns.so.2"; + } + push @filestoadd,keys %libhash; + if($basekernelver ne $kernelver) { + system("rm -rf $rootimg_dir/lib/modules/$basekernelver"); + unless (-d "$rootimg_dir/lib/modules/$kernelver") { + if(-d "/lib/modules/$kernelver") { + system("cd /lib/modules;cp -r $kernelver $rootimg_dir/lib/modules/"); + } + else { + xdie("Cannot read /lib/modules/$kernelver"); + } + } + } + find(\&isnetdriver, <$rootimg_dir/lib/modules/$kernelver/*>); + + foreach (@filestoadd) { + if (ref($_)) { + #print "$_->[0], $_->[1]\n"; + my $srcpath = "$rootimg_dir/".$_->[0]; + if (-f "$customdir/".$_->[0]) { + $srcpath="$customdir/".$_->[0]; + } elsif (-f "$pathtofiles/".$_->[0]) { + $srcpath="$pathtofiles/".$_->[0]; + } + mkpath(dirname("/tmp/xcatinitrd.$$/".$_->[1])); + copy($srcpath,"/tmp/xcatinitrd.$$/".$_->[1]); + chmod 0755,"/tmp/xcatinitrd.$$/".$_->[1]; + } else { + #print "$_\n"; + my $srcpath = "$rootimg_dir/$_"; + if (-f "$customdir/$_") { + $srcpath = "$customdir/$_"; + } elsif (-f "$pathtofiles/$_") { + $srcpath = "$pathtofiles/$_"; + } + mkpath(dirname("/tmp/xcatinitrd.$$/$_")); + copy("$srcpath","/tmp/xcatinitrd.$$/$_"); + chmod 0755,"/tmp/xcatinitrd.$$/".$_; + } + } + + #copy("$rootimg_dir/lib/modules/*d","/tmp/xcatinitrd.$$/$_"); + system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd.gz"); + system("rm -rf /tmp/xcatinitrd.$$"); + +} + +sub isaptdir { + if ($File::Find::name =~ /\/Packages.gz$/) { + my $location = $File::Find::name; + $location =~ s/\/Packages.gz$//; + push @aptdirs,$location; + } +} + +sub isnetdriver { + foreach (@ndrivers) { + if ($File::Find::name =~ /\/$_/) { + my $filetoadd = $File::Find::name; + $filetoadd =~ s!$rootimg_dir/!!; + push @filestoadd,[$filetoadd,"lib/$_"]; + } + } +} + + + + + + + +sub postscripts { # TODO: customized postscripts + generic_post(); + + if ($mode eq "statelite") { + if( ! -d "$rootimg_dir/opt/xcat/") { + mkdir "$rootimg_dir/opt/xcat/"; + } + copy ("$installroot/postscripts/xcatdsklspost", "$rootimg_dir/opt/xcat/"); + chmod '0755', "$rootimg_dir/opt/xcat/xcatdsklspost"; + } + + if (-d "$installroot/postscripts/hostkeys") { + for my $key (<$installroot/postscripts/hostkeys/*key>) { + copy ($key,"$rootimg_dir/etc/ssh/"); + } + chmod 0600,; + } + if (-d "/$installroot/postscripts/.ssh") { + mkpath("/$rootimg_dir/root/.ssh"); + chmod(0700,"/$rootimg_dir/root/.ssh/"); + for my $file () { + copy ($file,"/$rootimg_dir/root/.ssh/"); + } + chmod(0600,); + } + +} + +sub generic_post { #This function is meant to leave the image in a state approximating a normal install + my $cfgfile; + unlink("$rootimg_dir/dev/null"); + system("mknod $rootimg_dir/dev/null c 1 3"); + open($cfgfile,">","$rootimg_dir/etc/fstab"); + print $cfgfile "devpts /dev/pts devpts gid=5,mode=620 0 0\n"; + print $cfgfile "tmpfs /dev/shm tmpfs defaults 0 0\n"; + print $cfgfile "proc /proc proc defaults 0 0\n"; + print $cfgfile "sysfs /sys sysfs defaults 0 0\n"; + if ($tmplimit) { + print $cfgfile "tmpfs /tmp tmpfs defaults 0 0\n"; + print $cfgfile "tmpfs /var/tmp tmpfs defaults 0 0\n"; + } + close($cfgfile); + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network"); + print $cfgfile "NETWORKING=yes\n"; + close($cfgfile); + open($cfgfile,">","$rootimg_dir/etc/resolv.conf"); + print $cfgfile "#Dummy resolv.conf to make boot cleaner"; + close($cfgfile); + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$prinic"); + print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$prinic\n"; + close($cfgfile); + foreach (split /,/,$othernics) { + if (/^$/) { next; } + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$_"); + print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$_\n"; + close($cfgfile); + } + open($cfgfile,">>","$rootimg_dir/etc/securetty"); + print $cfgfile "ttyS0\n"; + print $cfgfile "ttyS1\n"; + close($cfgfile); + my @passwd; + open($cfgfile,"<","$rootimg_dir/etc/passwd"); + @passwd = <$cfgfile>; + close($cfgfile); + open($cfgfile,">","$rootimg_dir/etc/passwd"); + foreach (@passwd) { + if (/^root:/) { + s/^root:\*/root:x/ + } + print $cfgfile $_; + } + close($cfgfile); + foreach (<$rootimg_dir/etc/skel/.*>) { + if (basename($_) eq '.' or basename($_) eq '..') { + next; + } + copy $_,"$rootimg_dir/root/"; + } + unless ( -r <$rootimg_dir/etc/rc3.d/S??network>) { + symlink "/etc/init.d/network","$rootimg_dir/etc/rc3.d/S10network"; + } + open($cfgfile,">","$rootimg_dir/etc/rc3.d/S60gettyset"); + print $cfgfile "#!/bin/bash\n"; + print $cfgfile "for i in `cat /proc/cmdline`; do\n"; + print $cfgfile ' KEY=`echo $i|cut -d= -f 1`'."\n"; + print $cfgfile " if [ \"\$KEY\" == \"console\" -a \"\$i\" != \"console=tty0\" ]; then\n"; + print $cfgfile " VALUE=`echo \$i | cut -d= -f 2`\n"; + print $cfgfile " COTTY=`echo \$VALUE|cut -d, -f 1`\n"; + print $cfgfile " COSPEED=`echo \$VALUE|cut -d, -f 2|cut -dn -f 1`\n"; + print $cfgfile " if echo \$VALUE | grep n8r; then\n"; + print $cfgfile " FLOWFLAG=\"-h\"\n"; + print $cfgfile " fi\n"; + print $cfgfile " if [ -x /sbin/initctl ]; then\n"; #Upstart style + print $cfgfile " initctl emit --no-wait fedora.serial-console-available \$COTTY \$COSPEED\n"; + print $cfgfile " else\n"; + print $cfgfile " echo xco:2345:respawn:/sbin/agetty \$FLOWFLAG \$COTTY \$COSPEED xterm >> /etc/inittab\n"; + print $cfgfile " init q\n"; + print $cfgfile " fi\n"; + print $cfgfile " fi\n"; + print $cfgfile "done\n"; + chmod(0755,"$rootimg_dir/etc/rc3.d/S60gettyset"); + #link("$rootimg_dir/sbin/init","$rootimg_dir/init"); + #add postscript support for redhat + if($mode eq "statelite") { + print $cfgfile "/opt/xcat/xcatdsklspost 4\n"; + } else { + print $cfgfile "/opt/xcat/xcatdsklspost\n"; + } + close($cfgfile); + + copy(<$rootimg_dir/boot/vmlinuz*>,"$destdir/kernel"); } + +sub get_package_names { + my $plist_file_name=shift; + my %pkgnames=(); + my @tmp_array=(); + + + if ($plist_file_name) { + my $pkgfile; + open($pkgfile,"<","$plist_file_name"); + while (<$pkgfile>) { + chomp; + s/\s+$//; #remove trailing white spaces + next if /^\s*$/; #-- skip empty lines + push(@tmp_array,$_); + } + close($pkgfile); + + if ( @tmp_array > 0) { + my $pkgtext=join(',',@tmp_array); + + #handle the #INLCUDE# tag recursively + my $idir = dirname($plist_file_name); + my $doneincludes=0; + while (not $doneincludes) { + $doneincludes=1; + if ($pkgtext =~ /#INCLUDE:[^#^\n]+#/) { + $doneincludes=0; + $pkgtext =~ s/#INCLUDE:([^#^\n]+)#/include_file($1,$idir)/eg; + } + } + + #print "pkgtext=$pkgtext\n"; + my @tmp=split(',', $pkgtext); + my $pass=1; + foreach (@tmp) { + my $idir; + if (/^--/) { + $idir="POST_REMOVE"; #line starts with -- means the package should be removed after otherpkgs are installed + s/^--//; + } elsif (/^-/) { + $idir="PRE_REMOVE"; #line starts with single - means the package should be removed before otherpkgs are installed + s/^-//; + } elsif (/^#NEW_INSTALL_LIST#/) { + $pass++; + next; + } elsif (/^#/) { + # ignore all other comment lines + next; + } else { + $idir=dirname($_); + } + my $fn=basename($_); + if (exists($pkgnames{$pass}{$idir})) { + my $pa=$pkgnames{$pass}{$idir}; + push(@$pa, $fn); + } else { + $pkgnames{$pass}{$idir}=[$fn]; + } + } + } + } + + return %pkgnames; +} + + + +sub include_file +{ + my $file = shift; + my $idir = shift; + my @text = (); + unless ($file =~ /^\//) { + $file = $idir."/".$file; + } + + open(INCLUDE,$file) || \ + return "#INCLUDEBAD:cannot open $file#"; + + while() { + chomp($_); + s/\s+$//; #remove trailing spaces + next if /^\s*$/; #-- skip empty lines + push(@text, $_); + } + + close(INCLUDE); + + return join(',', @text); +} + + + +sub get_profile_def_filename { + my $base=shift; + my $ext=shift; + my $dotpos = rindex($osver, "."); + my $osbase = substr($osver, 0, $dotpos); + if (-r "$base/$profile.$osver.$arch.$ext") { + return "$base/$profile.$osver.$arch.$ext"; + } elsif (-r "$base/$profile.$osbase.$arch.$ext") { + return "$base/$profile.$osbase.$arch.$ext"; + } elsif (-r "$base/$profile.$arch.$ext") { + return "$base/$profile.$arch.$ext"; + } elsif (-r "$base/$profile.$osver.$ext") { + return "$base/$profile.$osver.$ext"; + } elsif (-r "$base/$profile.$osbase.$ext") { + return "$base/$profile.$osbase.$ext"; + } elsif (-r "$base/$profile.$ext") { + return "$base/$profile.$ext"; + } + + return ""; +} + + + diff --git a/xCAT-server/share/xcat/netboot/ubuntu/compute.exlist b/xCAT-server/share/xcat/netboot/ubuntu/compute.exlist new file mode 100644 index 000000000..fb4fb072b --- /dev/null +++ b/xCAT-server/share/xcat/netboot/ubuntu/compute.exlist @@ -0,0 +1,13 @@ +./usr/share/man* +./usr/share/locale* +./usr/share/i18n* +./var/cache/yum* +./usr/share/doc* +./usr/share/gnome* +./usr/share/zoneinfo* +./usr/share/cracklib* +./usr/share/info* +./usr/share/omf* +./usr/lib/locale* +./usr/lib/perl5* +./boot* diff --git a/xCAT-server/share/xcat/netboot/ubuntu/compute.pkglist b/xCAT-server/share/xcat/netboot/ubuntu/compute.pkglist new file mode 100644 index 000000000..62178a8da --- /dev/null +++ b/xCAT-server/share/xcat/netboot/ubuntu/compute.pkglist @@ -0,0 +1,12 @@ +bash +nfs-common +openssl +dhcp3-client +linux-image-generic +openssh-server +openssh-client +wget +vim +ntp +rsyslog +rsync diff --git a/xCAT-server/share/xcat/netboot/ubuntu/genimage b/xCAT-server/share/xcat/netboot/ubuntu/genimage new file mode 100755 index 000000000..c0bedc0f8 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/ubuntu/genimage @@ -0,0 +1,1265 @@ +#!/usr/bin/env perl +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; + +use File::Basename; +use File::Path; +use File::Copy; +use File::Find; +use Getopt::Long; +use Cwd qw(realpath); +#use strict; +Getopt::Long::Configure("bundling"); +Getopt::Long::Configure("pass_through"); + +my $prinic; #TODO be flexible on node primary nic +my $othernics; #TODO be flexible on node primary nic +my $netdriver; +my @yumdirs; +my $arch; +my %libhash; +my @filestoadd; +my $profile; +my $osver; +my $pathtofiles=dirname($0); +my $fullpath=realpath($pathtofiles); +my $name = basename($0); +my $onlyinitrd=0; +if ($name =~ /geninitrd/) { + $onlyinitrd=1; +} +my $rootlimit; +my $tmplimit; +my $installroot = "/install"; +my $kernelver = ""; #`uname -r`; +my $basekernelver; # = $kernelver; +my $customdir=$fullpath; +$customdir =~ s/.*share\/xcat/$installroot\/custom/; +my $imagename; +my $pkglist; +my $srcdir; +my $destdir; +my $srcdir_otherpkgs; +my $otherpkglist; +my $postinstall_filename; +my $rootimg_dir; +my $rwfiles; # these files are used by statelite for tmpfs rw +my $mode; +my $permission; # the permission works only for statelite mode currently + + +sub xdie { + system("rm -rf /tmp/xcatinitrd.$$"); + die @_; +} + +$SIG{INT} = $SIG{TERM} = sub { xdie "Interrupted" }; +GetOptions( + 'a=s' => \$arch, + 'p=s' => \$profile, + 'o=s' => \$osver, + 'n=s' => \$netdriver, + 'i=s' => \$prinic, + 'r=s' => \$othernics, + 'l=s' => \$rootlimit, + 't=s' => \$tmplimit, + 'k=s' => \$kernelver, + 'm=s' => \$mode, + 'permission=s' => \$permission +); +if (@ARGV > 0) { + $imagename=$ARGV[0]; + if ($arch or $osver or $profile) { + print "-o, -p and -a options are not allowed when a image name is specified.\n"; + exit 1; + } + #load the module in memory + eval {require("$::XCATROOT/lib/perl/xCAT/Table.pm")}; + if ($@) { + print $@; + exit 1; + } + + #get the info from the osimage and linux + my $osimagetab=xCAT::Table->new('osimage', -create=>1); + if (!$osimagetab) { + print "The osimage table cannot be opened.\n"; + exit 1; + } + my $linuximagetab=xCAT::Table->new('linuximage', -create=>1); + if (!$linuximagetab) { + print "The linuximage table cannot be opened.\n"; + exit 1; + } + (my $ref) = $osimagetab->getAttribs({imagename => $imagename}, 'osvers', 'osarch', 'profile', 'provmethod'); + if (!$ref) { + print "Cannot find image \'$imagename\' from the osimage table.\n"; + exit 1; + } + (my $ref1) = $linuximagetab->getAttribs({imagename => $imagename}, 'pkglist', 'pkgdir', 'otherpkglist', 'otherpkgdir', 'postinstall', 'rootimgdir'); + if (!$ref1) { + print "Cannot find $imagename from the linuximage table\n"; + exit 1; + } + + $osver=$ref->{'osvers'}; + $arch=$ref->{'osarch'}; + $profile=$ref->{'profile'}; + my $provmethod=$ref->{'provmethod'}; + + unless ($osver and $arch and $profile and $provmethod) { + print"osimage.osvers, osimage.osarch, osimage.profile and osimage.provmethod must be specified for the image $imagename in the database.\n"; + exit 1; + } + + if ($provmethod ne 'netboot') { + print "\'$imagename\' cannot be used to build diskless image. Make sure osimage.provmethod is 'netboot'."; + exit 1; + } + + if (! $ref1->{'pkglist'}) { + print"A .pkglist file must be specified for image \'$imagename\' in the linuximage table.\n"; + exit 0; + } + $pkglist =$ref1->{'pkglist'}; + + $srcdir=$ref1->{'pkgdir'}; + $srcdir_otherpkgs=$ref1->{'otherpkgdir'}; + $otherpkglist=$ref1->{'otherpkglist'}; + $postinstall_filename=$ref1->{'postinstall'}; + $destdir=$ref1->{'rootimgdir'}; +} + +if ($mode eq "statelite") { + if (!$permission) { + $permission = "755"; + } +} + +if (!$arch) { + $arch = `uname -m`; + chomp($arch); + if ($arch =~ /i.86$/) { + $arch = "x86"; + } +} + +if (!$srcdir) { + $srcdir="$installroot/$osver/$arch"; +} + +if (!$srcdir_otherpkgs) { + $srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch"; +} + +if (!$destdir) +{ + $destdir="$installroot/netboot/$osver/$arch/$profile"; +} +$rootimg_dir="$destdir/rootimg"; + + +unless ($osver and $profile and $netdriver and $prinic) { + print 'Usage: genimage -i -n [-r ] -o -p -k [-m [--permission ]]'."\n"; + print ' genimage -i -n [-r ] -k '."\n"; + print " --permission only works when '-m statelite' is set\n"; + print "Examples:\n"; + print " genimage -i eth0 -n tg3 -o centos5.1 -p compute\n"; + print " genimage -i eth0 -r eth1,eth2 -n tg3,bnx2 -o centos5.1 -p compute\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot -m statelite\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot -m statelite --permission 777\n"; + print " genimage -i eth0 -n tg3 myimage\n"; + exit 1; +} + +my @ndrivers; +foreach (split /,/,$netdriver) { + unless (/\.ko$/) { + s/$/.ko/; + } + if (/^$/) { + next; + } + push @ndrivers,$_; +} +if($mode eq "statelite"){ + push @ndrivers,"fscache.ko"; + push @ndrivers,"sunrpc.ko"; + push @ndrivers,"lockd.ko"; + push @ndrivers,"nfs_acl.ko"; + push @ndrivers,"nfs.ko"; + +} + +my $uarch=$arch; + +if ( $arch eq x86_64 ) +{ + $uarch="amd64"; +} + + +unless ($onlyinitrd) { + @aptdirs=(); + find(\&isaptdir, <$installroot/$osver/$arch/>); + unless (scalar(@aptdirs)) { + #unless ( -d $srcdir."/dists/stable/main/binary-$uarch/Packages.gz" ) { + print "Need $installroot/$osver/$arch/ available from a system that has ran copycds on $osver $arch\n"; + exit 1; + } + + my $aptconfig; + open($aptconfig,">","/tmp/genimage.$$.apt.list"); + my $repnum=0; + foreach $srcdir (@aptdirs) { + print $aptconfig "deb file://$srcdir main stable\n\n"; + $repnum += 1; + } + $repnum-=1; + close($aptconfig); + mkpath "$rootimg_dir/etc"; + + + my $fd; + open($fd,">>","$rootimg_dir/etc/fstab"); + print $fd "#Dummy fstab for rpm postscripts to see\n"; + close($fd); + + my @line=split(" ",`ls -lh $installroot/$osver/$arch/dists/ | grep dr`); + #print "$line\n"; + #print "$index\n"; + my $dist = $line[@line-1]; + + my $aptcmd1 = "debootstrap"; + my $aptcmd2 = "--arch $uarch $dist $rootimg_dir file://$installroot/$osver/$arch/"; + #foreach (0..$repnum) { + # $yumcmd .= "--enablerepo=$osver-$arch-$_ "; + #} + + #yumcmd .= "install "; + #mkpath("$rootimg_dir/var/lib/yum"); + + if (!$imagename) { + $pkglist= get_profile_def_filename($customdir,"pkglist"); + if (!$pkglist) { + $pkglist= get_profile_def_filename($pathtofiles, "pkglist"); + } + } + + if (!$pkglist) { + print "Unable to find package list for $profile!\n"; + exit 1; + } + + my %pkg_hash=get_package_names($pkglist); + my $index=1; + my $pass; + foreach $pass (sort (keys(%pkg_hash))) { + my $pkgnames = ""; + foreach (keys(%{$pkg_hash{$pass}})) { + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE")) { next;} + my $pa=$pkg_hash{$pass}{$_}; + $pkgnames .= "" . join(',', @$pa); + } + + print "$aptcmd1 --include=$pkgnames $aptcmd2\n"; + my $rc = system("$aptcmd1 --include=$pkgnames $aptcmd2"); + if ($rc) { + print "apt invocation failed\n"; + exit 1; + } + } + + #Now let's handle extra packages + if (!$imagename) { + $otherpkglist=get_profile_def_filename($customdir, "otherpkgs.pkglist"); + if (!$otherpkglist) { $otherpkglist=get_profile_def_filename($pathtofiles, "otherpkgs.pkglist"); } + } + my %extra_hash=(); + if ($otherpkglist) { + %extra_hash=get_package_names($otherpkglist); + } + my %extrapkgnames; + + if (keys(%extra_hash) > 0) { + open($yumconfig,">>","/tmp/genimage.$$.yum.conf"); + my $index=1; + foreach $pass (sort (keys(%extra_hash))) { + foreach (keys(%{$extra_hash{$pass}})) { + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE")) { next;} + print $yumconfig "[otherpkgs$index]\nname=otherpkgs$index\nbaseurl=file://$srcdir_otherpkgs/$_\ngpgpcheck=0\n\n"; + $index++; + my $pa=$extra_hash{$pass}{$_}; + $extrapkgnames{$pass} .= " " . join(' ', @$pa); + } + } + close($yumconfig); + $index--; + $yumcmd = "yum -y -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + foreach (0..$repnum) { + $yumcmd .= "--enablerepo=$osver-$arch-$_ "; + } + for (1..$index) { + $yumcmd .= "--enablerepo=otherpkgs$_ "; + } + + foreach $pass (sort (keys(%extra_hash))) { + #remove the packages that are specified in the otherpkgs.list files with leading '-' + my $yumcmd_remove= "$yumcmd erase "; + if (exists ($extra_hash{$pass}{'PRE_REMOVE'})) { + my $pa=$extra_hash{$pass}{'PRE_REMOVE'}; + my $rm_packges= join(' ', @$pa); + if ($rm_packges) { + print "$yumcmd_remove $rm_packges\n"; + $rc = system("$yumcmd_remove $rm_packges"); + } + } + + + #install extra packages + my $yumcmd_base = $yumcmd; + $yumcmd .= "install "; + #append extra pkg names to yum command + if ($extrapkgnames{$pass}) { + $yumcmd .= " $extrapkgnames{$pass} "; + } + $yumcmd =~ s/ $/\n/; + + #debug + print "yumcmd=$yumcmd\n"; + #my $repo=`cat /tmp/genimage.$$.yum.conf`; + #print "repo=$repo"; + + my $rc = system($yumcmd); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + + #remove the packages that are specified in the otherpkgs.list files with leading '--' + if (exists ($extra_hash{$pass}{'POST_REMOVE'})) { + my $pa=$extra_hash{$pass}{'POST_REMOVE'}; + my $rm_packges= join(' ', @$pa); + if ($rm_packges) { + print "$yumcmd_remove $rm_packges\n"; + $rc = system("$yumcmd_remove $rm_packges"); + } + } + } + } + + # run yum update to update any installed rpms + # needed when running genimage again after updating software in repositories + my $yumcmd_update = $yumcmd_base . " update "; + $rc = system("$yumcmd_update"); + # ignore any return code + + + postscripts(); #run 'postscripts' +} +#Default to the first kernel found in the install image if nothing specified explicitly. +#A more accurate guess than whatever the image build server happens to be running +#If specified, that takes precedence. +#if image has one, that is used +#if all else fails, resort to uname -r like this script did before +my @KVERS= <$rootimg_dir/boot/vmlinuz-*>; +foreach (@KVERS) { + s/vmlinuz-//; +} +unless (scalar(@KVERS)) { + @KVERS= <$rootimg_dir/lib/modules/*>; +} +if (scalar(@KVERS)) { + $basekernelver = basename(pop @KVERS); +} +unless ($basekernelver) { + $basekernelver = `uname -r`; +} +unless ($kernelver) { + $kernelver=$basekernelver; +} +chomp($kernelver); +open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); +my @moddeps = <$moddeps>; +my @checkdeps = @ndrivers; +while (scalar @checkdeps) { + my $driver = pop @checkdeps; + my @lines = grep /\/$driver:/,@moddeps; + foreach (@lines) { + chomp; + s/.*://; + s/^\s*//; + my @deps = split /\s+/,$_; + my $dep; + foreach $dep (@deps) { + $dep =~ s/.*\///; + unless (grep { $_ eq $dep } @ndrivers) { #only add if not added + unshift (@checkdeps,$dep); #recursively check dependencies + unshift (@ndrivers,$dep); + print "Added $dep as an autodetected depedency\n"; + } + } + } +} +close($moddeps); +unlink "/tmp/genimage.$$.yum.conf"; + +#-- run postinstall script +if (!$imagename) { + $postinstall_filename= get_profile_def_filename($customdir, "postinstall"); + if (!$postinstall_filename) { + $postinstall_filename= get_profile_def_filename($pathtofiles, "postinstall"); + } +} + +if (($postinstall_filename) && (-x $postinstall_filename)) { + my $rc = system($postinstall_filename, $rootimg_dir,$osver,$arch,$profile); + if($rc) { + print "postinstall script failed\n"; + exit 1; + } +} + + +# statelite .statelite directory added here. +# this is where tmpfs will be created. +if($mode eq "statelite"){ + mkpath "$rootimg_dir/.statelite"; # create place for NFS mounts. + # this script will get the directories. + unless(-f "../add-on/statelite/rc.statelite"){ + print "Can't find ../add-on/statelite/rc.statelite!\n"; + exit; + } + system("cp ../add-on/statelite/rc.statelite $rootimg_dir/etc/init.d/statelite"); + # also need to add this file: + # may have already been made into a symbolic link, if so ignore it + + unless(-l "$rootimg_dir/var/lib/dhclient" ){ + mkpath "$rootimg_dir/var/lib/dhclient/"; + system("touch $rootimg_dir/var/lib/dhclient/dhclient-$prinic.leases"); + } + + unless(-l "$rootimg_dir/var/lib/dhcp" ){ + mkpath "$rootimg_dir/var/lib/dhcp/"; + system("touch $rootimg_dir/var/lib/dhcp/dhclient-$prinic.leases"); + } +} + + + +mkinitrd(); + +sub getlibs { + my $file = shift; + my $liblist = `chroot $rootimg_dir ldd $file`; + my @libs = split/\n/,$liblist; + my @return; + foreach (@libs) { + unless (/=>/) { + (my $wjnk, my $lib,my $jnk) = split /\s+/,$_,3; + $lib =~ s/^\///; + $libhash{$lib}=1; + next; + } + (my $temp1,my $temp2) = split />/,$_,2; + (my $whitespace,$temp1,$temp2) = split /\s+/,$temp2,4; + unless ($temp1 =~ /\//) { + next; + } + $temp1 =~ s/^\///; + $libhash{$temp1}=1; + } +} + +sub mkinitrd { + mkpath("/tmp/xcatinitrd.$$/bin"); + if($basekernelver eq $kernelver) { + copy(<$rootimg_dir/boot/vmlinuz*>,"$destdir/kernel"); + } + else { + if(-r "$rootimg_dir/boot/vmlinuz-$kernelver") { + copy("$rootimg_dir/boot/vmlinuz-$kernelver","$destdir/kernel"); + } elsif(-r "/boot/vmlinuz-$kernelver") { + copy("/boot/vmlinuz-$kernelver","$destdir/kernel"); + } + else { + xdie("Cannot read /boot/vmlinuz-$kernelver"); + } + } + symlink("bin","/tmp/xcatinitrd.$$/sbin"); + mkpath("/tmp/xcatinitrd.$$/usr/bin"); + mkpath("/tmp/xcatinitrd.$$/usr/sbin"); + mkpath("/tmp/xcatinitrd.$$/usr/lib"); + mkpath("/tmp/xcatinitrd.$$/usr/lib64"); + mkpath("/tmp/xcatinitrd.$$/lib/firmware"); + mkpath("/tmp/xcatinitrd.$$/lib64/firmware"); + mkpath("/tmp/xcatinitrd.$$/proc"); + mkpath("/tmp/xcatinitrd.$$/sys"); + mkpath("/tmp/xcatinitrd.$$/dev/mapper"); + mkpath("/tmp/xcatinitrd.$$/sysroot"); + mkpath("/tmp/xcatinitrd.$$/etc/ld.so.conf.d"); + mkpath("/tmp/xcatinitrd.$$/var/lib/dhclient"); + my $inifile; + +# start writing to the init script. + open($inifile,">","/tmp/xcatinitrd.$$/init"); + print $inifile "#!/bin/busybox sh\n"; + +# add some functions + print $inifile < <\\ \\____/ | \\ | + /__/\\_ \\\\______ /\\____|__ /____| + \\/ \\/ \\/ +' + echo -e "\$RESET" +} + +EOS1 + + + print $inifile "busybox mount -t proc /proc /proc\n"; + #print $inifile "busybox --install\n"; + print $inifile "busybox mount -t sysfs /sys /sys\n"; + print $inifile "mount -o mode=0755 -t tmpfs /dev /dev\n"; + print $inifile "mkdir /dev/pts\n"; + print $inifile "mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts\n"; + print $inifile "mkdir /dev/shm\n"; + print $inifile "mkdir /dev/mapper\n"; + print $inifile "mknod /dev/null c 1 3\n"; + print $inifile "mknod /dev/zero c 1 5\n"; + print $inifile "mknod /dev/systty c 4 0\n"; + print $inifile "mknod /dev/tty c 5 0\n"; + print $inifile "mknod /dev/console c 5 1\n"; + print $inifile "mknod /dev/ptmx c 5 2\n"; + print $inifile "mknod /dev/rtc c 10 135\n"; + print $inifile "mknod /dev/tty0 c 4 0\n"; + print $inifile "mknod /dev/tty1 c 4 1\n"; + print $inifile "mknod /dev/tty2 c 4 2\n"; + print $inifile "mknod /dev/tty3 c 4 3\n"; + print $inifile "mknod /dev/tty4 c 4 4\n"; + print $inifile "mknod /dev/tty5 c 4 5\n"; + print $inifile "mknod /dev/tty6 c 4 6\n"; + print $inifile "mknod /dev/tty7 c 4 7\n"; + print $inifile "mknod /dev/tty8 c 4 8\n"; + print $inifile "mknod /dev/tty9 c 4 9\n"; + print $inifile "mknod /dev/tty10 c 4 10\n"; + print $inifile "mknod /dev/tty11 c 4 11\n"; + print $inifile "mknod /dev/tty12 c 4 12\n"; + print $inifile "mknod /dev/ttyS0 c 4 64\n"; + print $inifile "mknod /dev/ttyS1 c 4 65\n"; + print $inifile "mknod /dev/ttyS2 c 4 66\n"; + print $inifile "mknod /dev/ttyS3 c 4 67\n"; + foreach (@ndrivers) { + print $inifile "insmod /lib/$_\n"; + } + print $inifile < /dev/null && export DEBUG=1 +netstart +while ! ifconfig | grep inet; do + echo -e "\${RED}Failed to acquire address, retrying \${RESET}" + sleep 1 + netstart +done +ifconfig lo 127.0.0.1 +ifconfig lo up +cd / +for i in `cat /proc/cmdline`; do + KEY=`echo \$i |awk -F= '{print \$1}'` + if [ "\$KEY" == 'imgurl' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + if [ "http" == "`echo \$VALUE|awk -F: '{print \$1}'`" ]; then + #NOTE needs FT retry code to scale + #NOTE: should prob have max count + FILENAME=`echo \$VALUE|awk -F/ '{print \$NF}'` + while [ ! -r "\$FILENAME" ]; do + echo Getting \$VALUE... + if ! wget \$VALUE; then + ST=`expr \$RANDOM % 5` + sleep \$ST + rm -f \$FILENAME + fi + done + NFS=0 + fi + if [ "nfs" == "`echo \$VALUE|awk -F: '{print \$1}'`" ]; then + NFS=1 + SERVER=`echo \$VALUE|awk -F/ '{print \$3}'` + ROOTDIR=`echo \$VALUE|awk -F/ '{for(i=4;i<=NF;i++) printf "/%s",\$i}'` + fi + # for NFS root + elif [ "\$KEY" == 'NFSROOT' ]; then + NFSROOT=1 + VALUE=`echo \$i |awk -F= '{print \$2}'` + SERVER=`echo \$VALUE|awk -F: '{print \$1}'` + ROOTDIR=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'` + elif [ "\$KEY" == 'STATEMNT' ]; then + NFSROOT=1 + VALUE=`echo \$i |awk -F= '{print \$2}'` + SNAPSHOTSERVER=`echo \$VALUE|awk -F: '{print \$1}'` + SNAPSHOTROOT=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'` + # may be that there is not server and just a directory. + if [ -z \$SNAPSHOTROOT ] + then + SNAPSHOTROOT=\$SNAPSHOTSERVER + SNAPSHOTSERVER= + fi + fi +done + +# show xCAT logo +fancydisplay + + +echo 0 > /proc/sys/vm/zone_reclaim_mode #Avoid kernel bug + +# NFSROOT code here: +if [ "\$NFSROOT" = "1" ]; then + echo Setting up Statelite + # for loop back mounting capability! + mknod /dev/loop0 b 7 0 + mkdir -p \$NEWROOT + MAXTRIES=5 + ITER=0 + ME=`hostname` + while ! mount.nfs \${SERVER}:\${ROOTDIR}/rootimg \$NEWROOT -r -n -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14 + do + ITER=\$(expr \$ITER + 1) + if [ "\$ITER" == "\$MAXTRIES" ] + then + echo "You're dead. rpower \$ME boot to play again." + echo "Possible problems: +1. This initrd wasn't created for statelite node? rerun genimage with the -m statelite flag, then rerun 'nodeset \$ME statelite' +2. Is DNS set up? Maybe that's why I can't mount \${SERVER}. +3. The nfs modules aren't set right in this initfs?" + + shell + exit + fi + echo -e "\${RED}Could not mount \$SERVER:\$ROOTDIR on \$NEWROOT \$RESET" + RS=`expr \$RANDOM % 30` + echo -e "Trying again in \$RS seconds" + sleep \$RS + done + +# now we need to mount the rest of the system. This is the read/write portions +#echo "Mounting Snapshot directories" + + if [ ! -e "\$NEWROOT/\$RWDIR" ] + then + echo "" + echo -e "\${RED}Hmmm... this NFS root directory doesn't have a /\$RWDIR directory for me to mount a rw filesystem. You'd better create it... \${NORMAL}" + echo "." + shell + fi + + while [ ! -e "\$NEWROOT/etc/init.d/statelite" ] + do + echo "" + echo -e "\${RED}Hmmm... \$NEWROOT/etc/init.d/statelite doesn't exist. Perhaps you didn't create this image with the -m statelite mode" + echo "" + shell + done + grep '\\(shell\\)' /proc/cmdline >/dev/null && shell + mount -t tmpfs rw -o mode=$permission \$NEWROOT/\$RWDIR + mkdir -p \$NEWROOT/\$RWDIR/tmpfs + + + # mount the SNAPSHOT directory here for persistent use. + if [ ! -z \$SNAPSHOTSERVER ] + then + mkdir -p \$NEWROOT/\$RWDIR/persistent + MAXTRIES=5 + ITER=0 + while ! mount \$SNAPSHOTSERVER:\$SNAPSHOTROOT \$NEWROOT/\$RWDIR/persistent -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14 + do + ITER=\$(expr \$ITER + 1) + if [ "\$ITER" == "\$MAXTRIES" ] + then + echo "You're dead. rpower \$ME boot to play again." + echo "Possible problems: +1. \$SNAPSHOTSERVER is not exporting \$SNAPSHOTROOT ? +2. Is DNS set up? Maybe that's why I can't mount \$SNAPSHOTSERVER." + shell + exit + fi + echo -e "\${RED}Hmmm... Can't mount \$SNAPSHOTSERVER:\$SNAPSHOTROOT. \${NORMAL}" + RS=`expr \$RANDOM % 20` + echo -e "Trying again in \$RS seconds" + sleep \$RS + done + fi + + grep '\\(shell\\)' /proc/cmdline >/dev/null && shell + + # have to preserve the initial DHCP request. So we link it. + + if [ ! -d \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhclient ] + then + mkdir -p \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhclient + fi + if [ ! -d \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhcp ] + then + mkdir -p \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhcp + fi + + cp -fp /var/lib/dhclient/dhclient.leases \${NEWROOT}/\${RWDIR}/tmpfs/var/lib/dhclient/dhclient-$prinic.leases + cp -fp /var/lib/dhclient/dhclient.leases \${NEWROOT}/\${RWDIR}/tmpfs/var/lib/dhcp/dhclient-$prinic.leases + + # dhclient + #while ! mount -n --bind \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhclient/dhclient-$prinic.leases \$NEWROOT/var/lib/dhclient/dhclient-$prinic.leases + #do + # echo "Can't mount /tmpfs/var/lib/dhclient/dhclient-$prinic.leases to /var/lib/dhclient/dhclient-$prinic.leases" + # shell + #done + + # dhcp + #while ! mount -n --bind \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhcp/dhclient-$prinic.leases \$NEWROOT/var/lib/dhcp/dhclient-$prinic.leases + #do + # echo "Can't mount /tmpfs/var/lib/dhcp/dhclient-$prinic.leases to /var/lib/dhcp/dhclient-$prinic.leases" + # shell + #done + + + + [ -e /etc/ntp.conf ] && mkdir -p \$NEWROOT/\$RWDIR/tmpfs/etc && cp /etc/ntp.conf \$NEWROOT/\$RWDIR/tmpfs/etc/ + + + [ -e /etc/ntp/step-kickers ] && mkdir -p \$NEWROOT/\$RWDIR/tmpfs/etc/ntp && cp /etc/ntp/step-kickers \$NEWROOT/\$RWDIR/tmpfs/etc/ntp + + + [ -e /etc/resolv.conf ] && mkdir -p \$NEWROOT/\$RWDIR/tmpfs/etc && cp /etc/resolv.conf \$NEWROOT/\$RWDIR/tmpfs/etc/ + + # now that everything is mounted, lets do this + # hmmm, apparently I'm checking this twice... so I'd better + # be really sure the file is there. + while [ -z \$NEWROOT/etc/init.d/statelite ] + do + echo "\$NEWROOT/etc/init.d/statelite does not exist in image!" + shell + done + + # do all the mounts: + \$NEWROOT/etc/init.d/statelite + + # give the debug shell just before we go if specified! + grep '\(shell\)' /proc/cmdline > /dev/null && shell + + echo 0x100 > /proc/sys/kernel/real-root-dev + export keep_old_ip=yes + export fastboot=yes + export READONLY=yes + grep '\\(shell\\)' /proc/cmdline >/dev/null && shell + mount -n --bind /dev /sysroot/dev + umount /sys + umount /proc + + if ! exec /sbin/switch_root -c /dev/console \$NEWROOT /sbin/init + then + echo "" + echo -e "\${RED}Couldn't switch_root. Something must be wrong with NFS root image.\${RESET}" + # mount -t proc proc /proc + shell + fi + exit +fi +# END NFSROOT/Statelite code + +# RAM root Hybrid with NFS root +if [ "\$NFS" = "1" ]; then + echo Setting up nfs with ram overlay. + mknod /dev/loop0 b 7 0 + mkdir -p /ro + mkdir -p /rw + #NOTE: should prob have max count + while [ ! -d /ro/bin ]; do + echo mounting \$SERVER:\$ROOTDIR on /ro + mount.nfs \$SERVER:\$ROOTDIR /ro -r -n -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14 + ST=`expr \$RANDOM % 5` + sleep \$ST + done + mount -t tmpfs rw /rw + mkdir -p /rw/etc + mkdir -p /rw/var/lib/dhclient + cp /etc/resolv.conf /rw/etc/ + cp /var/lib/dhclient/dhclient.leases /rw/var/lib/dhclient/dhclient-$prinic.leases + mount -t aufs -o dirs=/rw:/ro mergedroot /sysroot + mkdir -p /sysroot/ro + mkdir -p /sysroot/rw + mount --move /ro /sysroot/ro + mount --move /rw /sysroot/rw + cp /etc/resolv.conf /sysroot/etc/ + echo xcatfs / aufs rw,_netdev 0 0 >> /sysroot/etc/fstab +elif [ -r /rootimg.sfs ]; then + echo Setting up squashfs with ram overlay. + mknod /dev/loop0 b 7 0 + mkdir -p /ro + mkdir -p /rw + mount -t squashfs /rootimg.sfs /ro + mount -t tmpfs rw /rw + mount -t aufs -o dirs=/rw:/ro mergedroot /sysroot + mkdir -p /sysroot/ro + mkdir -p /sysroot/rw + mount --move /ro /sysroot/ro + mount --move /rw /sysroot/rw +EOMS + print $inifile "elif [ -r /rootimg.gz ]; then\n"; + print $inifile "echo Setting up RAM-root tmpfs.\n"; + if ($rootlimit) { + print $inifile " mount -o size=$rootlimit -t tmpfs rootfs /sysroot\n"; + } else { + print $inifile " mount -t tmpfs rootfs /sysroot\n"; + } + print $inifile " cd /sysroot\n"; + print $inifile " echo -n \"Extracting root filesystem:\"\n"; + print $inifile " if [ -x /bin/cpio ]; then\n"; + print $inifile " zcat /rootimg.gz |/bin/cpio -idum\n"; + print $inifile " else\n"; + print $inifile " zcat /rootimg.gz |cpio -idum\n"; + print $inifile " fi\n"; + print $inifile " echo Done\n"; + print $inifile "else\n"; + print $inifile " echo -n Failed to download image, panicing in 5...\n"; + print $inifile " for i in 4 3 2 1 0; do\n"; + print $inifile " /bin/sleep 1\n"; + print $inifile " echo -n \$i...\n"; + print $inifile " done\n"; + print $inifile " echo\n"; + print $inifile <"."/tmp/xcatinitrd.$$/bin/netstart"); + print $inifile "#!/sbin/nash\n"; + print $inifile "network --device $prinic --bootproto dhcp\n"; + close($inifile); + chmod(0755,"/tmp/xcatinitrd.$$/init"); + chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart"); + @filestoadd=(); + foreach (@ndrivers) { + if (-f "$customdir/$_") { + push @filestoadd,[$_,"lib/$_"]; + } elsif (-f "$pathtofiles/$_") { + push @filestoadd,[$_,"lib/$_"]; + } + } + # add rsync for statelite + foreach ("bin/cpio","sbin/nash","bin/busybox","bin/bash", "usr/sbin/chroot", "sbin/rmmod","sbin/mount.nfs","/usr/bin/rsync") { + getlibs($_); + push @filestoadd,$_; + } + if ($arch =~ /x86_64/) { + push @filestoadd,"lib64/libnss_dns.so.2"; + push @filestoadd,"lib64/libresolv.so.2"; + } + else { + push @filestoadd,"lib/libnss_dns.so.2"; + } + push @filestoadd,keys %libhash; + if($basekernelver ne $kernelver) { + system("rm -rf $rootimg_dir/lib/modules/$basekernelver"); + unless (-d "$rootimg_dir/lib/modules/$kernelver") { + if(-d "/lib/modules/$kernelver") { + system("cd /lib/modules;cp -r $kernelver $rootimg_dir/lib/modules/"); + } + else { + xdie("Cannot read /lib/modules/$kernelver"); + } + } + } + find(\&isnetdriver, <$rootimg_dir/lib/modules/$kernelver/*>); + + foreach (@filestoadd) { + if (ref($_)) { + #print "$_->[0], $_->[1]\n"; + my $srcpath = "$rootimg_dir/".$_->[0]; + if (-f "$customdir/".$_->[0]) { + $srcpath="$customdir/".$_->[0]; + } elsif (-f "$pathtofiles/".$_->[0]) { + $srcpath="$pathtofiles/".$_->[0]; + } + mkpath(dirname("/tmp/xcatinitrd.$$/".$_->[1])); + copy($srcpath,"/tmp/xcatinitrd.$$/".$_->[1]); + chmod 0755,"/tmp/xcatinitrd.$$/".$_->[1]; + } else { + #print "$_\n"; + my $srcpath = "$rootimg_dir/$_"; + if (-f "$customdir/$_") { + $srcpath = "$customdir/$_"; + } elsif (-f "$pathtofiles/$_") { + $srcpath = "$pathtofiles/$_"; + } + mkpath(dirname("/tmp/xcatinitrd.$$/$_")); + copy("$srcpath","/tmp/xcatinitrd.$$/$_"); + chmod 0755,"/tmp/xcatinitrd.$$/".$_; + } + } + + #copy("$rootimg_dir/lib/modules/*d","/tmp/xcatinitrd.$$/$_"); + system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd.gz"); + system("rm -rf /tmp/xcatinitrd.$$"); + +} + +sub isaptdir { + if ($File::Find::name =~ /\/Packages.gz$/) { + my $location = $File::Find::name; + $location =~ s/\/Packages.gz$//; + push @aptdirs,$location; + } +} + +sub isnetdriver { + foreach (@ndrivers) { + if ($File::Find::name =~ /\/$_/) { + my $filetoadd = $File::Find::name; + $filetoadd =~ s!$rootimg_dir/!!; + push @filestoadd,[$filetoadd,"lib/$_"]; + } + } +} + + + + + + + +sub postscripts { # TODO: customized postscripts + generic_post(); + + if ($mode eq "statelite") { + if( ! -d "$rootimg_dir/opt/xcat/") { + mkdir "$rootimg_dir/opt/xcat/"; + } + copy ("$installroot/postscripts/xcatdsklspost", "$rootimg_dir/opt/xcat/"); + chmod '0755', "$rootimg_dir/opt/xcat/xcatdsklspost"; + } + + if (-d "$installroot/postscripts/hostkeys") { + for my $key (<$installroot/postscripts/hostkeys/*key>) { + copy ($key,"$rootimg_dir/etc/ssh/"); + } + chmod 0600,; + } + if (-d "/$installroot/postscripts/.ssh") { + mkpath("/$rootimg_dir/root/.ssh"); + chmod(0700,"/$rootimg_dir/root/.ssh/"); + for my $file () { + copy ($file,"/$rootimg_dir/root/.ssh/"); + } + chmod(0600,); + } + +} + +sub generic_post { #This function is meant to leave the image in a state approximating a normal install + my $cfgfile; + unlink("$rootimg_dir/dev/null"); + system("mknod $rootimg_dir/dev/null c 1 3"); + open($cfgfile,">","$rootimg_dir/etc/fstab"); + print $cfgfile "devpts /dev/pts devpts gid=5,mode=620 0 0\n"; + print $cfgfile "tmpfs /dev/shm tmpfs defaults 0 0\n"; + print $cfgfile "proc /proc proc defaults 0 0\n"; + print $cfgfile "sysfs /sys sysfs defaults 0 0\n"; + if ($tmplimit) { + print $cfgfile "tmpfs /tmp tmpfs defaults 0 0\n"; + print $cfgfile "tmpfs /var/tmp tmpfs defaults 0 0\n"; + } + close($cfgfile); + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network"); + print $cfgfile "NETWORKING=yes\n"; + close($cfgfile); + open($cfgfile,">","$rootimg_dir/etc/resolv.conf"); + print $cfgfile "#Dummy resolv.conf to make boot cleaner"; + close($cfgfile); + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$prinic"); + print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$prinic\n"; + close($cfgfile); + foreach (split /,/,$othernics) { + if (/^$/) { next; } + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$_"); + print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$_\n"; + close($cfgfile); + } + open($cfgfile,">>","$rootimg_dir/etc/securetty"); + print $cfgfile "ttyS0\n"; + print $cfgfile "ttyS1\n"; + close($cfgfile); + my @passwd; + open($cfgfile,"<","$rootimg_dir/etc/passwd"); + @passwd = <$cfgfile>; + close($cfgfile); + open($cfgfile,">","$rootimg_dir/etc/passwd"); + foreach (@passwd) { + if (/^root:/) { + s/^root:\*/root:x/ + } + print $cfgfile $_; + } + close($cfgfile); + foreach (<$rootimg_dir/etc/skel/.*>) { + if (basename($_) eq '.' or basename($_) eq '..') { + next; + } + copy $_,"$rootimg_dir/root/"; + } + unless ( -r <$rootimg_dir/etc/rc3.d/S??network>) { + symlink "/etc/init.d/network","$rootimg_dir/etc/rc3.d/S10network"; + } + open($cfgfile,">","$rootimg_dir/etc/rc3.d/S60gettyset"); + print $cfgfile "#!/bin/bash\n"; + print $cfgfile "for i in `cat /proc/cmdline`; do\n"; + print $cfgfile ' KEY=`echo $i|cut -d= -f 1`'."\n"; + print $cfgfile " if [ \"\$KEY\" == \"console\" -a \"\$i\" != \"console=tty0\" ]; then\n"; + print $cfgfile " VALUE=`echo \$i | cut -d= -f 2`\n"; + print $cfgfile " COTTY=`echo \$VALUE|cut -d, -f 1`\n"; + print $cfgfile " COSPEED=`echo \$VALUE|cut -d, -f 2|cut -dn -f 1`\n"; + print $cfgfile " if echo \$VALUE | grep n8r; then\n"; + print $cfgfile " FLOWFLAG=\"-h\"\n"; + print $cfgfile " fi\n"; + print $cfgfile " if [ -x /sbin/initctl ]; then\n"; #Upstart style + print $cfgfile " initctl emit --no-wait fedora.serial-console-available \$COTTY \$COSPEED\n"; + print $cfgfile " else\n"; + print $cfgfile " echo xco:2345:respawn:/sbin/agetty \$FLOWFLAG \$COTTY \$COSPEED xterm >> /etc/inittab\n"; + print $cfgfile " init q\n"; + print $cfgfile " fi\n"; + print $cfgfile " fi\n"; + print $cfgfile "done\n"; + chmod(0755,"$rootimg_dir/etc/rc3.d/S60gettyset"); + #link("$rootimg_dir/sbin/init","$rootimg_dir/init"); + #add postscript support for redhat + if($mode eq "statelite") { + print $cfgfile "/opt/xcat/xcatdsklspost 4\n"; + } else { + print $cfgfile "/opt/xcat/xcatdsklspost\n"; + } + close($cfgfile); + + copy(<$rootimg_dir/boot/vmlinuz*>,"$destdir/kernel"); } + +sub get_package_names { + my $plist_file_name=shift; + my %pkgnames=(); + my @tmp_array=(); + + + if ($plist_file_name) { + my $pkgfile; + open($pkgfile,"<","$plist_file_name"); + while (<$pkgfile>) { + chomp; + s/\s+$//; #remove trailing white spaces + next if /^\s*$/; #-- skip empty lines + push(@tmp_array,$_); + } + close($pkgfile); + + if ( @tmp_array > 0) { + my $pkgtext=join(',',@tmp_array); + + #handle the #INLCUDE# tag recursively + my $idir = dirname($plist_file_name); + my $doneincludes=0; + while (not $doneincludes) { + $doneincludes=1; + if ($pkgtext =~ /#INCLUDE:[^#^\n]+#/) { + $doneincludes=0; + $pkgtext =~ s/#INCLUDE:([^#^\n]+)#/include_file($1,$idir)/eg; + } + } + + #print "pkgtext=$pkgtext\n"; + my @tmp=split(',', $pkgtext); + my $pass=1; + foreach (@tmp) { + my $idir; + if (/^--/) { + $idir="POST_REMOVE"; #line starts with -- means the package should be removed after otherpkgs are installed + s/^--//; + } elsif (/^-/) { + $idir="PRE_REMOVE"; #line starts with single - means the package should be removed before otherpkgs are installed + s/^-//; + } elsif (/^#NEW_INSTALL_LIST#/) { + $pass++; + next; + } elsif (/^#/) { + # ignore all other comment lines + next; + } else { + $idir=dirname($_); + } + my $fn=basename($_); + if (exists($pkgnames{$pass}{$idir})) { + my $pa=$pkgnames{$pass}{$idir}; + push(@$pa, $fn); + } else { + $pkgnames{$pass}{$idir}=[$fn]; + } + } + } + } + + return %pkgnames; +} + + + +sub include_file +{ + my $file = shift; + my $idir = shift; + my @text = (); + unless ($file =~ /^\//) { + $file = $idir."/".$file; + } + + open(INCLUDE,$file) || \ + return "#INCLUDEBAD:cannot open $file#"; + + while() { + chomp($_); + s/\s+$//; #remove trailing spaces + next if /^\s*$/; #-- skip empty lines + push(@text, $_); + } + + close(INCLUDE); + + return join(',', @text); +} + + + +sub get_profile_def_filename { + my $base=shift; + my $ext=shift; + my $dotpos = rindex($osver, "."); + my $osbase = substr($osver, 0, $dotpos); + if (-r "$base/$profile.$osver.$arch.$ext") { + return "$base/$profile.$osver.$arch.$ext"; + } elsif (-r "$base/$profile.$osbase.$arch.$ext") { + return "$base/$profile.$osbase.$arch.$ext"; + } elsif (-r "$base/$profile.$arch.$ext") { + return "$base/$profile.$arch.$ext"; + } elsif (-r "$base/$profile.$osver.$ext") { + return "$base/$profile.$osver.$ext"; + } elsif (-r "$base/$profile.$osbase.$ext") { + return "$base/$profile.$osbase.$ext"; + } elsif (-r "$base/$profile.$ext") { + return "$base/$profile.$ext"; + } + + return ""; +} + + + diff --git a/xCAT/postscripts/otherpkgs.ubuntu b/xCAT/postscripts/otherpkgs.ubuntu new file mode 100755 index 000000000..296e14323 --- /dev/null +++ b/xCAT/postscripts/otherpkgs.ubuntu @@ -0,0 +1,461 @@ +#!/bin/bash +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html + +#------------------------------------------------------------------------------- +#=head1 otherpkgs +#=head2 It gets the extra rpms and install/update them. +# The environment variable OTHERPKGS contains the rpms to be installed/updated. +# On MN, You need to: +# 1. put rpms under /install/post/otherpkgs/os/arch directory where 'os' and 'arch' +# can be found in the nodetype table. +# 2. put the name of the packages to /opt/xcat/share/xcat/netboot(install)/platform +# directory. The file name is one of the following: +# profile.os.arch.otherpkgs.pkglist +# profile.os.otherpkgs.pkglist +# profile.arch.otherpkgs.pkglist +# profile.otherpkgs.pkglist +# The install/deployment process will pick up the rpms and install them on the nodes. +# However, if the nodes have already installed and up and running, you can run the following +# command to have the extra rpms installed: +# updatenode noderange otherpkgs +# +#=cut +#------------------------------------------------------------------------------- + + +# do nothing for diskless deployment case because it is done in the image already +if [[ $UPDATENODE -ne 1 ]]; then + if [ "$NODESETSTATE" = "netboot" -o \ + "$NODESETSTATE" = "statelite" -o \ + "$NODESETSTATE" = "diskless" -o \ + "$NODESETSTATE" = "dataless" ] + then + echo " Did not install any extra rpms." + exit 0 + fi +fi + +if [[ -z "$OTHERPKGS_INDEX" ]]; then + echo "$0: no extra rpms to install" + exit 0 +fi + +if [[ -z "$NFSSERVER" ]]; then + NFSSERVER=$MASTER +fi + +if [[ -z "$INSTALLDIR" ]]; then + INSTALLDIR="/install" +fi + +#check if /install is mounted on the server, we may need to add code to conver NFSSERVER to ip +mounted=0; +result=`mount |grep /install |grep $NFSSERVER` +if [ $? -eq 0 ]; then + NFSSERVER="/install" + mounted=1 +fi + +if [[ -z "$OTHERPKGDIR" ]]; then + OTHERPKGDIR="$NFSSERVER/post/otherpkgs/$OSVER/$ARCH" +fi + +if [ $mounted -eq 0 ]; then + OTHERPKGDIR=${OTHERPKGDIR/#$INSTALLDIR/$NFSSERVER/} +fi + +echo NFSSERVER=$NFSSERVER +logger -t xcat "NFSSERVER=$NFSSERVER" +echo OTHERPKGDIR=$OTHERPKGDIR +logger -t xcat "OTHERPKGDIR=$OTHERPKGDIR" + +#if [ -x "/sbin/dhcpcd" ]; then +# dhcpcd -n $PRIMARYNIC +#fi + +#check if the node has yum or zypper installed, it will try yum first, then zypper and last rpm +# for rpm based machines, or check if apt is installed, then it will use apt then dpkg + +hasrpm=0 +hasyum=0 +haszypper=0 +hasapt=0 +hasdpkg=0 +scommand="rpm" +sinstallcommad="$scommand -ivh" +supdatecommad="$scommand -Uvh --replacepkgs" +sremovecommad="$scommand -ev" + +result=`which rpm` +if [ $? -eq 0 ]; then + hasrpm=1 + result=`rpm -q yum` + if [ $? -eq 0 ]; then + hasyum=1 + else + result=`rpm -q zypper` + if [ "$?" = "0" ]; then + haszypper=1 + fi + fi +else + result=`which dpkg` + if [ $? -eq 0 ]; then + hasdpkg=1 + scommand="dpkg" + sinstallcommand="$scommand -i" + supdatecommand="$sinstallcommand" + sremovecommand="$scommand -r" + result=`dpkg -l apt` + if [ $? -eq 0 ]; then + hasapt=1 + fi + fi +fi + + +# To support the #NEW_INSTALL_LIST# entry in otherpkgs.pkglist files, +# multiple lists of packages are provided to this script in the form: +# OTHERPKGS1, OTHERPKGS2, ... OTHERPKSn where n=OTHERPKGS_INDEX +# Each sublist will be installed in a separate call (separate pass +# through this loop) +op_index=1 +#echo "OTHERPKGS_INDEX = $OTHERPKGS_INDEX" +while [ $op_index -le $OTHERPKGS_INDEX ]; do + eval pkglist=\$OTHERPKGS$op_index + #echo "pkglist = $pkglist" + if [ $hasyum -eq 1 ]; then + mkdir -p /etc/yum.repos.d + result=`rm /etc/yum.repos.d/xCAT-otherpkgs*.repo 2>&1` + result=`yum clean all` + repo_base="/etc/yum.repos.d" + elif [ $haszypper -eq 1 ]; then + #remove old repo + old_repo=`zypper sl |grep xcat-otherpkgs | cut -f2 -d '|'` + for x in $old_repo + do + result=`zypper sd $x` + done + zypper --non-interactive refresh + repo_base="/tmp" + elif [ $hasapt -eq 1 ] ; then + mkdir -p /etc/apt/sources.list.d + result=`rm /etc/apt/sources.list.d/xCAT-otherpkgs*.list 2>&1` + result=`apt-get -y update` + repo_base="/etc/apt/sources.list.d" + fi + + repo_path=() + repo_pkgs="" + repo_pkgs_preremove="" + repo_pkgs_postremove="" + plain_pkgs="" + plain_pkgs_preremove="" + plain_pkgs_postremove="" + handled_path=() + for x in `echo "$pkglist" | tr "," "\n"` + do + #check if the file name starts with -- or -. + #If it is start with -, then the rpm must be removed before installing other packages + #If it is start with --, then the rpm will be removed after installing other packages + string_type=0; #nornmal rpm + pos=`expr index $x -` + if [ $pos -eq 1 ]; then + x=`echo ${x#-}` + pos=`expr index $x -` + if [ $pos -eq 1 ]; then + x=`echo ${x#-}` + string_type=1 #start with -- + else + string_type=-1 #start with - + fi + fi + + if [ $hasyum -eq 0 ] && [ $haszypper -eq 0 ] && [ $hasapt -eq 0 ]; then + if [ $string_type -eq -1 ]; then + plain_pkgs_preremove="$plain_pkgs_preremove $x" + elif [ $string_type -eq 1 ]; then + plain_pkgs_postremove="$plain_pkgs_postremove $x" + else + plain_pkgs="$plain_pkgs $x*" + fi + continue + fi + + if [ $string_type -eq -1 ]; then + repo_pkgs_preremove="$repo_pkgs_preremove $x" + elif [ $string_type -eq 1 ]; then + repo_pkgs_postremove="$repo_pkgs_postremove $x" + else + fn=`basename $x` + path=`dirname $x` + whole_path=$OTHERPKGDIR/$path + #whole_path=$OTHERPKGDIR + + #find out if this path has already handled + try_repo=1 + rc=1 + i=0 + while [ $i -lt ${#handled_path[*]} ]; do + if [ ${handled_path[$i]} = $path ]; then + try_repo=0 + j=0 + while [ $j -lt ${#repo_path[*]} ]; do + if [ ${repo_path[$j]} = $path ]; then + rc=0 + break + fi + let j++ + done + break + fi + let i++ + done + + + #try to add the path to the repo + if [ $try_repo -eq 1 ]; then + index=${#repo_path[*]} + if [ $hasyum -eq 1 ] || [ $haszypper -eq 1 ] ; then + REPOFILE="$repo_base/xCAT-otherpkgs$index.repo" + echo "[xcat-otherpkgs$index]" > $REPOFILE + echo "name=xcat-otherpkgs$index" >> $REPOFILE + if [ $mounted -eq 0 ]; then + echo "baseurl=ftp://$whole_path" >> $REPOFILE + else + echo "baseurl=file://$whole_path" >> $REPOFILE + fi + echo "enabled=1" >> $REPOFILE + echo "gpgcheck=0" >> $REPOFILE + elif [ $hasapt -eq 1 ] ; then + REPOFILE="$repo_base/xCAT-otherpkgs$index.list" + + if [ $mounted -eq 0 ]; then + type=ftp + else + type=file + fi + + echo "deb $type://$whole_path /" >> $REPOFILE + fi + + if [ $hasyum -eq 1 ]; then + #use yum + result=`yum list $fn 2>&1` + if [ $? -eq 0 ]; then + rc=0 + repo_path[${#repo_path[*]}]=$path + else + rm $REPOFILE + fi + elif [ $haszypper -eq 1 ]; then + #use zypper + if [[ "$OSVER" = sles11* ]]; then + result=`zypper ar -c $REPOFILE` + else + result=`zypper sa -c $REPOFILE` + fi + + result=`zypper --non-interactive refresh xcat-otherpkgs$index 2>&1` + if [ $? -eq 0 ]; then + rc=0 + repo_path[${#repo_path[*]}]=$path + else + result=`zypper sd xcat-otherpkgs$index` + fi + elif [ $hasapt -eq 1 ]; then + #use apt + result=`apt-cache search $fn 2>&1` + if [ $? -eq 0 ]; then + rc=0 + repo_path[${#repo_path[*]}]=$path + else + rm $REPOFILE + fi + + fi + + fi + + if [ $rc -eq 0 ]; then + repo_pkgs="$repo_pkgs $fn" + else + #now no hope we have to use rpm command + plain_pkgs="$plain_pkgs $x*" + fi + handled_path[${#handled_path[*]}]=$path + fi + done + + #now update all the existing rpms + if [ $hasyum -eq 1 ]; then + echo "yum -y upgrade" + result=`yum -y upgrade 2>&1` + logger -t xcat "$result" + if [ $? -ne 0 ]; then + logger -t xcat "otherpkgs: $result" + fi + echo "$result" + elif [ $haszypper -eq 1 ]; then + echo "zypper --non-interactive update --auto-agree-with-license" + result=`zypper --non-interactive update --auto-agree-with-license 2>&1` + logger -t xcat "$result" + if [ $? -ne 0 ]; then + logger -t xcat "otherpkgs: $result" + fi + echo "$result" + fi + + #echo "repo_pkgs=$repo_pkgs,\nrepo_pkgs_preremove=$repo_pkgs_preremove,\nrepo_pkgs_postremove=$repo_pkgs_postremove" + #echo "plain_pkgs=$plain_pkgs,\nplain_pkgs_preremove=$plain_pkgs_preremove,\nplain_pkgs_postremove=$plain_pkgs_postremove" + + + #Now we have parsed the input, let's remove rpms if is specified with - + if [ "$repo_pkgs_preremove" != "" ]; then + if [ $hasyum -eq 1 ]; then + echo "yum -y remove $repo_pkgs_preremove" + result=`yum -y remove $repo_pkgs_preremove 2>&1` + logger -t xcat "$result" + if [ $? -ne 0 ]; then + logger -t xcat "otherpkgs: $result" + fi + echo "$result" + elif [ $haszypper -eq 1 ]; then + echo "zypper remove -y $repo_pkgs_preremove" + result=`zypper remove -y $repo_pkgs_preremove 2>&1` + logger -t xcat "$result" + if [ $? -ne 0 ]; then + logger -t xcat "otherpkgs: $result" + fi + echo "$result" + fi + fi + + if [ "$plain_pkgs_preremove" != "" ]; then + echo "$sremovecommand $plain_pkgs_preremove" + result=`$sremovecommand $plain_pkgs_preremove 2>&1` + logger -t xcat "$result" + if [ $? -ne 0 ]; then + logger -t xcat "otherpkgs $result" + fi + echo "$result" + fi + + + #installation using yum or zypper + if [ "$repo_pkgs" != "" ]; then + if [ $hasyum -eq 1 ]; then + echo "yum -y install $repo_pkgs" + result=`yum -y install $repo_pkgs 2>&1` + logger -t xcat "$result" + if [ $? -ne 0 ]; then + logger -t xcat "otherpkgs: $result" + fi + echo "$result" + elif [ $haszypper -eq 1 ]; then + echo "zypper install -y $repo_pkgs" + result=`zypper install -y $repo_pkgs 2>&1` + logger -t xcat "$result" + if [ $? -ne 0 ]; then + logger -t xcat "otherpkgs: $result" + fi + echo "$result" + #remove the repos + #old_repo=`zypper lr -u |grep xcat-otherpkgs | cut -f2 -d '|'` + #for x in $old_repo + #do + # result=`zypper sd $x` + #done + elif [ $hasapt -eq 1 ]; then + echo "apt-get -q -y --force-yes install $repo_pkgs" + result=`apt-get -q -y --force-yes install $repo_pkgs 2>&1` + logger -t xcat "$result" + if [ $? -ne 0 ]; then + logger -t xcat "otherpkgs: $result" + fi + echo "$result" + fi + fi + + #Handle the rest with rpm + if [ "$plain_pkgs" != "" ]; then + if [ $mounted -eq 0 ]; then + dir_no_ftproot=${OTHERPKGDIR#$INSTALLDIR/} + mkdir -p /xcatpost/$dir_no_ftproot + rm -f -R /xcatpost/$dir_no_ftproot/* + mkdir -p /tmp/postage/ + rm -f -R /tmp/postage/* + cd /tmp/postage + + for x in `echo "$plain_pkgs" | tr " " "\n"` + do + wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 0 -T 60 ftp://$OTHERPKGDIR/$x 2> /tmp/wget.log + done + + mv $dir_no_ftproot/* /xcatpost/$dir_no_ftproot; + rm -rf $NFSSERVER + cd /xcatpost/$dir_no_ftproot + else + cd $OTHERPKGDIR + fi + + echo "$supdatecommand --replacepkgs $plain_pkgs" + result=`$supdatecommand --replacepkgs $plain_pkgs 2>&1` + logger -t xcat "$result" + if [ $? -ne 0 ]; then + logger -t xcat "otherpkgs $result" + fi + echo "$result" + + if [ $mounted -eq 0 ]; then + cd /xcatpost + dir_no_ftproot=${OTHERPKGDIR#$INSTALLDIR/} + dir_no_ftproot=${dir_no_ftproot/\/*/} + rm -f -R $dir_no_ftproot + fi + fi + + #remove more rpms if specified with -- + if [ "$repo_pkgs_postremove" != "" ]; then + if [ $hasyum -eq 1 ]; then + echo "yum -y remove $repo_pkgs_postremove" + result=`yum -y remove $repo_pkgs_postremove 2>&1` + logger -t xcat "$result" + if [ $? -ne 0 ]; then + logger -t xcat "otherpkgs: $result" + fi + echo "$result" + elif [ $haszypper -eq 1 ]; then + echo "zypper remove -y $repo_pkgs_postremove" + result=`zypper remove -y $repo_pkgs_postremove 2>&1` + logger -t xcat "$result" + if [ $? -ne 0 ]; then + logger -t xcat "otherpkgs: $result" + fi + echo "$result" + elif [ $hasapt -eq 1 ]; then + echo "apt-get -y remove $repo_pkgs_postremove" + result=`apt-get -y remove $repo_pkgs_postremove 2>&1` + logger -t xcat "$result" + if [ $? -ne 0 ]; then + logger -t xcat "otherpkgs: $result" + fi + echo "$result" + fi + fi + + if [ "$plain_pkgs_postremove" != "" ]; then + echo "$sremovecommand $plain_pkgs_postremove" + result=`$sremovecommand $plain_pkgs_postremove 2>&1` + logger -t xcat "$result" + if [ $? -ne 0 ]; then + logger -t xcat "otherpkgs $result" + fi + echo "$result" + fi + + let op_index=$op_index+1 +done + +exit 0 + diff --git a/xCAT/postscripts/syslog b/xCAT/postscripts/syslog index 9334a88ab..2bb2d4be2 100755 --- a/xCAT/postscripts/syslog +++ b/xCAT/postscripts/syslog @@ -74,7 +74,7 @@ if [[ $NTYPE = service ]]; then fi if [[ $OSTYPE = linux* ]]; then - if [[ $OSVER = fedora* ]] || [[ $OSVER = rhels5* ]] || [[ $OSVER = rhel6* ]] || [[ $OSVER = rhels6* ]] || [[ -f /etc/fedora-release ]] || [[ -f /etc/redhat-release ]]; then + if [[ $OSVER = fedora* ]] || [[ $OSVER = rhels5* ]] || [[ $OSVER = rhel6* ]] || [[ $OSVER = rhels6* ]] || [[ -f /etc/fedora-release ]] || [[ -f /etc/redhat-release ]] || [[ $OSVER = ubuntu* ]]; then if [ -e /etc/rsyslog.conf ]; then conf_file="/etc/rsyslog.conf" sysconfig="/etc/sysconfig/rsyslog" diff --git a/xCAT/postscripts/xcatpostinit b/xCAT/postscripts/xcatpostinit index da837ce6f..c213fc0fd 100755 --- a/xCAT/postscripts/xcatpostinit +++ b/xCAT/postscripts/xcatpostinit @@ -34,6 +34,9 @@ stop) logger -t xcat "nothing to stop" ;; start) + # For nodes that unmount/remove /tmp at install time, like ubuntu + #cp /root/mypostscript* /tmp/. + # Node is stateless by default STATELITE="No" diff --git a/xCAT/postscripts/xcatpostinit1 b/xCAT/postscripts/xcatpostinit1 index f3ae9f4f6..e4f4cc010 100755 --- a/xCAT/postscripts/xcatpostinit1 +++ b/xCAT/postscripts/xcatpostinit1 @@ -31,6 +31,9 @@ stop) echo -n "nothing to stop " ;; start) + # For nodes that unmount/remove /tmp at install time, like ubuntu + #cp /root/mypostscript* /tmp/. + # run /opt/xcat/xcatinstallpost if [ -r /opt/xcat/xcatinstallpost ]; then /opt/xcat/xcatinstallpost