From 03e0de28d9e45ee926bcb7886b28bb97454910e0 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 18 Mar 2017 13:09:30 -0400 Subject: [PATCH 1/7] Initial implementation of option scripts on panel side. --- .../Controllers/Admin/OptionController.php | 38 +++++++ .../Controllers/Daemon/OptionController.php | 56 +++++++++ app/Http/Routes/AdminRoutes.php | 8 ++ app/Http/Routes/DaemonRoutes.php | 5 + app/Models/ServiceOption.php | 1 + app/Repositories/OptionRepository.php | 31 +++++ ...03_17_223714_AddInstallAndUpgradePaths.php | 36 ++++++ .../admin/services/options/scripts.blade.php | 107 ++++++++++++++++++ .../services/options/variables.blade.php | 1 + .../admin/services/options/view.blade.php | 1 + 10 files changed, 284 insertions(+) create mode 100644 app/Http/Controllers/Daemon/OptionController.php create mode 100644 database/migrations/2017_03_17_223714_AddInstallAndUpgradePaths.php create mode 100644 resources/themes/pterodactyl/admin/services/options/scripts.blade.php diff --git a/app/Http/Controllers/Admin/OptionController.php b/app/Http/Controllers/Admin/OptionController.php index 68ddfaf9e..9300fcedb 100644 --- a/app/Http/Controllers/Admin/OptionController.php +++ b/app/Http/Controllers/Admin/OptionController.php @@ -137,6 +137,18 @@ class OptionController extends Controller return view('admin.services.options.variables', ['option' => ServiceOption::with('variables')->findOrFail($id)]); } + /** + * Display script management page for an option. + * + * @param Request $request + * @param int $id + * @return \Illuminate\View\View + */ + public function viewScripts(Request $request, $id) + { + return view('admin.services.options.scripts', ['option' => ServiceOption::findOrFail($id)]); + } + /** * Handles POST when editing a configration for a service option. * @@ -207,4 +219,30 @@ class OptionController extends Controller return redirect()->route('admin.services.option.variables', $option); } + + /** + * Handles POST when updating scripts for a service option. + * + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ + public function updateScripts(Request $request, $id) + { + $repo = new OptionRepository; + + try { + $repo->scripts($id, $request->only([ + 'script_install', 'script_upgrade', + ])); + Alert::success('Successfully updated option scripts to be run when servers are installed or updated.')->flash(); + } catch (DisplayValidationException $ex) { + return redirect()->route('admin.services.option.scripts', $id)->withErrors(json_decode($ex->getMessage())); + } catch (\Exception $ex) { + Log::error($ex); + Alert::danger('An unhandled exception was encountered while attempting to process that request. This error has been logged.')->flash(); + } + + return redirect()->route('admin.services.option.scripts', $id); + } } diff --git a/app/Http/Controllers/Daemon/OptionController.php b/app/Http/Controllers/Daemon/OptionController.php new file mode 100644 index 000000000..8c61e42f2 --- /dev/null +++ b/app/Http/Controllers/Daemon/OptionController.php @@ -0,0 +1,56 @@ +. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +namespace Pterodactyl\Http\Controllers\Daemon; + +use Illuminate\Http\Request; +use Pterodactyl\Models\Server; +use Pterodactyl\Models\ServiceOption; +use Pterodactyl\Http\Controllers\Controller; + +class OptionController extends Controller +{ + public function details(Request $request, $server) + { + $server = Server::with('allocation', 'option', 'variables.variable')->where('uuid', $server)->firstOrFail(); + + $environment = $server->variables->map(function ($item) { + return sprintf('%s=%s', $item->variable->env_variable, $item->variable_value); + }); + + return response()->json([ + 'scripts' => [ + 'install' => str_replace(["\r\n", "\n", "\r"], "\n", $server->option->script_install), + 'upgrade' => str_replace(["\r\n", "\n", "\r"], "\n", $server->option->script_upgrade), + 'privileged' => $server->option->script_is_privileged, + ], + 'env' => $environment->merge([ + 'STARTUP=' . $server->startup, + 'SERVER_MEMORY=' . $server->memory, + 'SERVER_IP=' . $server->allocation->ip, + 'SERVER_PORT=' . $server->allocation->port, + ])->toArray(), + ]); + } +} diff --git a/app/Http/Routes/AdminRoutes.php b/app/Http/Routes/AdminRoutes.php index 41ab22482..a371bf02b 100644 --- a/app/Http/Routes/AdminRoutes.php +++ b/app/Http/Routes/AdminRoutes.php @@ -434,6 +434,14 @@ class AdminRoutes 'as' => 'admin.services.option.variables.edit', 'uses' => 'Admin\OptionController@editVariable', ]); + + $router->get('/option/{id}/scripts', [ + 'as' => 'admin.services.option.scripts', + 'uses' => 'Admin\OptionController@viewScripts', + ]); + + $router->post('/option/{id}/scripts', 'Admin\OptionController@updateScripts'); + }); // Service Packs diff --git a/app/Http/Routes/DaemonRoutes.php b/app/Http/Routes/DaemonRoutes.php index 7367fae5f..4458da895 100644 --- a/app/Http/Routes/DaemonRoutes.php +++ b/app/Http/Routes/DaemonRoutes.php @@ -49,6 +49,11 @@ class DaemonRoutes 'as' => 'daemon.pack.hash', 'uses' => 'Daemon\PackController@hash', ]); + + $router->get('details/option/{server}', [ + 'as' => 'daemon.pack.hash', + 'uses' => 'Daemon\OptionController@details', + ]); }); } } diff --git a/app/Models/ServiceOption.php b/app/Models/ServiceOption.php index a0f76df23..fdafed020 100644 --- a/app/Models/ServiceOption.php +++ b/app/Models/ServiceOption.php @@ -49,6 +49,7 @@ class ServiceOption extends Model */ protected $casts = [ 'service_id' => 'integer', + 'script_is_privileged' => 'boolean', ]; /** diff --git a/app/Repositories/OptionRepository.php b/app/Repositories/OptionRepository.php index d0535b575..8169c9d60 100644 --- a/app/Repositories/OptionRepository.php +++ b/app/Repositories/OptionRepository.php @@ -154,4 +154,35 @@ class OptionRepository return $option; } + + /** + * Updates a service option's scripts in the database. + * + * @param int $id + * @param array $data + * @return \Pterodactyl\Models\ServiceOption + * + * @throws \Pterodactyl\Exceptions\DisplayValidationException + */ + public function scripts($id, array $data) + { + $option = ServiceOption::findOrFail($id); + + $data['script_install'] = empty($data['script_install']) ? null : $data['script_install']; + $data['script_upgrade'] = empty($data['script_upgrade']) ? null : $data['script_upgrade']; + + $validator = Validator::make($data, [ + 'script_install' => 'sometimes|nullable|string', + 'script_upgrade' => 'sometimes|nullable|string', + 'script_is_privileged' => 'sometimes|required|boolean', + ]); + + if ($validator->fails()) { + throw new DisplayValidationException(json_encode($validator->errors())); + } + + $option->fill($data)->save(); + + return $option; + } } diff --git a/database/migrations/2017_03_17_223714_AddInstallAndUpgradePaths.php b/database/migrations/2017_03_17_223714_AddInstallAndUpgradePaths.php new file mode 100644 index 000000000..3081c3b9d --- /dev/null +++ b/database/migrations/2017_03_17_223714_AddInstallAndUpgradePaths.php @@ -0,0 +1,36 @@ +text('script_upgrade')->after('startup')->nullable(); + $table->text('script_install')->after('startup')->nullable(); + $table->boolean('script_is_privileged')->default(false)->after('startup'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('service_options', function (Blueprint $table) { + $table->dropColumn('script_upgrade'); + $table->dropColumn('script_install'); + $table->dropColumn('script_is_privileged'); + }); + } +} diff --git a/resources/themes/pterodactyl/admin/services/options/scripts.blade.php b/resources/themes/pterodactyl/admin/services/options/scripts.blade.php new file mode 100644 index 000000000..b2cee5c5c --- /dev/null +++ b/resources/themes/pterodactyl/admin/services/options/scripts.blade.php @@ -0,0 +1,107 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Services → Option: {{ $option->name }} → Scripts +@endsection + +@section('content-header') +

