Merge pull request #1792 from dmcgowan/schema1-resumeable

Support unknown size from schema 1 manifests
This commit is contained in:
Phil Estes 2017-11-22 21:35:22 -05:00 committed by GitHub
commit 908df29ad5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 4 deletions

View File

@ -64,6 +64,9 @@ func (hrs *httpReadSeeker) Seek(offset int64, whence int) (int64, error) {
case io.SeekCurrent: case io.SeekCurrent:
abs += offset abs += offset
case io.SeekEnd: case io.SeekEnd:
if hrs.size == -1 {
return 0, errors.Wrap(errdefs.ErrUnavailable, "Fetcher.Seek: unknown size, cannot seek from end")
}
abs = hrs.size + offset abs = hrs.size + offset
default: default:
return 0, errors.Wrap(errdefs.ErrInvalidArgument, "Fetcher.Seek: invalid whence") return 0, errors.Wrap(errdefs.ErrInvalidArgument, "Fetcher.Seek: invalid whence")
@ -93,7 +96,7 @@ func (hrs *httpReadSeeker) reader() (io.Reader, error) {
return hrs.rc, nil return hrs.rc, nil
} }
if hrs.offset < hrs.size { if hrs.size == -1 || hrs.offset < hrs.size {
// only try to reopen the body request if we are seeking to a value // only try to reopen the body request if we are seeking to a value
// less than the actual size. // less than the actual size.
if hrs.open == nil { if hrs.open == nil {

View File

@ -83,6 +83,7 @@ func (c *Converter) Handle(ctx context.Context, desc ocispec.Descriptor) ([]ocis
{ {
MediaType: images.MediaTypeDockerSchema2LayerGzip, MediaType: images.MediaTypeDockerSchema2LayerGzip,
Digest: c.pulledManifest.FSLayers[i].BlobSum, Digest: c.pulledManifest.FSLayers[i].BlobSum,
Size: -1,
}, },
}, descs...) }, descs...)
} }
@ -209,10 +210,16 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro
ref = remotes.MakeRefKey(ctx, desc) ref = remotes.MakeRefKey(ctx, desc)
calc = newBlobStateCalculator() calc = newBlobStateCalculator()
retry = 16 retry = 16
size = desc.Size
) )
// size may be unknown, set to zero for content ingest
if size == -1 {
size = 0
}
tryit: tryit:
cw, err := c.contentStore.Writer(ctx, ref, desc.Size, desc.Digest) cw, err := c.contentStore.Writer(ctx, ref, size, desc.Digest)
if err != nil { if err != nil {
if errdefs.IsUnavailable(err) { if errdefs.IsUnavailable(err) {
select { select {
@ -273,7 +280,8 @@ tryit:
eg.Go(func() error { eg.Go(func() error {
defer pw.Close() defer pw.Close()
return content.Copy(ctx, cw, io.TeeReader(rc, pw), desc.Size, desc.Digest)
return content.Copy(ctx, cw, io.TeeReader(rc, pw), size, desc.Digest)
}) })
if err := eg.Wait(); err != nil { if err := eg.Wait(); err != nil {
@ -281,7 +289,7 @@ tryit:
} }
} }
if desc.Size == 0 { if desc.Size == -1 {
info, err := c.contentStore.Info(ctx, desc.Digest) info, err := c.contentStore.Info(ctx, desc.Digest)
if err != nil { if err != nil {
return errors.Wrap(err, "failed to get blob info") return errors.Wrap(err, "failed to get blob info")