feat: 修改应用文件
@ -1,4 +1,4 @@
|
||||
{
|
||||
"version": "0.0.3",
|
||||
"package": ""
|
||||
"version": "0.0.6",
|
||||
"package": "https://1panel.oss-cn-hangzhou.aliyuncs.com/apps-0.0.6.zip"
|
||||
}
|
||||
|
@ -1,4 +0,0 @@
|
||||
version: '3'
|
||||
networks:
|
||||
1panel:
|
||||
driver: bridge
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.6",
|
||||
"tags": [
|
||||
{
|
||||
"key": "WebSite",
|
||||
@ -21,10 +21,9 @@
|
||||
"tags": ["Database"],
|
||||
"versions": ["5.7.39"],
|
||||
"short_desc": "常用关系型数据库",
|
||||
"icon": "mysql.png",
|
||||
"author": "Oracle",
|
||||
"type": "runtime",
|
||||
"required": [""],
|
||||
"required": [],
|
||||
"crossVersionUpdate": false,
|
||||
"limit": 1,
|
||||
"source": "https://www.mysql.com"
|
||||
@ -35,10 +34,9 @@
|
||||
"tags": ["Database"],
|
||||
"versions": ["8.0.30"],
|
||||
"short_desc": "常用关系型数据库",
|
||||
"icon": "mysql.png",
|
||||
"author": "Oracle",
|
||||
"type": "runtime",
|
||||
"required": [""],
|
||||
"required": [],
|
||||
"crossVersionUpdate": false,
|
||||
"limit": 1,
|
||||
"source": "https://www.mysql.com"
|
||||
@ -49,10 +47,9 @@
|
||||
"tags": ["Server"],
|
||||
"versions": ["1.23.1"],
|
||||
"short_desc": "高性能的HTTP和反向代理web服务器",
|
||||
"icon": "nginx.png",
|
||||
"author": "Nginx",
|
||||
"type": "runtime",
|
||||
"required": [""],
|
||||
"required": [],
|
||||
"limit": 1,
|
||||
"crossVersionUpdate": true,
|
||||
"source": "http://nginx.org/"
|
||||
@ -63,7 +60,6 @@
|
||||
"tags": ["WebSite"],
|
||||
"versions": ["6.0.1","6.0.2"],
|
||||
"short_desc": "老牌博客网站模版",
|
||||
"icon": "wordpress.png",
|
||||
"author": "Wordpress",
|
||||
"type": "website",
|
||||
"required": ["mysql8.0"],
|
||||
@ -77,10 +73,9 @@
|
||||
"tags": ["Database"],
|
||||
"versions": ["7.0.5","6.0.16"],
|
||||
"short_desc": "缓存数据库",
|
||||
"icon": "redis.png",
|
||||
"author": "Salvatore Sanfilippo",
|
||||
"type": "runtime",
|
||||
"required": [""],
|
||||
"required": [],
|
||||
"limit": 0,
|
||||
"crossVersionUpdate": true,
|
||||
"source": "https://redis.io/"
|
||||
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
BIN
apps/mysql8.0/metadata/logo.png
Normal file
After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
0
apps/wordpress/versions/6.0.1/README.md
Normal file
@ -4,9 +4,7 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/gin-gonic/gin"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func (b *BaseApi) SearchApp(c *gin.Context) {
|
||||
@ -78,133 +76,3 @@ func (b *BaseApi) InstallApp(c *gin.Context) {
|
||||
|
||||
helper.SuccessWithData(c, install)
|
||||
}
|
||||
|
||||
func (b *BaseApi) DeleteAppBackup(c *gin.Context) {
|
||||
var req dto.AppBackupDeleteRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := appService.DeleteBackup(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
func (b *BaseApi) SearchInstalled(c *gin.Context) {
|
||||
var req dto.AppInstalledRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(req.PageInfo, dto.PageInfo{}) {
|
||||
total, list, err := appService.PageInstalled(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Items: list,
|
||||
Total: total,
|
||||
})
|
||||
} else {
|
||||
list, err := appService.SearchInstalled(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, list)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BaseApi) SearchInstalledBackup(c *gin.Context) {
|
||||
var req dto.AppBackupRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
total, list, err := appService.PageInstallBackups(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Items: list,
|
||||
Total: total,
|
||||
})
|
||||
}
|
||||
|
||||
func (b *BaseApi) OperateInstalled(c *gin.Context) {
|
||||
var req dto.AppInstallOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := appService.OperateInstall(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
func (b *BaseApi) SyncInstalled(c *gin.Context) {
|
||||
if err := appService.SyncAllInstalled(); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, "")
|
||||
}
|
||||
|
||||
func (b *BaseApi) GetServices(c *gin.Context) {
|
||||
|
||||
key := c.Param("key")
|
||||
services, err := appService.GetServices(key)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, services)
|
||||
}
|
||||
|
||||
func (b *BaseApi) GetUpdateVersions(c *gin.Context) {
|
||||
|
||||
appInstallId, err := helper.GetIntParamByKey(c, "appInstallId")
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||
return
|
||||
}
|
||||
|
||||
versions, err := appService.GetUpdateVersions(appInstallId)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, versions)
|
||||
}
|
||||
|
||||
func (b *BaseApi) ChangeAppPort(c *gin.Context) {
|
||||
var req dto.PortUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := appService.ChangeAppPort(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
139
backend/app/api/v1/app_install.go
Normal file
@ -0,0 +1,139 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/gin-gonic/gin"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func (b *BaseApi) SearchAppInstalled(c *gin.Context) {
|
||||
var req dto.AppInstalledRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(req.PageInfo, dto.PageInfo{}) {
|
||||
total, list, err := appInstallService.Page(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Items: list,
|
||||
Total: total,
|
||||
})
|
||||
} else {
|
||||
list, err := appInstallService.Search(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, list)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BaseApi) SyncInstalled(c *gin.Context) {
|
||||
if err := appInstallService.SyncAll(); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, "")
|
||||
}
|
||||
|
||||
func (b *BaseApi) SearchInstalledBackup(c *gin.Context) {
|
||||
var req dto.AppBackupRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
total, list, err := appInstallService.PageInstallBackups(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Items: list,
|
||||
Total: total,
|
||||
})
|
||||
}
|
||||
|
||||
func (b *BaseApi) OperateInstalled(c *gin.Context) {
|
||||
var req dto.AppInstallOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := appInstallService.Operate(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
func (b *BaseApi) DeleteAppBackup(c *gin.Context) {
|
||||
var req dto.AppBackupDeleteRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := appInstallService.DeleteBackup(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
func (b *BaseApi) GetServices(c *gin.Context) {
|
||||
|
||||
key := c.Param("key")
|
||||
services, err := appInstallService.GetServices(key)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, services)
|
||||
}
|
||||
|
||||
func (b *BaseApi) GetUpdateVersions(c *gin.Context) {
|
||||
|
||||
appInstallId, err := helper.GetIntParamByKey(c, "appInstallId")
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||
return
|
||||
}
|
||||
|
||||
versions, err := appInstallService.GetUpdateVersions(appInstallId)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, versions)
|
||||
}
|
||||
|
||||
func (b *BaseApi) ChangeAppPort(c *gin.Context) {
|
||||
var req dto.PortUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := appInstallService.ChangeAppPort(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
@ -12,6 +12,7 @@ var (
|
||||
authService = service.ServiceGroupApp.AuthService
|
||||
|
||||
appService = service.ServiceGroupApp.AppService
|
||||
appInstallService = service.ServiceGroupApp.AppInstallService
|
||||
|
||||
containerService = service.ServiceGroupApp.ContainerService
|
||||
composeTemplateService = service.ServiceGroupApp.ComposeTemplateService
|
||||
|
@ -130,7 +130,7 @@ type AppDefine struct {
|
||||
Name string `json:"name"`
|
||||
Tags []string `json:"tags"`
|
||||
Versions []string `json:"versions"`
|
||||
Icon string `json:"icon"`
|
||||
//Icon string `json:"icon"`
|
||||
Author string `json:"author"`
|
||||
Source string `json:"source"`
|
||||
ShortDesc string `json:"short_desc"`
|
||||
|
@ -3,31 +3,26 @@ package repo
|
||||
import (
|
||||
"context"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type AppTagRepo struct {
|
||||
}
|
||||
|
||||
func (a AppTagRepo) BatchCreate(ctx context.Context, tags []*model.AppTag) error {
|
||||
db := ctx.Value("db").(*gorm.DB)
|
||||
return db.Create(&tags).Error
|
||||
return getTx(ctx).Create(&tags).Error
|
||||
}
|
||||
|
||||
func (a AppTagRepo) DeleteByAppIds(ctx context.Context, appIds []uint) error {
|
||||
db := ctx.Value("db").(*gorm.DB)
|
||||
return db.Where("app_id in (?)", appIds).Delete(&model.AppTag{}).Error
|
||||
return getTx(ctx).Where("app_id in (?)", appIds).Delete(&model.AppTag{}).Error
|
||||
}
|
||||
|
||||
func (a AppTagRepo) DeleteAll(ctx context.Context) error {
|
||||
db := ctx.Value("db").(*gorm.DB)
|
||||
return db.Where("1 = 1").Delete(&model.AppTag{}).Error
|
||||
return getTx(ctx).Where("1 = 1").Delete(&model.AppTag{}).Error
|
||||
}
|
||||
|
||||
func (a AppTagRepo) GetByAppId(appId uint) ([]model.AppTag, error) {
|
||||
var appTags []model.AppTag
|
||||
if err := global.DB.Where("app_id = ?", appId).Find(&appTags).Error; err != nil {
|
||||
if err := getDb().Where("app_id = ?", appId).Find(&appTags).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return appTags, nil
|
||||
@ -35,7 +30,7 @@ func (a AppTagRepo) GetByAppId(appId uint) ([]model.AppTag, error) {
|
||||
|
||||
func (a AppTagRepo) GetByTagIds(tagIds []uint) ([]model.AppTag, error) {
|
||||
var appTags []model.AppTag
|
||||
if err := global.DB.Where("tag_id in (?)", tagIds).Find(&appTags).Error; err != nil {
|
||||
if err := getDb().Where("tag_id in (?)", tagIds).Find(&appTags).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return appTags, nil
|
||||
|
@ -3,26 +3,22 @@ package repo
|
||||
import (
|
||||
"context"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type TagRepo struct {
|
||||
}
|
||||
|
||||
func (t TagRepo) BatchCreate(ctx context.Context, tags []*model.Tag) error {
|
||||
db := ctx.Value("db").(*gorm.DB)
|
||||
return db.Create(&tags).Error
|
||||
return getTx(ctx).Create(&tags).Error
|
||||
}
|
||||
|
||||
func (t TagRepo) DeleteAll(ctx context.Context) error {
|
||||
db := ctx.Value("db").(*gorm.DB)
|
||||
return db.Where("1 = 1 ").Delete(&model.Tag{}).Error
|
||||
return getTx(ctx).Where("1 = 1 ").Delete(&model.Tag{}).Error
|
||||
}
|
||||
|
||||
func (t TagRepo) All() ([]model.Tag, error) {
|
||||
var tags []model.Tag
|
||||
if err := global.DB.Where("1 = 1 ").Find(&tags).Error; err != nil {
|
||||
if err := getDb().Where("1 = 1 ").Find(&tags).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tags, nil
|
||||
@ -30,7 +26,7 @@ func (t TagRepo) All() ([]model.Tag, error) {
|
||||
|
||||
func (t TagRepo) GetByIds(ids []uint) ([]model.Tag, error) {
|
||||
var tags []model.Tag
|
||||
if err := global.DB.Where("id in (?)", ids).Find(&tags).Error; err != nil {
|
||||
if err := getDb().Where("id in (?)", ids).Find(&tags).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tags, nil
|
||||
@ -38,7 +34,7 @@ func (t TagRepo) GetByIds(ids []uint) ([]model.Tag, error) {
|
||||
|
||||
func (t TagRepo) GetByKeys(keys []string) ([]model.Tag, error) {
|
||||
var tags []model.Tag
|
||||
if err := global.DB.Where("key in (?)", keys).Find(&tags).Error; err != nil {
|
||||
if err := getDb().Where("key in (?)", keys).Find(&tags).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tags, nil
|
||||
@ -46,7 +42,7 @@ func (t TagRepo) GetByKeys(keys []string) ([]model.Tag, error) {
|
||||
|
||||
func (t TagRepo) GetByAppId(appId uint) ([]model.Tag, error) {
|
||||
var tags []model.Tag
|
||||
if err := global.DB.Where("id in (select tag_id from app_tags where app_id = ?)", appId).Find(&tags).Error; err != nil {
|
||||
if err := getDb().Where("id in (select tag_id from app_tags where app_id = ?)", appId).Find(&tags).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tags, nil
|
||||
|
@ -3,12 +3,9 @@ package service
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
@ -17,10 +14,8 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/compose"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||
"golang.org/x/net/context"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
@ -114,56 +109,6 @@ func (a AppService) GetApp(id uint) (dto.AppDTO, error) {
|
||||
return appDTO, nil
|
||||
}
|
||||
|
||||
func (a AppService) PageInstalled(req dto.AppInstalledRequest) (int64, []dto.AppInstalled, error) {
|
||||
total, installed, err := appInstallRepo.Page(req.Page, req.PageSize)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
var installDTOs []dto.AppInstalled
|
||||
for _, in := range installed {
|
||||
installDto := dto.AppInstalled{
|
||||
AppInstall: in,
|
||||
}
|
||||
installDTOs = append(installDTOs, installDto)
|
||||
}
|
||||
|
||||
return total, installDTOs, nil
|
||||
}
|
||||
|
||||
func (a AppService) SearchInstalled(req dto.AppInstalledRequest) ([]dto.AppInstalled, error) {
|
||||
var installs []model.AppInstall
|
||||
var err error
|
||||
if req.Type != "" {
|
||||
apps, err := appRepo.GetBy(appRepo.WithType(req.Type))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var ids []uint
|
||||
for _, app := range apps {
|
||||
ids = append(ids, app.ID)
|
||||
}
|
||||
installs, err = appInstallRepo.GetBy(appInstallRepo.WithAppIdsIn(ids))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
installs, err = appInstallRepo.GetBy()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var installDTOs []dto.AppInstalled
|
||||
for _, in := range installs {
|
||||
installDto := dto.AppInstalled{
|
||||
AppInstall: in,
|
||||
}
|
||||
installDTOs = append(installDTOs, installDto)
|
||||
}
|
||||
|
||||
return installDTOs, nil
|
||||
}
|
||||
|
||||
func (a AppService) GetAppDetail(appId uint, version string) (dto.AppDetailDTO, error) {
|
||||
|
||||
var (
|
||||
@ -183,120 +128,6 @@ func (a AppService) GetAppDetail(appId uint, version string) (dto.AppDetailDTO,
|
||||
return appDetailDTO, nil
|
||||
}
|
||||
|
||||
func (a AppService) PageInstallBackups(req dto.AppBackupRequest) (int64, []model.AppInstallBackup, error) {
|
||||
return appInstallBackupRepo.Page(req.Page, req.PageSize, appInstallBackupRepo.WithAppInstallID(req.AppInstallID))
|
||||
}
|
||||
|
||||
func (a AppService) OperateInstall(req dto.AppInstallOperate) error {
|
||||
install, err := appInstallRepo.GetFirst(commonRepo.WithByID(req.InstallId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dockerComposePath := install.GetComposePath()
|
||||
|
||||
switch req.Operate {
|
||||
case dto.Up:
|
||||
out, err := compose.Up(dockerComposePath)
|
||||
if err != nil {
|
||||
return handleErr(install, err, out)
|
||||
}
|
||||
install.Status = constant.Running
|
||||
case dto.Down:
|
||||
out, err := compose.Down(dockerComposePath)
|
||||
if err != nil {
|
||||
return handleErr(install, err, out)
|
||||
}
|
||||
install.Status = constant.Stopped
|
||||
case dto.Restart:
|
||||
out, err := compose.Restart(dockerComposePath)
|
||||
if err != nil {
|
||||
return handleErr(install, err, out)
|
||||
}
|
||||
install.Status = constant.Running
|
||||
case dto.Delete:
|
||||
tx, ctx := getTxAndContext()
|
||||
if err := deleteAppInstall(ctx, install); err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
tx.Commit()
|
||||
return nil
|
||||
case dto.Sync:
|
||||
return a.SyncInstalled(install.ID)
|
||||
case dto.Backup:
|
||||
tx, ctx := getTxAndContext()
|
||||
if err := backupInstall(ctx, install); err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
tx.Commit()
|
||||
return nil
|
||||
case dto.Restore:
|
||||
return restoreInstall(install, req.BackupId)
|
||||
case dto.Update:
|
||||
return updateInstall(install.ID, req.DetailId)
|
||||
default:
|
||||
return errors.New("operate not support")
|
||||
}
|
||||
|
||||
return appInstallRepo.Save(&install)
|
||||
}
|
||||
|
||||
func (a AppService) ChangeAppPort(req dto.PortUpdate) error {
|
||||
var (
|
||||
files []string
|
||||
newFiles []string
|
||||
)
|
||||
app, err := mysqlRepo.LoadBaseInfoByName(req.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ComposeDir := fmt.Sprintf("%s/%s/%s", constant.AppInstallDir, req.Key, req.Name)
|
||||
ComposeFile := fmt.Sprintf("%s/%s/%s/docker-compose.yml", constant.AppInstallDir, req.Key, req.Name)
|
||||
path := fmt.Sprintf("%s/.env", ComposeDir)
|
||||
lineBytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
files = strings.Split(string(lineBytes), "\n")
|
||||
}
|
||||
for _, line := range files {
|
||||
if strings.HasPrefix(line, "PANEL_APP_PORT_HTTP=") {
|
||||
newFiles = append(newFiles, fmt.Sprintf("PANEL_APP_PORT_HTTP=%v", req.Port))
|
||||
} else {
|
||||
newFiles = append(newFiles, line)
|
||||
}
|
||||
}
|
||||
file, err := os.OpenFile(path, os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
_, err = file.WriteString(strings.Join(newFiles, "\n"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := mysqlRepo.UpdateDatabaseInfo(app.ID, map[string]interface{}{
|
||||
"env": strings.ReplaceAll(app.Env, strconv.FormatInt(app.Port, 10), strconv.FormatInt(req.Port, 10)),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
stdout, err := compose.Down(ComposeFile)
|
||||
if err != nil {
|
||||
return errors.New(stdout)
|
||||
}
|
||||
stdout, err = compose.Up(ComposeFile)
|
||||
if err != nil {
|
||||
return errors.New(stdout)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
func (a AppService) Install(name string, appDetailId uint, params map[string]interface{}) (*model.AppInstall, error) {
|
||||
|
||||
httpPort, err := checkPort("PANEL_APP_PORT_HTTP", params)
|
||||
@ -384,46 +215,6 @@ func (a AppService) Install(name string, appDetailId uint, params map[string]int
|
||||
return &appInstall, nil
|
||||
}
|
||||
|
||||
func (a AppService) SyncAllInstalled() error {
|
||||
allList, err := appInstallRepo.GetBy()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
for _, i := range allList {
|
||||
if err := a.SyncInstalled(i.ID); err != nil {
|
||||
global.LOG.Errorf("sync install app[%s] error,mgs: %s", i.Name, err.Error())
|
||||
}
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a AppService) DeleteBackup(req dto.AppBackupDeleteRequest) error {
|
||||
|
||||
backups, err := appInstallBackupRepo.GetBy(commonRepo.WithIdsIn(req.Ids))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fileOp := files.NewFileOp()
|
||||
|
||||
var errStr strings.Builder
|
||||
for _, backup := range backups {
|
||||
dst := path.Join(backup.Path, backup.Name)
|
||||
if err := fileOp.DeleteFile(dst); err != nil {
|
||||
errStr.WriteString(err.Error())
|
||||
continue
|
||||
}
|
||||
if err := appInstallBackupRepo.Delete(context.TODO(), commonRepo.WithIdsIn(req.Ids)); err != nil {
|
||||
errStr.WriteString(err.Error())
|
||||
}
|
||||
}
|
||||
if errStr.String() != "" {
|
||||
return errors.New(errStr.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a AppService) SyncInstalled(installId uint) error {
|
||||
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
|
||||
if err != nil {
|
||||
@ -520,7 +311,6 @@ func (a AppService) SyncAppList() error {
|
||||
}
|
||||
|
||||
appDir := constant.AppResourceDir
|
||||
iconDir := path.Join(appDir, "icons")
|
||||
listFile := path.Join(appDir, "list.json")
|
||||
|
||||
content, err := os.ReadFile(listFile)
|
||||
@ -553,7 +343,7 @@ func (a AppService) SyncAppList() error {
|
||||
for _, l := range list.Items {
|
||||
|
||||
app := appsMap[l.Key]
|
||||
icon, err := os.ReadFile(path.Join(iconDir, l.Icon))
|
||||
icon, err := os.ReadFile(path.Join(appDir, l.Key, "metadata", "logo.png"))
|
||||
if err != nil {
|
||||
global.LOG.Errorf("get [%s] icon error: %s", l.Name, err.Error())
|
||||
continue
|
||||
@ -567,7 +357,7 @@ func (a AppService) SyncAppList() error {
|
||||
|
||||
for _, v := range versions {
|
||||
detail := detailsMap[v]
|
||||
detailPath := path.Join(appDir, l.Key, v)
|
||||
detailPath := path.Join(appDir, l.Key, "versions", v)
|
||||
if _, err := os.Stat(detailPath); err != nil {
|
||||
global.LOG.Errorf("get [%s] folder error: %s", detailPath, err.Error())
|
||||
continue
|
||||
@ -611,8 +401,7 @@ func (a AppService) SyncAppList() error {
|
||||
}
|
||||
}
|
||||
|
||||
tx := global.DB.Begin()
|
||||
ctx := context.WithValue(context.Background(), "db", tx)
|
||||
tx, ctx := getTxAndContext()
|
||||
|
||||
if len(addAppArray) > 0 {
|
||||
if err := appRepo.BatchCreate(ctx, addAppArray); err != nil {
|
||||
@ -742,47 +531,3 @@ func syncCanUpdate() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppService) GetServices(key string) ([]dto.AppService, error) {
|
||||
app, err := appRepo.GetFirst(appRepo.WithKey(key))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
installs, err := appInstallRepo.GetBy(appInstallRepo.WithAppId(app.ID), appInstallRepo.WithStatus(constant.Running))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []dto.AppService
|
||||
for _, install := range installs {
|
||||
res = append(res, dto.AppService{
|
||||
Label: install.Name,
|
||||
Value: install.ServiceName,
|
||||
})
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (a AppService) GetUpdateVersions(installId uint) ([]dto.AppVersion, error) {
|
||||
install, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
|
||||
var versions []dto.AppVersion
|
||||
if err != nil {
|
||||
return versions, err
|
||||
}
|
||||
app, err := appRepo.GetFirst(commonRepo.WithByID(install.AppId))
|
||||
if err != nil {
|
||||
return versions, err
|
||||
}
|
||||
details, err := appDetailRepo.GetBy(appDetailRepo.WithAppId(app.ID))
|
||||
if err != nil {
|
||||
return versions, err
|
||||
}
|
||||
for _, detail := range details {
|
||||
if common.CompareVersion(detail.Version, install.Version) {
|
||||
versions = append(versions, dto.AppVersion{
|
||||
Version: detail.Version,
|
||||
DetailId: detail.ID,
|
||||
})
|
||||
}
|
||||
}
|
||||
return versions, nil
|
||||
}
|
||||
|
358
backend/app/service/app_install.go
Normal file
@ -0,0 +1,358 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/compose"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||
"github.com/pkg/errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type AppInstallService struct {
|
||||
}
|
||||
|
||||
func (a AppInstallService) Page(req dto.AppInstalledRequest) (int64, []dto.AppInstalled, error) {
|
||||
total, installed, err := appInstallRepo.Page(req.Page, req.PageSize)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
var installDTOs []dto.AppInstalled
|
||||
for _, in := range installed {
|
||||
installDto := dto.AppInstalled{
|
||||
AppInstall: in,
|
||||
}
|
||||
installDTOs = append(installDTOs, installDto)
|
||||
}
|
||||
|
||||
return total, installDTOs, nil
|
||||
}
|
||||
|
||||
func (a AppInstallService) Search(req dto.AppInstalledRequest) ([]dto.AppInstalled, error) {
|
||||
var installs []model.AppInstall
|
||||
var err error
|
||||
if req.Type != "" {
|
||||
apps, err := appRepo.GetBy(appRepo.WithType(req.Type))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var ids []uint
|
||||
for _, app := range apps {
|
||||
ids = append(ids, app.ID)
|
||||
}
|
||||
installs, err = appInstallRepo.GetBy(appInstallRepo.WithAppIdsIn(ids))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
installs, err = appInstallRepo.GetBy()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var installDTOs []dto.AppInstalled
|
||||
for _, in := range installs {
|
||||
installDto := dto.AppInstalled{
|
||||
AppInstall: in,
|
||||
}
|
||||
installDTOs = append(installDTOs, installDto)
|
||||
}
|
||||
|
||||
return installDTOs, nil
|
||||
}
|
||||
|
||||
func (a AppInstallService) Operate(req dto.AppInstallOperate) error {
|
||||
install, err := appInstallRepo.GetFirst(commonRepo.WithByID(req.InstallId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dockerComposePath := install.GetComposePath()
|
||||
|
||||
switch req.Operate {
|
||||
case dto.Up:
|
||||
out, err := compose.Up(dockerComposePath)
|
||||
if err != nil {
|
||||
return handleErr(install, err, out)
|
||||
}
|
||||
install.Status = constant.Running
|
||||
case dto.Down:
|
||||
out, err := compose.Down(dockerComposePath)
|
||||
if err != nil {
|
||||
return handleErr(install, err, out)
|
||||
}
|
||||
install.Status = constant.Stopped
|
||||
case dto.Restart:
|
||||
out, err := compose.Restart(dockerComposePath)
|
||||
if err != nil {
|
||||
return handleErr(install, err, out)
|
||||
}
|
||||
install.Status = constant.Running
|
||||
case dto.Delete:
|
||||
tx, ctx := getTxAndContext()
|
||||
if err := deleteAppInstall(ctx, install); err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
tx.Commit()
|
||||
return nil
|
||||
case dto.Sync:
|
||||
return syncById(install.ID)
|
||||
case dto.Backup:
|
||||
tx, ctx := getTxAndContext()
|
||||
if err := backupInstall(ctx, install); err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
tx.Commit()
|
||||
return nil
|
||||
case dto.Restore:
|
||||
return restoreInstall(install, req.BackupId)
|
||||
case dto.Update:
|
||||
return updateInstall(install.ID, req.DetailId)
|
||||
default:
|
||||
return errors.New("operate not support")
|
||||
}
|
||||
|
||||
return appInstallRepo.Save(&install)
|
||||
}
|
||||
|
||||
func (a AppInstallService) SyncAll() error {
|
||||
allList, err := appInstallRepo.GetBy()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
for _, i := range allList {
|
||||
if err := syncById(i.ID); err != nil {
|
||||
global.LOG.Errorf("sync install app[%s] error,mgs: %s", i.Name, err.Error())
|
||||
}
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a AppInstallService) PageInstallBackups(req dto.AppBackupRequest) (int64, []model.AppInstallBackup, error) {
|
||||
return appInstallBackupRepo.Page(req.Page, req.PageSize, appInstallBackupRepo.WithAppInstallID(req.AppInstallID))
|
||||
}
|
||||
|
||||
func (a AppInstallService) DeleteBackup(req dto.AppBackupDeleteRequest) error {
|
||||
|
||||
backups, err := appInstallBackupRepo.GetBy(commonRepo.WithIdsIn(req.Ids))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fileOp := files.NewFileOp()
|
||||
|
||||
var errStr strings.Builder
|
||||
for _, backup := range backups {
|
||||
dst := path.Join(backup.Path, backup.Name)
|
||||
if err := fileOp.DeleteFile(dst); err != nil {
|
||||
errStr.WriteString(err.Error())
|
||||
continue
|
||||
}
|
||||
if err := appInstallBackupRepo.Delete(context.TODO(), commonRepo.WithIdsIn(req.Ids)); err != nil {
|
||||
errStr.WriteString(err.Error())
|
||||
}
|
||||
}
|
||||
if errStr.String() != "" {
|
||||
return errors.New(errStr.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a AppInstallService) GetServices(key string) ([]dto.AppService, error) {
|
||||
app, err := appRepo.GetFirst(appRepo.WithKey(key))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
installs, err := appInstallRepo.GetBy(appInstallRepo.WithAppId(app.ID), appInstallRepo.WithStatus(constant.Running))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []dto.AppService
|
||||
for _, install := range installs {
|
||||
res = append(res, dto.AppService{
|
||||
Label: install.Name,
|
||||
Value: install.ServiceName,
|
||||
})
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (a AppInstallService) GetUpdateVersions(installId uint) ([]dto.AppVersion, error) {
|
||||
install, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
|
||||
var versions []dto.AppVersion
|
||||
if err != nil {
|
||||
return versions, err
|
||||
}
|
||||
app, err := appRepo.GetFirst(commonRepo.WithByID(install.AppId))
|
||||
if err != nil {
|
||||
return versions, err
|
||||
}
|
||||
details, err := appDetailRepo.GetBy(appDetailRepo.WithAppId(app.ID))
|
||||
if err != nil {
|
||||
return versions, err
|
||||
}
|
||||
for _, detail := range details {
|
||||
if common.CompareVersion(detail.Version, install.Version) {
|
||||
versions = append(versions, dto.AppVersion{
|
||||
Version: detail.Version,
|
||||
DetailId: detail.ID,
|
||||
})
|
||||
}
|
||||
}
|
||||
return versions, nil
|
||||
}
|
||||
|
||||
func (a AppInstallService) ChangeAppPort(req dto.PortUpdate) error {
|
||||
var (
|
||||
files []string
|
||||
newFiles []string
|
||||
)
|
||||
app, err := mysqlRepo.LoadBaseInfoByName(req.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ComposeDir := fmt.Sprintf("%s/%s/%s", constant.AppInstallDir, req.Key, req.Name)
|
||||
ComposeFile := fmt.Sprintf("%s/%s/%s/docker-compose.yml", constant.AppInstallDir, req.Key, req.Name)
|
||||
path := fmt.Sprintf("%s/.env", ComposeDir)
|
||||
lineBytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
files = strings.Split(string(lineBytes), "\n")
|
||||
}
|
||||
for _, line := range files {
|
||||
if strings.HasPrefix(line, "PANEL_APP_PORT_HTTP=") {
|
||||
newFiles = append(newFiles, fmt.Sprintf("PANEL_APP_PORT_HTTP=%v", req.Port))
|
||||
} else {
|
||||
newFiles = append(newFiles, line)
|
||||
}
|
||||
}
|
||||
file, err := os.OpenFile(path, os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
_, err = file.WriteString(strings.Join(newFiles, "\n"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := mysqlRepo.UpdateDatabaseInfo(app.ID, map[string]interface{}{
|
||||
"env": strings.ReplaceAll(app.Env, strconv.FormatInt(app.Port, 10), strconv.FormatInt(req.Port, 10)),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
stdout, err := compose.Down(ComposeFile)
|
||||
if err != nil {
|
||||
return errors.New(stdout)
|
||||
}
|
||||
stdout, err = compose.Up(ComposeFile)
|
||||
if err != nil {
|
||||
return errors.New(stdout)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func syncById(installId uint) error {
|
||||
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
containerNames, err := getContainerNames(appInstall)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cli, err := docker.NewClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
containers, err := cli.ListContainersByName(containerNames)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var (
|
||||
errorContainers []string
|
||||
notFoundContainers []string
|
||||
runningContainers []string
|
||||
)
|
||||
|
||||
for _, n := range containers {
|
||||
if n.State != "running" {
|
||||
errorContainers = append(errorContainers, n.Names[0])
|
||||
} else {
|
||||
runningContainers = append(runningContainers, n.Names[0])
|
||||
}
|
||||
}
|
||||
for _, old := range containerNames {
|
||||
exist := false
|
||||
for _, new := range containers {
|
||||
if common.ExistWithStrArray(old, new.Names) {
|
||||
exist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !exist {
|
||||
notFoundContainers = append(notFoundContainers, old)
|
||||
}
|
||||
}
|
||||
|
||||
containerCount := len(containers)
|
||||
errCount := len(errorContainers)
|
||||
notFoundCount := len(notFoundContainers)
|
||||
normalCount := len(containerNames)
|
||||
runningCount := len(runningContainers)
|
||||
|
||||
if containerCount == 0 {
|
||||
appInstall.Status = constant.Error
|
||||
appInstall.Message = "container is not found"
|
||||
return appInstallRepo.Save(&appInstall)
|
||||
}
|
||||
if errCount == 0 && notFoundCount == 0 {
|
||||
appInstall.Status = constant.Running
|
||||
return appInstallRepo.Save(&appInstall)
|
||||
}
|
||||
if errCount == normalCount {
|
||||
appInstall.Status = constant.Error
|
||||
}
|
||||
if notFoundCount == normalCount {
|
||||
appInstall.Status = constant.Stopped
|
||||
}
|
||||
if runningCount < normalCount {
|
||||
appInstall.Status = constant.UnHealthy
|
||||
}
|
||||
|
||||
var errMsg strings.Builder
|
||||
if errCount > 0 {
|
||||
errMsg.Write([]byte(string(rune(errCount)) + " error containers:"))
|
||||
for _, e := range errorContainers {
|
||||
errMsg.Write([]byte(e))
|
||||
}
|
||||
errMsg.Write([]byte("\n"))
|
||||
}
|
||||
if notFoundCount > 0 {
|
||||
errMsg.Write([]byte(string(rune(notFoundCount)) + " not found containers:"))
|
||||
for _, e := range notFoundContainers {
|
||||
errMsg.Write([]byte(e))
|
||||
}
|
||||
errMsg.Write([]byte("\n"))
|
||||
}
|
||||
appInstall.Message = errMsg.String()
|
||||
return appInstallRepo.Save(&appInstall)
|
||||
}
|
@ -411,7 +411,7 @@ func handleMap(params map[string]interface{}, envParams map[string]string) {
|
||||
}
|
||||
|
||||
func copyAppData(key, version, installName string, params map[string]interface{}) (err error) {
|
||||
resourceDir := path.Join(constant.AppResourceDir, key, version)
|
||||
resourceDir := path.Join(constant.AppResourceDir, key, "versions", version)
|
||||
installDir := path.Join(constant.AppInstallDir, key)
|
||||
installVersionDir := path.Join(installDir, version)
|
||||
fileOp := files.NewFileOp()
|
||||
|
@ -6,6 +6,7 @@ type ServiceGroup struct {
|
||||
AuthService
|
||||
|
||||
AppService
|
||||
AppInstallService
|
||||
|
||||
ContainerService
|
||||
ImageService
|
||||
|
@ -21,7 +21,7 @@ func (a *AppRouter) InitAppRouter(Router *gin.RouterGroup) {
|
||||
appRouter.GET("/detail/:appId/:version", baseApi.GetAppDetail)
|
||||
appRouter.POST("/install", baseApi.InstallApp)
|
||||
appRouter.GET("/installed/:appInstallId/versions", baseApi.GetUpdateVersions)
|
||||
appRouter.POST("/installed", baseApi.SearchInstalled)
|
||||
appRouter.POST("/installed", baseApi.SearchAppInstalled)
|
||||
appRouter.POST("/installed/op", baseApi.OperateInstalled)
|
||||
appRouter.POST("/installed/sync", baseApi.SyncInstalled)
|
||||
appRouter.POST("/installed/backups", baseApi.SearchInstalledBackup)
|
||||
|
@ -720,5 +720,6 @@ export default {
|
||||
renewSSL: '续签',
|
||||
renewHelper: '确定续签证书?',
|
||||
renewSuccess: '续签证书',
|
||||
config: '配置',
|
||||
},
|
||||
};
|
||||
|
@ -9,8 +9,9 @@
|
||||
<el-tab-pane :label="$t('website.rate')">
|
||||
<LimitConn :id="id" v-if="index == '2'"></LimitConn>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'HTTPS'"></el-tab-pane>
|
||||
<el-tab-pane :label="$t('website.other')">
|
||||
<Other :id="id" v-if="index == '3'"></Other>
|
||||
<Other :id="id" v-if="index == '4'"></Other>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
|
@ -2,9 +2,11 @@
|
||||
<LayoutContent :header="'网站设置'" :back-name="'Website'">
|
||||
<el-tabs v-model="index" @click="changeTab(index)">
|
||||
<el-tab-pane label="基本" name="basic">
|
||||
<Basic :id="id" v-if="index === 'basic'"></Basic>
|
||||
<Basic :key="id" :id="id" v-if="index === 'basic'"></Basic>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="安全" name="safety">
|
||||
<Safety :key="id" :id="id" v-if="index === 'safety'"></Safety>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="安全">反代</el-tab-pane>
|
||||
<el-tab-pane label="备份">反代</el-tab-pane>
|
||||
<el-tab-pane label="源文">反代</el-tab-pane>
|
||||
</el-tabs>
|
||||
@ -15,6 +17,7 @@
|
||||
import LayoutContent from '@/layout/layout-content.vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import Basic from './basic/index.vue';
|
||||
import Safety from './safety/index.vue';
|
||||
import router from '@/routers';
|
||||
|
||||
const props = defineProps({
|
||||
@ -36,9 +39,7 @@ const changeTab = (index: string) => {
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
id.value = Number(props.id);
|
||||
if (props.tab !== index.value) {
|
||||
index.value = props.tab;
|
||||
}
|
||||
id.value = Number(props.id);
|
||||
});
|
||||
</script>
|
||||
|
26
frontend/src/views/website/website/config/safety/index.vue
Normal file
@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<el-tabs tab-position="left" type="border-card" v-model="index">
|
||||
<el-tab-pane :label="'CC 防护'" :id="id"></el-tab-pane>
|
||||
<el-tab-pane :label="'白名单'"></el-tab-pane>
|
||||
<el-tab-pane :label="'黑名单'"></el-tab-pane>
|
||||
<el-tab-pane :label="'并发限制'"></el-tab-pane>
|
||||
<el-tab-pane :label="'请求限制'"></el-tab-pane>
|
||||
<el-tab-pane :label="'禁止爬虫'"></el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const id = computed(() => {
|
||||
return props.id;
|
||||
});
|
||||
|
||||
let index = ref('0');
|
||||
</script>
|
@ -4,8 +4,8 @@
|
||||
<template #toolbar>
|
||||
<el-button type="primary" plain @click="openCreate">{{ $t('commons.button.create') }}</el-button>
|
||||
<el-button type="primary" plain @click="openGroup">{{ $t('website.group') }}</el-button>
|
||||
<el-button type="primary" plain>{{ '修改默认页' }}</el-button>
|
||||
<el-button type="primary" plain>{{ '默认站点' }}</el-button>
|
||||
<!-- <el-button type="primary" plain>{{ '修改默认页' }}</el-button>
|
||||
<el-button type="primary" plain>{{ '默认站点' }}</el-button> -->
|
||||
</template>
|
||||
<el-table-column :label="$t('commons.table.name')" fix show-overflow-tooltip prop="primaryDomain">
|
||||
<template #default="{ row }">
|
||||
@ -13,9 +13,9 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.status')" prop="status"></el-table-column>
|
||||
<el-table-column :label="'备份'" prop="backup"></el-table-column>
|
||||
<!-- <el-table-column :label="'备份'" prop="backup"></el-table-column> -->
|
||||
<el-table-column :label="'备注'" prop="remark"></el-table-column>
|
||||
<el-table-column :label="'SSL证书'" prop="ssl"></el-table-column>
|
||||
<!-- <el-table-column :label="'SSL证书'" prop="ssl"></el-table-column> -->
|
||||
<fu-table-operations
|
||||
:ellipsis="1"
|
||||
:buttons="buttons"
|
||||
@ -73,8 +73,10 @@ const openConfig = (id: number) => {
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
label: '设置',
|
||||
click: open,
|
||||
label: i18n.global.t('website.config'),
|
||||
click: function (row: WebSite.WebSite) {
|
||||
openConfig(row.id);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('app.delete'),
|
||||
|
76
package-lock.json
generated
@ -1,76 +0,0 @@
|
||||
{
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"@codemirror/commands": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.1.1.tgz",
|
||||
"integrity": "sha512-ibDohwkk7vyu3VsnZNlQhwk0OETBtlkYV+6AHfn5Zgq0sxa+yGVX+apwtC3M4wh6AH7yU5si/NysoECs5EGS3Q==",
|
||||
"requires": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/language": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz",
|
||||
"integrity": "sha512-MC3svxuvIj0MRpFlGHxLS6vPyIdbTr2KKPEW46kCoCXw2ktb4NTkpkPBI/lSP/FoNXLCBJ0mrnUi1OoZxtpW1Q==",
|
||||
"requires": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/common": "^1.0.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0",
|
||||
"style-mod": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/state": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.1.2.tgz",
|
||||
"integrity": "sha512-Mxff85Hp5va+zuj+H748KbubXjrinX/k28lj43H14T2D0+4kuvEFIEIO7hCEcvBT8ubZyIelt9yGOjj2MWOEQA=="
|
||||
},
|
||||
"@codemirror/view": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.3.0.tgz",
|
||||
"integrity": "sha512-jMN9OGKmzRPJ+kksfMrB5e/A9heQncirHsz8XNBpgEbYONCk5tWHMKVWKTNwznkUGD5mnigXI1i5YIcWpscSPg==",
|
||||
"requires": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"style-mod": "^4.0.0",
|
||||
"w3c-keyname": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"@lezer/common": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.1.tgz",
|
||||
"integrity": "sha512-8TR5++Q/F//tpDsLd5zkrvEX5xxeemafEaek7mUp7Y+bI8cKQXdSqhzTOBaOogETcMOVr0pT3BBPXp13477ciw=="
|
||||
},
|
||||
"@lezer/highlight": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.1.1.tgz",
|
||||
"integrity": "sha512-duv9D23O9ghEDnnUDmxu+L8pJy4nYo4AbCOHIudUhscrLSazqeJeK1V50EU6ZufWF1zv0KJwu/frFRyZWXxHBQ==",
|
||||
"requires": {
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"@lezer/lr": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.3.tgz",
|
||||
"integrity": "sha512-qpB7rBzH8f6Mzjv2AVZRahcm+2Cf7nbIH++uXbvVOL1yIRvVWQ3HAM/saeBLCyz/togB7LGo76qdJYL1uKQlqA==",
|
||||
"requires": {
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"style-mod": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz",
|
||||
"integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw=="
|
||||
},
|
||||
"w3c-keyname": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.6.tgz",
|
||||
"integrity": "sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg=="
|
||||
}
|
||||
}
|
||||
}
|