diff --git a/app/Console/Commands/Maintenance/PruneOrphanedBackupsCommand.php b/app/Console/Commands/Maintenance/PruneOrphanedBackupsCommand.php new file mode 100644 index 000000000..d1dbb0336 --- /dev/null +++ b/app/Console/Commands/Maintenance/PruneOrphanedBackupsCommand.php @@ -0,0 +1,47 @@ +option('since-minutes'); + if (!is_digit($since)) { + throw new InvalidArgumentException('The --since-minutes option must be a valid numeric digit.'); + } + + $query = $repository->getBuilder() + ->whereNull('completed_at') + ->whereDate('created_at', '<=', CarbonImmutable::now()->subMinutes($since)); + + $count = $query->count(); + if (!$count) { + $this->info('There are no orphaned backups to be removed.'); + + return; + } + + $this->warn("Deleting {$count} backups that have not been marked as completed in the last {$since} minutes."); + + $query->delete(); + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index c87cd5394..1f83ddf93 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -22,7 +22,16 @@ class Kernel extends ConsoleKernel */ protected function schedule(Schedule $schedule) { + // Execute scheduled commands for servers every minute, as if there was a normal cron running. $schedule->command('p:schedule:process')->everyMinute()->withoutOverlapping(); + + // Every 30 minutes, run the backup pruning command so that any abandoned backups can be removed + // from the UI view for the server. + $schedule->command('p:maintenance:prune-backups', [ + '--since-minutes' => '30', + ])->everyThirtyMinutes(); + + // Every day cleanup any internal backups of service files. $schedule->command('p:maintenance:clean-service-backups')->daily(); } }