From 611f55e79a2934680cbe843a17bc0c9c2f965a52 Mon Sep 17 00:00:00 2001 From: Adam Wolfe Gordon Date: Mon, 24 Aug 2020 13:49:09 -0600 Subject: [PATCH] Return a sensible error in races between blob upload completions Completing a blob upload is a multi-step process, especially on a storage backend like S3 which lacks a "move" primitive. If a client times out (or disconnects) during a commit, then retries immediately, we'll end up invoking the "resume" logic for the blob upload while the completion from the previous request is still in progress. The resume tries to find the upload's data, but the commit has already moved it to its new location, resulting in a PathNotFound error from the storage driver. Previously, this error was passed back to the HTTP handler and translated into a 500 Internal Server Error. Return ErrBlobUploadUnknown instead, so that the HTTP handler will return a 404. --- registry/storage/linkedblobstore.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/registry/storage/linkedblobstore.go b/registry/storage/linkedblobstore.go index c8bde1ab1..3e3fffe19 100644 --- a/registry/storage/linkedblobstore.go +++ b/registry/storage/linkedblobstore.go @@ -210,7 +210,17 @@ func (lbs *linkedBlobStore) Resume(ctx context.Context, id string) (distribution return nil, err } - return lbs.newBlobUpload(ctx, id, path, startedAt, true) + bw, err := lbs.newBlobUpload(ctx, id, path, startedAt, true) + if err != nil { + switch err := err.(type) { + case driver.PathNotFoundError: + return nil, distribution.ErrBlobUploadUnknown + default: + return nil, err + } + } + + return bw, nil } func (lbs *linkedBlobStore) Delete(ctx context.Context, dgst digest.Digest) error {