CluPilotCloud/tests/Feature/Admin
nexxo d1755f5921 Der Update-Agent sagt, dass er lebt — auch wenn er nicht arbeiten kann
Gemeldet: „seit 1.5.1 muss ich nach jedem Update install-agent.sh fahren,
sonst kommt kein Update mehr". Die Konsole meldete „Der Update-Dienst auf dem
Server laeuft nicht" und schickte genau dorthin.

Er lief. Das Journal zeigt zwei Tage lang lueckenlos 57-59 Laeufe je Stunde.
Aber ueber zweiundachtzig Minuten hinweg startete und endete jeder Lauf in
DERSELBEN Sekunde, waehrend ein arbeitender Lauf zwei braucht: sie stiegen
alle sofort wieder aus, an der Sperre eines anderen Vorgangs — `flock -n 9 ||
exit 0`. Lautlos. Kein Journal-Eintrag (systemd sieht einen sauberen Lauf),
keine Zeile in der Statusdatei, nichts in der Konsole.

Und die Statusdatei war die einzige Lebendmeldung, die es gab. Sie wird erst
nach rund 190 Zeilen geschrieben — nach dem `git fetch` und nach einem
`docker compose exec`, beide ohne Zeitgrenze und beide unter der Sperre. Ein
Lauf, der davor aussteigt, hinterlaesst nichts, und nach zwanzig Minuten
schliesst die Konsole daraus, der Dienst sei tot. Sie schloss falsch, und die
Handlungsanweisung dazu aendert an einer gehaltenen Sperre nichts.

Drei Aenderungen:

  * Ein Lebenszeichen (agent-alive.json) als ERSTES bei jedem Lauf, vor allem,
    was blockieren kann. Zwei Zustaende: `running` heisst "ich habe die Sperre
    und arbeite", `blocked` heisst "ich bin ausgestiegen" — mit `since` (seit
    wann ununterbrochen) und `held_by` (wer, per fuser und ps).
  * Zeitgrenzen: 45 Sekunden um den docker-exec, 120 um den git fetch. Ohne
    sie wartet ein Abruf gegen eine tote Verbindung, bis das Betriebssystem
    ihn nach vielen Minuten aufgibt — und haelt dabei die Sperre.
  * Die Konsole liest das Lebenszeichen statt der Statusdatei. Der Unterschied
    ist der Punkt: Status heisst "zuletzt ERFOLGREICH nachgesehen",
    Lebenszeichen heisst "zuletzt ueberhaupt gelaufen". Ein blockierter Agent
    gilt als lebendig, aber seine Zahlen zaehlen nicht mehr als aktuell —
    `behind` und `target_release` fallen auf "unbekannt", statt eine Stunde
    alte Auskunft als frisch auszugeben.

Statt "laeuft nicht" steht dort jetzt "laeuft, kommt aber seit HH:MM nicht an
die Arbeit", mit dem Prozess darunter.

Ein Agent von VOR dieser Aenderung schreibt die Datei nicht — fuer den gilt
weiter die alte Regel. Ihn dafuer fuer tot zu erklaeren waere derselbe Fehler
mit umgekehrtem Vorzeichen; ein Test haelt das fest.

Widerlegt und damit ausgeschlossen: Besitzrechte (Wirt, .env und Behaelter
fuehren alle 1001), das Ausführbar-Bit (100755 im Repo), systemds
Startdrosselung (seit v1.1.0 abgeschaltet), ein zwischengespeicherter Zustand
im Panel (es liest bei jedem Aufruf frisch) und eine Luecke im Timer (keine).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 01:31:19 +02:00
..
AdminConsoleTest.php Send a guest bounced off the console to the console's own sign-in 2026-07-28 13:32:05 +02:00
AdminHostRestrictionTest.php Move the console's identity out of the customer table 2026-07-28 10:31:43 +02:00
AdminSettingsTest.php Check users directly for the reverse operator-identity collision, not just customers 2026-07-28 15:36:29 +02:00
BroadcastAuthTest.php Authorize the console's live feed on the operator guard, not the default 2026-07-28 13:31:50 +02:00
CapacityQueueTest.php Ein angehefteter Host umging die Reservierung 2026-08-01 18:53:11 +02:00
CatalogueSyncTest.php Hetzner-Cloud-DNS, Bereitschaftsseite aus sich heraus behebbar 2026-07-31 19:50:01 +02:00
CodexFixRoundTest.php Stripe-Client: offene Rechnungen listen und einziehen 2026-07-31 20:04:09 +02:00
ConnectionTestFeedbackTest.php Pruefergebnis als Modal statt am Seitenende 2026-07-31 21:36:43 +02:00
ConsoleAccessListTest.php Ein Waechter, der aufraeumt — und die vier offenen Punkte aus dem Betrieb 2026-08-03 09:43:33 +02:00
ConsoleHostSeparationTest.php Match the logout exemption through AdminArea, not a bare route check 2026-07-28 15:27:06 +02:00
ConsoleNavigationTest.php Sicht auf die Spuren, und ein Schalter, der die Drossel abstellt 2026-08-03 17:44:29 +02:00
ConsoleNetworkTest.php Move the console's identity out of the customer table 2026-07-28 10:31:43 +02:00
ConsoleReportsRealDataTest.php Merge main into the operating-mode branch 2026-07-30 17:53:20 +02:00
CustomerDetailTabsTest.php Die neue Leiter: Start 39, Team 79, Business 139 2026-08-01 17:05:58 +02:00
CustomerRevenueTest.php Schalter je Paket, ehrliche Statusanzeige, Reste der alten Leiter 2026-08-01 17:53:06 +02:00
DatacenterTest.php Hostnamen vergibt CluPilot: ein Name statt zweier, und der Zaehler ueberlebt das Loeschen 2026-08-01 13:45:43 +02:00
DunningFeesInEurosTest.php Ein Waechter, der aufraeumt — und die vier offenen Punkte aus dem Betrieb 2026-08-03 09:43:33 +02:00
EditCustomerTest.php Take the address by field, fix the customer type, ask why they leave 2026-07-30 16:41:32 +02:00
EnvFileEditorTest.php Add a raw .env editor to the Integrations page, with a net under it 2026-07-29 01:51:27 +02:00
EnvRestartTest.php Der Tunnel bekommt einen eigenen Container 2026-08-03 07:49:29 +02:00
GrantPlanTest.php Die neue Leiter: Start 39, Team 79, Business 139 2026-08-01 17:05:58 +02:00
HostCapacityTest.php Die neue Leiter: Start 39, Team 79, Business 139 2026-08-01 17:05:58 +02:00
HostManagementTest.php Host anlegen: die Seite beschrieb das Rettungssystem und startete die Pipeline 2026-08-02 01:38:48 +02:00
HostNamingTest.php Hostdetailseite: die Adresse steht neben den IPs und ist ein Klick zur Proxmox-Oberflaeche 2026-08-01 14:12:03 +02:00
HostReservationTest.php Fix-Runde: preferredDatacenter() blind fuer Reservierung, Loeschen hob sie auf 2026-08-01 16:21:46 +02:00
HostTakeoverGuideTest.php Host anlegen: die Seite beschrieb das Rettungssystem und startete die Pipeline 2026-08-02 01:38:48 +02:00
HostTakeoverPageTest.php Host anlegen: die Seite beschrieb das Rettungssystem und startete die Pipeline 2026-08-02 01:38:48 +02:00
HostTerminalTest.php Terminal: das Fenster sagt jetzt selbst, ob die Bruecke laeuft 2026-08-02 22:34:32 +02:00
HostVpnStateTest.php Read VPN host state from the synced peer table, not a live hub call 2026-07-29 00:18:21 +02:00
InboundMailTest.php Read the mailbox password where it actually is, and let the console test it 2026-07-30 13:12:29 +02:00
IncidentConsoleTest.php Rebuild the status page as a status page 2026-07-29 12:45:18 +02:00
IncidentDeleteTest.php Let an incident be deleted, and start measuring whether the hosts answer 2026-07-29 15:16:48 +02:00
InstanceAdminAccessTest.php Move the console's identity out of the customer table 2026-07-28 10:31:43 +02:00
IntegrationsPageTest.php Name the server variable under a credential, not the internal key 2026-07-30 13:20:29 +02:00
MailDeliverySwitchTest.php Hetzner-Cloud-DNS, Bereitschaftsseite aus sich heraus behebbar 2026-07-31 19:50:01 +02:00
MailPacePageTest.php Unter jeder Spur steht, was in ihr faehrt 2026-08-04 00:55:23 +02:00
MailPreviewTest.php Zwei Empfaengerkreise, und eine Wegwahl, die auch das Konto verschiebt 2026-08-03 17:00:20 +02:00
MailRegisterTest.php Der Altbestand des Registers wird geradegezogen 2026-08-03 21:18:26 +02:00
MailRoutingTest.php Zwei Empfaengerkreise, und eine Wegwahl, die auch das Konto verschiebt 2026-08-03 17:00:20 +02:00
MailTemplateTest.php Die neue Leiter: Start 39, Team 79, Business 139 2026-08-01 17:05:58 +02:00
MaintenanceTest.php Move the console's identity out of the customer table 2026-07-28 10:31:43 +02:00
OpenWorkTest.php Offene Punkte: was fehlt und was folgt nebeneinander, statt auf halber Breite zu enden 2026-08-02 16:40:26 +02:00
OperatorLogoutTest.php Stop the console logout from destroying a shared portal session 2026-07-28 13:58:42 +02:00
OperatorModelTest.php Give the people who run CluPilot a table of their own 2026-07-28 09:20:54 +02:00
OperatorTwoFactorEnrollmentTest.php Give the two-factor page a way back, and a shape 2026-07-28 22:25:42 +02:00
OperatorTwoFactorPolicyTest.php Move operator two-factor enrolment off admin.settings onto its own page 2026-07-28 15:11:20 +02:00
PasswordConfirmationGuardTest.php Merge credentials and infrastructure into one Integrations page 2026-07-29 01:49:39 +02:00
PlanAdminTest.php Test für den Normalfall der Statusanzeige: "Im Verkauf" 2026-08-01 18:04:28 +02:00
ProvisioningActionsTest.php Ein Waechter, der aufraeumt — und die vier offenen Punkte aus dem Betrieb 2026-08-03 09:43:33 +02:00
ProxyHostsTest.php Keep IP addresses out of a certificate overview 2026-07-31 01:01:47 +02:00
RbacMoveTest.php Sperren sehen und aufheben: Portalseite fuer den Inhaber, Abschnitte in der Konsole 2026-08-03 15:53:24 +02:00
RbacTest.php Move the console's identity out of the customer table 2026-07-28 10:31:43 +02:00
RevenueGrantedTest.php Skip the invoice for a full gift, keep it out of revenue, hide its price 2026-07-29 12:41:32 +02:00
RoleManagementTest.php Zwei Attrappen: ein Banner ohne Hintergrund und Rechte, die ihren Schluessel statt ihrer Beschreibung zeigten 2026-08-02 16:47:15 +02:00
SecretCipherTest.php Make isUsable() apply the same 32-byte rule encrypter() does 2026-07-28 05:09:09 +02:00
SecretVaultTest.php Hetzner-Cloud-DNS, Bereitschaftsseite aus sich heraus behebbar 2026-07-31 19:50:01 +02:00
ServiceInvoiceTest.php Write an invoice for work that came off no price list 2026-07-29 20:12:26 +02:00
SettingsTabsTest.php Seitenleiste neu geordnet: Betrieb trug zwoelf Eintraege aus drei Themen 2026-08-02 00:29:14 +02:00
SshKeypairTest.php Hetzner-Cloud-DNS, Bereitschaftsseite aus sich heraus behebbar 2026-07-31 19:50:01 +02:00
StripePublishableKeyTest.php Hetzner-Cloud-DNS, Bereitschaftsseite aus sich heraus behebbar 2026-07-31 19:50:01 +02:00
StripeWebhookSecretInVaultTest.php Hetzner-Cloud-DNS, Bereitschaftsseite aus sich heraus behebbar 2026-07-31 19:50:01 +02:00
UpdateButtonTest.php Der Update-Agent sagt, dass er lebt — auch wenn er nicht arbeiten kann 2026-08-04 01:31:19 +02:00
UpdateWindowTest.php Update on a schedule if the owner wants one, and say where incidents go 2026-07-29 15:01:54 +02:00
VpnTest.php Release v1.3.85 — Handshake-Prüfung hing an einem Programm, das es nicht gibt 2026-08-01 03:00:19 +02:00