#!/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; #----------------------------------------------------------------------------- =head3 print_usage - usage message =cut #----------------------------------------------------------------------------- sub print_usage { print "Usage:\n"; print " genimage\n\n"; print " genimage --dryrun\n\n"; print ' genimage -o [-a ] -p -i -n [--onlyinitrd] [-r ] [-k ] [-g ] [-m statelite] [-l rootlimitsize] [-t tmplimitsize] [--permission ] [--interactive] [--dryrun]'."\n\n"; print ' genimage [-o ] [-a ] [-p ] [-i ] [-n ] [--onlyinitrd] [-r ] [-k ] [-g ] [-m statelite] [-l rootlimitsize] [-t tmplimitsize] [--permission ] [--interactive] [--dryrun] '."\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, '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 = ; 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 = ; 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 = ; 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 = ; 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? []"; $interface = ; 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 = ; 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"; } 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 = ; 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; } }