Repository navigation
fix(operator): bound CSI snapshot capture and safely abort stalled quiesced backups #719
Description
A CSI VolumeSnapshot that never reports either readiness or an error can keep a quiesced game's saving disabled indefinitely. The Restic Job deadline does not cover this strategy. Add a persisted CSI capture deadline and an abort policy that invalidates incomplete captures before restoring saves.
Evidence comes from static inspection of master 04e41075cafc4c1a99bcb3723b0a8745ee810957; this review did not stop a CSI controller or reproduce the behavior at runtime. The issue applies to the optional volume-snapshot strategy with quiesce enabled.
Trigger and impact
Create a quiesced CSI backup, then leave its VolumeSnapshot pending by interrupting the snapshot controller/driver or delaying its response. The operator keeps polling because the object has neither readyToUse=true nor a reported error. It has already called save-off for games such as Minecraft.
Deleting the Backup is not a reliable escape. Cleanup first considers the pending CSI capture a live copy and returns before attempting unquiesce. The existing ten-minute unquiesce retry budget starts later in deletion handling, so it does not bound this wait. Other protected backups of the same server also remain behind the owner.
Pinned evidence
- Quiesce, snapshot creation, and readiness/error branching.
- Pending capture records start time and polls without an elapsed-time check.
- Cleanup treats an unfinished snapshot as live.
- Deletion waits for copy drainage before entering bounded unquiesce retries.
- An existing persisted abort marker permits cleanup after API/creation failure.
Recommended implementation
Persist the capture start/deadline before quiescing so controller restarts retain the same budget. Add a configurable CSI capture timeout independent of the Restic Job deadline. Report elapsed time and the pending capture condition in Backup status.
On expiry, persist a terminal abort decision before cleanup. Extend the existing abort marker into a defined state transition: the capture is invalid for restoration, the operator requests cancellation/deletion where supported, and cleanup may restore saves even if the driver later completes an abandoned capture. Prevent a late readiness event from changing that Backup to Succeeded or assigning it a usable snapshot identity.
Keep cleanup idempotent and UID-bound. Track any abandoned VolumeSnapshot/VolumeSnapshotContent for later reclamation according to its deletion policy, and expose a condition when cleanup needs administrator intervention. Specify deletion-before-deadline behavior so users can cancel a pending operation without waiting forever. Preserve normal worker/capture drainage for successful backups; the timeout path must explicitly invalidate its result.
Acceptance criteria
- CI covers a snapshot with no status, a stalled non-ready status, and a driver that reports readiness after timeout.
- Operator restart does not reset the deadline or repeat quiesce after abort.
- Cancellation and expiry retry save-on and release ownership after the defined safe-abort transition.
- An aborted capture cannot become a successful or restorable Backup.
- Missing APIs, ambiguous creation errors, replacement UIDs, and snapshot cleanup failures retain clear conditions and existing protections.
Build on #590's API preflight and creation-error abort handling. Preserve #454's terminal cleanup retries; #573's Job deadline remains a separate Restic control.
Activity
ValgulNecron commentedon Oct 20, 2026
Thanks, confirmed on master:
markVolumeSnapshotRunningrequeues every 10 seconds with no elapsed-time check (operator/internal/controller/backup_volumesnapshot.go:99-120), and a pending capture counts as live (backup_guard.go:381-412), so it blocks unquiesce before the 10-minute finalize budget (backup_controller.go:51) ever applies. A stuck CSI driver can leave the game in save-off indefinitely.Go ahead with a PR:
This builds on the ownership record from #718, so please reference it.
Baylem commentedon Oct 25, 2026
Implemented in #772 on top of #760's ownership record for #718. A separate CSI capture deadline is persisted before quiesce, defaults to 10 minutes and is configurable per install. Expiry writes the durable abort decision before save-on; late readiness cannot turn the Backup into a valid restore source.
Cleanup requests deletion of the original VolumeSnapshot and verified Delete-policy content using UID preconditions. Retain-policy, replaced or otherwise unverifiable resources are left for administrators and identified by the SnapshotCleaned condition. Snapshot reclamation proceeds independently of resuming saving, so a stuck driver cannot extend save-off indefinitely. The regression sources cover expiry/late readiness and Delete, Retain and replacement cleanup cases.