Signed-off-by: John Howard <jhoward@microsoft.com>
| ... | ... |
@@ -30,9 +30,15 @@ func untar() {
|
| 30 | 30 |
|
| 31 | 31 |
var options *archive.TarOptions |
| 32 | 32 |
|
| 33 |
- //read the options from the pipe "ExtraFiles" |
|
| 34 |
- if err := json.NewDecoder(os.NewFile(3, "options")).Decode(&options); err != nil {
|
|
| 35 |
- fatal(err) |
|
| 33 |
+ if runtime.GOOS != "windows" {
|
|
| 34 |
+ //read the options from the pipe "ExtraFiles" |
|
| 35 |
+ if err := json.NewDecoder(os.NewFile(3, "options")).Decode(&options); err != nil {
|
|
| 36 |
+ fatal(err) |
|
| 37 |
+ } |
|
| 38 |
+ } else {
|
|
| 39 |
+ if err := json.Unmarshal([]byte(os.Getenv("OPT")), &options); err != nil {
|
|
| 40 |
+ fatal(err) |
|
| 41 |
+ } |
|
| 36 | 42 |
} |
| 37 | 43 |
|
| 38 | 44 |
if err := chroot(flag.Arg(0)); err != nil {
|
| ... | ... |
@@ -68,37 +74,68 @@ func Untar(tarArchive io.Reader, dest string, options *archive.TarOptions) error |
| 68 | 68 |
if err != nil {
|
| 69 | 69 |
return err |
| 70 | 70 |
} |
| 71 |
+ |
|
| 72 |
+ var data []byte |
|
| 73 |
+ var r, w *os.File |
|
| 71 | 74 |
defer decompressedArchive.Close() |
| 72 | 75 |
|
| 73 |
- // We can't pass a potentially large exclude list directly via cmd line |
|
| 74 |
- // because we easily overrun the kernel's max argument/environment size |
|
| 75 |
- // when the full image list is passed (e.g. when this is used by |
|
| 76 |
- // `docker load`). We will marshall the options via a pipe to the |
|
| 77 |
- // child |
|
| 78 |
- r, w, err := os.Pipe() |
|
| 79 |
- if err != nil {
|
|
| 80 |
- return fmt.Errorf("Untar pipe failure: %v", err)
|
|
| 76 |
+ if runtime.GOOS != "windows" {
|
|
| 77 |
+ // We can't pass a potentially large exclude list directly via cmd line |
|
| 78 |
+ // because we easily overrun the kernel's max argument/environment size |
|
| 79 |
+ // when the full image list is passed (e.g. when this is used by |
|
| 80 |
+ // `docker load`). We will marshall the options via a pipe to the |
|
| 81 |
+ // child |
|
| 82 |
+ |
|
| 83 |
+ // This solution won't work on Windows as it will fail in golang |
|
| 84 |
+ // exec_windows.go as at the lowest layer because attr.Files > 3 |
|
| 85 |
+ r, w, err = os.Pipe() |
|
| 86 |
+ if err != nil {
|
|
| 87 |
+ return fmt.Errorf("Untar pipe failure: %v", err)
|
|
| 88 |
+ } |
|
| 89 |
+ } else {
|
|
| 90 |
+ // We can't pass the exclude list directly via cmd line |
|
| 91 |
+ // because we easily overrun the shell max argument list length |
|
| 92 |
+ // when the full image list is passed (e.g. when this is used |
|
| 93 |
+ // by `docker load`). Instead we will add the JSON marshalled |
|
| 94 |
+ // and placed in the env, which has significantly larger |
|
| 95 |
+ // max size |
|
| 96 |
+ data, err = json.Marshal(options) |
|
| 97 |
+ if err != nil {
|
|
| 98 |
+ return fmt.Errorf("Untar json encode: %v", err)
|
|
| 99 |
+ } |
|
| 81 | 100 |
} |
| 101 |
+ |
|
| 82 | 102 |
cmd := reexec.Command("docker-untar", dest)
|
| 83 | 103 |
cmd.Stdin = decompressedArchive |
| 84 |
- cmd.ExtraFiles = append(cmd.ExtraFiles, r) |
|
| 85 |
- output := bytes.NewBuffer(nil) |
|
| 86 |
- cmd.Stdout = output |
|
| 87 |
- cmd.Stderr = output |
|
| 88 | 104 |
|
| 89 |
- if err := cmd.Start(); err != nil {
|
|
| 90 |
- return fmt.Errorf("Untar error on re-exec cmd: %v", err)
|
|
| 91 |
- } |
|
| 92 |
- //write the options to the pipe for the untar exec to read |
|
| 93 |
- if err := json.NewEncoder(w).Encode(options); err != nil {
|
|
| 94 |
- return fmt.Errorf("Untar json encode to pipe failed: %v", err)
|
|
| 95 |
- } |
|
| 96 |
- w.Close() |
|
| 105 |
+ if runtime.GOOS != "windows" {
|
|
| 106 |
+ cmd.ExtraFiles = append(cmd.ExtraFiles, r) |
|
| 107 |
+ output := bytes.NewBuffer(nil) |
|
| 108 |
+ cmd.Stdout = output |
|
| 109 |
+ cmd.Stderr = output |
|
| 110 |
+ |
|
| 111 |
+ if err := cmd.Start(); err != nil {
|
|
| 112 |
+ return fmt.Errorf("Untar error on re-exec cmd: %v", err)
|
|
| 113 |
+ } |
|
| 114 |
+ //write the options to the pipe for the untar exec to read |
|
| 115 |
+ if err := json.NewEncoder(w).Encode(options); err != nil {
|
|
| 116 |
+ return fmt.Errorf("Untar json encode to pipe failed: %v", err)
|
|
| 117 |
+ } |
|
| 118 |
+ w.Close() |
|
| 97 | 119 |
|
| 98 |
- if err := cmd.Wait(); err != nil {
|
|
| 99 |
- return fmt.Errorf("Untar re-exec error: %v: output: %s", err, output)
|
|
| 120 |
+ if err := cmd.Wait(); err != nil {
|
|
| 121 |
+ return fmt.Errorf("Untar re-exec error: %v: output: %s", err, output)
|
|
| 122 |
+ } |
|
| 123 |
+ return nil |
|
| 124 |
+ } else {
|
|
| 125 |
+ cmd.Env = append(cmd.Env, fmt.Sprintf("OPT=%s", data))
|
|
| 126 |
+ out, err := cmd.CombinedOutput() |
|
| 127 |
+ if err != nil {
|
|
| 128 |
+ return fmt.Errorf("Untar %s %s", err, out)
|
|
| 129 |
+ } |
|
| 130 |
+ return nil |
|
| 100 | 131 |
} |
| 101 |
- return nil |
|
| 132 |
+ |
|
| 102 | 133 |
} |
| 103 | 134 |
|
| 104 | 135 |
func TarUntar(src, dst string) error {
|