github.com/rsampaio/docker@v0.7.2-0.20150827203920-fdc73cc3fc31/pkg/chrootarchive/diff_unix.go (about) 1 //+build !windows 2 3 package chrootarchive 4 5 import ( 6 "bytes" 7 "encoding/json" 8 "flag" 9 "fmt" 10 "io/ioutil" 11 "os" 12 "path/filepath" 13 "runtime" 14 15 "github.com/docker/docker/pkg/archive" 16 "github.com/docker/docker/pkg/reexec" 17 "github.com/docker/docker/pkg/system" 18 ) 19 20 type applyLayerResponse struct { 21 LayerSize int64 `json:"layerSize"` 22 } 23 24 // applyLayer is the entry-point for docker-applylayer on re-exec. This is not 25 // used on Windows as it does not support chroot, hence no point sandboxing 26 // through chroot and rexec. 27 func applyLayer() { 28 29 var ( 30 tmpDir = "" 31 err error 32 ) 33 runtime.LockOSThread() 34 flag.Parse() 35 36 if err := chroot(flag.Arg(0)); err != nil { 37 fatal(err) 38 } 39 40 // We need to be able to set any perms 41 oldmask, err := system.Umask(0) 42 defer system.Umask(oldmask) 43 if err != nil { 44 fatal(err) 45 } 46 47 if tmpDir, err = ioutil.TempDir("/", "temp-docker-extract"); err != nil { 48 fatal(err) 49 } 50 51 os.Setenv("TMPDIR", tmpDir) 52 size, err := archive.UnpackLayer("/", os.Stdin) 53 os.RemoveAll(tmpDir) 54 if err != nil { 55 fatal(err) 56 } 57 58 encoder := json.NewEncoder(os.Stdout) 59 if err := encoder.Encode(applyLayerResponse{size}); err != nil { 60 fatal(fmt.Errorf("unable to encode layerSize JSON: %s", err)) 61 } 62 63 flush(os.Stdout) 64 flush(os.Stdin) 65 os.Exit(0) 66 } 67 68 // applyLayerHandler parses a diff in the standard layer format from `layer`, and 69 // applies it to the directory `dest`. Returns the size in bytes of the 70 // contents of the layer. 71 func applyLayerHandler(dest string, layer archive.Reader, decompress bool) (size int64, err error) { 72 dest = filepath.Clean(dest) 73 if decompress { 74 decompressed, err := archive.DecompressStream(layer) 75 if err != nil { 76 return 0, err 77 } 78 defer decompressed.Close() 79 80 layer = decompressed 81 } 82 83 cmd := reexec.Command("docker-applyLayer", dest) 84 cmd.Stdin = layer 85 86 outBuf, errBuf := new(bytes.Buffer), new(bytes.Buffer) 87 cmd.Stdout, cmd.Stderr = outBuf, errBuf 88 89 if err = cmd.Run(); err != nil { 90 return 0, fmt.Errorf("ApplyLayer %s stdout: %s stderr: %s", err, outBuf, errBuf) 91 } 92 93 // Stdout should be a valid JSON struct representing an applyLayerResponse. 94 response := applyLayerResponse{} 95 decoder := json.NewDecoder(outBuf) 96 if err = decoder.Decode(&response); err != nil { 97 return 0, fmt.Errorf("unable to decode ApplyLayer JSON response: %s", err) 98 } 99 100 return response.LayerSize, nil 101 }