Repository navigation
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
dbb7290 to
9503c93
Compare
|
Thanks for moving this forward! I noticed the Golden Snapshot limitation mentioned in this PR, particularly the mount-option mismatch when restoring an actor with an external NFS volume. We're building a multi-tenant agent execution platform where each session needs actor-specific external mounts (read-only skills/knowledgebase files and writable persistent memory), with a target of sub-second sandbox startup using microVMs. We'd be interested in contributing Golden Snapshot compatibility for shared volumes, including the necessary runtime changes and end-to-end benchmarks. I see this is already tracked as We'd initially focus on Cloud Hypervisor/virtio-fs, while ensuring the design doesn't prevent subsequent gVisor support. We're also interested in contributing per-actor Would you prefer these as two separate follow-up PRs? |
| @@ -1341,6 +1535,25 @@ message Volume { | |||
| // +k8s:optional | |||
| // +k8s:unionMember | |||
| ImageVolumeSource image = 6; | |||
|
|
|||
| reserved 3; | |||
There was a problem hiding this comment.
No need to reserve ids or field names for now.
9896525 to
21adc9a
Compare
The ActorTemplate volume union now carries one CSI member, Volume.external (ExternalVolumeSource), whose template member replaces external_volume_template. The field name matches its siblings and the message follows the *VolumeSource convention; a member for shared volumes follows after GA. The ExternalVolumes preview gate moves with it. atelet's resolved handle ExternalVolumeSource becomes ExternalVolume, matching its sibling volume messages and no longer sharing a name with the new ateapi message. Templates that still carry external_volume_template must be recreated. Fixes agent-substrate#2407, agent-substrate#2436. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
An EmptyDirVolume is an empty host directory at the same path an external volume would be published to, mounted into the sandbox the same way. It lets a golden actor warm up against a placeholder for an external volume it must not mount, so the snapshot's mount table matches the real actor's on both gVisor and microVM. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A SharedVolume is an atespace-scoped CSI volume whose lifetime is independent of any actor. It is provisioned from a StorageClass or registers a volume that already exists, carries an immutable access mode, and is removed either manually or when the last actor referencing it is deleted, according to its delete trigger. Deleting the record also deletes the storage. This adds the resource, its Postgres table and store methods, the authorization rules and OpenFGA type, the create/get/list/update/delete RPCs, and kubectl-ate commands. Nothing references a volume yet; actor references arrive separately. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A template volume whose external source names a shared_volume mounts a SharedVolume instead of provisioning one per actor. The reference names the volume, or leaves the name empty so each actor binds it at creation through Actor.shared_volume_bindings. Every actor referencing a volume is recorded in the volume's refs, with active set while the actor is resumed. Resume refuses a READ_WRITE_ONCE volume another actor holds active, pause and suspend mark the reference inactive, crash leaves it as is, and delete removes it and deletes a LAST_ACTOR volume that no actor references any more. Golden actors never reference a volume; they warm up against an empty directory at the same mount path. Depends on the empty_dir volume source and the SharedVolume resource. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The golden actor warms up against a local empty directory in place of a shared volume, but runsc derives the disable_file_handle_sharing mount option from the bind source's filesystem and refuses a restore whose mount options differ from the checkpoint's. On NFS the first resume of every such actor therefore failed with "Mounts" does not match across checkpoint restore. Actors created from a template that references a SharedVolume no longer seed from the golden tag: the first resume boots from the image and later resumes restore the actor's own snapshot, which was taken over the real volume. An explicit source tag is refused for these templates. Golden restores for shared volumes remain follow-up work, tracked by TODO(shared-volumes). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
21adc9a to
a987b68
Compare
Part of #1637 (sequential hand-off is the first milestone; concurrent READ_WRITE_MANY holders follow). Post-GA follow-up.
Depends on #2653, which carries the breaking change (
Volume.externalwith theExternalVolumeSourceunion, and atelet's handle renamed toExternalVolume). This branch includes that commit until #2653 merges; review commits 2 to 5 here. The per-actor record onActorStatus.external_volumeskeeps its name,ExternalVolume.What this adds
A
SharedVolumeis an atespace-scoped CSI volume whose lifetime is independent of any actor, so several actors can mount the same storage in turn: a producer writes, suspends, and a consumer resumes and reads. Design: go/substrate-shared-volumes. User docs:docs/csi-volumes.md, section "Shared Volumes".Create/Get/List/Update/DeleteSharedVolume(annotated with(resource)and(method).resource, list paging throughListOptions), a Postgres table (migration000004_shared_volumes.sql), store contract tests, authorization rules and an OpenFGAshared_volumetype (atespace editors create, update and delete; viewers get and list), andkubectl ate {create,get,update,delete} sharedvolume.volume_id,volume_type,volume_context).READ_WRITE_ONCEis accepted today, so at most one resumed actor holds the volume; a resume that would take a held volume fails withFailedPreconditionnaming the holder.MANUAL(default when registering) removes the volume only on an explicit delete;LAST_ACTOR(default when provisioning) removes it when the last actor referencing it is deleted. Deleting the record always deletes the storage. A referenced volume cannot be deleted.status.refslists every actor referencing the volume withactiveset while the actor is resumed. Create adds an inactive ref, resume activates it, pause and suspend deactivate it, crash leaves it as is, delete removes it.Volume.external.sharedVolumeeither names the volume or leaves the name empty so each actor binds it at creation throughActor.shared_volume_bindings(--volume <slot>=<volume>). Bindings are validated at create and immutable afterwards. The per-actorExternalVolumerecord carriesshared_volume_namewhen the volume is borrowed.empty_dirvolume source). Actors created from such a template cold-boot on their first resume and restore their own snapshot afterwards, because runsc derives thedisable_file_handle_sharingmount option from the bind source's filesystem and refuses to restore a golden checkpoint taken over a local directory onto an NFS mount. Details and candidate fixes are in the docs; tracked byTODO(shared-volumes).Commits
api: nest the external volume template under Volume.externalis Volume templates nest the external volume template under external.template #2653.atelet: add the empty_dir volume sourceis the golden actor's placeholder mount.ateapi: add the SharedVolume resourceadds the resource, store, RPCs and CLI. Nothing references a volume yet.ateapi: let actors reference SharedVolumesaddsExternalVolumeSource.shared_volumeas the union's second member (inside the existingExternalVolumespreview gate), refs, bindings, the RWO holder check, and the e2e hand-off test.ateapi: cold-boot actors whose template references a SharedVolumeis the first-resume behaviour described above.Commits 2 to 5 are additive: no existing field, message or RPC changes shape.
Testing
hack/verify/gofmt.sh,hack/verify/boilerplate.shand the apitool checks pass.TestSharedVolumeHandoffandTestSharedVolumeMissingininternal/e2e/suites/combinedvolumes.csi-nfs-scandcsi-hostpath-sc(under the previous names): provisioning and registration, create-time rejections, named and per-actor bindings, the holder check, ref tracking across resume, pause, suspend and crash, delete guards, both delete triggers, and golden actors staying out of refs.Known follow-ups
READ_WRITE_MANYclaims, a dedicated refs table, and safe unstaging (Milestone 2).🤖 Generated with Claude Code