diff --git a/.github/workflows/xcat_test.yml b/.github/workflows/xcat_test.yml index 7159916c7..86d3d6c88 100644 --- a/.github/workflows/xcat_test.yml +++ b/.github/workflows/xcat_test.yml @@ -26,6 +26,9 @@ jobs: - name: Exercise image package policy if: ${{ !cancelled() }} run: prove xCAT-test/native/el10_image_package_policy.t + - name: Exercise image chroot mounts + if: ${{ !cancelled() }} + run: prove xCAT-test/native/rh_genimage_chroot_mounts.t - name: Check Debian probe payload permissions if: ${{ !cancelled() }} run: bats xCAT-test/native/probe_debian_permissions.bats diff --git a/xCAT-server/share/xcat/netboot/rh/genimage b/xCAT-server/share/xcat/netboot/rh/genimage index 1afc5d325..e6c2543ae 100755 --- a/xCAT-server/share/xcat/netboot/rh/genimage +++ b/xCAT-server/share/xcat/netboot/rh/genimage @@ -123,7 +123,8 @@ sub mount_chroot { } if (-d "/run") { - system("mount --bind /run $rootimg_dir/run"); + system("mkdir -p $rootimage_dir/run"); + system("mount --bind /run $rootimage_dir/run"); } } diff --git a/xCAT-test/native/README.md b/xCAT-test/native/README.md index f5d6f834c..3678c74f4 100644 --- a/xCAT-test/native/README.md +++ b/xCAT-test/native/README.md @@ -86,15 +86,17 @@ Net::DNS: ``` prove xCAT-test/native/genimage_network_drivers.t \ - xCAT-test/native/el10_image_package_policy.t + xCAT-test/native/el10_image_package_policy.t \ + xCAT-test/native/rh_genimage_chroot_mounts.t ``` These cases run complete callers in private filesystems with no network. They check driver configuration after real driver-disk loading, media-import -records and parsed RPM installation scriptlets. +records, parsed RPM installation scriptlets and the mounts that a new RPM +image has when its packages install. External package downloads, service management, disk mounts and initrd creation use command fixtures. These cases do not boot an image or qualify hardware. -The two Perl image caller tests fail if run as root. +The Perl image caller tests fail if run as root. The default BATS suite also runs `networkmanager_postscript.bats`. It renders installation postscripts and checks their network configuration in isolation. diff --git a/xCAT-test/native/rh_genimage_chroot_mounts.t b/xCAT-test/native/rh_genimage_chroot_mounts.t new file mode 100644 index 000000000..5096d0d4c --- /dev/null +++ b/xCAT-test/native/rh_genimage_chroot_mounts.t @@ -0,0 +1,56 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use FindBin; +use lib "$FindBin::Bin/../lib"; +use File::Path qw(make_path); +use Test::More; +use XCAT::Test::ImageSandbox; + +plan skip_all => 'Linux namespaces require Linux' unless $^O eq 'linux'; +die('Run the image caller tests as an unprivileged user') unless $>; + +my $image = 'work/image/rootimg'; +for my $case (['rh', 'rhels9.6'], ['rocky', 'rocky9.6'], ['rh', 'rhels6.10']) { + my ($builder, $os) = @$case; + my @expected = ("--bind /run /$image/run"); + unshift @expected, "proc /$image/proc -t proc", "sysfs /$image/sys -t sysfs" unless $os eq 'rhels6.10'; + for my $build (qw(first repeated)) { + subtest "$builder $os $build build" => sub { + my $box = XCAT::Test::ImageSandbox->new(); + make_path("$box->{root}/install/$os/x86_64/repodata"); + make_path(map { "$box->{root}/$image/$_" } qw(proc sys dev run)) if $build eq 'repeated'; + $box->write('work/compute.pkglist', "bash\n"); + + # Like mount(8), the fixture refuses a mount point that does not exist. + $box->command('mount', <<'SH'); +mount=$* +operands=0 +while [ "$#" -gt 0 ]; do + case $1 in + -t|-o) shift ;; + -*) ;; + *) operands=$((operands + 1)); [ "$operands" -eq 2 ] && target=$1 ;; + esac + shift +done +if [ ! -d "$target" ]; then + printf 'mount: %s: mount point does not exist.\n' "$target" >&2 + exit 32 +fi +printf '%s\n' "$mount" >>/work/mounts +SH + $box->command($_, ": >>/work/mounts\ncat /work/mounts >/work/install-mounts\nexit 1\n") for qw(dnf yum); + + my ($rc, $output, $error) = $box->run('perl', "/repo/xCAT-server/share/xcat/netboot/$builder/genimage", + '-a', 'x86_64', '-o', $os, '-p', 'compute', '--pkglist', '/work/compute.pkglist', + '--srcdir', "/install/$os/x86_64", '--rootimgdir', '/work/image', 'fixture-image'); + ok(-f "$box->{root}/work/install-mounts", 'the build reaches the package installation') + or diag($output, $error); + unlike($error, qr/mount point does not exist/, 'every mount point exists before its mount'); + my $mounts = -f "$box->{root}/work/install-mounts" ? $box->read('work/install-mounts') : ''; + is_deeply([split /\n/, $mounts], \@expected, 'packages install with the host /run in the image'); + }; + } +} +done_testing();