Repository navigation
Conversation
The control-plane volume plugin can now seed a new volume from an existing CSI snapshot and look a snapshot up by its handle. CreateVolume takes a CreateVolumeRequest and returns a CreateVolumeResponse. A request's SourceSnapshotID becomes the CSI CreateVolume volume_content_source. The response's ContentSourceSnapshotID is the snapshot the driver's response reports as the volume's content source, not the one requested: a driver that ignores the content source answers with an empty volume and success, and only the response tells a restore from that silent data loss. GetSnapshot maps to ListSnapshots filtered to one handle, the CSI spec having no single-snapshot read. A handle the driver does not list is not found; a driver that does not implement ListSnapshots is an error with code Unimplemented, since it cannot tell either way. Signed-off-by: Timo Derstappen <teemow@gmail.com>
A session that starts in a prepared workspace needs its own read-write copy of a snapshot taken outside the actor, chosen when the actor is created. An ActorTemplate's external volume was created empty for every actor of the template. ExternalVolumeTemplate.seeded makes a template volume optional and seeded: an actor gets it only when CreateActor names a seed for it in Actor.volume_seeds (volume, CSI driver, snapshot handle), and the volume is then created from that snapshot. CreateActor refuses a seed for a volume that is not seeded, a driver that is not the volume's StorageClass provisioner or is not registered, and a snapshot the driver does not list as ready. A volume the driver does not report as restored from the seed is deleted and fails the resume, so an actor is never handed an empty volume in place of its seed. An actor created without a seed has neither the volume nor its mounts, and its workload is that of the template without the volume. A seeded actor boots from its image rather than restoring the template's golden snapshot, which was built without the seeded volume's mount. ate-setup's hostpath CSI setup installs the volume snapshot CRDs and the snapshot-controller from external-snapshotter v8.6.0. pr-workflow sets up both CSI drivers and runs the new seededvolumes suite, which takes a VolumeSnapshot of a filled PVC and seeds actors from its handle. Signed-off-by: Timo Derstappen <teemow@gmail.com>
This was referenced Oct 9, 2026
DeepEqual handed a slice of proto messages to reflect.DeepEqual, which compares each message's internal state as well as its fields. The RPC logger's marshal fills the size cache of a request's messages, so a repeated message field and its clone compared unequal, and declarative validation's unchanged-value shortcut then ran the field's update checks: an immutable repeated field failed every create, because the create validates the stored object as an update of the request. A slice of messages is now compared element by element with proto.Equal, a nil and an empty one being the same field value. Signed-off-by: Timo Derstappen <teemow@gmail.com>
Signed-off-by: Timo Derstappen <teemow@gmail.com>
Signed-off-by: Timo Derstappen <teemow@gmail.com>
Later subtests use the actor the first one started, so its deletion is registered on the suite's test rather than the subtest's. Signed-off-by: Timo Derstappen <teemow@gmail.com>
A seeded volume's content differs per actor, so one template capacity cannot fit them all. VolumeSeed.capacity sizes that actor's volume and falls back to the template's when empty; CreateActor refuses a capacity below the size the driver reports for the snapshot. Signed-off-by: Timo Derstappen <teemow@gmail.com>
teemow
marked this pull request as draft
October 9, 2026 14:32
This was referenced Oct 9, 2026
Member
Author
|
Closed as superseded: the snapshot-seeded per-actor volume this draft implemented was replaced by the existing-volume-at-a-sub-path design, which landed in #234 (released as v1.7.0-rc.1). Written by an agent. |
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.
Problem
A session that starts in a prepared workspace needs its own read-write volume whose content comes from a snapshot taken outside the actor, chosen when the actor is created. An ActorTemplate's external volume was created empty for every actor of the template, and an
Actorcarried no volume of its own.Proposed solution
ExternalVolumeTemplate.seeded(field 10001) makes a template's external volume optional and seeded per actor.Actor.volume_seeds(field 10001, immutable):VolumeSeed= volume name, CSI driver, snapshot handle (thestatus.snapshotHandleof aVolumeSnapshotContent), and an optionalcapacitythat sizes this actor's volume instead of the template's (the caller computes it; substrate bakes in no default).CreateActorrefuses, with the reason, a seed whose volume is not a seeded external volume of the template, whose driver is not the volume's StorageClass provisioner or has noCSIDriverConfig, or whose snapshot the driver does not list as ready (CSIListSnapshots), and a capacity (the seed's or the template's) below the snapshot's reported size.CreateVolumewith the snapshot asvolume_content_source. A response that does not report that source deletes the volume and fails the resume, so a driver that ignores content sources never hands an actor an empty volume.source_tagtogether with seeds stays refused, as tag cloning of templates with external volumes already is: a tag does not record which seeded mounts its guest state was captured with (upstream's volume-snapshot work, Add snapshotting support for external volumes agent-substrate/substrate#1951).CreateVolumeRequest/CreateVolumeResponseshape withSourceSnapshotID/ContentSourceSnapshotIDfrom Add volume snapshot support to volume plugins agent-substrate/substrate#1849, and gainsGetSnapshot. Unlike Add volume snapshot support to volume plugins agent-substrate/substrate#1849,ContentSourceSnapshotIDis the source the driver's response reports, not the one requested, so the data-loss check can fire. This seed shape, with that difference, is proposed upstream in Add snapshotting support for external volumes agent-substrate/substrate#1951 (Add snapshotting support for external volumes agent-substrate/substrate#1951 (comment)).ate-setup setup csi hostpathinstalls the volume snapshot CRDs and snapshot-controller (external-snapshotter v8.6.0, vendored underhack/third_party/external-snapshotter). pr-workflow sets up both CSI drivers and runs the newseededvolumessuite withE2E_CSI_HOSTPATH=1, where a missing driver fails instead of skipping.resources.DeepEqual, the unchanged-value check of the generated validation, compares a repeated message field withproto.Equal. It usedreflect.DeepEqual, which compares the size cache a marshal fills, so the immutablevolume_seedsfailed everyCreateActorwith "field is immutable" (found by this PR's e2e; a functional test covers it now). Upstream has the same code.FORK.mdrow naming the upstream series it follows (Add volume snapshot support to volume plugins agent-substrate/substrate#1849, Add snapshotting support for external volumes agent-substrate/substrate#1951, Add a "preview gate" concept, use it for external volumes agent-substrate/substrate#1994) and its exit;docs/csi-volumes.mdsection.Acceptance criteria
TestSeededVolumes/StartsWithSnapshotFilesReadWrite)ActorsFromOneHandleAreIndependent)SeedCapacityReplacesTheTemplates: the driver's recorded volume size; unitTestCreateActorVolumes_Seeded,TestValidateVolumeSeeds,TestValidateCreateActorRequest). Provisioned size proven on the kind hostpath driver; filesystem size needs a block-backed CSI driver, followed up in test: prove a seeded volume's filesystem size on a block-backed CSI driver #232.PauseResumeKeepsContent,DeleteDeletesTheVolume: the driver's data directory no longer holds the volume)TestInitialActorVolumes_Seeded,TestWorkloadSpecFromActorTemplateSeededVolume,TestPlugin_CreateVolume; e2eUnseededActorHasNoVolumeOrMount)TestValidateVolumeSeeds; e2eRefusesBadSeedsAtCreate)FORK.mdrow naming the upstream series it follows; released as a line release candidateCloses #227. Replaces #229 and #230 (same change, split into an upstream-ready plugin commit and the seed API commit, DCO-signed).
This pull request was written by an agent.