Skip to content

Commit de923bb

Browse files
committed
Fix server deletion logic, and clean up suspend/unsuspend operations
1 parent bdfab16 commit de923bb

File tree

5 files changed

+55
-80
lines changed

5 files changed

+55
-80
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ This project follows [Semantic Versioning](http://semver.org) guidelines.
1111
* `[beta.2]` — Fixes exception in tasks when deleting a server.
1212
* `[beta.2]` — Fixes bug with Terarria and Voice servers reporting a `TypeError: Service is not a constructor` in the daemon due to a missing service configuration.
1313

14+
### Changed
15+
* Deleting a server safely now continues even if the daemon reports a `HTTP/404` missing server error (requires `Daemon@0.4.0-beta.2.1`)
16+
17+
### Added
18+
* Server listing and view in Admin CP now shows the SFTP username/Docker container name.
19+
1420
## v0.6.0-beta.2 (Courageous Carniadactylus)
1521
### Fixed
1622
* `[beta.1]` — Fixes task management ststem not running correctly.

app/Http/Controllers/API/Admin/ServerController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ public function suspend(Request $request, $id)
318318
}
319319

320320
try {
321-
$repo->$action($id);
321+
$repo->toggleAccess($id, ($action === 'unsuspend'));
322322

323323
return response('', 204);
324324
} catch (DisplayException $ex) {

app/Http/Controllers/Admin/ServersController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ public function manageSuspension(Request $request, $id)
367367
}
368368

369369
try {
370-
$repo->$action($id);
370+
$repo->toggleAccess($id, ($action === 'unsuspend'));
371371

372372
Alert::success('Server has been ' . $action . 'ed.');
373373
} catch (TransferException $ex) {

app/Models/Server.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,16 @@ public function databases()
333333
return $this->hasMany(Database::class);
334334
}
335335

