Fix: Mailbox Stats über Dovecot mit config/mailpool.php

main v1.0.46
boban 2025-10-26 16:46:16 +01:00
parent 64afb9d9af
commit ea12b97497
4 changed files with 173 additions and 55 deletions

View File

@ -1,20 +0,0 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Jobs\RunHealthChecks;
class CollectWoltGuardServices extends Command
{
protected $signature = 'woltguard:collect-services';
protected $description = 'Collect WoltGuard services status synchronously';
public function handle(): int
{
// synchron ausführen, unabhängig vom Queue-Worker
RunHealthChecks::dispatchSync();
$this->info('WoltGuard services collected.');
return self::SUCCESS;
}
}

View File

@ -1,4 +1,5 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
@ -13,24 +14,107 @@ class MailwoltRestart extends Command
$units = config('mailwolt.units', []);
foreach ($units as $u) {
$unit = rtrim($u['name'] ?? '', '.service') . '.service';
$action = $u['action'] ?? 'try-reload-or-restart';
$base = (string)($u['name'] ?? '');
$unit = str_ends_with($base, '.service') ? $base : $base . '.service';
$action = (string)($u['action'] ?? 'try-reload-or-restart');
$cmd = sprintf('sudo -n /usr/bin/systemctl %s %s', escapeshellarg($action), escapeshellarg($unit));
$this->info("{$unit} ({$action})");
// Existiert die Unit?
$existsCmd = sprintf('systemctl status %s >/dev/null 2>&1', escapeshellarg($unit));
exec($existsCmd, $_o, $existsRc);
if ($existsRc !== 0) {
$this->line(" {$unit} existiert nicht übersprungen");
continue;
}
// Restart/Reload via sudo (ohne Passwort)
$cmd = sprintf('sudo -n /usr/bin/systemctl %s %s', escapeshellarg($action), escapeshellarg($unit));
exec($cmd . ' 2>&1', $out, $rc);
foreach ($out as $line) {
$this->line(" $line");
}
if ($rc !== 0) {
$this->warn(" [!] Fehler beim Neustart von {$unit} (rc={$rc})");
} else {
$this->line(" [✓] Erfolgreich");
}
$rc === 0 ? $this->line(' [✓] Erfolgreich') : $this->warn(" [!] Fehler (rc={$rc})");
}
return self::SUCCESS;
}
}
//class MailwoltRestart extends Command
//{
// protected $signature = 'mailwolt:restart-services';
// protected $description = 'Restart or reload MailWolt-related system services';
//
// public function handle(): int
// {
// $units = config('mailwolt.units', []);
// $allowed = ['reload','restart','try-reload-or-restart'];
//
// foreach ($units as $u) {
// $base = (string)($u['name'] ?? '');
// $unit = str_ends_with($base, '.service') ? $base : $base . '.service';
// $action = $u['action'] ?? 'try-reload-or-restart';
// if (!in_array($action, $allowed, true)) $action = 'try-reload-or-restart';
//
// // existiert Unit überhaupt?
// $probe = Process::fromShellCommandline("systemctl status $unit >/dev/null 2>&1");
// $probe->run();
// if ($probe->getExitCode() !== 0) {
// $this->warn("→ {$unit} existiert nicht übersprungen");
// continue;
// }
//
// $this->info("→ {$unit} ({$action})");
// $p = new Process(['sudo','-n','/usr/bin/systemctl',$action,$unit]);
// $p->setTimeout(15);
// $p->run();
//
// if (!$p->isSuccessful()) {
// $this->warn(" [!] Fehler (rc={$p->getExitCode()})");
// Log::warning('service restart failed', [
// 'unit'=>$unit,'action'=>$action,
// 'out'=>$p->getOutput(), 'err'=>$p->getErrorOutput()
// ]);
// } else {
// $this->line(" [✓] Erfolgreich");
// }
// }
// return self::SUCCESS;
// }
//}
//
//use Illuminate\Console\Command;
//
//class MailwoltRestart extends Command
//{
// protected $signature = 'mailwolt:restart-services';
// protected $description = 'Restart or reload MailWolt-related system services';
//
// public function handle(): int
// {
// $units = config('mailwolt.units', []);
//
// foreach ($units as $u) {
// $unit = rtrim($u['name'] ?? '', '.service') . '.service';
// $action = $u['action'] ?? 'try-reload-or-restart';
//
// $cmd = sprintf('sudo -n /usr/bin/systemctl %s %s', escapeshellarg($action), escapeshellarg($unit));
// $this->info("→ {$unit} ({$action})");
//
// exec($cmd . ' 2>&1', $out, $rc);
// foreach ($out as $line) {
// $this->line(" $line");
// }
//
// if ($rc !== 0) {
// $this->warn(" [!] Fehler beim Neustart von {$unit} (rc={$rc})");
// } else {
// $this->line(" [✓] Erfolgreich");
// }
// }
//
// return self::SUCCESS;
// }
//}

View File

@ -85,58 +85,97 @@ class UpdateCard extends Component
$this->recomputeUi();
}
// public function pollUpdate(): void
// {
// // 1) aktuellen Wrapper-Status einlesen
// $this->refreshLowLevelState();
//
// // 2) Failsafe
// $started = (int)Cache::get($this->cacheStartedAtKey, 0);
// if ($this->running && $started > 0 && (time() - $started) > $this->failsafeSeconds) {
// $this->running = false;
// $this->rc ??= 0; // wenn unklar, als erfolgreich werten
// }
//
// // 3) Abschluss?
// if (!$this->running) {
// Cache::forget($this->cacheStartedAtKey);
//
// // Nachlauf: Versionen & Vergleich neu aufbauen
// $this->reloadVersionsAndStatus();
// $this->recompute();
//
// if ($this->rc === 0 && !$this->postActionsDone) {
// // Dienste neu starten (asynchron)
// @shell_exec('nohup php /var/www/mailwolt/artisan mailwolt:restart-services >/dev/null 2>&1 &');
// $this->postActionsDone = true;
//
// $ver = $this->displayCurrent ?? 'aktuelle Version';
// $this->progressLine = '';
// $this->dispatch('reload-page', delay: 5000);
// $this->dispatch('toast',
// type: 'success',
// title: 'Update erfolgreich',
// text: "MailWolt wurde auf {$ver} aktualisiert.",
// badge: 'System',
// duration: 4000
// );
// } elseif ($this->rc !== null && $this->rc !== 0 && !$this->postActionsDone) {
// // Fehlerfall
// $this->postActionsDone = true;
// $this->errorLine = "Update fehlgeschlagen (rc={$this->rc}).";
// $this->dispatch('toast',
// type: 'error',
// title: 'Update fehlgeschlagen',
// text: $this->progressLine ?: 'Bitte Logs prüfen: /var/log/mailwolt-update.log',
// badge: 'System',
// duration: 0
// );
// }
//
// $this->state = 'idle';
// }
//
// // UI bei jedem Poll neu ableiten
// $this->recomputeUi();
// }
public function pollUpdate(): void
{
// 1) aktuellen Wrapper-Status einlesen
$this->refreshLowLevelState();
// 2) Failsafe
$started = (int)Cache::get($this->cacheStartedAtKey, 0);
$started = (int) Cache::get($this->cacheStartedAtKey, 0);
if ($this->running && $started > 0 && (time() - $started) > $this->failsafeSeconds) {
$this->running = false;
$this->rc ??= 0; // wenn unklar, als erfolgreich werten
$this->rc ??= 0; // failsafe: als erfolgreich werten
}
// 3) Abschluss?
if (!$this->running) {
Cache::forget($this->cacheStartedAtKey);
// Nachlauf: Versionen & Vergleich neu aufbauen
$this->reloadVersionsAndStatus();
$this->recompute();
if ($this->rc === 0 && !$this->postActionsDone) {
// Dienste neu starten (asynchron)
// Restarts DE-coupled
@shell_exec('nohup php /var/www/mailwolt/artisan mailwolt:restart-services >/dev/null 2>&1 &');
$this->postActionsDone = true;
$ver = $this->displayCurrent ?? 'aktuelle Version';
$this->progressLine = '';
$this->dispatch('toast', type: 'success', title: 'Update erfolgreich',
text: "MailWolt wurde auf {$ver} aktualisiert.", badge: 'System', duration: 4000);
$this->dispatch('reload-page', delay: 5000);
$this->dispatch('toast',
type: 'success',
title: 'Update erfolgreich',
text: "MailWolt wurde auf {$ver} aktualisiert.",
badge: 'System',
duration: 4000
);
} elseif ($this->rc !== null && $this->rc !== 0 && !$this->postActionsDone) {
// Fehlerfall
$this->postActionsDone = true;
$this->errorLine = "Update fehlgeschlagen (rc={$this->rc}).";
$this->dispatch('toast',
type: 'error',
title: 'Update fehlgeschlagen',
text: $this->progressLine ?: 'Bitte Logs prüfen: /var/log/mailwolt-update.log',
badge: 'System',
duration: 0
);
$this->dispatch('toast', type: 'error', title: 'Update fehlgeschlagen',
text: $this->progressLine ?: 'Bitte /var/log/mailwolt-update.log prüfen', badge: 'System', duration: -1);
}
$this->state = 'idle';
}
// UI bei jedem Poll neu ableiten
$this->recomputeUi();
}
@ -230,14 +269,27 @@ class UpdateCard extends Component
}
// protected function refreshLowLevelState(): void
// {
// $state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: '');
// $this->running = ($state === 'running');
//
// $rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: '');
// $this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null;
//
// $this->progressLine = $this->tailUpdateLog();
// }
protected function refreshLowLevelState(): void
{
$state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: '');
$this->running = ($state === 'running');
$rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: '');
$this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null;
// läuft nur, solange KEINE rc vorliegt
$this->running = ($state === 'running' && $this->rc === null);
$this->progressLine = $this->tailUpdateLog();
}

View File

@ -3,12 +3,14 @@
return [
'units' => [
['name' => 'nginx', 'action' => 'reload'],
// ['name' => 'php8.2-fpm', 'action' => 'restart'],
['name' => 'postfix', 'action' => 'try-reload-or-restart'],
['name' => 'dovecot', 'action' => 'try-reload-or-restart'],
['name' => 'rspamd', 'action' => 'try-reload-or-restart'],
// nur drin lassen, wenn wirklich installiert:
['name' => 'opendkim', 'action' => 'try-reload-or-restart'],
['name' => 'opendmarc', 'action' => 'try-reload-or-restart'],
['name' => 'clamav-daemon', 'action' => 'try-reload-or-restart'],
['name' => 'redis-server', 'action' => 'try-reload-or-restart'],
],