diff --git a/.github/docker/entrypoint.sh b/.github/docker/entrypoint.sh index 9cd4c9b0f..7f4de80cd 100644 --- a/.github/docker/entrypoint.sh +++ b/.github/docker/entrypoint.sh @@ -1,7 +1,7 @@ #!/bin/ash -e cd /app -mkdir -p /var/log/panel/logs/ /var/log/supervisord/ /var/log/nginx/ /var/log/php7/ \ +mkdir -p /var/log/panel/logs/ /var/log/supervisord/ /var/log/nginx/ /var/log/php8/ \ && chmod 777 /var/log/panel/logs/ \ && ln -s /app/storage/logs/ /var/log/panel/ diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index be1b59369..4bbbae1fd 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -12,7 +12,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [18] + node-version: [18, 21] steps: - name: Code Checkout uses: actions/checkout@v4 diff --git a/Dockerfile b/Dockerfile index 95d0fefe2..1c3c34a62 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ # Build the assets that are needed for the frontend. This build stage is then discarded # since we won't need NodeJS anymore in the future. This Docker image ships a final production # level distribution -FROM --platform=$TARGETOS/$TARGETARCH mhart/alpine-node:14 +FROM --platform=$TARGETOS/$TARGETARCH node:21-alpine WORKDIR /app COPY . ./ RUN yarn install --frozen-lockfile \ @@ -10,13 +10,13 @@ RUN yarn install --frozen-lockfile \ # Stage 1: # Build the actual container with all of the needed PHP dependencies that will run the application. -FROM --platform=$TARGETOS/$TARGETARCH php:8.1-fpm-alpine +FROM --platform=$TARGETOS/$TARGETARCH php:8.3-fpm-alpine WORKDIR /app COPY . ./ COPY --from=0 /app/public/assets ./public/assets -RUN apk add --no-cache --update ca-certificates dcron curl git supervisor tar unzip nginx libpng-dev libxml2-dev libzip-dev certbot certbot-nginx \ +RUN apk add --no-cache --update ca-certificates dcron curl git supervisor tar unzip nginx libpng-dev libxml2-dev libzip-dev icu-dev certbot certbot-nginx \ && docker-php-ext-configure zip \ - && docker-php-ext-install bcmath gd pdo_mysql zip \ + && docker-php-ext-install bcmath gd intl pdo_mysql zip \ && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \ && cp .env.example .env \ && mkdir -p bootstrap/cache/ storage/logs storage/framework/sessions storage/framework/views storage/framework/cache \ diff --git a/app/Console/Commands/Node/MakeNodeCommand.php b/app/Console/Commands/Node/MakeNodeCommand.php index 4cf36452c..002b36b78 100644 --- a/app/Console/Commands/Node/MakeNodeCommand.php +++ b/app/Console/Commands/Node/MakeNodeCommand.php @@ -58,9 +58,9 @@ class MakeNodeCommand extends Command $data['disk'] = $this->option('maxDisk') ?? $this->ask('Enter the maximum amount of disk space'); $data['disk_overallocate'] = $this->option('overallocateDisk') ?? $this->ask('Enter the amount of memory to over allocate by, -1 will disable checking and 0 will prevent creating new server'); $data['upload_size'] = $this->option('uploadSize') ?? $this->ask('Enter the maximum filesize upload', '100'); - $data['daemonListen'] = $this->option('daemonListeningPort') ?? $this->ask('Enter the daemon listening port', '8080'); - $data['daemonSFTP'] = $this->option('daemonSFTPPort') ?? $this->ask('Enter the daemon SFTP listening port', '2022'); - $data['daemonBase'] = $this->option('daemonBase') ?? $this->ask('Enter the base folder', '/var/lib/pelican/volumes'); + $data['daemon_listen'] = $this->option('daemonListeningPort') ?? $this->ask('Enter the daemon listening port', '8080'); + $data['daemon_sftp'] = $this->option('daemonSFTPPort') ?? $this->ask('Enter the daemon SFTP listening port', '2022'); + $data['daemon_base'] = $this->option('daemonBase') ?? $this->ask('Enter the base folder', '/var/lib/pelican/volumes'); $node = $this->creationService->handle($data); $this->line('Successfully created a new node with the name ' . $data['name'] . ' and has an id of ' . $node->id . '.'); diff --git a/app/Filament/Resources/EggResource.php b/app/Filament/Resources/EggResource.php index dd3d62b3e..5741c49af 100644 --- a/app/Filament/Resources/EggResource.php +++ b/app/Filament/Resources/EggResource.php @@ -100,11 +100,11 @@ class EggResource extends Resource ->label('Log Configuration') ->helperText('This should be a JSON representation of where log files are stored, and whether or not the daemon should be creating custom logs.'), ]), - Forms\Components\Tabs\Tab::make('Variables') + Forms\Components\Tabs\Tab::make('Egg Variables') ->columnSpanFull() ->columns(2) ->schema([ - Forms\Components\Repeater::make('Blah') + Forms\Components\Repeater::make('variables') ->grid() ->relationship('variables') ->name('name') @@ -113,12 +113,36 @@ class EggResource extends Resource ->collapsible()->collapsed() ->columnSpan(2) ->itemLabel(fn (array $state) => $state['name']) + ->mutateRelationshipDataBeforeCreateUsing(function (array $data): array { + $data['default_value'] ??= ''; + $data['description'] ??= ''; + $data['rules'] ??= ''; + + return $data; + }) + ->mutateRelationshipDataBeforeSaveUsing(function (array $data): array { + $data['default_value'] ??= ''; + $data['description'] ??= ''; + $data['rules'] ??= ''; + + return $data; + }) ->schema([ - Forms\Components\TextInput::make('name')->live()->maxLength(191)->columnSpanFull(), + Forms\Components\TextInput::make('name') + ->live() + ->debounce(1000) + ->maxLength(191) + ->columnSpanFull() + ->afterStateUpdated(fn (Forms\Set $set, $state) => $set('env_variable', str($state)->trim()->snake()->upper())) + ->required(), Forms\Components\Textarea::make('description')->columnSpanFull(), - Forms\Components\TextInput::make('env_variable')->maxLength(191)->required()->hint(fn ($state) => "{{{$state}}}"), - Forms\Components\TextInput::make('default_value')->maxLength(191)->required(), - Forms\Components\TextInput::make('rules')->columnSpanFull()->required(), + Forms\Components\TextInput::make('env_variable') + ->label('Environment Variable') + ->maxLength(191) + ->hint(fn ($state) => "{{{$state}}}") + ->required(), + Forms\Components\TextInput::make('default_value')->maxLength(191), + Forms\Components\Textarea::make('rules')->rows(3)->columnSpanFull(), ]), ]), Forms\Components\Tabs\Tab::make('Install Script') diff --git a/app/Filament/Resources/NodeResource.php b/app/Filament/Resources/NodeResource.php index f07b85fac..92599c666 100644 --- a/app/Filament/Resources/NodeResource.php +++ b/app/Filament/Resources/NodeResource.php @@ -43,17 +43,17 @@ class NodeResource extends Resource ->required() ->integer() ->default(100), - Forms\Components\TextInput::make('daemonListen') + Forms\Components\TextInput::make('daemon_listen') ->required() ->integer() ->label('Daemon Port') ->default(8080), - Forms\Components\TextInput::make('daemonSFTP') + Forms\Components\TextInput::make('daemon_sftp') ->required() ->integer() ->label('Daemon SFTP Port') ->default(2022), - Forms\Components\TextInput::make('daemonBase') + Forms\Components\TextInput::make('daemon_base') ->required() ->maxLength(191) ->default('/home/daemon-files'), diff --git a/app/Filament/Resources/NodeResource/Pages/CreateNode.php b/app/Filament/Resources/NodeResource/Pages/CreateNode.php index 4427bea4e..1da210fe9 100644 --- a/app/Filament/Resources/NodeResource/Pages/CreateNode.php +++ b/app/Filament/Resources/NodeResource/Pages/CreateNode.php @@ -113,7 +113,7 @@ class CreateNode extends CreateRecord 'lg' => 1, ]), - Forms\Components\TextInput::make('daemonListen') + Forms\Components\TextInput::make('daemon_listen') ->columnSpan([ 'default' => 1, 'sm' => 1, diff --git a/app/Filament/Resources/NodeResource/Pages/EditNode.php b/app/Filament/Resources/NodeResource/Pages/EditNode.php index ff0b6eaef..65553abd2 100644 --- a/app/Filament/Resources/NodeResource/Pages/EditNode.php +++ b/app/Filament/Resources/NodeResource/Pages/EditNode.php @@ -3,12 +3,12 @@ namespace App\Filament\Resources\NodeResource\Pages; use App\Filament\Resources\NodeResource; -use App\Models\Allocation; use App\Models\Node; use Filament\Actions; use Filament\Forms; use Filament\Forms\Components\Tabs; use Filament\Resources\Pages\EditRecord; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\HtmlString; use Webbingbrasil\FilamentCopyActions\Forms\Actions\CopyAction; @@ -91,6 +91,52 @@ class EditNode extends EditRecord 'md' => 1, 'lg' => 1, ]) + ->live() + ->afterStateUpdated(function ($state, Forms\Set $set) { + $ports = collect(); + $update = false; + foreach ($state as $portEntry) { + if (!str_contains($portEntry, '-')) { + if (is_numeric($portEntry)) { + $ports->push((int) $portEntry); + + continue; + } + + // Do not add non numerical ports + $update = true; + + continue; + } + + $update = true; + [$start, $end] = explode('-', $portEntry); + if (!is_numeric($start) || !is_numeric($end)) { + continue; + } + + $start = max((int) $start, 0); + $end = min((int) $end, 2 ** 16 - 1); + for ($i = $start; $i <= $end; $i++) { + $ports->push($i); + } + } + + $uniquePorts = $ports->unique()->values(); + if ($ports->count() > $uniquePorts->count()) { + $update = true; + $ports = $uniquePorts; + } + + $sortedPorts = $ports->sort()->values(); + if ($sortedPorts->all() !== $ports->all()) { + $update = true; + $ports = $sortedPorts; + } + if ($update) { + $set('port', $ports->all()); + } + }) ->placeholder('25565') ->helperText('Individual ports or port ranges here separated by spaces') ->splitKeys(['Tab', ' ']), @@ -108,6 +154,15 @@ class EditNode extends EditRecord Forms\Components\Repeater::make('allocations') ->orderColumn('server_id') ->columnSpan(4) + ->collapsible()->collapsed() + ->itemLabel(function (array $state) { + $host = $state['ip'] . ':' . $state['port']; + if ($state['ip_alias']) { + return $state['ip_alias'] ." ($host)"; + } + + return $host; + }) ->columns([ 'default' => 1, 'sm' => 3, @@ -133,7 +188,7 @@ class EditNode extends EditRecord 'default' => 1, 'sm' => 1, 'md' => 1, - 'lg' => 1, + 'lg' => 2, ]) ->minValue(0) ->maxValue(65535) @@ -147,15 +202,21 @@ class EditNode extends EditRecord 'lg' => 3, ]) ->label('Alias'), - Forms\Components\TextInput::make('server') + Forms\Components\Select::make('server') ->columnSpan([ 'default' => 1, 'sm' => 1, 'md' => 2, - 'lg' => 3, + 'lg' => 2, ]) - ->formatStateUsing(fn (Allocation $allocation) => $allocation->server?->name) - ->activeUrl(true) + ->searchable() + ->preload() + ->relationship( + 'server', + 'name', + fn (Builder $query, Forms\Get $get) => $query + ->where('node_id', $get('node_id')), + ) ->placeholder('Not assigned'), ]), ]), diff --git a/app/Http/Controllers/Admin/Nodes/NodeViewController.php b/app/Http/Controllers/Admin/Nodes/NodeViewController.php index f7e72773f..9407ef2a7 100644 --- a/app/Http/Controllers/Admin/Nodes/NodeViewController.php +++ b/app/Http/Controllers/Admin/Nodes/NodeViewController.php @@ -96,7 +96,7 @@ class NodeViewController extends Controller { $this->plainInject([ 'node' => Collection::wrap($node->makeVisible(['daemon_token_id', 'daemon_token'])) - ->only(['scheme', 'fqdn', 'daemonListen', 'daemon_token_id', 'daemon_token']), + ->only(['scheme', 'fqdn', 'daemon_listen', 'daemon_token_id', 'daemon_token']), ]); return view('admin.nodes.view.servers', [ diff --git a/app/Http/Controllers/Admin/Servers/ServerTransferController.php b/app/Http/Controllers/Admin/Servers/ServerTransferController.php index 9518092f1..fbfc7530e 100644 --- a/app/Http/Controllers/Admin/Servers/ServerTransferController.php +++ b/app/Http/Controllers/Admin/Servers/ServerTransferController.php @@ -68,7 +68,7 @@ class ServerTransferController extends Controller // Check if the node is viable for the transfer. $node = Node::query() - ->select(['nodes.id', 'nodes.fqdn', 'nodes.scheme', 'nodes.daemon_token', 'nodes.daemonListen', 'nodes.memory', 'nodes.disk', 'nodes.memory_overallocate', 'nodes.disk_overallocate']) + ->select(['nodes.id', 'nodes.fqdn', 'nodes.scheme', 'nodes.daemon_token', 'nodes.daemon_listen', 'nodes.memory', 'nodes.disk', 'nodes.memory_overallocate', 'nodes.disk_overallocate']) ->selectRaw('IFNULL(SUM(servers.memory), 0) as sum_memory, IFNULL(SUM(servers.disk), 0) as sum_disk') ->leftJoin('servers', 'servers.node_id', '=', 'nodes.id') ->where('nodes.id', $node_id) diff --git a/app/Http/Controllers/Api/Application/Servers/ServerController.php b/app/Http/Controllers/Api/Application/Servers/ServerController.php index e91e437e3..2d675516b 100644 --- a/app/Http/Controllers/Api/Application/Servers/ServerController.php +++ b/app/Http/Controllers/Api/Application/Servers/ServerController.php @@ -33,7 +33,7 @@ class ServerController extends ApplicationApiController public function index(GetServersRequest $request): array { $servers = QueryBuilder::for(Server::query()) - ->allowedFilters(['uuid', 'uuidShort', 'name', 'description', 'image', 'external_id']) + ->allowedFilters(['uuid', 'uuid_short', 'name', 'description', 'image', 'external_id']) ->allowedSorts(['id', 'uuid']) ->paginate($request->query('per_page') ?? 50); diff --git a/app/Http/Controllers/Api/Remote/SftpAuthenticationController.php b/app/Http/Controllers/Api/Remote/SftpAuthenticationController.php index 17fd0f6ca..af9cf97b1 100644 --- a/app/Http/Controllers/Api/Remote/SftpAuthenticationController.php +++ b/app/Http/Controllers/Api/Remote/SftpAuthenticationController.php @@ -89,7 +89,7 @@ class SftpAuthenticationController extends Controller protected function getServer(Request $request, string $uuid): Server { return Server::query() - ->where(fn ($builder) => $builder->where('uuid', $uuid)->orWhere('uuidShort', $uuid)) + ->where(fn ($builder) => $builder->where('uuid', $uuid)->orWhere('uuid_short', $uuid)) ->where('node_id', $request->attributes->get('node')->id) ->firstOr(function () use ($request) { $this->reject($request); diff --git a/app/Http/Requests/Api/Application/Nodes/StoreNodeRequest.php b/app/Http/Requests/Api/Application/Nodes/StoreNodeRequest.php index 99b98c375..fb426e3d9 100644 --- a/app/Http/Requests/Api/Application/Nodes/StoreNodeRequest.php +++ b/app/Http/Requests/Api/Application/Nodes/StoreNodeRequest.php @@ -29,11 +29,11 @@ class StoreNodeRequest extends ApplicationApiRequest 'disk', 'disk_overallocate', 'upload_size', - 'daemonListen', - 'daemonSFTP', - 'daemonBase', + 'daemon_listen', + 'daemon_sftp', + 'daemon_base', ])->mapWithKeys(function ($value, $key) { - $key = ($key === 'daemonSFTP') ? 'daemonSftp' : $key; + $key = ($key === 'daemon_sftp') ? 'daemon_sftp' : $key; return [snake_case($key) => $value]; })->toArray(); @@ -58,9 +58,9 @@ class StoreNodeRequest extends ApplicationApiRequest public function validated($key = null, $default = null): array { $response = parent::validated(); - $response['daemonListen'] = $response['daemon_listen']; - $response['daemonSFTP'] = $response['daemon_sftp']; - $response['daemonBase'] = $response['daemon_base'] ?? (new Node())->getAttribute('daemonBase'); + $response['daemon_listen'] = $response['daemon_listen']; + $response['daemon_sftp'] = $response['daemon_sftp']; + $response['daemon_base'] = $response['daemon_base'] ?? (new Node())->getAttribute('daemon_base'); unset($response['daemon_base'], $response['daemon_listen'], $response['daemon_sftp']); diff --git a/app/Models/EggVariable.php b/app/Models/EggVariable.php index 6df7c53b9..fceba3d8c 100644 --- a/app/Models/EggVariable.php +++ b/app/Models/EggVariable.php @@ -56,7 +56,7 @@ class EggVariable extends Model 'default_value' => 'string', 'user_viewable' => 'boolean', 'user_editable' => 'boolean', - 'rules' => 'required|string', + 'rules' => 'string', ]; protected $attributes = [ diff --git a/app/Models/Filters/AdminServerFilter.php b/app/Models/Filters/AdminServerFilter.php index 6e24a5b50..d3c1eea60 100644 --- a/app/Models/Filters/AdminServerFilter.php +++ b/app/Models/Filters/AdminServerFilter.php @@ -24,7 +24,7 @@ class AdminServerFilter implements Filter ->where(function (Builder $builder) use ($value) { $builder->where('servers.uuid', $value) ->orWhere('servers.uuid', 'LIKE', "$value%") - ->orWhere('servers.uuidShort', $value) + ->orWhere('servers.uuid_short', $value) ->orWhere('servers.external_id', $value) ->orWhereRaw('LOWER(users.username) LIKE ?', ["%$value%"]) ->orWhereRaw('LOWER(users.email) LIKE ?', ["$value%"]) diff --git a/app/Models/Filters/MultiFieldServerFilter.php b/app/Models/Filters/MultiFieldServerFilter.php index 39b1c2235..da3f91f6d 100644 --- a/app/Models/Filters/MultiFieldServerFilter.php +++ b/app/Models/Filters/MultiFieldServerFilter.php @@ -61,7 +61,7 @@ class MultiFieldServerFilter implements Filter ->where(function (Builder $builder) use ($value) { $builder->where('servers.uuid', $value) ->orWhere('servers.uuid', 'LIKE', "$value%") - ->orWhere('servers.uuidShort', $value) + ->orWhere('servers.uuid_short', $value) ->orWhere('servers.external_id', $value) ->orWhereRaw('LOWER(servers.name) LIKE ?', ["%$value%"]); }); diff --git a/app/Models/Node.php b/app/Models/Node.php index c93fd8f89..a3096c57b 100644 --- a/app/Models/Node.php +++ b/app/Models/Node.php @@ -29,9 +29,9 @@ use Illuminate\Database\Eloquent\Relations\HasManyThrough; * @property int $upload_size * @property string $daemon_token_id * @property string $daemon_token - * @property int $daemonListen - * @property int $daemonSFTP - * @property string $daemonBase + * @property int $daemon_listen + * @property int $daemon_sftp + * @property string $daemon_base * @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $updated_at * @property \App\Models\Mount[]|\Illuminate\Database\Eloquent\Collection $mounts @@ -71,8 +71,8 @@ class Node extends Model 'public', 'name', 'fqdn', 'scheme', 'behind_proxy', 'memory', 'memory_overallocate', 'disk', - 'disk_overallocate', 'upload_size', 'daemonBase', - 'daemonSFTP', 'daemonListen', + 'disk_overallocate', 'upload_size', 'daemon_base', + 'daemon_sftp', 'daemon_listen', 'description', 'maintenance_mode', ]; @@ -87,9 +87,9 @@ class Node extends Model 'memory_overallocate' => 'required|numeric|min:-1', 'disk' => 'required|numeric|min:0', 'disk_overallocate' => 'required|numeric|min:-1', - 'daemonBase' => 'sometimes|required|regex:/^([\/][\d\w.\-\/]+)$/', - 'daemonSFTP' => 'required|numeric|between:1,65535', - 'daemonListen' => 'required|numeric|between:1,65535', + 'daemon_base' => 'sometimes|required|regex:/^([\/][\d\w.\-\/]+)$/', + 'daemon_sftp' => 'required|numeric|between:1,65535', + 'daemon_listen' => 'required|numeric|between:1,65535', 'maintenance_mode' => 'boolean', 'upload_size' => 'int|between:1,1024', ]; @@ -104,9 +104,9 @@ class Node extends Model 'memory_overallocate' => 0, 'disk' => 0, 'disk_overallocate' => 0, - 'daemonBase' => '/var/lib/pelican/volumes', - 'daemonSFTP' => 2022, - 'daemonListen' => 8080, + 'daemon_base' => '/var/lib/pelican/volumes', + 'daemon_sftp' => 2022, + 'daemon_listen' => 8080, 'maintenance_mode' => false, ]; @@ -115,8 +115,8 @@ class Node extends Model return [ 'memory' => 'integer', 'disk' => 'integer', - 'daemonListen' => 'integer', - 'daemonSFTP' => 'integer', + 'daemon_listen' => 'integer', + 'daemon_sftp' => 'integer', 'behind_proxy' => 'boolean', 'public' => 'boolean', 'maintenance_mode' => 'boolean', @@ -148,7 +148,7 @@ class Node extends Model */ public function getConnectionAddress(): string { - return "$this->scheme://$this->fqdn:$this->daemonListen"; + return "$this->scheme://$this->fqdn:$this->daemon_listen"; } /** @@ -163,7 +163,7 @@ class Node extends Model 'token' => decrypt($this->daemon_token), 'api' => [ 'host' => '0.0.0.0', - 'port' => $this->daemonListen, + 'port' => $this->daemon_listen, 'ssl' => [ 'enabled' => (!$this->behind_proxy && $this->scheme === 'https'), 'cert' => '/etc/letsencrypt/live/' . Str::lower($this->fqdn) . '/fullchain.pem', @@ -172,9 +172,9 @@ class Node extends Model 'upload_limit' => $this->upload_size, ], 'system' => [ - 'data' => $this->daemonBase, + 'data' => $this->daemon_base, 'sftp' => [ - 'bind_port' => $this->daemonSFTP, + 'bind_port' => $this->daemon_sftp, ], ], 'allowed_mounts' => $this->mounts->pluck('source')->toArray(), diff --git a/app/Models/Server.php b/app/Models/Server.php index 11db6854c..172317437 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -22,7 +22,7 @@ use App\Exceptions\Http\Server\ServerStateConflictException; * @property int $id * @property string|null $external_id * @property string $uuid - * @property string $uuidShort + * @property string $uuid_short * @property int $node_id * @property string $name * @property string $description @@ -99,7 +99,7 @@ use App\Exceptions\Http\Server\ServerStateConflictException; * @method static \Illuminate\Database\Eloquent\Builder|Server whereThreads($value) * @method static \Illuminate\Database\Eloquent\Builder|Server whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|Server whereUuid($value) - * @method static \Illuminate\Database\Eloquent\Builder|Server whereUuidShort($value) + * @method static \Illuminate\Database\Eloquent\Builder|Server whereuuid_short($value) * * @mixin \Eloquent */ @@ -329,7 +329,7 @@ class Server extends Model public function resolveRouteBinding($value, $field = null): ?self { return match ($field) { - 'uuid' => $this->where('uuidShort', $value)->orWhere('uuid', $value)->firstOrFail(), + 'uuid' => $this->where('uuid_short', $value)->orWhere('uuid', $value)->firstOrFail(), default => $this->where('id', $value)->firstOrFail(), }; } diff --git a/app/Notifications/AddedToServer.php b/app/Notifications/AddedToServer.php index 34d46f0b2..647c33822 100644 --- a/app/Notifications/AddedToServer.php +++ b/app/Notifications/AddedToServer.php @@ -38,6 +38,6 @@ class AddedToServer extends Notification implements ShouldQueue ->greeting('Hello ' . $this->server->user . '!') ->line('You have been added as a subuser for the following server, allowing you certain control over the server.') ->line('Server Name: ' . $this->server->name) - ->action('Visit Server', url('/server/' . $this->server->uuidShort)); + ->action('Visit Server', url('/server/' . $this->server->uuid_short)); } } diff --git a/app/Observers/SubuserObserver.php b/app/Observers/SubuserObserver.php index 0acb86777..25842045c 100644 --- a/app/Observers/SubuserObserver.php +++ b/app/Observers/SubuserObserver.php @@ -27,7 +27,7 @@ class SubuserObserver $subuser->user->notify(new AddedToServer([ 'user' => $subuser->user->name_first, 'name' => $subuser->server->name, - 'uuidShort' => $subuser->server->uuidShort, + 'uuid_short' => $subuser->server->uuid_short, ])); } diff --git a/app/Services/Servers/ServerCreationService.php b/app/Services/Servers/ServerCreationService.php index 7ba8b73e9..22861632e 100644 --- a/app/Services/Servers/ServerCreationService.php +++ b/app/Services/Servers/ServerCreationService.php @@ -129,7 +129,7 @@ class ServerCreationService return Server::create([ 'external_id' => Arr::get($data, 'external_id'), 'uuid' => $uuid, - 'uuidShort' => substr($uuid, 0, 8), + 'uuid_short' => substr($uuid, 0, 8), 'node_id' => Arr::get($data, 'node_id'), 'name' => Arr::get($data, 'name'), 'description' => Arr::get($data, 'description') ?? '', @@ -194,7 +194,7 @@ class ServerCreationService $uuid = Uuid::uuid4()->toString(); $shortUuid = str($uuid)->substr(0, 8); - if (Server::query()->where('uuid', $uuid)->orWhere('uuidShort', $shortUuid)->exists()) { + if (Server::query()->where('uuid', $uuid)->orWhere('uuid_short', $shortUuid)->exists()) { return $this->generateUniqueUuidCombo(); } diff --git a/app/Traits/Helpers/AvailableLanguages.php b/app/Traits/Helpers/AvailableLanguages.php index c4bf74966..53b45c5a6 100644 --- a/app/Traits/Helpers/AvailableLanguages.php +++ b/app/Traits/Helpers/AvailableLanguages.php @@ -21,6 +21,7 @@ trait AvailableLanguages 'ja', 'nl', 'pl', + 'sk', 'ru', 'tr', ]; diff --git a/app/Transformers/Api/Application/NodeTransformer.php b/app/Transformers/Api/Application/NodeTransformer.php index 39bd452a3..439d5c873 100644 --- a/app/Transformers/Api/Application/NodeTransformer.php +++ b/app/Transformers/Api/Application/NodeTransformer.php @@ -31,7 +31,7 @@ class NodeTransformer extends BaseTransformer $response = collect($node->toArray())->mapWithKeys(function ($value, $key) { // I messed up early in 2016 when I named this column as poorly // as I did. This is the tragic result of my mistakes. - $key = ($key === 'daemonSFTP') ? 'daemonSftp' : $key; + $key = ($key === 'daemon_sftp') ? 'daemon_sftp' : $key; return [snake_case($key) => $value]; })->toArray(); diff --git a/app/Transformers/Api/Application/ServerTransformer.php b/app/Transformers/Api/Application/ServerTransformer.php index 4f789f99d..b315422c5 100644 --- a/app/Transformers/Api/Application/ServerTransformer.php +++ b/app/Transformers/Api/Application/ServerTransformer.php @@ -52,7 +52,7 @@ class ServerTransformer extends BaseTransformer 'id' => $server->getKey(), 'external_id' => $server->external_id, 'uuid' => $server->uuid, - 'identifier' => $server->uuidShort, + 'identifier' => $server->uuid_short, 'name' => $server->name, 'description' => $server->description, 'status' => $server->status, diff --git a/app/Transformers/Api/Client/ServerTransformer.php b/app/Transformers/Api/Client/ServerTransformer.php index 2c8ee8fe5..aece52bd5 100644 --- a/app/Transformers/Api/Client/ServerTransformer.php +++ b/app/Transformers/Api/Client/ServerTransformer.php @@ -38,7 +38,7 @@ class ServerTransformer extends BaseClientTransformer return [ 'server_owner' => $user->id === $server->owner_id, - 'identifier' => $server->uuidShort, + 'identifier' => $server->uuid_short, 'internal_id' => $server->id, 'uuid' => $server->uuid, 'name' => $server->name, @@ -46,7 +46,7 @@ class ServerTransformer extends BaseClientTransformer 'is_node_under_maintenance' => $server->node->isUnderMaintenance(), 'sftp_details' => [ 'ip' => $server->node->fqdn, - 'port' => $server->node->daemonSFTP, + 'port' => $server->node->daemon_sftp, ], 'description' => $server->description, 'limits' => [ diff --git a/database/Factories/NodeFactory.php b/database/Factories/NodeFactory.php index c879683bb..ccee27214 100644 --- a/database/Factories/NodeFactory.php +++ b/database/Factories/NodeFactory.php @@ -36,9 +36,9 @@ class NodeFactory extends Factory 'upload_size' => 100, 'daemon_token_id' => Str::random(Node::DAEMON_TOKEN_ID_LENGTH), 'daemon_token' => Crypt::encrypt(Str::random(Node::DAEMON_TOKEN_LENGTH)), - 'daemonListen' => 8080, - 'daemonSFTP' => 2022, - 'daemonBase' => '/var/lib/pelican/volumes', + 'daemon_listen' => 8080, + 'daemon_sftp' => 2022, + 'daemon_base' => '/var/lib/panel/volumes', ]; } } diff --git a/database/Factories/ServerFactory.php b/database/Factories/ServerFactory.php index c454ca26e..3bd7931b3 100644 --- a/database/Factories/ServerFactory.php +++ b/database/Factories/ServerFactory.php @@ -24,7 +24,7 @@ class ServerFactory extends Factory { return [ 'uuid' => Uuid::uuid4()->toString(), - 'uuidShort' => Str::lower(Str::random(8)), + 'uuid_short' => Str::lower(Str::random(8)), 'name' => $this->faker->firstName(), 'description' => implode(' ', $this->faker->sentences()), 'skip_scripts' => 0, diff --git a/database/migrations/2024_04_14_002250_update_column_names.php b/database/migrations/2024_04_14_002250_update_column_names.php new file mode 100644 index 000000000..21303f36b --- /dev/null +++ b/database/migrations/2024_04_14_002250_update_column_names.php @@ -0,0 +1,44 @@ +string('daemonBase', 191)->default(null)->change(); + }); + + Schema::table('nodes', function (Blueprint $table) { + $table->renameColumn('daemonListen', 'daemon_listen'); + $table->renameColumn('daemonBase', 'daemon_base'); + $table->renameColumn('daemonSFTP', 'daemon_sftp'); + }); + + Schema::table('servers', function (Blueprint $table) { + $table->renameColumn('uuidShort', 'uuid_short'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('nodes', function (Blueprint $table) { + $table->renameColumn('daemon_listen', 'daemonListen'); + $table->renameColumn('daemon_sftp', 'daemonSFTP'); + $table->renameColumn('daemon_base', 'daemonBase'); + }); + + Schema::table('servers', function (Blueprint $table) { + $table->renameColumn('uuid_short', 'uuidShort'); + }); + } +}; diff --git a/package.json b/package.json index 82fc4d539..11f9b9020 100644 --- a/package.json +++ b/package.json @@ -133,10 +133,10 @@ "clean": "cd public/assets && find . \\( -name \"*.js\" -o -name \"*.map\" \\) -type f -delete", "test": "jest", "lint": "eslint ./resources/scripts/**/*.{ts,tsx} --ext .ts,.tsx", - "watch": "cross-env NODE_ENV=development ./node_modules/.bin/webpack --watch --progress", + "watch": "cross-env NODE_OPTIONS='--openssl-legacy-provider' NODE_ENV=development ./node_modules/.bin/webpack --watch --progress", "build": "cross-env NODE_OPTIONS='--openssl-legacy-provider' NODE_ENV=development ./node_modules/.bin/webpack --progress", "build:production": "yarn run clean && cross-env NODE_OPTIONS='--openssl-legacy-provider' NODE_ENV=production ./node_modules/.bin/webpack --mode production", - "serve": "yarn run clean && cross-env WEBPACK_PUBLIC_PATH=/webpack@hmr/ NODE_ENV=development webpack-dev-server --host 0.0.0.0 --port 8080 --public https://panel.test --hot" + "serve": "yarn run clean && cross-env WEBPACK_PUBLIC_PATH=/webpack@hmr/ NODE_OPTIONS='--openssl-legacy-provider' NODE_ENV=development webpack-dev-server --host 0.0.0.0 --port 8080 --public https://panel.test --hot" }, "browserslist": [ "> 0.5%", diff --git a/resources/views/admin/nodes/index.blade.php b/resources/views/admin/nodes/index.blade.php index f2ff1617a..8f003d953 100644 --- a/resources/views/admin/nodes/index.blade.php +++ b/resources/views/admin/nodes/index.blade.php @@ -49,7 +49,7 @@ @foreach ($nodes as $node)
Enter the directory where server files should be stored. If you use OVH you should check your partition scheme. You may need to use /home/daemon-data
to have enough space.
The daemon runs its own SFTP management container and does not use the SSHd process on the main physical server. Do not use the same port that you have assigned for your physical server's SSH process. If you will be running the daemon behind CloudFlare® you should set the daemon port to 8443
to allow websocket proxying over SSL.
{{ $server->uuidShort }}
{{ $server->uuid_short }}
{{ $server->uuid }}