Skip to content

Commit

Permalink
Use CompressedSize in legacy/tarball
Browse files Browse the repository at this point in the history
  • Loading branch information
jonjohnsonjr committed Jan 14, 2020
1 parent 5dc7958 commit 303e951
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 9 deletions.
32 changes: 23 additions & 9 deletions pkg/legacy/tarball/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,20 +249,34 @@ func MultiWrite(refToImage map[name.Reference]v1.Image, w io.Writer) error {
return err
}
layerFiles[i] = fmt.Sprintf("%s/layer.tar", cur.config.ID)

u, err := l.Uncompressed()
if err != nil {
return err
}
defer u.Close()
// Reads the entire uncompressed blob into memory! Can be avoided
// for some layer implementations where the uncompressed blob is
// stored on disk and the layer can just stat the file.
uncompressedBlob, err := ioutil.ReadAll(u)
if err != nil {
return err
}
if err := writeTarEntry(tf, layerFiles[i], bytes.NewReader(uncompressedBlob), int64(len(uncompressedBlob))); err != nil {
return err

if partial.HasUncompressedSize(l) {
// If the v1.Layer implements UncompressedSize efficiently, use that
// for the tar header.
size, err := partial.UncompressedSize(l)
if err != nil {
return err
}
if err := writeTarEntry(tf, layerFiles[i], u, size); err != nil {
return err
}
} else {
// Reads the entire uncompressed blob into memory! Can be avoided
// for some layer implementations where the uncompressed blob is
// stored on disk and the layer can just stat the file.
uncompressedBlob, err := ioutil.ReadAll(u)
if err != nil {
return err
}
if err := writeTarEntry(tf, layerFiles[i], bytes.NewReader(uncompressedBlob), int64(len(uncompressedBlob))); err != nil {
return err
}
}
j, err := cur.json()
if err != nil {
Expand Down
55 changes: 55 additions & 0 deletions pkg/legacy/tarball/write_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/mutate"
"github.com/google/go-containerregistry/pkg/v1/partial"
"github.com/google/go-containerregistry/pkg/v1/random"
"github.com/google/go-containerregistry/pkg/v1/tarball"
"github.com/google/go-containerregistry/pkg/v1/types"
Expand Down Expand Up @@ -401,3 +402,57 @@ func TestMultiWriteMismatchedHistory(t *testing.T) {
t.Errorf("Got unexpected error when writing image with mismatched history & layer, got %v, want substring %q", err, want)
}
}

type fastSizeLayer struct {
v1.Layer
size int64
called bool
}

func (l *fastSizeLayer) UncompressedSize() (int64, error) {
l.called = true
return l.size, nil
}

func TestUncompressedSize(t *testing.T) {
// Make a random image
img, err := random.Image(256, 8)
if err != nil {
t.Fatalf("Error creating random image: %v", err)
}

rand, err := random.Layer(1000, types.DockerLayer)
if err != nil {
t.Fatal(err)
}

size, err := partial.UncompressedSize(rand)
if err != nil {
t.Fatal(err)
}

l := &fastSizeLayer{Layer: rand, size: size}

img, err = mutate.AppendLayers(img, l)
if err != nil {
t.Fatal(err)
}
tag, err := name.NewTag("gcr.io/foo/bar:latest", name.StrictValidation)
if err != nil {
t.Fatalf("Error creating test tag: %v", err)
}
// Make a tempfile for tarball writes.
fp, err := ioutil.TempFile("", "")
if err != nil {
t.Fatalf("Error creating temp file: %v", err)
}
t.Log(fp.Name())
defer fp.Close()
defer os.Remove(fp.Name())
if err := Write(tag, img, fp); err != nil {
t.Fatalf("Write(): %v", err)
}
if !l.called {
t.Errorf("expected UncompressedSize to be called, but it wasn't")
}
}

0 comments on commit 303e951

Please sign in to comment.