Files
devstar-create-from-template/modules/docker/docker_api.go
2025-08-25 15:46:12 +08:00

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
}