the code change for genimage enhancement is here

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@7491 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
mxi1 2010-09-17 09:54:47 +00:00
parent 5f4315fd34
commit 444bdd0b8e
11 changed files with 1534 additions and 1331 deletions

View File

@ -588,7 +588,7 @@ osimage => {
},
},
linuximage => {
cols => [qw(imagename template pkglist pkgdir otherpkglist otherpkgdir exlist postinstall rootimgdir netdrivers kernelver comments disable)],
cols => [qw(imagename template pkglist pkgdir otherpkglist otherpkgdir exlist postinstall rootimgdir nodebootif otherifce netdrivers kernelver permission comments disable)],
keys => [qw(imagename)],
table_desc => 'Information about a Linux operating system image that can be used to deploy cluster nodes.',
descriptions => {
@ -601,8 +601,11 @@ linuximage => {
exlist => 'The fully qualified name of the file that stores the file names and directory names that will be excluded from the image during packimage command. It is used for diskless image only.',
postinstall => 'The fully qualified name of the script file that will be run at the end of the packimage command. It is used for diskless image only.',
rootimgdir => 'The directory name where the image is stored. It is used for diskless image only.',
nodebootif => 'The network interface the stateless/statelite node will boot over (e.g. eth0)',
otherifce => 'Other network interfaces (e.g. eth1) in the image that should be configured via DHCP',
netdrivers => 'the ethernet device drivers of the nodes which will use this linux image, at least the device driver for the nodes\' installnic should be included',
kernelver => 'the version of linux kernel used in the linux image. If the kernel version is not set, the default kernel in rootimgdir will be used',
permission => 'the mount permission of /.statelite directory is used, its default value is 755',
comments => 'Any user-written notes.',
disable => "Set to 'yes' or '1' to comment out this row.",
},
@ -1816,6 +1819,16 @@ push(@{$defspec{node}->{'attrs'}}, @nodeattrs);
tabentry => 'linuximage.rootimgdir',
access_tabentry => 'linuximage.imagename=attr:imagename',
},
{attr_name => 'nodebootif',
only_if => 'imagetype=linux',
tabentry => 'linuximage.nodebootif',
access_tabentry => 'linuximage.imagename=attr:imagename',
},
{attr_name => 'otherifce',
only_if => 'imagetype=linux',
tabentry => 'linuximage.otherifce',
access_tabentry => 'linuximage.imagename=attr:imagename',
},
{attr_name => 'netdrivers',
only_if => 'imagetype=linux',
tabentry => 'linuximage.netdrivers',
@ -1826,6 +1839,11 @@ push(@{$defspec{node}->{'attrs'}}, @nodeattrs);
tabentry => 'linuximage.kernelver',
access_tabentry => 'linuximage.imagename=attr:imagename',
},
{attr_name => 'permission',
only_if => 'imagetype=linux',
tabentry => 'linuximage.permission',
access_tabentry => 'linuximage.imagename=attr:imagename',
},
####################
# nimimage table#
####################

View File

@ -217,7 +217,11 @@ sub mknetboot
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 $mactab = xCAT::Table->new('mac');
my $machash = $mactab->getNodesAttribs(\@nodes, ['interface','mac']);
my $reshash = $restab->getNodesAttribs(\@nodes, ['primarynic','tftpserver','xcatmaster','nfsserver','nfsdir', 'installnic']);
my $hmhash =
$hmtab->getNodesAttribs(\@nodes,
['serialport', 'serialspeed', 'serialflow']);
@ -234,53 +238,60 @@ sub mknetboot
my $osver;
my $arch;
my $profile;
my $platform;
my $platform;
my $rootimgdir;
my $nodebootif; # nodebootif will be used if noderes.installnic is not set
my $installnic; # the noderes.installnic value
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};
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', 'nodebootif');
if (($ref1) && ($ref1->{'rootimgdir'})) {
$img_hash{$imagename}->{rootimgdir}=$ref1->{'rootimgdir'};
}
if (($ref1) && ($ref1->{'nodebootif'})) {
$img_hash{$imagename}->{nodebootif} = $ref1->{'nodebootif'};
}
} 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";
$rootimgdir=$ph->{rootimgdir};
unless ($rootimgdir) {
$rootimgdir="$installroot/netboot/$osver/$arch/$profile";
}
$nodebootif = $ph->{nodebootif};
}
}
else {
$osver = $ent->{os};
$arch = $ent->{arch};
$profile = $ent->{profile};
$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)
@ -296,39 +307,30 @@ sub mknetboot
$platform=xCAT_plugin::anaconda::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;
$suffix = 'sfs' if (-r "$rootimgdir/rootimg.sfs");
# statelite images are not packed.
if ($statelite) {
unless ( -r "$rootimgdir/kernel" and -r "$rootimgdir/initrd-statelite.gz" ) {
$callback->({
error=>[qq{Did you run "genimage" before running "liteimg"? kernel or initial ramdisk cannot be found...}],
errorcode=>[1]
});
next;
}
} else {
unless ( -r "$rootimgdir/kernel" and -r "$rootimgdir/initrd-stateless.gz" ) {
$callback->({
error => [qq{Did you run "genimage" before running "packimage"? kernel or initial ramdisk cannot be found...}],
errorcode => [1]
});
next;
}
unless ( -r "$rootimgdir/rootimg.gz" or -r "$rootimgdir/rootimg.sfs" ) {
$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
@ -339,30 +341,40 @@ sub mknetboot
#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/");
if (-f "$rootimgdir/hypervisor") {
copy("$rootimgdir/hypervisor", "/$tftpdir/xcat/netboot/$osver/$arch/$profile/");
$xenstyle=1;
}
copy("$rootimgdir/kernel", "/$tftpdir/xcat/netboot/$osver/$arch/$profile/");
if ($statelite) {
copy("$rootimgdir/initrd-statelite.gz", "/$tftpdir/xcat/netboot/$osver/$arch/$profile/");
} else {
copy("$rootimgdir/initrd-stateless.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;
if ($statelite) {
unless ( -r "/$tftpdir/xcat/netboot/$osver/$arch/$profile/kernel"
and -r "/$tftpdir/xcat/netboot/$osver/$arch/$profile/initrd-statelite.gz") {
$callback->({
error=>[qq{copying to /$tftpdir/xcat/netboot/$osver/$arch/$profile failed}],
errorcode=>[1]
});
next;
}
} else {
unless ( -r "/$tftpdir/xcat/netboot/$osver/$arch/$profile/kernel"
and -r "/$tftpdir/xcat/netboot/$osver/$arch/$profile/initrd-stateless.gz") {
$callback->({
error=>[qq{copying to /$tftpdir/xcat/netboot/$osver/$arch/$profile failed}],
errorcode=>[1]
});
next;
}
}
$ent = $reshash->{$node}->[0];#$restab->getNodeAttribs($node, ['primarynic']);
my $sent = $hmhash->{$node}->[0];
# $hmtab->getNodeAttribs($node,
@ -421,86 +433,130 @@ sub mknetboot
);
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";
my $kcmdline; # add two more arguments: XCAT=xcatmaster:xcatport and ifname=<eth0>:<mac address>
if($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!^/!!;
}
}
if($ient->{nfsdir} =~ m!^//!) {
$nfsdir = $ient->{nfsdir};
$nfsdir =~ s!^/!!;
}
}
# special case for redhat6, fedora12/13
if ($osver =~ m/rhel6/ || $osver =~ m/rhels6/
|| $osver =~ m/fedora12/ || $osver =~ m/fedora13/ ) {
$kcmdline = "root=nfs:$nfssrv:$nfsdir/rootimg:ro STATEMNT=";
} else {
$kcmdline = "NFSROOT=$nfssrv:$nfsdir STATEMNT=";
}
# special case for redhat6, fedora12/13
if ($osver =~ m/rhel6/ || $osver =~ m/rhels6/
|| $osver =~ m/fedora12/ || $osver =~ m/fedora13/ ) {
$kcmdline = "root=nfs:$nfssrv:$nfsdir/rootimg:ro STATEMNT=";
} else {
$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);
# 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 server is blank, then its the directory
unless($dir) {
$dir = $server;
$server = '';
}
if(grep /\$|#CMD/, $dir) {
$dir = xCAT::SvrUtils->subVars($dir, $node, 'dir', $callback);
$dir = ~ s/\/\//\//g;
}
if($server) {
$server = xCAT::SvrUtils->subVars($server, $node, 'server', $callback);
}
$statemnt = $server . ":" . $dir;
}
if(grep /\$|#CMD/, $dir) {
$dir = xCAT::SvrUtils->subVars($dir, $node, 'dir', $callback);
$dir = ~ s/\/\//\//g;
}
$kcmdline .= $statemnt ." ";
$kcmdline .=
"XCAT=$xcatmaster:$xcatdport ";
# BEGIN service node
my $isSV = xCAT::Utils->isServiceNode();
my $res = xCAT::Utils->runcmd("hostname", 0);
my $sip = xCAT::NetworkUtils->getipaddr($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
xCAT::SvrUtils->setupNFSTree($node, $sip, $callback);
# then, export the statemnt directory if it is on the service node
if($statemnt) {
xCAT::SvrUtils->setupStatemnt($sip, $statemnt, $callback);
}
if($server) {
$server = xCAT::SvrUtils->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 = xCAT::NetworkUtils->getipaddr($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
xCAT::SvrUtils->setupNFSTree($node, $sip, $callback);
# then, export the statemnt directory if it is on the service node
if($statemnt) {
xCAT::SvrUtils->setupStatemnt($sip, $statemnt, $callback);
}
}
# END service node
}
else
{
# END service node
}
else {
$kcmdline =
"imgurl=http://$imgsrv/install/netboot/$osver/$arch/$profile/rootimg.$suffix ";
$kcmdline .= "XCAT=$xcatmaster:$xcatdport ";
}
# add one parameter: ifname=<eth0>:<mac address>
# which is used for dracut
# the redhat5.x os will ignore it
$kcmdline .= "ifname=";
if ($reshash->{$node}->[0] and $reshash->{$node}->[0]->{installnic}) {
if ($reshash->{$node}->[0]->{installnic} ne "mac") {
$kcmdline .= $reshash->{$node}->[0]->{installnic} . ":";
}
} elsif ($nodebootif) {
$kcmdline .= "$nodebootif:";
} elsif ($reshash->{$node}->[0] and $reshash->{$node}->[0]->{primarynic}) {
$kcmdline .= "$primarynic:";
}
else {
$kcmdline .="eth0:";
print "eth0 is used as the default booting network devices...\n";
}
# append the mac address
my $mac;
if($machash->{$node}->[0] && $machash->{$node}->[0]->{'mac'}) {
# TODO: currently, only "mac" attribute with classic style is used, the "|" delimited string of "macaddress!hostname" format is not used
$mac = $machash->{$node}->[0]->{'mac'};
if ( (index($mac, "|") eq -1) and (index($mac, "!") eq -1) ) {
$kcmdline .= "$mac";
} else {
print qq{In the "mac" table, the "|" delimited string of "macaddress!hostname" format is not supported by "nodeset <nr> netboot|statelite".};
}
} else { # it should never happen
$callback->({error=>["cannot find the mac address for $node in mac table"], errorcode=>[1]});
}
$kcmdline .= " ";
# add "netdev=<eth0>" or "BOOTIF=<mac>"
my $netdev = "";
if ($reshash->{$node}->[0] and $reshash->{$node}->[0]->{installnic}) {
if ($reshash->{$node}->[0]->{installnic} ne "mac") {
$kcmdline .= "netdev=" . $reshash->{$node}->[0]->{installnic} . " ";
}
} elsif ($nodebootif) {
$kcmdline .= "netdev=" . $nodebootif . " ";
} elsif ( $reshash->{$node}->[0] and $reshash->{$node}->[0]->{primarynic}) {
$kcmdline .= "netdev=" . $reshash->{$node}->[0]->{primarynic} . " ";
} else {
if ($mac) {
$kcmdline .= "BOOTIF=" . $mac . " ";
}
}
if (defined $sent->{serialport})
{
@ -540,18 +596,20 @@ sub mknetboot
#}
my $kernstr="xcat/netboot/$osver/$arch/$profile/kernel";
if ($xenstyle) {
$kernstr.= "!xcat/netboot/$osver/$arch/$profile/hypervisor";
}
my $kernstr="xcat/netboot/$osver/$arch/$profile/kernel";
if ($xenstyle) {
$kernstr.= "!xcat/netboot/$osver/$arch/$profile/hypervisor";
}
my $initrdstr = "xcat/netboot/$osver/$arch/$profile/initrd-stateless.gz";
$initrdstr = "xcat/netboot/$osver/$arch/$profile/initrd-statelite.gz" if ($statelite);
$bptab->setNodeAttribs(
$node,
{
kernel => "$kernstr",
initrd => "xcat/netboot/$osver/$arch/$profile/initrd.gz",
kcmdline => $kcmdline
}
);
$node,
{
kernel => $kernstr,
initrd => $initrdstr,
kcmdline => $kcmdline
}
);
}
#my $rc = xCAT::Utils->create_postscripts_tar();

View File

@ -367,11 +367,9 @@ sub mergeArrays {
}
}elsif($type =~ /file|image/){
foreach(@$arr){
if($_->{file} eq ''){ next; }
next if($_->{file} eq '');
my $o = $_->{options};
if(!$o){
$o = "tmpfs,rw";
}
$o = "bind" unless ($o);
# TODO: put some logic in here to make sure that ro is alone.
# if type is ro and con, then this is wrong silly!
#if($p eq "ro" and $t eq "con"){

View File

@ -4,6 +4,7 @@ BEGIN
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use Data::Dumper;
use xCAT::Table;
use Getopt::Long;
use File::Path;
@ -17,6 +18,10 @@ use xCAT::SvrUtils;
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("pass_through");
my $verbose = 0;
#$verbose = 1;
sub handled_commands {
return {
packimage => "packimage",
@ -66,36 +71,36 @@ sub process_request {
if (@ARGV > 0) {
$imagename=$ARGV[0];
if ($arch or $osver or $profile) {
$callback->({error=>["-o, -p and -a options are not allowed when a image name is specified."],errorcode=>[1]});
return;
$callback->({error=>["-o, -p and -a options are not allowed when a image name is specified."],errorcode=>[1]});
return;
}
#load the module in memory
# load the module in memory
eval {require("$::XCATROOT/lib/perl/xCAT/Table.pm")};
if ($@) {
$callback->({error=>[$@],errorcode=>[1]});
return;
$callback->({error=>[$@],errorcode=>[1]});
return;
}
#get the info from the osimage and linux
# get the info from the osimage and linux
my $osimagetab=xCAT::Table->new('osimage', -create=>1);
if (!$osimagetab) {
$callback->({error=>["The osimage table cannot be opened."],errorcode=>[1]});
return;
unless ($osimagetab) {
$callback->({error=>["The osimage table cannot be opened."],errorcode=>[1]});
return;
}
my $linuximagetab=xCAT::Table->new('linuximage', -create=>1);
if (!$linuximagetab) {
$callback->({error=>["The linuximage table cannot be opened."],errorcode=>[1]});
return;
unless ($linuximagetab) {
$callback->({error=>["The linuximage table cannot be opened."],errorcode=>[1]});
return;
}
(my $ref) = $osimagetab->getAttribs({imagename => $imagename}, 'osvers', 'osarch', 'profile', 'provmethod', 'synclists');
if (!$ref) {
$callback->({error=>["Cannot find image \'$imagename\' from the osimage table."],errorcode=>[1]});
return;
unless ($ref) {
$callback->({error=>["Cannot find image \'$imagename\' from the osimage table."],errorcode=>[1]});
return;
}
(my $ref1) = $linuximagetab->getAttribs({imagename => $imagename}, 'exlist', 'rootimgdir');
if (!$ref1) {
$callback->({error=>["Cannot find $imagename from the linuximage table."],errorcode=>[1]});
return;
unless ($ref1) {
$callback->({error=>["Cannot find $imagename from the linuximage table."],errorcode=>[1]});
return;
}
$osver=$ref->{'osvers'};
@ -105,21 +110,20 @@ sub process_request {
my $provmethod=$ref->{'provmethod'};
unless ($osver and $arch and $profile and $provmethod) {
$callback->({error=>["osimage.osvers, osimage.osarch, osimage.profile and osimage.provmethod must be specified for the image $imagename in the database."],errorcode=>[1]});
return;
$callback->({error=>["osimage.osvers, osimage.osarch, osimage.profile and osimage.provmethod must be specified for the image $imagename in the database."],errorcode=>[1]});
return;
}
if ($provmethod ne 'netboot') {
$callback->({error=>["\'$imagename\' cannot be used to build diskless image. Make sure osimage.provmethod is 'netboot'."],errorcode=>[1]});
return;
$callback->({error=>["\'$imagename\' cannot be used to build diskless image. Make sure osimage.provmethod is 'netboot'."],errorcode=>[1]});
return;
}
$exlistloc =$ref1->{'exlist'};
$destdir=$ref1->{'rootimgdir'};
}
if (!$destdir)
{
unless ($destdir) {
$destdir="$installroot/netboot/$osver/$arch/$profile";
}
$rootimg_dir="$destdir/rootimg";
@ -137,71 +141,137 @@ sub process_request {
return;
}
my $oldpath=cwd();
if (!$imagename) {
unless ($imagename) {
$exlistloc=xCAT::SvrUtils->get_exlist_file_name("$installroot/custom/netboot/$distname", $profile, $osver, $arch);
if (!$exlistloc) { $exlistloc=xCAT::SvrUtils->get_exlist_file_name("$::XCATROOT/share/xcat/netboot/$distname", $profile, $osver, $arch); }
unless ($exlistloc) { $exlistloc=xCAT::SvrUtils->get_exlist_file_name("$::XCATROOT/share/xcat/netboot/$distname", $profile, $osver, $arch); }
}
#if (!$exlistloc)
#{
# $callback->({data=>["WARNING: Unable to find file exclusion list under $installroot/custom/netboot/$distname or $::XCATROOT/share/xcat/netboot/$distname/ for $profile/$arch/$osver\n"]});
#}
# before generating rootimg.gz or rootimg.sfs, need to switch the rootimg to stateless mode if necessary
my $rootimg_status = 0; # 0 means stateless mode, while 1 means statelite mode
$rootimg_status = 1 if (-f "$rootimg_dir/.statelite/litefile.save");
my $ref_liteList; # get the litefile entries
my @ret = xCAT::SvrUtils->update_tables_with_diskless_image($osver, $arch, $profile, "statelite");
unless ($ret[0] eq 0) {
$callback->({error=>["Error when updating the osimage tables: " . $ret[1]], errorcode=>[1]});
return;
}
my @ret = xCAT::Utils->runcmd("ilitefile $osver-$arch-statelite-$profile" , 0, 1);
$ref_liteList = $ret[0];
my %liteHash; # create hash table for the entries in @listList
if (parseLiteFiles($ref_liteList, \%liteHash)) {
$callback->({error=>["Failed for parsing litefile table!"], errorcode=>[1]});
return;
}
$verbose && $callback->({data=>["rootimg_status = $rootimg_status at line " . __LINE__ ]});
if($rootimg_status) {
xCAT::Utils->runcmd("mkdir $rootimg_dir/.statebackup", 0, 1);
# read through the litefile table to decide which file/directory should be restore
my $defaultloc = "$rootimg_dir/.default";
foreach my $entry (keys %liteHash) {
my @tmp = split /\s+/, $entry;
my $filename = $tmp[1];
my $fileopt = $tmp[0];
if ($fileopt eq "tmpfs,rw" or $fileopt eq "ro") {
# backup them into .statebackup dirctory
# restore the files with "tmpfs" options
if ($filename =~ m/\/$/) {
chop $filename;
}
# create the parent directory if $filename's directory is not there,
my $parent = dirname $filename;
unless ( -d "$rootimg_dir/.statebackup$parent" ) {
unlink "$rootimg_dir/.statebackup$parent";
$verbose && $callback->({data=>["mkdir -p $rootimg_dir/.statebackup$parent"]});
xCAT::Utils->runcmd("mkdir -p $rootimg_dir/.statebackup$parent", 0, 1);
}
$verbose && $callback->({data=>["backing up the file $filename.. at line " . __LINE__ ]});
$verbose && print "++ $defaultloc$filename ++ $rootimg_dir$filename ++ at " . __LINE__ . "\n";
xCAT::Utils->runcmd("mv $rootimg_dir$filename $rootimg_dir/.statebackup$filename", 0, 1);
xCAT::Utils->runcmd("cp -r -a $defaultloc$filename $rootimg_dir$filename", 0, 1);
}
}
}
# TODO: following the old genimage code, to update the stateles-only files/directories
# another file should be /opt/xcat/xcatdsklspost, but it seems not necessary
xCAT::Utils->runcmd("mv $rootimg_dir/etc/init.d/statelite $rootimg_dir/.statebackup/statelite ", 0, 1) if ( -e "$rootimg_dir/etc/init.d/statelite");
if ( -e "$rootimg_dir/usr/share/dracut" ) {
# currently only used for redhat families, not available for SuSE families
if ( -e "$rootimg_dir/etc/rc.sysinit.backup" ) {
xCAT::Utils->runcmd("mv $rootimg_dir/etc/rc.sysinit.backup $rootimg_dir/etc/rc.sysinit", 0, 1);
}
}
my $excludestr = "find . ";
my $includestr;
if ($exlistloc) {
my $exlist;
my $excludetext;
my $excludetext;
open($exlist,"<",$exlistloc);
system("echo -n > /tmp/xcat_packimg.txt");
while (<$exlist>) {
$excludetext .= $_;
}
$excludetext .= $_;
}
close($exlist);
#handle the #INLCUDE# tag recursively
my $idir = dirname($exlistloc);
my $doneincludes=0;
while (not $doneincludes) {
$doneincludes=1;
if ($excludetext =~ /#INCLUDE:[^#^\n]+#/) {
$doneincludes=0;
$excludetext =~ s/#INCLUDE:([^#^\n]+)#/include_file($1,$idir)/eg;
while (not $doneincludes) {
$doneincludes=1;
if ($excludetext =~ /#INCLUDE:[^#^\n]+#/) {
$doneincludes=0;
$excludetext =~ s/#INCLUDE:([^#^\n]+)#/include_file($1,$idir)/eg;
}
}
}
my @tmp=split("\n", $excludetext);
foreach (@tmp) {
chomp $_;
my @tmp=split("\n", $excludetext);
foreach (@tmp) {
chomp $_;
s/\s*#.*//; #-- remove comments
next if /^\s*$/; #-- skip empty lines
if (/^\+/) {
s/^\+//; #remove '+'
$includestr .= "-path '". $_ ."' -o ";
s/^\+//; #remove '+'
$includestr .= "-path '". $_ ."' -o ";
} else {
s/^\-//; #remove '-' if any
$excludestr .= "'!' -path '".$_."' -a ";
}
s/^\-//; #remove '-' if any
$excludestr .= "'!' -path '".$_."' -a ";
}
}
}
# the files specified for statelite should be excluded
my @excludeStatelite = ("./etc/init.d/statelite", "./etc/rc.sysinit.backup", "./.statelite*", "./.default*", "./.statebackup*");
foreach my $entry (@excludeStatelite) {
$excludestr .= "'!' -path '" . $entry . "' -a ";
}
$excludestr =~ s/-a $//;
if ($includestr) {
$includestr =~ s/-o $//;
$includestr = "find . " . $includestr;
}
# print "\nexcludestr=$excludestr\n\n includestr=$includestr\n\n";
print "\nexcludestr=$excludestr\n\n includestr=$includestr\n\n"; # debug
# add the xCAT post scripts to the image
if (! -d "$rootimg_dir") {
$callback->({error=>["$rootimg_dir does not exist, run genimage -o $osver -p $profile on a server with matching architecture"]});
unless ( -d "$rootimg_dir") {
$callback->({error=>["$rootimg_dir does not exist, run genimage -o $osver -p $profile on a server with matching architecture"], errorcode=>[1]});
return;
}
#some rpms like atftp mount the rootimg/proc to /proc, we need to make sure rootimg/proc is free of junk
#before packaging the image
`umount $rootimg_dir/proc`;
copybootscript($installroot, $rootimg_dir, $osver, $arch, $profile, $callback);
# some rpms like atftp mount the rootimg/proc to /proc, we need to make sure rootimg/proc is free of junk
# before packaging the image
system("umount $rootimg_dir/proc");
copybootscript($installroot, $rootimg_dir, $osver, $arch, $profile, $callback);
my $passtab = xCAT::Table->new('passwd');
if ($passtab) {
(my $pent) = $passtab->getAttribs({key=>'system',username=>'root'},'password');
@ -228,41 +298,35 @@ sub process_request {
}
# sync fils configured in the synclist to the rootimage
if (!$imagename) {
unless ($imagename) {
$syncfile = xCAT::SvrUtils->getsynclistfile(undef, $osver, $arch, $profile, "netboot");
if (defined ($syncfile) && -f $syncfile
&& -d $rootimg_dir) {
print "sync files from $syncfile to the $rootimg_dir\n";
`$::XCATROOT/bin/xdcp -i $rootimg_dir -F $syncfile`;
&& -d $rootimg_dir) {
print "sync files from $syncfile to the $rootimg_dir\n";
system("$::XCATROOT/bin/xdcp -i $rootimg_dir -F $syncfile");
}
}
my $verb = "Packing";
if ($method =~ /nfs/) {
$verb = "Prepping";
}
if ($method =~ /nfs/) {
$callback->({data=>["\nNOTE: Contents of $rootimg_dir\nMUST be available on all service and management nodes and NFS exported."]});
}
my $temppath;
my $oldumask;
if (! -d $rootimg_dir) {
unless ( -d $rootimg_dir) {
$callback->({error=>["$rootimg_dir does not exist, run genimage -o $osver -p $profile on a server with matching architecture"]});
return;
}
$callback->({data=>["$verb contents of $rootimg_dir"]});
unlink("$destdir/rootimg.gz");
unlink("$destdir/rootimg.sfs");
unlink("$destdir/rootimg.nfs");
if ($method =~ /cpio/) {
if (!$exlistloc) {
if ( ! $exlistloc ) {
$excludestr = "find . |cpio -H newc -o | gzip -c - > ../rootimg.gz";
}else {
chdir("$rootimg_dir");
system("$excludestr >> /tmp/xcat_packimg.txt");
if ($includestr) {
system("$includestr >> /tmp/xcat_packimg.txt");
}
chdir("$rootimg_dir");
system("$excludestr >> /tmp/xcat_packimg.txt");
if ($includestr) {
system("$includestr >> /tmp/xcat_packimg.txt");
}
#$excludestr =~ s!-a \z!|cpio -H newc -o | gzip -c - > ../rootimg.gz!;
$excludestr = "cat /tmp/xcat_packimg.txt|cpio -H newc -o | gzip -c - > ../rootimg.gz";
}
@ -276,13 +340,11 @@ sub process_request {
system("$includestr >> /tmp/xcat_packimg.txt");
}
$excludestr = "cat /tmp/xcat_packimg.txt|cpio -dump $temppath";
} elsif ($method =~ /nfs/) {
$excludestr = "touch ../rootimg.nfs";
} else {
$callback->({error=>["Invalid method '$method' requested"],errorcode=>[1]});
}
chdir("$rootimg_dir");
system($excludestr);
`$excludestr`;
if ($method =~ /cpio/) {
chmod 0644,"$destdir/rootimg.gz";
umask $oldmask;
@ -309,13 +371,25 @@ sub process_request {
}
chmod(0644,"../rootimg.sfs");
}
# move the files in /.statebackup back to rootimg_dir
if ($rootimg_status) { # statelite mode
foreach my $entry (keys %liteHash) {
my @tmp = split /\s+/, $entry;
my $filename = $tmp[1];
my $fileopt = $tmp[0];
if ($fileopt eq "tmpfs,rw" or $fileopt eq "ro") {
chop $filename if ($filename =~ m/\/$/);
xCAT::Utils->runcmd("rm -rf $rootimg_dir$filename", 0, 1);
xCAT::Utils->runcmd("mv $rootimg_dir/.statebackup$filename $rootimg_dir$filename", 0, 1);
}
}
xCAT::Utils->runcmd("mv $rootimg_dir/.statebackup/statelite $rootimg_dir/etc/init.d/statelite", 0, 1);
xCAT::Utils->runcmd("rm -rf $rootimg_dir/.statebackup", 0, 1);
}
chdir($oldpath);
if (!$imagename) {
my @ret=xCAT::SvrUtils->update_tables_with_diskless_image($osver, $arch, $profile);
if ($ret[0] != 0) {
$callback->({error=>["Error when updating the osimage tables: " . $ret[1]]});
}
}
}
###########################################################
@ -411,3 +485,86 @@ sub include_file
return join("\n", @text);
}
=head3 parseLiteFiles
In the liteentry table, one directory and its sub-items (including sub-directory and entries) can co-exist;
In order to handle such a scenario, one hash is generated to show the hirarachy relationship
For example, one array with entry names is used as the input:
my @entries = (
"imagename bind,persistent /var/",
"imagename bind /var/tmp/",
"imagename tmpfs,rw /root/",
"imagename tmpfs,rw /root/.bashrc",
"imagename tmpfs,rw /root/test/",
"imagename bind /etc/resolv.conf",
"imagename bind /var/run/"
);
Then, one hash will generated as:
%hashentries = {
'bind,persistent /var/' => [
'bind /var/tmp/',
'bind /var/run/'
],
'bind /etc/resolv.conf' => undef,
'tmpfs,rw /root/' => [
'tmpfs,rw /root/.bashrc',
'tmpfs,rw /root/test/'
]
};
Arguments:
one array with entrynames,
one hash to hold the entries parsed
Returns:
0 if sucucess
1 if fail
=cut
sub parseLiteFiles {
my ($flref, $dhref) = @_;
my @entries = @{$flref};
foreach (@entries) {
my $entry = $_;
my @str = split /\s+/, $entry;
shift @str;
$entry = join "\t", @str;
my $file = $str[1];
chop $file if ($file =~ m{/$});
unless (exists $dhref->{"$entry"}) {
my $parent = dirname($file);
# to see whether $parent exists in @entries or not
unless ($parent =~ m/\/$/) {
$parent .= "/";
}
my @res = grep {$_ =~ m/\Q$parent\E$/} @entries;
my $found = scalar @res;
if($found eq 1) { # $parent is found in @entries
# handle $res[0];
my @tmpresentry=split /\s+/, $res[0];
shift @tmpresentry;
$res[0] = join "\t", @tmpresentry;
chop $parent;
my @keys = keys %{$dhref};
my $kfound = grep {$_ =~ m/\Q$res[0]\E$/} @keys;
if($kfound eq 0) {
$dhref->{$res[0]} = [];
}
push @{$dhref->{"$res[0]"}}, $entry;
}else {
$dhref->{"$entry"} = ();
}
}
}
return 0;
}
1;

View File

@ -83,7 +83,15 @@ sub mknetboot
$statetab = xCAT::Table->new('statelite', -create=>1);
$stateHash = $statetab->getNodesAttribs(\@nodes, ['statemnt']);
}
# TODO: following the redhat change, get the necessary attributes before the next foreach
# get the mac addresses for all the nodes
my $mactab = xCAT::Table->new('mac');
my $machash = $mactab->getNodesAttribs(\@nodes, ['interface', 'mac']);
my $restab = xCAT::Table->new('noderes');
my $reshash = $restab->getNodesAttribs(\@nodes, ['primarynic', 'tftpserver', 'xcatmaster', 'nfsserver', 'nfsdir', 'installdir']);
my %donetftp=();
foreach my $node (@nodes)
{
@ -91,6 +99,8 @@ sub mknetboot
my $arch;
my $profile;
my $rootimgdir;
my $nodebootif; # nodebootif will be used if noderes.installnic is not set
my $installnic; # the noderes.installnic value
my $ent= $ntents->{$node}->[0];
if ($ent and $ent->{provmethod} and ($ent->{provmethod} ne 'install') and ($ent->{provmethod} ne 'netboot') and ($ent->{provmethod} ne 'statelite')) {
@ -109,10 +119,13 @@ sub mknetboot
if (!$linuximagetab) {
$linuximagetab=xCAT::Table->new('linuximage', -create=>1);
}
(my $ref1) = $linuximagetab->getAttribs({imagename => $imagename}, 'rootimgdir');
(my $ref1) = $linuximagetab->getAttribs({imagename => $imagename}, 'rootimgdir', 'nodebootif');
if (($ref1) && ($ref1->{'rootimgdir'})) {
$img_hash{$imagename}->{rootimgdir}=$ref1->{'rootimgdir'};
}
if (($ref1) && ($ref1->{'nodebootif'})) {
$img_hash{$imagename}->{nodebootif} = $ref1->{'nodebootif'};
}
} else {
$callback->(
{error => ["The os image $imagename does not exists on the osimage table for $node"],
@ -125,9 +138,9 @@ sub mknetboot
$arch = $ph->{osarch};
$profile = $ph->{profile};
$rootimgdir=$ph->{rootimgdir};
if (!$rootimgdir) {
$rootimgdir="$installroot/netboot/$osver/$arch/$profile";
$rootimgdir = $ph->{rootimgdir};
unless ($rootimgdir) {
$rootimgdir = "$installroot/netboot/$osver/$arch/$profile";
}
}
else {
@ -153,7 +166,7 @@ sub mknetboot
if ($osver =~ /sles.*/)
{
$platform = "sles";
#TODO: should get the $pkgdir value from the linuximage table
# TODO: should get the $pkgdir value from the linuximage table
$pkgdir = "$installroot/$osver/$arch";
}elsif($osver =~ /suse.*/){
$platform = "sles";
@ -164,65 +177,72 @@ sub mknetboot
{
$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) {
# TODO: maybe the $osver-$arch-statelite-$profile record doesn't exist in osimage, but it the statelite rootimg can exist
$callback->({error=> ["$node: statelite image $osver-$arch-statelite-$profile doesn't exist; or kernel/initrd.gz doesn't 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]
}
);
if ($statelite) {
unless ( -r "$rootimgdir/kernel" and -r "$rootimgdir/initrd-statelite.gz") {
$callback->({
error=>[qq{Did you run "genimage" before running "liteimg"? kernel or initrd-statelite.gz cannot be found}],
errorcode => [1]
});
next;
}
} else {
unless ( -r "$rootimgdir/kernel" and -r "$rootimgdir/initrd-stateless.gz" ) {
$callback->({
error=>[qq{Did you run "genimage" before running "packimage"? kernel or initrd-stateless.gz cannot be found}],
errorcode=>[1]
});
next;
}
unless ( -r "$rootimgdir/rootimg.gz" or -r "$rootimgdir/rootimg.sfs" ) {
$callback->({
error=>[qq{No packed image for platform $osver, architecture $arch, and profile $profile, please run packimage before nodeset}],
errorcode=>[1]
});
next;
}
next;
}
mkpath("/$tftpdir/xcat/netboot/$osver/$arch/$profile/");
#TODO: only copy if newer...
unless ($donetftp{$osver,$arch,$profile}) {
copy("$rootimgdir/kernel",
"/$tftpdir/xcat/netboot/$osver/$arch/$profile/");
copy("$rootimgdir/initrd.gz",
"/$tftpdir/xcat/netboot/$osver/$arch/$profile/");
copy("$rootimgdir/kernel", "/$tftpdir/xcat/netboot/$osver/$arch/$profile/");
if ($statelite) {
copy("$rootimgdir/initrd-statelite.gz", "/$tftpdir/xcat/netboot/$osver/$arch/$profile/");
} else {
copy("$rootimgdir/initrd-stateless.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;
if ($statelite) {
unless ( -r "/$tftpdir/xcat/netboot/$osver/$arch/$profile/kernel"
and -r "/$tftpdir/xcat/netboot/$osver/$arch/$profile/initrd-statelite.gz") {
$callback->({
error=>[qq{copying to /$tftpdir/xcat/netboot/$osver/$arch/$profile failed}],
errorcode=>[1]
});
next;
}
} else {
unless ( -r "/$tftpdir/xcat/netboot/$osver/$arch/$profile/kernel"
and -r "/$tftpdir/xcat/netboot/$osver/$arch/$profile/initrd-stateless.gz") {
$callback->({
error=>[qq{copying to /$tftpdir/xcat/netboot/$osver/$arch/$profile failed}],
errorcode=>[1]
});
next;
}
}
# TODO: move the table operations out of the foreach loop
my $restab = xCAT::Table->new('noderes');
my $bptab = xCAT::Table->new('bootparams',-create=>1);
my $hmtab = xCAT::Table->new('nodehm');
$ent = $restab->getNodeAttribs($node, ['primarynic']);
$ent = $restab->getNodeAttribs($node, ['primarynic', 'installnic']);
my $sent =
$hmtab->getNodeAttribs($node,
['serialport', 'serialspeed', 'serialflow']);
@ -281,12 +301,7 @@ sub mknetboot
next;
}
my $kcmdline;
if ($suffix eq "nfs")
{
$kcmdline =
"imgurl=nfs://$imgsrv/install/netboot/$osver/$arch/$profile/rootimg ";
}
elsif ($statelite)
if ($statelite)
{
# get entry for nfs root if it exists;
# have to get nfssvr, nfsdir and xcatmaster from noderes table
@ -329,9 +344,6 @@ sub mknetboot
$kcmdline .= $statemnt . " ";
# get "xcatmaster" value from the "noderes" table
$kcmdline .=
"XCAT=$xcatmaster:$xcatdport ";
#BEGIN service node
my $isSV = xCAT::Utils->isServiceNode();
my $res = xCAT::Utils->runcmd("hostname", 0);
@ -352,6 +364,32 @@ sub mknetboot
$kcmdline =
"imgurl=http://$imgsrv/install/netboot/$osver/$arch/$profile/rootimg.$suffix ";
}
$kcmdline .= "XCAT=$xcatmaster:$xcatdport ";
# add the kernel-booting parameter: netdev=<eth0>, or BOOTIF=<mac>
my $netdev = "";
my $mac = $machash->{$node}->[0]->{mac};
if ($reshash->{$node}->[0] and $reshash->{$node}->[0]->{installnic}) {
if ($reshash->{$node}->[0]->{installnic} ne "mac") {
$kcmdline .= "netdev=" . $reshash->{$node}->[0]->{installnic} . " ";
}
} elsif ($nodebootif) {
$kcmdline .= "netdev=" . $nodebootif . " ";
} elsif ($reshash->{$node}->[0] and $reshash->{$node}->[0]->{primarynic}) {
$kcmdline .= "netdev=" . $reshash->{$node}->[0]->{primarynic} . " ";
} else {
if ($mac) {
$kcmdline .= "BOOTIF=" . $mac . " ";
} else {
$callback->({
error=>[qq{"cannot get the mac address for $node in mac table"}],
errorcode=>[1]
});
}
}
if (defined $sent->{serialport})
{
@ -375,11 +413,14 @@ sub mknetboot
$kcmdline .= "n8r";
}
}
my $initrdstr = "xcat/netboot/$osver/$arch/$profile/initrd-stateless.gz";
$initrdstr = "xcat/netboot/$osver/$arch/$profile/initrd-statelite.gz" if ($statelite);
$bptab->setNodeAttribs(
$node,
{
kernel => "xcat/netboot/$osver/$arch/$profile/kernel",
initrd => "xcat/netboot/$osver/$arch/$profile/initrd.gz",
initrd => $initrdstr,
kcmdline => $kcmdline
}
);

View File

@ -222,19 +222,23 @@ sub process_request {
foreach my $entry (keys %hashNew) {
my @tmp = split (/\s+/, $entry);
if ($hashNew{$entry}) {
if ( $tmp[0] eq "ro" or $tmp[0] eq "con") {
$callback->({error=>[qq{the parent directory should not be with "ro" or "con" as its option}], errorcode=>[1]});
return;
}
foreach my $child ( @{$hashNew{$entry}} ) {
my @tmpc = split (/\s+/, $child);
my $f = $tmp[1];
my $fc = $tmpc[1];
if ($tmp[0] =~ m/bind/ && $tmpc[0] !~ m/bind/) {
$callback->({error=>["$fc should have bind options like $f "], errorcode=> [ 1]});
if ( ($tmp[0] eq "tmpfs,rw") and ( $tmpc[0] ne "tmpfs,rw" or $tmpc[0] ne "ro") ) {
$callback->({error=>[qq{$fc can only use "tmpfs,rw" or "ro" as its option based on the option of $f}], errorcode=> [ 1]});
return;
}
if ($tmp[0] =~ m/tmpfs/ && $tmpc[0] =~ m/bind/) {
$callback->({error=>["$fc shouldnot use bind options "], errorcode=> [ 1]});
if ( ($tmp[0] ne "tmpfs,rw") and ($tmpc[0] eq "tmpfs,rw" or $tmpc[0] eq "ro") ) {
$callback->({error=>[qq{$fc shouldnot use "tmpfs,rw" options }], errorcode=> [ 1]});
return;
}
if ($tmp[0] =~ m/persistent/ && $tmpc[0] !~ m/persistent/) {
if ( ($tmp[0] eq qq{persistent}) and ($tmpc[0] ne qq{persistent}) ) {
$callback->({error=>["$fc should have persistent option like $f "], errorcode=> [ 1]});
return;
}
@ -283,7 +287,7 @@ sub process_request {
}
}
unless ($entry[0] eq $oldentry[0]) {
unless ($entry[1] eq $oldentry[0]) {
recoverFiles($rootimg_dir, \@oldentry, $callback);
if ($hashSaved{$line}) {
$verbose && $callback->({info=>["$f has sub items in the litefile table."]});
@ -293,7 +297,6 @@ sub process_request {
my @tmpc = split (/\s+/, $child);
my $name = $tmpc[1];
my @newentries = grep /\s+$name$/, @{listNew};
my @entry;
my $destf = $rootimg_dir . $name;
my $srcf = $rootimg_dir . "/.statebackup" . $name;
@ -324,7 +327,7 @@ sub process_request {
if (scalar @newentries == 1) {
@entry = split(/\s+/, $newentries[0]);
}
unless($tmpc[0] eq $entry[0]) {
unless($tmpc[0] eq $entry[1]) {
recoverFiles($rootimg_dir, \@tmpc, $callback);
}
}
@ -343,43 +346,8 @@ sub process_request {
print SAVED "$line\n";
}
close SAVED;
=head3
# then the @synclist
# We need to consider the characteristics of the file if the option is "persistent,bind" or "bind"
my @files;
my @bindedFiles;
foreach my $line (@synclist){
foreach (@{$line}){
my @entry = split(/\s+/, $_);
# $entry[0] => imgname or nodename
# $entry[1] => option value
# $entry[2] => file/directory name
my $f = $entry[2];
if($entry[1] =~ m/bind/) {
if($f =~ /^\//) {
push @bindedFiles, $f;
}else {
# make sure each file begins with "/"
$callback->({error=>["$f in litefile does not begin with absolute path! Need a '/' in the beginning"],errorcode=>[1]});
return;
}
} else {
if($f =~ /^\//){
push @files, $f;
}else{
# make sure each file begins with "/"
$callback->({error=>["$f in litefile does not begin with absolute path! Need a '/' in the beginning"],errorcode=>[1]});
return;
}
}
}
}
liteMe($rootimg_dir,\@files, \@bindedFiles, $callback);
=cut
liteMeNew($rootimg_dir, \%hashNew, $callback);
liteMe($rootimg_dir, \%hashNew, $callback);
# now stick the rc file in:
# this is actually a pre-rc file because it gets run before the node boots up all the way.
@ -392,7 +360,7 @@ sub process_request {
}
sub liteMeNew {
sub liteMe {
my $rootimg_dir = shift;
my $hashNewRef = shift;
my $callback = shift;
@ -421,184 +389,6 @@ sub liteMeNew {
# end loop, synclist should now all be in place.
}
sub liteMe {
# Arg 1: root image dir: /install/netboot/centos5.3/x86_64/compute/rootimg
my $rootimg_dir = shift;
my $files = shift;
my $bindedFiles = shift;
# Arg 2: callback ref to make comments...
my $callback = shift;
unless(-d $rootimg_dir){
$callback->({error=>["no rootimage dir"],errorcode=>[1]});
return;
}
# snapshot directory for tmpfs and persistent data.
$callback->({info=>["creating $rootimg_dir/$statedir"]});
mkpath("$rootimg_dir/$statedir/tmpfs");
# now make a place for all the files.
# this loop uses "mount --bind" to mount files instead of creating symbolic links for
# each of the files in the @$bindedFiles sync list;
# 1. copy original contents if they exist to .default directory
foreach my $f (@$bindedFiles) {
# copy the file to /.defaults
my $rif = $rootimg_dir . $f;
my $d = dirname($f);
# if no such file like $rif, create one
unless ( -e "$rif" ) {
if($f =~ m{/$}) {
$verbose && $callback->({info=>["mkdir -p $rif"]});
system("mkdir -p $rif");
} else {
# check whether its directory exists or not
my $rifdir = dirname($rif);
unless( -e $rifdir ) {
$verbose && $callback->({info => ["mkdir $rifdir"]});
mkdir($rifdir);
}
$verbose && $callback->({info=>["touch $rif"]});
system("touch $rif");
}
}
unless ( -e "$rootimg_dir/.default$d" ) {
$verbose && $callback->({info=>["mkdir -p $rootimg_dir/.default$d"]});
system("mkdir -p $rootimg_dir/.default$d");
}
# copy the file in place.
$verbose && $callback->({info=>["cp -r -a $rif $rootimg_dir/.default$d"]});
system("cp -r -a $rif $rootimg_dir/.default$d");
}
# this loop creates symbolic links for each of the files in the sync list.
# 1. copy original contents if they exist to .default directory
# 2. remove file
# 3. create symbolic link to .statelite
my $sym = "1"; # sym = 0 means no symlinks, just bindmount
if($sym){
foreach my $f (@$files){
#check if the file has been moved to .default by its parent or by last liteimg, if yes, then do nothing
my $ret=`readlink -m $rootimg_dir$f`;
if ($? == 0) {
if ($ret =~ /$rootimg_dir\/.default/)
{
$verbose && $callback->({info=>["do nothing for file $f"]});
next;
}
}
# copy the file to /.defaults
my $rif = $rootimg_dir . $f;
my $d = dirname($f);
if( -f "$rif" or -d "$rif"){
# if its already a link then leave it alone.
unless(-l $rif){
# mk the directory if it doesn't exist:
$verbose && $callback->({info=>["mkdir -p $rootimg_dir/.default$d"]});
system("mkdir -p $rootimg_dir/.default$d");
# copy the file in place.
$verbose && $callback->({info=>["cp -r -a $rif $rootimg_dir/.default$d"]});
system("cp -r -a $rif $rootimg_dir/.default$d");
# remove the real file
$verbose && $callback->({info=>["rm -rf $rif"]});
system("rm -rf $rif");
}
}else{
# in this case the file doesn't exist in the image so we create something to it.
# here we're modifying the read/only image
unless(-d "$rootimg_dir$d"){
$verbose && $callback->({info=>["mkdir -p $rootimg_dir$d"]});
system("mkdir -p $rootimg_dir$d");
}
unless(-d "$rootimg_dir/.default$d"){
$verbose && $callback->({info=>["mkdir -p $rootimg_dir/.default$d"]});
system("mkdir -p $rootimg_dir/.default$d");
}
# now make touch the file:
if($f =~ /\/$/){
# if its a directory, make the directory in .default
$verbose && $callback->({info=>["mkdir -p $rootimg_dir/.default$f"]});
system("mkdir -p $rootimg_dir/.default$f");
}else{
# if its just a file then link it.
$verbose && $callback->({info=>["touch $rootimg_dir/.default$f"]});
system("touch $rootimg_dir/.default$f");
}
}
# now create the spot in tmpfs
$verbose && $callback->({info=>["mkdir -p $rootimg_dir/$statedir/tmpfs$d"]});
system("mkdir -p $rootimg_dir/$statedir/tmpfs$d");
# now for each file, create a symbollic link to /.statelite/tmpfs/
# strip the last / if its a directory for linking, but be careful!
# doing ln -sf ../../tmp <blah>../tmp when tmp is a directory creates 50 levels of links.
# have to do:
# ln -sf ../../tmp <blah>../../tmp/ <- note the / on the end!
if($f =~ /\/$/){
$f =~ s/\/$//g;
}
# now do the links.
# link the .default file to the .statelite file and the real file to the .statelite file.
# ../ for tmpfs
# ../ for .statelite
# the rest are for the paths in the file.
my $l = getRelDir($f);
$verbose && $callback->({info=>["ln -sf ../../$l/.default$f $rootimg_dir/$statedir/tmpfs$f"]});
system("ln -sfn ../../$l/.default$f $rootimg_dir/$statedir/tmpfs/$f");
$verbose && $callback->({info=>["ln -sf $l/$statedir/tmpfs$f $rootimg_dir$f"]});
system("ln -sfn $l/$statedir/tmpfs$f $rootimg_dir$f");
}
}else{
# if we go the bindmount method, create some files
foreach my $f (@$files){
my $rif = $rootimg_dir . $f;
my $d = dirname($rif);
unless(-e "$rif"){
# if it doesn't exist, create it on base image:
unless(-d $d){
#$callback->({info=>["mkdir -p $d"]});
system("mkdir -p $d");
}
if($rif =~ /\/$/){
#$callback->({info=>["mkdir -p $rif"]});
system("mkdir -p $rif");
}else{
#$callback->({info=>["touch $rif"]});
system("touch $rif");
}
}
else {
#$callback->({info=>["$rif exists"]});
}
}
}
# end loop, synclist should now all be in place.
# now stick the rc files in:
# this is actually a pre-rc file because it gets run before the node boots up all the way.
system("cp -a $::XCATROOT/share/xcat/netboot/add-on/statelite/rc.statelite $rootimg_dir/etc/init.d/statelite");
}
sub getRelDir {
my $f = shift;
$f = dirname($f);
@ -671,14 +461,11 @@ sub parseLiteFiles {
unless ($parent =~ m/\/$/) {
$parent .= "/";
}
#$verbose && print "+++$parent+++\n";
#my $found = grep $_ =~ m/\Q$parent\E$/, @entries;
my @res = grep {$_ =~ m/\Q$parent\E$/} @entries;
my $found = scalar @res;
#$verbose && print "+++found = $found+++\n";
if($found eq 1) { # $parent is found in @entries
#$verbose && print "+++$parent is found+++\n";
# handle $res[0];
my @tmpresentry=split /\s+/, $res[0];
shift @tmpresentry;
@ -710,11 +497,7 @@ sub recoverFiles {
#$callback->({info => ["! updating $f ..."]});
if ($oldentry->[0] =~ m/bind/) {
# shouldn't copy back from /.default, maybe the user has replaced the file/directory in .postinstall file
my $default = $rootimg_dir . $f;
xCAT::Utils->runcmd("rm -rf $default", 0, 1); # not sure whether it's necessary right now
} else {
if ($oldentry->[0] eq "tmpfs,rw" or $oldentry->[0] eq "ro" ) {
my $target = $rootimg_dir . $f;
if (-l $target) { #not one directory
my $location = readlink $target;
@ -745,6 +528,10 @@ sub recoverFiles {
}
$target = $rootimg_dir . "/.statelite/tmpfs" . $f;
xCAT::Utils->runcmd("rm -rf $target", 0, 1);
} else {
# shouldn't copy back from /.default, maybe the user has replaced the file/directory in .postinstall file
my $default = $rootimg_dir . $f;
xCAT::Utils->runcmd("rm -rf $default", 0, 1); # TODO: not sure whether it's necessary right now
}
return 0;
@ -764,35 +551,7 @@ sub liteItem {
my $rif = $rootimg_dir . $f;
my $d = dirname($f);
if($entry[0] =~ m/bind/) {
# if no such file like $rif, create one
unless ( -e "$rif" ) {
if ($f =~ m{/$}) {
$verbose && $callback->({info=>["mkdir -p $rif"]});
system("mkdir -p $rif");
} else {
# check whether its directory exists or not
my $rifdir = $rootimg_dir . $d;
unless (-e $rifdir) {
$verbose && $callback->({info => ["mkdir $rifdir"]});
mkdir($rifdir);
}
$verbose && $callback->({info=>["touch $rif"]});
system("touch $rif");
}
}
unless ( -e "$rootimg_dir/.default$d" ) {
$verbose && $callback->({info=>["mkdir -p $rootimg_dir/.default$d"]});
system("mkdir -p $rootimg_dir/.default$d");
}
# copy the file to /.defaults
$verbose && $callback->({info=>["cp -r -a $rif $rootimg_dir/.default$d"]});
system("cp -r -a $rif $rootimg_dir/.default$d");
}else {
if (($entry[0] eq "tmpfs,rw") or ($entry[0] eq "ro")) {
# 1. copy original contents if they exist to .default directory
# 2. remove file
# 3. create symbolic link to .statelite
@ -897,8 +656,33 @@ sub liteItem {
}
}
}
}
} else {
# if no such file like $rif, create one
unless ( -e "$rif" ) {
if ($f =~ m{/$}) {
$verbose && $callback->({info=>["mkdir -p $rif"]});
system("mkdir -p $rif");
} else {
# check whether its directory exists or not
my $rifdir = $rootimg_dir . $d;
unless (-e $rifdir) {
$verbose && $callback->({info => ["mkdir $rifdir"]});
mkdir($rifdir);
}
$verbose && $callback->({info=>["touch $rif"]});
system("touch $rif");
}
}
unless ( -e "$rootimg_dir/.default$d" ) {
$verbose && $callback->({info=>["mkdir -p $rootimg_dir/.default$d"]});
system("mkdir -p $rootimg_dir/.default$d");
}
# copy the file to /.defaults
$verbose && $callback->({info=>["cp -r -a $rif $rootimg_dir/.default$d"]});
system("cp -r -a $rif $rootimg_dir/.default$d");
}
}

View File

@ -20,14 +20,7 @@ ELIST=[] # entry list, each entry will contain the type and the path
declare -a CLIST
declare -a PLIST
# hostname -s does not work on boot for SUSE
# You get this error:
# hostname: Unknown server error
if [ -e "${MNTDIR}/etc/SuSE-release" ]; then
ME=`hostname`
else
ME=`hostname -s`
fi
ME=`hostname`
PERSISTENT="${MNTDIR}/$SL/persistent/$ME"
@ -61,14 +54,7 @@ GetSyncInfo () {
fi
done
# hostname -s does not work on boot for SUSE
# You get this error:
# hostname: Unknown server error
if [ -e "${MNTDIR}/etc/SuSE-release" ]; then
hn=`hostname`
else
hn=`hostname -s`
fi
hn=`hostname`
if [ -z $XCATSERVER ]; then
echo "Cannot find the xCAT server for node $hn"
@ -183,18 +169,6 @@ MountTrees () {
done
}
ResolveLinksOld () {
# go through each file and do the right thing to it.
cat $SYNCLIST | grep -v "^#" | \
while read type path
do
FindFile ${path} ${type}
done
}
ResolveLinks () {
exec <$SYNCLIST
i=0
@ -273,7 +247,7 @@ ProcessType () {
# the link will already be in place on the image, so nothing else to do!
;;
con)
# cons go in tmpfs
# cons go in bind # TODO ???
cat ${1} >>${TMPFS}${2}
echo "cat ${1} >>${TMPFS}${2}" >>$LOG
;;
@ -294,7 +268,7 @@ ProcessType () {
mount --bind ${TMPFS}${2} /sysroot${ORIG}>>$LOG 2>&1
fi
;;
bind,persistent)
persistent)
if [ ! -d ${PERSISTENT}${PPATH} ]; then
mkdir -p ${PERSISTENT}${PPATH}
echo "mkdir -p ${PERSISTENT}${PPATH}" >>$LOG
@ -312,71 +286,6 @@ ProcessType () {
echo "mount --bind ${TARGET} /sysroot/${ORIG}" >>$LOG
mount --bind ${TARGET} /sysroot/${ORIG}>>$LOG 2>&1
;;
persistent*)
# everything from root image points to tmpfs
# so have tmpfs point to persistent
# make tree in persistent and tmpfs
# need to check whether the option of its parent direcotry is persistent or not
TMPDIR=`dirname ${2}`
if [ ! -e ${PERSISTENT}${TMPDIR} ]; then
mkdir -p ${PERSISTENT}${TMPDIR}
echo "mkdir -p ${PERSISTENT}${TMPDIR}" >>$LOG
fi
if [ "$isChild" = "1" ]; then
num=${#PLIST[@]}
for ((i=0;i<$num; i++)); do
set -- ${PLIST[$i]}
itype=$1
ipath=$2
if [ "$PPATH" = "$ipath" ]; then
if [[ ! "$itype" =~ "persistent*" ]]; then
if [ ! -e ${PERSISTENT}${2} ]; then
echo "cp -r -a ${1} ${PERSISTENT}${2}" >>$LOG
cp -r -a ${1} ${PERSISTENT}${2} 2>&1 >>$LOG
fi
# mount it to ${TARGET}
echo "mount --bind ${PERSISTENT}${2} ${TARGET}" >>$LOG
mount --bind ${PERSISTENT}${2} ${TARGET}
fi
fi
done
else
if [[ ! -d ${PERSISTENT}${PPATH} && ! -d `readlink -m ${PERSISTENT}${PPERS}` ]]; then
# unless the entry is one directory or one link to the directory
rm -rf ${PERSISTENT}${PPERS}
mkdir -p ${PERSISTENT}${PPERS}
echo "mkdir -p ${PERSISTENT}${PPERS}" >>$LOG
fi
# if the file doesn't exist, then copy it over to persistent
if [ ! -e ${PERSISTENT}${2} ]; then
# if its not there, then take it from something else
echo "cp -r -a ${1} ${PERSISTENT}${2}" >>$LOG
cp -r -a ${1} ${PERSISTENT}${2} 2>&1 >>$LOG
fi
#if target is a directory, then remove it first,
#otherwise, the link will be created under this dir instead of replacing it.
# whack of trailing / for persistent directories:
TARGET=`echo ${TMPFS}${2} | sed -e 's/\/$//'`
if [ -d ${TARGET} ]; then
echo "rm -Rf ${TARGET}" >>$LOG
rm -Rf ${TARGET} 2>&1 >>$LOG
fi
# finally make the tmpfs link point to the persistent file
# you have to get rid of the /sysroot in the beginning
# so that when the chroot happens the link is valid.
LINK=`echo ${PERSISTENT}${2} | sed -e 's/^\/sysroot//'`
echo "ln -sf ${LINK} ${TARGET}" >>$LOG
ln -sf ${LINK} ${TARGET} >>$LOG 2>&1
fi
;;
ro)
# need to make sure directory exists:
if [ ! -d ${TMPFS}${PPATH} ]; then
@ -412,7 +321,7 @@ FindFile () {
FOUND=0
else
ProcessType ${TREEMOUNT}/${DIR}${path} ${path} ${type} ${isChild}
if [ "${2}" = "con" ]; then
if [[ "${2}" =~ "con" ]]; then
continue
else
break

View File

@ -1,5 +1,8 @@
#!/bin/sh
NEWROOT=$3
XCATMASTER=$XCAT
if [ ! -z "$imgurl" ]; then
if [ xhttp = x${imgurl%:*} ]; then
NFS=0
@ -24,32 +27,7 @@ if [ ! -z "$imgurl" ]; then
fi
#echo 0 > /proc/sys/vm/zone_reclaim_mode #Avoid kernel bug
# RAM root Hybrid with NFS root
if [ "$NFS" = "1" ]; then
echo Setting up nfs with ram overlay.
modprobe nfs
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/
mount -t aufs -o dirs=/rw:/ro mergedroot $NEWROOT
mkdir -p $NEWROOT/ro
mkdir -p $NEWROOT/rw
mount --move /ro $NEWROOT/ro
mount --move /rw $NEWROOT/rw
cp /etc/resolv.conf $NEWROOT/etc/
echo xcatfs / aufs rw,_netdev 0 0 >> $NEWROOT/etc/fstab
elif [ -r /rootimg.sfs ]; then
if [ -r /rootimg.sfs ]; then
echo Setting up squashfs with ram overlay.
mknod /dev/loop0 b 7 0
mkdir -p /ro
@ -62,14 +40,14 @@ elif [ -r /rootimg.sfs ]; then
mount --move /ro $NEWROOT/ro
mount --move /rw $NEWROOT/rw
elif [ -r /rootimg.gz ]; then
echo Setting up RAM-root tmpfs.
echo Setting up RAM-root tmpfs.
mount -t tmpfs rootfs $NEWROOT
cd $NEWROOT
echo -n "Extracting root filesystem:"
if [ -x /bin/cpio ]; then
gzip -cd /rootimg.gz |/bin/cpio -idum
gzip -cd /rootimg.gz |/bin/cpio -idum
else
gzip -cd /rootimg.gz |cpio -idum
gzip -cd /rootimg.gz |cpio -idum
fi
echo Done
else

View File

@ -53,7 +53,6 @@ my $srcdir_otherpkgs;
my $otherpkglist;
my $postinstall_filename;
my $rootimg_dir;
my $mode;
my $permission; # the permission works only for statelite mode currently
@ -73,98 +72,148 @@ GetOptions(
'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";
# if "Table.pm" can be found here, the attributes in linuximage and osimage will be updated
my $needUpdateTable = 0;
my %keyhash = ();
my %updates_os = (); # the hash for updating osimage table
my %updates = (); # the hash for updating linuximage table
my $osimagetab;
my $linuximagetab;
my $ref_linuximage_tab;
my $ref_osimage_tab;
# load the module in memory
eval { require("$::XCATROOT/lib/perl/xCAT/Table.pm") };
unless ($@) {
# Table.pm is there, we can update the xCAT tables
$needUpdateTable = 1;
# get the info from the osimage and linux
$osimagetab = xCAT::Table->new('osimage', -create=>1);
unless ($osimagetab) {
print "The osimage table cannot be opened.\n";
exit 1;
}
#load the module in memory
eval {require("$::XCATROOT/lib/perl/xCAT/Table.pm")};
if ($@) {
print $@;
exit 1;
$linuximagetab = xCAT::Table->new('linuximage', -create=>1);
unless ($linuximagetab) {
print "The linuximage table cannot be opened.\n";
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;
}
if (@ARGV > 0 and $needUpdateTable eq 1) {
$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;
}
$osver=$ref->{'osvers'};
$arch=$ref->{'osarch'};
$profile=$ref->{'profile'};
my $provmethod=$ref->{'provmethod'};
($ref_osimage_tab) = $osimagetab->getAttribs({imagename => $imagename}, 'osvers', 'osarch', 'profile', 'provmethod');
unless ($ref_osimage_tab) {
print "Cannot find image \'$imagename\' from the osimage table.\n";
exit 1;
}
($ref_linuximage_tab) = $linuximagetab->getAttribs({imagename => $imagename}, 'pkglist', 'pkgdir', 'otherpkglist', 'otherpkgdir', 'postinstall', 'rootimgdir', 'nodebootif', 'otherifce', 'kernelver', 'netdrivers', 'permission');
unless ($ref_linuximage_tab) {
print "Cannot find $imagename from the linuximage table\n";
exit 1;
}
$osver = $ref_osimage_tab->{'osvers'};
$arch = $ref_osimage_tab->{'osarch'};
$profile = $ref_osimage_tab->{'profile'};
my $provmethod = $ref_osimage_tab->{'provmethod'}; # TODO: not necessary; and need to update both statelite and stateless modes
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;
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;
unless ($provmethod eq 'netboot' || $provmethod eq 'statelite') {
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";
unless ( $ref_linuximage_tab->{'pkglist'} ) {
print"A .pkglist file must be specified for image \'$imagename\' in the linuximage table.\n";
exit 0;
}
$pkglist =$ref1->{'pkglist'};
$pkglist = $ref_linuximage_tab->{'pkglist'};
$srcdir=$ref1->{'pkgdir'};
$srcdir_otherpkgs=$ref1->{'otherpkgdir'};
$otherpkglist=$ref1->{'otherpkglist'};
$postinstall_filename=$ref1->{'postinstall'};
$destdir=$ref1->{'rootimgdir'};
}
$srcdir= $ref_linuximage_tab->{'pkgdir'};
$srcdir_otherpkgs = $ref_linuximage_tab->{'otherpkgdir'};
$otherpkglist = $ref_linuximage_tab->{'otherpkglist'};
$postinstall_filename = $ref_linuximage_tab->{'postinstall'};
$destdir = $ref_linuximage_tab->{'rootimgdir'};
if ($mode eq "statelite") {
if (!$permission) {
$permission = "755";
# TODO: how can we do if the user specifies one wrong value to the following attributes?
# currently, one message is output to indicate the users there will be some updates
if ($prinic) {
if ($prinic ne $ref_linuximage_tab->{'nodebootif'}) {
print "The primary nic is different from the value in linuximage table, will update it\n";
$updates{'nodebootif'} = $prinic;
}
} else {
$prinic = $ref_linuximage_tab->{'nodebootif'};
}
if ($othernics) {
if ($othernics ne $ref_linuximage_tab->{'otherifce'}) {
print "The other ifces are different from the value in linuximage table, will update it\n";
$updates{'otherifce'} = $othernics;
}
} else {
$othernics = $ref_linuximage_tab->{'otherifce'};
}
if ($kernelver) {
if ($kernelver ne $ref_linuximage_tab->{'kernelver'}) {
print "The kernelver is different from the value in linuximage table, will update it\n";
$updates{'kernelver'} = $kernelver;
}
} else {
$kernelver = $ref_linuximage_tab->{'kernelver'};
}
if ($ndrivers) {
if ($ndrivers ne $ref_linuximage_tab->{'netdrivers'}) {
print "The netdrivers are different from the value in linuximage table, will update it\n";
$updates{'netdrivers'} = $ndrivers;
}
} else {
$ndrivers = $ref_linuximage_tab->{'netdrivers'};
}
if ($permission) {
if ($permission ne $ref_linuximage_tab->{'permission'}) {
print "The permission value is different from the value in linuximage table, will update it\n";
$updates{'permission'} = $permission;
}
} else {
$permission = $ref_linuximage_tab->{'permission'};
}
}
if (!$arch) {
$permission = "755" unless ($permission);
$updates{'permission'} = $permission if ( $needUpdateTable );
unless ($arch) {
$arch = `uname -m`;
chomp($arch);
if ($arch =~ /i.86$/) {
$arch = "x86";
}
$arch = "x86" if ($arch =~ /i.86$/);
}
if (!$srcdir) {
$srcdir="$installroot/$osver/$arch";
}
$srcdir="$installroot/$osver/$arch" unless ($srcdir);
$updates{'pkgdir'} = $srcdir if ($needUpdateTable);
if (!$srcdir_otherpkgs) {
$srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch";
}
$srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch" unless ($srcdir_otherpkgs);
$updates{'otherpkgdir'} = $srcdir_otherpkgs if ($needUpdateTable);
$destdir="$installroot/netboot/$osver/$arch/$profile" unless ($destdir);
$updates{'rootimgdir'} = $destdir if ($needUpdateTable);
if (!$destdir)
{
$destdir="$installroot/netboot/$osver/$arch/$profile";
}
$rootimg_dir="$destdir/rootimg";
# Get the subchannels of the given interface
@ -194,46 +243,37 @@ if ($arch eq "s390x") {
}
unless ($osver and $profile) {
print 'Usage: genimage [ -i <nodebootif> ] [ -n <nodenetdrivers> ] [-r <otherifaces>] -o <OSVER> -p <PROFILE> -k <KERNELVER> [-m <mode> [--permission <permission>]]'."\n";
print 'Usage: genimage [ -i <nodebootif> ] [ -n <nodenetdrivers> ] [-r <otherifaces>] -o <OSVER> -p <PROFILE> -k <KERNELVER> [--permission <permission>]'."\n";
print ' genimage [ -i <nodebootif> ] [ -n <nodenetdrivers> ] [-r <otherifaces>] -k <KERNELVER> <imagename>'."\n";
print " --permission only works when '-m statelite' is set\n";
print " --permission only works with statelite mode\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 igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot\n";
print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot --permission 777\n";
print " genimage -i eth0 -n tg3 myimage\n";
exit 1;
}
my @ndrivers;
unless ($netdriver) {
@ndrivers = qw/tg3 bnx2 bnx2x e1000 e1000e igb mlx_en/;
if ($netdriver) {
if ( ($updates{'netdrivers'} ne $netdriver) and ($needUpdateTable) ) {
$updates{'netdrivers'} = $netdriver;
}
} else {
if ($arch eq 'x86' or $arch eq 'x86_64') {
@ndrivers = qw/tg3 bnx2 bnx2x e1000 e1000e igb mlx_en/;
} elsif ($arch eq 'ppc64') {
@ndrivers = qw/e1000 e1000e igb ibmveth ehea/;
}
# TODO: need to set the default network drivers for s390x ?
}
foreach (split /,/,$netdriver) {
unless (/\.ko$/) {
s/$/.ko/;
}
if (/^$/) {
next;
}
push @ndrivers,$_;
}
unless (-d "$rootimg_dir/usr/share/dracut") { # dracut will handle the nfs-related kernel modules
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";
# Additional modules needed on s390x
if ($arch eq "s390x") {
# The network drivers need to be loaded in this order
unshift @ndrivers,"ccwgroup.ko";
unshift @ndrivers,"qdio.ko";
}
}
next if (/^$/);
push @ndrivers, $_;
}
unless ($onlyinitrd) {
@ -268,16 +308,18 @@ unless ($onlyinitrd) {
$yumcmd .= "install ";
mkpath("$rootimg_dir/var/lib/yum");
if (!$imagename) {
unless ($imagename) {
$pkglist= imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "pkglist");
if (!$pkglist) {
$pkglist= imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "pkglist");
unless ($pkglist) {
$pkglist= imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "pkglist");
}
}
if (!$pkglist) {
print "Unable to find package list for $profile!";
exit 1;
if ($pkglist) {
$updates{'pkglist'} = $pkglist if ($needUpdateTable);
} else {
print "Unable to find package list for $profile!";
exit 1;
}
my %pkg_hash=imgutils::get_package_names($pkglist);
@ -300,13 +342,14 @@ unless ($onlyinitrd) {
}
#Now let's handle extra packages
if (!$imagename) {
$otherpkglist=imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "otherpkgs.pkglist");
if (!$otherpkglist) { $otherpkglist=imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "otherpkgs.pkglist"); }
unless ($imagename) {
$otherpkglist = imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "otherpkgs.pkglist");
unless ($otherpkglist) { $otherpkglist=imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "otherpkgs.pkglist"); }
}
my %extra_hash=();
if ($otherpkglist) {
%extra_hash=imgutils::get_package_names($otherpkglist);
$updates{'otherpkglist'} = $otherpkglist if ($needUpdateTable);
%extra_hash = imgutils::get_package_names($otherpkglist);
}
my %extrapkgnames;
@ -315,64 +358,64 @@ unless ($onlyinitrd) {
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);
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-$_ ";
$yumcmd .= "--enablerepo=$osver-$arch-$_ ";
}
for (1..$index) {
$yumcmd .= "--enablerepo=otherpkgs$_ ";
$yumcmd .= "--enablerepo=otherpkgs$_ ";
}
foreach $pass (sort (keys(%extra_hash))) {
#remove the packages that are specified in the otherpkgs.list files with leading '-'
# 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) {
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");
}
$rc = system("$yumcmd_remove $rm_packges");
}
}
#install extra packages
# install extra packages
my $yumcmd_base = $yumcmd;
$yumcmd .= "install ";
#append extra pkg names to yum command
# append extra pkg names to yum command
if ($extrapkgnames{$pass}) {
$yumcmd .= " $extrapkgnames{$pass} ";
$yumcmd .= " $extrapkgnames{$pass} ";
}
$yumcmd =~ s/ $/\n/;
#debug
print "yumcmd=$yumcmd\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;
print "yum invocation failed\n";
exit 1;
}
#remove the packages that are specified in the otherpkgs.list files with leading '--'
# 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) {
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");
}
$rc = system("$yumcmd_remove $rm_packges");
}
}
}
}
@ -395,20 +438,17 @@ unless ($onlyinitrd) {
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;
}
@KVERS= <$rootimg_dir/lib/modules/*> unless (scalar(@KVERS));
$basekernelver = basename(pop @KVERS) if (scalar(@KVERS));
$basekernelver = `uname -r` unless ($basekernelver);
$kernelver = $basekernelver unless ($kernelver);
chomp($kernelver);
$updates{'kernelver'} = $kernelver if ($needUpdateTable);
if ($kernelver ne $basekernelver) {
# the kernelver is specified by "-k",
# the kernel file should be in /boot
@ -473,18 +513,21 @@ while (scalar @checkdeps) {
close($moddeps);
unlink "/tmp/genimage.$$.yum.conf";
if (-d "$rootimg_dir/usr/share/dracut") {
$dracutmode=1;
$dracutmode = 1;
}
#-- run postinstall script
if (!$imagename) {
unless ($imagename) {
$postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "postinstall");
if (!$postinstall_filename) {
$postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "postinstall");
unless ($postinstall_filename) {
$postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "postinstall");
}
}
if (($postinstall_filename) && (-x $postinstall_filename)) {
$updates{'postinstall'} = $postinstall_filename if ($needUpdateTable);
my $rc = system($postinstall_filename, $rootimg_dir,$osver,$arch,$profile);
if($rc) {
print "postinstall script failed\n";
@ -492,33 +535,81 @@ if (($postinstall_filename) && (-x $postinstall_filename)) {
}
}
if ($needUpdateTable) {
# all the attributes have been gathered
# now, update the linuximage and osimage tables
# TODO: do statelite and stateless share the same attributes?
if ($imagename) {
$keyhash{'imagename'} = $imagename;
$linuximagetab->setAttribs(\%keyhash, \%updates);
$linuximagetab->commit;
} else {
# update the imagename for diskless
$keyhash{'imagename'} = "$osver-$arch-netboot-$profile";
$updates_os{'profile'} = $profile;
$updates_os{'imagetype'} = 'linux';
$updates_os{'provmethod'} = 'netboot';
$updates_os{'osname'} = 'Linux';
$updates_os{'osvers'} = $osver;
$updates_os{'osdistro'} = 'rh'; # it is not used currently
$updates_os{'osarch'} = $arch;
$osimagetab->setAttribs(\%keyhash, \%updates_os);
$osimagetab->commit;
$linuximagetab->setAttribs(\%keyhash, \%updates);
$linuximagetab->commit;
# update the imagename for netboot
$keyhash{'imagename'} = "$osver-$arch-statelite-$profile";
$updates_os{'provmethod'} = 'statelite';
$osimagetab->setAttribs(\%keyhash, \%updates_os);
$osimagetab->commit;
$linuximagetab->setAttribs(\%keyhash, \%updates);
$linuximagetab->commit;
}
}
# 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 ($dracutmode) { #in dracut mode, we delegate all this activity
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");
}
mkpath "$rootimg_dir/.statelite"; # create place for NFS mounts.
# this script will get the directories.
# TODO: the file is re-copied in liteimg.pm
unless (-f "../add-on/statelite/rc.statelite") {
print "Can't find ../add-on/statelite/rc.statelite!\n";
exit 1;
}
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 ($dracutmode) { #in dracut mode, we delegate all this activity
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");
}
}
if ($dracutmode) {
# backup etc/rc.sysinit file before modifing it
system("cp -a $rootimg_dir/etc/rc.sysinit $rootimg_dir/etc/rc.sysinit.backup");
# modify etc/rc.sysinit, prevent remounting
# TODO: need to find one way to prevent remounting
my $SYSINITFILE;
my $TMPSYSINITFILE;
if (-f "$rootimg_dir/etc/rc.sysinit") {
@ -539,16 +630,23 @@ if($mode eq "statelite"){
close($TMPSYSINITFILE);
cp("/tmp/rc.sysinit.tmp", "$rootimg_dir/etc/rc.sysinit");
}
}
}
# before mkinitrd, run depmod to generate modules.dep
system("chroot $rootimg_dir depmod $kernelver");
# TODO: for the genimage-enchement, need to create two initial ramdisks,
# one is for stateless
# the other one is for statelite
# move the load_dd() and @ndrivers-related code here
if ($dracutmode) {
mkinitrd_dracut();
mkinitrd_dracut("statelite");
mkinitrd_dracut("stateless");
} else {
mkinitrd();
mkinitrd("statelite");
mkinitrd("stateless");
}
sub getlibs {
@ -569,11 +667,12 @@ sub getlibs {
next;
}
$temp1 =~ s/^\///;
$libhash{$temp1}=1;
$libhash{$temp1}=1;
}
}
sub mkinitrd_dracut {
my ($mode) = @_; # the mode is for statelite or stateless
my $dracutmpath = "$rootimg_dir/usr/share/dracut/modules.d/97xcat";
mkpath($dracutmpath);
@ -598,12 +697,11 @@ sub mkinitrd_dracut {
# update etc/dracut.conf
open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf");
print $DRACUTCONF qq{dracutmodules+="xcat nfs base network"\n};
print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n};
print $DRACUTCONF qq{add_drivers+="$add_drivers"\n};
print $DRACUTCONF qq{filesystems+="nfs"\n};
close $DRACUTCONF;
} else {
# for diskless
} elsif ($mode eq "stateless") {
cp("$fullpath/dracut/install.netboot","$dracutmpath/install");
$perm = (stat("$fullpath/dracut/install.netboot"))[2];
chmod($perm&07777, "$dracutmpath/install");
@ -615,7 +713,7 @@ sub mkinitrd_dracut {
if ($prinic) {
my $optspec;
open($optspec,'>>',"$dracutmpath/xcat-cmdline.sh");
print $optspec "IFACE=$prinic\n";
print $optspec "PRINIC=$prinic\n";
close $optspec;
}
@ -632,13 +730,33 @@ sub mkinitrd_dracut {
print $DRACUTCONF qq{dracutmodules+="xcat base network kernel-modules"\n};
print $DRACUTCONF qq{add_drivers+="$add_drivers"\n};
close $DRACUTCONF;
} else {
xdie "the mode: $mode is not supported by genimage";
}
system("chroot '$rootimg_dir' dracut -f /tmp/initrd.$$.gz $kernelver");
system("chroot $rootimg_dir dracut -f /tmp/initrd.$$.gz $kernelver");
print "the initial ramdisk is generated successfully.\n";
move("$rootimg_dir/tmp/initrd.$$.gz", "$destdir/initrd.gz");
move("$rootimg_dir/tmp/initrd.$$.gz", "$destdir/initrd-$mode.gz");
}
sub mkinitrd {
my ($mode) = @_; # statelite or stateless
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";
# Additional modules needed on s390x
if ($arch eq "s390x") {
# The network drivers need to be loaded in this order
unshift @ndrivers, "ccwgroup.ko";
unshift @ndrivers, "qdio.ko";
}
}
mkpath("/tmp/xcatinitrd.$$/bin");
symlink("bin","/tmp/xcatinitrd.$$/sbin");
@ -680,7 +798,7 @@ NORMAL=\$RESET
# This function is used to mount files/directories from the .statelite directory
# over the root directory.
# This function stolen from redhat
# This function is stolen from redhat
shell() {
echo ''
echo -e "\$YELLOW Entering rescue/debug init shell."
@ -732,9 +850,9 @@ echo '
EOS1
print $inifile "busybox.anaconda mount -t proc /proc /proc\n";
print $inifile "busybox.anaconda --install\n";
print $inifile "mount -t sysfs /sys /sys\n";
print $inifile "busybox.anaconda 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";
@ -764,6 +882,7 @@ EOS1
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";
}
@ -802,28 +921,60 @@ EOMS
# check and see if debug is specified on command line
grep '\(debug\)' /proc/cmdline > /dev/null && export DEBUG=1
IFACE=$prinic
# check the kernel parameter at first
# if one parameter for the booting device is there, we will use it
# TODO
# ( netdevice is recognized by SLES, )
# ( Dracut has one "network" module to handle the booting network devices, which use "ifname" )
# ( What should the other redhat versions use ? netdev=<eth0> and BOOTIF=<mac address> )
# besides this action, the following code is also used to get the XCAT= value, which is for XCAT server
# TODO: does "anaconda.busybox sh" support "set " ?
PRINIC=$prinic
for i in `cat /proc/cmdline`; do
KEY=`echo \$i |awk -F= '{print \$1}'`
if [ "\$KEY" == 'netdev' ]; then
NETDEV=`echo \$i |awk -F= '{print \$2}'`
elif [ "\$KEY" == 'BOOTIF' ]; then
VALUE=`echo \$i |awk -F= '{print \$2}'`
BOOTIF=`ifconfig -a|grep -i "hwaddr $VALUE"|awk '{print $1}'`
if [ ! -z "\$XCATSERVER" ]; then
break
fi
elif [ "\$KEY" == 'XCAT' ]; then
VALUE=`echo \$i |awk -F= '{print \$2}'`
# format: XCAT=xcatmaster:3001
XCATSERVER=\$VALUE
if [ ! -z "\$BOOTIF" ]; then
break
fi
fi
done
if [ -z "\$IFACE" ]; then
for i in `cat /proc/cmdline`; do
KEY=`echo \$i |awk -F= '{print \$1}'`
if [ "\$KEY" == 'netdev' ]; then
IFACE=`echo \$i |awk -F= '{print \$2}'`
break
fi
if [ "\$KEY" == 'BOOTIF' ]; then
VALUE=`echo \$i |awk -F= '{print \$2}'`
IFACE=`ifconfig -a|grep -i "hwaddr $VALUE"|awk '{print $1}'`
fi
done
if [ ! -z "\$NETDEV" ]; then
IFACE=\$NETDEV
elif [ ! -z "\$BOOTIF" ]; then
IFACE=\$BOOTIF
elif [ ! -z "\$PRINIC" ]; then
IFACE=\$PRINIC
else
echo "\${RED}Couldn't find the proper booting device, switch to shell...\${RESET}"
shell
exit
fi
fi
export IFACE=\$IFACE
netstart
netstart \$IFACE
while ! ifconfig | grep inet; do
echo -e "\${RED}Failed to acquire address, retrying \${RESET}"
sleep 1
netstart
sleep 5
netstart \$IFACE
done
ifconfig lo 127.0.0.1
ifconfig lo up
@ -920,7 +1071,7 @@ if [ "\$NFSROOT" = "1" ]; then
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 -e "\${RED}Hmmm... \$NEWROOT/etc/init.d/statelite doesn't exist. Perhaps you didn't run liteimg for the current osimage"
echo ""
shell
done
@ -986,6 +1137,7 @@ if [ "\$NFSROOT" = "1" ]; then
do
echo "\$NEWROOT/etc/init.d/statelite does not exist in image!"
shell
exit
done
# do all the mounts:
@ -1014,32 +1166,7 @@ if [ "\$NFSROOT" = "1" ]; then
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-\$IFACE.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
if [ -r /rootimg.sfs ]; then
echo Setting up squashfs with ram overlay.
mknod /dev/loop0 b 7 0
mkdir -p /ro
@ -1070,7 +1197,7 @@ EOMS
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 " /bin/sleep 5\n";
print $inifile " echo -n \$i...\n";
print $inifile " done\n";
print $inifile " echo\n";
@ -1096,22 +1223,18 @@ EOMS
print $inifile "exec switch_root -c /dev/console /sysroot /sbin/init\n";
close($inifile);
open($inifile,">"."/tmp/xcatinitrd.$$/bin/netstart");
print $inifile "#!/sbin/nash\n";
print $inifile "network --device \$IFACE --bootproto dhcp\n";
print $inifile "network --device \${1} --bootproto dhcp\n";
close($inifile);
chmod(0755,"/tmp/xcatinitrd.$$/init");
chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart");
chmod(0755,"/tmp/xcatinitrd.$$/init");
chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart");
@filestoadd=();
foreach (@ndrivers) {
if (-f "$customdir/$_") {
push @filestoadd,[$_,"lib/$_"];
if (-f "$customdir/$_") {
push @filestoadd,[$_,"lib/$_"];
} elsif (-f "$pathtofiles/$_") {
push @filestoadd,[$_,"lib/$_"];
push @filestoadd,[$_,"lib/$_"];
}
}
# add rsync for statelite
@ -1120,34 +1243,32 @@ EOMS
push @filestoadd,$_;
}
# Additional binaries needed for udev on s390x
if ($arch eq "s390x") {
foreach ("sbin/udevsettle", "sbin/udevtrigger", "sbin/udevd", "sbin/depmod") {
getlibs($_);
push @filestoadd,$_;
}
}
# Additional binaries needed for udev on s390x
if ($arch eq "s390x") {
foreach ("sbin/udevsettle", "sbin/udevtrigger", "sbin/udevd", "sbin/depmod") {
getlibs($_);
push @filestoadd,$_;
}
}
if ($arch =~ /x86_64/) {
push @filestoadd,"lib64/libnss_dns.so.2";
push @filestoadd,"lib64/libresolv.so.2";
}
else {
} else {
push @filestoadd,"lib/libnss_dns.so.2";
}
push @filestoadd,keys %libhash;
if($basekernelver ne $kernelver) {
system("rm -rf $rootimg_dir/lib/modules/$basekernelver");
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");
}
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) {
@ -1201,7 +1322,7 @@ EOMS
}
#copy("$rootimg_dir/lib/modules/*d","/tmp/xcatinitrd.$$/$_");
system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd.gz");
system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd-$mode.gz");
system("rm -rf /tmp/xcatinitrd.$$");
}
@ -1233,13 +1354,11 @@ sub isnetdriver {
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 "$rootimg_dir/opt/xcat/") {
mkdir "$rootimg_dir/opt/xcat/";
}
copy ("$installroot/postscripts/xcatdsklspost", "$rootimg_dir/opt/xcat/");
chmod '0755', "$rootimg_dir/opt/xcat/xcatdsklspost";
}
sub generic_post { #This function is meant to leave the image in a state approximating a normal install
@ -1251,17 +1370,18 @@ sub generic_post { #This function is meant to leave the image in a state approxi
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,size=$tmplimit 0 2\n";
print $cfgfile "tmpfs /var/tmp tmpfs defaults,size=$tmplimit 0 2\n";
}
if ($mode ne "statelite") {
my $rootfs_name=$profile."_".$arch;
print $cfgfile "$rootfs_name / tmpfs rw 0 1\n";
} else {
print $cfgfile "sunrpc /var/lib/nfs/rpc_pipefs rpc_pipefs rw 0 0\n";
print $cfgfile "tmpfs /tmp tmpfs defaults,size=10m 0 2\n";
print $cfgfile "tmpfs /var/tmp tmpfs defaults,size=10m 0 2\n";
}
my $rootfs_name=$profile."_".$arch;
print $cfgfile "$rootfs_name / tmpfs rw 0 1\n";
close($cfgfile);
open($cfgfile,">","$rootimg_dir/etc/sysconfig/network");
print $cfgfile "NETWORKING=yes\n";
@ -1271,7 +1391,7 @@ sub generic_post { #This function is meant to leave the image in a state approxi
close($cfgfile);
# open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$prinic");
# print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$prinic\n";
close($cfgfile);
# close($cfgfile);
foreach (split /,/,$othernics) {
if (/^$/) { next; }
open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$_");

View File

@ -21,14 +21,14 @@ profile=$4
workdir=$5
#-- Example how /etc/fstab can be automatically generated during image generation:
cat <<END >$installroot/etc/fstab
proc /proc proc rw 0 0
sysfs /sys sysfs rw 0 0
devpts /dev/pts devpts rw,gid=5,mode=620 0 0
#cat <<END >$installroot/etc/fstab
#proc /proc proc rw 0 0
#sysfs /sys sysfs rw 0 0
#devpts /dev/pts devpts rw,gid=5,mode=620 0 0
#${profile}_${arch} / tmpfs rw 0 1
none /tmp tmpfs defaults,size=10m 0 2
none /var/tmp tmpfs defaults,size=10m 0 2
END
#none /tmp tmpfs defaults,size=10m 0 2
#none /var/tmp tmpfs defaults,size=10m 0 2
#END
#-- Uncomment the line contains "cons" in /etc/inittab
#cons:12345:respawn:/sbin/smart_agetty -L 38400 console

File diff suppressed because it is too large Load Diff