diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index 299721ab..57227b6d 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -142,7 +142,12 @@ class ServersController extends Controller ], 500); } - return response()->json(Models\ServiceOptions::select('id', 'name', 'docker_image')->where('parent_service', $request->input('service'))->orderBy('name', 'asc')->get()); + $service = Models\Service::select('executable', 'startup')->where('id', $request->input('service'))->first(); + return response()->json([ + 'exec' => $service->executable, + 'startup' => $service->startup, + 'options' => Models\ServiceOptions::select('id', 'name', 'docker_image')->where('parent_service', $request->input('service'))->orderBy('name', 'asc')->get() + ]); } diff --git a/app/Repositories/ServerRepository.php b/app/Repositories/ServerRepository.php index 131a8ac5..d383917a 100644 --- a/app/Repositories/ServerRepository.php +++ b/app/Repositories/ServerRepository.php @@ -52,6 +52,7 @@ class ServerRepository 'node' => 'required|numeric|min:1|exists:nodes,id', 'name' => 'required|regex:([\w -]{4,35})', 'memory' => 'required|numeric|min:1', + 'swap' => 'required|numeric|min:0', 'disk' => 'required|numeric|min:1', 'cpu' => 'required|numeric|min:0', 'io' => 'required|numeric|min:10|max:1000', @@ -59,6 +60,7 @@ class ServerRepository 'port' => 'required|numeric|min:1|max:65535', 'service' => 'required|numeric|min:1|exists:services,id', 'option' => 'required|numeric|min:1|exists:service_options,id', + 'startup' => 'required', 'custom_image_name' => 'required_if:use_custom_image,on', ]); @@ -155,21 +157,25 @@ class ServerRepository // Add Server to the Database $server = new Models\Server; + $generatedUuid = $uuid->generate('servers', 'uuid'); $server->fill([ - 'uuid' => $uuid->generate('servers', 'uuid'), - 'uuidShort' => $uuid->generateShort(), + 'uuid' => $generatedUuid, + 'uuidShort' => $uuid->generateShort('servers', 'uuidShort', $generatedUuid), 'node' => $data['node'], 'name' => $data['name'], 'active' => 1, 'owner' => $user->id, 'memory' => $data['memory'], + 'swap' => $data['swap'], 'disk' => $data['disk'], 'io' => $data['io'], 'cpu' => $data['cpu'], + 'oom_disabled' => (isset($data['oom_disabled'])) ? true : false, 'ip' => $data['ip'], 'port' => $data['port'], 'service' => $data['service'], 'option' => $data['option'], + 'startup' => $data['startup'], 'daemonSecret' => $uuid->generate('servers', 'daemonSecret'), 'username' => $this->generateSFTPUsername($data['name']) ]); diff --git a/database/migrations/2016_01_02_023924_add_new_server_options.php b/database/migrations/2016_01_02_023924_add_new_server_options.php new file mode 100644 index 00000000..7a9b7f7e --- /dev/null +++ b/database/migrations/2016_01_02_023924_add_new_server_options.php @@ -0,0 +1,35 @@ +<?php + +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +class AddNewServerOptions extends Migration +{ + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + Schema::table('servers', function (Blueprint $table) { + $table->boolean('oom_disabled')->default(false)->after('cpu'); + $table->mediumInteger('swap')->default(0)->after('memory'); + $table->text('startup')->after('option'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('servers', function (Blueprint $table) { + $table->dropColumn('oom_enabled'); + $table->dropColumn('swap'); + $table->dropColumn('startup'); + }); + } +} diff --git a/database/migrations/2016_01_02_024253_modify_service_options.php b/database/migrations/2016_01_02_024253_modify_service_options.php new file mode 100644 index 00000000..840da3bd --- /dev/null +++ b/database/migrations/2016_01_02_024253_modify_service_options.php @@ -0,0 +1,33 @@ +<?php + +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +class ModifyServiceOptions extends Migration +{ + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + Schema::table('service_options', function (Blueprint $table) { + $table->dropColumn('config_file'); + $table->dropColumn('config_blob'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('service_options', function (Blueprint $table) { + $table->string('config_file')->after('description'); + $table->binary('config_blob')->after('config_file'); + }); + } +} diff --git a/database/migrations/2016_01_02_024552_modify_services_add_startup.php b/database/migrations/2016_01_02_024552_modify_services_add_startup.php new file mode 100644 index 00000000..38214a7b --- /dev/null +++ b/database/migrations/2016_01_02_024552_modify_services_add_startup.php @@ -0,0 +1,33 @@ +<?php + +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +class ModifyServicesAddStartup extends Migration +{ + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + Schema::table('services', function (Blueprint $table) { + $table->text('executable')->after('description'); + $table->text('startup')->after('executable'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('services', function (Blueprint $table) { + $table->dropColumn('executable'); + $table->dropColumn('startup'); + }); + } +} diff --git a/resources/views/admin/servers/new.blade.php b/resources/views/admin/servers/new.blade.php index 272f506e..0865f17a 100644 --- a/resources/views/admin/servers/new.blade.php +++ b/resources/views/admin/servers/new.blade.php @@ -96,31 +96,56 @@ </div> <div class="well"> <div class="row"> - <div class="form-group col-md-3 col-xs-6"> + <div class="form-group col-md-4 col-xs-4"> <label for="memory" class="control-label">Memory</label> <div class="input-group"> <input type="text" name="memory" class="form-control" value="{{ old('memory') }}"/> <span class="input-group-addon">MB</span> </div> </div> - <div class="form-group col-md-3 col-xs-6"> + <div class="form-group col-md-4 col-xs-4"> + <label for="memory" class="control-label">Swap</label> + <div class="input-group"> + <input type="text" name="swap" class="form-control" value="{{ old('swap', 0) }}"/> + <span class="input-group-addon">MB</span> + </div> + </div> + <div class="form-group col-md-4 col-xs-4"> + <label for="memory" class="control-label">OOM Killer</label> + <div> + <span class="input-group-addon" style="height:36px;"> + <input type="checkbox" name="oom_disabled"/> + </span> + <span class="input-group-addon" style="height:36px;"> + Disable OOM Killer + </span> + </div> + </div> + </div> + <div class="row"> + <div class="col-md-12"> + <p class="text-muted"><small>If you do not want to assign swap space to a server simply put <code>0</code> for the value. We suggest leaving OOM Killer enabled unless you know what you are doing, disabling it could cause your server to hang unexpectedly.</small><p> + </div> + </div> + <div class="row"> + <div class="form-group col-md-4 col-xs-4"> <label for="disk" class="control-label">Disk Space</label> <div class="input-group"> <input type="text" name="disk" class="form-control" value="{{ old('disk') }}"/> <span class="input-group-addon">MB</span> </div> </div> - <div class="form-group col-md-3 col-xs-6"> + <div class="form-group col-md-4 col-xs-4"> <label for="cpu" class="control-label">CPU Limit</label> <div class="input-group"> - <input type="text" name="cpu" value="0" class="form-control" value="{{ old('cpu') }}"/> + <input type="text" name="cpu" class="form-control" value="{{ old('cpu', 0) }}"/> <span class="input-group-addon">%</span> </div> </div> - <div class="form-group col-md-3 col-xs-6"> + <div class="form-group col-md-4 col-xs-4"> <label for="io" class="control-label">Block I/O</label> <div class="input-group"> - <input type="text" name="io" value="500" class="form-control" value="{{ old('io') }}"/> + <input type="text" name="io" class="form-control" value="{{ old('io', 500) }}"/> <span class="input-group-addon">I/O</span> </div> </div> @@ -167,7 +192,7 @@ <label for="use_custom_image" class="control-label">Use Custom Docker Image</label> <div class="input-group"> <span class="input-group-addon"> - <input @if(old('name') === 'use_custom_image')checked="checked"@endif type="checkbox" name="use_custom_image"/> + <input @if(old('use_custom_image') === 'use_custom_image')checked="checked"@endif type="checkbox" name="use_custom_image"/> </span> <input type="text" class="form-control" name="custom_image_name" value="{{ old('custom_image_name') }}" disabled /> </div> @@ -177,11 +202,20 @@ </div> </div> </div> - <div class="well"> + <div class="well" id="serviceOptions" style="display:none;"> + <div class="row"> + <div class="form-group col-md-12"> + <h3 class="nopad">Service Setup & Options</h3> + <hr /> + <label for="startup" class="control-label">Startup Command</label> + <div class="input-group"> + <span class="input-group-addon" id="startupExec"></span> + <input type="text" class="form-control" name="startup" value="{{ old('startup') }}" /> + </div> + </div> + </div> <div class="row"> <div class="col-md-12"> - <h3 class="nopad">Service Environment Variables</h3> - <hr /> <div class="alert alert-info">Some service options have additional environment variables that you can define for a given instance. They will show up below when you select a service option. If none show up, chances are that none were defined, and there is nothing to worry about.</div> <span id="serverVariables"></span> </div> @@ -313,6 +347,8 @@ $(document).ready(function () { currentService = $('#getService').val(); handleLoader('#load_services', true); + $('#serviceOptions').slideUp(); + $('#getOption').html('<option disabled selected> -- Select a Service Option</option>'); $.ajax({ method: 'POST', @@ -324,7 +360,9 @@ $(document).ready(function () { service: $('#getService').val() } }).done(function (data) { - $.each(data, function (i, option) { + $('#startupExec').html(data.exec); + $('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').parent().parent().removeClass('hidden'); @@ -341,6 +379,7 @@ $(document).ready(function () { $('#getOption').on('change', function (event) { handleLoader('#load_services', true); + handleLoader('#serviceOptions', true); $('#serverVariables').html(''); $('input[name="custom_image_name"]').val($(this).find(':selected').data('image')); @@ -363,15 +402,18 @@ $(document).ready(function () { <input type="text" autocomplete="off" name="env_' + item.env_variable + '" class="form-control" value="' + item.default_value + '" />\ <p class="text-muted"><small>' + item.description + '</small></p>\ <p class="text-muted"><small>Regex Requirements for Input: <code>' + item.regex + '</code></small></p>\ + <p class="text-muted"><small>Access in Startup: <code>${' + item.env_variable + '}</code></small></p>\ </div>\ </div>\ '; $('#serverVariables').append(dataAppend); }); + $('#serviceOptions').slideDown(); }).fail(function (jqXHR) { console.error(jqXHR); }).always(function () { handleLoader('#load_services'); + handleLoader('#serviceOptions'); }); });