mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-25 00:15:43 +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;
 |