From 55c49c4ab287214da5fe1988a78f1db930f704e8 Mon Sep 17 00:00:00 2001 From: Daniel Hilst <392820+dhilst@users.noreply.github.com> Date: Tue, 28 Jul 2026 11:39:49 -0300 Subject: [PATCH] fix(xcat-dep): pin manifest package Versions and enforce them at build time Replace the `*` placeholders in package-manifest.conf with the concrete package Versions each source builds (e.g. ipmitool-xcat=1.8.18, perl-Sys-Virt=11.10.0, xCAT-genesis-base=2.19.0). Only the Version is pinned, not the Release (per-EL dist tag / genesis snap), and the Version is identical across all targets so the same pin applies everywhere. Enforce the pins: after collection, rpm_version() reads each required package's built %{version} from the repo and build_one_target fails the run if it differs from the pin (or the package is absent). `*` still accepts any version. This turns an unnoticed source Version bump into an explicit, actionable failure instead of a silently-shipped surprise. Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com> --- mockbuild-all.pl | 39 ++++++++++ packages-manifest.conf | 163 +++++++++++++++++++++-------------------- 2 files changed, 123 insertions(+), 79 deletions(-) diff --git a/mockbuild-all.pl b/mockbuild-all.pl index f1651ae..b074877 100755 --- a/mockbuild-all.pl +++ b/mockbuild-all.pl @@ -584,6 +584,24 @@ if (!$skip_genesis && !$dry_run) { } } +# Manifest version pins: every required package must be present at its pinned version. A build +# that produces a different version (a source version bump not reflected here) fails the run; +# a manifest value of '*' accepts any version. Only the Version is pinned, not the Release +# (which carries the per-EL dist tag and the genesis snap timestamp). +if (!$dry_run && !$skip_build) { + my @vmiss; + for my $pkg (sort keys %req) { + my $want = $req{$pkg}; + next if !defined($want) || $want eq '*'; + my $got = rpm_version($repo_dir, $pkg); + if (!defined $got) { push @vmiss, "$pkg: not built"; } + elsif ($got ne $want) { push @vmiss, "$pkg: built $got, manifest pins $want"; } + } + die "FATAL: manifest version mismatch for $target:\n " . join("\n ", @vmiss) . "\n" + if @vmiss; + print "[manifest] version pins satisfied for $target\n"; +} + print_step('Collect source RPM artifacts'); print "source collection roots:\n"; print " $_\n" for @srpm_collect_roots; @@ -1108,6 +1126,27 @@ sub have_rpm { return scalar(@m) > 0; } +# rpm_version: %{version} of the built binary rpm named under $dir (undef if absent). +# Skips src/debug rpms and confirms the rpm's real %{name} matches (glob can over-match). +# 'xCAT-genesis-base' matches the arch-suffixed rpm name (xCAT-genesis-base-x86_64 / -ppc64). +sub rpm_version { + my ($dir, $name) = @_; + my $glob = ($name eq 'xCAT-genesis-base') + ? "$dir/xCAT-genesis-base-*.rpm" + : "$dir/${name}-*.rpm"; + for my $f (sort glob($glob)) { + next if $f =~ /\.src\.rpm$/ || $f =~ /-debug(?:info|source)-/; + my $n = `rpm -qp --qf '%{name}' ${\ sh_quote($f)} 2>/dev/null`; + my $match = ($name eq 'xCAT-genesis-base') + ? ($n =~ /^xCAT-genesis-base-/) : ($n eq $name); + next unless $match; + my $v = `rpm -qp --qf '%{version}' ${\ sh_quote($f)} 2>/dev/null`; + chomp $v; + return $v; + } + return undef; +} + # read_manifest: parse packages-manifest.conf into %{ target => { package => version|'*' } }. # INI format: [target] sections; "package=version|*" entries; blank / "#" / ";" lines ignored. # Returns an empty hash if the file is absent (callers that build require a section per target). diff --git a/packages-manifest.conf b/packages-manifest.conf index 9fe17fc..56fbee8 100644 --- a/packages-manifest.conf +++ b/packages-manifest.conf @@ -3,12 +3,17 @@ # One [section] per mockbuild-all target (matches --target). Each entry is # = # where is the builder/package name (the dep builder name, the perl -# package name, or xCAT-genesis-base) and the value is a required version or `*` -# for "any version the source produces". +# package name, or xCAT-genesis-base) and the value is the required package +# Version. The build must produce exactly that Version or the run fails (a value +# of `*` accepts any version). Only the Version is pinned -- not the Release, +# which carries the per-EL dist tag (elN) and the genesis snap. Bump a +# pin here when the corresponding source Version is bumped; xCAT-genesis-base's +# Version tracks xcat-core's marketing Version. # # mockbuild-all.pl reads this file and, per target, builds ONLY the listed # packages -- a package not listed for a target is not built for it. Any listed -# package that fails to build fails the whole run (no tolerated failures). +# package that fails to build (or builds a mismatched version) fails the whole +# run (no tolerated failures). # # # Per-EL perl set: a perl module is required from xcat-dep only on the releases @@ -23,89 +28,89 @@ # but it is built for every target anyway because some users still deploy it. [alma+epel-8-x86_64] -conserver-xcat=* -elilo-xcat=* -goconserver=* -grub2-xcat=* -ipmitool-xcat=* -syslinux-xcat=* -xnba-undi=* -perl-HTML-Form=* -perl-HTTP-Async=* -perl-IO-Stty=* -perl-Net-HTTPS-NB=* -xCAT-genesis-base=* +conserver-xcat=8.2.1 +elilo-xcat=3.14 +goconserver=0.3.3 +grub2-xcat=1.0 +ipmitool-xcat=1.8.18 +syslinux-xcat=6.03 +xnba-undi=1.21.1 +perl-HTML-Form=6.07 +perl-HTTP-Async=0.30 +perl-IO-Stty=0.04 +perl-Net-HTTPS-NB=0.14 +xCAT-genesis-base=2.19.0 [alma+epel-8-ppc64le] -conserver-xcat=* -elilo-xcat=* -goconserver=* -grub2-xcat=* -ipmitool-xcat=* -syslinux-xcat=* -xnba-undi=* -perl-HTML-Form=* -perl-HTTP-Async=* -perl-IO-Stty=* -perl-Net-HTTPS-NB=* -xCAT-genesis-base=* +conserver-xcat=8.2.1 +elilo-xcat=3.14 +goconserver=0.3.3 +grub2-xcat=1.0 +ipmitool-xcat=1.8.18 +syslinux-xcat=6.03 +xnba-undi=1.21.1 +perl-HTML-Form=6.07 +perl-HTTP-Async=0.30 +perl-IO-Stty=0.04 +perl-Net-HTTPS-NB=0.14 +xCAT-genesis-base=2.19.0 [alma+epel-9-x86_64] -conserver-xcat=* -elilo-xcat=* -goconserver=* -grub2-xcat=* -ipmitool-xcat=* -syslinux-xcat=* -xnba-undi=* -perl-HTTP-Async=* -perl-IO-Stty=* -perl-Net-HTTPS-NB=* -perl-Sys-Virt=* -xCAT-genesis-base=* +conserver-xcat=8.2.1 +elilo-xcat=3.14 +goconserver=0.3.3 +grub2-xcat=1.0 +ipmitool-xcat=1.8.18 +syslinux-xcat=6.03 +xnba-undi=1.21.1 +perl-HTTP-Async=0.30 +perl-IO-Stty=0.04 +perl-Net-HTTPS-NB=0.14 +perl-Sys-Virt=11.10.0 +xCAT-genesis-base=2.19.0 [alma+epel-9-ppc64le] -conserver-xcat=* -elilo-xcat=* -goconserver=* -grub2-xcat=* -ipmitool-xcat=* -syslinux-xcat=* -xnba-undi=* -perl-HTTP-Async=* -perl-IO-Stty=* -perl-Net-HTTPS-NB=* -perl-Sys-Virt=* -xCAT-genesis-base=* +conserver-xcat=8.2.1 +elilo-xcat=3.14 +goconserver=0.3.3 +grub2-xcat=1.0 +ipmitool-xcat=1.8.18 +syslinux-xcat=6.03 +xnba-undi=1.21.1 +perl-HTTP-Async=0.30 +perl-IO-Stty=0.04 +perl-Net-HTTPS-NB=0.14 +perl-Sys-Virt=11.10.0 +xCAT-genesis-base=2.19.0 [alma+epel-10-x86_64] -conserver-xcat=* -elilo-xcat=* -goconserver=* -grub2-xcat=* -ipmitool-xcat=* -syslinux-xcat=* -xnba-undi=* -perl-Crypt-SSLeay=* -perl-HTTP-Async=* -perl-IO-Stty=* -perl-Net-HTTPS-NB=* -perl-Net-Telnet=* -perl-Sys-Virt=* -xCAT-genesis-base=* +conserver-xcat=8.2.1 +elilo-xcat=3.14 +goconserver=0.3.3 +grub2-xcat=1.0 +ipmitool-xcat=1.8.18 +syslinux-xcat=6.03 +xnba-undi=1.21.1 +perl-Crypt-SSLeay=0.72 +perl-HTTP-Async=0.30 +perl-IO-Stty=0.04 +perl-Net-HTTPS-NB=0.14 +perl-Net-Telnet=3.04 +perl-Sys-Virt=11.10.0 +xCAT-genesis-base=2.19.0 [alma+epel-10-ppc64le] -conserver-xcat=* -elilo-xcat=* -goconserver=* -grub2-xcat=* -ipmitool-xcat=* -syslinux-xcat=* -xnba-undi=* -perl-Crypt-SSLeay=* -perl-HTTP-Async=* -perl-IO-Stty=* -perl-Net-HTTPS-NB=* -perl-Net-Telnet=* -perl-Sys-Virt=* -xCAT-genesis-base=* +conserver-xcat=8.2.1 +elilo-xcat=3.14 +goconserver=0.3.3 +grub2-xcat=1.0 +ipmitool-xcat=1.8.18 +syslinux-xcat=6.03 +xnba-undi=1.21.1 +perl-Crypt-SSLeay=0.72 +perl-HTTP-Async=0.30 +perl-IO-Stty=0.04 +perl-Net-HTTPS-NB=0.14 +perl-Net-Telnet=3.04 +perl-Sys-Virt=11.10.0 +xCAT-genesis-base=2.19.0