diff --git a/.github/workflows/xcat_test.yml b/.github/workflows/xcat_test.yml index fa31e51ee5..46e4509e66 100644 --- a/.github/workflows/xcat_test.yml +++ b/.github/workflows/xcat_test.yml @@ -50,7 +50,7 @@ jobs: status=0 sudo sh -c 'cd "$1" && bats xCAT-test/native/getinstdisk_selection.bats' sh "$workdir" || status=1 sudo sh -c 'cd "$1" && bats xCAT-test/native/syslog_log_directory.bats' sh "$workdir" || status=1 - sudo sh -c 'cd "$1" && prove -v xCAT-test/native/getinstdisk_installer.t xCAT-test/native/enablekdump_per_node.t xCAT-test/native/sudoer_password_source.t xCAT-test/native/remoteshell_credentials.t' sh "$workdir" || status=1 + sudo sh -c 'cd "$1" && prove -v xCAT-test/native/getinstdisk_installer.t xCAT-test/native/template_root_password.t xCAT-test/native/enablekdump_per_node.t xCAT-test/native/sudoer_password_source.t xCAT-test/native/remoteshell_credentials.t' sh "$workdir" || status=1 exit "$status" - name: Prepare xCAT syslog directory if: ${{ !cancelled() }} diff --git a/xCAT-server/lib/perl/xCAT/Template.pm b/xCAT-server/lib/perl/xCAT/Template.pm index 747ba01e04..0fa6f3447c 100644 --- a/xCAT-server/lib/perl/xCAT/Template.pm +++ b/xCAT-server/lib/perl/xCAT/Template.pm @@ -1657,7 +1657,7 @@ sub envvar return ($ENV{$envvar}); } -sub crydb +sub crypt_field { my ($table, $key, $field) = @_; my @fields = [$field, 'cryptmethod']; @@ -1681,10 +1681,19 @@ sub crydb return xCAT::PasswordUtils::crypt_system_password($table, $kp, \@fields); } +sub crydb +{ + my ( $table, $key, $field ) = @_; + my $crypted = crypt_field( $table, $key, $field ); + return $crypted if defined($crypted) && length($crypted); + $tmplerr = "Unable to find requested field <$field> from table <$table>, with key <$key>"; + return ""; +} + sub crydb_or_locked { my ( $table, $key, $field ) = @_; - my $crypted = crydb( $table, $key, $field ); + my $crypted = crypt_field( $table, $key, $field ); return $crypted if defined($crypted) && length($crypted); return '*'; } diff --git a/xCAT-test/native/template_root_password.t b/xCAT-test/native/template_root_password.t new file mode 100644 index 0000000000..013c46a863 --- /dev/null +++ b/xCAT-test/native/template_root_password.t @@ -0,0 +1,56 @@ +#!/usr/bin/env perl +use strict; +use warnings; + +use File::Slurper qw(read_text write_text); +use FindBin; +use lib "$FindBin::Bin/../lib"; +use lib "$FindBin::Bin/../../perl-xCAT", "$FindBin::Bin/../../xCAT-server/lib/perl"; +use Test::More; + +use XCAT::Test::File qw(repo_path); +use XCAT::Test::Template qw(template_database set_row render_template); + +plan skip_all => 'template rendering requires Linux namespaces' unless $^O eq 'linux'; +my $database = template_database(); +set_row('site', {key => 'secureroot'}, {value => 0}); +set_row('nodetype', {node => 'node'}, {os => 'rhels10.0', arch => 'x86_64', provmethod => 'install'}); +my $kickstart = repo_path('xCAT-server/share/xcat/install/rh/compute.rhels10.tmpl'); +(my $pkglist = $kickstart) =~ s/\.tmpl$/.pkglist/; +my $output = "$database/ks"; + +sub render_kickstart { + return eval { + render_template($database, $kickstart, $output, 'node', $pkglist, '/install/media', 'rh', undef, + {xcatmaster => '192.0.2.1'}); + 1; + } ? '' : $@; +} + +my $error = render_kickstart(); +like($error, qr/Unable to find requested field from table , with key /, + 'a kickstart without a root password row is refused'); + +set_row('passwd', {key => 'system', username => 'root'}, {password => 'cluster'}); +$error = render_kickstart(); +is($error, '', 'a kickstart with a root password row renders') or diag($error); +my ($hash) = (-f $output ? read_text($output) : '') =~ /^rootpw --iscrypted (\S+)$/m; +ok(defined($hash) && crypt('cluster', $hash) eq $hash, 'the kickstart carries the hash of the root password'); + +set_row('nodetype', {node => 'node'}, {os => 'ubuntu24.04', arch => 'x86_64', provmethod => 'install'}); +my $passwd = xCAT::Table->new('passwd') or die 'Cannot open passwd'; +$passwd->delEntries({key => 'system', username => 'root'}); +$passwd->close(); +write_text("$database/image.pkglist", "vim\n"); +my $autoinstall = "$database/autoinstall.yaml"; +my $locked = eval { + render_template($database, repo_path('xCAT-server/share/xcat/install/ubuntu/compute.subiquity.tmpl'), + $autoinstall, 'node', "$database/image.pkglist", '/install/ubuntu24.04/x86_64', 'ubuntu', undef, + {xcatmaster => '192.0.2.1'}, osarch => 'x86_64'); + 1; +}; +ok($locked, 'an autoinstall without a root password row renders') or diag($@); +like(-f $autoinstall ? read_text($autoinstall) : '', qr/^\s+password: "\*"$/m, + 'the autoinstall locks the password that has no row'); + +done_testing();