92e3700612
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@10183 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
358 lines
12 KiB
Perl
358 lines
12 KiB
Perl
package xCAT_plugin::genimage;
|
|
BEGIN
|
|
{
|
|
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
|
}
|
|
use lib "$::XCATROOT/lib/perl";
|
|
use xCAT::Utils;
|
|
use xCAT::SvrUtils;
|
|
use xCAT::Table;
|
|
use Data::Dumper;
|
|
use File::Path;
|
|
use Getopt::Long;
|
|
Getopt::Long::Configure("bundling");
|
|
Getopt::Long::Configure("pass_through");
|
|
|
|
my $prinic; #TODO be flexible on node primary nic
|
|
my $othernics; #TODO be flexible on node primary nic
|
|
my $netdriver;
|
|
my $arch;
|
|
my $profile;
|
|
my $osver;
|
|
my $rootlimit;
|
|
my $tmplimit;
|
|
my $installroot = "/install";
|
|
my $kerneldir;
|
|
my $kernelver = "";
|
|
my $imagename;
|
|
my $pkglist;
|
|
my $srcdir;
|
|
my $destdir;
|
|
my $srcdir_otherpkgs;
|
|
my $otherpkglist;
|
|
my $postinstall_filename;
|
|
my $rootimg_dir;
|
|
my $mode;
|
|
my $permission; #the permission works only for statelite mode currently
|
|
my $krpmver;
|
|
my $kerneldir;
|
|
my $mode;
|
|
|
|
|
|
|
|
sub handled_commands {
|
|
return {
|
|
genimage => "genimage",
|
|
}
|
|
}
|
|
|
|
sub process_request {
|
|
my $request = shift;
|
|
my $callback = shift;
|
|
my $doreq = shift;
|
|
my $installroot = xCAT::Utils->getInstallDir();
|
|
|
|
@ARGV = @{$request->{arg}};
|
|
|
|
#my $rsp;
|
|
#$rsp->{data}->[0]="genimage plugin gets called with ARGV=@ARGV" ;
|
|
#$callback->($rsp);
|
|
|
|
GetOptions(
|
|
'a=s' => \$arch,
|
|
'p=s' => \$profile,
|
|
'o=s' => \$osver,
|
|
'n=s' => \$netdriver,
|
|
'i=s' => \$prinic,
|
|
'r=s' => \$othernics,
|
|
'l=s' => \$rootlimit,
|
|
't=s' => \$tmplimit,
|
|
'k=s' => \$kernelver,
|
|
'g=s' => \$krpmver,
|
|
'm=s' => \$mode,
|
|
'kerneldir=s' => \$kerneldir,
|
|
'permission=s' => \$permission
|
|
);
|
|
|
|
my $osimagetab;
|
|
my $linuximagetab;
|
|
my $ref_linuximage_tab;
|
|
my $ref_osimage_tab;
|
|
my %keyhash = ();
|
|
my %updates_os = (); # the hash for updating osimage table
|
|
my %updates_linux = (); # the hash for updating linuximage table
|
|
|
|
#always save the input values to the db
|
|
if ($arch) { $updates_os{'osarch'}=$arch; }
|
|
if ($profile) { $updates_os{'profile'} = $profile; }
|
|
if ($osver) { $updates_os{'osvers'} = $osver; }
|
|
|
|
if ($netdriver) { $updates_linux{'netdrivers'} = $netdriver; }
|
|
if ($prinic) { $updates_linux{'nodebootif'} = $prinic; }
|
|
if ($othernics) { $updates_linux{'otherifce'} = $othernics; }
|
|
if ($kernelver) { $updates_linux{'kernelver'} = $kernelver; }
|
|
if ($krpmver) { $updates_linux{'krpmver'} = $krpmver; }
|
|
if ($kerneldir) { $updates_linux{'kerneldir'} = $kerneldir; }
|
|
if ($permission){ $updates_linux{'permission'} = $permission; }
|
|
|
|
# get the info from the osimage and linuximage table
|
|
$osimagetab = xCAT::Table->new('osimage', -create=>1);
|
|
unless ($osimagetab) {
|
|
$callback->({error=>["The osimage table cannot be open."],errorcode=>[1]});
|
|
return 1;
|
|
}
|
|
|
|
$linuximagetab = xCAT::Table->new('linuximage', -create=>1);
|
|
unless($linuximagetab) {
|
|
$callback->({error=>["The linuximage table cannot be open."],errorcode=>[1]});
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
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 1;
|
|
}
|
|
|
|
(my $ref_osimage_tab) = $osimagetab->getAttribs({imagename => $imagename}, 'osvers', 'osarch', 'profile', 'provmethod');
|
|
unless ($ref_osimage_tab) {
|
|
$callback->({error=>["Cannot find image \'$imagename\' from the osimage table."],errorcode=>[1]});
|
|
return 1;
|
|
}
|
|
|
|
(my $ref_linuximage_tab) = $linuximagetab->getAttribs({imagename => $imagename}, 'pkglist', 'pkgdir', 'otherpkglist', 'otherpkgdir', 'postinstall', 'rootimgdir', 'kerneldir', 'krpmver', 'nodebootif', 'otherifce', 'kernelver', 'netdrivers', 'permission');
|
|
unless ($ref_linuximage_tab) {
|
|
$callback->({error=>["Cannot find $imagename from the linuximage table."],errorcode=>[1]});
|
|
return 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) {
|
|
$callback->({error=>["osimage.osvers, osimage.osarch, osimage.profile and osimage.provmethod must be specified for the image $imagename in the database."],errorcode=>[1]});
|
|
return 1;
|
|
}
|
|
|
|
unless ($provmethod eq 'netboot' || $provmethod eq 'statelite') {
|
|
$callback->({error=>["\'$imagename\' cannot be used to build diskless image. Make sure osimage.provmethod is 'netboot'."],errorcode=>[1]});
|
|
return 1;
|
|
}
|
|
|
|
unless ( $ref_linuximage_tab->{'pkglist'}) {
|
|
$callback->({error=>["A .pkglist file must be specified for image \'$imagename\' in the linuximage table."],errorcode=>[1]});
|
|
return 1;
|
|
}
|
|
$pkglist = $ref_linuximage_tab->{'pkglist'};
|
|
|
|
$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'};
|
|
|
|
# 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'}) {
|
|
$callback->({info=>["The primary nic is different from the value in linuximage table, will update it."]});
|
|
$updates{'nodebootif'} = $prinic;
|
|
}
|
|
} else {
|
|
$prinic = $ref_linuximage_tab->{'nodebootif'};
|
|
}
|
|
if ($othernics) {
|
|
if ($othernics ne $ref_linuximage_tab->{'otherifce'}) {
|
|
$callback->({info=>["The other ifces are different from the value in linuximage table, will update it."]});
|
|
$updates{'otherifce'} = $othernics;
|
|
}
|
|
} else {
|
|
$othernics = $ref_linuximage_tab->{'otherifce'};
|
|
}
|
|
if ($kernelver) {
|
|
if ($kernelver ne $ref_linuximage_tab->{'kernelver'}) {
|
|
$callback->({info=>["The kernelver is different from the value in linuximage table, will update it."]});
|
|
$updates{'kernelver'} = $kernelver;
|
|
}
|
|
} else {
|
|
$kernelver = $ref_linuximage_tab->{'kernelver'};
|
|
}
|
|
|
|
if ($krpmver) {
|
|
if ($krpmver ne $ref_linuximage_tab->{'krpmver'}) {
|
|
$callback->({info=>["The krpmver is different from the value in linuximage table, will update it."]});
|
|
$updates{'krpmver'} = $krpmver;
|
|
}
|
|
} else {
|
|
$krpmver = $ref_linuximage_tab->{'krpmver'};
|
|
}
|
|
|
|
if ($kerneldir) {
|
|
if ($kerneldir ne $ref_linuximage_tab->{'kerneldir'}) {
|
|
print "The kerneldir is different from the value in linuximage table, will update it\n";
|
|
$updates{'kerneldir'} = $kerneldir;
|
|
}
|
|
} else {
|
|
$kerneldir = $ref_linuximage_tab->{'kerneldir'};
|
|
}
|
|
if ($netdriver) {
|
|
if ($netdriver ne $ref_linuximage_tab->{'netdrivers'}) {
|
|
$callback->({info=>["The netdrivers is different from the value in linuximage table, will update it."]});
|
|
$updates{'netdrivers'} = $netdriver;
|
|
}
|
|
} else {
|
|
$netdriver = $ref_linuximage_tab->{'netdrivers'};
|
|
}
|
|
|
|
if ($permission) {
|
|
if ($permission ne $ref_linuximage_tab->{'permission'}) {
|
|
$callback->({info=>["The permission is different from the value in linuximage table, will update it."]});
|
|
$updates{'permission'} = $permission;
|
|
}
|
|
} else {
|
|
$permission = $ref_linuximage_tab->{'permission'};
|
|
}
|
|
}
|
|
|
|
|
|
### Get the Profile ####
|
|
my $osfamily = $osver;
|
|
$osfamily =~ s/\d+//g;
|
|
$osfamily =~ s/\.//g;
|
|
if($osfamily =~ /rh/){
|
|
$osfamily = "rh";
|
|
}
|
|
|
|
# OS version on s390x can contain 'sp', e.g. sles11sp1
|
|
# If the $osfamily contains 'sles' and 'sp', the $osfamily = sles
|
|
if ($osfamily =~ /sles/ && $osfamily =~ /sp/) {
|
|
$osfamily = "sles";
|
|
}
|
|
|
|
$osfamily =~ s/ //g;
|
|
|
|
#-m flag is used only for ubuntu, debian and ferdora12, for others genimage will create
|
|
#initrd.gz for both netboot and statelite, no -m is needed.
|
|
if ($mode) {
|
|
if (($osfamily ne "ubuntu") && ($osfamily ne "debian") && ($osver !~ /fedora12/)) {
|
|
$mode="";
|
|
$callback->({error=>["-m flag is valid for Ubuntu, Debian and Fedora12 only."],errorcode=>[1]});
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
$profDir = "$::XCATROOT/share/xcat/netboot/$osfamily";
|
|
unless(-d $profDir){
|
|
$callback->({error=>["Unable to find genimage script in $profDir."],errorcode=>[1]});
|
|
return 1;
|
|
}
|
|
|
|
if ($krpmver) {
|
|
if ($osfamily ne "sles") {
|
|
$krpmver="";
|
|
$callback->({error=>["-g flag is valid for Sles only."],errorcode=>[1]});
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
my $cmd="cd $profDir; ./genimage";
|
|
if ($arch) { $cmd .= " -a $arch";}
|
|
if ($osver) { $cmd .= " -o $osver";}
|
|
if ($profile) { $cmd .= " -p $profile";}
|
|
|
|
if ($netdriver) { $cmd .= " -n $netdriver";}
|
|
if ($prinic) { $cmd .= " -i $prinic";}
|
|
if ($othernics) { $cmd .= " -r $othernics";}
|
|
if ($rootlimit) { $cmd .= " -l $rootlimit";}
|
|
if ($tmplimit) { $cmd .= " -t $tmplimit";}
|
|
if ($kernelver) { $cmd .= " -k $kernelver";}
|
|
if ($krpmver) { $cmd .= " -g $krpmver";}
|
|
if ($mode) { $cmd .= " -m $mode";}
|
|
if ($permission) { $cmd .= " --permission $permission"; }
|
|
if ($kerneldir) { $cmd .= " --kerneldir $kerneldir"; }
|
|
|
|
$cmd.= " --internal";
|
|
if ($srcdir) { $cmd .= " --srcdir $srcdir";}
|
|
if ($pkglist) { $cmd .= " --pkglist $pkglist";}
|
|
if ($srcdir_otherpkgs) { $cmd .= " --otherpkgdir $srcdir_otherpkgs"; }
|
|
if ($otherpkglist) { $cmd .= " --otherpkglist $otherpkglist"; }
|
|
if ($postinstall_filename) { $cmd .= " --postinstall $postinstall_filename"; }
|
|
if ($destdir) { $cmd .= " --rootimgdir $destdir"; }
|
|
|
|
if ($imagename) {
|
|
$cmd.= " $imagename";
|
|
}
|
|
|
|
# now run the specific genimage command
|
|
$callback->({info=>["$cmd"]});
|
|
$::CALLBACK=$callback;
|
|
#my $output = xCAT::Utils->runcmd("$cmd", 0, 1);
|
|
my $output = xCAT::Utils->runcmd_S("$cmd", 0, 1); # stream output
|
|
open(FILE, ">/tmp/genimageoutput");
|
|
foreach my $entry (@$output) {
|
|
print FILE $entry;
|
|
print FILE "\n";
|
|
}
|
|
close FILE;
|
|
|
|
#save the new settings to the osimage and linuximage tables
|
|
$cmd="cat /tmp/genimageoutput";
|
|
$output = xCAT::Utils->runcmd("$cmd", 0, 1);
|
|
if ($output && (@$output > 0)) {
|
|
my $i=0;
|
|
while ($i < @$output) {
|
|
if ( $output->[$i] =~ /The output for table updates starts here/) {
|
|
#print "----got here $i\n";
|
|
my $tn;
|
|
my %keyhash;
|
|
my %updates;
|
|
my $s1=$output->[$i +1];
|
|
my $s2=$output->[$i +2];
|
|
my $s3=$output->[$i +3];
|
|
if ($s1 =~ /^table::(.*)$/) {
|
|
$tn=$1;
|
|
}
|
|
if ($s2 =~ /^imagename::(.*)$/) {
|
|
$keyhash{'imagename'} = $1;
|
|
}
|
|
|
|
if ($tn eq 'osimage') {
|
|
%updates=%updates_os;
|
|
} elsif ($tn eq 'linuximage') {
|
|
%updates=%updates_linux;
|
|
}
|
|
|
|
my @a=split("::", $s3);
|
|
for (my $j=0; $j < @a; $j=$j+2) {
|
|
$updates{$a[$j]} = $a[$j+1];
|
|
}
|
|
splice(@$output, $i, 5);
|
|
if (($tn) && (keys(%keyhash) > 0) && (keys(%updates) > 0)) {
|
|
my $tab= xCAT::Table->new($tn, -create=>1);
|
|
if ($tab) {
|
|
$tab->setAttribs(\%keyhash, \%updates);
|
|
#print "table=$tn,%keyhash,%updates\n";
|
|
#print Dumper(%keyhash);
|
|
#print Dumper(%updates);
|
|
}
|
|
}
|
|
} else {
|
|
$i++;
|
|
}
|
|
}
|
|
# remove tmp file
|
|
#`rm /tmp/genimageoutput`;
|
|
#remove the database upgrade section
|
|
# runcmd_S displays the output
|
|
#$callback->({info=>$output});
|
|
}
|
|
}
|
|
|
|
1;
|