github.com/campoy/docker@v1.8.0-rc1/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 // ApplyLayer 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 ApplyLayer(dest string, layer archive.ArchiveReader) (size int64, err error) { 72 dest = filepath.Clean(dest) 73 decompressed, err := archive.DecompressStream(layer) 74 if err != nil { 75 return 0, err 76 } 77 78 defer decompressed.Close() 79 80 cmd := reexec.Command("docker-applyLayer", dest) 81 cmd.Stdin = decompressed 82 83 outBuf, errBuf := new(bytes.Buffer), new(bytes.Buffer) 84 cmd.Stdout, cmd.Stderr = outBuf, errBuf 85 86 if err = cmd.Run(); err != nil { 87 return 0, fmt.Errorf("ApplyLayer %s stdout: %s stderr: %s", err, outBuf, errBuf) 88 } 89 90 // Stdout should be a valid JSON struct representing an applyLayerResponse. 91 response := applyLayerResponse{} 92 decoder := json.NewDecoder(outBuf) 93 if err = decoder.Decode(&response); err != nil { 94 return 0, fmt.Errorf("unable to decode ApplyLayer JSON response: %s", err) 95 } 96 97 return response.LayerSize, nil 98 }