2
0
mirror of https://github.com/xcat2/xcat-dep.git synced 2026-09-12 04:26:25 +00:00
Files
xcat-dep/goconserver/sbuild.pl
T
Daniel Hilst c808e06da3 fix(xcat-dep): address code review — run lock, loud tree wipes, wire tested genesis copier, dedupe pool, honest Release arches
Review follow-up for the Ubuntu sbuild matrix:

- Add a fail-fast exclusive flock over the whole run (<output-root>/.sbuild-all.lock,
  file-scoped handle) so two overlapping runs can't corrupt the shared staging/apt
  tree -- this is the root of the observed 'remove_tree .../staging/<cn>/<arch>:
  Directory not empty' (an NFS silly-rename from a concurrent run).
- wipe_tree(): remove_tree that captures {error} and dies loud, so an ENOTEMPTY no
  longer carps-and-continues leaving stale debs; used for all staging/pool/dists wipes.
- Wire the tested, hash-based cross_copy_genesis_deb into build_genesis (was a naive
  glob+copy, so the unit-tested stale-dropping copier was dead code); remove the
  genuinely-unused deb_snap_version/rewrite_changelog_top helpers + their subtests
  (compiled deps intentionally ship their tracked changelog version).
- Dedupe assemble_apt on binary Package+Architecture (keep highest via
  dpkg --compare-versions) so a double-produced genesis can't land two versions in
  the pool, independent of the --skip-genesis contract.
- Derive Release Architectures from the arches actually staged (non-empty
  binary-<arch>/Packages), not a hard-coded 'amd64 ppc64el'.
- goconserver: guard 'go mod init' when a go.mod exists (+ TODO to commit go.sum for
  the pinned SHA). Accept-and-ignore the unused per-package --log-dir/--build-number/
  --skip-install flags (documented). Remove orphaned make_deb.sh dispatchers
  (build-debs-all, build.sh, ipmitool/build.sh) + update the READMEs.

perl -c clean; prove t/sbuild-all.t: 71/71.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-08-12 11:49:54 -03:00

114 lines
5.9 KiB
Prolog
Executable File

