golang docker sdk中ContainerExecCreate方法ContainerExecStart方法和ContainerExecAttach方法用这个三个方法写一个虚拟终端用户输入命令行可以直接进入容器内部运行并返回运行后的结果
以下是一个使用golang docker sdk编写的虚拟终端示例代码:
package main
import (
"bufio"
"context"
"fmt"
"io"
"os"
"strings"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
)
func main() {
// 创建docker客户端
cli, err := client.NewEnvClient()
if err != nil {
panic(err)
}
// 获取容器ID
containerID := "CONTAINER_ID"
// 创建exec
execConfig := types.ExecConfig{
AttachStdout: true,
AttachStderr: true,
Tty: true,
Cmd: []string{"/bin/sh"},
}
respCreate, err := cli.ContainerExecCreate(context.Background(), containerID, execConfig)
if err != nil {
panic(err)
}
// 启动exec
respStart, err := cli.ContainerExecStart(context.Background(), respCreate.ID, types.ExecStartCheck{})
if err != nil {
panic(err)
}
// 创建session
in, out := io.Pipe()
session := types.HijackedResponse{
Conn: out,
}
// 将session与exec绑定
errCh := make(chan error, 1)
go func() {
errCh <- cli.ContainerExecAttach(context.Background(), respCreate.ID, types.ExecConfig{
Tty: true,
}, session)
}()
// 读取输出
go func() {
scanner := bufio.NewScanner(in)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}()
// 读取用户输入
scanner := bufio.NewScanner(os.Stdin)
for {
fmt.Print("$ ")
if !scanner.Scan() {
break
}
cmd := scanner.Text()
if strings.TrimSpace(cmd) == "" {
continue
}
// 发送命令到容器
_, err := fmt.Fprintln(session.Conn, cmd)
if err != nil {
panic(err)
}
}
// 关闭session
err = session.Close()
if err != nil {
panic(err)
}
// 等待exec结束
err = <-errCh
if err != nil {
panic(err)
}
}
在上面的代码中,我们首先创建了一个docker客户端,然后获取了要进入的容器的ID。接着,我们使用ContainerExecCreate方法创建了一个exec,然后使用ContainerExecStart方法启动了这个exec。在启动exec之后,我们使用ContainerExecAttach方法将一个session与这个exec绑定,并在后台读取输出。同时,我们在前台读取用户输入,并将输入的命令发送到容器中运行。最后,我们等待exec结束,并关闭session。
需要注意的是,由于我们在创建exec时设置了Tty为true,因此我们需要将session与终端进行绑定,以便能够正确地读取输出和发送命令。在上面的代码中,我们使用了io.Pipe方法创建了一个管道,然后将管道的写端作为session的Conn字段,从而实现了session与终端的绑定。另外,由于我们使用了bufio.Scanner方法读取输入和输出,因此我们需要在读取输出时使用bufio.NewScanner方法创建一个scanner对象,以便能够逐行读取输出
原文地址: https://www.cveoy.top/t/topic/dxTg 著作权归作者所有。请勿转载和采集!