Merge branch 'develop' into feature/react-admin
This commit is contained in:
commit
a3b59f24af
95 changed files with 2671 additions and 1777 deletions
|
@ -9,6 +9,7 @@ use Illuminate\Database\ConnectionInterface;
|
|||
use Pterodactyl\Extensions\Backups\BackupManager;
|
||||
use Pterodactyl\Repositories\Eloquent\BackupRepository;
|
||||
use Pterodactyl\Repositories\Wings\DaemonBackupRepository;
|
||||
use Pterodactyl\Exceptions\Service\Backup\BackupLockedException;
|
||||
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
|
||||
|
||||
class DeleteBackupService
|
||||
|
@ -55,6 +56,10 @@ class DeleteBackupService
|
|||
*/
|
||||
public function handle(Backup $backup)
|
||||
{
|
||||
if ($backup->is_locked) {
|
||||
throw new BackupLockedException();
|
||||
}
|
||||
|
||||
if ($backup->disk === Backup::ADAPTER_AWS_S3) {
|
||||
$this->deleteFromS3($backup);
|
||||
|
||||
|
|
|
@ -21,6 +21,11 @@ class InitiateBackupService
|
|||
*/
|
||||
private $ignoredFiles;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isLocked = false;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\BackupRepository
|
||||
*/
|
||||
|
@ -49,7 +54,11 @@ class InitiateBackupService
|
|||
/**
|
||||
* InitiateBackupService constructor.
|
||||
*
|
||||
* @param \Pterodactyl\Repositories\Eloquent\BackupRepository $repository
|
||||
* @param \Illuminate\Database\ConnectionInterface $connection
|
||||
* @param \Pterodactyl\Repositories\Wings\DaemonBackupRepository $daemonBackupRepository
|
||||
* @param \Pterodactyl\Services\Backups\DeleteBackupService $deleteBackupService
|
||||
* @param \Pterodactyl\Extensions\Backups\BackupManager $backupManager
|
||||
*/
|
||||
public function __construct(
|
||||
BackupRepository $repository,
|
||||
|
@ -65,6 +74,19 @@ class InitiateBackupService
|
|||
$this->deleteBackupService = $deleteBackupService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if the backup should be locked once it is created which will prevent
|
||||
* its deletion by users or automated system processes.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setIsLocked(bool $isLocked): self
|
||||
{
|
||||
$this->isLocked = $isLocked;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the files to be ignored by this backup.
|
||||
*
|
||||
|
@ -91,7 +113,7 @@ class InitiateBackupService
|
|||
}
|
||||
|
||||
/**
|
||||
* Initiates the backup process for a server on the daemon.
|
||||
* Initiates the backup process for a server on Wings.
|
||||
*
|
||||
* @throws \Throwable
|
||||
* @throws \Pterodactyl\Exceptions\Service\Backup\TooManyBackupsException
|
||||
|
@ -104,23 +126,30 @@ class InitiateBackupService
|
|||
if ($period > 0) {
|
||||
$previous = $this->repository->getBackupsGeneratedDuringTimespan($server->id, $period);
|
||||
if ($previous->count() >= $limit) {
|
||||
throw new TooManyRequestsHttpException(CarbonImmutable::now()->diffInSeconds($previous->last()->created_at->addSeconds($period)), sprintf('Only %d backups may be generated within a %d second span of time.', $limit, $period));
|
||||
$message = sprintf('Only %d backups may be generated within a %d second span of time.', $limit, $period);
|
||||
|
||||
throw new TooManyRequestsHttpException(CarbonImmutable::now()->diffInSeconds($previous->last()->created_at->addSeconds($period)), $message);
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// Check if the server has reached or exceeded it's backup limit.
|
||||
$successful = $server->backups()->where('is_successful', true);
|
||||
if (!$server->backup_limit || $successful->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);
|
||||
}
|
||||
|
||||
// Get the oldest backup the server has.
|
||||
/** @var \Pterodactyl\Models\Backup $oldestBackup */
|
||||
$oldestBackup = $server->backups()->where('is_successful', true)->orderBy('created_at')->first();
|
||||
// Get the oldest backup the server has that is not "locked" (indicating a backup that should
|
||||
// never be automatically purged). If we find a backup we will delete it and then continue with
|
||||
// this process. If no backup is found that can be used an exception is thrown.
|
||||
/** @var \Pterodactyl\Models\Backup $oldest */
|
||||
$oldest = $successful->where('is_locked', false)->orderBy('created_at')->first();
|
||||
if (!$oldest) {
|
||||
throw new TooManyBackupsException($server->backup_limit);
|
||||
}
|
||||
|
||||
// Delete the oldest backup.
|
||||
$this->deleteBackupService->handle($oldestBackup);
|
||||
$this->deleteBackupService->handle($oldest);
|
||||
}
|
||||
|
||||
return $this->connection->transaction(function () use ($server, $name) {
|
||||
|
@ -131,6 +160,7 @@ class InitiateBackupService
|
|||
'name' => trim($name) ?: sprintf('Backup at %s', CarbonImmutable::now()->toDateTimeString()),
|
||||
'ignored_files' => array_values($this->ignoredFiles ?? []),
|
||||
'disk' => $this->backupManager->getDefaultAdapter(),
|
||||
'is_locked' => $this->isLocked,
|
||||
], true, true);
|
||||
|
||||
$this->daemonBackupRepository->setServer($server)
|
||||
|
|
|
@ -83,7 +83,7 @@ class FindViableNodesService
|
|||
*
|
||||
* @throws \Pterodactyl\Exceptions\Service\Deployment\NoViableNodeException
|
||||
*/
|
||||
public function handle(int $page = null)
|
||||
public function handle(int $perPage = null, int $page = null)
|
||||
{
|
||||
Assert::integer($this->disk, 'Disk space must be an int, got %s');
|
||||
Assert::integer($this->memory, 'Memory usage must be an int, got %s');
|
||||
|
@ -103,7 +103,7 @@ class FindViableNodesService
|
|||
->havingRaw('(IFNULL(SUM(servers.disk), 0) + ?) <= (nodes.disk * (1 + (nodes.disk_overallocate / 100)))', [$this->disk]);
|
||||
|
||||
if (!is_null($page)) {
|
||||
$results = $results->paginate(50, ['*'], 'page', $page);
|
||||
$results = $results->paginate($perPage ?? 50, ['*'], 'page', $page);
|
||||
} else {
|
||||
$results = $results->get()->toBase();
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ use Illuminate\Contracts\Bus\Dispatcher;
|
|||
use Pterodactyl\Jobs\Schedule\RunTaskJob;
|
||||
use Illuminate\Database\ConnectionInterface;
|
||||
use Pterodactyl\Exceptions\DisplayException;
|
||||
use Pterodactyl\Repositories\Wings\DaemonServerRepository;
|
||||
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
|
||||
|
||||
class ProcessScheduleService
|
||||
{
|
||||
|
@ -21,13 +23,19 @@ class ProcessScheduleService
|
|||
*/
|
||||
private $connection;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Wings\DaemonServerRepository
|
||||
*/
|
||||
private $serverRepository;
|
||||
|
||||
/**
|
||||
* ProcessScheduleService constructor.
|
||||
*/
|
||||
public function __construct(ConnectionInterface $connection, Dispatcher $dispatcher)
|
||||
public function __construct(ConnectionInterface $connection, DaemonServerRepository $serverRepository, Dispatcher $dispatcher)
|
||||
{
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->connection = $connection;
|
||||
$this->serverRepository = $serverRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,7 +46,7 @@ class ProcessScheduleService
|
|||
public function handle(Schedule $schedule, bool $now = false)
|
||||
{
|
||||
/** @var \Pterodactyl\Models\Task $task */
|
||||
$task = $schedule->tasks()->orderBy('sequence_id', 'asc')->first();
|
||||
$task = $schedule->tasks()->orderBy('sequence_id')->first();
|
||||
|
||||
if (is_null($task)) {
|
||||
throw new DisplayException('Cannot process schedule for task execution: no tasks are registered.');
|
||||
|
@ -53,7 +61,31 @@ class ProcessScheduleService
|
|||
$task->update(['is_queued' => true]);
|
||||
});
|
||||
|
||||
$job = new RunTaskJob($task);
|
||||
$job = new RunTaskJob($task, $now);
|
||||
if ($schedule->only_when_online) {
|
||||
// Check that the server is currently in a starting or running state before executing
|
||||
// this schedule if this option has been set.
|
||||
try {
|
||||
$details = $this->serverRepository->setServer($schedule->server)->getDetails();
|
||||
$state = $details['state'] ?? 'offline';
|
||||
// If the server is stopping or offline just do nothing with this task.
|
||||
if (in_array($state, ['offline', 'stopping'])) {
|
||||
$job->failed();
|
||||
|
||||
return;
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
if (!$exception instanceof DaemonConnectionException) {
|
||||
// If we encountered some exception during this process that wasn't just an
|
||||
// issue connecting to Wings run the failed sequence for a job. Otherwise we
|
||||
// can just quietly mark the task as completed without actually running anything.
|
||||
$job->failed($exception);
|
||||
}
|
||||
$job->failed();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$now) {
|
||||
$this->dispatcher->dispatch($job->delay($task->time_offset));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue