- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我有一个小项目,我的 go 服务器将通过 http 发送的 C 文件复制到 Docker 容器中,在那里它们被编译和运行。但是,我无法获取发送到容器中标准输出的任何数据。
我已确定文件已发送到 Docker 容器中,此外 - 任何编译问题都会显示在错误流中。但是,在 C 程序中通过 stderr 发送数据也没有显示任何结果,直到我使用 Dockerfile 使用 '>&2 echo ""' 以某种方式将数据推送到流中并且我能够读取它。
现在,如上所述,我只能阅读 stderr,这完全归功于一种解决方法。知道为什么我不能使用标准方法来做到这一点吗?
转到服务器
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
// http://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, 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, resp.ID, dockertypes.ContainerLogsOptions{ShowStdout: true, ShowStderr: false})
if err != nil {
panic(err)
}
errorOut, err := cli.ContainerLogs(ctx, resp.ID, 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,0,0
}
if(sOut!=""){
fmt.Sscanf(sOut, "%d %d", &testsPositive, &testsTotal)
return 1,1,testsPositive,testsTotal
}
return 1,0,0,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
FROM ubuntu
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \
apt-get -y install gcc
COPY . /WORKING_FOLDER
WORKDIR /WORKING_FOLDER
CMD ["./chain"]
链式文件
#!/bin/bash
gcc -Wall $F00 -o hello
./hello
>&2 echo ""
最佳答案
相信可以通过下面的方法获取运行容器的stdout
和stderr
。
import "github.com/docker/docker/pkg/stdcopy"
从 docker SDK 导入这个包。
data, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true})
if err != nil {
panic(err)
}
从正在运行的容器中获取日志并将其存储到 data
。现在创建两个缓冲区来存储流。
// Demultiplex stdout and stderror
// from the container logs
stdoutput := new(bytes.Buffer)
stderror := new(bytes.Buffer)
现在使用导入的 stdcopy
将两个流保存到缓冲区。
stdcopy.StdCopy(stdoutput, stderror, data)
if err != nil {
panic(err)
}
关于使用 Go 客户端无法从 Docker 访问标准输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46285216/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
PowerShell Web Access 允许您通过 Web 浏览器运行 PowerShell cmdlet。它显示了一个基于 Web 的控制台窗口。 有没有办法运行 cmdlet 而无需在控制台窗
我尝试在无需用户登录的情况下访问 Sharepoint 文件。 我可以通过以下任一方式获取访问 token 方法一: var client = new RestClient("https://logi
我目前正在尝试通过 Chrome 扩展程序访问 Google 服务。我的理解是,对于 JS 应用程序,Google 首选的身份验证机制是 OAuth。我的应用目前已成功通过 OAuth 向服务进行身份
假设我有纯抽象类 IHandler 和派生自它的类: class IHandler { public: virtual int process_input(char input) = 0; };
我有一个带有 ThymeLeaf 和 Dojo 的 Spring 应用程序,这给我带来了问题。当我从我的 HTML 文件中引用 CSS 文件时,它们在 Firebug 中显示为中止。但是,当我通过在地
这个问题已经有答案了: JavaScript property access: dot notation vs. brackets? (17 个回答) 已关闭 6 年前。 为什么这不起作用? func
我想将所有流量重定向到 https,只有 robot.txt 应该可以通过 http 访问。 是否可以为 robot.txt 文件创建异常(exception)? 我的 .htaccess 文件: R
我遇到了 LinkedIn OAuth2: "Unable to verify access token" 中描述的相同问题;但是,那里描述的解决方案并不能解决我的问题。 我能够成功请求访问 toke
问题 我有一个暴露给 *:8080 的 Docker 服务容器. 我无法通过 localhost:8080 访问容器. Chrome /curl无限期挂断。 但是如果我使用任何其他本地IP,我就可以访
我正在使用 Google 的 Oauth 2.0 来获取用户的 access_token,但我不知道如何将它与 imaplib 一起使用来访问收件箱。 最佳答案 下面是带有 oauth 2.0 的 I
我正在做 docker 入门指南:https://docs.docker.com/get-started/part3/#recap-and-cheat-sheet-optional docker-co
我正在尝试使用静态 IP 在 AKS 上创建一个 Web 应用程序,自然找到了一个带有 Nginx ingress controller in Azure's documentation 的解决方案。
这是我在名为 foo.js 的文件中的代码。 console.log('module.exports:', module.exports) console.log('module.id:', modu
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用 MGTwitterEngine"将 twitter 集成到我的应用程序中。它在 iOS 4.2 上运行良好。当我尝试从任何 iOS 5 设备访问 twitter 时,我遇到了身份验证 to
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用以下 API 列出我的 Facebook 好友。 https://graph.facebook.com/me/friends?access_token= ??? 我想知道访问 token 过
401 Unauthorized - Show headers - { "error": { "errors": [ { "domain": "global", "reas
我已经将我的 django 应用程序部署到 heroku 并使用 Amazon s3 存储桶存储静态文件,我发现从 s3 存储桶到 heroku 获取数据没有问题。但是,当我测试查看内容存储位置时,除
我是一名优秀的程序员,十分优秀!