mailwolt/app/Services/MailStorage.php

82 lines
3.3 KiB
PHP

<?php
namespace App\Services;
use App\Models\Domain;
use Illuminate\Support\Facades\Cache;
class MailStorage
{
/**
* Basiswerte & abgeleitete Pools in MiB.
* - percent_reserve enthält bereits die "Systemmail" (z. B. 5 % in deinen 15 %)
* - fixed_reserve_mb ist eine fixe Sicherheitsmarge (z. B. 2048 MiB)
* - committed_mb = Summe der Domain-Quotas (verplanter Speicher)
*/
public function stats(): array
{
$path = (string) config('mailpool.mail_data_path', '/var/mail');
$totalMb = (int) floor((@disk_total_space($path) ?: 0) / 1048576);
$freeMb = (int) floor((@disk_free_space($path) ?: 0) / 1048576);
$percentReserve = max(0, (int) config('mailpool.percent_reserve', 15)); // inkl. „Systemmail“
$fixedReserveMb = max(0, (int) config('mailpool.fixed_reserve_mb', 2048));
// 1) Reserve auf *freiem* Platz (dein gewünschtes Verhalten)
$percentReserveOnFreeMb = (int) round($freeMb * ($percentReserve / 100));
$systemReserveFreeBaseMb = $fixedReserveMb + $percentReserveOnFreeMb;
$freeAfterReserveMb = max(0, $freeMb - $systemReserveFreeBaseMb);
// 2) Reserve auf *Gesamt*platz (Kapazitätsbremse gegen Überbuchung)
$percentReserveOnTotalMb = (int) round($totalMb * ($percentReserve / 100));
$systemReserveTotalMb = $fixedReserveMb + $percentReserveOnTotalMb;
// bereits „verplant“: Summe der Domain-Quotas (achte auf Spaltennamen!)
$committedMb = (int) Domain::where('is_active', true)->sum('total_quota_mb');
// Kapazität, die du *maximal* noch als Quotas verteilen darfst
$capacityLeftMb = max(0, $totalMb - $systemReserveTotalMb - $committedMb);
// Für Eingabefelder konservativ das Minimum verwenden
$remainingPoolMb = min($freeAfterReserveMb, $capacityLeftMb);
return [
'path' => $path,
'total_mb' => $totalMb,
'free_mb' => $freeMb,
'fixed_reserve_mb' => $fixedReserveMb,
'percent_reserve' => $percentReserve,
'percent_reserve_on_free_mb' => $percentReserveOnFreeMb,
'free_after_reserve_mb' => $freeAfterReserveMb, // ≈ 70 GB bei deinen Werten
'percent_reserve_on_total_mb' => $percentReserveOnTotalMb,
'system_reserve_total_mb' => $systemReserveTotalMb,
'committed_mb' => $committedMb,
'capacity_left_mb' => $capacityLeftMb, // Kapazitätsbremse
'remaining_pool_mb' => $remainingPoolMb, // MIN(free-basiert, total-basiert)
];
}
/** Für UI: konservativer, gecachter Rest-Pool (in MiB) */
public function remainingPoolMb(): int
{
return Cache::remember('mailpool.remaining', 10, fn () => $this->stats()['remaining_pool_mb']);
}
/** Vorschlag für max. Eingabewert */
public function suggestMaxAllocMb(): int
{
return $this->remainingPoolMb();
}
/** Prüfen, ob X MiB sauber in den Pool passen */
public function canAllocate(int $mb): bool
{
return $mb >= 0 && $mb <= $this->remainingPoolMb();
}
}