Files
cozystack/packages/apps/vm-disk/values.schema.json
Myasnikov Daniil a115745c69 feat(vm-disk): let the operator defer binding to the consumer
Immediate binding for every source fixed a real bug: a standalone disk
on a WaitForFirstConsumer class has no consumer to wait for, so it never
populated. It also took away the path that is correct for the other case.
For a disk a VMInstance consumes, KubeVirt renders a temporary launcher
pod carrying the VM's own affinity and nodeSelector, so the volume binds
where the VM can actually run; with the annotation always present the CDI
worker becomes the first consumer instead and the volume lands where that
pod happened to be scheduled. On a node-pinned class the VM is then
unschedulable against a node-affinity conflict, and storageClass is
immutable, so the only exit is deleting the disk.

The two cases want opposite defaults and only the operator knows which
one a given disk is. bindImmediately defaults to true, so nothing moves
for existing disks or for anyone on `replicated`, which binds Immediate
either way. Both branches are pinned in tests, including the
existing-DataVolume path, which renders its own annotation block.

Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
Assisted-By: LLM
2026-09-07 16:27:24 +05:00

104 lines
2.7 KiB
JSON

{
"title": "Chart Values",
"type": "object",
"properties": {
"source": {
"description": "The source image location used to create a disk.",
"type": "object",
"default": {},
"properties": {
"disk": {
"description": "Clone an existing vm-disk.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"description": "Name of the vm-disk to clone.",
"type": "string"
}
}
},
"http": {
"description": "Download image from an HTTP source.",
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"description": "URL to download the image.",
"type": "string"
}
}
},
"image": {
"description": "Use image by name from default collection.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"description": "Name of the image to use.",
"type": "string",
"x-cozystack-options": {
"source": "image"
}
}
}
},
"upload": {
"description": "Upload local image.",
"type": "object"
}
},
"x-kubernetes-validations": [
{
"rule": "self == oldSelf",
"message": "source is immutable"
}
]
},
"optical": {
"description": "Defines if disk should be considered optical.",
"type": "boolean",
"default": false
},
"storage": {
"description": "The size of the disk allocated for the virtual machine.",
"default": "5Gi",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"x-kubernetes-int-or-string": true
},
"storageClass": {
"description": "StorageClass used to store the data.",
"type": "string",
"default": "replicated",
"x-kubernetes-validations": [
{
"rule": "self == oldSelf",
"message": "storageClass is immutable"
}
],
"x-cozystack-options": {
"source": "storageclass"
}
},
"bindImmediately": {
"description": "Provision the volume at disk creation instead of waiting for a consumer.",
"type": "boolean",
"default": true
}
}
}