mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-09-25 09:14:05 +00:00
fix(xcat-core): two Genesis builds in different chroots share one directory
The sbuild chroots bind-mount /var/lib/sbuild/build on /build, so every session of every chroot sees the same directory. Staging the builder there let two builds running at once overwrite each other's copy: one of them read a half-written script and stopped with "-get: command not found". The output of an earlier run stayed in it too, so a build collected another codename's deb and left 1.9 GB on the build host. Stage under /xcat-genesis-build instead. It lives in the session overlay and goes away with the session. 26.04 also moved the backward-compatibility zone names out of tzdata into tzdata-legacy, and the dracut module names 106 of them. Install it where apt has it. The three images (jammy 180 MB, noble 328 MB, resolute 432 MB) build with no error in any log. Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This commit is contained in:
+20
-11
@@ -293,6 +293,11 @@ sub collect_debs {
|
||||
# (<codename>-<arch>-sbuild). They hand out disposable overlay sessions, so what the build
|
||||
# installs is discarded and the next codename starts from the pristine base.
|
||||
|
||||
# Where the build runs inside the chroot. A directory of its own at the chroot root, because
|
||||
# every other candidate is shared: /build and /opt/xcat-ci-shared are bind mounts the sbuild
|
||||
# chroots give to every session.
|
||||
my $GENESIS_STAGE = '/xcat-genesis-build';
|
||||
|
||||
sub host_deb_arch {
|
||||
my $arch = `dpkg --print-architecture 2>/dev/null` // '';
|
||||
chomp $arch;
|
||||
@@ -350,24 +355,28 @@ sub build_one_genesis_deb {
|
||||
# The builder needs its own directory, and Version and Release beside it. Copy them
|
||||
# in rather than bind-mount the checkout: the build rewrites debian/control and
|
||||
# debian/changelog, and it must not rewrite them in the tree the pipeline builds from.
|
||||
sh_or_die("mkdir -p " . sh_quote("$root/build/xCAT-genesis-builder"),
|
||||
#
|
||||
# NOT under /build: the sbuild chroots bind-mount /var/lib/sbuild/build there, so every
|
||||
# session of every chroot shares one directory. Two builds running at once overwrite each
|
||||
# other's copy of the builder, and the output of an earlier run is still in it. A
|
||||
# directory of its own at the chroot root lives in the session overlay and goes with it.
|
||||
my $stage = "$root$GENESIS_STAGE";
|
||||
sh_or_die("rm -rf " . sh_quote($stage) . " && mkdir -p "
|
||||
. sh_quote("$stage/xCAT-genesis-builder"),
|
||||
"FATAL: cannot make the build directory in session:$id\n");
|
||||
sh_or_die("cp -a " . sh_quote("$ROOT/xCAT-genesis-builder") . "/. "
|
||||
. sh_quote("$root/build/xCAT-genesis-builder") . "/",
|
||||
. sh_quote("$stage/xCAT-genesis-builder") . "/",
|
||||
"FATAL: cannot copy xCAT-genesis-builder into session:$id\n");
|
||||
for my $f (qw(Version Release)) {
|
||||
next unless -f "$ROOT/$f";
|
||||
copy("$ROOT/$f", "$root/build/$f")
|
||||
or die "FATAL: cannot copy $f into session:$id: $!\n";
|
||||
}
|
||||
write_text("$root/build/Release", "$RELEASE\n");
|
||||
copy("$ROOT/Version", "$stage/Version")
|
||||
or die "FATAL: cannot copy Version into session:$id: $!\n";
|
||||
write_text("$stage/Release", "$RELEASE\n");
|
||||
|
||||
# --expect-codename is the guard that keeps the image and the root together: the
|
||||
# builder stops when the root it woke up in is not the release it was asked for.
|
||||
my $cmd = join ' ',
|
||||
'schroot', '--run-session', '-c', sh_quote("session:$id"), '-u', 'root', '-d', '/',
|
||||
'--', '/bin/bash', '/build/xCAT-genesis-builder/builddeb-genesis-base',
|
||||
'--expect-codename', sh_quote($codename), '--outdir', '/build/out';
|
||||
'--', '/bin/bash', "$GENESIS_STAGE/xCAT-genesis-builder/builddeb-genesis-base",
|
||||
'--expect-codename', sh_quote($codename), '--outdir', "$GENESIS_STAGE/out";
|
||||
my $rc = sh("$cmd > " . sh_quote($logfile) . " 2>&1");
|
||||
|
||||
# The log is read whether or not the command failed: a build that exits 0 with
|
||||
@@ -379,7 +388,7 @@ sub build_one_genesis_deb {
|
||||
}
|
||||
die $problems if $problems;
|
||||
|
||||
my @debs = glob("$root/build/out/*.deb");
|
||||
my @debs = glob("$root$GENESIS_STAGE/out/*.deb");
|
||||
die "FATAL: the Genesis build for $codename produced no .deb; log: $logfile\n"
|
||||
unless @debs;
|
||||
for my $deb (@debs) {
|
||||
|
||||
@@ -65,6 +65,20 @@ ppc64el, and every release the repository serves declares the architecture;
|
||||
``xCAT-genesis-scripts`` keeps the two architectures it has control files for,
|
||||
because riscv64 Genesis ships as an OpenEmbedded package instead.
|
||||
|
||||
The Genesis image is the exception, and it is off unless it is asked for::
|
||||
|
||||
./builddebs.pl --genesis-only --genesis-dist jammy --genesis-dist noble
|
||||
|
||||
``dracut`` copies the kernel, the kernel modules and every command out of the root
|
||||
it runs in, so the image belongs to the release that built it. ``--genesis`` builds
|
||||
one image per ``--genesis-dist`` codename inside that codename's
|
||||
``<codename>-<arch>-sbuild`` schroot -- the chroots xcat-dep's ``sbuild-all.pl``
|
||||
creates on the Ubuntu build host -- for the architecture of the build host. It
|
||||
refuses to run in a root of another release, it fails the build on an error in the
|
||||
log even when the exit status is 0, and it checks the extracted payload against the
|
||||
commands the dracut module installs. ``--genesis-only`` builds the images and
|
||||
nothing else, which is what xcat-dep consumes with ``--genesis-deb``.
|
||||
|
||||
Helpers shared by both builders live in ``build-utils/lib/XCAT/BuildUtils.pm``.
|
||||
|
||||
``buildcore.sh`` builds the architecture specific packages (``xCAT``, ``xCATsn``,
|
||||
|
||||
@@ -105,14 +105,35 @@ add_first_available() {
|
||||
echo "ERROR: $CODENAME carries none of these packages: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
# A package that exists only on some releases. 26.04 moved the backward-compatibility zone
|
||||
# names (Chile/Continental and the rest of the list the dracut module installs) out of tzdata
|
||||
# into tzdata-legacy.
|
||||
add_if_available() {
|
||||
local p
|
||||
for p in "$@"; do
|
||||
apt-cache show "$p" >/dev/null 2>&1 && REQUIRED_PACKAGES="$REQUIRED_PACKAGES $p"
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
add_first_available bind9-dnsutils dnsutils
|
||||
add_first_available util-linux-extra util-linux
|
||||
add_if_available tzdata-legacy
|
||||
|
||||
apt-get install -y --no-install-recommends $REQUIRED_PACKAGES
|
||||
|
||||
# dpkg-architecture comes from dpkg-dev, which the line above installs.
|
||||
TRIPLET=$(dpkg-architecture -qDEB_HOST_MULTIARCH)
|
||||
|
||||
# ncurses-base put its terminfo entries under /lib/terminfo before 24.04, and both dracut's own
|
||||
# terminfo module and the 97xcat module ask for /usr/share/terminfo. On jammy the build stopped
|
||||
# on /usr/share/terminfo/l/linux. Give this build root the path they ask for; the chroot is
|
||||
# thrown away when the build ends.
|
||||
if [ -d /lib/terminfo ]; then
|
||||
mkdir -p /usr/share/terminfo
|
||||
cp -an /lib/terminfo/. /usr/share/terminfo/ 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Set up dracut module
|
||||
if [ -d /usr/lib/dracut/modules.d ]; then
|
||||
DRACUT_PARENT=/usr/lib/dracut/modules.d
|
||||
|
||||
Reference in New Issue
Block a user