diff.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package chrootarchive
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "flag"
  6. "fmt"
  7. "io"
  8. "io/ioutil"
  9. "os"
  10. "path/filepath"
  11. "runtime"
  12. "syscall"
  13. "github.com/docker/docker/pkg/archive"
  14. "github.com/docker/docker/pkg/reexec"
  15. )
  16. type applyLayerResponse struct {
  17. LayerSize int64 `json:"layerSize"`
  18. }
  19. func applyLayer() {
  20. runtime.LockOSThread()
  21. flag.Parse()
  22. if err := chroot(flag.Arg(0)); err != nil {
  23. fatal(err)
  24. }
  25. // We need to be able to set any perms
  26. oldmask := syscall.Umask(0)
  27. defer syscall.Umask(oldmask)
  28. tmpDir, err := ioutil.TempDir("/", "temp-docker-extract")
  29. if err != nil {
  30. fatal(err)
  31. }
  32. os.Setenv("TMPDIR", tmpDir)
  33. size, err := archive.UnpackLayer("/", os.Stdin)
  34. os.RemoveAll(tmpDir)
  35. if err != nil {
  36. fatal(err)
  37. }
  38. encoder := json.NewEncoder(os.Stdout)
  39. if err := encoder.Encode(applyLayerResponse{size}); err != nil {
  40. fatal(fmt.Errorf("unable to encode layerSize JSON: %s", err))
  41. }
  42. flush(os.Stdout)
  43. flush(os.Stdin)
  44. os.Exit(0)
  45. }
  46. func ApplyLayer(dest string, layer archive.ArchiveReader) (size int64, err error) {
  47. dest = filepath.Clean(dest)
  48. decompressed, err := archive.DecompressStream(layer)
  49. if err != nil {
  50. return 0, err
  51. }
  52. defer func() {
  53. if c, ok := decompressed.(io.Closer); ok {
  54. c.Close()
  55. }
  56. }()
  57. cmd := reexec.Command("docker-applyLayer", dest)
  58. cmd.Stdin = decompressed
  59. outBuf, errBuf := new(bytes.Buffer), new(bytes.Buffer)
  60. cmd.Stdout, cmd.Stderr = outBuf, errBuf
  61. if err = cmd.Run(); err != nil {
  62. return 0, fmt.Errorf("ApplyLayer %s stdout: %s stderr: %s", err, outBuf, errBuf)
  63. }
  64. // Stdout should be a valid JSON struct representing an applyLayerResponse.
  65. response := applyLayerResponse{}
  66. decoder := json.NewDecoder(outBuf)
  67. if err = decoder.Decode(&response); err != nil {
  68. return 0, fmt.Errorf("unable to decode ApplyLayer JSON response: %s", err)
  69. }
  70. return response.LayerSize, nil
  71. }