mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-04 05:12:30 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			468 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			468 lines
		
	
	
		
			12 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]'."\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 = `XCATXMLTRACE=0 XCATBYPASS=0 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 $installdir = `XCATXMLTRACE=0 XCATBYPASS=0 lsdef -t site -o clustersite -i installdir|grep -w 'installdir'|cut -d= -f2`;
 | 
						|
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 == -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 == -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 == 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;
 | 
						|
    }
 | 
						|
}
 | 
						|
 |