Skip to content

Commit 046536c

Browse files
committed
fixbug: blob for schemav1 could be uncompressed
Signed-off-by: frank yang <[email protected]>
1 parent 63522d9 commit 046536c

File tree

2 files changed

+34
-13
lines changed

2 files changed

+34
-13
lines changed

archive/compression/compression.go

+16-4
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,17 @@ var (
4343
}
4444
)
4545

46+
// DecompressReadCloser include the stream after decompress and the compress method detected.
47+
type DecompressReadCloser interface {
48+
io.ReadCloser
49+
// GetCompression returns the compress method which is used before decompressing
50+
GetCompression() Compression
51+
}
52+
4653
type readCloserWrapper struct {
4754
io.Reader
48-
closer func() error
55+
compression Compression
56+
closer func() error
4957
}
5058

5159
func (r *readCloserWrapper) Close() error {
@@ -55,6 +63,10 @@ func (r *readCloserWrapper) Close() error {
5563
return nil
5664
}
5765

66+
func (r *readCloserWrapper) GetCompression() Compression {
67+
return r.compression
68+
}
69+
5870
type writeCloserWrapper struct {
5971
io.Writer
6072
closer func() error
@@ -84,7 +96,7 @@ func DetectCompression(source []byte) Compression {
8496
}
8597

8698
// DecompressStream decompresses the archive and returns a ReaderCloser with the decompressed archive.
87-
func DecompressStream(archive io.Reader) (io.ReadCloser, error) {
99+
func DecompressStream(archive io.Reader) (DecompressReadCloser, error) {
88100
buf := bufioReader32KPool.Get().(*bufio.Reader)
89101
buf.Reset(archive)
90102
bs, err := buf.Peek(10)
@@ -105,14 +117,14 @@ func DecompressStream(archive io.Reader) (io.ReadCloser, error) {
105117
}
106118
switch compression := DetectCompression(bs); compression {
107119
case Uncompressed:
108-
readBufWrapper := &readCloserWrapper{buf, closer}
120+
readBufWrapper := &readCloserWrapper{buf, compression, closer}
109121
return readBufWrapper, nil
110122
case Gzip:
111123
gzReader, err := gzip.NewReader(buf)
112124
if err != nil {
113125
return nil, err
114126
}
115-
readBufWrapper := &readCloserWrapper{gzReader, closer}
127+
readBufWrapper := &readCloserWrapper{gzReader, compression, closer}
116128
return readBufWrapper, nil
117129
default:
118130
return nil, fmt.Errorf("unsupported compression format %s", (&compression).Extension())

remotes/docker/schema1/converter.go

+18-9
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package schema1
1818

1919
import (
2020
"bytes"
21-
"compress/gzip"
2221
"context"
2322
"encoding/base64"
2423
"encoding/json"
@@ -31,6 +30,7 @@ import (
3130

3231
"golang.org/x/sync/errgroup"
3332

33+
"github.com/containerd/containerd/archive/compression"
3434
"github.com/containerd/containerd/content"
3535
"github.com/containerd/containerd/errdefs"
3636
"github.com/containerd/containerd/images"
@@ -255,8 +255,9 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro
255255
log.G(ctx).Debug("fetch blob")
256256

257257
var (
258-
ref = remotes.MakeRefKey(ctx, desc)
259-
calc = newBlobStateCalculator()
258+
ref = remotes.MakeRefKey(ctx, desc)
259+
calc = newBlobStateCalculator()
260+
compressMethod = compression.Gzip
260261
)
261262

262263
// size may be unknown, set to zero for content ingest
@@ -280,13 +281,14 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro
280281
}
281282
defer ra.Close()
282283

283-
gr, err := gzip.NewReader(content.NewReader(ra))
284+
r, err := compression.DecompressStream(content.NewReader(ra))
284285
if err != nil {
285286
return err
286287
}
287-
defer gr.Close()
288288

289-
_, err = io.Copy(calc, gr)
289+
compressMethod = r.GetCompression()
290+
_, err = io.Copy(calc, r)
291+
r.Close()
290292
if err != nil {
291293
return err
292294
}
@@ -303,13 +305,14 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro
303305
pr, pw := io.Pipe()
304306

305307
eg.Go(func() error {
306-
gr, err := gzip.NewReader(pr)
308+
r, err := compression.DecompressStream(pr)
307309
if err != nil {
308310
return err
309311
}
310-
defer gr.Close()
311312

312-
_, err = io.Copy(calc, gr)
313+
compressMethod = r.GetCompression()
314+
_, err = io.Copy(calc, r)
315+
r.Close()
313316
pr.CloseWithError(err)
314317
return err
315318
})
@@ -333,6 +336,11 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro
333336
desc.Size = info.Size
334337
}
335338

339+
if compressMethod == compression.Uncompressed {
340+
log.G(ctx).WithField("id", desc.Digest).Debugf("changed media type for uncompressed schema1 layer blob")
341+
desc.MediaType = images.MediaTypeDockerSchema2Layer
342+
}
343+
336344
state := calc.State()
337345

338346
c.mu.Lock()
@@ -342,6 +350,7 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro
342350

343351
return nil
344352
}
353+
345354
func (c *Converter) schema1ManifestHistory() ([]ocispec.History, []digest.Digest, error) {
346355
if c.pulledManifest == nil {
347356
return nil, nil, errors.New("missing schema 1 manifest for conversion")

0 commit comments

Comments
 (0)