Skip to content

Commit 8c40f64

Browse files
authored
Merge pull request pterodactyl#75 from Pterodactyl/features/suspension
Add server suspension, closes pterodactyl#73
2 parents 3ca7e4d + 8e657a0 commit 8c40f64

File tree

13 files changed

+260
-33
lines changed

13 files changed

+260
-33
lines changed

app/Console/Commands/RunTasks.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public function __construct()
6767
*/
6868
public function handle()
6969
{
70-
$tasks = Models\Task::where('queued', 0)->where('active', 1)->where('next_run', '<=', (Carbon::now())->toAtomString())->get();
70+
$tasks = Models\Task::where('queued', 0)->where('suspended', 0)->where('next_run', '<=', (Carbon::now())->toAtomString())->get();
7171

7272
$this->info(sprintf('Preparing to queue %d tasks.', count($tasks)));
7373
$bar = $this->output->createProgressBar(count($tasks));

app/Http/Controllers/Admin/ServersController.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,4 +424,42 @@ public function postDatabase(Request $request, $id)
424424
])->withInput();
425425
}
426426

427+
public function postSuspendServer(Request $request, $id)
428+
{
429+
try {
430+
$repo = new ServerRepository;
431+
$repo->suspend($id);
432+
Alert::success('Server has been suspended on the system. All running processes have been stopped and will not be startable until it is un-suspended.');
433+
} catch (\Pterodactyl\Exceptions\DisplayException $e) {
434+
Alert::danger($e->getMessage())->flash();
435+
} catch(\Exception $e) {
436+
Log::error($e);
437+
Alert::danger('An unhandled exception occured while attemping to suspend this server. Please try again.')->flash();
438+
} finally {
439+
return redirect()->route('admin.servers.view', [
440+
'id' => $id,
441+
'tab' => 'tab_manage'
442+
]);
443+
}
444+
}
445+
446+
public function postUnsuspendServer(Request $request, $id)
447+
{
448+
try {
449+
$repo = new ServerRepository;
450+
$repo->unsuspend($id);
451+
Alert::success('Server has been unsuspended on the system. Access has been re-enabled.');
452+
} catch (\Pterodactyl\Exceptions\DisplayException $e) {
453+
Alert::danger($e->getMessage())->flash();
454+
} catch(\Exception $e) {
455+
Log::error($e);
456+
Alert::danger('An unhandled exception occured while attemping to unsuspend this server. Please try again.')->flash();
457+
} finally {
458+
return redirect()->route('admin.servers.view', [
459+
'id' => $id,
460+
'tab' => 'tab_manage'
461+
]);
462+
}
463+
}
464+
427465
}

app/Http/Controllers/Admin/UserController.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ public function getView(Request $request, $id)
6969
->join('nodes', 'servers.node', '=', 'nodes.id')
7070
->join('locations', 'nodes.location', '=', 'locations.id')
7171
->where('owner', $id)
72-
->where('active', 1)
7372
->get(),
7473
]);
7574
}

app/Http/Middleware/CheckServer.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,15 @@ public function handle($request, Closure $next)
4646

4747
$server = Server::getByUUID($request->route()->server);
4848
if (!$server) {
49-
return response()->view('errors.403', [], 403);
49+
return response()->view('errors.404', [], 404);
50+
}
51+
52+
if ($server->suspended === 1) {
53+
return response()->view('errors.suspended', [], 403);
5054
}
5155

5256
if ($server->installed !== 1) {
53-
return response()->view('errors.installing', [], 503);
57+
return response()->view('errors.installing', [], 403);
5458
}
5559

5660
return $next($request);

app/Http/Routes/AdminRoutes.php

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -129,21 +129,21 @@ public function map(Router $router) {
129129
]);
130130

131131
// Assorted Page Helpers
132-
$router->post('/new/get-nodes', [
133-
'uses' => 'Admin\ServersController@postNewServerGetNodes'
134-
]);
132+
$router->post('/new/get-nodes', [
133+
'uses' => 'Admin\ServersController@postNewServerGetNodes'
134+
]);
135135

136-
$router->post('/new/get-ips', [
137-
'uses' => 'Admin\ServersController@postNewServerGetIps'
138-
]);
136+
$router->post('/new/get-ips', [
137+
'uses' => 'Admin\ServersController@postNewServerGetIps'
138+
]);
139139

