Path: blob/1.0-develop/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php
10287 views
<?php12namespace Pterodactyl\Http\Controllers\Api\Remote\Servers;34use Illuminate\Http\Request;5use Pterodactyl\Models\Server;6use Illuminate\Http\JsonResponse;7use Pterodactyl\Facades\Activity;8use Illuminate\Database\ConnectionInterface;9use Pterodactyl\Http\Controllers\Controller;10use Pterodactyl\Services\Eggs\EggConfigurationService;11use Pterodactyl\Repositories\Eloquent\ServerRepository;12use Pterodactyl\Http\Resources\Wings\ServerConfigurationCollection;13use Pterodactyl\Services\Servers\ServerConfigurationStructureService;1415class ServerDetailsController extends Controller16{17/**18* ServerConfigurationController constructor.19*/20public function __construct(21protected ConnectionInterface $connection,22private ServerRepository $repository,23private ServerConfigurationStructureService $configurationStructureService,24private EggConfigurationService $eggConfigurationService,25) {26}2728/**29* Returns details about the server that allows Wings to self-recover and ensure30* that the state of the server matches the Panel at all times.31*32* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException33*/34public function __invoke(Request $request, string $uuid): JsonResponse35{36$server = $this->repository->getByUuid($uuid);3738return new JsonResponse([39'settings' => $this->configurationStructureService->handle($server),40'process_configuration' => $this->eggConfigurationService->handle($server),41]);42}4344/**45* Lists all servers with their configurations that are assigned to the requesting node.46*/47public function list(Request $request): ServerConfigurationCollection48{49/** @var \Pterodactyl\Models\Node $node */50$node = $request->attributes->get('node');5152// Avoid run-away N+1 SQL queries by preloading the relationships that are used53// within each of the services called below.54$servers = Server::query()->with('allocations', 'egg', 'mounts', 'variables', 'location')55->where('node_id', $node->id)56// If you don't cast this to a string you'll end up with a stringified per_page returned in57// the metadata, and then Wings will panic crash as a result.58->paginate((int) $request->input('per_page', 50));5960return new ServerConfigurationCollection($servers);61}6263/**64* Resets the state of all servers on the node to be normal. This is triggered65* when Wings restarts and is useful for ensuring that any servers on the node66* do not get incorrectly stuck in installing/restoring from backup states since67* a Wings reboot would completely stop those processes.68*69* @throws \Throwable70*/71public function resetState(Request $request): JsonResponse72{73$node = $request->attributes->get('node');7475// Get all the servers that are currently marked as restoring from a backup76// on this node that do not have a failed backup tracked in the audit logs table77// as well.78//79// For each of those servers we'll track a new audit log entry to mark them as80// failed and then update them all to be in a valid state.81$servers = Server::query()82->with([83'activity' => fn ($builder) => $builder84->where('activity_logs.event', 'server:backup.restore-started')85->latest('timestamp'),86])87->where('node_id', $node->id)88->where('status', Server::STATUS_RESTORING_BACKUP)89->get();9091$this->connection->transaction(function () use ($node, $servers) {92/** @var Server $server */93foreach ($servers as $server) {94/** @var \Pterodactyl\Models\ActivityLog|null $activity */95$activity = $server->activity->first();96if (!is_null($activity)) {97if ($subject = $activity->subjects->where('subject_type', 'backup')->first()) {98// Just create a new audit entry for this event and update the server state99// so that power actions, file management, and backups can resume as normal.100Activity::event('server:backup.restore-failed')101->subject($server, $subject->subject)102->property('name', $subject->subject->name) // @phpstan-ignore property.notFound103->log();104}105}106}107108// Update any server marked as installing or restoring as being in a normal state109// at this point in the process.110Server::query()->where('node_id', $node->id)111->whereIn('status', [Server::STATUS_INSTALLING, Server::STATUS_RESTORING_BACKUP])112->update(['status' => null]);113});114115return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);116}117}118119120