Skip to content

cocoon: clone workloads from snapshot:// images and expose snapshot ops - #760

Open
CMGS wants to merge 3 commits into
masterfrom
feat/cocoon-clone-snapshot
Open

CMGS wants to merge 3 commits into
masterfrom
feat/cocoon-clone-snapshot

Conversation

@CMGS

@CMGS CMGS commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

Lets the cocoon engine start a workload from a cocoon snapshot instead of an OCI image, and exposes snapshot operations through RawEngine.

What changes

  • Clone via the image field. An image ref of the form snapshot://<name> makes VirtualizationCreate run cocoon vm clone --output json --name <id> [--network ...] [--data-disk ...] <name> instead of create/run. Any other ref keeps the existing path. Windows clones are refused.
  • Image resolution. A snapshot:// ref is resolved with cocoon snapshot inspect only; the ref is its own digest, so no pull happens.
  • Snapshot ops through RawEngine. snapshot.save, snapshot.list, snapshot.inspect and snapshot.remove, with names validated against ^[a-zA-Z0-9][a-zA-Z0-9._:/-]{0,62}$.
  • Post-clone reseed. A clone resumes from memory with the source's guest config: the old static NIC files, hostname and /etc/hosts. After the record is written, the engine runs a reseed through cocoon vm exec. It rewrites the systemd-networkd files by MAC from the clone's network_configs, sets the hostname, maps it in /etc/hosts, and restarts networkd. The reseed retries for up to 30 s while the guest agent comes up. If it fails, the VM is discarded rather than handed out with a stale network.
  • Docs for the scheme and the reseed, plus tests: the clone argv, the three-command clone sequence, the discard-on-reseed-failure path, and the RawEngine ops.

Validation

  • make lint reports 0 issues; asl is clean on darwin and linux; go test ./engine/cocoon/... passes.
  • End-to-end on a bridge-CNI cocoon host with eru-core built from this branch:
    • golden and user snapshots were built with snapshot.save;
    • workloads were deployed from snapshot://... images with a published IP;
    • the clones reached the internet, had working apt, and sudo in the guest no longer warned about the hostname.
  • Clone to SSH-ready took 2–5 s.

Open points

  • RawEngine is routed by workload ID and locks that workload, so node-level ops (snapshot.list/inspect/remove) currently have to target some workload on the node.
  • The reseed assumes guests that use systemd-networkd static configs, which is what the cocoon cloud images ship.

…gine

A deploy whose image is snapshot://<name> runs `vm clone --output json
--name <id> [--network] [--data-disk] <name>` instead of `vm create`; the
snapshot fixes cpu, memory, storage and guest os, the meta record is written
from the clone's JSON as after a create, and a failed record removes the VM.
A windows deploy of a snapshot is refused. The start path is unchanged:
cocoon's PrepareStart returns without launching when the VMM already runs, so
`vm start` on the running clone succeeds and the record refresh still runs.

ImagePull only looks the snapshot up, and a present snapshot is its own local
and remote digest, so such a deploy never reaches a registry and a missing
snapshot fails the pull.

RawEngine serves snapshot.save (save then inspect, one round trip),
snapshot.list (the prose empty banner reads as []), snapshot.inspect and
snapshot.remove; names are checked against cocoon's snapshot-name grammar
before any round trip, and any other op stays ErrEngineNotImplemented.
A clone resumes with the source VM's systemd-networkd files keyed on the old MAC and its hostname, so the new NIC comes up without an address. After the record the engine rewrites them through vm exec from the clone's own network_configs (the same content cocoon prints as post-clone hints, which --output json omits), retrying until cocoon-agent answers; a clone that will not take its address is removed.
A clone keeps the source's /etc/hosts, so sudo in the guest warns that it cannot resolve the new hostname.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant