mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-09-21 16:39:30 +00:00
test(xcat-core): the Ubuntu POWER diskful install loops in the installer
reg_linux_diskfull_installation_flat fails on ubuntu-22-ppc64le-devel and ubuntu-24-ppc64le-devel in build #121 of xcat-core-devel-ubuntu-cd. The node answers ping but the case ends on "root@xcat25-cn: Permission denied (publickey,password)" and the node status never leaves powering-on. The serial console shows why: the Subiquity installer starts, runs the early-commands, errors, tars /var/log/installer to port 8080 and reboots. Nine cycles in 75 minutes. The installed system never exists, so the address belongs to the live installer and it refuses the root key. Two causes, both POWER-only. mkinstall picks pre.ubuntu.subiquity, then overwrites that choice with pre.ubuntu.ppc64 for every ppc64 node. That script writes a partman recipe; the early-commands append it to /autoinstall.yaml, which Subiquity then cannot parse. pre.ubuntu.subiquity has a UEFI branch and a BIOS branch and nothing else, so a ppc64el node takes the BIOS branch and is given a bios_grub partition. POWER firmware boots from a PReP partition. debian_install_prescript.t drives the script choice, which mkinstall keeps inline, so it bails out. ubuntu_subiquity_storage.t gains a PReP case; its extracted block asks uname for the machine architecture, which the block does not do yet. Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
use Test::More;
|
||||
|
||||
# Ubuntu has two installers and two pre-install scripts that are not interchangeable.
|
||||
# pre.ubuntu.subiquity writes a curtin "storage:" document that the autoinstall
|
||||
# early-commands append to /autoinstall.yaml. pre.ubuntu.ppc64 writes a partman recipe
|
||||
# for the debian-installer, which is not YAML at all.
|
||||
#
|
||||
# mkinstall chose the subiquity script, then overwrote that choice for every ppc64
|
||||
# node. A ppc64el 24.04 install therefore appended a partman recipe to its
|
||||
# autoinstall.yaml, Subiquity failed on the malformed document, the error-commands
|
||||
# tarred /var/log/installer and the node rebooted into the installer again -- nine
|
||||
# times in build #121 of xcat-core-devel-ubuntu-cd, cell ubuntu-24-ppc64le-devel,
|
||||
# case reg_linux_diskfull_installation_flat. The node answered ping from the live
|
||||
# installer the whole time, so the case failed on
|
||||
# "root@xcat25-cn: Permission denied (publickey,password)".
|
||||
#
|
||||
# The ppc64 script belongs to the debian-installer path only.
|
||||
|
||||
use lib "$FindBin::Bin/../../perl-xCAT";
|
||||
use lib "$FindBin::Bin/../../xCAT-server/lib/perl";
|
||||
my $plugin = "$FindBin::Bin/../../xCAT-server/lib/xcat/plugins/debian.pm";
|
||||
plan skip_all => 'debian.pm not found' unless -r $plugin;
|
||||
eval { require $plugin; 1 } or plan skip_all => "could not load debian.pm: $@";
|
||||
|
||||
can_ok('xCAT_plugin::debian', 'install_prescript')
|
||||
or BAIL_OUT('mkinstall still chooses the pre-install script inline, so nothing can drive it');
|
||||
|
||||
sub chosen {
|
||||
my ($platform, $arch, $subiquity) = @_;
|
||||
my $path = xCAT_plugin::debian::install_prescript($platform, $arch, $subiquity);
|
||||
$path =~ s{.*/}{};
|
||||
return $path;
|
||||
}
|
||||
|
||||
# --- subiquity: the arch never changes the script -------------------------
|
||||
is(chosen('ubuntu', 'x86_64', 1), 'pre.ubuntu.subiquity',
|
||||
'an x86_64 subiquity install gets the subiquity pre-install script');
|
||||
is(chosen('ubuntu', 'ppc64el', 1), 'pre.ubuntu.subiquity',
|
||||
'a ppc64el subiquity install gets the subiquity pre-install script, not the partman one');
|
||||
is(chosen('ubuntu', 'ppc64le', 1), 'pre.ubuntu.subiquity',
|
||||
'the ppc64le spelling reaches the same script');
|
||||
is(chosen('ubuntu', 'ppc64', 1), 'pre.ubuntu.subiquity',
|
||||
'so does the bare ppc64 spelling');
|
||||
|
||||
# --- debian-installer: ppc64 keeps its own script -------------------------
|
||||
is(chosen('ubuntu', 'ppc64el', 0), 'pre.ubuntu.ppc64',
|
||||
'a ppc64el debian-installer install keeps the partman pre-install script');
|
||||
is(chosen('ubuntu', 'ppc64', 0), 'pre.ubuntu.ppc64',
|
||||
'and so does the bare ppc64 spelling');
|
||||
is(chosen('ubuntu', 'x86_64', 0), 'pre.ubuntu',
|
||||
'an x86_64 debian-installer install gets the plain script');
|
||||
|
||||
# --- the override is Ubuntu only -----------------------------------------
|
||||
is(chosen('debian', 'ppc64el', 0), 'pre.debian',
|
||||
'Debian on POWER has no ppc64 pre-install script to select');
|
||||
|
||||
done_testing();
|
||||
@@ -34,9 +34,10 @@ my ($storage_block) = $script =~ /(^if \[ -d \/sys\/firmware\/efi \]; then\n.*?\
|
||||
BAIL_OUT('the firmware branch that writes the partition file no longer matches')
|
||||
unless $storage_block;
|
||||
|
||||
my $brackets = () = $storage_block =~ /\[ /g;
|
||||
BAIL_OUT("the partitioning block now has $brackets bracket tests; the shadow below covers one")
|
||||
unless $brackets == 1;
|
||||
BAIL_OUT('the firmware test the shadow below answers is gone')
|
||||
unless $storage_block =~ /\[ -d \/sys\/firmware\/efi \]/;
|
||||
BAIL_OUT('the block no longer asks uname for the machine architecture')
|
||||
unless $storage_block =~ /uname -m/;
|
||||
|
||||
my $sandbox = File::Temp::tempdir( CLEANUP => 1 );
|
||||
my $partfile = File::Spec->catfile( $sandbox, 'partitionfile' );
|
||||
@@ -54,13 +55,17 @@ sub partition_config_for {
|
||||
open( my $fh, '>', $script ) or die "Unable to write $script: $!";
|
||||
# `[` is shadowed rather than the condition rewritten: bash resolves a function
|
||||
# ahead of the builtin, so the script's own test runs unmodified.
|
||||
my $machine = $firmware eq 'prep' ? 'ppc64le' : 'x86_64';
|
||||
print {$fh} <<"SHELL";
|
||||
INSTALL_DISK=/dev/sdz
|
||||
logger() { :; }
|
||||
uname() { builtin echo $machine; }
|
||||
# `[` is shadowed only for the firmware probe; every other test runs unmodified,
|
||||
# so the architecture branch is taken by the block's own comparison.
|
||||
[() {
|
||||
case "\$1 \$2" in
|
||||
"-d /sys/firmware/efi") return @{[ $firmware eq 'uefi' ? 0 : 1 ]} ;;
|
||||
*) builtin echo "unexpected bracket test: \$*" >&2; builtin return 2 ;;
|
||||
*) builtin [ "\$@" ;;
|
||||
esac
|
||||
}
|
||||
$storage_block
|
||||
@@ -110,7 +115,22 @@ ok( !exists $bios->{'efi-part'}, 'BIOS installs get no EFI partition' );
|
||||
is( $bios->{'bios-grub'}{flag}, 'bios_grub', 'they get a bios_grub partition instead' );
|
||||
is( $bios->{'disk-detected'}{grub_device}, 'true', 'and grub is installed to the disk' );
|
||||
|
||||
foreach my $firmware ( [ UEFI => $uefi ], [ BIOS => $bios ] ) {
|
||||
# POWER firmware reads neither an ESP nor a bios_grub partition. It boots from a PReP
|
||||
# partition, and curtin installs grub to that partition rather than to the disk.
|
||||
my $prep = partition_config_for('prep');
|
||||
ok( !exists $prep->{'efi-part'}, 'POWER installs get no EFI partition' );
|
||||
ok( !exists $prep->{'bios-grub'}, 'POWER installs get no bios_grub partition' );
|
||||
is( $prep->{'prep-part'}{type}, 'partition', 'POWER installs get a PReP partition' );
|
||||
is( $prep->{'prep-part'}{device}, 'disk-detected', 'on the detected install disk' );
|
||||
is( $prep->{'prep-part'}{flag}, 'prep', 'flagged prep, which is what SLOF reads' );
|
||||
is( $prep->{'prep-part'}{number}, '1', 'as the first partition' );
|
||||
is( $prep->{'prep-part'}{grub_device}, 'true', 'and grub is installed to it' );
|
||||
isnt( $prep->{'disk-detected'}{grub_device}, 'true',
|
||||
'not to the disk, which leaves POWER with nothing to boot' );
|
||||
ok( !exists $prep->{'prep-part-fs'},
|
||||
'the PReP partition carries no filesystem' );
|
||||
|
||||
foreach my $firmware ( [ UEFI => $uefi ], [ BIOS => $bios ], [ PReP => $prep ] ) {
|
||||
my ( $name, $config ) = @{$firmware};
|
||||
is( $config->{'root-part-fs'}{fstype}, 'ext4', "$name root filesystem is ext4" );
|
||||
is( $config->{'root-part-mount'}{path}, '/', "$name mounts root at /" );
|
||||
@@ -122,7 +142,7 @@ foreach my $firmware ( [ UEFI => $uefi ], [ BIOS => $bios ] ) {
|
||||
|
||||
# Subiquity re-serializes autoinstall.yaml and appends this file, so the block has
|
||||
# to start at column 0 -- asserted on what was written, not on the heredoc.
|
||||
foreach my $firmware ( [ UEFI => 'uefi' ], [ BIOS => 'bios' ] ) {
|
||||
foreach my $firmware ( [ UEFI => 'uefi' ], [ BIOS => 'bios' ], [ PReP => 'prep' ] ) {
|
||||
my ( $name, $key ) = @{$firmware};
|
||||
like( partition_yaml_for($key), qr/\Astorage:\n version: 1\n/,
|
||||
"$name config starts at column 0 with storage: version: 1" );
|
||||
|
||||
Reference in New Issue
Block a user