Commit Graph
5 Commits
Author SHA1 Message Date
Ron Lev 0741459b15 Mount an OCI image read-only into an actor (#923)
Fixes #783
Adds an `image` source to `ActorTemplate`'s `VolumeSource`: a container
can mount the contents of an OCI image it does not run. This is how
tooling gets into images built by third parties without rebuilding them.

```yaml
spec:
  containers:
  - name: sandbox
    image: docker.io/example/benchmark@sha256:...
    command: ["/ate/agent"]
    volumeMounts:
    - name: agent
      mountPath: /ate
  volumes:
  - name: agent
    image:
      reference: registry.example.com/agent@sha256:...
```
## How it works

atelet pulls the image through the existing layer cache and records the
volume's layers in the bundle's overlay spec, next to the rootfs layers.
ateom composes the volume inside the bundle — the cached layers with no
writable layer on top, so the mount is read-only — and the container
binds it at the declared path. The volume is composed per container:
containers of one actor may mount the same volume, and each gets its own
mount point inside its own bundle, all backed by the same shared layers.
On resume the volume is re-composed the same way.

References must be digest-pinned, the same rule as container images: a
snapshot is only valid against the exact bytes it was taken with.

On micro-VMs the volume rides the same read-only virtio-fs share as the
container rootfs: ateom stages each composed volume beside the rootfs on
the host, and the guest binds it into the container at the declared
path.
2026-08-20 10:22:56 -07:00
Benjamin Elder 51f8d0d37a microvm: mount the rootfs overlays volatile (#1053) 2026-08-18 19:04:31 -07:00
dberkov e648e74af3 imagecache: repair implicit parent-dir metadata in the composed rootfs
Layer tars omit parents that exist in lower layers; unpack fabricates them
(root:root 0755) and overlayfs takes merged dir attrs from the top-most
layer containing the dir — so a fabricated parent shadowed real lower-layer
metadata (/tmp's 1777, /root's 0700). Record implicit dirs in the layer
metadata at unpack, and at compose repair the merged view from the top-most
non-implicit provider in the image's chain; the chown/chmod copy-ups land
in the bundle's private upper, never in the shared pool. Residual gaps
(mtimes, xattrs, implicit-everywhere dirs) documented in the README.

Addresses PR #467 review feedback (phantom parent dirs shadowing lower-
layer directory metadata).
2026-07-22 21:15:39 -07:00
dberkov 7533f52a1f imagecache: mount rootfs overlays via the new mount API to lift the layer cap
mount(2) copies its option string through a single page, which caps
digest-derived lowerdir chains (~114 bytes per layer path) at roughly 34
layers and fails with a bare EINVAL beyond that. Appending lowerdirs one
fsconfig(2) call at a time removes the aggregate limit structurally, and
failed mounts now carry the kernel's fs-context error log instead of an
opaque errno. Adds a 64-layer regression test that asserts the joined
paths exceed one page before mounting.

Minimum supported kernel: Linux 6.5 (overlayfs "lowerdir+"). All current
GKE channels meet it: Stable runs COS 121 LTS (kernel 6.6), Regular and
Rapid run COS 125/129 (kernel 6.12).
2026-07-22 21:15:39 -07:00
dberkov 610e3916ad Add node-local OCI image layer cache (imagecache), replacing memorypullcache
Content-addressed pool of unpacked image layers, shared by every actor on
the node; actor rootfs becomes an overlayfs mount (cached layers as read-
only lowers, bundle-local upper) instead of a full re-untar per run.
atelet (no capabilities) pulls and unpacks; the privileged ateoms finalize
whiteouts and mount. Tag refs resolve via one HEAD and become cacheable;
pull memory is O(stream buffers); the cache survives restarts.

Phase 1 of #463. Fixes #437, #166, #228.

Validated: kind + GKE counter demos (gvisor and microvm), suspend/resume
(oci_unpack ~3ms vs ~15-20s), 411 SWE-bench-scale images pulled and
unpacked with 0 failures, root-gated unit tests for the privileged paths.
Known gaps: no GC yet (Phase 2, see internal/imagecache/README.md);
upgrade ordering — deploy new ateoms before/with the new atelet.
2026-07-22 21:15:39 -07:00