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:
parent
5f4315fd34
commit
444bdd0b8e
@ -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#
|
||||
####################
|
||||
|
@ -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();
|
||||
|
@ -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"){
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
);
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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-$_");
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user