fix: 镜像拉取同步系统认证信息 (#5571)
Some checks failed
Build Test / build-linux-binary (push) Failing after -5m50s
Build / SonarCloud (push) Failing after -5m52s
sync2gitee / repo-sync (push) Failing after -5m54s

Refs #5537
This commit is contained in:
ssongliu 2024-06-26 14:28:49 +08:00 committed by GitHub
parent 0886bcd310
commit 18719f9112
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 65 additions and 9 deletions

View file

@ -6,7 +6,6 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"io"
"net/http"
"net/url"
@ -21,6 +20,8 @@ import (
"time"
"unicode/utf8"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
"github.com/1Panel-dev/1Panel/backend/app/dto"
@ -988,12 +989,12 @@ func checkImageExist(client *client.Client, imageItem string) bool {
return false
}
func pullImages(ctx context.Context, client *client.Client, image string) error {
options := types.ImagePullOptions{}
func pullImages(ctx context.Context, client *client.Client, imageName string) error {
options := image.PullOptions{}
repos, _ := imageRepoRepo.List()
if len(repos) != 0 {
for _, repo := range repos {
if strings.HasPrefix(image, repo.DownloadUrl) && repo.Auth {
if strings.HasPrefix(imageName, repo.DownloadUrl) && repo.Auth {
authConfig := registry.AuthConfig{
Username: repo.Username,
Password: repo.Password,
@ -1006,8 +1007,13 @@ func pullImages(ctx context.Context, client *client.Client, image string) error
options.RegistryAuth = authStr
}
}
} else {
hasAuth, authStr := loadAuthInfo(imageName)
if hasAuth {
options.RegistryAuth = authStr
}
}
out, err := client.ImagePull(ctx, image, options)
out, err := client.ImagePull(ctx, imageName, options)
if err != nil {
return err
}

View file

@ -24,6 +24,7 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/homedir"
)
type ImageService struct{}
@ -253,10 +254,15 @@ func (u *ImageService) ImagePull(req dto.ImagePull) (string, error) {
if err != nil {
return "", err
}
options := image.PullOptions{}
if req.RepoID == 0 {
hasAuth, authStr := loadAuthInfo(req.ImageName)
if hasAuth {
options.RegistryAuth = authStr
}
go func() {
defer file.Close()
out, err := client.ImagePull(context.TODO(), req.ImageName, types.ImagePullOptions{})
out, err := client.ImagePull(context.TODO(), req.ImageName, options)
if err != nil {
global.LOG.Errorf("image %s pull failed, err: %v", req.ImageName, err)
return
@ -271,7 +277,6 @@ func (u *ImageService) ImagePull(req dto.ImagePull) (string, error) {
if err != nil {
return "", err
}
options := image.PullOptions{}
if repo.Auth {
authConfig := registry.AuthConfig{
Username: repo.Username,
@ -464,3 +469,49 @@ func checkUsed(imageID string, containers []types.Container) bool {
}
return false
}
func loadAuthInfo(image string) (bool, string) {
if !strings.Contains(image, "/") {
return false, ""
}
homeDir := homedir.Get()
confPath := path.Join(homeDir, ".docker/config.json")
configFileBytes, err := os.ReadFile(confPath)
if err != nil {
return false, ""
}
var config dockerConfig
if err = json.Unmarshal(configFileBytes, &config); err != nil {
return false, ""
}
var (
user string
passwd string
)
imagePrefix := strings.Split(image, "/")[0]
if val, ok := config.Auths[imagePrefix]; ok {
itemByte, _ := base64.StdEncoding.DecodeString(val.Auth)
itemStr := string(itemByte)
if strings.Contains(itemStr, ":") {
user = strings.Split(itemStr, ":")[0]
passwd = strings.Split(itemStr, ":")[1]
}
}
authConfig := registry.AuthConfig{
Username: user,
Password: passwd,
}
encodedJSON, err := json.Marshal(authConfig)
if err != nil {
return false, ""
}
authStr := base64.URLEncoding.EncodeToString(encodedJSON)
return true, authStr
}
type dockerConfig struct {
Auths map[string]authConfig `json:"auths"`
}
type authConfig struct {
Auth string `json:"auth"`
}

View file

@ -13,7 +13,6 @@ import (
"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/image"
"github.com/pkg/errors"
@ -300,7 +299,7 @@ func loadImageTag() (string, error) {
itemTag = "postgres:16.1-alpine"
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
defer cancel()
if _, err := client.ImagePull(ctx, itemTag, types.ImagePullOptions{}); err != nil {
if _, err := client.ImagePull(ctx, itemTag, image.PullOptions{}); err != nil {
if ctx.Err() == context.DeadlineExceeded {
return itemTag, buserr.New(constant.ErrPgImagePull)
}