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