Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 32 additions & 29 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
uses: actions/checkout@v6

- name: Install uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@v8.1.0

- name: Install lint tools
run: make lint-install
Expand Down Expand Up @@ -96,7 +96,7 @@ jobs:
run: cat .github/config.env >> "$GITHUB_ENV"

- name: Log in to GHCR
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand Down Expand Up @@ -141,7 +141,7 @@ jobs:
key: ${{ steps.kernel-cache-key.outputs.key }}

- name: Install uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@v8.1.0

- name: Build kernel
run: uv run ./build.py kernel
Expand All @@ -158,7 +158,7 @@ jobs:
key: ${{ steps.kernel-cache-key.outputs.key }}

- name: Upload kernel artifacts
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: kernel-${{ matrix.arch }}
path: |
Expand Down Expand Up @@ -194,7 +194,7 @@ jobs:
key: tools-${{ matrix.arch }}-${{ hashFiles('captain/tools.py') }}

- name: Install uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@v8.1.0

- name: Download tools
run: uv run ./build.py tools
Expand All @@ -209,7 +209,7 @@ jobs:
key: tools-${{ matrix.arch }}-${{ hashFiles('captain/tools.py') }}

- name: Upload tools artifacts
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: tools-${{ matrix.arch }}
path: |
Expand All @@ -236,13 +236,13 @@ jobs:
uses: actions/checkout@v6

- name: Download kernel artifacts
uses: actions/download-artifact@v6
uses: actions/download-artifact@v8
with:
name: kernel-${{ matrix.arch }}
path: mkosi.output/kernel/${{ env.KERNEL_VERSION }}/${{ matrix.arch }}

- name: Download tools artifacts
uses: actions/download-artifact@v6
uses: actions/download-artifact@v8
with:
name: tools-${{ matrix.arch }}
path: mkosi.output/tools/${{ matrix.arch }}
Expand All @@ -258,21 +258,24 @@ jobs:
run: sudo apt-get -o "Dpkg::Use-Pty=0" update

- name: setup-mkosi
uses: systemd/mkosi@v26
# Pinned post-v26 to pick up systemd/mkosi@1f811f05 ("tools: move grub-pc-bin
# to arch-specific drop-in"), which fixes arm64 builds failing on the
# default tools-tree pulling in grub-pc-bin (BIOS GRUB, x86-only).
uses: systemd/mkosi@1f811f0524be3096872e79161c8e6ab3e7c2bb1f

- name: Install bubblewrap
run: |
sudo apt-get -o "Dpkg::Use-Pty=0" update
sudo apt-get -o "Dpkg::Use-Pty=0" install -y bubblewrap

- name: Install uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@v8.1.0

- name: Build initramfs
run: uv run ./build.py initramfs

- name: Upload initramfs artifacts
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: initramfs-${{ matrix.arch }}
path: out/
Expand Down Expand Up @@ -306,7 +309,7 @@ jobs:
run: cat .github/config.env >> "$GITHUB_ENV"

- name: Log in to GHCR
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand Down Expand Up @@ -339,13 +342,13 @@ jobs:
docker push "${REMOTE}:${HASH}-${{ matrix.arch }}"

- name: Download kernel artifacts
uses: actions/download-artifact@v6
uses: actions/download-artifact@v8
with:
name: kernel-${{ matrix.arch }}
path: mkosi.output/kernel/${{ env.KERNEL_VERSION }}/${{ matrix.arch }}

- name: Download initramfs artifacts
uses: actions/download-artifact@v6
uses: actions/download-artifact@v8
with:
name: initramfs-${{ matrix.arch }}
path: out
Expand All @@ -357,13 +360,13 @@ jobs:
"mkosi.output/initramfs/${KERNEL_VERSION}/${{ matrix.arch }}/image.cpio.zst"

- name: Install uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@v8.1.0

- name: Build ISO
run: uv run ./build.py iso

- name: Upload ISO artifact
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: iso-${{ matrix.arch }}
path: out/captainos-${{ env.KERNEL_VERSION }}-${{ matrix.output_arch }}.iso
Expand Down Expand Up @@ -393,28 +396,28 @@ jobs:
run: cat .github/config.env >> "$GITHUB_ENV"

- name: Download kernel artifacts
uses: actions/download-artifact@v6
uses: actions/download-artifact@v8
with:
name: kernel-${{ matrix.target }}
path: mkosi.output/kernel/${{ env.KERNEL_VERSION }}/${{ matrix.target }}

- name: Download initramfs artifacts
uses: actions/download-artifact@v6
uses: actions/download-artifact@v8
with:
name: initramfs-${{ matrix.target }}
path: out

- name: Download ISO artifact
uses: actions/download-artifact@v6
uses: actions/download-artifact@v8
with:
name: iso-${{ matrix.target }}
path: out

- name: Install uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@v8.1.0

- name: Log in to GHCR
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand Down Expand Up @@ -443,46 +446,46 @@ jobs:
run: cat .github/config.env >> "$GITHUB_ENV"

- name: Download kernel artifacts (amd64)
uses: actions/download-artifact@v6
uses: actions/download-artifact@v8
with:
name: kernel-amd64
path: mkosi.output/kernel/${{ env.KERNEL_VERSION }}/amd64

- name: Download initramfs artifacts (amd64)
uses: actions/download-artifact@v6
uses: actions/download-artifact@v8
with:
name: initramfs-amd64
path: out

