mirror of
https://gitee.com/fit2cloud-feizhiyun/1Panel.git
synced 2024-12-02 03:48:02 +08:00
feat: 应用导入备份恢复优化 (#1347)
This commit is contained in:
parent
f9fb16198b
commit
95bc3d9855
@ -19,6 +19,7 @@ type IAppInstallResourceRpo interface {
|
||||
GetFirst(opts ...DBOption) (model.AppInstallResource, error)
|
||||
Create(ctx context.Context, resource *model.AppInstallResource) error
|
||||
DeleteBy(ctx context.Context, opts ...DBOption) error
|
||||
BatchUpdateBy(maps map[string]interface{}, opts ...DBOption) error
|
||||
}
|
||||
|
||||
func NewIAppInstallResourceRpo() IAppInstallResourceRpo {
|
||||
@ -71,3 +72,11 @@ func (a AppInstallResourceRpo) Create(ctx context.Context, resource *model.AppIn
|
||||
func (a AppInstallResourceRpo) DeleteBy(ctx context.Context, opts ...DBOption) error {
|
||||
return getTx(ctx, opts...).Delete(&model.AppInstallResource{}).Error
|
||||
}
|
||||
|
||||
func (a *AppInstallResourceRpo) BatchUpdateBy(maps map[string]interface{}, opts ...DBOption) error {
|
||||
db := getDb(opts...).Model(&model.AppInstallResource{})
|
||||
if len(opts) == 0 {
|
||||
db = db.Where("1=1")
|
||||
}
|
||||
return db.Updates(&maps).Error
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
|
||||
if err := json.Unmarshal(appjson, &oldInstall); err != nil {
|
||||
return fmt.Errorf("unmarshal app.json failed, err: %v", err)
|
||||
}
|
||||
if oldInstall.App.Key != install.App.Key || oldInstall.Name != install.Name || oldInstall.Version != install.Version || oldInstall.ID != install.ID {
|
||||
if oldInstall.App.Key != install.App.Key || oldInstall.Name != install.Name || oldInstall.Version != install.Version {
|
||||
return errors.New("the current backup file does not match the application")
|
||||
}
|
||||
|
||||
@ -182,7 +182,14 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := handleMysqlRecover(mysqlInfo, tmpPath, db.Name, fmt.Sprintf("%s.sql.gz", install.Name), true); err != nil {
|
||||
|
||||
newDB, err := reCreateDB(db.ID, oldInstall.Env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = appInstallResourceRepo.BatchUpdateBy(map[string]interface{}{"resource_id": newDB.ID}, commonRepo.WithByID(resource.ID))
|
||||
|
||||
if err := handleMysqlRecover(mysqlInfo, tmpPath, newDB.Name, fmt.Sprintf("%s.sql.gz", install.Name), true); err != nil {
|
||||
global.LOG.Errorf("handle recover from sql.gz failed, err: %v", err)
|
||||
return err
|
||||
}
|
||||
@ -193,11 +200,39 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
|
||||
return err
|
||||
}
|
||||
|
||||
oldInstall.Status = constant.Running
|
||||
if err := appInstallRepo.Save(context.Background(), install); err != nil {
|
||||
oldInstall.ID = install.ID
|
||||
oldInstall.Status = constant.StatusRunning
|
||||
oldInstall.AppId = install.AppId
|
||||
oldInstall.AppDetailId = install.AppDetailId
|
||||
if err := appInstallRepo.Save(context.Background(), &oldInstall); err != nil {
|
||||
global.LOG.Errorf("save db app install failed, err: %v", err)
|
||||
return err
|
||||
}
|
||||
isOk = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func reCreateDB(dbID uint, oldEnv string) (*model.DatabaseMysql, error) {
|
||||
mysqlService := NewIMysqlService()
|
||||
ctx := context.Background()
|
||||
_ = mysqlService.Delete(ctx, dto.MysqlDBDelete{ID: dbID, DeleteBackup: true, ForceDelete: true})
|
||||
|
||||
envMap := make(map[string]interface{})
|
||||
if err := json.Unmarshal([]byte(oldEnv), &envMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
oldName, _ := envMap["PANEL_DB_NAME"].(string)
|
||||
oldUser, _ := envMap["PANEL_DB_USER"].(string)
|
||||
oldPassword, _ := envMap["PANEL_DB_USER_PASSWORD"].(string)
|
||||
createDB, err := mysqlService.Create(context.Background(), dto.MysqlDBCreate{
|
||||
Name: oldName,
|
||||
Format: "utf8mb4",
|
||||
Username: oldUser,
|
||||
Password: oldPassword,
|
||||
Permission: "%",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return createDB, nil
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ import (
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
@ -100,7 +99,7 @@ func (u *MysqlService) Create(ctx context.Context, req dto.MysqlDBCreate) (*mode
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if err := u.createUser(app, req); err != nil {
|
||||
if err := u.createUser(app.ContainerName, app.Password, app.Version, req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -291,7 +290,7 @@ func (u *MysqlService) ChangeAccess(info dto.ChangeDBInfo) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := u.createUser(app, dto.MysqlDBCreate{
|
||||
if err := u.createUser(app.ContainerName, app.Password, app.Version, dto.MysqlDBCreate{
|
||||
Username: mysql.Username,
|
||||
Name: mysql.Name,
|
||||
Permission: info.Value,
|
||||
@ -470,7 +469,7 @@ func (u *MysqlService) LoadStatus() (*dto.MysqlStatus, error) {
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
func (u *MysqlService) createUser(app *repo.RootInfo, req dto.MysqlDBCreate) error {
|
||||
func (u *MysqlService) createUser(container, password, version string, req dto.MysqlDBCreate) error {
|
||||
var userlist []string
|
||||
if strings.Contains(req.Permission, ",") {
|
||||
ips := strings.Split(req.Permission, ",")
|
||||
@ -484,8 +483,8 @@ func (u *MysqlService) createUser(app *repo.RootInfo, req dto.MysqlDBCreate) err
|
||||
}
|
||||
|
||||
for _, user := range userlist {
|
||||
if err := excSQL(app.ContainerName, app.Password, fmt.Sprintf("create user %s identified by '%s';", user, req.Password)); err != nil {
|
||||
handleCreateError(req.Name, userlist, app)
|
||||
if err := excSQL(container, password, fmt.Sprintf("create user %s identified by '%s';", user, req.Password)); err != nil {
|
||||
handleCreateError(container, password, req.Name, userlist)
|
||||
if strings.Contains(err.Error(), "ERROR 1396") {
|
||||
return buserr.New(constant.ErrUserIsExist)
|
||||
}
|
||||
@ -495,20 +494,20 @@ func (u *MysqlService) createUser(app *repo.RootInfo, req dto.MysqlDBCreate) err
|
||||
if req.Name == "*" {
|
||||
grantStr = fmt.Sprintf("grant all privileges on *.* to %s", user)
|
||||
}
|
||||
if strings.HasPrefix(app.Version, "5.7") {
|
||||
if strings.HasPrefix(version, "5.7") {
|
||||
grantStr = fmt.Sprintf("%s identified by '%s' with grant option;", grantStr, req.Password)
|
||||
}
|
||||
if err := excSQL(app.ContainerName, app.Password, grantStr); err != nil {
|
||||
handleCreateError(req.Name, userlist, app)
|
||||
if err := excSQL(container, password, grantStr); err != nil {
|
||||
handleCreateError(container, password, req.Name, userlist)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func handleCreateError(dbName string, userlist []string, app *repo.RootInfo) {
|
||||
_ = excSQL(app.ContainerName, app.Password, fmt.Sprintf("drop database `%s`", dbName))
|
||||
func handleCreateError(contaienr, password, dbName string, userlist []string) {
|
||||
_ = excSQL(contaienr, password, fmt.Sprintf("drop database `%s`", dbName))
|
||||
for _, user := range userlist {
|
||||
if err := excSQL(app.ContainerName, app.Password, fmt.Sprintf("drop user if exists %s", user)); err != nil {
|
||||
if err := excSQL(contaienr, password, fmt.Sprintf("drop user if exists %s", user)); err != nil {
|
||||
global.LOG.Errorf("drop user failed, err: %v", err)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user