Build the custom vminit image locally via make vminit-image; drop the CI workflow

The GitHub-hosted macos runners can't build the host framework (needs the
macOS 26+ Virtualization SDK), so publish the custom vminit guest image from a
local macOS 26/27 machine instead. Adds root-Makefile targets:
  - vminit-image-prep : one-time swiftly + musl static SDK install
  - vminit-image      : build cctl + cross-build vminitd, package the image
  - vminit-image-push : push to GHCR (REGISTRY_* env creds)
Forces WARNINGS_AS_ERRORS=false (Xcode Swift 6.4 rejects -warnings-as-errors
alongside SwiftPM's -suppress-warnings). Removes .github/workflows/vminit-image.yml
and repoints vminitReference + PATCHES.md docs at the Makefile.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
2026-07-13 19:31:56 -07:00
co-authored by Claude Opus 4.8
parent 3f939a84c6
commit b81d12553c
4 changed files with 64 additions and 131 deletions
-118
View File
@@ -1,118 +0,0 @@
name: Publish custom vminitd init image
# Builds and pushes Nucleic's **custom** vminitd guest image — the init filesystem (guest PID 1,
# gRPC-over-vsock) that every Nucleic Control / sandbox container boots. Nucleic pulls this instead of
# Apple's stock `ghcr.io/apple/containerization/vminit` (see ContainerEngine.vminitReference) because
# we carry guest-side patches in third_party/containerization/vminitd (per-exec cgroups, event-loop
# offload — see third_party/containerization/PATCHES.md).
#
# Built from the VENDORED source (third_party/containerization, pinned upstream commit 6b7b42ca), so
# the guest vminitd and the host `Containerization` framework are compiled from the same tree and are
# guaranteed protocol-compatible — a stock `vminit:0.34.0` could drift from our vendored commit.
#
# Runner: macOS 26 arm64. This must be macOS (not Linux like the rest of our CI) because `cctl images
# push` is macOS-only (`#if os(macOS)` in cctl/ImageCommand.swift) and the Makefile `init` flow is a
# Darwin flow (it codesigns cctl). It must be macOS *26* specifically: `make containerization` compiles
# the whole host framework, and Sources/Containerization/{VmnetNetwork,NATNetworkInterface}.swift use
# vmnet_network_ref / VZVmnetNetworkDeviceAttachment — symbols that exist only in the macOS 26 SDK, so
# an older runner (macos-15) fails with "cannot find type 'vmnet_network_ref' in scope". The guest
# binaries are cross-built for aarch64-linux-musl via the Swift static SDK; this job only packages +
# pushes an image, it does not boot a VM.
#
# If GitHub-hosted `macos-26` isn't available in this org yet, switch to a self-hosted macOS 26 runner
# (the dev machines already run macOS 26 / Darwin 27, which is why local `swift build` succeeds).
#
# Manual + on-change. FIRST publish only: set the `vminit` GHCR package to Public (GitHub → Packages)
# so it can be pulled anonymously while the repo stays private — exactly like nucleic-kernel /
# nucleic-sandbox / the linux-vm-agents artifacts.
#
# NOTE (unvalidated until first run): CI for this image has not executed yet. The build steps mirror
# the documented `make init` + `cctl images push` flow and third_party/containerization/.github/
# workflows/linux-build.yml, but the toolchain/SDK install and the push have to be confirmed on the
# first dispatch. Keep `publish: false` on the first run to build-only and inspect the artifact.
on:
workflow_dispatch:
inputs:
tag:
description: "GHCR tag for the vminit image (keep in lockstep with ContainerEngine.vminitReference)"
required: true
default: "0.34.0-nucleic1"
publish:
description: "Push to GHCR (else just build + upload the image tar as a workflow artifact)"
type: boolean
default: true
push:
paths:
- "third_party/containerization/vminitd/**"
- "third_party/containerization/Sources/Containerization/**"
- ".github/workflows/vminit-image.yml"
jobs:
vminit:
name: Build + push custom vminit image
runs-on: macos-26 # macOS 26 arm64 — needs the macOS 26 SDK (vmnet_network_* symbols); see header
timeout-minutes: 45
permissions:
contents: read
packages: write
defaults:
run:
working-directory: third_party/containerization
steps:
- uses: actions/checkout@v4
# Install the exact Swift the vendored tree pins (.swift-version = 6.3.0) via swiftly, plus the
# aarch64 static-linux (musl) SDK the guest binaries cross-compile against. `cross-prep` is the
# repo's own target for this (vminitd/Makefile: `cross-prep: swift linux-sdk`).
- name: Install Swift 6.3 toolchain + musl static SDK
run: make -C vminitd cross-prep
# Put swiftly's Swift on PATH so BOTH makefiles use 6.3.0 (the top Makefile defaults SWIFT to
# /usr/bin/swift on Darwin, which may be an older Xcode Swift — force the swiftly one instead).
- name: Select the swiftly toolchain
run: |
echo "$HOME/.swiftly/bin" >> "$GITHUB_PATH"
- name: Resolve GHCR reference
id: ref
run: |
O=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')
echo "image=ghcr.io/$O/vminit:${{ inputs.tag }}" >> "$GITHUB_OUTPUT"
# Build cctl (native macOS, ad-hoc codesigned by `make containerization`) and vminitd/vmexec
# (aarch64-linux-musl static via the SDK), then assemble the init image into the local content
# store under our GHCR reference. Mirrors the Makefile `init` target with `--image` set to our ref.
- name: Build cctl + vminitd (musl) and assemble the init image
env:
SWIFT: swift # the swiftly 6.3 one, now first on PATH
run: |
set -euo pipefail
make containerization
make -C vminitd # default LIBC=musl → static aarch64-linux-musl vminitd + vmexec
rm -f bin/init.rootfs.tar.gz bin/init.block bin/initfs.ext4
./bin/cctl rootfs create \
--vminitd vminitd/bin/vminitd \
--vmexec vminitd/bin/vmexec \
--ext4 ./bin/initfs.ext4 \
--label org.opencontainers.image.source=https://github.com/apple/containerization \
--image "${{ steps.ref.outputs.image }}" \
bin/init.rootfs.tar.gz
# Build-only fallback: on the first (unvalidated) run keep publish=false and inspect this.
- name: Upload init ext4 as a workflow artifact
uses: actions/upload-artifact@v4
with:
name: vminit-initfs-arm64
path: third_party/containerization/bin/initfs.ext4
if-no-files-found: error
# `cctl images push` (macOS-only) reads registry creds from REGISTRY_HOST/USERNAME/TOKEN
# (cctl/ImageCommand.swift authenticationFromEnv), so no docker login is needed.
- name: Push init image to GHCR
if: ${{ github.event_name == 'workflow_dispatch' && inputs.publish }}
env:
REGISTRY_HOST: ghcr.io
REGISTRY_USERNAME: ${{ github.actor }}
REGISTRY_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./bin/cctl images push "${{ steps.ref.outputs.image }}"