Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions apps/list.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
"items": [
{
"key": "mysql",
"name": "Mysql",
"name": "MySQL",
"tags": ["Database"],
"versions": ["5.7.39","8.0.30"],
"short_desc": "常用关系型数据库",
"short_desc": "开源关系型数据库管理系统",
"author": "Oracle",
"type": "runtime",
"required": [],
Expand All @@ -37,7 +37,7 @@
"name": "Nginx",
"tags": ["Server"],
"versions": ["1.23.1"],
"short_desc": "高性能的HTTP和反向代理web服务器",
"short_desc": "高性能的 HTTP 和反向代理服务器",
"author": "Nginx",
"type": "runtime",
"required": [],
Expand All @@ -47,10 +47,10 @@
},
{
"key": "wordpress",
"name": "Wordpress",
"name": "WordPress",
"tags": ["WebSite"],
"versions": ["6.0.1","6.0.2"],
"short_desc": "老牌博客网站模版",
"short_desc": "开源博客软件和内容管理系统",
"author": "Wordpress",
"type": "website",
"required": ["mysql"],
Expand All @@ -63,7 +63,7 @@
"name": "redis",
"tags": ["Database"],
"versions": ["7.0.5","6.0.16"],
"short_desc": "缓存数据库",
"short_desc": "高性能的 key-value 数据库",
"author": "Salvatore Sanfilippo",
"type": "runtime",
"required": [],
Expand All @@ -76,7 +76,7 @@
"name": "Halo",
"tags": ["WebSite"],
"versions": ["1.6.0"],
"short_desc": "现代化的CMS",
"short_desc": "好用又强大的开源建站工具",
"author": "Halo",
"type": "website",
"required": ["mysql"],
Expand All @@ -86,10 +86,10 @@
},
{
"key": "phpmyadmin",
"name": "phpmyadmin",
"name": "phpMyAdmin",
"tags": ["Tool"],
"versions": ["5.2.0"],
"short_desc": "Mysql 客户端",
"short_desc": "MySQL 数据库管理工具",
"author": "phpmyadmin",
"type": "tool",
"required": ["mysql"],
Expand All @@ -99,10 +99,10 @@
},
{
"key": "redis-commander",
"name": "redis-commander",
"name": "Redis-Commander",
"tags": ["Tool"],
"versions": ["0.8.0"],
"short_desc": "Redis 客户端",
"short_desc": "Redis web 管理工具",
"author": "redis-commander",
"type": "tool",
"required": ["redis"],
Expand Down
16 changes: 16 additions & 0 deletions backend/app/api/v1/app_install.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ func (b *BaseApi) CheckAppInstalled(c *gin.Context) {
helper.SuccessWithData(c, checkData)
}

func (b *BaseApi) DeleteCheck(c *gin.Context) {

appInstallId, err := helper.GetIntParamByKey(c, "appInstallId")
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
return
}

checkData, err := appInstallService.DeleteCheck(appInstallId)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, checkData)
}

