461 lines
10 KiB
Perl
Executable File
461 lines
10 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
BEGIN
|
|
{
|
|
$::XCATROOT =
|
|
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
|
|
: -d '/opt/xcat' ? '/opt/xcat'
|
|
: '/usr';
|
|
}
|
|
use lib "$::XCATROOT/lib/perl";
|
|
use strict;
|
|
|
|
use Getopt::Long;
|
|
require xCAT::MsgUtils;
|
|
require xCAT::DSHCLI;
|
|
require xCAT::Client;
|
|
|
|
use xCAT::Utils;
|
|
use xCAT::TableUtils;
|
|
use File::Basename;
|
|
|
|
$::XCATROOT = "/opt/xcat";
|
|
my $os = "";
|
|
my $profile = "";
|
|
my $interface = "";
|
|
my $version;
|
|
my $drivers = "";
|
|
my $otherInterfaces = "";
|
|
my $kernel = "";
|
|
my @oses; # available OSes.
|
|
my @profiles; # available profiles
|
|
my $profDir; # root where you do ./genimage from
|
|
my $help;
|
|
my $match = 0;
|
|
my $imagename;
|
|
my $arch;
|
|
my $permission;
|
|
my $rootlimit;
|
|
my $tmplimit;
|
|
my $krpmver;
|
|
my $kerneldir;
|
|
my $mode;
|
|
my $interactive;
|
|
my $onlyinitrd;
|
|
my $dryrun;
|
|
my $ignorekernelchk;
|
|
my $noupdate;
|
|
#-----------------------------------------------------------------------------
|
|
|
|
=head3 print_usage - usage message
|
|
|
|
=cut
|
|
|
|
#-----------------------------------------------------------------------------
|
|
sub print_usage
|
|
{
|
|
print "Usage:\n";
|
|
print " genimage\n\n";
|
|
print " genimage --dryrun\n\n";
|
|
print ' genimage -o <osver> [-a <arch>] -p <profile> -i <nodebootif> -n <nodenetdrivers> [--onlyinitrd] [-r <otherifaces>] [-k <kernelver>] [-g <krpmver>] [-m statelite] [-l rootlimitsize] [-t tmplimitsize] [--permission <permission>] [--interactive] [--dryrun] [--noupdate]'."\n\n";
|
|
print ' genimage [-o <osver>] [-a <arch>] [-p <profile>] [-i <nodebootif>] [-n <nodenetdrivers>] [--onlyinitrd] [-r <otherifaces>] [-k <kernelver>] [-g <krpmver>] [-m statelite] [-l rootlimitsize] [-t tmplimitsize] [--permission <permission>] [--interactive] [--dryrun] [--noupdate] <imagename>'."\n\n";
|
|
print " --permission is used for statelite only\n";
|
|
print " -g is used for SLES only\n\n";
|
|
print " -m is used for urbuntu, debian and fedora12 only\n\n";
|
|
print "Examples:\n";
|
|
print " genimage\n";
|
|
print " genimage --interactive\n";
|
|
print " genimage -i eth0 -n tg3 -o sles11 -p compute\n";
|
|
print " genimage -i eth0 -n tg3 -o sles11 -p compute --onlyinitrd\n";
|
|
print " genimage -i eth0 -r eth1,eth2 -n tg3,bnx2 -o centos5.1 -p compute --interactive\n";
|
|
print " genimage -i eth0 -n tg3,bnx2 -o sles11 -p compute --dryrun\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 --interactive myimagename\n";
|
|
print " genimage myimagename\n";
|
|
}
|
|
|
|
if (!GetOptions(
|
|
'a=s' => \$arch,
|
|
'p=s' => \$profile,
|
|
'o=s' => \$os,
|
|
'n=s' => \$drivers,
|
|
'i=s' => \$interface,
|
|
'r=s' => \$otherInterfaces,
|
|
'l=s' => \$rootlimit,
|
|
't=s' => \$tmplimit,
|
|
'k=s' => \$kernel,
|
|
'g=s' => \$krpmver,
|
|
'm=s' => \$mode,
|
|
'permission=s' => \$permission,
|
|
'kerneldir=s' => \$kerneldir,
|
|
'interactive' => \$interactive,
|
|
'onlyinitrd' => \$onlyinitrd,
|
|
'dryrun' => \$dryrun,
|
|
'ignorekernelchk' => \$ignorekernelchk,
|
|
'noupdate' => \$noupdate,
|
|
'h|help' => \$help,
|
|
'v|version' => \$version,
|
|
)) {
|
|
&print_usage;
|
|
exit 1;
|
|
}
|
|
|
|
if($help){
|
|
&print_usage;
|
|
exit 0;
|
|
}
|
|
|
|
if ($version){
|
|
my $version = xCAT::Utils->Version();
|
|
xCAT::MsgUtils->message("N", $version);
|
|
exit 0;
|
|
|
|
}
|
|
if (@ARGV > 0) {
|
|
$imagename=$ARGV[0];
|
|
}
|
|
|
|
if ((!$imagename) && (!$profile) && (!$os) && (!$arch)) {
|
|
my $tmpimgs=`lsdef -t osimage -w provmethod=~'/statelite|netboot/' |cut -d' ' -f1`;
|
|
if ($? == 0) {
|
|
if (($tmpimgs) && ($tmpimgs !~ /^Could/)) { #Could is returned when the osimage table is empty
|
|
my @images=split('\n', $tmpimgs);
|
|
print "Do you want to re-generate an existing image from the osimage table? ";
|
|
print "[y/n] ";
|
|
my $conf = <stdin>;
|
|
chomp($conf);
|
|
if($conf ne "" && $conf !~/N|n|[Nn][Oo]/) {
|
|
$match = 0;
|
|
while(1){
|
|
print "Available images: \n";
|
|
foreach(sort @images){
|
|
print " $_\n";
|
|
}
|
|
# default is the first image
|
|
print "Which image do you want to re-generate? [";
|
|
print $images[0];
|
|
print "] ";
|
|
|
|
my $img = <stdin>;
|
|
chomp($img);
|
|
if($img eq ""){
|
|
$imagename = $images[0];
|
|
last;
|
|
}
|
|
foreach(@images){
|
|
if($img eq $_){
|
|
$imagename=$img;
|
|
$match = 1;
|
|
}
|
|
}
|
|
if ($match) {
|
|
last;
|
|
} else {
|
|
print "$img is not found in the osimage table.\n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
# get the install directory
|
|
my @entries = xCAT::TableUtils->get_site_attribute("installdir");
|
|
my $installdir = $entries[0];
|
|
chomp($installdir);
|
|
# lots of error checking to make sure it exists.
|
|
if($installdir eq ''){
|
|
print "Could not get install directory from site table. Assuming your OSes are stored in '/install'\n";
|
|
$installdir = "/install";
|
|
}
|
|
|
|
unless(-d $installdir){
|
|
print "The directory where your OS distributions resides: $installdir does not exist. Please check site table\n";
|
|
exit 1;
|
|
}
|
|
|
|
if ((!$imagename) && (!$os)){
|
|
my @dircontents = `ls $installdir`;
|
|
chomp(@dircontents);
|
|
foreach (@dircontents) {
|
|
# SL matches Scientific Linux, sl matches sles amd sled
|
|
if($_ =~ /(rhel|fedora|SL|centos|sl|suse)/){
|
|
push @oses,$_;
|
|
}
|
|
}
|
|
|
|
if($#oses eq -1){
|
|
print "There are no OS repositories in $installdir. Please run copycds for the OS first.\n";
|
|
exit 1;
|
|
}
|
|
|
|
# now they have the OSes, make sure they select one that is available
|
|
$match = 0;
|
|
while(1){
|
|
print "Available OSes: \n";
|
|
foreach(@oses){
|
|
print " $_\n";
|
|
}
|
|
# default is the first OS cause in many cases, they'll only have 1.
|
|
print "Which OS do you want to build a image for? [";
|
|
print $oses[0] ;
|
|
print "] ";
|
|
|
|
$os = <stdin>;
|
|
chomp($os);
|
|
if($os eq ""){
|
|
$os = $oses[0];
|
|
last;
|
|
}
|
|
foreach(@oses){
|
|
if($os eq $_){
|
|
$match = 1;
|
|
}
|
|
}
|
|
|
|
if($match){
|
|
last;
|
|
}else{
|
|
print "$os is not found in '$installdir'\n";
|
|
}
|
|
}
|
|
|
|
chomp($os);
|
|
}
|
|
if ($os) { print " OS: $os\n"; }
|
|
|
|
|
|
|
|
### Get the Profile ####
|
|
my $osfamily = $os;
|
|
$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";
|
|
}
|
|
|
|
#print "OSfamily: $osfamily\n";
|
|
$profDir = "$::XCATROOT/share/xcat/netboot/$osfamily";
|
|
unless(-d $profDir){
|
|
print "Unable to find genimage script in $profDir\n";
|
|
exit 1;
|
|
}
|
|
|
|
if ((!$imagename) && (!$profile)){
|
|
my $profDir2 = "$installdir/custom/netboot/$osfamily";
|
|
my @proList = `ls $profDir/*.pkglist`;
|
|
if (-d $profDir2) {
|
|
@proList = (@proList, `ls $profDir2/*.pkglist`);
|
|
}
|
|
my %seen = ();
|
|
foreach (@proList) {
|
|
my $f = basename($_);
|
|
$f =~ s/([^\.]*).*/$1/;
|
|
chomp($f);
|
|
$seen{$f}++;
|
|
}
|
|
@profiles = sort keys %seen;
|
|
if($#profiles eq -1){
|
|
print "There are no profiles in $::XCATROOT/share/xcat/netboot/$osfamily.\n";
|
|
exit 1;
|
|
}
|
|
$match = 0;
|
|
while(1){
|
|
print "Available Profiles for $os: \n";
|
|
foreach(@profiles){
|
|
print " $_\n";
|
|
}
|
|
# default is the first OS cause in many cases, they'll only have 1.
|
|
print "Which profile do you want to use for $os? [";
|
|
print "$profiles[0] ";
|
|
print "] ";
|
|
|
|
$profile = <stdin>;
|
|
chomp($profile);
|
|
if($profile eq ""){
|
|
$profile = $profiles[0];
|
|
last;
|
|
}
|
|
foreach(@profiles){
|
|
if($profile eq $_){
|
|
$match = 1;
|
|
}
|
|
}
|
|
if($match eq 1){
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
if ($profile) { print " Profile: $profile\n"; }
|
|
|
|
# get the interface
|
|
if ((!$imagename) && (!$interface)){
|
|
while(1){
|
|
print "OPTIONAL: Which specific network interface will the image boot from? [<blank>]";
|
|
$interface = <stdin>;
|
|
chomp($interface);
|
|
if($interface eq ""){
|
|
last;
|
|
}else{
|
|
print "You want your stateless machines to boot off of ";
|
|
print "$interface";
|
|
print "? ";
|
|
print "[Y/n] ";
|
|
my $conf = <stdin>;
|
|
chomp($conf);
|
|
if($conf eq ""){
|
|
last;
|
|
}
|
|
if($conf =~ /Y|y|[Yy][Ee][Ss]/){
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
if ($interface) { print " Interface: $interface\n"; }
|
|
else { print " No interface specified. The interface will be determined at network boot time.\n"; }
|
|
}
|
|
|
|
|
|
|
|
print "Generating image: \n";
|
|
my @arg;
|
|
if ($imagename) {
|
|
push @arg, "$imagename";
|
|
}
|
|
|
|
if ($interface) {
|
|
push @arg, "-i";
|
|
push @arg, "$interface";
|
|
}
|
|
if ($drivers) {
|
|
push @arg, "-n";
|
|
push @arg, "$drivers";
|
|
}
|
|
if ($os) {
|
|
push @arg, "-o";
|
|
push @arg, "$os";
|
|
}
|
|
if ($profile) {
|
|
push @arg, "-p";
|
|
push @arg, "$profile";
|
|
}
|
|
if ($arch) {
|
|
push @arg, "-a";
|
|
push @arg, "$arch";
|
|
}
|
|
|
|
if ($kernel) {
|
|
push @arg, "-k";
|
|
push @arg, "$kernel";
|
|
}
|
|
|
|
if($otherInterfaces){
|
|
push @arg, "-r";
|
|
push @arg, "$otherInterfaces";
|
|
}
|
|
|
|
if ($permission) {
|
|
push @arg, "--permission";
|
|
push @arg, "$permission";
|
|
}
|
|
|
|
if ($rootlimit) {
|
|
push @arg, "-l";
|
|
push @arg, "$rootlimit";
|
|
}
|
|
|
|
if($tmplimit) {
|
|
push @arg, "-t";
|
|
push @arg, "$tmplimit";
|
|
}
|
|
|
|
if ($krpmver) {
|
|
push @arg, "-g";
|
|
push @arg, "$krpmver";
|
|
}
|
|
|
|
if ($mode) {
|
|
push @arg, "-m";
|
|
push @arg, "$mode";
|
|
}
|
|
|
|
if ($kerneldir) {
|
|
push @arg, "--kerneldir";
|
|
push @arg, "$kerneldir";
|
|
}
|
|
|
|
my $tempfile="/tmp/xcat_genimage.$$";
|
|
push @arg, "--tempfile"; #this is the file that contains the output
|
|
push @arg, "$tempfile";
|
|
|
|
if ($interactive) {
|
|
push @arg, "--interactive";
|
|
}
|
|
|
|
|
|
if ($onlyinitrd) {
|
|
push @arg, "--onlyinitrd";
|
|
}
|
|
|
|
if ($dryrun) {
|
|
push @arg, "--dryrun";
|
|
}
|
|
|
|
if ($ignorekernelchk) {
|
|
push @arg, "--ignorekernelchk";
|
|
}
|
|
|
|
if ($noupdate) {
|
|
push @arg, "--noupdate";
|
|
}
|
|
|
|
my $cmdref;
|
|
push (@{$cmdref->{arg}}, @arg);
|
|
$cmdref->{command}->[0] = "genimage";
|
|
|
|
if (!$interactive) {
|
|
xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response);
|
|
exit $xCAT::Client::EXITCODE;
|
|
} else {
|
|
if ($dryrun) { exit 0; }
|
|
#when in interactive mode, first call genimage.pm get info from DB,
|
|
xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response);
|
|
|
|
#then call the specific genimage under /opt/xcat/share...
|
|
if (-f $tempfile) {
|
|
my $cmdname;
|
|
#read the command name
|
|
open(FILE1, "<$tempfile");
|
|
my @output = <FILE1>;
|
|
if (@output >0) {
|
|
$cmdname=$output[0];
|
|
} else {
|
|
close FILE1;
|
|
return 1;
|
|
}
|
|
close FILE1;
|
|
|
|
# run the specific genimage command
|
|
#print "cmdname=$cmdname\n";
|
|
system("$cmdname");
|
|
|
|
#then call genimage.pm to save the DB
|
|
my @arg1;
|
|
push @arg1, $tempfile;
|
|
my $request;
|
|
push (@{$request->{arg}}, @arg1);
|
|
$request->{command}->[0] = "saveimgdata";
|
|
xCAT::Client::submit_request($request, \&xCAT::Client::handle_response);
|
|
exit $xCAT::Client::EXITCODE;
|
|
} else {
|
|
exit 1;
|
|
}
|
|
}
|
|
|