无法使用Go客户端从Docker到达stdout

前端之家收集整理的这篇文章主要介绍了无法使用Go客户端从Docker到达stdout前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我有一个小项目,我的服务器将http发送的C文件复制到Docker容器中,在那里编译和运行它们.
但是,我无法获取任何数据发送到容器中的stdout.

我已确定将文件发送到Docker容器中,还有更多 – 编译的任何问题都显示错误流中.但是,在C程序中通过stderr发送数据也没有显示任何结果,直到我使用Dockerfile,使用’>& 2 echo“”’以某种方式将数据推送到流中并且我能够读取它.

现在,如上所述,我只能阅读stderr,完全归功于一种解决方法.知道为什么我不能使用标准方法吗?

去服务器

@H_403_12@package main import ( "fmt" "net/http" "io" "os" "os/exec" "log" "encoding/json" "github.com/docker/docker/client" dockertypes "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "golang.org/x/net/context" "time" "bytes" ) type Result struct { CompilationCode int RunCode int TestsPositive int TestsTotal int } func upload(w http.ResponseWriter,r *http.Request) { log.Println("method:",r.Method) if r.Method == "POST" { log.Println("Processing new SUBMISSION.") // https://github.com/astaxie/build-web-application-with-golang/blob/master/de/04.5.md r.ParseMultipartForm(32 << 20) file,handler,err := r.FormFile("file") if err != nil { fmt.Println(err) return } defer file.Close() baseName:= os.Args[1] f,err := os.OpenFile(baseName+handler.Filename,os.O_WRONLY|os.O_CREATE,777) if err != nil { fmt.Println(err) return } defer f.Close() io.Copy(f,file) if err != nil { fmt.Println(err) return } compilationCode,runCode,testsPositive,testsTotal := processWithDocker(baseName + handler.Filename,handler.Filename) result := Result{ CompilationCode: compilationCode,RunCode: runCode,TestsPositive:testsPositive,TestsTotal:testsTotal,} resultMarshaled,_ := json.Marshal(result) w.Write(resultMarshaled) } else { w.Write([]byte("GO server is active. Use POST to submit your solution.")) } } // there is assumption that docker is installed where server.go is running // and the container is already pulled // TODO: handle situation when container is not pulled // TODO: somehow capture if compilation wasn't successful and // TODO: distinguish it from possible execution / time limit / memory limit error // https://stackoverflow.com/questions/18986943/in-golang-how-can-i-write-the-stdout-of-an-exec-cmd-to-a-file func processWithDocker(filenameWithDir string,filenameWithoutDir string) (int,int,int) { ctx,cancel := context.WithTimeout(context.Background(),10*time.Second) defer cancel() cli,err := client.NewEnvClient() if err != nil { panic(err) } var hostVolumeString = filenameWithDir var hostConfigBindString = hostVolumeString + ":/WORKING_FOLDER/" + filenameWithoutDir var hostConfig = &container.HostConfig{ Binds: []string{hostConfigBindString},} resp,err := cli.ContainerCreate(ctx,&container.Config{ Image: "tusty53/ubuntu_c_runner:twelfth",Env: []string{"F00=" + filenameWithoutDir},Volumes: map[string]struct{}{ hostVolumeString: struct{}{},},hostConfig,nil,"") if err != nil { panic(err) } if err := cli.ContainerStart(ctx,resp.ID,dockertypes.ContainerStartOptions{}); err != nil { panic(err) } fmt.Println(resp.ID) var exited = false for !exited { json,err := cli.ContainerInspect(ctx,resp.ID) if err != nil { panic(err) } exited = json.State.Running fmt.Println(json.State.Status) } normalOut,err := cli.ContainerLogs(ctx,dockertypes.ContainerLogsOptions{ShowStdout: true,ShowStderr: false}) if err != nil { panic(err) } errorOut,dockertypes.ContainerLogsOptions{ShowStdout: false,ShowStderr: true}) if err != nil { panic(err) } buf := new(bytes.Buffer) buf.ReadFrom(normalOut) sOut := buf.String() buf2 := new(bytes.Buffer) buf2.ReadFrom(errorOut) sErr := buf2.String() log.Printf("start\n") log.Printf(sOut) log.Printf("end\n") log.Printf("start error\n") log.Printf(sErr) log.Printf("end error\n") var testsPositive=0 var testsTotal=0 if(sErr!=""){ return 0,0 } if(sOut!=""){ fmt.Sscanf(sOut,"%d %d",&testsPositive,&testsTotal) return 1,1,testsTotal } return 1,0 } // Creates examine directory if it doesn't exist. // If examine directory already exists,then comes an error. func prepareDir() { cmdMkdir := exec.Command("mkdir",os.Args[1]) errMkdir := cmdMkdir.Run() if errMkdir != nil { log.Println(errMkdir) } } func main() { prepareDir() go http.HandleFunc("/submission",upload) http.ListenAndServe(":8123",nil) }

Dockerfile

@H_403_12@FROM ubuntu ENV DEBIAN_FRONTEND noninteractive RUN apt-get update && \ apt-get -y install gcc COPY . /WORKING_FOLDER WORKDIR /WORKING_FOLDER CMD ["./chain"]

文件

@H_403_12@#!/bin/bash gcc -Wall $F00 -o hello ./hello >&2 echo ""
最佳答案
您应该考虑将Docker CLI作为一个单独的进程运行,只需读取其stdout和stderr,例如:

@H_403_12@cmd := exec.Command("docker","run","-v=

猜你在找的Docker相关文章