Skip to content

os: add experimental reproducible Debian/mkosi backend #13

os: add experimental reproducible Debian/mkosi backend

os: add experimental reproducible Debian/mkosi backend #13

Workflow file for this run

# SPDX-FileCopyrightText: © 2026 Phala Network <dstack@phala.network>
#
# SPDX-License-Identifier: Apache-2.0
name: Verify mkosi reproducibility
on:
workflow_dispatch:
# Bootstrap this new workflow once before it exists on the default branch.
# Remove this trigger after the hosted-runner baseline check completes.
pull_request:
paths:
- '.github/workflows/mkosi-build.yml'
concurrency:
group: mkosi-build-${{ github.ref }}
cancel-in-progress: true
env:
# These values were produced by two cache-disabled local builds. The job
# checks out this exact source revision so the embedded Git revision is also
# identical. Refresh all four values together when updating the baseline.
BASELINE_REVISION: b5980267b2012fdd6664511ce583c15c6d6d7af8
SOURCE_DATE_EPOCH: '1784810849'
BARE_SHA256: ab4ff5981f0979652ec4829688570807357e287a7c8d8c7da8324965d44fdeb4
UKI_SHA256: 67284c00f8092448437319ae71f74ca3229061f155559367b07871f566199d0e
jobs:
cross-host:
name: Compare with local mkosi baseline
runs-on: ubuntu-latest
timeout-minutes: 360
permissions:
contents: read
steps:
# GitHub-hosted runners have enough CPU and memory for this build, but
# their preinstalled SDKs consume most of the available disk. Remove only
# those unused SDKs before checkout; the OS build itself remains hermetic.
- name: Reclaim runner disk space
run: |
sudo rm -rf \
/opt/ghc \
/opt/hostedtoolcache/CodeQL \
/usr/local/.ghcup \
/usr/local/lib/android \
/usr/local/share/boost \
/usr/share/dotnet
df -h /
- name: Checkout locally verified revision
uses: actions/checkout@v5
with:
ref: ${{ env.BASELINE_REVISION }}
fetch-depth: 0
- name: Set up Python for mkosi
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install host image assembly tools
run: |
sudo apt-get update
sudo apt-get install --yes --no-install-recommends \
build-essential ca-certificates cmake cpio cryptsetup-bin curl \
debian-archive-keyring dosfstools gdisk git jq libssl-dev mtools \
pax-utils pkg-config python3-venv squashfs-tools systemd-ukify \
xz-utils zstd
- name: Install pinned mkosi and Rust/Go tools
run: |
python3 -m venv "$RUNNER_TEMP/mkosi-venv"
"$RUNNER_TEMP/mkosi-venv/bin/pip" install --disable-pip-version-check \
'mkosi @ git+https://github.com/systemd/mkosi.git@84af20892b61c8e177e391f997ded8b4cb5514f2'
echo "$RUNNER_TEMP/mkosi-venv/bin" >> "$GITHUB_PATH"
sudo ./os/mkosi/scripts/install-toolchains.sh \
"$RUNNER_TEMP/toolchain-downloads"
echo '/opt/dstack-toolchains/rust/bin' >> "$GITHUB_PATH"
echo '/opt/dstack-toolchains/go/bin' >> "$GITHUB_PATH"
- name: Build pinned host measurement tools
env:
CARGO_HOME: ${{ runner.temp }}/cargo-home
CARGO_TARGET_DIR: ${{ runner.temp }}/cargo-target
run: |
cargo install --locked \
--git https://github.com/aws/NitroTPM-Tools \
--rev d76d6eeebd4169b00a3c3af9858852d48f40e748 \
--root "$RUNNER_TEMP/host-tools" nitro-tpm-pcr-compute
cargo build --locked --release --manifest-path dstack/Cargo.toml \
-p dstack-mr
echo "$RUNNER_TEMP/host-tools/bin" >> "$GITHUB_PATH"
echo "DSTACK_MR_BIN=$RUNNER_TEMP/cargo-target/release/dstack-mr" \
>> "$GITHUB_ENV"
- name: Build without component cache
env:
# ubuntu-latest currently provides four vCPUs and 16 GiB of RAM.
# Two compile jobs keep peak kernel/OVMF memory safely below that.
JOBS: '2'
run: |
test -z "${DSTACK_DEV_CACHE_DIR:-}"
# GitHub-hosted Ubuntu runners restrict unprivileged user namespaces.
# Run mkosi as root instead of weakening the runner's AppArmor policy.
# Keep setup-python out of the build PATH because Ubuntu's lddtree
# expects the distro Python and its python3-pyelftools module.
ci_bin="$RUNNER_TEMP/mkosi-ci-bin"
mkdir -p "$ci_bin"
ln -s "$(command -v mkosi)" "$ci_bin/mkosi"
ln -s "$(command -v nitro-tpm-pcr-compute)" \
"$ci_bin/nitro-tpm-pcr-compute"
sudo --set-home env \
"PATH=$ci_bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
"SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH" \
"DSTACK_MR_BIN=$DSTACK_MR_BIN" \
"JOBS=$JOBS" \
./os/mkosi/build.sh image "$RUNNER_TEMP/mkosi-cross-host"
- name: Compare with local byte-for-byte baseline
run: |
cd "$RUNNER_TEMP/mkosi-cross-host/out/prod"
printf '%s %s\n' "$BARE_SHA256" dstack-0.6.0.tar.gz \
| sha256sum --check --strict
printf '%s %s\n' "$UKI_SHA256" dstack-0.6.0-uki.tar.gz \
| sha256sum --check --strict
sha256sum dstack-0.6.0.tar.gz dstack-0.6.0-uki.tar.gz \
> cross-host.sha256
- name: Upload verification record
uses: actions/upload-artifact@v4
with:
name: mkosi-cross-host-sha256
path: ${{ runner.temp }}/mkosi-cross-host/out/prod/cross-host.sha256
retention-days: 30