Merge branch 'develop' of https://github.com/Pterodactyl/Panel into develop

This commit is contained in:
Dane Everitt 2020-12-06 10:53:38 -08:00
commit ec7bb22866
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
6 changed files with 27 additions and 11 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

@ -24,7 +24,7 @@ const schema = object().shape({
.matches(/^[A-Za-z0-9_\-.]{3,48}$/, 'Database name should only contain alphanumeric characters, underscores, dashes, and/or periods.'), .matches(/^[A-Za-z0-9_\-.]{3,48}$/, 'Database name should only contain alphanumeric characters, underscores, dashes, and/or periods.'),
connectionsFrom: string() connectionsFrom: string()
.required('A connection value must be provided.') .required('A connection value must be provided.')
.matches(/^([1-9]{1,3}|%)(\.([0-9]{1,3}|%))?(\.([0-9]{1,3}|%))?(\.([0-9]{1,3}|%))?$/, 'A valid connection address must be provided.'), .matches(/^([0-9]{1,3}|%)(\.([0-9]{1,3}|%))?(\.([0-9]{1,3}|%))?(\.([0-9]{1,3}|%))?$/, 'A valid connection address must be provided.'),
}); });
export default () => { export default () => {

View file

@ -131,7 +131,7 @@ export default ({ database, className }: Props) => {
</div> </div>
</Can> </Can>
<div css={tw`mt-6`}> <div css={tw`mt-6`}>
<Label>JBDC Connection String</Label> <Label>JDBC Connection String</Label>
<CopyOnClick text={`jdbc:mysql://${database.username}:${database.password}@${database.connectionString}/${database.name}`}> <CopyOnClick text={`jdbc:mysql://${database.username}:${database.password}@${database.connectionString}/${database.name}`}>
<Input <Input
type={'text'} type={'text'}

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>

View file

@ -51,7 +51,7 @@
<td data-attr="info-system"><i class="fa fa-refresh fa-fw fa-spin"></i></td> <td data-attr="info-system"><i class="fa fa-refresh fa-fw fa-spin"></i></td>
</tr> </tr>
<tr> <tr>
<td>Total CPU Cores</td> <td>Total CPU Threads</td>
<td data-attr="info-cpus"><i class="fa fa-refresh fa-fw fa-spin"></i></td> <td data-attr="info-cpus"><i class="fa fa-refresh fa-fw fa-spin"></i></td>
</tr> </tr>
</table> </table>