Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/dwarves

containers/runa-toolchain.Containerfile

# nordisk RUNA TOOLCHAIN — the image a runa PROGRAM STEP runs in.
#
# `runs_on: Container` is the default place of every step that runs a program
# (CargoBuild, Nextest, CargoTest, Bench, Coverage, Trace, Profile, Lint, Xtask, DeployPages, Sbom,
# SecurityScan, HolgerPackage — `runa_exec::step_runs_a_program`). The forge boots this image
# through draupnir (`BootSpec::container` → `ContainerBoot`, podman's REST API),
# bind-mounts the constellation root at its own path, and runs the step's argv in
# the step's checkout. The host contributes an engine socket and the checkout.
#
#   podman build -t nordisk-runa-toolchain:nightly-2026-10-05 \
#       -f containers/runa-toolchain.Containerfile containers/
#
# The tag is `runa_exec::DEFAULT_RUNA_IMAGE`; `DWARVES_RUNA_IMAGE` overrides it.
# `runa_exec::tests::the_default_image_is_this_recipe` holds the tag, the ARG
# below and the package list together.
#
# NOT `nordisk-cargo-toolchain`: that name is build-thing's image (stable
# 1.97.1, the musl/wasm/uefi targets) and recipes PIN it by digest
# (edda-build-thing `recipe.rs`). A second image under its tag would make that
# pin name two things.
#
# The same BASE and ARCHIVE pins as edda's `cargo-toolchain.Containerfile`
# (debian:trixie by digest, apt from the snapshot.debian.org instant it was built
# from), so the constellation still has one base.
FROM debian:trixie@sha256:d63a99144861e4e460196ed93d07777490cbeab53ca660c434f2a589a6c50ea3

ENV DEBIAN_FRONTEND=noninteractive
ENV SOURCE_DATE_EPOCH=1783900800

# THE TOOLCHAIN: the nightly the Mímir consumer reads the workspace with
# (nornir `crates/mimir-driver/rust-toolchain.toml`:
#  rustc 1.101.0-nightly (282215592 2026-10-04)), so a pipeline compiles with the
# compiler the code room was read with. Bump both ON PURPOSE, in one go.
ARG RUST_TOOLCHAIN=nightly-2026-10-05

RUN set -eu; \
    printf '%s\n' \
      'Types: deb' \
      'URIs: http://snapshot.debian.org/archive/debian/20260713T000000Z' \
      'Suites: trixie trixie-updates' \
      'Components: main' \
      'Signed-By: /usr/share/keyrings/debian-archive-keyring.pgp' \
      '' \
      'Types: deb' \
      'URIs: http://snapshot.debian.org/archive/debian-security/20260713T000000Z' \
      'Suites: trixie-security' \
      'Components: main' \
      'Signed-By: /usr/share/keyrings/debian-archive-keyring.pgp' \
      > /etc/apt/sources.list.d/debian.sources; \
    printf 'Acquire::Check-Valid-Until "false";\n' > /etc/apt/apt.conf.d/10no-check-valid-until; \
    apt-get update && apt-get install -y --no-install-recommends \
    `# COMPILE — rustup (Debian's, signed archive) fetches the pinned nightly;` \
    `# ca-certificates makes that fetch (and crates.io) verifiable.` \
    rustup ca-certificates \
    `# LINK — the planner's ONE linker set: every repo links with` \
    `# -C linker=clang -C link-arg=--ld-path=/usr/bin/ld.mold (dwarves' own` \
    `# .cargo/config.toml says exactly that). clang drives, mold links.` \
    clang mold \
    `# LINK / build scripts — cc-rs falls back to cc; the C runtime to link to.` \
    gcc g++ libc6-dev \
    `# FETCH — cargo runs git for git dependencies; xtasks read the tree's git.` \
    git \
    `# CODEGEN — tonic-build shells out to protoc (every gRPC crate's build.rs).` \
    protobuf-compiler \
    `# -sys crates — pkg-config finds system libraries; cmake builds the C++ of` \
    `# openzl-sys-rs (znippy-common's path dependency).` \
    pkg-config cmake \
    `# openssl-sys (edda, knut … through native-tls / git2): its build script` \
    `# asks pkg-config for libssl; the headers and the .pc come from here.` \
    libssl-dev \
    `# graphblas-sys (nornir's graph engine, in dwarves' default build): links` \
    `# -lgraphblas and checks GraphBLAS.h is 7.x. Without it every test binary` \
    `# that pulls nornir dies in mold, "library not found: graphblas".` \
    libgraphblas-dev \
    `# OVMF — tunnr's firmware tests resolve the stock UEFI pair (OVMF_CODE /` \
    `# OVMF_VARS) before they judge a named one; without it they fail here.` \
    ovmf \
    `# TRACE — runa's Trace step builds with -Z instrument-xray and links with` \
    `# clang -fxray-instrument: clang pulls compiler-rt's XRay runtime` \
    `# (libclang_rt.xray*.a), which Debian ships apart from clang.` \
    libclang-rt-19-dev \
    `# PROFILE — runa's Profile step samples with perf record -g (no rebuild).` \
    `# It runs only where the box allows perf_event_open (perf_event_paranoid` \
    `# <= 2, or CAP_PERFMON): the image carries the tool, never the permission.` \
    linux-perf \
    && rm -rf /var/lib/apt/lists/* /var/log/apt /var/log/dpkg.log /var/log/alternatives.log \
    && rm -f /var/cache/ldconfig/aux-cache && rm -rf /root/.cache

# rustup and cargo under /usr/local: the image behaves the same for whatever uid
# the engine runs it as (rootless: 0:0 = the forge's user; rootful: the forge's
# own uid). The forge points CARGO_HOME at a cache of its own per run.
ENV RUSTUP_HOME=/usr/local/rustup \
    CARGO_HOME=/usr/local/cargo \
    PATH=/usr/local/cargo/bin:$PATH
# NO toolchain override here: the nightly is rustup's DEFAULT (below), so a
# checkout that pins its own (`rust-toolchain.toml`: gunnar-ui 1.96.0, tunnr
# 1.97.1) builds with its pin — the forge then points RUSTUP_HOME at a cache of
# its own and rustup fetches the pin there once (runa_backend::pinned_toolchain_file).

# `minimal` + the components a runa pipeline names: rustfmt (Lint(Fmt),
# the xtask fmt-check) and clippy (Lint(Clippy)) — and rust-src: the Mímir
# consumer's container road dumps the toolchain's own std/core/alloc into the
# ring once per toolchain (`cargo mimir-dump --std` compiles the sysroot's
# sources); without it that dump fails on the container road.
RUN rustup toolchain install "${RUST_TOOLCHAIN}" --profile minimal --component rustfmt,clippy,rust-src --no-self-update \
    && rustup default "${RUST_TOOLCHAIN}" \
    `# Debian's rustup keeps its proxies in /usr/bin: CARGO_HOME starts empty` \
    && mkdir -p /usr/local/cargo && chmod -R a+rX /usr/local/rustup /usr/local/cargo \
    && rustc --version && cargo --version && cargo fmt --version && cargo clippy --version

# TEST — runa's `Nextest` step runs `cargo nextest run`; nextest is not a
# rustup component, so it is built here, version-pinned and `--locked`.
ARG NEXTEST_VERSION=0.9.148
RUN CARGO_BUILD_JOBS=8 cargo install --locked cargo-nextest --version "${NEXTEST_VERSION}" --root /usr/local/cargo \
    && rm -rf /usr/local/cargo/registry /usr/local/cargo/git \
    && chmod -R a+rX /usr/local/cargo && cargo nextest --version

# COVERAGE — runa's `Coverage` step runs `cargo llvm-cov` (LLVM source-based
# coverage): the toolchain's `llvm-tools` component and cargo-llvm-cov, built here
# version-pinned and `--locked` like nextest.
ARG LLVM_COV_VERSION=0.9.1
RUN rustup component add llvm-tools-preview --toolchain "${RUST_TOOLCHAIN}" \
    && CARGO_BUILD_JOBS=8 cargo install --locked cargo-llvm-cov --version "${LLVM_COV_VERSION}" --root /usr/local/cargo \
    && rm -rf /usr/local/cargo/registry /usr/local/cargo/git \
    && chmod -R a+rX /usr/local/cargo /usr/local/rustup && cargo llvm-cov --version

# THE IMAGE ASSERTS XRAY: a function built with every function instrumented and
# linked with the XRay runtime must log its calls (runa's Trace step).
RUN set -eu; \
    printf '#[inline(never)] fn f(x: u64) -> u64 { x + 1 }\nfn main() { println!("{}", f(1)); }\n' > /tmp/xr.rs; \
    rustc -Z instrument-xray=always -C linker=clang -C link-arg=-fxray-instrument -C link-arg=--ld-path=/usr/bin/ld.mold -o /tmp/xr /tmp/xr.rs; \
    mkdir /tmp/xl; XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic xray_logfile_base=/tmp/xl/" XRAY_BASIC_OPTIONS="func_duration_threshold_us=0" /tmp/xr; \
    test -s "$(ls /tmp/xl/* | head -1)"; \
    perf --version; \
    rm -rf /tmp/xr /tmp/xr.rs /tmp/xl

# THE IMAGE ASSERTS ITS LINKER: a hello world linked exactly the way the
# constellation links (clang + mold) must run.
RUN set -eu; \
    printf 'fn main() { println!("linked"); }\n' > /tmp/probe.rs; \
    rustc -C linker=clang -C link-arg=--ld-path=/usr/bin/ld.mold -o /tmp/probe /tmp/probe.rs; \
    test "$(/tmp/probe)" = linked; \
    git --version; \
    rm -f /tmp/probe /tmp/probe.rs

WORKDIR /work