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"` Label string `json:"label"`
Value string `json:"value"` Value string `json:"value"`
Config interface{} `json:"config"` Config interface{} `json:"config"`
From string `json:"from"`
} }
type AppParam struct { 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) { func (a *AppInstallService) GetServices(key string) ([]response.AppService, error) {
var res []response.AppService var res []response.AppService
if DatabaseKeys[key] > 0 { if DatabaseKeys[key] > 0 {
dbs, _ := databaseRepo.GetList(databaseRepo.WithByFrom("local"), commonRepo.WithByType(key)) dbs, _ := databaseRepo.GetList(commonRepo.WithByType(key))
if len(dbs) == 0 { if len(dbs) == 0 {
return res, nil return res, nil
} }
@ -447,6 +447,9 @@ func (a *AppInstallService) GetServices(key string) ([]response.AppService, erro
_ = json.Unmarshal([]byte(install.Param), &paramMap) _ = json.Unmarshal([]byte(install.Param), &paramMap)
} }
service.Config = paramMap service.Config = paramMap
service.From = constant.AppResourceLocal
} else {
service.From = constant.AppResourceRemote
} }
res = append(res, service) 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 != "" { if !reflect.DeepEqual(dbConfig, dto.AppDatabase{}) && dbConfig.ServiceName != "" {
dbInstall, err := appInstallRepo.GetFirst(appInstallRepo.WithServiceName(dbConfig.ServiceName)) hostName := params["PANEL_DB_HOST_NAME"]
if err != nil { if hostName == nil || hostName.(string) == "" {
return err return nil
}
database, _ := databaseRepo.Get(commonRepo.WithByName(hostName.(string)))
if database.ID == 0 {
return nil
} }
var resourceId uint var resourceId uint
if dbConfig.DbName != "" && dbConfig.DbUser != "" && dbConfig.Password != "" { 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 var createMysql dto.MysqlDBCreate
createMysql.Name = dbConfig.DbName createMysql.Name = dbConfig.DbName
createMysql.Username = dbConfig.DbUser createMysql.Username = dbConfig.DbUser
createMysql.Database = dbInstall.Name createMysql.Database = database.Name
createMysql.Format = "utf8mb4" createMysql.Format = "utf8mb4"
createMysql.Permission = "%" createMysql.Permission = "%"
createMysql.Password = dbConfig.Password createMysql.Password = dbConfig.Password
createMysql.From = "local" createMysql.From = database.From
mysqldb, err := NewIMysqlService().Create(ctx, createMysql) mysqldb, err := NewIMysqlService().Create(ctx, createMysql)
if err != nil { if err != nil {
return err return err
@ -232,8 +236,13 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall
var installResource model.AppInstallResource var installResource model.AppInstallResource
installResource.ResourceId = resourceId installResource.ResourceId = resourceId
installResource.AppInstallId = appInstall.ID installResource.AppInstallId = appInstall.ID
installResource.LinkId = dbInstall.ID if database.AppInstallID > 0 {
installResource.Key = dbInstall.App.Key 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 { if err := appInstallResourceRepo.Create(ctx, &installResource); err != nil {
return err return err
} }

View File

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

View File

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

View File

@ -79,7 +79,13 @@
:key="service.label" :key="service.label"
:value="service.value" :value="service.value"
:label="service.label" :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-select>
</el-form-item> </el-form-item>
</el-col> </el-col>