Skip to content

feat: verify xcopy plan status observability annotations (MTV-7021) - #787

Open
AmenB wants to merge 5 commits into
RedHatQE:mainfrom
AmenB:feat/mtv-7021-xcopy-plan-observability
Open

AmenB wants to merge 5 commits into
RedHatQE:mainfrom
AmenB:feat/mtv-7021-xcopy-plan-observability

Conversation

@AmenB

@AmenB AmenB commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Automates MTV-7021 ([Automation] Xcopy Plan Status & Observability) under epic MTV-6086.

Forklift (PR kubev2v/forklift#7278 + follow-ups, in MTV 5.0.0 and recent 2.12.z) propagates the volume populator's copy details to Plan CR DiskTransfer task annotations after copy-offload migrations. The xcopyUsed annotation was already verified by verify_xcopy_used(); this PR extends the verification to the remaining observability annotations:

  • result must be success
  • copyDurationSeconds and provisionedBytes must be positive numbers
  • allocatedBytes must not be negative
  • storageVendor, cloneMethod, and storageProtocol must be present (Forklift never propagates empty values, so presence is the contract)

Implementation

  • New _get_task_annotation_value() (generic annotation reader — dedupes _get_xcopy_used_annotation, which now delegates to it)
  • New _get_task_number_annotation() for fail-fast numeric parsing
  • New _verify_task_offload_annotations() performing the per-task checks, called from _verify_xcopy_plan_annotations() and _verify_xcopy_plan_annotations_per_datastore()
  • All 25 existing test_check_xcopy_used steps get the coverage with zero test-file changes
  • Values are reported on both XCOPY and software-fallback copies, so fallback/mixed-datastore classes rely on the same checks
  • Docs updated in docs/copy-offload-migrations.md, docsite regenerated

Verification

  • Forklift source checked on main and release-2.12: all 8 annotations are propagated non-empty on successful copies (both XCOPY and fallback paths); copyDurationSeconds is a raw Prometheus float string, never integer-truncated
  • Lab cluster runs MTV 5.0.0 (epic fix version)
  • pre-commit run --all-files: all hooks pass
  • Code review: no blockers; 2 suggestion-level findings resolved (float-precision confirmed safe from source; version-requirement note added to docs)
  • Live run on qemtvd-01: pending (draft until validated)

Resolves: MTV-7021

Extend verify_xcopy_used() and verify_xcopy_used_per_datastore() to verify
the storage-offload observability annotations Forklift propagates from the
volume populator to Plan DiskTransfer task annotations (MTV-6086): result,
copyDurationSeconds, storageVendor, cloneMethod, storageProtocol,
provisionedBytes, and allocatedBytes.

- result must be "success", copyDurationSeconds and provisionedBytes must
  be positive numbers, allocatedBytes must not be negative
- storageVendor, cloneMethod, and storageProtocol must be present (Forklift
  never propagates empty values)
- values are reported on both XCOPY and software-fallback copies, so all
  existing copy-offload test classes get the coverage with no test-file
  changes
- dedupe annotation reading via _get_task_annotation_value; add
  _get_task_number_annotation for numeric parsing
- document the verification in docs/copy-offload-migrations.md and
  regenerate the docsite
@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
  • 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

@AmenB
AmenB marked this pull request as ready for review October 29, 2026 11:50
@redhat-qe-bot

Copy link
Copy Markdown

Report bugs in Issues

Welcome! 🎉

This pull request will be automatically processed with the following features:

🔄 Automatic Actions

  • Reviewer Assignment: Reviewers are automatically assigned based on the OWNERS file in the repository root
  • Size Labeling: PR size labels (XS, S, M, L, XL, XXL) are automatically applied based on changes
  • Issue Creation: Disabled for this repository
  • Branch Labeling: Branch-specific labels are applied to track the target branch
  • Auto-verification: Auto-verified users have their PRs automatically marked as verified
  • Labels: All label categories are enabled (default configuration)

📋 Available Commands

PR Status Management

  • /wip - Mark PR as work in progress (adds WIP: prefix to title)
  • /wip cancel - Remove work in progress status
  • /hold - Block PR merging (PR author or approvers)
  • /hold cancel - Unblock PR merging (PR author or approvers)
  • /verified - Mark PR as verified
  • /verified cancel - Remove verification status
  • /reprocess - Trigger complete PR workflow reprocessing (useful if webhook failed or configuration changed)
  • /regenerate-welcome - Regenerate this welcome message
  • /security-override - Set security check runs to pass (maintainers only)
  • /security-override cancel - Re-run security checks

Review & Approval

  • /lgtm - Approve changes (looks good to me)
  • /approve - Approve PR (approvers only)
  • /automerge - Enable automatic merging when all requirements are met (maintainers and approvers only)
  • /automerge cancel - Remove automerge label (maintainers and approvers only)
  • /assign-reviewers - Assign reviewers based on OWNERS file
  • /assign-reviewer @username - Assign specific reviewer
  • /check-can-merge - Check if PR meets merge requirements

Testing & Validation

  • /retest tox - Run Python test suite with tox
  • /retest build-container - Rebuild and test container image
  • /retest conventional-title - Validate commit message format
  • /retest all - Run all available tests

Container Operations

  • /build-and-push-container - Build and push container image (tagged with PR number)
    • Supports additional build arguments: /build-and-push-container --build-arg KEY=value

Cherry-pick Operations

  • /cherry-pick <branch> - Schedule cherry-pick to target branch when PR is merged
    • Multiple branches: /cherry-pick branch1 branch2 branch3
  • /cherry-pick-retry <branch> - Retry a failed cherry-pick (merged PRs only)

Branch Management

  • /rebase - Rebase this PR branch onto its base branch

Label Management

  • /<label-name> - Add a label to the PR
  • /<label-name> cancel - Remove a label from the PR

✅ Merge Requirements

This PR will be automatically approved when the following conditions are met:

  1. Approval: /approve from at least one approver
  2. Status Checks: All required status checks must pass
  3. No Blockers: No wip, hold, has-conflicts labels and PR must be mergeable (no conflicts)
  4. Verified: PR must be marked as verified

📊 Review Process

Approvers and Reviewers

Approvers:

  • krcmarik
  • myakove
  • solenoci

Reviewers:

  • krcmarik
  • myakove
  • solenoci
Available Labels
  • hold
  • verified
  • wip
  • lgtm
  • approve
  • automerge
AI Features
  • Conventional Title: Mode: fix (EnMaaS/rits/zai-org/glm-5-3)
  • Cherry-Pick Conflict Resolution: Enabled (EnMaaS/rits/zai-org/glm-5-3)
Security Checks
  • Suspicious Path Detection: Monitors paths: .claude/, .vscode/, .cursor/, .devcontainer/, .pi/, .github/workflows/, .github/actions/
  • Committer Identity Check: Verifies last committer matches PR author
  • Mandatory: Security checks block merge (use /security-override to bypass — maintainers only)

💡 Tips

  • WIP Status: Use /wip when your PR is not ready for review
  • Verification: The verified label is removed on new commits unless the push is detected as a clean rebase
  • Cherry-picking: Cherry-pick labels are processed when the PR is merged
  • Container Builds: Container images are automatically tagged with the PR number
  • Permission Levels: Some commands require approver permissions
  • Auto-verified Users: Certain users have automatic verification and merge privileges

For more information, please refer to the project documentation or contact the maintainers.

…-plan-observability

# Conflicts:
#	docs/llms-full.txt
#	docs/search-index.json
@qodo-code-review

qodo-code-review Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

PR Summary by Qodo

Verify copy-offload observability annotations on Plan tasks

✨ Enhancement 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Extend existing XCOPY tests to validate Plan task observability annotations for accelerated and
 fallback copies.
• Require finite duration and byte counts, successful results, and storage metadata on supported MTV
 releases.
• Document the checks and their MTV version requirement.
Diagram

graph TD
  T["XCOPY test steps"] --> V["Shared verifiers"] --> L["Populate logs"] --> X["XCOPY checks"] --> G{"MTV 2.12.6+?"} -->|yes| O["Offload checks"]
  V --> P["Plan tasks"] --> X
  G -->|no| S["Skip extra checks"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Separate observability test step
  • ➕ Would isolate observability failures from XCOPY failures.
  • ➖ Would require additional test steps across the copy-offload scenarios and repeat access to Plan task status.

Recommendation: Keep the checks in the shared XCOPY verifiers: both verification paths already traverse every DiskTransfer task, so this covers accelerated, fallback, and mixed-datastore copies without duplicating scenario tests. Validate the new assertions on a supported live cluster before merging.

Files changed (4) +212 / -28

Tests (1) +180 / -25
copyoffload_migration.pyValidate offload annotations in shared XCOPY verifiers +180/-25

Validate offload annotations in shared XCOPY verifiers

• Adds reusable annotation readers and per-task checks for result, finite numeric metrics, and storage metadata. Both Plan verification paths run the checks when the cluster reports MTV 2.12.6 or newer, while retaining existing XCOPY verification on older releases.

utilities/copyoffload_migration.py

Documentation (3) +32 / -3
copy-offload-migrations.htmlPublish observability checks in the generated guide +10/-1

Publish observability checks in the generated guide

• The generated HTML describes the Plan task assertions, coverage of fallback copies, and the MTV 2.12.6 version requirement. It also expands the description of what the XCOPY test step verifies.

docs/copy-offload-migrations.html

copy-offload-migrations.mdDocument Plan task observability verification +11/-1

Document Plan task observability verification

• The source guide specifies the required annotation values and explains that older MTV releases skip the new checks. It clarifies that existing XCOPY test steps cover software fallback as well.

docs/copy-offload-migrations.md

llms-full.txtSynchronize generated documentation text +11/-1

Synchronize generated documentation text

• The generated documentation text incorporates the annotation requirements, version gate, and expanded description of XCOPY test coverage.

docs/llms-full.txt

@qodo-code-review

qodo-code-review Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Invalid infinite copy metrics pass ✓ Resolved

Resolving commit: 186a8fb

Resolution reason
After parsing numeric annotations with float(), the code now calls math.isfinite() and raises a
contextual ValueError for infinity or overflowed values such as inf and 1e309.
Description
_get_task_number_annotation accepts positive infinity and overflowing literals through
float(value) without checking that the result is finite. When any numeric annotation contains
inf or 1e309, the subsequent positive or non-negative assertions pass and verification accepts
an invalid copy metric.

2. Older clusters fail copy-offload checks ✓ Resolved

Resolving commit: 186a8fb

Resolution reason
Added an MTV version capability gate for the storage-offload annotations, skipping their
verification on versions before 2.12.6 in both aggregate and per-datastore paths while continuing to
validate xcopyUsed.
Description
_verify_xcopy_plan_annotations and its per-datastore counterpart now require the new annotations
on every task without checking whether the installed MTV release produces them. On releases before
annotation propagation, the existing copy-offload tests reach these calls after migration and fail
with a missing-annotation error even when xcopyUsed is correct.


Informational

3. Generated documentation enters the PR ✗ Dismissed
Description
The change edits docs/copy-offload-migrations.html and docs/llms-full.txt, both listed generated
outputs, rather than only Markdown sources and navigation. This makes generated artifacts part of
the commit alongside the source update and violates the repository's documentation-generation
workflow.

4. Helpers use unjustified dynamic types ✓ Resolved

Resolving commit: 186a8fb

Resolution reason
Added immediately preceding comments to each dynamic task helper explaining that DiskTransfer task
objects are untyped dynamic Kubernetes resources, justifying the use of Any.
Description
The four new annotation helpers use Any for task without an immediately preceding rationale
comment. These helpers receive DiskTransfer objects from the dynamic Plan status path, so the
changed signatures add four unqualified dynamic-type usages to the modified module.

Grey Divider

Context sources
❌ Tickets: failed to load — Ticket collection could not establish complete evidence
✅ Compliance rules (platform): 96 rules
✅ Skills: remote-debugging
✅ Cross-repo context — repo relationships
  Explored: repo: RedHatQE/openshift-python-wrapper (sha: 8846aed5) — View relationship
✅ REVIEW.md
Review mode: Auto: ⚖️ Balanced: Substantial runtime validation spans multiple paths with meaningful compatibility risk.
✅ Fix-loop round: fix loop

Grey Divider

Tip of the day
💡 Did you know, you can commit Qodo's fix in one click with committable suggestions (GitHub & GitLab)

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Previous reviews

Review updated until commit 7aadba5

Results up to commit a30f1bd ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Remediation recommended
1. Invalid infinite copy metrics pass ✓ Resolved

Resolving commit: 186a8fb

Resolution reason
After parsing numeric annotations with float(), the code now calls math.isfinite() and raises a
contextual ValueError for infinity or overflowed values such as inf and 1e309.
Description
_get_task_number_annotation accepts positive infinity and overflowing literals through
float(value) without checking that the result is finite. When any numeric annotation contains
inf or 1e309, the subsequent positive or non-negative assertions pass and verification accepts
an invalid copy metric.

2. Older clusters fail copy-offload checks ✓ Resolved

Resolving commit: 186a8fb

Resolution reason
Added an MTV version capability gate for the storage-offload annotations, skipping their
verification on versions before 2.12.6 in both aggregate and per-datastore paths while continuing to
validate xcopyUsed.
Description
_verify_xcopy_plan_annotations and its per-datastore counterpart now require the new annotations
on every task without checking whether the installed MTV release produces them. On releases before
annotation propagation, the existing copy-offload tests reach these calls after migration and fail
with a missing-annotation error even when xcopyUsed is correct.


Informational
3. Generated documentation enters the PR ✗ Dismissed
Description
The change edits docs/copy-offload-migrations.html and docs/llms-full.txt, both listed generated
outputs, rather than only Markdown sources and navigation. This makes generated artifacts part of
the commit alongside the source update and violates the repository's documentation-generation
workflow.

4. Helpers use unjustified dynamic types ✓ Resolved

Resolving commit: 186a8fb

Resolution reason
Added immediately preceding comments to each dynamic task helper explaining that DiskTransfer task
objects are untyped dynamic Kubernetes resources, justifying the use of Any.
Description
The four new annotation helpers use Any for task without an immediately preceding rationale
comment. These helpers receive DiskTransfer objects from the dynamic Plan status path, so the
changed signatures add four unqualified dynamic-type usages to the modified module.

Grey Divider

Qodo Logo

Comment thread utilities/copyoffload_migration.py Resolved
Comment thread utilities/copyoffload_migration.py Resolved
…, Any justifications (MTV-7021)

- _get_task_number_annotation rejects non-finite values (inf/NaN/overflow) with a
  contextual ValueError before the sign checks
- storage-offload observability annotation verification is now gated on
  MTV >= 2.12.6 (first release propagating the full MTV-6086 annotation set),
  via has_mtv_minimum_version(); older clusters skip those checks with a log line
- added justification comments for the four task: Any helper parameters
  (dynamic Kubernetes objects without a typed wrapper)
- docs updated for the version gate; docsite regenerated
@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 186a8fb

@AmenB

AmenB commented Oct 29, 2026

Copy link
Copy Markdown
Contributor Author

/qodo

The following review comments were reviewed and a decision was made:

utilities/copyoffload_migration.py:1053 (qodo bug) — Invalid infinite copy metrics pass

Addressed: Addressed in commit 186a8fb: _get_task_number_annotation now validates math.isfinite() after parsing and raises a contextual ValueError for inf/NaN/overflow literals before the sign checks are applied. Docstring and Raises sections updated to "finite number".

utilities/copyoffload_migration.py:1176 (qodo bug) — Older clusters fail copy-offload checks

Addressed: Addressed in commit 186a8fb: the storage-offload observability annotation verification is now gated on MTV >= 2.12.6 — the first release propagating the full MTV-6086 annotation set (verified against forklift release-2.12 tags: v2.12.5 carries only xcopyUsed, v2.12.6 carries all eight annotations). The gate uses the existing has_mtv_minimum_version() helper via a new _offload_annotations_supported() check called from both verify_xcopy_used() and verify_xcopy_used_per_datastore(); older releases skip only the observability checks with a log line while the xcopyUsed verification stays strict. The docs note was updated accordingly.

docs/copy-offload-migrations.html:719 (qodo rule violation) — Generated documentation enters the PR

Skipped: Skipped: I updated the issue spec in #788 to document this design decision. The repo's documented workflow (AGENTS.md "Documentation Sync (MUST)": "Any docs/.md or docs/nav.json edit | Regenerate the site and commit generated output together with the source change") requires committing docs/.html, search-index.json and llms-full.txt together with the Markdown source change: they are pi-docsite build outputs, hand-editing them is forbidden, and removing them would leave the committed site stale. The only human-edited file is docs/copy-offload-migrations.md; the artifacts were regenerated with the documented build command (uvx pi-docsite). Issue #788 tracks updating Qodo rule 1255924 to exempt these generated artifacts.

utilities/copyoffload_migration.py:997 (qodo rule violation) — Helpers use unjustified dynamic types

Addressed: Addressed in commit 186a8fb: all four new helpers (_get_task_annotation_value, _get_xcopy_used_annotation, _get_task_number_annotation, _verify_task_offload_annotations) now carry a justification comment above the signature: "DiskTransfer task objects are dynamic Kubernetes resources without a typed wrapper, hence Any." — matching the pre-existing task: Any usage in _get_disk_transfer_tasks on main.

@qodo-code-review

Copy link
Copy Markdown

The following review comments were reviewed and a decision was made:

utilities/copyoffload_migration.py:1053 (qodo bug) — Invalid infinite copy metrics pass

Addressed: Addressed in commit 186a8fb: _get_task_number_annotation now validates math.isfinite() after parsing and raises a contextual ValueError for inf/NaN/overflow literals before the sign checks are applied. Docstring and Raises sections updated to "finite number".

utilities/copyoffload_migration.py:1176 (qodo bug) — Older clusters fail copy-offload checks

Addressed: Addressed in commit 186a8fb: the storage-offload observability annotation verification is now gated on MTV >= 2.12.6 — the first release propagating the full MTV-6086 annotation set (verified against forklift release-2.12 tags: v2.12.5 carries only xcopyUsed, v2.12.6 carries all eight annotations). The gate uses the existing has_mtv_minimum_version() helper via a new _offload_annotations_supported() check called from both verify_xcopy_used() and verify_xcopy_used_per_datastore(); older releases skip only the observability checks with a log line while the xcopyUsed verification stays strict. The docs note was updated accordingly.

docs/copy-offload-migrations.html:719 (qodo rule violation) — Generated documentation enters the PR

Skipped: Skipped: I updated the issue spec in #788 to document this design decision. The repo's documented workflow (AGENTS.md "Documentation Sync (MUST)": "Any docs/.md or docs/nav.json edit | Regenerate the site and commit generated output together with the source change") requires committing docs/.html, search-index.json and llms-full.txt together with the Markdown source change: they are pi-docsite build outputs, hand-editing them is forbidden, and removing them would leave the committed site stale. The only human-edited file is docs/copy-offload-migrations.md; the artifacts were regenerated with the documented build command (uvx pi-docsite). Issue #788 tracks updating Qodo rule 1255924 to exempt these generated artifacts.

utilities/copyoffload_migration.py:997 (qodo rule violation) — Helpers use unjustified dynamic types

Addressed: Addressed in commit 186a8fb: all four new helpers (_get_task_annotation_value, _get_xcopy_used_annotation, _get_task_number_annotation, _verify_task_offload_annotations) now carry a justification comment above the signature: "DiskTransfer task objects are dynamic Kubernetes resources without a typed wrapper, hence Any." — matching the pre-existing task: Any usage in _get_disk_transfer_tasks on main.

Acknowledged. The current review status is:

  • finding 1, finding 2, and finding 4 are implemented in commit 186a8fb.
  • finding 3 remains open, but the generated documentation is intentional under the repository’s documented pi-docsite workflow. The rule scope can be updated to exempt these generated artifacts at https://app.qodo.ai/rules/1255924?state=active.

No code changes are needed based on these decisions.

@AmenB

AmenB commented Oct 29, 2026

Copy link
Copy Markdown
Contributor Author

/qodo Please re-evaluate all remaining sticky findings against the current code.
For each finding, check if the referenced code has been fixed in subsequent commits.
Remove findings that are fully addressed. Keep any findings where the issue is still present in the code.

@qodo-code-review

Copy link
Copy Markdown

Please re-evaluate all remaining sticky findings against the current code.
For each finding, check if the referenced code has been fixed in subsequent commits.
Remove findings that are fully addressed. Keep any findings where the issue is still present in the code.

Re-evaluated the one remaining active finding:

  • finding 3 — Generated documentation enters the PR: Keep open. The issue is still present: the generated docs/copy-offload-migrations.html contains the new content at lines 719–726, and docs/llms-full.txt also contains the generated update at line 7263. AGENTS.md confirms these files are generated outputs and must not be hand-edited; documentation changes should be made in Markdown and then regenerated.
  • No remaining finding is fully addressed, so none were removed or dismissed.

For the rule scope or applicability, update or disable the rule here: https://app.qodo.ai/rules/1255924?state=active

@AmenB

AmenB commented Oct 29, 2026

Copy link
Copy Markdown
Contributor Author

/qodo

The following review comments were reviewed and a decision was made:

docs/copy-offload-migrations.html:719 (qodo rule violation) — Generated documentation enters the PR

Skipped: Skipped: I updated the issue spec in #788 to document this design decision. This is the same finding resolved in the previous review cycle and acknowledged by Qodo above ("the generated documentation is intentional under the repository's documented pi-docsite workflow... No code changes are needed"). The repo's AGENTS.md "Documentation Sync (MUST)" rule requires committing the regenerated artifacts (docs/*.html, search-index.json, llms-full.txt) together with the Markdown source change; they are pi-docsite build outputs and hand-editing them is forbidden. The rule scope can be updated per Qodo's suggestion at https://app.qodo.ai/rules/1255924 — tracked in issue #788.

@qodo-code-review

Copy link
Copy Markdown

The following review comments were reviewed and a decision was made:

docs/copy-offload-migrations.html:719 (qodo rule violation) — Generated documentation enters the PR

Skipped: Skipped: I updated the issue spec in #788 to document this design decision. This is the same finding resolved in the previous review cycle and acknowledged by Qodo above ("the generated documentation is intentional under the repository's documented pi-docsite workflow... No code changes are needed"). The repo's AGENTS.md "Documentation Sync (MUST)" rule requires committing the regenerated artifacts (docs/*.html, search-index.json, llms-full.txt) together with the Markdown source change; they are pi-docsite build outputs and hand-editing them is forbidden. The rule scope can be updated per Qodo's suggestion at https://app.qodo.ai/rules/1255924 — tracked in issue #788.

The repository guidance supports your decision: AGENTS.md requires committing regenerated docs/*.html and docs/llms-full.txt outputs after Markdown changes, while forbidding hand-editing them. Therefore, finding 3 is not applicable to this PR and should be treated as an intentional generated-artifact change. The rule scope can be updated or disabled here: https://app.qodo.ai/rules/1255924?state=active. I can’t change the rule or close the finding from this reply; if you want it formally closed, explicitly ask me to dismiss finding 3.

…-plan-observability

# Conflicts:
#	docs/search-index.json
…-plan-observability

# Conflicts:
#	docs/search-index.json

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants