doulan3436 2019-04-17 09:46
浏览 1038
已采纳

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

I want to execute a powershell command in a docker container running on a windows host.

The specific command I want to execute is "powershell Get-PSDrive C | Select-Object Used,Free"

I have implemented this using the Docker API for python and it is simple like calling:

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

This works as intended, but I need to implement this in golang.

But somehow, it is not clear for me how to interact with the Docker API for golang. I looked into the API and was confused by the hijackedSession. How do I have to setup the calls for ContainerExecCreate, ContainerExecAttach and ContainerExecStart ?

I expect the golang script to deliver the same results like the python code does:

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

Which then can be parsed by me.

  • 写回答

1条回答 默认 最新

  • doupang3062 2019-04-21 15:03
    关注

    The HijackedResponse struct:

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

    You need to copy the response from the resp.Reader,here is my code:

    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
    
    }
    
    

    Do remember to change the container id.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 微信夜间被转走了1w对,当天手机剪切板里就出现了这个乱码,有铁子可以看看是啥吗可以
  • ¥50 跑通github上的代码 深度学习 pytorch
  • ¥50 求写,批处理调用分区助手分区脚本
  • ¥15 求购HI3519AV100开发板
  • ¥15 请问1553 RT怎么测试,没有BC有方法吗
  • ¥100 业务编程如何选择学习方向和内容?
  • ¥15 wamp3.3.5安装完成后图标正常显示绿色,鼠标左右键点击图标均无反应。求解决方法。
  • ¥15 鼠标点击的这条记录了什么?
  • ¥15 在写pid调速的程序时,电机始终维持最大速度
  • ¥15 【有偿】调用DXGI截图初始化失败,提示0xf 887a0004