From 79a2802499fa9849509b27a88adfe40c7176e00f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= Date: Sat, 7 Jan 2017 03:14:02 +0100 Subject: [PATCH 1/2] Fail in HasBlob on unexpected HTTP statuses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code originates in PutBlob, where unexpected HTTP statuses made us abort and not even try to upload; so, it seems that HasBlob should similarly return an error (possibly causing the caller to abort) similarly. The caller can of course still decide to ignore unexpected errors, but this is not an “all is well, blob has not been uploaded” situation (or at least we have been happy enough not to treat it as such a situation in PutBlob so far). Signed-off-by: Miloslav Trmač --- docker/docker_image_dest.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docker/docker_image_dest.go b/docker/docker_image_dest.go index f19e8cfd54..1ce4d25f31 100644 --- a/docker/docker_image_dest.go +++ b/docker/docker_image_dest.go @@ -199,10 +199,8 @@ func (d *dockerImageDestination) HasBlob(info types.BlobInfo) (bool, int64, erro logrus.Debugf("... not present") return false, -1, types.ErrBlobNotFound default: - logrus.Errorf("failed to read from destination repository %s: %v", reference.Path(d.ref.ref), http.StatusText(res.StatusCode)) + return false, -1, errors.Errorf("failed to read from destination repository %s: %v", reference.Path(d.ref.ref), http.StatusText(res.StatusCode)) } - logrus.Debugf("... failed, status %d, ignoring", res.StatusCode) - return false, -1, types.ErrBlobNotFound } func (d *dockerImageDestination) ReapplyBlob(info types.BlobInfo) (types.BlobInfo, error) { From f06fdf3434f2a14c6a007afecb4440183799950d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= Date: Sat, 7 Jan 2017 00:29:51 +0100 Subject: [PATCH 2/2] Call HasBlob in dockerImageDestination.PutBlob MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … so that we only have one copy of the code. Signed-off-by: Miloslav Trmač --- docker/docker_image_dest.go | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/docker/docker_image_dest.go b/docker/docker_image_dest.go index 1ce4d25f31..0d1b0234e4 100644 --- a/docker/docker_image_dest.go +++ b/docker/docker_image_dest.go @@ -100,27 +100,14 @@ func (c *sizeCounter) Write(p []byte) (n int, err error) { // If stream.Read() at any time, ESPECIALLY at end of input, returns an error, PutBlob MUST 1) fail, and 2) delete any data stored so far. func (d *dockerImageDestination) PutBlob(stream io.Reader, inputInfo types.BlobInfo) (types.BlobInfo, error) { if inputInfo.Digest.String() != "" { - checkURL := fmt.Sprintf(blobsURL, reference.Path(d.ref.ref), inputInfo.Digest.String()) - - logrus.Debugf("Checking %s", checkURL) - res, err := d.c.makeRequest("HEAD", checkURL, nil, nil) - if err != nil { + haveBlob, size, err := d.HasBlob(inputInfo) + if err != nil && err != types.ErrBlobNotFound { return types.BlobInfo{}, err } - defer res.Body.Close() - switch res.StatusCode { - case http.StatusOK: - logrus.Debugf("... already exists, not uploading") - return types.BlobInfo{Digest: inputInfo.Digest, Size: getBlobSize(res)}, nil - case http.StatusUnauthorized: - logrus.Debugf("... not authorized") - return types.BlobInfo{}, errors.Errorf("not authorized to read from destination repository %s", reference.Path(d.ref.ref)) - case http.StatusNotFound: - // noop - default: - return types.BlobInfo{}, errors.Errorf("failed to read from destination repository %s: %v", reference.Path(d.ref.ref), http.StatusText(res.StatusCode)) + // Now err == nil || err == types.ErrBlobNotFound + if err == nil && haveBlob { + return types.BlobInfo{Digest: inputInfo.Digest, Size: size}, nil } - logrus.Debugf("... failed, status %d", res.StatusCode) } // FIXME? Chunked upload, progress reporting, etc.