2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-09-25 01:04:05 +00:00

test(xcat-core): a failed extraction in the error-commands test stops the whole suite

ubuntu_subiquity_error_commands.t called BAIL_OUT at both places where
its extraction of the error-commands block stopped matching. prove stops
every remaining file on a bail-out, so a change to the template that
breaks the regex in this file also hides every test that would have run
after it. die is just as loud and costs only this file.

Three comments the branch added also carried the bug report: the test
header, the template comment and the Template.pm comment each traced the
failure from the error command to the provisioning timeout. Each now
states the constraint the reader cannot see in the code.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This commit is contained in:
Daniel Hilst
2026-09-14 08:29:39 -03:00
parent c98e868cb3
commit db820cfcc0
3 changed files with 13 additions and 18 deletions
+1 -2
View File
@@ -1853,8 +1853,7 @@ my $UBUNTU_ARCHIVE_KEYRING = '/usr/share/keyrings/ubuntu-archive-keyring.gpg';
# The apt lines that keep the recommended packages out of the install. ospkgs installs without
# them and the installer matches it. ppc64el is the exception: curtin installs a bootloader
# package of its own for UEFI and for s390x only, and on a PReP machine install_grub runs
# "dpkg-reconfigure grub-ieee1275" on a package the Ubuntu kernel image merely recommends. With
# the recommended packages off that package is absent and the install stops there.
# "dpkg-reconfigure grub-ieee1275" on a package the Ubuntu kernel image only recommends.
sub ubuntu_subiquity_no_recommends_lines
{
my ($osarch) = @_;
@@ -128,8 +128,7 @@ autoinstall:
- ['bash', '-c', 'xm=#XCATVAR:XCATMASTER#; port="#TABLEBLANKOKAY:site:key=xcatiport:value#"; [ -n "$port" ] || port=3002; ok=0; for i in 1 2 3 4 5; do if exec 3<>/dev/tcp/$xm/$port; then if read -r -t 10 hello <&3 && [ "$hello" = "ready" ]; then printf "next\n" >&3; if read -r -t 10 ack <&3 && [ "$ack" = "done" ]; then ok=1; fi; fi; exec 3>&- 3<&-; [ "$ok" = 1 ] && break; fi; sleep 5; done; if [ "$ok" != 1 ]; then echo "xcat: FAILED to flip $(hostname) to local-disk boot via $xm:$port; the node will PXE back into the installer" >>/target/var/log/xcat/xcat.log; fi; exit 0']
error-commands:
# Subiquity waits for every error command to return. "nc -l 8080" waits for a collector, which
# an unattended install does not have, so the node held the failure until the provisioning
# timeout reset it and the reason never left the node. Keep the archive on the installer, and
# print the end of the curtin log to the console, which the management node records.
# an unattended install does not have. Keep the archive on the installer, and print the end of
# the curtin log to the console, which the management node records.
- ['sh', '-c', 'tar -c --ignore-failed-read --transform="s/^/#HOSTNAME#-logs\//" /var/crash /var/log/installer /tmp/pre-install.log /autoinstall.yaml >/run/#HOSTNAME#-logs.tar 2>/dev/null; exit 0']
- ['sh', '-c', 'tail -n 80 /var/log/installer/curtin-install.log >"${XCAT_ERROR_CONSOLE:-/dev/console}" 2>/dev/null; exit 0']
@@ -6,15 +6,13 @@ use FindBin;
use File::Temp qw(tempdir);
use Test::More;
# Subiquity waits for every error command to return before it reports the failure. The template
# used to offer the installer logs with "nc -l 8080", which waits for a collector that an
# unattended install never has, so a failed install stopped there: the node answered ping with no
# disk or network activity for as long as the provisioning timeout allowed, and the reason for the
# failure stayed on the node. That is how a missing grub-ieee1275 on ppc64el read as a wedged
# curtin extract.
# Subiquity waits for every error command to return before it reports the failure. An error
# command that waits for a collector an unattended install does not have therefore holds the
# node until the provisioning timeout.
#
# Run the error commands, with the programs that would reach the host or the network replaced, and
# check that they return and that they write the end of the curtin log where the caller points.
# Run the error commands, with the programs that would reach the host or the network replaced,
# and check that they return and that they write the end of the curtin log where the caller
# points.
my $tmpl = "$FindBin::Bin/../../xCAT-server/share/xcat/install/ubuntu/compute.subiquity.tmpl";
plan skip_all => 'compute.subiquity.tmpl not found' unless -r $tmpl;
@@ -24,7 +22,7 @@ my $source = do { local $/; <$fh> };
close $fh;
my ($block) = $source =~ m{^ error-commands:\n((?: [-#].*\n)+)}m;
BAIL_OUT('the template declares no error-commands') unless $block;
die('the template declares no error-commands') unless $block;
# One command per list item. The list form ['sh', '-c', '...'] carries the command in its last
# element; a plain item is the command itself.
@@ -35,15 +33,14 @@ foreach my $line (split /\n/, $block) {
if ($item =~ m{^\['[^']+', '-c', '(.*)'\]$}) { push @commands, $1; }
else { push @commands, $item; }
}
BAIL_OUT('no error command found in the block') unless @commands;
die('no error command found in the block') unless @commands;
my $root = tempdir(CLEANUP => 1);
my $console = "$root/console";
my $script = "$root/error-commands.sh";
# nc, tar and tail are shadowed: bash resolves a function ahead of PATH, so the commands run as
# written while nothing reaches the host or the network. nc waits the way a listener with no
# collector waits.
# bash resolves a function ahead of PATH, so the commands run as written while nothing reaches
# the host or the network. The nc shadow waits the way a listener with no collector waits.
open(my $out, '>', $script) or die "open $script: $!";
print {$out} "export XCAT_ERROR_CONSOLE='$console'\n";
print {$out} "nc() { sleep 300; }\n";