Update logic for tracking a server's transfer state

This commit is contained in:
Matthew Penner 2020-12-16 09:34:47 -07:00
parent 5d03c0d2e5
commit e6c4a68e4a
20 changed files with 206 additions and 74 deletions

View file

@ -117,7 +117,7 @@ class ServerTransferController extends Controller
$this->daemonConfigurationRepository->setNode($node)->getSystemInformation();
// Suspend the server and request an archive to be created.
$this->suspensionService->toggle($server, 'suspend');
//$this->suspensionService->toggle($server, 'suspend');
// Create a new ServerTransfer entry.
$transfer = new ServerTransfer;

View file

@ -120,9 +120,12 @@ class ServerTransferController extends Controller
// Unsuspend the server and don't continue the transfer.
if (! $request->input('successful')) {
$this->suspensionService->toggle($server, 'unsuspend');
//$this->suspensionService->toggle($server, 'unsuspend');
$server->transfer->forceFill([
'successful' => false,
])->saveOrFail();
return JsonResponse::create([], Response::HTTP_NO_CONTENT);
return new JsonResponse([], Response::HTTP_NO_CONTENT);
}
$server->node_id = $server->transfer->new_node;
@ -151,21 +154,23 @@ class ServerTransferController extends Controller
// because setServer() tells the repository to use the server's node and not the one
// we want to specify.
try {
/** @var \Pterodactyl\Models\Node $newNode */
$newNode = $this->nodeRepository->find($server->transfer->new_node);
$this->daemonTransferRepository
->setServer($server)
->setNode($this->nodeRepository->find($server->transfer->new_node))
->setNode($newNode)
->notify($server, $data, $server->node, $token->__toString());
} catch (DaemonConnectionException $exception) {
throw $exception;
}
return JsonResponse::create([], Response::HTTP_NO_CONTENT);
return new JsonResponse([], Response::HTTP_NO_CONTENT);
}
/**
* The daemon notifies us about a transfer failure.
*
* @param \Illuminate\Http\Request $request
* @param string $uuid
* @return \Illuminate\Http\JsonResponse
*
@ -183,9 +188,9 @@ class ServerTransferController extends Controller
$this->allocationRepository->updateWhereIn('id', $allocationIds, ['server_id' => null]);
// Unsuspend the server.
$this->suspensionService->toggle($server, 'unsuspend');
//$this->suspensionService->toggle($server, 'unsuspend');
return JsonResponse::create([], Response::HTTP_NO_CONTENT);
return new JsonResponse([], Response::HTTP_NO_CONTENT);
}
/**
@ -213,11 +218,11 @@ class ServerTransferController extends Controller
// Update the server's allocation_id and node_id.
$server->allocation_id = $transfer->new_allocation;
$server->node_id = $transfer->new_node;
$server->save();
$server->saveOrFail();
// Mark the transfer as successful.
$transfer->successful = true;
$transfer->save();
$transfer->saveOrFail();
// Commit the transaction.
$this->connection->commit();
@ -231,8 +236,8 @@ class ServerTransferController extends Controller
// Unsuspend the server
$server->load('node');
$this->suspensionService->toggle($server, $this->suspensionService::ACTION_UNSUSPEND);
//$this->suspensionService->toggle($server, $this->suspensionService::ACTION_UNSUSPEND);
return JsonResponse::create([], Response::HTTP_NO_CONTENT);
return new JsonResponse([], Response::HTTP_NO_CONTENT);
}
}

View file

@ -112,13 +112,13 @@ class SftpAuthenticationController extends Controller
// Remeber, for security purposes, only reveal the existence of the server to people that
// have provided valid credentials, and have permissions to know about it.
if ($server->installed !== 1 || $server->suspended) {
if ($server->installed !== 1 || $server->suspended || $server->transfer !== null) {
throw new BadRequestHttpException(
'Server is not installed or is currently suspended.'
);
}
return JsonResponse::create([
return new JsonResponse([
'server' => $server->uuid,
// Deprecated, but still needed at the moment for Wings.
'token' => '',

View file

@ -9,7 +9,6 @@ use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
class AuthenticateServerAccess
{
@ -24,7 +23,6 @@ class AuthenticateServerAccess
* @var string[]
*/
protected $except = [
'api:client:server.view',
'api:client:server.ws',
];
@ -65,17 +63,26 @@ class AuthenticateServerAccess
}
}
if ($server->suspended && !$request->routeIs('api:client:server.resources')) {
if ($server->suspended && ! $request->routeIs('api:client:server.resources')) {
throw new BadRequestHttpException(
'This server is currently suspended and the functionality requested is unavailable.'
);
}
if (! $server->isInstalled()) {
// Throw an exception for all server routes; however if the user is an admin and requesting the
// server details, don't throw the exception for them.
if (! $user->root_admin || ($user->root_admin && ! $request->routeIs($this->except))) {
throw new ConflictHttpException('Server has not completed the installation process.');
// Still allow users to get information about there server if it is installing or being transferred.
if (! $request->routeIs('api:client:server.view')) {
if (! $server->isInstalled()) {
// Throw an exception for all server routes; however if the user is an admin and requesting the
// server details, don't throw the exception for them.
if (! $user->root_admin || ($user->root_admin && ! $request->routeIs($this->except))) {
throw new ConflictHttpException('Server has not completed the installation process.');
}
}
if ($server->transfer !== null) {
if (! $user->root_admin || ($user->root_admin && ! $request->routeIs($this->except))) {
throw new ConflictHttpException('Server is currently being transferred.');
}
}
}

View file

@ -80,6 +80,14 @@ class AccessingValidServer
return $this->response->view('errors.installing', [], 409);
}
if ($server->transfer !== null) {
if ($isApiRequest) {
throw new ConflictHttpException('Server is currently being transferred.');
}
return $this->response->view('errors.transferring', [], 409);
}
// Add server to the request attributes. This will replace sessions
// as files are updated.
$request->attributes->set('server', $server);