Skip to content

Drop epoch: serve snapshots & cloud images from a standard OCI registry (move /dl/ reassembly into vk) #25

Description

@CMGS

Goal

Remove the epoch dependency entirely and use any standard OCI-compatible registry (e.g. GCP Artifact Registry) for snapshots and cloud images.

Why this is tractable

epoch is already a standard OCI Distribution registry; snapshots and cloud images are plain OCI artifacts (custom artifactType application/vnd.cocoonstack.{snapshot,os-image}.v1+json). The OCI↔cocoon bridge (epoch/snapshot, epoch/cloudimg) is registry-agnostic Go that vk already imports behind Downloader/Uploader interfaces. The only epoch-server-specific runtime tie is the /dl/{repo}/{tag} reassembly endpoint — and vk already has the client-side reassembly (cloudimg.Stream / snapshot.Stream / EnsureCloudImageFromRaw).

So "drop epoch" ≈ "do the /dl/ reassembly in vk + point the registry client at a standard registry."

Core change — move /dl/ into vk

  • Today provider/cocoon/create.go ensureRunImage rewrites a cloud image to canonicalCloudImgURL = <base>/dl/{repo}/{tag} and hands that URL to cocoon's vm run. cocoon then HTTP-downloads the whole qcow2 to a temp file (images/cloudimg/pull.go: http.Getio.Copy, 20 GiB cap, 30 min timeout) and boots from local — it is not a streaming boot, so moving the reassembly client-side costs no boot latency.
  • Replace with: vk pulls the OCI cloud-image artifact from the standard registry, reassembles the qcow2 client-side via the existing cloudimg.Streamcocoon image import (this is today's EnsureCloudImageFromRaw / "Path A"), and boots the local image. No /dl/, no epoch server.

Tasks

  • Registry client → standard OCI. Make the Downloader/Uploader (today epoch's registryclient.Client) speak standard OCI: standard blob upload session (POST /v2/<name>/blobs/uploads/PUT ?digest=, not epoch's non-standard PUT /v2/<name>/blobs/<digest> shortcut) + standard WWW-Authenticate token exchange (not the static bearer). Recommended: back it with google/go-containerregistry (cocoon already uses it) — standard push/pull + keychain auth (AR / GHCR / Docker Hub) for free.
  • cloudimg boot → client-side. ensureRunImage: drop the /dl/ rewrite; always pre-import via EnsureCloudImageFromRaw and boot the local image.
  • Relocate the bridge packages. epoch/snapshot + epoch/cloudimg (the OCI↔cocoon converters vk imports) need a new home once epoch is removed — move into vk or a shared lib (e.g. cocoon-common). (Or keep epoch as a thin library-only module — decide.)
  • Snapshot path — already registry-agnostic; verify push/pull works against the standard registry once the client is standardized (snapshot never used /dl/).
  • Remove all epoch imports / config / endpoints from vk.

Caveats / decisions

  • Artifact Registry has no resumable upload — each blob is a single monolithic PUT; a multi-GB (~40 GiB) incompressible memory layer on a flaky link restarts from zero. Add whole-blob retry. (If cloud-image blobs go to GCS instead, GCS does support resumable + signed-URL download = an even closer /dl/ replacement.)
  • Never enable immutable tags:hibernate is re-pointed every cycle; rollback deletes by tag.
  • Registry and nodes must be regional + same-region for free egress.
  • Dropping epoch loses its dashboard / catalog / global cross-repo dedup / ref-counted GC — acceptable for this goal (AR provides its own GC + console).

Reference

Spec research: cocoon-specs/design/epoch-oci-registry-evaluation.md (epoch-is-already-OCI analysis, consumer contract, blockers) + the GCP option breakdown (AR for the snapshot OCI catalog + GCS for cloud-image boot URLs).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions