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 #57
This commit is contained in:
parent
5678d643cd
commit
a903ae313a
5 changed files with 150 additions and 84 deletions
|
@ -25,6 +25,7 @@ namespace Pterodactyl\Http\Controllers\Admin;
|
||||||
|
|
||||||
use Alert;
|
use Alert;
|
||||||
use Debugbar;
|
use Debugbar;
|
||||||
|
use DB;
|
||||||
use Log;
|
use Log;
|
||||||
|
|
||||||
use Pterodactyl\Models;
|
use Pterodactyl\Models;
|
||||||
|
@ -196,11 +197,7 @@ class ServersController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
$service = Models\Service::select('executable', 'startup')->where('id', $request->input('service'))->first();
|
$service = Models\Service::select('executable', 'startup')->where('id', $request->input('service'))->first();
|
||||||
return response()->json([
|
return response()->json(Models\ServiceOptions::select('id', 'name', 'docker_image')->where('parent_service', $request->input('service'))->orderBy('name', 'asc')->get());
|
||||||
'exec' => $service->executable,
|
|
||||||
'startup' => $service->startup,
|
|
||||||
'options' => Models\ServiceOptions::select('id', 'name', 'docker_image')->where('parent_service', $request->input('service'))->orderBy('name', 'asc')->get()
|
|
||||||
]);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +216,18 @@ class ServersController extends Controller
|
||||||
], 500);
|
], 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(Models\ServiceVariables::where('option_id', $request->input('option'))->get());
|
$option = Models\ServiceOptions::select(
|
||||||
|
DB::raw('COALESCE(service_options.executable, services.executable) as executable'),
|
||||||
|
DB::raw('COALESCE(service_options.startup, services.startup) as startup')
|
||||||
|
)->leftJoin('services', 'services.id', '=', 'service_options.parent_service')
|
||||||
|
->where('service_options.id', $request->input('option'))
|
||||||
|
->first();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'variables' => Models\ServiceVariables::where('option_id', $request->input('option'))->get(),
|
||||||
|
'exec' => $option->executable,
|
||||||
|
'startup' => $option->startup
|
||||||
|
]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
namespace Pterodactyl\Http\Controllers\Server;
|
namespace Pterodactyl\Http\Controllers\Server;
|
||||||
|
|
||||||
use Auth;
|
use Auth;
|
||||||
|
use DB;
|
||||||
use Debugbar;
|
use Debugbar;
|
||||||
use Uuid;
|
use Uuid;
|
||||||
use Alert;
|
use Alert;
|
||||||
|
@ -194,12 +195,24 @@ class ServerController extends Controller
|
||||||
public function getSettings(Request $request, $uuid)
|
public function getSettings(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::getByUUID($uuid);
|
||||||
$variables = Models\ServiceVariables::select('service_variables.*', 'server_variables.variable_value as a_serverValue')
|
// $variables = Models\ServiceVariables::select('service_variables.*', 'server_variables.variable_value as a_serverValue')
|
||||||
->join('server_variables', 'server_variables.variable_id', '=', 'service_variables.id')
|
// ->join('server_variables', 'server_variables.variable_id', '=', 'service_variables.id')
|
||||||
->where('service_variables.option_id', $server->option)
|
// ->where('service_variables.option_id', $server->option)
|
||||||
->where('server_variables.server_id', $server->id)
|
// ->where('server_variables.server_id', $server->id)
|
||||||
|
// ->get();
|
||||||
|
$variables = Models\ServiceVariables::select(
|
||||||
|
'service_variables.*',
|
||||||
|
DB::raw('COALESCE(server_variables.variable_value, service_variables.default_value) as a_serverValue')
|
||||||
|
)->leftJoin('server_variables', 'server_variables.variable_id', '=', 'service_variables.id')
|
||||||
|
->where('option_id', $server->option)
|
||||||
->get();
|
->get();
|
||||||
$service = Models\Service::findOrFail($server->service);
|
|
||||||
|
$service = Models\Service::select(
|
||||||
|
DB::raw('COALESCE(service_options.executable, services.executable) as executable'),
|
||||||
|
DB::raw('COALESCE(service_options.startup, services.startup) as startup')
|
||||||
|
)->leftJoin('service_options', 'service_options.parent_service', '=', 'services.id')
|
||||||
|
->where('services.id', $server->service)
|
||||||
|
->first();
|
||||||
|
|
||||||
$serverVariables = [
|
$serverVariables = [
|
||||||
'{{SERVER_MEMORY}}' => $server->memory,
|
'{{SERVER_MEMORY}}' => $server->memory,
|
||||||
|
@ -216,7 +229,7 @@ class ServerController extends Controller
|
||||||
return view('server.settings', [
|
return view('server.settings', [
|
||||||
'server' => $server,
|
'server' => $server,
|
||||||
'node' => Models\Node::find($server->node),
|
'node' => Models\Node::find($server->node),
|
||||||
'variables' => $variables,
|
'variables' => $variables->where('user_viewable', 1),
|
||||||
'service' => $service,
|
'service' => $service,
|
||||||
'processedStartup' => $processed,
|
'processedStartup' => $processed,
|
||||||
]);
|
]);
|
||||||
|
@ -258,12 +271,11 @@ class ServerController extends Controller
|
||||||
} catch(\Exception $ex) {
|
} catch(\Exception $ex) {
|
||||||
Log::error($ex);
|
Log::error($ex);
|
||||||
Alert::danger('An unhandled exception occured while attemping to update startup variables for this server. Please try again.')->flash();
|
Alert::danger('An unhandled exception occured while attemping to update startup variables for this server. Please try again.')->flash();
|
||||||
} finally {
|
|
||||||
return redirect()->route('server.settings', [
|
|
||||||
'uuid' => $uuid,
|
|
||||||
'tab' => 'tab_startup'
|
|
||||||
])->withInput();
|
|
||||||
}
|
}
|
||||||
|
return redirect()->route('server.settings', [
|
||||||
|
'uuid' => $uuid,
|
||||||
|
'tab' => 'tab_startup'
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -554,70 +554,83 @@ class ServerRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check those Variables
|
// Check those Variables
|
||||||
$variables = Models\ServiceVariables::select('service_variables.*', 'server_variables.variable_value as a_currentValue')
|
$variables = Models\ServiceVariables::select(
|
||||||
->join('server_variables', 'server_variables.variable_id', '=', 'service_variables.id')
|
'service_variables.*',
|
||||||
->where('option_id', $server->option)->get();
|
DB::raw('COALESCE(server_variables.variable_value, service_variables.default_value) as a_currentValue')
|
||||||
|
)->leftJoin('server_variables', 'server_variables.variable_id', '=', 'service_variables.id')
|
||||||
$variableList = [];
|
->where('option_id', $server->option)
|
||||||
if ($variables) {
|
->get();
|
||||||
foreach($variables as &$variable) {
|
|
||||||
// Move on if the new data wasn't even sent
|
|
||||||
if (!isset($data[$variable->env_variable])) {
|
|
||||||
$variableList = array_merge($variableList, [[
|
|
||||||
'id' => $variable->id,
|
|
||||||
'env' => $variable->env_variable,
|
|
||||||
'val' => $variable->a_currentValue
|
|
||||||
]]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update Empty but skip validation
|
|
||||||
if (empty($data[$variable->env_variable])) {
|
|
||||||
$variableList = array_merge($variableList, [[
|
|
||||||
'id' => $variable->id,
|
|
||||||
'env' => $variable->env_variable,
|
|
||||||
'val' => null
|
|
||||||
]]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is the variable required?
|
|
||||||
// @TODO: is this even logical to perform this check?
|
|
||||||
if (isset($data[$variable->env_variable]) && empty($data[$variable->env_variable])) {
|
|
||||||
if ($variable->required === 1) {
|
|
||||||
throw new DisplayException('A required service option variable field (' . $variable->env_variable . ') was included in this request but was left blank.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check aganist Regex Pattern
|
|
||||||
if (!is_null($variable->regex) && !preg_match($variable->regex, $data[$variable->env_variable])) {
|
|
||||||
throw new DisplayException('Failed to validate service option variable field (' . $variable->env_variable . ') aganist regex (' . $variable->regex . ').');
|
|
||||||
}
|
|
||||||
|
|
||||||
$variableList = array_merge($variableList, [[
|
|
||||||
'id' => $variable->id,
|
|
||||||
'env' => $variable->env_variable,
|
|
||||||
'val' => $data[$variable->env_variable]
|
|
||||||
]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add Variables
|
|
||||||
$environmentVariables = [];
|
|
||||||
$environmentVariables = array_merge($environmentVariables, [
|
|
||||||
'STARTUP' => $server->startup
|
|
||||||
]);
|
|
||||||
foreach($variableList as $item) {
|
|
||||||
$environmentVariables = array_merge($environmentVariables, [
|
|
||||||
$item['env'] => $item['val']
|
|
||||||
]);
|
|
||||||
$var = Models\ServerVariables::where('server_id', $server->id)->where('variable_id', $item['id'])->update([
|
|
||||||
'variable_value' => $item['val']
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
$variableList = [];
|
||||||
|
if ($variables) {
|
||||||
|
foreach($variables as &$variable) {
|
||||||
|
// Move on if the new data wasn't even sent
|
||||||
|
if (!isset($data[$variable->env_variable])) {
|
||||||
|
$variableList = array_merge($variableList, [[
|
||||||
|
'id' => $variable->id,
|
||||||
|
'env' => $variable->env_variable,
|
||||||
|
'val' => $variable->a_currentValue
|
||||||
|
]]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update Empty but skip validation
|
||||||
|
if (empty($data[$variable->env_variable])) {
|
||||||
|
$variableList = array_merge($variableList, [[
|
||||||
|
'id' => $variable->id,
|
||||||
|
'env' => $variable->env_variable,
|
||||||
|
'val' => null
|
||||||
|
]]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the variable required?
|
||||||
|
// @TODO: is this even logical to perform this check?
|
||||||
|
if (isset($data[$variable->env_variable]) && empty($data[$variable->env_variable])) {
|
||||||
|
if ($variable->required === 1) {
|
||||||
|
throw new DisplayException('A required service option variable field (' . $variable->env_variable . ') was included in this request but was left blank.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variable hidden and/or not user editable
|
||||||
|
if ($variable->user_viewable === 0 || $variable->user_editable === 0) {
|
||||||
|
throw new DisplayException('A service option variable field (' . $variable->env_variable . ') does not exist or you do not have permission to edit it.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check aganist Regex Pattern
|
||||||
|
if (!is_null($variable->regex) && !preg_match($variable->regex, $data[$variable->env_variable])) {
|
||||||
|
throw new DisplayException('Failed to validate service option variable field (' . $variable->env_variable . ') aganist regex (' . $variable->regex . ').');
|
||||||
|
}
|
||||||
|
|
||||||
|
$variableList = array_merge($variableList, [[
|
||||||
|
'id' => $variable->id,
|
||||||
|
'env' => $variable->env_variable,
|
||||||
|
'val' => $data[$variable->env_variable]
|
||||||
|
]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add Variables
|
||||||
|
$environmentVariables = [];
|
||||||
|
$environmentVariables = array_merge($environmentVariables, [
|
||||||
|
'STARTUP' => $server->startup
|
||||||
|
]);
|
||||||
|
foreach($variableList as $item) {
|
||||||
|
$environmentVariables = array_merge($environmentVariables, [
|
||||||
|
$item['env'] => $item['val']
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Update model or make a new record if it doesn't exist.
|
||||||
|
$model = Models\ServerVariables::firstOrNew([
|
||||||
|
'variable_id' => $item['id'],
|
||||||
|
'server_id' => $server->id
|
||||||
|
]);
|
||||||
|
$model->variable_value = $item['val'];
|
||||||
|
$model->save();
|
||||||
|
}
|
||||||
|
|
||||||
$node = Models\Node::getByID($server->node);
|
$node = Models\Node::getByID($server->node);
|
||||||
$client = Models\Node::guzzleRequest($server->node);
|
$client = Models\Node::guzzleRequest($server->node);
|
||||||
|
|
||||||
|
@ -638,9 +651,9 @@ class ServerRepository
|
||||||
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw new DisplayException('An error occured while attempting to update the server configuration: ' . $ex->getMessage());
|
throw new DisplayException('An error occured while attempting to update the server configuration: ' . $ex->getMessage());
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw $e;
|
throw $ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddServiceOptionDefaultStartup extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('service_options', function (Blueprint $table) {
|
||||||
|
$table->text('executable')->after('docker_image')->nullable()->default(null);
|
||||||
|
$table->text('startup')->after('executable')->nullable()->default(null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('service_options', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('executable');
|
||||||
|
$table->dropColumn('startup');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -362,9 +362,7 @@ $(document).ready(function () {
|
||||||
service: $('#getService').val()
|
service: $('#getService').val()
|
||||||
}
|
}
|
||||||
}).done(function (data) {
|
}).done(function (data) {
|
||||||
$('#startupExec').html(data.exec);
|
$.each(data, function (i, option) {
|
||||||
$('input[name="startup"]').val(data.startup);
|
|
||||||
$.each(data.options, function (i, option) {
|
|
||||||
$('#getOption').append('<option value="' + option.id + '" data-image="' + option.docker_image + '">' + option.name + '</option>');
|
$('#getOption').append('<option value="' + option.id + '" data-image="' + option.docker_image + '">' + option.name + '</option>');
|
||||||
});
|
});
|
||||||
$('#getOption').parent().parent().removeClass('hidden');
|
$('#getOption').parent().parent().removeClass('hidden');
|
||||||
|
@ -395,7 +393,9 @@ $(document).ready(function () {
|
||||||
option: $('#getOption').val()
|
option: $('#getOption').val()
|
||||||
}
|
}
|
||||||
}).done(function (data) {
|
}).done(function (data) {
|
||||||
$.each(data, function (i, item) {
|
$('#startupExec').html(data.exec);
|
||||||
|
$('input[name="startup"]').val(data.startup);
|
||||||
|
$.each(data.variables, function (i, item) {
|
||||||
var isRequired = (item.required === 1) ? '<span class="label label-primary">Required</span> ' : '';
|
var isRequired = (item.required === 1) ? '<span class="label label-primary">Required</span> ' : '';
|
||||||
var dataAppend = ' \
|
var dataAppend = ' \
|
||||||
<div class="form-group col-md-12">\
|
<div class="form-group col-md-12">\
|
||||||
|
|
Loading…
Reference in a new issue