func (b *BaseApi) SyncInstalled(c *gin.Context) {
if err := appInstallService.SyncAll(); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
Expand Down
6 changes: 6 additions & 0 deletions backend/app/dto/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type AppDTO struct {

type AppDetailDTO struct {
model.AppDetail
Enable bool `json:"enable"`
Params interface{} `json:"params"`
}

Expand Down Expand Up @@ -176,3 +177,8 @@ type AppFormFields struct {
Default string `json:"default"`
EnvKey string `json:"env_variable"`
}

type AppResource struct {
Type string `json:"type"`
Name string `json:"name"`
}
6 changes: 6 additions & 0 deletions backend/app/repo/app_install_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ func (a AppInstallResourceRpo) WithAppInstallId(appInstallId uint) DBOption {
}
}

func (a AppInstallResourceRpo) WithLinkId(linkId uint) DBOption {
return func(db *gorm.DB) *gorm.DB {
return db.Where("link_id = ?", linkId)
}
}

func (a AppInstallResourceRpo) GetBy(opts ...DBOption) ([]model.AppInstallResource, error) {
db := global.DB.Model(&model.AppInstallResource{})
var resources []model.AppInstallResource
Expand Down
15 changes: 12 additions & 3 deletions backend/app/service/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package service
import (
"encoding/base64"
"encoding/json"
"fmt"
"os"
"path"
"strings"
Expand Down Expand Up @@ -125,18 +124,28 @@ func (a AppService) GetAppDetail(appId uint, version string) (dto.AppDetailDTO,
_ = json.Unmarshal([]byte(detail.Params), &paramMap)
appDetailDTO.AppDetail = detail
appDetailDTO.Params = paramMap
appDetailDTO.Enable = true

app, err := appRepo.GetFirst(commonRepo.WithByID(detail.AppId))
if err != nil {
return appDetailDTO, err
}
if err := checkLimit(app); err != nil {
appDetailDTO.Enable = false
}

return appDetailDTO, nil
}

func (a AppService) Install(name string, appDetailId uint, params map[string]interface{}) (*model.AppInstall, error) {

httpPort, err := checkPort("PANEL_APP_PORT_HTTP", params)
if err != nil {
return nil, fmt.Errorf("%d port is in used", httpPort)
return nil, err
}
httpsPort, err := checkPort("PANEL_APP_PORT_HTTPS", params)
if err != nil {
return nil, fmt.Errorf("%d port is in used", httpsPort)
return nil, err
}

appDetail, err := appDetailRepo.GetFirst(commonRepo.WithByID(appDetailId))
Expand Down
52 changes: 52 additions & 0 deletions backend/app/service/app_install.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,58 @@ func (a AppInstallService) ChangeAppPort(req dto.PortUpdate) error {
return nil
}

func (a AppInstallService) DeleteCheck(installId uint) ([]dto.AppResource, error) {
var res []dto.AppResource
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
if err != nil {
return nil, err
}
app, err := appRepo.GetFirst(commonRepo.WithByID(appInstall.AppId))
if err != nil {
return nil, err
}
if app.Type == "website" {
websites, _ := websiteRepo.GetBy(websiteRepo.WithAppInstallId(appInstall.ID))
for _, website := range websites {
res = append(res, dto.AppResource{
Type: "website",
Name: website.PrimaryDomain,
})
}
}
if app.Key == "nginx" {
websites, _ := websiteRepo.GetBy()
for _, website := range websites {
res = append(res, dto.AppResource{
Type: "website",
Name: website.PrimaryDomain,
})
}
}
if app.Type == "runtime" {
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithLinkId(appInstall.ID))
for _, resource := range resources {
linkInstall, _ := appInstallRepo.GetFirst(commonRepo.WithByID(resource.AppInstallId))
res = append(res, dto.AppResource{
Type: "app",
Name: linkInstall.Name,
})
}
}

if app.Key == "mysql" {
databases, _ := mysqlRepo.List()
for _, database := range databases {
res = append(res, dto.AppResource{
Type: "database",
Name: database.Name,
})
}
}

return res, nil
}

func syncById(installId uint) error {
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
if err != nil {
Expand Down
48 changes: 40 additions & 8 deletions backend/app/service/app_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/1Panel-dev/1Panel/backend/buserr"
"io/ioutil"
"math"
"net/http"
Expand Down Expand Up @@ -88,7 +89,7 @@ func checkPort(key string, params map[string]interface{}) (int, error) {
if ok {
portN := int(math.Ceil(port.(float64)))
if common.ScanPort(portN) {
return portN, errors.New("port is in used")
return portN, buserr.New(constant.ErrPortInUsed, portN, nil)
} else {
return portN, nil
}
Expand Down Expand Up @@ -174,6 +175,10 @@ func deleteAppInstall(ctx context.Context, install model.AppInstall) error {
if err := deleteLink(ctx, &install); err != nil {
return err
}
backups, _ := appInstallBackupRepo.GetBy(appInstallBackupRepo.WithAppInstallID(install.ID))
for _, backup := range backups {
_ = op.DeleteDir(backup.Path)
}
if err := appInstallBackupRepo.Delete(ctx, appInstallBackupRepo.WithAppInstallID(install.ID)); err != nil {
return err
}
Expand Down Expand Up @@ -242,11 +247,31 @@ func updateInstall(installId uint, detailId uint) error {
func backupInstall(ctx context.Context, install model.AppInstall) error {
var backup model.AppInstallBackup
appPath := install.GetPath()
backupDir := path.Join(constant.BackupDir, install.App.Key, install.Name)

backupAccount, err := backupRepo.Get(commonRepo.WithByType("LOCAL"))
if err != nil {
return err
}
varMap := make(map[string]interface{})
if err := json.Unmarshal([]byte(backupAccount.Vars), &varMap); err != nil {
return err
}
dir, ok := varMap["dir"]
if !ok {
return errors.New("load local backup dir failed")
}
baseDir, ok := dir.(string)
if !ok {
return errors.New("load local backup dir failed")
}
backupDir := path.Join(baseDir, "apps", install.App.Key, install.Name)
fileOp := files.NewFileOp()
if !fileOp.Stat(backupDir) {
_ = fileOp.CreateDir(backupDir, 0775)
}
now := time.Now()
day := now.Format("2006-01-02-15-04")
fileName := fmt.Sprintf("%s-%s-%s%s", install.Name, install.Version, day, ".tar.gz")
day := now.Format("20060102150405")
fileName := fmt.Sprintf("%s_%s%s", install.Name, day, ".tar.gz")
if err := fileOp.Compress([]string{appPath}, backupDir, fileName, files.TarGz); err != nil {
return err
}
Expand Down Expand Up @@ -346,17 +371,24 @@ func getContainerNames(install model.AppInstall) ([]string, error) {
return containerNames, nil
}

func checkRequiredAndLimit(app model.App) error {

func checkLimit(app model.App) error {
if app.Limit > 0 {
installs, err := appInstallRepo.GetBy(appInstallRepo.WithAppId(app.ID))
if err != nil {
return err
}
if len(installs) >= app.Limit {
return errors.New(fmt.Sprintf("app install limit %d", app.Limit))
return buserr.New(constant.ErrAppLimit, "", nil)
}
}
return nil
}

func checkRequiredAndLimit(app model.App) error {

if err := checkLimit(app); err != nil {
return err
}

if app.Required != "" {
var requiredArray []string
Expand All @@ -382,7 +414,7 @@ func checkRequiredAndLimit(app model.App) error {

_, err = appInstallRepo.GetFirst(appInstallRepo.WithDetailIdsIn(detailIds))
if err != nil {
return errors.New(fmt.Sprintf("%s is required", requireApp.Key))
return buserr.New(constant.ErrAppRequired, requireApp.Name, nil)
}
}
}
Expand Down
32 changes: 32 additions & 0 deletions backend/buserr/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package buserr

import (
"github.com/1Panel-dev/1Panel/backend/i18n"
"github.com/pkg/errors"
)

type BusinessError struct {
Msg string
Detail interface{}
Err error
}

func (e BusinessError) Error() string {

content := i18n.GetErrMsg(e.Msg, map[string]interface{}{"detail": e.Detail})
if content == "" {
if e.Err != nil {
return e.Err.Error()
}
return errors.New(e.Msg).Error()
}
return content
}

func New(Key string, detail interface{}, err error) BusinessError {
return BusinessError{
Msg: Key,
Detail: detail,
Err: err,
}
}
2 changes: 0 additions & 2 deletions backend/constant/dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,4 @@ var (
ResourceDir = path.Join(DefaultDataDir, "resource")
AppResourceDir = path.Join(ResourceDir, "apps")
AppInstallDir = path.Join(DefaultDataDir, "apps")
BackupDir = path.Join(DefaultDataDir, "backup")
AppBackupDir = path.Join(BackupDir, "apps")
)
7 changes: 7 additions & 0 deletions backend/constant/errs.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,10 @@ var (
ErrTypePasswordExpired = "ErrPasswordExpired"
ErrTypeNotSafety = "ErrNotSafety"
)

// app
var (
ErrPortInUsed = "ErrPortInUsed"
ErrAppLimit = "ErrAppLimit"
ErrAppRequired = "ErrAppRequired"
)
Loading