2
0
mirror of https://github.com/xcat2/xcat-dep.git synced 2026-09-30 23:05:17 +00:00

test(xcat-dep): publish and finalize take locks of cells they do not own

The apt publish reads staging/<codename>/<arch> of every expected arch,
but takes only the run lock of the host arch. A ppc64el run can refill
its staging while the publish assembles from it.

Finalize runs on one host and takes the cell locks of both arches. If it
dies, only that host can reclaim the locks of the other arch's cells,
and the builds that own those cells wait on them and fail.

These tests fail until the fix: the publish must refuse while any
expected arch holds its run lock, and finalize --finalize-arch must
write and lock only the cells of that arch.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This commit is contained in:
Daniel Hilst
2026-09-28 11:28:47 -03:00
parent f23a4e8786
commit 56631f8f36
2 changed files with 49 additions and 8 deletions
+27 -8
View File
@@ -1026,6 +1026,22 @@ sub test_finalize_cell_lock {
'finalize names the cell lock it waited for');
ok(-d $cell_lock, 'the build keeps its cell lock');
ok(!-e "$ppc/rh10/.ppc64le.lock", 'finalize releases the cell locks it took');
# Finalize of the ppc64le cells takes only their locks: the x86_64 cell lock of another machine
# does not stop it. It stops at the next check, the missing genesis rpm.
my $arch_log = "$tmp/finalize-arch.log";
my $arch_status = run_capture(
$arch_log,
$^X, $rpm_consumer,
'--repo-root', $repo_root,
'--finalize-xcat-dep', '--finalize-arch', 'ppc64le',
'--x86_64-repo', $x86, '--ppc64le-repo', $ppc,
);
isnt($arch_status, 0, 'finalize of an empty ppc64le cell fails');
unlike(read_binary($arch_log), qr/^Trying to unlock/m, 'finalize of ppc64le cells takes no x86_64 cell lock');
like(read_binary($arch_log), qr/no x86_64 xCAT-genesis-base rpm/, 'finalize of ppc64le cells reaches the genesis check');
ok(-d $cell_lock, 'the x86_64 cell lock of the other machine is left in place');
ok(!-e "$ppc/rh10/.ppc64le.lock", 'finalize releases the ppc64le cell lock');
}
sub test_rpm_signal_cleanup {
@@ -1082,16 +1098,19 @@ sub test_publish_lock {
stage_legacy_deb("$tmp/lock-deb", $output);
make_path($output);
# This process is a live amd64 run on the same host. The run lock is an XCAT::NFSLock, because
# flock on the shared tree fails with ENOTSUPP through the NFS re-export.
{
my $run_lock = "$output/.sbuild-all.amd64.nfslock";
# This process is a live build run on the same host. The publish reads the staging of every
# expected arch, so it waits for the run lock of each one. The run lock is an XCAT::NFSLock,
# because flock on the shared tree fails with ENOTSUPP through the NFS re-export.
for my $build_arch (qw(amd64 ppc64el)) {
my $run_lock = "$output/.sbuild-all.$build_arch.nfslock";
my $running = XCAT::NFSLock->acquire($run_lock);
my $run_log = "$tmp/deb-run-locked.log";
my $run_status = run_apt_consumer(log => $run_log, output => $output, apt_dir => $apt_root);
isnt($run_status, 0, 'a second amd64 run does not start beside a live one');
my $run_log = "$tmp/deb-run-locked-$build_arch.log";
my $run_status = run_apt_consumer(log => $run_log, output => $output, apt_dir => $apt_root,
extra => [ '--publish-lock-wait', '2' ]);
isnt($run_status, 0, "a publish does not start while a $build_arch run holds its lock");
like(read_binary($run_log), qr/^Trying to unlock \Q$run_lock\E failed after 1 retry;/m,
'the refusal names the run lock');
"the refusal names the $build_arch run lock");
ok(!-d "$apt_root/dists", "nothing is published while a $build_arch run holds its lock");
$running->release;
}
+22
View File
@@ -10,6 +10,7 @@ use lib "$RealBin/..";
use File::Temp qw(tempdir);
use File::Path qw(make_path);
use File::Basename qw(basename);
use File::Slurper qw(write_text);
use MockBuildUtils qw(install_deps_packages install_deps_command missing_perl_modules
required_pkgs version_matches rpm_sigmd5 rpm_version rpm_release rpm_is_signed
rpm_arch rpm_in_cell resolve_mock_cfg
@@ -381,6 +382,27 @@ SPEC
is($tarch{ppc64le}, 'ppc64', 'GENESIS_ARCHES: ppc64le maps to xCAT tarch ppc64');
}
# ---- finalize_xcat_dep only => [...]: write only the cells of the named arches -----------------
# Each host finalizes the cells it deploys, so a cell lock is never held from another host.
{
my $tmp = tempdir(CLEANUP => 1);
my ($x, $p) = ("$tmp/r/rh9/x86_64", "$tmp/r/rh9/ppc64le");
make_path($x, $p);
write_text("$x/xCAT-genesis-base-x86_64-2.19.1-1.noarch.rpm", "x86 genesis\n");
write_text("$p/xCAT-genesis-base-ppc64-2.19.1-1.noarch.rpm", "ppc genesis\n");
my @reindexed;
quiet { finalize_xcat_dep("$tmp/r", "$tmp/r", only => ['ppc64le'],
reindex => sub { push @reindexed, $_[0] }) };
ok(-f "$p/xCAT-genesis-base-x86_64-2.19.1-1.noarch.rpm", 'the ppc64le cell gets the x86_64 genesis');
ok(!-e "$x/xCAT-genesis-base-ppc64-2.19.1-1.noarch.rpm", 'the x86_64 cell is not written');
is_deeply(\@reindexed, [$p], 'only the ppc64le cell is re-indexed');
my $bad = eval { quiet { finalize_xcat_dep("$tmp/r", "$tmp/r", only => ['riscv64']) }; 1 };
ok(!$bad, 'an arch outside the cross-arch matrix is refused');
like($@, qr/\AFATAL: \[finalize\] no cross-arch genesis for arch 'riscv64'/,
'the refusal names the arch');
}
# ---- restamp_release_line: CD --build-number Release stamping (PR #62 review point 1) ----------
# A fresh stamp is appended after the Release token, preserving any %{?dist} macro.
{