1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-31 22:18:07 +08:00

feat: 修改本地应用同步逻辑

This commit is contained in:
zhengkunwang223 2023-05-16 17:31:47 +08:00 committed by zhengkunwang223
parent aeabed70db
commit 872581fa4b
8 changed files with 335 additions and 257 deletions

View File

@ -1,7 +1,7 @@
package dto package dto
import ( import (
"encoding/json" "github.com/1Panel-dev/1Panel/backend/app/model"
) )
type AppDatabase struct { type AppDatabase struct {
@ -31,12 +31,6 @@ type AppVersion struct {
DetailId uint `json:"detailId"` DetailId uint `json:"detailId"`
} }
//type AppList struct {
// Version string `json:"version"`
// Tags []Tag `json:"tags"`
// Items []AppDefine `json:"items"`
//}
type AppList struct { type AppList struct {
Valid bool `json:"valid"` Valid bool `json:"valid"`
Violations []string `json:"violations"` Violations []string `json:"violations"`
@ -56,6 +50,18 @@ type AppDefine struct {
Versions []AppConfigVersion `json:"versions"` Versions []AppConfigVersion `json:"versions"`
} }
type LocalAppAppDefine struct {
AppProperty model.App `json:"additionalProperties" yaml:"additionalProperties"`
}
type LocalAppParam struct {
AppParams LocalAppInstallDefine `json:"additionalProperties" yaml:"additionalProperties"`
}
type LocalAppInstallDefine struct {
FormFields interface{} `json:"formFields" yaml:"formFields"`
}
type ExtraProperties struct { type ExtraProperties struct {
Tags []Tag `json:"tags"` Tags []Tag `json:"tags"`
} }
@ -84,11 +90,6 @@ type AppConfigVersion struct {
AppForm interface{} `json:"additionalProperties"` AppForm interface{} `json:"additionalProperties"`
} }
func (config AppProperty) GetRequired() string {
by, _ := json.Marshal(config.Required)
return string(by)
}
type Tag struct { type Tag struct {
Key string `json:"key"` Key string `json:"key"`
Name string `json:"name"` Name string `json:"name"`

View File

@ -3,13 +3,13 @@ package model
type App struct { type App struct {
BaseModel BaseModel
Name string `json:"name" gorm:"type:varchar(64);not null"` Name string `json:"name" gorm:"type:varchar(64);not null"`
Key string `json:"key" gorm:"type:varchar(64);not null;uniqueIndex"` Key string `json:"key" gorm:"type:varchar(64);not null;"`
ShortDescZh string `json:"shortDescZh" gorm:"type:longtext;"` ShortDescZh string `json:"shortDescZh" yaml:"shortDescZh" gorm:"type:longtext;"`
ShortDescEn string `json:"shortDescEn" gorm:"type:longtext;"` ShortDescEn string `json:"shortDescEn" yaml:"shortDescEn" gorm:"type:longtext;"`
Icon string `json:"icon" gorm:"type:longtext;"` Icon string `json:"icon" gorm:"type:longtext;"`
Type string `json:"type" gorm:"type:varchar(64);not null"` Type string `json:"type" gorm:"type:varchar(64);not null"`
Status string `json:"status" 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"` Required string `json:"required" gorm:"type:varchar(64);"`
CrossVersionUpdate bool `json:"crossVersionUpdate"` CrossVersionUpdate bool `json:"crossVersionUpdate"`
Limit int `json:"limit" gorm:"type:Integer;not null"` Limit int `json:"limit" gorm:"type:Integer;not null"`
Website string `json:"website" gorm:"type:varchar(64);not null"` Website string `json:"website" gorm:"type:varchar(64);not null"`
@ -21,6 +21,6 @@ type App struct {
LastModified int `json:"lastModified" gorm:"type:Integer;"` LastModified int `json:"lastModified" gorm:"type:Integer;"`
Details []AppDetail `json:"-" gorm:"-:migration"` Details []AppDetail `json:"-" gorm:"-:migration"`
TagsKey []string `json:"-" gorm:"-"` TagsKey []string `json:"tags" yaml:"tags" gorm:"-"`
AppTags []AppTag `json:"-" gorm:"-:migration"` AppTags []AppTag `json:"-" gorm:"-:migration"`
} }

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"github.com/1Panel-dev/1Panel/backend/app/model" "github.com/1Panel-dev/1Panel/backend/app/model"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/clause"
) )
type AppDetailRepo struct { type AppDetailRepo struct {
@ -18,6 +19,7 @@ type IAppDetailRepo interface {
DeleteByAppIds(ctx context.Context, appIds []uint) error DeleteByAppIds(ctx context.Context, appIds []uint) error
GetBy(opts ...DBOption) ([]model.AppDetail, error) GetBy(opts ...DBOption) ([]model.AppDetail, error)
BatchUpdateBy(maps map[string]interface{}, opts ...DBOption) error BatchUpdateBy(maps map[string]interface{}, opts ...DBOption) error
BatchDelete(ctx context.Context, appDetails []model.AppDetail) error
} }
func NewIAppDetailRepo() IAppDetailRepo { func NewIAppDetailRepo() IAppDetailRepo {
@ -66,3 +68,7 @@ func (a AppDetailRepo) BatchUpdateBy(maps map[string]interface{}, opts ...DBOpti
} }
return db.Updates(&maps).Error return db.Updates(&maps).Error
} }
func (a AppDetailRepo) BatchDelete(ctx context.Context, appDetails []model.AppDetail) error {
return getTx(ctx).Omit(clause.Associations).Delete(&appDetails).Error
}

View File

@ -9,6 +9,7 @@ import (
"github.com/1Panel-dev/1Panel/backend/utils/docker" "github.com/1Panel-dev/1Panel/backend/utils/docker"
"io" "io"
"net/http" "net/http"
"os"
"path" "path"
"strconv" "strconv"
@ -332,6 +333,10 @@ func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (
} }
go func() { go func() {
if err = downloadApp(app, appDetail, appInstall, req); err != nil { if err = downloadApp(app, appDetail, appInstall, req); err != nil {
if appInstall.Status == constant.Installing {
appInstall.Status = constant.Error
appInstall.Message = err.Error()
}
_ = appInstallRepo.Save(ctx, appInstall) _ = appInstallRepo.Save(ctx, appInstall)
return return
} }
@ -376,152 +381,274 @@ func (a AppService) GetAppUpdate() (*response.AppUpdateRes, error) {
} }
func (a AppService) SyncAppListFromLocal() { func (a AppService) SyncAppListFromLocal() {
//fileOp := files.NewFileOp() fileOp := files.NewFileOp()
//appDir := constant.LocalAppResourceDir localAppDir := constant.LocalAppResourceDir
//listFile := path.Join(appDir, "list.json") if !fileOp.Stat(localAppDir) {
//if !fileOp.Stat(listFile) { return
// return }
//} var (
//global.LOG.Infof("start sync local apps...") err error
//content, err := fileOp.GetContent(listFile) dirEntries []os.DirEntry
//if err != nil { localApps []model.App
// global.LOG.Errorf("get list.json content failed %s", err.Error()) )
// return
//} defer func() {
//list := &dto.AppList{} if err != nil {
//if err := json.Unmarshal(content, list); err != nil { global.LOG.Errorf("sync app failed %v", err)
// global.LOG.Errorf("unmarshal list.json failed %s", err.Error()) }
// return }()
//}
//oldApps, _ := appRepo.GetBy(appRepo.WithResource(constant.AppResourceLocal)) global.LOG.Infof("start sync local apps...")
//appsMap := getApps(oldApps, list.Apps, true) dirEntries, err = os.ReadDir(localAppDir)
//for _, l := range list.Apps { if err != nil {
// localKey := "local" + l.Config.Key return
// app := appsMap[localKey] }
// icon, err := os.ReadFile(path.Join(appDir, l.Config.Key, "metadata", "logo.png")) for _, dirEntry := range dirEntries {
// if err != nil { if dirEntry.IsDir() {
// global.LOG.Errorf("get [%s] icon error: %s", l.Name, err.Error()) appDir := path.Join(localAppDir, dirEntry.Name())
// continue appDirEntries, err := os.ReadDir(appDir)
// } if err != nil || len(appDirEntries) == 0 {
// iconStr := base64.StdEncoding.EncodeToString(icon) continue
// app.Icon = iconStr }
// app.TagsKey = append(l.Tags, "Local") configYamlPath := path.Join(appDir, "data.yml")
// app.Recommend = 9999 if !fileOp.Stat(configYamlPath) {
// versions := l.Versions continue
// detailsMap := getAppDetails(app.Details, versions) }
// iconPath := path.Join(appDir, "logo.png")
// for _, v := range versions { if !fileOp.Stat(iconPath) {
// detail := detailsMap[v] continue
// detailPath := path.Join(appDir, l.Key, "versions", v) }
// if _, err := os.Stat(detailPath); err != nil { configYamlByte, err := fileOp.GetContent(configYamlPath)
// global.LOG.Errorf("get [%s] folder error: %s", detailPath, err.Error()) if err != nil {
// continue continue
// } }
// readmeStr, err := os.ReadFile(path.Join(detailPath, "README.md")) localAppDefine := dto.LocalAppAppDefine{}
// if err != nil { if err := yaml.Unmarshal(configYamlByte, &localAppDefine); err != nil {
// global.LOG.Errorf("get [%s] README error: %s", detailPath, err.Error()) continue
// } }
// detail.Readme = string(readmeStr) app := localAppDefine.AppProperty
// dockerComposeStr, err := os.ReadFile(path.Join(detailPath, "docker-compose.yml")) app.Resource = constant.AppResourceLocal
// if err != nil { app.Status = constant.AppNormal
// global.LOG.Errorf("get [%s] docker-compose.yml error: %s", detailPath, err.Error()) app.Recommend = 9999
// continue app.TagsKey = append(app.TagsKey, "Local")
// } app.Key = "local" + app.Key
// detail.DockerCompose = string(dockerComposeStr) readMePath := path.Join(appDir, "README.md")
// paramStr, err := os.ReadFile(path.Join(detailPath, "config.json")) if fileOp.Stat(configYamlPath) {
// if err != nil { readMeByte, err := fileOp.GetContent(readMePath)
// global.LOG.Errorf("get [%s] form.json error: %s", detailPath, err.Error()) if err == nil {
// } app.ReadMe = string(readMeByte)
// detail.Params = string(paramStr) }
// detailsMap[v] = detail }
// }
// var newDetails []model.AppDetail iconByte, _ := fileOp.GetContent(iconPath)
// for _, v := range detailsMap { if iconByte != nil {
// newDetails = append(newDetails, v) iconStr := base64.StdEncoding.EncodeToString(iconByte)
// } app.Icon = iconStr
// app.Details = newDetails }
// appsMap[localKey] = app var appDetails []model.AppDetail
//} for _, appDirEntry := range appDirEntries {
//var ( if appDirEntry.IsDir() {
// addAppArray []model.App appDetail := model.AppDetail{
// updateArray []model.App Version: appDirEntry.Name(),
// appIds []uint Status: constant.AppNormal,
//) }
//for _, v := range appsMap { versionDir := path.Join(appDir, appDirEntry.Name())
// if v.ID == 0 { dockerComposePath := path.Join(versionDir, "docker-compose.yml")
// addAppArray = append(addAppArray, v) if !fileOp.Stat(dockerComposePath) {
// } else { continue
// updateArray = append(updateArray, v) }
// appIds = append(appIds, v.ID) dockerComposeByte, _ := fileOp.GetContent(dockerComposePath)
// } if dockerComposeByte == nil {
//} continue
//tx, ctx := getTxAndContext() }
//if len(addAppArray) > 0 { appDetail.DockerCompose = string(dockerComposeByte)
// if err := appRepo.BatchCreate(ctx, addAppArray); err != nil { paramPath := path.Join(versionDir, "data.yml")
// tx.Rollback() if !fileOp.Stat(paramPath) {
// return continue
// } }
//} paramByte, _ := fileOp.GetContent(paramPath)
//for _, update := range updateArray { if paramByte == nil {
// if err := appRepo.Save(ctx, &update); err != nil { continue
// tx.Rollback() }
// return appParamConfig := dto.LocalAppParam{}
// } if err := yaml.Unmarshal(paramByte, &appParamConfig); err != nil {
//} continue
//if err := appTagRepo.DeleteByAppIds(ctx, appIds); err != nil { }
// tx.Rollback() dataJson, err := json.Marshal(appParamConfig.AppParams)
// return if err != nil {
//} continue
//apps := append(addAppArray, updateArray...) }
//var ( appDetail.Params = string(dataJson)
// addDetails []model.AppDetail appDetails = append(appDetails, appDetail)
// updateDetails []model.AppDetail }
// appTags []*model.AppTag }
//) app.Details = appDetails
//tags, _ := tagRepo.All() localApps = append(localApps, app)
//tagMap := make(map[string]uint, len(tags)) }
//for _, app := range tags { }
// tagMap[app.Key] = app.ID
//} var (
//for _, a := range apps { newApps []model.App
// for _, t := range a.TagsKey { deleteApps []model.App
// tagId, ok := tagMap[t] updateApps []model.App
// if ok { oldAppIds []uint
// appTags = append(appTags, &model.AppTag{
// AppId: a.ID, deleteAppIds []uint
// TagId: tagId, deleteAppDetails []model.AppDetail
// }) newAppDetails []model.AppDetail
// } updateDetails []model.AppDetail
// }
// for _, d := range a.Details { appTags []*model.AppTag
// d.AppId = a.ID )
// if d.ID == 0 {
// addDetails = append(addDetails, d) oldApps, _ := appRepo.GetBy(appRepo.WithResource(constant.AppResourceLocal))
// } else { apps := make(map[string]model.App, len(oldApps))
// updateDetails = append(updateDetails, d) for _, old := range oldApps {
// } old.Status = constant.AppTakeDown
// } apps[old.Key] = old
//} }
//if len(addDetails) > 0 { for _, app := range localApps {
// if err := appDetailRepo.BatchCreate(ctx, addDetails); err != nil { if oldApp, ok := apps[app.Key]; ok {
// tx.Rollback() app.ID = oldApp.ID
// return appDetails := make(map[string]model.AppDetail, len(oldApp.Details))
// } for _, old := range oldApp.Details {
//} old.Status = constant.AppTakeDown
//for _, u := range updateDetails { appDetails[old.Version] = old
// if err := appDetailRepo.Update(ctx, u); err != nil { }
// tx.Rollback() for i, newDetail := range app.Details {
// return version := newDetail.Version
// } newDetail.Status = constant.AppNormal
//} newDetail.AppId = app.ID
//if len(appTags) > 0 { oldDetail, exist := appDetails[version]
// if err := appTagRepo.BatchCreate(ctx, appTags); err != nil { if exist {
// tx.Rollback() newDetail.ID = oldDetail.ID
// return }
// } app.Details[i] = newDetail
//} }
//tx.Commit() }
//global.LOG.Infof("sync local apps success") app.TagsKey = append(app.TagsKey, constant.AppResourceLocal)
apps[app.Key] = app
}
for _, app := range apps {
if app.ID == 0 {
newApps = append(newApps, app)
} else {
oldAppIds = append(oldAppIds, app.ID)
if app.Status == constant.AppTakeDown {
installs, _ := appInstallRepo.ListBy(appInstallRepo.WithAppId(app.ID))
if len(installs) > 0 {
continue
}
deleteAppIds = append(deleteAppIds, app.ID)
deleteApps = append(deleteApps, app)
deleteAppDetails = append(deleteAppDetails, app.Details...)
} else {
updateApps = append(updateApps, app)
}
}
}
tags, _ := tagRepo.All()
tagMap := make(map[string]uint, len(tags))
for _, tag := range tags {
tagMap[tag.Key] = tag.ID
}
tx, ctx := getTxAndContext()
defer tx.Rollback()
if len(newApps) > 0 {
if err := appRepo.BatchCreate(ctx, newApps); err != nil {
return
}
}
for _, update := range updateApps {
if err := appRepo.Save(ctx, &update); err != nil {
return
}
}
if len(deleteApps) > 0 {
if err := appRepo.BatchDelete(ctx, deleteApps); err != nil {
return
}
if err := appDetailRepo.DeleteByAppIds(ctx, deleteAppIds); err != nil {
return
}
}
if err := appTagRepo.DeleteByAppIds(ctx, oldAppIds); err != nil {
return
}
var ()
for _, newApp := range newApps {
if newApp.ID > 0 {
for _, detail := range newApp.Details {
detail.AppId = newApp.ID
newAppDetails = append(newAppDetails, detail)
}
}
}
for _, update := range updateApps {
for _, detail := range update.Details {
if detail.ID == 0 {
detail.AppId = update.ID
newAppDetails = append(newAppDetails, detail)
} else {
if detail.Status == constant.AppNormal {
updateDetails = append(updateDetails, detail)
} else {
deleteAppDetails = append(deleteAppDetails, detail)
}
}
}
}
allApps := append(newApps, updateApps...)
for _, app := range allApps {
for _, t := range app.TagsKey {
tagId, ok := tagMap[t]
if ok {
appTags = append(appTags, &model.AppTag{
AppId: app.ID,
TagId: tagId,
})
}
}
}
if len(newAppDetails) > 0 {
if err := appDetailRepo.BatchCreate(ctx, newAppDetails); err != nil {
return
}
}
for _, updateAppDetail := range updateDetails {
if err := appDetailRepo.Update(ctx, updateAppDetail); err != nil {
return
}
}
if len(deleteAppDetails) > 0 {
if err := appDetailRepo.BatchDelete(ctx, deleteAppDetails); err != nil {
return
}
}
if len(oldAppIds) > 0 {
if err := appTagRepo.DeleteByAppIds(ctx, oldAppIds); err != nil {
return
}
}
if len(appTags) > 0 {
if err := appTagRepo.BatchCreate(ctx, appTags); err != nil {
return
}
}
tx.Commit()
global.LOG.Infof("sync local apps success")
} }
func (a AppService) SyncAppListFromRemote() error { func (a AppService) SyncAppListFromRemote() error {
updateRes, err := a.GetAppUpdate() updateRes, err := a.GetAppUpdate()
@ -533,9 +660,10 @@ func (a AppService) SyncAppListFromRemote() error {
return nil return nil
} }
var ( var (
tags []*model.Tag tags []*model.Tag
appTags []*model.AppTag appTags []*model.AppTag
list = updateRes.List list = updateRes.List
oldAppIds []uint
) )
for _, t := range list.Extra.Tags { for _, t := range list.Extra.Tags {
tags = append(tags, &model.Tag{ tags = append(tags, &model.Tag{
@ -547,8 +675,12 @@ func (a AppService) SyncAppListFromRemote() error {
if err != nil { if err != nil {
return err return err
} }
for _, old := range oldApps {
oldAppIds = append(oldAppIds, old.ID)
}
baseRemoteUrl := fmt.Sprintf("%s/%s/1panel", global.CONF.System.AppRepo, global.CONF.System.Mode) baseRemoteUrl := fmt.Sprintf("%s/%s/1panel", global.CONF.System.AppRepo, global.CONF.System.Mode)
appsMap := getApps(oldApps, list.Apps, false) appsMap := getApps(oldApps, list.Apps)
for _, l := range list.Apps { for _, l := range list.Apps {
app := appsMap[l.AppProperty.Key] app := appsMap[l.AppProperty.Key]
iconRes, err := http.Get(l.Icon) iconRes, err := http.Get(l.Icon)
@ -630,29 +762,25 @@ func (a AppService) SyncAppListFromRemote() error {
} }
} }
tx, ctx := getTxAndContext() tx, ctx := getTxAndContext()
defer tx.Rollback()
if len(addAppArray) > 0 { if len(addAppArray) > 0 {
if err := appRepo.BatchCreate(ctx, addAppArray); err != nil { if err := appRepo.BatchCreate(ctx, addAppArray); err != nil {
tx.Rollback()
return err return err
} }
} }
if len(deleteAppArray) > 0 { if len(deleteAppArray) > 0 {
if err := appRepo.BatchDelete(ctx, deleteAppArray); err != nil { if err := appRepo.BatchDelete(ctx, deleteAppArray); err != nil {
tx.Rollback()
return err return err
} }
if err := appDetailRepo.DeleteByAppIds(ctx, deleteIds); err != nil { if err := appDetailRepo.DeleteByAppIds(ctx, deleteIds); err != nil {
tx.Rollback()
return err return err
} }
} }
if err := tagRepo.DeleteAll(ctx); err != nil { if err := tagRepo.DeleteAll(ctx); err != nil {
tx.Rollback()
return err return err
} }
if len(tags) > 0 { if len(tags) > 0 {
if err := tagRepo.BatchCreate(ctx, tags); err != nil { if err := tagRepo.BatchCreate(ctx, tags); err != nil {
tx.Rollback()
return err return err
} }
for _, t := range tags { for _, t := range tags {
@ -661,7 +789,6 @@ func (a AppService) SyncAppListFromRemote() error {
} }
for _, update := range updateAppArray { for _, update := range updateAppArray {
if err := appRepo.Save(ctx, &update); err != nil { if err := appRepo.Save(ctx, &update); err != nil {
tx.Rollback()
return err return err
} }
} }
@ -697,24 +824,23 @@ func (a AppService) SyncAppListFromRemote() error {
} }
if len(addDetails) > 0 { if len(addDetails) > 0 {
if err := appDetailRepo.BatchCreate(ctx, addDetails); err != nil { if err := appDetailRepo.BatchCreate(ctx, addDetails); err != nil {
tx.Rollback()
return err return err
} }
} }
for _, u := range updateDetails { for _, u := range updateDetails {
if err := appDetailRepo.Update(ctx, u); err != nil { if err := appDetailRepo.Update(ctx, u); err != nil {
tx.Rollback()
return err return err
} }
} }
if err := appTagRepo.DeleteAll(ctx); err != nil { if len(oldAppIds) > 0 {
tx.Rollback() if err := appTagRepo.DeleteByAppIds(ctx, oldAppIds); err != nil {
return err return err
}
} }
if len(appTags) > 0 { if len(appTags) > 0 {
if err := appTagRepo.BatchCreate(ctx, appTags); err != nil { if err := appTagRepo.BatchCreate(ctx, appTags); err != nil {
tx.Rollback()
return err return err
} }
} }

View File

@ -316,34 +316,6 @@ func checkRequiredAndLimit(app model.App) error {
if err := checkLimit(app); err != nil { if err := checkLimit(app); err != nil {
return err return err
} }
if app.Required != "" {
var requiredArray []string
if err := json.Unmarshal([]byte(app.Required), &requiredArray); err != nil {
return err
}
for _, key := range requiredArray {
if key == "" {
continue
}
requireApp, err := appRepo.GetFirst(appRepo.WithKey(key))
if err != nil {
return err
}
details, err := appDetailRepo.GetBy(appDetailRepo.WithAppId(requireApp.ID))
if err != nil {
return err
}
var detailIds []uint
for _, d := range details {
detailIds = append(detailIds, d.ID)
}
_, err = appInstallRepo.GetFirst(appInstallRepo.WithDetailIdsIn(detailIds))
if err != nil {
return buserr.WithDetail(constant.ErrAppRequired, requireApp.Name, nil)
}
}
}
return nil return nil
} }
@ -391,7 +363,7 @@ func downloadApp(app model.App, appDetail model.AppDetail, appInstall *model.App
installAppDir := path.Join(constant.AppInstallDir, app.Key) installAppDir := path.Join(constant.AppInstallDir, app.Key)
if app.Resource == constant.AppResourceLocal { if app.Resource == constant.AppResourceLocal {
appResourceDir = constant.LocalAppResourceDir appResourceDir = constant.LocalAppResourceDir
appKey = strings.TrimPrefix(app.Resource, "local") appKey = strings.TrimPrefix(app.Key, "local")
installAppDir = path.Join(constant.LocalAppInstallDir, appKey) installAppDir = path.Join(constant.LocalAppInstallDir, appKey)
} }
resourceDir := path.Join(appResourceDir, appKey, appDetail.Version) resourceDir := path.Join(appResourceDir, appKey, appDetail.Version)
@ -520,7 +492,7 @@ func getAppDetails(details []model.AppDetail, versions []dto.AppConfigVersion) m
return appDetails return appDetails
} }
func getApps(oldApps []model.App, items []dto.AppDefine, isLocal bool) map[string]model.App { func getApps(oldApps []model.App, items []dto.AppDefine) map[string]model.App {
apps := make(map[string]model.App, len(oldApps)) apps := make(map[string]model.App, len(oldApps))
for _, old := range oldApps { for _, old := range oldApps {
old.Status = constant.AppTakeDown old.Status = constant.AppTakeDown
@ -529,18 +501,11 @@ func getApps(oldApps []model.App, items []dto.AppDefine, isLocal bool) map[strin
for _, item := range items { for _, item := range items {
config := item.AppProperty config := item.AppProperty
key := config.Key key := config.Key
if isLocal {
key = "local" + key
}
app, ok := apps[key] app, ok := apps[key]
if !ok { if !ok {
app = model.App{} app = model.App{}
} }
if isLocal { app.Resource = constant.AppResourceRemote
app.Resource = constant.AppResourceLocal
} else {
app.Resource = constant.AppResourceRemote
}
app.Name = item.Name app.Name = item.Name
app.Limit = config.Limit app.Limit = config.Limit
app.Key = key app.Key = key
@ -551,7 +516,6 @@ func getApps(oldApps []model.App, items []dto.AppDefine, isLocal bool) map[strin
app.Github = config.Github app.Github = config.Github
app.Type = config.Type app.Type = config.Type
app.CrossVersionUpdate = config.CrossVersionUpdate app.CrossVersionUpdate = config.CrossVersionUpdate
app.Required = config.GetRequired()
app.Status = constant.AppNormal app.Status = constant.AppNormal
app.LastModified = item.LastModified app.LastModified = item.LastModified
app.ReadMe = item.ReadMe app.ReadMe = item.ReadMe
@ -572,29 +536,6 @@ func handleErr(install model.AppInstall, err error, out string) error {
return reErr return reErr
} }
func getAppFromRepo(downloadPath, version string) error {
downloadUrl := downloadPath
appDir := constant.AppResourceDir
global.LOG.Infof("download file from %s", downloadUrl)
fileOp := files.NewFileOp()
if _, err := fileOp.CopyAndBackup(appDir); err != nil {
return err
}
packagePath := path.Join(constant.ResourceDir, path.Base(downloadUrl))
if err := fileOp.DownloadFile(downloadUrl, packagePath); err != nil {
return err
}
if err := fileOp.Decompress(packagePath, constant.ResourceDir, files.TarGz); err != nil {
return err
}
_ = NewISettingService().Update("AppStoreVersion", version)
defer func() {
_ = fileOp.DeleteFile(packagePath)
}()
return nil
}
func handleInstalled(appInstallList []model.AppInstall, updated bool) ([]response.AppInstalledDTO, error) { func handleInstalled(appInstallList []model.AppInstall, updated bool) ([]response.AppInstalledDTO, error) {
var res []response.AppInstalledDTO var res []response.AppInstalledDTO
for _, installed := range appInstallList { for _, installed := range appInstallList {

View File

@ -7,11 +7,12 @@ import (
) )
var ( var (
DataDir = global.CONF.System.DataDir DataDir = global.CONF.System.DataDir
ResourceDir = path.Join(DataDir, "resource") ResourceDir = path.Join(DataDir, "resource")
AppResourceDir = path.Join(ResourceDir, "apps") AppResourceDir = path.Join(ResourceDir, "apps")
AppInstallDir = path.Join(DataDir, "apps") AppInstallDir = path.Join(DataDir, "apps")
LocalAppResourceDir = path.Join(ResourceDir, "localApps") LocalAppResourceDir = path.Join(AppResourceDir, "local")
LocalAppInstallDir = path.Join(DataDir, "localApps") LocalAppInstallDir = path.Join(AppInstallDir, "local")
RuntimeDir = path.Join(DataDir, "runtime") RemoteAppResourceDir = path.Join(AppResourceDir, "remote")
RuntimeDir = path.Join(DataDir, "runtime")
) )

View File

@ -15,10 +15,13 @@ func Init() {
constant.AppResourceDir = path.Join(constant.ResourceDir, "apps") constant.AppResourceDir = path.Join(constant.ResourceDir, "apps")
constant.AppInstallDir = path.Join(constant.DataDir, "apps") constant.AppInstallDir = path.Join(constant.DataDir, "apps")
constant.RuntimeDir = path.Join(constant.DataDir, "runtime") constant.RuntimeDir = path.Join(constant.DataDir, "runtime")
constant.LocalAppResourceDir = path.Join(constant.ResourceDir, "localApps")
constant.LocalAppInstallDir = path.Join(constant.DataDir, "localApps")
dirs := []string{constant.DataDir, constant.ResourceDir, constant.AppResourceDir, constant.AppInstallDir, global.CONF.System.Backup, constant.RuntimeDir, constant.LocalAppResourceDir} constant.LocalAppResourceDir = path.Join(constant.AppResourceDir, "local")
constant.LocalAppInstallDir = path.Join(constant.AppInstallDir, "local")
constant.RemoteAppResourceDir = path.Join(constant.AppResourceDir, "remote")
dirs := []string{constant.DataDir, constant.ResourceDir, constant.AppResourceDir, constant.AppInstallDir,
global.CONF.System.Backup, constant.RuntimeDir, constant.LocalAppResourceDir, constant.RemoteAppResourceDir}
fileOp := files.NewFileOp() fileOp := files.NewFileOp()
for _, dir := range dirs { for _, dir := range dirs {

View File

@ -314,12 +314,9 @@ var AddEntranceAndSSL = &gormigrate.Migration{
} }
var UpdateTableSetting = &gormigrate.Migration{ var UpdateTableSetting = &gormigrate.Migration{
ID: "20200511-update-table-setting", ID: "20200516-update-table-setting",
Migrate: func(tx *gorm.DB) error { Migrate: func(tx *gorm.DB) error {
if err := tx.AutoMigrate(&model.App{}); err != nil { if err := tx.Create(&model.Setting{Key: "AppStoreLastModified", Value: "0"}).Error; err != nil {
return err
}
if err := tx.Create(&model.Setting{Key: "AppStoreLastModified", Value: ""}).Error; err != nil {
return err return err
} }
return nil return nil
@ -327,8 +324,11 @@ var UpdateTableSetting = &gormigrate.Migration{
} }
var UpdateTableAppDetail = &gormigrate.Migration{ var UpdateTableAppDetail = &gormigrate.Migration{
ID: "20200513-update-table-app-detail", ID: "20200517-update-table-app-detail",
Migrate: func(tx *gorm.DB) error { Migrate: func(tx *gorm.DB) error {
if err := tx.AutoMigrate(&model.App{}); err != nil {
return err
}
if err := tx.AutoMigrate(&model.AppDetail{}); err != nil { if err := tx.AutoMigrate(&model.AppDetail{}); err != nil {
return err return err
} }