- name: Download ISO artifact (amd64)
uses: actions/download-artifact@v6
uses: actions/download-artifact@v8
with:
name: iso-amd64
path: out

- name: Download kernel artifacts (arm64)
uses: actions/download-artifact@v6
uses: actions/download-artifact@v8
with:
name: kernel-arm64
path: mkosi.output/kernel/${{ env.KERNEL_VERSION }}/arm64

- name: Download initramfs artifacts (arm64)
uses: actions/download-artifact@v6
uses: actions/download-artifact@v8
with:
name: initramfs-arm64
path: out

- name: Download ISO artifact (arm64)
uses: actions/download-artifact@v6
uses: actions/download-artifact@v8
with:
name: iso-arm64
path: out

- name: Install uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@v8.1.0

- name: Log in to GHCR
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
fetch-depth: 0

- name: Log in to GHCR
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand All @@ -28,7 +28,7 @@ jobs:
run: cat .github/config.env >> "$GITHUB_ENV"

- name: Install uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@v8.1.0

- name: Pull release artifacts (combined)
env:
Expand Down
23 changes: 16 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
# Usage: docker build -t captainos-builder . && docker run --rm --privileged -v $(pwd):/work captainos-builder build
FROM debian:trixie

ARG MKOSI_VERSION=v26
# Pinned post-v26 to pick up systemd/mkosi@1f811f05 ("tools: move grub-pc-bin
# to arch-specific drop-in"), which fixes arm64 builds failing on the default
# tools-tree pulling in grub-pc-bin (BIOS GRUB, x86-only). Bump to a release
# tag once v27 lands.
ARG MKOSI_VERSION=1f811f0524be3096872e79161c8e6ab3e7c2bb1f

# Avoid interactive prompts
ENV DEBIAN_FRONTEND=noninteractive
Expand Down Expand Up @@ -74,12 +78,17 @@ RUN ln -sf ~/.local/bin/mkosi /usr/bin/mkosi
# Verify mkosi is functional
RUN mkosi --version

# Prime uv's cache with our pyproject.toml to speed up runtime
COPY pyproject.toml /tmp/pyproject.toml
COPY captain /tmp/captain
COPY build.py /tmp/build.py
WORKDIR /tmp
RUN uv --verbose run build.py --help
# Install project dependencies into a persistent venv so that
# `uv run` inside the container reuses it instead of recreating one.
COPY pyproject.toml /opt/captain/pyproject.toml
COPY captain /opt/captain/captain
COPY build.py /opt/captain/build.py
RUN uv venv /opt/captain-venv && \
VIRTUAL_ENV=/opt/captain-venv uv pip install --project /opt/captain /opt/captain

# Point uv at the pre-built venv for all future runs.
ENV VIRTUAL_ENV=/opt/captain-venv
ENV UV_PROJECT_ENVIRONMENT=/opt/captain-venv

WORKDIR /work
ENTRYPOINT ["mkosi"]
Expand Down
7 changes: 7 additions & 0 deletions captain/cli/_stages.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ def _build_mkosi_stage(cfg: Config, extra_args: list[str]) -> None:
log.info("MKOSI_MODE=skip — skipping image assembly")
return

# --- idempotency --------------------------------------------------
initramfs_image = cfg.initramfs_output / "image.cpio.zst"
force = "--force" in cfg.mkosi_args
if initramfs_image.is_file() and not force:
log.info("Initramfs already built: %s (use --force to rebuild)", initramfs_image)
return

mkosi_args = list(cfg.mkosi_args) + list(extra_args)

# --- native -------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions captain/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def build_builder(cfg: Config) -> None:
return

log.info("Building Docker image '%s'...", cfg.builder_image)
cmd = ["docker", "buildx", "build"]
cmd = ["docker", "buildx", "build", "--load"]
if cfg.no_cache:
cmd.append("--no-cache")
cmd.extend(
Expand Down Expand Up @@ -88,7 +88,7 @@ def build_release_image(cfg: Config) -> None:
return

log.info("Building Docker image '%s'...", RELEASE_IMAGE)
cmd = ["docker", "buildx", "build", "-f", str(cfg.project_dir / "Dockerfile.release")]
cmd = ["docker", "buildx", "build", "--load", "-f", str(cfg.project_dir / "Dockerfile.release")]
if cfg.no_cache:
cmd.append("--no-cache")
cmd.extend(["--progress=plain"])
Expand Down
6 changes: 3 additions & 3 deletions mkosi.extra/etc/rsyslog.conf
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ global(
# want journal entries from specific units, not all daemon syslog output.
module(load="imjournal")

# Tail containerd container log files (workflow action stdout/stderr).
# Tail nerdctl container log files (workflow action stdout/stderr).
module(load="imfile")
input(type="imfile"
File="/var/lib/containerd/io.containerd.grpc.v2.task/*/log"
File="/var/lib/nerdctl/*/containers/*/*/*-json.log"
Tag="container"
Severity="info"
Facility="local0"
Expand All @@ -38,7 +38,7 @@ if ($!_SYSTEMD_UNIT == "tink-agent.service" or $!_SYSTEMD_UNIT == "tink-agent-se

# Forward container logs (from imfile).
# Match "container:" specifically — NOT "containerd" (the daemon).
if ($syslogtag startswith "container:") then {
if ($syslogtag startswith "container") then {
action(type="omfwd"
target=`echo $SYSLOG_HOST`
port=`echo $SYSLOG_PORT`
Expand Down
Loading