From e26f2878d301cb097edbe473a9bb9696ba1a65e3 Mon Sep 17 00:00:00 2001 From: Riyaz Faizullabhoy Date: Thu, 11 May 2017 17:32:32 -0700 Subject: [PATCH] Revert "Use Docker API for run" This reverts commit ec6fea1d679012b9633a476f337f6602c665dfe9. --- cmd/moby/docker.go | 140 +++++++++++++++++++++++---------------------- cmd/moby/output.go | 4 +- 2 files changed, 73 insertions(+), 71 deletions(-) diff --git a/cmd/moby/docker.go b/cmd/moby/docker.go index a83ee766c..4bd4af5fd 100644 --- a/cmd/moby/docker.go +++ b/cmd/moby/docker.go @@ -20,89 +20,91 @@ import ( "golang.org/x/net/context" ) -func dockerRunInput(input io.Reader, image string, args ...string) ([]byte, error) { - log.Debugf("docker run (input): %s %s", image, strings.Join(args, " ")) - - cli, err := dockerClient() +func dockerRun(args ...string) ([]byte, error) { + log.Debugf("docker run: %s", strings.Join(args, " ")) + docker, err := exec.LookPath("docker") if err != nil { - return []byte{}, errors.New("could not initialize Docker API client") + return []byte{}, errors.New("Docker does not seem to be installed") } + args = append([]string{"run", "--rm", "--log-driver=none"}, args...) + cmd := exec.Command(docker, args...) - origStdin := os.Stdin - defer func() { - os.Stdin = origStdin - }() - - // write input to a file - rawInput, err := ioutil.ReadAll(input) - if err != nil { - return []byte{}, errors.New("could not read input") - } - tmpInputFileName := "tmpInput" - if err := ioutil.WriteFile(tmpInputFileName, rawInput, 0644); err != nil { - return []byte{}, errors.New("could not stage input to file") - } - inputFile, err := os.Open(tmpInputFileName) - if err != nil { - return []byte{}, errors.New("could not open input file for container stdin") - } - defer os.Remove(tmpInputFileName) - - os.Stdin = inputFile - - var resp container.ContainerCreateCreatedBody - resp, err = cli.ContainerCreate(context.Background(), &container.Config{ - Image: image, - Cmd: args, - AttachStdout: true, - AttachStdin: true, - }, &container.HostConfig{ - AutoRemove: true, - LogConfig: container.LogConfig{Type: "none"}, - }, nil, "") - if err != nil { - // if the image wasn't found, try to do a pull and another create - if client.IsErrNotFound(err) { - if err := dockerPull(image, false); err != nil { - return []byte{}, err - } - resp, err = cli.ContainerCreate(context.Background(), &container.Config{ - Image: image, - Cmd: args, - AttachStdout: true, - AttachStdin: true, - }, &container.HostConfig{ - AutoRemove: true, - LogConfig: container.LogConfig{Type: "none"}, - }, nil, "") - // if we error again, bail - if err != nil { - return []byte{}, err - } - } - return []byte{}, err - } - - hijackedResp, err := cli.ContainerAttach(context.Background(), resp.ID, types.ContainerAttachOptions{ - Stdout: true, - Stdin: true, - Stream: true, - }) + stderrPipe, err := cmd.StderrPipe() if err != nil { return []byte{}, err } - if err := cli.ContainerStart(context.Background(), resp.ID, types.ContainerStartOptions{}); err != nil { + stdoutPipe, err := cmd.StdoutPipe() + if err != nil { return []byte{}, err } - if _, err = cli.ContainerWait(context.Background(), resp.ID); err != nil { + err = cmd.Start() + if err != nil { return []byte{}, err } - out, _ := ioutil.ReadAll(hijackedResp.Reader) + stdout, err := ioutil.ReadAll(stdoutPipe) + if err != nil { + return []byte{}, err + } + + stderr, err := ioutil.ReadAll(stderrPipe) + if err != nil { + return []byte{}, err + } + + err = cmd.Wait() + if err != nil { + return []byte{}, fmt.Errorf("%v: %s", err, stderr) + } + + log.Debugf("docker run: %s...Done", strings.Join(args, " ")) + return stdout, nil +} + +func dockerRunInput(input io.Reader, args ...string) ([]byte, error) { + log.Debugf("docker run (input): %s", strings.Join(args, " ")) + docker, err := exec.LookPath("docker") + if err != nil { + return []byte{}, errors.New("Docker does not seem to be installed") + } + args = append([]string{"run", "--rm", "-i"}, args...) + cmd := exec.Command(docker, args...) + cmd.Stdin = input + + stderrPipe, err := cmd.StderrPipe() + if err != nil { + return []byte{}, err + } + + stdoutPipe, err := cmd.StdoutPipe() + if err != nil { + return []byte{}, err + } + + err = cmd.Start() + if err != nil { + return []byte{}, err + } + + stdout, err := ioutil.ReadAll(stdoutPipe) + if err != nil { + return []byte{}, err + } + + stderr, err := ioutil.ReadAll(stderrPipe) + if err != nil { + return []byte{}, err + } + + err = cmd.Wait() + if err != nil { + return []byte{}, fmt.Errorf("%v: %s", err, stderr) + } + log.Debugf("docker run (input): %s...Done", strings.Join(args, " ")) - return out, nil + return stdout, nil } func dockerCreate(image string) (string, error) { diff --git a/cmd/moby/output.go b/cmd/moby/output.go index 664574ce0..918987f56 100644 --- a/cmd/moby/output.go +++ b/cmd/moby/output.go @@ -158,7 +158,7 @@ func outputImg(image, filename string, kernel []byte, initrd []byte, args ...str if err != nil { return err } - img, err := dockerRunInput(buf, image, args...) + img, err := dockerRunInput(buf, append([]string{image}, args...)...) if err != nil { return err } @@ -176,7 +176,7 @@ func outputISO(image, filename string, kernel []byte, initrd []byte, args ...str if err != nil { return err } - iso, err := dockerRunInput(buf, image, args...) + iso, err := dockerRunInput(buf, append([]string{image}, args...)...) if err != nil { return err }