github.com/lazyboychen7/engine@v17.12.1-ce-rc2+incompatible/pkg/chrootarchive/archive.go (about)

     1  package chrootarchive
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  
    10  	"github.com/docker/docker/pkg/archive"
    11  	"github.com/docker/docker/pkg/idtools"
    12  )
    13  
    14  // NewArchiver returns a new Archiver which uses chrootarchive.Untar
    15  func NewArchiver(idMappings *idtools.IDMappings) *archive.Archiver {
    16  	if idMappings == nil {
    17  		idMappings = &idtools.IDMappings{}
    18  	}
    19  	return &archive.Archiver{
    20  		Untar:         Untar,
    21  		IDMappingsVar: idMappings,
    22  	}
    23  }
    24  
    25  // Untar reads a stream of bytes from `archive`, parses it as a tar archive,
    26  // and unpacks it into the directory at `dest`.
    27  // The archive may be compressed with one of the following algorithms:
    28  //  identity (uncompressed), gzip, bzip2, xz.
    29  func Untar(tarArchive io.Reader, dest string, options *archive.TarOptions) error {
    30  	return untarHandler(tarArchive, dest, options, true)
    31  }
    32  
    33  // UntarUncompressed reads a stream of bytes from `archive`, parses it as a tar archive,
    34  // and unpacks it into the directory at `dest`.
    35  // The archive must be an uncompressed stream.
    36  func UntarUncompressed(tarArchive io.Reader, dest string, options *archive.TarOptions) error {
    37  	return untarHandler(tarArchive, dest, options, false)
    38  }
    39  
    40  // Handler for teasing out the automatic decompression
    41  func untarHandler(tarArchive io.Reader, dest string, options *archive.TarOptions, decompress bool) error {
    42  	if tarArchive == nil {
    43  		return fmt.Errorf("Empty archive")
    44  	}
    45  	if options == nil {
    46  		options = &archive.TarOptions{}
    47  	}
    48  	if options.ExcludePatterns == nil {
    49  		options.ExcludePatterns = []string{}
    50  	}
    51  
    52  	idMappings := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps)
    53  	rootIDs := idMappings.RootPair()
    54  
    55  	dest = filepath.Clean(dest)
    56  	if _, err := os.Stat(dest); os.IsNotExist(err) {
    57  		if err := idtools.MkdirAllAndChownNew(dest, 0755, rootIDs); err != nil {
    58  			return err
    59  		}
    60  	}
    61  
    62  	r := ioutil.NopCloser(tarArchive)
    63  	if decompress {
    64  		decompressedArchive, err := archive.DecompressStream(tarArchive)
    65  		if err != nil {
    66  			return err
    67  		}
    68  		defer decompressedArchive.Close()
    69  		r = decompressedArchive
    70  	}
    71  
    72  	return invokeUnpack(r, dest, options)
    73  }