Repository navigation
snapshots: a snapshot request on the pod pushes a live snapshot of the running VM - #129
Merged
Merged
Conversation
tonicmuroq
force-pushed
the
tonic/snapshot-request
branch
5 times, most recently
from
October 12, 2026 01:52
076e85e to
b1024fb
Compare
…e running VM vm.cocoonstack.io/snapshot names a registry-relative repo[:tag]. While the VM runs and no hibernate is asked for, UpdatePod saves it as snap-<vm> (never the VM-named warm-wake cache), pushes it there, drops the local copy, and answers in vm.cocoonstack.io/snapshot-status with the ref echoed and pushed or failed. The save pauses the VM only for its duration and keeps the NICs, so the result is a clone source. The pending ref is read before the pod is tracked, like the hibernate intent. PushSnapshot now exports its vmName argument as the local snapshot (PushOptions.LocalName) instead of the repo; the hibernate and latest pushes pass the same name for both, so they are unchanged. The delete-time latest push and the requested push share saveAndPush. cocoon-common is pinned to cocoonstack/cocoon-common#38 until it merges.
tonicmuroq
force-pushed
the
tonic/snapshot-request
branch
from
October 12, 2026 02:03
b1024fb to
40ff313
Compare
A request on a Creating pod (fresh clone, or a wake from hibernate that is still restoring) saved the guest mid post-clone setup. It now waits for Ready through the op retry, which reads the tracked pod; vk's own Ready patch updates that copy, so it re-delivers no UpdatePod. The update path and the restart resume share one Creating predicate. A macOS pod answers failed instead of never answering. A failure message is truncated like other failures and logged; a superseded status patch is not retried. Re-pins cocoon-common to the branch head 9b3ba3a, where ReadSnapshotStatus returns the plain status.
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.
What
UpdatePodreads a pendingvm.cocoonstack.io/snapshotref (a registry-relativerepo[:tag]with no matchingsnapshot-status) before the pod is tracked, like the hibernate intent.applyUpdatecallssnapshotbefore the hibernate/wake switch when a VM is tracked, no hibernate is asked for, and a pusher is configured. A pod still Creating (fresh clone, or a wake that is still restoring) returns an error so the op retry serves the request once the VM is Ready; vk's own Ready patch updates the tracked copy and re-delivers no UpdatePod. A macOS pod answersfailed.snapshotsaves the VM assnap-<vm>, pushes it to the ref, removes the local copy, and patchesvm.cocoonstack.io/snapshot-statuswith{ref, state: pushed|failed, message}.owedOpForreturnsresumeOpSnapshot), like an interrupted hibernate; UpdatePod is one-shot, so nothing else re-delivers it.context.WithoutCancel: vk-cocoon's shutdown cancels its context, andexec.CommandContextwould then SIGKILL the cocoon CLI, possibly between CH's pause and resume, leaving a running VM paused. WithKillMode=processthe detached CLI outlives vk-cocoon and resumes the VM (cocoon writes no log between pause and resume, and its resume is itself detached). It may still die on its first stderr write afterwards (SIGPIPE on the closedCombinedOutputpipe), leaving a partial snapshot; the resumed request'sSnapshotSavealready removes a name holder by ID and retries.<vm>, so the request cannot overwrite the node-local snapshot that same-node wake uses.latestpush and the requested push sharesaveAndPush; the delete path behaves as before.Pusher.PushSnapshotexports itsvmNameargument as the local snapshot (PushOptions.LocalName) rather than the repo. Until now the two were always the same name (hibernate passes it for both, the delete push leaves repo empty), so those paths are unchanged; the requested push is the first to differ.Why
The developer API needs "snapshot my machine" and "create / reset a machine from that snapshot". vk-cocoon only pushes on hibernate (CH+Windows drops the NIC first, so that snapshot cannot be a clone source) and on delete (the VM is gone afterwards).
cocoon snapshot savepauses only for the save and resumes, and keeps the NICs, which clone hot-swaps for fresh ones, so a requested save is a clone source like the base snapshots. The request sits on the pod rather than the CocoonSet because it touches one VM and creates or deletes no pods.Dependency
Needs cocoonstack/cocoon-common#38, merged as ba211c8;
go.modpinsv0.3.8-0.20261012121517-ba211c820075.Evidence
provider/cocoon/snapshot_test.go: a running VM savessnap-<vm>, exportssnap-<vm>(not the repo), pushes to the requestedrepo:tag, removes the local copy and patchespushed; an answered ref does nothing; a save failure patchesfailedand pushes nothing; a pending request on a Ready pod is resumed bydispatchOwedWorkand answered (fails without theowedOpForbranch).make fmt-checkclean,go test -race ./...green.make lintcould not run locally (golangci-lint cannot read Go 1.27.2 export data); leaving it to CI.Known gaps
snap-<vm>stays on disk: the reclaimer skips names without thevk-prefix and pod delete does not remove it.