Wartung: Online-Watchdog nach Neustart, Status-Reset, Zugangsdaten-Spalte

- Nach einem ausgelösten SSH-Neustart blieb der Job-Status bisher für
  immer auf "Neustart ausgelöst" stehen -- ergänzt um einen Ping-
  Watchdog (gleiche Invocation wie das bestehende Monitoring in
  poe.sh: "ping -c 1 -W 2"), der nach einer kurzen Schonfrist (15s)
  regelmäßig prüft, bis das Gerät wieder antwortet (Timeout 5min).
  Status wechselt dann sichtbar auf "wieder online" bzw. auf einen
  Fehler bei Zeitüberschreitung.
- Ein abgeschlossener ERFOLGREICHER Job wird bei jedem (erneuten) Laden
  der Wartungsseite zurückgesetzt (wieder "Noch keine Aktion") -- ein
  Erfolg ist nur relevant, solange man ihn live mitverfolgt. Fehler
  bleiben bewusst bis zur nächsten Aktion sichtbar, um sie nicht durch
  einen einfachen Reload zu übersehen.
- Clients-Tabelle zeigt jetzt wie die Switche-Tabelle eine
  "Zugangsdaten"-Spalte (Name + Username oder "— keine —").

Live gegen das dedizierte Testsystem verifiziert: zwei echte Neustarts,
beide per uptime -s bestätigt (kein False-Positive-Ping gegen die noch
nicht heruntergefahrene alte Instanz), Status korrekt von "wartet auf
Online" auf "wieder online" gewechselt; Status-Reset beim Seitenaufruf
ebenfalls live bestätigt (sichtbar vor, leer nach einem GET /maintenance).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-12 11:35:51 +02:00
co-authored by Claude Sonnet 5
parent 8772f7777b
commit 3b2a5fc76c
3 changed files with 116 additions and 18 deletions
+10 -2
View File
@@ -8,7 +8,7 @@
{% set can_edit = current_user.has_permission('devices.edit') %}
{% set can_delete = current_user.has_permission('devices.edit') %}
{% set show_actions_col = can_edit or can_delete %}
{% set col_count = 5 + (1 if can_toggle else 0) + (1 if show_actions_col else 0) %}
{% set col_count = 6 + (1 if can_toggle else 0) + (1 if show_actions_col else 0) %}
{% block page_title %}Clients{% endblock %}
{% block page_sub %}<div class="topbar-sub">{{ devices|length }} Geräte</div>{% endblock %}
@@ -43,18 +43,26 @@
<th data-sort-key="mac">MAC-Adresse</th>
<th data-sort-key="switch">Switch</th>
<th data-sort-key="port">Switchport</th>
<th data-sort-key="credential">Zugangsdaten</th>
{% if can_toggle %}<th>Status</th>{% endif %}
{% if show_actions_col %}<th style="width:1%;">Aktionen</th>{% endif %}
</tr>
</thead>
<tbody>
{% for d in devices %}
<tr data-sort-hostname="{{ d['name']|lower }}" data-sort-ip="{{ d['rpi_ip']|lower }}" data-sort-mac="{{ d['mac']|lower }}" data-sort-switch="{{ (d['switch_hostname'] or '')|lower }}" data-sort-port="{{ (d['port'] or '')|lower }}">
<tr data-sort-hostname="{{ d['name']|lower }}" data-sort-ip="{{ d['rpi_ip']|lower }}" data-sort-mac="{{ d['mac']|lower }}" data-sort-switch="{{ (d['switch_hostname'] or '')|lower }}" data-sort-port="{{ (d['port'] or '')|lower }}" data-sort-credential="{{ (d['credential_name'] or '')|lower }}">
<td class="cell-name">{{ d['name'] }}</td>
<td class="mono">{{ d['rpi_ip'] }}</td>
<td class="mono">{{ d['mac'] }}</td>
<td>{{ d['switch_hostname'] or '—' }}</td>
<td>{{ d['port'] or '—' }}</td>
<td>
{% if d['credential_name'] %}
{{ d['credential_name'] }} <span class="text-faint mono" style="font-size:11.5px;">({{ d['credential_username'] }})</span>
{% else %}
<span class="text-faint">— keine —</span>
{% endif %}
</td>
{% if can_toggle %}
<td>
<label class="switch-check">