140-
$router->post('/new/service-options', [
141-
'uses' => 'Admin\ServersController@postNewServerServiceOptions'
142-
]);
140+
$router->post('/new/service-options', [
141+
'uses' => 'Admin\ServersController@postNewServerServiceOptions'
142+
]);
143143

144-
$router->post('/new/service-variables', [
145-
'uses' => 'Admin\ServersController@postNewServerServiceVariables'
146-
]);
144+
$router->post('/new/service-variables', [
145+
'uses' => 'Admin\ServersController@postNewServerServiceVariables'
146+
]);
147147
// End Assorted Page Helpers
148148

149149
// View Specific Server
@@ -179,6 +179,16 @@ public function map(Router $router) {
179179
'uses' => 'Admin\ServersController@postUpdateServerUpdateBuild'
180180
]);
181181

182+
// Suspend Server
183+
$router->post('/view/{id}/suspend', [
184+
'uses' => 'Admin\ServersController@postSuspendServer'
185+
]);
186+
187+
// Unsuspend Server
188+
$router->post('/view/{id}/unsuspend', [
189+
'uses' => 'Admin\ServersController@postUnsuspendServer'
190+
]);
191+
182192
// Change Install Status
183193
$router->post('/view/{id}/installed', [
184194
'uses' => 'Admin\ServersController@postToggleInstall'

app/Models/Server.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class Server extends Model
5959
*/
6060
protected $casts = [
6161
'node' => 'integer',
62-
'active' => 'integer',
62+
'suspended' => 'integer',
6363
'owner' => 'integer',
6464
'memory' => 'integer',
6565
'swap' => 'integer',
@@ -117,7 +117,7 @@ protected static function getUserDaemonSecret(Server $server)
117117

118118
/**
119119
* Returns array of all servers owned by the logged in user.
120-
* Returns all active servers if user is a root admin.
120+
* Returns all users servers if user is a root admin.
121121
*
122122
* @return \Illuminate\Database\Eloquent\Collection
123123
*/
@@ -132,8 +132,7 @@ public static function getUserServers($paginate = null)
132132
'allocations.port'
133133
)->join('nodes', 'servers.node', '=', 'nodes.id')
134134
->join('locations', 'nodes.location', '=', 'locations.id')
135-
->join('allocations', 'servers.allocation', '=', 'allocations.id')
136-
->where('active', 1);
135+
->join('allocations', 'servers.allocation', '=', 'allocations.id');
137136

138137
if (self::$user->root_admin !== 1) {
139138
$query->whereIn('servers.id', Subuser::accessServers());
@@ -164,7 +163,7 @@ public static function getByUUID($uuid)
164163

165164
$query = self::select('servers.*', 'services.file as a_serviceFile')
166165
->join('services', 'services.id', '=', 'servers.service')
167-
->where('uuidShort', $uuid)->where('active', 1);
166+
->where('uuidShort', $uuid);
168167

169168
if (self::$user->root_admin !== 1) {
170169
$query->whereIn('servers.id', Subuser::accessServers());

app/Repositories/ServerRepository.php

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ public function create(array $data)
205205
'uuidShort' => $uuid->generateShort('servers', 'uuidShort', $generatedUuid),
206206
'node' => $data['node'],
207207
'name' => $data['name'],
208-
'active' => 1,
208+
'suspended' => 0,
209209
'owner' => $user->id,
210210
'memory' => $data['memory'],
211211
'swap' => $data['swap'],
@@ -728,9 +728,31 @@ public function toggleInstall($id)
728728
*/
729729
public function suspend($id)
730730
{
731-
// @TODO: Implement logic; not doing it now since that is outside of the
732-
// scope of this API brance.
733-
return true;
731+
$server = Models\Server::findOrFail($id);
732+
$node = Models\Node::findOrFail($server->node);
733+
734+
DB::beginTransaction();
735+
736+
try {
737+
$server->suspended = 1;
738+
$server->save();
739+
740+
$client = Models\Node::guzzleRequest($server->node);
741+
$client->request('POST', '/server/suspend', [
742+
'headers' => [
743+
'X-Access-Token' => $node->daemonSecret,
744+
'X-Access-Server' => $server->uuid
745+
]
746+
]);
747+
748+
return DB::commit();
749+
} catch (\GuzzleHttp\Exception\TransferException $ex) {
750+
DB::rollBack();
751+
throw new DisplayException('An error occured while attempting to suspend this server.', $ex);
752+
} catch (\Exception $ex) {
753+
DB::rollBack();
754+
throw $ex;
755+
}
734756
}
735757

736758
/**
@@ -740,9 +762,31 @@ public function suspend($id)
740762
*/
741763
public function unsuspend($id)
742764
{
743-
// @TODO: Implement logic; not doing it now since that is outside of the
744-
// scope of this API brance.
745-
return true;
765+
$server = Models\Server::findOrFail($id);
766+
$node = Models\Node::findOrFail($server->node);
767+
768+
DB::beginTransaction();
769+
770+
try {
771+
$server->suspended = 0;
772+
$server->save();
773+
774+
$client = Models\Node::guzzleRequest($server->node);
775+
$client->request('POST', '/server/unsuspend', [
776+
'headers' => [
777+
'X-Access-Token' => $node->daemonSecret,
778+
'X-Access-Server' => $server->uuid
779+
]
780+
]);
781+
782+
return DB::commit();
783+
} catch (\GuzzleHttp\Exception\TransferException $ex) {
784+
DB::rollBack();
785+
throw new DisplayException('An error occured while attempting to un-suspend this server.', $ex);
786+
} catch (\Exception $ex) {
787+
DB::rollBack();
788+
throw $ex;
789+
}
746790
}
747791

748792
public function updateSFTPPassword($id, $password)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
use Illuminate\Database\Schema\Blueprint;
4+
use Illuminate\Database\Migrations\Migration;
5+
6+
class AddSuspensionForServers extends Migration
7+
{
8+
/**
9+
* Run the migrations.
10+
*
11+
* @return void
12+
*/
13+
public function up()
14+
{
15+
Schema::table('servers', function (Blueprint $table) {
16+
$table->tinyInteger('suspended')->unsigned()->default(0)->after('active');
17+
});
18+
}
19+
20+
/**
21+
* Reverse the migrations.
22+
*
23+
* @return void
24+
*/
25+
public function down()
26+
{
27+
Schema::table('servers', function (Blueprint $table) {
28+
$table->dropColumn('suspended');
29+
});
30+
}
31+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
use Illuminate\Database\Schema\Blueprint;
4+
use Illuminate\Database\Migrations\Migration;
5+
6+
class RemoveActiveColumn extends Migration
7+
{
8+
/**
9+
* Run the migrations.
10+
*
11+
* @return void
12+
*/
13+
public function up()
14+
{
15+
Schema::table('servers', function (Blueprint $table) {
16+
$table->dropColumn('active');
17+
});
18+
}
19+
20+
/**
21+
* Reverse the migrations.
22+
*
23+
* @return void
24+
*/
25+
public function down()
26+
{
27+
Schema::table('servers', function (Blueprint $table) {
28+
$table->tinyInteger('active')->after('name')->unsigned()->default(0);
29+
});
30+
}
31+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@
4242
</thead>
4343
<tbody>
4444
@foreach ($servers as $server)
45-
<tr class="dynUpdate @if($server->active !== 1)active @endif" id="{{ $server->uuidShort }}">
46-
<td><a href="/admin/servers/view/{{ $server->id }}">{{ $server->name }}</td>
45+
<tr class="dynUpdate @if($server->suspended === 1)warning @endif" id="{{ $server->uuidShort }}">
46+
<td><a href="/admin/servers/view/{{ $server->id }}">{{ $server->name }}</a>@if($server->suspended === 1) <span class="label label-warning">Suspended</span>@endif</td>
4747
<td><a href="/admin/users/view/{{ $server->owner }}">{{ $server->a_ownerEmail }}</a></td>
4848
<td class="hidden-xs"><a href="/admin/nodes/view/{{ $server->node }}">{{ $server->a_nodeName }}</a></td>
4949
<td><code>{{ $server->ip_alias }}:{{ $server->port }}</code> @if($server->ip !== $server->ip_alias)<span class="label label-default">alias</span>@endif</td>

0 commit comments

Comments
 (0)