Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 57 additions & 37 deletions agent/app/service/backup_mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,44 +59,12 @@ func (u *BackupService) MysqlRecover(req dto.CommonRecover) error {
}

func (u *BackupService) MysqlRecoverByUpload(req dto.CommonRecover) error {
file := req.File
fileName := path.Base(req.File)
if strings.HasSuffix(fileName, ".tar.gz") {
fileNameItem := time.Now().Format(constant.DateTimeSlimLayout)
dstDir := fmt.Sprintf("%s/%s", path.Dir(req.File), fileNameItem)
fileOp := files.NewFileOp()
if !fileOp.Stat(dstDir) {
if err := fileOp.CreateDir(dstDir, os.ModePerm); err != nil {
return fmt.Errorf("mkdir %s failed, err: %v", dstDir, err)
}
}
if err := fileOp.TarGzExtractPro(req.File, dstDir, ""); err != nil {
_ = os.RemoveAll(dstDir)
return err
}
global.LOG.Infof("decompress file %s successful, now start to check test.sql is exist", req.File)
hasTestSql := false
_ = filepath.Walk(dstDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return nil
}
if !info.IsDir() && info.Name() == "test.sql" {
hasTestSql = true
file = path
fileName = "test.sql"
}
return nil
})
if !hasTestSql {
_ = os.RemoveAll(dstDir)
return fmt.Errorf("no such file named test.sql in %s", fileName)
}
defer func() {
_ = os.RemoveAll(dstDir)
}()
recoveFile, err := loadSqlFile(req.File)
if err != nil {
return err
}

req.File = path.Dir(file) + "/" + fileName
req.File = recoveFile
defer os.RemoveAll(path.Dir(recoveFile))
if err := handleMysqlRecover(req, nil, false, req.TaskID); err != nil {
return err
}
Expand Down Expand Up @@ -243,3 +211,55 @@ func doMysqlBackup(db DatabaseHelper, targetDir, fileName string) error {
}
return cli.Backup(backupInfo)
}

func loadSqlFile(file string) (string, error) {
if !strings.HasSuffix(file, ".tar.gz") && !strings.HasSuffix(file, ".zip") {
return file, nil
}
fileName := path.Base(file)
fileDir := path.Dir(file)
fileNameItem := time.Now().Format(constant.DateTimeSlimLayout)
dstDir := fmt.Sprintf("%s/%s", fileDir, fileNameItem)
_ = os.Mkdir(dstDir, constant.DirPerm)
if strings.HasSuffix(fileName, ".tar.gz") {
fileOp := files.NewFileOp()
if err := fileOp.TarGzExtractPro(file, dstDir, ""); err != nil {
_ = os.RemoveAll(dstDir)
return "", err
}
}
if strings.HasSuffix(fileName, ".zip") {
archiver, err := files.NewShellArchiver(files.Zip)
if err != nil {
_ = os.RemoveAll(dstDir)
return "", err
}
if err := archiver.Extract(file, dstDir, ""); err != nil {
_ = os.RemoveAll(dstDir)
return "", err
}
}
global.LOG.Infof("decompress file %s successful, now start to check test.sql is exist", file)
var sqlFiles []string
hasTestSql := false
_ = filepath.Walk(dstDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return nil
}
if !info.IsDir() && strings.HasSuffix(info.Name(), ".sql") {
sqlFiles = append(sqlFiles, path)
if info.Name() == "test.sql" {
hasTestSql = true
}
}
return nil
})
if len(sqlFiles) == 1 {
return sqlFiles[0], nil
}
if !hasTestSql {
_ = os.RemoveAll(dstDir)
return "", fmt.Errorf("no such file named test.sql in %s", fileName)
}
return "", nil
}
44 changes: 5 additions & 39 deletions agent/app/service/backup_postgresql.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"fmt"
"os"
"path"
"path/filepath"
"strings"
"time"

"github.com/1Panel-dev/1Panel/agent/app/repo"
Expand Down Expand Up @@ -59,44 +57,12 @@ func (u *BackupService) PostgresqlRecover(req dto.CommonRecover) error {
}

