Skip to content

fix: reclaim clone-source copies no pod on the node clones from - #120

Merged
CMGS merged 1 commit into
mainfrom
reclaim-clone-source-copies
Sep 29, 2026
Merged

CMGS merged 1 commit into
mainfrom
reclaim-clone-source-copies

Conversation

@CMGS

@CMGS CMGS commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

Bug

Found on hardware (kit run N28, case D6) after #118. reclaimLocalSnapshots treats every unused vk--prefixed local snapshot as a VM's hibernate copy and checks it against <name>:hibernate in the registry. A clone-source copy pulled for a non-default tag or a digest has a colon in its local name (vk-…:v2, vk-…:sha256:…-hash), so GetManifest builds base/vk-…:sha256:…-hash:hibernate, which ParseReference rejects. That error is not errStaleLocalSnapshot, so the copy is kept forever, silently. Default-tag copies (vk-…, no colon) happened to be reclaimed because their hibernate tag is absent. On the kit, two 1 GiB digest copies stayed on host B after every pod was gone and vk restarted.

This predates #118 for any repo:tag clone source; #118 put every digest clone on the same path.

Fix

  • A local snapshot whose name contains a colon is a pulled clone-source copy (VM names never carry one): when no pod on the node clones from it, remove it directly, without the hibernate-manifest verify. In-use protection is unchanged (snapshotNamesInUse derives the same name from each tracked pod's image).
  • A verify error that is not staleness now logs at Warn (keep local snapshot …) instead of being dropped.

Tests

TestTheReclaimerDropsOnlyWhatNoPodOnTheNodeCanWakeFrom gains four cases, each with a registry that cannot answer (so the reclaim cannot depend on it): an unused tagged copy and an unused digest copy are removed; a tagged and a digest copy that a tracked pod clones from are kept. Both removal cases fail on main (removed [], want [...]) and pass here; every existing case keeps its result.

Gates

make lint 0 issues on linux and darwin, make fmt-check clean, asl ./... clean on both GOOS, go test -race ./... green (GOWORK=off). Hardware: the N28 D6 case is the acceptance; not rerun yet. Hot path: none, the reclaimer runs every 10 minutes.

The reclaimer treated every unused vk- snapshot as a VM's hibernate copy and
verified it against <name>:hibernate in the registry. A clone-source copy of a
non-default tag or a digest carries a colon in its local name, so that lookup
built an invalid reference, the error was not errStaleLocalSnapshot, and the
copy was kept forever with no log line. #118 made every digest clone source
land on this path; the kit's N28 run left two 1 GiB digest copies on the node.

VM names never contain a colon, so a colon in the name marks a pulled
clone-source copy: re-pullable, owned by no VM, and safe to drop once no pod on
the node clones from it. Verify errors that are not staleness now log at Warn
instead of vanishing.
@CMGS
CMGS merged commit ea65b02 into main Sep 29, 2026
4 checks passed
@CMGS
CMGS deleted the reclaim-clone-source-copies branch September 29, 2026 02:34
CMGS added a commit that referenced this pull request Sep 29, 2026
The reclaimer only looked at vk- names, so a clone source pulled from another
repository (simular/osworld-ref:ref12, or a default-tag simular/golden) stayed
on the node forever once no pod used it. A name alone cannot tell such a copy
from a snapshot an operator imported by hand, which may exist nowhere else.

vk-cocoon now imports every clone-source pull with the description
"vk-cocoon clone source" (cocoon's snapshot import already takes one and
snapshot list reports it). The reclaimer removes a marked snapshot once no pod
on the node clones from it, whatever its name; the registry still holds it.
Unmarked snapshots outside the vk- names are never touched, and the #120 colon
rule stays for vk- copies pulled before the mark existed. Hibernate wake
imports stay unmarked. docs/reconcile.md now describes both rules.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant