mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-09-09 14:36:43 +00:00
649 lines
24 KiB
Perl
649 lines
24 KiB
Perl
#!/usr/bin/env perl
|
|
use strict;
|
|
use warnings;
|
|
## no critic (Modules::RequireFilenameMatchesPackage, TestingAndDebugging::ProhibitNoStrict, TestingAndDebugging::ProhibitNoWarnings)
|
|
|
|
use FindBin;
|
|
use lib "$FindBin::Bin/../lib";
|
|
use File::Slurper qw(write_text);
|
|
use File::Path qw(make_path);
|
|
use File::Temp qw(tempdir);
|
|
use Test::More;
|
|
use XCAT::Test::File qw(repo_path);
|
|
use xCAT::DHCP::BootPolicy;
|
|
|
|
BEGIN {
|
|
package xCAT::Utils;
|
|
$INC{'xCAT/Utils.pm'} = __FILE__;
|
|
|
|
package xCAT::TableUtils;
|
|
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;
|
|
}
|
|
$INC{'xCAT/TableUtils.pm'} = __FILE__;
|
|
|
|
package xCAT::NetworkUtils;
|
|
our ($normnet_addresses, $hexnet_addresses, @master_addresses);
|
|
sub my_nets {
|
|
die "mknb did not request all normalized-network addresses"
|
|
unless $_[-1] eq 'all';
|
|
return $normnet_addresses;
|
|
}
|
|
sub my_hexnets {
|
|
die "mknb did not request all hexadecimal-network addresses"
|
|
unless $_[-1] eq 'all';
|
|
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;
|
|
sub import {
|
|
my $caller = caller;
|
|
no strict 'refs';
|
|
*{"${caller}::noderange"} = sub { return; };
|
|
}
|
|
$INC{'xCAT/NodeRange.pm'} = __FILE__;
|
|
}
|
|
|
|
my $source_mknb_plugin = repo_path('xCAT-server/lib/xcat/plugins/mknb.pm');
|
|
require $source_mknb_plugin;
|
|
|
|
my ($legacy, $selected) = xCAT_plugin::mknb::_select_network_addresses(
|
|
{
|
|
'10.20.30.0/24' => [
|
|
'10.20.30.10',
|
|
'10.20.30.250',
|
|
],
|
|
},
|
|
['10.20.30.250'],
|
|
);
|
|
is_deeply(
|
|
$legacy,
|
|
{ '10.20.30.0/24' => '10.20.30.250' },
|
|
'Linux HA keeps the last address as the legacy network address',
|
|
);
|
|
is_deeply(
|
|
$selected,
|
|
{ '10.20.30.0/24' => '10.20.30.250' },
|
|
'Linux HA selects the local site.master virtual address',
|
|
);
|
|
|
|
($legacy, $selected) = xCAT_plugin::mknb::_select_network_addresses(
|
|
{
|
|
'10.30.40.0/24' => [
|
|
'10.30.40.20',
|
|
'10.30.40.100',
|
|
],
|
|
},
|
|
['192.0.2.1'],
|
|
);
|
|
is_deeply(
|
|
$legacy,
|
|
{ '10.30.40.0/24' => '10.30.40.100' },
|
|
'a service node keeps its last address as the legacy network address',
|
|
);
|
|
is_deeply(
|
|
$selected,
|
|
{ '10.30.40.0/24' => '10.30.40.20' },
|
|
'a service node ignores a remote site.master address and selects its first local address',
|
|
);
|
|
|
|
($legacy, $selected) = xCAT_plugin::mknb::_select_network_addresses(
|
|
{
|
|
'192.168.144.0/20' => [
|
|
'192.168.148.10',
|
|
'192.168.149.100',
|
|
],
|
|
'198.51.100.0/24' => [],
|
|
},
|
|
[],
|
|
);
|
|
is_deeply(
|
|
$legacy,
|
|
{ '192.168.144.0/20' => '192.168.149.100' },
|
|
'missing site.master preference preserves the last-address legacy value',
|
|
);
|
|
is_deeply(
|
|
$selected,
|
|
{ '192.168.144.0/20' => '192.168.148.10' },
|
|
'missing site.master preference falls back to the first candidate and skips empty networks',
|
|
);
|
|
|
|
sub prepare_tftpdir {
|
|
my ($root, $name, $arch, $image_type) = @_;
|
|
$image_type //= 'genesis';
|
|
$xCAT::TableUtils::tftpdir = "$root/$name";
|
|
make_path(
|
|
"$xCAT::TableUtils::tftpdir/xcat",
|
|
"$xCAT::TableUtils::tftpdir/etc",
|
|
);
|
|
my @files = ("$xCAT::TableUtils::tftpdir/xcat/genesis.kernel.$arch");
|
|
if ($image_type eq 'legacy') {
|
|
push @files,
|
|
"$xCAT::TableUtils::tftpdir/xcat/nbk.$arch",
|
|
"$xCAT::TableUtils::tftpdir/xcat/nbfs.$arch.gz";
|
|
} else {
|
|
push @files, "$xCAT::TableUtils::tftpdir/xcat/genesis.fs.$arch.gz";
|
|
}
|
|
foreach my $file (@files) {
|
|
open(my $fh, '>', $file) or die "Unable to create $file: $!";
|
|
close($fh);
|
|
}
|
|
}
|
|
|
|
sub run_mknb {
|
|
my ($arch) = @_;
|
|
my @responses;
|
|
xCAT_plugin::mknb::process_request(
|
|
{ arg => [$arch, '--configfileonly'] },
|
|
sub { push @responses, @_; },
|
|
);
|
|
return \@responses;
|
|
}
|
|
|
|
sub read_config {
|
|
my ($path) = @_;
|
|
open(my $fh, '<', $path) or die "Unable to read $path: $!";
|
|
my $content = do { local $/; <$fh> };
|
|
close($fh);
|
|
return $content;
|
|
}
|
|
|
|
sub generation_succeeded {
|
|
my ($responses, $description) = @_;
|
|
ok(
|
|
!grep({ ref($_) eq 'HASH' && $_->{error} } @{$responses}),
|
|
$description,
|
|
);
|
|
}
|
|
|
|
sub use_reporter_address_maps {
|
|
$xCAT::NetworkUtils::normnet_addresses = {
|
|
'192.168.144.0/20' => [
|
|
'192.168.148.10',
|
|
'192.168.149.100',
|
|
],
|
|
};
|
|
$xCAT::NetworkUtils::hexnet_addresses = {
|
|
c0a89 => [
|
|
'192.168.148.10',
|
|
'192.168.149.100',
|
|
],
|
|
};
|
|
$xCAT::TableUtils::site_master = 'master.example.com';
|
|
@xCAT::NetworkUtils::master_addresses = ('203.0.113.10');
|
|
}
|
|
|
|
my $tmpdir = tempdir(CLEANUP => 1);
|
|
$::XCATROOT = "$tmpdir/xcatroot";
|
|
make_path(
|
|
"$::XCATROOT/share/xcat/netboot/genesis/x86_64",
|
|
"$::XCATROOT/share/xcat/netboot/genesis/ppc64",
|
|
);
|
|
|
|
use_reporter_address_maps();
|
|
prepare_tftpdir($tmpdir, 'tftpboot-x86', 'x86_64');
|
|
my $responses = run_mknb('x86_64');
|
|
generation_succeeded($responses, 'x86 configuration generation succeeds');
|
|
|
|
my $genesis_pxe = read_config(
|
|
"$xCAT::TableUtils::tftpdir/pxelinux.cfg/C0A89"
|
|
);
|
|
like(
|
|
$genesis_pxe,
|
|
qr/^ KERNEL xcat\/genesis\.kernel\.x86_64$/m,
|
|
'PXELINUX selects the Genesis kernel',
|
|
);
|
|
like(
|
|
$genesis_pxe,
|
|
qr/^ APPEND initrd=xcat\/genesis\.fs\.x86_64\.gz /m,
|
|
'PXELINUX makes the Genesis initramfs relative to the configured TFTP root',
|
|
);
|
|
unlike(
|
|
$genesis_pxe,
|
|
qr/\Q$xCAT::TableUtils::tftpdir\E/,
|
|
'PXELINUX does not expose the configured TFTP root',
|
|
);
|
|
|
|
foreach my $relative_path (
|
|
'xcat/xnba/nets/192.168.144.0_20',
|
|
'pxelinux.cfg/C0A89',
|
|
) {
|
|
my $content = read_config("$xCAT::TableUtils::tftpdir/$relative_path");
|
|
like(
|
|
$content,
|
|
qr/xcatd=192\.168\.148\.10:3001/,
|
|
"$relative_path uses the first address as the xcatd endpoint",
|
|
);
|
|
unlike(
|
|
$content,
|
|
qr/xcatd=192\.168\.149\.100:3001/,
|
|
"$relative_path does not use the later floating address as the xcatd endpoint",
|
|
);
|
|
}
|
|
|
|
use_reporter_address_maps();
|
|
prepare_tftpdir($tmpdir, 'tftpboot-x86-legacy', 'x86_64', 'legacy');
|
|
$responses = run_mknb('x86_64');
|
|
generation_succeeded($responses, 'legacy x86 configuration generation succeeds');
|
|
|
|
my $legacy_pxe = read_config(
|
|
"$xCAT::TableUtils::tftpdir/pxelinux.cfg/C0A89"
|
|
);
|
|
like(
|
|
$legacy_pxe,
|
|
qr/^ KERNEL xcat\/nbk\.x86_64$/m,
|
|
'PXELINUX keeps the legacy kernel',
|
|
);
|
|
like(
|
|
$legacy_pxe,
|
|
qr/^ APPEND initrd=xcat\/nbfs\.x86_64\.gz /m,
|
|
'PXELINUX keeps the legacy initramfs path',
|
|
);
|
|
|
|
use_reporter_address_maps();
|
|
prepare_tftpdir($tmpdir, 'tftpboot-power', 'ppc64');
|
|
$responses = run_mknb('ppc64');
|
|
generation_succeeded($responses, 'POWER configuration generation succeeds');
|
|
|
|
foreach my $relative_path (
|
|
'pxelinux.cfg/p/192.168.144.0_20',
|
|
'etc/c0a89',
|
|
) {
|
|
my $content = read_config("$xCAT::TableUtils::tftpdir/$relative_path");
|
|
like(
|
|
$content,
|
|
qr/kernel http:\/\/192\.168\.148\.10\//,
|
|
"$relative_path uses the first address for the kernel URL",
|
|
);
|
|
like(
|
|
$content,
|
|
qr/initrd http:\/\/192\.168\.148\.10\//,
|
|
"$relative_path uses the first address for the initrd URL",
|
|
);
|
|
like(
|
|
$content,
|
|
qr/xcatd=192\.168\.148\.10:3001/,
|
|
"$relative_path uses the first address as the xcatd endpoint",
|
|
);
|
|
unlike(
|
|
$content,
|
|
qr/(?:kernel|initrd) http:\/\/192\.168\.149\.100\/|xcatd=192\.168\.149\.100:3001/,
|
|
"$relative_path has no functional endpoint using the later floating address",
|
|
);
|
|
}
|
|
|
|
# the default HTTP port is left out of the generated URLs, but a port that is
|
|
# not the default still has to be carried through
|
|
$xCAT::TableUtils::site_httpport = '8080';
|
|
use_reporter_address_maps();
|
|
prepare_tftpdir($tmpdir, 'tftpboot-power-altport', 'ppc64');
|
|
$responses = run_mknb('ppc64');
|
|
generation_succeeded($responses, 'POWER configuration generation succeeds with a non-default HTTP port');
|
|
|
|
my $altport_content = read_config("$xCAT::TableUtils::tftpdir/pxelinux.cfg/p/192.168.144.0_20");
|
|
like(
|
|
$altport_content,
|
|
qr/kernel http:\/\/192\.168\.148\.10:8080\//,
|
|
'a non-default HTTP port is kept in the kernel URL',
|
|
);
|
|
like(
|
|
$altport_content,
|
|
qr/initrd http:\/\/192\.168\.148\.10:8080\//,
|
|
'a non-default HTTP port is kept in the initrd URL',
|
|
);
|
|
$xCAT::TableUtils::site_httpport = undef;
|
|
|
|
$xCAT::NetworkUtils::normnet_addresses = {
|
|
'192.168.144.0/20' => ['192.168.148.10'],
|
|
};
|
|
$xCAT::NetworkUtils::hexnet_addresses = {
|
|
c0a89 => ['192.168.148.10'],
|
|
};
|
|
$xCAT::TableUtils::site_master = 'master.example.com';
|
|
@xCAT::NetworkUtils::master_addresses = ('203.0.113.10');
|
|
prepare_tftpdir($tmpdir, 'tftpboot-no-floating', 'x86_64');
|
|
$responses = run_mknb('x86_64');
|
|
generation_succeeded($responses, 'configuration generation without a floating address succeeds');
|
|
my $no_floating_xnba = read_config(
|
|
"$xCAT::TableUtils::tftpdir/xcat/xnba/nets/192.168.144.0_20"
|
|
);
|
|
my $no_floating_pxe = read_config(
|
|
"$xCAT::TableUtils::tftpdir/pxelinux.cfg/C0A89"
|
|
);
|
|
|
|
$xCAT::TableUtils::site_master = undef;
|
|
@xCAT::NetworkUtils::master_addresses = ();
|
|
prepare_tftpdir($tmpdir, 'tftpboot-no-floating', 'x86_64');
|
|
$responses = run_mknb('x86_64');
|
|
generation_succeeded($responses, 'configuration generation without site.master succeeds');
|
|
is(
|
|
read_config("$xCAT::TableUtils::tftpdir/xcat/xnba/nets/192.168.144.0_20"),
|
|
$no_floating_xnba,
|
|
'xNBA output is byte-identical without a site.master preference',
|
|
);
|
|
is(
|
|
read_config("$xCAT::TableUtils::tftpdir/pxelinux.cfg/C0A89"),
|
|
$no_floating_pxe,
|
|
'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/^set fallback=1$/m, 'a payload that cannot be fetched over HTTP falls back to the TFTP entry');
|
|
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 /tftpboot/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 /tftpboot/xcat/genesis\.fs\.riscv64\.gz$}m,
|
|
'the initrd line loads the Genesis initramfs',
|
|
);
|
|
|
|
# the Genesis payload is large and TFTP serves one client at a time, so the default
|
|
# entry fetches it over HTTP and the TFTP entry stays behind it
|
|
like($grub_cfg, qr/^ set root=http,192\.168\.148\.10$/m, 'the default entry fetches the payload over HTTP');
|
|
like($grub_cfg, qr/^ insmod http$/m, 'the HTTP entry loads the grub2 http module');
|
|
my ($first_entry) = $grub_cfg =~ /^(menuentry .*?^\})/ms;
|
|
like($first_entry || '', qr/set root=http,/, 'the first, default entry is the HTTP one');
|
|
like($grub_cfg, qr/^menuentry "xCAT Genesis riscv64 \(TFTP\)" \{$/m, 'a TFTP entry follows it');
|
|
like(
|
|
$grub_cfg,
|
|
qr/^menuentry "xCAT Genesis riscv64 \(TFTP\)" \{\n insmod tftp\n set root=tftp,192\.168\.148\.10\n linux \/xcat\/genesis\.kernel\.riscv64 xcatd=192\.168\.148\.10:3001 BOOTIF=\$net_default_mac\n initrd \/xcat\/genesis\.fs\.riscv64\.gz\n\}$/m,
|
|
'the TFTP entry keeps the paths relative to the TFTP root',
|
|
);
|
|
like($grub_cfg, qr/^\}\nfi\n\z/m, 'the configuration closes the menu entries and the cpu guard');
|
|
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 /tftpboot/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 = ();
|
|
|
|
# a non-default site.httpport reaches the HTTP entry
|
|
%xCAT::TableUtils::site_extra = ( httpport => '8080' );
|
|
$responses = run_mknb('riscv64');
|
|
generation_succeeded($responses, 'riscv64 configuration generation succeeds with a non-default HTTP port');
|
|
like(
|
|
read_config($grub_cfg_path),
|
|
qr/^ set root=http,192\.168\.148\.10:8080$/m,
|
|
'the HTTP entry uses the configured HTTP port',
|
|
);
|
|
like(
|
|
read_config($grub_cfg_path),
|
|
qr/^ set root=tftp,192\.168\.148\.10$/m,
|
|
'the TFTP entry is unaffected by the HTTP port',
|
|
);
|
|
%xCAT::TableUtils::site_extra = ();
|
|
|
|
# an lzma initramfs is preferred when mknb produced one
|
|
write_text(
|
|
"$xCAT::TableUtils::tftpdir/xcat/genesis.fs.riscv64.lzma", ''
|
|
);
|
|
$responses = run_mknb('riscv64');
|
|
generation_succeeded($responses, 'riscv64 configuration generation succeeds with an lzma initramfs');
|
|
like(
|
|
read_config($grub_cfg_path),
|
|
qr{^ initrd /tftpboot/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.<arch>, 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");
|
|
write_text( $loader, '' );
|
|
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");
|
|
write_text(
|
|
"$xCAT::TableUtils::tftpdir/boot/grub2/grub.cfg-C0A89", ''
|
|
);
|
|
$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;
|
|
|
|
make_path("$::XCATROOT/share/xcat/netboot/genesis-openembedded/s390x");
|
|
use_reporter_address_maps();
|
|
prepare_tftpdir($tmpdir, 'tftpboot-s390x', 's390x');
|
|
make_path("$xCAT::TableUtils::tftpdir/pxelinux.cfg");
|
|
chmod(0700, "$xCAT::TableUtils::tftpdir/pxelinux.cfg");
|
|
$responses = run_mknb('s390x');
|
|
generation_succeeded($responses, 's390x configuration generation succeeds');
|
|
is((stat "$xCAT::TableUtils::tftpdir/pxelinux.cfg")[2] & 07777, 0755,
|
|
's390x configuration generation repairs the parent directory mode');
|
|
|
|
my $s390x_qemu_path =
|
|
"$xCAT::TableUtils::tftpdir/pxelinux.cfg/s390x/192.168.144.0_20";
|
|
ok(-f $s390x_qemu_path, 's390x writes a QEMU network IPL configuration');
|
|
my $s390x_classes = xCAT::DHCP::BootPolicy->kea_s390x_network_classes(
|
|
net => '192.168.144.0', prefix => 20,
|
|
);
|
|
my ($s390x_conf_file) = map { $_->{data} }
|
|
grep { $_->{name} eq 'conf-file' }
|
|
@{ $s390x_classes->[0]{'option-data'} };
|
|
is(
|
|
"$xCAT::TableUtils::tftpdir/pxelinux.cfg/$s390x_conf_file",
|
|
$s390x_qemu_path,
|
|
'the DHCP configuration name resolves to the file written by mknb',
|
|
);
|
|
is(
|
|
read_config($s390x_qemu_path),
|
|
"# pxelinux.cfg xCAT Genesis s390x\n"
|
|
. "DEFAULT xCAT\n"
|
|
. "LABEL xCAT\n"
|
|
. " KERNEL xcat/genesis.kernel.s390x\n"
|
|
. " INITRD xcat/genesis.fs.s390x.gz\n"
|
|
. " APPEND xcatd=192.168.148.10:3001 xcat.bootloader=s390-ccw console=ttysclp0\n",
|
|
'the QEMU configuration selects Genesis and the SCLP console',
|
|
);
|
|
unlike(
|
|
read_config($s390x_qemu_path),
|
|
qr/192\.168\.149\.100/,
|
|
's390x configurations do not use the later floating address',
|
|
);
|
|
%xCAT::TableUtils::site_extra = ( dhcpinterfaces => 'eth0,eth1:noboot' );
|
|
$xCAT::NetworkUtils::nic_ips = { eth0 => '10.0.0.1', eth1 => '192.168.148.10' };
|
|
$responses = run_mknb('s390x');
|
|
generation_succeeded($responses, 's390x honors :noboot on the selected xcatd address');
|
|
ok(!-e $s390x_qemu_path,
|
|
'a selected xcatd address on :noboot gets no s390x configuration');
|
|
%xCAT::TableUtils::site_extra = ();
|
|
$xCAT::NetworkUtils::nic_ips = undef;
|
|
$responses = run_mknb('s390x');
|
|
generation_succeeded($responses, 's390x configuration is restored after :noboot');
|
|
|
|
write_text($s390x_qemu_path, "admin network configuration\n");
|
|
$responses = run_mknb('s390x');
|
|
ok(
|
|
scalar(grep { ref($_) eq 'HASH' && $_->{error} && "@{$_->{error}}" =~ /Refusing to replace unmanaged/ } @{$responses}),
|
|
's390x refuses to replace an administrator-owned configuration',
|
|
);
|
|
is(read_config($s390x_qemu_path), "admin network configuration\n",
|
|
'the administrator-owned configuration is unchanged');
|
|
unlink($s390x_qemu_path);
|
|
$responses = run_mknb('s390x');
|
|
generation_succeeded($responses, 's390x configuration is restored after removing the unmanaged file');
|
|
|
|
unlink($s390x_qemu_path);
|
|
my $s390x_symlink_target = "$tmpdir/s390x-symlink-target";
|
|
symlink($s390x_symlink_target, $s390x_qemu_path)
|
|
or die "Unable to create s390x test symlink: $!";
|
|
$responses = run_mknb('s390x');
|
|
ok(
|
|
scalar(grep { ref($_) eq 'HASH' && $_->{error} && "@{$_->{error}}" =~ /Refusing to replace unmanaged/ } @{$responses}),
|
|
's390x refuses to follow an unmanaged configuration symlink',
|
|
);
|
|
ok(!-e $s390x_symlink_target,
|
|
'an unmanaged configuration symlink target is unchanged');
|
|
unlink($s390x_qemu_path);
|
|
$responses = run_mknb('s390x');
|
|
generation_succeeded($responses, 's390x configuration is restored after removing the symlink');
|
|
|
|
my $s390x_legacy_root = "$tmpdir/tftpboot-s390x-legacy";
|
|
make_path("$s390x_legacy_root/pxelinux.cfg/s390x");
|
|
my ($s390x_legacy_path, $s390x_legacy_error) =
|
|
xCAT_plugin::mknb::_write_s390x_discovery_config(
|
|
tftpdir => $s390x_legacy_root,
|
|
network => '192.168.144.0_20',
|
|
xcatd_address => '192.168.148.10',
|
|
xcatdport => 3001,
|
|
consolecmdline => 'console=ttysclp0',
|
|
kernel => 'xcat/nbk.s390x',
|
|
initrd => "$s390x_legacy_root/xcat/nbfs.s390x.gz",
|
|
);
|
|
is($s390x_legacy_error, undef, 'legacy s390x configuration is written');
|
|
like(
|
|
read_config($s390x_legacy_path),
|
|
qr/^ KERNEL xcat\/nbk\.s390x$/m,
|
|
'legacy s390x configuration selects its published kernel',
|
|
);
|
|
|
|
my $s390x_failure_root = "$tmpdir/tftpboot-s390x-failure";
|
|
make_path("$s390x_failure_root/pxelinux.cfg");
|
|
my (undef, $s390x_write_error) =
|
|
xCAT_plugin::mknb::_write_s390x_discovery_config(
|
|
tftpdir => $s390x_failure_root,
|
|
network => '192.168.144.0_20',
|
|
xcatd_address => '192.168.148.10',
|
|
xcatdport => 3001,
|
|
consolecmdline => 'console=ttysclp0',
|
|
kernel => 'xcat/genesis.kernel.s390x',
|
|
initrd => "$s390x_failure_root/xcat/genesis.fs.s390x.gz",
|
|
);
|
|
like(
|
|
$s390x_write_error,
|
|
qr/^Unable to write s390x Genesis configuration:/,
|
|
's390x configuration write failures are reported',
|
|
);
|
|
|
|
%xCAT::TableUtils::site_extra = (
|
|
defserialport => '2',
|
|
defserialspeed => '9600',
|
|
defserialflow => 'hard',
|
|
xcatdport => '3002',
|
|
);
|
|
$responses = run_mknb('s390x');
|
|
generation_succeeded($responses, 's390x ignores PC serial settings');
|
|
like(
|
|
read_config($s390x_qemu_path),
|
|
qr/^ APPEND xcatd=192\.168\.148\.10:3002 xcat\.bootloader=s390-ccw console=ttysclp0$/m,
|
|
's390x keeps its SCLP console and the configured xcatd port',
|
|
);
|
|
|
|
%xCAT::TableUtils::site_extra = ( dhcpinterfaces => 'eth0,eth1:noboot' );
|
|
$xCAT::NetworkUtils::nic_ips = { eth0 => '10.0.0.1', eth1 => '192.168.149.100' };
|
|
$responses = run_mknb('s390x');
|
|
generation_succeeded($responses, 's390x configuration generation honors :noboot');
|
|
ok(!-e $s390x_qemu_path, 'a :noboot network gets no QEMU s390x configuration');
|
|
%xCAT::TableUtils::site_extra = ();
|
|
$xCAT::NetworkUtils::nic_ips = undef;
|
|
|
|
done_testing();
|