Skip to content

Commit 4928620

Browse files
authored
Merge pull request pterodactyl#401 from Pterodactyl/feature/option-scripts
Feature/option scripts
2 parents d695532 + 2ba9d51 commit 4928620

File tree

19 files changed

+744
-92
lines changed

19 files changed

+744
-92
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@ This file is a running track of new features and fixes to each version of the pa
33

44
This project follows [Semantic Versioning](http://semver.org) guidelines.
55

6+
## v0.6.0-beta.2.1 (Courageous Carniadactylus)
7+
### Fixed
8+
* `[beta.2.1]` — Fixed a bug preventing the deletion of a server.
9+
10+
### Added
11+
* 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.
12+
* Added ability to reinstall a server using the currently assigned service and option.
13+
* Added ability to change a server's service and service option, as well as change pack assignments and other management services in that regard.
14+
615
## v0.6.0-beta.2.1 (Courageous Carniadactylus)
716
### Fixed
817
* `[beta.2]` — Suspended servers now show as suspended.

app/Http/Controllers/Admin/OptionController.php

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public function createVariable(Request $request, $id)
9595
$repo = new VariableRepository;
9696

9797
try {
98-
$variable = $repo->create($id, $request->only([
98+
$variable = $repo->create($id, $request->intersect([
9999
'name', 'description', 'env_variable',
100100
'default_value', 'options', 'rules',
101101
]));
@@ -137,6 +137,18 @@ public function viewVariables(Request $request, $id)
137137
return view('admin.services.options.variables', ['option' => ServiceOption::with('variables')->findOrFail($id)]);
138138
}
139139

140+
/**
141+
* Display script management page for an option.
142+
*
143+
* @param Request $request
144+
* @param int $id
145+
* @return \Illuminate\View\View
146+
*/
147+
public function viewScripts(Request $request, $id)
148+
{
149+
return view('admin.services.options.scripts', ['option' => ServiceOption::findOrFail($id)]);
150+
}
151+
140152
/**
141153
* Handles POST when editing a configration for a service option.
142154
*
@@ -188,7 +200,7 @@ public function editVariable(Request $request, $option, $variable)
188200

189201
try {
190202
if ($request->input('action') !== 'delete') {
191-
$variable = $repo->update($variable, $request->only([
203+
$variable = $repo->update($variable, $request->intersect([
192204
'name', 'description', 'env_variable',
193205
'default_value', 'options', 'rules',
194206
]));
@@ -208,4 +220,30 @@ public function editVariable(Request $request, $option, $variable)
208220

209221
return redirect()->route('admin.services.option.variables', $option);
210222
}
223+
224+
/**
225+
* Handles POST when updating scripts for a service option.
226+
*
227+
* @param Request $request
228+
* @param int $id
229+
* @return \Illuminate\Response\RedirectResponse
230+
*/
231+
public function updateScripts(Request $request, $id)
232+
{
233+
$repo = new OptionRepository;
234+
235+
try {
236+
$repo->scripts($id, $request->only([
237+
'script_install', 'script_entry', 'script_container',
238+
]));
239+
Alert::success('Successfully updated option scripts to be run when servers are installed.')->flash();
240+
} catch (DisplayValidationException $ex) {
241+
return redirect()->route('admin.services.option.scripts', $id)->withErrors(json_decode($ex->getMessage()));
242+
} catch (\Exception $ex) {
243+
Log::error($ex);
244+
Alert::danger('An unhandled exception was encountered while attempting to process that request. This error has been logged.')->flash();
245+
}
246+
247+
return redirect()->route('admin.services.option.scripts', $id);
248+
}
211249
}

app/Http/Controllers/Admin/ServersController.php

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,24 @@ public function viewStartup(Request $request, $id)
198198
return $item;
199199
});
200200

201-
return view('admin.servers.view.startup', ['server' => $server]);
201+
$services = Models\Service::with('options.packs', 'options.variables')->get();
202+
Javascript::put([
203+
'services' => $services->map(function ($item) {
204+
return array_merge($item->toArray(), [
205+
'options' => $item->options->keyBy('id')->toArray(),
206+
]);
207+
})->keyBy('id'),
208+
'server_variables' => $server->variables->mapWithKeys(function ($item) {
209+
return ['env_' . $item->variable_id => [
210+
'value' => $item->variable_value,
211+
]];
212+
})->toArray(),
213+
]);
214+
215+
return view('admin.servers.view.startup', [
216+
'server' => $server,
217+
'services' => $services,
218+
]);
202219
}
203220

