Repository navigation
feat(sandbox): add the guest image build and publish pipeline (sandbox Phase 3) - #199
Merged
Merged
Conversation
…x Phase 3) Build the sandbox guest images with Docker so the pipeline runs the same on macOS and Linux. Per arch it produces a bwrap rootfs tarball, a vz bundle of vmlinux plus an ext4 rootfs, and a manifest.json matching src/manifest.ts. - image/: one Debian guest consumed by every backend, a minimal virtio-only kernel, a tools image for ext4 conversion, and the system-wide codev-office install (skipped with --no-office) - script/build-image.ts: per-arch build, digest-pinned base, sparse-aware tarring, sha256 manifest assembly - script/publish-image.ts: uploads versioned artifacts first, manifest.json last, so clients never see a version before its assets exist - script/e2e-vz.ts: boots a locally built vz image end-to-end through codev-vmm and the vsock health check Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… builds manifest.json is deliberately unversioned because it is the pointer every client reads, so publishing replaces it wholesale. Nothing stopped a single-arch or dev-versioned build from retiring the working manifest for the platforms it omits; publish-image.ts now refuses both unless --force. build-image.ts prepulls the digest-pinned base, but buildkit still resolves the FROM remotely and a real run died on "load metadata ... DeadlineExceeded" even with the image local. Route the pull and the three buildx builds through one bounded retry; buildkit keeps completed layers, so a retry resumes. Also ignore the office bundle staging dir contents, which are build inputs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the sandbox guest image build and publish pipeline (Phase 3), plus two fixes found while running it end to end.
Pipeline
Builds the guest images with Docker so the process is identical on macOS and Linux. Per arch it produces a bwrap rootfs tarball, a vz bundle of
vmlinux+ an ext4 rootfs, and amanifest.jsonmatchingsrc/manifest.ts.image/— one Debian guest consumed by every backend, a minimal virtio-only kernel, a tools image for ext4 conversion, and the system-wide codev-office install (skipped with--no-office)script/build-image.ts— per-arch build, digest-pinned base, sparse-aware tarring, sha256 manifest assemblyscript/publish-image.ts— versioned artifacts upload first,manifest.jsonlast, so clients never see a version before its assets existscript/e2e-vz.ts— boots a locally built vz image throughcodev-vmmand the vsock health checkFixes
Partial publishes could retire the working manifest.
manifest.jsonis deliberately unversioned — it is the pointer every client reads viaSANDBOX_MANIFEST_URL, so publishing replaces it wholesale. Nothing stopped an arm64-only or0.0.0-devbuild from being published over it, which would leave the omitted platforms failing on every launch withsandbox manifest has no image for bwrap-x64.publish-image.tsnow refuses a manifest missing any{bwrap,vz}-{arm64,x64}asset, and refuses a version that is notN.N.N, unless--forceis passed.Registry-facing steps had no retry. The prepull primes the local store, but buildkit still resolves the
FROMremotely — a real run died onload metadata ... DeadlineExceededwith the base image already local. The pull and all three buildx builds now share one bounded retry; buildkit keeps completed layers, so a retry resumes rather than restarts. The comment claiming the prepull removes remote resolution was wrong and has been corrected.Verification
A full arm64 image was built end to end on Apple Silicon with
--no-office:bwrap-arm64.tar.gzvz-arm64.tar.gzBoth digests in the generated
manifest.jsonmatchshasum -a 256of the artifacts.bun typecheckclean;bun test61 pass / 2 skip / 0 fail.The new guard was exercised against that real manifest and against synthetic ones:
has no bwrap-x64, vz-x64, exit 1--force→ proceeds to the upload dry run, exit 00.0.0-dev→ refused on the version, exit 12026.08.1→ passes both guards and continues to the artifact checkNotes
DIVERGENCES.md: every file here is under the fork-onlypackages/codev-sandbox. NoCHANGELOG.mdentry, matching the three prior sandbox phase PRs.--arch x64on a native x86_64 host and--office-bundle.e2e-vz.tscallshash.digest("hex")inside theresolveImagecallback.resolveImageruns once today (onlycreate()callsprepare), so it works, but a second invocation would throwDigest already called. Hoisting the digest out of the closure would make it robust.🤖 Generated with Claude Code