1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-03-14 01:34:47 +08:00

feat: 应用安装支持选择远程数据库 (#2439)

This commit is contained in:
zhengkunwang 2023-10-07 03:02:44 -05:00 committed by GitHub
parent f004df42af
commit d685bed167
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 52 additions and 27 deletions

View File

@ -77,6 +77,7 @@ type AppService struct {
Label string `json:"label"`
Value string `json:"value"`
Config interface{} `json:"config"`
From string `json:"from"`
}
type AppParam struct {

View File

@ -428,7 +428,7 @@ func (a *AppInstallService) SyncAll(systemInit bool) error {
func (a *AppInstallService) GetServices(key string) ([]response.AppService, error) {
var res []response.AppService
if DatabaseKeys[key] > 0 {
dbs, _ := databaseRepo.GetList(databaseRepo.WithByFrom("local"), commonRepo.WithByType(key))
dbs, _ := databaseRepo.GetList(commonRepo.WithByType(key))
if len(dbs) == 0 {
return res, nil
}
@ -447,6 +447,9 @@ func (a *AppInstallService) GetServices(key string) ([]response.AppService, erro
_ = json.Unmarshal([]byte(install.Param), &paramMap)
}
service.Config = paramMap
service.From = constant.AppResourceLocal
} else {
service.From = constant.AppResourceRemote
}
res = append(res, service)
}

View File

@ -200,9 +200,13 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall
}
if !reflect.DeepEqual(dbConfig, dto.AppDatabase{}) && dbConfig.ServiceName != "" {
dbInstall, err := appInstallRepo.GetFirst(appInstallRepo.WithServiceName(dbConfig.ServiceName))
if err != nil {
return err
hostName := params["PANEL_DB_HOST_NAME"]
if hostName == nil || hostName.(string) == "" {
return nil
}
database, _ := databaseRepo.Get(commonRepo.WithByName(hostName.(string)))
if database.ID == 0 {
return nil
}
var resourceId uint
if dbConfig.DbName != "" && dbConfig.DbUser != "" && dbConfig.Password != "" {
@ -217,11 +221,11 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall
var createMysql dto.MysqlDBCreate
createMysql.Name = dbConfig.DbName
createMysql.Username = dbConfig.DbUser
createMysql.Database = dbInstall.Name
createMysql.Database = database.Name
createMysql.Format = "utf8mb4"
createMysql.Permission = "%"
createMysql.Password = dbConfig.Password
createMysql.From = "local"
createMysql.From = database.From
mysqldb, err := NewIMysqlService().Create(ctx, createMysql)
if err != nil {
return err
@ -232,8 +236,13 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall
var installResource model.AppInstallResource
installResource.ResourceId = resourceId
installResource.AppInstallId = appInstall.ID
installResource.LinkId = dbInstall.ID
installResource.Key = dbInstall.App.Key
if database.AppInstallID > 0 {
installResource.LinkId = database.AppInstallID
} else {
installResource.LinkId = database.ID
}
installResource.Key = database.Type
installResource.From = database.From
if err := appInstallResourceRepo.Create(ctx, &installResource); err != nil {
return err
}

View File

@ -173,31 +173,36 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
newEnvFile := ""
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithAppInstallId(install.ID))
for _, resource := range resources {
if resource.From != "local" {
continue
var database model.Database
switch resource.From {
case constant.AppResourceRemote:
database, err = databaseRepo.Get(commonRepo.WithByID(resource.LinkId))
if err != nil {
return err
}
case constant.AppResourceLocal:
resourceApp, err := appInstallRepo.GetFirst(commonRepo.WithByID(resource.LinkId))
if err != nil {
return err
}
if resource.Key == "mysql" || resource.Key == "mariadb" {
mysqlInfo, err := appInstallRepo.LoadBaseInfo(resource.Key, resourceApp.Name)
database, err = databaseRepo.Get(databaseRepo.WithAppInstallID(resourceApp.ID), commonRepo.WithByType(resource.Key), databaseRepo.WithByFrom(constant.AppResourceLocal), commonRepo.WithByName(resourceApp.Name))
if err != nil {
return err
}
}
if database.Type == "mysql" || database.Type == "mariadb" {
db, err := mysqlRepo.Get(commonRepo.WithByID(resource.ResourceId))
if err != nil {
return err
}
newDB, envMap, err := reCreateDB(db.ID, resourceApp, oldInstall.Env)
newDB, envMap, err := reCreateDB(db.ID, database, oldInstall.Env)
if err != nil {
return err
}
oldHost := fmt.Sprintf("\"PANEL_DB_HOST\":\"%v\"", envMap["PANEL_DB_HOST"].(string))
newHost := fmt.Sprintf("\"PANEL_DB_HOST\":\"%v\"", mysqlInfo.ServiceName)
newHost := fmt.Sprintf("\"PANEL_DB_HOST\":\"%v\"", database.Address)
oldInstall.Env = strings.ReplaceAll(oldInstall.Env, oldHost, newHost)
envMap["PANEL_DB_HOST"] = mysqlInfo.ServiceName
envMap["PANEL_DB_HOST"] = database.Address
newEnvFile, err = coverEnvJsonToStr(oldInstall.Env)
if err != nil {
return err
@ -252,10 +257,10 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
return nil
}
func reCreateDB(dbID uint, app model.AppInstall, oldEnv string) (*model.DatabaseMysql, map[string]interface{}, error) {
func reCreateDB(dbID uint, database model.Database, oldEnv string) (*model.DatabaseMysql, map[string]interface{}, error) {
mysqlService := NewIMysqlService()
ctx := context.Background()
_ = mysqlService.Delete(ctx, dto.MysqlDBDelete{ID: dbID, Database: app.Name, Type: app.App.Key, DeleteBackup: false, ForceDelete: true})
_ = mysqlService.Delete(ctx, dto.MysqlDBDelete{ID: dbID, Database: database.Name, Type: database.Type, DeleteBackup: false, ForceDelete: true})
envMap := make(map[string]interface{})
if err := json.Unmarshal([]byte(oldEnv), &envMap); err != nil {
@ -266,8 +271,8 @@ func reCreateDB(dbID uint, app model.AppInstall, oldEnv string) (*model.Database
oldPassword, _ := envMap["PANEL_DB_USER_PASSWORD"].(string)
createDB, err := mysqlService.Create(context.Background(), dto.MysqlDBCreate{
Name: oldName,
From: "local",
Database: app.Name,
From: database.From,
Database: database.Name,
Format: "utf8mb4",
Username: oldUser,
Password: oldPassword,
@ -276,6 +281,5 @@ func reCreateDB(dbID uint, app model.AppInstall, oldEnv string) (*model.Database
if err != nil {
return nil, envMap, err
}
return createDB, envMap, nil
}

View File

@ -84,6 +84,7 @@ export namespace App {
export interface ServiceParam {
label: '';
value: '';
from?: '';
}
export interface AppInstall {
@ -168,6 +169,7 @@ export namespace App {
label: string;
value: string;
config?: Object;
from?: string;
}
export interface VersionDetail {

View File

@ -79,7 +79,13 @@
:key="service.label"
:value="service.value"
:label="service.label"
></el-option>
>
<span>{{ service.label }}</span>
<span class="float-right" v-if="service.from != ''">
<el-tag v-if="service.from === 'local'">{{ $t('database.local') }}</el-tag>
<el-tag v-else type="success">{{ $t('database.remote') }}</el-tag>
</span>
</el-option>
</el-select>
</el-form-item>
</el-col>