mirror of
https://github.com/kvcache-ai/AgentENV.git
synced 2026-11-05 01:17:36 +00:00
[PR #433] [MERGED] fix(snapshot): stop interrupted deletes from shadowing aliases #434
Labels
No labels
bug
documentation
enhancement
enhancement
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/AgentENV#434
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/kvcache-ai/AgentENV/pull/433
Author: @yingdi-shan
Created: 10/24/2026
Status: ✅ Merged
Merged: 10/26/2026
Merged by: @yingdi-shan
Base:
main← Head:fix/template-delete-tombstones📝 Commits (1)
d1fe9fafix(snapshot): stop interrupted deletes from shadowing aliases📊 Changes
4 files changed (+180 additions, -17 deletions)
View changed files
📝
docs/src/concepts/templates/managing.md(+3 -0)📝
src/api/impls/image_build/tests.rs(+45 -0)📝
src/api/impls/template.rs(+12 -1)📝
src/snapshot/catalog.rs(+120 -16)📄 Description
What
Stops template deletes that stopped partway (
deleting: truetombstones) from holding on to their alias:src/snapshot/catalog.rs):delete()now releases the alias right after marking the recorddeleting, before it removes files, the build log and the record. This is the order used before087f599. A delete that stops partway no longer keeps the name, and it is retried by ID.src/snapshot/catalog.rs):claim_aliasandensure_alias_availablenow treat an alias whose owner record isdeletingas stale, the same way they already treat a missing owner. This heals tombstones left by earlier versions, whose aliases still point at them.src/api/impls/template.rs): when lookup finds no live template, the handler now also runs the catalog delete, which finishes a partial delete. Before, this path only deleted image-build records, so a retry returned204and left the tombstone in place.Why
In #432, 10 of 16 production templates became unusable: start-by-name returned
400 template <name> not found, and re-registering the name failed with an alias conflict.087f599moved the alias release to the end of the delete so that a retry by alias could find the record. The side effect was that any delete interrupted during the slow blob removal left the alias pointing at a record that every lookup hides.Related issue
Closes #432
Scope and non-goals
GET /templates.DELETE /snapshots/{id}is unchanged.Design and behavior changes
delete(): markdeleting→ release alias → delete files → build log → record.release_aliasonly removes the alias while it still points at this ID, so a retry is safe, and so is a new snapshot claiming the name in the meantime.Compatibility and operations
DELETE /templates/{id|name}now finishes partial deletes it used to skip.DELETE /templates/{id}on them. Rolling back is safe.Validation
make fmtmake clippymake test-unitmake -C services test(required whenservices/changes)maketargetCommands and results:
New tests:
snapshot::catalog::tests::deletes_that_fail_partway_release_the_alias: makes removing the snapshot directory fail, then checks that the alias is gone, the name can be registered again, and a retry by ID finishes the delete. It fails when the alias is released last.snapshot::catalog::tests::aliases_of_snapshots_being_deleted_can_be_claimed_again: covers the create and commit claims over a tombstone, and finishing the old delete without touching the new alias.api::impls::image_build::tests::template_deletion_by_id_finishes_an_interrupted_delete: covers the API retry path.Skipped checks and reasons: no integration or E2E suites were run. The change is limited to catalog and API logic, which the unit tests above cover with the POSIX backend. No
services/or schema changes.Risks and reviewer notes
src/snapshot/catalog.rs(deleteorder and alias claims) andsrc/api/impls/template.rs(delete_hidden_template).087f599added on purpose. Retry by ID still works becausefind_recordreturns records that are being deleted.Checklist
🤖 Generated with Claude Code
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.