Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

registry: implement blob deletion #1432

Merged
merged 1 commit into from Oct 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
38 changes: 38 additions & 0 deletions pkg/registry/blobs.go
Expand Up @@ -76,6 +76,13 @@ type blobPutHandler interface {
Put(ctx context.Context, repo string, h v1.Hash, rc io.ReadCloser) error
}

// blobDeleteHandler is an extension interface representing a blob storage
// backend that can delete blob contents.
type blobDeleteHandler interface {
// Delete the blob contents.
Delete(ctx context.Context, repo string, h v1.Hash) error
}

// redirectError represents a signal that the blob handler doesn't have the blob
// contents, but that those contents are at another location which registry
// clients should redirect to.
Expand Down Expand Up @@ -129,6 +136,17 @@ func (m *memHandler) Put(_ context.Context, _ string, h v1.Hash, rc io.ReadClose
m.m[h.String()] = all
return nil
}
func (m *memHandler) Delete(_ context.Context, _ string, h v1.Hash) error {
m.lock.Lock()
defer m.lock.Unlock()

if _, found := m.m[h.String()]; !found {
return errNotFound
}

delete(m.m, h.String())
return nil
}

// blobs
type blobs struct {
Expand Down Expand Up @@ -435,6 +453,26 @@ func (b *blobs) handle(resp http.ResponseWriter, req *http.Request) *regError {
resp.WriteHeader(http.StatusCreated)
return nil

case http.MethodDelete:
bdh, ok := b.blobHandler.(blobDeleteHandler)
if !ok {
return regErrUnsupported
}

h, err := v1.NewHash(target)
if err != nil {
return &regError{
Status: http.StatusBadRequest,
Code: "NAME_INVALID",
Message: "invalid digest",
}
}
if err := bdh.Delete(req.Context(), repo, h); err != nil {
return regErrInternal(err)
}
resp.WriteHeader(http.StatusAccepted)
return nil

default:
return &regError{
Status: http.StatusBadRequest,
Expand Down
7 changes: 7 additions & 0 deletions pkg/registry/registry_test.go
Expand Up @@ -149,6 +149,13 @@ func TestCalls(t *testing.T) {
"Docker-Content-Digest": "sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
},
},
{
Description: "DELETE blob",
Digests: map[string]string{"sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae": "foo"},
Method: "DELETE",
URL: "/v2/foo/blobs/sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
Code: http.StatusAccepted,
},
{
Description: "blob url with no container",
Method: "GET",
Expand Down