ci(msan): repin Dockerfile.msan clang-22 -> clang-21 (apt.llvm.org rotated noble-22 out) (#2123)

The test-msan lane was red repo-wide: the Dockerfile.msan image build could
no longer install clang-22 from apt.llvm.org's noble-22 channel, failing with
"E: Unable to locate package clang-22 / libclang-rt-22-dev / llvm-22" after
the 5 apt retries, so the image never built and every PR's required test-msan
check could not go green (#2123).

apt.llvm.org keeps only the last few majors for noble and rotates newer ones
in and out; the -22 channel's package index was empty when CI fetched it (the
channel has since flapped back, confirming the transience). Rather than stay on
that volatile channel, repin to clang-21 - the highest well-established stable
noble channel apt.llvm.org currently serves (verified installable on both
amd64 and arm64):

  - apt source noble-22 -> noble-21, clang-22/libclang-rt-22-dev/llvm-22 ->
    clang-21/libclang-rt-21-dev/llvm-21, and the clang/clang++ symlinks
  - MSan runtimes clone llvmorg-22.1.0 -> llvmorg-21.1.8 (matches the apt
    clang 21.1.8, keeping the libc++/libc++abi/libunwind build at the
    compiler's major, as the layer requires)
  - MSAN_SYMBOLIZER_PATH /usr/lib/llvm-22 -> /usr/lib/llvm-21

Verified in an ubuntu:noble container that clang-21/libclang-rt-21-dev/llvm-21
install cleanly, the clang/clang++ symlinks resolve, libclang_rt.msan-*.a and
llvm-symbolizer are present, and the full image builds via Colima.

Infra only; the MSan lane's other files (docker-compose.yml, scripts/msan.sh)
use the version-agnostic clang/clang++ symlinks and need no change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
Martin VogelandClaude Fable 5.1 committed 2026-09-09 07:37:54 +02:00
1 parent 1db8bace03
commit 8134712dc4
1 file changed
+16 -10
+16 -10
View File
@@ -39,21 +39,27 @@ RUN printf '%s\n' \
> /usr/local/bin/retry \
&& chmod 0755 /usr/local/bin/retry
# clang 22 from apt.llvm.org, matching the diag and analyzer lanes. Noble's
# default is clang 18 — four majors behind everything else here, which is both
# an inconsistency and a bad vantage point for debugging sanitizer behaviour.
# clang 21 from apt.llvm.org — a modern sanitizer toolchain well ahead of
# Noble's default clang 18 (three majors back), a better vantage point for
# debugging sanitizer behaviour. We track the highest *stable* noble channel
# apt.llvm.org serves rather than its bleeding edge: apt.llvm.org keeps only
# the last few majors and rotates newer ones in and out, and the -22 channel
# was transiently pulled out from under this build (#2123: "Unable to locate
# package clang-22"), reddening test-msan repo-wide. Bump deliberately, and
# only to a channel proven installable (and with a matching llvmorg-*.*.* tag
# for the runtimes build below), never automatically to the newest number.
# The key is fetched with `wget -O <file>` rather than `-qO- > <file>`: under
# retry a redirect is opened once for all attempts, so a partial write from a
# failed attempt would be prepended to the output of a later successful one.
RUN retry apt-get -o Acquire::Retries=3 update \
&& retry apt-get -o Acquire::Retries=3 install -y --no-install-recommends wget gnupg ca-certificates \
&& retry wget -q -O /etc/apt/trusted.gpg.d/apt.llvm.org.asc https://apt.llvm.org/llvm-snapshot.gpg.key \
&& echo "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-22 main" > /etc/apt/sources.list.d/llvm-22.list \
&& echo "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-21 main" > /etc/apt/sources.list.d/llvm-21.list \
&& retry apt-get -o Acquire::Retries=3 update \
&& retry apt-get -o Acquire::Retries=3 install -y --no-install-recommends \
clang-22 libclang-rt-22-dev llvm-22 \
&& ln -sf /usr/bin/clang-22 /usr/bin/clang \
&& ln -sf /usr/bin/clang++-22 /usr/bin/clang++
clang-21 libclang-rt-21-dev llvm-21 \
&& ln -sf /usr/bin/clang-21 /usr/bin/clang \
&& ln -sf /usr/bin/clang++-21 /usr/bin/clang++
RUN retry apt-get -o Acquire::Retries=3 update \
&& retry apt-get -o Acquire::Retries=3 install -y --no-install-recommends \
@@ -72,7 +78,7 @@ RUN retry apt-get -o Acquire::Retries=3 update \
# the compiler above — a runtimes build must match its clang. The clone clears
# its destination first: a half-finished clone would make every later attempt
# fail on "destination path already exists".
RUN retry sh -c 'rm -rf /tmp/llvm-project && git clone --depth 1 --branch llvmorg-22.1.0 https://github.com/llvm/llvm-project.git /tmp/llvm-project' \
RUN retry sh -c 'rm -rf /tmp/llvm-project && git clone --depth 1 --branch llvmorg-21.1.8 https://github.com/llvm/llvm-project.git /tmp/llvm-project' \
&& cmake -G Ninja -S /tmp/llvm-project/runtimes -B /tmp/llvm-msan \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=clang \
@@ -97,11 +103,11 @@ RUN retry sh -c 'rm -rf /tmp/zlib && git clone --depth 1 --branch v1.3.1 https:/
&& rm -rf /tmp/zlib
# Symbolizer path in its own (last) layer so adding tools never invalidates
# the expensive libc++ build layers above. libclang-rt-22-dev is installed
# the expensive libc++ build layers above. libclang-rt-21-dev is installed
# explicitly with the compiler: it is only a Recommends of clang, which
# --no-install-recommends drops, and the link then fails to find
# libclang_rt.msan-*.a.
ENV MSAN_SYMBOLIZER_PATH=/usr/lib/llvm-22/bin/llvm-symbolizer
ENV MSAN_SYMBOLIZER_PATH=/usr/lib/llvm-21/bin/llvm-symbolizer
WORKDIR /src
ENTRYPOINT ["scripts/msan.sh"]