diff --git a/xCAT-test/unit/mknb_xcatd_address.t b/xCAT-test/unit/mknb_xcatd_address.t index 56339f98e..b20e335fd 100644 --- a/xCAT-test/unit/mknb_xcatd_address.t +++ b/xCAT-test/unit/mknb_xcatd_address.t @@ -13,10 +13,11 @@ BEGIN { $INC{'xCAT/Utils.pm'} = __FILE__; package xCAT::TableUtils; - our ($tftpdir, $site_master, $site_httpport); + our ($tftpdir, $site_master, $site_httpport, %site_extra); sub getTftpDir { return $tftpdir; } sub get_site_attribute { my $attribute = $_[-1]; + return ($site_extra{$attribute}) if exists $site_extra{$attribute}; return ($site_master) if $attribute eq 'master'; return ($site_httpport) if $attribute eq 'httpport' and defined $site_httpport; return; @@ -36,6 +37,8 @@ BEGIN { return $hexnet_addresses; } sub getipaddr { return @master_addresses; } + our $nic_ips; + sub get_nic_ip { return $nic_ips || {}; } $INC{'xCAT/NetworkUtils.pm'} = __FILE__; package xCAT::NodeRange; @@ -334,4 +337,146 @@ is( 'legacy PXE output is byte-identical without a site.master preference', ); +# riscv64 discovery boots through UEFI firmware and grub2: mknb writes one +# grub2 configuration per network, named by the network's hex prefix the same +# way PXELINUX files are, instead of PXELINUX/xNBA or petitboot files. +make_path("$::XCATROOT/share/xcat/netboot/genesis/riscv64"); +use_reporter_address_maps(); +prepare_tftpdir($tmpdir, 'tftpboot-riscv64', 'riscv64'); +$responses = run_mknb('riscv64'); +generation_succeeded($responses, 'riscv64 configuration generation succeeds'); + +my $grub_cfg_path = "$xCAT::TableUtils::tftpdir/boot/grub2/grub.cfg-C0A89"; +ok(-f $grub_cfg_path, 'riscv64 writes a grub2 configuration named by the network hex prefix'); +my $grub_cfg = read_config($grub_cfg_path); +like( + $grub_cfg, + qr/^# xCAT Genesis discovery for network C0A89 - generated by mknb, do not edit$/m, + 'the grub2 discovery configuration names its network and generator', +); +like($grub_cfg, qr/^set default=0$/m, 'the grub2 discovery configuration selects the first entry'); +like($grub_cfg, qr/^set timeout=5$/m, 'the grub2 discovery configuration boots after a short timeout'); +like( + $grub_cfg, + qr/^if \[ "\$grub_cpu" = "riscv64" \]; then$/m, + 'the riscv64 menu entry is guarded by the GRUB cpu', +); +like($grub_cfg, qr/^menuentry "xCAT Genesis riscv64" \{$/m, 'the menu entry names the architecture'); +like( + $grub_cfg, + qr/^ linux \/xcat\/genesis\.kernel\.riscv64 xcatd=192\.168\.148\.10:3001 BOOTIF=\$net_default_mac$/m, + 'the kernel line loads the Genesis kernel with the xcatd endpoint and the booting MAC', +); +like($grub_cfg, qr/^ initrd \/xcat\/genesis\.fs\.riscv64\.gz$/m, 'the initrd line loads the Genesis initramfs'); +like($grub_cfg, qr/^\}\nfi\n\z/m, 'the configuration closes the menu entry and the cpu guard'); +unlike( + $grub_cfg, + qr/\Q$xCAT::TableUtils::tftpdir\E/, + 'the grub2 configuration does not expose the configured TFTP root', +); +unlike( + $grub_cfg, + qr/xcatd=192\.168\.149\.100:3001/, + 'the grub2 configuration does not use the later floating address as the xcatd endpoint', +); +ok(!-e "$xCAT::TableUtils::tftpdir/pxelinux.cfg/C0A89", 'riscv64 writes no PXELINUX configuration'); +ok(!-e "$xCAT::TableUtils::tftpdir/xcat/xnba", 'riscv64 writes no xNBA configuration'); +ok(!-e "$xCAT::TableUtils::tftpdir/etc/c0a89", 'riscv64 writes no petitboot configuration'); +ok(!-e "$xCAT::TableUtils::tftpdir/pxelinux.cfg/p", 'riscv64 writes no POWER network configuration'); +is_deeply( + [ xCAT_plugin::mknb::_grub2_discovery_arches($xCAT::TableUtils::tftpdir) ], + [ [ 'riscv64', 'riscv64', 'xcat/genesis.kernel.riscv64', 'xcat/genesis.fs.riscv64.gz' ] ], + 'the published riscv64 Genesis artifacts are enumerated relative to the TFTP root', +); + +# serial console settings reach the Genesis kernel line +%xCAT::TableUtils::site_extra = ( + defserialport => '0', + defserialspeed => '115200', + defserialflow => 'hard', + xcatdport => '3002', +); +$responses = run_mknb('riscv64'); +generation_succeeded($responses, 'riscv64 configuration generation succeeds with a serial console'); +like( + read_config($grub_cfg_path), + qr/^ linux \/xcat\/genesis\.kernel\.riscv64 xcatd=192\.168\.148\.10:3002 console=tty0 console=ttyS0,115200n8r BOOTIF=\$net_default_mac$/m, + 'the serial console and a non-default xcatd port are carried into the kernel line', +); +%xCAT::TableUtils::site_extra = (); + +# an lzma initramfs is preferred when mknb produced one +open(my $lzma_fh, '>', "$xCAT::TableUtils::tftpdir/xcat/genesis.fs.riscv64.lzma") or die "Unable to create lzma: $!"; +close($lzma_fh); +$responses = run_mknb('riscv64'); +generation_succeeded($responses, 'riscv64 configuration generation succeeds with an lzma initramfs'); +like( + read_config($grub_cfg_path), + qr/^ initrd \/xcat\/genesis\.fs\.riscv64\.lzma$/m, + 'the lzma Genesis initramfs is preferred over the gzip one', +); +unlink("$xCAT::TableUtils::tftpdir/xcat/genesis.fs.riscv64.lzma"); + +# the discovery configurations are only reachable through grub2., which mknb does not +# build: a missing boot loader is reported instead of failing silently in firmware +{ + my $loader = "$xCAT::TableUtils::tftpdir/boot/grub2/grub2.riscv64"; + my $missing = run_mknb('riscv64'); + generation_succeeded($missing, 'riscv64 configuration generation succeeds without the grub2 boot loader'); + ok( + scalar(grep { ref($_) eq 'HASH' && $_->{data} && "@{$_->{data}}" =~ m{\Qboot/grub2/grub2.riscv64\E is missing} } @{$missing}), + 'a missing grub2.riscv64 boot loader is reported', + ); + make_path("$xCAT::TableUtils::tftpdir/boot/grub2"); + open(my $loader_fh, '>', $loader) or die "Unable to create $loader: $!"; + close($loader_fh); + my $present = run_mknb('riscv64'); + ok( + !grep({ ref($_) eq 'HASH' && $_->{data} && "@{$_->{data}}" =~ /is missing/ } @{$present}), + 'nothing is reported once the boot loader is in place', + ); + unlink($loader); +} + + +# the configuration is rebuilt from what is published: without artifacts it goes away +unlink("$xCAT::TableUtils::tftpdir/xcat/genesis.kernel.riscv64"); +is( + xCAT_plugin::mknb::_write_grub2_discovery_config( + tftpdir => $xCAT::TableUtils::tftpdir, + hexnet => 'c0a89', + xcatd_address => '192.168.148.10', + xcatdport => 3001, + ), + undef, + 'no grub2 discovery configuration is written without a published Genesis kernel', +); +ok(!-e $grub_cfg_path, 'a stale grub2 discovery configuration is removed with its artifacts'); + +# --configfileonly without published artifacts fails like the other architectures +$xCAT::TableUtils::tftpdir = "$tmpdir/tftpboot-riscv64-empty"; +make_path("$xCAT::TableUtils::tftpdir/xcat"); +$responses = run_mknb('riscv64'); +ok( + scalar(grep { ref($_) eq 'HASH' && $_->{error} && "@{$_->{error}}" =~ /No kernel file found/ } @{$responses}), + 'riscv64 --configfileonly without a kernel reports the missing kernel', +); + +# a :noboot interface keeps no discovery configuration for its network +%xCAT::TableUtils::site_extra = ( dhcpinterfaces => 'eth0,eth1:noboot' ); +$xCAT::NetworkUtils::nic_ips = { eth0 => '10.0.0.1', eth1 => '192.168.148.10' }; +use_reporter_address_maps(); +prepare_tftpdir($tmpdir, 'tftpboot-riscv64-noboot', 'riscv64'); +make_path("$xCAT::TableUtils::tftpdir/boot/grub2"); +open(my $stale_fh, '>', "$xCAT::TableUtils::tftpdir/boot/grub2/grub.cfg-C0A89") or die "Unable to create stale config: $!"; +close($stale_fh); +$responses = run_mknb('riscv64'); +generation_succeeded($responses, 'riscv64 configuration generation succeeds with a :noboot interface'); +ok( + !-e "$xCAT::TableUtils::tftpdir/boot/grub2/grub.cfg-C0A89", + 'a network served by a :noboot interface gets no grub2 discovery configuration', +); +%xCAT::TableUtils::site_extra = (); +$xCAT::NetworkUtils::nic_ips = undef; + done_testing();