From ff0ed465542f27df120a7ed7d178ed8a88511005 Mon Sep 17 00:00:00 2001 From: zhengkunwang <31820853+zhengkunwang223@users.noreply.github.com> Date: Thu, 31 Aug 2023 15:14:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=BA=94=E7=94=A8=E5=AE=89=E8=A3=85?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=80=89=E6=8B=A9=20mariadb=20=E5=92=8C?= =?UTF-8?q?=E5=85=B6=E4=BB=96=20mysql=20(#2130)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/model/app_install_resource.go | 1 + backend/app/repo/database.go | 8 +++ backend/app/service/app.go | 9 +++ backend/app/service/app_install.go | 59 ++++++++++++++------ backend/app/service/app_utils.go | 67 +++++++++++++++++------ backend/init/migration/migrate.go | 1 + backend/init/migration/migrations/init.go | 15 +++++ 7 files changed, 126 insertions(+), 34 deletions(-) diff --git a/backend/app/model/app_install_resource.go b/backend/app/model/app_install_resource.go index 5cdbabe3e..863090459 100644 --- a/backend/app/model/app_install_resource.go +++ b/backend/app/model/app_install_resource.go @@ -6,4 +6,5 @@ type AppInstallResource struct { LinkId uint `json:"linkId" gorm:"type:integer;not null;"` ResourceId uint `json:"resourceId" gorm:"type:integer;"` Key string `json:"key" gorm:"type:varchar(64);not null"` + From string `json:"from" gorm:"type:varchar(64);not null;default:local"` } diff --git a/backend/app/repo/database.go b/backend/app/repo/database.go index 873806da9..a69f8e59c 100644 --- a/backend/app/repo/database.go +++ b/backend/app/repo/database.go @@ -20,6 +20,7 @@ type IDatabaseRepo interface { WithoutByFrom(from string) DBOption WithByMysqlList() DBOption WithAppInstallID(appInstallID uint) DBOption + WithType(dbType string) DBOption } func NewIDatabaseRepo() IDatabaseRepo { @@ -75,6 +76,13 @@ func (d *DatabaseRepo) WithoutByFrom(from string) DBOption { return g.Where("`from` != ?", from) } } + +func (d *DatabaseRepo) WithType(dbType string) DBOption { + return func(g *gorm.DB) *gorm.DB { + return g.Where("`type` = ?", dbType) + } +} + func (d *DatabaseRepo) WithAppInstallID(appInstallID uint) DBOption { return func(g *gorm.DB) *gorm.DB { return g.Where("app_install_id = ?", appInstallID) diff --git a/backend/app/service/app.go b/backend/app/service/app.go index afbfc0884..ee5948267 100644 --- a/backend/app/service/app.go +++ b/backend/app/service/app.go @@ -23,6 +23,7 @@ import ( "net/http" "os" "path" + "reflect" "strconv" "strings" ) @@ -389,6 +390,14 @@ func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) ( } } }() + if hostName, ok := req.Params["PANEL_DB_HOST"]; ok { + database, _ := databaseRepo.Get(commonRepo.WithByName(hostName.(string))) + if !reflect.DeepEqual(database, model.Database{}) { + req.Params["PANEL_DB_HOST"] = database.Address + req.Params["PANEL_DB_PORT"] = database.Port + req.Params["PANEL_DB_HOST_NAME"] = hostName + } + } paramByte, err = json.Marshal(req.Params) if err != nil { return diff --git a/backend/app/service/app_install.go b/backend/app/service/app_install.go index bdf5e2d50..be94b6a1c 100644 --- a/backend/app/service/app_install.go +++ b/backend/app/service/app_install.go @@ -426,25 +426,50 @@ func (a *AppInstallService) SyncAll(systemInit bool) error { } func (a *AppInstallService) GetServices(key string) ([]response.AppService, error) { - app, err := appRepo.GetFirst(appRepo.WithKey(key)) - if err != nil { - return nil, err - } - installs, err := appInstallRepo.ListBy(appInstallRepo.WithAppId(app.ID), appInstallRepo.WithStatus(constant.Running)) - if err != nil { - return nil, err - } var res []response.AppService - for _, install := range installs { - paramMap := make(map[string]string) - if install.Param != "" { - _ = json.Unmarshal([]byte(install.Param), ¶mMap) + if DatabaseKeys[key] { + dbs, _ := databaseRepo.GetList(databaseRepo.WithByFrom("local"), databaseRepo.WithType(key)) + if len(dbs) == 0 { + return res, nil + } + for _, db := range dbs { + service := response.AppService{ + Label: db.Name, + Value: db.Name, + } + if db.AppInstallID > 0 { + install, err := appInstallRepo.GetFirst(commonRepo.WithByID(db.AppInstallID)) + if err != nil { + return nil, err + } + paramMap := make(map[string]string) + if install.Param != "" { + _ = json.Unmarshal([]byte(install.Param), ¶mMap) + } + service.Config = paramMap + } + res = append(res, service) + } + } else { + app, err := appRepo.GetFirst(appRepo.WithKey(key)) + if err != nil { + return nil, err + } + installs, err := appInstallRepo.ListBy(appInstallRepo.WithAppId(app.ID), appInstallRepo.WithStatus(constant.Running)) + if err != nil { + return nil, err + } + for _, install := range installs { + paramMap := make(map[string]string) + if install.Param != "" { + _ = json.Unmarshal([]byte(install.Param), ¶mMap) + } + res = append(res, response.AppService{ + Label: install.Name, + Value: install.ServiceName, + Config: paramMap, + }) } - res = append(res, response.AppService{ - Label: install.Name, - Value: install.ServiceName, - Config: paramMap, - }) } return res, nil } diff --git a/backend/app/service/app_utils.go b/backend/app/service/app_utils.go index 5ef3a0c94..eac2c964e 100644 --- a/backend/app/service/app_utils.go +++ b/backend/app/service/app_utils.go @@ -81,11 +81,47 @@ func checkPort(key string, params map[string]interface{}) (int, error) { return 0, nil } +var DatabaseKeys = map[string]bool{ + "mysql": true, + "mariadb": true, + "postgresql": true, + "mongodb": true, + "redis": true, + "memcached": true, +} + func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall, params map[string]interface{}) error { var dbConfig dto.AppDatabase - if app.Type == "runtime" { + if app.Type == "runtime" && DatabaseKeys[app.Key] { + database := &model.Database{ + AppInstallID: appInstall.ID, + Name: appInstall.Name, + Type: app.Key, + Version: appInstall.Version, + From: "local", + Address: appInstall.ServiceName, + } + detail, err := appDetailRepo.GetFirst(commonRepo.WithByID(appInstall.AppDetailId)) + if err != nil { + return err + } + + formFields := &dto.AppForm{} + if err := json.Unmarshal([]byte(detail.Params), formFields); err != nil { + return err + } + for _, form := range formFields.FormFields { + if form.EnvKey == "PANEL_APP_PORT_HTTP" { + portFloat, ok := form.Default.(float64) + if ok { + database.Port = uint(int(portFloat)) + } + break + } + } + switch app.Key { - case "mysql", "mariadb", "postgresql": + case "mysql", "mariadb", "postgresql", "mongodb": if password, ok := params["PANEL_DB_ROOT_PASSWORD"]; ok { if password != "" { authParam := dto.AuthParam{ @@ -96,24 +132,14 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall return err } appInstall.Param = string(authByte) + database.Password = password.(string) if app.Key == "mysql" || app.Key == "mariadb" { - database := &model.Database{ - AppInstallID: appInstall.ID, - Name: appInstall.Name, - Type: app.Key, - Version: appInstall.Version, - From: "local", - Address: appInstall.ServiceName, - Username: "root", - Password: password.(string), - Port: 3306, - } - if err := databaseRepo.Create(ctx, database); err != nil { - return err - } + database.Username = "root" + } + if rootUser, ok := params["PANEL_DB_ROOT_USER"]; ok { + database.Username = rootUser.(string) } } - } case "redis": if password, ok := params["PANEL_REDIS_ROOT_PASSWORD"]; ok { @@ -127,8 +153,12 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall } appInstall.Param = string(authByte) } + database.Password = password.(string) } } + if err := databaseRepo.Create(ctx, database); err != nil { + return err + } } if app.Type == "website" || app.Type == "tool" { paramByte, err := json.Marshal(params) @@ -264,6 +294,7 @@ func deleteLink(ctx context.Context, install *model.AppInstall, deleteDB bool, f if err := mysqlService.Delete(ctx, dto.MysqlDBDelete{ ID: database.ID, ForceDelete: forceDelete, + Database: database.MysqlName, }); err != nil && !forceDelete { return err } @@ -519,6 +550,8 @@ func handleMap(params map[string]interface{}, envParams map[string]string) { envParams[k] = t case float64: envParams[k] = strconv.FormatFloat(t, 'f', -1, 32) + case uint: + envParams[k] = strconv.Itoa(int(t)) default: envParams[k] = t.(string) } diff --git a/backend/init/migration/migrate.go b/backend/init/migration/migrate.go index cf40f8b51..f006923d6 100644 --- a/backend/init/migration/migrate.go +++ b/backend/init/migration/migrate.go @@ -41,6 +41,7 @@ func Init() { migrations.AddTableFirewall, migrations.AddMariaDB, migrations.UpdateDatabase, + migrations.UpdateAppInstallResource, }) if err := m.Migrate(); err != nil { global.LOG.Error(err) diff --git a/backend/init/migration/migrations/init.go b/backend/init/migration/migrations/init.go index dc1fd1476..f544ded1b 100644 --- a/backend/init/migration/migrations/init.go +++ b/backend/init/migration/migrations/init.go @@ -663,3 +663,18 @@ var UpdateDatabase = &gormigrate.Migration{ return nil }, } + +var UpdateAppInstallResource = &gormigrate.Migration{ + ID: "20230831-update-app_install_resource", + Migrate: func(tx *gorm.DB) error { + if err := tx.AutoMigrate(&model.AppInstallResource{}); err != nil { + return err + } + if err := global.DB.Model(&model.AppInstallResource{}).Where("1 = 1").Updates(map[string]interface{}{ + "from": "local", + }).Error; err != nil { + return err + } + return nil + }, +}