github.com/wulonghui/docker@v1.8.0-rc2/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/system" 12 ) 13 14 var chrootArchiver = &archive.Archiver{Untar: Untar} 15 16 // Untar reads a stream of bytes from `archive`, parses it as a tar archive, 17 // and unpacks it into the directory at `dest`. 18 // The archive may be compressed with one of the following algorithms: 19 // identity (uncompressed), gzip, bzip2, xz. 20 func Untar(tarArchive io.Reader, dest string, options *archive.TarOptions) error { 21 return untarHandler(tarArchive, dest, options, true) 22 } 23 24 // UntarUncompressed reads a stream of bytes from `archive`, parses it as a tar archive, 25 // and unpacks it into the directory at `dest`. 26 // The archive must be an uncompressed stream. 27 func UntarUncompressed(tarArchive io.Reader, dest string, options *archive.TarOptions) error { 28 return untarHandler(tarArchive, dest, options, false) 29 } 30 31 // Handler for teasing out the automatic decompression 32 func untarHandler(tarArchive io.Reader, dest string, options *archive.TarOptions, decompress bool) error { 33 34 if tarArchive == nil { 35 return fmt.Errorf("Empty archive") 36 } 37 if options == nil { 38 options = &archive.TarOptions{} 39 } 40 if options.ExcludePatterns == nil { 41 options.ExcludePatterns = []string{} 42 } 43 44 dest = filepath.Clean(dest) 45 if _, err := os.Stat(dest); os.IsNotExist(err) { 46 if err := system.MkdirAll(dest, 0777); err != nil { 47 return err 48 } 49 } 50 51 r := ioutil.NopCloser(tarArchive) 52 if decompress { 53 decompressedArchive, err := archive.DecompressStream(tarArchive) 54 if err != nil { 55 return err 56 } 57 defer decompressedArchive.Close() 58 r = decompressedArchive 59 } 60 61 return invokeUnpack(r, dest, options) 62 } 63 64 // TarUntar is a convenience function which calls Tar and Untar, with the output of one piped into the other. 65 // If either Tar or Untar fails, TarUntar aborts and returns the error. 66 func TarUntar(src, dst string) error { 67 return chrootArchiver.TarUntar(src, dst) 68 } 69 70 // CopyWithTar creates a tar archive of filesystem path `src`, and 71 // unpacks it at filesystem path `dst`. 72 // The archive is streamed directly with fixed buffering and no 73 // intermediary disk IO. 74 func CopyWithTar(src, dst string) error { 75 return chrootArchiver.CopyWithTar(src, dst) 76 } 77 78 // CopyFileWithTar emulates the behavior of the 'cp' command-line 79 // for a single file. It copies a regular file from path `src` to 80 // path `dst`, and preserves all its metadata. 81 // 82 // If `dst` ends with a trailing slash '/' ('\' on Windows), the final 83 // destination path will be `dst/base(src)` or `dst\base(src)` 84 func CopyFileWithTar(src, dst string) (err error) { 85 return chrootArchiver.CopyFileWithTar(src, dst) 86 } 87 88 // UntarPath is a convenience function which looks for an archive 89 // at filesystem path `src`, and unpacks it at `dst`. 90 func UntarPath(src, dst string) error { 91 return chrootArchiver.UntarPath(src, dst) 92 }