handlers: Handle QuotaExceededError and return a DENIED to the client

If we get a QuotaExceededError back from the storage driver when doing a write
for either manifests or blobs, return a DENIED to the client with the message
"quota exceeded".

Signed-off-by: Adam Wolfe Gordon <awg@digitalocean.com>
This commit is contained in:
Adam Wolfe Gordon 2020-10-23 15:45:11 -06:00
parent d192a974fb
commit c1574b87be
2 changed files with 20 additions and 2 deletions

View File

@ -11,6 +11,7 @@ import (
"github.com/docker/distribution/registry/api/errcode" "github.com/docker/distribution/registry/api/errcode"
v2 "github.com/docker/distribution/registry/api/v2" v2 "github.com/docker/distribution/registry/api/v2"
"github.com/docker/distribution/registry/storage" "github.com/docker/distribution/registry/storage"
storagedriver "github.com/docker/distribution/registry/storage/driver"
"github.com/gorilla/handlers" "github.com/gorilla/handlers"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
) )
@ -81,6 +82,8 @@ func (buh *blobUploadHandler) StartBlobUpload(w http.ResponseWriter, r *http.Req
if err := buh.writeBlobCreatedHeaders(w, ebm.Descriptor); err != nil { if err := buh.writeBlobCreatedHeaders(w, ebm.Descriptor); err != nil {
buh.Errors = append(buh.Errors, errcode.ErrorCodeUnknown.WithDetail(err)) buh.Errors = append(buh.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
} }
} else if _, ok := err.(storagedriver.QuotaExceededError); ok {
buh.Errors = append(buh.Errors, errcode.ErrorCodeDenied.WithMessage("quota exceeded"))
} else if err == distribution.ErrUnsupported { } else if err == distribution.ErrUnsupported {
buh.Errors = append(buh.Errors, errcode.ErrorCodeUnsupported) buh.Errors = append(buh.Errors, errcode.ErrorCodeUnsupported)
} else { } else {
@ -137,7 +140,12 @@ func (buh *blobUploadHandler) PatchBlobData(w http.ResponseWriter, r *http.Reque
// TODO(dmcgowan): support Content-Range header to seek and write range // TODO(dmcgowan): support Content-Range header to seek and write range
if err := copyFullPayload(buh, w, r, buh.Upload, -1, "blob PATCH"); err != nil { if err := copyFullPayload(buh, w, r, buh.Upload, -1, "blob PATCH"); err != nil {
switch err := err.(type) {
case storagedriver.QuotaExceededError:
buh.Errors = append(buh.Errors, errcode.ErrorCodeDenied.WithMessage("quota exceeded"))
default:
buh.Errors = append(buh.Errors, errcode.ErrorCodeUnknown.WithDetail(err.Error())) buh.Errors = append(buh.Errors, errcode.ErrorCodeUnknown.WithDetail(err.Error()))
}
return return
} }
@ -185,7 +193,12 @@ func (buh *blobUploadHandler) BlobUploadComplete(w http.ResponseWriter, r *http.
} }
if err := copyFullPayload(buh, w, r, buh.Upload, -1, "blob PUT"); err != nil { if err := copyFullPayload(buh, w, r, buh.Upload, -1, "blob PUT"); err != nil {
switch err := err.(type) {
case storagedriver.QuotaExceededError:
buh.Errors = append(buh.Errors, errcode.ErrorCodeDenied.WithMessage("quota exceeded"))
default:
buh.Errors = append(buh.Errors, errcode.ErrorCodeUnknown.WithDetail(err.Error())) buh.Errors = append(buh.Errors, errcode.ErrorCodeUnknown.WithDetail(err.Error()))
}
return return
} }
@ -201,6 +214,8 @@ func (buh *blobUploadHandler) BlobUploadComplete(w http.ResponseWriter, r *http.
switch err := err.(type) { switch err := err.(type) {
case distribution.ErrBlobInvalidDigest: case distribution.ErrBlobInvalidDigest:
buh.Errors = append(buh.Errors, v2.ErrorCodeDigestInvalid.WithDetail(err)) buh.Errors = append(buh.Errors, v2.ErrorCodeDigestInvalid.WithDetail(err))
case storagedriver.QuotaExceededError:
buh.Errors = append(buh.Errors, errcode.ErrorCodeDenied.WithMessage("quota exceeded"))
case errcode.Error: case errcode.Error:
buh.Errors = append(buh.Errors, err) buh.Errors = append(buh.Errors, err)
default: default:

View File

@ -17,6 +17,7 @@ import (
"github.com/docker/distribution/registry/api/errcode" "github.com/docker/distribution/registry/api/errcode"
v2 "github.com/docker/distribution/registry/api/v2" v2 "github.com/docker/distribution/registry/api/v2"
"github.com/docker/distribution/registry/auth" "github.com/docker/distribution/registry/auth"
storagedriver "github.com/docker/distribution/registry/storage/driver"
"github.com/gorilla/handlers" "github.com/gorilla/handlers"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1" v1 "github.com/opencontainers/image-spec/specs-go/v1"
@ -369,6 +370,8 @@ func (imh *manifestHandler) PutManifest(w http.ResponseWriter, r *http.Request)
} }
} }
} }
case storagedriver.QuotaExceededError:
imh.Errors = append(imh.Errors, errcode.ErrorCodeDenied.WithMessage("quota exceeded"))
case errcode.Error: case errcode.Error:
imh.Errors = append(imh.Errors, err) imh.Errors = append(imh.Errors, err)
default: default: