func makeTestLayer(paths []string) (rc io.ReadCloser, err error) { tmpDir, err := ioutil.TempDir("", "graphdriver-test-mklayer") if err != nil { return } defer func() { if err != nil { os.RemoveAll(tmpDir) } }() for _, p := range paths { if p[len(p)-1] == filepath.Separator { if err = os.MkdirAll(filepath.Join(tmpDir, p), 0700); err != nil { return } } else { if err = ioutil.WriteFile(filepath.Join(tmpDir, p), nil, 0600); err != nil { return } } } archive, err := Tar(tmpDir, Uncompressed) if err != nil { return } return ioutils.NewReadCloserWrapper(archive, func() error { err := archive.Close() os.RemoveAll(tmpDir) return err }), nil }
// NewReadCloserWrapper returns a wrapper which puts the bufio.Reader back // into the pool and closes the reader if it's an io.ReadCloser. func (bufPool *BufioReaderPool) NewReadCloserWrapper(buf *bufio.Reader, r io.Reader) io.ReadCloser { return ioutils.NewReadCloserWrapper(r, func() error { if readCloser, ok := r.(io.ReadCloser); ok { readCloser.Close() } bufPool.Put(buf) return nil }) }
// DecompressStream decompress the archive and returns a ReaderCloser with the decompressed archive. func DecompressStream(archive io.Reader) (io.ReadCloser, error) { p := pools.BufioReader32KPool buf := p.Get(archive) bs, err := buf.Peek(10) if err != nil && err != io.EOF { // Note: we'll ignore any io.EOF error because there are some odd // cases where the layer.tar file will be empty (zero bytes) and // that results in an io.EOF from the Peek() call. So, in those // cases we'll just treat it as a non-compressed stream and // that means just create an empty layer. // See Issue 18170 return nil, err } compression := DetectCompression(bs) switch compression { case Uncompressed: readBufWrapper := p.NewReadCloserWrapper(buf, buf) return readBufWrapper, nil case Gzip: gzReader, err := gzip.NewReader(buf) if err != nil { return nil, err } readBufWrapper := p.NewReadCloserWrapper(buf, gzReader) return readBufWrapper, nil case Bzip2: bz2Reader := bzip2.NewReader(buf) readBufWrapper := p.NewReadCloserWrapper(buf, bz2Reader) return readBufWrapper, nil case Xz: xzReader, chdone, err := xzDecompress(buf) if err != nil { return nil, err } readBufWrapper := p.NewReadCloserWrapper(buf, xzReader) return ioutils.NewReadCloserWrapper(readBufWrapper, func() error { <-chdone return readBufWrapper.Close() }), nil default: return nil, fmt.Errorf("Unsupported compression format %s", (&compression).Extension()) } }