From 362d2d26163d6d43f9526f840e67d22052093371 Mon Sep 17 00:00:00 2001 From: zhengkunwang223 Date: Mon, 3 Oct 2022 17:35:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E5=8F=AF=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/model/app.go | 2 +- backend/app/model/app_config.go | 8 ---- backend/app/model/app_container.go | 1 - backend/app/model/app_detail.go | 3 +- backend/app/model/app_install.go | 7 +-- backend/app/repo/app.go | 7 --- backend/app/repo/app_detail.go | 21 ++++++--- backend/app/repo/app_install.go | 15 ++++++ backend/app/service/app.go | 56 +++++++++++++++++------ backend/init/migration/migrations/init.go | 2 +- backend/utils/common/common.go | 16 +++++++ 11 files changed, 97 insertions(+), 41 deletions(-) delete mode 100644 backend/app/model/app_config.go diff --git a/backend/app/model/app.go b/backend/app/model/app.go index f996ebc49..fe906b0c3 100644 --- a/backend/app/model/app.go +++ b/backend/app/model/app.go @@ -11,7 +11,7 @@ type App struct { Type string `json:"type" gorm:"type:varchar(64);not null"` Status string `json:"status" gorm:"type:varchar(64);not null"` Required string `json:"required" gorm:"type:varchar(64);not null"` - CrossVersionUpdate bool `json:"crossVersionUpdate" gorm:"type:varchar(64);not null"` + CrossVersionUpdate bool `json:"crossVersionUpdate"` Details []AppDetail `json:"-"` TagsKey []string `json:"-" gorm:"-"` AppTags []AppTag `json:"-" ` diff --git a/backend/app/model/app_config.go b/backend/app/model/app_config.go deleted file mode 100644 index 1d8d83bce..000000000 --- a/backend/app/model/app_config.go +++ /dev/null @@ -1,8 +0,0 @@ -package model - -type AppConfig struct { - BaseModel - Version string `json:"version"` - OssPath string `json:"ossPath"` - CanUpdate bool `json:"canUpdate"` -} diff --git a/backend/app/model/app_container.go b/backend/app/model/app_container.go index 18b0eb62c..83131effb 100644 --- a/backend/app/model/app_container.go +++ b/backend/app/model/app_container.go @@ -5,5 +5,4 @@ type AppContainer struct { ServiceName string `json:"serviceName"` ContainerName string `json:"containerName"` AppInstallId uint `json:"appInstallId"` - Image string `json:"image"` } diff --git a/backend/app/model/app_detail.go b/backend/app/model/app_detail.go index e2e777abb..26b3fe877 100644 --- a/backend/app/model/app_detail.go +++ b/backend/app/model/app_detail.go @@ -6,6 +6,7 @@ type AppDetail struct { Version string `json:"version" gorm:"type:varchar(64);not null"` Params string `json:"-" gorm:"type:longtext;"` DockerCompose string `json:"-" gorm:"type:longtext;not null"` - Readme string `json:"readme" gorm:"type:longtext;not null"` + Readme string `json:"readme" gorm:"type:longtext;"` Status string `json:"status" gorm:"type:varchar(64);not null"` + LastVersion string `json:"lastVersion" gorm:"type:varchar(64);"` } diff --git a/backend/app/model/app_install.go b/backend/app/model/app_install.go index 946811a5e..6339676cc 100644 --- a/backend/app/model/app_install.go +++ b/backend/app/model/app_install.go @@ -11,10 +11,11 @@ type AppInstall struct { Version string `json:"version" gorm:"type:varchar(256);not null"` AppId uint `json:"appId" gorm:"type:integer;not null"` AppDetailId uint `json:"appDetailId" gorm:"type:integer;not null"` - Params string `json:"params" gorm:"type:longtext;not null"` + Params string `json:"params" gorm:"type:longtext;"` Status string `json:"status" gorm:"type:varchar(256);not null"` - Description string `json:"description" gorm:"type:varchar(256);not null"` - Message string `json:"message" gorm:"type:longtext;not null"` + Description string `json:"description" gorm:"type:varchar(256);"` + Message string `json:"message" gorm:"type:longtext;"` + CanUpdate bool `json:"canUpdate"` App App `json:"-"` Containers []AppContainer `json:"containers"` } diff --git a/backend/app/repo/app.go b/backend/app/repo/app.go index 3fc9560eb..a43a158f1 100644 --- a/backend/app/repo/app.go +++ b/backend/app/repo/app.go @@ -70,10 +70,3 @@ func (a AppRepo) Save(ctx context.Context, app *model.App) error { db := ctx.Value("db").(*gorm.DB) return db.Omit(clause.Associations).Save(app).Error } - -func (a AppRepo) UpdateAppConfig(ctx context.Context, app *model.AppConfig) error { - db := ctx.Value("db").(*gorm.DB) - return db.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "id"}}, - }).Create(app).Error -} diff --git a/backend/app/repo/app_detail.go b/backend/app/repo/app_detail.go index 22171f1fa..92fc14603 100644 --- a/backend/app/repo/app_detail.go +++ b/backend/app/repo/app_detail.go @@ -21,7 +21,7 @@ func (a AppDetailRepo) WithAppId(id uint) DBOption { } } -func (a AppDetailRepo) GetAppDetail(opts ...DBOption) (model.AppDetail, error) { +func (a AppDetailRepo) GetFirst(opts ...DBOption) (model.AppDetail, error) { var detail model.AppDetail db := global.DB for _, opt := range opts { @@ -46,11 +46,20 @@ func (a AppDetailRepo) DeleteByAppIds(ctx context.Context, appIds []uint) error return db.Where("app_id in (?)", appIds).Delete(&model.AppDetail{}).Error } -func (a AppDetailRepo) GetByAppId(ctx context.Context, appId uint) ([]model.AppDetail, error) { - db := ctx.Value("db").(*gorm.DB) +func (a AppDetailRepo) GetBy(opts ...DBOption) ([]model.AppDetail, error) { var details []model.AppDetail - if err := db.Where("app_id = ?", appId).Find(&details).Error; err != nil { - return nil, err + db := global.DB + for _, opt := range opts { + db = opt(db) } - return details, nil + err := db.Find(&details).Error + return details, err +} + +func (a AppDetailRepo) BatchUpdateBy(update model.AppDetail, opts ...DBOption) error { + db := global.DB.Model(model.AppDetail{}) + for _, opt := range opts { + db = opt(db) + } + return db.Updates(update).Error } diff --git a/backend/app/repo/app_install.go b/backend/app/repo/app_install.go index 3feca3baf..0a72c23be 100644 --- a/backend/app/repo/app_install.go +++ b/backend/app/repo/app_install.go @@ -3,10 +3,17 @@ package repo import ( "github.com/1Panel-dev/1Panel/app/model" "github.com/1Panel-dev/1Panel/global" + "gorm.io/gorm" ) type AppInstallRepo struct{} +func (a AppInstallRepo) WithDetailIdsIn(detailIds []uint) DBOption { + return func(g *gorm.DB) *gorm.DB { + return g.Where("app_detail_id in (?)", detailIds) + } +} + func (a AppInstallRepo) GetBy(opts ...DBOption) ([]model.AppInstall, error) { db := global.DB.Model(&model.AppInstall{}) for _, opt := range opts { @@ -56,3 +63,11 @@ func (a AppInstallRepo) Page(page, size int, opts ...DBOption) (int64, []model.A err := db.Debug().Limit(size).Offset(size * (page - 1)).Preload("App").Preload("Containers").Find(&apps).Error return count, apps, err } + +func (a AppInstallRepo) BatchUpdateBy(update model.AppInstall, opts ...DBOption) error { + db := global.DB.Model(model.AppInstall{}) + for _, opt := range opts { + db = opt(db) + } + return db.Updates(update).Error +} diff --git a/backend/app/service/app.go b/backend/app/service/app.go index ec921c9de..c15e9fa0c 100644 --- a/backend/app/service/app.go +++ b/backend/app/service/app.go @@ -18,7 +18,6 @@ import ( "gopkg.in/yaml.v3" "os" "path" - "sort" "strconv" "strings" ) @@ -96,7 +95,7 @@ func (a AppService) GetApp(id uint) (dto.AppDTO, error) { return appDTO, err } appDTO.App = app - details, err := appDetailRepo.GetByAppId(context.WithValue(context.Background(), "db", global.DB), id) + details, err := appDetailRepo.GetBy(appDetailRepo.WithAppId(app.ID)) if err != nil { return appDTO, err } @@ -105,10 +104,7 @@ func (a AppService) GetApp(id uint) (dto.AppDTO, error) { versionsRaw = append(versionsRaw, detail.Version) } - sort.Slice(versionsRaw, func(i, j int) bool { - return common.CompareVersion(versionsRaw[i], versionsRaw[j]) - }) - appDTO.Versions = versionsRaw + appDTO.Versions = common.GetSortedVersions(versionsRaw) return appDTO, nil } @@ -139,7 +135,7 @@ func (a AppService) GetAppDetail(appId uint, version string) (dto.AppDetailDTO, ) opts = append(opts, appDetailRepo.WithAppId(appId), appDetailRepo.WithVersion(version)) - detail, err := appDetailRepo.GetAppDetail(opts...) + detail, err := appDetailRepo.GetFirst(opts...) if err != nil { return appDetailDTO, err } @@ -225,7 +221,7 @@ func (a AppService) Install(name string, appDetailId uint, params map[string]int } } - appDetail, err := appDetailRepo.GetAppDetail(commonRepo.WithByID(appDetailId)) + appDetail, err := appDetailRepo.GetFirst(commonRepo.WithByID(appDetailId)) if err != nil { return err } @@ -289,14 +285,9 @@ func (a AppService) Install(name string, appDetailId uint, params map[string]int value := v.(map[string]interface{}) containerName := constant.ContainerPrefix + k + "-" + common.RandStr(4) value["container_name"] = containerName - var image string - if i, ok := value["image"]; ok { - image = i.(string) - } appContainers = append(appContainers, &model.AppContainer{ ServiceName: serviceName, ContainerName: containerName, - Image: image, }) } for k, v := range changeKeys { @@ -666,5 +657,44 @@ func (a AppService) SyncAppList() error { } tx.Commit() + + go syncCanUpdate() return nil } + +func syncCanUpdate() { + + apps, err := appRepo.GetBy() + if err != nil { + global.LOG.Errorf("sync update app error: %s", err.Error()) + } + for _, app := range apps { + details, err := appDetailRepo.GetBy(appDetailRepo.WithAppId(app.ID)) + if err != nil { + global.LOG.Errorf("sync update app error: %s", err.Error()) + } + var versions []string + for _, detail := range details { + versions = append(versions, detail.Version) + } + versions = common.GetSortedVersions(versions) + lastVersion := versions[0] + + var updateDetailIds []uint + for _, detail := range details { + if common.CompareVersion(lastVersion, detail.Version) { + if app.CrossVersionUpdate || !common.IsCrossVersion(detail.Version, lastVersion) { + updateDetailIds = append(updateDetailIds, detail.ID) + } + } + } + if len(updateDetailIds) > 0 { + if err := appDetailRepo.BatchUpdateBy(model.AppDetail{LastVersion: lastVersion}, commonRepo.WithIdsIn(updateDetailIds)); err != nil { + global.LOG.Errorf("sync update app error: %s", err.Error()) + } + if err := appInstallRepo.BatchUpdateBy(model.AppInstall{CanUpdate: true}, appInstallRepo.WithDetailIdsIn(updateDetailIds)); err != nil { + global.LOG.Errorf("sync update app error: %s", err.Error()) + } + } + } +} diff --git a/backend/init/migration/migrations/init.go b/backend/init/migration/migrations/init.go index aaa5f6b87..6be0797ec 100644 --- a/backend/init/migration/migrations/init.go +++ b/backend/init/migration/migrations/init.go @@ -150,6 +150,6 @@ var AddTableCronjob = &gormigrate.Migration{ var AddTableApp = &gormigrate.Migration{ ID: "20200921-add-table-app", Migrate: func(tx *gorm.DB) error { - return tx.AutoMigrate(&model.App{}, &model.AppDetail{}, &model.Tag{}, &model.AppTag{}, &model.AppConfig{}, &model.AppInstall{}, &model.AppContainer{}, &model.AppContainer{}) + return tx.AutoMigrate(&model.App{}, &model.AppDetail{}, &model.Tag{}, &model.AppTag{}, &model.AppInstall{}, &model.AppContainer{}, &model.AppContainer{}) }, } diff --git a/backend/utils/common/common.go b/backend/utils/common/common.go index d3ab545a9..eafc9fa89 100644 --- a/backend/utils/common/common.go +++ b/backend/utils/common/common.go @@ -7,6 +7,7 @@ import ( mathRand "math/rand" "net" "regexp" + "sort" "strconv" "strings" ) @@ -37,6 +38,21 @@ func CompareVersion(version1 string, version2 string) bool { return true } +func GetSortedVersions(versions []string) []string { + sort.Slice(versions, func(i, j int) bool { + return CompareVersion(versions[i], versions[j]) + }) + return versions +} + +func IsCrossVersion(version1, version2 string) bool { + version1s := strings.Split(version1, ".") + version2s := strings.Split(version2, ".") + v1num, _ := strconv.Atoi(version1s[0]) + v2num, _ := strconv.Atoi(version2s[0]) + return v2num > v1num +} + func min(a, b int) int { if a < b { return a