2013-07-15 03:05:27 +00:00
# IBM(c) 2013 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT_plugin::geninitrd ;
BEGIN
{
$ ::XCATROOT = $ ENV { 'XCATROOT' } ? $ ENV { 'XCATROOT' } : '/opt/xcat' ;
}
use strict ;
use lib "$::XCATROOT/lib/perl" ;
2013-07-31 10:57:34 +00:00
use File::Path ;
2013-07-15 03:05:27 +00:00
use File::Copy ;
use xCAT::MsgUtils ;
use xCAT::TableUtils ;
use xCAT::Table ;
use xCAT::Scope ;
sub handled_commands
{
return {
geninitrd = > "geninitrd" ,
}
}
sub preprocess_request
{
my $ req = shift ;
my $ callback = shift ;
2013-08-12 15:18:49 +00:00
my $ usage = sub {
my $ callback = shift ;
2013-11-19 11:27:11 +00:00
xCAT::MsgUtils - > message ( "I" , { data = > [ "Usage: geninitrd <imagename> [--ignorekernelchk] [-h | --help]" ] } , $ callback ) ;
2013-08-12 15:18:49 +00:00
} ;
my $ osimage ;
2013-11-19 11:27:11 +00:00
my $ ignorekernelchk ;
2013-08-12 15:18:49 +00:00
if ( defined ( $ req - > { arg } ) ) {
foreach ( @ { $ req - > { arg } } ) {
if ( /^-/ ) {
2013-11-19 11:27:11 +00:00
if ( /--ignorekernelchk/ ) {
$ ignorekernelchk = 1 ;
} else {
$ usage - > ( $ callback ) ;
return ;
}
2013-08-12 15:18:49 +00:00
} else {
$ osimage = $ _ ;
}
}
} else {
$ usage - > ( $ callback ) ;
return ;
}
unless ( $ osimage ) {
$ usage - > ( $ callback ) ;
2013-07-15 03:05:27 +00:00
return ;
}
2013-11-19 11:27:11 +00:00
$ req - > { 'ignorekernelchk' } = [ $ ignorekernelchk ] ;
2013-07-15 03:05:27 +00:00
#if tftpshared is not set, dispatch this command to all the service nodes
my @ entries = xCAT::TableUtils - > get_site_attribute ( "sharedtftp" ) ;
my $ t_entry = $ entries [ 0 ] ;
if ( defined ( $ t_entry ) and ( $ t_entry == 0 or $ t_entry =~ /no/i ) ) {
2013-11-19 11:27:11 +00:00
$ req - > { '_disparatetftp' } = [ 1 ] ;
2013-07-15 03:05:27 +00:00
return xCAT::Scope - > get_broadcast_scope ( $ req , @ _ ) ;
}
return [ $ req ] ;
}
sub process_request
{
my $ req = shift ;
my $ callback = shift ;
2013-08-12 15:18:49 +00:00
my $ doreq = shift ;
2013-07-15 03:05:27 +00:00
if ( $ req - > { command } - > [ 0 ] eq 'geninitrd' )
{
2013-08-12 15:18:49 +00:00
return geninitrd ( $ req , $ callback , $ doreq ) ;
2013-07-15 03:05:27 +00:00
}
}
sub geninitrd {
my $ req = shift ;
my $ callback = shift ;
2013-08-12 15:18:49 +00:00
my $ doreq = shift ;
2013-07-15 03:05:27 +00:00
my $ osimage = $ req - > { arg } - > [ 0 ] ;
2013-11-19 11:27:11 +00:00
my $ ignorekernelchk ;
if ( defined ( $ req - > { 'ignorekernelchk' } ) && $ req - > { 'ignorekernelchk' } - > [ 0 ] ) {
$ ignorekernelchk = $ req - > { 'ignorekernelchk' } - > [ 0 ] ;
}
2013-07-15 03:05:27 +00:00
my ( $ osvers , $ arch , $ pkgdir , $ driverupdatesrc , $ netdrivers , $ osdisupdir ) ;
# get attributes from osimage table
my $ osimagetab = xCAT::Table - > new ( 'osimage' ) ;
unless ( $ osimagetab ) {
xCAT::MsgUtils - > message ( "E" , { error = > [ "Cannot open the table osimage." ] , errorcode = > [ "1" ] } , $ callback ) ;
return ;
}
2013-08-12 15:18:49 +00:00
my $ oient = $ osimagetab - > getAttribs ( { imagename = > $ osimage } , 'provmethod' , 'osvers' , 'osarch' , 'osupdatename' ) ;
2013-07-15 03:05:27 +00:00
unless ( $ oient && $ oient - > { 'osvers' } && $ oient - > { 'osarch' } ) {
xCAT::MsgUtils - > message ( "E" , { error = > [ "The osimage [$osimage] was not defined or [osvers, osarch] attributes were not set." ] , errorcode = > [ "1" ] } , $ callback ) ;
return ;
}
$ osvers = $ oient - > { 'osvers' } ;
$ arch = $ oient - > { 'osarch' } ;
# get attributes from linuximage table
my $ linuximagetab = xCAT::Table - > new ( 'linuximage' ) ;
unless ( $ linuximagetab ) {
xCAT::MsgUtils - > message ( "E" , { error = > [ "Cannot open the table linuximage." ] , errorcode = > [ "1" ] } , $ callback ) ;
return ;
}
2013-08-12 15:18:49 +00:00
my $ lient = $ linuximagetab - > getAttribs ( { imagename = > $ osimage } , 'rootimgdir' , 'pkgdir' , 'driverupdatesrc' , 'netdrivers' ) ;
2013-07-15 03:05:27 +00:00
unless ( $ lient && $ lient - > { 'pkgdir' } ) {
xCAT::MsgUtils - > message ( "E" , { error = > [ "The osimage [$osimage] was not defined or [pkgdir] attribute was not set." ] , errorcode = > [ "1" ] } , $ callback ) ;
return ;
}
$ pkgdir = $ lient - > { 'pkgdir' } ;
$ driverupdatesrc = $ lient - > { 'driverupdatesrc' } ;
$ netdrivers = $ lient - > { 'netdrivers' } ;
2013-08-12 15:18:49 +00:00
# if the provmethod equals 'netboot', call the genimage --onlyinitrd directly
2013-08-22 11:05:41 +00:00
if ( $ oient - > { 'provmethod' } && ( $ oient - > { 'provmethod' } eq "netboot" || $ oient - > { 'provmethod' } eq "statelite" ) ) {
2013-08-12 15:18:49 +00:00
if ( $ lient - > { 'rootimgdir' } ) {
unless ( - d $ lient - > { 'rootimgdir' } . "/rootimg/lib/modules" ) {
xCAT::MsgUtils - > message ( "E" , { error = > [ "The genimage should be run before running geninitrd." ] , errorcode = > [ "1" ] } , $ callback ) ;
return ;
}
} else {
xCAT::MsgUtils - > message ( "E" , { error = > [ "The rootimgdir attribute for the osimage should be set." ] , errorcode = > [ "1" ] } , $ callback ) ;
return ;
}
my @ output = `genimage $osimage --onlyinitrd` ;
xCAT::MsgUtils - > message ( "I" , { data = > \ @ output } , $ callback ) ;
#$doreq->({ command => ['genimage'],
# arg => [$osimage, '--onlyinitrd'] }, $callback);
return ;
} elsif ( ! $ oient - > { 'provmethod' } || $ oient - > { 'provmethod' } ne "install" ) {
2013-08-22 11:05:41 +00:00
xCAT::MsgUtils - > message ( "E" , { error = > [ "The attribute [provmethod] for osimage [$osimage] must be set to install, netboot or statelite." ] , errorcode = > [ "1" ] } , $ callback ) ;
2013-08-12 15:18:49 +00:00
return ;
}
2013-07-15 03:05:27 +00:00
# get the path list of the osdistroupdate
if ( $ oient - > { 'osupdatename' } ) {
my @ osupdatenames = split ( /,/ , $ oient - > { 'osupdatename' } ) ;
my $ osdistrouptab = xCAT::Table - > new ( 'osdistroupdate' , - create = > 1 ) ;
unless ( $ osdistrouptab ) {
xCAT::MsgUtils - > message ( "E" , { error = > [ "Cannot open the table osdistroupdate." ] , errorcode = > [ 1 ] } , $ callback ) ;
return ;
}
my @ osdup = $ osdistrouptab - > getAllAttribs ( "osupdatename" , "dirpath" ) ;
foreach my $ upname ( @ osupdatenames ) {
foreach my $ upref ( @ osdup ) {
if ( $ upref - > { 'osupdatename' } eq $ upname ) {
$ osdisupdir . = ",$upref->{'dirpath'}" ;
last ;
}
}
}
$ osdisupdir =~ s/^,// ;
}
# get the source path of initrd and kernel from the pkgdir of osimage
# copy the initrd and kernel to /tftpboot
# pass the path of initrd and kernel in /tftpboot to insertdd
my $ initrdpath ;
my $ kernelpath ;
my $ tftpdir = "/tftpboot" ;
my @ entries = xCAT::TableUtils - > get_site_attribute ( "$tftpdir" ) ;
my $ t_entry = $ entries [ 0 ] ;
if ( defined ( $ t_entry ) ) {
$ tftpdir = $ t_entry ;
}
my $ tftppath = "$tftpdir/xcat/osimage/$osimage" ;
2013-07-31 10:57:34 +00:00
unless ( - d $ tftppath ) {
mkpath $ tftppath ;
}
2013-07-15 03:05:27 +00:00
if ( $ arch =~ /x86/ ) {
if ( $ osvers =~ /(^ol[0-9].*)|(centos.*)|(rh.*)|(fedora.*)|(SL.*)/ ) {
$ kernelpath = "$tftppath/vmlinuz" ;
copy ( "$pkgdir/images/pxeboot/vmlinuz" , $ kernelpath ) ;
$ initrdpath = "$tftppath/initrd.img" ;
copy ( "$pkgdir/images/pxeboot/initrd.img" , $ initrdpath ) ;
} elsif ( $ osvers =~ /(sles.*)|(suse.*)/ ) {
$ kernelpath = "$tftppath/linux" ;
copy ( "$pkgdir/1/boot/$arch/loader/linux" , $ kernelpath ) ;
$ initrdpath = "$tftppath/initrd" ;
copy ( "$pkgdir/1/boot/$arch/loader/initrd" , $ initrdpath ) ;
} else {
xCAT::MsgUtils - > message ( "E" , { error = > [ "unknow osvers [$osvers]." ] , errorcode = > [ 1 ] } , $ callback ) ;
return ;
}
} elsif ( $ arch =~ /ppc/ ) {
if ( $ osvers =~ /(^ol[0-9].*)|(centos.*)|(rh.*)|(fedora.*)|(SL.*)/ ) {
$ kernelpath = "$tftppath/vmlinuz" ;
copy ( "$pkgdir/ppc/ppc64/vmlinuz" , $ kernelpath ) ;
if ( - r "$pkgdir/ppc/ppc64/ramdisk.image.gz" ) {
$ initrdpath = "$tftppath/initrd.img" ;
copy ( "$pkgdir/ppc/ppc64/ramdisk.image.gz" , $ initrdpath ) ;
} elsif ( - r "$pkgdir/ppc/ppc64/initrd.img" ) {
$ initrdpath = "$tftppath/initrd.img" ;
copy ( "$pkgdir/ppc/ppc64/initrd.img" , $ initrdpath ) ;
}
} elsif ( $ osvers =~ /(sles.*)|(suse.*)/ ) {
$ kernelpath = undef ;
$ initrdpath = "$tftppath/inst64" ;
copy ( "$pkgdir/1/suseboot/inst64" , $ initrdpath ) ;
} else {
xCAT::MsgUtils - > message ( "E" , { error = > [ "unknow osvers [$osvers]." ] , errorcode = > [ 1 ] } , $ callback ) ;
return ;
}
} else {
xCAT::MsgUtils - > message ( "E" , { error = > [ "unknow arch [$arch]." ] , errorcode = > [ 1 ] } , $ callback ) ;
return ;
}
# call the insert_dd function in the anaconda or sles to hack the initrd that:
# 1. Get the new kernel from update distro and copy it to /tftpboot
# 2. Inject the drivers to initrd in /tftpboot base on the new kernel ver
if ( $ osvers =~ /(^ol[0-9].*)|(centos.*)|(rh.*)|(fedora.*)|(SL.*)/ ) {
require xCAT_plugin::anaconda ;
2013-11-19 11:27:11 +00:00
xCAT_plugin::anaconda - > insert_dd ( $ callback , $ osvers , $ arch , $ initrdpath , $ kernelpath , $ driverupdatesrc , $ netdrivers , $ osdisupdir , $ ignorekernelchk ) ;
2013-07-15 03:05:27 +00:00
} elsif ( $ osvers =~ /(sles.*)|(suse.*)/ ) {
require xCAT_plugin::sles ;
2013-11-19 11:27:11 +00:00
xCAT_plugin::sles - > insert_dd ( $ callback , $ osvers , $ arch , $ initrdpath , $ kernelpath , $ driverupdatesrc , $ netdrivers , $ osdisupdir , $ ignorekernelchk ) ;
2013-07-15 03:05:27 +00:00
}
}
1 ;