func (u *BackupService) PostgresqlRecoverByUpload(req dto.CommonRecover) error {
file := req.File
fileName := path.Base(req.File)
if strings.HasSuffix(fileName, ".tar.gz") {
fileNameItem := time.Now().Format(constant.DateTimeSlimLayout)
dstDir := fmt.Sprintf("%s/%s", path.Dir(req.File), fileNameItem)
fileOp := files.NewFileOp()
if !fileOp.Stat(dstDir) {
if err := fileOp.CreateDir(dstDir, os.ModePerm); err != nil {
return fmt.Errorf("mkdir %s failed, err: %v", dstDir, err)
}
}
if err := fileOp.TarGzExtractPro(req.File, dstDir, ""); err != nil {
_ = os.RemoveAll(dstDir)
return err
}
global.LOG.Infof("decompress file %s successful, now start to check test.sql is exist", req.File)
hasTestSql := false
_ = filepath.Walk(dstDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return nil
}
if !info.IsDir() && info.Name() == "test.sql" {
hasTestSql = true
file = path
fileName = "test.sql"
}
return nil
})
if !hasTestSql {
_ = os.RemoveAll(dstDir)
return fmt.Errorf("no such file named test.sql in %s", fileName)
}
defer func() {
_ = os.RemoveAll(dstDir)
}()
recoveFile, err := loadSqlFile(req.File)
if err != nil {
return err
}

req.File = path.Dir(file) + "/" + fileName
req.File = recoveFile
defer os.RemoveAll(path.Dir(recoveFile))
if err := handlePostgresqlRecover(req, nil, false); err != nil {
return err
}
Expand Down
48 changes: 34 additions & 14 deletions frontend/src/components/upload/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,9 @@
<li v-if="type === 'mysql' || type === 'mariadb'">
{{ $t('database.formatHelper', [remark]) }}
</li>
<li v-if="type === 'website'">{{ $t('website.websiteBackupWarn') }}</li>
<span v-if="isDb()">
<li>{{ $t('database.supportUpType') }}</li>
<li>{{ $t('database.zipFormat') }}</li>
</span>
<span v-else>
<li>{{ $t('website.supportUpType') }}</li>
<li>{{ $t('website.zipFormat', [type + '.json']) }}</li>
</span>
<li v-if="isDb()">{{ $t('database.supportUpType') }}</li>
<li v-if="!isDb()">{{ $t('website.websiteBackupWarn') }}</li>
<li v-if="!isDb()">{{ $t('website.supportUpType', [type]) }}</li>
</ul>
</template>
</el-alert>
Expand All @@ -42,7 +36,7 @@
:limit="1"
class="float-left"
ref="uploadRef"
accept=".tar.gz,.sql,.sql.gz"
accept=".tar.gz,.sql,.gz,.zip"
:show-file-list="false"
:on-exceed="handleExceed"
:on-change="fileOnChange"
Expand Down Expand Up @@ -156,7 +150,7 @@ const paginationConfig = reactive({
total: 0,
});
const uploadOpen = ref(false);
const type = ref();
const type = ref('mysql');
const name = ref();
const detailName = ref();
const remark = ref();
Expand Down Expand Up @@ -208,15 +202,38 @@ const search = async () => {
paginationConfig.total = res.data.total;
};

const beforeUpload = (fileName: string) => {
const itemName = fileName.toLowerCase();
let reg = /^[a-zA-Z0-9\u4e00-\u9fa5]{1}[a-z:A-Z0-9_.\u4e00-\u9fa5-]{0,256}$/;
if (!reg.test(itemName)) {
MsgError(i18n.global.t('commons.msg.fileNameErr'));
return false;
}
if (isDb()) {
const allowedExtensions = ['.sql', '.sql.gz', '.tar.gz', '.zip'];
const isValidFile = allowedExtensions.some((ext) => itemName.endsWith(ext));
if (!isValidFile) {
MsgError(i18n.global.t('database.supportUpType'));
return false;
}
return true;
}
const allowedExtensions = ['.tar.gz'];
const isValidFile = allowedExtensions.some((ext) => itemName.endsWith(ext));
if (!isValidFile) {
MsgError(i18n.global.t('website.supportUpType'));
return false;
}
return true;
};

