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

feat: 修改应用安装删除数据库逻辑 (#2311)

This commit is contained in:
zhengkunwang 2023-09-15 16:46:13 +08:00 committed by GitHub
parent 9ae935d06a
commit 4e7350aaae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 69 additions and 44 deletions

View File

@ -16,6 +16,7 @@ type IMysqlRepo interface {
Get(opts ...DBOption) (model.DatabaseMysql, error) Get(opts ...DBOption) (model.DatabaseMysql, error)
WithByDatabase(databaseID uint) DBOption WithByDatabase(databaseID uint) DBOption
WithByFrom(from string) DBOption WithByFrom(from string) DBOption
WithDatabaseIDIn(databaseIDs []uint) DBOption
List(opts ...DBOption) ([]model.DatabaseMysql, error) List(opts ...DBOption) ([]model.DatabaseMysql, error)
Page(limit, offset int, opts ...DBOption) (int64, []model.DatabaseMysql, error) Page(limit, offset int, opts ...DBOption) (int64, []model.DatabaseMysql, error)
Create(ctx context.Context, mysql *model.DatabaseMysql) error Create(ctx context.Context, mysql *model.DatabaseMysql) error
@ -121,3 +122,12 @@ func (u *MysqlRepo) WithByFrom(from string) DBOption {
return g return g
} }
} }
func (u *MysqlRepo) WithDatabaseIDIn(databaseIDs []uint) DBOption {
return func(g *gorm.DB) *gorm.DB {
if len(databaseIDs) != 0 {
return g.Where("database_id in (?)", databaseIDs)
}
return g
}
}

View File

