Skip to content

fix(vm-disk): refuse a disk smaller than the golden image it clones - #4960

Merged
Aleksei Sviridkin (lexfrei) merged 2 commits into
cozystack:mainfrom
yankawai:fix/vm-disk-size-below-image
Nov 13, 2026
Merged

Aleksei Sviridkin (lexfrei) merged 2 commits into
cozystack:mainfrom
yankawai:fix/vm-disk-size-below-image

Conversation

@yankawai

@yankawai europrinter (yankawai) commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

What this PR does

A VMDisk created from source.image with a storage smaller than its golden image never comes up. CDI v1.66.1 checks a clone against its source in validateClone (pkg/controller/datavolume/pvc-clone-controller.go) before it creates the target claim. When the source PVC is in Block mode and requests more than the DataVolume, CDI records CloneValidationFailed ("target resources requests storage size is smaller than the source"), creates no claim and leaves the DataVolume Pending for good. The webhook admits such a DataVolume, so nothing fails at install. Raising storage afterwards does not help either, because the chart renders an existing DataVolume's spec as it is (CDI does not let it change) and the resize hook only patches a claim that exists.

This is the default path. Every image in vm-default-images is 20Gi on replicated, the StorageProfile CDI builds for the LINSTOR driver puts Block first, and the chart defaults storage to 5Gi. Seen on a v1.6.4 cluster with CDI v1.66.1. A 10Gi disk from a 20Gi golden image sat Pending with CloneValidationFailed while its release kept timing out, and raising the disk to 25Gi left the DataVolume at 10Gi. The only way out is to delete the disk and create it again at 20Gi or more.

The chart now refuses such a disk at render time, before any DataVolume exists, with a message that names both sizes and the minimum to set, for example storage 5Gi is smaller than golden image "vm-default-images-ubuntu" (20Gi), so CDI refuses to clone it and the disk would stay pending forever. Set storage to 20Gi or more. It compares what CDI compares, the golden PVC's request against the disk's request in bytes, and first raises the disk's request to the target StorageProfile's cdi.kubevirt.io/minimumSupportedPvcSize the way GetEffectiveStorageResources does. For an empty storageClass the target is the class the check from #4796 already resolves, the default virt class or else the Kubernetes default.

Nothing is compared, and the disk renders as before, when the golden PVC cannot be read (under helm template, or before CDI created it), when the golden PVC is in Filesystem mode, and for any source other than image. For a Filesystem source CDI sizes a Block target from the virtual size of the image inside it and otherwise compares requests inflated by a per-class filesystem overhead, neither of which the chart reproduces. An existing disk is exempt, as for the other golden checks, since its DataVolume spec cannot change anyway.

Not covered here. A source.disk clone into a smaller disk goes through the same CDI check and still renders. The chart default of 5Gi stays below every default image, so a disk created from one at the default size is now refused with the message above instead of hanging. Whether the default should follow the images is a separate decision.

A new helm-unittest suite, tests/dv_golden_size_test.yaml, has 15 cases. It pins the refusal at the chart default against a 20Gi Block golden with the whole message, the equal and the larger size, the comparison in bytes (21G is refused against 20Gi, 20480Mi renders), a StorageProfile minimum that covers the golden and one that stays below it, the minimum read from the default class for an empty storageClass, and the cases that render as before, a Filesystem golden, no cluster, a golden PVC that does not exist yet, a disk without a size, an existing disk, an http and an upload source. Against the template on main the 3 refusal cases fail and the other 12 pass. Six mutations of the new block each turn at least one case red (any volume mode compared, the minimum dropped, the minimum read from the requested class only, no check that storage is set, an equal size refused, sizes compared as strings). helm unittest passes 129 of 129 for vm-disk, against 114 on main, with helm-unittest 1.1.2 as CI pins it. Merged with the current heads of #4802 or #4955, which touch the same template, vm-disk passes 137 and 131 cases. helm template without a cluster renders an image disk at 5Gi as before. I have not run it on a live cluster.

The commit does not cherry-pick onto release-1.6 or release-1.7. Neither carries the check from #4796 it builds on, and release-1.6 has none of the golden checks, so a backport would be an adapted change.

Screenshots

Not a UI change.

Downstream repositories

Template and tests only. No values, schema, README, defaults or ApplicationDefinition change. The golden images guide on the website already creates its example disk at the image's 20Gi.

Release note

fix(vm-disk): a new disk from a golden image is now refused at render time when its storage is smaller than the image, with a message that names both sizes. Before, CDI refused the clone with CloneValidationFailed, the disk stayed pending forever, and raising its storage afterwards did not help. The default images are 20Gi and the default storage is 5Gi, so a disk from one of them needs storage set to 20Gi or more.

