Add successful column to server_transfers table, get server transfers working properly :)
This commit is contained in:
parent
6ba6c34252
commit
454ce6ce45
|
@ -55,7 +55,7 @@ class ServerTransferController extends Controller
|
|||
* ServerTransferController constructor.
|
||||
*
|
||||
* @param \Prologue\Alerts\AlertsMessageBag $alert
|
||||
* @param \Pterodactyl\Contracts\Repository\AllocationRepositoryInterface $allocationRepository,
|
||||
* @param \Pterodactyl\Contracts\Repository\AllocationRepositoryInterface $allocationRepository
|
||||
* @param \Pterodactyl\Repositories\Eloquent\ServerRepository $repository
|
||||
* @param \Pterodactyl\Repositories\Eloquent\LocationRepository $locationRepository
|
||||
* @param \Pterodactyl\Repositories\Eloquent\NodeRepository $nodeRepository
|
||||
|
@ -104,9 +104,11 @@ class ServerTransferController extends Controller
|
|||
// Check if the node is viable for the transfer.
|
||||
$node = $this->nodeRepository->getNodeWithResourceUsage($node_id);
|
||||
if ($node->isViable($server->memory, $server->disk)) {
|
||||
//$this->assignAllocationsToServer($server, $node_id, $allocation_id, $additional_allocations);
|
||||
// Suspend the server and request an archive to be created.
|
||||
$this->suspensionService->toggle($server, 'suspend');
|
||||
|
||||
/*$transfer = new ServerTransfer;
|
||||
// Create a new ServerTransfer entry.
|
||||
$transfer = new ServerTransfer;
|
||||
|
||||
$transfer->server_id = $server->id;
|
||||
$transfer->old_node = $server->node_id;
|
||||
|
@ -116,10 +118,12 @@ class ServerTransferController extends Controller
|
|||
$transfer->old_additional_allocations = json_encode($server->allocations->where('id', '!=', $server->allocation_id)->pluck('id'));
|
||||
$transfer->new_additional_allocations = json_encode($additional_allocations);
|
||||
|
||||
$transfer->save();*/
|
||||
$transfer->save();
|
||||
|
||||
// Suspend the server and request an archive to be created.
|
||||
// $this->suspensionService->toggle($server, 'suspend');
|
||||
// Add the allocations to the server so they cannot be automatically assigned while the transfer is in progress.
|
||||
$this->assignAllocationsToServer($server, $node_id, $allocation_id, $additional_allocations);
|
||||
|
||||
// Request an archive from the server's current daemon.
|
||||
$this->transferService->requestArchive($server);
|
||||
|
||||
$this->alert->success(trans('admin/server.alerts.transfer_started'))->flash();
|
||||
|
@ -130,6 +134,14 @@ class ServerTransferController extends Controller
|
|||
return redirect()->route('admin.servers.view.manage', $server->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the specified allocations to the specified server.
|
||||
*
|
||||
* @param Server $server
|
||||
* @param int $node_id
|
||||
* @param int $allocation_id
|
||||
* @param array $additional_allocations
|
||||
*/
|
||||
private function assignAllocationsToServer(Server $server, int $node_id, int $allocation_id, array $additional_allocations)
|
||||
{
|
||||
$allocations = $additional_allocations;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace Pterodactyl\Http\Controllers\Api\Remote\Servers;
|
||||
|
||||
use Cake\Chronos\Chronos;
|
||||
use Illuminate\Database\ConnectionInterface;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
|
@ -10,19 +11,32 @@ use Illuminate\Support\Facades\Log;
|
|||
use Lcobucci\JWT\Builder;
|
||||
use Lcobucci\JWT\Signer\Hmac\Sha256;
|
||||
use Lcobucci\JWT\Signer\Key;
|
||||
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
|
||||
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||
use Pterodactyl\Repositories\Eloquent\NodeRepository;
|
||||
use Pterodactyl\Repositories\Wings\DaemonTransferRepository;
|
||||
use Pterodactyl\Services\Servers\ServerConfigurationStructureService;
|
||||
use Pterodactyl\Services\Servers\SuspensionService;
|
||||
|
||||
class ServerTransferController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Database\ConnectionInterface
|
||||
*/
|
||||
private $connection;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\AllocationRepositoryInterface
|
||||
*/
|
||||
private $allocationRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\NodeRepository
|
||||
*/
|
||||
|
@ -33,21 +47,43 @@ class ServerTransferController extends Controller
|
|||
*/
|
||||
private $daemonTransferRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\ServerConfigurationStructureService
|
||||
*/
|
||||
private $configurationStructureService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\SuspensionService
|
||||
*/
|
||||
private $suspensionService;
|
||||
|
||||
/**
|
||||
* ServerTransferController constructor.
|
||||
*
|
||||
* @param \Illuminate\Database\ConnectionInterface $connection
|
||||
* @param \Pterodactyl\Repositories\Eloquent\ServerRepository $repository
|
||||
* @param \Pterodactyl\Contracts\Repository\AllocationRepositoryInterface $allocationRepository
|
||||
* @param \Pterodactyl\Repositories\Eloquent\NodeRepository $nodeRepository
|
||||
* @param DaemonTransferRepository $daemonTransferRepository
|
||||
* @param \Pterodactyl\Repositories\Wings\DaemonTransferRepository $daemonTransferRepository
|
||||
* @param \Pterodactyl\Services\Servers\ServerConfigurationStructureService $configurationStructureService
|
||||
* @param \Pterodactyl\Services\Servers\SuspensionService $suspensionService
|
||||
*/
|
||||
public function __construct(
|
||||
ConnectionInterface $connection,
|
||||
ServerRepository $repository,
|
||||
AllocationRepositoryInterface $allocationRepository,
|
||||
NodeRepository $nodeRepository,
|
||||
DaemonTransferRepository $daemonTransferRepository
|
||||
DaemonTransferRepository $daemonTransferRepository,
|
||||
ServerConfigurationStructureService $configurationStructureService,
|
||||
SuspensionService $suspensionService
|
||||
) {
|
||||
$this->connection = $connection;
|
||||
$this->repository = $repository;
|
||||
$this->allocationRepository = $allocationRepository;
|
||||
$this->nodeRepository = $nodeRepository;
|
||||
$this->daemonTransferRepository = $daemonTransferRepository;
|
||||
$this->configurationStructureService = $configurationStructureService;
|
||||
$this->suspensionService = $suspensionService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,6 +95,7 @@ class ServerTransferController extends Controller
|
|||
*
|
||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function archive(Request $request, string $uuid)
|
||||
{
|
||||
|
@ -66,10 +103,20 @@ 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');
|
||||
return JsonResponse::create([], Response::HTTP_NO_CONTENT);
|
||||
}
|
||||
|
||||
$server->node_id = $server->transfer->new_node;
|
||||
|
||||
$data = $this->configurationStructureService->handle($server);
|
||||
$data['suspended'] = false;
|
||||
$data['service']['skip_scripts'] = true;
|
||||
|
||||
$allocations = $server->getAllocationMappings();
|
||||
$data['allocations']['default']['ip'] = array_key_first($allocations);
|
||||
$data['allocations']['default']['port'] = $allocations[$data['allocations']['default']['ip']][0];
|
||||
|
||||
$now = Chronos::now();
|
||||
$signer = new Sha256;
|
||||
|
||||
|
@ -85,10 +132,92 @@ class ServerTransferController extends Controller
|
|||
// On the daemon transfer repository, make sure to set the node after the server
|
||||
// because setServer() tells the repository to use the server's node and not the one
|
||||
// we want to specify.
|
||||
$this->daemonTransferRepository
|
||||
->setServer($server)
|
||||
->setNode($this->nodeRepository->find($server->transfer->new_node))
|
||||
->notify($server, $server->node, $token->__toString());
|
||||
try {
|
||||
$this->daemonTransferRepository
|
||||
->setServer($server)
|
||||
->setNode($this->nodeRepository->find($server->transfer->new_node))
|
||||
->notify($server, $data, $server->node, $token->__toString());
|
||||
} catch (DaemonConnectionException $exception) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
return JsonResponse::create([], Response::HTTP_NO_CONTENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* The daemon notifies us about a transfer failure.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $uuid
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function failure(string $uuid)
|
||||
{
|
||||
$server = $this->repository->getByUuid($uuid);
|
||||
$transfer = $server->transfer;
|
||||
|
||||
$allocationIds = json_decode($transfer->new_additional_allocations);
|
||||
array_push($allocationIds, $transfer->new_allocation);
|
||||
|
||||
// Begin a transaction.
|
||||
$this->connection->beginTransaction();
|
||||
|
||||
// Remove the new allocations.
|
||||
$this->allocationRepository->updateWhereIn('id', $allocationIds, ['server_id' => null]);
|
||||
|
||||
// Commit the transaction.
|
||||
$this->connection->commit();
|
||||
|
||||
// Unsuspend the server.
|
||||
$this->suspensionService->toggle($server, 'unsuspend');
|
||||
|
||||
return JsonResponse::create([], Response::HTTP_NO_CONTENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* The daemon notifies us about a transfer success.
|
||||
*
|
||||
* @param string $uuid
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function success(string $uuid)
|
||||
{
|
||||
$server = $this->repository->getByUuid($uuid);
|
||||
$transfer = $server->transfer;
|
||||
|
||||
// TODO: Notify old daemon about transfer and get it to remove server files.
|
||||
|
||||
$allocationIds = json_decode($transfer->old_additional_allocations);
|
||||
array_push($allocationIds, $transfer->old_allocation);
|
||||
|
||||
// Begin a transaction.
|
||||
$this->connection->beginTransaction();
|
||||
|
||||
// Remove the old allocations.
|
||||
$this->allocationRepository->updateWhereIn('id', $allocationIds, ['server_id' => null]);
|
||||
|
||||
// Update the server's allocation_id and node_id.
|
||||
$server->allocation_id = $transfer->new_allocation;
|
||||
$server->node_id = $transfer->new_node;
|
||||
$server->save();
|
||||
|
||||
// Mark the transfer as successful.
|
||||
$transfer->successful = true;
|
||||
$transfer->save();
|
||||
|
||||
// Commit the transaction.
|
||||
$this->connection->commit();
|
||||
|
||||
// Unsuspend the server
|
||||
$server->load('node');
|
||||
Log::debug(json_encode($server));
|
||||
Log::debug(json_encode($server->node_id));
|
||||
Log::debug(json_encode($server->node));
|
||||
$this->suspensionService->toggle($server, $this->suspensionService::ACTION_UNSUSPEND);
|
||||
|
||||
return JsonResponse::create([], Response::HTTP_NO_CONTENT);
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ class Server extends Validable
|
|||
*/
|
||||
public function getAllocationMappings(): array
|
||||
{
|
||||
return $this->allocations->groupBy('ip')->map(function ($item) {
|
||||
return $this->allocations->where('node_id', $this->node_id)->groupBy('ip')->map(function ($item) {
|
||||
return $item->pluck('port');
|
||||
})->toArray();
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace Pterodactyl\Models;
|
|||
* @property int $new_allocation
|
||||
* @property string $old_additional_allocations
|
||||
* @property string $new_additional_allocations
|
||||
* @property bool $successful
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
*
|
||||
|
@ -51,6 +52,7 @@ class ServerTransfer extends Validable
|
|||
'new_allocation' => 'int',
|
||||
'old_additional_allocations' => 'string',
|
||||
'new_additional_allocations' => 'string',
|
||||
'successful' => 'bool',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -64,10 +66,11 @@ class ServerTransfer extends Validable
|
|||
'new_allocation' => 'required|numeric',
|
||||
'old_additional_allocations' => 'nullable',
|
||||
'new_additional_allocations' => 'nullable',
|
||||
'successful' => 'sometimes|boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* Gets the server associated with a subuser.
|
||||
* Gets the server associated with a server transfer.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
|
|
|
@ -11,18 +11,20 @@ class DaemonTransferRepository extends DaemonRepository
|
|||
{
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param array $data
|
||||
* @param Node $node
|
||||
* @param string $token
|
||||
*
|
||||
* @throws DaemonConnectionException
|
||||
*/
|
||||
public function notify(Server $server, Node $node, string $token): void {
|
||||
public function notify(Server $server, array $data, Node $node, string $token): void {
|
||||
try {
|
||||
$this->getHttpClient()->post('/api/transfer', [
|
||||
'json' => [
|
||||
'server_id' => $server->uuid,
|
||||
'url' => $node->getConnectionAddress() . sprintf('/api/servers/%s/archive', $server->uuid),
|
||||
'token' => 'Bearer ' . $token,
|
||||
'server' => $data,
|
||||
],
|
||||
]);
|
||||
} catch(TransferException $exception) {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Pterodactyl\Services\Servers;
|
||||
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Webmozart\Assert\Assert;
|
||||
use Pterodactyl\Models\Server;
|
||||
|
@ -73,10 +74,14 @@ class SuspensionService
|
|||
return;
|
||||
}
|
||||
|
||||
Log::debug('SuspensionService: ' . $action);
|
||||
|
||||
$this->connection->transaction(function () use ($action, $server) {
|
||||
$this->repository->withoutFreshModel()->update($server->id, [
|
||||
'suspended' => $action === self::ACTION_SUSPEND,
|
||||
]);
|
||||
Log::debug('Server suspended: ' . ($action === self::ACTION_SUSPEND) ? 'true' : 'false');
|
||||
Log::debug('Daemon unsuspended: ' . ($action === self::ACTION_UNSUSPEND) ? 'true' : 'false');
|
||||
|
||||
$this->daemonServerRepository->setServer($server)->suspend($action === self::ACTION_UNSUSPEND);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddSuccessfulColumnToServerTransfers extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('server_transfers', function (Blueprint $table) {
|
||||
$table->tinyInteger('successful')->unsigned()->default(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('server_transfers', function (Blueprint $table) {
|
||||
$table->dropColumn('successful');
|
||||
});
|
||||
}
|
||||
}
|
|
@ -12,6 +12,8 @@ Route::group(['prefix' => '/servers/{uuid}'], function () {
|
|||
Route::get('/install', 'Servers\ServerInstallController@index');
|
||||
Route::post('/install', 'Servers\ServerInstallController@store');
|
||||
Route::post('/archive', 'Servers\ServerTransferController@archive');
|
||||
Route::get('/transfer/failure', 'Servers\ServerTransferController@failure');
|
||||
Route::get('/transfer/success', 'Servers\ServerTransferController@success');
|
||||
});
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue