From 85c16f8bbf1c9c8cd8fa501c93e4f520326e3957 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 7 Jul 2026 11:30:48 -0400 Subject: [PATCH] Add debian-stable bootc image variant The existing debian image is based on debian:unstable, which has been causing VM boot failures in downstream CI (composefs-rs) since July 5 due to openssh package restructuring and PAM updates in unstable. Add a debian-stable variant based on debian:stable (currently Debian 13 trixie) which provides a more reliable base for CI consumers. Note we need to cherry pick an updated ostree though. Tested: image builds and boots with no failed systemd units. Signed-off-by: Colin Walters --- .github/workflows/build-debian-stable.yaml | 47 +++++++++++++++++++ bcvk.just | 2 + debian-stable/Containerfile | 54 ++++++++++++++++++++++ debian/Containerfile | 16 +++---- shared/setup-networking-debian.sh | 17 +++++++ 5 files changed, 127 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/build-debian-stable.yaml create mode 100644 debian-stable/Containerfile create mode 100755 shared/setup-networking-debian.sh diff --git a/.github/workflows/build-debian-stable.yaml b/.github/workflows/build-debian-stable.yaml new file mode 100644 index 0000000..a9e40e0 --- /dev/null +++ b/.github/workflows/build-debian-stable.yaml @@ -0,0 +1,47 @@ +name: Build Debian Stable + +permissions: + contents: read + packages: write + id-token: write + +on: + push: + paths: + - 'debian-stable/**' + - Justfile + - bcvk.just + pull_request: + paths: + - 'debian-stable/**' + - Justfile + - bcvk.just + branches: + - main + schedule: + - cron: "0 1 * * *" + merge_group: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + build: + uses: ./.github/workflows/reusable-build.yaml + secrets: inherit + with: + image-name: debian-stable-bootc + image-desc: "Experimental debian-stable-bootc POC image" + image-keywords: "bootc,debian,stable" + image-logo: "https://avatars.githubusercontent.com/u/230667510?s=400&u=cb912a5db49aee164a609a0fb4967d2d8170feb9&v=4" + platforms: amd64,arm64 + rechunk: ${{ github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }} + publish: ${{ github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }} + + boot-test: + needs: build + uses: ./.github/workflows/reusable-boot-test.yaml + with: + image-name: debian-stable-bootc diff --git a/bcvk.just b/bcvk.just index c40d58b..1be011d 100644 --- a/bcvk.just +++ b/bcvk.just @@ -54,6 +54,7 @@ libvirt-check IMAGE: check-all: just bcvk check arch just bcvk check debian + just bcvk check debian-stable just bcvk check opensuse just bcvk check ubuntu @@ -61,5 +62,6 @@ check-all: test-all: just bcvk ephemeral arch just bcvk ephemeral debian + just bcvk ephemeral debian-stable just bcvk ephemeral opensuse just bcvk ephemeral ubuntu diff --git a/debian-stable/Containerfile b/debian-stable/Containerfile new file mode 100644 index 0000000..ad2dfb5 --- /dev/null +++ b/debian-stable/Containerfile @@ -0,0 +1,54 @@ +FROM scratch AS ctx + +COPY ../shared/ /shared + +FROM docker.io/library/debian:stable AS base + +# Add unstable repo pinned low so it is only used when explicitly +# requested (-t unstable). bootc and ostree need a newer libostree +# than trixie ships (>= 2025.3, trixie has 2025.2). +RUN printf 'deb http://deb.debian.org/debian unstable main\n' \ + > /etc/apt/sources.list.d/unstable.list && \ + printf 'Package: *\nPin: release a=unstable\nPin-Priority: 100\n' \ + > /etc/apt/preferences.d/unstable.pref + +FROM base AS builder + +RUN --mount=type=tmpfs,dst=/tmp --mount=type=tmpfs,dst=/root --mount=type=tmpfs,dst=/boot \ + apt update -y && \ + apt install -y git curl make build-essential go-md2man libzstd-dev pkgconf dracut && \ + apt install -y -t unstable libostree-dev ostree + +ENV CARGO_HOME=/tmp/rust +ENV RUSTUP_HOME=/tmp/rust +WORKDIR /home/build +RUN --mount=type=bind,from=ctx,source=/,target=/ctx \ + curl --proto '=https' --tlsv1.2 -sSf "https://sh.rustup.rs" | sh -s -- --profile minimal -y && \ + sh -c ". ${RUSTUP_HOME}/env ; /ctx/shared/build.sh" + +FROM base AS system +COPY --from=builder /output / + +RUN --mount=type=tmpfs,dst=/tmp --mount=type=tmpfs,dst=/run --mount=type=tmpfs,dst=/root --mount=type=tmpfs,dst=/boot apt update -y && \ + apt install -y btrfs-progs bubblewrap dosfstools dracut e2fsprogs fdisk firmware-linux-free linux-image-$(dpkg --print-architecture) netplan.io libnss-resolve libnss-myhostname openssh-server skopeo systemd systemd-boot* systemd-resolved xfsprogs && \ + apt install -y -t unstable libostree-dev ostree && \ + cp /boot/vmlinuz-* "$(find /usr/lib/modules -maxdepth 1 -type d | tail -n 1)/vmlinuz" && \ + printf 'g _ssh -\n' >> /usr/lib/sysusers.d/openssh-server.conf && \ + apt clean -y + +RUN --mount=type=bind,from=ctx,source=/,target=/ctx \ + /ctx/shared/setup-networking-debian.sh + +RUN --mount=type=tmpfs,dst=/tmp --mount=type=tmpfs,dst=/root \ + --mount=type=bind,from=ctx,source=/,target=/ctx \ + /ctx/shared/initramfs.sh + +RUN --mount=type=bind,from=ctx,source=/,target=/ctx \ + sed -i 's|^HOME=.*|HOME=/var/home|' "/etc/default/useradd" && \ + /ctx/shared/bootc-rootfs.sh + +RUN find /run -mindepth 1 -not -name .containerenv -not -name secrets -delete + +LABEL containers.bootc 1 + +RUN bootc container lint --fatal-warnings diff --git a/debian/Containerfile b/debian/Containerfile index 711e4cd..85d8c0a 100644 --- a/debian/Containerfile +++ b/debian/Containerfile @@ -20,17 +20,13 @@ RUN --mount=type=bind,from=ctx,source=/,target=/ctx \ FROM base AS system COPY --from=builder /output / -RUN --mount=type=tmpfs,dst=/tmp --mount=type=tmpfs,dst=/root --mount=type=tmpfs,dst=/boot apt update -y && \ - apt install -y btrfs-progs bubblewrap dosfstools e2fsprogs fdisk firmware-linux-free linux-image-generic netplan.io libnss-resolve libnss-myhostname openssh-server skopeo systemd systemd-boot* systemd-resolved xfsprogs libostree-dev && \ +RUN --mount=type=tmpfs,dst=/tmp --mount=type=tmpfs,dst=/run --mount=type=tmpfs,dst=/root --mount=type=tmpfs,dst=/boot apt update -y && \ + apt install -y btrfs-progs bubblewrap dosfstools dracut e2fsprogs fdisk firmware-linux-free linux-image-generic netplan.io libnss-resolve libnss-myhostname openssh-server skopeo systemd systemd-boot* systemd-resolved xfsprogs libostree-dev && \ cp /boot/vmlinuz-* "$(find /usr/lib/modules -maxdepth 1 -type d | tail -n 1)/vmlinuz" && \ apt clean -y -RUN systemctl enable systemd-networkd systemd-resolved ssh && \ - printf 'L! /etc/resolv.conf - - - - /run/systemd/resolve/stub-resolv.conf\n' \ - > /usr/lib/tmpfiles.d/resolv-conf.conf && \ - mkdir -p /etc/netplan && \ - printf 'network:\n version: 2\n ethernets:\n all-en:\n match:\n name: en*\n dhcp4: true\n dhcp4-overrides:\n use-domains: true\n dhcp6: true\n dhcp6-overrides:\n use-domains: true\n all-eth:\n match:\n name: eth*\n dhcp4: true\n dhcp4-overrides:\n use-domains: true\n dhcp6: true\n dhcp6-overrides:\n use-domains: true\n' > /etc/netplan/90-default.yaml && \ - sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config || true +RUN --mount=type=bind,from=ctx,source=/,target=/ctx \ + /ctx/shared/setup-networking-debian.sh RUN --mount=type=tmpfs,dst=/tmp --mount=type=tmpfs,dst=/root \ --mount=type=bind,from=ctx,source=/,target=/ctx \ @@ -40,6 +36,8 @@ RUN --mount=type=bind,from=ctx,source=/,target=/ctx \ sed -i 's|^HOME=.*|HOME=/var/home|' "/etc/default/useradd" && \ /ctx/shared/bootc-rootfs.sh +RUN find /run -mindepth 1 -not -name .containerenv -not -name secrets -delete + LABEL containers.bootc 1 -RUN bootc container lint +RUN bootc container lint --fatal-warnings diff --git a/shared/setup-networking-debian.sh b/shared/setup-networking-debian.sh new file mode 100755 index 0000000..41fd8d2 --- /dev/null +++ b/shared/setup-networking-debian.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# Common networking and SSH setup for debian-based bootc images. +# Enables systemd-networkd/resolved, writes a netplan config matching +# cloud-image conventions (DHCP on en*/eth* with use-domains), and +# disables SSH password auth. + +set -xeuo pipefail + +systemctl enable systemd-networkd systemd-resolved ssh + +printf 'L! /etc/resolv.conf - - - - /run/systemd/resolve/stub-resolv.conf\n' \ + > /usr/lib/tmpfiles.d/resolv-conf.conf + +mkdir -p /etc/netplan +printf 'network:\n version: 2\n ethernets:\n all-en:\n match:\n name: en*\n dhcp4: true\n dhcp4-overrides:\n use-domains: true\n dhcp6: true\n dhcp6-overrides:\n use-domains: true\n all-eth:\n match:\n name: eth*\n dhcp4: true\n dhcp4-overrides:\n use-domains: true\n dhcp6: true\n dhcp6-overrides:\n use-domains: true\n' > /etc/netplan/90-default.yaml + +sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config || true