feat: 实现远程数据备份恢复功能 (#1774)

This commit is contained in:
ssongliu 2023-07-27 14:32:23 +08:00 committed by GitHub
parent 87a7cf3aca
commit e83e592e0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 154 additions and 170 deletions

View File

@ -15,6 +15,7 @@ type MysqlDBInfo struct {
CreatedAt time.Time `json:"createdAt"`
Name string `json:"name"`
From string `json:"from"`
MysqlName string `json:"mysqlName"`
Format string `json:"format"`
Username string `json:"username"`
Password string `json:"password"`

View File

@ -57,7 +57,7 @@ func (u *RemoteDBRepo) GetList(opts ...DBOption) ([]model.RemoteDB, error) {
func (c *RemoteDBRepo) WithByFrom(from string) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("`from` != ?", from)
return g.Where("`from` == ?", from)
}
}

View File

@ -106,15 +106,11 @@ func handleAppBackup(install *model.AppInstall, backupDir, fileName string) erro
resource, _ := appInstallResourceRepo.GetFirst(appInstallResourceRepo.WithAppInstallId(install.ID))
if resource.ID != 0 && resource.ResourceId != 0 {
mysqlInfo, err := appInstallRepo.LoadBaseInfo(constant.AppMysql, "")
if err != nil {
return err
}
db, err := mysqlRepo.Get(commonRepo.WithByID(resource.ResourceId))
if err != nil {
return err
}
if err := handleMysqlBackup(mysqlInfo, tmpDir, db.Name, fmt.Sprintf("%s.sql.gz", install.Name)); err != nil {
if err := handleMysqlBackup(db.Name, tmpDir, fmt.Sprintf("%s.sql.gz", install.Name)); err != nil {
return err
}
}
@ -198,7 +194,11 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
}
_ = 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 {
if err := handleMysqlRecover(dto.CommonRecover{
Name: newDB.MysqlName,
DetailName: newDB.Name,
File: tmpPath + "/" + fmt.Sprintf("%s/%s.sql.gz", tmpPath, install.Name),
}, true); err != nil {
global.LOG.Errorf("handle recover from sql.gz failed, err: %v", err)
return err
}

View File

@ -1,10 +1,8 @@
package service
import (
"compress/gzip"
"fmt"
"os"
"os/exec"
"path"
"path/filepath"
"strings"
@ -12,9 +10,9 @@ 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/global"
"github.com/1Panel-dev/1Panel/backend/utils/files"
"github.com/1Panel-dev/1Panel/backend/utils/mysql/client"
"github.com/pkg/errors"
)
@ -23,24 +21,22 @@ func (u *BackupService) MysqlBackup(req dto.CommonBackup) error {
if err != nil {
return err
}
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
if err != nil {
timeNow := time.Now().Format("20060102150405")
targetDir := fmt.Sprintf("%s/database/mysql/%s/%s", localDir, req.Name, req.DetailName)
fileName := fmt.Sprintf("%s_%s.sql.gz", req.DetailName, timeNow)
if err := handleMysqlBackup(req.DetailName, targetDir, fileName); err != nil {
return err
}
timeNow := time.Now().Format("20060102150405")
backupDir := fmt.Sprintf("%s/database/mysql/%s/%s", localDir, req.Name, req.DetailName)
fileName := fmt.Sprintf("%s_%s.sql.gz", req.DetailName, timeNow)
if err := handleMysqlBackup(app, backupDir, req.DetailName, fileName); err != nil {
return err
}
record := &model.BackupRecord{
Type: "mysql",
Name: app.Name,
Name: req.Name,
DetailName: req.DetailName,
Source: "LOCAL",
BackupType: "LOCAL",
FileDir: backupDir,
FileDir: targetDir,
FileName: fileName,
}
if err := backupRepo.CreateRecord(record); err != nil {
@ -50,26 +46,13 @@ func (u *BackupService) MysqlBackup(req dto.CommonBackup) error {
}
func (u *BackupService) MysqlRecover(req dto.CommonRecover) error {
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
if err != nil {
return err
}
fileOp := files.NewFileOp()
if !fileOp.Stat(req.File) {
return errors.New(fmt.Sprintf("%s file is not exist", req.File))
}
global.LOG.Infof("recover database %s-%s from backup file %s", req.Name, req.DetailName, req.File)
if err := handleMysqlRecover(app, path.Dir(req.File), req.DetailName, path.Base(req.File), false); err != nil {
if err := handleMysqlRecover(req, false); err != nil {
return err
}
return nil
}
func (u *BackupService) MysqlRecoverByUpload(req dto.CommonRecover) error {
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
if err != nil {
return err
}
file := req.File
fileName := path.Base(req.File)
if strings.HasSuffix(fileName, ".tar.gz") {
@ -106,78 +89,92 @@ func (u *BackupService) MysqlRecoverByUpload(req dto.CommonRecover) error {
}()
}
if err := handleMysqlRecover(app, path.Dir(file), req.DetailName, fileName, false); err != nil {
req.File = path.Dir(file) + "/" + fileName
if err := handleMysqlRecover(req, false); err != nil {
return err
}
global.LOG.Info("recover from uploads successful!")
return nil
}
func handleMysqlBackup(app *repo.RootInfo, backupDir, dbName, fileName string) error {
fileOp := files.NewFileOp()
if !fileOp.Stat(backupDir) {
if err := os.MkdirAll(backupDir, os.ModePerm); err != nil {
return fmt.Errorf("mkdir %s failed, err: %v", backupDir, err)
}
func handleMysqlBackup(dbName, targetDir, fileName string) error {
dbInfo, err := mysqlRepo.Get(commonRepo.WithByName(dbName))
if err != nil {
return err
}
cli, _, err := LoadMysqlClientByFrom(dbInfo.From)
if err != nil {
return err
}
outfile, _ := os.OpenFile(backupDir+"/"+fileName, os.O_RDWR|os.O_CREATE, 0755)
global.LOG.Infof("start to mysqldump | gzip > %s.gzip", backupDir+"/"+fileName)
cmd := exec.Command("docker", "exec", app.ContainerName, "mysqldump", "-uroot", "-p"+app.Password, dbName)
gzipCmd := exec.Command("gzip", "-cf")
gzipCmd.Stdin, _ = cmd.StdoutPipe()
gzipCmd.Stdout = outfile
_ = gzipCmd.Start()
_ = cmd.Run()
_ = gzipCmd.Wait()
backupInfo := client.BackupInfo{
Name: dbName,
Format: dbInfo.Format,
TargetDir: targetDir,
FileName: fileName,
Timeout: 300,
}
if err := cli.Backup(backupInfo); err != nil {
return err
}
return nil
}
func handleMysqlRecover(mysqlInfo *repo.RootInfo, recoverDir, dbName, fileName string, isRollback bool) error {
func handleMysqlRecover(req dto.CommonRecover, isRollback bool) error {
isOk := false
if !isRollback {
rollbackFile := fmt.Sprintf("%s/original/database/%s_%s.sql.gz", global.CONF.System.BaseDir, mysqlInfo.Name, time.Now().Format("20060102150405"))
if err := handleMysqlBackup(mysqlInfo, path.Dir(rollbackFile), dbName, path.Base(rollbackFile)); err != nil {
return fmt.Errorf("backup mysql db %s for rollback before recover failed, err: %v", mysqlInfo.Name, err)
fileOp := files.NewFileOp()
if !fileOp.Stat(req.File) {
return errors.New(fmt.Sprintf("%s file is not exist", req.File))
}
dbInfo, err := mysqlRepo.Get(commonRepo.WithByName(req.DetailName))
if err != nil {
return err
}
cli, _, err := LoadMysqlClientByFrom(dbInfo.From)
if err != nil {
return err
}
if isRollback {
rollbackFile := fmt.Sprintf("%s/original/database/%s_%s.sql.gz", global.CONF.System.BaseDir, req.DetailName, time.Now().Format("20060102150405"))
if err := cli.Backup(client.BackupInfo{
Name: req.DetailName,
Format: dbInfo.Format,
TargetDir: path.Dir(rollbackFile),
FileName: path.Base(rollbackFile),
Timeout: 300,
}); err != nil {
return fmt.Errorf("backup mysql db %s for rollback before recover failed, err: %v", req.DetailName, err)
}
defer func() {
if !isOk {
global.LOG.Info("recover failed, start to rollback now")
if err := handleMysqlRecover(mysqlInfo, path.Dir(rollbackFile), dbName, path.Base(rollbackFile), true); err != nil {
global.LOG.Errorf("rollback mysql db %s from %s failed, err: %v", dbName, rollbackFile, err)
return
if err := cli.Recover(client.RecoverInfo{
Name: req.DetailName,
Format: dbInfo.Format,
SourceFile: rollbackFile,
Timeout: 300,
}); err != nil {
global.LOG.Errorf("rollback mysql db %s from %s failed, err: %v", req.DetailName, rollbackFile, err)
}
global.LOG.Infof("rollback mysql db %s from %s successful", dbName, rollbackFile)
global.LOG.Infof("rollback mysql db %s from %s successful", req.DetailName, rollbackFile)
_ = os.RemoveAll(rollbackFile)
} else {
_ = os.RemoveAll(rollbackFile)
}
}()
}
file := recoverDir + "/" + fileName
fi, _ := os.Open(file)
defer fi.Close()
cmd := exec.Command("docker", "exec", "-i", mysqlInfo.ContainerName, "mysql", "-uroot", "-p"+mysqlInfo.Password, dbName)
if strings.HasSuffix(fileName, ".gz") {
gzipFile, err := os.Open(file)
if err != nil {
return err
}
defer gzipFile.Close()
gzipReader, err := gzip.NewReader(gzipFile)
if err != nil {
return err
}
defer gzipReader.Close()
cmd.Stdin = gzipReader
} else {
cmd.Stdin = fi
if err := cli.Recover(client.RecoverInfo{
Name: req.DetailName,
Format: dbInfo.Format,
SourceFile: req.File,
Timeout: 300,
}); err != nil {
return err
}
stdout, err := cmd.CombinedOutput()
stdStr := strings.ReplaceAll(string(stdout), "mysql: [Warning] Using a password on the command line interface can be insecure.\n", "")
if err != nil || strings.HasPrefix(string(stdStr), "ERROR ") {
return errors.New(stdStr)
}
isOk = true
return nil
}

View File

@ -10,7 +10,6 @@ import (
"time"
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/app/repo"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/cloud_storage"
@ -118,11 +117,7 @@ func (u *CronjobService) handleBackup(cronjob *model.Cronjob, startTime time.Tim
switch cronjob.Type {
case "database":
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
if err != nil {
return "", err
}
paths, err := u.handleDatabase(*cronjob, app, backup, startTime)
paths, err := u.handleDatabase(*cronjob, backup, startTime)
return strings.Join(paths, ","), err
case "website":
paths, err := u.handleWebsite(*cronjob, backup, startTime)
@ -252,7 +247,7 @@ func handleUnTar(sourceFile, targetDir string) error {
return nil
}
func (u *CronjobService) handleDatabase(cronjob model.Cronjob, app *repo.RootInfo, backup model.BackupAccount, startTime time.Time) ([]string, error) {
func (u *CronjobService) handleDatabase(cronjob model.Cronjob, backup model.BackupAccount, startTime time.Time) ([]string, error) {
var paths []string
localDir, err := loadLocalDir()
if err != nil {
@ -282,15 +277,20 @@ func (u *CronjobService) handleDatabase(cronjob model.Cronjob, app *repo.RootInf
var record model.BackupRecord
record.Type = "mysql"
record.Name = app.Name
record.Source = "LOCAL"
record.BackupType = backup.Type
backupDir := fmt.Sprintf("%s/database/mysql/%s/%s", localDir, app.Name, dbName)
record.FileName = fmt.Sprintf("db_%s_%s.sql.gz", dbName, startTime.Format("20060102150405"))
if err = handleMysqlBackup(app, backupDir, dbName, record.FileName); err != nil {
dbInfo, err := mysqlRepo.Get(commonRepo.WithByName(dbName))
if err != nil {
return paths, err
}
record.Name = dbInfo.MysqlName
backupDir := fmt.Sprintf("%s/database/mysql/%s/%s", localDir, record.Name, dbName)
record.FileName = fmt.Sprintf("db_%s_%s.sql.gz", dbName, startTime.Format("20060102150405"))
if err = handleMysqlBackup(dbName, backupDir, record.FileName); err != nil {
return paths, err
}
record.DetailName = dbName
record.FileDir = backupDir
itemFileDir := strings.TrimPrefix(backupDir, localDir+"/")

View File

@ -93,7 +93,7 @@ func (u *MysqlService) Create(ctx context.Context, req dto.MysqlDBCreate) (*mode
return nil, errors.New("Cannot set 127.0.0.1 as address")
}
cli, version, err := loadClientByFrom(req.From)
cli, version, err := LoadMysqlClientByFrom(req.From)
if err != nil {
return nil, err
}
@ -105,11 +105,7 @@ func (u *MysqlService) Create(ctx context.Context, req dto.MysqlDBCreate) (*mode
}
createItem.MysqlName = app.Name
} else {
mysqlData, err := remoteDBRepo.Get(remoteDBRepo.WithByFrom(req.From))
if err != nil {
return nil, err
}
createItem.MysqlName = mysqlData.Name
createItem.MysqlName = req.From
}
defer cli.Close()
if err := cli.Create(client.CreateInfo{
@ -162,7 +158,7 @@ func (u *MysqlService) Delete(ctx context.Context, req dto.MysqlDBDelete) error
if err != nil && !req.ForceDelete {
return err
}
cli, version, err := loadClientByFrom(db.From)
cli, version, err := LoadMysqlClientByFrom(db.From)
if err != nil {
return err
}
@ -207,7 +203,7 @@ func (u *MysqlService) ChangePassword(info dto.ChangeDBInfo) error {
if cmd.CheckIllegal(info.Value) {
return buserr.New(constant.ErrCmdIllegal)
}
cli, version, err := loadClientByFrom(info.From)
cli, version, err := LoadMysqlClientByFrom(info.From)
if err != nil {
return err
}
@ -236,22 +232,31 @@ func (u *MysqlService) ChangePassword(info dto.ChangeDBInfo) error {
}
if info.ID != 0 {
// appRess, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithLinkId(app.ID), appInstallResourceRepo.WithResourceId(mysqlData.ID))
// for _, appRes := range appRess {
// appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(appRes.AppInstallId))
// if err != nil {
// return err
// }
// appModel, err := appRepo.GetFirst(commonRepo.WithByID(appInstall.AppId))
// if err != nil {
// return err
// }
var appRess []model.AppInstallResource
if info.From == "local" {
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
if err != nil {
return err
}
appRess, _ = appInstallResourceRepo.GetBy(appInstallResourceRepo.WithLinkId(app.ID), appInstallResourceRepo.WithResourceId(mysqlData.ID))
} else {
appRess, _ = appInstallResourceRepo.GetBy(appInstallResourceRepo.WithResourceId(mysqlData.ID))
}
for _, appRes := range appRess {
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(appRes.AppInstallId))
if err != nil {
return err
}
appModel, err := appRepo.GetFirst(commonRepo.WithByID(appInstall.AppId))
if err != nil {
return err
}
// global.LOG.Infof("start to update mysql password used by app %s-%s", appModel.Key, appInstall.Name)
// if err := updateInstallInfoInDB(appModel.Key, appInstall.Name, "user-password", true, info.Value); err != nil {
// return err
// }
// }
global.LOG.Infof("start to update mysql password used by app %s-%s", appModel.Key, appInstall.Name)
if err := updateInstallInfoInDB(appModel.Key, appInstall.Name, "user-password", true, info.Value); err != nil {
return err
}
}
global.LOG.Info("excute password change sql successful")
_ = mysqlRepo.Update(mysqlData.ID, map[string]interface{}{"password": info.Value})
return nil
@ -270,7 +275,7 @@ func (u *MysqlService) ChangeAccess(info dto.ChangeDBInfo) error {
if cmd.CheckIllegal(info.Value) {
return buserr.New(constant.ErrCmdIllegal)
}
cli, version, err := loadClientByFrom(info.From)
cli, version, err := LoadMysqlClientByFrom(info.From)
if err != nil {
return err
}
@ -535,15 +540,17 @@ func updateMyCnf(oldFiles []string, group string, param string, value interface{
return newFiles
}
func loadClientByFrom(from string) (mysql.MysqlClient, string, error) {
func LoadMysqlClientByFrom(from string) (mysql.MysqlClient, string, error) {
var (
dbInfo client.DBInfo
version string
err error
)
dbInfo.From = from
dbInfo.Timeout = 300
if from != "local" {
databaseItem, err := remoteDBRepo.Get(remoteDBRepo.WithByFrom(from))
databaseItem, err := remoteDBRepo.Get(commonRepo.WithByName(from))
if err != nil {
return nil, "", err
}

View File

@ -17,7 +17,7 @@ type MysqlClient interface {
ChangePassword(info client.PasswordChangeInfo) error
ChangeAccess(info client.AccessChangeInfo) error
Backup(info client.BackupInfo) (string, error)
Backup(info client.BackupInfo) error
Recover(info client.RecoverInfo) error
Close()

View File

@ -56,6 +56,7 @@ type BackupInfo struct {
Name string `json:"name"`
Format string `json:"format"`
TargetDir string `json:"targetDir"`
FileName string `json:"fileName"`
Timeout uint `json:"timeout"` // second
}

View File

@ -205,16 +205,15 @@ func (r *Local) ChangeAccess(info AccessChangeInfo) error {
return nil
}
func (r *Local) Backup(info BackupInfo) (string, error) {
func (r *Local) Backup(info BackupInfo) error {
fileOp := files.NewFileOp()
if !fileOp.Stat(info.TargetDir) {
if err := os.MkdirAll(info.TargetDir, os.ModePerm); err != nil {
return "", fmt.Errorf("mkdir %s failed, err: %v", info.TargetDir, err)
return fmt.Errorf("mkdir %s failed, err: %v", info.TargetDir, err)
}
}
fileName := fmt.Sprintf("%s/%s_%s.sql.gz", info.TargetDir, info.Name, time.Now().Format("20060102150405"))
outfile, _ := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0755)
global.LOG.Infof("start to mysqldump | gzip > %s.gzip", info.TargetDir+"/"+fileName)
outfile, _ := os.OpenFile(info.FileName, os.O_RDWR|os.O_CREATE, 0755)
global.LOG.Infof("start to mysqldump | gzip > %s.gzip", info.TargetDir+"/"+info.FileName)
cmd := exec.Command("docker", "exec", r.ContainerName, "mysqldump", "-uroot", "-p"+r.Password, info.Name)
gzipCmd := exec.Command("gzip", "-cf")
gzipCmd.Stdin, _ = cmd.StdoutPipe()
@ -222,7 +221,7 @@ func (r *Local) Backup(info BackupInfo) (string, error) {
_ = gzipCmd.Start()
_ = cmd.Run()
_ = gzipCmd.Wait()
return fileName, nil
return nil
}
func (r *Local) Recover(info RecoverInfo) error {

View File

@ -208,26 +208,26 @@ func (r *Remote) ChangeAccess(info AccessChangeInfo) error {
return nil
}
func (r *Remote) Backup(info BackupInfo) (string, error) {
func (r *Remote) Backup(info BackupInfo) error {
fileOp := files.NewFileOp()
if !fileOp.Stat(info.TargetDir) {
if err := os.MkdirAll(info.TargetDir, os.ModePerm); err != nil {
return "", fmt.Errorf("mkdir %s failed, err: %v", info.TargetDir, err)
return fmt.Errorf("mkdir %s failed, err: %v", info.TargetDir, err)
}
}
fileName := fmt.Sprintf("%s/%s_%s.sql", info.TargetDir, info.Name, time.Now().Format("20060102150405"))
fileNameItem := info.TargetDir + "/" + strings.TrimSuffix(info.FileName, ".gz")
dns := fmt.Sprintf("%s:%s@tcp(%s:%v)/%s?charset=%s&parseTime=true&loc=Asia%sShanghai", r.User, r.Password, r.Address, r.Port, info.Name, info.Format, "%2F")
f, _ := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0755)
f, _ := os.OpenFile(fileNameItem, os.O_RDWR|os.O_CREATE, 0755)
defer f.Close()
if err := mysqldump.Dump(dns, mysqldump.WithData(), mysqldump.WithWriter(f)); err != nil {
return "", err
if err := mysqldump.Dump(dns, mysqldump.WithData(), mysqldump.WithDropTable(), mysqldump.WithWriter(f)); err != nil {
return err
}
if err := fileOp.Compress([]string{fileName}, info.TargetDir, path.Base(fileName)+".gz", files.Gz); err != nil {
return "", err
if err := fileOp.Compress([]string{fileNameItem}, info.TargetDir, info.FileName, files.Gz); err != nil {
return err
}
return fileName, nil
return nil
}
func (r *Remote) Recover(info RecoverInfo) error {
@ -235,13 +235,7 @@ func (r *Remote) Recover(info RecoverInfo) error {
fileName := info.SourceFile
if strings.HasSuffix(info.SourceFile, ".sql.gz") {
fileName = strings.TrimSuffix(info.SourceFile, ".gz")
if err := fileOp.Decompress(info.SourceFile, fileName, files.Gz); err != nil {
return err
}
}
if strings.HasSuffix(info.SourceFile, ".tar.gz") {
fileName = strings.TrimSuffix(info.SourceFile, ".tar.gz")
if err := fileOp.Decompress(info.SourceFile, fileName, files.TarGz); err != nil {
if err := fileOp.Decompress(info.SourceFile, path.Dir(fileName), files.Gz); err != nil {
return err
}
}
@ -251,7 +245,7 @@ func (r *Remote) Recover(info RecoverInfo) error {
return err
}
defer f.Close()
if err := mysqldump.Source(dns, f); err != nil {
if err := mysqldump.Source(dns, f, mysqldump.WithMergeInsert(1000)); err != nil {
return err
}
return nil

View File

@ -17,6 +17,7 @@ export namespace Database {
id: number;
createdAt: Date;
name: string;
mysqlName: string;
from: string;
format: string;
username: string;

View File

@ -215,7 +215,6 @@ import { ElForm } from 'element-plus';
import { Cronjob } from '@/api/interface/cronjob';
import { addCronjob, editCronjob } from '@/api/modules/cronjob';
import { loadDBNames } from '@/api/modules/database';
import { CheckAppInstalled } from '@/api/modules/app';
import { GetWebsiteOptions } from '@/api/modules/website';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgError, MsgSuccess } from '@/utils/message';
@ -454,14 +453,8 @@ const loadContainers = async () => {
};
const checkMysqlInstalled = async () => {
const res = await CheckAppInstalled('mysql');
mysqlInfo.isExist = res.data.isExist;
mysqlInfo.name = res.data.name;
mysqlInfo.version = res.data.version;
if (mysqlInfo.isExist) {
const data = await loadDBNames();
mysqlInfo.dbNames = data.data;
}
const data = await loadDBNames();
mysqlInfo.dbNames = data.data;
};
function isBackup() {

View File

@ -21,7 +21,7 @@
<el-option
v-for="(item, index) in dbOptions"
:key="index"
:value="item.address"
:value="item.name"
:label="item.name"
></el-option>
</el-option-group>
@ -265,14 +265,6 @@ const onOpenDialog = async () => {
};
const dialogBackupRef = ref();
const onOpenBackupDialog = async (dbName: string) => {
let params = {
type: 'mysql',
name: mysqlName.value,
detailName: dbName,
};
dialogBackupRef.value!.acceptParams(params);
};
const uploadRef = ref();
@ -422,22 +414,21 @@ const buttons = [
},
{
label: i18n.global.t('database.backupList'),
disabled: (row: Database.MysqlDBInfo) => {
return row.from !== 'local';
},
click: (row: Database.MysqlDBInfo) => {
onOpenBackupDialog(row.name);
let params = {
type: 'mysql',
name: row.mysqlName,
detailName: row.name,
};
dialogBackupRef.value!.acceptParams(params);
},
},
{
label: i18n.global.t('database.loadBackup'),
disabled: (row: Database.MysqlDBInfo) => {
return row.from !== 'local';
},
click: (row: Database.MysqlDBInfo) => {
let params = {
type: 'mysql',
name: mysqlName.value,
name: mysqlName.value || row.name,
detailName: row.name,
};
uploadRef.value!.acceptParams(params);