mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-04 05:12:30 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			280 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			280 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env perl
 | 
						|
# generate the image for mic
 | 
						|
# Since the root file system for mic is generated on the host by
 | 
						|
# micctrl command, this script only help to generate the /etc/hosts,
 | 
						|
# /root/.ssh from the management node to the root file system.
 | 
						|
 | 
						|
BEGIN
 | 
						|
{
 | 
						|
    $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
 | 
						|
}
 | 
						|
use lib "$::XCATROOT/lib/perl";
 | 
						|
 | 
						|
use strict;
 | 
						|
use File::Path;
 | 
						|
use File::Basename;
 | 
						|
use File::Copy;
 | 
						|
use File::Find;
 | 
						|
use Getopt::Long;
 | 
						|
Getopt::Long::Configure("bundling");
 | 
						|
Getopt::Long::Configure("pass_through");
 | 
						|
 | 
						|
use FindBin;
 | 
						|
use lib "$FindBin::Bin/../imgutils";
 | 
						|
use imgutils;
 | 
						|
use xCAT::Table;
 | 
						|
 | 
						|
 | 
						|
my $arch;
 | 
						|
my $profile;
 | 
						|
my $osver;
 | 
						|
my $pkglist;
 | 
						|
my $srcdir;
 | 
						|
my $otherpkglist;
 | 
						|
my $rootimg_dir;
 | 
						|
my $srcdir_otherpkgs;
 | 
						|
my $tempfile;
 | 
						|
my $postinstall;
 | 
						|
my $rootimgdir;
 | 
						|
my $prompt;
 | 
						|
 | 
						|
my $imagename;
 | 
						|
 | 
						|
GetOptions(
 | 
						|
    'a=s'            => \$arch,
 | 
						|
    'p=s'            => \$profile,
 | 
						|
    'o=s'            => \$osver,
 | 
						|
    'pkglist=s'      => \$pkglist,
 | 
						|
    'srcdir=s'       => \$srcdir,
 | 
						|
    'otherpkglist=s' => \$otherpkglist,
 | 
						|
    'otherpkgdir=s'  => \$srcdir_otherpkgs,
 | 
						|
    'tempfile=s'     => \$tempfile,
 | 
						|
    'postinstall=s'  => \$postinstall,
 | 
						|
    'rootimgdir=s'   => \$rootimgdir,
 | 
						|
    'imagename=s'    => \$imagename,
 | 
						|
    'interactive'    => \$prompt,
 | 
						|
);
 | 
						|
 | 
						|
if ($rootimgdir) {
 | 
						|
    $rootimg_dir = $rootimgdir . "/rootimg";    # for 2.8.4 and later
 | 
						|
} else {
 | 
						|
    $rootimg_dir = "$srcdir/overlay/package"; # for 2.8.3 that rootimgdir was not set by default
 | 
						|
}
 | 
						|
 | 
						|
my @yumdirs;
 | 
						|
if (!$imagename && @ARGV > 0) {
 | 
						|
    $imagename = $ARGV[0];
 | 
						|
}
 | 
						|
unless ($imagename) {
 | 
						|
    print "Error: osimage name needs be specified.\n";
 | 
						|
    exit 1;
 | 
						|
}
 | 
						|
 | 
						|
