Files
michaelschiemer/src/Framework/Process/Services/SystemdService.php
Michael Schiemer 95147ff23e refactor(deployment): Remove WireGuard VPN dependency and restore public service access
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.
2025-11-05 12:48:25 +01:00

220 lines
4.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Process\Services;
use App\Framework\Process\Process;
use App\Framework\Process\ValueObjects\Command;
/**
* Systemd Service.
*
* Verwaltet Systemd-Services über systemctl.
*/
final readonly class SystemdService
{
public function __construct(
private Process $process
) {
}
/**
* Listet alle Services.
*
* @return array<string, array{name: string, status: string, active: bool}>
*/
public function listServices(bool $all = false): array
{
$command = Command::fromArray([
'systemctl',
'list-units',
'--type=service',
'--no-pager',
'--no-legend',
]);
if ($all) {
$command = Command::fromArray([
'systemctl',
'list-units',
'--type=service',
'--all',
'--no-pager',
'--no-legend',
]);
}
$result = $this->process->run($command);
if (! $result->isSuccess()) {
return [];
}
$services = [];
$lines = explode("\n", trim($result->stdout));
foreach ($lines as $line) {
if (empty(trim($line))) {
continue;
}
$parts = preg_split('/\s+/', $line, 6);
if (count($parts) < 5) {
continue;
}
$name = $parts[0];
$status = $parts[3] ?? 'unknown';
$active = ($parts[3] ?? '') === 'active';
$services[] = [
'name' => $name,
'status' => $status,
'active' => $active,
];
}
return $services;
}
/**
* Gibt den Status eines Services zurück.
*/
public function getServiceStatus(string $service): ?array
{
$command = Command::fromArray([
'systemctl',
'status',
$service,
'--no-pager',
]);
$result = $this->process->run($command);
if (! $result->isSuccess()) {
return null;
}
// Parse status output
$lines = explode("\n", $result->stdout);
$status = [
'name' => $service,
'active' => false,
'enabled' => false,
];
foreach ($lines as $line) {
if (strpos($line, 'Active:') !== false) {
$status['active'] = strpos($line, 'active') !== false;
}
if (strpos($line, 'Loaded:') !== false) {
$status['enabled'] = strpos($line, 'enabled') !== false;
}
}
return $status;
}
/**
* Startet einen Service.
*/
public function startService(string $service): bool
{
$result = $this->process->run(
Command::fromArray(['systemctl', 'start', $service])
);
return $result->isSuccess();
}
/**
* Stoppt einen Service.
*/
public function stopService(string $service): bool
{
$result = $this->process->run(
Command::fromArray(['systemctl', 'stop', $service])
);
return $result->isSuccess();
}
/**
* Startet einen Service neu.
*/
public function restartService(string $service): bool
{
$result = $this->process->run(
Command::fromArray(['systemctl', 'restart', $service])
);
return $result->isSuccess();
}
/**
* Aktiviert einen Service.
*/
public function enableService(string $service): bool
{
$result = $this->process->run(
Command::fromArray(['systemctl', 'enable', $service])
);
return $result->isSuccess();
}
/**
* Deaktiviert einen Service.
*/
public function disableService(string $service): bool
{
$result = $this->process->run(
Command::fromArray(['systemctl', 'disable', $service])
);
return $result->isSuccess();
}
/**
* Gibt fehlgeschlagene Services zurück.
*
* @return array<string>
*/
public function getFailedServices(): array
{
$command = Command::fromArray([
'systemctl',
'list-units',
'--type=service',
'--state=failed',
'--no-pager',
'--no-legend',
]);
$result = $this->process->run($command);
if (! $result->isSuccess()) {
return [];
}
$failed = [];
$lines = explode("\n", trim($result->stdout));
foreach ($lines as $line) {
if (empty(trim($line))) {
continue;
}
$parts = preg_split('/\s+/', $line);
if (! empty($parts[0])) {
$failed[] = $parts[0];
}
}
return $failed;
}
}