118 lines
2.8 KiB
Go
118 lines
2.8 KiB
Go
package docker
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"os"
|
|
|
|
"github.com/docker/docker/api/types"
|
|
"github.com/docker/docker/api/types/container"
|
|
"github.com/docker/docker/client"
|
|
)
|
|
|
|
// CreateDockerClient 创建Docker客户端
|
|
func CreateDockerClient(ctx context.Context) (*client.Client, error) {
|
|
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return cli, nil
|
|
}
|
|
|
|
// GetDockerSocketPath 获取Docker Socket路径
|
|
func GetDockerSocketPath() (string, error) {
|
|
// 检查常见的Docker socket路径
|
|
socketPaths := []string{
|
|
"/var/run/docker.sock",
|
|
"/run/podman/podman.sock",
|
|
"$HOME/.colima/docker.sock",
|
|
"$XDG_RUNTIME_DIR/docker.sock",
|
|
"$XDG_RUNTIME_DIR/podman/podman.sock",
|
|
`\\.\pipe\docker_engine`,
|
|
"$HOME/.docker/run/docker.sock",
|
|
}
|
|
|
|
for _, path := range socketPaths {
|
|
if _, err := os.Stat(path); err == nil {
|
|
return path, nil
|
|
}
|
|
}
|
|
|
|
// 如果找不到,返回默认路径
|
|
return "/var/run/docker.sock", nil
|
|
}
|
|
|
|
// PullImage 拉取Docker镜像
|
|
func PullImage(cli *client.Client, dockerHost, imageName string) error {
|
|
ctx := context.Background()
|
|
|
|
reader, err := cli.ImagePull(ctx, imageName, types.ImagePullOptions{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer reader.Close()
|
|
|
|
// 读取并丢弃输出,确保拉取完成
|
|
_, err = io.Copy(io.Discard, reader)
|
|
return err
|
|
}
|
|
|
|
// CreateAndStartContainer 创建并启动容器
|
|
func CreateAndStartContainer(cli *client.Client, imageName string, cmd []string, env []string, binds []string, ports map[string]string, containerName string) error {
|
|
ctx := context.Background()
|
|
|
|
// 配置容器
|
|
config := &container.Config{
|
|
Image: imageName,
|
|
Env: env,
|
|
}
|
|
|
|
if cmd != nil {
|
|
config.Cmd = cmd
|
|
}
|
|
|
|
hostConfig := &container.HostConfig{
|
|
Binds: binds,
|
|
}
|
|
|
|
// 如果有端口映射配置
|
|
if ports != nil && len(ports) > 0 {
|
|
// 这里可以根据需要添加端口映射逻辑
|
|
// hostConfig.PortBindings = portBindings
|
|
}
|
|
|
|
// 创建容器
|
|
resp, err := cli.ContainerCreate(ctx, config, hostConfig, nil, nil, containerName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 启动容器
|
|
return cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{})
|
|
}
|
|
|
|
// DeleteContainer 停止并删除指定名称的容器
|
|
func DeleteContainer(cli *client.Client, containerName string) error {
|
|
ctx := context.Background()
|
|
|
|
// 首先尝试停止容器
|
|
timeout := 10
|
|
err := cli.ContainerStop(ctx, containerName, container.StopOptions{
|
|
Timeout: &timeout,
|
|
})
|
|
if err != nil {
|
|
// 如果容器已经停止或不存在,继续执行删除操作
|
|
// 这里不返回错误,因为我们的目标是删除容器
|
|
}
|
|
|
|
// 删除容器
|
|
err = cli.ContainerRemove(ctx, containerName, types.ContainerRemoveOptions{
|
|
Force: true, // 强制删除,即使容器正在运行
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|