Phase 7: OCI delete path for manifests and blobs
Manifest delete (DELETE /v2/<name>/manifests/<digest>): rejects tag references with 405 UNSUPPORTED per OCI spec, cascades to tags and manifest_blobs via ON DELETE CASCADE, returns 202 Accepted. Blob delete (DELETE /v2/<name>/blobs/<digest>): removes manifest_blobs associations only — blob row and file are preserved for GC to handle, since other repos may reference the same content-addressed blob. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
46
PROGRESS.md
46
PROGRESS.md
@@ -6,7 +6,7 @@ See `PROJECT_PLAN.md` for the implementation roadmap and
|
||||
|
||||
## Current State
|
||||
|
||||
**Phase:** 6 complete, ready for Phase 7
|
||||
**Phase:** 7 complete, ready for Phase 9
|
||||
**Last updated:** 2026-03-19
|
||||
|
||||
### Completed
|
||||
@@ -18,6 +18,7 @@ See `PROJECT_PLAN.md` for the implementation roadmap and
|
||||
- Phase 4: Policy engine (all 4 steps)
|
||||
- Phase 5: OCI pull path (all 5 steps)
|
||||
- Phase 6: OCI push path (all 3 steps)
|
||||
- Phase 7: OCI delete path (all 2 steps)
|
||||
- Phase 8: Admin REST API (all 5 steps)
|
||||
- `ARCHITECTURE.md` — Full design specification (18 sections)
|
||||
- `CLAUDE.md` — AI development guidance
|
||||
@@ -26,14 +27,51 @@ See `PROJECT_PLAN.md` for the implementation roadmap and
|
||||
|
||||
### Next Steps
|
||||
|
||||
1. Phase 7 (OCI delete)
|
||||
2. After Phase 7, Phase 9 (garbage collection)
|
||||
3. Phase 10 (gRPC admin API)
|
||||
1. Phase 9 (garbage collection)
|
||||
2. Phase 10 (gRPC admin API)
|
||||
|
||||
---
|
||||
|
||||
## Log
|
||||
|
||||
### 2026-03-19 — Phase 7: OCI delete path
|
||||
|
||||
**Task:** Implement manifest and blob deletion per OCI Distribution Spec.
|
||||
|
||||
**Changes:**
|
||||
|
||||
Step 7.1 — Manifest delete:
|
||||
- `db/delete.go`: `DeleteManifest(repoID, digest)` — deletes manifest
|
||||
row; ON DELETE CASCADE handles manifest_blobs and tags
|
||||
- `oci/delete.go`: `handleManifestDelete()` — policy check
|
||||
(registry:delete), rejects deletion by tag (405 UNSUPPORTED per OCI
|
||||
spec), returns 202 Accepted, writes `manifest_deleted` audit event
|
||||
- Updated `oci/routes.go` dispatch to handle DELETE on manifests
|
||||
|
||||
Step 7.2 — Blob delete:
|
||||
- `db/delete.go`: `DeleteBlobFromRepo(repoID, digest)` — removes
|
||||
manifest_blobs associations only; does NOT delete the blob row or
|
||||
file (GC's responsibility, since other repos may reference it)
|
||||
- `oci/delete.go`: `handleBlobDelete()` — policy check, returns 202,
|
||||
writes `blob_deleted` audit event
|
||||
- Updated `oci/routes.go` dispatch to handle DELETE on blobs
|
||||
- Extended `DBQuerier` interface with delete methods
|
||||
|
||||
**Verification:**
|
||||
- `make all` passes: vet clean, lint 0 issues, all tests passing,
|
||||
all 3 binaries built
|
||||
- DB delete tests (5 new): delete manifest (verify cascade to tags and
|
||||
manifest_blobs, blob row preserved), manifest not found, delete blob
|
||||
from repo (manifest_blobs removed, blob row preserved, manifest
|
||||
preserved), blob not found, blob exists globally but not in repo
|
||||
- OCI delete tests (8 new): manifest delete by digest (202), delete by
|
||||
tag (405 UNSUPPORTED), manifest not found (404 MANIFEST_UNKNOWN),
|
||||
repo not found (404 NAME_UNKNOWN), cascading tag deletion verified,
|
||||
blob delete (202), blob not in repo (404 BLOB_UNKNOWN), blob delete
|
||||
repo not found
|
||||
|
||||
---
|
||||
|
||||
### 2026-03-19 — Phase 6: OCI push path
|
||||
|
||||
**Task:** Implement blob uploads (monolithic and chunked) and manifest
|
||||
|
||||
Reference in New Issue
Block a user