1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Handle compressed tars in ApplyLayer

When pulling from a registry we get a compressed tar archive, so
we need to wrap the stream in the right kind of compress reader.

Unfortunately go doesn't have an Xz decompression method, but I
don't think any docker layers use that atm anyway.
This commit is contained in:
Alexander Larsson 2013-12-17 14:19:48 +01:00
parent 124da338fd
commit a96a26c62f
2 changed files with 36 additions and 0 deletions

View file

@ -3,6 +3,8 @@ package archive
import (
"archive/tar"
"bytes"
"compress/gzip"
"compress/bzip2"
"fmt"
"github.com/dotcloud/docker/utils"
"io"
@ -59,6 +61,35 @@ func DetectCompression(source []byte) Compression {
return Uncompressed
}
func DecompressStream(archive io.Reader) (io.Reader, error) {
buf := make([]byte, 10)
totalN := 0
for totalN < 10 {
n, err := archive.Read(buf[totalN:])
if err != nil {
if err == io.EOF {
return nil, fmt.Errorf("Tarball too short")
}
return nil, err
}
totalN += n
utils.Debugf("[tar autodetect] n: %d", n)
}
compression := DetectCompression(buf)
wrap := io.MultiReader(bytes.NewReader(buf), archive)
switch compression {
case Uncompressed:
return wrap, nil
case Gzip:
return gzip.NewReader(wrap)
case Bzip2:
return bzip2.NewReader(wrap), nil
default:
return nil, fmt.Errorf("Unsupported compression format %s", (&compression).Extension())
}
}
func (compression *Compression) Flag() string {
switch *compression {
case Bzip2:

View file

@ -34,6 +34,11 @@ func ApplyLayer(dest string, layer Archive) error {
oldmask := syscall.Umask(0)
defer syscall.Umask(oldmask)
layer, err := DecompressStream(layer)
if err != nil {
return err
}
tr := tar.NewReader(layer)
var dirs []*tar.Header