PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / 3.1.13.4
JetBackup – Backup, Restore & Migrate v3.1.13.4
3.1.22.3 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.8.1 1.4.9 1.5.0 1.5.1 1.5.1.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.10 1.6.11 1.6.12 1.6.13 1.6.15 1.6.5.1 1.6.8.8 1.6.9 1.6.9.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7.5 2.0.8.7 2.0.9.11 2.0.9.14 2.0.9.15 2.0.9.6 2.0.9.7 2.0.9.9 3.1.10.7 3.1.11.1 3.1.12.3 3.1.13.4 3.1.14.17 3.1.15.4 3.1.16.1 3.1.17.5 3.1.18.10 3.1.18.8 3.1.18.9 3.1.19.8 3.1.20.3 3.1.21.3 3.1.7.9 3.1.9.2 trunk 1.1.90 1.1.91 1.2.0 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2
backup / src / JetBackup / Cron / Task / RetentionCleanup.php
backup / src / JetBackup / Cron / Task Last commit date
.htaccess 9 months ago Backup.php 9 months ago Download.php 9 months ago DownloadBackupLog.php 9 months ago Export.php 9 months ago Extract.php 9 months ago PreRestore.php 9 months ago Reindex.php 9 months ago Restore.php 9 months ago RetentionCleanup.php 9 months ago System.php 9 months ago Task.php 9 months ago index.html 9 months ago web.config 9 months ago
RetentionCleanup.php
184 lines
1 <?php
2
3 namespace JetBackup\Cron\Task;
4
5 use JetBackup\Data\Engine;
6 use JetBackup\Destination\Destination;
7 use JetBackup\Exception\DBException;
8 use JetBackup\Exception\TaskException;
9 use JetBackup\Factory;
10 use JetBackup\JetBackup;
11 use JetBackup\Queue\Queue;
12 use JetBackup\Queue\QueueItem;
13 use JetBackup\Schedule\Schedule;
14 use JetBackup\Snapshot\Snapshot;
15 use SleekDB\Exceptions\InvalidArgumentException;
16 use SleekDB\Exceptions\IOException;
17
18 if (!defined( '__JETBACKUP__')) die('Direct access is not allowed');
19
20 class RetentionCleanup extends Task {
21
22 const LOG_FILENAME = 'retention';
23
24 public function __construct() {
25 parent::__construct(self::LOG_FILENAME);
26 }
27
28 /**
29 * @return void
30 * @throws TaskException
31 * @throws IOException
32 * @throws InvalidArgumentException
33 */
34 public function execute():void {
35 parent::execute();
36
37 if($this->getQueueItem()->getStatus() == Queue::STATUS_PENDING) {
38 $this->getLogController()->logMessage("Starting snapshots retention cleanup");
39
40 $this->getQueueItem()->getProgress()->setTotalItems(count(Queue::STATUS_CLEANUP_NAMES)+3);
41 $this->getQueueItem()->save();
42 $this->getQueueItem()->updateProgress('Starting cleanup');
43 } else if($this->getQueueItem()->getStatus() > Queue::STATUS_PENDING) {
44 $this->getLogController()->logMessage('Resumed snapshots retention cleanup');
45 }
46
47 try {
48 $this->func([$this, '_markManualSnapshots']);
49 $this->func([$this, '_deleteSnapshots']);
50 if($this->getQueueItem()->getStatus() < Queue::STATUS_DONE && !$this->getQueueItem()->getErrors()) $this->getQueueItem()->updateStatus(Queue::STATUS_DONE);
51 else $this->getQueueItem()->updateStatus(Queue::STATUS_PARTIALLY);
52 $this->getLogController()->logMessage('Completed!');
53 } catch(\Exception $e) {
54 $this->getLogController()->logError($e->getMessage());
55 $this->getQueueItem()->addError();
56 $this->getQueueItem()->updateStatus(Queue::STATUS_PARTIALLY);
57 }
58
59 $this->getQueueItem()->updateProgress(
60 $this->getQueueItem()->getStatus() == Queue::STATUS_DONE
61 ? 'Cleanup Completed!'
62 : ($this->getQueueItem()->getStatus() == Queue::STATUS_PARTIALLY
63 ? 'Completed with errors (see logs)'
64 : 'Cleanup Failed!'),
65 QueueItem::PROGRESS_LAST_STEP
66 );
67
68 $this->getLogController()->logMessage('Total time: ' . $this->getExecutionTimeElapsed());
69 }
70
71 /**
72 * get a list of manual snapshots limit results based on retention limit
73 *
74 * @param int $destinationID
75 *
76 * @return array
77 * @throws IOException
78 * @throws InvalidArgumentException
79 */
80 static public function getManualSnapshots(int $destinationID): array {
81
82 return Snapshot::query()
83 ->where([Snapshot::SCHEDULES, 'contains', Schedule::TYPE_MANUALLY])
84 ->where([Engine::ENGINE, '=', Engine::ENGINE_WP])
85 ->where([Snapshot::DESTINATION_ID, '=', $destinationID])
86 ->orderBy([Snapshot::CREATED => 'desc'])
87 ->skip(Factory::getSettingsGeneral()->getManualBackupsRetention())
88 ->getQuery()
89 ->fetch();
90 }
91
92 /**
93 * Mark manual snapshots for deletion per retention global settings
94 * @return void
95 * @throws IOException
96 * @throws InvalidArgumentException
97 * @throws DBException
98 */
99 public function _markManualSnapshots(): void {
100
101 if (!Factory::getSettingsGeneral()->getManualBackupsRetention()) {
102 $this->getLogController()->logMessage('[_markManualSnapshots] Manual Backups retention disabled, skipping');
103 return;
104 }
105
106 $this->getLogController()->logMessage('[_markManualSnapshots] Execution time: ' . $this->getExecutionTimeElapsed());
107 $this->getLogController()->logMessage('[_markManualSnapshots] TTL time: ' . $this->getExecutionTimeLimit());
108
109 $destinations = Destination::query()->select([JetBackup::ID_FIELD])->getQuery()->fetch();
110 foreach($destinations as $id) {
111
112 $destination = new Destination($id[JetBackup::ID_FIELD]);
113 if (!$destination->getId()) continue;
114 if (!$destination->isEnabled()) continue;
115 if ($destination->isReadOnly()) continue;
116
117 foreach(self::getManualSnapshots($destination->getId()) as $snapshot_details) {
118 $snapshot = new Snapshot($snapshot_details[JetBackup::ID_FIELD]);
119 $this->getLogController()->logDebug('Marking Manual snapshot for delete: ' . $snapshot->getName() . ' ' . $snapshot->getDestinationName() . ' [ID ' . $snapshot->getDestinationId() . ']');
120 $snapshot->removeSchedule(Schedule::TYPE_MANUALLY);
121 // if there is no more schedules assigned for this snapshot we need to delete it
122 if(!sizeof($snapshot->getSchedules())) $snapshot->setDeleted(time());
123 $snapshot->save();
124 }
125
126 }
127
128 }
129
130 /**
131 * @return array
132 * @throws IOException
133 * @throws InvalidArgumentException
134 */
135 static public function listSnapshots(): array {
136
137 return Snapshot::query()
138 ->where([Snapshot::DELETED, '>', 0])
139 ->where([Snapshot::DELETED, '<=', time()])
140 ->where([Engine::ENGINE, '=', Engine::ENGINE_WP])
141 ->orderBy([Snapshot::DESTINATION_ID => 'asc'])
142 ->getQuery()
143 ->fetch();
144
145 }
146
147 /**
148 * @return void
149 */
150 public function _deleteSnapshots() {
151
152
153 $this->getLogController()->logMessage('[_deleteSnapshots] Execution time: ' . $this->getExecutionTimeElapsed());
154 $this->getLogController()->logMessage('[_deleteSnapshots] TTL time: ' . $this->getExecutionTimeLimit());
155
156 $this->getQueueItem()->updateStatus(Queue::STATUS_CLEANUP_DELETING);
157 $this->getQueueItem()->updateProgress('Deleting snapshots');
158
159 $destinations = [];
160
161 $this->foreachCallable(['JetBackup\Cron\Task\RetentionCleanup', 'listSnapshots'], [], function($i, $snapshot_details) use ($destinations) {
162
163 try {
164 $snapshot = new Snapshot($snapshot_details[JetBackup::ID_FIELD]);
165
166 if(!isset($destinations[$snapshot->getDestinationId()]))
167 $destinations[$snapshot->getDestinationId()] = new Destination($snapshot->getDestinationId());
168
169 $destination = $destinations[$snapshot->getDestinationId()];
170
171 $this->getLogController()->logMessage("Deleting snapshot \"{$snapshot->getName()}\" from destination \"{$destination->getName()}\"");
172 $destination->removeDir($snapshot->getJobIdentifier() . '/' . $snapshot->getName());
173 $snapshot->delete();
174 } catch (\Exception $e) {
175 $this->getLogController()->logError("Error deleting snapshot \"{$snapshot->getName()}\" from destination \"{$destination->getName()}\"");
176 $this->getLogController()->logError($e->getMessage());
177 $this->getQueueItem()->addError();
178 return;
179 }
180
181
182 });
183 }
184 }