#!/usr/bin/env perl
# goconserver/sbuild.pl -- per-package Ubuntu/Debian builder for goconserver; the apt/sbuild analogue
# of goconserver/mockbuild.pl. Builds the package inside the matching <codename>-<arch>-sbuild chroot
# from its MAINTAINED debian/ packaging and collects the .deb(s) into --result-dir. Invoked by
# sbuild-all.pl per (codename,arch); also runnable standalone. Out-of-tree: the build runs on a COPY of
# the package tree (the checkout is never mutated). The common chroot orchestration lives in
# BuildUtils::build_deb_in_chroot; goconserver's source clone + Go toolchain + build is below.
use strict;
use warnings;
use Cwd qw(abs_path);
use File::Basename qw(basename);
use Getopt::Long qw(GetOptions);
use FindBin qw($RealBin);
use lib "$RealBin/..";
use BuildUtils qw(chroot_name build_deb_in_chroot);
my $pkg_dir = abs_path($RealBin);
my $pkg = basename($pkg_dir);
my ($codename, $arch, $chroot, $result_dir, $log_dir) = ('', '', '', '', '');
my ($build_timestamp, $build_number, $skip_install) = (undef, undef, 0);
# --log-dir / --build-number / --skip-install are accepted for CLI-compat with sbuild-all.pl (which
# passes them uniformly to every per-package builder) but are intentionally UNUSED here: sbuild-all
# does its own per-package logging and there is no deb install-smoke. They are parsed and ignored.
GetOptions(
'codename=s' => \$codename, 'arch=s' => \$arch, 'chroot=s' => \$chroot,
'result-dir=s' => \$result_dir, 'log-dir=s' => \$log_dir,
'build-timestamp=i' => \$build_timestamp, 'build-number=i' => \$build_number,
'skip-install!' => \$skip_install,
) or die "bad options\n";
$arch ||= `dpkg --print-architecture 2>/dev/null`; chomp $arch; $arch ||= 'amd64';
die "FATAL: --codename required\n" unless $codename;
$chroot ||= chroot_name($codename, $arch);
$result_dir ||= "$pkg_dir/../build-output/sbuild/$codename/$arch";
$build_timestamp = time() unless defined $build_timestamp;
# goconserver's pinned SHA + Go toolchain (see the shell below). goconserver 0.3.3 is UNRELEASED so it
# lives only on master -- pin an immutable SHA so every matrix cell builds the SAME source (reproducible,
# matching the EL GOCONSERVER_REF in mockbuild-all.pl). Its modules require Go >= 1.25, but the Ubuntu
# codenames ship older toolchains (focal=go1.13 ... noble=go1.22) and the pre-1.21 ones cannot even
# auto-switch toolchains; goconserver is a static CGO-free binary, so a pinned Go downloaded into the
# build works in ANY codename chroot and keeps the compiler reproducible. Bump these two deliberately.
# ---- package-specific build (absorbed from the former make_deb.sh); CWD = the copied package dir ----
# The maintained debian/ is at ./debian in the copied package dir; the upstream source is cloned fresh
# at the pinned SHA into ./gcsrc, the maintained debian/ copied in, and dpkg-buildpackage run there
# (its .deb(s) land in the copied package dir, which the collector picks up).
my $build = <<'BUILD';
set -e
VERSION=0.3.3
REPO=https://github.com/xcat2/goconserver.git
REF=6166fe5ec1c5b3c20475e322a9f0e8e93c87e45f
GO_PIN=1.25.12
# pinned modern Go toolchain (static CGO-free build, portable across codenames; reproducible compiler)
go_arch=$(dpkg --print-architecture); [ "$go_arch" = ppc64el ] && go_arch=ppc64le
echo "installing pinned go${GO_PIN} (${go_arch}) for the goconserver build"
rm -rf /usr/local/go
curl -fsSL "https://go.dev/dl/go${GO_PIN}.linux-${go_arch}.tar.gz" | tar -C /usr/local -xz
export PATH=/usr/local/go/bin:$PATH
export GOTOOLCHAIN=local # use exactly the pinned toolchain; never auto-download another
go version
if [ -n "${SOURCE_DATE_EPOCH:-}" ]; then
SNAP_TS=$(date -d "@$SOURCE_DATE_EPOCH" --utc '+%Y%m%d%H%M')
else
SNAP_TS=$(date '+%Y%m%d%H%M')
fi
FULL_VERSION="${VERSION}-snap${SNAP_TS}"
# shallow-fetch the pinned commit by object id (GitHub allows reachable-SHA fetches)
gc=gcsrc
git init -q "$gc"
git -C "$gc" remote add origin "$REPO"
git -C "$gc" fetch -q --depth 1 origin "$REF"
git -C "$gc" checkout -q FETCH_HEAD
# etcd storage backend has broken deps with modern Go modules
rm -rf "$gc/storage/etcd.go" "$gc/storage/etcd/"
cp -rL debian "$gc/debian"
cd "$gc"
export GOPATH="$PWD/.gopath" GOCACHE="$PWD/.gocache" GOMODCACHE="$PWD/.gomodcache" CGO_ENABLED=0
# Guard `go mod init`: the pinned upstream tree may already carry a go.mod at this SHA, and re-running
# `go mod init` on an existing module aborts (fatal under `set -e`). Only initialize when absent.
[ -f go.mod ] || go mod init github.com/xcat2/goconserver
# kr/pty is abandoned and its pty.Start sets Ctty in a way Go >=1.15 rejects; creack/pty is the
# maintained, API-compatible fork that fixes it.
go mod edit -replace github.com/kr/pty=github.com/creack/pty@v1.1.21
# TODO(reproducibility): commit go.sum for the pinned SHA (6166fe5ec1c5b3c20475e322a9f0e8e93c87e45f)
# and build with `go mod download`/module verification instead of `go mod tidy`. The EL branch pins
# deps via a committed go.sum (built from a goconserver/gomod/ tree); this Ubuntu branch has no such
# committed go.mod/go.sum, and producing one soundly requires a Go build with network access, so
# `go mod tidy` (which resolves module versions from the network at build time) stays for now.
go mod tidy
# stamp the maintained debian/ to the snapshot version, OUT-OF-TREE (this is the cloned copy)
sed -i "s/Version=${VERSION}/Version=${FULL_VERSION}/g" debian/rules
export DEBEMAIL="${DEBEMAIL:-xcat-build@xcat.org}" DEBFULLNAME="${DEBFULLNAME:-xCAT Build}"
if [ -n "${SOURCE_DATE_EPOCH:-}" ]; then
deterministic_date=$(date -R -d "@$SOURCE_DATE_EPOCH" --utc)
sed -i "1s/(.*)/(${FULL_VERSION})/" debian/changelog
sed -i "s/^ -- .*/ -- $DEBFULLNAME <$DEBEMAIL> $deterministic_date/" debian/changelog
else
dch -v "$FULL_VERSION" -b -D unstable "Snap build for xCAT"
fi
dpkg-buildpackage -uc -us
BUILD
build_deb_in_chroot(
pkg => $pkg, chroot => $chroot, pkg_dir => $pkg_dir, result_dir => $result_dir,
build_timestamp => $build_timestamp, build => $build,
);