diff --git a/docs/design/microvm-linux.md b/docs/design/microvm-linux.md index 151a3dd7..cfd3bf51 100644 --- a/docs/design/microvm-linux.md +++ b/docs/design/microvm-linux.md @@ -139,6 +139,11 @@ Each is its own branch, tested before the next. `4a6755ac…`, rootfs `bf06cedb…` (aarch64) and `4f4e67cb…` (x86_64), and the layers over them. The kernels, agent-init and berth-init rebuilt unchanged. This will recur until the apk cache is pinned (open problem 10 in `microvm-runtime.md`). +- **Re-pinned for the agent-init log fix, 2026-10-25.** agent-init's `eprintln!` wrote each line in + pieces, so two apps sharing a stderr spliced their lines together and the Multi-App check failed about + one run in three. Both manifests now pin agent-init to the fix (`0204e8f2…`), which also carries main's + libc, tokio and sqlite bumps. `update_pins` runs 40198606357 (aarch64) and 40198603422 (x86_64) give + rootfs `e6017262…` (aarch64) and `0c623b43…` (x86_64); the kernels are unchanged. - **Linux arm64 booted**, 2026-10-24, on a nested-KVM Lima VM (Ubuntu 24.04, Linux 6.8, VZ on an M4) with the published linux-arm64 berth-vmm `a3cf2a09…` and its libkrun, rootfs `62f96e1b…`: host sandbox Landlock ABI 4 with TCP rules and seccomp; `e2e.mjs` single 18/18, multi 17/17, enforce 12/12, stdio 3/3, diff --git a/docs/local-vm.md b/docs/local-vm.md index cdfc0ba6..f4cae695 100644 --- a/docs/local-vm.md +++ b/docs/local-vm.md @@ -65,11 +65,11 @@ By default, from the GitHub release that [`.github/workflows/vm-artifacts.yml`]( | File | Asset | sha256 (this CLI) | Size | |---|---|---|---| | `~/.berth/vm/kernel/sha256//Image` | `Image-` | `8f79e8dae97ebc0ab8fcdc4ad209bb025ec967be82c713503e0612cfdd340ec8` | 23,668,744 B | -| `~/.berth/vm/rootfs/rootfs-.erofs` | `rootfs-.erofs` | `bf06cedb9b40c5f23a74e2b2fe87458cd43b81a7d65ce09a65730b1e7cf590fa` | 107,937,792 B | +| `~/.berth/vm/rootfs/rootfs-.erofs` | `rootfs-.erofs` | `e60172628d1bbc5d36f3df44d81e4b9cf79b02fd87a974621d15e51dec570522` | 108,072,960 B | | `~/.berth/vm/bin/berth-vmm` | `berth-vmm-darwin-arm64-`, `berth-vmm-linux-arm64-` | `VMM_PINS` in `packages/cli/src/vm/pins.ts` | about 700 KB (macOS), 2.7 MB (Linux) | | `~/.berth/vm/bin/libkrun.1.19.6.dylib`, `libkrun.so.1.19.6` | `libkrun-darwin-arm64-.dylib`, `libkrun-linux-arm64-.so` | `LIBKRUN_PINS` in the same file | about 4.7 MB | -That is `https://github.com/Ash20pk/BerthOS/releases/download/vm-artifacts-8f79e8da-bf06cedb/`. The x86_64 one is `vm-artifacts-10d4b54c-4f4e67cb`: kernel `10d4b54c0896668a93f9d26d0a701aac4a14ce813f3ed4d3b4d26e50d7b7b8d1` (an ELF `vmlinux`, 27,928,992 B), rootfs `4f4e67cb49a1b07e96412e802bd2c6e42cfabee95d7c126b8589b1048a79a538` (108,765,184 B), and `berth-vmm-linux-x64-` with `libkrun-linux-x64-.so`. CI rebuilds each architecture's kernel and rootfs from source on GitHub's Linux runners of that architecture, and publishes the release only if they match the pins bit for bit. The release also carries `SHA256SUMS`, each rootfs's input record, berth-vmm's build record, and the kernel's GPL sources (the exact linux and libkrunfw tarballs, the config delta, the resolved config and the build script; see `SOURCES.md` there). +That is `https://github.com/Ash20pk/BerthOS/releases/download/vm-artifacts-8f79e8da-e6017262/`. The x86_64 one is `vm-artifacts-10d4b54c-0c623b43`: kernel `10d4b54c0896668a93f9d26d0a701aac4a14ce813f3ed4d3b4d26e50d7b7b8d1` (an ELF `vmlinux`, 27,928,992 B), rootfs `0c623b43a2c2852fd156d1ea6d4f00a8612143299ec7381cf2d1516607d0a9f6` (108,904,448 B), and `berth-vmm-linux-x64-` with `libkrun-linux-x64-.so`. CI rebuilds each architecture's kernel and rootfs from source on GitHub's Linux runners of that architecture, and publishes the release only if they match the pins bit for bit. The release also carries `SHA256SUMS`, each rootfs's input record, berth-vmm's build record, and the kernel's GPL sources (the exact linux and libkrunfw tarballs, the config delta, the resolved config and the build script; see `SOURCES.md` there). berth-vmm and its libkrun are downloaded only when the CLI pins their sha256 for your platform (macOS arm64, Linux arm64 and Linux x86_64). A build from CI can't be pinned until CI has built it, so a CLI released before the first artifacts release has no pin, and says so. Then build berth-vmm and pass `--vmm`, or download it by hand (below). @@ -95,7 +95,7 @@ If the kernel and rootfs aren't installed, `berth dev --runtime vm` installs the #### Verifying by hand ```bash -tag=vm-artifacts-8f79e8da-bf06cedb +tag=vm-artifacts-8f79e8da-e6017262 gh release download "$tag" -R Ash20pk/BerthOS -p 'Image-*' -p 'rootfs-*.erofs' -p 'berth-vmm-darwin-arm64-*' -p 'libkrun-darwin-arm64-*' -p SHA256SUMS shasum -a 256 -c --ignore-missing SHA256SUMS # each asset against the list shasum -a 256 Image-* rootfs-*.erofs # and against the pins above, which are also in diff --git a/packages/agent-init/src/main.rs b/packages/agent-init/src/main.rs index 3abe1f25..144780bd 100644 --- a/packages/agent-init/src/main.rs +++ b/packages/agent-init/src/main.rs @@ -22,6 +22,20 @@ use landlock::{ }; use serde::Deserialize; +// Shadows std's eprintln! for this crate (seccomp.rs included, since it is +// declared below). std's version writes each piece of the format string with +// its own write(2), so when two apps' agent-init share one stderr their lines +// interleave mid-line. Formatting first and writing once keeps each line +// whole: a single write under PIPE_BUF to a pipe is atomic. +macro_rules! eprintln { + ($($arg:tt)*) => {{ + use std::io::Write as _; + let mut line = format!($($arg)*); + line.push('\n'); + let _ = std::io::stderr().write_all(line.as_bytes()); + }}; +} + mod seccomp; #[derive(Deserialize)] diff --git a/packages/cli/src/vm/pins.ts b/packages/cli/src/vm/pins.ts index b575f966..9d6f8cfe 100644 --- a/packages/cli/src/vm/pins.ts +++ b/packages/cli/src/vm/pins.ts @@ -40,11 +40,11 @@ export interface GuestPins { export const GUEST_PINS: Partial> = { aarch64: { kernel: { sha256: "8f79e8dae97ebc0ab8fcdc4ad209bb025ec967be82c713503e0612cfdd340ec8", size: 23668744, linux: "6.12.109", configSha256: "e3f33c2bd4bffa16e52a066c325967e4bde091f20063e6eb5b81e8a2efac4dc8" }, - rootfs: { sha256: "bf06cedb9b40c5f23a74e2b2fe87458cd43b81a7d65ce09a65730b1e7cf590fa", size: 107937792 }, + rootfs: { sha256: "e60172628d1bbc5d36f3df44d81e4b9cf79b02fd87a974621d15e51dec570522", size: 108072960 }, }, x86_64: { kernel: { sha256: "10d4b54c0896668a93f9d26d0a701aac4a14ce813f3ed4d3b4d26e50d7b7b8d1", size: 27928992, linux: "6.12.109", configSha256: "6e0fd31c75cd563f8bf650765504d97989316f70e9bbb333fb0230db78fe4283" }, - rootfs: { sha256: "4f4e67cb49a1b07e96412e802bd2c6e42cfabee95d7c126b8589b1048a79a538", size: 108765184 }, + rootfs: { sha256: "0c623b43a2c2852fd156d1ea6d4f00a8612143299ec7381cf2d1516607d0a9f6", size: 108904448 }, }, }; @@ -121,15 +121,15 @@ export type VmmPlatform = "darwin-arm64" | "linux-arm64" | "linux-x64"; * `berth vm install` refuses any other bytes, and clears macOS's quarantine * attribute only on a file that matched. * - * All three are from the per-architecture releases vm-artifacts-8f79e8da-bf06cedb - * (aarch64: darwin-arm64, linux-arm64) and vm-artifacts-10d4b54c-4f4e67cb - * (x86_64: linux-x64). Runs 40103596964 / 40103557191 and 40104945503 built - * each of them to the same bytes. + * All three are from the per-architecture releases vm-artifacts-8f79e8da-e6017262 + * (aarch64: darwin-arm64, linux-arm64) and vm-artifacts-10d4b54c-0c623b43 + * (x86_64: linux-x64). Run 40200731376 built all three; it also rebuilt both + * rootfs images to their pins and passed the x86_64 e2e under KVM. */ export const VMM_PINS: Partial> = { - "darwin-arm64": { sha256: "92fd7ae2a97e029f1689cfd626600dfcbef39e8933ed304b0e2466a385c167ae", size: 700608 }, - "linux-arm64": { sha256: "2ecc29d88ea0fd1abadc7a142bb0f7b53de5f8e104860ef2e24ce3c487646dc6", size: 725632 }, - "linux-x64": { sha256: "e5809f8c43281b1e821be4b48003855a7913fe5905d2f32a52c7bf377b91e6d1", size: 742152 }, + "darwin-arm64": { sha256: "628e6ac16dde4657a2c177a0614ee89de91f9d47db631b8c8d59e111fc2904f0", size: 700608 }, + "linux-arm64": { sha256: "1b72e4966c5c96c0ff89eab64bb868e8ee9a2cac75640f8b3ee65ec2c53e7fd1", size: 725632 }, + "linux-x64": { sha256: "308dd7d8a6e7a0cb5c821dcd2c2eefe7775d3a3859c7891ea5154ed8582cb0dd", size: 742152 }, }; export function vmmPin(platform: string = `${process.platform}-${process.arch}`, pins: Partial> = VMM_PINS): ArtifactPin | undefined { diff --git a/packages/vmm/rootfs/layers/browser/aarch64.apk.lock b/packages/vmm/rootfs/layers/browser/aarch64.apk.lock index d1709406..6c8a19cc 100644 --- a/packages/vmm/rootfs/layers/browser/aarch64.apk.lock +++ b/packages/vmm/rootfs/layers/browser/aarch64.apk.lock @@ -35,10 +35,10 @@ e2fsprogs-1.47.4-r0 e2fsprogs-libs-1.47.4-r0 encodings-1.1.0-r0 eudev-libs-3.2.14-r6 -ffmpeg-libavcodec-8.1.2-r0 -ffmpeg-libavformat-8.1.2-r0 -ffmpeg-libavutil-8.1.2-r0 -ffmpeg-libswresample-8.1.2-r0 +ffmpeg-libavcodec-8.1.3-r0 +ffmpeg-libavformat-8.1.3-r0 +ffmpeg-libavutil-8.1.3-r0 +ffmpeg-libswresample-8.1.3-r0 file-5.47-r2 font-alias-1.0.6-r0 font-cursor-misc-1.0.4-r1 diff --git a/packages/vmm/rootfs/layers/browser/x86_64.apk.lock b/packages/vmm/rootfs/layers/browser/x86_64.apk.lock index 1005d834..4aa2f7b4 100644 --- a/packages/vmm/rootfs/layers/browser/x86_64.apk.lock +++ b/packages/vmm/rootfs/layers/browser/x86_64.apk.lock @@ -35,10 +35,10 @@ e2fsprogs-1.47.4-r0 e2fsprogs-libs-1.47.4-r0 encodings-1.1.0-r0 eudev-libs-3.2.14-r6 -ffmpeg-libavcodec-8.1.2-r0 -ffmpeg-libavformat-8.1.2-r0 -ffmpeg-libavutil-8.1.2-r0 -ffmpeg-libswresample-8.1.2-r0 +ffmpeg-libavcodec-8.1.3-r0 +ffmpeg-libavformat-8.1.3-r0 +ffmpeg-libavutil-8.1.3-r0 +ffmpeg-libswresample-8.1.3-r0 file-5.47-r2 font-alias-1.0.6-r0 font-cursor-misc-1.0.4-r1 diff --git a/packages/vmm/rootfs/manifest-aarch64.toml b/packages/vmm/rootfs/manifest-aarch64.toml index 64e6e901..98d424af 100644 --- a/packages/vmm/rootfs/manifest-aarch64.toml +++ b/packages/vmm/rootfs/manifest-aarch64.toml @@ -17,18 +17,18 @@ packages = "rootfs/packages.txt" source_date_epoch = 1790812800 # /usr/local/bin/agent-init and berth-probe: build-agent-init.sh, from # packages/agent-init at this commit (main contains it). -agent_init_ref = "fix/seccomp-io-uring-vsock" -agent_init_commit = "c558ef85a920eece0413f2c08345a67396342153" -agent_init_sha256 = "9ec8b25e38d31ee82a28155304f730c0ec589b057d11fce2a56c661455929483" +agent_init_ref = "fix/agent-init-atomic-log" +agent_init_commit = "0204e8f2c9b924d8fe2f20c7390fe43689b4b2fa" +agent_init_sha256 = "0c1d011166a4e35167c4023cc65fb89a9aa2087ba7681c4c597cfd4111f9148f" probe_sha256 = "6ec735d885b58861b33abdd70a5a4d48ecad803cc92bd94c02f876a3346453d0" # /sbin/berth-init and /usr/local/bin/context-bus-daemon: build-berth-init.sh, # from this tree (packages/vmm/init, packages/context-bus-daemon). berth_init_sha256 = "eb9f699e91a4a1aba01d6778f346c279a9f6f1f5cdaa85d999b9e6b400c323ed" -context_bus_daemon_sha256 = "1138c3595142a3235145b530d0cf1157b0971aa2230d417befe0a6e783477544" +context_bus_daemon_sha256 = "401eec5ecd99024fdca5cbaee626947f47be2075e04b8b30013951b5e5a5055f" # /usr/local/bin/semantic-fs-daemon: build-semantic-fs.sh, from # packages/semantic-fs-daemon at HEAD: the daemon that serves /context # (docs/design/microvm-semantic-fs.md). -semantic_fs_daemon_sha256 = "957bb9632d4faa4a3cd92436a95d18e07f7a01ea0314cf1553d72137b40c023a" +semantic_fs_daemon_sha256 = "ef1a0d0c62b6e0f10120de5ceb947fad1b975f48fa999f54343de504244d4b78" # /usr/local/bin/berth-github-api-broker.cjs: packages/docker-orchestrator/docker/github-api-broker.cjs. github_api_broker_sha256 = "0a809855c067d76b2074746b2390f6b204d1d80a7cafdc8cea4371efa624baaa" # /usr/local/bin/berth-egress-broker.cjs: packages/docker-orchestrator/docker/egress-broker.cjs. @@ -56,13 +56,13 @@ terminal = "tmux" # builder.apk.lock the builder's (erofs-utils). .github/workflows/vm-artifacts.yml # rebuilds it on a Linux runner and fails on any other hash. berth-vmm # compiles this in; berth-vmm run boots it by default. -image_sha256 = "bf06cedb9b40c5f23a74e2b2fe87458cd43b81a7d65ce09a65730b1e7cf590fa" -image_size = 107937792 +image_sha256 = "e60172628d1bbc5d36f3df44d81e4b9cf79b02fd87a974621d15e51dec570522" +image_size = 108072960 # Optional layer example (rootfs/layers/example, build-layer.sh), built for the base above. layer_example_sha256 = "707d1c9ea2b77472954ae2cddb281dbbd1ca2e8f45b1bd191ba8c1f1ee3359c6" layer_example_size = 471040 -layer_example_base = "bf06cedb9b40c5f23a74e2b2fe87458cd43b81a7d65ce09a65730b1e7cf590fa" +layer_example_base = "e60172628d1bbc5d36f3df44d81e4b9cf79b02fd87a974621d15e51dec570522" # Optional layer browser (rootfs/layers/browser, build-layer.sh), built for the base above. -layer_browser_sha256 = "92ad1a7b184bdc844c4611918930834c831d5cfed54e1e3c48100e1a794eb827" -layer_browser_size = 485199872 -layer_browser_base = "bf06cedb9b40c5f23a74e2b2fe87458cd43b81a7d65ce09a65730b1e7cf590fa" +layer_browser_sha256 = "643b36055173d7698bfcd103646ec09d0c57b9f61977d4c30e29bef3d5957ce8" +layer_browser_size = 485203968 +layer_browser_base = "e60172628d1bbc5d36f3df44d81e4b9cf79b02fd87a974621d15e51dec570522" diff --git a/packages/vmm/rootfs/manifest-x86_64.toml b/packages/vmm/rootfs/manifest-x86_64.toml index 05ac6f16..267e2426 100644 --- a/packages/vmm/rootfs/manifest-x86_64.toml +++ b/packages/vmm/rootfs/manifest-x86_64.toml @@ -17,18 +17,18 @@ packages = "rootfs/packages.txt" source_date_epoch = 1790812800 # /usr/local/bin/agent-init and berth-probe: build-agent-init.sh, from # packages/agent-init at this commit (main contains it). -agent_init_ref = "fix/seccomp-io-uring-vsock" -agent_init_commit = "c558ef85a920eece0413f2c08345a67396342153" -agent_init_sha256 = "112c5f4ff89706e810b867da2e3121196e1294247a876c80b10de1ab337ec129" +agent_init_ref = "fix/agent-init-atomic-log" +agent_init_commit = "0204e8f2c9b924d8fe2f20c7390fe43689b4b2fa" +agent_init_sha256 = "e8ba190c2b317d574eebfc99aa04e867ed1e5aa8cca562eb153f34a78672348a" probe_sha256 = "c722bb79589e8fa0f89d75ff3cdd47763aefdf2034ae15bb70baa2ddfcea9d80" # /sbin/berth-init and /usr/local/bin/context-bus-daemon: build-berth-init.sh, # from this tree (packages/vmm/init, packages/context-bus-daemon). berth_init_sha256 = "8fbcb33c88edf01d3e863d82a477b2c9a19c1f2c3d35ba4ad027a48ca3a6ac44" -context_bus_daemon_sha256 = "29b094f36cfd578eb72241a4fc8beb4688e856e95bd434db9bd51c6e36bf5f69" +context_bus_daemon_sha256 = "c9f32a6f42f18c48b3647c5c06b03fc87611f123d2642f33dcf5dea10928edcf" # /usr/local/bin/semantic-fs-daemon: build-semantic-fs.sh, from # packages/semantic-fs-daemon at HEAD: the daemon that serves /context # (docs/design/microvm-semantic-fs.md). -semantic_fs_daemon_sha256 = "4a6755ac4d3e6bd7233f895f1ea35aa11394961d63ad59faec0b2faa3f2d88f9" +semantic_fs_daemon_sha256 = "fbf507612ce1714172e103d2fa3df2dc524ccd2dd899d047970ce7e8a0761deb" # /usr/local/bin/berth-github-api-broker.cjs: packages/docker-orchestrator/docker/github-api-broker.cjs. github_api_broker_sha256 = "0a809855c067d76b2074746b2390f6b204d1d80a7cafdc8cea4371efa624baaa" # /usr/local/bin/berth-egress-broker.cjs: packages/docker-orchestrator/docker/egress-broker.cjs. @@ -56,13 +56,13 @@ terminal = "tmux" # builder.apk.lock the builder's (erofs-utils). .github/workflows/vm-artifacts.yml # rebuilds it on a Linux runner and fails on any other hash. berth-vmm # compiles this in; berth-vmm run boots it by default. -image_sha256 = "4f4e67cb49a1b07e96412e802bd2c6e42cfabee95d7c126b8589b1048a79a538" -image_size = 108765184 +image_sha256 = "0c623b43a2c2852fd156d1ea6d4f00a8612143299ec7381cf2d1516607d0a9f6" +image_size = 108904448 # Optional layer example (rootfs/layers/example, build-layer.sh), built for the base above. layer_example_sha256 = "a79169aeed42b12ecb28cf40427439d5870056362ea8728036354137cd6d273d" layer_example_size = 475136 -layer_example_base = "4f4e67cb49a1b07e96412e802bd2c6e42cfabee95d7c126b8589b1048a79a538" +layer_example_base = "0c623b43a2c2852fd156d1ea6d4f00a8612143299ec7381cf2d1516607d0a9f6" # Optional layer browser (rootfs/layers/browser, build-layer.sh), built for the base above. -layer_browser_sha256 = "ed05e3d09c5de3a01184333174215c4f8a4fe9c1f2f227590290a68724b48641" -layer_browser_size = 511881216 -layer_browser_base = "4f4e67cb49a1b07e96412e802bd2c6e42cfabee95d7c126b8589b1048a79a538" +layer_browser_sha256 = "b02cec7e83efe1dcb39b78ebbef5bf30e8ebda082c7b87a4bd30e7375d976fb2" +layer_browser_size = 511885312 +layer_browser_base = "0c623b43a2c2852fd156d1ea6d4f00a8612143299ec7381cf2d1516607d0a9f6"