1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-19 08:19:15 +08:00

fix: 解决应用升级镜像拉取失败导致应用服务异常的问题 (#1921)

This commit is contained in:
zhengkunwang 2023-08-11 15:52:13 +08:00 committed by GitHub
parent 85f8c1e634
commit 5bbda8f842
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 84 additions and 22 deletions

View File

@ -341,6 +341,24 @@ func upgradeInstall(installId uint, detailId uint, backup bool) error {
install.Version = detail.Version install.Version = detail.Version
install.AppDetailId = detailId install.AppDetailId = detailId
images, err := getImages(install)
if err != nil {
upErr = err
return
}
dockerCli, err := composeV2.NewClient()
if err != nil {
upErr = err
return
}
for _, image := range images {
if err = dockerCli.PullImage(image, true); err != nil {
upErr = buserr.WithNameAndErr("ErrDockerPullImage", "", err)
return
}
}
if out, err := compose.Down(install.GetComposePath()); err != nil { if out, err := compose.Down(install.GetComposePath()); err != nil {
if out != "" { if out != "" {
upErr = errors.New(out) upErr = errors.New(out)
@ -398,6 +416,26 @@ func getContainerNames(install model.AppInstall) ([]string, error) {
return containerNames, nil return containerNames, nil
} }
func getImages(install model.AppInstall) ([]string, error) {
envStr, err := coverEnvJsonToStr(install.Env)
if err != nil {
return nil, err
}
project, err := composeV2.GetComposeProject(install.Name, install.GetPath(), []byte(install.DockerCompose), []byte(envStr), true)
if err != nil {
return nil, err
}
imagesMap := make(map[string]struct{})
for _, service := range project.AllServices() {
imagesMap[service.Image] = struct{}{}
}
var images []string
for k := range imagesMap {
images = append(images, k)
}
return images, nil
}
func coverEnvJsonToStr(envJson string) (string, error) { func coverEnvJsonToStr(envJson string) (string, error) {
envMap := make(map[string]interface{}) envMap := make(map[string]interface{})
_ = json.Unmarshal([]byte(envJson), &envMap) _ = json.Unmarshal([]byte(envJson), &envMap)

View File

@ -61,3 +61,18 @@ func WithMap(Key string, maps map[string]interface{}, err error) BusinessError {
Err: err, Err: err,
} }
} }
func WithNameAndErr(Key string, name string, err error) BusinessError {
paramMap := map[string]interface{}{}
if name != "" {
paramMap["name"] = name
}
if err != nil {
paramMap["err"] = err.Error()
}
return BusinessError{
Msg: Key,
Map: paramMap,
Err: err,
}
}

View File

@ -45,6 +45,7 @@ ErrImagePullTimeOut: 'Image pull timeout'
ErrContainerNotFound: '{{ .name }} container does not exist' ErrContainerNotFound: '{{ .name }} container does not exist'
ErrContainerMsg: '{{ .name }} container is abnormal, please check the log on the container page for details' ErrContainerMsg: '{{ .name }} container is abnormal, please check the log on the container page for details'
ErrAppBackup: '{{ .name }} application backup failed err {{.err}}' ErrAppBackup: '{{ .name }} application backup failed err {{.err}}'
ErrImagePull: '{{ .name }} image pull failed err {{.err}}'
#file #file
ErrFileCanNotRead: "File can not read" ErrFileCanNotRead: "File can not read"

View File

@ -45,6 +45,7 @@ ErrImagePullTimeOut: "鏡像拉取超時"
ErrContainerNotFound: '{{ .name }} 容器不存在' ErrContainerNotFound: '{{ .name }} 容器不存在'
ErrContainerMsg: '{{ .name }} 容器異常,具體請在容器頁面查看日誌' ErrContainerMsg: '{{ .name }} 容器異常,具體請在容器頁面查看日誌'
ErrAppBackup: '{{ .name }} 應用備份失敗 err {{.err}}' ErrAppBackup: '{{ .name }} 應用備份失敗 err {{.err}}'
ErrImagePull: '{{ .name }} 鏡像拉取失敗 err {{.err}}'
#file #file
ErrFileCanNotRead: "此文件不支持預覽" ErrFileCanNotRead: "此文件不支持預覽"

View File

@ -45,6 +45,7 @@ ErrImagePullTimeOut: '镜像拉取超时'
ErrContainerNotFound: '{{ .name }} 容器不存在' ErrContainerNotFound: '{{ .name }} 容器不存在'
ErrContainerMsg: '{{ .name }} 容器异常,具体请在容器页面查看日志' ErrContainerMsg: '{{ .name }} 容器异常,具体请在容器页面查看日志'
ErrAppBackup: '{{ .name }} 应用备份失败 err {{.err}}' ErrAppBackup: '{{ .name }} 应用备份失败 err {{.err}}'
ErrImagePull: '镜像拉取失败 {{.err}}'
#file #file
ErrFileCanNotRead: "此文件不支持预览" ErrFileCanNotRead: "此文件不支持预览"

View File

@ -4,11 +4,7 @@ import (
"context" "context"
"github.com/compose-spec/compose-go/loader" "github.com/compose-spec/compose-go/loader"
"github.com/compose-spec/compose-go/types" "github.com/compose-spec/compose-go/types"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/flags"
"github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/compose"
"github.com/docker/docker/client"
"github.com/joho/godotenv" "github.com/joho/godotenv"
"path" "path"
"regexp" "regexp"
@ -21,24 +17,6 @@ type ComposeService struct {
project *types.Project project *types.Project
} }
func NewComposeService(ops ...command.DockerCliOption) (*ComposeService, error) {
apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
return nil, err
}
ops = append(ops, command.WithAPIClient(apiClient), command.WithDefaultContextStoreConfig())
cli, err := command.NewDockerCli(ops...)
if err != nil {
return nil, err
}
cliOp := flags.NewClientOptions()
if err := cli.Initialize(cliOp); err != nil {
return nil, err
}
service := compose.NewComposeService(cli)
return &ComposeService{service, nil}, nil
}
func (s *ComposeService) SetProject(project *types.Project) { func (s *ComposeService) SetProject(project *types.Project) {
s.project = project s.project = project
for i, s := range project.Services { for i, s := range project.Services {

View File

@ -72,6 +72,22 @@ func (c Client) DeleteImage(imageID string) error {
return nil return nil
} }
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) { func (c Client) GetImageIDByName(imageName string) (string, error) {
filter := filters.NewArgs() filter := filters.NewArgs()
filter.Add("reference", imageName) filter.Add("reference", imageName)
@ -87,6 +103,18 @@ func (c Client) GetImageIDByName(imageName string) (string, error) {
return "", 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 { func (c Client) NetworkExist(name string) bool {
var options types.NetworkListOptions var options types.NetworkListOptions
options.Filters = filters.NewArgs(filters.Arg("name", name)) options.Filters = filters.NewArgs(filters.Arg("name", name))