通过Docker API在正在运行的容器中执行powershell命令

时间:2019-04-17 09:46:54

标签: powershell docker go docker-for-windows

我想在Windows主机上运行的Docker容器中执行powershell命令。

我要执行的特定命令是"powershell Get-PSDrive C | Select-Object Used,Free"

我已经使用适用于python的Docker API来实现了这一点,就像调用这样简单:

cmd = "powershell Get-PSDrive C | Select-Object Used,Free"
output = container.exec_run(cmd)

这可以按预期工作,但是我需要在golang中实现。

但是以某种方式,我不清楚如何与用于golang的Docker API交互。我查看了API,并对hijackedSession感到困惑。如何设置ContainerExecCreateContainerExecAttachContainerExecStart的呼叫?

我希望golang脚本能够提供与python代码相同的结果:

        Used         Free
        ----         ----
199181606912 307151622144

那我可以解析。

1 个答案:

答案 0 :(得分:1)

HijackedResponse结构:

type HijackedResponse struct {
    Conn   net.Conn
    Reader *bufio.Reader
}


您需要从resp.Reader复制响应,这是我的代码:

package main

import (
    "bytes"
    "context"
    "fmt"
    "github.com/docker/docker/api/types"
    "github.com/docker/docker/client"
    "github.com/docker/docker/pkg/stdcopy"
    "strings"
)

func readFromCommand() (string, error) {
    cli, err := client.NewEnvClient()
    if err != nil {
        return "", err
    }
    ctx := context.Background()
    config := types.ExecConfig{
        Cmd:          strings.Split("powershell Get-PSDrive C | Select-Object Used,Free", " "),
        AttachStdout: true,
        AttachStderr: true,
    }
    response, err := cli.ContainerExecCreate(ctx,
        // container id
        "cf59d65ab1", config)
    if err != nil {
        return "", err
    }
    execID := response.ID

    resp, err := cli.ContainerExecAttach(ctx, execID, config)
    if err != nil {
        return "", err
    }
    defer resp.Close()
    stdout := new(bytes.Buffer)
    stderr := new(bytes.Buffer)
    _, err = stdcopy.StdCopy(stdout, stderr, resp.Reader)
    if err != nil {
        return "", err
    }
    s := stdout.String()
    fmt.Println(s)
    i := stderr.String()
    fmt.Println(i)
    return s, nil

}

请记住更改容器ID。