github.com/ssdev-go/moby@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 }