mirror of https://github.com/1Panel-dev/1Panel
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
4.2 KiB
155 lines
4.2 KiB
2 years ago
|
package service
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"github.com/1Panel-dev/1Panel/app/dto"
|
||
|
"github.com/1Panel-dev/1Panel/app/model"
|
||
|
"github.com/1Panel-dev/1Panel/constant"
|
||
|
"github.com/1Panel-dev/1Panel/global"
|
||
|
"github.com/1Panel-dev/1Panel/utils/cmd"
|
||
|
"github.com/1Panel-dev/1Panel/utils/compose"
|
||
|
"github.com/1Panel-dev/1Panel/utils/files"
|
||
|
"github.com/joho/godotenv"
|
||
|
"path"
|
||
|
"strconv"
|
||
|
)
|
||
|
|
||
|
type DatabaseOp string
|
||
|
|
||
|
var (
|
||
|
Add DatabaseOp = "add"
|
||
|
Delete DatabaseOp = "delete"
|
||
|
)
|
||
|
|
||
|
func execDockerCommand(database model.Database, container model.AppContainer, op DatabaseOp) error {
|
||
|
var auth dto.AuthParam
|
||
|
var dbConfig dto.AppDatabase
|
||
|
dbConfig.Password = database.Password
|
||
|
dbConfig.DbUser = database.Username
|
||
|
dbConfig.DbName = database.Dbname
|
||
|
json.Unmarshal([]byte(container.Auth), &auth)
|
||
|
execConfig := dto.ContainerExec{
|
||
|
ContainerName: container.ContainerName,
|
||
|
Auth: auth,
|
||
|
DbParam: dbConfig,
|
||
|
}
|
||
|
_, err := cmd.Exec(getSqlStr(database.Key, op, execConfig))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func getSqlStr(key string, operate DatabaseOp, exec dto.ContainerExec) string {
|
||
|
var str string
|
||
|
param := exec.DbParam
|
||
|
switch key {
|
||
|
case "mysql":
|
||
|
if operate == Add {
|
||
|
str = fmt.Sprintf("docker exec -i %s mysql -uroot -p%s -e \"CREATE USER '%s'@'%%' IDENTIFIED BY '%s';\" -e \"create database %s;\" -e \"GRANT ALL ON %s.* TO '%s'@'%%';\"",
|
||
|
exec.ContainerName, exec.Auth.RootPassword, param.DbUser, param.Password, param.DbName, param.DbName, param.DbUser)
|
||
|
}
|
||
|
if operate == Delete {
|
||
|
str = fmt.Sprintf("docker exec -i %s mysql -uroot -p%s -e \"drop database %s;\" -e \"drop user %s;\" ",
|
||
|
exec.ContainerName, exec.Auth.RootPassword, param.DbName, param.DbUser)
|
||
|
}
|
||
|
}
|
||
|
return str
|
||
|
}
|
||
|
|
||
|
func copyAppData(key, version, installName string, params map[string]interface{}) (composeFilePath string, err error) {
|
||
|
resourceDir := path.Join(global.CONF.System.ResourceDir, "apps", key, version)
|
||
|
installDir := path.Join(global.CONF.System.AppDir, key)
|
||
|
installVersionDir := path.Join(installDir, version)
|
||
|
fileOp := files.NewFileOp()
|
||
|
if err = fileOp.Copy(resourceDir, installVersionDir); err != nil {
|
||
|
return
|
||
|
}
|
||
|
appDir := path.Join(installDir, installName)
|
||
|
if err = fileOp.Rename(installVersionDir, appDir); err != nil {
|
||
|
return
|
||
|
}
|
||
|
composeFilePath = path.Join(appDir, "docker-compose.yml")
|
||
|
envPath := path.Join(appDir, ".env")
|
||
|
|
||
|
envParams := make(map[string]string, len(params))
|
||
|
for k, v := range params {
|
||
|
switch t := v.(type) {
|
||
|
case string:
|
||
|
envParams[k] = t
|
||
|
case float64:
|
||
|
envParams[k] = strconv.FormatFloat(t, 'f', -1, 32)
|
||
|
default:
|
||
|
envParams[k] = t.(string)
|
||
|
}
|
||
|
}
|
||
|
if err = godotenv.Write(envParams, envPath); err != nil {
|
||
|
return
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func upApp(composeFilePath string, appInstall model.AppInstall) {
|
||
|
out, err := compose.Up(composeFilePath)
|
||
|
if err != nil {
|
||
|
if out != "" {
|
||
|
appInstall.Message = out
|
||
|
} else {
|
||
|
appInstall.Message = err.Error()
|
||
|
}
|
||
|
appInstall.Status = constant.Error
|
||
|
_ = appInstallRepo.Save(appInstall)
|
||
|
} else {
|
||
|
appInstall.Status = constant.Running
|
||
|
_ = appInstallRepo.Save(appInstall)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func getAppDetails(details []model.AppDetail, versions []string) map[string]model.AppDetail {
|
||
|
appDetails := make(map[string]model.AppDetail, len(details))
|
||
|
for _, old := range details {
|
||
|
old.Status = constant.AppTakeDown
|
||
|
appDetails[old.Version] = old
|
||
|
}
|
||
|
|
||
|
for _, v := range versions {
|
||
|
detail, ok := appDetails[v]
|
||
|
if ok {
|
||
|
detail.Status = constant.AppNormal
|
||
|
appDetails[v] = detail
|
||
|
} else {
|
||
|
appDetails[v] = model.AppDetail{
|
||
|
Version: v,
|
||
|
Status: constant.AppNormal,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return appDetails
|
||
|
}
|
||
|
|
||
|
func getApps(oldApps []model.App, items []dto.AppDefine) map[string]model.App {
|
||
|
apps := make(map[string]model.App, len(oldApps))
|
||
|
for _, old := range oldApps {
|
||
|
old.Status = constant.AppTakeDown
|
||
|
apps[old.Key] = old
|
||
|
}
|
||
|
for _, item := range items {
|
||
|
app, ok := apps[item.Key]
|
||
|
if !ok {
|
||
|
app = model.App{}
|
||
|
}
|
||
|
app.Name = item.Name
|
||
|
app.Key = item.Key
|
||
|
app.ShortDesc = item.ShortDesc
|
||
|
app.Author = item.Author
|
||
|
app.Source = item.Source
|
||
|
app.Type = item.Type
|
||
|
app.CrossVersionUpdate = item.CrossVersionUpdate
|
||
|
app.Required = item.GetRequired()
|
||
|
app.Status = constant.AppNormal
|
||
|
apps[item.Key] = app
|
||
|
}
|
||
|
return apps
|
||
|
}
|