mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-09-05 04:27:55 +00:00
test(xCAT-test): cover the boot loader published by copycds
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Cwd qw(realpath);
|
||||
use File::Path qw(make_path);
|
||||
use File::Spec;
|
||||
use File::Temp qw(tempdir);
|
||||
use FindBin;
|
||||
use Test::More;
|
||||
|
||||
# copycd publishes the grub2 UEFI image of the installation media so that nodes
|
||||
# of an architecture xCAT builds no boot loader for -- riscv64 -- can net boot
|
||||
# without a further step. An image the management node already has is never
|
||||
# replaced, and the media of every other architecture is left alone.
|
||||
|
||||
my $repo_root = realpath( File::Spec->catdir( $FindBin::Bin, '..', '..' ) );
|
||||
my $plugin = File::Spec->catfile( $repo_root, 'xCAT-server', 'lib', 'xcat', 'plugins', 'anaconda.pm' );
|
||||
plan skip_all => "$plugin not found" unless -r $plugin;
|
||||
|
||||
my $source = do {
|
||||
open( my $fh, '<', $plugin ) or die "Unable to read $plugin: $!";
|
||||
local $/;
|
||||
<$fh>;
|
||||
};
|
||||
|
||||
# anaconda.pm needs a database to load, so take just the loader publication out
|
||||
# of it, the way the other unit tests here isolate a shipped sub.
|
||||
my ($loaders) = $source =~ /^(my %MEDIA_GRUB2_LOADERS = \([^)]*\);)$/m;
|
||||
ok( $loaders, 'the media boot loader map was located in anaconda.pm' )
|
||||
or BAIL_OUT('anaconda.pm no longer defines %MEDIA_GRUB2_LOADERS');
|
||||
my ($sub) = $source =~ /^(sub _install_media_grub2_loader \{.*?^\})$/ms;
|
||||
ok( $sub, 'the media boot loader publication was located in anaconda.pm' )
|
||||
or BAIL_OUT('anaconda.pm no longer defines _install_media_grub2_loader');
|
||||
|
||||
my $tftpdir;
|
||||
{
|
||||
package xCAT::TableUtils;
|
||||
sub getTftpDir { return $tftpdir; }
|
||||
}
|
||||
|
||||
eval "use File::Path qw(mkpath); use File::Copy; $loaders $sub 1;" or die $@;
|
||||
|
||||
sub media {
|
||||
my ( $root, $name, $image ) = @_;
|
||||
my $path = File::Spec->catdir( $root, $name );
|
||||
make_path( File::Spec->catdir( $path, 'EFI', 'BOOT' ) );
|
||||
if ($image) {
|
||||
my $file = File::Spec->catfile( $path, 'EFI', 'BOOT', $image );
|
||||
open( my $fh, '>', $file ) or die "Unable to create $file: $!";
|
||||
print $fh "boot loader from the media\n";
|
||||
close($fh);
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
sub messages {
|
||||
my ($responses) = @_;
|
||||
return join( ' ', map { ref($_) eq 'HASH' && $_->{data} ? "@{[ $_->{data} ]}" : () } @{$responses} );
|
||||
}
|
||||
|
||||
my $root = tempdir( CLEANUP => 1 );
|
||||
$tftpdir = File::Spec->catdir( $root, 'tftpboot' );
|
||||
make_path($tftpdir);
|
||||
|
||||
# riscv64 media, nothing published yet: the image is installed
|
||||
my $riscv_media = media( $root, 'rocky10-riscv64', 'grubriscv64.efi' );
|
||||
my @responses;
|
||||
my $written = _install_media_grub2_loader( $riscv_media, 'riscv64', sub { push @responses, @_; } );
|
||||
my $loader = File::Spec->catfile( $tftpdir, 'boot', 'grub2', 'grub2.riscv64' );
|
||||
is( $written, $loader, 'riscv64 media publish their grub2 image as the riscv64 boot loader' );
|
||||
ok( -f $loader, 'the boot loader is written under the TFTP root' );
|
||||
is( ( stat($loader) )[7], ( stat( File::Spec->catfile( $riscv_media, 'EFI', 'BOOT', 'grubriscv64.efi' ) ) )[7],
|
||||
'the published image is the one from the media' );
|
||||
like( messages( \@responses ), qr/\QInstalled $loader from the media\E/, 'the published boot loader is reported' );
|
||||
|
||||
# a boot loader that is already there is never replaced
|
||||
open( my $fh, '>', $loader ) or die "Unable to rewrite $loader: $!";
|
||||
print $fh "installed by grub2-xcat\n";
|
||||
close($fh);
|
||||
@responses = ();
|
||||
is( scalar _install_media_grub2_loader( $riscv_media, 'riscv64', sub { push @responses, @_; } ),
|
||||
undef, 'an existing boot loader is kept' );
|
||||
open( my $rfh, '<', $loader ) or die "Unable to read $loader: $!";
|
||||
my $content = do { local $/; <$rfh> };
|
||||
close($rfh);
|
||||
is( $content, "installed by grub2-xcat\n", 'the existing boot loader is left untouched' );
|
||||
is( messages( \@responses ), '', 'nothing is reported when there is nothing to do' );
|
||||
unlink($loader);
|
||||
|
||||
# other architectures are not touched, even when their media carry an image.
|
||||
# Start from an empty TFTP root so the check covers the directory as well.
|
||||
$tftpdir = File::Spec->catdir( $root, 'tftpboot-x86' );
|
||||
make_path($tftpdir);
|
||||
my $x86_media = media( $root, 'rocky10-x86_64', 'grubx64.efi' );
|
||||
@responses = ();
|
||||
is( scalar _install_media_grub2_loader( $x86_media, 'x86_64', sub { push @responses, @_; } ),
|
||||
undef, 'x86_64 media publish no boot loader' );
|
||||
ok( !-e File::Spec->catfile( $tftpdir, 'boot', 'grub2', 'grub2.x86_64' ), 'no x86_64 boot loader is written' );
|
||||
ok( !-d File::Spec->catdir( $tftpdir, 'boot' ), 'the grub2 directory is only created when there is an image to put in it' );
|
||||
|
||||
# riscv64 media without the image are a no-op rather than an error
|
||||
$tftpdir = File::Spec->catdir( $root, 'tftpboot-bare' );
|
||||
make_path($tftpdir);
|
||||
my $bare_media = media( $root, 'rocky10-riscv64-bare' );
|
||||
@responses = ();
|
||||
is( scalar _install_media_grub2_loader( $bare_media, 'riscv64', sub { push @responses, @_; } ),
|
||||
undef, 'media without a grub2 image publish nothing' );
|
||||
is( messages( \@responses ), '', 'media without a grub2 image report nothing' );
|
||||
ok( !-d File::Spec->catdir( $tftpdir, 'boot' ), 'media without a grub2 image create no directories' );
|
||||
|
||||
done_testing();
|
||||
Reference in New Issue
Block a user