diff_unix.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. //go:build !windows
  2. // +build !windows
  3. package chrootarchive // import "github.com/docker/docker/pkg/chrootarchive"
  4. import (
  5. "io"
  6. "path/filepath"
  7. "github.com/containerd/containerd/pkg/userns"
  8. "github.com/docker/docker/pkg/archive"
  9. "golang.org/x/sys/unix"
  10. )
  11. // applyLayerHandler parses a diff in the standard layer format from `layer`, and
  12. // applies it to the directory `dest`. Returns the size in bytes of the
  13. // contents of the layer.
  14. func applyLayerHandler(dest string, layer io.Reader, options *archive.TarOptions, decompress bool) (size int64, err error) {
  15. dest = filepath.Clean(dest)
  16. if decompress {
  17. decompressed, err := archive.DecompressStream(layer)
  18. if err != nil {
  19. return 0, err
  20. }
  21. defer decompressed.Close()
  22. layer = decompressed
  23. }
  24. if options == nil {
  25. options = &archive.TarOptions{}
  26. }
  27. if userns.RunningInUserNS() {
  28. options.InUserNS = true
  29. }
  30. if options.ExcludePatterns == nil {
  31. options.ExcludePatterns = []string{}
  32. }
  33. type result struct {
  34. layerSize int64
  35. err error
  36. }
  37. done := make(chan result)
  38. err = Go(dest, func() {
  39. // We need to be able to set any perms
  40. _ = unix.Umask(0)
  41. size, err := archive.UnpackLayer("/", layer, options)
  42. done <- result{layerSize: size, err: err}
  43. })
  44. if err != nil {
  45. return 0, err
  46. }
  47. res := <-done
  48. return res.layerSize, res.err
  49. }