Fix server transfer backend (#1139)

* fix notify in transfer service

* remove magical array

* fix phpstan

* better validation for allocation_additional and better docs generation

* update transfer ui

* update request body
This commit is contained in:
Boy132 2025-04-01 11:19:14 +02:00 committed by GitHub
parent 630031e1c2
commit 9c3f47590c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 38 additions and 27 deletions

View File

@ -55,6 +55,7 @@ use Filament\Resources\Pages\EditRecord;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\HtmlString;
use LogicException;
@ -921,7 +922,7 @@ class EditServer extends EditRecord
->modalheading(trans('admin/server.transfer'))
->action(function (TransferServerService $transfer, Server $server, $data) {
try {
$transfer->handle($server, $data);
$transfer->handle($server, Arr::get($data, 'node_id'), Arr::get($data, 'allocation_id'), Arr::get($data, 'allocation_additional', []));
Notification::make()
->title('Transfer started')

View File

@ -13,6 +13,7 @@ use App\Services\Servers\TransferServerService;
use Dedoc\Scramble\Attributes\Group;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Response;
use Illuminate\Support\Arr;
#[Group('Server', weight: 4)]
class ServerManagementController extends ApplicationApiController
@ -82,15 +83,24 @@ class ServerManagementController extends ApplicationApiController
$validatedData = $request->validate([
'node_id' => 'required|exists:nodes,id',
'allocation_id' => 'required|bail|unique:servers|exists:allocations,id',
'allocation_additional' => 'nullable',
'allocation_additional' => 'nullable|array',
'allocation_additional.*' => 'integer|exists:allocations,id',
]);
if ($this->transferServerService->handle($server, $validatedData)) {
// Transfer started
if ($this->transferServerService->handle($server, Arr::get($validatedData, 'node_id'), Arr::get($validatedData, 'allocation_id'), Arr::get($validatedData, 'allocation_additional', []))) {
/**
* Transfer started
*
* @status 204
*/
return $this->returnNoContent();
}
// Node was not viable
/**
* Node was not viable
*
* @status 406
*/
return $this->returnNotAcceptable();
}
@ -104,7 +114,11 @@ class ServerManagementController extends ApplicationApiController
public function cancelTransfer(ServerWriteRequest $request, Server $server): Response
{
if (!$transfer = $server->transfer) {
// Server is not transferring
/**
* Server is not transferring
*
* @status 406
*/
return $this->returnNotAcceptable();
}
@ -113,6 +127,11 @@ class ServerManagementController extends ApplicationApiController
$this->daemonServerRepository->setServer($server)->cancelTransfer();
/**
* Transfer cancelled
*
* @status 204
*/
return $this->returnNoContent();
}
}

View File

@ -22,37 +22,28 @@ class TransferServerService
private NodeJWTService $nodeJWTService,
) {}
private function notify(Server $server, Plain $token): void
private function notify(ServerTransfer $transfer, Plain $token): void
{
Http::daemon($server->node)->post('/api/transfer', [
'json' => [
'server_id' => $server->uuid,
'url' => $server->node->getConnectionAddress() . "/api/servers/$server->uuid/archive",
Http::daemon($transfer->oldNode)->post("/api/servers/{$transfer->server->uuid}/transfer", [
'url' => $transfer->newNode->getConnectionAddress() . '/api/transfers',
'token' => 'Bearer ' . $token->toString(),
'server' => [
'uuid' => $server->uuid,
'uuid' => $transfer->server->uuid,
'start_on_completion' => false,
],
],
])->toPsrResponse();
]);
}
/**
* Starts a transfer of a server to a new node.
*
* @param array{
* allocation_id: int,
* node_id: int,
* allocation_additional?: ?int[],
* } $data
* @param int[] $additional_allocations
*
* @throws \Throwable
*/
public function handle(Server $server, array $data): bool
public function handle(Server $server, int $node_id, int $allocation_id, array $additional_allocations): bool
{
$node_id = $data['node_id'];
$allocation_id = intval($data['allocation_id']);
$additional_allocations = array_map(intval(...), $data['allocation_additional'] ?? []);
$additional_allocations = array_map(intval(...), $additional_allocations);
// Check if the node is viable for the transfer.
$node = Node::query()
@ -94,7 +85,7 @@ class TransferServerService
->handle($transfer->newNode, $server->uuid, 'sha256');
// Notify the source node of the pending outgoing transfer.
$this->notify($server, $token);
$this->notify($transfer, $token);
return $transfer;
});