Remove backup and mount repositories

This commit is contained in:
Lance Pioch 2024-03-16 23:01:45 -04:00
parent 9d3a6ae494
commit aa93cd65c1
9 changed files with 41 additions and 132 deletions

View File

@ -2,9 +2,9 @@
namespace App\Console\Commands\Maintenance; namespace App\Console\Commands\Maintenance;
use App\Models\Backup;
use Carbon\CarbonImmutable; use Carbon\CarbonImmutable;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use App\Repositories\Eloquent\BackupRepository;
class PruneOrphanedBackupsCommand extends Command class PruneOrphanedBackupsCommand extends Command
{ {
@ -12,14 +12,6 @@ class PruneOrphanedBackupsCommand extends Command
protected $description = 'Marks all backups older than "n" minutes that have not yet completed as being failed.'; protected $description = 'Marks all backups older than "n" minutes that have not yet completed as being failed.';
/**
* PruneOrphanedBackupsCommand constructor.
*/
public function __construct(private BackupRepository $backupRepository)
{
parent::__construct();
}
public function handle() public function handle()
{ {
$since = $this->option('prune-age') ?? config('backups.prune_age', 360); $since = $this->option('prune-age') ?? config('backups.prune_age', 360);
@ -27,7 +19,7 @@ class PruneOrphanedBackupsCommand extends Command
throw new \InvalidArgumentException('The "--prune-age" argument must be a value greater than 0.'); throw new \InvalidArgumentException('The "--prune-age" argument must be a value greater than 0.');
} }
$query = $this->backupRepository->getBuilder() $query = Backup::query()
->whereNull('completed_at') ->whereNull('completed_at')
->where('created_at', '<=', CarbonImmutable::now()->subMinutes($since)->toDateTimeString()); ->where('created_at', '<=', CarbonImmutable::now()->subMinutes($since)->toDateTimeString());

View File

@ -13,7 +13,6 @@ use Prologue\Alerts\AlertsMessageBag;
use Illuminate\View\Factory as ViewFactory; use Illuminate\View\Factory as ViewFactory;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\MountFormRequest; use App\Http\Requests\Admin\MountFormRequest;
use App\Repositories\Eloquent\MountRepository;
class MountController extends Controller class MountController extends Controller
{ {
@ -22,7 +21,6 @@ class MountController extends Controller
*/ */
public function __construct( public function __construct(
protected AlertsMessageBag $alert, protected AlertsMessageBag $alert,
protected MountRepository $repository,
protected ViewFactory $view protected ViewFactory $view
) { ) {
} }
@ -33,7 +31,7 @@ class MountController extends Controller
public function index(): View public function index(): View
{ {
return $this->view->make('admin.mounts.index', [ return $this->view->make('admin.mounts.index', [
'mounts' => $this->repository->getAllWithDetails(), 'mounts' => Mount::query()->withCount(['eggs', 'nodes'])->get(),
]); ]);
} }
@ -44,11 +42,9 @@ class MountController extends Controller
*/ */
public function view(string $id): View public function view(string $id): View
{ {
$eggs = Egg::all();
return $this->view->make('admin.mounts.view', [ return $this->view->make('admin.mounts.view', [
'mount' => $this->repository->getWithRelations($id), 'mount' => Mount::with(['eggs', 'nodes'])->findOrFail($id),
'eggs' => $eggs, 'eggs' => Egg::all(),
]); ]);
} }

View File

@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin\Servers;
use App\Models\DatabaseHost; use App\Models\DatabaseHost;
use App\Models\Egg; use App\Models\Egg;
use App\Models\Mount;
use App\Models\Node; use App\Models\Node;
use Illuminate\View\View; use Illuminate\View\View;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@ -12,7 +13,6 @@ use App\Exceptions\DisplayException;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Services\Servers\EnvironmentService; use App\Services\Servers\EnvironmentService;
use Illuminate\Contracts\View\Factory as ViewFactory; use Illuminate\Contracts\View\Factory as ViewFactory;
use App\Repositories\Eloquent\MountRepository;
use App\Traits\Controllers\JavascriptInjection; use App\Traits\Controllers\JavascriptInjection;
class ServerViewController extends Controller class ServerViewController extends Controller
@ -23,7 +23,6 @@ class ServerViewController extends Controller
* ServerViewController constructor. * ServerViewController constructor.
*/ */
public function __construct( public function __construct(
private MountRepository $mountRepository,
private EnvironmentService $environmentService, private EnvironmentService $environmentService,
private ViewFactory $view private ViewFactory $view
) { ) {
@ -96,8 +95,13 @@ class ServerViewController extends Controller
{ {
$server->load('mounts'); $server->load('mounts');
$mounts = Mount::query()
->whereHas('eggs', fn ($q) => $q->where('id', $server->egg_id))
->whereHas('nodes', fn ($q) => $q->where('id', $server->node_id))
->get();
return $this->view->make('admin.servers.view.mounts', [ return $this->view->make('admin.servers.view.mounts', [
'mounts' => $this->mountRepository->getMountListForServer($server), 'mounts' => $mounts,
'server' => $server, 'server' => $server,
]); ]);
} }

View File

@ -15,7 +15,6 @@ use App\Exceptions\DisplayException;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use Illuminate\Validation\ValidationException; use Illuminate\Validation\ValidationException;
use App\Services\Servers\SuspensionService; use App\Services\Servers\SuspensionService;
use App\Repositories\Eloquent\MountRepository;
use App\Services\Servers\ServerDeletionService; use App\Services\Servers\ServerDeletionService;
use App\Services\Servers\ReinstallServerService; use App\Services\Servers\ReinstallServerService;
use App\Exceptions\Model\DataValidationException; use App\Exceptions\Model\DataValidationException;
@ -44,7 +43,6 @@ class ServersController extends Controller
protected ServerDeletionService $deletionService, protected ServerDeletionService $deletionService,
protected DetailsModificationService $detailsModificationService, protected DetailsModificationService $detailsModificationService,
protected ReinstallServerService $reinstallService, protected ReinstallServerService $reinstallService,
protected MountRepository $mountRepository,
protected ServerConfigurationStructureService $serverConfigurationStructureService, protected ServerConfigurationStructureService $serverConfigurationStructureService,
protected StartupModificationService $startupModificationService, protected StartupModificationService $startupModificationService,
protected SuspensionService $suspensionService protected SuspensionService $suspensionService

View File

@ -11,7 +11,6 @@ use App\Models\Permission;
use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Auth\Access\AuthorizationException;
use App\Services\Backups\DeleteBackupService; use App\Services\Backups\DeleteBackupService;
use App\Services\Backups\DownloadLinkService; use App\Services\Backups\DownloadLinkService;
use App\Repositories\Eloquent\BackupRepository;
use App\Services\Backups\InitiateBackupService; use App\Services\Backups\InitiateBackupService;
use App\Repositories\Daemon\DaemonBackupRepository; use App\Repositories\Daemon\DaemonBackupRepository;
use App\Transformers\Api\Client\BackupTransformer; use App\Transformers\Api\Client\BackupTransformer;
@ -30,7 +29,6 @@ class BackupController extends ClientApiController
private DeleteBackupService $deleteBackupService, private DeleteBackupService $deleteBackupService,
private InitiateBackupService $initiateBackupService, private InitiateBackupService $initiateBackupService,
private DownloadLinkService $downloadLinkService, private DownloadLinkService $downloadLinkService,
private BackupRepository $repository
) { ) {
parent::__construct(); parent::__construct();
} }
@ -52,7 +50,7 @@ class BackupController extends ClientApiController
return $this->fractal->collection($server->backups()->paginate($limit)) return $this->fractal->collection($server->backups()->paginate($limit))
->transformWith($this->getTransformer(BackupTransformer::class)) ->transformWith($this->getTransformer(BackupTransformer::class))
->addMeta([ ->addMeta([
'backup_count' => $this->repository->getNonFailedBackups($server)->count(), 'backup_count' => $server->getNonFailedBackups()->count(),
]) ])
->toArray(); ->toArray();
} }

View File

@ -3,10 +3,12 @@
namespace App\Models; namespace App\Models;
use App\Exceptions\Http\Connection\DaemonConnectionException; use App\Exceptions\Http\Connection\DaemonConnectionException;
use Carbon\Carbon;
use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\TransferException; use GuzzleHttp\Exception\TransferException;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Query\JoinClause; use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Znck\Eloquent\Traits\BelongsToThrough; use Znck\Eloquent\Traits\BelongsToThrough;
@ -386,4 +388,27 @@ class Server extends Model
throw new DaemonConnectionException($exception); throw new DaemonConnectionException($exception);
} }
} }
/**
* Determines if too many backups have been generated by the server.
*/
public function getBackupsGeneratedDuringTimespan(int $seconds = 600): array|Collection
{
return self::query()
->backups()
->where(fn ($query) => $query->whereNull('completed_at')->orWhere('is_successful', true))
->where('created_at', '>=', now()->subSeconds($seconds))
->withTrashed()
->get();
}
/**
* Returns a query filtering only non-failed backups for a specific server.
*/
public function getNonFailedBackups(): HasMany
{
return $this->backups()->where(
fn ($query) => $query->whereNull('completed_at')->orWhere('is_successful', true)
);
}
} }

View File

@ -1,45 +0,0 @@
<?php
namespace App\Repositories\Eloquent;
use Carbon\Carbon;
use App\Models\Backup;
use App\Models\Server;
use Illuminate\Support\Collection;
use Illuminate\Database\Eloquent\Relations\HasMany;
class BackupRepository extends EloquentRepository
{
public function model(): string
{
return Backup::class;
}
/**
* Determines if too many backups have been generated by the server.
*/
public function getBackupsGeneratedDuringTimespan(int $server, int $seconds = 600): array|Collection
{
return $this->getBuilder()
->withTrashed()
->where('server_id', $server)
->where(function ($query) {
$query->whereNull('completed_at')
->orWhere('is_successful', '=', true);
})
->where('created_at', '>=', Carbon::now()->subSeconds($seconds)->toDateTimeString())
->get()
->toBase();
}
/**
* Returns a query filtering only non-failed backups for a specific server.
*/
public function getNonFailedBackups(Server $server): HasMany
{
return $server->backups()->where(function ($query) {
$query->whereNull('completed_at')
->orWhere('is_successful', true);
});
}
}

View File

@ -1,57 +0,0 @@
<?php
namespace App\Repositories\Eloquent;
use App\Models\Mount;
use App\Models\Server;
use Illuminate\Support\Collection;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use App\Exceptions\Repository\RecordNotFoundException;
class MountRepository extends EloquentRepository
{
/**
* Return the model backing this repository.
*/
public function model(): string
{
return Mount::class;
}
/**
* Return mounts with a count of eggs, nodes, and servers attached to it.
*/
public function getAllWithDetails(): Collection
{
return $this->getBuilder()->withCount('eggs', 'nodes')->get($this->getColumns());
}
/**
* Return all the mounts and their respective relations.
*
* @throws \App\Exceptions\Repository\RecordNotFoundException
*/
public function getWithRelations(string $id): Mount
{
try {
return $this->getBuilder()->with('eggs', 'nodes')->findOrFail($id, $this->getColumns());
} catch (ModelNotFoundException $exception) {
throw new RecordNotFoundException();
}
}
/**
* Return mounts available to a server (ignoring if they are or are not mounted).
*/
public function getMountListForServer(Server $server): Collection
{
return $this->getBuilder()
->whereHas('eggs', function ($q) use ($server) {
$q->where('id', '=', $server->egg_id);
})
->whereHas('nodes', function ($q) use ($server) {
$q->where('id', '=', $server->node_id);
})
->get($this->getColumns());
}
}

View File

@ -9,7 +9,6 @@ use App\Models\Backup;
use App\Models\Server; use App\Models\Server;
use Illuminate\Database\ConnectionInterface; use Illuminate\Database\ConnectionInterface;
use App\Extensions\Backups\BackupManager; use App\Extensions\Backups\BackupManager;
use App\Repositories\Eloquent\BackupRepository;
use App\Repositories\Daemon\DaemonBackupRepository; use App\Repositories\Daemon\DaemonBackupRepository;
use App\Exceptions\Service\Backup\TooManyBackupsException; use App\Exceptions\Service\Backup\TooManyBackupsException;
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
@ -24,7 +23,6 @@ class InitiateBackupService
* InitiateBackupService constructor. * InitiateBackupService constructor.
*/ */
public function __construct( public function __construct(
private BackupRepository $repository,
private ConnectionInterface $connection, private ConnectionInterface $connection,
private DaemonBackupRepository $daemonBackupRepository, private DaemonBackupRepository $daemonBackupRepository,
private DeleteBackupService $deleteBackupService, private DeleteBackupService $deleteBackupService,
@ -78,7 +76,7 @@ class InitiateBackupService
$limit = config('backups.throttles.limit'); $limit = config('backups.throttles.limit');
$period = config('backups.throttles.period'); $period = config('backups.throttles.period');
if ($period > 0) { if ($period > 0) {
$previous = $this->repository->getBackupsGeneratedDuringTimespan($server->id, $period); $previous = $server->getBackupsGeneratedDuringTimespan($period);
if ($previous->count() >= $limit) { if ($previous->count() >= $limit) {
$message = sprintf('Only %d backups may be generated within a %d second span of time.', $limit, $period); $message = sprintf('Only %d backups may be generated within a %d second span of time.', $limit, $period);
@ -88,7 +86,7 @@ class InitiateBackupService
// Check if the server has reached or exceeded its backup limit. // Check if the server has reached or exceeded its backup limit.
// completed_at == null will cover any ongoing backups, while is_successful == true will cover any completed backups. // completed_at == null will cover any ongoing backups, while is_successful == true will cover any completed backups.
$successful = $this->repository->getNonFailedBackups($server); $successful = $server->getNonFailedBackups();
if (!$server->backup_limit || $successful->count() >= $server->backup_limit) { if (!$server->backup_limit || $successful->count() >= $server->backup_limit) {
// Do not allow the user to continue if this server is already at its limit and can't override. // Do not allow the user to continue if this server is already at its limit and can't override.
if (!$override || $server->backup_limit <= 0) { if (!$override || $server->backup_limit <= 0) {
@ -109,7 +107,7 @@ class InitiateBackupService
return $this->connection->transaction(function () use ($server, $name) { return $this->connection->transaction(function () use ($server, $name) {
/** @var \App\Models\Backup $backup */ /** @var \App\Models\Backup $backup */
$backup = $this->repository->create([ $backup = Backup::query()->create([
'server_id' => $server->id, 'server_id' => $server->id,
'uuid' => Uuid::uuid4()->toString(), 'uuid' => Uuid::uuid4()->toString(),
'name' => trim($name) ?: sprintf('Backup at %s', CarbonImmutable::now()->toDateTimeString()), 'name' => trim($name) ?: sprintf('Backup at %s', CarbonImmutable::now()->toDateTimeString()),