2008-05-24 17:29:40 +00:00
#!/usr/bin/env perl
2009-09-24 18:51:53 +00:00
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
2008-05-24 17:29:40 +00:00
use File::Basename;
use File::Path;
use File::Copy;
use File::Find;
use Getopt::Long;
2008-09-11 22:03:01 +00:00
use Cwd qw(realpath);
2008-05-24 17:29:40 +00:00
#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;
2009-09-24 18:51:53 +00:00
my $arch;
2008-05-24 17:29:40 +00:00
my %libhash;
my @filestoadd;
my $profile;
my $osver;
my $pathtofiles=dirname($0);
2008-09-11 22:03:01 +00:00
my $fullpath=realpath($pathtofiles);
2008-05-24 17:29:40 +00:00
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;
2008-09-11 22:03:01 +00:00
my $customdir=$fullpath;
$customdir =~ s/.*share\/xcat/$installroot\/custom/;
2009-09-24 18:51:53 +00:00
my $imagename;
my $pkglist;
my $srcdir;
my $destdir;
my $srcdir_otherpkgs;
my $otherpkglist;
my $postinstall_filename;
my $rootimg_dir;
2010-01-26 12:10:16 +00:00
my $rwfiles; #these files are used by statelite for tmpfs rw
my $mode;
2010-03-05 06:54:52 +00:00
my $permission; #the permission works only for statelite mode currently
2008-05-24 17:29:40 +00:00
sub xdie {
system("rm -rf /tmp/xcatinitrd.$$");
die @_;
}
2008-09-10 14:59:34 +00:00
#-- fetch current version form CVS (overwrite locally changed versions)
# if (opendir(CVS,"$pathtofiles/CVS")){
# close CVS;
# my $cvsout = qx/cd $pathtofiles; cvs update -C 2>&1/;
# chomp $cvsout;
# if ( $cvsout ne "cvs update: Updating ." ) {
# print "Difference of local copy from CVS detected\n";
# print $cvsout,"\n";
# print "Trying to re-run $name\n";
# print("$pathtofiles/$name ",join(" ",@ARGV),"\n");
# exec("$pathtofiles/$name",@ARGV);
# }
# }
2008-05-24 17:29:40 +00:00
$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,
2010-01-26 12:10:16 +00:00
'k=s' => \$kernelver,
2010-03-05 06:54:52 +00:00
'm=s' => \$mode, #provide options for the mode of "genimage"
'permission=s' => \$permission
2008-05-24 17:29:40 +00:00
);
2010-03-05 06:54:52 +00:00
2009-09-24 18:51:53 +00:00
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'};
if ($srcdir) { $srcdir="$srcdir/1"; }
$srcdir_otherpkgs=$ref1->{'otherpkgdir'};
$otherpkglist=$ref1->{'otherpkglist'};
$postinstall_filename=$ref1->{'postinstall'};
$destdir=$ref1->{'rootimgdir'};
}
2010-03-05 06:54:52 +00:00
if ($mode eq "statelite") {
if (!$permission) {
$permission = "755";
}
}
2009-09-24 18:51:53 +00:00
if (!$arch) {
2009-10-13 11:39:37 +00:00
$arch = `uname -m`;
2009-09-24 18:51:53 +00:00
chomp($arch);
if ($arch =~ /i.86$/) {
$arch = "x86";
}
}
if (!$srcdir) {
$srcdir="$installroot/$osver/$arch/1";
}
if (!$srcdir_otherpkgs) {
$srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch";
}
if (!$destdir)
{
$destdir="$installroot/netboot/$osver/$arch/$profile";
}
$rootimg_dir="$destdir/rootimg";
2008-05-24 17:29:40 +00:00
unless ($osver and $profile and $netdriver and $prinic) {
2010-03-05 10:18:04 +00:00
print 'Usage: genimage -i <nodebootif> -n <nodenetdrivers> [-r <otherifaces>] -k <KERNELVER> -o <OSVER> -p <PROFILE> -a <ARCH> [-m <mode> [--permission <permission>]]'."\n";
2009-09-24 18:51:53 +00:00
print ' genimage -i <nodebootif> -n <nodenetdrivers> [-r <otherifaces>] -k <KERNELVER> <imagename>'."\n";
2010-03-05 10:18:04 +00:00
print ' --permission only works when "-m statelite" is set'."\n";
2008-05-24 17:29:40 +00:00
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";
2010-03-24 08:47:35 +00:00
print " genimage -i eth0 -n tg3,bnx2 -o centos5.1 -p compute -m statelite\n";
print " genimage -i eth0 -n tg3,bnx2 -o centos5.1 -p compute -m statelite --permission 777\n";
2009-09-24 18:51:53 +00:00
print " genimage -i eth0 -ntg3 myimagename\n";
2008-05-24 17:29:40 +00:00
exit 1;
}
my @ndrivers;
foreach (split /,/,$netdriver) {
unless (/\.ko$/) {
s/$/.ko/;
}
if (/^$/) {
next;
}
push @ndrivers,$_;
}
2008-05-26 16:11:24 +00:00
unless (grep /af_packet/,@ndrivers) {
unshift(@ndrivers,"af_packet.ko");
}
2008-05-24 17:29:40 +00:00
2010-01-26 12:10:16 +00:00
if($mode eq "statelite") {
push @ndrivers, "sunrpc.ko";
push @ndrivers, "lockd.ko";
push @ndrivers, "nfs_acl.ko";
2010-02-11 02:24:48 +00:00
push @ndrivers, "fscache.ko";
2010-01-26 12:10:16 +00:00
push @ndrivers, "auth_rpcgss.ko";
push @ndrivers, "exportfs.ko";
push @ndrivers, "nfsd.ko";
push @ndrivers, "nfs.ko";
}
2009-02-18 13:43:11 +00:00
my $osver_host;
if(`grep VERSION /etc/SuSE-release` =~ /VERSION = (\d+)/) {
$osver_host=$1;
} else {
$osver_host=11;
}
2009-09-24 18:51:53 +00:00
unless ($onlyinitrd) {
2010-03-19 21:12:56 +00:00
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);
}
2008-09-09 23:52:04 +00:00
2009-09-24 18:51:53 +00:00
mkpath "$rootimg_dir/etc";
mkpath "$rootimg_dir/dev";
#system "mount -o bind /dev $rootimg_dir/dev";
2010-01-26 12:10:16 +00:00
if( ! -e "$rootimg_dir/dev/zero") {
system "mknod $rootimg_dir/dev/zero c 1 5";
}
if( ! -e "$rootimg_dir/dev/null") {
system "mknod $rootimg_dir/dev/null c 1 3"; #that's neccessary for SLES11
}
2009-09-24 18:51:53 +00:00
open($fd,">>","$rootimg_dir/etc/fstab");
2008-05-24 17:29:40 +00:00
print $fd "#Dummy fstab for rpm postscripts to see\n";
close($fd);
2009-02-18 13:43:11 +00:00
if($osver_host == 11) {#zypper in SLES11 is different
2009-02-12 12:04:51 +00:00
if(-e "$rootimg_dir/etc/zypp/repos.d/$osver.repo") {
system("rm -rf $rootimg_dir/etc/zypp/repos.d/$osver.repo");
}
system("zypper -R $rootimg_dir ar file:$srcdir $osver");
}else {
2009-09-24 18:51:53 +00:00
system("zypper -R $rootimg_dir sa file:$srcdir");
2009-02-12 12:04:51 +00:00
}
2008-09-09 23:52:04 +00:00
2009-07-02 20:24:27 +00:00
#remove the old repository for extra packages
2009-10-06 20:21:11 +00:00
my $result=`zypper -R $rootimg_dir sl |grep otherpkg|cut -f2 -d '|'|tr "\n" " "`;
2009-07-02 20:24:27 +00:00
if ($result =~ /\S/) {
2009-09-24 18:51:53 +00:00
system("zypper -R $rootimg_dir sd $result");
2009-07-02 20:24:27 +00:00
}
#add the new repository for extra packages
2010-03-22 16:14:06 +00:00
my %extrapkgnames;
2009-07-02 20:24:27 +00:00
if($osver_host == 11) { #SLES11
2009-09-24 18:51:53 +00:00
if(-e "$rootimg_dir/etc/zypp/repos.d/otherpkg.repo") {
system("rm -rf $rootimg_dir/etc/zypp/repos.d/otherpkg.repo");
2009-07-02 20:24:27 +00:00
}
}
my $index=1;
2010-03-22 16:14:06 +00:00
my $pass;
2010-03-31 00:51:21 +00:00
foreach $pass (sort (keys(%extra_hash))) {
2010-03-22 16:14:06 +00:00
foreach (keys(%{$extra_hash{$pass}})) {
2009-10-06 20:21:11 +00:00
if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE")) { next;}
2009-09-24 18:51:53 +00:00
my $whole_path="$srcdir_otherpkgs/$_";
2009-07-02 20:24:27 +00:00
if (-r "$srcdir_otherpkgs/$_/repodata/repomd.xml") {
if($osver_host == 11) {
2009-09-24 18:51:53 +00:00
system("zypper -R $rootimg_dir ar file:$srcdir_otherpkgs/$_ otherpkg$index");
2009-07-02 20:24:27 +00:00
}else {
2009-09-24 18:51:53 +00:00
system("zypper -R $rootimg_dir sa file:$srcdir_otherpkgs/$_");
2009-07-02 20:24:27 +00:00
}
} else {
if($osver_host == 11) {
2009-09-24 18:51:53 +00:00
system("zypper -R $rootimg_dir ar -t Plaindir file:$srcdir_otherpkgs/$_ otherpkg$index");
2009-07-02 20:24:27 +00:00
}else {
2009-09-24 18:51:53 +00:00
system("zypper -R $rootimg_dir sa -t Plaindir file:$srcdir_otherpkgs/$_");
2009-07-02 20:24:27 +00:00
}
}
$index++;
2010-03-22 16:14:06 +00:00
my $pa=$extra_hash{$pass}{$_};
$extrapkgnames{$pass} .= " " . join(' ', @$pa);
}
2008-09-09 23:52:04 +00:00
}
2009-09-24 18:51:53 +00:00
#-- add custom repositories to the image
#TODO: should we add the support to otherpkgs for this? we have too many list files and it seems only SLES supports this
my $repolist;
2009-04-08 07:37:35 +00:00
if ( -r "$pathtofiles/$profile.$osver.$arch.repolist") {
$repolist = "$pathtofiles/$profile.$osver.$arch.repolist";
}elsif ( -r "$pathtofiles/$profile.$osver.repolist") {
$repolist = "$pathtofiles/$profile.$osver.repolist";
}elsif ( -r "$pathtofiles/$profile.repolist") {
$repolist = "$pathtofiles/$profile.repolist";
}
if ( -r "$repolist") {
2008-09-10 14:38:27 +00:00
print "Reading custom repositories\n";
open($repoconfig,"<","$repolist");
while (<$repoconfig>) {
chomp;
next if /^\s*#/;
2009-09-24 18:51:53 +00:00
my ($repotype,$repourl,$repoalias) = split m/\|/;
system("zypper -R $rootimg_dir ar $repourl $repoalias");
2008-09-10 14:38:27 +00:00
}
}
2010-03-09 17:25:45 +00:00
# Refresh the zypper cache in case there is still old data out there
system("zypper -R $rootimg_dir refresh");
2009-09-24 18:51:53 +00:00
#my $yumcmd = "yum -y -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir --disablerepo=* ";
2008-05-24 17:29:40 +00:00
#$yumcmd .= "install ";
2009-09-24 18:51:53 +00:00
#mkpath("$rootimg_dir/var/lib/yum");
2009-02-12 12:04:51 +00:00
my $yumcmd;
2009-02-18 13:43:11 +00:00
if($osver =~ /sles11/ && $osver_host == 11) {
2009-09-24 18:51:53 +00:00
$yumcmd = "zypper -R $rootimg_dir install -l "; #add -l for SLES11
2009-02-12 12:04:51 +00:00
}else {
2009-09-24 18:51:53 +00:00
$yumcmd = "zypper -R $rootimg_dir install ";
}
2010-03-19 21:12:56 +00:00
2010-03-22 16:14:06 +00:00
#install packages from pkglist file
2010-03-19 21:12:56 +00:00
my $pkgnames;
2009-09-24 18:51:53 +00:00
if (!$imagename) {
2010-03-19 21:12:56 +00:00
$pkglist=get_profile_def_filename($customdir, "pkglist");
if (!$pkglist) { $pkglist=get_profile_def_filename($pathtofiles, "pkglist"); }
2009-02-12 12:04:51 +00:00
}
2008-09-11 22:03:01 +00:00
if (!$pkglist) {
2008-05-24 17:29:40 +00:00
print "Unable to find package list for $profile!";
2009-02-16 22:12:03 +00:00
exit 1;
2008-05-24 17:29:40 +00:00
}
2008-09-11 22:03:01 +00:00
2010-03-19 21:12:56 +00:00
my %pkg_hash=get_package_names($pkglist);
my $index=1;
2010-03-31 00:51:21 +00:00
foreach $pass (sort (keys(%pkg_hash))) {
2010-03-22 16:14:06 +00:00
$pkgnames = "";
foreach (keys(%{$pkg_hash{$pass}})) {
if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE")) { next;}
2010-03-24 08:47:35 +00:00
my $pa=$pkg_hash{$pass}{$_};
2010-03-22 16:14:06 +00:00
$pkgnames .= " " . join(' ', @$pa);
}
2010-03-31 00:51:21 +00:00
print "$yumcmd $pkgnames\n";
2010-03-22 16:14:06 +00:00
my $rc = system("$yumcmd $pkgnames");
2010-03-31 00:51:21 +00:00
$rc = $rc >> 8;
if (($rc) && ($rc != '104')) {
print "zypper invocation failed with rc: $rc\n";
2010-03-22 16:14:06 +00:00
exit 1;
}
2008-05-24 17:29:40 +00:00
}
2009-04-23 19:12:33 +00:00
2010-03-31 00:51:21 +00:00
foreach $pass (sort (keys(%extra_hash))) {
2010-03-22 16:14:06 +00:00
#remove the packages that are specified in the otherpkgs.list files with leading '-'
my $yumcmd_remove= "zypper -R $rootimg_dir remove ";
if (exists ($extra_hash{$pass}{'PRE_REMOVE'})) {
my $pa=$extra_hash{$pass}{'PRE_REMOVE'};
my $rm_packges= join(' ', @$pa);
if ($rm_packges) {
$rc = system("$yumcmd_remove $rm_packges");
}
2009-10-06 20:21:11 +00:00
}
2010-03-22 16:14:06 +00:00
#add extra packages in the list
if ($extrapkgnames{$pass}) {
2010-03-31 00:51:21 +00:00
print "$yumcmd $extrapkgnames{$pass}\n";
2010-03-22 16:14:06 +00:00
$rc = system("$yumcmd $extrapkgnames{$pass}");
2010-03-31 00:51:21 +00:00
$rc = $rc >> 8;
if (($rc) && ($rc != '104')) {
print "zypper invocation failed with rc: $rc\n";
2010-03-22 16:14:06 +00:00
exit 1;
}
2009-04-23 19:12:33 +00:00
}
2010-03-22 16:14:06 +00:00
#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) {
$rc = system("$yumcmd_remove $rm_packges");
}
2009-10-06 20:21:11 +00:00
}
}
2010-03-08 20:46:07 +00:00
# run zypper update to update any installed rpms
# needed when running genimage again after updating software in repositories
my $yumcmd_update = "zypper -R $rootimg_dir update ";
$rc = system("$yumcmd_update");
# ignore any return code
2008-05-24 17:29:40 +00:00
postscripts(); #run 'postscripts'
}
unlink "/tmp/genimage.$$.yum.conf";
2008-09-10 14:32:35 +00:00
#-- run postinstall script
2009-09-24 18:51:53 +00:00
if (!$imagename) {
2010-03-19 21:12:56 +00:00
$postinstall_filename= get_profile_def_filename($customdir, "postinstall");
2009-09-24 18:51:53 +00:00
if (!$postinstall_filename) {
2010-03-19 21:12:56 +00:00
$postinstall_filename= get_profile_def_filename($pathtofiles, "postinstall");
2009-09-24 18:51:53 +00:00
}
2009-04-23 14:13:56 +00:00
}
if (($postinstall_filename) && (-x $postinstall_filename)) {
2010-03-19 21:12:56 +00:00
#print "postinstall_filename=$postinstall_filename\n";
2009-09-24 18:51:53 +00:00
my $rc = system($postinstall_filename, $rootimg_dir,$osver,$arch,$profile);
2009-02-18 13:43:11 +00:00
if($rc) {
print "postinstall script failed\n";
exit 1;
}
}
2009-04-23 14:13:56 +00:00
2010-01-26 12:10:16 +00:00
if($mode eq "statelite") {
mkpath "$rootimg_dir/.statelite"; # create place for NFS mounts;
2010-02-11 02:24:48 +00:00
mkpath "$rootimg_dir/root/.ssh"; # create place for NFS mounts for ssh;
2010-01-26 12:10:16 +00:00
# this script will get the directories;
2010-02-11 02:24:48 +00:00
unless( -r "$pathtofiles/../add-on/statelite/rc.statelite") {
print "Can't find $pathtofiles/../add-on/statelite/rc.statelite!\n";
2010-01-26 12:10:16 +00:00
exit;
}
2010-02-11 02:24:48 +00:00
system("cp $pathtofiles/../add-on/statelite/rc.statelite $rootimg_dir/etc/init.d/statelite");
2010-01-26 12:10:16 +00:00
# the dhcp client information stores in the directory "/var/lib/dhcpcd/"
unless(-l "$rootimg_dir/var/lib/dhcpcd") {
mkpath "$rootimg_dir/var/lib/dhcpcd/";
system("touch $rootimg_dir/var/lib/dhcpcd/dhcpcd-$prinic.info");
}
# which is different from the Redhat family
}
2009-04-23 19:12:33 +00:00
#some rpms mounts the imageroot/proc on the /proc, need to release it,
#otherwise got kernal panic when installing
2009-08-13 08:36:38 +00:00
#sometimes, the proc fs is not mounted, so one warning/error message will display,
#and I add one check point here.
2010-03-05 18:53:20 +00:00
my $MFD;
open MFD, "/proc/mounts";
my @lines = <MFD>;
close MFD;
2009-08-13 08:36:38 +00:00
2009-09-24 18:51:53 +00:00
my $ret = grep m{$rootimg_dir/proc}, @lines;
2009-08-13 08:36:38 +00:00
if($ret > 0) {
2010-03-05 18:53:20 +00:00
system("umount -l $rootimg_dir/proc");
2009-08-13 08:36:38 +00:00
}
2008-09-10 14:32:35 +00:00
2010-04-02 07:11:44 +00:00
#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
2010-04-02 12:05:33 +00:00
my @KVERS= <$rootimg_dir/boot/vmlinux-*>;
unless (scalar(@KVERS)) {
@KVERS= <$rootimg_dir/boot/vmlinuz-*>;
}
foreach (@KVERS) {
s/vmlinu.-//;
}
unless (scalar(@KVERS)) {
@KVERS= <$rootimg_dir/lib/modules/*>;
}
2010-04-02 07:11:44 +00:00
if (scalar(@KVERS)) {
2010-04-02 12:05:33 +00:00
$basekernelver = basename(pop @KVERS);
2010-04-02 07:11:44 +00:00
}
unless ($basekernelver) {
$basekernelver = `uname -r`;
}
unless ($kernelver) {
$kernelver=$basekernelver;
}
chomp($kernelver);
2010-04-02 12:05:33 +00:00
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);
2008-05-24 17:29:40 +00:00
mkinitrd();
2009-04-23 19:12:33 +00:00
2008-05-24 17:29:40 +00:00
sub getlibs {
my $file = shift;
2009-09-24 18:51:53 +00:00
my $liblist = `chroot $rootimg_dir ldd $file`;
2008-05-24 17:29:40 +00:00
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 {
2010-04-02 12:05:33 +00:00
mkpath("/tmp/xcatinitrd.$$/bin");
if($basekernelver eq $kernelver) {
2009-09-24 18:51:53 +00:00
if (-f "$rootimg_dir/boot/vmlinuz-$kernelver") {
2010-04-02 12:05:33 +00:00
copy(<$rootimg_dir/boot/vmlinuz-*>,"$destdir/kernel");
} elsif (-f "$rootimg_dir/boot/vmlinux-$kernelver"){
copy(<$rootimg_dir/boot/vmlinux-*>,"$destdir/kernel");
2009-02-16 22:12:03 +00:00
}
2010-04-02 12:05:33 +00:00
}
else {
if(-r "$rootimg_dir/boot/vmlinuz-$kernelver") {
copy("$rootimg_dir/boot/vmlinuz-$kernelver","$destdir/kernel");
2009-09-24 18:51:53 +00:00
} elsif(-r "$rootimg_dir/boot/vmlinux-$kernelver") {
2010-04-02 12:05:33 +00:00
copy("$rootimg_dir/boot/vmlinux-$kernelver","$destdir/kernel");
} elsif(-r "/boot/vmlinuz-$kernelver") {
copy("/boot/vmlinuz-$kernelver","$destdir/kernel");
} elsif(-r "/boot/vmlinux-$kernelver") {#for SLES10,11
copy("/boot/vmlinux-$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.$$/tmp");
mkpath("/tmp/xcatinitrd.$$/var/run");
mkpath("/tmp/xcatinitrd.$$/lib64/firmware");
# if($osver =~ /sles/ && $arch eq "ppc64") {#SLES for Power6&7
# mkpath("/tmp/xcatinitrd.$$/lib64/power6");
# mkpath("/tmp/xcatinitrd.$$/lib64/power7");
# }
mkpath("/tmp/xcatinitrd.$$/lib/power6");#SLES10
mkpath("/tmp/xcatinitrd.$$/lib/power7");#SLES10
mkpath("/tmp/xcatinitrd.$$/lib/mkinitrd/bin");
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/dhcpcd");
my $inifile;
open($inifile,">","/tmp/xcatinitrd.$$/init");
print $inifile "#!/bin/bash\n";
2010-01-26 12:10:16 +00:00
# copied from genimage for rh
# add some functions
print $inifile <<EOS1;
NEWROOT="/sysroot"
SHELL="/bin/sh"
RWDIR=".statelite"
# Define some colors
RESET="\033[0m"
RED="\033[31m"
CYAN="\033[36m"
YELLOW="\033[33m\033[1m"
GREEN="\033[32m"
PINK="\033[35m\033[1m"
MAGENTA="\033[35m"
BROWN="\033[33m"
NORMAL=\$RESET
# This function is used to mount files/directories from the .statelite directory
# over the root directory.
# This function stolen from redhat
shell() {
echo ''
echo -e "\$YELLOW Entering rescue/debug init shell."
echo -e " Exit shell to continue booting.\$RESET"
\$SHELL
}
mountfile () {
snapshotfile=\${NEWROOT}/\${RWDIR}/\${2}\${1}
dir=`dirname \$snapshotfile`
#
# Check if file already exists in snapshot directory. If not attempt to copy
# from root directory to snapshot directory.
#
if [ ! -e \$snapshotfile ]; then
mkdir -p \$dir || echo -e "\${RED}Can't make \$dir\${NORMAL}"
#echo -e "\${YELLOW} \${1} missing from client specific area.\${RESET}"
if [ -e \$NEWROOT/\${1} ] ; then
#echo "Copying \${1}"
rsync -a \$NEWROOT/\${1} \$snapshotfile
else
#echo "Creating \${1}"
touch \$snapshotfile
fi
fi
#
# Mount the snapshotfile over the root file so the client will have r/w access
#
mount -n -o bind \$NEWROOT/\$RWDIR/\${2}\${1} \$NEWROOT/\${1}
}
fancydisplay () {
clear
echo -e "\$CYAN"
echo '
.. :iiii,
:tLL; .,:...,.
.j;:tLt. :. .;j: ij::::;.
:tt;:::,ii:.jEEGi :tDEEG:.ti,::::;t:
.,,,,,,,,,,,tLEEEEj: tDEEEEDtj;,,,::::::
.:,,::::::,;fDEEEEEL,. .,ijDEDDDEEGt,,,,:,ijj;
.... ..:;jDDLGDEEEGGGfjjjjjjfffLGDEEDEEDLjfGDt,:..
.iftffGDLLDEEEDDDEEDDDDEDEEGLfLjjtti:
,fii;jGDGffLjifLGLjtfffffGDEDGfji
;DEEGffDDDjiii;;ii;,tGDEGjfEEEEf.
,GEGGftiGEEEDt:,;,;;LEEDGjLEEEEEEG
;DEDGjtjfitjGGjfDGj;jLLiitfGDEGjEEDj
fGjjtfLfji;itjfGDjLDfjjjji;tGGLDEEDj
fEDGffjti;ittjjjjtjjjjt:,,iiGGGGjtf.
:fGGLfLLfLGf;i;ijffj,,tjLGDDGLfjtf,
:;tLfjiiffLGDDDGLGEEEEjfGDDGGLfjfff:
.. ,;tLLLLLL,;tijfLGGGjfDEEEEDLLGGGLLLjtjLLfi,.
.jffLLLLGGLfjj;: :,;ijLGLfjGEDDEGtfGGLfjj:.,jjLGGLti;,,;fj,
,fGGGGGGLj,. ;jGGGGLLjffftjLj;.. .,tfGGGGGGGGGGi
,jGDDDj,. :tLGLGGLGDLjt, :iLGGDDDDGLif
,LDDDL, .;LDDDDGfff, ,;iGDDj;,..
;fGGGf, ,;;;;,: tf;jL,
;.:::, Powered by xCAT ,j.:;
'
echo -e "\$RESET"
echo -e "\$YELLOW"
echo '
_________ ________________
___ __\\_ ___ \\ / _ \\__ ___/
\\ \\/ / \\ \\/ / /_\\ \\| |
> <\\ \\____/ | \\ |
/__/\\_ \\\\______ /\\____|__ /____|
\\/ \\/ \\/
'
echo -e "\$RESET"
}
EOS1
2008-05-26 16:11:24 +00:00
print $inifile "mount -t proc /proc /proc\n";
2008-05-24 17:29:40 +00:00
print $inifile "mount -t sysfs /sys /sys\n";
2010-03-05 08:00:51 +00:00
print $inifile "mount -o mode=0755 -t tmpfs /dev /dev\n";
2008-05-24 17:29:40 +00:00
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";
2009-08-17 06:40:04 +00:00
print $inifile "mknod /dev/random c 1 8\n";
print $inifile "mknod /dev/urandom c 1 9\n";
2008-05-24 17:29:40 +00:00
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";
2010-01-26 12:10:16 +00:00
2008-05-24 17:29:40 +00:00
foreach (@ndrivers) {
print $inifile "insmod /lib/$_\n";
}
2010-01-26 12:10:16 +00:00
if($mode eq "statelite") {
print $inifile "echo debug: before netstart\n";
print $inifile "# check and see if debug is specified on command line\n";
print $inifile "grep '\(debug\)' /proc/cmdline > /dev/null && export DEBUG=1\n";
}
2008-05-24 17:29:40 +00:00
print $inifile <<EOMS;
netstart
2010-01-26 12:10:16 +00:00
while ! ifconfig | grep inet; do
echo -e "\${RED}Failed to acquire address, retrying \${RESET}"
sleep 1
netstart
done
2008-05-26 16:11:24 +00:00
ip addr add dev lo 127.0.0.1/8
ip link set lo up
2008-05-24 17:29:40 +00:00
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
sleep 5 #should be random, exponential for scale
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
2010-01-26 12:10:16 +00:00
elif [[ "\$KEY" == NFSROOT ]]; then # for NFSROOT
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}'`
2010-02-11 02:24:48 +00:00
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
2008-05-24 17:29:40 +00:00
fi
done
2010-01-26 12:10:16 +00:00
# show xCAT logo
fancydisplay
# begin NFSROOT/Statelite code
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,udp,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
2010-03-05 08:00:51 +00:00
mount -t tmpfs rw -o mode=$permission \$NEWROOT/\$RWDIR
2010-01-26 12:10:16 +00:00
mkdir -p \$NEWROOT/\$RWDIR/tmpfs
2010-03-05 08:00:51 +00:00
#mount the /root/.ssh, it needs more strict permission in order for ssh work
2010-02-11 02:24:48 +00:00
if [ ! -e "\$NEWROOT/root/.ssh" ]
then
mkdir -p \$NEWROOT/root/.ssh
fi
mount -t tmpfs -o mode=755 ssh \$NEWROOT/root/.ssh
2010-01-26 12:10:16 +00:00
# mount the SNAPSHOT directory here for persistent use.
if [ ! -z \$SNAPSHOTSERVER ]
then
mkdir -p \$NEWROOT/\$RWDIR/persistent
MAXTRIES=5
ITER=0
2010-02-11 02:24:48 +00:00
while ! mount \$SNAPSHOTSERVER:\$SNAPSHOTROOT \$NEWROOT/\$RWDIR/persistent -o nolock
2010-01-26 12:10:16 +00:00
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.
# SLES uses different file to store DHCP info
if [ ! -d \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhcpcd ]
then
mkdir -p \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhcpcd
fi
cp -fp /var/lib/dhcpcd/dhcpcd-$prinic.info \${NEWROOT}/\${RWDIR}/tmpfs/var/lib/dhcpcd/dhcpcd-$prinic.info
[ -e /etc/ntp.conf ] && mkdir -p \$NEWROOT/\$RWDIR/tmpfs/etc && cp /etc/ntp.conf \$NEWROOT/\$RWDIR/tmpfs/etc/
[ -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
# sles use the standard utility to chroot
if ! exec /usr/bin/chroot \$NEWROOT /sbin/init
then
echo ""
echo -e "\${RED}Couldn't chroot. Something must be wrong with NFS root image.\${RESET}"
shell
fi
exit
fi
# end NFSROOT/Statelite code
2008-05-24 17:29:40 +00:00
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
2008-05-26 16:11:24 +00:00
mount \$SERVER:\$ROOTDIR /ro -r -n -o nolock,rsize=32768,udp,nfsvers=3,timeo=14
2010-01-26 12:10:16 +00:00
ST=`expr \$RANDOM % 5`
sleep \$ST
2008-05-24 17:29:40 +00:00
done
mount -t tmpfs rw /rw
mkdir -p /rw/etc
2008-05-27 18:21:23 +00:00
mkdir -p /rw/var/lib/dhcpcd
2008-05-24 17:29:40 +00:00
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
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 <<EOMS;
echo "You're dead. rpower nodename reset to play again.
* Did you packimage with -m cpio, -m squashfs, or -m nfs?
* If using -m squashfs did you include aufs.ko with geninitrd?
e.g.: -n tg3,squashfs,aufs,loop
* If using -m nfs did you export NFS and sync rootimg? And
did you include the aufs and nfs modules in the proper order:
e.g.: -n tg3,aufs,loop,sunrpc,lockd,nfs_acl,nfs
"
sleep 5
EOMS
print $inifile " exit\n";
print $inifile "fi\n";
print $inifile "cd /\n";
2009-02-12 12:04:51 +00:00
print $inifile "mkdir /sysroot/var/lib/dhcpcd/\n"; #neccessary for SLES11, not sure for SLES10
2008-05-27 18:21:23 +00:00
print $inifile "cp /var/lib/dhcpcd/* /sysroot/var/lib/dhcpcd/\n";
print $inifile "cp /etc/resolv.conf /sysroot/etc/\n";
2008-05-27 20:20:15 +00:00
print $inifile "cp /etc/HOSTNAME /sysroot/etc/\n";
2008-05-24 17:29:40 +00:00
print $inifile "mknod /sysroot/dev/console c 5 1\n";
2008-05-26 16:11:24 +00:00
print $inifile "exec /lib/mkinitrd/bin/run-init -c /dev/console /sysroot /sbin/init\n";
2008-05-24 17:29:40 +00:00
close($inifile);
open($inifile,">"."/tmp/xcatinitrd.$$/bin/netstart");
2008-05-26 16:11:24 +00:00
print $inifile "#!/bin/bash\n";
print $inifile "dhcpcd $prinic\n";
Allows diskless nodes to boot via other interfaces aside of primary boot interface, ie. provides ethernet failover.
1) In initrd, bring up aside from main interface (genimage -i option) also other interfaces (-r option).
2) /etc/resolv.conf creation needed to be rewritten, othewise it gets confused by several dhcpcd records.
3) Fill database with MAC addresses for all interfaces. Since it't not possible to have several stanzas of the same name in dhcpd.conf, we need to define unique "alias" for every interface. For example, for host "host1" we will add '00:1A:64:5D:1B:84!host1e0|00:1A:64:5D:1B:86!host1e1' to macs table. Of course, this aliases have to be defined in DNS, otherwise makedhcp command will not use this aliases:
/etc/hosts:
10.217.249.232 host1 host1e0 host1e1
Since this are aliases (need not be nessesary), both interfaces get the same IP address during initrd, but this doesn't break anything.
a) blades - changed getmacs function to gather all MAC addresses. Which interfaces we are interested in are defined in noderes.installnic or noderes.primarynic as "eth0|eth1".
b) all other - TODO. We have only 8 non-blade nodes, so we fill database manually.
Backwards compatible:
- if there is only one interface in noderes.installnic, getmacs function gathers only this one MAC address
- if we run genimage without -r option, only one interface is brought up
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@2124 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
2008-09-10 15:04:32 +00:00
#-- Bring other NICs up in /bin/netstart in initrd for NIC failover
foreach (split /,/,$othernics) {
if (/^$/) { next; }
print $inifile "dhcpcd $_\n";
}
print $inifile <<END;
cat /var/lib/dhcpcd/*info | grep HOSTNAME | uniq | awk -F= '{print \$2}'| sed \"s/'//g\" >> /etc/HOSTNAME
END
2008-05-27 20:20:15 +00:00
2008-05-24 17:29:40 +00:00
close($inifile);
chmod(0755,"/tmp/xcatinitrd.$$/init");
chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart");
@filestoadd=();
foreach (@ndrivers) {
2008-09-11 22:03:01 +00:00
if (-f "$customdir/$_") {
2008-05-24 17:29:40 +00:00
push @filestoadd,[$_,"lib/$_"];
2008-09-11 22:03:01 +00:00
} elsif (-f "$pathtofiles/$_") {
push @filestoadd,[$_,"lib/$_"];
}
2008-05-24 17:29:40 +00:00
}
2010-01-26 12:10:16 +00:00
if($mode eq "statelite") {
foreach ("sbin/ifconfig", "usr/bin/clear", "sbin/mount.nfs","sbin/umount.nfs","bin/hostname","usr/bin/egrep","bin/ln","bin/ls","usr/bin/dirname","usr/bin/expr","usr/bin/chroot","usr/bin/grep","bin/cpio","bin/sleep","bin/mount","bin/umount","sbin/dhcpcd","bin/bash","sbin/insmod","bin/mkdir","bin/mknod","sbin/ip","bin/cat","usr/bin/awk","usr/bin/wget","bin/cp","usr/bin/cpio","usr/bin/zcat","usr/bin/gzip","lib/mkinitrd/bin/run-init","usr/bin/uniq","usr/bin/sed") {
getlibs($_);
push @filestoadd,$_;
}
}else {
foreach ("sbin/ifconfig","usr/bin/clear", "usr/bin/grep","bin/cpio","bin/sleep","bin/mount","sbin/dhcpcd","bin/bash","sbin/insmod","bin/mkdir","bin/mknod","sbin/ip","bin/cat","usr/bin/awk","usr/bin/wget","bin/cp","usr/bin/cpio","usr/bin/zcat","usr/bin/gzip","lib/mkinitrd/bin/run-init","usr/bin/uniq","usr/bin/sed") {
2010-03-31 09:17:51 +00:00
getlibs($_);
2010-01-26 12:10:16 +00:00
push @filestoadd,$_;
}
}
2008-05-24 17:29:40 +00:00
if ($arch =~ /x86_64/) {
push @filestoadd,"lib64/libnss_dns.so.2";
}
else {
push @filestoadd,"lib/libnss_dns.so.2";
}
2010-03-31 09:17:51 +00:00
# cross-platfrom support on power6&7 etc
# ldd can't handle such one scenario: mn is power6, the target platform is power7
if ($arch =~ /ppc64/) {
my @archs = ("power6", "power6x", "power7", "ppc-cell-be");
foreach my $arch (@archs) {
if(-d "$rootimg_dir/lib64/$arch") {
system("cp -a $rootimg_dir/lib64/$arch /tmp/xcatinitrd.$$/lib64/");
}
}
}
2008-05-24 17:29:40 +00:00
push @filestoadd,keys %libhash;
if($basekernelver ne $kernelver) {
2009-09-24 18:51:53 +00:00
system("rm -rf $rootimg_dir/lib/modules/$basekernelver");
unless (-d "$rootimg_dir/lib/modules/$kernelver") {
2008-05-24 17:29:40 +00:00
if(-d "/lib/modules/$kernelver") {
2009-09-24 18:51:53 +00:00
system("cd /lib/modules;cp -r $kernelver $rootimg_dir/lib/modules/");
2008-05-24 17:29:40 +00:00
}
else {
xdie("Cannot read /lib/modules/$kernelver");
}
}
}
2009-09-24 18:51:53 +00:00
find(\&isnetdriver, <$rootimg_dir/lib/modules/$kernelver/*>);
2008-05-24 17:29:40 +00:00
foreach (@filestoadd) {
if (ref($_)) {
2008-09-11 22:03:01 +00:00
#print "$_->[0], $_->[1]\n";
2009-10-06 20:21:11 +00:00
my $srcpath = "$rootimg_dir/".$_->[0];
2008-09-11 22:03:01 +00:00
if (-f "$customdir/".$_->[0]) {
$srcpath="$customdir/".$_->[0];
} elsif (-f "$pathtofiles/".$_->[0]) {
2008-05-24 17:29:40 +00:00
$srcpath="$pathtofiles/".$_->[0];
}
copy($srcpath,"/tmp/xcatinitrd.$$/".$_->[1]);
chmod 0755,"/tmp/xcatinitrd.$$/".$_->[1];
} else {
2008-09-11 22:03:01 +00:00
#print "$_\n";
2009-09-24 18:51:53 +00:00
my $srcpath = "$rootimg_dir/$_";
2008-09-11 22:03:01 +00:00
if (-f "$customdir/$_") {
$srcpath = "$customdir/$_";
} elsif (-f "$pathtofiles/$_") {
2008-09-09 23:52:04 +00:00
$srcpath = "$pathtofiles/$_";
2008-05-24 17:29:40 +00:00
}
copy("$srcpath","/tmp/xcatinitrd.$$/$_");
chmod 0755,"/tmp/xcatinitrd.$$/".$_;
}
}
2009-09-24 18:51:53 +00:00
#copy("$rootimg_dir/lib/modules/*d","/tmp/xcatinitrd.$$/$_");
2009-02-12 12:04:51 +00:00
system("cd /tmp/xcatinitrd.$$/bin/; ln -sf bash sh"); #neccessary for SLES11
2009-09-24 18:51:53 +00:00
system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd.gz");
2008-05-24 17:29:40 +00:00
system("rm -rf /tmp/xcatinitrd.$$");
}
sub isyumdir {
if ($File::Find::name =~ /\/repodata$/) {
my $location = $File::Find::name;
$location =~ s/\/repodata$//;
push @yumdirs,$location;
}
}
sub isnetdriver {
foreach (@ndrivers) {
if ($File::Find::name =~ /\/$_/) {
my $filetoadd = $File::Find::name;
2009-09-24 18:51:53 +00:00
$filetoadd =~ s!$rootimg_dir!!;
2008-05-24 17:29:40 +00:00
push @filestoadd,[$filetoadd,"lib/$_"];
}
}
}
sub postscripts { # TODO: customized postscripts
generic_post();
2010-01-26 12:10:16 +00:00
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";
2010-02-11 02:24:48 +00:00
#system("$XCATROOT/share/xcat/netboot/add-on/statelite/add_passwd $rootimg_dir");
#system("$XCATROOT/share/xcat/netboot/add-on/statelite/add_ssh $rootimg_dir");
2010-01-26 12:10:16 +00:00
}
2008-05-24 17:29:40 +00:00
if (-d "$installroot/postscripts/hostkeys") {
for my $key (<$installroot/postscripts/hostkeys/*key>) {
2009-09-24 18:51:53 +00:00
copy ($key,"$rootimg_dir/etc/ssh/");
2008-05-24 17:29:40 +00:00
}
2009-09-24 18:51:53 +00:00
chmod 0600,<$rootimg_dir/etc/ssh/*key>;
2008-05-24 17:29:40 +00:00
}
if (-d "/$installroot/postscripts/.ssh") {
2009-09-24 18:51:53 +00:00
mkpath("$rootimg_dir/root/.ssh");
chmod(0700,"$rootimg_dir/root/.ssh/");
2008-05-24 17:29:40 +00:00
for my $file (</$installroot/postscripts/.ssh/*>) {
2009-09-24 18:51:53 +00:00
copy ($file,"$rootimg_dir/root/.ssh/");
2008-05-24 17:29:40 +00:00
}
2009-09-24 18:51:53 +00:00
chmod(0600,<$rootimg_dir/root/.ssh/*>);
2008-05-24 17:29:40 +00:00
}
}
sub generic_post { #This function is meant to leave the image in a state approximating a normal install
my $cfgfile;
2010-01-26 12:10:16 +00:00
if($mode ne "statelite") {
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);
}
2009-09-24 18:51:53 +00:00
open($cfgfile,">","$rootimg_dir/etc/sysconfig/network");
2008-05-24 17:29:40 +00:00
print $cfgfile "NETWORKING=yes\n";
close($cfgfile);
2009-09-24 18:51:53 +00:00
open($cfgfile,">","$rootimg_dir/etc/resolv.conf");
2008-05-24 17:29:40 +00:00
print $cfgfile "#Dummy resolv.conf to make boot cleaner";
close($cfgfile);
2010-04-06 05:54:54 +00:00
open($cfgfile,">","$rootimg_dir/etc/sysconfig/network/ifcfg-$prinic");
2010-04-06 06:45:36 +00:00
print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$prinic\nSTARTMODE=auto\n";
2008-05-24 17:29:40 +00:00
close($cfgfile);
foreach (split /,/,$othernics) {
if (/^$/) { next; }
2010-04-06 05:54:54 +00:00
open($cfgfile,">","$rootimg_dir/etc/sysconfig/network/ifcfg-$_");
2010-04-06 06:45:36 +00:00
print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$_\nSTARTMODE=auto\n";
2008-05-24 17:29:40 +00:00
close($cfgfile);
}
2009-09-24 18:51:53 +00:00
open($cfgfile,">>","$rootimg_dir/etc/securetty");
2008-05-24 17:29:40 +00:00
print $cfgfile "ttyS0\n";
print $cfgfile "ttyS1\n";
2009-02-16 22:12:03 +00:00
print $cfgfile "console\n";
2008-05-24 17:29:40 +00:00
close($cfgfile);
my @passwd;
2009-09-24 18:51:53 +00:00
open($cfgfile,"<","$rootimg_dir/etc/passwd");
2008-05-24 17:29:40 +00:00
@passwd = <$cfgfile>;
close($cfgfile);
2009-09-24 18:51:53 +00:00
open($cfgfile,">","$rootimg_dir/etc/passwd");
2008-05-24 17:29:40 +00:00
foreach (@passwd) {
if (/^root:/) {
s/^root:\*/root:x/
}
print $cfgfile $_;
}
close($cfgfile);
2009-09-24 18:51:53 +00:00
foreach (<$rootimg_dir/etc/skel/.*>) {
2008-05-24 17:29:40 +00:00
if (basename($_) eq '.' or basename($_) eq '..') {
next;
}
2009-09-24 18:51:53 +00:00
copy $_,"$rootimg_dir/root/";
2008-05-24 17:29:40 +00:00
}
2009-09-24 18:51:53 +00:00
open($cfgfile,">","$rootimg_dir/etc/init.d/gettyset");
2008-05-24 17:29:40 +00:00
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";
2009-09-21 16:00:57 +00:00
print $cfgfile " if [ \"\$KEY\" == \"console\" -a \"\$i\" != \"console=tty0\" ]; then\n";
2008-05-24 17:29:40 +00:00
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";
2009-09-21 15:49:18 +00:00
print $cfgfile " echo xco:2345:respawn:/sbin/agetty \$FLOWFLAG \$COTTY \$COSPEED xterm >> /etc/inittab\n";
2008-05-24 17:29:40 +00:00
print $cfgfile " init q\n";
print $cfgfile " fi\n";
print $cfgfile "done\n";
2008-05-27 21:11:56 +00:00
print $cfgfile "/etc/init.d/boot.localnet start\n";
2010-01-26 12:10:16 +00:00
if($mode eq "statelite") {
print $cfgfile "/opt/xcat/xcatdsklspost 4\n";
} else {
print $cfgfile "/opt/xcat/xcatdsklspost\n";
}
2008-05-24 17:29:40 +00:00
close($cfgfile);
2009-09-24 18:51:53 +00:00
chmod(0755,"$rootimg_dir/etc/init.d/gettyset");
#link("$rootimg_dir/sbin/init","$rootimg_dir/init");
my $rc = system("grep sshd $rootimg_dir/etc/init.d/.depend.start");
2008-05-26 16:11:24 +00:00
if ($rc) {
2009-09-24 18:51:53 +00:00
system("sed -i '".'s/^\(TARGETS = .*\)$/\1 sshd/'."' $rootimg_dir/etc/init.d/.depend.start");
system("ln -s ../sshd $rootimg_dir/etc/init.d/rc3.d/S20sshd");
2008-05-26 16:11:24 +00:00
}
2009-09-24 18:51:53 +00:00
my $rc = system("grep gettyset $rootimg_dir/etc/init.d/.depend.start");
2008-05-26 16:11:24 +00:00
if ($rc) {
2009-09-24 18:51:53 +00:00
system("sed -i '".'s/^\(TARGETS = .*\)$/\1 gettyset/'."' $rootimg_dir/etc/init.d/.depend.start");
system("ln -s ../gettyset $rootimg_dir/etc/init.d/rc3.d/S60gettyset");
2008-05-26 16:11:24 +00:00
}
2009-02-16 22:12:03 +00:00
if(($osver =~ /sles11/) || ($osver =~ /sles10/)) {#for sles11,sles10
2010-04-02 12:05:33 +00:00
copy(<$rootimg_dir/boot/vmlinux-*>,"$destdir/kernel");
2009-02-12 12:04:51 +00:00
}else {
2010-04-02 12:05:33 +00:00
copy(<$rootimg_dir/boot/vmlinuz-*>,"$destdir/kernel");
2009-02-12 12:04:51 +00:00
}
2008-05-24 17:29:40 +00:00
}
2008-09-09 23:52:04 +00:00
2009-10-06 20:21:11 +00:00
2010-03-19 21:12:56 +00:00
sub get_package_names {
my $plist_file_name=shift;
2009-10-06 20:21:11 +00:00
my %pkgnames=();
2009-07-02 20:24:27 +00:00
my @tmp_array=();
2008-09-11 22:03:01 +00:00
2010-03-19 21:12:56 +00:00
if ($plist_file_name) {
2008-09-09 23:52:04 +00:00
my $pkgfile;
2010-03-19 21:12:56 +00:00
open($pkgfile,"<","$plist_file_name");
2008-09-09 23:52:04 +00:00
while (<$pkgfile>) {
chomp;
2009-07-02 20:24:27 +00:00
s/\s+$//; #remove trailing white spaces
2009-05-19 18:56:27 +00:00
next if /^\s*$/; #-- skip empty lines
2009-07-02 20:24:27 +00:00
push(@tmp_array,$_);
2008-09-09 23:52:04 +00:00
}
close($pkgfile);
2009-07-02 20:24:27 +00:00
if ( @tmp_array > 0) {
my $pkgtext=join(',',@tmp_array);
#handle the #INLCUDE# tag recursively
2010-03-19 21:12:56 +00:00
my $idir = dirname($plist_file_name);
2009-07-02 20:24:27 +00:00
my $doneincludes=0;
while (not $doneincludes) {
$doneincludes=1;
if ($pkgtext =~ /#INCLUDE:[^#]+#/) {
$doneincludes=0;
$pkgtext =~ s/#INCLUDE:([^#]+)#/include_file($1,$idir)/eg;
}
}
2010-03-19 21:12:56 +00:00
#print "pkgtext=$pkgtext\n";
2009-07-02 20:24:27 +00:00
my @tmp=split(',', $pkgtext);
2010-03-22 16:14:06 +00:00
my $pass=1;
2009-10-06 20:21:11 +00:00
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/^-//;
2010-03-22 16:14:06 +00:00
} elsif (/^#NEW_INSTALL_LIST#/) {
$pass++;
next;
} elsif (/^#/) {
# ignore all other comment lines
next;
2009-10-06 20:21:11 +00:00
} else {
$idir=dirname($_);
}
2009-07-02 20:24:27 +00:00
my $fn=basename($_);
2010-03-22 16:14:06 +00:00
if (exists($pkgnames{$pass}{$idir})) {
my $pa=$pkgnames{$pass}{$idir};
push(@$pa, $fn);
} else {
$pkgnames{$pass}{$idir}=[$fn];
2009-07-02 20:24:27 +00:00
}
}
}
2008-09-09 23:52:04 +00:00
}
2009-07-02 20:24:27 +00:00
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(<INCLUDE>) {
chomp($_);
s/\s+$//; #remove trailing spaces
next if /^\s*$/; #-- skip empty lines
push(@text, $_);
}
close(INCLUDE);
return join(',', @text);
2008-09-09 23:52:04 +00:00
}
2008-09-11 22:03:01 +00:00
2010-03-19 21:12:56 +00:00
sub get_profile_def_filename {
2008-09-11 22:03:01 +00:00
my $base=shift;
2010-03-19 21:12:56 +00:00
my $ext=shift;
2009-10-13 11:39:37 +00:00
my $dotpos = rindex($osver, ".");
my $osbase = substr($osver, 0, $dotpos);
2010-03-19 21:12:56 +00:00
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";
2008-09-11 22:03:01 +00:00
}
return "";
}
2009-04-23 14:13:56 +00:00