Skip to content

Commit a903ae3

Browse files
committed
Add per-service-option startup & executable
Also fixes display issue on front-end where users could see and edit hidden settings Fixes a bug in relation to pterodactyl#57
1 parent 5678d64 commit a903ae3

File tree

5 files changed

+140
-74
lines changed

5 files changed

+140
-74
lines changed

app/Http/Controllers/Admin/ServersController.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
use Alert;
2727
use Debugbar;
28+
use DB;
2829
use Log;
2930

3031
use Pterodactyl\Models;
@@ -196,11 +197,7 @@ public function postNewServerServiceOptions(Request $request)
196197
}
197198

198199
$service = Models\Service::select('executable', 'startup')->where('id', $request->input('service'))->first();
199-
return response()->json([
200-
'exec' => $service->executable,
201-
'startup' => $service->startup,
202-
'options' => Models\ServiceOptions::select('id', 'name', 'docker_image')->where('parent_service', $request->input('service'))->orderBy('name', 'asc')->get()
203-
]);
200+
return response()->json(Models\ServiceOptions::select('id', 'name', 'docker_image')->where('parent_service', $request->input('service'))->orderBy('name', 'asc')->get());
204201

205202
}
206203

@@ -219,7 +216,18 @@ public function postNewServerServiceVariables(Request $request)
219216
], 500);
220217
}
221218

222-
return response()->json(Models\ServiceVariables::where('option_id', $request->input('option'))->get());
219+
$option = Models\ServiceOptions::select(
220+
DB::raw('COALESCE(service_options.executable, services.executable) as executable'),
221+
DB::raw('COALESCE(service_options.startup, services.startup) as startup')
222+
)->leftJoin('services', 'services.id', '=', 'service_options.parent_service')
223+
->where('service_options.id', $request->input('option'))
224+
->first();
225+
226+
return response()->json([
227+
'variables' => Models\ServiceVariables::where('option_id', $request->input('option'))->get(),
228+
'exec' => $option->executable,
229+
'startup' => $option->startup
230+
]);
223231

224232
}
225233

app/Http/Controllers/Server/ServerController.php

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
namespace Pterodactyl\Http\Controllers\Server;
2525

2626
use Auth;
27+
use DB;
2728
use Debugbar;
2829
use Uuid;
2930
use Alert;
@@ -194,12 +195,24 @@ public function getDownloadFile(Request $request, $uuid, $file)
194195
public function getSettings(Request $request, $uuid)
195196
{
196197
$server = Models\Server::getByUUID($uuid);
197-
$variables = Models\ServiceVariables::select('service_variables.*', 'server_variables.variable_value as a_serverValue')
198-
->join('server_variables', 'server_variables.variable_id', '=', 'service_variables.id')
199-
->where('service_variables.option_id', $server->option)
200-
->where('server_variables.server_id', $server->id)
198+
// $variables = Models\ServiceVariables::select('service_variables.*', 'server_variables.variable_value as a_serverValue')
199+
// ->join('server_variables', 'server_variables.variable_id', '=', 'service_variables.id')
200+
// ->where('service_variables.option_id', $server->option)
201+
// ->where('server_variables.server_id', $server->id)
202+
// ->get();
203+
$variables = Models\ServiceVariables::select(
204+
'service_variables.*',
205+
DB::raw('COALESCE(server_variables.variable_value, service_variables.default_value) as a_serverValue')
206+
)->leftJoin('server_variables', 'server_variables.variable_id', '=', 'service_variables.id')
207+
->where('option_id', $server->option)
201208
->get();
202-
$service = Models\Service::findOrFail($server->service);
209+
210+
$service = Models\Service::select(
211+
DB::raw('COALESCE(service_options.executable, services.executable) as executable'),
212+
DB::raw('COALESCE(service_options.startup, services.startup) as startup')
213+
)->leftJoin('service_options', 'service_options.parent_service', '=', 'services.id')
214+
->where('services.id', $server->service)
215+
->first();
203216

204217
$serverVariables = [
205218
'{{SERVER_MEMORY}}' => $server->memory,
@@ -216,7 +229,7 @@ public function getSettings(Request $request, $uuid)
216229
return view('server.settings', [
217230
'server' => $server,
218231
'node' => Models\Node::find($server->node),
219-
'variables' => $variables,
232+
'variables' => $variables->where('user_viewable', 1),
220233
'service' => $service,
221234
'processedStartup' => $processed,
222235
]);
@@ -258,12 +271,11 @@ public function postSettingsStartup(Request $request, $uuid)
258271
} catch(\Exception $ex) {
259272
Log::error($ex);
260273
Alert::danger('An unhandled exception occured while attemping to update startup variables for this server. Please try again.')->flash();
261-
} finally {
262-
return redirect()->route('server.settings', [
263-
'uuid' => $uuid,
264-
'tab' => 'tab_startup'
265-
])->withInput();
266274
}
275+
return redirect()->route('server.settings', [
276+
'uuid' => $uuid,
277+
'tab' => 'tab_startup'
278+
]);
267279
}
268280

269281
}

app/Repositories/ServerRepository.php

Lines changed: 66 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -554,69 +554,82 @@ public function updateStartup($id, array $data)
554554
}
555555

556556
// Check those Variables
557-
$variables = Models\ServiceVariables::select('service_variables.*', 'server_variables.variable_value as a_currentValue')
558-
->join('server_variables', 'server_variables.variable_id', '=', 'service_variables.id')
559-
->where('option_id', $server->option)->get();
557+
$variables = Models\ServiceVariables::select(
558+
'service_variables.*',
559+
DB::raw('COALESCE(server_variables.variable_value, service_variables.default_value) as a_currentValue')
560+
)->leftJoin('server_variables', 'server_variables.variable_id', '=', 'service_variables.id')
561+
->where('option_id', $server->option)
562+
->get();
560563

561-
$variableList = [];
562-
if ($variables) {
563-
foreach($variables as &$variable) {
564-
// Move on if the new data wasn't even sent
565-
if (!isset($data[$variable->env_variable])) {
566-
$variableList = array_merge($variableList, [[
567-
'id' => $variable->id,
568-
'env' => $variable->env_variable,
569-
'val' => $variable->a_currentValue
570-
]]);
571-
continue;
572-
}
564+
try {
565+
566+
$variableList = [];
567+
if ($variables) {
568+
foreach($variables as &$variable) {
569+
// Move on if the new data wasn't even sent
570+
if (!isset($data[$variable->env_variable])) {
571+
$variableList = array_merge($variableList, [[
572+
'id' => $variable->id,
573+
'env' => $variable->env_variable,
574+
'val' => $variable->a_currentValue
575+
]]);
576+
continue;
577+
}
578+
579+
// Update Empty but skip validation
580+
if (empty($data[$variable->env_variable])) {
581+
$variableList = array_merge($variableList, [[
582+
'id' => $variable->id,
583+
'env' => $variable->env_variable,
584+
'val' => null
585+
]]);
586+
continue;
587+
}
588+
589+
// Is the variable required?
590+
// @TODO: is this even logical to perform this check?
591+
if (isset($data[$variable->env_variable]) && empty($data[$variable->env_variable])) {
592+
if ($variable->required === 1) {
593+
throw new DisplayException('A required service option variable field (' . $variable->env_variable . ') was included in this request but was left blank.');
594+
}
595+
}
596+
597+
// Variable hidden and/or not user editable
598+
if ($variable->user_viewable === 0 || $variable->user_editable === 0) {
599+
throw new DisplayException('A service option variable field (' . $variable->env_variable . ') does not exist or you do not have permission to edit it.');
600+
}
601+
602+
// Check aganist Regex Pattern
603+
if (!is_null($variable->regex) && !preg_match($variable->regex, $data[$variable->env_variable])) {
604+
throw new DisplayException('Failed to validate service option variable field (' . $variable->env_variable . ') aganist regex (' . $variable->regex . ').');
605+
}
573606

574-
// Update Empty but skip validation
575-
if (empty($data[$variable->env_variable])) {
576607
$variableList = array_merge($variableList, [[
577608
'id' => $variable->id,
578609
'env' => $variable->env_variable,
579-
'val' => null
610+
'val' => $data[$variable->env_variable]
580611
]]);
581-
continue;
582-
}
583-
584-
// Is the variable required?
585-
// @TODO: is this even logical to perform this check?
586-
if (isset($data[$variable->env_variable]) && empty($data[$variable->env_variable])) {
587-
if ($variable->required === 1) {
588-
throw new DisplayException('A required service option variable field (' . $variable->env_variable . ') was included in this request but was left blank.');
589-
}
590612
}
591-
592-
// Check aganist Regex Pattern
593-
if (!is_null($variable->regex) && !preg_match($variable->regex, $data[$variable->env_variable])) {
594-
throw new DisplayException('Failed to validate service option variable field (' . $variable->env_variable . ') aganist regex (' . $variable->regex . ').');
595-
}
596-
597-
$variableList = array_merge($variableList, [[
598-
'id' => $variable->id,
599-
'env' => $variable->env_variable,
600-
'val' => $data[$variable->env_variable]
601-
]]);
602613
}
603-
}
604614

605-
// Add Variables
606-
$environmentVariables = [];
607-
$environmentVariables = array_merge($environmentVariables, [
608-
'STARTUP' => $server->startup
609-
]);
610-
foreach($variableList as $item) {
615+
// Add Variables
616+
$environmentVariables = [];
611617
$environmentVariables = array_merge($environmentVariables, [
612-
$item['env'] => $item['val']
618+
'STARTUP' => $server->startup
613619
]);
614-
$var = Models\ServerVariables::where('server_id', $server->id)->where('variable_id', $item['id'])->update([
615-
'variable_value' => $item['val']
616-
]);
617-
}
620+
foreach($variableList as $item) {
621+
$environmentVariables = array_merge($environmentVariables, [
622+
$item['env'] => $item['val']
623+
]);
618624

619-
try {
625+
// Update model or make a new record if it doesn't exist.
626+
$model = Models\ServerVariables::firstOrNew([
627+
'variable_id' => $item['id'],
628+
'server_id' => $server->id
629+
]);
630+
$model->variable_value = $item['val'];
631+
$model->save();
632+
}
620633

621634
$node = Models\Node::getByID($server->node);
622635
$client = Models\Node::guzzleRequest($server->node);
@@ -638,9 +651,9 @@ public function updateStartup($id, array $data)
638651
} catch (\GuzzleHttp\Exception\TransferException $ex) {
639652
DB::rollBack();
640653
throw new DisplayException('An error occured while attempting to update the server configuration: ' . $ex->getMessage());
641-
} catch (\Exception $e) {
654+
} catch (\Exception $ex) {
642655
DB::rollBack();
643-
throw $e;
656+
throw $ex;
644657
}
645658

646659
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
use Illuminate\Database\Schema\Blueprint;
4+
use Illuminate\Database\Migrations\Migration;
5+
6+
class AddServiceOptionDefaultStartup extends Migration
7+
{
8+
/**
9+
* Run the migrations.
10+
*
11+
* @return void
12+
*/
13+
public function up()
14+
{
15+
Schema::table('service_options', function (Blueprint $table) {
16+
$table->text('executable')->after('docker_image')->nullable()->default(null);
17+
$table->text('startup')->after('executable')->nullable()->default(null);
18+
});
19+
}
20+
21+
/**
22+
* Reverse the migrations.
23+
*
24+
* @return void
25+
*/
26+
public function down()
27+
{
28+
Schema::table('service_options', function (Blueprint $table) {
29+
$table->dropColumn('executable');
30+
$table->dropColumn('startup');
31+
});
32+
}
33+
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,7 @@
362362
service: $('#getService').val()
363363
}
364364
}).done(function (data) {
365-
$('#startupExec').html(data.exec);
366-
$('input[name="startup"]').val(data.startup);
367-
$.each(data.options, function (i, option) {
365+
$.each(data, function (i, option) {
368366
$('#getOption').append('<option value="' + option.id + '" data-image="' + option.docker_image + '">' + option.name + '</option>');
369367
});
370368
$('#getOption').parent().parent().removeClass('hidden');
@@ -395,7 +393,9 @@
395393
option: $('#getOption').val()
396394
}
397395
}).done(function (data) {
398-
$.each(data, function (i, item) {
396+
$('#startupExec').html(data.exec);
397+
$('input[name="startup"]').val(data.startup);
398+
$.each(data.variables, function (i, item) {
399399
var isRequired = (item.required === 1) ? '<span class="label label-primary">Required</span> ' : '';
400400
var dataAppend = ' \
401401
<div class="form-group col-md-12">\

0 commit comments

Comments
 (0)