【问题标题】:Execute powershell command in running container via Docker API通过 Docker API 在正在运行的容器中执行 powershell 命令
【发布时间】:2019-04-17 09:46:54
【问题描述】:

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

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

我已经使用 Docker API for python 实现了这一点,它就像调用一样简单:

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

然后我可以解析。

【问题讨论】:

  • 只是为尝试使用 powershell 连接 windows 容器的用户提供的快速信息。 nanoserver docker 镜像不包含 powershell。我用servercore

标签: powershell docker go docker-for-windows


【解决方案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。

【讨论】:

  • 谢谢你的例子。但是,有什么遗漏吗? func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error) 表示配置类型为 ExecStartCheck。在上面的示例中,传递了 ExecConfig 类型的配置。
  • @semaph0r 在我的docker客户端版本docker v1.13.1中是func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config types.ExecConfig) (types.HijackedResponse, error) { ,当然你可以修改代码来满足你的api版本需要。
  • 感谢您的评论。我添加了execConfig := types.ExecStartCheck{Tty: false, Detach: false} 并将其传递给ContainerExecAttach。干得好,谢谢你的工作。这个赏金当之无愧!
猜你喜欢
  • 2020-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-08
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
相关资源
最近更新 更多