diff --git a/agent/app/dto/cronjob.go b/agent/app/dto/cronjob.go index a760e916b..6f0118b7c 100644 --- a/agent/app/dto/cronjob.go +++ b/agent/app/dto/cronjob.go @@ -113,17 +113,20 @@ type CronjobInfo struct { ContainerName string `json:"containerName"` User string `json:"user"` - AppID string `json:"appID"` - Website string `json:"website"` - ExclusionRules string `json:"exclusionRules"` - DBType string `json:"dbType"` - DBName string `json:"dbName"` - URL string `json:"url"` - IsDir bool `json:"isDir"` - SourceDir string `json:"sourceDir"` - SourceAccounts []string `json:"sourceAccounts"` - DownloadAccount string `json:"downloadAccount"` - RetainCopies int `json:"retainCopies"` + AppID string `json:"appID"` + Website string `json:"website"` + ExclusionRules string `json:"exclusionRules"` + DBType string `json:"dbType"` + DBName string `json:"dbName"` + URL string `json:"url"` + IsDir bool `json:"isDir"` + SourceDir string `json:"sourceDir"` + RetainCopies int `json:"retainCopies"` + + SourceAccounts []string `json:"sourceAccounts"` + DownloadAccount string `json:"downloadAccount"` + SourceAccountIDs string `json:"sourceAccountIDs"` + DownloadAccountID uint `json:"downloadAccountID"` LastRecordStatus string `json:"lastRecordStatus"` LastRecordTime string `json:"lastRecordTime"` diff --git a/agent/app/service/backup.go b/agent/app/service/backup.go index d8d10fe34..a8ba8b908 100644 --- a/agent/app/service/backup.go +++ b/agent/app/service/backup.go @@ -314,7 +314,7 @@ func (u *BackupService) RefreshToken(req dto.OperateByID) error { } func (u *BackupService) checkBackupConn(backup *model.BackupAccount) (bool, error) { - client, err := newClient(backup) + client, err := newClient(backup, false) if err != nil { return false, err } @@ -340,7 +340,12 @@ func (u *BackupService) checkBackupConn(backup *model.BackupAccount) (bool, erro if backup.Type != constant.Sftp && backup.Type != constant.Local && targetPath != "/" { targetPath = strings.TrimPrefix(targetPath, "/") } - return client.Upload(fileItem, targetPath) + + if _, err := client.Upload(fileItem, targetPath); err != nil { + return false, err + } + _, _ = client.Delete(path.Join(backup.BackupPath, "test")) + return true, nil } func (u *BackupService) Sync(req dto.SyncFromMaster) error { @@ -408,7 +413,7 @@ func (u *BackupService) CheckUsed(id uint) error { func NewBackupClientWithID(id uint) (*model.BackupAccount, cloud_storage.CloudStorageClient, error) { account, _ := backupRepo.Get(repo.WithByID(id)) - backClient, err := newClient(&account) + backClient, err := newClient(&account, true) if err != nil { return nil, nil, err } @@ -433,7 +438,7 @@ func NewBackupClientMap(ids []string) (map[string]backupClientHelper, error) { accounts, _ = backupRepo.List(repo.WithByIDs(idItems)) clientMap := make(map[string]backupClientHelper) for _, item := range accounts { - backClient, err := newClient(&item) + backClient, err := newClient(&item, true) if err != nil { return nil, err } @@ -448,7 +453,7 @@ func NewBackupClientMap(ids []string) (map[string]backupClientHelper, error) { return clientMap, nil } -func newClient(account *model.BackupAccount) (cloud_storage.CloudStorageClient, error) { +func newClient(account *model.BackupAccount, isEncrypt bool) (cloud_storage.CloudStorageClient, error) { varMap := make(map[string]interface{}) if len(account.Vars) != 0 { if err := json.Unmarshal([]byte(account.Vars), &varMap); err != nil { @@ -457,8 +462,10 @@ func newClient(account *model.BackupAccount) (cloud_storage.CloudStorageClient, } varMap["bucket"] = account.Bucket varMap["backupPath"] = account.BackupPath - account.AccessKey, _ = encrypt.StringDecrypt(account.AccessKey) - account.Credential, _ = encrypt.StringDecrypt(account.Credential) + if isEncrypt { + account.AccessKey, _ = encrypt.StringDecrypt(account.AccessKey) + account.Credential, _ = encrypt.StringDecrypt(account.Credential) + } switch account.Type { case constant.Sftp, constant.WebDAV: varMap["username"] = account.AccessKey diff --git a/core/app/service/backup.go b/core/app/service/backup.go index bc75023f8..bec79e9b8 100644 --- a/core/app/service/backup.go +++ b/core/app/service/backup.go @@ -357,7 +357,11 @@ func (u *BackupService) checkBackupConn(backup *model.BackupAccount) (bool, erro if backup.Type != constant.Sftp && backup.Type != constant.Local && targetPath != "/" { targetPath = strings.TrimPrefix(targetPath, "/") } - return client.Upload(fileItem, targetPath) + if _, err := client.Upload(fileItem, targetPath); err != nil { + return false, err + } + _, _ = client.Delete(path.Join(backup.BackupPath, "test")) + return true, nil } func syncAccountToAgent(backup model.BackupAccount, operation string) { diff --git a/core/app/task/task.go b/core/app/task/task.go index 9ba08e3e0..f77876485 100644 --- a/core/app/task/task.go +++ b/core/app/task/task.go @@ -207,14 +207,14 @@ func (t *Task) DeleteLogFile() { func (t *Task) LogWithStatus(msg string, err error) { if err != nil { - t.Logger.Printf(i18n.GetWithNameAndErr("FailedStatus", msg, err)) + t.Logger.Print(i18n.GetWithNameAndErr("FailedStatus", msg, err)) } else { - t.Logger.Printf(i18n.GetWithName("SuccessStatus", msg)) + t.Logger.Print(i18n.GetWithName("SuccessStatus", msg)) } } func (t *Task) Log(msg string) { - t.Logger.Printf(msg) + t.Logger.Print(msg) } func (t *Task) Logf(format string, v ...any) { @@ -222,22 +222,22 @@ func (t *Task) Logf(format string, v ...any) { } func (t *Task) LogFailed(msg string) { - t.Logger.Printf(msg + i18n.GetMsgByKey("Failed")) + t.Logger.Print(msg + i18n.GetMsgByKey("Failed")) } func (t *Task) LogFailedWithErr(msg string, err error) { - t.Logger.Printf(fmt.Sprintf("%s %s : %s", msg, i18n.GetMsgByKey("Failed"), err.Error())) + t.Logger.Printf("%s %s : %s", msg, i18n.GetMsgByKey("Failed"), err.Error()) } func (t *Task) LogSuccess(msg string) { - t.Logger.Printf(msg + i18n.GetMsgByKey("Success")) + t.Logger.Print(msg + i18n.GetMsgByKey("Success")) } func (t *Task) LogSuccessF(format string, v ...any) { - t.Logger.Printf(fmt.Sprintf(format, v...) + i18n.GetMsgByKey("Success")) + t.Logger.Print(fmt.Sprintf(format, v...) + i18n.GetMsgByKey("Success")) } func (t *Task) LogStart(msg string) { - t.Logger.Printf(fmt.Sprintf("%s%s", i18n.GetMsgByKey("Start"), msg)) + t.Logger.Printf("%s%s", i18n.GetMsgByKey("Start"), msg) } func (t *Task) LogWithOps(operate, msg string) { diff --git a/core/i18n/i18n.go b/core/i18n/i18n.go index 2bfa9c292..e85019643 100644 --- a/core/i18n/i18n.go +++ b/core/i18n/i18n.go @@ -2,6 +2,7 @@ package i18n import ( "embed" + "fmt" "strings" "github.com/1Panel-dev/1Panel/core/global" @@ -64,9 +65,10 @@ func GetErrMsg(key string, maps map[string]interface{}) string { } func GetMsgByKey(key string) string { - content, _ := global.I18n.Localize(&i18n.LocalizeConfig{ + content, err := global.I18n.Localize(&i18n.LocalizeConfig{ MessageID: key, }) + fmt.Println(err) return content } @@ -132,6 +134,7 @@ func Init() { _, _ = bundle.LoadMessageFileFS(fs, "lang/ru.yaml") _, _ = bundle.LoadMessageFileFS(fs, "lang/ms.yaml") _, _ = bundle.LoadMessageFileFS(fs, "lang/ko.yaml") + global.I18n = i18n.NewLocalizer(bundle, "en") } func UseI18nForCmd(lang string) { diff --git a/core/i18n/lang/en.yaml b/core/i18n/lang/en.yaml index 8a096550c..e1610e709 100644 --- a/core/i18n/lang/en.yaml +++ b/core/i18n/lang/en.yaml @@ -28,7 +28,6 @@ ErrBackupCheck: "Backup account connection test failed {{ .err}}" ErrBackupLocal: "Local backup account does not support this operation!" ErrBackupPublic: "Non-public backup account detected, please check and retry!" ErrOSSConn: "Cannot retrieve latest version, please check if the server can connect to external network." -ErrEntrance: "Security entrance error, please check and retry!" #license ErrLicense: "License format error, please check and retry!" diff --git a/core/i18n/lang/ja.yaml b/core/i18n/lang/ja.yaml index 116231463..456e90779 100644 --- a/core/i18n/lang/ja.yaml +++ b/core/i18n/lang/ja.yaml @@ -28,7 +28,6 @@ ErrBackupCheck: "バックアップアカウントの接続テストに失敗し ErrBackupLocal: "ローカルサーバーのバックアップアカウントはこの操作をサポートしていません!" ErrBackupPublic: "バックアップアカウントが公開ではないことが検出されました、確認して再試行してください!" ErrOSSConn: "最新バージョンを取得できませんでした、サーバーが外部ネットワークに接続できるか確認してください。" -ErrEntrance: "セキュアエントランス情報エラー、確認して再試行してください!" #license ErrLicense: "ライセンスフォーマットエラー、確認して再試行してください!" diff --git a/core/i18n/lang/ko.yaml b/core/i18n/lang/ko.yaml index d96ea103d..e6f39eb82 100644 --- a/core/i18n/lang/ko.yaml +++ b/core/i18n/lang/ko.yaml @@ -28,7 +28,6 @@ ErrBackupCheck: "백업 계정 연결 테스트 실패 {{ .err}}" ErrBackupLocal: "로컬 서버 백업 계정은 현재 작업을 지원하지 않습니다!" ErrBackupPublic: "이 백업 계정이 공용이 아님을 감지했습니다. 다시 확인하고 시도해 주세요!" ErrOSSConn: "최신 버전을 가져올 수 없습니다. 서버가 외부 네트워크에 연결되어 있는지 확인하세요." -ErrEntrance: "보안 입구 정보가 잘못되었습니다. 다시 확인하고 시도해 주세요!" #license ErrLicense: "라이선스 형식이 잘못되었습니다. 다시 확인하고 시도해 주세요!" diff --git a/core/i18n/lang/ms.yml b/core/i18n/lang/ms.yml index b58145f6f..602bf355c 100644 --- a/core/i18n/lang/ms.yml +++ b/core/i18n/lang/ms.yml @@ -28,7 +28,6 @@ ErrBackupCheck: "Cubaan sambungan akaun sandaran gagal {{ .err}}" ErrBackupLocal: "Akaun sandaran pelayan tempatan tidak menyokong operasi ini!" ErrBackupPublic: "Akaun sandaran ini didapati bukan awam, sila semak dan cuba lagi!" ErrOSSConn: "Tidak dapat mendapatkan versi terkini, sila pastikan pelayan boleh disambung ke rangkaian luar." -ErrEntrance: "Maklumat pintu masuk selamat salah, sila semak dan cuba lagi!" #license ErrLicense: "Format lesen salah, sila semak dan cuba lagi!" diff --git a/core/i18n/lang/pt-BR.yaml b/core/i18n/lang/pt-BR.yaml index cbdeef6c0..6e15cf084 100644 --- a/core/i18n/lang/pt-BR.yaml +++ b/core/i18n/lang/pt-BR.yaml @@ -28,7 +28,6 @@ ErrBackupCheck: "Falha na conexão de teste da conta de backup {{ .err}}" ErrBackupLocal: "A conta de backup do servidor local não suporta essa operação!" ErrBackupPublic: "Detectamos que a conta de backup não é pública, verifique e tente novamente!" ErrOSSConn: "Não foi possível obter a versão mais recente, verifique se o servidor pode se conectar à rede externa." -ErrEntrance: "Erro nas informações de entrada de segurança, verifique e tente novamente!" #license ErrLicense: "Erro no formato da licença, verifique e tente novamente!" diff --git a/core/i18n/lang/pt.yaml b/core/i18n/lang/pt.yaml index 4527246a3..311c863d5 100644 --- a/core/i18n/lang/pt.yaml +++ b/core/i18n/lang/pt.yaml @@ -28,7 +28,6 @@ ErrBackupCheck: "Falha na conexão de teste da conta de backup {{ .err}}" ErrBackupLocal: "A conta de backup do servidor local não suporta essa operação!" ErrBackupPublic: "Detectamos que a conta de backup não é pública, verifique e tente novamente!" ErrOSSConn: "Não foi possível obter a versão mais recente, verifique se o servidor pode se conectar à rede externa." -ErrEntrance: "Erro nas informações de entrada de segurança, verifique e tente novamente!" #license ErrLicense: "Erro no formato da licença, verifique e tente novamente!" diff --git a/core/i18n/lang/zh-Hant.yaml b/core/i18n/lang/zh-Hant.yaml index 78ebd58bb..10d40bb87 100644 --- a/core/i18n/lang/zh-Hant.yaml +++ b/core/i18n/lang/zh-Hant.yaml @@ -28,7 +28,6 @@ ErrBackupCheck: "備份帳號測試連接失敗 {{ .err}}" ErrBackupLocal: "本地伺服器備份帳號暫不支持該操作!" ErrBackupPublic: "檢測到該備份帳號為非公用,請檢查後重試!" ErrOSSConn: "無法獲取最新版本,請確認伺服器是否能夠連接外部網絡。" -ErrEntrance: "安全入口信息錯誤,請檢查後重試!" #license ErrLicense: "許可證格式錯誤,請檢查後重試!" diff --git a/core/i18n/lang/zh.yaml b/core/i18n/lang/zh.yaml index a57912a91..f0e305cd5 100644 --- a/core/i18n/lang/zh.yaml +++ b/core/i18n/lang/zh.yaml @@ -19,7 +19,7 @@ ErrApiConfigKeyTimeInvalid: "API 接口时间戳错误: {{ .detail }}" ErrDemoEnvironment: "演示服务器,禁止此操作!" ErrCmdTimeout: "命令执行超时!" ErrEntrance: "安全入口信息错误,请检查后重试!" -ErrGroupIsDefault: '默认分组,无法删除' +ErrGroupIsDefault: "默认分组,无法删除" ErrLocalDelete: "无法删除本地节点!" #backup @@ -28,7 +28,6 @@ ErrBackupCheck: "备份账号测试连接失败 {{ .err}}" ErrBackupLocal: "本地服务器备份账号暂不支持该操作!" ErrBackupPublic: "检测到该备份账号为非公用,请检查后重试!" ErrOSSConn: "无法获取最新版本,请确认服务器是否能够连接外部网络。" -ErrEntrance: "安全入口信息错误,请检查后重试!" #license ErrLicense: "许可证格式错误,请检查后重试!" diff --git a/core/utils/cloud_storage/client/ali.go b/core/utils/cloud_storage/client/ali.go index 6a5084211..ee0b52f9c 100644 --- a/core/utils/cloud_storage/client/ali.go +++ b/core/utils/cloud_storage/client/ali.go @@ -88,6 +88,69 @@ func (a aliClient) Upload(src, target string) (bool, error) { return true, nil } +func (a aliClient) Delete(pathItem string) (bool, error) { + pathItem = path.Join("root", pathItem) + fileInfo, err := a.loadFileWithName(pathItem) + if err != nil { + return false, err + } + client := resty.New() + data := map[string]interface{}{ + "drive_id": a.driveID, + "file_id": fileInfo.FileID, + } + url := "https://api.alipan.com/v2/file/delete" + resp, err := client.R(). + SetHeader("Authorization", a.token). + SetBody(data). + Post(url) + if err != nil { + return false, err + } + if resp.StatusCode() != 204 { + return false, fmt.Errorf("delete file %s failed, err: %v", pathItem, string(resp.Body())) + } + return true, nil +} + +func (a aliClient) loadFileWithName(pathItem string) (fileInfo, error) { + pathItems := strings.Split(pathItem, "/") + var ( + fileInfos []fileInfo + err error + ) + parentID := "root" + for i := 0; i < len(pathItems); i++ { + if len(pathItems[i]) == 0 { + continue + } + fileInfos, err = a.loadFileWithParentID(parentID) + if err != nil { + return fileInfo{}, err + } + isEnd := false + if i == len(pathItems)-2 { + isEnd = true + } + exist := false + for _, item := range fileInfos { + if item.Name == pathItems[i+1] { + if isEnd { + return item, nil + } else { + parentID = item.FileID + exist = true + } + } + } + if !exist { + return fileInfo{}, errors.New("no such file or dir") + } + + } + return fileInfo{}, errors.New("no such file or dir") +} + func (a aliClient) loadFileWithParentID(parentID string) ([]fileInfo, error) { client := resty.New() data := map[string]interface{}{ diff --git a/core/utils/cloud_storage/client/cos.go b/core/utils/cloud_storage/client/cos.go index d000dc232..ede0e9c7e 100644 --- a/core/utils/cloud_storage/client/cos.go +++ b/core/utils/cloud_storage/client/cos.go @@ -94,3 +94,10 @@ func (c cosClient) Upload(src, target string) (bool, error) { } return true, nil } + +func (c cosClient) Delete(path string) (bool, error) { + if _, err := c.clientWithBucket.Object.Delete(context.Background(), path); err != nil { + return false, err + } + return true, nil +} diff --git a/core/utils/cloud_storage/client/google_drive.go b/core/utils/cloud_storage/client/google_drive.go index e38ce7762..b2e67a751 100644 --- a/core/utils/cloud_storage/client/google_drive.go +++ b/core/utils/cloud_storage/client/google_drive.go @@ -72,6 +72,23 @@ func (g *googleDriveClient) Upload(src, target string) (bool, error) { return true, nil } +func (g *googleDriveClient) Delete(pathItem string) (bool, error) { + pathItem = path.Join("root", pathItem) + fileInfo, err := g.loadFileWithName(pathItem) + if err != nil { + return false, err + } + if len(fileInfo.ID) == 0 { + return false, fmt.Errorf("no such file %s", pathItem) + } + res, err := g.googleRequest("https://www.googleapis.com/drive/v3/files/"+fileInfo.ID, http.MethodDelete, nil, nil) + if err != nil { + return false, err + } + fmt.Println(string(res)) + return true, nil +} + type googleFileResp struct { Files []googleFile `json:"files"` } @@ -147,6 +164,44 @@ func (g *googleDriveClient) mkdir(parentID, name string) (string, error) { return mkdirResp.ID, nil } +func (g *googleDriveClient) loadFileWithName(pathItem string) (googleFile, error) { + pathItems := strings.Split(pathItem, "/") + var ( + fileInfos []googleFile + err error + ) + parentID := "root" + for i := 0; i < len(pathItems); i++ { + if len(pathItems[i]) == 0 { + continue + } + fileInfos, err = g.loadFileWithParentID(parentID) + if err != nil { + return googleFile{}, err + } + isEnd := false + if i == len(pathItems)-2 { + isEnd = true + } + exist := false + for _, item := range fileInfos { + if item.Name == pathItems[i+1] { + if isEnd { + return item, nil + } else { + parentID = item.ID + exist = true + } + } + } + if !exist { + return googleFile{}, errors.New("no such file or dir") + } + + } + return googleFile{}, errors.New("no such file or dir") +} + func (g *googleDriveClient) loadFileWithParentID(parentID string) ([]googleFile, error) { query := map[string]string{ "fields": "files(id,name,mimeType,size)", diff --git a/core/utils/cloud_storage/client/kodo.go b/core/utils/cloud_storage/client/kodo.go index dd21e8614..18719309e 100644 --- a/core/utils/cloud_storage/client/kodo.go +++ b/core/utils/cloud_storage/client/kodo.go @@ -64,3 +64,10 @@ func (k kodoClient) Upload(src, target string) (bool, error) { } return true, nil } + +func (k kodoClient) Delete(path string) (bool, error) { + if err := k.client.Delete(k.bucket, path); err != nil { + return false, err + } + return true, nil +} diff --git a/core/utils/cloud_storage/client/local.go b/core/utils/cloud_storage/client/local.go index 0b0f92913..8df304a6a 100644 --- a/core/utils/cloud_storage/client/local.go +++ b/core/utils/cloud_storage/client/local.go @@ -38,3 +38,10 @@ func (c localClient) Upload(src, target string) (bool, error) { } return true, nil } + +func (c localClient) Delete(file string) (bool, error) { + if err := os.RemoveAll(file); err != nil { + return false, err + } + return true, nil +} diff --git a/core/utils/cloud_storage/client/minio.go b/core/utils/cloud_storage/client/minio.go index 2c9db7a86..56dc5dcfd 100644 --- a/core/utils/cloud_storage/client/minio.go +++ b/core/utils/cloud_storage/client/minio.go @@ -76,3 +76,21 @@ func (m minIoClient) Upload(src, target string) (bool, error) { } return true, nil } + +func (m minIoClient) Delete(path string) (bool, error) { + object, err := m.client.GetObject(context.Background(), m.bucket, path, minio.GetObjectOptions{}) + if err != nil { + return false, err + } + info, err := object.Stat() + if err != nil { + return false, err + } + if err = m.client.RemoveObject(context.Background(), m.bucket, path, minio.RemoveObjectOptions{ + GovernanceBypass: true, + VersionID: info.VersionID, + }); err != nil { + return false, err + } + return true, nil +} diff --git a/core/utils/cloud_storage/client/onedrive.go b/core/utils/cloud_storage/client/onedrive.go index 956230352..0ca8c6ef8 100644 --- a/core/utils/cloud_storage/client/onedrive.go +++ b/core/utils/cloud_storage/client/onedrive.go @@ -80,6 +80,19 @@ func (o oneDriveClient) Upload(src, target string) (bool, error) { return isOk, err } +func (o oneDriveClient) Delete(path string) (bool, error) { + path = "/" + strings.TrimPrefix(path, "/") + req, err := o.client.NewRequest("DELETE", fmt.Sprintf("me/drive/root:%s", path), nil) + if err != nil { + return false, fmt.Errorf("new request for delete file failed, err: %v \n", err) + } + if err := o.client.Do(context.Background(), req, false, nil); err != nil { + return false, fmt.Errorf("do request for delete file failed, err: %v \n", err) + } + + return true, nil +} + func (o *oneDriveClient) loadIDByPath(path string) (string, error) { pathItem := "root:" + path if path == "/" { diff --git a/core/utils/cloud_storage/client/oss.go b/core/utils/cloud_storage/client/oss.go index e0b96701a..929b1359c 100644 --- a/core/utils/cloud_storage/client/oss.go +++ b/core/utils/cloud_storage/client/oss.go @@ -53,3 +53,14 @@ func (o ossClient) Upload(src, target string) (bool, error) { } return true, nil } + +func (o ossClient) Delete(path string) (bool, error) { + bucket, err := o.client.Bucket(o.bucketStr) + if err != nil { + return false, err + } + if err := bucket.DeleteObject(path); err != nil { + return false, err + } + return true, nil +} diff --git a/core/utils/cloud_storage/client/s3.go b/core/utils/cloud_storage/client/s3.go index 285d1248b..d64983d5d 100644 --- a/core/utils/cloud_storage/client/s3.go +++ b/core/utils/cloud_storage/client/s3.go @@ -81,3 +81,17 @@ func (s s3Client) Upload(src, target string) (bool, error) { } return true, nil } + +func (s s3Client) Delete(path string) (bool, error) { + svc := s3.New(&s.Sess) + if _, err := svc.DeleteObject(&s3.DeleteObjectInput{Bucket: aws.String(s.bucket), Key: aws.String(path)}); err != nil { + return false, err + } + if err := svc.WaitUntilObjectNotExists(&s3.HeadObjectInput{ + Bucket: aws.String(s.bucket), + Key: aws.String(path), + }); err != nil { + return false, err + } + return true, nil +} diff --git a/core/utils/cloud_storage/client/sftp.go b/core/utils/cloud_storage/client/sftp.go index 167ba0415..04943335d 100644 --- a/core/utils/cloud_storage/client/sftp.go +++ b/core/utils/cloud_storage/client/sftp.go @@ -108,3 +108,21 @@ func (s sftpClient) ListBuckets() ([]interface{}, error) { var result []interface{} return result, nil } + +func (s sftpClient) Delete(filePath string) (bool, error) { + sshClient, err := ssh.Dial("tcp", s.connInfo, s.config) + if err != nil { + return false, err + } + client, err := sftp.NewClient(sshClient) + if err != nil { + return false, err + } + defer client.Close() + defer sshClient.Close() + + if err := client.Remove(filePath); err != nil { + return false, err + } + return true, nil +} diff --git a/core/utils/cloud_storage/client/up.go b/core/utils/cloud_storage/client/up.go index f96d5aa8e..4255e7099 100644 --- a/core/utils/cloud_storage/client/up.go +++ b/core/utils/cloud_storage/client/up.go @@ -45,3 +45,12 @@ func (s upClient) Upload(src, target string) (bool, error) { } return true, nil } + +func (s upClient) Delete(path string) (bool, error) { + if err := s.client.Delete(&upyun.DeleteObjectConfig{ + Path: path, + }); err != nil { + return false, err + } + return true, nil +} diff --git a/core/utils/cloud_storage/client/webdav.go b/core/utils/cloud_storage/client/webdav.go index d4bcf6641..38d236b10 100644 --- a/core/utils/cloud_storage/client/webdav.go +++ b/core/utils/cloud_storage/client/webdav.go @@ -3,12 +3,13 @@ package client import ( "crypto/tls" "fmt" - "github.com/1Panel-dev/1Panel/core/constant" "net/http" "os" "path" "strings" + "github.com/1Panel-dev/1Panel/core/constant" + "github.com/studio-b12/gowebdav" ) @@ -61,3 +62,10 @@ func (s webDAVClient) ListBuckets() ([]interface{}, error) { var result []interface{} return result, nil } + +func (s webDAVClient) Delete(pathItem string) (bool, error) { + if err := s.client.Remove(path.Join(s.Bucket, pathItem)); err != nil { + return false, err + } + return true, nil +} diff --git a/core/utils/cloud_storage/cloud_storage_client.go b/core/utils/cloud_storage/cloud_storage_client.go index 0ffd2061f..f1a3193df 100644 --- a/core/utils/cloud_storage/cloud_storage_client.go +++ b/core/utils/cloud_storage/cloud_storage_client.go @@ -8,6 +8,7 @@ import ( type CloudStorageClient interface { ListBuckets() ([]interface{}, error) Upload(src, target string) (bool, error) + Delete(path string) (bool, error) } func NewCloudStorageClient(backupType string, vars map[string]interface{}) (CloudStorageClient, error) { diff --git a/frontend/package.json b/frontend/package.json index a9f099173..3ca9c181d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -26,8 +26,6 @@ "@codemirror/language": "^6.10.2", "@codemirror/legacy-modes": "^6.4.0", "@codemirror/theme-one-dark": "^6.1.2", - "@codemirror/lang-html": "^6.4.9", - "@codemirror/lang-php": "^6.0.1", "@element-plus/icons-vue": "^1.1.4", "@highlightjs/vue-plugin": "^2.1.0", "@vue-office/docx": "^1.6.2", diff --git a/frontend/src/api/interface/cronjob.ts b/frontend/src/api/interface/cronjob.ts index 21a218e72..cd7b77165 100644 --- a/frontend/src/api/interface/cronjob.ts +++ b/frontend/src/api/interface/cronjob.ts @@ -31,6 +31,10 @@ export namespace Cronjob { sourceAccounts: Array; downloadAccount: string; + sourceAccountIDs: string; + downloadAccountID: number; + sourceAccountItems: Array; + retainCopies: number; status: string; secret: string; diff --git a/frontend/src/layout/components/Sidebar/index.vue b/frontend/src/layout/components/Sidebar/index.vue index ff2422652..f02974a9b 100644 --- a/frontend/src/layout/components/Sidebar/index.vue +++ b/frontend/src/layout/components/Sidebar/index.vue @@ -92,7 +92,6 @@ const nodeChangeRef = ref(); const version = ref(); bus.on('refreshTask', () => { - console.log('on bus message'); checkTask(); }); diff --git a/frontend/src/views/cronjob/operate/index.vue b/frontend/src/views/cronjob/operate/index.vue index c7727b64f..9ad3499b0 100644 --- a/frontend/src/views/cronjob/operate/index.vue +++ b/frontend/src/views/cronjob/operate/index.vue @@ -409,11 +409,11 @@
- +
@@ -585,6 +585,16 @@ const acceptParams = (params: DialogProps): void => { if (dialogData.value.rowData?.specCustom && dialogData.value.rowData?.spec) { dialogData.value.rowData.specs = dialogData.value.rowData.spec.split(','); } + if (dialogData.value.rowData.sourceAccountIDs) { + let list = []; + dialogData.value.rowData.sourceAccountItems = []; + list = dialogData.value.rowData.sourceAccountIDs.split(','); + for (const item of list) { + if (item) { + dialogData.value.rowData.sourceAccountItems.push(item); + } + } + } dialogData.value.rowData.specs = dialogData.value.rowData.specs || []; dialogData.value.rowData.files = []; if (!dialogData.value.rowData.isDir) { @@ -787,7 +797,7 @@ const rules = reactive({ url: [Rules.requiredInput], files: [{ validator: verifyFiles, trigger: 'blur', required: true }], sourceDir: [Rules.requiredInput], - sourceAccounts: [Rules.requiredSelect], + sourceAccountItems: [Rules.requiredSelect], downloadAccountID: [Rules.requiredSelect], retainCopies: [Rules.number], alertCount: [Rules.integerNumber, { validator: checkSendCount, trigger: 'blur' }], @@ -917,8 +927,8 @@ const loadBackups = async () => { } backupOptions.value.push({ id: item.id, type: i18n.global.t('setting.' + item.type), name: item.name }); } - if (!dialogData.value.rowData!.sourceAccounts) { - dialogData.value.rowData!.sourceAccounts = local === 0 ? [local] : []; + if (!dialogData.value.rowData!.sourceAccountItems) { + dialogData.value.rowData!.sourceAccountItems = local === 0 ? [local] : []; } changeAccount(); }; @@ -928,7 +938,7 @@ const changeAccount = async () => { let isInAccounts = false; for (const item of backupOptions.value) { let exist = false; - for (const ac of dialogData.value.rowData.sourceAccounts) { + for (const ac of dialogData.value.rowData.sourceAccountItems) { if (item.id == ac) { exist = true; break; @@ -1010,7 +1020,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => { } dialogData.value.rowData.sourceDir = files.join(','); } - dialogData.value.rowData.sourceAccountIDs = dialogData.value.rowData.sourceAccounts.join(','); + dialogData.value.rowData.sourceAccountIDs = dialogData.value.rowData.sourceAccountItems.join(','); dialogData.value.rowData.spec = specs.join(','); if (!formEl) return; formEl.validate(async (valid) => { @@ -1055,8 +1065,30 @@ defineExpose({ });