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
|
@ -6,11 +6,12 @@ use Illuminate\Bus\Dispatcher;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Prologue\Alerts\AlertsMessageBag;
|
use Prologue\Alerts\AlertsMessageBag;
|
||||||
use Pterodactyl\Http\Controllers\Controller;
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
use Pterodactyl\Jobs\Server\TransferJob;
|
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||||
use Pterodactyl\Repositories\Eloquent\LocationRepository;
|
use Pterodactyl\Repositories\Eloquent\LocationRepository;
|
||||||
use Pterodactyl\Repositories\Eloquent\NodeRepository;
|
use Pterodactyl\Repositories\Eloquent\NodeRepository;
|
||||||
|
use Pterodactyl\Services\Servers\SuspensionService;
|
||||||
|
use Pterodactyl\Services\Servers\TransferService;
|
||||||
|
|
||||||
class ServerTransferController extends Controller
|
class ServerTransferController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -39,6 +40,16 @@ class ServerTransferController extends Controller
|
||||||
*/
|
*/
|
||||||
private $nodeRepository;
|
private $nodeRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Services\Servers\SuspensionService
|
||||||
|
*/
|
||||||
|
private $suspensionService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Services\Servers\TransferService
|
||||||
|
*/
|
||||||
|
private $transferService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServerTransferController constructor.
|
* ServerTransferController constructor.
|
||||||
*
|
*
|
||||||
|
@ -47,19 +58,25 @@ class ServerTransferController extends Controller
|
||||||
* @param \Pterodactyl\Repositories\Eloquent\ServerRepository $repository
|
* @param \Pterodactyl\Repositories\Eloquent\ServerRepository $repository
|
||||||
* @param \Pterodactyl\Repositories\Eloquent\LocationRepository $locationRepository
|
* @param \Pterodactyl\Repositories\Eloquent\LocationRepository $locationRepository
|
||||||
* @param \Pterodactyl\Repositories\Eloquent\NodeRepository $nodeRepository
|
* @param \Pterodactyl\Repositories\Eloquent\NodeRepository $nodeRepository
|
||||||
|
* @param \Pterodactyl\Services\Servers\SuspensionService $suspensionService
|
||||||
|
* @param \Pterodactyl\Services\Servers\TransferService $transferService
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
AlertsMessageBag $alert,
|
AlertsMessageBag $alert,
|
||||||
Dispatcher $dispatcher,
|
Dispatcher $dispatcher,
|
||||||
ServerRepository $repository,
|
ServerRepository $repository,
|
||||||
LocationRepository $locationRepository,
|
LocationRepository $locationRepository,
|
||||||
NodeRepository $nodeRepository
|
NodeRepository $nodeRepository,
|
||||||
|
SuspensionService $suspensionService,
|
||||||
|
TransferService $transferService
|
||||||
) {
|
) {
|
||||||
$this->alert = $alert;
|
$this->alert = $alert;
|
||||||
$this->dispatcher = $dispatcher;
|
$this->dispatcher = $dispatcher;
|
||||||
$this->repository = $repository;
|
$this->repository = $repository;
|
||||||
$this->locationRepository = $locationRepository;
|
$this->locationRepository = $locationRepository;
|
||||||
$this->nodeRepository = $nodeRepository;
|
$this->nodeRepository = $nodeRepository;
|
||||||
|
$this->suspensionService = $suspensionService;
|
||||||
|
$this->transferService = $transferService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,6 +85,8 @@ class ServerTransferController extends Controller
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request $request
|
||||||
* @param \Pterodactyl\Models\Server $server
|
* @param \Pterodactyl\Models\Server $server
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*
|
||||||
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function transfer(Request $request, Server $server)
|
public function transfer(Request $request, Server $server)
|
||||||
{
|
{
|
||||||
|
@ -84,8 +103,9 @@ class ServerTransferController extends Controller
|
||||||
// Check if the node is viable for the transfer.
|
// Check if the node is viable for the transfer.
|
||||||
$node = $this->nodeRepository->getNodeWithResourceUsage($node_id);
|
$node = $this->nodeRepository->getNodeWithResourceUsage($node_id);
|
||||||
if ($node->isViable($server->memory, $server->disk)) {
|
if ($node->isViable($server->memory, $server->disk)) {
|
||||||
// TODO: Run TransferJob.
|
// Suspend the server and request an archive to be created.
|
||||||
$this->dispatcher->dispatch(new TransferJob($server, $node, $allocation_id, $additional_allocations));
|
// $this->suspensionService->toggle($server, 'suspend');
|
||||||
|
$this->transferService->requestArchive($server);
|
||||||
|
|
||||||
$this->alert->success(trans('admin/server.alerts.transfer_started'))->flash();
|
$this->alert->success(trans('admin/server.alerts.transfer_started'))->flash();
|
||||||
} else {
|
} 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' => [
|
'system' => [
|
||||||
'data' => $this->daemonBase,
|
'data' => $this->daemonBase,
|
||||||
|
'archive_directory' => $this->daemonBase . '/.archives',
|
||||||
'username' => 'pterodactyl',
|
'username' => 'pterodactyl',
|
||||||
'timezone_path' => '/etc/timezone',
|
'timezone_path' => '/etc/timezone',
|
||||||
'set_permissions_on_boot' => true,
|
'set_permissions_on_boot' => true,
|
||||||
|
|
|
@ -124,4 +124,24 @@ class DaemonServerRepository extends DaemonRepository
|
||||||
throw new DaemonConnectionException($exception);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
class TransferService
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Illuminate\Database\ConnectionInterface
|
|
||||||
*/
|
|
||||||
private $connection;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
||||||
*/
|
*/
|
||||||
|
@ -26,33 +20,29 @@ class TransferService
|
||||||
*/
|
*/
|
||||||
private $daemonServerRepository;
|
private $daemonServerRepository;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Psr\Log\LoggerInterface
|
|
||||||
*/
|
|
||||||
private $writer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TransferService constructor.
|
* TransferService constructor.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\ConnectionInterface $connection
|
|
||||||
* @param \Pterodactyl\Repositories\Wings\DaemonServerRepository $daemonServerRepository
|
* @param \Pterodactyl\Repositories\Wings\DaemonServerRepository $daemonServerRepository
|
||||||
* @param \Pterodactyl\Contracts\Repository\ServerRepositoryInterface $repository
|
* @param \Pterodactyl\Contracts\Repository\ServerRepositoryInterface $repository
|
||||||
* @param \Psr\Log\LoggerInterface $writer
|
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ConnectionInterface $connection,
|
|
||||||
DaemonServerRepository $daemonServerRepository,
|
DaemonServerRepository $daemonServerRepository,
|
||||||
ServerRepositoryInterface $repository,
|
ServerRepositoryInterface $repository
|
||||||
LoggerInterface $writer
|
|
||||||
) {
|
) {
|
||||||
$this->connection = $connection;
|
|
||||||
$this->repository = $repository;
|
$this->repository = $repository;
|
||||||
$this->daemonServerRepository = $daemonServerRepository;
|
$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('/', 'Servers\ServerDetailsController');
|
||||||
Route::get('/install', 'Servers\ServerInstallController@index');
|
Route::get('/install', 'Servers\ServerInstallController@index');
|
||||||
Route::post('/install', 'Servers\ServerInstallController@store');
|
Route::post('/install', 'Servers\ServerInstallController@store');
|
||||||
|
Route::post('/archive', 'Servers\ServerTransferController@archive');
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue