xcat-core/xCAT-server/share/xcat/netboot/mic/genimage

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;