Commit bea200c
fix(controller): prune source replica after node evacuate completes (Bug 389) (#81)
* fix(controller): prune source replica after node evacuate completes (Bug 389)
`node evacuate` is an online drain: place a replacement diskful replica
on a healthy peer, wait for it to reach UpToDate, then delete the source
replica on the evacuated node so the node is left empty and `node delete`
completes cleanly.
The NodeReconciler previously gap-filled the replacement but returned
early on the EVICTED (non-LOST) path without ever deleting the source.
The RD then ran at place_count+1 diskful forever with one copy pinned to
an EVICTED node, storage was never reclaimed, and the drain never
finished.
Add a strict add-before-drop gate mirroring the resource-migration
controller: the source is pruned only once at least place_count diskful
replicas on healthy (non-evicted, non-lost) nodes are observed UpToDate
via the Resource CRD Status. Until then the source lives so redundancy
never dips mid-drain. The LOST path is unchanged (no replacement to wait
on). An evacuated-but-unreachable node prunes the CRD through the same
finalizer path the LOST case uses.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
* test(controller): pin Bug 389 evacuate source-prune add-before-drop
Two-phase regression: with a replacement placed but not yet UpToDate the
source on the evacuated node must survive (redundancy preserved); once
the replacement reaches UpToDate the source Resource CRD must be deleted.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
* test(cli-matrix): add L6 node-evacuate source-prune cell (Bug 389)
Drives the real `linstor node evacuate` against a 3-node stand and
asserts the replacement reaches UpToDate and the source replica on the
evacuated node is drained empty.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
* test(harness): add L7 evacuate source-prune replay (Bug 389)
3-node workflow: place 2 diskful, evacuate node1, assert replacement on
node3 reaches UpToDate, source on node1 pruned (resource_absent), and
both survivors UpToDate (redundancy preserved).
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
* fix(controller): derive evacuate place_count from current diskful count, not RG default (Bug 389)
The round-1 Bug 389 fix added an add-before-drop gate but derived the
drain target from the parent RG's place_count, defaulting it to 1 when
the RG carried place_count=0. The default DfltRscGrp ships place_count=0
and CLI-created RDs inherit it, so on that path the placer treated the
single surviving peer as satisfied (gap-filling no replacement) and the
readiness gate passed at one healthy replica — pruneSource then dropped
the source on the evacuated node, leaving the RD at ONE diskful
(drop-without-add, strictly worse than the original bug).
Anchor the effective target to max(RG place_count, current diskful
count): count the RD's diskful replicas now, including the one being
evacuated (so it is replaced) but excluding diskless/tiebreaker
witnesses and replicas on other EVICTED/LOST nodes. The raw count is
capped at the number of non-disabled nodes so the freshly placed
replacement cannot inflate the target across the requeue loop. The
placer then gap-fills a replacement before pruneSource runs, and the
readiness gate only passes once the pre-drain diskful count is
re-established on healthy peers.
Reuses drainingNodes and the DISKLESS-flag diskful convention shared
with the placer / auto-diskful controller.
Adds an L1 regression covering the DfltRscGrp / place_count=0 path
(evacuating one of two diskful replicas must place a replacement before
pruning and end at two diskful, never one) and extends the L7 replay to
reproduce that path and assert two diskful remain.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
---------
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>1 parent 6f36131 commit bea200c
5 files changed
Lines changed: 940 additions & 20 deletions
File tree
- internal/controller
- tests
- e2e/cli-matrix
- operator-harness/replay
0 commit comments