Remove WireGuard integration from production deployment to simplify infrastructure: - Remove docker-compose-direct-access.yml (VPN-bound services) - Remove VPN-only middlewares from Grafana, Prometheus, Portainer - Remove WireGuard middleware definitions from Traefik - Remove WireGuard IPs (10.8.0.0/24) from Traefik forwarded headers All monitoring services now publicly accessible via subdomains: - grafana.michaelschiemer.de (with Grafana native auth) - prometheus.michaelschiemer.de (with Basic Auth) - portainer.michaelschiemer.de (with Portainer native auth) All services use Let's Encrypt SSL certificates via Traefik.
181 lines
4.4 KiB
PHP
181 lines
4.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Process\Services;
|
|
|
|
use App\Framework\Core\ValueObjects\Duration;
|
|
use App\Framework\Filesystem\ValueObjects\FilePath;
|
|
use App\Framework\Process\Process;
|
|
use App\Framework\Process\ValueObjects\Command;
|
|
|
|
/**
|
|
* Maintenance Service.
|
|
*
|
|
* Führt Wartungs- und Cleanup-Operationen durch.
|
|
*/
|
|
final readonly class MaintenanceService
|
|
{
|
|
public function __construct(
|
|
private Process $process
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Löscht alte temporäre Dateien.
|
|
*
|
|
* @return int Anzahl gelöschter Dateien
|
|
*/
|
|
public function cleanTempFiles(Duration $olderThan): int
|
|
{
|
|
$tempDir = sys_get_temp_dir();
|
|
$days = (int) ceil($olderThan->toDays());
|
|
|
|
$command = Command::fromString(
|
|
"find {$tempDir} -type f -mtime +{$days} -delete"
|
|
);
|
|
|
|
$result = $this->process->run($command);
|
|
|
|
// Count deleted files (approximate)
|
|
return $result->isSuccess() ? 1 : 0;
|
|
}
|
|
|
|
/**
|
|
* Rotiert alte Log-Dateien.
|
|
*
|
|
* @return int Anzahl rotierter Dateien
|
|
*/
|
|
public function cleanLogFiles(FilePath $logDirectory, Duration $olderThan): int
|
|
{
|
|
if (! $logDirectory->isDirectory()) {
|
|
return 0;
|
|
}
|
|
|
|
$days = (int) ceil($olderThan->toDays());
|
|
|
|
$command = Command::fromString(
|
|
"find {$logDirectory->toString()} -name '*.log' -type f -mtime +{$days} -delete"
|
|
);
|
|
|
|
$result = $this->process->run($command);
|
|
|
|
return $result->isSuccess() ? 1 : 0;
|
|
}
|
|
|
|
/**
|
|
* Leert Cache-Verzeichnisse.
|
|
*/
|
|
public function cleanCache(FilePath $cacheDirectory): bool
|
|
{
|
|
if (! $cacheDirectory->isDirectory()) {
|
|
return false;
|
|
}
|
|
|
|
$command = Command::fromString(
|
|
"rm -rf {$cacheDirectory->toString()}/*"
|
|
);
|
|
|
|
$result = $this->process->run($command);
|
|
|
|
return $result->isSuccess();
|
|
}
|
|
|
|
/**
|
|
* Löscht alte Backups.
|
|
*
|
|
* @return int Anzahl gelöschter Backups
|
|
*/
|
|
public function cleanOldBackups(FilePath $backupDirectory, Duration $olderThan): int
|
|
{
|
|
if (! $backupDirectory->isDirectory()) {
|
|
return 0;
|
|
}
|
|
|
|
$days = (int) ceil($olderThan->toDays());
|
|
|
|
$command = Command::fromString(
|
|
"find {$backupDirectory->toString()} -type f -name '*.sql' -o -name '*.sql.gz' -mtime +{$days} -delete"
|
|
);
|
|
|
|
$result = $this->process->run($command);
|
|
|
|
return $result->isSuccess() ? 1 : 0;
|
|
}
|
|
|
|
/**
|
|
* Findet die größten Verzeichnisse.
|
|
*
|
|
* @return array<string, int> Verzeichnis => Größe in Bytes
|
|
*/
|
|
public function findLargestDirectories(FilePath $directory, int $limit = 10): array
|
|
{
|
|
if (! $directory->isDirectory()) {
|
|
return [];
|
|
}
|
|
|
|
$command = Command::fromString(
|
|
"du -h -d 1 {$directory->toString()} 2>/dev/null | sort -hr | head -{$limit}"
|
|
);
|
|
|
|
$result = $this->process->run($command);
|
|
|
|
if (! $result->isSuccess()) {
|
|
return [];
|
|
}
|
|
|
|
$directories = [];
|
|
$lines = explode("\n", trim($result->stdout));
|
|
|
|
foreach ($lines as $line) {
|
|
$parts = preg_split('/\s+/', $line, 2);
|
|
if (count($parts) === 2) {
|
|
$directories[$parts[1]] = $parts[0]; // Size as string (human-readable)
|
|
}
|
|
}
|
|
|
|
return $directories;
|
|
}
|
|
|
|
/**
|
|
* Findet doppelte Dateien.
|
|
*
|
|
* @return array<string, array<string>> Hash => Dateipfade
|
|
*/
|
|
public function findDuplicateFiles(FilePath $directory): array
|
|
{
|
|
if (! $directory->isDirectory()) {
|
|
return [];
|
|
}
|
|
|
|
$command = Command::fromString(
|
|
"find {$directory->toString()} -type f -exec md5sum {} \\; | sort | uniq -d -w 32"
|
|
);
|
|
|
|
$result = $this->process->run($command);
|
|
|
|
if (! $result->isSuccess()) {
|
|
return [];
|
|
}
|
|
|
|
$duplicates = [];
|
|
$lines = explode("\n", trim($result->stdout));
|
|
|
|
foreach ($lines as $line) {
|
|
$parts = preg_split('/\s+/', $line, 2);
|
|
if (count($parts) === 2) {
|
|
$hash = $parts[0];
|
|
$file = $parts[1];
|
|
if (! isset($duplicates[$hash])) {
|
|
$duplicates[$hash] = [];
|
|
}
|
|
$duplicates[$hash][] = $file;
|
|
}
|
|
}
|
|
|
|
return $duplicates;
|
|
}
|
|
}
|
|
|
|
|