mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-10-10 15:36:45 +08:00
feat: Support the retention of remote backup files when deleting sche… (#8296)
Refs #8236
This commit is contained in:
parent
bba8aab18c
commit
90be74504e
14 changed files with 70 additions and 25 deletions
|
@ -71,14 +71,16 @@ type CronjobDownload struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type CronjobClean struct {
|
type CronjobClean struct {
|
||||||
IsDelete bool `json:"isDelete"`
|
IsDelete bool `json:"isDelete"`
|
||||||
CleanData bool `json:"cleanData"`
|
CleanData bool `json:"cleanData"`
|
||||||
CronjobID uint `json:"cronjobID" validate:"required"`
|
CleanRemoteData bool `json:"cleanRemoteData"`
|
||||||
|
CronjobID uint `json:"cronjobID" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CronjobBatchDelete struct {
|
type CronjobBatchDelete struct {
|
||||||
CleanData bool `json:"cleanData"`
|
CleanData bool `json:"cleanData"`
|
||||||
IDs []uint `json:"ids" validate:"required"`
|
CleanRemoteData bool `json:"cleanRemoteData"`
|
||||||
|
IDs []uint `json:"ids" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CronjobInfo struct {
|
type CronjobInfo struct {
|
||||||
|
|
|
@ -114,6 +114,13 @@ func (u *CronjobService) CleanRecord(req dto.CronjobClean) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if !req.CleanRemoteData {
|
||||||
|
for key := range accountMap {
|
||||||
|
if key != constant.Local {
|
||||||
|
delete(accountMap, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
cronjob.RetainCopies = 0
|
cronjob.RetainCopies = 0
|
||||||
u.removeExpiredBackup(cronjob, accountMap, model.BackupRecord{})
|
u.removeExpiredBackup(cronjob, accountMap, model.BackupRecord{})
|
||||||
} else {
|
} else {
|
||||||
|
@ -249,7 +256,7 @@ func (u *CronjobService) Delete(req dto.CronjobBatchDelete) error {
|
||||||
global.Cron.Remove(cron.EntryID(idItem))
|
global.Cron.Remove(cron.EntryID(idItem))
|
||||||
}
|
}
|
||||||
global.LOG.Infof("stop cronjob entryID: %s", cronjob.EntryIDs)
|
global.LOG.Infof("stop cronjob entryID: %s", cronjob.EntryIDs)
|
||||||
if err := u.CleanRecord(dto.CronjobClean{CronjobID: id, CleanData: req.CleanData, IsDelete: true}); err != nil {
|
if err := u.CleanRecord(dto.CronjobClean{CronjobID: id, CleanData: req.CleanData, CleanRemoteData: req.CleanRemoteData, IsDelete: true}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := cronjobRepo.Delete(commonRepo.WithByID(id)); err != nil {
|
if err := cronjobRepo.Delete(commonRepo.WithByID(id)); err != nil {
|
||||||
|
|
|
@ -81,6 +81,7 @@ export namespace Cronjob {
|
||||||
export interface CronjobDelete {
|
export interface CronjobDelete {
|
||||||
ids: Array<number>;
|
ids: Array<number>;
|
||||||
cleanData: boolean;
|
cleanData: boolean;
|
||||||
|
cleanRemoteData: boolean;
|
||||||
}
|
}
|
||||||
export interface UpdateStatus {
|
export interface UpdateStatus {
|
||||||
id: number;
|
id: number;
|
||||||
|
|
|
@ -27,8 +27,12 @@ export const searchRecords = (params: Cronjob.SearchRecord) => {
|
||||||
return http.post<ResPage<Cronjob.Record>>(`cronjobs/search/records`, params);
|
return http.post<ResPage<Cronjob.Record>>(`cronjobs/search/records`, params);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const cleanRecords = (id: number, cleanData: boolean) => {
|
export const cleanRecords = (id: number, cleanData: boolean, cleanRemoteData: boolean) => {
|
||||||
return http.post(`cronjobs/records/clean`, { cronjobID: id, cleanData: cleanData });
|
return http.post(`cronjobs/records/clean`, {
|
||||||
|
cronjobID: id,
|
||||||
|
cleanData: cleanData,
|
||||||
|
cleanRemoteData: cleanRemoteData,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getRecordDetail = (params: string) => {
|
export const getRecordDetail = (params: string) => {
|
||||||
|
|
|
@ -1013,6 +1013,7 @@ const message = {
|
||||||
errHandle: 'Cronjob execution failure',
|
errHandle: 'Cronjob execution failure',
|
||||||
noRecord: 'Trigger the Cron Job, and you will see the records here.',
|
noRecord: 'Trigger the Cron Job, and you will see the records here.',
|
||||||
cleanData: 'Clean data',
|
cleanData: 'Clean data',
|
||||||
|
cleanRemoteData: 'Delete remote data',
|
||||||
cleanDataHelper: 'Delete the backup file generated during this task.',
|
cleanDataHelper: 'Delete the backup file generated during this task.',
|
||||||
noLogs: 'No task output yet...',
|
noLogs: 'No task output yet...',
|
||||||
errPath: 'Backup path [{0}] error, cannot download!',
|
errPath: 'Backup path [{0}] error, cannot download!',
|
||||||
|
|
|
@ -998,6 +998,7 @@ const message = {
|
||||||
errHandle: 'cronjob実行障害',
|
errHandle: 'cronjob実行障害',
|
||||||
noRecord: 'Cronジョブをトリガーすると、ここにレコードが表示されます。',
|
noRecord: 'Cronジョブをトリガーすると、ここにレコードが表示されます。',
|
||||||
cleanData: 'クリーンデータ',
|
cleanData: 'クリーンデータ',
|
||||||
|
cleanRemoteData: 'リモートデータを削除',
|
||||||
cleanDataHelper: 'このタスク中に生成されたバックアップファイルを削除します。',
|
cleanDataHelper: 'このタスク中に生成されたバックアップファイルを削除します。',
|
||||||
noLogs: 'タスク出力はまだありません...',
|
noLogs: 'タスク出力はまだありません...',
|
||||||
errPath: 'バックアップパス[{0}]エラー、ダウンロードできません!',
|
errPath: 'バックアップパス[{0}]エラー、ダウンロードできません!',
|
||||||
|
|
|
@ -992,6 +992,7 @@ const message = {
|
||||||
errHandle: '크론 작업 실행 실패',
|
errHandle: '크론 작업 실행 실패',
|
||||||
noRecord: '크론 작업을 트리거하고 나면 여기에 레코드가 표시됩니다.',
|
noRecord: '크론 작업을 트리거하고 나면 여기에 레코드가 표시됩니다.',
|
||||||
cleanData: '데이터 정리',
|
cleanData: '데이터 정리',
|
||||||
|
cleanRemoteData: '원격 데이터 삭제',
|
||||||
cleanDataHelper: '이 작업에서 생성된 백업 파일을 삭제합니다.',
|
cleanDataHelper: '이 작업에서 생성된 백업 파일을 삭제합니다.',
|
||||||
noLogs: '작업 출력이 아직 없습니다...',
|
noLogs: '작업 출력이 아직 없습니다...',
|
||||||
errPath: '백업 경로 [{0}] 오류, 다운로드할 수 없습니다!',
|
errPath: '백업 경로 [{0}] 오류, 다운로드할 수 없습니다!',
|
||||||
|
|
|
@ -1027,6 +1027,7 @@ const message = {
|
||||||
errHandle: 'Kegagalan pelaksanaan tugas cron',
|
errHandle: 'Kegagalan pelaksanaan tugas cron',
|
||||||
noRecord: 'Picu Tugas Cron, dan anda akan melihat rekod di sini.',
|
noRecord: 'Picu Tugas Cron, dan anda akan melihat rekod di sini.',
|
||||||
cleanData: 'Bersihkan data',
|
cleanData: 'Bersihkan data',
|
||||||
|
cleanRemoteData: 'Padam data jarak jauh',
|
||||||
cleanDataHelper: 'Padam fail sandaran yang dijana semasa tugas ini.',
|
cleanDataHelper: 'Padam fail sandaran yang dijana semasa tugas ini.',
|
||||||
noLogs: 'Tiada keluaran tugas lagi...',
|
noLogs: 'Tiada keluaran tugas lagi...',
|
||||||
errPath: 'Laluan sandaran [{0}] salah, tidak boleh dimuat turun!',
|
errPath: 'Laluan sandaran [{0}] salah, tidak boleh dimuat turun!',
|
||||||
|
|
|
@ -1018,6 +1018,7 @@ const message = {
|
||||||
errHandle: 'Falha na execução do Cronjob',
|
errHandle: 'Falha na execução do Cronjob',
|
||||||
noRecord: 'Acione a tarefa Cron e você verá os registros aqui.',
|
noRecord: 'Acione a tarefa Cron e você verá os registros aqui.',
|
||||||
cleanData: 'Limpar dados',
|
cleanData: 'Limpar dados',
|
||||||
|
cleanRemoteData: 'Excluir dados remotos',
|
||||||
cleanDataHelper: 'Excluir o arquivo de backup gerado durante esta tarefa.',
|
cleanDataHelper: 'Excluir o arquivo de backup gerado durante esta tarefa.',
|
||||||
noLogs: 'Ainda não há saída de tarefa...',
|
noLogs: 'Ainda não há saída de tarefa...',
|
||||||
errPath: 'Caminho de backup [{0}] com erro, não é possível fazer o download!',
|
errPath: 'Caminho de backup [{0}] com erro, não é possível fazer o download!',
|
||||||
|
|
|
@ -1021,6 +1021,7 @@ const message = {
|
||||||
errHandle: 'Сбой выполнения задачи Cron',
|
errHandle: 'Сбой выполнения задачи Cron',
|
||||||
noRecord: 'Запустите задачу Cron, и вы увидите записи здесь.',
|
noRecord: 'Запустите задачу Cron, и вы увидите записи здесь.',
|
||||||
cleanData: 'Очистить данные',
|
cleanData: 'Очистить данные',
|
||||||
|
cleanRemoteData: 'Удалить удалённые данные',
|
||||||
cleanDataHelper: 'Удалить файл резервной копии, созданный во время этой задачи.',
|
cleanDataHelper: 'Удалить файл резервной копии, созданный во время этой задачи.',
|
||||||
noLogs: 'Пока нет вывода задачи...',
|
noLogs: 'Пока нет вывода задачи...',
|
||||||
errPath: 'Ошибка пути резервной копии [{0}], невозможно скачать!',
|
errPath: 'Ошибка пути резервной копии [{0}], невозможно скачать!',
|
||||||
|
|
|
@ -965,6 +965,7 @@ const message = {
|
||||||
errHandle: '任務執行失敗',
|
errHandle: '任務執行失敗',
|
||||||
noRecord: '目前計劃任務暫未產生記錄',
|
noRecord: '目前計劃任務暫未產生記錄',
|
||||||
cleanData: '刪除備份檔案',
|
cleanData: '刪除備份檔案',
|
||||||
|
cleanRemoteData: '刪除遠端備份檔案',
|
||||||
cleanDataHelper: '刪除該任務執行過程中產生的備份檔案',
|
cleanDataHelper: '刪除該任務執行過程中產生的備份檔案',
|
||||||
noLogs: '暫無任務輸出...',
|
noLogs: '暫無任務輸出...',
|
||||||
errPath: '備份路徑 [{0}] 錯誤,無法下載!',
|
errPath: '備份路徑 [{0}] 錯誤,無法下載!',
|
||||||
|
|
|
@ -966,6 +966,7 @@ const message = {
|
||||||
errHandle: '任务执行失败',
|
errHandle: '任务执行失败',
|
||||||
noRecord: '当前计划任务暂未产生记录',
|
noRecord: '当前计划任务暂未产生记录',
|
||||||
cleanData: '删除备份文件',
|
cleanData: '删除备份文件',
|
||||||
|
cleanRemoteData: '删除远程备份文件',
|
||||||
cleanDataHelper: '删除该任务执行过程中产生的备份文件',
|
cleanDataHelper: '删除该任务执行过程中产生的备份文件',
|
||||||
noLogs: '暂无任务输出...',
|
noLogs: '暂无任务输出...',
|
||||||
errPath: '备份路径 [{0}] 错误,无法下载!',
|
errPath: '备份路径 [{0}] 错误,无法下载!',
|
||||||
|
|
|
@ -163,6 +163,11 @@
|
||||||
<el-form class="mt-4 mb-1" v-if="showClean" ref="deleteForm" label-position="left">
|
<el-form class="mt-4 mb-1" v-if="showClean" ref="deleteForm" label-position="left">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-checkbox v-model="cleanData" :label="$t('cronjob.cleanData')" />
|
<el-checkbox v-model="cleanData" :label="$t('cronjob.cleanData')" />
|
||||||
|
<el-checkbox
|
||||||
|
v-if="cleanData"
|
||||||
|
v-model="cleanRemoteData"
|
||||||
|
:label="$t('cronjob.cleanRemoteData')"
|
||||||
|
/>
|
||||||
<span class="input-help">
|
<span class="input-help">
|
||||||
{{ $t('cronjob.cleanDataHelper') }}
|
{{ $t('cronjob.cleanDataHelper') }}
|
||||||
</span>
|
</span>
|
||||||
|
@ -197,6 +202,7 @@ const operateIDs = ref();
|
||||||
const opRef = ref();
|
const opRef = ref();
|
||||||
const showClean = ref();
|
const showClean = ref();
|
||||||
const cleanData = ref();
|
const cleanData = ref();
|
||||||
|
const cleanRemoteData = ref(true);
|
||||||
|
|
||||||
const data = ref();
|
const data = ref();
|
||||||
const paginationConfig = reactive({
|
const paginationConfig = reactive({
|
||||||
|
@ -312,7 +318,7 @@ const onDelete = async (row: Cronjob.CronjobInfo | null) => {
|
||||||
|
|
||||||
const onSubmitDelete = async () => {
|
const onSubmitDelete = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await deleteCronjob({ ids: operateIDs.value, cleanData: cleanData.value })
|
await deleteCronjob({ ids: operateIDs.value, cleanData: cleanData.value, cleanRemoteData: cleanRemoteData.value })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
MsgSuccess(i18n.global.t('commons.msg.deleteSuccess'));
|
MsgSuccess(i18n.global.t('commons.msg.deleteSuccess'));
|
||||||
|
|
|
@ -223,6 +223,7 @@
|
||||||
<el-form ref="deleteForm" label-position="left" v-loading="delLoading">
|
<el-form ref="deleteForm" label-position="left" v-loading="delLoading">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-checkbox v-model="cleanData" :label="$t('cronjob.cleanData')" />
|
<el-checkbox v-model="cleanData" :label="$t('cronjob.cleanData')" />
|
||||||
|
<el-checkbox v-if="cleanData" v-model="cleanRemoteData" :label="$t('cronjob.cleanRemoteData')" />
|
||||||
<span class="input-help">
|
<span class="input-help">
|
||||||
{{ $t('cronjob.cleanDataHelper') }}
|
{{ $t('cronjob.cleanDataHelper') }}
|
||||||
</span>
|
</span>
|
||||||
|
@ -282,6 +283,7 @@ const currentRecordDetail = ref<string>('');
|
||||||
const deleteVisible = ref();
|
const deleteVisible = ref();
|
||||||
const delLoading = ref();
|
const delLoading = ref();
|
||||||
const cleanData = ref();
|
const cleanData = ref();
|
||||||
|
const cleanRemoteData = ref(true);
|
||||||
|
|
||||||
const acceptParams = async (params: DialogProps): Promise<void> => {
|
const acceptParams = async (params: DialogProps): Promise<void> => {
|
||||||
let itemSize = Number(localStorage.getItem(searchInfo.cacheSizeKey));
|
let itemSize = Number(localStorage.getItem(searchInfo.cacheSizeKey));
|
||||||
|
@ -433,26 +435,30 @@ const loadRecord = async (row: Cronjob.Record) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const onClean = async () => {
|
const onClean = async () => {
|
||||||
ElMessageBox.confirm(i18n.global.t('commons.msg.clean'), i18n.global.t('commons.msg.deleteTitle'), {
|
if (!isBackup()) {
|
||||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
ElMessageBox.confirm(i18n.global.t('commons.msg.clean'), i18n.global.t('commons.msg.deleteTitle'), {
|
||||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||||
type: 'warning',
|
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||||
}).then(async () => {
|
type: 'warning',
|
||||||
await cleanRecords(dialogData.value.rowData.id, cleanData.value)
|
}).then(async () => {
|
||||||
.then(() => {
|
await cleanRecords(dialogData.value.rowData.id, cleanData.value, cleanRemoteData.value)
|
||||||
delLoading.value = false;
|
.then(() => {
|
||||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
delLoading.value = false;
|
||||||
search();
|
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||||
})
|
search();
|
||||||
.catch(() => {
|
})
|
||||||
delLoading.value = false;
|
.catch(() => {
|
||||||
});
|
delLoading.value = false;
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
deleteVisible.value = true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const cleanRecord = async () => {
|
const cleanRecord = async () => {
|
||||||
delLoading.value = true;
|
delLoading.value = true;
|
||||||
await cleanRecords(dialogData.value.rowData.id, cleanData.value)
|
await cleanRecords(dialogData.value.rowData.id, cleanData.value, cleanRemoteData.value)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
delLoading.value = false;
|
delLoading.value = false;
|
||||||
deleteVisible.value = false;
|
deleteVisible.value = false;
|
||||||
|
@ -464,6 +470,17 @@ const cleanRecord = async () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function isBackup() {
|
||||||
|
return (
|
||||||
|
dialogData.value.rowData!.type === 'app' ||
|
||||||
|
dialogData.value.rowData!.type === 'website' ||
|
||||||
|
dialogData.value.rowData!.type === 'database' ||
|
||||||
|
dialogData.value.rowData!.type === 'directory' ||
|
||||||
|
dialogData.value.rowData!.type === 'snapshot' ||
|
||||||
|
dialogData.value.rowData!.type === 'log'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
clearInterval(Number(timer));
|
clearInterval(Number(timer));
|
||||||
timer = null;
|
timer = null;
|
||||||
|
|
Loading…
Add table
Reference in a new issue