From 7363b1b831fe442af185911c1a1acacba846eeba Mon Sep 17 00:00:00 2001 From: zhaixiaojian Date: Tue, 31 Dec 2024 15:20:52 +0800 Subject: [PATCH] * [task#135722,done,1h,0h] Fixed backup cleanup bug. --- db/update21.3.sql | 3 ++ db/zentao.sql | 3 +- module/instance/control.php | 22 +++++++++++- module/instance/lang/de.php | 2 ++ module/instance/lang/en.php | 2 ++ module/instance/lang/fr.php | 2 ++ module/instance/lang/zh-cn.php | 2 ++ module/instance/model.php | 61 ++++++++++++++++++++++------------ 8 files changed, 74 insertions(+), 23 deletions(-) diff --git a/db/update21.3.sql b/db/update21.3.sql index 52b27c0fd7..19d16d2aaa 100644 --- a/db/update21.3.sql +++ b/db/update21.3.sql @@ -41,3 +41,6 @@ ALTER TABLE `zt_projectproduct` DROP INDEX `PRIMARY`; ALTER TABLE `zt_projectproduct` ADD UNIQUE `project_product` (`project`, `product`, `branch`); ALTER TABLE `zt_userview` ADD `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`id`); + +INSERT INTO `zt_cron` (`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type`, `buildin`, `status`, `lastTime`) VALUES +('30', '1', '*', '*', '*', 'moduleName=instance&methodName=cronCleanBackup', 'Devops服务备份清理', 'zentao', 1, 'normal', NULL); diff --git a/db/zentao.sql b/db/zentao.sql index f226d424df..6c24c1fa7a 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -16151,7 +16151,8 @@ CREATE INDEX `idx_repo_deleted` ON `zt_job` (`repo`,`deleted`); INSERT INTO `zt_cron` (`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type`, `buildin`, `status`, `lastTime`) VALUES ('*/5', '*', '*', '*', '*', 'moduleName=program&methodName=refreshStats', '刷新项目集统计数据', 'zentao', 1, 'normal', NULL), -('*/5', '*', '*', '*', '*', 'moduleName=product&methodName=refreshStats', '刷新产品统计数据', 'zentao', 1, 'normal', NULL); +('*/5', '*', '*', '*', '*', 'moduleName=product&methodName=refreshStats', '刷新产品统计数据', 'zentao', 1, 'normal', NULL), +('30', '1', '*', '*', '*', 'moduleName=instance&methodName=cronCleanBackup', 'Devops服务备份清理', 'zentao', 1, 'normal', NULL); REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`, `vision`) VALUES ('zh-cn', 'custom', 'relationList', '1', '{\"relation\":\"\\u76f8\\u5173\",\"relativeRelation\":\"\\u76f8\\u5173\"}', '0', 'all'), diff --git a/module/instance/control.php b/module/instance/control.php index db6d256f18..7ba3ae0a77 100644 --- a/module/instance/control.php +++ b/module/instance/control.php @@ -646,7 +646,7 @@ class instance extends control public function cronBackup(string $instanceID) { $instance = $this->instance->getByID((int)$instanceID); - if(empty($instance)) $this->send(array('result' => 'success', 'message' => $this->lang->instance->instanceNotExists)); + if(empty($instance)) return $this->send(array('result' => 'success', 'message' => $this->lang->instance->instanceNotExists)); $sysUser = new stdclass; $sysUser->account = 'system'; @@ -658,6 +658,26 @@ class instance extends control return $this->send(array('result' => 'success', 'message' => zget($this->lang->instance->notices, 'backupSuccess'))); } + /** + * Cron cleaning backup. + * 定时清理备份。 + * + * @return void + */ + public function cronCleanBackup() + { + if(!$this->config->inQuickon) return $this->send(array('result' => 'success', 'message' => zget($this->lang->instance->notices, 'NoCleanBackupFiles'))); + + /* Init instance list. */ + $instances = $this->loadModel('space')->getSpaceInstances(0, 'running'); + if(empty($instances)) return $this->send(array('result' => 'success', 'message' => zget($this->lang->instance->notices, 'NoCleanBackupFiles'))); + + /* Cycle cleaning backup. */ + foreach($instances as $instance) $this->instance->cleanBackup($instance); + + return $this->send(array('result' => 'success', 'message' => zget($this->lang->instance->notices, 'cleanBackupSuccess'))); + } + /** * Delete backup by ajax. * 删除备份。 diff --git a/module/instance/lang/de.php b/module/instance/lang/de.php index 9f8c1258fb..5a26bca3f0 100644 --- a/module/instance/lang/de.php +++ b/module/instance/lang/de.php @@ -345,6 +345,8 @@ $lang->instance->notices['disableSMTPSuccess'] = 'Disable SMTP successfull $lang->instance->notices['confirmCustom'] = 'After modifying the custom configuration, the service will automatically restart to make the configuration effective.'; $lang->instance->notices['required'] = 'cannot be empty'; $lang->instance->notices['notEnoughResource'] = 'Insufficient platform resources. Do you want to continue installing?'; +$lang->instance->notices['NoCleanBackupFiles'] = 'There are currently no backup files to clean.'; +$lang->instance->notices['cleanBackupSuccess'] = 'Backup cleanup succeeded.'; $lang->instance->nameChangeTo = '%s is modified to %s.'; $lang->instance->versionChangeTo = 'Upgrade %s to %s.'; diff --git a/module/instance/lang/en.php b/module/instance/lang/en.php index 9f8c1258fb..5a26bca3f0 100644 --- a/module/instance/lang/en.php +++ b/module/instance/lang/en.php @@ -345,6 +345,8 @@ $lang->instance->notices['disableSMTPSuccess'] = 'Disable SMTP successfull $lang->instance->notices['confirmCustom'] = 'After modifying the custom configuration, the service will automatically restart to make the configuration effective.'; $lang->instance->notices['required'] = 'cannot be empty'; $lang->instance->notices['notEnoughResource'] = 'Insufficient platform resources. Do you want to continue installing?'; +$lang->instance->notices['NoCleanBackupFiles'] = 'There are currently no backup files to clean.'; +$lang->instance->notices['cleanBackupSuccess'] = 'Backup cleanup succeeded.'; $lang->instance->nameChangeTo = '%s is modified to %s.'; $lang->instance->versionChangeTo = 'Upgrade %s to %s.'; diff --git a/module/instance/lang/fr.php b/module/instance/lang/fr.php index 9f8c1258fb..5a26bca3f0 100644 --- a/module/instance/lang/fr.php +++ b/module/instance/lang/fr.php @@ -345,6 +345,8 @@ $lang->instance->notices['disableSMTPSuccess'] = 'Disable SMTP successfull $lang->instance->notices['confirmCustom'] = 'After modifying the custom configuration, the service will automatically restart to make the configuration effective.'; $lang->instance->notices['required'] = 'cannot be empty'; $lang->instance->notices['notEnoughResource'] = 'Insufficient platform resources. Do you want to continue installing?'; +$lang->instance->notices['NoCleanBackupFiles'] = 'There are currently no backup files to clean.'; +$lang->instance->notices['cleanBackupSuccess'] = 'Backup cleanup succeeded.'; $lang->instance->nameChangeTo = '%s is modified to %s.'; $lang->instance->versionChangeTo = 'Upgrade %s to %s.'; diff --git a/module/instance/lang/zh-cn.php b/module/instance/lang/zh-cn.php index b1f56e78db..b9f9ad777e 100644 --- a/module/instance/lang/zh-cn.php +++ b/module/instance/lang/zh-cn.php @@ -348,6 +348,8 @@ $lang->instance->notices['disableSMTPSuccess'] = '禁用SMTP成功'; $lang->instance->notices['confirmCustom'] = '修改自定义配置后服务将自动重启以使配置生效。'; $lang->instance->notices['required'] = '不能为空'; $lang->instance->notices['notEnoughResource'] = '平台资源不足,要继续安装吗?'; +$lang->instance->notices['NoCleanBackupFiles'] = '当前无可清理的备份文件。'; +$lang->instance->notices['cleanBackupSuccess'] = '备份清理成功'; $lang->instance->nameChangeTo = ' %s 修改为 %s 。'; $lang->instance->versionChangeTo = ' %s 升级为 %s 。'; diff --git a/module/instance/model.php b/module/instance/model.php index ed5c89a39d..4e9e964210 100644 --- a/module/instance/model.php +++ b/module/instance/model.php @@ -1355,28 +1355,7 @@ class instanceModel extends model } $this->action->create('instance', $instance->id, 'autobackup', '', json_encode(array('result' => 'success', 'data' => $result))); - /* 2. Pick latest successful backup recorder. */ - $latestBackup = null; - $backupList = $this->backupList($instance); - foreach($backupList as $backup) - { - if(empty($latestBackup) or $backup->status == 'completed' && $backup->create_time > $latestBackup->create_time) $latestBackup = $backup; - } - /* 3. delete expired backup. Get backup list of instance, then check every backup is expired or not.*/ - $deleteData = array(); - foreach($backupList as $backup) - { - if($latestBackup && $latestBackup->name == $backup->name) continue; // Keep latest successful backup. - - $deadline = intval($backup->create_time) + $instance->backupKeepDays * 24 * 3600; - if($deadline < time()) - { - $this->cne->deleteBackup($instance, $backup->name); - array_push($deleteData, array('backupName' => $backup->name, 'backupCreateTime' => $backup->create_time)); - } - } - if(count($deleteData) > 0) $this->action->create('instance', $instance->id, 'deleteexpiredbackup', '', json_encode(array('result' => 'success', 'data' =>$deleteData))); return true; } @@ -1424,4 +1403,44 @@ class instanceModel extends model if(!$instance) return new stdClass(); return $instance; } + + /** + * 清理备份 + * Cleanup Backup. + * + * @param $instance + * @return void + */ + public function cleanBackup(object $instance): bool + { + $instance->spaceData = $this->dao->select('*')->from(TABLE_SPACE)->where('id')->eq($instance->space)->fetch(); + + /* 1. Pick latest successful backup recorder. */ + $latestBackup = null; + $backupList = $this->backupList($instance); + if(empty($backupList)) return true; + foreach($backupList as $backup) + { + if(empty($latestBackup) or $backup->status == 'completed' && $backup->create_time > $latestBackup->create_time) $latestBackup = $backup; + } + + /* 2. delete expired backup. Get backup list of instance, then check every backup is expired or not.*/ + $deleteData = array(); + foreach($backupList as $backup) + { + if($latestBackup && $latestBackup->name == $backup->name) continue; // Keep latest successful backup. + + $keepDays = !empty($instance->backupKeepDays) ? $instance->backupKeepDays : 1; + $deadline = intval($backup->create_time) + $keepDays * 24 * 3600; + $backupName = base64_decode(helper::safe64Decode($backup->name)); + if($deadline < time()) + { + $cneResult = $this->cne->deleteBackup($instance, $backupName); + array_push($deleteData, array('instanceId' => $instance->id, 'instanceName' => $instance->name, 'backupName' => $backupName, 'backupCreateTime' => $backup->create_time, 'cneResult' => $cneResult)); + } + } + if(count($deleteData) > 0) $this->action->create('instance', $instance->id, 'deleteexpiredbackup', '', json_encode(array('result' => 'success', 'data' => $deleteData))); + + return true; + } }