279 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			279 lines
		
	
	
		
			7.8 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/ssh_host_key",
 | |
|   "/etc/ssh/sshd_config",
 | |
|   "/etc/ssh/ssh_host_dsa_key",
 | |
|   "/etc/ssh/ssh_host_key.pub",
 | |
|   "/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;
 |