mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-09-04 20:17:55 +00:00
test(dhcp): makedhcp -q hides a dhcpd.conf read failure and loses InfiniBand addresses
The static host query reads dhcpd.conf when no configuration is in memory. When the read fails the query returns nothing, and listnode reports "no DHCP reservation found" -- the answer for a node that has no reservation. The operator cannot tell the two apart. The same query only reads a "hardware ethernet" line. An InfiniBand node declares "hardware infiniband", so its query answer carries no hardware address. A twin declaration inside the same markers must not replace the primary one either. The new assertions drive the writer to build both InfiniBand shapes, set the path of dhcpd.conf to a file that does not exist, and call listnode. A deletion that names a hostname is asserted to keep the other declarations of the node. Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This commit is contained in:
@@ -7,6 +7,7 @@ use lib "$FindBin::Bin/../../xCAT-server/lib";
|
||||
use lib "$FindBin::Bin/../../xCAT-server/lib/perl";
|
||||
use lib "$FindBin::Bin/../../perl-xCAT";
|
||||
|
||||
use File::Temp qw(tempdir);
|
||||
use Test::More;
|
||||
|
||||
$ENV{XCATCFG} ||= 'SQLite:/tmp';
|
||||
@@ -111,4 +112,96 @@ my ($c1name, $c1ip) = xCAT_plugin::dhcp::_query_isc_static_host('compute-01', @s
|
||||
is($c1ip, 'ip-address = 192.168.201.12',
|
||||
'querying "compute-01" returns its own block');
|
||||
|
||||
# An InfiniBand node declares "hardware infiniband". Build the block with the writer, so
|
||||
# the query reads what makedhcp writes rather than a hand-made copy of it.
|
||||
my @ib_config;
|
||||
xCAT_plugin::dhcp::_add_isc_static_host(
|
||||
'ibnode', 'ibnode',
|
||||
'ff:00:00:00:00:00:02:00:00:02:c9:00:00:02:c9:03:00:0a:6f:ba',
|
||||
32, 'ib0', '192.0.2.20', '', 1, \@ib_config,
|
||||
);
|
||||
my ($ibname, $ibip, $ibhw) =
|
||||
xCAT_plugin::dhcp::_query_isc_static_host('ibnode', @ib_config);
|
||||
is($ibip, 'ip-address = 192.0.2.20',
|
||||
'an InfiniBand node reports the address of its reservation');
|
||||
is($ibhw,
|
||||
'hardware-address = ff:00:00:00:00:00:02:00:00:02:c9:00:00:02:c9:03:00:0a:6f:ba',
|
||||
'an InfiniBand node reports the hardware address of its reservation');
|
||||
|
||||
# An Ethernet node on an InfiniBand interface gets a twin declaration inside the same
|
||||
# markers. The query must answer with the primary declaration.
|
||||
my @twin_config;
|
||||
xCAT_plugin::dhcp::_add_isc_static_host(
|
||||
'twinnode', 'twinnode', 'b8:3f:d2:4a:68:aa', 1,
|
||||
'ib0', '192.0.2.21', '', 0, \@twin_config,
|
||||
);
|
||||
like(join('', @twin_config), qr/^host twinnode-xcat-ib \{$/m,
|
||||
'the writer produced the InfiniBand twin declaration the query must step over');
|
||||
my ($tname, $tip, $thw) =
|
||||
xCAT_plugin::dhcp::_query_isc_static_host('twinnode', @twin_config);
|
||||
is($thw, 'hardware-address = b8:3f:d2:4a:68:aa',
|
||||
'the twin declaration does not replace the primary hardware address');
|
||||
is($tip, 'ip-address = 192.0.2.21',
|
||||
'the twin declaration does not replace the primary address');
|
||||
|
||||
# `makedhcp -q` runs with no configuration in memory, so the query reads dhcpd.conf. A
|
||||
# file it cannot read must not look like a node without a reservation.
|
||||
my $tmpdir = tempdir(CLEANUP => 1);
|
||||
my $conffile = "$tmpdir/dhcpd.conf";
|
||||
open(my $wfh, '>', $conffile) or BAIL_OUT("cannot write $conffile: $!");
|
||||
print $wfh @dhcpconf;
|
||||
close($wfh);
|
||||
open(my $efh, '>', "$tmpdir/empty.conf") or BAIL_OUT("cannot write empty.conf: $!");
|
||||
close($efh);
|
||||
|
||||
{
|
||||
no warnings 'once';
|
||||
$xCAT_plugin::dhcp::dhcpconffile = $conffile;
|
||||
}
|
||||
my ($fname, $fip, $fhw, $ferr) =
|
||||
xCAT_plugin::dhcp::_query_isc_static_host('xcat30-cn');
|
||||
is($ferr, undef, 'a readable dhcpd.conf reports no error');
|
||||
is($fip, 'ip-address = 192.168.201.30',
|
||||
'the query reads the reservation from dhcpd.conf');
|
||||
|
||||
{
|
||||
no warnings 'once';
|
||||
$xCAT_plugin::dhcp::dhcpconffile = "$tmpdir/absent.conf";
|
||||
}
|
||||
my ($aname, $aip, $ahw, $aerr) =
|
||||
xCAT_plugin::dhcp::_query_isc_static_host('xcat30-cn');
|
||||
like($aerr, qr/\Qabsent.conf\E/,
|
||||
'a dhcpd.conf the query cannot read is reported as an error');
|
||||
is($aip, undef, 'a dhcpd.conf the query cannot read reports no address');
|
||||
|
||||
{
|
||||
no warnings 'once';
|
||||
$xCAT_plugin::dhcp::dhcpconffile = "$tmpdir/empty.conf";
|
||||
}
|
||||
my ($ename, $eip, $ehw, $eerr) =
|
||||
xCAT_plugin::dhcp::_query_isc_static_host('xcat30-cn');
|
||||
is($eerr, undef, 'an empty dhcpd.conf is not an error');
|
||||
is($eip, undef, 'an empty dhcpd.conf reports no reservation');
|
||||
|
||||
# listnode is what `makedhcp -q` calls. On an ISC-limited release it must pass the read
|
||||
# failure to the caller instead of answering "no reservation found".
|
||||
{
|
||||
no warnings 'once';
|
||||
$xCAT_plugin::dhcp::distro = 'ubuntu22.04';
|
||||
$xCAT_plugin::dhcp::dhcpconffile = "$tmpdir/absent.conf";
|
||||
}
|
||||
my @responses;
|
||||
eval {
|
||||
local $SIG{ALRM} = sub { die "listnode did not return\n" };
|
||||
alarm 20;
|
||||
xCAT_plugin::dhcp::listnode('xcat30-cn', sub { push @responses, $_[0] });
|
||||
alarm 0;
|
||||
1;
|
||||
};
|
||||
alarm 0;
|
||||
is(scalar(@responses), 1, 'a query answers once when dhcpd.conf cannot be read');
|
||||
like($responses[0]->{error}->[0], qr/\Qabsent.conf\E/,
|
||||
'the query reports the unreadable dhcpd.conf to the caller');
|
||||
is($responses[0]->{errorcode}->[0], 1, 'the query fails when dhcpd.conf cannot be read');
|
||||
|
||||
done_testing();
|
||||
|
||||
@@ -181,4 +181,22 @@ like($lazy_replacement, qr/^host node06-current \{$/m,
|
||||
is($update_started, 1,
|
||||
'the successful replacement records that cleanup has started');
|
||||
|
||||
# A node can hold several declarations. A deletion that names one hostname must remove
|
||||
# that declaration only.
|
||||
my @hostname_config;
|
||||
xCAT_plugin::dhcp::_add_isc_static_host(
|
||||
'node07', 'node07', '00:11:22:33:44:33', 1,
|
||||
'eth0', '192.0.2.9', '', 0, \@hostname_config,
|
||||
);
|
||||
xCAT_plugin::dhcp::_add_isc_static_host(
|
||||
'node07', 'node07-ib', '00:11:22:33:44:44', 32,
|
||||
'ib0', '192.0.2.9', '', 1, \@hostname_config,
|
||||
);
|
||||
xCAT_plugin::dhcp::_delete_isc_static_host('node07', \@hostname_config, 'node07-ib');
|
||||
my $hostname_remaining = join( '', @hostname_config );
|
||||
unlike($hostname_remaining, qr/^host node07-ib \{$/m,
|
||||
'a deletion that names a hostname removes that declaration');
|
||||
like($hostname_remaining, qr/^host node07 \{$/m,
|
||||
'a deletion that names a hostname keeps the other declarations of the node');
|
||||
|
||||
done_testing();
|
||||
|
||||
Reference in New Issue
Block a user