Skip to main content

k7 creates Kubernetes VolumeSnapshot objects in three situations:

KindCreated byDefault nameLifetime
pausePOST /api/v1/sandboxes/{name}/pause with snapshot<sandbox>-paused-<unix>Persistent — until you delete it.
forkPOST /api/v1/sandboxes/{name}/fork (no snapshot)<source>-fork-<unix>Auto-deleted inline once the clone PVC binds; the GC CronJob sweeps any leftovers older than 10 min.
namedPOST /api/v1/sandboxes/{name}/snapshot or fork with snapshot body fielduser-suppliedPersistent — until you delete it.

Each snapshot carries k7.io/kind and k7.io/source-sandbox annotations so list / GC don’t have to guess from the name.

List snapshots#

Endpoint: GET /api/v1/snapshots

namespacestring#
Namespace

Default: "default"

all_namespacesboolean#
List across all namespaces

Default: "false"

sandboxstring#
Filter to snapshots tied to a sandbox
kindstring#
pause, fork, or named

Inspect one snapshot#

Endpoint: GET /api/v1/snapshots/{name}

namestringrequired#
Snapshot name
namespacestring#
Namespace

Default: "default"

Returns the same shape as one element of the list endpoint, or 404 if not found.

Create a named snapshot#

Endpoint: POST /api/v1/sandboxes/{name}/snapshot

Snapshots a running sandbox’s root PVC without pausing it. The PVC name is derived server-side (<sandbox>-root-lh for kata-qemu-longhorn); the resulting snapshot is annotated k7.io/kind=named so the GC sweep leaves it alone.

namestringrequired#
Source sandbox name

Body:

  • 201 Created with Location: /api/v1/snapshots/{name}?namespace={namespace} on success.
  • 400 BadRequest when snapshot_name is missing, or the sandbox runs on a backend with no PVC to snapshot (kfd, k7d, k7d-fc).
  • 403 QuotaExceeded when the tenant’s snapshotStorage quota would be exceeded.
  • 404 NotFound when the sandbox does not exist (was 400 before 0.5.0).
  • 409 Conflict when the name already exists in the namespace.

The request returns once the root snapshot (and the Docker graph snapshot, with docker: true) is readyToUse, so a snapshot you can see is one you can restore or delete safely.

Restore a sandbox from a snapshot#

Endpoint: POST /api/v1/snapshots/{name}/restore

Boots a brand-new sandbox from a standalone VolumeSnapshot without needing the original sandbox’s Deployment to still exist. Useful for “thaw this paused snapshot from last week” flows where the source has been deleted in the meantime.

namestringrequired#
Snapshot name

Body:

  • new_sandbox_name (required) — name for the restored sandbox.
  • overrides (optional) — any combination of image, backend, root_disk_size, sidecar ("docker" is the deprecated alias of docker: true; restore does not accept docker / docker_disk yet), limits, entrypoint, cmd, before_script. Each override wins over the snapshot’s k7.io/source-* annotation; fields not supplied fall back to the annotation. image is the only field with no safe default — restore fails with a clear error if the snapshot lacks k7.io/source-image and no override is supplied.
  • keep_snapshot (default true) — when false, deletes the source snapshot once the new sandbox is Ready. Useful for “thaw and discard”.

Responses:

  • 201 Created with Location: /api/v1/sandboxes/{new_sandbox_name}?namespace={namespace} on success.
  • 400 BadRequest when new_sandbox_name is missing, the snapshot lacks k7.io/source-image and no override supplied, or the rehydrated backend isn’t kata-qemu-longhorn.
  • 404 NotFound when the snapshot doesn’t exist in the namespace.
  • 409 Conflict when new_sandbox_name already exists.

Restore is kata-qemu-longhorn-only (kata-firecracker-devmapper has no PVC to clone from). When the snapshot’s k7.io/source-backend annotation says kata-firecracker-devmapper, the API returns 400.

Delete a snapshot#

Endpoint: DELETE /api/v1/snapshots/{name}

namestringrequired#
Snapshot name
namespacestring#
Namespace

Default: "default"

Returns 200 OK on success, 404 when the snapshot is absent. Snapshot routes follow the caller’s tenant: a tenant key sees and deletes only snapshots in its tenant’s namespaces; gc with all_namespaces=true needs operator or admin.

Garbage-collect fork snapshots#

Endpoint: POST /api/v1/snapshots/gc

Sweeps kind=fork snapshots older than keep_fork_for. Never touches pause or named snapshots — anything the user named survives.

Body (all keys optional):

keep_fork_for accepts 10m / 2h / 45s or a plain integer (seconds).

Auto-GC mechanics#

k7 fork deletes its auto-named kind=fork snapshot inline as soon as the cloned PVC reaches Bound. A backstop CronJob (k7-snapshot-gc in kube-system) runs python -m k7.api.snapshot_gc every 10 minutes and cleans up anything the inline path missed — for example after a k7-api pod restart mid-fork. The CronJob runs cluster-wide and uses the same ServiceAccount as the API.