mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-09-05 04:27:55 +00:00
2ef44d5d7f
EL riscv64 media lay out the installer kernel and initrd under
images/pxeboot exactly like x86 and aarch64 media, but anaconda.pm only
looked there for those two families and geninitrd.pm refused riscv64
outright ("unknow arch"). Treat riscv64 like x86/aarch64 in both
places and recognise riscv64 kernels when a driver disk updates the
installer kernel. There is no riscv64 SUSE media, so geninitrd keeps the
unsupported-architecture error for sles/suse rather than reading the x86
SUSE layout.
Diskless images get a riscv64 default network driver list (virtio,
Intel, Realtek, Broadcom and Mellanox) and take the resolver libraries
from lib64, which is where riscv64 EL puts them.
247 lines
9.0 KiB
Perl
247 lines
9.0 KiB
Perl
# IBM(c) 2013 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
package xCAT_plugin::geninitrd;
|
|
|
|
BEGIN
|
|
{
|
|
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
|
}
|
|
|
|
use strict;
|
|
use lib "$::XCATROOT/lib/perl";
|
|
use File::Path;
|
|
use File::Copy;
|
|
use xCAT::MsgUtils;
|
|
use xCAT::TableUtils;
|
|
use xCAT::Table;
|
|
use xCAT::Scope;
|
|
|
|
sub handled_commands
|
|
{
|
|
return {
|
|
geninitrd => "geninitrd",
|
|
}
|
|
}
|
|
|
|
sub preprocess_request
|
|
{
|
|
my $req = shift;
|
|
my $callback = shift;
|
|
|
|
my $usage = sub {
|
|
my $callback = shift;
|
|
xCAT::MsgUtils->message("I", { data => ["Usage: geninitrd <imagename> [--ignorekernelchk] [-h | --help]"] }, $callback);
|
|
};
|
|
|
|
my $osimage;
|
|
my $ignorekernelchk;
|
|
if (defined($req->{arg})) {
|
|
foreach (@{ $req->{arg} }) {
|
|
if (/^-/) {
|
|
if (/--ignorekernelchk/) {
|
|
$ignorekernelchk = 1;
|
|
} else {
|
|
$usage->($callback);
|
|
return;
|
|
}
|
|
} else {
|
|
$osimage = $_;
|
|
}
|
|
}
|
|
} else {
|
|
$usage->($callback);
|
|
return;
|
|
}
|
|
|
|
unless ($osimage) {
|
|
$usage->($callback);
|
|
return;
|
|
}
|
|
|
|
$req->{'ignorekernelchk'} = [$ignorekernelchk];
|
|
|
|
#if tftpshared is not set, dispatch this command to all the service nodes
|
|
my @entries = xCAT::TableUtils->get_site_attribute("sharedtftp");
|
|
my $t_entry = $entries[0];
|
|
if (defined($t_entry) and ($t_entry == 0 or $t_entry =~ /no/i)) {
|
|
$req->{'_disparatetftp'} = [1];
|
|
return xCAT::Scope->get_broadcast_scope($req, @_);
|
|
}
|
|
return [$req];
|
|
}
|
|
|
|
|
|
sub process_request
|
|
{
|
|
my $req = shift;
|
|
my $callback = shift;
|
|
my $doreq = shift;
|
|
|
|
if ($req->{command}->[0] eq 'geninitrd')
|
|
{
|
|
return geninitrd($req, $callback, $doreq);
|
|
}
|
|
|
|
}
|
|
|
|
sub geninitrd {
|
|
my $req = shift;
|
|
my $callback = shift;
|
|
my $doreq = shift;
|
|
|
|
my $osimage = $req->{arg}->[0];
|
|
my $ignorekernelchk;
|
|
if (defined($req->{'ignorekernelchk'}) && $req->{'ignorekernelchk'}->[0]) {
|
|
$ignorekernelchk = $req->{'ignorekernelchk'}->[0];
|
|
}
|
|
|
|
my ($osvers, $arch, $pkgdir, $driverupdatesrc, $netdrivers, $osdisupdir);
|
|
|
|
# get attributes from osimage table
|
|
my $osimagetab = xCAT::Table->new('osimage');
|
|
unless ($osimagetab) {
|
|
xCAT::MsgUtils->message("E", { error => ["Cannot open the table osimage."], errorcode => ["1"] }, $callback);
|
|
return;
|
|
}
|
|
|
|
my $oient = $osimagetab->getAttribs({ imagename => $osimage }, 'provmethod', 'osvers', 'osarch', 'osupdatename');
|
|
unless ($oient && $oient->{'osvers'} && $oient->{'osarch'}) {
|
|
xCAT::MsgUtils->message("E", { error => ["The osimage [$osimage] was not defined or [osvers, osarch] attributes were not set."], errorcode => ["1"] }, $callback);
|
|
return;
|
|
}
|
|
$osvers = $oient->{'osvers'};
|
|
$arch = $oient->{'osarch'};
|
|
|
|
# get attributes from linuximage table
|
|
my $linuximagetab = xCAT::Table->new('linuximage');
|
|
unless ($linuximagetab) {
|
|
xCAT::MsgUtils->message("E", { error => ["Cannot open the table linuximage."], errorcode => ["1"] }, $callback);
|
|
return;
|
|
}
|
|
|
|
my $lient = $linuximagetab->getAttribs({ imagename => $osimage }, 'rootimgdir', 'pkgdir', 'driverupdatesrc', 'netdrivers');
|
|
unless ($lient && $lient->{'pkgdir'}) {
|
|
xCAT::MsgUtils->message("E", { error => ["The osimage [$osimage] was not defined or [pkgdir] attribute was not set."], errorcode => ["1"] }, $callback);
|
|
return;
|
|
}
|
|
$pkgdir = $lient->{'pkgdir'};
|
|
my @srcdir = split(/,/, $pkgdir);
|
|
$pkgdir = $srcdir[0];
|
|
$driverupdatesrc = $lient->{'driverupdatesrc'};
|
|
$netdrivers = $lient->{'netdrivers'};
|
|
|
|
# if the provmethod equals 'netboot', call the genimage --onlyinitrd directly
|
|
if ($oient->{'provmethod'} && ($oient->{'provmethod'} eq "netboot" || $oient->{'provmethod'} eq "statelite")) {
|
|
if ($lient->{'rootimgdir'}) {
|
|
unless (-d $lient->{'rootimgdir'} . "/rootimg/lib/modules") {
|
|
xCAT::MsgUtils->message("E", { error => ["The genimage should be run before running geninitrd."], errorcode => ["1"] }, $callback);
|
|
return;
|
|
}
|
|
} else {
|
|
xCAT::MsgUtils->message("E", { error => ["The rootimgdir attribute for the osimage should be set."], errorcode => ["1"] }, $callback);
|
|
return;
|
|
}
|
|
my @output = `genimage $osimage --onlyinitrd`;
|
|
xCAT::MsgUtils->message("I", { data => \@output }, $callback);
|
|
|
|
#$doreq->({ command => ['genimage'],
|
|
# arg => [$osimage, '--onlyinitrd'] }, $callback);
|
|
return;
|
|
} elsif (!$oient->{'provmethod'} || $oient->{'provmethod'} ne "install") {
|
|
xCAT::MsgUtils->message("E", { error => ["The attribute [provmethod] for osimage [$osimage] must be set to install, netboot or statelite."], errorcode => ["1"] }, $callback);
|
|
return;
|
|
}
|
|
|
|
# get the path list of the osdistroupdate
|
|
if ($oient->{'osupdatename'}) {
|
|
my @osupdatenames = split(/,/, $oient->{'osupdatename'});
|
|
|
|
my $osdistrouptab = xCAT::Table->new('osdistroupdate', -create => 1);
|
|
unless ($osdistrouptab) {
|
|
xCAT::MsgUtils->message("E", { error => ["Cannot open the table osdistroupdate."], errorcode => [1] }, $callback);
|
|
return;
|
|
}
|
|
|
|
my @osdup = $osdistrouptab->getAllAttribs("osupdatename", "dirpath");
|
|
foreach my $upname (@osupdatenames) {
|
|
foreach my $upref (@osdup) {
|
|
if ($upref->{'osupdatename'} eq $upname) {
|
|
$osdisupdir .= ",$upref->{'dirpath'}";
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
|
|
$osdisupdir =~ s/^,//;
|
|
}
|
|
|
|
# get the source path of initrd and kernel from the pkgdir of osimage
|
|
# copy the initrd and kernel to /tftpboot
|
|
# pass the path of initrd and kernel in /tftpboot to insertdd
|
|
my $initrdpath;
|
|
my $kernelpath;
|
|
my $tftpdir = "/tftpboot";
|
|
my @entries = xCAT::TableUtils->get_site_attribute("tftpdir");
|
|
my $t_entry = $entries[0];
|
|
if (defined($t_entry)) {
|
|
$tftpdir = $t_entry;
|
|
}
|
|
my $tftppath = "$tftpdir/xcat/osimage/$osimage";
|
|
unless (-d $tftppath) {
|
|
mkpath $tftppath;
|
|
}
|
|
# riscv64 installation media exist for the EL family only; leave any other
|
|
# distribution to the "unknow arch" error below instead of reading it as x86
|
|
if ($arch =~ /x86/ or ($arch =~ /riscv64/ and $osvers !~ /sles|suse/)) {
|
|
if ($osvers =~ /(^ol[0-9].*)|(centos.*)|(alma.*)|(rocky.*)|(rh.*)|(fedora.*)|(SL.*)/) {
|
|
$kernelpath = "$tftppath/vmlinuz";
|
|
copy("$pkgdir/images/pxeboot/vmlinuz", $kernelpath);
|
|
$initrdpath = "$tftppath/initrd.img";
|
|
copy("$pkgdir/images/pxeboot/initrd.img", $initrdpath);
|
|
} elsif ($osvers =~ /(sles.*)|(suse.*)/) {
|
|
$kernelpath = "$tftppath/linux";
|
|
copy("$pkgdir/1/boot/$arch/loader/linux", $kernelpath);
|
|
$initrdpath = "$tftppath/initrd";
|
|
copy("$pkgdir/1/boot/$arch/loader/initrd", $initrdpath);
|
|
} else {
|
|
xCAT::MsgUtils->message("E", { error => ["unknow osvers [$osvers]."], errorcode => [1] }, $callback);
|
|
return;
|
|
}
|
|
} elsif ($arch =~ /ppc/) {
|
|
if ($osvers =~ /(^ol[0-9].*)|(centos.*)|(alma.*)|(rocky.*)|(rh.*)|(fedora.*)|(SL.*)|(pkvm.*)/) {
|
|
$kernelpath = "$tftppath/vmlinuz";
|
|
copy("$pkgdir/ppc/ppc64/vmlinuz", $kernelpath);
|
|
if (-r "$pkgdir/ppc/ppc64/ramdisk.image.gz") {
|
|
$initrdpath = "$tftppath/initrd.img";
|
|
copy("$pkgdir/ppc/ppc64/ramdisk.image.gz", $initrdpath);
|
|
} elsif (-r "$pkgdir/ppc/ppc64/initrd.img") {
|
|
$initrdpath = "$tftppath/initrd.img";
|
|
copy("$pkgdir/ppc/ppc64/initrd.img", $initrdpath);
|
|
}
|
|
} elsif ($osvers =~ /(sles.*)|(suse.*)/) {
|
|
$kernelpath = undef;
|
|
$initrdpath = "$tftppath/inst64";
|
|
copy("$pkgdir/1/suseboot/inst64", $initrdpath);
|
|
} else {
|
|
xCAT::MsgUtils->message("E", { error => ["unknow osvers [$osvers]."], errorcode => [1] }, $callback);
|
|
return;
|
|
}
|
|
} else {
|
|
xCAT::MsgUtils->message("E", { error => ["unknow arch [$arch]."], errorcode => [1] }, $callback);
|
|
return;
|
|
}
|
|
|
|
# call the insert_dd function in the anaconda or sles to hack the initrd that:
|
|
# 1. Get the new kernel from update distro and copy it to /tftpboot
|
|
# 2. Inject the drivers to initrd in /tftpboot base on the new kernel ver
|
|
if ($osvers =~ /(^ol[0-9].*)|(centos.*)|(alma.*)|(rocky.*)|(rh.*)|(fedora.*)|(SL.*)/) {
|
|
require xCAT_plugin::anaconda;
|
|
xCAT_plugin::anaconda->insert_dd($callback, $osvers, $arch, $initrdpath, $kernelpath, $driverupdatesrc, $netdrivers, $osdisupdir, $ignorekernelchk);
|
|
} elsif ($osvers =~ /(sles.*)|(suse.*)/) {
|
|
require xCAT_plugin::sles;
|
|
xCAT_plugin::sles->insert_dd($callback, $osvers, $arch, $initrdpath, $kernelpath, $driverupdatesrc, $netdrivers, $osdisupdir, $ignorekernelchk);
|
|
}
|
|
|
|
}
|
|
|
|
1;
|