2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 16:10:59 +08:00
Files
panel/internal/data/container_image.go
2024-10-31 03:34:02 +08:00

105 lines
2.5 KiB
Go

package data
import (
"context"
"fmt"
"net"
"net/http"
"slices"
"strings"
"time"
"github.com/go-resty/resty/v2"
"github.com/TheTNB/panel/internal/biz"
"github.com/TheTNB/panel/internal/http/request"
"github.com/TheTNB/panel/pkg/shell"
"github.com/TheTNB/panel/pkg/str"
"github.com/TheTNB/panel/pkg/types"
"github.com/TheTNB/panel/pkg/types/docker/image"
)
type containerImageRepo struct {
client *resty.Client
}
func NewContainerImageRepo(sock ...string) biz.ContainerImageRepo {
if len(sock) == 0 {
sock = append(sock, "/var/run/docker.sock")
}
client := resty.New()
client.SetTimeout(1 * time.Minute)
client.SetRetryCount(2)
client.SetTransport(&http.Transport{
DialContext: func(ctx context.Context, _ string, _ string) (net.Conn, error) {
return (&net.Dialer{}).DialContext(ctx, "unix", sock[0])
},
})
client.SetBaseURL("http://d/v1.40")
return &containerImageRepo{
client: client,
}
}
// List 列出镜像
func (r *containerImageRepo) List() ([]types.ContainerImage, error) {
var resp []image.Image
_, err := r.client.R().SetResult(&resp).SetQueryParam("all", "true").Get("/images/json")
if err != nil {
return nil, err
}
var images []types.ContainerImage
for _, item := range resp {
images = append(images, types.ContainerImage{
ID: item.ID,
Containers: item.Containers,
RepoTags: item.RepoTags,
RepoDigests: item.RepoDigests,
Size: str.FormatBytes(float64(item.Size)),
Labels: types.MapToKV(item.Labels),
CreatedAt: time.Unix(item.Created, 0),
})
}
slices.SortFunc(images, func(a types.ContainerImage, b types.ContainerImage) int {
return strings.Compare(a.ID, b.ID)
})
return images, nil
}
// Pull 拉取镜像
func (r *containerImageRepo) Pull(req *request.ContainerImagePull) error {
var sb strings.Builder
if req.Auth {
sb.WriteString(fmt.Sprintf("docker login -u %s -p %s", req.Username, req.Password))
if _, err := shell.ExecfWithTimeout(1*time.Minute, sb.String()); err != nil { // nolint: govet
return fmt.Errorf("login failed: %w", err)
}
sb.Reset()
}
sb.WriteString(fmt.Sprintf("docker pull %s", req.Name))
if _, err := shell.Execf(sb.String()); err != nil { // nolint: govet
return err
}
return nil
}
// Remove 删除镜像
func (r *containerImageRepo) Remove(id string) error {
_, err := shell.ExecfWithTimeout(120*time.Second, "docker rmi %s", id)
return err
}
// Prune 清理未使用的镜像
func (r *containerImageRepo) Prune() error {
_, err := shell.ExecfWithTimeout(120*time.Second, "docker image prune -f")
return err
}