Skip to content

fix(vm-disk): name the importer error in the disk's WorkloadsReady message - #4815

Merged
Aleksei Sviridkin (lexfrei) merged 2 commits into
mainfrom
fix/vm-disk-datavolume-error-message
Oct 12, 2026
Merged

Aleksei Sviridkin (lexfrei) merged 2 commits into
mainfrom
fix/vm-disk-datavolume-error-message

Conversation

@scooby87

@scooby87 scooby87 commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

What this PR does

A VMDisk whose HTTP source answers 404 or does not resolve never finishes importing, and since #4380 its WorkloadsReady condition says only DataVolume vm-disk-x is ImportInProgress. That reads the same as a large download that is still running. CDI fails an import only on a fatal error (a checksum mismatch) and restarts the importer pod otherwise, so the phase never moves, and the reason the disk will not finish was visible only in the importer logs.

CDI already keeps that reason on the DataVolume: the Running condition goes False with the importer's termination message, and keeps it through the back-off between restarts. The WorkloadMonitor now appends it, so the condition reads DataVolume vm-disk-x is ImportInProgress: Unable to connect to http data source: expected status code 200, got 404. Status: 404 Not Found. The console already shows the WorkloadsReady message on the disk's overview page, so no UI change is needed. The same text covers an unschedulable importer, a failed image pull and a checksum failure, since CDI reports all of them through Running=False.

Only Running=False is read: Unknown is not a failure, and Bound repeats the same error behind PVC details. For a host-assisted clone CDI joins the target and source pod messages as <target> and <source>, which comes out as and when both pods are still being created, so empty halves are dropped.

Behaviour to be aware of: while the importer pod is briefly running between restarts, CDI flips Running to True and clears the message, so the condition shows the bare phase for those seconds. This is not a terminal state either: a disk with a broken source still stays ImportInProgress and keeps retrying. Deciding when such an import should count as failed is left for a separate change.

Tests

A table test covers a 404, an unresolvable host, an unschedulable importer, a fatal checksum error, a DataVolume without a phase and joined clone messages with one or both halves empty, plus the cases that must not add text: an importer that has not started, a running importer, an Unknown condition, a populated disk and an error that only sits on Bound. Each conjunct of the condition check and the append itself were mutated and each mutant fails the test. A second test runs against a DataVolume captured from a test cluster after its importer had restarted about two thousand times on a 404, with only names and the URL changed, so the parsing is pinned against what CDI actually writes rather than a hand-built shape.

Screenshots

No UI code changes: the console renders the WorkloadsReady message it already receives. A message that carries a long source URL is not wrapped on the overview card; that is a styling follow-up for the console and is left out of this change.

Downstream repositories

The only non-Go change is a sentence in the packages/apps/vm-disk/README.md notes; no values, schema, API kind or default changes. The website reference page for vm-disk is regenerated from that README by the release bot.

Release note

fix(vm-disk): the WorkloadsReady condition of a VM disk now includes the importer error reported by CDI, such as a 404 or an unresolvable host, so a disk whose source keeps failing shows why it is stuck instead of only ImportInProgress.

Summary by CodeRabbit

  • Bug Fixes
    • Workload status messages now include available DataVolume import failure details, such as HTTP errors or DNS resolution problems, making the cause of an import issue clearer.
  • Documentation
    • Updated the workload readiness documentation to explain when DataVolume phase and import error details appear in status messages.

…ssage

A disk whose HTTP source answers 404 or does not resolve never leaves
ImportInProgress: CDI fails an import only on a fatal error and restarts
the importer pod otherwise, so the condition only ever said the disk was
still importing. The reason it will not finish was visible only in the
importer logs and on the DataVolume, whose Running condition carries the
error through the back-off between restarts.

Appending that message lets the user see why the disk is stuck from the
application status and the console, which already shows the
WorkloadsReady message for a disk.

Assisted-by: LLM
Signed-off-by: Alexey Artamonov <[email protected]>
The table test builds its Running conditions by hand, so it can only
confirm the shape it already assumes. A DataVolume read off a cluster
where the importer had failed on a 404 for days carries a Bound
condition with the same error, which the message must not pick up, and
proves the error sits where the controller looks for it.

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

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: cozystack/cozystack/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b9caf482-b26b-4b3c-ab8b-6710bffe3780
📥 Commits

Reviewing files that changed from the base of the PR and between d7f3f0d and 970ccc2.

📒 Files selected for processing (4)
  • internal/controller/testdata/datavolume-http-404.json
  • internal/controller/workloadmonitor_controller.go
  • internal/controller/workloadmonitor_controller_test.go
  • packages/apps/vm-disk/README.md

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


📝 Walkthrough

Walkthrough

The workload monitor now includes errors from failed DataVolume Running conditions in status messages. Tests cover importer and clone errors, and the README describes how HTTP import errors appear during CDI retries.

Changes

DataVolume status messages

Layer / File(s) Summary
Extract and report DataVolume errors
internal/controller/workloadmonitor_controller.go, internal/controller/workloadmonitor_controller_test.go, internal/controller/testdata/datavolume-http-404.json, packages/apps/vm-disk/README.md
The monitor appends a non-empty message from a Running=False condition to the existing DataVolume phase text. Tests cover importer and clone errors, missing phases, other condition states, and an HTTP 404 fixture. The README documents the phase and error text during CDI retries.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 970cc

Disk status messages will now show the importer error, such as an HTTP 404 or an unresolvable host. The change is small, documented and tested, and no merge-blocking risk was found.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 2 files. (2 skipped: 2… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
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: exposing the CDI importer error in the disk's WorkloadsReady message.
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

Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 2 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · 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

Comment @coderabbitai help to get the list of available commands.

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.

LGTM. The importer error CDI already keeps on the DataVolume now reaches WorkloadsReady, and ready disks get no extra text.

Business context: a VMDisk whose HTTP source keeps failing sits in ImportInProgress forever, and the reason was visible only in the importer logs.

scooby87 here is what I checked.

  1. CDI behaves the way the comment says, at v1.66.1 which the platform ships. setAnnotationsFromPodWithPrefix in pkg/controller/util.go copies the importer's termination message into the running-condition annotation, keeps it through CrashLoopBackOff and clears it once every container runs. Clone messages are joined with "%s and %s" in updateWithTargetNotRunning. The phase goes to Failed only with AnnImportFatalError (see updateStatusPhase), so a 404 stays ImportInProgress.
  2. Healthy disks don't change. Ready DataVolumes are skipped before the new code runs. The DataVolume watch has no predicate, so a Running flip does reconcile the monitor. The lastTransitionTime of WorkloadsReady comes from the monitor's creationTimestamp, so the extra status writes on each importer restart don't move it.
  3. Nothing sensitive reaches the tenant. The vm-disk chart renders source.http with url only, without secretRef or a cert ConfigMap. The connect error comes from Go's HTTP client, which strips a password from the URL. What is left is the tenant's own URL and CDI's error, in a WorkloadMonitor in the tenant's namespace. The fixture has only example names and URLs.
  4. Tests pass on a trial merge with current main (go test ./internal/controller/...). I broke the append, the Running type check, the False status check and the empty-half filter one at a time, and each mutant fails the new tests.

Nit, not blocking: the dataVolumesMessage doc comment still says it names each DataVolume "with its phase". It now appends CDI's error too.

@lexfrei
Aleksei Sviridkin (lexfrei) merged commit 8deaa8e into main Oct 12, 2026
57 checks passed
@lexfrei
Aleksei Sviridkin (lexfrei) deleted the fix/vm-disk-datavolume-error-message branch October 12, 2026 09:29
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.

2 participants