#!/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;