@ -23,7 +23,6 @@ import (
"net/http" "net/http"
"os" "os"
"path" "path"
"reflect"
"strconv" "strconv"
"strings" "strings"
) )
@ -283,12 +282,6 @@ func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (
if err != nil { if err != nil {
return return
} }
if DatabaseKeys[app.Key] > 0 {
if existDatabases, _ := databaseRepo.GetList(commonRepo.WithByName(req.Name)); len(existDatabases) > 0 {
err = buserr.New(constant.ErrRemoteExist)
return
}
}
for key := range req.Params { for key := range req.Params {
if !strings.Contains(key, "PANEL_APP_PORT") { if !strings.Contains(key, "PANEL_APP_PORT") {
continue continue
@ -396,13 +389,22 @@ func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (
} }
} }
}() }()
if hostName, ok := req.Params["PANEL_DB_HOST"]; ok { if dbHost, ok := req.Params["PANEL_DB_HOST"]; ok {
database, _ := databaseRepo.Get(commonRepo.WithByName(hostName.(string))) var (
if !reflect.DeepEqual(database, model.Database{}) { databaseID int
req.Params["PANEL_DB_HOST"] = database.Address database model.Database
req.Params["PANEL_DB_PORT"] = database.Port )
req.Params["PANEL_DB_HOST_NAME"] = hostName databaseID, err = strconv.Atoi(dbHost.(string))
if err != nil {
return
} }
database, err = databaseRepo.Get(commonRepo.WithByID(uint(databaseID)))
if err != nil {
return
}
req.Params["PANEL_DB_HOST"] = database.Address
req.Params["PANEL_DB_PORT"] = database.Port
req.Params["PANEL_DB_HOST_ID"] = uint(databaseID)
} }
paramByte, err = json.Marshal(req.Params) paramByte, err = json.Marshal(req.Params)
if err != nil { if err != nil {

View File

@ -435,7 +435,7 @@ func (a *AppInstallService) GetServices(key string) ([]response.AppService, erro
for _, db := range dbs { for _, db := range dbs {
service := response.AppService{ service := response.AppService{
Label: db.Name, Label: db.Name,
Value: db.Name, Value: strconv.Itoa(int(db.ID)),
} }
if db.AppInstallID > 0 { if db.AppInstallID > 0 {
install, err := appInstallRepo.GetFirst(commonRepo.WithByID(db.AppInstallID)) install, err := appInstallRepo.GetFirst(commonRepo.WithByID(db.AppInstallID))

View File

@ -187,19 +187,25 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall
return buserr.New(constant.ErrDbUserNotValid) return buserr.New(constant.ErrDbUserNotValid)
} }
} else { } else {
var createMysql dto.MysqlDBCreate if databaseID, ok := params["PANEL_DB_HOST_ID"]; ok {
createMysql.Name = dbConfig.DbName database, err := databaseRepo.Get(commonRepo.WithByID(databaseID.(uint)))
createMysql.Username = dbConfig.DbUser if err != nil {
// createMysql.Database = dbInstall.Name return err
createMysql.Format = "utf8mb4" }
createMysql.Permission = "%" var createMysql dto.MysqlDBCreate
createMysql.Password = dbConfig.Password createMysql.Name = dbConfig.DbName
createMysql.From = "local" createMysql.Username = dbConfig.DbUser
mysqldb, err := NewIMysqlService().Create(ctx, createMysql) createMysql.DatabaseID = database.ID
if err != nil { createMysql.Format = "utf8mb4"
return err createMysql.Permission = "%"
createMysql.Password = dbConfig.Password
createMysql.From = "local"
mysqldb, err := NewIMysqlService().Create(ctx, createMysql)
if err != nil {
return err
}
resourceId = mysqldb.ID
} }
resourceId = mysqldb.ID
} }
} }
var installResource model.AppInstallResource var installResource model.AppInstallResource
@ -252,17 +258,23 @@ func deleteAppInstall(install model.AppInstall, deleteBackup bool, forceDelete b
if err := deleteLink(ctx, &install, deleteDB, forceDelete, deleteBackup); err != nil && !forceDelete { if err := deleteLink(ctx, &install, deleteDB, forceDelete, deleteBackup); err != nil && !forceDelete {
return err return err
} }
var databaseIDs []uint
// if DatabaseKeys[install.App.Key] > 0 { if DatabaseKeys[install.App.Key] > 0 {
// _ = databaseRepo.Delete(ctx, databaseRepo.WithAppInstallID(install.ID)) databases, _ := databaseRepo.GetList(databaseRepo.WithAppInstallID(install.ID))
// } for _, database := range databases {
databaseIDs = append(databaseIDs, database.ID)
}
_ = databaseRepo.Delete(ctx, databaseRepo.WithAppInstallID(install.ID))
}
switch install.App.Key { switch install.App.Key {
case constant.AppOpenresty: case constant.AppOpenresty:
_ = websiteRepo.DeleteAll(ctx) _ = websiteRepo.DeleteAll(ctx)
_ = websiteDomainRepo.DeleteAll(ctx) _ = websiteDomainRepo.DeleteAll(ctx)
case constant.AppMysql, constant.AppMariaDB: case constant.AppMysql, constant.AppMariaDB:
// _ = mysqlRepo.Delete(ctx, mysqlRepo.WithByMysqlName(install.Name)) if len(databaseIDs) > 0 {
_ = mysqlRepo.Delete(ctx, mysqlRepo.WithDatabaseIDIn(databaseIDs))
}
} }
_ = backupRepo.DeleteRecord(ctx, commonRepo.WithByType("app"), commonRepo.WithByName(install.App.Key), backupRepo.WithByDetailName(install.Name)) _ = backupRepo.DeleteRecord(ctx, commonRepo.WithByType("app"), commonRepo.WithByName(install.App.Key), backupRepo.WithByDetailName(install.Name))
@ -284,7 +296,6 @@ func deleteAppInstall(install model.AppInstall, deleteBackup bool, forceDelete b
} }
func deleteLink(ctx context.Context, install *model.AppInstall, deleteDB bool, forceDelete bool, deleteBackup bool) error { func deleteLink(ctx context.Context, install *model.AppInstall, deleteDB bool, forceDelete bool, deleteBackup bool) error {
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithAppInstallId(install.ID)) resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithAppInstallId(install.ID))
if len(resources) == 0 { if len(resources) == 0 {
return nil return nil
@ -292,16 +303,15 @@ func deleteLink(ctx context.Context, install *model.AppInstall, deleteDB bool, f
for _, re := range resources { for _, re := range resources {
mysqlService := NewIMysqlService() mysqlService := NewIMysqlService()
if (re.Key == constant.AppMysql || re.Key == constant.AppMariaDB) && deleteDB { if (re.Key == constant.AppMysql || re.Key == constant.AppMariaDB) && deleteDB {
database, _ := mysqlRepo.Get(commonRepo.WithByID(re.ResourceId)) mysqlDatabase, _ := mysqlRepo.Get(commonRepo.WithByID(re.ResourceId))
if reflect.DeepEqual(database, model.DatabaseMysql{}) { if mysqlDatabase.ID == 0 {
continue continue
} }
if err := mysqlService.Delete(ctx, dto.MysqlDBDelete{ if err := mysqlService.Delete(ctx, dto.MysqlDBDelete{
ID: database.ID, ID: mysqlDatabase.ID,
ForceDelete: forceDelete, ForceDelete: forceDelete,
DeleteBackup: deleteBackup, DeleteBackup: deleteBackup,
Type: re.Key, Type: re.Key,
// Database: database.MysqlName,
}); err != nil && !forceDelete { }); err != nil && !forceDelete {
return err return err
} }

View File

@ -96,8 +96,6 @@ var (
ErrUserIsExist = "ErrUserIsExist" ErrUserIsExist = "ErrUserIsExist"
ErrDatabaseIsExist = "ErrDatabaseIsExist" ErrDatabaseIsExist = "ErrDatabaseIsExist"
ErrExecTimeOut = "ErrExecTimeOut" ErrExecTimeOut = "ErrExecTimeOut"
ErrRemoteExist = "ErrRemoteExist"
ErrLocalExist = "ErrLocalExist"
) )
// redis // redis

View File

@ -82,8 +82,6 @@ ErrSSLCertificateFormat: 'Certificate file format error, please use pem format'
ErrUserIsExist: "The current user already exists. Please enter a new user" ErrUserIsExist: "The current user already exists. Please enter a new user"
ErrDatabaseIsExist: "The current database already exists. Please enter a new database" ErrDatabaseIsExist: "The current database already exists. Please enter a new database"
ErrExecTimeOut: "SQL execution timed out, please check the database" ErrExecTimeOut: "SQL execution timed out, please check the database"
ErrRemoteExist: "The remote database already exists with that name, please modify it and try again"
ErrLocalExist: "The local database already exists with that name, please modify it and try again"
#redis #redis
ErrTypeOfRedis: "The recovery file type does not match the current persistence mode. Modify the file type and try again" ErrTypeOfRedis: "The recovery file type does not match the current persistence mode. Modify the file type and try again"

View File

@ -82,8 +82,6 @@ ErrSSLCertificateFormat: '證書文件格式錯誤,請使用 pem 格式'
ErrUserIsExist: "當前用戶已存在,請重新輸入" ErrUserIsExist: "當前用戶已存在,請重新輸入"
ErrDatabaseIsExist: "當前資料庫已存在,請重新輸入" ErrDatabaseIsExist: "當前資料庫已存在,請重新輸入"
ErrExecTimeOut: "SQL 執行超時,請檢查數據庫" ErrExecTimeOut: "SQL 執行超時,請檢查數據庫"
ErrRemoteExist: "遠程數據庫已存在該名稱,請修改後重試"
ErrLocalExist: "本地數據庫已存在該名稱,請修改後重試"
#redis #redis
ErrTypeOfRedis: "恢復文件類型與當前持久化方式不符,請修改後重試" ErrTypeOfRedis: "恢復文件類型與當前持久化方式不符,請修改後重試"

View File

@ -82,8 +82,6 @@ ErrSSLCertificateFormat: '证书文件格式错误,请使用 pem 格式'
ErrUserIsExist: "当前用户已存在,请重新输入" ErrUserIsExist: "当前用户已存在,请重新输入"
ErrDatabaseIsExist: "当前数据库已存在,请重新输入" ErrDatabaseIsExist: "当前数据库已存在,请重新输入"
ErrExecTimeOut: "SQL 执行超时,请检查数据库" ErrExecTimeOut: "SQL 执行超时,请检查数据库"
ErrRemoteExist: "远程数据库已存在该名称,请修改后重试"
ErrLocalExist: "本地数据库已存在该名称,请修改后重试"
#redis #redis
ErrTypeOfRedis: "恢复文件类型与当前持久化方式不符,请修改后重试" ErrTypeOfRedis: "恢复文件类型与当前持久化方式不符,请修改后重试"

View File

@ -44,6 +44,7 @@ func Init() {
migrations.UpdateAppInstallResource, migrations.UpdateAppInstallResource,
migrations.DropDatabaseLocal, migrations.DropDatabaseLocal,
migrations.AddDatabaseID, migrations.AddDatabaseID,
migrations.RemoveDatabaseUnique,
}) })
if err := m.Migrate(); err != nil { if err := m.Migrate(); err != nil {
global.LOG.Error(err) global.LOG.Error(err)

View File

@ -735,6 +735,16 @@ var AddDatabaseID = &gormigrate.Migration{
}, },
} }
var RemoveDatabaseUnique = &gormigrate.Migration{
ID: "20230914-update-database",
Migrate: func(tx *gorm.DB) error {
if err := tx.AutoMigrate(&model.Database{}); err != nil {
return err
}
return nil
},
}
func addDatabaseData(appType string, installRepo repo.IAppInstallRepo) *model.Database { func addDatabaseData(appType string, installRepo repo.IAppInstallRepo) *model.Database {
dbInfo, err := installRepo.LoadBaseInfo(appType, "") dbInfo, err := installRepo.LoadBaseInfo(appType, "")
if err == nil { if err == nil {