mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-25 13:12:03 +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;
|