Get to the point where we can start notifying the other daemon, remove TransferJob.php, add DaemonTransferRepository.php
This commit is contained in:
parent
a2eab3ca43
commit
5007ce0b1c
8 changed files with 172 additions and 115 deletions
|
@ -6,11 +6,12 @@ use Illuminate\Bus\Dispatcher;
|
|||
use Illuminate\Http\Request;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Jobs\Server\TransferJob;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||
use Pterodactyl\Repositories\Eloquent\LocationRepository;
|
||||
use Pterodactyl\Repositories\Eloquent\NodeRepository;
|
||||
use Pterodactyl\Services\Servers\SuspensionService;
|
||||
use Pterodactyl\Services\Servers\TransferService;
|
||||
|
||||
class ServerTransferController extends Controller
|
||||
{
|
||||
|
@ -39,6 +40,16 @@ class ServerTransferController extends Controller
|
|||
*/
|
||||
private $nodeRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\SuspensionService
|
||||
*/
|
||||
private $suspensionService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\TransferService
|
||||
*/
|
||||
private $transferService;
|
||||
|
||||
/**
|
||||
* ServerTransferController constructor.
|
||||
*
|
||||
|
@ -47,19 +58,25 @@ class ServerTransferController extends Controller
|
|||
* @param \Pterodactyl\Repositories\Eloquent\ServerRepository $repository
|
||||
* @param \Pterodactyl\Repositories\Eloquent\LocationRepository $locationRepository
|
||||
* @param \Pterodactyl\Repositories\Eloquent\NodeRepository $nodeRepository
|
||||
* @param \Pterodactyl\Services\Servers\SuspensionService $suspensionService
|
||||
* @param \Pterodactyl\Services\Servers\TransferService $transferService
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
Dispatcher $dispatcher,
|
||||
ServerRepository $repository,
|
||||
LocationRepository $locationRepository,
|
||||
NodeRepository $nodeRepository
|
||||
NodeRepository $nodeRepository,
|
||||
SuspensionService $suspensionService,
|
||||
TransferService $transferService
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->repository = $repository;
|
||||
$this->locationRepository = $locationRepository;
|
||||
$this->nodeRepository = $nodeRepository;
|
||||
$this->suspensionService = $suspensionService;
|
||||
$this->transferService = $transferService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,6 +85,8 @@ class ServerTransferController extends Controller
|
|||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Pterodactyl\Models\Server $server
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function transfer(Request $request, Server $server)
|
||||
{
|
||||
|
@ -84,8 +103,9 @@ 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)) {
|
||||
// TODO: Run TransferJob.
|
||||
$this->dispatcher->dispatch(new TransferJob($server, $node, $allocation_id, $additional_allocations));
|
||||
// Suspend the server and request an archive to be created.
|
||||
// $this->suspensionService->toggle($server, 'suspend');
|
||||
$this->transferService->requestArchive($server);
|
||||
|
||||
$this->alert->success(trans('admin/server.alerts.transfer_started'))->flash();
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Api\Remote\Servers;
|
||||
|
||||
use Cake\Chronos\Chronos;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Lcobucci\JWT\Builder;
|
||||
use Lcobucci\JWT\Signer\Hmac\Sha256;
|
||||
use Lcobucci\JWT\Signer\Key;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||
use Pterodactyl\Repositories\Eloquent\NodeRepository;
|
||||
use Pterodactyl\Repositories\Wings\DaemonTransferRepository;
|
||||
|
||||
class ServerTransferController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\NodeRepository
|
||||
*/
|
||||
private $nodeRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Wings\DaemonTransferRepository
|
||||
*/
|
||||
private $daemonTransferRepository;
|
||||
|
||||
/**
|
||||
* ServerTransferController constructor.
|
||||
*
|
||||
* @param \Pterodactyl\Repositories\Eloquent\ServerRepository $repository
|
||||
* @param \Pterodactyl\Repositories\Eloquent\NodeRepository $nodeRepository
|
||||
* @param DaemonTransferRepository $daemonTransferRepository
|
||||
*/
|
||||
public function __construct(
|
||||
ServerRepository $repository,
|
||||
NodeRepository $nodeRepository,
|
||||
DaemonTransferRepository $daemonTransferRepository
|
||||
) {
|
||||
$this->repository = $repository;
|
||||
$this->nodeRepository = $nodeRepository;
|
||||
$this->daemonTransferRepository = $daemonTransferRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* The daemon notifies us about the archive status.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Pterodactyl\Models\Server $server
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||
*/
|
||||
public function archive(Request $request, Server $server)
|
||||
{
|
||||
// Unsuspend the server and don't continue the transfer.
|
||||
if (!$request->input('successful')) {
|
||||
// $this->suspensionService->toggle($server, 'unsuspend');
|
||||
return JsonResponse::create([], Response::HTTP_NO_CONTENT);
|
||||
}
|
||||
|
||||
$now = Chronos::now();
|
||||
$signer = new Sha256;
|
||||
|
||||
$token = (new Builder)->issuedBy(config('app.url'))
|
||||
->permittedFor($server->node->getConnectionAddress())
|
||||
->identifiedBy(hash('sha256', $server->uuid), true)
|
||||
->issuedAt($now->getTimestamp())
|
||||
->canOnlyBeUsedAfter($now->getTimestamp())
|
||||
->expiresAt($now->addMinutes(15)->getTimestamp())
|
||||
->relatedTo($server->id, true)
|
||||
->getToken($signer, new Key($server->node->daemonSecret));
|
||||
|
||||
$this->daemonTransferRepository->notify($server, $token->__toString());
|
||||
|
||||
return JsonResponse::create([], Response::HTTP_NO_CONTENT);
|
||||
}
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Jobs\Server;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Pterodactyl\Models\Node;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Services\Servers\ServerCreationService;
|
||||
use Pterodactyl\Services\Servers\ServerDeletionService;
|
||||
use Pterodactyl\Services\Servers\SuspensionService;
|
||||
use Pterodactyl\Services\Servers\TransferService;
|
||||
|
||||
class TransferJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
private $server, $node, $allocation_id, $additional_allocations;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param Server $serverToTransfer
|
||||
* @param Node $newNode
|
||||
*/
|
||||
public function __construct(Server $serverToTransfer, Node $newNode, int $allocation_id, array $additional_allocations)
|
||||
{
|
||||
$this->server = $serverToTransfer;
|
||||
$this->node = $newNode;
|
||||
$this->allocation_id = $allocation_id;
|
||||
$this->additional_allocations = $additional_allocations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @param ServerCreationService $creationService
|
||||
* @param ServerDeletionService $deletionService
|
||||
* @param SuspensionService $suspensionService
|
||||
* @param TransferService $transferService
|
||||
* @return void
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function handle(
|
||||
ServerCreationService $creationService,
|
||||
ServerDeletionService $deletionService,
|
||||
SuspensionService $suspensionService,
|
||||
TransferService $transferService
|
||||
) {
|
||||
//$server = $this->server;
|
||||
//$newNode = $this->node;
|
||||
|
||||
// 1. Suspend Old Server
|
||||
//$suspensionService->toggle($server, 'suspend');
|
||||
|
||||
// 2. Zip Folder
|
||||
//$backup = $server->generateBackup();
|
||||
|
||||
// 3. Transfer Zip File
|
||||
//$archive = $newNode->transfer($backup);
|
||||
|
||||
// 4. Verify File Hash
|
||||
/*if ($backup->hash !== $archive->hash) {
|
||||
$archive->delete();
|
||||
abort(500, 'File transfer corrupted, please try again.');
|
||||
}*/
|
||||
|
||||
// 5. Unzip File
|
||||
//$archive->extract();
|
||||
|
||||
// 6. Update Settings on New Node
|
||||
//$newServerDetails = $server->toArray();
|
||||
//$newServerDetails['node_id'] = $newNode->id;
|
||||
//$newServer = $creationService->create($newServerDetails);
|
||||
|
||||
// 7. Verify Server Status
|
||||
/*if (!$newServer->isWorking()) {
|
||||
$deletionService->withForce()->handle($newServer);
|
||||
abort(500, 'Server failed to startup, please try again.');
|
||||
}*/
|
||||
|
||||
// 8. Unsuspend Old Server
|
||||
//$deletionService->withForce()->handle($server);
|
||||
//$suspensionService->toggle($server, 'unsuspend');
|
||||
}
|
||||
}
|
|
@ -170,6 +170,7 @@ class Node extends Validable
|
|||
],
|
||||
'system' => [
|
||||
'data' => $this->daemonBase,
|
||||
'archive_directory' => $this->daemonBase . '/.archives',
|
||||
'username' => 'pterodactyl',
|
||||
'timezone_path' => '/etc/timezone',
|
||||
'set_permissions_on_boot' => true,
|
||||
|
|
|
@ -124,4 +124,24 @@ class DaemonServerRepository extends DaemonRepository
|
|||
throw new DaemonConnectionException($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the daemon to create a full archive of the server.
|
||||
* Once the daemon is finished they will send a POST request to
|
||||
* "/api/remote/servers/{uuid}/archive" with a boolean.
|
||||
*
|
||||
* @throws DaemonConnectionException
|
||||
*/
|
||||
public function requestArchive(): void
|
||||
{
|
||||
Assert::isInstanceOf($this->server, Server::class);
|
||||
|
||||
try {
|
||||
$this->getHttpClient()->post(sprintf(
|
||||
'/api/servers/%s/archive', $this->server->uuid
|
||||
));
|
||||
} catch (TransferException $exception) {
|
||||
throw new DaemonConnectionException($exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
31
app/Repositories/Wings/DaemonTransferRepository.php
Normal file
31
app/Repositories/Wings/DaemonTransferRepository.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Repositories\Wings;
|
||||
|
||||
use Pterodactyl\Models\Server;
|
||||
use GuzzleHttp\Exception\TransferException;
|
||||
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
|
||||
|
||||
class DaemonTransferRepository extends DaemonRepository
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param string $token
|
||||
*
|
||||
* @throws DaemonConnectionException
|
||||
*/
|
||||
public function notify(Server $server, string $token): void
|
||||
{
|
||||
try {
|
||||
$this->getHttpClient()->post('/api/transfer', [
|
||||
'json' => [
|
||||
'url' => $server->node->getConnectionAddress() . sprintf('/api/servers/%s/archive', $server->uuid),
|
||||
'token' => $token,
|
||||
],
|
||||
]);
|
||||
} catch (TransferException $exception) {
|
||||
throw new DaemonConnectionException($exception);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,12 +10,6 @@ use Pterodactyl\Repositories\Wings\DaemonServerRepository;
|
|||
|
||||
class TransferService
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Database\ConnectionInterface
|
||||
*/
|
||||
private $connection;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
||||
*/
|
||||
|
@ -26,33 +20,29 @@ class TransferService
|
|||
*/
|
||||
private $daemonServerRepository;
|
||||
|
||||
/**
|
||||
* @var \Psr\Log\LoggerInterface
|
||||
*/
|
||||
private $writer;
|
||||
|
||||
/**
|
||||
* TransferService constructor.
|
||||
*
|
||||
* @param \Illuminate\Database\ConnectionInterface $connection
|
||||
* @param \Pterodactyl\Repositories\Wings\DaemonServerRepository $daemonServerRepository
|
||||
* @param \Pterodactyl\Contracts\Repository\ServerRepositoryInterface $repository
|
||||
* @param \Psr\Log\LoggerInterface $writer
|
||||
*/
|
||||
public function __construct(
|
||||
ConnectionInterface $connection,
|
||||
DaemonServerRepository $daemonServerRepository,
|
||||
ServerRepositoryInterface $repository,
|
||||
LoggerInterface $writer
|
||||
ServerRepositoryInterface $repository
|
||||
) {
|
||||
$this->connection = $connection;
|
||||
$this->repository = $repository;
|
||||
$this->daemonServerRepository = $daemonServerRepository;
|
||||
$this->writer = $writer;
|
||||
}
|
||||
|
||||
public function handle(Server $server)
|
||||
/**
|
||||
* Requests an archive from the daemon.
|
||||
*
|
||||
* @param int|\Pterodactyl\Models\Server $server
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function requestArchive(Server $server)
|
||||
{
|
||||
|
||||
$this->daemonServerRepository->setServer($server)->requestArchive();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,4 +11,5 @@ Route::group(['prefix' => '/servers/{uuid}'], function () {
|
|||
Route::get('/', 'Servers\ServerDetailsController');
|
||||
Route::get('/install', 'Servers\ServerInstallController@index');
|
||||
Route::post('/install', 'Servers\ServerInstallController@store');
|
||||
Route::post('/archive', 'Servers\ServerTransferController@archive');
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue