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 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条