const loadFile = async (path: string) => {
let filaName = path.split('/').pop();
if (!filaName) {
MsgError(i18n.global.t('commons.msg.fileNameErr'));
return;
}
let reg = /^[a-zA-Z0-9\u4e00-\u9fa5]{1}[a-z:A-Z0-9_.\u4e00-\u9fa5-]{0,256}$/;
if (!reg.test(filaName)) {
MsgError(i18n.global.t('commons.msg.fileNameErr'));
if (!beforeUpload(filaName)) {
return;
}
ElMessageBox.confirm(i18n.global.t('database.selectHelper', [path]), i18n.global.t('database.loadBackup'), {
Expand Down Expand Up @@ -297,6 +314,9 @@ const fileOnChange = (_uploadFile: UploadFile, uploadFiles: UploadFiles) => {
MsgError(i18n.global.t('commons.msg.fileNameErr'));
return;
}
if (!beforeUpload(file.raw.name)) {
return;
}
ElMessageBox.confirm(
i18n.global.t('database.selectHelper', [file.raw.name]),
i18n.global.t('database.loadBackup'),
Expand Down
7 changes: 3 additions & 4 deletions frontend/src/lang/modules/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -521,8 +521,8 @@ const message = {
selectFile: 'Select file',
dropHelper: 'You can drag and drop the uploaded file here or',
clickHelper: 'click to upload',
supportUpType: 'Only sql, sql.gz, and tar.gz files are supported',
zipFormat: 'tar.gz compressed package structure: test.tar.gz compressed package must contain test.sql',
supportUpType:
'Only supports sql, sql.gz, tar.gz, .zip file formats. The imported compressed file must contain only one .sql file or include test.sql',

currentStatus: 'Current state',
baseParam: 'Basic parameter',
Expand Down Expand Up @@ -2211,8 +2211,7 @@ const message = {
otherDomains: 'Other domains',
static: 'Static',
deployment: 'Deployment',
supportUpType: 'Only .tar.gz files are supported',
zipFormat: '.tar.gz compressed package structure: test.tar.gz compressed package must contain {0} file',
supportUpType: 'Only .tar.gz file format is supported, and the compressed package must contain {0}.json file',
proxy: 'Reverse proxy',
alias: 'Alias',
ftpUser: 'FTP account',
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/lang/modules/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,8 +509,8 @@ const message = {
selectFile: '[ファイル]を選択します',
dropHelper: 'ここでアップロードされたファイルをドラッグアンドドロップするか、',
clickHelper: 'クリックしてアップロードします',
supportUpType: 'SQL、SQL.GZ、およびTAR.GZファイルのみがサポートされています',
zipFormat: 'tar.gz圧縮パッケージ構造:test.tar.gz圧縮パッケージにはtest.sqlが含まれている必要があります',
supportUpType:
'sql、sql.gz、tar.gz、.zip ファイル形式のみサポートしています。インポートする圧縮ファイルには、1つの.sqlファイルのみ、またはtest.sqlが含まれている必要があります',

currentStatus: '現在の状態',
baseParam: '基本パラメーター',
Expand Down Expand Up @@ -2125,8 +2125,8 @@ const message = {
otherDomains: '他のドメイン',
static: '静的',
deployment: '展開',
supportUpType: '.tar.gzファイルのみがサポートされています',
zipFormat: '.tar.gz圧縮パッケージ構造:test.tar.gz圧縮パッケージは{0}ファイルを含める必要があります',
supportUpType:
'.tar.gz ファイル形式のみサポートされており、圧縮パッケージには {0}.json ファイルが含まれている必要があります',
proxy: '逆プロキシ',
alias: 'エイリアス',
ftpUser: 'FTPアカウント',
Expand Down
7 changes: 3 additions & 4 deletions frontend/src/lang/modules/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -507,8 +507,8 @@ const message = {
selectFile: '파일 선택',
dropHelper: '여기에 업로드한 파일을 드래그 앤 드롭하거나',
clickHelper: '클릭하여 업로드',
supportUpType: 'sql, sql.gz, tar.gz 파일만 지원됩니다.',
zipFormat: 'tar.gz 압축 패키지 구조: test.tar.gz 압축 패키지에는 test.sql이 포함되어야 합니다.',
supportUpType:
'sql, sql.gz, tar.gz, .zip 파일 형식만 지원합니다. 가져오는 압축 파일에는 하나의 .sql 파일만 있거나 test.sql이 포함되어 있어야 합니다',

currentStatus: '현재 상태',
baseParam: '기본 파라미터',
Expand Down Expand Up @@ -2090,8 +2090,7 @@ const message = {
otherDomains: '기타 도메인',
static: '정적',
deployment: '배포',
supportUpType: '지원되는 파일 형식: .tar.gz',
zipFormat: '.tar.gz 압축 패키지 구조: test.tar.gz 패키지에는 반드시 {0} 파일이 포함되어야 합니다.',
supportUpType: '.tar.gz 파일 형식만 지원되며, 압축 패키지에는 {0}.json 파일이 포함되어야 합니다',
proxy: '리버스 프록시',
alias: '별칭',
ftpUser: 'FTP 계정',
Expand Down
7 changes: 3 additions & 4 deletions frontend/src/lang/modules/ms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -521,8 +521,8 @@ const message = {
selectFile: 'Pilih fail',
dropHelper: 'Anda boleh seret dan lepaskan fail yang ingin dimuat naik di sini atau',
clickHelper: 'klik untuk memuat naik',
supportUpType: 'Hanya fail sql, sql.gz, dan tar.gz yang disokong',
zipFormat: 'Struktur pakej mampatan tar.gz: Pakej mampatan test.tar.gz mesti mengandungi test.sql',
supportUpType:
'Hanya menyokong format fail sql, sql.gz, tar.gz, .zip. Fail termampat yang diimport mesti mengandungi hanya satu fail .sql atau termasuk test.sql',

currentStatus: 'Keadaan semasa',
baseParam: 'Parameter asas',
Expand Down Expand Up @@ -2181,8 +2181,7 @@ const message = {
otherDomains: 'Domain Lain',
static: 'Statik',
deployment: 'Penerapan',
supportUpType: 'Hanya fail .tar.gz disokong',
zipFormat: 'Struktur fail .tar.gz: fail test.tar.gz mesti mengandungi fail {0}',
supportUpType: 'Hanya format fail .tar.gz yang disokong, dan pakej termampat mesti mengandungi fail {0}.json',
proxy: 'Proksi Terbalik',
alias: 'Alias',
ftpUser: 'Akaun FTP',
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/lang/modules/pt-br.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,8 +519,8 @@ const message = {
selectFile: 'Selecionar arquivo',
dropHelper: 'Você pode arrastar e soltar o arquivo carregado aqui ou',
clickHelper: 'clicar para fazer upload',
supportUpType: 'Apenas arquivos sql, sql.gz e tar.gz são suportados',
zipFormat: 'Estrutura do pacote comprimido tar.gz: o pacote comprimido test.tar.gz deve conter test.sql',
supportUpType:
'Suporta apenas os formatos de arquivo sql, sql.gz, tar.gz, .zip. O arquivo compactado importado deve conter apenas um arquivo .sql ou incluir test.sql',

currentStatus: 'Estado atual',
baseParam: 'Parâmetro básico',
Expand Down Expand Up @@ -2178,8 +2178,8 @@ const message = {
otherDomains: 'Outros domínios',
static: 'Estático',
deployment: 'Implantação',
supportUpType: 'Somente arquivos .tar.gz são suportados',
zipFormat: 'Estrutura de pacote comprimido .tar.gz: o pacote comprimido test.tar.gz deve conter o arquivo {0}',
supportUpType:
'Apenas o formato de arquivo .tar.gz é suportado, e o pacote compactado deve conter o arquivo {0}.json',
proxy: 'Proxy reverso',
alias: 'Alias',
ftpUser: 'Conta FTP',
Expand Down
7 changes: 3 additions & 4 deletions frontend/src/lang/modules/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -513,8 +513,8 @@ const message = {
selectFile: 'Выбрать файл',
dropHelper: 'Вы можете перетащить загружаемый файл сюда или',
clickHelper: 'нажмите для загрузки',
supportUpType: 'Поддерживаются только файлы sql, sql.gz и tar.gz',
zipFormat: 'Структура архива tar.gz: архив test.tar.gz должен содержать файл test.sql',
supportUpType:
'Поддерживаются только форматы файлов sql, sql.gz, tar.gz, .zip. Импортируемый сжатый файл должен содержать только один файл .sql или включать test.sql',

currentStatus: 'Текущее состояние',
baseParam: 'Базовые параметры',
Expand Down Expand Up @@ -2174,8 +2174,7 @@ const message = {
otherDomains: 'Другие домены',
static: 'Статический',
deployment: 'Развертывание',
supportUpType: 'Поддерживаются только файлы .tar.gz',
zipFormat: 'Структура архива .tar.gz: архив test.tar.gz должен содержать файл {0}',
supportUpType: 'Поддерживается только формат файла .tar.gz, и сжатый пакет должен содержать файл {0}.json',
proxy: 'Обратный прокси',
alias: 'Псевдоним',
ftpUser: 'FTP аккаунт',
Expand Down
Loading
Loading