sub isyumdir {
 | 
						|
    if ($File::Find::name =~ /\/repodata$/) {
 | 
						|
        my $location = $File::Find::name;
 | 
						|
        $location =~ s/\/repodata$//;
 | 
						|
        push @yumdirs, $location;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
# creae default paths
 | 
						|
mkpath "$srcdir/common";
 | 
						|
mkpath "$srcdir/overlay/rootimg";
 | 
						|
mkpath "$srcdir/overlay/simple";
 | 
						|
mkpath "$srcdir/overlay/package";
 | 
						|
mkpath "$srcdir/overlay/rpm";
 | 
						|
 | 
						|
if ($otherpkglist) {
 | 
						|
 | 
						|
    # get the distroname
 | 
						|
    my $oitab = xCAT::Table->new('osimage');
 | 
						|
    unless ($oitab) {
 | 
						|
        print "Error: Cannot open table osimage.\n";
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
 | 
						|
    # generate the yum configuration file
 | 
						|
 | 
						|
    my $aiddistro;
 | 
						|
    my $oient = $oitab->getAttribs({ 'imagename' => $imagename }, 'osdistroname');
 | 
						|
    if ($oient && $oient->{'osdistroname'}) {
 | 
						|
        $aiddistro = $oient->{'osdistroname'};
 | 
						|
    }
 | 
						|
 | 
						|
    my $distrotab = xCAT::Table->new('osdistro');
 | 
						|
    unless ($distrotab) {
 | 
						|
        print "Error: Cannot open table osdistro.\n";
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
    my $aiddistrodir;
 | 
						|
    my $distroent = $distrotab->getAttribs({ 'osdistroname' => $aiddistro }, 'dirpaths');
 | 
						|
    if ($distroent && $distroent->{'dirpaths'}) {
 | 
						|
        $aiddistrodir = $distroent->{'dirpaths'}
 | 
						|
    }
 | 
						|
 | 
						|
    my @pkgdirs = split(",", $aiddistrodir);
 | 
						|
    foreach my $dir (@pkgdirs) {
 | 
						|
        find(\&isyumdir, <$dir/>);
 | 
						|
        if (!grep /$dir/, @yumdirs) {
 | 
						|
            print "The repository for $dir should be created before running the genimge. Try to run [createrepo $dir].\n";
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    my $yumconfig;
 | 
						|
    open($yumconfig, ">", "/tmp/genimage.$$.yum.conf");
 | 
						|
    my $repnum = 0;
 | 
						|
    foreach $srcdir (@yumdirs) {
 | 
						|
        print $yumconfig "[$aiddistro-$repnum]\nname=$aiddistro-$repnum\nbaseurl=file://$srcdir\ngpgpcheck=0\n\n";
 | 
						|
        $repnum += 1;
 | 
						|
    }
 | 
						|
    $repnum -= 1;
 | 
						|
    close($yumconfig);
 | 
						|
    mkpath "$rootimg_dir/etc";
 | 
						|
 | 
						|
    my %extra_hash = imgutils::get_package_names($otherpkglist);
 | 
						|
    my %extrapkgnames;
 | 
						|
 | 
						|
    my %repohash;
 | 
						|
    if (keys(%extra_hash) > 0) {
 | 
						|
        open($yumconfig, ">>", "/tmp/genimage.$$.yum.conf");
 | 
						|
        my $index = 1;
 | 
						|
        my $pass;
 | 
						|
        foreach $pass (sort { $a <=> $b } (keys(%extra_hash))) {
 | 
						|
            foreach (keys(%{ $extra_hash{$pass} })) {
 | 
						|
                if ($_ eq "INCLUDEBAD") {
 | 
						|
                    print "Unable to open the following pkglist files:\n" . join("\n", @{ $extra_hash{$pass}{INCLUDEBAD} });
 | 
						|
                    exit 1;
 | 
						|
                }
 | 
						|
 | 
						|
                if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next; }
 | 
						|
                print $yumconfig "[otherpkgs$index]\nname=otherpkgs$index\nbaseurl=file://$srcdir_otherpkgs/$_\ngpgpcheck=0\n\n";
 | 
						|
                $repohash{$pass}{$index} = 1;
 | 
						|
                $index++;
 | 
						|
                my $pa = $extra_hash{$pass}{$_};
 | 
						|
                $extrapkgnames{$pass} .= " " . join(' ', @$pa);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        close($yumconfig);
 | 
						|
        $index--;
 | 
						|
        my $yumcmd_base = "yum -y -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* ";
 | 
						|
        foreach (0 .. $repnum) {
 | 
						|
            $yumcmd_base .= "--enablerepo=$aiddistro-$_ ";
 | 
						|
        }
 | 
						|
 | 
						|
        foreach $pass (sort { $a <=> $b } (keys(%extra_hash))) {
 | 
						|
            my $yumcmd = $yumcmd_base;
 | 
						|
            foreach my $repo_index (keys %{ $repohash{$pass} }) {
 | 
						|
                $yumcmd .= "--enablerepo=otherpkgs$repo_index ";
 | 
						|
            }
 | 
						|
 | 
						|
            system("$yumcmd clean all");
 | 
						|
 | 
						|
            my $envlist;
 | 
						|
            if (exists($extra_hash{$pass}{ENVLIST})) {
 | 
						|
                $envlist = join(' ', @{ $extra_hash{$pass}{ENVLIST} });
 | 
						|
            }
 | 
						|
 | 
						|
            # remove the packages that are specified in the otherpkgs.list files with leading '-'
 | 
						|
            my $yumcmd_remove = "$yumcmd erase ";
 | 
						|
            if (exists($extra_hash{$pass}{'PRE_REMOVE'})) {
 | 
						|
                my $pa = $extra_hash{$pass}{'PRE_REMOVE'};
 | 
						|
                my $rm_packges = join(' ', @$pa);
 | 
						|
                if ($rm_packges) {
 | 
						|
                    print "$envlist $yumcmd_remove $rm_packges\n";
 | 
						|
                    my $rc = system("$envlist $yumcmd_remove $rm_packges");
 | 
						|
                    if ($rc) {
 | 
						|
                        print "yum invocation failed\n";
 | 
						|
                        exit 1;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            # install extra packages
 | 
						|
            $yumcmd .= "install ";
 | 
						|
 | 
						|
            # append extra pkg names to yum command
 | 
						|
            if ($extrapkgnames{$pass}) {
 | 
						|
                $yumcmd .= " $extrapkgnames{$pass} ";
 | 
						|
                $yumcmd =~ s/ $/\n/;
 | 
						|
 | 
						|
                print "$envlist $yumcmd\n";
 | 
						|
                my $rc = system("$envlist $yumcmd");
 | 
						|
                if ($rc) {
 | 
						|
                    print "yum invocation failed\n";
 | 
						|
                    exit 1;
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                print "No Packages marked for install\n";
 | 
						|
            }
 | 
						|
 | 
						|
            # remove the packages that are specified in the otherpkgs.list files with leading '--'
 | 
						|
            if (exists($extra_hash{$pass}{'POST_REMOVE'})) {
 | 
						|
                my $pa = $extra_hash{$pass}{'POST_REMOVE'};
 | 
						|
                my $rm_packges = join(' ', @$pa);
 | 
						|
                if ($rm_packges) {
 | 
						|
                    print "$envlist $yumcmd_remove $rm_packges\n";
 | 
						|
                    my $rc = system("$envlist $yumcmd_remove $rm_packges");
 | 
						|
                    if ($rc) {
 | 
						|
                        print "yum invocation failed\n";
 | 
						|
                        exit 1;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
# run postinstall scripts
 | 
						|
foreach my $post (split /,/, $postinstall) {
 | 
						|
    if (!-x $post) {
 | 
						|
        print "postinstall script $post is not executable\n";
 | 
						|
        exit 1;
 | 
						|
    }
 | 
						|
    my $rc = system($postinstall, $rootimg_dir, $osver, $arch, $profile);
 | 
						|
    if ($rc) {
 | 
						|
        print "postinstall script $post failed\n";
 | 
						|
        exit 1;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
my $fsdir     = "$srcdir/";
 | 
						|
my $systemdir = "$fsdir/system";
 | 
						|
mkpath($systemdir);
 | 
						|
 | 
						|
# this is the file list which includes the files which should be copied
 | 
						|
# from MN to the root file system
 | 
						|
my @sysfilelist = (
 | 
						|
    "/etc/hosts",
 | 
						|
    "/etc/group",
 | 
						|
    "/etc/passwd",
 | 
						|
    "/etc/shadow",
 | 
						|
    "/etc/resolv.conf",
 | 
						|
    "/etc/nsswitch.conf",
 | 
						|
    "/etc/ssh/ssh_host_rsa_key",
 | 
						|
    "/etc/ssh/ssh_config",
 | 
						|
    "/etc/ssh/sshd_config",
 | 
						|
    "/etc/ssh/ssh_host_dsa_key",
 | 
						|
    "/root/.ssh/id_rsa",
 | 
						|
    "/root/.ssh/id_rsa.pub",
 | 
						|
    "/root/.ssh/authorized_keys",);
 | 
						|
 | 
						|
# do the copy
 | 
						|
foreach my $file (@sysfilelist) {
 | 
						|
    my $dirname = dirname("$systemdir/$file");
 | 
						|
    unless (-d $dirname) {
 | 
						|
        mkpath($dirname);
 | 
						|
    }
 | 
						|
    copy($file, "$systemdir/$file");
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
# Create emtpy common dir and common.filelist for later using
 | 
						|
mkpath("$fsdir/common");
 | 
						|
system("touch $fsdir/common.filelist");
 | 
						|
 | 
						|
print "Genimage for mic has been done.\n";
 | 
						|
 | 
						|
1;
 |