Merge pull request #2691 from GravityCube/develop

Backup rotation for schedules.
This commit is contained in:
Dane Everitt 2020-11-29 13:42:48 -08:00 committed by GitHub
commit 9a1c9f3e46
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 8 deletions

View file

@ -69,7 +69,7 @@ class RunTaskJob extends Job implements ShouldQueue
$commandRepository->setServer($server)->send($this->task->payload); $commandRepository->setServer($server)->send($this->task->payload);
break; break;
case 'backup': case 'backup':
$backupService->setIgnoredFiles(explode(PHP_EOL, $this->task->payload))->handle($server, null); $backupService->setIgnoredFiles(explode(PHP_EOL, $this->task->payload))->handle($server, null, true);
break; break;
default: default:
throw new InvalidArgumentException('Cannot run a task that points to a non-existent action.'); throw new InvalidArgumentException('Cannot run a task that points to a non-existent action.');

View file

@ -13,6 +13,7 @@ use Pterodactyl\Repositories\Eloquent\BackupRepository;
use Pterodactyl\Repositories\Wings\DaemonBackupRepository; use Pterodactyl\Repositories\Wings\DaemonBackupRepository;
use Pterodactyl\Exceptions\Service\Backup\TooManyBackupsException; use Pterodactyl\Exceptions\Service\Backup\TooManyBackupsException;
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
use Pterodactyl\Services\Backups\DeleteBackupService;
class InitiateBackupService class InitiateBackupService
{ {
@ -41,24 +42,32 @@ class InitiateBackupService
*/ */
private $backupManager; private $backupManager;
/**
* @var \Pterodactyl\Services\Backups\DeleteBackupService
*/
private $deleteBackupService;
/** /**
* InitiateBackupService constructor. * InitiateBackupService constructor.
* *
* @param \Pterodactyl\Repositories\Eloquent\BackupRepository $repository * @param \Pterodactyl\Repositories\Eloquent\BackupRepository $repository
* @param \Illuminate\Database\ConnectionInterface $connection * @param \Illuminate\Database\ConnectionInterface $connection
* @param \Pterodactyl\Repositories\Wings\DaemonBackupRepository $daemonBackupRepository * @param \Pterodactyl\Repositories\Wings\DaemonBackupRepository $daemonBackupRepository
* @param \Pterodactyl\Services\Backups\DeleteBackupService $deleteBackupService
* @param \Pterodactyl\Extensions\Backups\BackupManager $backupManager * @param \Pterodactyl\Extensions\Backups\BackupManager $backupManager
*/ */
public function __construct( public function __construct(
BackupRepository $repository, BackupRepository $repository,
ConnectionInterface $connection, ConnectionInterface $connection,
DaemonBackupRepository $daemonBackupRepository, DaemonBackupRepository $daemonBackupRepository,
DeleteBackupService $deleteBackupService,
BackupManager $backupManager BackupManager $backupManager
) { ) {
$this->repository = $repository; $this->repository = $repository;
$this->connection = $connection; $this->connection = $connection;
$this->daemonBackupRepository = $daemonBackupRepository; $this->daemonBackupRepository = $daemonBackupRepository;
$this->backupManager = $backupManager; $this->backupManager = $backupManager;
$this->deleteBackupService = $deleteBackupService;
} }
/** /**
@ -96,13 +105,8 @@ class InitiateBackupService
* @throws \Pterodactyl\Exceptions\Service\Backup\TooManyBackupsException * @throws \Pterodactyl\Exceptions\Service\Backup\TooManyBackupsException
* @throws \Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException * @throws \Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException
*/ */
public function handle(Server $server, string $name = null): Backup public function handle(Server $server, string $name = null, bool $override = false): Backup
{ {
// Do not allow the user to continue if this server is already at its limit.
if (! $server->backup_limit || $server->backups()->where('is_successful', true)->count() >= $server->backup_limit) {
throw new TooManyBackupsException($server->backup_limit);
}
$previous = $this->repository->getBackupsGeneratedDuringTimespan($server->id, 10); $previous = $this->repository->getBackupsGeneratedDuringTimespan($server->id, 10);
if ($previous->count() >= 2) { if ($previous->count() >= 2) {
throw new TooManyRequestsHttpException( throw new TooManyRequestsHttpException(
@ -111,6 +115,18 @@ class InitiateBackupService
); );
} }
// Check if the server has reached or exceeded it's backup limit
if (!$server->backup_limit || $server->backups()->where('is_successful', true)->count() >= $server->backup_limit) {
// Do not allow the user to continue if this server is already at its limit and can't override.
if (!$override || $server->backup_limit <= 0) {
throw new TooManyBackupsException($server->backup_limit);
}
// Remove oldest backup
$oldestBackup = $server->backups()->where('is_successful', true)->orderByDesc('created_at')->first();
$this->deleteBackupService->handle($oldestBackup);
}
return $this->connection->transaction(function () use ($server, $name) { return $this->connection->transaction(function () use ($server, $name) {
/** @var \Pterodactyl\Models\Backup $backup */ /** @var \Pterodactyl\Models\Backup $backup */
$backup = $this->repository->create([ $backup = $this->repository->create([

View file

@ -91,7 +91,7 @@ const TaskDetailsForm = ({ isEditingTask }: { isEditingTask: boolean }) => {
<Label>Ignored Files</Label> <Label>Ignored Files</Label>
<FormikFieldWrapper <FormikFieldWrapper
name={'payload'} name={'payload'}
description={'Optional. Include the files and folders to be excluded in this backup. By default, the contents of your .pteroignore file will be used.'} description={'Optional. Include the files and folders to be excluded in this backup. By default, the contents of your .pteroignore file will be used. If you have reached your backup limit, the oldest backup will be rotated.'}
> >
<FormikField as={Textarea} name={'payload'} rows={6} /> <FormikField as={Textarea} name={'payload'} rows={6} />
</FormikFieldWrapper> </FormikFieldWrapper>