diff --git a/xCAT-test/unit/debian_install_prescript.t b/xCAT-test/unit/debian_install_prescript.t new file mode 100644 index 000000000..9edfde213 --- /dev/null +++ b/xCAT-test/unit/debian_install_prescript.t @@ -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(); diff --git a/xCAT-test/unit/ubuntu_subiquity_storage.t b/xCAT-test/unit/ubuntu_subiquity_storage.t index 288296db0..a6983d543 100644 --- a/xCAT-test/unit/ubuntu_subiquity_storage.t +++ b/xCAT-test/unit/ubuntu_subiquity_storage.t @@ -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" );