mirror of
https://github.com/pelican-dev/panel.git
synced 2025-05-20 00:34:44 +02:00
Remove DaemonConnectionException
(#885)
* remove DaemonConnectionException * update tests
This commit is contained in:
parent
6fcf4173d3
commit
c93a836ad8
@ -8,7 +8,7 @@ use Illuminate\Database\Eloquent\Builder;
|
|||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
use Illuminate\Validation\Factory as ValidatorFactory;
|
use Illuminate\Validation\Factory as ValidatorFactory;
|
||||||
use App\Repositories\Daemon\DaemonPowerRepository;
|
use App\Repositories\Daemon\DaemonPowerRepository;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
use Exception;
|
||||||
|
|
||||||
class BulkPowerActionCommand extends Command
|
class BulkPowerActionCommand extends Command
|
||||||
{
|
{
|
||||||
@ -71,7 +71,7 @@ class BulkPowerActionCommand extends Command
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
$powerRepository->setServer($server)->send($action);
|
$powerRepository->setServer($server)->send($action);
|
||||||
} catch (DaemonConnectionException $exception) {
|
} catch (Exception $exception) {
|
||||||
$this->output->error(trans('command/messages.server.power.action_failed', [
|
$this->output->error(trans('command/messages.server.power.action_failed', [
|
||||||
'name' => $server->name,
|
'name' => $server->name,
|
||||||
'id' => $server->id,
|
'id' => $server->id,
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions\Http\Connection;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
use App\Exceptions\DisplayException;
|
|
||||||
use Illuminate\Support\Facades\Context;
|
|
||||||
|
|
||||||
class DaemonConnectionException extends DisplayException
|
|
||||||
{
|
|
||||||
private int $statusCode = Response::HTTP_GATEWAY_TIMEOUT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Every request to the daemon instance will return a unique X-Request-Id header
|
|
||||||
* which allows for all errors to be efficiently tied to a specific request that
|
|
||||||
* triggered them, and gives users a more direct method of informing hosts when
|
|
||||||
* something goes wrong.
|
|
||||||
*/
|
|
||||||
private ?string $requestId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Throw a displayable exception caused by a daemon connection error.
|
|
||||||
*/
|
|
||||||
public function __construct(?Exception $previous, bool $useStatusCode = true)
|
|
||||||
{
|
|
||||||
/** @var \GuzzleHttp\Psr7\Response|null $response */
|
|
||||||
$response = method_exists($previous, 'getResponse') ? $previous->getResponse() : null;
|
|
||||||
$this->requestId = $response?->getHeaderLine('X-Request-Id');
|
|
||||||
|
|
||||||
Context::add('request_id', $this->requestId);
|
|
||||||
|
|
||||||
if ($useStatusCode) {
|
|
||||||
$this->statusCode = is_null($response) ? $this->statusCode : $response->getStatusCode();
|
|
||||||
// There are rare conditions where daemon encounters a panic condition and crashes the
|
|
||||||
// request being made after content has already been sent over the wire. In these cases
|
|
||||||
// you can end up with a "successful" response code that is actual an error.
|
|
||||||
//
|
|
||||||
// Handle those better here since we shouldn't ever end up in this exception state and
|
|
||||||
// be returning a 2XX level response.
|
|
||||||
if ($this->statusCode < 400) {
|
|
||||||
$this->statusCode = Response::HTTP_BAD_GATEWAY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_null($response)) {
|
|
||||||
$message = 'Could not establish a connection to the machine running this server. Please try again.';
|
|
||||||
} else {
|
|
||||||
$message = sprintf('There was an error while communicating with the machine running this server. This error has been logged, please try again. (code: %s) (request_id: %s)', $response->getStatusCode(), $this->requestId ?? '<nil>');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to pull the actual error message off the response and return that if it is not
|
|
||||||
// a 500 level error.
|
|
||||||
if ($this->statusCode < 500 && !is_null($response)) {
|
|
||||||
$body = json_decode($response->getBody()->__toString(), true);
|
|
||||||
$message = sprintf('An error occurred on the remote host: %s. (request id: %s)', $body['error'] ?? $message, $this->requestId ?? '<nil>');
|
|
||||||
}
|
|
||||||
|
|
||||||
$level = $this->statusCode >= 500 && $this->statusCode !== 504
|
|
||||||
? DisplayException::LEVEL_ERROR
|
|
||||||
: DisplayException::LEVEL_WARNING;
|
|
||||||
|
|
||||||
parent::__construct($message, $previous, $level);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the HTTP status code for this exception.
|
|
||||||
*/
|
|
||||||
public function getStatusCode(): int
|
|
||||||
{
|
|
||||||
return $this->statusCode;
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,10 +3,10 @@
|
|||||||
namespace App\Filament\Server\Pages;
|
namespace App\Filament\Server\Pages;
|
||||||
|
|
||||||
use App\Enums\ServerState;
|
use App\Enums\ServerState;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
|
||||||
use App\Facades\Activity;
|
use App\Facades\Activity;
|
||||||
use App\Models\Permission;
|
use App\Models\Permission;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
|
use App\Repositories\Daemon\DaemonServerRepository;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Filament\Facades\Filament;
|
use Filament\Facades\Filament;
|
||||||
use Filament\Forms\Components\Actions\Action;
|
use Filament\Forms\Components\Actions\Action;
|
||||||
@ -18,8 +18,6 @@ use Filament\Forms\Components\TextInput;
|
|||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Support\Enums\Alignment;
|
use Filament\Support\Enums\Alignment;
|
||||||
use GuzzleHttp\Exception\TransferException;
|
|
||||||
use Illuminate\Support\Facades\Http;
|
|
||||||
use Illuminate\Support\Number;
|
use Illuminate\Support\Number;
|
||||||
|
|
||||||
class Settings extends ServerFormPage
|
class Settings extends ServerFormPage
|
||||||
@ -202,17 +200,23 @@ class Settings extends ServerFormPage
|
|||||||
->modalHeading('Are you sure you want to reinstall the server?')
|
->modalHeading('Are you sure you want to reinstall the server?')
|
||||||
->modalDescription('Some files may be deleted or modified during this process, please back up your data before continuing.')
|
->modalDescription('Some files may be deleted or modified during this process, please back up your data before continuing.')
|
||||||
->modalSubmitActionLabel('Yes, Reinstall')
|
->modalSubmitActionLabel('Yes, Reinstall')
|
||||||
->action(function (Server $server) {
|
->action(function (Server $server, DaemonServerRepository $serverRepository) {
|
||||||
abort_unless(auth()->user()->can(Permission::ACTION_SETTINGS_REINSTALL, $server), 403);
|
abort_unless(auth()->user()->can(Permission::ACTION_SETTINGS_REINSTALL, $server), 403);
|
||||||
|
|
||||||
$server->fill(['status' => ServerState::Installing])->save();
|
$server->fill(['status' => ServerState::Installing])->save();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Http::daemon($server->node)->post(sprintf(
|
$serverRepository->reinstall();
|
||||||
'/api/servers/%s/reinstall',
|
} catch (Exception $exception) {
|
||||||
$server->uuid
|
report($exception);
|
||||||
));
|
|
||||||
} catch (TransferException $exception) {
|
Notification::make()
|
||||||
throw new DaemonConnectionException($exception);
|
->danger()
|
||||||
|
->title('Server Reinstall failed')
|
||||||
|
->body($exception->getMessage())
|
||||||
|
->send();
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Activity::event('server:settings.reinstall')
|
Activity::event('server:settings.reinstall')
|
||||||
@ -220,7 +224,7 @@ class Settings extends ServerFormPage
|
|||||||
|
|
||||||
Notification::make()
|
Notification::make()
|
||||||
->success()
|
->success()
|
||||||
->title('Server Reinstall Started')
|
->title('Server Reinstall started')
|
||||||
->send();
|
->send();
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
|
@ -70,4 +70,12 @@ abstract class ApplicationApiController extends Controller
|
|||||||
{
|
{
|
||||||
return new Response('', Response::HTTP_NO_CONTENT);
|
return new Response('', Response::HTTP_NO_CONTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an HTTP/406 response for the API.
|
||||||
|
*/
|
||||||
|
protected function returnNotAcceptable(): Response
|
||||||
|
{
|
||||||
|
return new Response('', Response::HTTP_NOT_ACCEPTABLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ use App\Repositories\Daemon\DaemonServerRepository;
|
|||||||
use App\Services\Servers\ReinstallServerService;
|
use App\Services\Servers\ReinstallServerService;
|
||||||
use App\Services\Servers\SuspensionService;
|
use App\Services\Servers\SuspensionService;
|
||||||
use App\Services\Servers\TransferServerService;
|
use App\Services\Servers\TransferServerService;
|
||||||
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
|
|
||||||
class ServerManagementController extends ApplicationApiController
|
class ServerManagementController extends ApplicationApiController
|
||||||
@ -80,19 +81,19 @@ class ServerManagementController extends ApplicationApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Node was not viable
|
// Node was not viable
|
||||||
return new Response('', Response::HTTP_NOT_ACCEPTABLE);
|
return $this->returnNotAcceptable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels a transfer of a server to a new node.
|
* Cancels a transfer of a server to a new node.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function cancelTransfer(ServerWriteRequest $request, Server $server): Response
|
public function cancelTransfer(ServerWriteRequest $request, Server $server): Response
|
||||||
{
|
{
|
||||||
if (!$transfer = $server->transfer) {
|
if (!$transfer = $server->transfer) {
|
||||||
// Server is not transferring
|
// Server is not transferring
|
||||||
return new Response('', Response::HTTP_NOT_ACCEPTABLE);
|
return $this->returnNotAcceptable();
|
||||||
}
|
}
|
||||||
|
|
||||||
$transfer->successful = true;
|
$transfer->successful = true;
|
||||||
|
@ -2,12 +2,15 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Api\Application\Servers;
|
namespace App\Http\Controllers\Api\Application\Servers;
|
||||||
|
|
||||||
|
use App\Exceptions\Model\DataValidationException;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Services\Servers\StartupModificationService;
|
use App\Services\Servers\StartupModificationService;
|
||||||
use App\Transformers\Api\Application\ServerTransformer;
|
use App\Transformers\Api\Application\ServerTransformer;
|
||||||
use App\Http\Controllers\Api\Application\ApplicationApiController;
|
use App\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
use App\Http\Requests\Api\Application\Servers\UpdateServerStartupRequest;
|
use App\Http\Requests\Api\Application\Servers\UpdateServerStartupRequest;
|
||||||
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
|
||||||
class StartupController extends ApplicationApiController
|
class StartupController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
@ -22,9 +25,9 @@ class StartupController extends ApplicationApiController
|
|||||||
/**
|
/**
|
||||||
* Update the startup and environment settings for a specific server.
|
* Update the startup and environment settings for a specific server.
|
||||||
*
|
*
|
||||||
* @throws \Illuminate\Validation\ValidationException
|
* @throws ValidationException
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
* @throws \App\Exceptions\Model\DataValidationException
|
* @throws DataValidationException
|
||||||
*/
|
*/
|
||||||
public function index(UpdateServerStartupRequest $request, Server $server): array
|
public function index(UpdateServerStartupRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
|
@ -10,27 +10,25 @@ use GuzzleHttp\Exception\BadResponseException;
|
|||||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||||
use App\Http\Controllers\Api\Client\ClientApiController;
|
use App\Http\Controllers\Api\Client\ClientApiController;
|
||||||
use App\Http\Requests\Api\Client\Servers\SendCommandRequest;
|
use App\Http\Requests\Api\Client\Servers\SendCommandRequest;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
use Exception;
|
||||||
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
|
||||||
class CommandController extends ClientApiController
|
class CommandController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Send a command to a running server.
|
* Send a command to a running server.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function index(SendCommandRequest $request, Server $server): Response
|
public function index(SendCommandRequest $request, Server $server): Response
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$server->send($request->input('command'));
|
$server->send($request->input('command'));
|
||||||
} catch (DaemonConnectionException $exception) {
|
} catch (Exception $exception) {
|
||||||
$previous = $exception->getPrevious();
|
$previous = $exception->getPrevious();
|
||||||
|
|
||||||
if ($previous instanceof BadResponseException) {
|
if ($previous instanceof BadResponseException) {
|
||||||
if (
|
if ($previous->getResponse() instanceof ResponseInterface && $previous->getResponse()->getStatusCode() === Response::HTTP_BAD_GATEWAY) {
|
||||||
$previous->getResponse() instanceof ResponseInterface
|
|
||||||
&& $previous->getResponse()->getStatusCode() === Response::HTTP_BAD_GATEWAY
|
|
||||||
) {
|
|
||||||
throw new HttpException(Response::HTTP_BAD_GATEWAY, 'Server must be online in order to send commands.', $exception);
|
throw new HttpException(Response::HTTP_BAD_GATEWAY, 'Server must be online in order to send commands.', $exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -38,7 +36,9 @@ class CommandController extends ClientApiController
|
|||||||
throw $exception;
|
throw $exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
Activity::event('server:console.command')->property('command', $request->input('command'))->log();
|
Activity::event('server:console.command')
|
||||||
|
->property('command', $request->input('command'))
|
||||||
|
->log();
|
||||||
|
|
||||||
return $this->returnNoContent();
|
return $this->returnNoContent();
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ use App\Http\Requests\Api\Client\Servers\Files\CompressFilesRequest;
|
|||||||
use App\Http\Requests\Api\Client\Servers\Files\DecompressFilesRequest;
|
use App\Http\Requests\Api\Client\Servers\Files\DecompressFilesRequest;
|
||||||
use App\Http\Requests\Api\Client\Servers\Files\GetFileContentsRequest;
|
use App\Http\Requests\Api\Client\Servers\Files\GetFileContentsRequest;
|
||||||
use App\Http\Requests\Api\Client\Servers\Files\WriteFileContentRequest;
|
use App\Http\Requests\Api\Client\Servers\Files\WriteFileContentRequest;
|
||||||
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
|
||||||
class FileController extends ClientApiController
|
class FileController extends ClientApiController
|
||||||
{
|
{
|
||||||
@ -38,7 +39,7 @@ class FileController extends ClientApiController
|
|||||||
/**
|
/**
|
||||||
* Returns a listing of files in a given directory.
|
* Returns a listing of files in a given directory.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function directory(ListFilesRequest $request, Server $server): array
|
public function directory(ListFilesRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
@ -63,7 +64,9 @@ class FileController extends ClientApiController
|
|||||||
config('panel.files.max_edit_size')
|
config('panel.files.max_edit_size')
|
||||||
);
|
);
|
||||||
|
|
||||||
Activity::event('server:file.read')->property('file', $request->get('file'))->log();
|
Activity::event('server:file.read')
|
||||||
|
->property('file', $request->get('file'))
|
||||||
|
->log();
|
||||||
|
|
||||||
return new Response($response, Response::HTTP_OK, ['Content-Type' => 'text/plain']);
|
return new Response($response, Response::HTTP_OK, ['Content-Type' => 'text/plain']);
|
||||||
}
|
}
|
||||||
@ -102,13 +105,17 @@ class FileController extends ClientApiController
|
|||||||
/**
|
/**
|
||||||
* Writes the contents of the specified file to the server.
|
* Writes the contents of the specified file to the server.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function write(WriteFileContentRequest $request, Server $server): JsonResponse
|
public function write(WriteFileContentRequest $request, Server $server): JsonResponse
|
||||||
{
|
{
|
||||||
$this->fileRepository->setServer($server)->putContent($request->get('file'), $request->getContent());
|
$this->fileRepository
|
||||||
|
->setServer($server)
|
||||||
|
->putContent($request->get('file'), $request->getContent());
|
||||||
|
|
||||||
Activity::event('server:file.write')->property('file', $request->get('file'))->log();
|
Activity::event('server:file.write')
|
||||||
|
->property('file', $request->get('file'))
|
||||||
|
->log();
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||||
}
|
}
|
||||||
@ -154,7 +161,7 @@ class FileController extends ClientApiController
|
|||||||
/**
|
/**
|
||||||
* Copies a file on the server.
|
* Copies a file on the server.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function copy(CopyFileRequest $request, Server $server): JsonResponse
|
public function copy(CopyFileRequest $request, Server $server): JsonResponse
|
||||||
{
|
{
|
||||||
@ -162,13 +169,15 @@ class FileController extends ClientApiController
|
|||||||
->setServer($server)
|
->setServer($server)
|
||||||
->copyFile($request->input('location'));
|
->copyFile($request->input('location'));
|
||||||
|
|
||||||
Activity::event('server:file.copy')->property('file', $request->input('location'))->log();
|
Activity::event('server:file.copy')
|
||||||
|
->property('file', $request->input('location'))
|
||||||
|
->log();
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function compress(CompressFilesRequest $request, Server $server): array
|
public function compress(CompressFilesRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
@ -188,7 +197,7 @@ class FileController extends ClientApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function decompress(DecompressFilesRequest $request, Server $server): JsonResponse
|
public function decompress(DecompressFilesRequest $request, Server $server): JsonResponse
|
||||||
{
|
{
|
||||||
@ -210,7 +219,7 @@ class FileController extends ClientApiController
|
|||||||
/**
|
/**
|
||||||
* Deletes files or folders for the server in the given root directory.
|
* Deletes files or folders for the server in the given root directory.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function delete(DeleteFileRequest $request, Server $server): JsonResponse
|
public function delete(DeleteFileRequest $request, Server $server): JsonResponse
|
||||||
{
|
{
|
||||||
@ -230,7 +239,7 @@ class FileController extends ClientApiController
|
|||||||
/**
|
/**
|
||||||
* Updates file permissions for file(s) in the given root directory.
|
* Updates file permissions for file(s) in the given root directory.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function chmod(ChmodFilesRequest $request, Server $server): JsonResponse
|
public function chmod(ChmodFilesRequest $request, Server $server): JsonResponse
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,7 @@ use App\Transformers\Api\Client\StatsTransformer;
|
|||||||
use App\Repositories\Daemon\DaemonServerRepository;
|
use App\Repositories\Daemon\DaemonServerRepository;
|
||||||
use App\Http\Controllers\Api\Client\ClientApiController;
|
use App\Http\Controllers\Api\Client\ClientApiController;
|
||||||
use App\Http\Requests\Api\Client\Servers\GetServerRequest;
|
use App\Http\Requests\Api\Client\Servers\GetServerRequest;
|
||||||
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
|
||||||
class ResourceUtilizationController extends ClientApiController
|
class ResourceUtilizationController extends ClientApiController
|
||||||
{
|
{
|
||||||
@ -25,7 +26,7 @@ class ResourceUtilizationController extends ClientApiController
|
|||||||
* 20 seconds at a time to ensure that repeated requests to this endpoint do not cause
|
* 20 seconds at a time to ensure that repeated requests to this endpoint do not cause
|
||||||
* a flood of unnecessary API calls.
|
* a flood of unnecessary API calls.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function __invoke(GetServerRequest $request, Server $server): array
|
public function __invoke(GetServerRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
|
@ -11,7 +11,7 @@ use App\Models\ServerTransfer;
|
|||||||
use Illuminate\Database\ConnectionInterface;
|
use Illuminate\Database\ConnectionInterface;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
|
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
|
||||||
class ServerTransferController extends Controller
|
class ServerTransferController extends Controller
|
||||||
{
|
{
|
||||||
@ -75,7 +75,7 @@ class ServerTransferController extends Controller
|
|||||||
->setServer($server)
|
->setServer($server)
|
||||||
->setNode($transfer->oldNode)
|
->setNode($transfer->oldNode)
|
||||||
->delete();
|
->delete();
|
||||||
} catch (DaemonConnectionException $exception) {
|
} catch (ConnectionException $exception) {
|
||||||
logger()->warning($exception, ['transfer_id' => $server->transfer->id]);
|
logger()->warning($exception, ['transfer_id' => $server->transfer->id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,8 +11,9 @@ use Illuminate\Contracts\Queue\ShouldQueue;
|
|||||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
use App\Services\Backups\InitiateBackupService;
|
use App\Services\Backups\InitiateBackupService;
|
||||||
use App\Repositories\Daemon\DaemonPowerRepository;
|
use App\Repositories\Daemon\DaemonPowerRepository;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
|
||||||
use App\Services\Files\DeleteFilesService;
|
use App\Services\Files\DeleteFilesService;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
|
||||||
class RunTaskJob extends Job implements ShouldQueue
|
class RunTaskJob extends Job implements ShouldQueue
|
||||||
{
|
{
|
||||||
@ -72,10 +73,10 @@ class RunTaskJob extends Job implements ShouldQueue
|
|||||||
default:
|
default:
|
||||||
throw new \InvalidArgumentException('Invalid task action provided: ' . $this->task->action);
|
throw new \InvalidArgumentException('Invalid task action provided: ' . $this->task->action);
|
||||||
}
|
}
|
||||||
} catch (\Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
// If this isn't a DaemonConnectionException on a task that allows for failures
|
// If this isn't a ConnectionException on a task that allows for failures
|
||||||
// throw the exception back up the chain so that the task is stopped.
|
// throw the exception back up the chain so that the task is stopped.
|
||||||
if (!($this->task->continue_on_failure && $exception instanceof DaemonConnectionException)) {
|
if (!($this->task->continue_on_failure && $exception instanceof ConnectionException)) {
|
||||||
throw $exception;
|
throw $exception;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,7 +88,7 @@ class RunTaskJob extends Job implements ShouldQueue
|
|||||||
/**
|
/**
|
||||||
* Handle a failure while sending the action to the daemon or otherwise processing the job.
|
* Handle a failure while sending the action to the daemon or otherwise processing the job.
|
||||||
*/
|
*/
|
||||||
public function failed(?\Exception $exception = null): void
|
public function failed(): void
|
||||||
{
|
{
|
||||||
$this->markTaskNotQueued();
|
$this->markTaskNotQueued();
|
||||||
$this->markScheduleComplete();
|
$this->markScheduleComplete();
|
||||||
|
@ -310,7 +310,7 @@ class Node extends Model
|
|||||||
// @phpstan-ignore-next-line
|
// @phpstan-ignore-next-line
|
||||||
return resolve(DaemonConfigurationRepository::class)
|
return resolve(DaemonConfigurationRepository::class)
|
||||||
->setNode($this)
|
->setNode($this)
|
||||||
->getSystemInformation(connectTimeout: 3);
|
->getSystemInformation();
|
||||||
} catch (Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
$message = str($exception->getMessage());
|
$message = str($exception->getMessage());
|
||||||
|
|
||||||
|
@ -3,11 +3,8 @@
|
|||||||
namespace App\Repositories\Daemon;
|
namespace App\Repositories\Daemon;
|
||||||
|
|
||||||
use Illuminate\Http\Client\Response;
|
use Illuminate\Http\Client\Response;
|
||||||
use Webmozart\Assert\Assert;
|
|
||||||
use App\Models\Backup;
|
use App\Models\Backup;
|
||||||
use App\Models\Server;
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
use GuzzleHttp\Exception\TransferException;
|
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
|
||||||
|
|
||||||
class DaemonBackupRepository extends DaemonRepository
|
class DaemonBackupRepository extends DaemonRepository
|
||||||
{
|
{
|
||||||
@ -26,64 +23,42 @@ class DaemonBackupRepository extends DaemonRepository
|
|||||||
/**
|
/**
|
||||||
* Tells the remote Daemon to begin generating a backup for the server.
|
* Tells the remote Daemon to begin generating a backup for the server.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function backup(Backup $backup): Response
|
public function backup(Backup $backup): Response
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
return $this->getHttpClient()->post("/api/servers/{$this->server->uuid}/backup",
|
||||||
|
[
|
||||||
try {
|
'adapter' => $this->adapter ?? config('backups.default'),
|
||||||
return $this->getHttpClient()->post(
|
'uuid' => $backup->uuid,
|
||||||
sprintf('/api/servers/%s/backup', $this->server->uuid),
|
'ignore' => implode("\n", $backup->ignored_files),
|
||||||
[
|
]
|
||||||
'adapter' => $this->adapter ?? config('backups.default'),
|
);
|
||||||
'uuid' => $backup->uuid,
|
|
||||||
'ignore' => implode("\n", $backup->ignored_files),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a request to daemon to begin restoring a backup for a server.
|
* Sends a request to daemon to begin restoring a backup for a server.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function restore(Backup $backup, ?string $url = null, bool $truncate = false): Response
|
public function restore(Backup $backup, ?string $url = null, bool $truncate = false): Response
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
return $this->getHttpClient()->post("/api/servers/{$this->server->uuid}/backup/$backup->uuid/restore",
|
||||||
|
[
|
||||||
try {
|
'adapter' => $backup->disk,
|
||||||
return $this->getHttpClient()->post(
|
'truncate_directory' => $truncate,
|
||||||
sprintf('/api/servers/%s/backup/%s/restore', $this->server->uuid, $backup->uuid),
|
'download_url' => $url ?? '',
|
||||||
[
|
]
|
||||||
'adapter' => $backup->disk,
|
);
|
||||||
'truncate_directory' => $truncate,
|
|
||||||
'download_url' => $url ?? '',
|
|
||||||
]
|
|
||||||
);
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a backup from the daemon.
|
* Deletes a backup from the daemon.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function delete(Backup $backup): Response
|
public function delete(Backup $backup): Response
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
return $this->getHttpClient()->delete("/api/servers/{$this->server->uuid}/backup/$backup->uuid");
|
||||||
|
|
||||||
try {
|
|
||||||
return $this->getHttpClient()->delete(
|
|
||||||
sprintf('/api/servers/%s/backup/%s', $this->server->uuid, $backup->uuid)
|
|
||||||
);
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
namespace App\Repositories\Daemon;
|
namespace App\Repositories\Daemon;
|
||||||
|
|
||||||
use App\Models\Node;
|
use App\Models\Node;
|
||||||
use GuzzleHttp\Exception\TransferException;
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
|
||||||
use Illuminate\Http\Client\Response;
|
use Illuminate\Http\Client\Response;
|
||||||
|
|
||||||
class DaemonConfigurationRepository extends DaemonRepository
|
class DaemonConfigurationRepository extends DaemonRepository
|
||||||
@ -12,20 +11,13 @@ class DaemonConfigurationRepository extends DaemonRepository
|
|||||||
/**
|
/**
|
||||||
* Returns system information from the daemon instance.
|
* Returns system information from the daemon instance.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function getSystemInformation(?int $version = null, int $connectTimeout = 5): array
|
public function getSystemInformation(): array
|
||||||
{
|
{
|
||||||
try {
|
return $this->getHttpClient()
|
||||||
$response = $this
|
->connectTimeout(3)
|
||||||
->getHttpClient()
|
->get('/api/system')->throw()->json();
|
||||||
->connectTimeout($connectTimeout)
|
|
||||||
->get('/api/system' . (!is_null($version) ? '?v=' . $version : ''));
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response->json() ?? [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,17 +25,10 @@ class DaemonConfigurationRepository extends DaemonRepository
|
|||||||
* this instance using a passed-in model. This allows us to change plenty of information
|
* this instance using a passed-in model. This allows us to change plenty of information
|
||||||
* in the model, and still use the old, pre-update model to actually make the HTTP request.
|
* in the model, and still use the old, pre-update model to actually make the HTTP request.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function update(Node $node): Response
|
public function update(Node $node): Response
|
||||||
{
|
{
|
||||||
try {
|
return $this->getHttpClient()->post('/api/update', $node->getConfiguration());
|
||||||
return $this->getHttpClient()->post(
|
|
||||||
'/api/update',
|
|
||||||
$node->getConfiguration(),
|
|
||||||
);
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,10 @@
|
|||||||
|
|
||||||
namespace App\Repositories\Daemon;
|
namespace App\Repositories\Daemon;
|
||||||
|
|
||||||
use Carbon\CarbonInterval;
|
|
||||||
use Illuminate\Contracts\Filesystem\FileNotFoundException;
|
use Illuminate\Contracts\Filesystem\FileNotFoundException;
|
||||||
use Illuminate\Http\Client\Response;
|
use Illuminate\Http\Client\Response;
|
||||||
use Webmozart\Assert\Assert;
|
|
||||||
use App\Models\Server;
|
|
||||||
use GuzzleHttp\Exception\ClientException;
|
|
||||||
use GuzzleHttp\Exception\TransferException;
|
|
||||||
use App\Exceptions\Http\Server\FileSizeTooLargeException;
|
use App\Exceptions\Http\Server\FileSizeTooLargeException;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
|
||||||
class DaemonFileRepository extends DaemonRepository
|
class DaemonFileRepository extends DaemonRepository
|
||||||
{
|
{
|
||||||
@ -19,23 +14,16 @@ class DaemonFileRepository extends DaemonRepository
|
|||||||
*
|
*
|
||||||
* @param int|null $notLargerThan the maximum content length in bytes
|
* @param int|null $notLargerThan the maximum content length in bytes
|
||||||
*
|
*
|
||||||
* @throws \GuzzleHttp\Exception\TransferException
|
* @throws ConnectionException
|
||||||
* @throws \App\Exceptions\Http\Server\FileSizeTooLargeException
|
* @throws FileSizeTooLargeException
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
* @throws FileNotFoundException
|
* @throws FileNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getContent(string $path, ?int $notLargerThan = null): string
|
public function getContent(string $path, ?int $notLargerThan = null): string
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
$response = $this->getHttpClient()->get("/api/servers/{$this->server->uuid}/files/contents",
|
||||||
|
['file' => $path]
|
||||||
try {
|
);
|
||||||
$response = $this->getHttpClient()->get(
|
|
||||||
sprintf('/api/servers/%s/files/contents', $this->server->uuid),
|
|
||||||
['file' => $path]
|
|
||||||
);
|
|
||||||
} catch (ClientException|TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
$length = $response->header('Content-Length');
|
$length = $response->header('Content-Length');
|
||||||
if ($notLargerThan && $length > $notLargerThan) {
|
if ($notLargerThan && $length > $notLargerThan) {
|
||||||
@ -53,215 +41,145 @@ class DaemonFileRepository extends DaemonRepository
|
|||||||
* Save new contents to a given file. This works for both creating and updating
|
* Save new contents to a given file. This works for both creating and updating
|
||||||
* a file.
|
* a file.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function putContent(string $path, string $content): Response
|
public function putContent(string $path, string $content): Response
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
return $this->getHttpClient()
|
||||||
|
->withQueryParameters(['file' => $path])
|
||||||
try {
|
->withBody($content)
|
||||||
return $this->getHttpClient()
|
->post("/api/servers/{$this->server->uuid}/files/write");
|
||||||
->withQueryParameters(['file' => $path])
|
|
||||||
->withBody($content)
|
|
||||||
->post(sprintf('/api/servers/%s/files/write', $this->server->uuid));
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a directory listing for a given path.
|
* Return a directory listing for a given path.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function getDirectory(string $path): array
|
public function getDirectory(string $path): array
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
return $this->getHttpClient()->get("/api/servers/{$this->server->uuid}/files/list-directory",
|
||||||
|
['directory' => $path]
|
||||||
try {
|
)->json();
|
||||||
$response = $this->getHttpClient()->get(
|
|
||||||
sprintf('/api/servers/%s/files/list-directory', $this->server->uuid),
|
|
||||||
['directory' => $path]
|
|
||||||
);
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response->json();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new directory for the server in the given $path.
|
* Creates a new directory for the server in the given $path.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function createDirectory(string $name, string $path): Response
|
public function createDirectory(string $name, string $path): Response
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
return $this->getHttpClient()->post("/api/servers/{$this->server->uuid}/files/create-directory",
|
||||||
|
[
|
||||||
try {
|
'name' => $name,
|
||||||
return $this->getHttpClient()->post(
|
'path' => $path,
|
||||||
sprintf('/api/servers/%s/files/create-directory', $this->server->uuid),
|
]
|
||||||
[
|
);
|
||||||
'name' => $name,
|
|
||||||
'path' => $path,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renames or moves a file on the remote machine.
|
* Renames or moves a file on the remote machine.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function renameFiles(?string $root, array $files): Response
|
public function renameFiles(?string $root, array $files): Response
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
return $this->getHttpClient()->put("/api/servers/{$this->server->uuid}/files/rename",
|
||||||
|
[
|
||||||
try {
|
'root' => $root ?? '/',
|
||||||
return $this->getHttpClient()->put(
|
'files' => $files,
|
||||||
sprintf('/api/servers/%s/files/rename', $this->server->uuid),
|
]
|
||||||
[
|
);
|
||||||
'root' => $root ?? '/',
|
|
||||||
'files' => $files,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy a given file and give it a unique name.
|
* Copy a given file and give it a unique name.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function copyFile(string $location): Response
|
public function copyFile(string $location): Response
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
return $this->getHttpClient()->post("/api/servers/{$this->server->uuid}/files/copy",
|
||||||
|
['location' => $location]
|
||||||
try {
|
);
|
||||||
return $this->getHttpClient()->post(
|
|
||||||
sprintf('/api/servers/%s/files/copy', $this->server->uuid),
|
|
||||||
[
|
|
||||||
'location' => $location,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a file or folder for the server.
|
* Delete a file or folder for the server.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function deleteFiles(?string $root, array $files): Response
|
public function deleteFiles(?string $root, array $files): Response
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
return $this->getHttpClient()->post("/api/servers/{$this->server->uuid}/files/delete",
|
||||||
|
[
|
||||||
try {
|
'root' => $root ?? '/',
|
||||||
return $this->getHttpClient()->post(
|
'files' => $files,
|
||||||
sprintf('/api/servers/%s/files/delete', $this->server->uuid),
|
]
|
||||||
[
|
);
|
||||||
'root' => $root ?? '/',
|
|
||||||
'files' => $files,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compress the given files or folders in the given root.
|
* Compress the given files or folders in the given root.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function compressFiles(?string $root, array $files): array
|
public function compressFiles(?string $root, array $files): array
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
return $this->getHttpClient()
|
||||||
|
// Wait for up to 15 minutes for the archive to be completed when calling this endpoint
|
||||||
try {
|
// since it will likely take quite awhile for large directories.
|
||||||
$response = $this->getHttpClient()
|
->timeout(60 * 15)
|
||||||
// Wait for up to 15 minutes for the archive to be completed when calling this endpoint
|
->post("/api/servers/{$this->server->uuid}/files/compress",
|
||||||
// since it will likely take quite awhile for large directories.
|
[
|
||||||
->timeout(60 * 15)
|
'root' => $root ?? '/',
|
||||||
->post(
|
'files' => $files,
|
||||||
sprintf('/api/servers/%s/files/compress', $this->server->uuid),
|
]
|
||||||
[
|
)->json();
|
||||||
'root' => $root ?? '/',
|
|
||||||
'files' => $files,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response->json();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decompresses a given archive file.
|
* Decompresses a given archive file.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function decompressFile(?string $root, string $file): Response
|
public function decompressFile(?string $root, string $file): Response
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
return $this->getHttpClient()
|
||||||
|
// Wait for up to 15 minutes for the archive to be completed when calling this endpoint
|
||||||
try {
|
// since it will likely take quite awhile for large directories.
|
||||||
return $this->getHttpClient()
|
->timeout(60 * 15)
|
||||||
// Wait for up to 15 minutes for the decompress to be completed when calling this endpoint
|
->post("/api/servers/{$this->server->uuid}/files/decompress",
|
||||||
// since it will likely take quite awhile for large directories.
|
[
|
||||||
->timeout((int) CarbonInterval::minutes(15)->totalSeconds)
|
'root' => $root ?? '/',
|
||||||
->post(
|
'file' => $file,
|
||||||
sprintf('/api/servers/%s/files/decompress', $this->server->uuid),
|
]
|
||||||
[
|
);
|
||||||
'root' => $root ?? '/',
|
|
||||||
'file' => $file,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chmods the given files.
|
* Chmods the given files.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function chmodFiles(?string $root, array $files): Response
|
public function chmodFiles(?string $root, array $files): Response
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
return $this->getHttpClient()->post("/api/servers/{$this->server->uuid}/files/chmod",
|
||||||
|
[
|
||||||
try {
|
'root' => $root ?? '/',
|
||||||
return $this->getHttpClient()->post(
|
'files' => $files,
|
||||||
sprintf('/api/servers/%s/files/chmod', $this->server->uuid),
|
]
|
||||||
[
|
);
|
||||||
'root' => $root ?? '/',
|
|
||||||
'files' => $files,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pulls a file from the given URL and saves it to the disk.
|
* Pulls a file from the given URL and saves it to the disk.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function pull(string $url, ?string $directory, array $params = []): Response
|
public function pull(string $url, ?string $directory, array $params = []): Response
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
|
||||||
|
|
||||||
$attributes = [
|
$attributes = [
|
||||||
'url' => $url,
|
'url' => $url,
|
||||||
'root' => $directory ?? '/',
|
'root' => $directory ?? '/',
|
||||||
@ -270,39 +188,25 @@ class DaemonFileRepository extends DaemonRepository
|
|||||||
'foreground' => $params['foreground'] ?? null,
|
'foreground' => $params['foreground'] ?? null,
|
||||||
];
|
];
|
||||||
|
|
||||||
try {
|
return $this->getHttpClient()->post("/api/servers/{$this->server->uuid}/files/pull", array_filter($attributes, fn ($value) => !is_null($value)));
|
||||||
return $this->getHttpClient()->post(
|
|
||||||
sprintf('/api/servers/%s/files/pull', $this->server->uuid),
|
|
||||||
array_filter($attributes, fn ($value) => !is_null($value))
|
|
||||||
);
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches all files in the directory (and its subdirectories) for the given search term.
|
* Searches all files in the directory (and its subdirectories) for the given search term.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function search(string $searchTerm, ?string $directory): array
|
public function search(string $searchTerm, ?string $directory): array
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
return $this->getHttpClient()
|
||||||
|
// Wait for up to 2 minutes for the search to be completed when calling this endpoint
|
||||||
try {
|
// since it will likely take quite awhile for large directories.
|
||||||
$response = $this->getHttpClient()
|
->timeout(60 * 2)
|
||||||
->timeout(120)
|
->get("/api/servers/{$this->server->uuid}/files/search",
|
||||||
->get(
|
[
|
||||||
sprintf('/api/servers/%s/files/search', $this->server->uuid),
|
'pattern' => $searchTerm,
|
||||||
[
|
'directory' => $directory ?? '/',
|
||||||
'pattern' => $searchTerm,
|
]
|
||||||
'directory' => $directory ?? '/',
|
)->json();
|
||||||
]
|
|
||||||
);
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response->json();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,30 +2,20 @@
|
|||||||
|
|
||||||
namespace App\Repositories\Daemon;
|
namespace App\Repositories\Daemon;
|
||||||
|
|
||||||
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
use Illuminate\Http\Client\Response;
|
use Illuminate\Http\Client\Response;
|
||||||
use Webmozart\Assert\Assert;
|
|
||||||
use App\Models\Server;
|
|
||||||
use GuzzleHttp\Exception\TransferException;
|
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
|
||||||
|
|
||||||
class DaemonPowerRepository extends DaemonRepository
|
class DaemonPowerRepository extends DaemonRepository
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Sends a power action to the server instance.
|
* Sends a power action to the server instance.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function send(string $action): Response
|
public function send(string $action): Response
|
||||||
{
|
{
|
||||||
Assert::isInstanceOf($this->server, Server::class);
|
return $this->getHttpClient()->post("/api/servers/{$this->server->uuid}/power",
|
||||||
|
['action' => $action],
|
||||||
try {
|
);
|
||||||
return $this->getHttpClient()->post(
|
|
||||||
sprintf('/api/servers/%s/power', $this->server->uuid),
|
|
||||||
['action' => $action],
|
|
||||||
);
|
|
||||||
} catch (TransferException $exception) {
|
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,7 @@ class DaemonServerRepository extends DaemonRepository
|
|||||||
public function getDetails(): array
|
public function getDetails(): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return $this->getHttpClient()->get(
|
return $this->getHttpClient()->get("/api/servers/{$this->server->uuid}")->throw()->json();
|
||||||
sprintf('/api/servers/%s', $this->server->uuid)
|
|
||||||
)->throw()->json();
|
|
||||||
} catch (RequestException $exception) {
|
} catch (RequestException $exception) {
|
||||||
$cfId = $exception->response->header('Cf-Ray');
|
$cfId = $exception->response->header('Cf-Ray');
|
||||||
$cfCache = $exception->response->header('Cf-Cache-Status');
|
$cfCache = $exception->response->header('Cf-Cache-Status');
|
||||||
|
@ -11,7 +11,7 @@ use Illuminate\Database\ConnectionInterface;
|
|||||||
use App\Extensions\Backups\BackupManager;
|
use App\Extensions\Backups\BackupManager;
|
||||||
use App\Repositories\Daemon\DaemonBackupRepository;
|
use App\Repositories\Daemon\DaemonBackupRepository;
|
||||||
use App\Exceptions\Service\Backup\BackupLockedException;
|
use App\Exceptions\Service\Backup\BackupLockedException;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
|
||||||
class DeleteBackupService
|
class DeleteBackupService
|
||||||
{
|
{
|
||||||
@ -48,8 +48,9 @@ class DeleteBackupService
|
|||||||
$this->connection->transaction(function () use ($backup) {
|
$this->connection->transaction(function () use ($backup) {
|
||||||
try {
|
try {
|
||||||
$this->daemonBackupRepository->setServer($backup->server)->delete($backup);
|
$this->daemonBackupRepository->setServer($backup->server)->delete($backup);
|
||||||
} catch (DaemonConnectionException $exception) {
|
} catch (ConnectionException $exception) {
|
||||||
$previous = $exception->getPrevious();
|
$previous = $exception->getPrevious();
|
||||||
|
|
||||||
// Don't fail the request if the Daemon responds with a 404, just assume the backup
|
// Don't fail the request if the Daemon responds with a 404, just assume the backup
|
||||||
// doesn't actually exist and remove its reference from the Panel as well.
|
// doesn't actually exist and remove its reference from the Panel as well.
|
||||||
if (!$previous instanceof ClientException || $previous->getResponse()->getStatusCode() !== Response::HTTP_NOT_FOUND) {
|
if (!$previous instanceof ClientException || $previous->getResponse()->getStatusCode() !== Response::HTTP_NOT_FOUND) {
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Services\Files;
|
namespace App\Services\Files;
|
||||||
|
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Repositories\Daemon\DaemonFileRepository;
|
use App\Repositories\Daemon\DaemonFileRepository;
|
||||||
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class DeleteFilesService
|
class DeleteFilesService
|
||||||
@ -19,7 +19,7 @@ class DeleteFilesService
|
|||||||
/**
|
/**
|
||||||
* Deletes the given files.
|
* Deletes the given files.
|
||||||
*
|
*
|
||||||
* @throws DaemonConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function handle(Server $server, array $files): void
|
public function handle(Server $server, array $files): void
|
||||||
{
|
{
|
||||||
|
@ -6,8 +6,8 @@ use Illuminate\Support\Str;
|
|||||||
use App\Models\Node;
|
use App\Models\Node;
|
||||||
use Illuminate\Database\ConnectionInterface;
|
use Illuminate\Database\ConnectionInterface;
|
||||||
use App\Repositories\Daemon\DaemonConfigurationRepository;
|
use App\Repositories\Daemon\DaemonConfigurationRepository;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
|
||||||
use App\Exceptions\Service\Node\ConfigurationNotPersistedException;
|
use App\Exceptions\Service\Node\ConfigurationNotPersistedException;
|
||||||
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
|
||||||
class NodeUpdateService
|
class NodeUpdateService
|
||||||
{
|
{
|
||||||
@ -42,7 +42,7 @@ class NodeUpdateService
|
|||||||
$node->fqdn = $updated->fqdn;
|
$node->fqdn = $updated->fqdn;
|
||||||
|
|
||||||
$this->configurationRepository->setNode($node)->update($updated);
|
$this->configurationRepository->setNode($node)->update($updated);
|
||||||
} catch (DaemonConnectionException $exception) {
|
} catch (ConnectionException $exception) {
|
||||||
logger()->warning($exception, ['node_id' => $node->id]);
|
logger()->warning($exception, ['node_id' => $node->id]);
|
||||||
|
|
||||||
// Never actually throw these exceptions up the stack. If we were able to change the settings
|
// Never actually throw these exceptions up the stack. If we were able to change the settings
|
||||||
|
@ -9,7 +9,6 @@ use App\Jobs\Schedule\RunTaskJob;
|
|||||||
use Illuminate\Database\ConnectionInterface;
|
use Illuminate\Database\ConnectionInterface;
|
||||||
use App\Exceptions\DisplayException;
|
use App\Exceptions\DisplayException;
|
||||||
use App\Repositories\Daemon\DaemonServerRepository;
|
use App\Repositories\Daemon\DaemonServerRepository;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
|
||||||
|
|
||||||
class ProcessScheduleService
|
class ProcessScheduleService
|
||||||
{
|
{
|
||||||
@ -53,13 +52,7 @@ class ProcessScheduleService
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (\Exception $exception) {
|
} catch (Exception) {
|
||||||
if (!$exception instanceof DaemonConnectionException) {
|
|
||||||
// If we encountered some exception during this process that wasn't just an
|
|
||||||
// issue connecting to daemon run the failed sequence for a job. Otherwise we
|
|
||||||
// can just quietly mark the task as completed without actually running anything.
|
|
||||||
$job->failed($exception);
|
|
||||||
}
|
|
||||||
$job->failed();
|
$job->failed();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -73,8 +66,8 @@ class ProcessScheduleService
|
|||||||
// so we need to manually trigger it and then continue with the exception throw.
|
// so we need to manually trigger it and then continue with the exception throw.
|
||||||
try {
|
try {
|
||||||
$this->dispatcher->dispatchNow($job);
|
$this->dispatcher->dispatchNow($job);
|
||||||
} catch (\Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
$job->failed($exception);
|
$job->failed();
|
||||||
|
|
||||||
throw $exception;
|
throw $exception;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ use App\Models\Allocation;
|
|||||||
use Illuminate\Database\ConnectionInterface;
|
use Illuminate\Database\ConnectionInterface;
|
||||||
use App\Exceptions\DisplayException;
|
use App\Exceptions\DisplayException;
|
||||||
use App\Repositories\Daemon\DaemonServerRepository;
|
use App\Repositories\Daemon\DaemonServerRepository;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
|
||||||
class BuildModificationService
|
class BuildModificationService
|
||||||
{
|
{
|
||||||
@ -64,7 +64,7 @@ class BuildModificationService
|
|||||||
if (!empty($updateData['build'])) {
|
if (!empty($updateData['build'])) {
|
||||||
try {
|
try {
|
||||||
$this->daemonServerRepository->setServer($server)->sync();
|
$this->daemonServerRepository->setServer($server)->sync();
|
||||||
} catch (DaemonConnectionException $exception) {
|
} catch (ConnectionException $exception) {
|
||||||
logger()->warning($exception, ['server_id' => $server->id]);
|
logger()->warning($exception, ['server_id' => $server->id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ use App\Models\Server;
|
|||||||
use Illuminate\Database\ConnectionInterface;
|
use Illuminate\Database\ConnectionInterface;
|
||||||
use App\Traits\Services\ReturnsUpdatedModels;
|
use App\Traits\Services\ReturnsUpdatedModels;
|
||||||
use App\Repositories\Daemon\DaemonServerRepository;
|
use App\Repositories\Daemon\DaemonServerRepository;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
|
||||||
use Illuminate\Http\Client\ConnectionException;
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
|
||||||
class DetailsModificationService
|
class DetailsModificationService
|
||||||
@ -42,7 +41,7 @@ class DetailsModificationService
|
|||||||
if ($server->owner_id !== $owner) {
|
if ($server->owner_id !== $owner) {
|
||||||
try {
|
try {
|
||||||
$this->serverRepository->setServer($server)->revokeUserJTI($owner);
|
$this->serverRepository->setServer($server)->revokeUserJTI($owner);
|
||||||
} catch (ConnectionException|DaemonConnectionException) {
|
} catch (ConnectionException) {
|
||||||
// Do nothing. A failure here is not ideal, but it is likely to be caused by daemon
|
// Do nothing. A failure here is not ideal, but it is likely to be caused by daemon
|
||||||
// being offline, or in an entirely broken state. Remember, these tokens reset every
|
// being offline, or in an entirely broken state. Remember, these tokens reset every
|
||||||
// few minutes by default, we're just trying to help it along a little quicker.
|
// few minutes by default, we're just trying to help it along a little quicker.
|
||||||
|
@ -8,7 +8,7 @@ use App\Models\Server;
|
|||||||
use Illuminate\Database\ConnectionInterface;
|
use Illuminate\Database\ConnectionInterface;
|
||||||
use App\Repositories\Daemon\DaemonServerRepository;
|
use App\Repositories\Daemon\DaemonServerRepository;
|
||||||
use App\Services\Databases\DatabaseManagementService;
|
use App\Services\Databases\DatabaseManagementService;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
|
||||||
class ServerDeletionService
|
class ServerDeletionService
|
||||||
{
|
{
|
||||||
@ -43,12 +43,12 @@ class ServerDeletionService
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->daemonServerRepository->setServer($server)->delete();
|
$this->daemonServerRepository->setServer($server)->delete();
|
||||||
} catch (DaemonConnectionException $exception) {
|
} catch (ConnectionException $exception) {
|
||||||
// If there is an error not caused a 404 error and this isn't a forced delete,
|
// If there is an error not caused a 404 error and this isn't a forced delete,
|
||||||
// go ahead and bail out. We specifically ignore a 404 since that can be assumed
|
// go ahead and bail out. We specifically ignore a 404 since that can be assumed
|
||||||
// to be a safe error, meaning the server doesn't exist at all on daemon so there
|
// to be a safe error, meaning the server doesn't exist at all on daemon so there
|
||||||
// is no reason we need to bail out from that.
|
// is no reason we need to bail out from that.
|
||||||
if (!$this->force && $exception->getStatusCode() !== Response::HTTP_NOT_FOUND) {
|
if (!$this->force && $exception->getCode() !== Response::HTTP_NOT_FOUND) {
|
||||||
throw $exception;
|
throw $exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ class ServerDeletionService
|
|||||||
foreach ($server->databases as $database) {
|
foreach ($server->databases as $database) {
|
||||||
try {
|
try {
|
||||||
$this->databaseManagementService->delete($database);
|
$this->databaseManagementService->delete($database);
|
||||||
} catch (\Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
if (!$this->force) {
|
if (!$this->force) {
|
||||||
throw $exception;
|
throw $exception;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ use App\Enums\SuspendAction;
|
|||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Repositories\Daemon\DaemonServerRepository;
|
use App\Repositories\Daemon\DaemonServerRepository;
|
||||||
use Doctrine\DBAL\Exception\ConnectionException;
|
|
||||||
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
|
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
|
||||||
|
|
||||||
class SuspensionService
|
class SuspensionService
|
||||||
@ -47,11 +46,7 @@ class SuspensionService
|
|||||||
'status' => $isSuspending ? ServerState::Suspended : null,
|
'status' => $isSuspending ? ServerState::Suspended : null,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
try {
|
// Tell daemon to re-sync the server state.
|
||||||
// Tell daemon to re-sync the server state.
|
$this->daemonServerRepository->setServer($server)->sync();
|
||||||
$this->daemonServerRepository->setServer($server)->sync();
|
|
||||||
} catch (ConnectionException $exception) {
|
|
||||||
throw $exception;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,12 @@
|
|||||||
|
|
||||||
namespace App\Services\Servers;
|
namespace App\Services\Servers;
|
||||||
|
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
|
||||||
use App\Models\Allocation;
|
use App\Models\Allocation;
|
||||||
use App\Models\Node;
|
use App\Models\Node;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\ServerTransfer;
|
use App\Models\ServerTransfer;
|
||||||
use App\Services\Nodes\NodeJWTService;
|
use App\Services\Nodes\NodeJWTService;
|
||||||
use Carbon\CarbonImmutable;
|
use Carbon\CarbonImmutable;
|
||||||
use GuzzleHttp\Exception\TransferException;
|
|
||||||
use Illuminate\Database\ConnectionInterface;
|
use Illuminate\Database\ConnectionInterface;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Lcobucci\JWT\Token\Plain;
|
use Lcobucci\JWT\Token\Plain;
|
||||||
@ -26,21 +24,17 @@ class TransferServerService
|
|||||||
|
|
||||||
private function notify(Server $server, Plain $token): void
|
private function notify(Server $server, Plain $token): void
|
||||||
{
|
{
|
||||||
try {
|
Http::daemon($server->node)->post('/api/transfer', [
|
||||||
Http::daemon($server->node)->post('/api/transfer', [
|
'json' => [
|
||||||
'json' => [
|
'server_id' => $server->uuid,
|
||||||
'server_id' => $server->uuid,
|
'url' => $server->node->getConnectionAddress() . "/api/servers/$server->uuid/archive",
|
||||||
'url' => $server->node->getConnectionAddress() . "/api/servers/$server->uuid/archive",
|
'token' => 'Bearer ' . $token->toString(),
|
||||||
'token' => 'Bearer ' . $token->toString(),
|
'server' => [
|
||||||
'server' => [
|
'uuid' => $server->uuid,
|
||||||
'uuid' => $server->uuid,
|
'start_on_completion' => false,
|
||||||
'start_on_completion' => false,
|
|
||||||
],
|
|
||||||
],
|
],
|
||||||
])->toPsrResponse();
|
],
|
||||||
} catch (TransferException $exception) {
|
])->toPsrResponse();
|
||||||
throw new DaemonConnectionException($exception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
namespace App\Services\Subusers;
|
namespace App\Services\Subusers;
|
||||||
|
|
||||||
use App\Events\Server\SubUserRemoved;
|
use App\Events\Server\SubUserRemoved;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
|
||||||
use App\Facades\Activity;
|
use App\Facades\Activity;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Subuser;
|
use App\Models\Subuser;
|
||||||
@ -30,7 +29,7 @@ class SubuserDeletionService
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
$this->serverRepository->setServer($server)->revokeUserJTI($subuser->user_id);
|
$this->serverRepository->setServer($server)->revokeUserJTI($subuser->user_id);
|
||||||
} catch (ConnectionException|DaemonConnectionException $exception) {
|
} catch (ConnectionException $exception) {
|
||||||
// Don't block this request if we can't connect to the daemon instance.
|
// Don't block this request if we can't connect to the daemon instance.
|
||||||
logger()->warning($exception, ['user_id' => $subuser->user_id, 'server_id' => $server->id]);
|
logger()->warning($exception, ['user_id' => $subuser->user_id, 'server_id' => $server->id]);
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Services\Subusers;
|
namespace App\Services\Subusers;
|
||||||
|
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
|
||||||
use App\Facades\Activity;
|
use App\Facades\Activity;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Subuser;
|
use App\Models\Subuser;
|
||||||
@ -39,7 +38,7 @@ class SubuserUpdateService
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
$this->serverRepository->setServer($server)->revokeUserJTI($subuser->user_id);
|
$this->serverRepository->setServer($server)->revokeUserJTI($subuser->user_id);
|
||||||
} catch (ConnectionException|DaemonConnectionException $exception) {
|
} catch (ConnectionException $exception) {
|
||||||
// Don't block this request if we can't connect to the daemon instance. Chances are it is
|
// Don't block this request if we can't connect to the daemon instance. Chances are it is
|
||||||
// offline and the token will be invalid once daemon boots back.
|
// offline and the token will be invalid once daemon boots back.
|
||||||
logger()->warning($exception, ['user_id' => $subuser->user_id, 'server_id' => $server->id]);
|
logger()->warning($exception, ['user_id' => $subuser->user_id, 'server_id' => $server->id]);
|
||||||
|
@ -10,8 +10,8 @@ use App\Models\Server;
|
|||||||
use App\Models\Permission;
|
use App\Models\Permission;
|
||||||
use GuzzleHttp\Exception\BadResponseException;
|
use GuzzleHttp\Exception\BadResponseException;
|
||||||
use GuzzleHttp\Psr7\Response as GuzzleResponse;
|
use GuzzleHttp\Psr7\Response as GuzzleResponse;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
|
||||||
use App\Tests\Integration\Api\Client\ClientApiIntegrationTestCase;
|
use App\Tests\Integration\Api\Client\ClientApiIntegrationTestCase;
|
||||||
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||||
|
|
||||||
class CommandControllerTest extends ClientApiIntegrationTestCase
|
class CommandControllerTest extends ClientApiIntegrationTestCase
|
||||||
@ -77,11 +77,7 @@ class CommandControllerTest extends ClientApiIntegrationTestCase
|
|||||||
[$user, $server] = $this->generateTestAccount();
|
[$user, $server] = $this->generateTestAccount();
|
||||||
|
|
||||||
$server = \Mockery::mock($server)->makePartial();
|
$server = \Mockery::mock($server)->makePartial();
|
||||||
$server->expects('send')->andThrows(
|
$server->expects('send')->andThrows(new ConnectionException(previous: new BadResponseException('', new Request('GET', 'test'), new GuzzleResponse(Response::HTTP_BAD_GATEWAY))));
|
||||||
new DaemonConnectionException(
|
|
||||||
new BadResponseException('', new Request('GET', 'test'), new GuzzleResponse(Response::HTTP_BAD_GATEWAY))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->instance(Server::class, $server);
|
$this->instance(Server::class, $server);
|
||||||
|
|
||||||
|
@ -5,17 +5,14 @@ namespace App\Tests\Integration\Jobs\Schedule;
|
|||||||
use App\Enums\ServerState;
|
use App\Enums\ServerState;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Carbon\CarbonImmutable;
|
use Carbon\CarbonImmutable;
|
||||||
use GuzzleHttp\Psr7\Request;
|
|
||||||
use App\Models\Task;
|
use App\Models\Task;
|
||||||
use GuzzleHttp\Psr7\Response;
|
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Schedule;
|
use App\Models\Schedule;
|
||||||
use Illuminate\Support\Facades\Bus;
|
use Illuminate\Support\Facades\Bus;
|
||||||
use App\Jobs\Schedule\RunTaskJob;
|
use App\Jobs\Schedule\RunTaskJob;
|
||||||
use GuzzleHttp\Exception\BadResponseException;
|
|
||||||
use App\Tests\Integration\IntegrationTestCase;
|
use App\Tests\Integration\IntegrationTestCase;
|
||||||
use App\Repositories\Daemon\DaemonPowerRepository;
|
use App\Repositories\Daemon\DaemonPowerRepository;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
|
||||||
class RunTaskJobTest extends IntegrationTestCase
|
class RunTaskJobTest extends IntegrationTestCase
|
||||||
{
|
{
|
||||||
@ -126,12 +123,10 @@ class RunTaskJobTest extends IntegrationTestCase
|
|||||||
$mock = \Mockery::mock(DaemonPowerRepository::class);
|
$mock = \Mockery::mock(DaemonPowerRepository::class);
|
||||||
$this->instance(DaemonPowerRepository::class, $mock);
|
$this->instance(DaemonPowerRepository::class, $mock);
|
||||||
|
|
||||||
$mock->expects('setServer->send')->andThrow(
|
$mock->expects('setServer->send')->andThrow(new ConnectionException());
|
||||||
new DaemonConnectionException(new BadResponseException('Bad request', new Request('GET', '/test'), new Response()))
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!$continueOnFailure) {
|
if (!$continueOnFailure) {
|
||||||
$this->expectException(DaemonConnectionException::class);
|
$this->expectException(ConnectionException::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bus::dispatchSync(new RunTaskJob($task));
|
Bus::dispatchSync(new RunTaskJob($task));
|
||||||
|
@ -12,7 +12,7 @@ use App\Services\Backups\DeleteBackupService;
|
|||||||
use App\Tests\Integration\IntegrationTestCase;
|
use App\Tests\Integration\IntegrationTestCase;
|
||||||
use App\Repositories\Daemon\DaemonBackupRepository;
|
use App\Repositories\Daemon\DaemonBackupRepository;
|
||||||
use App\Exceptions\Service\Backup\BackupLockedException;
|
use App\Exceptions\Service\Backup\BackupLockedException;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
|
||||||
class DeleteBackupServiceTest extends IntegrationTestCase
|
class DeleteBackupServiceTest extends IntegrationTestCase
|
||||||
{
|
{
|
||||||
@ -54,11 +54,7 @@ class DeleteBackupServiceTest extends IntegrationTestCase
|
|||||||
$backup = Backup::factory()->create(['server_id' => $server->id]);
|
$backup = Backup::factory()->create(['server_id' => $server->id]);
|
||||||
|
|
||||||
$mock = $this->mock(DaemonBackupRepository::class);
|
$mock = $this->mock(DaemonBackupRepository::class);
|
||||||
$mock->expects('setServer->delete')->with($backup)->andThrow(
|
$mock->expects('setServer->delete')->with($backup)->andThrow(new ConnectionException(previous: new ClientException('', new Request('DELETE', '/'), new Response(404))));
|
||||||
new DaemonConnectionException(
|
|
||||||
new ClientException('', new Request('DELETE', '/'), new Response(404))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->app->make(DeleteBackupService::class)->handle($backup);
|
$this->app->make(DeleteBackupService::class)->handle($backup);
|
||||||
|
|
||||||
@ -73,13 +69,9 @@ class DeleteBackupServiceTest extends IntegrationTestCase
|
|||||||
$backup = Backup::factory()->create(['server_id' => $server->id]);
|
$backup = Backup::factory()->create(['server_id' => $server->id]);
|
||||||
|
|
||||||
$mock = $this->mock(DaemonBackupRepository::class);
|
$mock = $this->mock(DaemonBackupRepository::class);
|
||||||
$mock->expects('setServer->delete')->with($backup)->andThrow(
|
$mock->expects('setServer->delete')->with($backup)->andThrow(new ConnectionException(previous: new ClientException('', new Request('DELETE', '/'), new Response(500))));
|
||||||
new DaemonConnectionException(
|
|
||||||
new ClientException('', new Request('DELETE', '/'), new Response(500))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->expectException(DaemonConnectionException::class);
|
$this->expectException(ConnectionException::class);
|
||||||
|
|
||||||
$this->app->make(DeleteBackupService::class)->handle($backup);
|
$this->app->make(DeleteBackupService::class)->handle($backup);
|
||||||
|
|
||||||
|
@ -3,16 +3,13 @@
|
|||||||
namespace App\Tests\Integration\Services\Servers;
|
namespace App\Tests\Integration\Services\Servers;
|
||||||
|
|
||||||
use Mockery\MockInterface;
|
use Mockery\MockInterface;
|
||||||
use GuzzleHttp\Psr7\Request;
|
|
||||||
use GuzzleHttp\Psr7\Response;
|
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Allocation;
|
use App\Models\Allocation;
|
||||||
use GuzzleHttp\Exception\RequestException;
|
|
||||||
use App\Exceptions\DisplayException;
|
use App\Exceptions\DisplayException;
|
||||||
use App\Tests\Integration\IntegrationTestCase;
|
use App\Tests\Integration\IntegrationTestCase;
|
||||||
use App\Repositories\Daemon\DaemonServerRepository;
|
use App\Repositories\Daemon\DaemonServerRepository;
|
||||||
use App\Services\Servers\BuildModificationService;
|
use App\Services\Servers\BuildModificationService;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
|
||||||
class BuildModificationServiceTest extends IntegrationTestCase
|
class BuildModificationServiceTest extends IntegrationTestCase
|
||||||
{
|
{
|
||||||
@ -149,11 +146,7 @@ class BuildModificationServiceTest extends IntegrationTestCase
|
|||||||
|
|
||||||
$server = $this->createServerModel();
|
$server = $this->createServerModel();
|
||||||
|
|
||||||
$this->daemonServerRepository->expects('setServer->sync')->andThrows(
|
$this->daemonServerRepository->expects('setServer->sync')->andThrows(new ConnectionException());
|
||||||
new DaemonConnectionException(
|
|
||||||
new RequestException('Bad request', new Request('GET', '/test'), new Response())
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$response = $this->getService()->handle($server, ['memory' => 256, 'disk' => 10240]);
|
$response = $this->getService()->handle($server, ['memory' => 256, 'disk' => 10240]);
|
||||||
|
|
||||||
|
@ -3,16 +3,13 @@
|
|||||||
namespace App\Tests\Integration\Services\Servers;
|
namespace App\Tests\Integration\Services\Servers;
|
||||||
|
|
||||||
use Mockery\MockInterface;
|
use Mockery\MockInterface;
|
||||||
use GuzzleHttp\Psr7\Request;
|
|
||||||
use GuzzleHttp\Psr7\Response;
|
|
||||||
use App\Models\Database;
|
use App\Models\Database;
|
||||||
use App\Models\DatabaseHost;
|
use App\Models\DatabaseHost;
|
||||||
use GuzzleHttp\Exception\BadResponseException;
|
|
||||||
use App\Tests\Integration\IntegrationTestCase;
|
use App\Tests\Integration\IntegrationTestCase;
|
||||||
use App\Services\Servers\ServerDeletionService;
|
use App\Services\Servers\ServerDeletionService;
|
||||||
use App\Repositories\Daemon\DaemonServerRepository;
|
use App\Repositories\Daemon\DaemonServerRepository;
|
||||||
use App\Services\Databases\DatabaseManagementService;
|
use App\Services\Databases\DatabaseManagementService;
|
||||||
use App\Exceptions\Http\Connection\DaemonConnectionException;
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
|
||||||
class ServerDeletionServiceTest extends IntegrationTestCase
|
class ServerDeletionServiceTest extends IntegrationTestCase
|
||||||
{
|
{
|
||||||
@ -59,11 +56,9 @@ class ServerDeletionServiceTest extends IntegrationTestCase
|
|||||||
{
|
{
|
||||||
$server = $this->createServerModel();
|
$server = $this->createServerModel();
|
||||||
|
|
||||||
$this->expectException(DaemonConnectionException::class);
|
$this->expectException(ConnectionException::class);
|
||||||
|
|
||||||
$this->daemonServerRepository->expects('setServer->delete')->withNoArgs()->andThrows(
|
$this->daemonServerRepository->expects('setServer->delete')->withNoArgs()->andThrows(new ConnectionException());
|
||||||
new DaemonConnectionException(new BadResponseException('Bad request', new Request('GET', '/test'), new Response()))
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->getService()->handle($server);
|
$this->getService()->handle($server);
|
||||||
|
|
||||||
@ -77,9 +72,7 @@ class ServerDeletionServiceTest extends IntegrationTestCase
|
|||||||
{
|
{
|
||||||
$server = $this->createServerModel();
|
$server = $this->createServerModel();
|
||||||
|
|
||||||
$this->daemonServerRepository->expects('setServer->delete')->withNoArgs()->andThrows(
|
$this->daemonServerRepository->expects('setServer->delete')->withNoArgs()->andThrows(new ConnectionException(code: 404));
|
||||||
new DaemonConnectionException(new BadResponseException('Bad request', new Request('GET', '/test'), new Response(404)))
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->getService()->handle($server);
|
$this->getService()->handle($server);
|
||||||
|
|
||||||
@ -94,9 +87,7 @@ class ServerDeletionServiceTest extends IntegrationTestCase
|
|||||||
{
|
{
|
||||||
$server = $this->createServerModel();
|
$server = $this->createServerModel();
|
||||||
|
|
||||||
$this->daemonServerRepository->expects('setServer->delete')->withNoArgs()->andThrows(
|
$this->daemonServerRepository->expects('setServer->delete')->withNoArgs()->andThrows(new ConnectionException());
|
||||||
new DaemonConnectionException(new BadResponseException('Bad request', new Request('GET', '/test'), new Response(500)))
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->getService()->withForce()->handle($server);
|
$this->getService()->withForce()->handle($server);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user