Fix servers not being marked as install failed

This commit is contained in:
Dane Everitt 2019-03-03 13:44:28 -08:00
parent cf31d4276c
commit f15449f17b
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
3 changed files with 39 additions and 15 deletions

View file

@ -13,6 +13,7 @@ This project follows [Semantic Versioning](http://semver.org) guidelines.
and other session data to not be persisted properly when using the database as the session driver. and other session data to not be persisted properly when using the database as the session driver.
* Fix a bug introduced at some point in the past that causes internal data integrity exceptions to not bubble up to * Fix a bug introduced at some point in the past that causes internal data integrity exceptions to not bubble up to
the user correctly, leading to extraneous and confusing exception messages. the user correctly, leading to extraneous and confusing exception messages.
* Fixes a bug causing servers to not be marked as having failed installation in some cases.
### Changed ### Changed
* `allocation_limit` for servers now defaults to a null value, and is not required in PATCH/POST requests when adding * `allocation_limit` for servers now defaults to a null value, and is not required in PATCH/POST requests when adding

View file

@ -5,10 +5,14 @@ namespace Pterodactyl\Http\Controllers\Daemon;
use Cache; use Cache;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Pterodactyl\Models\Node; use Pterodactyl\Models\Node;
use Illuminate\Http\Response;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Illuminate\Http\JsonResponse;
use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Repositories\Eloquent\ServerRepository;
use Pterodactyl\Events\Server\Installed as ServerInstalled; use Pterodactyl\Events\Server\Installed as ServerInstalled;
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher; use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
class ActionController extends Controller class ActionController extends Controller
{ {
@ -16,15 +20,21 @@ class ActionController extends Controller
* @var \Illuminate\Contracts\Events\Dispatcher * @var \Illuminate\Contracts\Events\Dispatcher
*/ */
private $eventDispatcher; private $eventDispatcher;
/**
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
*/
private $repository;
/** /**
* ActionController constructor. * ActionController constructor.
* *
* @param \Illuminate\Contracts\Events\Dispatcher $eventDispatcher * @param \Pterodactyl\Repositories\Eloquent\ServerRepository $repository
* @param \Illuminate\Contracts\Events\Dispatcher $eventDispatcher
*/ */
public function __construct(EventDispatcher $eventDispatcher) public function __construct(ServerRepository $repository, EventDispatcher $eventDispatcher)
{ {
$this->eventDispatcher = $eventDispatcher; $this->eventDispatcher = $eventDispatcher;
$this->repository = $repository;
} }
/** /**
@ -32,34 +42,47 @@ class ActionController extends Controller
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse
*
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */
public function markInstall(Request $request) public function markInstall(Request $request): JsonResponse
{ {
$server = Server::where('uuid', $request->input('server'))->with('node')->first(); try {
if (! $server) { /** @var \Pterodactyl\Models\Server $server */
return response()->json([ $server = $this->repository->findFirstWhere([
'uuid' => $request->input('server'),
]);
} catch (RecordNotFoundException $exception) {
return JsonResponse::create([
'error' => 'No server by that ID was found on the system.', 'error' => 'No server by that ID was found on the system.',
], 422); ], Response::HTTP_UNPROCESSABLE_ENTITY);
}
if (! $server->relationLoaded('node')) {
$server->load('node');
} }
$hmac = $request->input('signed'); $hmac = $request->input('signed');
$status = $request->input('installed'); $status = $request->input('installed');
if (! hash_equals(base64_decode($hmac), hash_hmac('sha256', $server->uuid, $server->node->daemonSecret, true))) { if (! hash_equals(base64_decode($hmac), hash_hmac('sha256', $server->uuid, $server->getRelation('node')->daemonSecret, true))) {
return response()->json([ return JsonResponse::create([
'error' => 'Signed HMAC was invalid.', 'error' => 'Signed HMAC was invalid.',
], 403); ], Response::HTTP_FORBIDDEN);
} }
$server->installed = ($status === 'installed') ? 1 : 2; $this->repository->update($server->id, [
$server->save(); 'installed' => ($status === 'installed') ? 1 : 2,
], true, true);
// Only fire event if server installed successfully. // Only fire event if server installed successfully.
if ($server->installed === 1) { if ($status === 'installed') {
$this->eventDispatcher->dispatch(new ServerInstalled($server)); $this->eventDispatcher->dispatch(new ServerInstalled($server));
} }
return response()->json([]); // Don't use a 204 here, the daemon is hard-checking for a 200 code.
return JsonResponse::create([]);
} }
/** /**

View file

@ -87,7 +87,7 @@ class Server extends Model implements CleansAttributes, ValidableContract
'startup' => 'string', 'startup' => 'string',
'skip_scripts' => 'boolean', 'skip_scripts' => 'boolean',
'image' => 'string|max:255', 'image' => 'string|max:255',
'installed' => 'boolean', 'installed' => 'in:0,1,2',
'database_limit' => 'nullable|integer|min:0', 'database_limit' => 'nullable|integer|min:0',
'allocation_limit' => 'nullable|integer|min:0', 'allocation_limit' => 'nullable|integer|min:0',
]; ];