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:
parent
85f8c1e634
commit
5bbda8f842
@ -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)
|
||||||
|
@ -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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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"
|
||||||
|
@ -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: "此文件不支持預覽"
|
||||||
|
@ -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: "此文件不支持预览"
|
||||||
|
@ -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 {
|
||||||
|
@ -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))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user