Summary by CodeRabbit

  • Bug Fixes
    • Disk sizes are now checked against the size of Block-mode golden images when cloning. If the requested size is too small, it is increased to the target storage profile’s minimum supported size when possible; otherwise, rendering fails with an error that states the required size.
    • Size comparisons account for actual byte capacity, so equivalent size units are handled correctly. Filesystem-mode sources and other disk sources are unaffected.

CDI checks a clone against its source before it creates the claim. When
the golden image's PVC is in Block mode and requests more than the disk,
it records CloneValidationFailed and leaves the DataVolume pending for
good. The DataVolume spec is immutable, so raising storage on the VMDisk
afterwards changes nothing, and the resize hook finds no claim to patch.
Every image in vm-default-images is 20Gi on replicated, where CDI picks
Block mode for the LINSTOR driver, while the chart defaults storage to
5Gi, so a disk created from an image at the default size never comes up.

The chart now refuses such a disk at render time and names both sizes,
so the user sets storage to the golden's size before any DataVolume
exists. It compares what validateClone compares in CDI v1.66.1, the
golden PVC's request against the disk's request raised to the target
StorageProfile's minimumSupportedPvcSize. A Filesystem golden is not
compared, because CDI sizes that clone from the image inside it or with
a filesystem overhead, and neither is a golden whose PVC does not exist
yet. An existing disk is exempt, as for the other golden checks.

Assisted-by: LLM
Signed-off-by: Yan Bondarenko <[email protected]>
@github-actions github-actions Bot added area/virtualization Issues or PRs related to virtualization (kubevirt, cdi, vmi, vm-import) kind/bug Categorizes issue or PR as related to a bug size/L This PR changes 100-499 lines, ignoring generated files labels Oct 19, 2026
@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 8d82348 and 0bfd98f.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review

No actionable comments were generated in the recent review.

Walkthrough

The vm-disk template now checks configured storage against the size of a Block-mode golden PVC when cloning an image source. It accounts for the target StorageProfile’s minimum supported PVC size and reports an error if the resulting size remains too small. Tests cover size boundaries and cases not checked by this validation.

Changes: Golden size validation

Layer / File(s) Summary
Validate image-source clone storage
packages/apps/vm-disk/templates/dv.yaml, packages/apps/vm-disk/tests/dv_golden_size_test.yaml
The template compares configured storage with the golden PVC size for Block-mode image sources. It accounts for the target StorageProfile minimum and rejects sizes that remain too small. Tests cover size comparisons, minimums, and excluded cases.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Merge Risk: Minimal · previous review 8d823

The new Block-image size check has no established merge-blocking issue. Normal checks remain appropriate before merging.

Pre-merge checks: Passed 5

Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: vm-disk now refuses clone disks that are smaller than the golden image.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (2 skipped: 2 unsupported.)

Finishing Touches

🧪 Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

ℹ️ Recent review info

⚙️ Run configuration

  • Configuration used: Repository: cozystack/cozystack/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a4d5b673-8707-4426-87a3-3ba92c8d649e
📥 Commits

Reviewing files that changed from the base of the PR and between aed7fa8 and 8d82348.

📒 Files selected for processing: 2

  • packages/apps/vm-disk/templates/dv.yaml
  • packages/apps/vm-disk/tests/dv_golden_size_test.yaml

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

@IvanHunters IvanHunters left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked the full dv.yaml guard and the new unittest suite, rendered the merge base against the rejected inputs, ran mutations on both conjuncts, and ran the chart's helm-unittest (129/129). The size guard is nested inside the existing existingDV/release-PVC guard, so disks that already exist are excluded and upgrades keep rendering. No blocking issues.

Non-blocking:

  • packages/apps/vm-disk/values.yaml:30 and README: the new lower bound on storage is not reflected in the field description. The failure message is self-contained (names both sizes and the exact fix), so this is cosmetic.
  • templates/dv.yaml:161: with an empty storageClass and a tie between several default storage classes, $targetSC stays empty and the StorageProfile minimum is not read, so a small disk is refused without accounting for a minimum CDI could have raised. Only reachable on a cluster that already has multiple default storage classes.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <[email protected]>
@lexfrei

Copy link
Copy Markdown
Contributor

europrinter (@yankawai) I merged main into your branch (0bfd98f) so CI runs against the current base. Your commits are unchanged.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

europrinter (@yankawai) LGTM, CI and E2E are green on this head.

@lexfrei
Aleksei Sviridkin (lexfrei) merged commit a5c58e5 into cozystack:main Nov 13, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/virtualization Issues or PRs related to virtualization (kubevirt, cdi, vmi, vm-import) kind/bug Categorizes issue or PR as related to a bug size/L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants