Path: blob/1.0-develop/app/Http/Controllers/Api/Remote/Servers/ServerTransferController.php
10284 views
<?php12namespace Pterodactyl\Http\Controllers\Api\Remote\Servers;34use Illuminate\Http\Response;5use Illuminate\Http\JsonResponse;6use Pterodactyl\Models\Allocation;7use Illuminate\Support\Facades\Log;8use Pterodactyl\Models\ServerTransfer;9use Illuminate\Database\ConnectionInterface;10use Pterodactyl\Http\Controllers\Controller;11use Pterodactyl\Repositories\Eloquent\ServerRepository;12use Pterodactyl\Repositories\Wings\DaemonServerRepository;13use Symfony\Component\HttpKernel\Exception\ConflictHttpException;14use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;1516class ServerTransferController extends Controller17{18/**19* ServerTransferController constructor.20*/21public function __construct(22private ConnectionInterface $connection,23private ServerRepository $repository,24private DaemonServerRepository $daemonServerRepository,25) {26}2728/**29* The daemon notifies us about a transfer failure.30*31* @throws \Throwable32*/33public function failure(string $uuid): JsonResponse34{35$server = $this->repository->getByUuid($uuid);36$transfer = $server->transfer;37if (is_null($transfer)) {38throw new ConflictHttpException('Server is not being transferred.');39}4041return $this->processFailedTransfer($transfer);42}4344/**45* The daemon notifies us about a transfer success.46*47* @throws \Throwable48*/49public function success(string $uuid): JsonResponse50{51$server = $this->repository->getByUuid($uuid);52$transfer = $server->transfer;53if (is_null($transfer)) {54throw new ConflictHttpException('Server is not being transferred.');55}5657/** @var \Pterodactyl\Models\Server $server */58$server = $this->connection->transaction(function () use ($server, $transfer) {59$allocations = array_merge([$transfer->old_allocation], $transfer->old_additional_allocations);6061// Remove the old allocations for the server and re-assign the server to the new62// primary allocation and node.63Allocation::query()->whereIn('id', $allocations)->update(['server_id' => null]);64$server->update([65'allocation_id' => $transfer->new_allocation,66'node_id' => $transfer->new_node,67]);6869$server = $server->fresh();70$server->transfer->update(['successful' => true]);7172return $server;73});7475// Delete the server from the old node making sure to point it to the old node so76// that we do not delete it from the new node the server was transferred to.77try {78$this->daemonServerRepository79->setServer($server)80->setNode($transfer->oldNode)81->delete();82} catch (DaemonConnectionException $exception) {83Log::warning($exception, ['transfer_id' => $server->transfer->id]);84}8586return new JsonResponse([], Response::HTTP_NO_CONTENT);87}8889/**90* Release all the reserved allocations for this transfer and mark it as failed in91* the database.92*93* @throws \Throwable94*/95protected function processFailedTransfer(ServerTransfer $transfer): JsonResponse96{97$this->connection->transaction(function () use (&$transfer) {98$transfer->forceFill(['successful' => false])->saveOrFail();99100$allocations = array_merge([$transfer->new_allocation], $transfer->new_additional_allocations);101Allocation::query()->whereIn('id', $allocations)->update(['server_id' => null]);102});103104return new JsonResponse([], Response::HTTP_NO_CONTENT);105}106}107108109