diff.go 1.8 KB

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