From ee93ccd8e7446a6e4d8f531821313bcd5de285e2 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 14 Mar 2025 15:28:12 +0100 Subject: [PATCH] fix(backups): retention settings - If you set a low local backup retention, for example 2 backups for local backup retention and 10 backups for S3, then the S3 backups were never deleted, not even after 10 days. This was because we check the file paths based on the backup executions table, and as soon as a backup was deleted locally, the execution was removed, which meant after 10 days for s3 there where no backups older then 10 days just the 2 local backups which is just wrong. Now we only delete a backup execution if it has been removed from both locations. - Also added a nice little UI element to see where your backup is available. --- bootstrap/helpers/databases.php | 28 +++++++++--- ...deletion_tracking_to_backup_executions.php | 19 ++++++++ .../database/backup-executions.blade.php | 43 +++++++++++++++++++ 3 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 database/migrations/2025_03_14_140150_add_storage_deletion_tracking_to_backup_executions.php diff --git a/bootstrap/helpers/databases.php b/bootstrap/helpers/databases.php index f2c069ac4..2fd85337d 100644 --- a/bootstrap/helpers/databases.php +++ b/bootstrap/helpers/databases.php @@ -233,15 +233,29 @@ function deleteEmptyBackupFolder($folderPath, Server $server): void function removeOldBackups($backup): void { try { - $processedBackups = deleteOldBackupsLocally($backup); - - if ($backup->save_s3) { - $processedBackups = $processedBackups->merge(deleteOldBackupsFromS3($backup)); + if ($backup->executions) { + $localBackupsToDelete = deleteOldBackupsLocally($backup); + if ($localBackupsToDelete->isNotEmpty()) { + $backup->executions() + ->whereIn('id', $localBackupsToDelete->pluck('id')) + ->update(['local_storage_deleted' => true]); + } } - if ($processedBackups->isNotEmpty()) { - $backup->executions()->whereIn('id', $processedBackups->pluck('id'))->delete(); + if ($backup->save_s3 && $backup->executions) { + $s3BackupsToDelete = deleteOldBackupsFromS3($backup); + if ($s3BackupsToDelete->isNotEmpty()) { + $backup->executions() + ->whereIn('id', $s3BackupsToDelete->pluck('id')) + ->update(['s3_storage_deleted' => true]); + } } + + $backup->executions() + ->where('local_storage_deleted', true) + ->where('s3_storage_deleted', true) + ->delete(); + } catch (\Exception $e) { throw $e; } @@ -255,6 +269,7 @@ function deleteOldBackupsLocally($backup): Collection $successfulBackups = $backup->executions() ->where('status', 'success') + ->where('local_storage_deleted', false) ->orderBy('created_at', 'desc') ->get(); @@ -338,6 +353,7 @@ function deleteOldBackupsFromS3($backup): Collection $successfulBackups = $backup->executions() ->where('status', 'success') + ->where('s3_storage_deleted', false) ->orderBy('created_at', 'desc') ->get(); diff --git a/database/migrations/2025_03_14_140150_add_storage_deletion_tracking_to_backup_executions.php b/database/migrations/2025_03_14_140150_add_storage_deletion_tracking_to_backup_executions.php new file mode 100644 index 000000000..c6af6fc49 --- /dev/null +++ b/database/migrations/2025_03_14_140150_add_storage_deletion_tracking_to_backup_executions.php @@ -0,0 +1,19 @@ +boolean('local_storage_deleted')->default(false); + $table->boolean('s3_storage_deleted')->default(false); + }); + } +}; diff --git a/resources/views/livewire/project/database/backup-executions.blade.php b/resources/views/livewire/project/database/backup-executions.blade.php index d13f88e37..6420eb040 100644 --- a/resources/views/livewire/project/database/backup-executions.blade.php +++ b/resources/views/livewire/project/database/backup-executions.blade.php @@ -54,6 +54,49 @@
Location: {{ data_get($execution, 'filename', 'N/A') }}
+
+
+ Backup Availability: +
+ !data_get($execution, 'local_storage_deleted', false), + 'bg-gray-100 text-gray-600 dark:bg-gray-800/50 dark:text-gray-400' => data_get($execution, 'local_storage_deleted', false), + ])> + + @if(!data_get($execution, 'local_storage_deleted', false)) + + + + @else + + + + @endif + Local Storage + + + @if($backup->save_s3) + !data_get($execution, 's3_storage_deleted', false), + 'bg-gray-100 text-gray-600 dark:bg-gray-800/50 dark:text-gray-400' => data_get($execution, 's3_storage_deleted', false), + ])> + + @if(!data_get($execution, 's3_storage_deleted', false)) + + + + @else + + + + @endif + S3 Storage + + + @endif +
@if (data_get($execution, 'message'))
{{ data_get($execution, 'message') }}