cage-kernel is the reproducible build unit for macOS ContainerKit guest
kernels used by Cage. Public release artifacts are published from
Rjvs/cage-kernel; this monorepo copy
remains the local development and compatibility reference.
Cage can hotplug a direct ext4 volume into a running ContainerKit VM only when the guest kernel has SCSI disk, XHCI, USB mass storage, and UAS support. Cage can use guest-side NBD only when the kernel also has NBD support. Cage can mount SMB/Samba shares inside the guest only when the kernel also has CIFS support. The tool can create and publish three explicit profiles:
| Profile | Description |
|---|---|
hotplug |
Vanilla pinned apple/containerization guest kernel plus Cage's hotplug direct-volume config. This is the default profile and the backward-compatible vmlinux.zst release asset. |
nbd |
hotplug plus guest-side NBD transport config. |
nbd-cifs |
nbd plus SMB/CIFS guest-mount config. |
patches/containerization-hotplug-guest.patch: the minimalkernel/config-arm64patch for Cage hotplug direct-volume support.patches/containerization-nbd-guest.patch: the minimalkernel/config-arm64patch for Cage guest-side NBD transport support.patches/containerization-cifs-guest.patch: the optional CIFS config patch for upstream revisions that do not already carry the SMB/CIFS guest options.scripts/cage_kernel.py: a managed workflow to fetch upstreamapple/containerization, apply profile patches, buildkernel/vmlinux-arm64, verify the embedded kernel config, create profile artifacts, package release assets, publish them toRjvs/cage-kernel, install them for Cage, and run the focused live-volume acceptance test.- Unit metadata so the patch and workflow are visible through the normal repo commands.
- macOS on Apple silicon.
- Xcode command line tools.
- The Apple
containerCLI onPATH. - Network access to clone
https://github.com/apple/containerization.git. - Cage's integration-test prerequisites when running
acceptance.
The default upstream revision is
d9868bb657fac3b55ed5dcec97c8eb8a08e78bf5, matching Cage's current
Containerization SwiftPM pin.
app/isolate/cage-kernel/
CHANGELOG.md
VERSION
patches/
containerization-cifs-guest.patch
containerization-hotplug-guest.patch
containerization-nbd-guest.patch
scripts/
cage_kernel.py
Generated checkouts and build products are written under
.local/cage-kernel/, which is ignored by git.
./tools/run cage-kernel prepare
./tools/run cage-kernel build
./tools/run cage-kernel create
./tools/run cage-kernel package-release
./tools/run cage-kernel publish
./tools/run cage-kernel verify
./tools/run cage-kernel install-local
./tools/run cage-kernel acceptance
./tools/run cage-kernel list-profiles
./tools/run --raw cage-kernel diagnose-dnsprepare creates or refreshes .local/cage-kernel/containerization, checks out
the pinned upstream revision, resets that managed checkout, and applies the
selected profile patches. Commands that operate on one kernel accept
--profile hotplug, --profile nbd, or --profile nbd-cifs; the default is
hotplug.
build runs prepare, then performs the same steps as the upstream
kernel/Makefile: build the kernel-build:0.1 image, resolve the latest
non-EOL kernel.org release in the configured source series, download and
validate the source tarball when missing or corrupt, run build.sh in the
build container, and verify the resulting
.local/cage-kernel/containerization/kernel/vmlinux-arm64. The verified result is
also copied to .local/cage-kernel/kernels/<profile>/vmlinux.
The default source series is 6.18, matching the Apple Containerization kernel
series Cage tracks. cage-kernel first tries the source URL advertised by
kernel.org release metadata, then falls back to the matching git.kernel.org
stable snapshot if the CDN archive is not available. Override it when needed:
./tools/run --raw cage-kernel build --kernel-source-series 6.12
./tools/run --raw cage-kernel build --kernel-source-url https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.18.37.tar.xzHTTP errors and invalid cached downloads fail before the build container starts,
so a stale kernel.org 404 response cannot be reused as the local source archive.
Validated source archives are cached outside the managed upstream checkout and
copied back after each profile prepare, avoiding a fresh download when
git clean resets the checkout between profile builds.
create builds every kernel profile by default:
./tools/run cage-kernel create
./tools/run cage-kernel create --profile hotplug --profile nbd --profile nbd-cifs
./tools/run cage-kernel create --install-localcreate --install-local installs each profile for local Cage use. The default
hotplug profile is installed at app/isolate/cage/.local/vmlinux for
backwards compatibility. Other profiles install under
app/isolate/cage/.local/kernels/<profile>/vmlinux.
package-release packages existing profile artifacts from
.local/cage-kernel/kernels/<profile>/vmlinux into
.local/cage-kernel/release/:
hotplug-vmlinux.zst
nbd-vmlinux.zst
nbd-cifs-vmlinux.zst
vmlinux.zst
manifest.json
SHA256SUMS
vmlinux.zst is a backward-compatible alias for hotplug-vmlinux.zst, so
current Cage release download code continues to consume the hotplug kernel. The
manifest records all three profiles and keeps the existing top-level
artifacts.vmlinux / artifacts.vmlinux.zst shape for that default hotplug
asset.
publish runs package-release and uploads the assets with GitHub CLI:
./tools/run cage-kernel publish
./tools/run cage-kernel publish -- --draft
./tools/run cage-kernel publish -- --tag v0.3.3 --repo Rjvs/cage-kernelIf the release tag already exists, publish uploads with --clobber. If it
does not exist, it creates a full public release by default. Pass --draft only
when intentionally staging a draft; rerunning publish without --draft
publishes an existing draft release.
On macOS, build first checks that the Apple container system service is
running. If it is not available, start it before building:
container system startAfter that, build discovers host DNS servers from scutil --dns and passes
them to both container build and container run with --dns. This avoids a
known Apple container failure mode where containers get /etc/resolv.conf
pointing at the default NAT gateway, such as 192.168.73.1, but that resolver
cannot resolve ports.ubuntu.com for the Ubuntu package install in the build
image.
Some Apple container versions do not apply container build --dns to an
already-running BuildKit builder. When the image build fails, cage-kernel
falls back only for non-service failures to a direct ubuntu:focal build
container with the same package recipe and explicit DNS, without stopping,
deleting, or recreating the global builder.
If automatic DNS discovery is wrong for your network, pass one or more explicit DNS servers:
./tools/run --raw cage-kernel build --dns 10.2.1.1
./tools/run --raw cage-kernel acceptance --dns 10.2.1.1diagnose-dns prints the discovered host DNS servers, Apple container
service and builder status, and compares default container DNS with explicit
host DNS:
./tools/run --raw cage-kernel diagnose-dns
./tools/run --raw cage-kernel diagnose-dns --dns 10.2.1.1install-local copies the verified kernel to the profile's local Cage path.
For hotplug, that remains app/isolate/cage/.local/vmlinux, the
source-checkout location Cage probes before the managed public-release cache.
acceptance builds, installs, and runs the focused macOS live direct-volume
integration test with CAGE_TEST_KERNEL_PATH set to the installed kernel. It is
valid for all three profiles because each includes the hotplug storage config.
This unit is consumed by Cage on macOS only. It does not change the Cage public API and does not affect Windows/HCS.
The patches are intentionally kernel-config-only. Every published profile also
verifies that CONFIG_VSOCKETS_LOOPBACK is unset. Containerization 0.38 already
carries Cage's CIFS requirements, so the CIFS patch is retained only for older
compatible revisions and is skipped for the production revision. No Swift source edits to
apple/containerization are required for Cage's current direct live-attach
path; those belong to separate pod/shared-volume investigations.
Public releases are tagged in Rjvs/cage-kernel as v{version} and publish
the three profile artifacts, the backward-compatible vmlinux.zst hotplug
alias, manifest.json, and SHA256SUMS. The manifest records the upstream
Containerization revision, profile requirements, and artifact hashes.