204221
/**
@@ -322,6 +339,30 @@ public function toggleInstall(Request $request, $id)
322339
return redirect()->route('admin.servers.view.manage', $id);
323340
}
324341

342+
/**
343+
* Reinstalls the server with the currently assigned pack and service.
344+
*
345+
* @param \Illuminate\Http\Request $request
346+
* @param int $id
347+
* @return \Illuminate\Http\RedirectResponse
348+
*/
349+
public function reinstallServer(Request $request, $id)
350+
{
351+
$repo = new ServerRepository;
352+
try {
353+
$repo->reinstall($id);
354+
355+
Alert::success('Server successfully marked for reinstallation.')->flash();
356+
} catch (DisplayException $ex) {
357+
Alert::danger($ex->getMessage())->flash();
358+
} catch (\Exception $ex) {
359+
Log::error($ex);
360+
Alert::danger('An unhandled exception occured while attemping to perform this reinstallation. This error has been logged.')->flash();
361+
}
362+
363+
return redirect()->route('admin.servers.view.manage', $id);
364+
}
365+
325366
/**
326367
* Setup a server to have a container rebuild.
327368
*
@@ -455,9 +496,13 @@ public function saveStartup(Request $request, $id)
455496
$repo = new ServerRepository;
456497

457498
try {
458-
$repo->updateStartup($id, $request->except('_token'), true);
499+
if ($repo->updateStartup($id, $request->except('_token'), true)) {
500+
Alert::success('Service configuration successfully modfied for this server, reinstalling now.')->flash();
459501

460-
Alert::success('Startup variables were successfully modified and assigned for this server.')->flash();
502+
return redirect()->route('admin.servers.view', $id);
503+
} else {
504+
Alert::success('Startup variables were successfully modified and assigned for this server.')->flash();
505+
}
461506
} catch (DisplayValidationException $ex) {
462507
return redirect()->route('admin.servers.view.startup', $id)->withErrors(json_decode($ex->getMessage()));
463508
} catch (DisplayException $ex) {
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
/**
3+
* Pterodactyl - Panel
4+
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
namespace Pterodactyl\Http\Controllers\Daemon;
26+
27+
use Illuminate\Http\Request;
28+
use Pterodactyl\Models\Server;
29+
use Pterodactyl\Models\ServiceOption;
30+
use Pterodactyl\Http\Controllers\Controller;
31+
32+
class OptionController extends Controller
33+
{
34+
public function details(Request $request, $server)
35+
{
36+
$server = Server::with('allocation', 'option', 'variables.variable')->where('uuid', $server)->firstOrFail();
37+
38+
$environment = $server->variables->map(function ($item) {
39+
return sprintf('%s=%s', $item->variable->env_variable, $item->variable_value);
40+
});
41+
42+
return response()->json([
43+
'scripts' => [
44+
'install' => (! $server->option->script_install) ? null : str_replace(["\r\n", "\n", "\r"], "\n", $server->option->script_install),
45+
'privileged' => $server->option->script_is_privileged,
46+
],
47+
'config' => [
48+
'container' => $server->option->script_container,
49+
'entry' => $server->option->script_entry,
50+
],
51+
'env' => $environment->merge([
52+
'STARTUP=' . $server->startup,
53+
'SERVER_MEMORY=' . $server->memory,
54+
'SERVER_IP=' . $server->allocation->ip,
55+
'SERVER_PORT=' . $server->allocation->port,
56+
])->toArray(),
57+
]);
58+
}
59+
}

app/Models/Server.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class Server extends Model
7272
*/
7373
protected $casts = [
7474
'node_id' => 'integer',
75+
'skip_scripts' => 'boolean',
7576
'suspended' => 'integer',
7677
'owner_id' => 'integer',
7778
'memory' => 'integer',

app/Models/ServiceOption.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,15 @@ class ServiceOption extends Model
4242
*/
4343
protected $guarded = ['id', 'created_at', 'updated_at'];
4444

45-
/**
46-
* Cast values to correct type.
47-
*
48-
* @var array
49-
*/
50-
protected $casts = [
51-
'service_id' => 'integer',
52-
];
45+
/**
46+
* Cast values to correct type.
47+
*
48+
* @var array
49+
*/
50+
protected $casts = [
51+
'service_id' => 'integer',
52+
'script_is_privileged' => 'boolean',
53+
];
5354

5455
/**
5556
* Returns the display startup string for the option and will use the parent

app/Repositories/OptionRepository.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,4 +154,35 @@ public function update($id, array $data)
154154

155155
return $option;
156156
}
157+
158+
/**
159+
* Updates a service option's scripts in the database.
160+
*
161+
* @param int $id
162+
* @param array $data
163+
* @return \Pterodactyl\Models\ServiceOption
164+
*
165+
* @throws \Pterodactyl\Exceptions\DisplayValidationException
166+
*/
167+
public function scripts($id, array $data)
168+
{
169+
$option = ServiceOption::findOrFail($id);
170+
171+
$data['script_install'] = empty($data['script_install']) ? null : $data['script_install'];
172+
173+
$validator = Validator::make($data, [
174+
'script_install' => 'sometimes|nullable|string',
175+
'script_is_privileged' => 'sometimes|required|boolean',
176+
'script_entry' => 'sometimes|required|string',
177+
'script_container' => 'sometimes|required|string',
178+
]);
179+
180+
if ($validator->fails()) {
181+
throw new DisplayValidationException(json_encode($validator->errors()));
182+
}
183+
184+
$option->fill($data)->save();
185+
186+
return $option;
187+
}
157188
}

0 commit comments

Comments
 (0)