diff --git a/app/Filament/Admin/Resources/Servers/Pages/EditServer.php b/app/Filament/Admin/Resources/Servers/Pages/EditServer.php index 159eaa389a..e208b223a2 100644 --- a/app/Filament/Admin/Resources/Servers/Pages/EditServer.php +++ b/app/Filament/Admin/Resources/Servers/Pages/EditServer.php @@ -11,10 +11,12 @@ use App\Filament\Components\StateCasts\ServerConditionStateCast; use App\Filament\Server\Pages\Console; use App\Models\Allocation; +use App\Models\Backup; use App\Models\Egg; use App\Models\Server; use App\Models\User; use App\Repositories\Daemon\DaemonServerRepository; +use App\Services\Backups\DeleteBackupService; use App\Services\Eggs\EggChangerService; use App\Services\Servers\RandomWordService; use App\Services\Servers\ReinstallServerService; @@ -27,6 +29,7 @@ use Exception; use Filament\Actions\Action; use Filament\Actions\ActionGroup; +use Filament\Forms\Components\CheckboxList; use Filament\Forms\Components\FileUpload; use Filament\Forms\Components\Hidden; use Filament\Forms\Components\KeyValue; @@ -48,6 +51,7 @@ use Filament\Schemas\Components\StateCasts\BooleanStateCast; use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; +use Filament\Schemas\Components\Text; use Filament\Schemas\Components\Utilities\Get; use Filament\Schemas\Components\Utilities\Set; use Filament\Schemas\Schema; @@ -962,9 +966,17 @@ public function form(Schema $schema): Schema ->disabled(fn (Server $server) => user()?->accessibleNodes()->count() <= 1 || $server->isInConflictState()) ->modalHeading(trans('admin/server.transfer')) ->schema($this->transferServer()) - ->action(function (TransferServerService $transfer, Server $server, $data) { + ->action(function (TransferServerService $transfer, DeleteBackupService $deleteBackup, Server $server, $data) { try { - $transfer->handle($server, Arr::get($data, 'node_id'), Arr::get($data, 'allocation_id'), Arr::get($data, 'allocation_additional', [])); + $selectedBackupUuids = Arr::get($data, 'backups', []); + $transfer->handle($server, Arr::get($data, 'node_id'), Arr::get($data, 'allocation_id'), Arr::get($data, 'allocation_additional', []), $selectedBackupUuids); + + $server->backups + ->whereNotIn('uuid', $selectedBackupUuids) + ->where('disk', Backup::ADAPTER_DAEMON) + ->each(function ($backup) { + $backup->delete(); + }); Notification::make() ->title(trans('admin/server.notifications.transfer_started')) @@ -1054,6 +1066,19 @@ protected function transferServer(): array ->options(fn (Get $get) => Allocation::where('node_id', $get('node_id'))->whereNull('server_id')->when($get('allocation_id'), fn ($query) => $query->whereNot('id', $get('allocation_id')))->get()->mapWithKeys(fn (Allocation $allocation) => [$allocation->id => $allocation->address])) ->searchable(['ip', 'port', 'ip_alias']) ->placeholder(trans('admin/server.select_additional')), + Grid::make() + ->columnSpanFull() + ->schema([ + CheckboxList::make('backups') + ->label(trans('admin/server.backups')) + ->bulkToggleable() + ->options(fn (Server $server) => $server->backups->where('disk', Backup::ADAPTER_DAEMON)->mapWithKeys(fn ($backup) => [$backup->uuid => $backup->name])) + ->columns(fn (Server $record) => (int) ceil($record->backups->where('disk', Backup::ADAPTER_DAEMON)->count() / 4)), + Text::make('backup_helper') + ->columnSpanFull() + ->content(trans('admin/server.warning_backups')), + ]) + ->hidden(fn (Server $server) => $server->backups->where('disk', Backup::ADAPTER_DAEMON)->count() === 0), ]; } diff --git a/app/Services/Servers/TransferServerService.php b/app/Services/Servers/TransferServerService.php index 65a472ff4f..05a0fcc254 100644 --- a/app/Services/Servers/TransferServerService.php +++ b/app/Services/Servers/TransferServerService.php @@ -3,6 +3,7 @@ namespace App\Services\Servers; use App\Models\Allocation; +use App\Models\Backup; use App\Models\Node; use App\Models\Server; use App\Models\ServerTransfer; @@ -23,11 +24,19 @@ public function __construct( private NodeJWTService $nodeJWTService, ) {} - private function notify(ServerTransfer $transfer, UnencryptedToken $token): void + /** + * @param string[] $backup_uuids + */ + private function notify(ServerTransfer $transfer, UnencryptedToken $token, array $backup_uuids = []): void { + $backups = []; + if (config('backups.default') === Backup::ADAPTER_DAEMON) { + $backups = $backup_uuids; + } Http::daemon($transfer->oldNode)->post("/api/servers/{$transfer->server->uuid}/transfer", [ 'url' => $transfer->newNode->getConnectionAddress() . '/api/transfers', 'token' => 'Bearer ' . $token->toString(), + 'backups' => $backups, 'server' => [ 'uuid' => $transfer->server->uuid, 'start_on_completion' => false, @@ -39,10 +48,11 @@ private function notify(ServerTransfer $transfer, UnencryptedToken $token): void * Starts a transfer of a server to a new node. * * @param int[] $additional_allocations + * @param string[] $backup_uuid * * @throws Throwable */ - public function handle(Server $server, int $node_id, ?int $allocation_id = null, ?array $additional_allocations = []): bool + public function handle(Server $server, int $node_id, ?int $allocation_id = null, ?array $additional_allocations = [], ?array $backup_uuid = []): bool { $additional_allocations = array_map(intval(...), $additional_allocations); @@ -93,7 +103,7 @@ public function handle(Server $server, int $node_id, ?int $allocation_id = null, ->handle($transfer->newNode, $server->uuid, 'sha256'); // Notify the source node of the pending outgoing transfer. - $this->notify($transfer, $token); + $this->notify($transfer, $token, $backup_uuid); return true; } diff --git a/lang/en/admin/server.php b/lang/en/admin/server.php index e7dc121635..efa8b59197 100644 --- a/lang/en/admin/server.php +++ b/lang/en/admin/server.php @@ -109,6 +109,8 @@ 'add_allocation' => 'Add Allocation', 'view' => 'View', 'no_log' => 'No Log Available', + 'select_backups' => 'Select Backups', + 'warning_backups' => 'Be aware, not transferred backups will be deleted.', 'tabs' => [ 'information' => 'Information', 'egg_configuration' => 'Egg Configuration', @@ -142,6 +144,7 @@ 'transfer_started' => 'Transfer started', 'transfer_failed' => 'Transfer failed', 'already_transfering' => 'Server is currently being transferred.', + 'backup_transfer_failed' => 'Backup Transfer Failed', ], 'notes' => 'Notes', 'no_notes' => 'No Notes',