package docker import ( "context" "github.com/docker/docker/api/types/container" "github.com/1Panel-dev/1Panel/backend/app/model" "github.com/1Panel-dev/1Panel/backend/global" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/client" ) type Client struct { cli *client.Client } func NewClient() (Client, error) { var settingItem model.Setting _ = global.DB.Where("key = ?", "DockerSockPath").First(&settingItem).Error if len(settingItem.Value) == 0 { settingItem.Value = "unix:///var/run/docker.sock" } cli, err := client.NewClientWithOpts(client.FromEnv, client.WithHost(settingItem.Value), client.WithAPIVersionNegotiation()) if err != nil { return Client{}, err } return Client{ cli: cli, }, nil } func NewDockerClient() (*client.Client, error) { var settingItem model.Setting _ = global.DB.Where("key = ?", "DockerSockPath").First(&settingItem).Error if len(settingItem.Value) == 0 { settingItem.Value = "unix:///var/run/docker.sock" } cli, err := client.NewClientWithOpts(client.FromEnv, client.WithHost(settingItem.Value), client.WithAPIVersionNegotiation()) if err != nil { return nil, err } return cli, nil } func (c Client) ListAllContainers() ([]types.Container, error) { var options container.ListOptions containers, err := c.cli.ContainerList(context.Background(), options) if err != nil { return nil, err } return containers, nil } func (c Client) ListContainersByName(names []string) ([]types.Container, error) { var ( options container.ListOptions res []types.Container ) options.All = true if len(names) > 0 { var array []filters.KeyValuePair for _, n := range names { array = append(array, filters.Arg("name", n)) } options.Filters = filters.NewArgs(array...) } containers, err := c.cli.ContainerList(context.Background(), options) if err != nil { return nil, err } for _, container := range containers { if container.Names[0] == "/"+names[0] { res = append(res, container) } } return res, nil } func (c Client) CreateNetwork(name string) error { _, err := c.cli.NetworkCreate(context.Background(), name, types.NetworkCreate{ Driver: "bridge", }) return err } func (c Client) DeleteImage(imageID string) error { if _, err := c.cli.ImageRemove(context.Background(), imageID, types.ImageRemoveOptions{Force: true}); err != nil { return err } return nil } func (c Client) InspectContainer(containerID string) (types.ContainerJSON, error) { return c.cli.ContainerInspect(context.Background(), containerID) } func (c Client) PullImage(imageName string, force bool) error { if !force { exist, err := c.CheckImageExist(imageName) if err != nil { return err } if exist { return nil } } if _, err := c.cli.ImagePull(context.Background(), imageName, types.ImagePullOptions{}); err != nil { return err } return nil } func (c Client) GetImageIDByName(imageName string) (string, error) { filter := filters.NewArgs() filter.Add("reference", imageName) list, err := c.cli.ImageList(context.Background(), types.ImageListOptions{ Filters: filter, }) if err != nil { return "", err } if len(list) > 0 { return list[0].ID, nil } return "", nil } func (c Client) CheckImageExist(imageName string) (bool, error) { filter := filters.NewArgs() filter.Add("reference", imageName) list, err := c.cli.ImageList(context.Background(), types.ImageListOptions{ Filters: filter, }) if err != nil { return false, err } return len(list) > 0, nil } func (c Client) NetworkExist(name string) bool { var options types.NetworkListOptions options.Filters = filters.NewArgs(filters.Arg("name", name)) networks, err := c.cli.NetworkList(context.Background(), options) if err != nil { return false } return len(networks) > 0 } func CreateDefaultDockerNetwork() error { cli, err := NewClient() if err != nil { global.LOG.Errorf("init docker client error %s", err.Error()) return err } if !cli.NetworkExist("1panel-network") { if err := cli.CreateNetwork("1panel-network"); err != nil { global.LOG.Errorf("create default docker network error %s", err.Error()) return err } } return nil }