From 4ad09c5435e12a9ab216ca0e8a882e597ad3ed84 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Thu, 16 Mar 2017 21:11:15 -0400 Subject: [PATCH] Fixes bug introduced during admin rewrite that broke server creation --- .../Controllers/Admin/ServersController.php | 3 +- app/Models/Node.php | 4 +- app/Repositories/ServerRepository.php | 73 +++++++++---------- config/pterodactyl.php | 30 +++++--- 4 files changed, 60 insertions(+), 50 deletions(-) diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index 5ac430865..3de8d0c9f 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -454,9 +454,10 @@ class ServersController extends Controller * * @param Request $request * @param int $id + * @param string $method * @return \Illuminate\Response\RedirectResponse */ - public function continueDeletion(Request $request, $id, $method) + public function continueDeletion(Request $request, $id, $method = 'safe') { $repo = new ServerRepository; diff --git a/app/Models/Node.php b/app/Models/Node.php index 928633095..f1a3159be 100644 --- a/app/Models/Node.php +++ b/app/Models/Node.php @@ -97,8 +97,8 @@ class Node extends Model { return new Client([ 'base_uri' => sprintf('%s://%s:%s/', $this->scheme, $this->fqdn, $this->daemonListen), - 'timeout' => env('GUZZLE_TIMEOUT', 5.0), - 'connect_timeout' => env('GUZZLE_CONNECT_TIMEOUT', 3.0), + 'timeout' => config('pterodactyl.guzzle.timeout'), + 'connect_timeout' => config('pterodactyl.guzzle.connect_timeout'), 'headers' => $headers, ]); } diff --git a/app/Repositories/ServerRepository.php b/app/Repositories/ServerRepository.php index 5ffbe65c2..223659fcd 100644 --- a/app/Repositories/ServerRepository.php +++ b/app/Repositories/ServerRepository.php @@ -314,10 +314,10 @@ class ServerRepository 'io' => (int) $server->io, 'cpu' => (int) $server->cpu, 'disk' => (int) $server->disk, - 'image' => (isset($data['custom_container'])) ? $data['custom_container'] : $option->docker_image, + 'image' => $server->image, ], 'service' => [ - 'type' => $service->file, + 'type' => $service->folder, 'option' => $option->tag, 'pack' => (isset($pack)) ? $pack->uuid : null, ], @@ -701,7 +701,6 @@ class ServerRepository $server->installed = 3; $server->save(); } - $server->delete(); return DB::commit(); @@ -713,7 +712,7 @@ class ServerRepository public function delete($id, $force = false) { - $server = Models\Server::withTrashed()->with('node')->findOrFail($id); + $server = Models\Server::withTrashed()->with('node', 'allocations', 'variables')->findOrFail($id); // Handle server being restored previously or // an accidental queue. @@ -721,17 +720,34 @@ class ServerRepository return; } - DB::beginTransaction(); + // Due to MySQL lockouts if the daemon response fails, we need to + // delete the server from the daemon first. If it succeedes and then + // MySQL fails, users just need to force delete the server. + // + // If this is a force delete, continue anyways. try { - // Unassign Allocations - Models\Allocation::where('server_id', $server->id)->update([ - 'server_id' => null, - ]); + $server->node->guzzleClient([ + 'X-Access-Token' => $server->node->daemonSecret, + 'X-Access-Server' => $server->uuid, + ])->request('DELETE', '/servers'); + } catch (TransferException $ex) { + if ($server->installed !== 3 && ! $force) { + throw new DisplayException($ex->getMessage()); + } + } catch (\Exception $ex) { + throw $ex; + } - // Remove Variables - Models\ServerVariable::where('server_id', $server->id)->delete(); + DB::transaction(function () use ($server) { + $server->allocations->each(function ($item) { + $item->server_id = null; + $item->save(); + }); + + $server->variables->each(function ($item) { + $item->delete(); + }); - // Remove SubUsers foreach (Models\Subuser::with('permissions')->where('server_id', $server->id)->get() as &$subuser) { foreach ($subuser->permissions as &$permission) { $permission->delete(); @@ -748,33 +764,14 @@ class ServerRepository // Delete Databases // This is the one un-recoverable point where // transactions will not save us. - // - // @TODO: move to post-deletion event as a queued task! - // $repository = new DatabaseRepository; - // foreach (Models\Database::select('id')->where('server_id', $server->id)->get() as &$database) { - // $repository->drop($database->id); - // } - - $server->node->guzzleClient([ - 'X-Access-Token' => $server->node->daemonSecret, - 'X-Access-Server' => $server->uuid, - ])->request('DELETE', '/servers'); - - $server->forceDelete(); - DB::commit(); - } catch (TransferException $ex) { - // Set installed is set to 3 when force deleting. - if ($server->installed === 3 || $force) { - $server->forceDelete(); - DB::commit(); - } else { - DB::rollBack(); - throw $ex; + $repository = new DatabaseRepository; + foreach (Models\Database::select('id')->where('server_id', $server->id)->get() as $database) { + $repository->drop($database->id); } - } catch (\Exception $ex) { - DB::rollBack(); - throw $ex; - } + + // Fully delete the server. + $server->forceDelete(); + }); } public function cancelDeletion($id) diff --git a/config/pterodactyl.php b/config/pterodactyl.php index 77a946adb..1b946c6a3 100644 --- a/config/pterodactyl.php +++ b/config/pterodactyl.php @@ -11,10 +11,10 @@ return [ | author of custom services, and make upgrades easier by identifying | standard Pterodactyl shipped services. */ - 'service' => [ - 'core' => 'ptrdctyl-v040-11e6-8b77-86f30ca893d3', - 'author' => env('SERVICE_AUTHOR'), - ], + 'service' => [ + 'core' => 'ptrdctyl-v040-11e6-8b77-86f30ca893d3', + 'author' => env('SERVICE_AUTHOR'), + ], /* |-------------------------------------------------------------------------- @@ -24,10 +24,22 @@ return [ | Certain pagination result counts can be configured here and will take | effect globally. */ - 'paginate' => [ - 'frontend' => [ - 'servers' => 15, - ], - ], + 'paginate' => [ + 'frontend' => [ + 'servers' => 15, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Guzzle Connections + |-------------------------------------------------------------------------- + | + | Configure the timeout to be used for Guzzle connections here. + */ + 'guzzle' => [ + 'timeout' => env('GUZZLE_TIMEOUT', 5), + 'connect_timeout' => env('GUZZLE_CONNECT_TIMEOUT', 3), + ], ];