diff --git a/app/Http/Controllers/Api/Client/Servers/BackupController.php b/app/Http/Controllers/Api/Client/Servers/BackupController.php index 1cbecf262..cc8ba0917 100644 --- a/app/Http/Controllers/Api/Client/Servers/BackupController.php +++ b/app/Http/Controllers/Api/Client/Servers/BackupController.php @@ -2,7 +2,6 @@ namespace Pterodactyl\Http\Controllers\Api\Client\Servers; -use Carbon\Carbon; use Pterodactyl\Models\Backup; use Pterodactyl\Models\Server; use Illuminate\Http\JsonResponse; @@ -11,7 +10,6 @@ use Pterodactyl\Repositories\Eloquent\BackupRepository; use Pterodactyl\Services\Backups\InitiateBackupService; use Pterodactyl\Transformers\Api\Client\BackupTransformer; use Pterodactyl\Http\Controllers\Api\Client\ClientApiController; -use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\GetBackupsRequest; use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\StoreBackupRequest; use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\DeleteBackupRequest; @@ -78,14 +76,6 @@ class BackupController extends ClientApiController */ public function store(StoreBackupRequest $request, Server $server) { - $previous = $this->repository->getBackupsGeneratedDuringTimespan($server->id, 10); - if ($previous->count() >= 2) { - throw new TooManyRequestsHttpException( - Carbon::now()->diffInSeconds($previous->last()->created_at->addMinutes(10)), - 'Only two backups may be generated within a 10 minute span of time.' - ); - } - $backup = $this->initiateBackupService ->setIgnoredFiles( explode(PHP_EOL, $request->input('ignored') ?? '') diff --git a/app/Http/Requests/Api/Client/Servers/Schedules/StoreTaskRequest.php b/app/Http/Requests/Api/Client/Servers/Schedules/StoreTaskRequest.php index 86ec50f67..839fe2eac 100644 --- a/app/Http/Requests/Api/Client/Servers/Schedules/StoreTaskRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Schedules/StoreTaskRequest.php @@ -24,9 +24,9 @@ class StoreTaskRequest extends ViewScheduleRequest public function rules(): array { return [ - 'action' => 'required|in:command,power', - 'payload' => 'required|string', - 'time_offset' => 'required|numeric|min:0|max:900', + 'action' => 'required|in:command,power,backup', + 'payload' => 'required_unless:action,backup|string', + 'time_offset' => 'r=equired|numeric|min:0|max:900', 'sequence_id' => 'sometimes|required|numeric|min:1', ]; } diff --git a/app/Jobs/Schedule/RunTaskJob.php b/app/Jobs/Schedule/RunTaskJob.php index bab5b9f68..4f6bfd22f 100644 --- a/app/Jobs/Schedule/RunTaskJob.php +++ b/app/Jobs/Schedule/RunTaskJob.php @@ -12,10 +12,10 @@ use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\DispatchesJobs; use Pterodactyl\Repositories\Eloquent\TaskRepository; +use Pterodactyl\Services\Backups\InitiateBackupService; use Pterodactyl\Repositories\Wings\DaemonPowerRepository; use Pterodactyl\Repositories\Wings\DaemonCommandRepository; use Pterodactyl\Contracts\Repository\TaskRepositoryInterface; -use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService; use Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface; class RunTaskJob extends Job implements ShouldQueue @@ -54,16 +54,16 @@ class RunTaskJob extends Job implements ShouldQueue * Run the job and send actions to the daemon running the server. * * @param \Pterodactyl\Repositories\Wings\DaemonCommandRepository $commandRepository - * @param \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService $keyProviderService + * @param \Pterodactyl\Services\Backups\InitiateBackupService $backupService * @param \Pterodactyl\Repositories\Wings\DaemonPowerRepository $powerRepository * @param \Pterodactyl\Repositories\Eloquent\TaskRepository $taskRepository * * @throws \Pterodactyl\Exceptions\Model\DataValidationException - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException + * @throws \Throwable */ public function handle( DaemonCommandRepository $commandRepository, - DaemonKeyProviderService $keyProviderService, + InitiateBackupService $backupService, DaemonPowerRepository $powerRepository, TaskRepository $taskRepository ) { @@ -88,6 +88,9 @@ class RunTaskJob extends Job implements ShouldQueue case 'command': $commandRepository->setServer($server)->send($task->payload); break; + case 'backup': + $backupService->setIgnoredFiles(explode(PHP_EOL, $task->payload))->handle($server, null); + break; default: throw new InvalidArgumentException('Cannot run a task that points to a non-existent action.'); } diff --git a/app/Services/Backups/InitiateBackupService.php b/app/Services/Backups/InitiateBackupService.php index 24a3203cb..d952c46da 100644 --- a/app/Services/Backups/InitiateBackupService.php +++ b/app/Services/Backups/InitiateBackupService.php @@ -2,6 +2,7 @@ namespace Pterodactyl\Services\Backups; +use Carbon\Carbon; use Ramsey\Uuid\Uuid; use Carbon\CarbonImmutable; use Webmozart\Assert\Assert; @@ -10,6 +11,7 @@ use Pterodactyl\Models\Server; use Illuminate\Database\ConnectionInterface; use Pterodactyl\Repositories\Eloquent\BackupRepository; use Pterodactyl\Repositories\Wings\DaemonBackupRepository; +use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; class InitiateBackupService { @@ -85,6 +87,14 @@ class InitiateBackupService */ public function handle(Server $server, string $name = null): Backup { + $previous = $this->repository->getBackupsGeneratedDuringTimespan($server->id, 10); + if ($previous->count() >= 2) { + throw new TooManyRequestsHttpException( + Carbon::now()->diffInSeconds($previous->last()->created_at->addMinutes(10)), + 'Only two backups may be generated within a 10 minute span of time.' + ); + } + return $this->connection->transaction(function () use ($server, $name) { /** @var \Pterodactyl\Models\Backup $backup */ $backup = $this->repository->create([ diff --git a/resources/scripts/components/server/schedules/TaskDetailsModal.tsx b/resources/scripts/components/server/schedules/TaskDetailsModal.tsx index 53481a144..7c6cdbc7b 100644 --- a/resources/scripts/components/server/schedules/TaskDetailsModal.tsx +++ b/resources/scripts/components/server/schedules/TaskDetailsModal.tsx @@ -36,14 +36,17 @@ const TaskDetailsForm = ({ isEditingTask }: { isEditingTask: boolean }) => { return (