Skip to main content
Every VM on this platform starts as a copy of a golden image: a PVC holding a prepared operating system, cloned into a new disk when a VM is created. The library is where those goldens are imported, and the choices made there decide what the VMs cloned from them can do — including things that cannot be changed afterwards. The library is per supervisor. Each golden is a DataVolume in the image-library namespace of the supervisor it was imported on, and the Image Library entry in a supervisor’s sidebar shows that supervisor’s goldens only. GET /api/images?supervisor=<name> lists one supervisor. Without supervisor it lists every supervisor that Celum can reach.

Four fields, and two of them are one-way doors

A VM can only clone from a golden that lives on the class the VM is being built on. Not “more slowly” — at all. CDI clones by snapshot within one class, and a snapshot cannot be restored into another storage pool, so the claim sits Pending while the real error lands on a temporary PVC in the image namespace that nobody is watching.Left empty, an image goes to the cluster default, which then quietly decides which classes will ever be able to serve it. On a supervisor with one class that is the right behaviour and there is nothing to think about. On one with two — local disks and an array, say — import the golden onto each class you intend to build VMs on. The Create VM picker only offers images from the class you selected, and says how many exist elsewhere.The escape hatch, if you would rather keep one copy: set cloneStrategy: copy on the target class’s StorageProfile and CDI copies across classes instead of snapshotting. It works — measured, 3.5 GiB in 36 s — but it is a host-assisted byte copy, so a 60 GiB golden is minutes rather than seconds, on every VM created.
The access mode is chosen at import and cannot be changed on an existing image. A VM built on a ReadWriteOnce image can never live-migrate and can never hold an identity address — the create call refuses the combination outright. Converting means re-importing the image; converting a VM that already exists means rebuilding it.Default to ReadWriteMany unless you have a reason not to. That is what the platform defaults to.
The import form asks for the class; it did not always. Every golden used to go to the cluster default, which is why an estate predating the field may have its whole library on one class. There is no move — re-import onto the class you need it to serve.The message to search for when this bites, from the driver rather than from the claim: Not enough nodes fulfilling the auto-place criteria: has a deployed storage pool named [nvme].

Why the access mode also decides clone speed

This is the part nobody expects, and it is a twenty-fold difference. The access mode determines the PVC’s volume mode, and CDI will only use a fast clone when the source and the target agree on it. With both in Block mode the storage driver clones natively; across a mismatch CDI falls back to a host-assisted byte copy through two pods. Same cluster, same storage, same chart versions. And the mismatch is not a misconfiguration you can tune away: both efficient strategies refuse cross-mode pairs outright, whatever the storage profile says.
Block is used only where the StorageClass supports it. A ReadWriteMany image on file-based storage — NFS, SMB, CephFS — stays in Filesystem mode, because a Block PVC there would never bind. So on file storage you get the migration capability without the clone speedup, which is the correct trade rather than a failure.
Importing straight into Block mode needs the container runtime to hand the block device to a non-root process. Talos ships that setting, which is why this works here at all; a supervisor without it would fail an import with a permission error on the device rather than anything mentioning images.

Importing

Image Library → Import OS image. Pick the library and the image type as cards. Then set Mode to url and give a URL, or start from Browse catalog or Browse S3 bucket. Last, set the access mode and the storage class.
An import is asynchronous and the image is unusable until its status reads ready — creating a VM against anything else is refused by name.

Importing from an S3 bucket

You can keep goldens in your own object storage and import them from there instead of from the internet. Set up the bucket connections once, on Registries → Image buckets. See Image buckets.
Image Library → Browse S3 bucket. The browser lists the objects in the bucket that this supervisor imports from, with a name, version, type and size for each object. If more than one bucket is available, choose one in Bucket. Filter objects… narrows the list by key. Import on a row opens Import Image with Mode set to s3 and that object already selected. You can also start from Import OS image, set Mode to s3 and pick a Bucket object there.
  • Which bucket. If you choose no bucket, the import uses the supervisor’s own default connection. If there is none, it uses a connection declared for the supervisor’s site, then the supervisor’s only connection. On a Celum appliance, the appliance’s own image store comes last. A bucket that another supervisor lends through its site is shown as — from <supervisor> (site <site>).
  • What is listed. The browser lists disk and ISO files only: .img, .qcow2, .raw, .iso, .vmdk, .vhd and .vhdx, also when compressed with .zst, .gz, .xz or .bz2. It hides checksums and other files. It lists objects under every prefix.
  • Name and version. The browser takes these from object metadata, if the uploader set it: x-amz-meta-displayname, x-amz-meta-os, x-amz-meta-version and x-amz-meta-imagetype. If not, it guesses them from the object key. Check them in the form before you import.
  • Library. Import from the browser always selects the Virtual machine library. For a Talos node image, change it to Kubernetes.
  • The download. The bucket credentials stay in Celum. Celum gives the supervisor’s CDI importer a presigned URL that is valid for 12 hours, and the importer downloads the object directly from the bucket. Your supervisor’s nodes must be able to reach the bucket endpoint, not only Celum. A re-import signs a new URL for the same object.
The size rule below applies to bucket objects too: set the size by hand for a compressed object.

Two things about an import that produce no error at all