{{ $option->name }}Manage install and upgrade scripts for this service option.

+ +@endsection + +@section('content') +
+
+ +
+
+
+
+
+
+
+

Install Script

+
+
+
{{ $option->script_install }}
+
+
+
+
+
+
+

Upgrade Script

+
+
+
{{ $option->script_upgrade }}
+
+ +
+
+
+
+@endsection + +@section('footer-scripts') + @parent + {!! Theme::js('js/vendor/ace/ace.js') !!} + {!! Theme::js('js/vendor/ace/ext-modelist.js') !!} + +@endsection diff --git a/resources/themes/pterodactyl/admin/services/options/variables.blade.php b/resources/themes/pterodactyl/admin/services/options/variables.blade.php index 830bec458..dcc8882ca 100644 --- a/resources/themes/pterodactyl/admin/services/options/variables.blade.php +++ b/resources/themes/pterodactyl/admin/services/options/variables.blade.php @@ -42,6 +42,7 @@
  • Configuration
  • Variables
  • New Variable
  • +
  • Scripts
  • diff --git a/resources/themes/pterodactyl/admin/services/options/view.blade.php b/resources/themes/pterodactyl/admin/services/options/view.blade.php index 6450fdef3..b61f79f9d 100644 --- a/resources/themes/pterodactyl/admin/services/options/view.blade.php +++ b/resources/themes/pterodactyl/admin/services/options/view.blade.php @@ -40,6 +40,7 @@ From c8f1335a09a8a9979755e2d5c2529638423305d3 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Thu, 20 Apr 2017 17:26:20 -0400 Subject: [PATCH 2/7] Fixup merge --- .env.example | 2 +- .../Controllers/Admin/OptionController.php | 6 +- .../Controllers/Daemon/OptionController.php | 2 +- app/Http/Routes/AdminRoutes.php | 486 ------------------ app/Http/Routes/DaemonRoutes.php | 59 --- app/Models/ServiceOption.php | 11 - app/Repositories/OptionRepository.php | 2 - ..._20_171943_AddScriptsToServiceOptions.php} | 6 +- .../themes/pterodactyl/vendor/ace/mode-sh.js | 1 + .../admin/services/options/scripts.blade.php | 24 +- routes/admin.php | 2 + routes/daemon.php | 1 + 12 files changed, 13 insertions(+), 589 deletions(-) delete mode 100644 app/Http/Routes/AdminRoutes.php delete mode 100644 app/Http/Routes/DaemonRoutes.php rename database/migrations/{2017_03_17_223714_AddInstallAndUpgradePaths.php => 2017_04_20_171943_AddScriptsToServiceOptions.php} (73%) create mode 100644 public/themes/pterodactyl/vendor/ace/mode-sh.js diff --git a/.env.example b/.env.example index ed3a56b68..fa7e20965 100644 --- a/.env.example +++ b/.env.example @@ -13,7 +13,7 @@ DB_DATABASE=homestead DB_USERNAME=homestead DB_PASSWORD=secret -CACHE_DRIVER=memcached +CACHE_DRIVER=file SESSION_DRIVER=database MAIL_DRIVER=smtp diff --git a/app/Http/Controllers/Admin/OptionController.php b/app/Http/Controllers/Admin/OptionController.php index 9925e227a..9486f008a 100644 --- a/app/Http/Controllers/Admin/OptionController.php +++ b/app/Http/Controllers/Admin/OptionController.php @@ -233,10 +233,8 @@ class OptionController extends Controller $repo = new OptionRepository; try { - $repo->scripts($id, $request->only([ - 'script_install', 'script_upgrade', - ])); - Alert::success('Successfully updated option scripts to be run when servers are installed or updated.')->flash(); + $repo->scripts($id, $request->only('script_install')); + Alert::success('Successfully updated option scripts to be run when servers are installed.')->flash(); } catch (DisplayValidationException $ex) { return redirect()->route('admin.services.option.scripts', $id)->withErrors(json_decode($ex->getMessage())); } catch (\Exception $ex) { diff --git a/app/Http/Controllers/Daemon/OptionController.php b/app/Http/Controllers/Daemon/OptionController.php index 8c61e42f2..0a1718522 100644 --- a/app/Http/Controllers/Daemon/OptionController.php +++ b/app/Http/Controllers/Daemon/OptionController.php @@ -42,7 +42,7 @@ class OptionController extends Controller return response()->json([ 'scripts' => [ 'install' => str_replace(["\r\n", "\n", "\r"], "\n", $server->option->script_install), - 'upgrade' => str_replace(["\r\n", "\n", "\r"], "\n", $server->option->script_upgrade), + // 'upgrade' => str_replace(["\r\n", "\n", "\r"], "\n", $server->option->script_upgrade), 'privileged' => $server->option->script_is_privileged, ], 'env' => $environment->merge([ diff --git a/app/Http/Routes/AdminRoutes.php b/app/Http/Routes/AdminRoutes.php deleted file mode 100644 index a371bf02b..000000000 --- a/app/Http/Routes/AdminRoutes.php +++ /dev/null @@ -1,486 +0,0 @@ - - * Some Modifications (c) 2015 Dylan Seidt . - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -namespace Pterodactyl\Http\Routes; - -use Illuminate\Routing\Router; - -class AdminRoutes -{ - public function map(Router $router) - { - - // Admin Index - $router->get('admin', [ - 'as' => 'admin.index', - 'middleware' => [ - 'auth', - 'admin', - 'csrf', - ], - 'uses' => 'Admin\BaseController@getIndex', - ]); - - $router->group([ - 'prefix' => 'admin/databases', - 'middleware' => [ - 'auth', - 'admin', - 'csrf', - ], - ], function () use ($router) { - $router->get('/', [ - 'as' => 'admin.databases', - 'uses' => 'Admin\DatabaseController@index', - ]); - - $router->post('/', 'Admin\DatabaseController@create'); - - $router->get('/view/{id}', [ - 'as' => 'admin.databases.view', - 'uses' => 'Admin\DatabaseController@view', - ]); - - $router->post('/view/{id}', 'Admin\DatabaseController@update'); - }); - - $router->group([ - 'prefix' => 'admin/locations', - 'middleware' => [ - 'auth', - 'admin', - 'csrf', - ], - ], function () use ($router) { - $router->get('/', [ - 'as' => 'admin.locations', - 'uses' => 'Admin\LocationController@index', - ]); - - $router->post('/', 'Admin\LocationController@create'); - - $router->get('/view/{id}', [ - 'as' => 'admin.locations.view', - 'uses' => 'Admin\LocationController@view', - ]); - - $router->post('/view/{id}', 'Admin\LocationController@update'); - }); - - $router->group([ - 'prefix' => 'admin/settings', - 'middleware' => [ - 'auth', - 'admin', - 'csrf', - ], - ], function () use ($router) { - $router->get('/', [ - 'as' => 'admin.settings', - 'uses' => 'Admin\BaseController@getSettings', - ]); - $router->post('/', [ - 'uses' => 'Admin\BaseController@postSettings', - ]); - }); - - $router->group([ - 'prefix' => 'admin/users', - 'middleware' => [ - 'auth', - 'admin', - 'csrf', - ], - ], function () use ($router) { - - // View All Accounts on System - $router->get('/', [ - 'as' => 'admin.users', - 'uses' => 'Admin\UserController@getIndex', - ]); - - $router->get('/accounts.json', [ - 'as' => 'admin.users.json', - 'uses' => 'Admin\UserController@getJson', - ]); - - // View Specific Account - $router->get('/view/{id}', [ - 'as' => 'admin.users.view', - 'uses' => 'Admin\UserController@getView', - ]); - - // View Specific Account - $router->post('/view/{id}', [ - 'uses' => 'Admin\UserController@updateUser', - ]); - - // Delete an Account Matching an ID - $router->delete('/view/{id}', [ - 'uses' => 'Admin\UserController@deleteUser', - ]); - - // Show Create Account Page - $router->get('/new', [ - 'as' => 'admin.users.new', - 'uses' => 'Admin\UserController@getNew', - ]); - - // Handle Creating New Account - $router->post('/new', [ - 'uses' => 'Admin\UserController@postNew', - ]); - }); - - // Server Routes - $router->group([ - 'prefix' => 'admin/servers', - 'middleware' => [ - 'auth', - 'admin', - 'csrf', - ], - ], function () use ($router) { - - // View All Servers - $router->get('/', [ - 'as' => 'admin.servers', - 'uses' => 'Admin\ServersController@index', - ]); - - // View Create Server Page - $router->get('/new', [ - 'as' => 'admin.servers.new', - 'uses' => 'Admin\ServersController@new', - ]); - - // Handle POST Request for Creating Server - $router->post('/new', [ - 'uses' => 'Admin\ServersController@create', - ]); - - // Assorted Page Helpers - $router->post('/new/nodes', [ - 'as' => 'admin.servers.new.nodes', - 'uses' => 'Admin\ServersController@newServerNodes', - ]); - - $router->get('/view/{id}', [ - 'as' => 'admin.servers.view', - 'uses' => 'Admin\ServersController@viewIndex', - ]); - - $router->get('/view/{id}/details', [ - 'as' => 'admin.servers.view.details', - 'uses' => 'Admin\ServersController@viewDetails', - ]); - - $router->post('/view/{id}/details', [ - 'uses' => 'Admin\ServersController@setDetails', - ]); - - $router->post('/view/{id}/details/container', [ - 'as' => 'admin.servers.view.details.container', - 'uses' => 'Admin\ServersController@setContainer', - ]); - - $router->get('/view/{id}/build', [ - 'as' => 'admin.servers.view.build', - 'uses' => 'Admin\ServersController@viewBuild', - ]); - - $router->post('/view/{id}/build', [ - 'uses' => 'Admin\ServersController@updateBuild', - ]); - - $router->get('/view/{id}/startup', [ - 'as' => 'admin.servers.view.startup', - 'uses' => 'Admin\ServersController@viewStartup', - ]); - - $router->post('/view/{id}/startup', [ - 'uses' => 'Admin\ServersController@saveStartup', - ]); - - $router->get('/view/{id}/database', [ - 'as' => 'admin.servers.view.database', - 'uses' => 'Admin\ServersController@viewDatabase', - ]); - - $router->post('/view/{id}/database', [ - 'uses' => 'Admin\ServersController@newDatabase', - ]); - - $router->patch('/view/{id}/database', [ - 'uses' => 'Admin\ServersController@resetDatabasePassword', - ]); - - $router->delete('/view/{id}/database/{database}/delete', [ - 'as' => 'admin.servers.view.database.delete', - 'uses' => 'Admin\ServersController@deleteDatabase', - ]); - - $router->get('/view/{id}/manage', [ - 'as' => 'admin.servers.view.manage', - 'uses' => 'Admin\ServersController@viewManage', - ]); - - $router->post('/view/{id}/manage/toggle', [ - 'as' => 'admin.servers.view.manage.toggle', - 'uses' => 'Admin\ServersController@toggleInstall', - ]); - - $router->post('/view/{id}/manage/rebuild', [ - 'as' => 'admin.servers.view.manage.rebuild', - 'uses' => 'Admin\ServersController@rebuildContainer', - ]); - - $router->post('/view/{id}/manage/suspension', [ - 'as' => 'admin.servers.view.manage.suspension', - 'uses' => 'Admin\ServersController@manageSuspension', - ]); - - $router->get('/view/{id}/delete', [ - 'as' => 'admin.servers.view.delete', - 'uses' => 'Admin\ServersController@viewDelete', - ]); - - $router->post('/view/{id}/delete', [ - 'uses' => 'Admin\ServersController@delete', - ]); - - $router->post('/view/{id}/delete/continue/{force?}', [ - 'as' => 'admin.servers.view.delete.continue', - 'uses' => 'Admin\ServersController@continueDeletion', - ]); - - $router->post('/view/{id}/delete/cancel', [ - 'as' => 'admin.servers.view.delete.cancel', - 'uses' => 'Admin\ServersController@cancelDeletion', - ]); - }); - - // Node Routes - $router->group([ - 'prefix' => 'admin/nodes', - 'middleware' => [ - 'auth', - 'admin', - 'csrf', - ], - ], function () use ($router) { - - // View All Nodes - $router->get('/', [ - 'as' => 'admin.nodes', - 'uses' => 'Admin\NodesController@index', - ]); - - // Add New Node - $router->get('/new', [ - 'as' => 'admin.nodes.new', - 'uses' => 'Admin\NodesController@new', - ]); - - $router->post('/new', [ - 'uses' => 'Admin\NodesController@create', - ]); - - $router->get('/view/{id}', [ - 'as' => 'admin.nodes.view', - 'uses' => 'Admin\NodesController@viewIndex', - ]); - - $router->get('/view/{id}/settings', [ - 'as' => 'admin.nodes.view.settings', - 'uses' => 'Admin\NodesController@viewSettings', - ]); - - $router->post('/view/{id}/settings', [ - 'uses' => 'Admin\NodesController@updateSettings', - ]); - - $router->get('/view/{id}/configuration', [ - 'as' => 'admin.nodes.view.configuration', - 'uses' => 'Admin\NodesController@viewConfiguration', - ]); - - $router->get('/view/{id}/allocation', [ - 'as' => 'admin.nodes.view.allocation', - 'uses' => 'Admin\NodesController@viewAllocation', - ]); - - $router->post('/view/{id}/allocation', [ - 'uses' => 'Admin\NodesController@createAllocation', - ]); - - $router->get('/view/{id}/servers', [ - 'as' => 'admin.nodes.view.servers', - 'uses' => 'Admin\NodesController@viewServers', - ]); - - $router->delete('/view/{id}/delete', [ - 'as' => 'admin.nodes.view.delete', - 'uses' => 'Admin\NodesController@delete', - ]); - - $router->delete('/view/{id}/allocation/remove/{allocation}', [ - 'as' => 'admin.nodes.view.allocation.removeSingle', - 'uses' => 'Admin\NodesController@allocationRemoveSingle', - ]); - - $router->post('/view/{id}/allocation/remove', [ - 'as' => 'admin.nodes.view.allocation.removeBlock', - 'uses' => 'Admin\NodesController@allocationRemoveBlock', - ]); - - $router->post('/view/{id}/allocation/alias', [ - 'as' => 'admin.nodes.view.allocation.setAlias', - 'uses' => 'Admin\NodesController@allocationSetAlias', - ]); - - $router->get('/view/{id}/settings/token', [ - 'as' => 'admin.nodes.view.configuration.token', - 'uses' => 'Admin\NodesController@setToken', - ]); - }); - - // Service Routes - $router->group([ - 'prefix' => 'admin/services', - 'middleware' => [ - 'auth', - 'admin', - 'csrf', - ], - ], function () use ($router) { - $router->get('/', [ - 'as' => 'admin.services', - 'uses' => 'Admin\ServiceController@index', - ]); - - $router->get('/new', [ - 'as' => 'admin.services.new', - 'uses' => 'Admin\ServiceController@new', - ]); - - $router->post('/new', [ - 'uses' => 'Admin\ServiceController@create', - ]); - - $router->get('/view/{id}', [ - 'as' => 'admin.services.view', - 'uses' => 'Admin\ServiceController@view', - ]); - - $router->post('/view/{id}', 'Admin\ServiceController@edit'); - - $router->get('/view/{id}/functions', [ - 'as' => 'admin.services.view.functions', - 'uses' => 'Admin\ServiceController@viewFunctions', - ]); - - $router->delete('/view/{id}', [ - 'uses' => 'Admin\ServiceController@delete', - ]); - - // --------------------- - // Service Option Routes - // --------------------- - $router->get('/option/new', [ - 'as' => 'admin.services.option.new', - 'uses' => 'Admin\OptionController@new', - ]); - - $router->post('/option/new', 'Admin\OptionController@create'); - - $router->get('/option/{id}', [ - 'as' => 'admin.services.option.view', - 'uses' => 'Admin\OptionController@viewConfiguration', - ]); - - $router->post('/option/{id}', 'Admin\OptionController@editConfiguration'); - - $router->get('/option/{id}/variables', [ - 'as' => 'admin.services.option.variables', - 'uses' => 'Admin\OptionController@viewVariables', - ]); - - $router->post('/option/{id}/variables', 'Admin\OptionController@createVariable'); - - $router->post('/option/{id}/variables/{variable}', [ - 'as' => 'admin.services.option.variables.edit', - 'uses' => 'Admin\OptionController@editVariable', - ]); - - $router->get('/option/{id}/scripts', [ - 'as' => 'admin.services.option.scripts', - 'uses' => 'Admin\OptionController@viewScripts', - ]); - - $router->post('/option/{id}/scripts', 'Admin\OptionController@updateScripts'); - - }); - - // Service Packs - $router->group([ - 'prefix' => 'admin/packs', - 'middleware' => [ - 'auth', - 'admin', - 'csrf', - ], - ], function () use ($router) { - $router->get('/', [ - 'as' => 'admin.packs', - 'uses' => 'Admin\PackController@index', - ]); - - $router->get('/new', [ - 'as' => 'admin.packs.new', - 'uses' => 'Admin\PackController@new', - ]); - - $router->post('/new', 'Admin\PackController@create'); - - $router->get('/new/template', [ - 'as' => 'admin.packs.new.template', - 'uses' => 'Admin\PackController@newTemplate', - ]); - - $router->get('/view/{id}', [ - 'as' => 'admin.packs.view', - 'uses' => 'Admin\PackController@view', - ]); - - $router->post('/view/{id}', 'Admin\PackController@update'); - - $router->post('/view/{id}/export/{files?}', [ - 'as' => 'admin.packs.view.export', - 'uses' => 'Admin\PackController@export', - ]); - }); - } -} diff --git a/app/Http/Routes/DaemonRoutes.php b/app/Http/Routes/DaemonRoutes.php deleted file mode 100644 index 4458da895..000000000 --- a/app/Http/Routes/DaemonRoutes.php +++ /dev/null @@ -1,59 +0,0 @@ -. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -namespace Pterodactyl\Http\Routes; - -use Illuminate\Routing\Router; - -class DaemonRoutes -{ - public function map(Router $router) - { - $router->group(['prefix' => 'daemon', 'middleware' => 'daemon'], function () use ($router) { - $router->get('services', [ - 'as' => 'daemon.services', - 'uses' => 'Daemon\ServiceController@list', - ]); - - $router->get('services/pull/{service}/{file}', [ - 'as' => 'remote.install', - 'uses' => 'Daemon\ServiceController@pull', - ]); - - $router->get('packs/pull/{uuid}', [ - 'as' => 'daemon.pack.pull', - 'uses' => 'Daemon\PackController@pull', - ]); - $router->get('packs/pull/{uuid}/hash', [ - 'as' => 'daemon.pack.hash', - 'uses' => 'Daemon\PackController@hash', - ]); - - $router->get('details/option/{server}', [ - 'as' => 'daemon.pack.hash', - 'uses' => 'Daemon\OptionController@details', - ]); - }); - } -} diff --git a/app/Models/ServiceOption.php b/app/Models/ServiceOption.php index 159aaf328..bbd18e675 100644 --- a/app/Models/ServiceOption.php +++ b/app/Models/ServiceOption.php @@ -42,7 +42,6 @@ class ServiceOption extends Model */ protected $guarded = ['id', 'created_at', 'updated_at']; -<<<<<<< HEAD /** * Cast values to correct type. * @@ -52,16 +51,6 @@ class ServiceOption extends Model 'service_id' => 'integer', 'script_is_privileged' => 'boolean', ]; -======= - /** - * Cast values to correct type. - * - * @var array - */ - protected $casts = [ - 'service_id' => 'integer', - ]; ->>>>>>> develop /** * Returns the display startup string for the option and will use the parent diff --git a/app/Repositories/OptionRepository.php b/app/Repositories/OptionRepository.php index cc502a75f..4556063d5 100644 --- a/app/Repositories/OptionRepository.php +++ b/app/Repositories/OptionRepository.php @@ -169,11 +169,9 @@ class OptionRepository $option = ServiceOption::findOrFail($id); $data['script_install'] = empty($data['script_install']) ? null : $data['script_install']; - $data['script_upgrade'] = empty($data['script_upgrade']) ? null : $data['script_upgrade']; $validator = Validator::make($data, [ 'script_install' => 'sometimes|nullable|string', - 'script_upgrade' => 'sometimes|nullable|string', 'script_is_privileged' => 'sometimes|required|boolean', ]); diff --git a/database/migrations/2017_03_17_223714_AddInstallAndUpgradePaths.php b/database/migrations/2017_04_20_171943_AddScriptsToServiceOptions.php similarity index 73% rename from database/migrations/2017_03_17_223714_AddInstallAndUpgradePaths.php rename to database/migrations/2017_04_20_171943_AddScriptsToServiceOptions.php index 3081c3b9d..aeee7507f 100644 --- a/database/migrations/2017_03_17_223714_AddInstallAndUpgradePaths.php +++ b/database/migrations/2017_04_20_171943_AddScriptsToServiceOptions.php @@ -4,7 +4,7 @@ use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; -class AddInstallAndUpgradePaths extends Migration +class AddScriptsToServiceOptions extends Migration { /** * Run the migrations. @@ -14,9 +14,8 @@ class AddInstallAndUpgradePaths extends Migration public function up() { Schema::table('service_options', function (Blueprint $table) { - $table->text('script_upgrade')->after('startup')->nullable(); $table->text('script_install')->after('startup')->nullable(); - $table->boolean('script_is_privileged')->default(false)->after('startup'); + $table->boolean('script_is_privileged')->default(true)->after('startup'); }); } @@ -28,7 +27,6 @@ class AddInstallAndUpgradePaths extends Migration public function down() { Schema::table('service_options', function (Blueprint $table) { - $table->dropColumn('script_upgrade'); $table->dropColumn('script_install'); $table->dropColumn('script_is_privileged'); }); diff --git a/public/themes/pterodactyl/vendor/ace/mode-sh.js b/public/themes/pterodactyl/vendor/ace/mode-sh.js new file mode 100644 index 000000000..95e556e13 --- /dev/null +++ b/public/themes/pterodactyl/vendor/ace/mode-sh.js @@ -0,0 +1 @@ +define("ace/mode/sh_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=t.reservedKeywords="!|{|}|case|do|done|elif|else|esac|fi|for|if|in|then|until|while|&|;|export|local|read|typeset|unset|elif|select|set|function|declare|readonly",o=t.languageConstructs="[|]|alias|bg|bind|break|builtin|cd|command|compgen|complete|continue|dirs|disown|echo|enable|eval|exec|exit|fc|fg|getopts|hash|help|history|jobs|kill|let|logout|popd|printf|pushd|pwd|return|set|shift|shopt|source|suspend|test|times|trap|type|ulimit|umask|unalias|wait",u=function(){var e=this.createKeywordMapper({keyword:s,"support.function.builtin":o,"invalid.deprecated":"debugger"},"identifier"),t="(?:(?:[1-9]\\d*)|(?:0))",n="(?:\\.\\d+)",r="(?:\\d+)",i="(?:(?:"+r+"?"+n+")|(?:"+r+"\\.))",u="(?:(?:"+i+"|"+r+")"+")",a="(?:"+u+"|"+i+")",f="(?:&"+r+")",l="[a-zA-Z_][a-zA-Z0-9_]*",c="(?:"+l+"=)",h="(?:\\$(?:SHLVL|\\$|\\!|\\?))",p="(?:"+l+"\\s*\\(\\))";this.$rules={start:[{token:"constant",regex:/\\./},{token:["text","comment"],regex:/(^|\s)(#.*)$/},{token:"string.start",regex:'"',push:[{token:"constant.language.escape",regex:/\\(?:[$`"\\]|$)/},{include:"variables"},{token:"keyword.operator",regex:/`/},{token:"string.end",regex:'"',next:"pop"},{defaultToken:"string"}]},{token:"string",regex:"\\$'",push:[{token:"constant.language.escape",regex:/\\(?:[abeEfnrtv\\'"]|x[a-fA-F\d]{1,2}|u[a-fA-F\d]{4}([a-fA-F\d]{4})?|c.|\d{1,3})/},{token:"string",regex:"'",next:"pop"},{defaultToken:"string"}]},{regex:"<<<",token:"keyword.operator"},{stateName:"heredoc",regex:"(<<-?)(\\s*)(['\"`]?)([\\w\\-]+)(['\"`]?)",onMatch:function(e,t,n){var r=e[2]=="-"?"indentedHeredoc":"heredoc",i=e.split(this.splitRegex);return n.push(r,i[4]),[{type:"constant",value:i[1]},{type:"text",value:i[2]},{type:"string",value:i[3]},{type:"support.class",value:i[4]},{type:"string",value:i[5]}]},rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return t[0]==="heredoc"||t[0]==="indentedHeredoc"?t[0]:e}},{token:["keyword","text","text","text","variable"],regex:/(declare|local|readonly)(\s+)(?:(-[fixar]+)(\s+))?([a-zA-Z_][a-zA-Z0-9_]*\b)/},{token:"variable.language",regex:h},{token:"variable",regex:c},{include:"variables"},{token:"support.function",regex:p},{token:"support.function",regex:f},{token:"string",start:"'",end:"'"},{token:"constant.numeric",regex:a},{token:"constant.numeric",regex:t+"\\b"},{token:e,regex:"[a-zA-Z_][a-zA-Z0-9_]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|~|<|>|<=|=>|=|!=|[%&|`]"},{token:"punctuation.operator",regex:";"},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]]"},{token:"paren.rparen",regex:"[\\)\\}]",next:"pop"}],variables:[{token:"variable",regex:/(\$)(\w+)/},{token:["variable","paren.lparen"],regex:/(\$)(\()/,push:"start"},{token:["variable","paren.lparen","keyword.operator","variable","keyword.operator"],regex:/(\$)(\{)([#!]?)(\w+|[*@#?\-$!0_])(:[?+\-=]?|##?|%%?|,,?\/|\^\^?)?/,push:"start"},{token:"variable",regex:/\$[*@#?\-$!0_]/},{token:["variable","paren.lparen"],regex:/(\$)(\{)/,push:"start"}]},this.normalizeRules()};r.inherits(u,i),t.ShHighlightRules=u}),define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),define("ace/mode/sh",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/sh_highlight_rules","ace/range","ace/mode/folding/cstyle","ace/mode/behaviour/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./sh_highlight_rules").ShHighlightRules,o=e("../range").Range,u=e("./folding/cstyle").FoldMode,a=e("./behaviour/cstyle").CstyleBehaviour,f=function(){this.HighlightRules=s,this.foldingRules=new u,this.$behaviour=new a};r.inherits(f,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[:]\s*$/);o&&(r+=n)}return r};var e={pass:1,"return":1,raise:1,"break":1,"continue":1};this.checkOutdent=function(t,n,r){if(r!=="\r\n"&&r!=="\r"&&r!=="\n")return!1;var i=this.getTokenizer().getLineTokens(n.trim(),t).tokens;if(!i)return!1;do var s=i.pop();while(s&&(s.type=="comment"||s.type=="text"&&s.value.match(/^\s+$/)));return s?s.type=="keyword"&&e[s.value]:!1},this.autoOutdent=function(e,t,n){n+=1;var r=this.$getIndent(t.getLine(n)),i=t.getTabString();r.slice(-i.length)==i&&t.remove(new o(n,r.length-i.length,n,r.length))},this.$id="ace/mode/sh"}.call(f.prototype),t.Mode=f}) \ No newline at end of file diff --git a/resources/themes/pterodactyl/admin/services/options/scripts.blade.php b/resources/themes/pterodactyl/admin/services/options/scripts.blade.php index b2cee5c5c..8bb7250f0 100644 --- a/resources/themes/pterodactyl/admin/services/options/scripts.blade.php +++ b/resources/themes/pterodactyl/admin/services/options/scripts.blade.php @@ -55,20 +55,9 @@
    {{ $option->script_install }}
    - - -
    -
    -
    -

    Upgrade Script

    -
    -
    -
    {{ $option->script_upgrade }}
    -
    @@ -79,13 +68,11 @@ @section('footer-scripts') @parent - {!! Theme::js('js/vendor/ace/ace.js') !!} - {!! Theme::js('js/vendor/ace/ext-modelist.js') !!} + {!! Theme::js('vendor/ace/ace.js') !!} + {!! Theme::js('vendor/ace/ext-modelist.js') !!} + @endsection diff --git a/routes/admin.php b/routes/admin.php index 0ebe173b0..bfd08f7c4 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -169,11 +169,13 @@ Route::group(['prefix' => 'services'], function () { Route::get('/option/new', 'OptionController@create')->name('admin.services.option.new'); Route::get('/option/{id}', 'OptionController@viewConfiguration')->name('admin.services.option.view'); Route::get('/option/{id}/variables', 'OptionController@viewVariables')->name('admin.services.option.variables'); + Route::get('/option/{id}/scripts', 'OptionController@viewScripts')->name('admin.services.option.scripts'); Route::post('/new', 'ServiceController@store'); Route::post('/view/{id}', 'ServiceController@edit'); Route::post('/option/new', 'OptionController@store'); Route::post('/option/{id}', 'OptionController@editConfiguration'); + Route::post('/option/{id}/scripts', 'OptionController@updateScripts'); Route::post('/option/{id}/variables', 'OptionController@createVariable'); Route::post('/option/{id}/variables/{variable}', 'OptionController@editVariable')->name('admin.services.option.variables.edit'); diff --git a/routes/daemon.php b/routes/daemon.php index 78edf308f..d5ebcee67 100644 --- a/routes/daemon.php +++ b/routes/daemon.php @@ -25,3 +25,4 @@ Route::get('/services', 'ServiceController@list')->name('daemon.services'); Route::get('/services/pull/{service}/{file}', 'ServiceController@pull')->name('daemon.pull'); Route::get('/packs/pull/{uuid}', 'PackController@pull')->name('daemon.pack.pull'); Route::get('/packs/pull/{uuid}/hash', 'PackController@hash')->name('daemon.pack.hash'); +Route::get('/details/option/{server}', 'OptionController@details')->name('daemon.option.details'); From 3fe5d162f5a374541ee744c3db236dc745a05fb0 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Thu, 20 Apr 2017 17:57:40 -0400 Subject: [PATCH 3/7] Add skip scripting option --- app/Http/Controllers/Daemon/OptionController.php | 3 +-- app/Repositories/ServerRepository.php | 2 ++ resources/themes/pterodactyl/admin/servers/new.blade.php | 7 +++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Daemon/OptionController.php b/app/Http/Controllers/Daemon/OptionController.php index 0a1718522..087b1f503 100644 --- a/app/Http/Controllers/Daemon/OptionController.php +++ b/app/Http/Controllers/Daemon/OptionController.php @@ -41,8 +41,7 @@ class OptionController extends Controller return response()->json([ 'scripts' => [ - 'install' => str_replace(["\r\n", "\n", "\r"], "\n", $server->option->script_install), - // 'upgrade' => str_replace(["\r\n", "\n", "\r"], "\n", $server->option->script_upgrade), + 'install' => (! $server->option->script_install) ? null : str_replace(["\r\n", "\n", "\r"], "\n", $server->option->script_install), 'privileged' => $server->option->script_is_privileged, ], 'env' => $environment->merge([ diff --git a/app/Repositories/ServerRepository.php b/app/Repositories/ServerRepository.php index 674afa670..e782c938a 100644 --- a/app/Repositories/ServerRepository.php +++ b/app/Repositories/ServerRepository.php @@ -103,6 +103,7 @@ class ServerRepository 'startup' => 'string', 'auto_deploy' => 'sometimes|required|accepted', 'custom_id' => 'sometimes|required|numeric|unique:servers,id', + 'skip_scripting' => 'sometimes|required|boolean', ]); $validator->sometimes('node_id', 'required|numeric|min:1|exists:nodes,id', function ($input) { @@ -326,6 +327,7 @@ class ServerRepository 'type' => $service->folder, 'option' => $option->tag, 'pack' => (isset($pack)) ? $pack->uuid : null, + 'skip_scripting' => isset($data['skip_scripting']), ], 'keys' => [ (string) $server->daemonSecret => $this->daemonPermissions, diff --git a/resources/themes/pterodactyl/admin/servers/new.blade.php b/resources/themes/pterodactyl/admin/servers/new.blade.php index e2071d37d..eaf20445f 100644 --- a/resources/themes/pterodactyl/admin/servers/new.blade.php +++ b/resources/themes/pterodactyl/admin/servers/new.blade.php @@ -212,6 +212,13 @@

    Select a service pack to be automatically installed on this server when first created.

    +
    +
    + + +
    +

    If the selected Option has an install script attached to it, the script will run during install after the pack is installed. If you would like to skip this step, check this box.

    +
    From 8dc24471aebcea945d029979daec256a9e7f2bfd Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Thu, 20 Apr 2017 18:52:43 -0400 Subject: [PATCH 4/7] Add reinstall abilities and cleanup process for new servers --- .../Controllers/Admin/OptionController.php | 8 ++++--- .../Controllers/Admin/ServersController.php | 24 +++++++++++++++++++ .../Controllers/Daemon/OptionController.php | 4 ++++ app/Repositories/OptionRepository.php | 2 ++ app/Repositories/ServerRepository.php | 21 ++++++++++++++++ ...4_20_171943_AddScriptsToServiceOptions.php | 4 ++++ .../admin/servers/view/manage.blade.php | 16 +++++++++++++ .../admin/services/options/scripts.blade.php | 14 +++++++++++ routes/admin.php | 1 + 9 files changed, 91 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Admin/OptionController.php b/app/Http/Controllers/Admin/OptionController.php index 9486f008a..f7c5ac6db 100644 --- a/app/Http/Controllers/Admin/OptionController.php +++ b/app/Http/Controllers/Admin/OptionController.php @@ -95,7 +95,7 @@ class OptionController extends Controller $repo = new VariableRepository; try { - $variable = $repo->create($id, $request->only([ + $variable = $repo->create($id, $request->intersect([ 'name', 'description', 'env_variable', 'default_value', 'options', 'rules', ])); @@ -200,7 +200,7 @@ class OptionController extends Controller try { if ($request->input('action') !== 'delete') { - $variable = $repo->update($variable, $request->only([ + $variable = $repo->update($variable, $request->intersect([ 'name', 'description', 'env_variable', 'default_value', 'options', 'rules', ])); @@ -233,7 +233,9 @@ class OptionController extends Controller $repo = new OptionRepository; try { - $repo->scripts($id, $request->only('script_install')); + $repo->scripts($id, $request->only([ + 'script_install', 'script_entry', 'script_container', + ])); Alert::success('Successfully updated option scripts to be run when servers are installed.')->flash(); } catch (DisplayValidationException $ex) { return redirect()->route('admin.services.option.scripts', $id)->withErrors(json_decode($ex->getMessage())); diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index 1a8a8cfbc..509656952 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -322,6 +322,30 @@ class ServersController extends Controller return redirect()->route('admin.servers.view.manage', $id); } + /** + * Reinstalls the server with the currently assigned pack and service. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\RedirectResponse + */ + public function reinstallServer(Request $request, $id) + { + $repo = new ServerRepository; + try { + $repo->reinstall($id); + + Alert::success('Server successfully marked for reinstallation.')->flash(); + } catch (DisplayException $ex) { + Alert::danger($ex->getMessage())->flash(); + } catch (\Exception $ex) { + Log::error($ex); + Alert::danger('An unhandled exception occured while attemping to perform this reinstallation. This error has been logged.')->flash(); + } + + return redirect()->route('admin.servers.view.manage', $id); + } + /** * Setup a server to have a container rebuild. * diff --git a/app/Http/Controllers/Daemon/OptionController.php b/app/Http/Controllers/Daemon/OptionController.php index 087b1f503..9a27c1c64 100644 --- a/app/Http/Controllers/Daemon/OptionController.php +++ b/app/Http/Controllers/Daemon/OptionController.php @@ -44,6 +44,10 @@ class OptionController extends Controller 'install' => (! $server->option->script_install) ? null : str_replace(["\r\n", "\n", "\r"], "\n", $server->option->script_install), 'privileged' => $server->option->script_is_privileged, ], + 'config' => [ + 'container' => $server->option->script_container, + 'entry' => $server->option->script_entry, + ], 'env' => $environment->merge([ 'STARTUP=' . $server->startup, 'SERVER_MEMORY=' . $server->memory, diff --git a/app/Repositories/OptionRepository.php b/app/Repositories/OptionRepository.php index 4556063d5..53dab8c57 100644 --- a/app/Repositories/OptionRepository.php +++ b/app/Repositories/OptionRepository.php @@ -173,6 +173,8 @@ class OptionRepository $validator = Validator::make($data, [ 'script_install' => 'sometimes|nullable|string', 'script_is_privileged' => 'sometimes|required|boolean', + 'script_entry' => 'sometimes|required|string', + 'script_container' => 'sometimes|required|string', ]); if ($validator->fails()) { diff --git a/app/Repositories/ServerRepository.php b/app/Repositories/ServerRepository.php index e782c938a..adb14672e 100644 --- a/app/Repositories/ServerRepository.php +++ b/app/Repositories/ServerRepository.php @@ -864,4 +864,25 @@ class ServerRepository ]); }); } + + /** + * Marks a server for reinstallation on the node. + * + * @param int $id + * @return void + */ + public function reinstall($id) + { + $server = Models\Server::with('node')->findOrFail($id); + + DB::transaction(function () use ($server) { + $server->installed = 0; + $server->save(); + + $server->node->guzzleClient([ + 'X-Access-Token' => $server->node->daemonSecret, + 'X-Access-Server' => $server->uuid, + ])->request('POST', '/server/reinstall'); + }); + } } diff --git a/database/migrations/2017_04_20_171943_AddScriptsToServiceOptions.php b/database/migrations/2017_04_20_171943_AddScriptsToServiceOptions.php index aeee7507f..fb6d2da81 100644 --- a/database/migrations/2017_04_20_171943_AddScriptsToServiceOptions.php +++ b/database/migrations/2017_04_20_171943_AddScriptsToServiceOptions.php @@ -16,6 +16,8 @@ class AddScriptsToServiceOptions extends Migration Schema::table('service_options', function (Blueprint $table) { $table->text('script_install')->after('startup')->nullable(); $table->boolean('script_is_privileged')->default(true)->after('startup'); + $table->text('script_entry')->default('ash')->after('startup'); + $table->text('script_container')->default('alpine:3.4')->after('startup'); }); } @@ -29,6 +31,8 @@ class AddScriptsToServiceOptions extends Migration Schema::table('service_options', function (Blueprint $table) { $table->dropColumn('script_install'); $table->dropColumn('script_is_privileged'); + $table->dropColumn('script_entry'); + $table->dropColumn('script_container'); }); } } diff --git a/resources/themes/pterodactyl/admin/servers/view/manage.blade.php b/resources/themes/pterodactyl/admin/servers/view/manage.blade.php index 00043f221..0566a8a1c 100644 --- a/resources/themes/pterodactyl/admin/servers/view/manage.blade.php +++ b/resources/themes/pterodactyl/admin/servers/view/manage.blade.php @@ -53,6 +53,22 @@
    +
    +
    +
    +

    Reinstall Server

    +
    +
    +

    This will reinstall the server with the assigned pack and service scripts. Danger! This could overwrite server data.

    +
    + +
    +
    diff --git a/resources/themes/pterodactyl/admin/services/options/scripts.blade.php b/resources/themes/pterodactyl/admin/services/options/scripts.blade.php index 8bb7250f0..998247f70 100644 --- a/resources/themes/pterodactyl/admin/services/options/scripts.blade.php +++ b/resources/themes/pterodactyl/admin/services/options/scripts.blade.php @@ -55,6 +55,20 @@
    {{ $option->script_install }}
    +
    +
    +
    + + +

    Docker container to use when running this script for the server.

    +
    +
    + + +

    The entrypoint command to use for this script.

    +
    +
    +
    +
    + + +
    - @foreach($server->option->variables as $variable) -
    -
    -
    -

    {{ $variable->name }}

    -
    -
    - -

    {{ $variable->description }}

    -

    - @if($variable->required)Required@elseOptional@endif - @if($variable->user_viewable)Visible@elseHidden@endif - @if($variable->user_editable)Editable@elseLocked@endif +

    +
    +
    +
    +
    +

    Service Configuration

    +
    +
    +
    +

    + Changing any of the below values will result in the server processing a re-install command. The server will be stopped and will then proceede. + If you are changing the pack, exisiting data may be overwritten. If you would like the service scripts to not run, ensure the box is checked at the bottom. +

    +

    + This is a destructive operation in many cases. This server will be stopped immediately in order for this action to proceede.

    -
    - @endforeach +
    +
    +
    + @foreach($server->option->variables as $variable) +
    +
    +
    +

    {{ $variable->name }}

    +
    +
    + +

    {{ $variable->description }}

    +

    + @if($variable->required)Required@elseOptional@endif + @if($variable->user_viewable)Visible@elseHidden@endif + @if($variable->user_editable)Editable@elseLocked@endif +

    +
    + +
    +
    + @endforeach +
    +
    @endsection @section('footer-scripts') @parent + {!! Theme::js('vendor/lodash/lodash.js') !!} + @endsection From 2ba9d51f9c4dfdf1d3ad6ff83c61b8773ba55d5f Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Fri, 21 Apr 2017 17:54:32 -0400 Subject: [PATCH 7/7] Update changelog --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 960d838af..57096d1ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,15 @@ This file is a running track of new features and fixes to each version of the pa This project follows [Semantic Versioning](http://semver.org) guidelines. +## v0.6.0-beta.2.1 (Courageous Carniadactylus) +### Fixed +* `[beta.2.1]` — Fixed a bug preventing the deletion of a server. + +### Added +* Added new scripts for service options that allows installation of software in a privileged Docker container on the node prior to marking a server as installed. +* Added ability to reinstall a server using the currently assigned service and option. +* Added ability to change a server's service and service option, as well as change pack assignments and other management services in that regard. + ## v0.6.0-beta.2.1 (Courageous Carniadactylus) ### Fixed * `[beta.2]` — Suspended servers now show as suspended.