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;
|