Xeonr Developer Docs

Archive Volume

POST
/containers.api.v1.VolumeService/ArchiveVolume

Copies a persistent volume's current contents into the workspace store as a snapshot and returns its id. Only persistent volumes can be archived. label defaults to "archive of <volume_id>". Returns Unimplemented when no workspace store is configured. Returns FailedPrecondition if the volume has never been mounted (its node is not known yet) or its node is unreachable, and Unimplemented when the volume file API is not configured.

Access: any role in the volume's namespace, or a platform admin.

Authorization

BearerAuth
AuthorizationBearer <token>

A namespace-scoped API key (cpk_…) for machines, or a Xeonr Auth OIDC token for humans. The key's namespace and role are pinned server-side.

In: header

Header Parameters

Connect-Protocol-Version?number

Define the version of the Connect protocol

Connect-Timeout-Ms?number

Define the timeout, in ms

Request Body

application/json

volumeId?string
Length1 <= length <= 64
label?string

Label for the resulting snapshot.

Lengthlength <= 255
[key: string]?never

Response Body

application/json

application/json

curl -X POST "https://containers.xeonr.io/containers.api.v1.VolumeService/ArchiveVolume" \  -H "Connect-Protocol-Version: 1" \  -H "Connect-Timeout-Ms: 1000" \  -H "Content-Type: application/json" \  -d '{}'
{
  "snapshotId": "string",
  "archivedAtUnix": "string"
}
{
  "code": "not_found",
  "message": "string",
  "details": [
    {
      "type": "string",
      "value": "string",
      "debug": {}
    }
  ]
}

containers.api.v1.VolumeService

VolumeService manages platform-provisioned volumes: sparse ext4 disk images on node disk, attached by the platform's own CSI driver and mounted into a primitive via WorkspaceMount.volume (common.proto). How this differs from WorkspaceService, which is the question everyone asks: WorkspaceService is a CONTENT store. It knows files, dedupes blobs across every workspace, forks a snapshot for free because a fork is a metadata copy, and works identically whether or not anything is running. What it is bad at is being a filesystem: it has to be copied into the pod, one RPC per file, so start cost scales with file count and the big directories have to be excluded to keep it bearable. VolumeService is STORAGE. It knows bytes, not files. Nothing is copied at start, nothing is synced back, there is no ignore set, and size is a hard cap the filesystem enforces. What it is bad at is being content: a volume cannot be forked or diffed, it is opaque to anything that has not mounted it, and reaching it needs the node holding it to be up. They are complementary rather than competing. Content arrives via seed_snapshot_id and leaves via Archive; in between it is a filesystem. File operations are below. They route to the node holding the volume, which is the only thing that can open the image, and work whether or not a workload is running on it.

Create Volume POST

Creates a volume record in PENDING state; the image and its node are chosen when the first workload mounting it is scheduled. `tier` is required. `size_mb` must be 64 MiB-512 GiB. A cache volume requires a `cache_key` (AlreadyExists if the key is taken in the namespace) and cannot be seeded; a scratch volume takes neither a cache key nor a seed; `seed_snapshot_id` is for persistent volumes. Workload-scoped agent keys are refused. **Access:** operator or admin role in the namespace (via Xeonr team role or a namespace API key), or a platform admin.