Skip to content

Commit e4ee07d

Browse files
feat: Support batch installation of applications (#11539)
1 parent 8fb3e78 commit e4ee07d

File tree

38 files changed

+269
-55
lines changed

38 files changed

+269
-55
lines changed

agent/app/api/v2/app.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,23 @@ func (b *BaseApi) GetAppIcon(c *gin.Context) {
220220
c.Header("Last-Modified", time.Now().UTC().Format(http.TimeFormat))
221221
c.Data(http.StatusOK, "image/png", iconBytes)
222222
}
223+
224+
// @Tags App
225+
// @Summary Search app detail by appkey and version
226+
// @Accept json
227+
// @Param appId path integer true "app key"
228+
// @Param version path string true "app version"
229+
// @Success 200 {object} response.AppDetailSimpleDTO
230+
// @Security ApiKeyAuth
231+
// @Security Timestamp
232+
// @Router /apps/detail/node/:appKey/:version [get]
233+
func (b *BaseApi) GetAppDetailForNode(c *gin.Context) {
234+
appKey := c.Param("appKey")
235+
version := c.Param("version")
236+
appDetailDTO, err := appService.GetAppDetailByKey(appKey, version)
237+
if err != nil {
238+
helper.InternalServer(c, err)
239+
return
240+
}
241+
helper.SuccessWithData(c, appDetailDTO)
242+
}

agent/app/dto/app.go

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,25 +84,26 @@ type ExtraProperties struct {
8484
}
8585

8686
type AppProperty struct {
87-
Name string `json:"name"`
88-
Type string `json:"type"`
89-
Tags []string `json:"tags"`
90-
ShortDescZh string `json:"shortDescZh" yaml:"shortDescZh"`
91-
ShortDescEn string `json:"shortDescEn" yaml:"shortDescEn"`
92-
Description Locale `json:"description"`
93-
Key string `json:"key"`
94-
Required []string `json:"Required"`
95-
CrossVersionUpdate bool `json:"crossVersionUpdate" yaml:"crossVersionUpdate"`
96-
Limit int `json:"limit" yaml:"limit"`
97-
Recommend int `json:"recommend" yaml:"recommend"`
98-
Website string `json:"website"`
99-
Github string `json:"github"`
100-
Document string `json:"document"`
101-
Architectures []string `json:"architectures"`
102-
MemoryRequired int `json:"memoryRequired" yaml:"memoryRequired"`
103-
GpuSupport bool `json:"gpuSupport" yaml:"gpuSupport"`
104-
Version float64 `json:"version"`
105-
Deprecated float64 `json:"deprecated"`
87+
Name string `json:"name"`
88+
Type string `json:"type"`
89+
Tags []string `json:"tags"`
90+
ShortDescZh string `json:"shortDescZh" yaml:"shortDescZh"`
91+
ShortDescEn string `json:"shortDescEn" yaml:"shortDescEn"`
92+
Description Locale `json:"description"`
93+
Key string `json:"key"`
94+
Required []string `json:"Required"`
95+
CrossVersionUpdate bool `json:"crossVersionUpdate" yaml:"crossVersionUpdate"`
96+
Limit int `json:"limit" yaml:"limit"`
97+
Recommend int `json:"recommend" yaml:"recommend"`
98+
Website string `json:"website"`
99+
Github string `json:"github"`
100+
Document string `json:"document"`
101+
Architectures []string `json:"architectures"`
102+
MemoryRequired int `json:"memoryRequired" yaml:"memoryRequired"`
103+
GpuSupport bool `json:"gpuSupport" yaml:"gpuSupport"`
104+
Version float64 `json:"version"`
105+
Deprecated float64 `json:"deprecated"`
106+
BatchInstallSupport bool `json:"batchInstallSupport"`
106107
}
107108

108109
type AppConfigVersion struct {

agent/app/dto/request/app.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,16 @@ type AppInstallCreate struct {
2222
Name string `json:"name" validate:"required"`
2323
Services map[string]string `json:"services"`
2424
TaskID string `json:"taskID"`
25+
2526
AppContainerConfig
27+
NodePushConfig
28+
}
29+
30+
type NodePushConfig struct {
31+
Nodes []string `json:"nodes"`
32+
PushNode bool `json:"pushNode"`
33+
AppKey string `json:"appKey"`
34+
Version string `json:"version"`
2635
}
2736

2837
type AppContainerConfig struct {

agent/app/dto/response/app.go

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,18 @@ type AppDTO struct {
2929
}
3030

3131
type AppItem struct {
32-
Name string `json:"name"`
33-
Key string `json:"key"`
34-
ID uint `json:"id"`
35-
Description string `json:"description"`
36-
Status string `json:"status"`
37-
Installed bool `json:"installed"`
38-
Limit int `json:"limit"`
39-
Tags []string `json:"tags"`
40-
GpuSupport bool `json:"gpuSupport"`
41-
Recommend int `json:"recommend"`
42-
Type string `json:"type"`
32+
Name string `json:"name"`
33+
Key string `json:"key"`
34+
ID uint `json:"id"`
35+
Description string `json:"description"`
36+
Status string `json:"status"`
37+
Installed bool `json:"installed"`
38+
Limit int `json:"limit"`
39+
Tags []string `json:"tags"`
40+
GpuSupport bool `json:"gpuSupport"`
41+
Recommend int `json:"recommend"`
42+
Type string `json:"type"`
43+
BatchInstallSupport bool `json:"batchInstallSupport"`
4344
}
4445

4546
type TagDTO struct {
@@ -75,6 +76,10 @@ type AppDetailDTO struct {
7576
GpuSupport bool `json:"gpuSupport"`
7677
}
7778

79+
type AppDetailSimpleDTO struct {
80+
ID uint `json:"id"`
81+
}
82+
7883
type IgnoredApp struct {
7984
Icon string `json:"icon"`
8085
Name string `json:"name"`

agent/app/model/app.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type App struct {
3434
MemoryRequired int `json:"memoryRequired"`
3535
GpuSupport bool `json:"gpuSupport"`
3636
RequiredPanelVersion float64 `json:"requiredPanelVersion"`
37+
BatchInstallSupport bool `json:"batchInstallSupport" yaml:"batchInstallSupport"`
3738

3839
Details []AppDetail `json:"-" gorm:"-:migration"`
3940
TagsKey []string `json:"tags" yaml:"tags" gorm:"-"`

agent/app/service/app.go

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ type IAppService interface {
4747
GetAppDetailByID(id uint) (*response.AppDetailDTO, error)
4848
SyncAppListFromLocal(taskID string)
4949
GetAppIcon(appID uint) ([]byte, error)
50+
GetAppDetailByKey(appKey, version string) (response.AppDetailSimpleDTO, error)
5051
}
5152

5253
func NewIAppService() IAppService {
@@ -118,14 +119,15 @@ func (a AppService) PageApp(ctx *gin.Context, req request.AppSearch) (*response.
118119
}
119120
}
120121
appDTO := &response.AppItem{
121-
ID: ap.ID,
122-
Name: ap.Name,
123-
Key: ap.Key,
124-
Limit: ap.Limit,
125-
GpuSupport: ap.GpuSupport,
126-
Recommend: ap.Recommend,
127-
Description: ap.GetDescription(ctx),
128-
Type: ap.Type,
122+
ID: ap.ID,
123+
Name: ap.Name,
124+
Key: ap.Key,
125+
Limit: ap.Limit,
126+
GpuSupport: ap.GpuSupport,
127+
Recommend: ap.Recommend,
128+
Description: ap.GetDescription(ctx),
129+
Type: ap.Type,
130+
BatchInstallSupport: ap.BatchInstallSupport,
129131
}
130132
appDTOs = append(appDTOs, appDTO)
131133
tags, err := getAppTags(ap.ID, lang)
@@ -203,6 +205,20 @@ func (a AppService) GetApp(ctx *gin.Context, key string) (*response.AppDTO, erro
203205
return &appDTO, nil
204206
}
205207

208+
func (a AppService) GetAppDetailByKey(appKey, version string) (response.AppDetailSimpleDTO, error) {
209+
var appDetailDTO response.AppDetailSimpleDTO
210+
app, err := appRepo.GetFirst(appRepo.WithKey(appKey))
211+
if err != nil {
212+
return appDetailDTO, err
213+
}
214+
appDetail, err := appDetailRepo.GetFirst(appDetailRepo.WithAppId(app.ID), appDetailRepo.WithVersion(version))
215+
if err != nil {
216+
return appDetailDTO, err
217+
}
218+
appDetailDTO.ID = appDetail.ID
219+
return appDetailDTO, nil
220+
}
221+
206222
func (a AppService) GetAppDetail(appID uint, version, appType string) (response.AppDetailDTO, error) {
207223
var (
208224
appDetailDTO response.AppDetailDTO
@@ -386,11 +402,21 @@ func (a AppService) Install(req request.AppInstallCreate) (appInstall *model.App
386402
App: app,
387403
}
388404
composeMap := make(map[string]interface{})
405+
var composeRes []byte
389406
if req.EditCompose {
390407
if err = yaml.Unmarshal([]byte(req.DockerCompose), &composeMap); err != nil {
391408
return
392409
}
393410
} else {
411+
if appDetail.DockerCompose == "" {
412+
dockerComposeUrl := fmt.Sprintf("%s/%s/1panel/%s/%s/docker-compose.yml", global.CONF.RemoteURL.AppRepo, global.CONF.Base.Mode, app.Key, appDetail.Version)
413+
_, composeRes, err = req_helper.HandleRequest(dockerComposeUrl, http.MethodGet, constant.TimeOut20s)
414+
if err != nil {
415+
return
416+
}
417+
appDetail.DockerCompose = string(composeRes)
418+
_ = appDetailRepo.Update(context.Background(), appDetail)
419+
}
394420
if err = yaml.Unmarshal([]byte(appDetail.DockerCompose), &composeMap); err != nil {
395421
return
396422
}

agent/app/service/app_utils.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,6 +1312,7 @@ func getApps(oldApps []model.App, items []dto.AppDefine, systemVersion string, t
13121312
app.MemoryRequired = config.MemoryRequired
13131313
app.Architectures = strings.Join(config.Architectures, ",")
13141314
app.GpuSupport = config.GpuSupport
1315+
app.BatchInstallSupport = config.BatchInstallSupport
13151316
apps[key] = app
13161317
}
13171318
return apps

agent/app/task/task.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ const (
9696
TaskScopeCustomAppstore = "CustomAppstore"
9797
TaskScopeTamper = "Tamper"
9898
TaskScopeFileConvert = "Convert"
99+
TaskScopeTask = "Task"
99100
)
100101

101102
func GetTaskName(resourceName, operate, scope string) string {

agent/init/migration/migrate.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ func InitAgentDB() {
6060
migrations.UpdateWebsite,
6161
migrations.AddisIPtoWebsiteSSL,
6262
migrations.InitPingStatus,
63+
migrations.UpdateApp,
6364
})
6465
if err := m.Migrate(); err != nil {
6566
global.LOG.Error(err)

agent/init/migration/migrations/init.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,3 +800,10 @@ var InitPingStatus = &gormigrate.Migration{
800800
return nil
801801
},
802802
}
803+
804+
var UpdateApp = &gormigrate.Migration{
805+
ID: "20251228-update-app",
806+
Migrate: func(tx *gorm.DB) error {
807+
return tx.AutoMigrate(&model.App{})
808+
},
809+
}

0 commit comments

Comments
 (0)