Merge pull request #11998 from chlins/fix/replication-pull-blob-content-length

fix(replication): ignore the problem of not getting Content-Length fr…
This commit is contained in:
Chlins Zhang 2020-05-29 10:06:44 +08:00 committed by GitHub
commit f862805244
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 8 deletions

View File

@ -351,16 +351,24 @@ func (c *client) PullBlob(repository, digest string) (int64, io.ReadCloser, erro
if err != nil { if err != nil {
return 0, nil, err return 0, nil, err
} }
req.Header.Add(http.CanonicalHeaderKey("Accept-Encoding"), "identity")
resp, err := c.do(req) resp, err := c.do(req)
if err != nil { if err != nil {
return 0, nil, err return 0, nil, err
} }
var size int64
n := resp.Header.Get(http.CanonicalHeaderKey("Content-Length")) n := resp.Header.Get(http.CanonicalHeaderKey("Content-Length"))
size, err := strconv.ParseInt(n, 10, 64) // no content-length is acceptable, which can taken from manifests
if err != nil { if len(n) > 0 {
defer resp.Body.Close() size, err = strconv.ParseInt(n, 10, 64)
return 0, nil, err if err != nil {
defer resp.Body.Close()
return 0, nil, err
}
} }
return size, resp.Body, nil return size, resp.Body, nil
} }

View File

@ -16,12 +16,13 @@ package image
import ( import (
"errors" "errors"
"net/http"
"strings"
"github.com/docker/distribution/manifest/manifestlist" "github.com/docker/distribution/manifest/manifestlist"
"github.com/docker/distribution/manifest/schema1" "github.com/docker/distribution/manifest/schema1"
common_http "github.com/goharbor/harbor/src/common/http" common_http "github.com/goharbor/harbor/src/common/http"
v1 "github.com/opencontainers/image-spec/specs-go/v1" v1 "github.com/opencontainers/image-spec/specs-go/v1"
"net/http"
"strings"
"github.com/docker/distribution" "github.com/docker/distribution"
"github.com/docker/distribution/manifest/schema2" "github.com/docker/distribution/manifest/schema2"
@ -243,12 +244,13 @@ func (t *transfer) copyContent(content distribution.Descriptor, srcRepo, dstRepo
// the media type of the layer or config can be "application/octet-stream", // the media type of the layer or config can be "application/octet-stream",
// schema1.MediaTypeManifestLayer, schema2.MediaTypeLayer, schema2.MediaTypeImageConfig // schema1.MediaTypeManifestLayer, schema2.MediaTypeLayer, schema2.MediaTypeImageConfig
default: default:
return t.copyBlob(srcRepo, dstRepo, digest) return t.copyBlob(srcRepo, dstRepo, digest, content.Size)
} }
} }
// copy the layer or artifact config from the source registry to destination // copy the layer or artifact config from the source registry to destination
func (t *transfer) copyBlob(srcRepo, dstRepo, digest string) error { // the size parameter is taken from manifests.
func (t *transfer) copyBlob(srcRepo, dstRepo, digest string, sizeFromDescriptor int64) error {
if t.shouldStop() { if t.shouldStop() {
return nil return nil
} }
@ -269,6 +271,12 @@ func (t *transfer) copyBlob(srcRepo, dstRepo, digest string) error {
return err return err
} }
defer data.Close() defer data.Close()
// get size 0 from PullBlob, use size from distribution.Descriptor instead.
if size == 0 {
size = sizeFromDescriptor
t.logger.Debugf("the blob size from remote registry is 0, use size %d from manifests instead", size)
}
if err = t.dst.PushBlob(dstRepo, digest, size, data); err != nil { if err = t.dst.PushBlob(dstRepo, digest, size, data); err != nil {
t.logger.Errorf("failed to pushing the blob %s: %v", digest, err) t.logger.Errorf("failed to pushing the blob %s: %v", digest, err)
return err return err