Correct tarsum finish logic
Tarsum now correctly closes the internal TarWriter which appends a block of 1024 zeros to the end of the returned archive. Signed-off-by: Josh Hawn <josh.hawn@docker.com>
This commit is contained in:
parent
ed3d01687d
commit
96721b293c
2 changed files with 80 additions and 0 deletions
|
@ -148,6 +148,12 @@ func (ts *tarSum) Read(buf []byte) (int, error) {
|
||||||
currentHeader, err := ts.tarR.Next()
|
currentHeader, err := ts.tarR.Next()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
|
if err := ts.tarW.Close(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if _, err := io.Copy(ts.gz, ts.bufTar); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
if err := ts.gz.Close(); err != nil {
|
if err := ts.gz.Close(); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,10 @@ package tarsum
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"compress/gzip"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
@ -101,6 +104,77 @@ func sizedTar(opts sizedOptions) io.Reader {
|
||||||
return fh
|
return fh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func emptyTarSum(gzip bool) (TarSum, error) {
|
||||||
|
reader, writer := io.Pipe()
|
||||||
|
tarWriter := tar.NewWriter(writer)
|
||||||
|
|
||||||
|
// Immediately close tarWriter and write-end of the
|
||||||
|
// Pipe in a separate goroutine so we don't block.
|
||||||
|
go func() {
|
||||||
|
tarWriter.Close()
|
||||||
|
writer.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
return NewTarSum(reader, !gzip, Version0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestEmptyTar tests that tarsum does not fail to read an empty tar
|
||||||
|
// and correctly returns the hex digest of an empty hash.
|
||||||
|
func TestEmptyTar(t *testing.T) {
|
||||||
|
// Test without gzip.
|
||||||
|
ts, err := emptyTarSum(false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
zeroBlock := make([]byte, 1024)
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
|
n, err := io.Copy(buf, ts)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n != int64(len(zeroBlock)) || !bytes.Equal(buf.Bytes(), zeroBlock) {
|
||||||
|
t.Fatalf("tarSum did not write the correct number of zeroed bytes: %d", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedSum := ts.Version().String() + "+sha256:" + hex.EncodeToString(sha256.New().Sum(nil))
|
||||||
|
resultSum := ts.Sum(nil)
|
||||||
|
|
||||||
|
if resultSum != expectedSum {
|
||||||
|
t.Fatalf("expected [%s] but got [%s]", expectedSum, resultSum)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test with gzip.
|
||||||
|
ts, err = emptyTarSum(true)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
buf.Reset()
|
||||||
|
|
||||||
|
n, err = io.Copy(buf, ts)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bufgz := new(bytes.Buffer)
|
||||||
|
gz := gzip.NewWriter(bufgz)
|
||||||
|
n, err = io.Copy(gz, bytes.NewBuffer(zeroBlock))
|
||||||
|
gz.Close()
|
||||||
|
gzBytes := bufgz.Bytes()
|
||||||
|
|
||||||
|
if n != int64(len(zeroBlock)) || !bytes.Equal(buf.Bytes(), gzBytes) {
|
||||||
|
t.Fatalf("tarSum did not write the correct number of gzipped-zeroed bytes: %d", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
resultSum = ts.Sum(nil)
|
||||||
|
|
||||||
|
if resultSum != expectedSum {
|
||||||
|
t.Fatalf("expected [%s] but got [%s]", expectedSum, resultSum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestTarSums(t *testing.T) {
|
func TestTarSums(t *testing.T) {
|
||||||
for _, layer := range testLayers {
|
for _, layer := range testLayers {
|
||||||
var (
|
var (
|
||||||
|
|
Loading…
Reference in a new issue