Skip to content

Commit 78c4ac8

Browse files
committed
Basic implemention of multiple selectable images for an egg
The admin side of this is quite ugly when creating/editing a server, but I'm not putting effort into that right now with React Admin soon™
1 parent 3e65a2d commit 78c4ac8

File tree

11 files changed

+123
-31
lines changed

11 files changed

+123
-31
lines changed

app/Http/Controllers/Admin/Servers/CreateServerController.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,17 +111,19 @@ public function index()
111111
*
112112
* @throws \Illuminate\Validation\ValidationException
113113
* @throws \Pterodactyl\Exceptions\DisplayException
114-
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
115-
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
116114
* @throws \Pterodactyl\Exceptions\Service\Deployment\NoViableAllocationException
117115
* @throws \Pterodactyl\Exceptions\Service\Deployment\NoViableNodeException
118116
* @throws \Throwable
119117
*/
120118
public function store(ServerFormRequest $request)
121119
{
122-
$server = $this->creationService->handle(
123-
$request->except(['_token'])
124-
);
120+
$data = $request->except(['_token']);
121+
if (!empty($data['custom_image'])) {
122+
$data['image'] = $data['custom_image'];
123+
unset($data['custom_image']);
124+
}
125+
126+
$server = $this->creationService->handle($data);
125127

126128
$this->alert->success(
127129
trans('admin/server.alerts.server_created')

app/Http/Controllers/Admin/ServersController.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,14 +334,19 @@ public function delete(Request $request, Server $server)
334334
* @return \Illuminate\Http\RedirectResponse
335335
*
336336
* @throws \Illuminate\Validation\ValidationException
337-
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
338337
*/
339338
public function saveStartup(Request $request, Server $server)
340339
{
340+
$data = $request->except('_token');
341+
if (!empty($data['custom_docker_image'])) {
342+
$data['docker_image'] = $data['custom_docker_image'];
343+
unset($data['custom_docker_image']);
344+
}
345+
341346
try {
342347
$this->startupModificationService
343348
->setUserLevel(User::USER_LEVEL_ADMIN)
344-
->handle($server, $request->except('_token'));
349+
->handle($server, $data);
345350
} catch (DataValidationException $exception) {
346351
throw new ValidationException($exception->validator);
347352
}

app/Http/Requests/Admin/ServerFormRequest.php

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
11
<?php
2-
/**
3-
* Pterodactyl - Panel
4-
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
5-
*
6-
* This software is licensed under the terms of the MIT license.
7-
* https://opensource.org/licenses/MIT
8-
*/
92

103
namespace Pterodactyl\Http\Requests\Admin;
114

@@ -23,6 +16,7 @@ public function rules()
2316
{
2417
$rules = Server::getRules();
2518
$rules['description'][] = 'nullable';
19+
$rules['custom_image'] = 'sometimes|nullable|string';
2620

2721
return $rules;
2822
}

app/Models/Egg.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
* @property string $name
1111
* @property string|null $description
1212
* @property array|null $features
13-
* @property string $docker_image
13+
* @property string $docker_image -- deprecated, use $docker_images
14+
* @property string $update_url
15+
* @property array $docker_images
1416
* @property string|null $config_files
1517
* @property string|null $config_startup
1618
* @property string|null $config_logs
@@ -76,7 +78,7 @@ class Egg extends Model
7678
'name',
7779
'description',
7880
'features',
79-
'docker_image',
81+
'docker_images',
8082
'config_files',
8183
'config_startup',
8284
'config_logs',
@@ -101,6 +103,7 @@ class Egg extends Model
101103
'script_is_privileged' => 'boolean',
102104
'copy_script_from' => 'integer',
103105
'features' => 'array',
106+
'docker_images' => 'array',
104107
];
105108

106109
/**
@@ -113,13 +116,15 @@ class Egg extends Model
113116
'description' => 'string|nullable',
114117
'features' => 'array|nullable',
115118
'author' => 'required|string|email',
116-
'docker_image' => 'required|string|max:191',
119+
'docker_images' => 'required|array|min:1',
120+
'docker_images.*' => 'required|string',
117121
'startup' => 'required|nullable|string',
118122
'config_from' => 'sometimes|bail|nullable|numeric|exists:eggs,id',
119123
'config_stop' => 'required_without:config_from|nullable|string|max:191',
120124
'config_startup' => 'required_without:config_from|nullable|json',
121125
'config_logs' => 'required_without:config_from|nullable|json',
122126
'config_files' => 'required_without:config_from|nullable|json',
127+
'update_url' => 'sometimes|nullable|string',
123128
];
124129

125130
/**
@@ -131,6 +136,7 @@ class Egg extends Model
131136
'config_startup' => null,
132137
'config_logs' => null,
133138
'config_files' => null,
139+
'update_url' => null,
134140
];
135141

136142
/**

app/Services/Eggs/Sharing/EggExporterService.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,14 @@ public function handle(int $egg): string
3838
'_comment' => 'DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PTERODACTYL PANEL - PTERODACTYL.IO',
3939
'meta' => [
4040
'version' => 'PTDL_v1',
41+
'update_url' => $egg->update_url,
4142
],
4243
'exported_at' => Carbon::now()->toIso8601String(),
4344
'name' => $egg->name,
4445
'author' => $egg->author,
4546
'description' => $egg->description,
4647
'features' => $egg->features,
47-
'image' => $egg->docker_image,
48+
'images' => $egg->docker_images,
4849
'startup' => $egg->startup,
4950
'config' => [
5051
'files' => $egg->inherit_config_files,

app/Services/Eggs/Sharing/EggImporterService.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,10 @@ public function handle(UploadedFile $file, int $nest): Egg
102102
'name' => object_get($parsed, 'name'),
103103
'description' => object_get($parsed, 'description'),
104104
'features' => object_get($parsed, 'features'),
105-
'docker_image' => object_get($parsed, 'image'),
105+
// Maintain backwards compatability for eggs that are still using the old single image
106+
// string format. New eggs can provide an array of Docker images that can be used.
107+
'docker_images' => object_get($parsed, 'images') ?? [object_get($parsed, 'image')],
108+
'update_url' => object_get($parsed, 'meta.update_url'),
106109
'config_files' => object_get($parsed, 'config.files'),
107110
'config_startup' => object_get($parsed, 'config.startup'),
108111
'config_logs' => object_get($parsed, 'config.logs'),

app/Transformers/Api/Application/EggTransformer.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ public function transform(Egg $model)
4545
'nest' => $model->nest_id,
4646
'author' => $model->author,
4747
'description' => $model->description,
48-
'docker_image' => $model->docker_image,
48+
// "docker_image" is deprecated, but left here to avoid breaking too many things at once
49+
// in external software. We'll remove it down the road once things have gotten the chance
50+
// to upgrade to using "docker_images".
51+
'docker_image' => count($model->docker_images) > 0 ? $model->docker_images[0] : '',
52+
'docker_images' => $model->docker_images,
4953
'config' => [
5054
'files' => json_decode($model->config_files, true),
5155
'startup' => json_decode($model->config_startup, true),
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
use Illuminate\Support\Facades\DB;
4+
use Illuminate\Database\Migrations\Migration;
5+
use Illuminate\Database\Schema\Blueprint;
6+
use Illuminate\Support\Facades\Schema;
7+
8+
class SupportMultipleDockerImagesAndUpdates extends Migration
9+
{
10+
/**
11+
* Run the migrations.
12+
*
13+
* @return void
14+
*/
15+
public function up()
16+
{
17+
Schema::table('eggs', function (Blueprint $table) {
18+
$table->json('docker_images')->after('docker_image')->nullable();
19+
$table->text('update_url')->after('docker_images')->nullable();
20+
});
21+
22+
Schema::table('eggs', function (Blueprint $table) {
23+
DB::statement('UPDATE `eggs` SET `docker_images` = JSON_ARRAY(docker_image)');
24+
});
25+
26+
Schema::table('eggs', function (Blueprint $table) {
27+
$table->dropColumn('docker_image');
28+
});
29+
}
30+
31+
/**
32+
* Reverse the migrations.
33+
*
34+
* @return void
35+
*/
36+
public function down()
37+
{
38+
Schema::table('eggs', function (Blueprint $table) {
39+
$table->text('docker_image')->after('docker_images');
40+
});
41+
42+
Schema::table('eggs', function (Blueprint $table) {
43+
DB::statement('UPDATE `eggs` SET `docker_image` = JSON_UNQUOTE(JSON_EXTRACT(docker_images, "$[0]"))');
44+
});
45+
46+
Schema::table('eggs', function (Blueprint $table) {
47+
$table->dropColumn('docker_images');
48+
$table->dropColumn('update_url');
49+
});
50+
}
51+
}

public/themes/pterodactyl/js/admin/new-server.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,13 @@ $('#pEggId').on('change', function (event) {
8282
let parentChain = _.get(Pterodactyl.nests, $('#pNestId').val(), null);
8383
let objectChain = _.get(parentChain, 'eggs.' + $(this).val(), null);
8484

85-
$('#pDefaultContainer').val(_.get(objectChain, 'docker_image', 'not defined!'));
85+
const images = _.get(objectChain, 'docker_images', [])
86+
for (let i = 0; i < images.length; i++) {
87+
let opt = document.createElement('option');
88+
opt.value = images[i];
89+
opt.innerHTML = images[i];
90+
$('#pDefaultContainer').append(opt);
91+
}
8692

8793
if (!_.get(objectChain, 'startup', false)) {
8894
$('#pStartup').val(_.get(parentChain, 'startup', 'ERROR: Startup Not Defined!'));

resources/views/admin/servers/new.blade.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,9 @@
265265
<div class="box-body row">
266266
<div class="form-group col-xs-12">
267267
<label for="pDefaultContainer">Docker Image</label>
268-
<input id="pDefaultContainer" name="image" value="{{ old('image') }}" class="form-control" />
269-
<p class="small text-muted no-margin">This is the default Docker image that will be used to run this server.</p>
268+
<select id="pDefaultContainer" name="image" class="form-control"></select>
269+
<input id="pDefaultContainerCustom" name="custom_image" value="{{ old('custom_image') }}" class="form-control" placeholder="Or enter a custom image..." style="margin-top:1rem"/>
270+
<p class="small text-muted no-margin">This is the default Docker image that will be used to run this server. Select an image from the dropdown above, or enter a custom image in the text field above.</p>
270271
</div>
271272
</div>
272273
</div>
@@ -323,11 +324,14 @@ function serviceVariablesUpdated(eggId, ids) {
323324
@endforeach
324325
@endif
325326
@endif
327+
@if(old('image'))
328+
$('#pDefaultContainer').val('{{ old('image') }}');
329+
@endif
326330
}
327331
// END Persist 'Service Variables'
328332
</script>
329333

330-
{!! Theme::js('js/admin/new-server.js?v=20201003') !!}
334+
{!! Theme::js('js/admin/new-server.js?v=20201212') !!}
331335

332336
<script type="application/javascript">
333337
$(document).ready(function() {

0 commit comments

Comments
 (0)