A golden is the one volume that never gets a consumer. Nothing mounts it; it exists to be cloned. Under a StorageClass with volumeBindingMode: WaitForFirstConsumer the PVC therefore waits for a pod nobody will ever create, the importer is never scheduled, and the DataVolume sits at PendingPopulation indefinitely. The only trace is a PVC event reading “waiting for first consumer to be created before binding” — which is not a failure message, because nothing failed. The import simply never started. The platform stamps cdi.kubevirt.io/storage.bind.immediate.requested on every image import to prevent it. This was invisible for as long as the estate ran only Ceph, whose classes bind Immediate; the first supervisor on other storage hung its entire library. Auto cannot size a compressed source. Leaving the size empty asks the platform to match the source, and against a .img.gz or similar it cannot: gzip’s ISIZE trailer is modulo 2³², so it wraps at 4 GiB and reports a plausible wrong number for exactly the images large enough to matter. The fallback is 10Gi, and a 60 GiB Windows golden then downloads in full before failing the conversion with “virtual image size … is larger than the reported available storage”. The form says so rather than guessing — set the size by hand for any compressed source.

Three things you can do to a golden afterwards

  • Re-import (POST /api/images/{id}/reimport, or Retry import on a failed row) deletes the golden’s DataVolume and downloads the same source again, with the same access mode and storage class. It takes no options, so it cannot change the access mode. To change it, delete the image and import it again with the other mode.
  • Bake the guest agent (POST /api/images/{id}/bake-guest-agent) installs qemu-guest-agent into the golden itself, so clones are agent-ready without any network access at first boot. Useful on an estate where a new VM cannot reach a package mirror. It is asynchronous and the image stays usable throughout — the rewrite happens at the end.
  • Upload to a bucket (POST /api/images/{id}/upload-to-bucket) puts it in object storage, which is where ISOs and large images are kept.

The default Talos image

Set as default in an image row’s menu marks that golden as the default for its library. Unset default removes the mark. The DEFAULT column shows which images have it. The mark matters in the Kubernetes library. The Simple setup of the cluster form does not ask for an image. On a KubeVirt-based ClusterClass it uses the ready Kubernetes-library image that is marked default. If no image is marked, it uses the ready image with the newest Talos release. The image it picks also sets the cluster’s Talos version and Kubernetes version. In Advanced you choose the image yourself, and the picker labels the default image default. In the VM library the mark is only a label. The VM form does not preselect it. On a talos-vsphere ClusterClass the mark does not apply. There, Simple setup uses a vCenter template instead (see vCenter templates).
Nothing keeps the default unique. When you set one image as the default, Celum does not unset the others. If two images are marked, Simple setup takes whichever comes first in the list. Unset the old default when you set a new one.
Image Library → the image’s row menu → Set as default or Unset default.

vCenter templates

Use the vSphere tab on supervisors that build Talos clusters on vSphere (talos-vsphere ClusterClasses). These clusters clone their nodes from a VM template in vCenter, not from a golden PVC. This tab lists the templates in vCenter and imports new ones. Celum stores nothing here. vCenter is the record, and a template shows in the list as soon as vCenter has it. The tab needs the supervisor’s Cluster API onboarding step done with a vSphere kind. Celum reads the vCenter address, thumbprint and credentials from what Cluster API uses, and the cluster agent on the supervisor connects to vCenter. If any of this is missing, the tab reads vCenter inventory unavailable.

Import a Talos OVA into vCenter

Image Library → vSphere → Import Talos OVA. Pick a Talos version from the catalog. Keep or change the Template name, which is talos-<version> by default. Set the Placement: Datacenter and Datastore are required, and Folder, Network and Resource pool are optional. Import starts the upload and waits up to 8 minutes for the template to show in the list.
  • The cluster agent on the supervisor downloads the OVA from its URL, uploads it to vCenter and marks the VM as a template. This runs in the background for up to 30 minutes.
  • Before the upload starts, the agent logs in and checks the datacenter, datastore, resource pool and folder. A wrong placement or a bad credential therefore fails at once. If a template with the same name exists, the import does nothing. If a VM that is not a template has that name, the import is refused.
  • The catalog offers the Talos vmware-amd64.ova from factory.talos.dev. It is built with the VMware guest-tools extension, which Cluster API needs to read a node’s address. The supervisor must be able to reach factory.talos.dev. To import from a mirror, call the API with your own url.
  • Network maps every network in the OVA to that port group.
Celum does not report a failed upload. The API returns as soon as the upload starts. A later failure is written only to the cluster agent’s log on the supervisor. If the template is still missing after 8 minutes, the dialog tells you so. Look for vsphere-import in the cluster agent’s log before you try again.
Keep the default talos-<version> name. On a talos-vsphere class, the Simple setup uses the template whose name has the highest x.y.z version, and it reads the Talos version from that name.

Verify

The image reads ready, with the access mode you asked for. Then create one VM from it and time the clone: a few seconds means the fast path, around a minute means the golden and the disk disagree on volume mode.

What commonly goes wrong

Create a VM

Where an image is consumed, and the rest of the create-time choices.

Classes & profiles

Clone strategy and access-mode support per StorageClass.

VM lifecycle

Live migration — the capability the access mode grants or withholds.

VM identity pools

Claim addresses, which need a migratable image.