2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-09-04 20:17:55 +00:00

test(xCAT-test): cover EL riscv64 install media and diskless defaults

Pin the riscv64 installer kernel lookup in anaconda.pm and
geninitrd.pm, and evaluate the rh/genimage default driver and resolver
library blocks for riscv64 and the existing architectures.

Add an autotest nodeset case with bogus riscv64 grub2 nodes and a
rhels10.99 riscv64 osimage, checking the per-node grub2 files, the
grub2.riscv64 loader link and the hex-ip/mac links.
This commit is contained in:
Vinícius Ferrão
2026-08-20 16:42:19 -03:00
parent 2ef44d5d7f
commit 16eea29daf
4 changed files with 195 additions and 1 deletions
@@ -26,6 +26,13 @@ cmd:/opt/xcat/share/xcat/tools/autotest/testcase/nodeset/nodeset_osimage_grub2
check:rc==0
end
start:nodeset_osimage_grub2_riscv64
label:others
description: Verify if `nodeset osimage` perform well for riscv64 nodes booted by grub2 over UEFI when part of nodes in a node range have problem
cmd:/opt/xcat/share/xcat/tools/autotest/testcase/nodeset/nodeset_osimage_grub2_riscv64
check:rc==0
end
start:nodeset_osimage_petitboot
label:others
description: Verify if `nodeset osimage` perform well when part of nodes in a node range have problem. Use petitboot OS loader
@@ -118,6 +118,21 @@ function make_bogus_petitboot_nodes()
done
}
function make_bogus_riscv64_grub2_nodes()
{
local i
# riscv64 boots through UEFI and grub2
for i in {001..005}
do
mkdef -t node -o tz${i} \
arch=riscv64 cons=ipmi groups=riscv64 mgt=ipmi \
netboot=grub2 \
ip=10.99.1.$((10#${i})) \
mac=e6:d4:d2:3a:ad:0$((10#${i})) \
profile=compute os=rhels10.99
done
}
function make_bogus_xnba_nodes()
{
local i
@@ -181,6 +196,16 @@ function make_bogus_x64_osimage()
echo blah >/install/rhels6.99/x86_64/images/pxeboot/initrd.img
}
function make_bogus_riscv64_osimage()
{
mkdef "rhels10.99-riscv64-install-compute" \
-u profile=compute provmethod=install \
osvers=rhels10.99 osarch=riscv64
mkdir -p /install/rhels10.99/riscv64/images/pxeboot
echo blah >/install/rhels10.99/riscv64/images/pxeboot/vmlinuz
echo blah >/install/rhels10.99/riscv64/images/pxeboot/initrd.img
}
function destory_bogus_osimages()
{
local o
@@ -188,7 +213,8 @@ function destory_bogus_osimages()
rhels7.99-ppc64le-install-compute \
rhels7.99-ppc64-install-compute \
rhels6.99-ppc64-install-compute \
rhels6.99-x86_64-install-compute
rhels6.99-x86_64-install-compute \
rhels10.99-riscv64-install-compute
do
rmdef -t osimage ${o}
done
@@ -0,0 +1,73 @@
#!/bin/bash
BASE_DIR="${0%/*}"
! source "${BASE_DIR}/functions.sh" >/dev/null 2>&1 &&
echo "File \"${BASE_DIR}/functions.sh\" not found" >&2 && exit 1
make_bogus_riscv64_osimage
make_bogus_riscv64_grub2_nodes
# riscv64 nodes are booted by the grub2.riscv64 UEFI image; provide a bogus
# one when the management node does not ship it so nodeset can link to it
GRUB2_RISCV64="/tftpboot/boot/grub2/grub2.riscv64"
BOGUS_GRUB2_RISCV64=""
if [ ! -e "${GRUB2_RISCV64}" ]
then
mkdir -p "${GRUB2_RISCV64%/*}"
echo blah >"${GRUB2_RISCV64}"
BOGUS_GRUB2_RISCV64="${GRUB2_RISCV64}"
fi
function custom_cleanup()
{
destory_bogus_nodes
destory_bogus_osimages
[ -n "${BOGUS_GRUB2_RISCV64}" ] && rm -f "${BOGUS_GRUB2_RISCV64}"
}
chdef tz002 mac=
chdef tz003 arch=
NODESET_STDOUT="${TMP_DIR}/nodeset.out"
NODESET_STDERR="${TMP_DIR}/nodeset.err"
nodeset tz001+4 osimage=rhels10.99-riscv64-install-compute \
> >(tee "${NODESET_STDOUT}") 2> >(tee "${NODESET_STDERR}")
# Check $? != 0
[ "$?" -ne "0" ]
exit_if_bad "$?" "nodeset command should exit with non-zero"
grep 'tz002: .*o MAC address' "${NODESET_STDERR}"
exit_if_bad "$?" "nodeset command error message checking failed"
# Make sure all other nodes are good
for node in tz001 tz004 tz005
do
[ -f "/tftpboot/boot/grub2/${node}" ]
exit_if_bad "$?" "file not found /tftpboot/boot/grub2/${node}"
# the per-node loader link points at the riscv64 grub2 image
[ "$(readlink "/tftpboot/boot/grub2/grub2-${node}")" = "grub2.riscv64" ]
exit_if_bad "$?" "grub2-${node} does not link to grub2.riscv64"
# the installer kernel and initrd come from images/pxeboot
grep 'vmlinuz' "/tftpboot/boot/grub2/${node}"
exit_if_bad "$?" "installer kernel not found in /tftpboot/boot/grub2/${node}"
grep 'initrd.img' "/tftpboot/boot/grub2/${node}"
exit_if_bad "$?" "installer initrd not found in /tftpboot/boot/grub2/${node}"
# the riscv64 grub2 image has no linuxefi command
! grep 'linuxefi' "/tftpboot/boot/grub2/${node}"
exit_if_bad "$?" "linuxefi must not be used for riscv64 in /tftpboot/boot/grub2/${node}"
done
# the hex ip and mac links nodeset writes shadow the discovery network files
[ -f "/tftpboot/boot/grub2/grub.cfg-0A630101" ]
exit_if_bad "$?" "file not found /tftpboot/boot/grub2/grub.cfg-0A630101"
[ -f "/tftpboot/boot/grub2/grub.cfg-01-e6-d4-d2-3a-ad-01" ]
exit_if_bad "$?" "file not found /tftpboot/boot/grub2/grub.cfg-01-e6-d4-d2-3a-ad-01"
nodeset tz001+4 offline
exit 0
+88
View File
@@ -0,0 +1,88 @@
#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use File::Spec;
use Test::More;
use lib "$FindBin::Bin/../../perl-xCAT";
use lib "$FindBin::Bin/../../xCAT-server/lib/perl";
use lib "$FindBin::Bin/../../xCAT-server/share/xcat/netboot/imgutils";
use imgutils;
# EL riscv64 media and diskless images: the installer kernel/initrd live under
# images/pxeboot like x86 and aarch64 media, and riscv64 diskless images need
# their own default network drivers and lib64 resolver libraries. The
# behavior is pinned without running the database-backed plugins: the arch
# conditions are asserted in the shipped source and the resolver block is
# extracted and evaluated directly.
my $repo_root = File::Spec->catdir( $FindBin::Bin, '..', '..' );
sub slurp {
my ($relative) = @_;
my $path = File::Spec->catfile( $repo_root, split( m{/}, $relative ) );
plan skip_all => "$path not found" unless -r $path;
open( my $fh, '<', $path ) or die "Unable to read $path: $!";
my $content = do { local $/; <$fh> };
close($fh);
return $content;
}
my $anaconda = slurp('xCAT-server/lib/xcat/plugins/anaconda.pm');
my $geninitrd = slurp('xCAT-server/lib/xcat/plugins/geninitrd.pm');
my $genimage = slurp('xCAT-server/share/xcat/netboot/rh/genimage');
# anaconda.pm: stateful install kernel/initrd discovery
like(
$anaconda,
qr/\( \$arch =~ \/x86\/ or \$arch =~ \/aarch64\/ or \$arch =~ \/riscv64\/ \) and\n\s*\(\n\s*-r "\$pkgdir\/images\/pxeboot\/vmlinuz"/,
'anaconda looks for riscv64 installer kernels under images/pxeboot like x86 and aarch64',
);
like(
$anaconda,
qr/\/\\\/vmlinuz-\(\.\*\(x86_64\|ppc64\|el\\d\+\|ppc64le\|aarch64\|riscv64\)\)\$\//,
'driver-disk kernel updates recognise riscv64 kernels',
);
# geninitrd.pm: diskless installer initrd source
like(
$geninitrd,
qr/if \(\$arch =~ \/x86\/ or \(\$arch =~ \/riscv64\/ and \$osvers !~ \/sles\|suse\/\)\) \{\n\s*if \(\$osvers =~ \/\(\^ol\[0-9\]\.\*\)\|\(centos\.\*\)\|\(alma\.\*\)\|\(rocky\.\*\)\|\(rh\.\*\)\|\(fedora\.\*\)\|\(SL\.\*\)\/\) \{\n\s*\$kernelpath = "\$tftppath\/vmlinuz";\n\s*copy\("\$pkgdir\/images\/pxeboot\/vmlinuz", \$kernelpath\);/,
'geninitrd copies riscv64 EL kernels from images/pxeboot',
);
like(
$geninitrd,
qr/\$arch =~ \/riscv64\/ and \$osvers !~ \/sles\|suse\//,
'a SUSE osimage on riscv64 keeps the unsupported-architecture error instead of reading SUSE installer media paths',
);
unlike(
$geninitrd,
qr/\} elsif \(\$arch =~ \/riscv64\/\)/,
'geninitrd does not need a separate riscv64 branch',
);
is_deeply(
[ imgutils::default_net_drivers( 'rh', 'riscv64' ) ],
[qw/e1000 e1000e igb ixgbe r8169 tg3 bnx2x mlx5_core virtio_net/],
'riscv64 diskless images default to virtio, Intel, Realtek, Broadcom and Mellanox drivers',
);
# rh/genimage: resolver libraries for the boot image
my ($lib_block) = $genimage =~ m{^(\s*if \(\$arch =~ /x86_64/ or \$arch =~ /aarch64/ or \$arch =~ /riscv64/\) \{\n\s*push \@filestoadd, "lib64/libnss_dns\.so\.2";\n.*?^\s*\}\n)}ms;
ok( $lib_block, 'the resolver library block was located in rh/genimage' )
or BAIL_OUT('rh/genimage no longer matches the expected resolver library block');
sub resolver_libs {
my ($arch) = @_;
my $code = "sub { my \$arch = shift; my \@filestoadd;\n$lib_block\n return \@filestoadd; }";
my $sub = eval $code; ## no critic (BuiltinFunctions::ProhibitStringyEval)
die "Unable to evaluate the resolver library block: $@" if $@;
return [ $sub->($arch) ];
}
is_deeply( resolver_libs('riscv64'), [ 'lib64/libnss_dns.so.2', 'lib64/libresolv.so.2' ], 'riscv64 images take the resolver libraries from lib64' );
is_deeply( resolver_libs('x86_64'), [ 'lib64/libnss_dns.so.2', 'lib64/libresolv.so.2' ], 'x86_64 images still use lib64' );
is_deeply( resolver_libs('ppc64'), [ 'lib/libnss_dns.so.2', 'lib/libresolv.so.2' ], 'ppc64 images still use lib' );
done_testing();