2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-09-28 16:20:51 +00:00

fix(xcat-core): a prerelease version keeps every package out of every suite

deb_belongs_to_dist read any trailing ~word in a package version as the
codename the deb was built for. Debian uses ~ for a prerelease and --release
takes whatever the caller gives it, so `--release 1~rc1` left every package
excluded from every suite, with --genesis nowhere in the command and the run
still reporting what it published. Only xcat-genesis-base carries a codename,
because only it carries a kernel, so only it is asked.

genesis_dists() names the releases a Genesis image can be built on. A plain
--genesis run took the release list the rest of the build uses, and focal is on
it: focal ships debhelper 12.10 and the package declares debhelper-compat
(= 13), so sbuild stopped on the build dependencies before dracut ran and the
run ended on its first release. The default plan now leaves focal out and says
so. A release named with --genesis-dist is still built as asked.

genesis_deb_per_codename.t covers both. Applying the codename rule to every
package again fails five assertions; a genesis_dists that filters nothing, or
an image that loses its own rule, fails two each.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This commit is contained in:
Daniel Hilst
2026-09-16 18:55:34 -03:00
parent 488a6d1fc7
commit 96aab32693
2 changed files with 40 additions and 1 deletions
+27
View File
@@ -38,6 +38,7 @@ our @EXPORT_OK = qw(
targetarch_from_target
genesis_chroot_name genesis_target_arch genesis_build_plan
genesis_log_errors genesis_log_deny_rules deb_belongs_to_dist
genesis_dists genesis_dist_reason
);
# Both builders echo the commands they run under --verbose. Set once, after
@@ -569,16 +570,42 @@ my @GENESIS_LOG_DENY = (
sub genesis_log_deny_rules { return @GENESIS_LOG_DENY; }
# The package built once per codename. It is the only one: it carries the kernel and the kernel
# modules of the root that built it.
my $GENESIS_IMAGE_DEB = qr{\Axcat-genesis-base-};
# Releases whose stock chroot cannot build that package, and why. focal ships debhelper 12 and
# xCAT-genesis-base declares debhelper-compat (= 13), so sbuild stops on the build dependencies
# before dracut runs.
my %GENESIS_DIST_UNSUPPORTED = (
focal => 'debhelper 12 cannot satisfy debhelper-compat (= 13)',
);
# genesis_dists: the releases of @dists a Genesis image can be built on.
sub genesis_dists {
my (@dists) = @_;
return grep { !exists $GENESIS_DIST_UNSUPPORTED{$_} } @dists;
}
# genesis_dist_reason: why a release was left out, or undef.
sub genesis_dist_reason { return $GENESIS_DIST_UNSUPPORTED{ $_[0] // '' }; }
# deb_belongs_to_dist: whether a built .deb may be published into one release.
#
# Almost every xcat-core deb is Architecture:all and the same file serves every release, so the
# answer is yes. The Genesis image is not: it is built per codename and carries that codename in
# its version (2.19.0-snap...~noble). Publishing all three into every suite lets apt serve the
# newest, which is the image of another release.
#
# Only that package is asked. A ~ in a version is Debian's prerelease separator before it is
# anything else, and --release takes whatever the caller gives it, so reading every ~ as a
# codename drops a whole `--release 1~rc1` build from every suite.
sub deb_belongs_to_dist {
my ($deb, $dist) = @_;
return 1 unless defined $deb && defined $dist && $dist ne '';
my $base = basename($deb);
my ($name) = $base =~ /\A([^_]+)_/;
return 1 unless defined $name && $name =~ $GENESIS_IMAGE_DEB;
return 1 unless $base =~ /_[^_]*~([A-Za-z0-9.]+)_[^_]*\.deb\z/;
return $1 eq $dist ? 1 : 0;
}
+13 -1
View File
@@ -40,6 +40,7 @@ use XCAT::BuildUtils qw(
lock_id_for take_build_lock sh_quote
sh sh_or_die usage rewrite_file write_script read_line buildinfo_text
genesis_build_plan genesis_log_errors deb_belongs_to_dist
genesis_dists genesis_dist_reason
);
# The xcat-core packages that ship as debs. xCAT-openbmc-py, xCAT-rmc and xCAT-release
@@ -91,7 +92,18 @@ $opts{gpg_key_name} //= 'xCAT Signing Key';
# The Genesis step is off unless it is asked for, so today's runs keep their behaviour.
$opts{genesis} = 1 if $opts{genesis_only};
$opts{genesis_dists} = @cli_genesis_dists ? \@cli_genesis_dists : $opts{dists};
# A release named on the command line is built as asked. The default list is the one the rest
# of the build uses, and not every release on it can build the image, so those are dropped and
# named rather than failing the run on its first codename.
if (@cli_genesis_dists) {
$opts{genesis_dists} = \@cli_genesis_dists;
} else {
$opts{genesis_dists} = [ genesis_dists($opts{dists}->@*) ];
for my $dist ($opts{dists}->@*) {
my $why = genesis_dist_reason($dist) or next;
say "genesis: leaving out $dist -- $why";
}
}
die "FATAL: --genesis-dist needs --genesis\n" if @cli_genesis_dists && !$opts{genesis};
die "FATAL: --genesis-arch needs --genesis\n" if $opts{genesis_arch} && !$opts{genesis};