From 0051d9fefcfae0a7b305b0b75fc56d0ea781b52c Mon Sep 17 00:00:00 2001 From: Boy132 Date: Tue, 10 Dec 2024 23:38:40 +0100 Subject: [PATCH] Allow admins to change server egg (#811) * add service that handles egg changing * add "change egg" action to EditServer page * add toggle for keeping old variables or not --- .../ServerResource/Pages/EditServer.php | 27 ++++++++++- app/Services/Eggs/EggChangerService.php | 48 +++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 app/Services/Eggs/EggChangerService.php diff --git a/app/Filament/Admin/Resources/ServerResource/Pages/EditServer.php b/app/Filament/Admin/Resources/ServerResource/Pages/EditServer.php index 58199d80d..05401cb2f 100644 --- a/app/Filament/Admin/Resources/ServerResource/Pages/EditServer.php +++ b/app/Filament/Admin/Resources/ServerResource/Pages/EditServer.php @@ -15,6 +15,7 @@ use App\Models\Server; use App\Models\ServerVariable; use App\Services\Databases\DatabaseManagementService; use App\Services\Databases\DatabasePasswordService; +use App\Services\Eggs\EggChangerService; use App\Services\Servers\RandomWordService; use App\Services\Servers\ReinstallServerService; use App\Services\Servers\ServerDeletionService; @@ -38,6 +39,7 @@ use Filament\Forms\Components\Tabs\Tab; use Filament\Forms\Components\TagsInput; use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; +use Filament\Forms\Components\Toggle; use Filament\Forms\Components\ToggleButtons; use Filament\Forms\Form; use Filament\Forms\Get; @@ -474,7 +476,7 @@ class EditServer extends EditRecord ]) ->schema([ Select::make('egg_id') - ->disabledOn('edit') + ->disabled() ->prefixIcon('tabler-egg') ->columnSpan([ 'default' => 6, @@ -485,7 +487,28 @@ class EditServer extends EditRecord ->relationship('egg', 'name') ->searchable() ->preload() - ->required(), + ->required() + ->hintAction( + Action::make('change_egg') + ->action(function (array $data, Server $server, EggChangerService $service) { + $service->handle($server, $data['egg_id'], $data['keepOldVariables']); + + // Use redirect instead of fillForm to prevent server variables from duplicating + $this->redirect($this->getUrl(['record' => $server, 'tab' => '-egg-tab']), true); + }) + ->form(fn (Server $server) => [ + Select::make('egg_id') + ->label('New Egg') + ->prefixIcon('tabler-egg') + ->options(fn () => Egg::all()->filter(fn (Egg $egg) => $egg->id !== $server->egg->id)->mapWithKeys(fn (Egg $egg) => [$egg->id => $egg->name])) + ->searchable() + ->preload() + ->required(), + Toggle::make('keepOldVariables') + ->label('Keep old variables if possible?') + ->default(true), + ]) + ), ToggleButtons::make('skip_scripts') ->label('Run Egg Install Script?')->inline() diff --git a/app/Services/Eggs/EggChangerService.php b/app/Services/Eggs/EggChangerService.php new file mode 100644 index 000000000..3b0f30bf6 --- /dev/null +++ b/app/Services/Eggs/EggChangerService.php @@ -0,0 +1,48 @@ +egg->id === $newEgg->id) { + return; + } + + // Change egg id, default image and startup command + $server->forceFill([ + 'egg_id' => $newEgg->id, + 'image' => array_values($newEgg->docker_images)[0], + 'startup' => $newEgg->startup, + ])->saveOrFail(); + + $oldVariables = []; + if ($keepOldVariables) { + // Keep copy of old server variables + foreach ($server->serverVariables as $serverVariable) { + $oldVariables[$serverVariable->variable->env_variable] = $serverVariable->variable_value; + } + } + + // Delete old server variables + ServerVariable::where('server_id', $server->id)->delete(); + + // Create new server variables + foreach ($newEgg->variables as $eggVariable) { + ServerVariable::create([ + 'server_id' => $server->id, + 'variable_id' => $eggVariable->id, + 'variable_value' => $oldVariables[$eggVariable->env_variable] ?? $eggVariable->default_value, + ]); + } + } +}