336+
/**
337+
* Gets all downloads associated with a server.
338+
*
339+
* @return \Illuminate\Database\Eloquent\Relations\HasMany
340+
*/
341+
public function downloads()
342+
{
343+
return $this->hasMany(Download::class, 'server', 'id');
344+
}
345+
336346
/**
337347
* Gets the location of the server.
338348
*

app/Repositories/ServerRepository.php

Lines changed: 37 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use Validator;
3030
use Pterodactyl\Models;
3131
use Pterodactyl\Services\UuidService;
32+
use GuzzleHttp\Exception\ClientException;
3233
use GuzzleHttp\Exception\TransferException;
3334
use Pterodactyl\Services\DeploymentService;
3435
use Pterodactyl\Exceptions\DisplayException;
@@ -722,6 +723,16 @@ public function delete($id, $force = false)
722723
'X-Access-Token' => $server->node->daemonSecret,
723724
'X-Access-Server' => $server->uuid,
724725
])->request('DELETE', '/servers');
726+
} catch (ClientException $ex) {
727+
// Exception is thrown on 4XX HTTP errors, so catch and determine
728+
// if we should continue, or if there is a permissions error.
729+
//
730+
// Daemon throws a 404 if the server doesn't exist, if that is returned
731+
// continue with deletion, even if not a force deletion.
732+
$response = $ex->getResponse();
733+
if ($ex->getResponse()->getStatusCode() !== 404 && ! $force) {
734+
throw new DisplayException($ex->getMessage());
735+
}
725736
} catch (TransferException $ex) {
726737
if (! $force) {
727738
throw new DisplayException($ex->getMessage());
@@ -736,30 +747,26 @@ public function delete($id, $force = false)
736747
$item->save();
737748
});
738749

739-
$server->variables->each(function ($item) {
740-
$item->delete();
741-
});
750+
$server->variables->each->delete();
742751

743-
foreach (Models\Subuser::with('permissions')->where('server_id', $server->id)->get() as &$subuser) {
744-
foreach ($subuser->permissions as &$permission) {
745-
$permission->delete();
746-
}
752+
$server->load('subusers.permissions');
753+
$server->subusers->each(function ($subuser) {
754+
$subuser->permissions->each(function ($permission) {
755+
$perm->delete();
756+
});
747757
$subuser->delete();
748-
}
749-
750-
// Remove Downloads
751-
Models\Download::where('server', $server->uuid)->delete();
758+
});
752759

753-
// Clear Tasks
754-
Models\Task::where('server_id', $server->id)->delete();
760+
$server->downloads->each->delete();
761+
$server->tasks->each->delete();
755762

756763
// Delete Databases
757764
// This is the one un-recoverable point where
758765
// transactions will not save us.
759766
$repository = new DatabaseRepository;
760-
foreach (Models\Database::select('id')->where('server_id', $server->id)->get() as $database) {
761-
$repository->drop($database->id);
762-
}
767+
$server->databases->each(function ($item) {
768+
$repository->drop($item->id);
769+
});
763770

764771
// Fully delete the server.
765772
$server->delete();
@@ -786,71 +793,32 @@ public function toggleInstall($id)
786793
}
787794

788795
/**
789-
* Suspends a server.
790-
*
791-
* @param int $id
792-
* @param bool $deleted
793-
* @return void
794-
*/
795-
public function suspend($id, $deleted = false)
796-
{
797-
$server = Models\Server::with('node')->findOrFail($id);
798-
799-
DB::beginTransaction();
800-
801-
try {
802-
803-
// Already suspended, no need to make more requests.
804-
if ($server->suspended) {
805-
return true;
806-
}
807-
808-
$server->suspended = 1;
809-
$server->save();
810-
811-
$server->node->guzzleClient([
812-
'X-Access-Token' => $server->node->daemonSecret,
813-
'X-Access-Server' => $server->uuid,
814-
])->request('POST', '/server/suspend');
815-
816-
return DB::commit();
817-
} catch (\Exception $ex) {
818-
DB::rollBack();
819-
throw $ex;
820-
}
821-
}
822-
823-
/**
824-
* Unsuspends a server.
796+
* Suspends or unsuspends a server.
825797
*
826798
* @param int $id
799+
* @param bool $unsuspend
827800
* @return void
828801
*/
829-
public function unsuspend($id)
802+
public function toggleAccess($id, $unsuspend = true)
830803
{
831804
$server = Models\Server::with('node')->findOrFail($id);
832805

833-
DB::beginTransaction();
834-
835-
try {
836-
// Already unsuspended, no need to make more requests.
837-
if ($server->suspended === 0) {
806+
DB::transaction(function () use ($server, $unsuspend) {
807+
if (
808+
(! $unsuspend && $server->suspended) ||
809+
($unsuspend && ! $server->suspended)
810+
) {
838811
return true;
839812
}
840813

841-
$server->suspended = 0;
814+
$server->suspended = ! $unsuspend;
842815
$server->save();
843816

844817
$server->node->guzzleClient([
845818
'X-Access-Token' => $server->node->daemonSecret,
846819
'X-Access-Server' => $server->uuid,
847-
])->request('POST', '/server/unsuspend');
848-
849-
return DB::commit();
850-
} catch (\Exception $ex) {
851-
DB::rollBack();
852-
throw $ex;
853-
}
820+
])->request('POST', ($unsuspend) ? '/server/unsuspend' : '/server/suspend');
821+
});
854822
}
855823

856824
/**
@@ -874,10 +842,8 @@ public function updateSFTPPassword($id, $password)
874842
throw new DisplayValidationException(json_encode($validator->errors()));
875843
}
876844

877-
DB::beginTransaction();
878-
$server->sftp_password = Crypt::encrypt($password);
879-
880-
try {
845+
DB::transaction(function () use ($password, $server) {
846+
$server->sftp_password = Crypt::encrypt($password);
881847
$server->save();
882848

883849
$server->node->guzzleClient([
@@ -886,13 +852,6 @@ public function updateSFTPPassword($id, $password)
886852
])->request('POST', '/server/password', [
887853
'json' => ['password' => $password],
888854
]);
889-
890-
DB::commit();
891-
892-
return true;
893-
} catch (\Exception $ex) {
894-
DB::rollBack();
895-
throw $ex;
896-
}
855+
});
897856
}
898857
}

0 commit comments

Comments
 (0)